Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
5.9KB

  1. ( Inner core. This unit represents core definitions that
  2. happen right after native definitions. Before core.fs.
  3. Unlike core.fs and its followers, this unit isn't self-
  4. sustained. Like native defs it uses the machinery of a
  5. full Forth interpreter, notably for flow structures.
  6. Because of that, it has to obey specific rules:
  7. 1. It cannot compile a word from higher layers. Using
  8. immediates is fine though.
  9. 2. If it references a word from this unit or from native
  10. definitions, these need to be properly offsetted
  11. because their offset at compile time are not the same
  12. as their runtime offsets.
  13. 3. Anything they refer to in the boot binary has to be
  14. properly stabilized.
  15. 4. Make sure that the words you compile are not overridden
  16. by the full interpreter.
  17. 5. When using words as immediates, make sure that they're
  18. not defined in icore or, if they are, make sure that
  19. they are *not* offsetted
  20. Those rules are mostly met by the "xcomp" unit, which is
  21. expected to have been loaded prior to icore and redefines
  22. ":" and other defining words. So, in other words, when
  23. compiling icore, ":" doesn't means what you think it means,
  24. go look in xcomp.
  25. )
  26. : RAM+
  27. [ RAMSTART LITN ] +
  28. ;
  29. : FLAGS 0x08 RAM+ ;
  30. : (parse*) 0x0a RAM+ ;
  31. : HERE 0x04 RAM+ ;
  32. : CURRENT* 0x51 RAM+ ;
  33. : CURRENT CURRENT* @ ;
  34. ( w -- a f )
  35. : (find) CURRENT @ SWAP _find ;
  36. : QUIT
  37. 0 FLAGS ! (resRS)
  38. LIT< INTERPRET (find) DROP EXECUTE
  39. ;
  40. : ABORT (resSP) QUIT ;
  41. : = CMP NOT ;
  42. : < CMP -1 = ;
  43. : > CMP 1 = ;
  44. ( r c -- r f )
  45. ( Parse digit c and accumulate into result r.
  46. Flag f is 0 when c was a valid digit, 1 when c was WS,
  47. -1 when c was an invalid digit. )
  48. : _pdacc
  49. DUP 0x21 < IF DROP 1 EXIT THEN
  50. ( parse char )
  51. '0' -
  52. ( if bad, return "r -1" )
  53. DUP 0 < IF DROP -1 EXIT THEN ( bad )
  54. DUP 9 > IF DROP -1 EXIT THEN ( bad )
  55. ( good, add to running result )
  56. SWAP 10 * + ( r*10+n )
  57. 0 ( good )
  58. ;
  59. : (parsed) ( a -- n f )
  60. ( read first char outside of the loop. it *has* to be
  61. nonzero. )
  62. DUP C@ ( a c )
  63. ( special case: do we have a negative? )
  64. DUP '-' = IF
  65. ( Oh, a negative, let's recurse and reverse )
  66. DROP 1+ ( a+1 )
  67. (parsed) ( n f )
  68. 0 ROT ( f 0 n )
  69. - SWAP EXIT ( 0-n f )
  70. THEN
  71. ( running result from first char )
  72. 0 SWAP ( a r c )
  73. _pdacc ( a r f )
  74. DUP IF
  75. ( first char was not a valid digit )
  76. 2DROP 0 EXIT ( a 0 )
  77. THEN
  78. BEGIN ( a r 0 )
  79. DROP SWAP 1+ ( r a+1 )
  80. DUP C@ ( r a c )
  81. ROT SWAP ( a r c )
  82. _pdacc ( a r f )
  83. DUP UNTIL
  84. ( a r f -- f is 1 on success, -1 on error, normalize
  85. to bool. )
  86. 1 = ( a r f )
  87. ( we want "r f" )
  88. ROT DROP
  89. ;
  90. ( This is only the "early parser" in earlier stages. No need
  91. for an abort message )
  92. : (parse)
  93. (parsed) NOT IF ABORT THEN
  94. ;
  95. : C<
  96. ( 0c == CINPTR )
  97. 0x0c RAM+ @ EXECUTE
  98. ;
  99. : ,
  100. HERE @ !
  101. HERE @ 2+ HERE !
  102. ;
  103. : C,
  104. HERE @ C!
  105. HERE @ 1+ HERE !
  106. ;
  107. ( The NOT is to normalize the negative/positive numbers to 1
  108. or 0. Hadn't we wanted to normalize, we'd have written:
  109. 32 CMP 1 - )
  110. : WS? 33 CMP 1+ NOT ;
  111. : TOWORD
  112. BEGIN
  113. C< DUP WS? NOT IF EXIT THEN DROP
  114. AGAIN
  115. ;
  116. ( Read word from C<, copy to WORDBUF, null-terminate, and
  117. return, make HL point to WORDBUF. )
  118. : WORD
  119. ( 0e == WORDBUF )
  120. 0x0e RAM+ ( a )
  121. TOWORD ( a c )
  122. BEGIN
  123. ( We take advantage of the fact that char MSB is
  124. always zero to pre-write our null-termination )
  125. OVER ! ( a )
  126. 1+ ( a+1 )
  127. C< ( a c )
  128. DUP WS?
  129. UNTIL
  130. ( a this point, PS is: a WS )
  131. ( null-termination is already written )
  132. 2DROP
  133. 0x0e RAM+
  134. ;
  135. : SCPY
  136. BEGIN ( a )
  137. DUP C@ ( a c )
  138. DUP C, ( a c )
  139. NOT IF DROP EXIT THEN
  140. 1+ ( a+1 )
  141. AGAIN
  142. ;
  143. : [entry]
  144. HERE @ ( w h )
  145. SWAP SCPY ( h )
  146. ( Adjust HERE -1 because SCPY copies the null )
  147. HERE @ 1- ( h h' )
  148. DUP HERE ! ( h h' )
  149. SWAP - ( sz )
  150. ( write prev value )
  151. HERE @ CURRENT @ - ,
  152. ( write size )
  153. C,
  154. HERE @ CURRENT !
  155. ;
  156. : (entry) WORD [entry] ;
  157. : INTERPRET
  158. BEGIN
  159. WORD
  160. (find)
  161. IF
  162. 1 FLAGS !
  163. EXECUTE
  164. 0 FLAGS !
  165. ELSE
  166. (parse*) @ EXECUTE
  167. THEN
  168. AGAIN
  169. ;
  170. ( system c< simply reads source from binary, starting at
  171. LATEST. Convenient way to bootstrap a new system. )
  172. : (boot<)
  173. ( 2e == BOOT C< PTR )
  174. 0x2e RAM+ @ ( a )
  175. DUP C@ ( a c )
  176. SWAP 1 + ( c a+1 )
  177. 0x2e RAM+ ! ( c )
  178. ;
  179. : BOOT
  180. 0x02 RAM+ CURRENT* !
  181. LIT< (parse) (find) DROP (parse*) !
  182. ( 2e == SYSTEM SCRATCHPAD )
  183. CURRENT @ 0x2e RAM+ !
  184. ( 0c == CINPTR )
  185. LIT< (boot<) (find) DROP 0x0c RAM+ !
  186. LIT< INIT (find)
  187. IF EXECUTE
  188. ELSE DROP INTERPRET THEN
  189. ;
  190. ( LITN has to be defined after the last immediate usage of
  191. it to avoid bootstrapping issues )
  192. : LITN
  193. ( 32 == NUMBER )
  194. 32 , ,
  195. ;
  196. : IMMED? 1- C@ 0x80 AND ;
  197. ( ';' can't have its name right away because, when created, it
  198. is not an IMMEDIATE yet and will not be treated properly by
  199. xcomp. )
  200. : _
  201. ['] EXIT ,
  202. R> DROP ( exit : )
  203. ; IMMEDIATE
  204. XCURRENT @ ( to PSP )
  205. : :
  206. (entry)
  207. ( We cannot use LITN as IMMEDIATE because of bootstrapping
  208. issues. Same thing for ",".
  209. 32 == NUMBER 14 == compiledWord )
  210. [ 32 H@ ! 2 ALLOT 14 H@ ! 2 ALLOT ] C,
  211. BEGIN
  212. WORD
  213. (find)
  214. ( is word )
  215. IF DUP IMMED? IF EXECUTE ELSE , THEN
  216. ( maybe number )
  217. ELSE (parse*) @ EXECUTE LITN THEN
  218. AGAIN
  219. ;
  220. ( from PSP ) ';' SWAP 4 - C!