blob: 5bb97cb60d7ecd11a62b942f3ce76e6fdcd0e168 [file] [log] [blame]
swissChilif7f1e2b2021-12-31 14:42:43 -08001;;; Dictionary manipulation & memory management words
2
3 ;; ( addr len -- entry? )
4 DEFWORD_RAW FIND, 'FIND'
5 POP CX ; String length
6 POP DI ; Start pointer
7 MOV BX, WORD [VAR_LATEST]
8
9.LOOP:
10 ;; BX and DI are clobbered
11 PUSH BX
12 PUSH DI
13 CALL WORD_MATCHES
14 POP DI
15 POP BX
16
17 TEST AX, AX
18 JNZ .MATCH
19
20 MOV BX, WORD [BX] ; Offset 0 = *LINK
21 TEST BX, BX
22 JNZ .LOOP ; If BX is 0 (end) fall through
23
24.MATCH:
25 PUSH BX ; BX holds dict entry
26 NEXT
27
28
29 ;; BX - Word
30 ;; CX - Length
31 ;; DI - Name
32 ;;
33 ;; All three parameter registers may be clobbered.
34 ;;
35 ;; Return: AX - 0 or 1
36WORD_MATCHES:
37 MOV AL, BYTE [BX + WORDSZ] ; Word length
38 AND AL, LENGTH_MASK | HIDDEN_BIT
39 CMP AL, CL
40
41 JE .EQUAL
42
43 XOR AX, AX
44 RET
45
46.EQUAL:
47 PUSH SI
48 LEA SI, [BX + 3] ; Point to the dict entry name
49
50.LOOP:
51 CMPSB
52 JNE .END
53 LOOP .LOOP
54
55 MOV AX, 1
56 POP SI
57 RET
58
59.END:
60 XOR AX, AX
61 POP SI
62 RET
63
64
65 ;; ( *addr -- value )
66 DEFWORD_RAW GET, '@'
67 POP BX
68 PUSH WORD [BX]
69 NEXT
70
71
72 ;; ( value *addr -- )
73 DEFWORD_RAW SET, '!'
74 POP BX
75 POP AX
76 MOV WORD [BX], AX
77 NEXT
78
79
80 DEFWORD_RAW GETCHAR, 'C@'
81 POP BX
82 XOR AX, AX
83 MOV AL, BYTE [BX]
84 PUSH AX
85 NEXT
86
87
88 ;; Code field address
89 DEFWORD_RAW CFA, '>CFA'
90 POP BX
91 ADD BX, 2
92
93 XOR CH, CH
94 MOV CL, BYTE [BX] ; String length
95 AND CL, LENGTH_MASK
96 ADD BX, CX ; Code field address
97 ADD BX, 2 ; 1 to round up, 1 to skip length
98 AND BX, (~1) ; Zero the last bit
99
100
101 PUSH BX
102 NEXT
103
104
105 DEFWORD_THREADED DFA, '>DFA'
106 DW CFA, ADD2, EXIT
107
108
swissChilif8849dc2021-12-31 23:15:57 -0800109 ;; ( *a *b num -- )
110 ;; Copy NUM bytes from A to B
111 DEFWORD_RAW CMOVE, 'CMOVE'
112 RSPUSH SI
113 POP CX
114 POP DI
115 POP SI
116 REP MOVSB
117 RSPOP SI
swissChilif7f1e2b2021-12-31 14:42:43 -0800118 NEXT
119
swissChilif7f1e2b2021-12-31 14:42:43 -0800120
swissChilif8849dc2021-12-31 23:15:57 -0800121 ;; ( a -- b )
122 ;; Round up to even number
123 DEFWORD_RAW ROUND_EVEN, 'ROUND-EVEN'
124 POP AX
125 INC AX
126 AND AX, (~1)
127 PUSH AX
128 NEXT
swissChilif7f1e2b2021-12-31 14:42:43 -0800129
swissChilif7f1e2b2021-12-31 14:42:43 -0800130
swissChilif8849dc2021-12-31 23:15:57 -0800131 DEFWORD_RAW CMOVE_HERE, 'CMOVE,'
132 POP CX
133 RSPUSH SI
swissChilif7f1e2b2021-12-31 14:42:43 -0800134 POP SI
swissChilif8849dc2021-12-31 23:15:57 -0800135 MOV DI, [VAR_HERE]
136 REP MOVSB
137 MOV [VAR_HERE], DI
138 RSPOP SI
139 NEXT
140
141
142 DEFWORD_THREADED CREATE, 'CREATE'
143 DW HERE, GET ; ( *here )
144 DW _WORD ; ( *here *string length )
145 DW _2DUP, TYPE, SPACE ; ( *here *string length )
146 DW LATEST, GET ; ( *here *string length link )
147 DW COMMA, DUP, CHAR_COMMA ; ( *here *string length )
148 DW CMOVE_HERE ; ( *here )
149 DW HERE, GET ; ( *here *here[new] )
150 DW ROUND_EVEN ; ( here[new,even] )
151 DW HERE, SET ; ( *here )
152 DW LATEST, SET ; ( )
153 DW EXIT
swissChilif7f1e2b2021-12-31 14:42:43 -0800154
155
156 DEFWORD_RAW COMMA, ','
157 POP AX
158 MOV DI, [VAR_HERE]
159 STOSW
160 MOV [VAR_HERE], DI
161 NEXT
162
163
swissChilif8849dc2021-12-31 23:15:57 -0800164 DEFWORD_RAW CHAR_COMMA, 'C,'
165 POP AX
166 MOV DI, [VAR_HERE]
167 STOSB
168 MOV [VAR_HERE], DI
169 NEXT
170
171
swissChilif7f1e2b2021-12-31 14:42:43 -0800172 ;; Switch to interpret mode
173 DEFWORD_RAW_IMMEDIATE LEFTBRACKET, '['
174 MOV WORD [VAR_STATE], 0
175 NEXT
176
177
swissChilif8849dc2021-12-31 23:15:57 -0800178 DEFWORD_RAW RIGHTBRACKET, ']'
swissChilif7f1e2b2021-12-31 14:42:43 -0800179 MOV WORD [VAR_STATE], 1
180 NEXT
181
182
swissChilif8849dc2021-12-31 23:15:57 -0800183 DEFWORD_RAW_IMMEDIATE IMMEDIATE, 'IMMEDIATE'
swissChilif7f1e2b2021-12-31 14:42:43 -0800184 MOV BX, [VAR_LATEST]
185 XOR BYTE [BX + 2], IMMEDIATE_BIT
186 NEXT
187
188
189 ;; LATEST HIDDEN
190 DEFWORD_RAW HIDDEN, 'HIDDEN'
191 POP BX
192 XOR BYTE [BX + 2], HIDDEN_BIT
193 NEXT
194
195
196 ;; HIDE DUP
197 DEFWORD_THREADED HIDE, 'HIDE'
198 DW _WORD, FIND, HIDDEN, EXIT
199
200
201 DEFWORD_THREADED_IMMED TICK, "'"
202 DW _WORD, FIND, CFA, EXIT
203
204
205 DEFWORD_RAW BRANCH, 'BRANCH'
206 LODSW
207 ADD SI, AX
208 NEXT
209
210
211 DEFWORD_RAW ZEROBRANCH, '0BRANCH'
212 POP DX
213 LODSW
214 TEST DX, DX
215 JNZ .NOTZERO
216 ADD SI, AX
217
218.NOTZERO:
219 NEXT
220
221
222 DEFWORD_RAW LITSTRING, 'LITSTRING'
223 LODSW ; Length
224 PUSH SI
225 ADD SI, AX
226 INC SI ; Round up
227 AND SI, (~1)
228 PUSH AX
229 NEXT
230
231
swissChilif8849dc2021-12-31 23:15:57 -0800232 ;; ( entry -- type )
233 ;; 0 = immediate; 1 = normal
234 DEFWORD_THREADED GET_WORD_TYPE, 'WORD-TYPE'
235 DW LITERAL, 2, PLUS ; ( entry+2 )
236 DW GETCHAR ; ( length/flags )
237 DW LITERAL, IMMEDIATE_BIT ; ( length/flags IMMEDIATE_BIT )
238 DW AND ; ( 1=immediate;0=normal )
239 DW LITERAL, IMMEDIATE_BIT
240 DW XOR ; Toggle the bit
241 DW EXIT
242
243
swissChilif7f1e2b2021-12-31 14:42:43 -0800244 DEFWORD_THREADED INTERPRET, 'INTERPRET'
245 DW _WORD ; ( addr len )
246 DW _2DUP, FIND ; ( addr len entry? )
247 DW DUP ; ( addr len entry? entry? )
swissChilif8849dc2021-12-31 23:15:57 -0800248 DW ZEROBRANCH ; ( addr len entry? )
249 RELATIVE_ADDRESS .NUM ; FIND returned 0
swissChilif7f1e2b2021-12-31 14:42:43 -0800250
swissChilif8849dc2021-12-31 23:15:57 -0800251 DW SWAP, DROP, SWAP, DROP ; ( entry )
252 DW DUP, CFA ; ( entry cfa )
swissChilif7f1e2b2021-12-31 14:42:43 -0800253
swissChilif8849dc2021-12-31 23:15:57 -0800254 DW SWAP ; ( cfa entry )
255 DW GET_WORD_TYPE ; ( cfa immediate? )
swissChilif7f1e2b2021-12-31 14:42:43 -0800256
swissChilif8849dc2021-12-31 23:15:57 -0800257 DW STATE, GET ; ( cfa immediate? interpreting? )
258 ;; In either case evaluate
259 DW ZEROBRANCH ; ( cfa immediate? )
260 RELATIVE_ADDRESS .WORD_IMMED
261 DW ZEROBRANCH ; ( cfa )
262 RELATIVE_ADDRESS .WORD_COMPILE_IMMED
263
264 ;; Compile the word
swissChilif7f1e2b2021-12-31 14:42:43 -0800265 DW COMMA ; Add to HERE
266 DW EXIT
267
swissChilif8849dc2021-12-31 23:15:57 -0800268.WORD_COMPILE_IMMED: ; ( cfa )
269 INCLUDE_STRING 'immediate bit set'
270 DW TYPE, CR
271 DW EXECUTE, EXIT
272
273.WORD_IMMED: ; ( cfa immediate? )
274 DW DROP ; ( cfa )
swissChilif7f1e2b2021-12-31 14:42:43 -0800275 DW EXECUTE ; ( )
276 DW EXIT
277
278.NUM: ; ( addr len 0 )
279 DW DROP ; ( addr len )
280 DW NUMBER ; ( number unparsed )
swissChilif8849dc2021-12-31 23:15:57 -0800281 DW ZEROBRANCH ; ( number )
282 RELATIVE_ADDRESS .NUMOK
swissChilif7f1e2b2021-12-31 14:42:43 -0800283
swissChilif8849dc2021-12-31 23:15:57 -0800284 INCLUDE_STRING 'Word is neither defined nor a number'
285 DW TYPE, CR ; ( number )
286 DW DROP, EXIT ; ( )
swissChilif7f1e2b2021-12-31 14:42:43 -0800287
288.NUMOK:
289 ;; ( number )
290 DW STATE, GET ; ( number STATE )
swissChilif8849dc2021-12-31 23:15:57 -0800291 DW ZEROBRANCH ; ( number )
292 RELATIVE_ADDRESS .NUM_IMMED
swissChilif7f1e2b2021-12-31 14:42:43 -0800293
294 DW LITERAL, LITERAL ; ( number LITERAL )
295 DW COMMA, COMMA ; ( )
296
swissChilif8849dc2021-12-31 23:15:57 -0800297.NUM_IMMED: ; ( number ) or ( )
swissChilif7f1e2b2021-12-31 14:42:43 -0800298 DW EXIT
299
swissChilif7f1e2b2021-12-31 14:42:43 -0800300
swissChilif8849dc2021-12-31 23:15:57 -0800301 ;; Jump to the word specified by the CFA on the stack
swissChilif7f1e2b2021-12-31 14:42:43 -0800302 DEFWORD_RAW EXECUTE, 'EXECUTE'
303 POP AX
304 MOV BX, AX
305 JMP [BX]
306
307
308 ;; TODO: await newline
309 DEFWORD_THREADED QUIT, 'QUIT'
swissChilif8849dc2021-12-31 23:15:57 -0800310.START:
swissChilif7f1e2b2021-12-31 14:42:43 -0800311 DW INTERPRET
swissChilif8849dc2021-12-31 23:15:57 -0800312 DW BRANCH
313 RELATIVE_ADDRESS .START
swissChilif7f1e2b2021-12-31 14:42:43 -0800314
315
316 DEFWORD_THREADED COLON, ':'
swissChilif8849dc2021-12-31 23:15:57 -0800317 DW CREATE
swissChilif7f1e2b2021-12-31 14:42:43 -0800318 DW LITERAL, DOCOL, COMMA
319 DW LATEST, GET, HIDDEN
320 DW RIGHTBRACKET
321 DW EXIT
322
323
324 DEFWORD_THREADED_IMMED SEMICOLON, ';'
325 DW LITERAL, EXIT, COMMA
326 DW LATEST, GET, HIDDEN
327 DW LEFTBRACKET
328 DW EXIT
329
330
331 ;; ( *entry -- len *string )
swissChilif8849dc2021-12-31 23:15:57 -0800332 DEFWORD_THREADED ENTRY_NAME, 'ENTRY->NAME'
swissChilif7f1e2b2021-12-31 14:42:43 -0800333 DW DUP ; ( *entry *entry )
swissChilif8849dc2021-12-31 23:15:57 -0800334 DW LITERAL, 2, PLUS ; ( *entry *len/flags )
335 DW GETCHAR ; ( *entry len/flags )
336 DW LITERAL, LENGTH_MASK, AND ; ( *entry len )
swissChilif7f1e2b2021-12-31 14:42:43 -0800337 DW SWAP ; ( len *entry )
338 DW LITERAL, 3, PLUS ; ( len *string )
339 DW SWAP
340 DW EXIT
341
342
swissChilif8849dc2021-12-31 23:15:57 -0800343 DEFWORD_THREADED SHOW_DICT, 'WORDS'
swissChilif7f1e2b2021-12-31 14:42:43 -0800344 DW LATEST, GET ; ( *entry )
swissChilif8849dc2021-12-31 23:15:57 -0800345.LOOP:
swissChilif7f1e2b2021-12-31 14:42:43 -0800346 DW DUP, ENTRY_NAME ; ( *entry len *string)
swissChilif8849dc2021-12-31 23:15:57 -0800347 DW TYPE, SPACE ; ( *entry )
swissChilif7f1e2b2021-12-31 14:42:43 -0800348 DW GET ; ( *prev-entry )
349 DW DUP ; ( *prev-entry *prev-entry )
swissChilif8849dc2021-12-31 23:15:57 -0800350 DW ZEROBRANCH
351 RELATIVE_ADDRESS .DONE
352
353 DW BRANCH ; Back to start!
354 RELATIVE_ADDRESS .LOOP
355.DONE:
356 DW CR, EXIT