1 \ simpleForth i386 backend
3 \ alter substitutes non-letter characters by upper case letters (to aid assemblers to deal with labels).
4 : replace ( c1 -- c2 c3 2 | c2 1 )
6 'A' 1 r> ''' case? ?exit >r 2drop
7 'B' 1 r> '\' case? ?exit >r 2drop
8 'C' 1 r> ':' case? ?exit >r 2drop
9 'D' 1 r> '.' case? ?exit >r 2drop
10 'E' 1 r> '=' case? ?exit >r 2drop
11 'F' 1 r> '[' case? ?exit >r 2drop
12 'G' 1 r> '>' case? ?exit >r 2drop
13 'H' 1 r> ']' case? ?exit >r 2drop
14 'I' 1 r> '1' case? ?exit >r 2drop
15 'J' 1 r> '2' case? ?exit >r 2drop
16 'K' 1 r> '/' case? ?exit >r 2drop
17 'L' 1 r> '<' case? ?exit >r 2drop
18 'M' 1 r> '-' case? ?exit >r 2drop
19 'N' 1 r> '#' case? ?exit >r 2drop
20 'O' 1 r> '0' case? ?exit >r 2drop
21 'P' 1 r> '+' case? ?exit >r 2drop
22 'Q' 1 r> '?' case? ?exit >r 2drop
23 'R' 1 r> '"' case? ?exit >r 2drop
24 'S' 1 r> '!' case? ?exit >r 2drop
25 'T' 1 r> '*' case? ?exit >r 2drop
26 'U' 1 r> '(' case? ?exit >r 2drop
27 'V' 1 r> '|' case? ?exit >r 2drop
28 'W' 1 r> ',' case? ?exit >r 2drop
29 \ also 'X' for machine code
30 'Y' 1 r> ')' case? ?exit >r 2drop
31 'Z' 1 r> ';' case? ?exit >r 2drop
32 'U' 'T' 2 r> '{' case? ?exit >r drop 2drop
33 'T' 'Y' 2 r> '}' case? ?exit >r drop 2drop
37 \ alter substitutes all non-letter characters by upper case letters.
39 '_' 1 rot ?dup 0= ?exit nip nip
41 swap >r 1- alter r> swap >r replace r> + ;
46 \ Output is done by emit.
47 \ We define convenience words of the form ."xxx" to output xxx and >"xxx" to output xxx on a new line indented by a tab.
50 'D' emit 'D' emit space ;
56 'D' emit 'B' emit space ;
62 'd' emit 'u' emit 'p' emit ;
65 'n' 'e' 's' 't' 4 alter show ;
68 'u' 'n' 'n' 'e' 's' 't' 6 alter show ;
71 'l' 'i' 't' 3 alter show ;
77 : escaped ( S1 -- S2 )
79 swap >r 1- escaped r> swap 1+ over '"' - ?exit '"' swap 1+ ;
81 \ ,string compiles the topmost string as a sequence of numeric DB values.
83 >"db" '"' emit escaped show '"' emit ;
85 \ dup roll >"db" u. \ 1st char
88 \ reproduce a verbatim line
92 \ compile a reference to an invoked word
96 \ compile a reference to an invoked word on a new line
100 \ compile reference to nest primitive
105 \ compile reference to unnest primitive
112 >"db" u. space ."dup" '(' emit '0' emit ')' emit ;
118 \ compile signed number
122 \ compile unsigned number
128 >"dd" ."lit" ,>word ;
134 \ output string as comment
136 cr tab ';' emit space show ;
139 cr show ':' emit tab ;
141 \ create a new symbolic label
145 \ body calculates the name of the body from a token
149 \ ,codefield compiles the code field of primitive
150 : ,codefield ( S -- )
151 body _dup ,word label ;
160 \ -----------------------------------
161 \ tail call optimization tail word ; -> [ ' word >body ] literal >r ;
166 \ ,tail compiles a tail call
171 \ Handle conditionals
173 \ initialize local labels
174 : (label ( S1 -- S1 S2 0 )
175 alter '_' swap 1+ '_' swap 1+ 0 ;
177 \ deinitialize local labels
181 : +label ( L1 i -- L1 L2 i+1 )
182 >r _dup nip r> dup >r '0' + swap r> 1+ ;
185 'b' 'r' 'a' 'n' 'c' 'h' 6 alter show ;
188 '?' 'b' 'r' 'a' 'n' 'c' 'h' 7 alter show ;
191 >"dd" ."branch" >"dd" show ;
194 >"dd" ."?branch" >"dd" show ;
199 'd' 'o' 'v' 'a' 'r' 5 alter show ;
202 'd' 'o' 'c' 'o' 'n' 's' 't' 7 alter show ;
211 \ prologue and epilogue
217 ';' emit space 'd' emit 'o' emit 'n' emit 'e' emit ;
220 ';' emit space 'l' emit 'a' emit 's' emit 't' emit ':' emit space ;
223 'l' 'a' 's' 't' 4 0 header cr tab _dup label ,dovar bodylabel _dup ."dd" alter show
225 'm' 'e' 'm' 't' 'o' 'p' 6 ,label 0 ,u
226 cr ."last:" alter show
232 \ preForth can optionally also create word headers with a very simple layout.
234 \ Word creation is split into parts
235 \ - header creates a dictionary header from a string on the stack.
236 \ - label creates the assembler label (with symbol substitution)
237 \ - body defined later by code (assembly code) or : (threaded code)
239 \ Headers are linked in a single linked list ending in 0.
240 \ The link-label name of the latest definition is always as a string on top of stack.
241 \ Creating a new header puts this in the link field of the new definition and
242 \ replaces the link-label with the current one.
245 \ link to previous header c. d is new header.
246 : ,link ( S1 S2 -- S3 S2 )
247 '_' swap 1+ _dup label \ d_:
251 \ create a new header with given name S2 and flags, S1 is the last link label
252 : header ( S1 S2 flags -- S3 S2 )