forth-compiler.meta 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. .syntax xforth "./meta";
  2. .initialize .var(*stacklen) .var(*entry) .prototype(comment);
  3. line = .token .neq(10) *.neq(10) .deftoken;
  4. id = .token .id .adjtoken \ *(.eq('.') .id) / .deftoken;
  5. mathop = '+' | '-' | '*' | '/';
  6. number = .token .number .adjtoken *(mathop .number) .deftoken;
  7. entry = 'entry' id .set(entry);
  8. stack = 'retstack' number .set(stacklen);
  9. configs = ^stack ^entry;
  10. prelude = 'prelude' {'; user prologue:\n'}
  11. *('endprelude' {nl} .success | comment | line {$ nl});
  12. includes = 'includes'
  13. *('endincludes' {nl} .success | .string {'include '$ nl});
  14. word = 'word' id {$ ':' nl ' dd _enter_routine' nl}
  15. *('endword' {' dd _leave_routine' nl} .success
  16. |'literal' {' dd _literal' nl} (.number|id) {' dd '$ nl}
  17. |(.number|id) {' dd '$ nl} );
  18. code = 'code' id {$ ':' nl ' dd _enter_native' nl}
  19. *('endcode' {' jmp _next_routine' nl} .success
  20. | line {' '$ nl});
  21. comment = '/' line | ';' line;
  22. fasm_bootstrap = {"format elf executable 3
  23. entry _start
  24. include './symbols.inc'
  25. include './structs.inc'
  26. include './ithread.inc'\n\n"};
  27. fasm_start = {'segment writeable
  28. return_stack_top dd ?
  29. stack_top dd ?
  30. segment executable
  31. _start:
  32. cld
  33. mov ebp, esp
  34. sub esp, '} .ifte(stacklen,"2*1024*1024") {'
  35. mov [stack_top], esp
  36. mov [return_stack_top], ebp
  37. mov esi, .forth_boot
  38. jmp _next
  39. .forth_boot:
  40. dd _enter_routine
  41. dd '} .ifte(entry,"main") {'
  42. dd _halt
  43. ; user code:\n'};
  44. program =
  45. *comment (configs | .e)
  46. fasm_bootstrap
  47. *comment (includes | .e)
  48. *comment (prelude | .e)
  49. fasm_start
  50. .expect('Comentário ou código')
  51. (comment | word | code) *(comment | word | code);
  52. .end program;