ма-а-аленький, но рабочий набросок преобразователя форт в асм
source file: f2a.fts
memory/ buff.fts
\ -- буфер для склейки строк ---------------------------------------------------
USER-VALUE outbuf
\ создать буфер размером в 1 МБ (должно хватать)
: init-buf 0x100000 Buffer TO outbuf ;
\ освободить занятый буфер
: del-buf outbuf Retire ;
\ добавить в буфер строку текста
: +>buf ( asc # --> ) outbuf >Buffer DROP ;
\ вернуть содержимое буфера
: buf> ( --> asc # ) outbuf Buffer> ;
\ открыть буфер
: buf< ( --> ) outbuf Clean ;
\ -- сохранение содержимого в файл ---------------------------------------------
0 VALUE FId
\ создать файл с заданным именем
: file ( asc # --> fid ) W/O CREATE-FILE THROW TO FId ;
\ сохранить содержимое буфера в файл
: save ( fid --> )
>L buf> L@ WRITE-FILE THROW
L> CLOSE-FILE THROW ;
\ -- создание новой метки ------------------------------------------------------
USER-VALUE LastLab
: l>name ( lab --> asc # ) S>D 0x10 {# # # # # s" lab_" HOLDS #> ;
\ создать новую метку, вернуть имя
: label ( --> lab asc # ) LastLab 1 + DUP TO LastLab DUP l>name ;
\ -- словарь для хранения макросов
VOCABULARY MACRO
\ завершить создание макроса
: ;M ( --> ) [COMPILE] ; IMMEDIATE DEFINITIONS ; IMMEDIATE
\ начать создание макроса с указанным именем
: (:) ( asc # --> ) ALSO MACRO DEFINITIONS PREVIOUS S: ;
\ начать создание макроса
: M: ( /name --> ) NextWord (:) ;
\ начать трансляцию текста
: TRANSLATE: ( /name --> )
NextWord <| KEEPS s" .asm" KEEPS 0 KEEP |> file
init-buf
ONLY MACRO DEFINITIONS ;
\ -- ---------------------------------------------------------------------------
\ завершить трансляцию текста
M: ;TRANSLATE ( --> ) FId save ONLY DEFINITIONS del-buf ;M
\ создать безымянную метку для перехода назад
M: BEGIN ( --> lab p )
label +>buf s" :\t" +>buf s" ; переход назад\n\r" +>buf
NOTICE" Не обнаружена метка для перехода назад!" ;M
\ создать безусловный переход назад на метку lab
M: AGAIN ( lab p --> )
?PAIRS" Не обнаружена метка для перехода назад!"
s" \tJMP " +>buf l>name +>buf s" \n\r" +>buf ;M
M: NOOP s" \t\tNOP\n\r" +>buf ;M
M: DROP s" \t\tMOV EAX, [EBP]\n\r\t\tLEA EBP, [EBP]\n\r" +>buf ;M
M: SWAP s" \t\tMOV EDX, [EBP]\n\r\t\tMOV [EBP], EAX\n\r\t\tMOV EAX, EDX\n\r "
+>buf ;M
M: : ( / name --> )
NextWord DDUP (:)
DDUP SLIT, <: s" \t CALL _" +>buf +>buf s" \n\r" +>buf ;>
COMPILE,
<| s" _" KEEPS KEEPS s" : ; новое определение\n\r" KEEPS |> +>buf
;M
M: ; ( --> ) [COMPILE] ;M ;M
M: \ [COMPILE] \ ;M
\ -- ---------------------------------------------------------------------------
\ пример транслируемого текста
TRANSLATE: zzz
NOOP BEGIN DROP SWAP AGAIN DROP
: zzz DROP SWAP ;
NOOP
zzz
NOOP
;TRANSLATE
в результате выходит следующее:
Код:
NOP
lab_0001: ; переход назад
MOV EAX, [EBP]
LEA EBP, [EBP]
MOV EDX, [EBP]
MOV [EBP], EAX
MOV EAX, EDX
JMP lab_0001
MOV EAX, [EBP]
LEA EBP, [EBP]
_zzz: ; новое определение
MOV EAX, [EBP]
LEA EBP, [EBP]
MOV EDX, [EBP]
MOV [EBP], EAX
MOV EAX, EDX
NOP
CALL _zzz
NOP