PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/cross.4

https://bitbucket.org/kt97679/relf
Forth | 312 lines | 238 code | 63 blank | 11 comment | 10 complexity | 6541de142a75f91760d2dbe3a374e0fb MD5 | raw file
  1. \ Cross compiler to produce machine-independent binary image of RelF
  2. \ (Relative Forth). Uses kernel.4.
  3. \ Based on SOD32 by L.C. Benschop
  4. \ Copyright 2001 - 2005, Kirill Timofeev, kt97679@gmail.com
  5. \ The program is released under the GNU General Public License version 2.
  6. \ There is NO WARRANTY.
  7. \ PART 1: THE VOCABULARIES.
  8. VOCABULARY TARGET
  9. \ This vocabulary will hold shadow definitions for all words that are in
  10. \ the target dictionary. When a shadow definition is executed, it
  11. \ performs the compile action in the target dictionary.
  12. VOCABULARY TRANSIENT
  13. \ This vocabulary will hold definitions that must be executed by the
  14. \ host system ( the system on which the cross compiler runs) and that
  15. \ compile to the target system.
  16. \ Expl: The word IF occurs in all three vocabularies. The word IF in the
  17. \ FORTH vocabulary is run by the host system and is used when
  18. \ compiling host definitions. A different version is in the
  19. \ TRANSIENT vocabulary. This one runs on the host system and
  20. \ is used when compiling target definitions. The version in the
  21. \ TARGET vocabulary is the version that will run on the target
  22. \ system.
  23. \ PART 2: THE TARGET DICTIONARY SPACE.
  24. \ Next we need to define the target space and the words to access it.
  25. 20000 CONSTANT IMAGE_SIZE
  26. CREATE IMAGE IMAGE_SIZE CHARS ALLOT \ This space contains the target image.
  27. IMAGE IMAGE_SIZE 0 FILL \ Initialize it to zero.
  28. \ Fetch and store characters in the target space.
  29. : C@-T ( t-addr --- c) CHARS IMAGE + C@ ;
  30. : C!-T ( c t-addr ---) CHARS IMAGE + C! ;
  31. \ Fetch and store cells in the target space.
  32. \ SOD32 is big endian 32 bit so store explicitly big-endian.
  33. : @-T ( t-addr --- x)
  34. CHARS IMAGE + DUP C@ 24 LSHIFT OVER 1 CHARS + C@ 16 LSHIFT +
  35. OVER 2 CHARS + C@ 8 LSHIFT + SWAP 3 CHARS + C@ + ;
  36. : !-T ( x t-addr ---)
  37. CHARS IMAGE + OVER 24 RSHIFT OVER C! OVER 16 RSHIFT OVER 1 CHARS + C!
  38. OVER 8 RSHIFT OVER 2 CHARS + C! 3 CHARS + C! ;
  39. \ A dictionary is constructed in the target space. Here are the primitives
  40. \ to maintain the dictionary pointer and to reserve space.
  41. VARIABLE DP-T \ Dictionary pointer for target dictionary.
  42. 0 DP-T ! \ Initialize it to zero, SOD starts at 0.
  43. : THERE ( --- t-addr) DP-T @ ; \ Equivalent of HERE in target space.
  44. : ALLOT-T ( n --- ) DP-T +! ; \ Reserve n bytes in the dictionary.
  45. : CHARS-T ( n1 --- n2 ) ;
  46. : CELLS-T ( n1 --- n2 ) 2 LSHIFT ; \ Cells are 4 chars.
  47. : ALIGN-T \ SOD only accesses cells at aligned
  48. \ addresses.
  49. BEGIN THERE 3 AND WHILE 1 ALLOT-T REPEAT ;
  50. : ALIGNED-T ( n1 --- n2 ) 3 + -4 AND ;
  51. : C,-T ( c --- ) THERE C!-T 1 CHARS ALLOT-T ;
  52. : ,-T ( x --- ) THERE !-T 1 CELLS-T ALLOT-T ;
  53. : PLACE-T ( c-addr len t-addr --- ) \ Move counted string to target space.
  54. OVER OVER C!-T 1+ CHARS IMAGE + SWAP CHARS CMOVE ;
  55. \ After the Forth system is constructed, its image must be saved.
  56. : SAVE-IMAGE ( "name" --- )
  57. 32 WORD COUNT W/O BIN CREATE-FILE ABORT" Can't create file" >R
  58. IMAGE THERE R@ WRITE-FILE ABORT" Can't write file"
  59. R> CLOSE-FILE ABORT" Can't close file" ;
  60. \ PART 3: CREATING NEW DEFINITIONS IN THE TARGET SYSTEM.
  61. \ These words create new target definitions, both the shadow definition
  62. \ and the header in the target dictionary. The layout of target headers
  63. \ can be changed but FIND in the target system must be changed accordingly.
  64. VARIABLE TLINK 0 TLINK ! \ This variable points to the name
  65. \ of the last definition.
  66. : "HEADER >IN @ CREATE >IN ! \ Create the shadow definition.
  67. ALIGN-T
  68. TLINK @ IF
  69. TLINK @ THERE - ,-T \ Lay out the link field.
  70. ELSE
  71. 0 ,-T
  72. THEN
  73. BL WORD
  74. COUNT DUP >R THERE PLACE-T \ Place name in target dictionary.
  75. THERE TLINK !
  76. THERE C@-T 128 OR THERE C!-T R> 1+ ALLOT-T ALIGN-T ;
  77. \ Set bit 7 of count byte as a marker.
  78. \ : "HEADER CREATE ALIGN-T ; \ Alternative for "HEADER in case the target system
  79. \ is just an application without headers.
  80. ALSO TRANSIENT DEFINITIONS
  81. : IMMEDIATE TLINK @ DUP C@-T 64 OR SWAP C!-T ;
  82. \ Set the IMMEDIATE bit of last name.
  83. PREVIOUS DEFINITIONS
  84. \ PART 4: CODE GENERATION
  85. VARIABLE STATE-T 0 STATE-T ! \ State variable for cross compiler.
  86. : T] 1 STATE-T ! ;
  87. : T[ 0 STATE-T ! ;
  88. VARIABLE CSP \ Stack pointer checking between : and ;
  89. : !CSP DEPTH CSP ! ;
  90. : ?CSP DEPTH CSP @ - ABORT" Incomplete control structure" ;
  91. VARIABLE LAST-PRIMITIVE 1 LAST-PRIMITIVE !
  92. : LITERAL-T ( n --- ) 9 ,-T ,-T ;
  93. ONLY FORTH ALSO TRANSIENT DEFINITIONS FORTH
  94. \ Now define the words that do compile code.
  95. : PRIMITIVE ( c --- )
  96. LAST-PRIMITIVE @ DUP 4 LAST-PRIMITIVE +!
  97. "HEADER DUP , ,-T 5 ,-T \ Create an executable target definition.
  98. TLINK @ DUP C@-T 32 OR SWAP C!-T \ Set the MACRO bit of last name.
  99. DOES> @ ,-T
  100. ;
  101. : : !CSP "HEADER THERE , T] DOES> @ THERE - 4 - ,-T ;
  102. : ; 5 ,-T T[ ?CSP ; \ Compile EXIT (5). Quit compilation state.
  103. FORTH DEFINITIONS
  104. \ PART 5: FORWARD REFERENCES
  105. \ Some definitions are referenced before they are defined. A definition
  106. \ in the TRANSIENT voc is created for each forward referenced definition.
  107. \ This links all addresses together where the forward reference is used.
  108. \ The word RESOLVE stores the real address everywhere it is needed.
  109. : FORWARD
  110. CREATE -1 , \ Store head of list in the definition.
  111. DOES>
  112. DUP @ ,-T THERE 1 CELLS-T - SWAP ! \ Reserve a cell in the dictionary
  113. \ where the call to the forward definition must come.
  114. \ As the call address is unknown, store link to next
  115. \ reference instead.
  116. ;
  117. : RESOLVE
  118. ALSO TARGET >IN @ ' >BODY @ >R >IN ! \ Find the resolving word in the
  119. \ target voc. and take the CFA out of the definition.
  120. TRANSIENT ' >BODY @ \ Find the forward ref word in the
  121. \ TRANSIENT VOC and take list head.
  122. BEGIN
  123. DUP -1 - \ Traverse all the links until end.
  124. WHILE
  125. DUP @-T \ Take address of next link from dict.
  126. R@ ROT SWAP OVER - 4 - SWAP !-T \ Set resolved address in dict.
  127. REPEAT DROP R> DROP PREVIOUS
  128. ;
  129. \ PART 6: DEFINING WORDS.
  130. TRANSIENT DEFINITIONS FORTH
  131. FORWARD DOVAR \ Dovar is the runtime part of a variable.
  132. : VARIABLE "HEADER THERE , [ TRANSIENT ] DOVAR [ FORTH ] 0 ,-T
  133. \ Create a variable.
  134. DOES> @ THERE - 4 - ,-T ;
  135. : CONSTANT "HEADER THERE ,
  136. 9 ,-T ,-T 5 ,-T \ Assemble the instruction LIT (9) with EXIT (5).
  137. DOES> @ 4 + @-T LITERAL-T \ Compile const as a literal for speed.
  138. ;
  139. FORTH DEFINITIONS
  140. : T' ( --- t-addr) \ Find the execution token of a target definition.
  141. ALSO TARGET ' >BODY @ \ Get the address from the shadow definition.
  142. PREVIOUS
  143. ;
  144. : >BODY-T ( t-addr1 --- t-addr2 ) \ Convert executing token to param address.
  145. 1 CELLS + ;
  146. \ PART 7: COMPILING WORDS
  147. TRANSIENT DEFINITIONS FORTH
  148. : BEGIN THERE ;
  149. : UNTIL 17 ,-T THERE - ,-T ; \ 17 - conditional jump
  150. : IF 17 ,-T THERE 1 CELLS ALLOT-T ; \ 13 - unconditional jump
  151. : THEN THERE OVER - SWAP !-T ;
  152. : ELSE 13 ,-T THERE 1 CELLS ALLOT-T SWAP THERE OVER - SWAP !-T ;
  153. : WHILE 17 ,-T THERE 1 CELLS ALLOT-T SWAP ;
  154. : REPEAT 13 ,-T THERE - ,-T THERE OVER - SWAP !-T ;
  155. FORWARD (DO)
  156. FORWARD (LOOP)
  157. FORWARD (.")
  158. FORWARD (ABORT")
  159. FORWARD (POSTPONE)
  160. : DO [ TRANSIENT ] (DO) [ FORTH ] THERE ;
  161. : LOOP [ TRANSIENT ] (LOOP) [ FORTH ] THERE - ,-T ;
  162. : ." [ TRANSIENT ] (.") [ FORTH ] 34 WORD COUNT DUP 1+ >R
  163. THERE PLACE-T R> ALLOT-T ALIGN-T ;
  164. : POSTPONE [ TRANSIENT ] (POSTPONE) [ FORTH ] T' THERE - ,-T ;
  165. : ABORT" [ TRANSIENT ] (ABORT") [ FORTH ] 34 WORD COUNT DUP 1+ >R
  166. THERE PLACE-T R> ALLOT-T ALIGN-T ;
  167. : \ POSTPONE \ ; IMMEDIATE
  168. : ( POSTPONE ( ; IMMEDIATE \ Move duplicates of comment words to TRANSIENT
  169. : CHARS-T CHARS-T ; \ Also words that must be executed while cross compiling.
  170. : CELLS-T CELLS-T ;
  171. : ALLOT-T ALLOT-T ;
  172. : ['] T' LITERAL-T ;
  173. FORTH DEFINITIONS
  174. \ PART 8: THE CROSS COMPILER ITSELF.
  175. VARIABLE DPL
  176. : NUMBER? ( c-addr ---- d f)
  177. -1 DPL !
  178. BASE @ >R
  179. COUNT
  180. OVER C@ 45 = DUP >R IF 1 - SWAP 1 + SWAP THEN \ Get any - sign
  181. OVER C@ 36 = IF 16 BASE ! 1 - SWAP 1 + SWAP THEN \ $ sign for hex.
  182. OVER C@ 35 = IF 10 BASE ! 1 - SWAP 1 + SWAP THEN \ # sign for decimal
  183. DUP 0 > 0= IF R> DROP R> BASE ! 0 EXIT THEN \ Length 0 or less?
  184. >R >R 0 0 R> R>
  185. BEGIN
  186. >NUMBER
  187. DUP IF OVER C@ 46 = IF 1 - DUP DPL ! SWAP 1 + SWAP ELSE \ handle point.
  188. R> DROP R> BASE ! 0 EXIT THEN \ Error if anything but point
  189. THEN
  190. DUP 0= UNTIL DROP DROP R> IF DNEGATE THEN
  191. R> BASE ! -1
  192. ;
  193. : CROSS-COMPILE
  194. ONLY TARGET DEFINITIONS ALSO TRANSIENT \ Restrict search order.
  195. BEGIN
  196. BL WORD
  197. DUP C@ 0= IF \ Get new word
  198. DROP REFILL DROP \ If empty, get new line.
  199. ELSE
  200. DUP COUNT S" END-CROSS" COMPARE 0= \ Exit cross compiler on END-CROSS
  201. IF
  202. ONLY FORTH ALSO DEFINITIONS \ Normal search order again.
  203. DROP EXIT
  204. THEN
  205. FIND IF \ Execute if found.
  206. EXECUTE
  207. ELSE
  208. NUMBER? 0= ABORT" Undefined word" DROP
  209. STATE-T @ IF \ Parse it as a number.
  210. LITERAL-T \ If compiling then compile as a literal.
  211. THEN
  212. THEN
  213. THEN
  214. 0 UNTIL
  215. ;
  216. \ PART 9: CROSS COMPILING THE KERNEL
  217. \ Up till now not a single byte of the new Forth kernel has actually been
  218. \ compiled.
  219. TRANSIENT DEFINITIONS
  220. FORWARD COLD
  221. FORWARD WARM
  222. FORWARD DIV-EX
  223. FORWARD BREAK-EX
  224. FORWARD TIMER-EX
  225. FORWARD THROW
  226. FORTH DEFINITIONS
  227. S" kernel.4" INCLUDED
  228. \ PART 10: FINISHING AND SAVING THE TARGET IMAGE.
  229. \ Resolve the forward references created by the cross compiler.
  230. RESOLVE (DO)
  231. RESOLVE DOVAR
  232. RESOLVE (LOOP)
  233. RESOLVE (.")
  234. RESOLVE (ABORT")
  235. RESOLVE COLD
  236. RESOLVE WARM
  237. \ RESOLVE DIV-EX
  238. \ RESOLVE BREAK-EX
  239. \ RESOLVE TIMER-EX
  240. RESOLVE THROW
  241. RESOLVE (POSTPONE)
  242. \ Store appropriate values into some of the new Forth's variables.
  243. TLINK @ T' FORTH-WORDLIST >BODY-T !-T
  244. THERE T' DP >BODY-T !-T
  245. SAVE-IMAGE kernel.img \ Save the newly constructed Forth system to disk.
  246. BYE