vm.fs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. \ vm.fs VM Interpreter, RosettaCode Compiler Task 20170521
  2. \ Copyright 2017, Eric Bavier <bavier@member.fsf.org>
  3. \ This is Free Software licensed under the GPLv3, or any later
  4. CREATE BUF 0 , \ single-character look-ahead buffer
  5. : PEEK BUF @ 0= IF KEY BUF ! THEN BUF @ ;
  6. : GETC PEEK 0 BUF ! ;
  7. : SPACE? DUP BL = SWAP 9 14 WITHIN OR ;
  8. : >SPACE BEGIN PEEK SPACE? WHILE GETC DROP REPEAT ;
  9. : DIGIT? 48 58 WITHIN ;
  10. : >INT ( -- n) >SPACE 0
  11. BEGIN PEEK DIGIT?
  12. WHILE GETC [CHAR] 0 - SWAP 10 * + REPEAT ;
  13. CREATE A 0 ,
  14. : C@A ( -- c) A @ C@ ;
  15. : C@A+ ( -- c) C@A 1 CHARS A +! ;
  16. : C!A+ ( c --) A @ C! 1 CHARS A +! ;
  17. : WORD ( -- c-addr) >SPACE PAD 1+ A !
  18. BEGIN PEEK SPACE? INVERT WHILE GETC C!A+ REPEAT
  19. >SPACE PAD A @ OVER - 1- PAD C! ;
  20. : >STRING ( -- c-addr) >SPACE GETC DROP PAD 1+ A !
  21. BEGIN PEEK [CHAR] " <> WHILE GETC C!A+ REPEAT
  22. GETC DROP PAD A @ OVER - 1- PAD C! ;
  23. : \INTERN ( c-addr -- c-addr) HERE >R A ! C@A+ DUP C,
  24. BEGIN DUP WHILE C@A+
  25. DUP [CHAR] \ = IF DROP -1 R@ +! C@A+
  26. [CHAR] n = IF 10 ELSE [CHAR] \ THEN
  27. THEN C, 1-
  28. REPEAT DROP R> ;
  29. : . 0 .R ;
  30. CREATE DATA 0 ,
  31. CREATE STRINGS 0 ,
  32. : >DATA HERE DATA !
  33. WORD DROP >INT 4 * BEGIN DUP WHILE 0 C, 1- REPEAT DROP ;
  34. : >STRINGS HERE STRINGS !
  35. WORD DROP >INT DUP >R CELLS ALLOT
  36. 0 BEGIN DUP R@ < WHILE
  37. DUP CELLS >STRING \INTERN STRINGS @ ROT + ! 1+
  38. REPEAT R> DROP DROP ;
  39. : >HEADER >DATA >STRINGS ;
  40. : i32! ( n addr --)
  41. OVER $FF AND OVER C! 1+
  42. OVER 8 RSHIFT $FF AND OVER C! 1+
  43. OVER 16 RSHIFT $FF AND OVER C! 1+
  44. SWAP 24 RSHIFT $FF AND SWAP C! ;
  45. : i32@ ( addr -- n) >R \ This is kinda slow... hmm
  46. R@ C@
  47. R@ 1 + C@ 8 LSHIFT OR
  48. R@ 2 + C@ 16 LSHIFT OR
  49. R> 3 + C@ 24 LSHIFT OR
  50. DUP $7FFFFFFF AND SWAP $80000000 AND - ; \ sign extend
  51. : i32, ( n --) HERE 4 ALLOT i32! ;
  52. : i32@+ ( -- n) A @ i32@ A @ 4 + A ! ;
  53. CREATE BYTECODE 0 ,
  54. : @fetch i32@+ 4 * DATA @ + i32@ ;
  55. : @store i32@+ 4 * DATA @ + i32! ;
  56. : @jmp i32@+ BYTECODE @ + A ! ;
  57. : @jz IF 4 A +! ELSE @jmp THEN ;
  58. : @prts CELLS STRINGS @ + @ COUNT TYPE ;
  59. : @div >R S>D R> SM/REM SWAP DROP ;
  60. CREATE OPS
  61. ' @fetch , ' @store , ' i32@+ , ' @jmp , ' @jz ,
  62. ' EMIT , ' . , ' @prts , ' NEGATE , ' 0= ,
  63. ' + , ' - , ' * , ' @div , ' MOD ,
  64. ' < , ' > , ' <= , ' >= ,
  65. ' = , ' <> , ' AND , ' OR , ' BYE ,
  66. CREATE #OPS 0 ,
  67. : OP: CREATE #OPS @ , 1 #OPS +! DOES> @ ;
  68. OP: fetch OP: store OP: push OP: jmp OP: jz
  69. OP: prtc OP: prti OP: prts OP: neg OP: not
  70. OP: add OP: sub OP: mul OP: div OP: mod
  71. OP: lt OP: gt OP: le OP: ge
  72. OP: eq OP: ne OP: and OP: or OP: halt
  73. : >OP WORD FIND
  74. 0= IF ." Unrecognized opcode" ABORT THEN EXECUTE ;
  75. : >i32 >INT i32, ;
  76. : >[i32] GETC DROP >i32 GETC DROP ;
  77. : >OFFSET WORD DROP ( drop relative offset) >i32 ;
  78. CREATE >PARAM ' >[i32] DUP , , ' >i32 , ' >OFFSET DUP , ,
  79. : >BYTECODE HERE >R
  80. BEGIN >INT DROP >OP >R R@ C,
  81. R@ 5 < IF R@ CELLS >PARAM + @ EXECUTE THEN
  82. R> halt = UNTIL R> BYTECODE ! ;
  83. : RUN BYTECODE @ A !
  84. BEGIN C@A+ CELLS OPS + @ EXECUTE AGAIN ;
  85. : INTERPRET >HEADER >BYTECODE RUN ;
  86. :NONAME DEFERS 'COLD INTERPRET ; IS 'COLD