Commit | Line | Data |
---|---|---|
01e8850d | 1 | REM APPLY should really be in types.in.bas but it is here because it |
af621e3a JM |
2 | REM calls DO_TCO_FUNCTION so it will cause syntax errors for steps1-3 |
3 | REM if it is in types.in.bas because there are unresolved labels. | |
01e8850d JM |
4 | |
5 | REM APPLY(F, AR) -> R | |
6 | REM - restores E | |
7 | REM - call using GOTO and with return label/address on the stack | |
af621e3a | 8 | SUB APPLY |
01e8850d | 9 | REM if metadata, get the actual object |
4202ef7b JM |
10 | GOSUB TYPE_F |
11 | IF T=14 THEN F=Z%(F+1):GOSUB TYPE_F | |
01e8850d | 12 | |
4202ef7b | 13 | ON T-8 GOTO APPLY_FUNCTION,APPLY_MAL_FUNCTION,APPLY_MAL_FUNCTION |
01e8850d JM |
14 | |
15 | APPLY_FUNCTION: | |
16 | REM regular function | |
5bbc7a1f | 17 | IF Z%(F+1)<64 THEN GOSUB DO_FUNCTION:GOTO APPLY_DONE |
01e8850d | 18 | REM for recur functions (apply, map, swap!), use GOTO |
5bbc7a1f | 19 | IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION |
01e8850d JM |
20 | GOTO APPLY_DONE |
21 | ||
22 | APPLY_MAL_FUNCTION: | |
93593012 | 23 | Q=E:GOSUB PUSH_Q: REM save the current environment |
01e8850d JM |
24 | |
25 | REM create new environ using env and params stored in the | |
26 | REM function and bind the params to the apply arguments | |
d7a6c2d6 | 27 | C=Z%(F+3):A=Z%(F+2):B=AR:GOSUB ENV_NEW_BINDS |
01e8850d | 28 | |
d7a6c2d6 | 29 | A=Z%(F+1):E=R:CALL EVAL |
01e8850d JM |
30 | |
31 | AY=E:GOSUB RELEASE: REM release the new environment | |
32 | ||
93593012 | 33 | GOSUB POP_Q:E=Q: REM pop/restore the saved environment |
01e8850d JM |
34 | |
35 | APPLY_DONE: | |
af621e3a | 36 | END SUB |
01e8850d JM |
37 | |
38 | ||
39 | REM DO_TCO_FUNCTION(F, AR) | |
af621e3a | 40 | SUB DO_TCO_FUNCTION |
d7a6c2d6 | 41 | G=Z%(F+1) |
01e8850d JM |
42 | |
43 | REM Get argument values | |
d7a6c2d6 JM |
44 | A=Z%(AR+2) |
45 | B=Z%(Z%(AR+1)+2) | |
01e8850d | 46 | |
4202ef7b | 47 | REM PRINT "F:"+STR$(F)+", Z%(F):"+STR$(Z%(F))+", G:"+STR$(G) |
5bbc7a1f | 48 | ON G-64 GOTO DO_APPLY,DO_MAP,DO_SWAP_BANG |
01e8850d JM |
49 | |
50 | DO_APPLY: | |
037815e0 | 51 | F=A |
d7a6c2d6 | 52 | AR=Z%(AR+1) |
037815e0 | 53 | A=AR:GOSUB COUNT:C=R |
01e8850d | 54 | |
d7a6c2d6 | 55 | A=Z%(AR+2) |
01e8850d | 56 | REM no intermediate args, but not a list, so convert it first |
4202ef7b JM |
57 | GOSUB TYPE_A |
58 | IF C<=1 AND T<>6 THEN T=6:GOSUB FORCE_SEQ_TYPE:GOTO DO_APPLY_2 | |
01e8850d | 59 | REM no intermediate args, just call APPLY directly |
f9f1cec9 | 60 | IF C<=1 THEN GOTO DO_APPLY_1 |
01e8850d JM |
61 | |
62 | REM prepend intermediate args to final args element | |
f9f1cec9 | 63 | A=AR:B=0:C=C-1:GOSUB SLICE |
01e8850d | 64 | REM release the terminator of new list (we skip over it) |
9d59cdb3 JM |
65 | REM we already checked for an empty list above, so R6 is pointer |
66 | REM a real non-empty list | |
d7a6c2d6 | 67 | AY=Z%(R6+1):GOSUB RELEASE |
01e8850d | 68 | REM attach end of slice to final args element |
4202ef7b JM |
69 | A2=Z%(A+2) |
70 | Z%(R6+1)=A2 | |
71 | Z%(A2)=Z%(A2)+32 | |
01e8850d JM |
72 | |
73 | GOTO DO_APPLY_2 | |
74 | ||
75 | DO_APPLY_1: | |
af621e3a | 76 | AR=A:CALL APPLY |
01e8850d | 77 | |
af621e3a | 78 | GOTO DO_TCO_FUNCTION_DONE |
01e8850d JM |
79 | |
80 | DO_APPLY_2: | |
93593012 | 81 | GOSUB PUSH_R: REM push/save new args for release |
01e8850d | 82 | |
af621e3a | 83 | AR=R:CALL APPLY |
01e8850d | 84 | |
93593012 JM |
85 | REM pop/release new args |
86 | GOSUB POP_Q:AY=Q | |
87 | GOSUB RELEASE | |
af621e3a | 88 | GOTO DO_TCO_FUNCTION_DONE |
01e8850d JM |
89 | |
90 | DO_MAP: | |
037815e0 | 91 | F=A |
01e8850d | 92 | |
9d59cdb3 JM |
93 | REM setup the stack for the loop |
94 | T=6:GOSUB MAP_LOOP_START | |
01e8850d JM |
95 | |
96 | DO_MAP_LOOP: | |
d7a6c2d6 | 97 | IF Z%(B+1)=0 THEN GOTO DO_MAP_DONE |
01e8850d | 98 | |
9d59cdb3 | 99 | REM create argument list for apply |
d7a6c2d6 | 100 | T=6:L=6:M=Z%(B+2):GOSUB ALLOC |
01e8850d | 101 | |
9d59cdb3 JM |
102 | GOSUB PUSH_R: REM push argument list |
103 | Q=F:GOSUB PUSH_Q: REM push F | |
104 | Q=B:GOSUB PUSH_Q: REM push B | |
01e8850d | 105 | |
af621e3a | 106 | AR=R:CALL APPLY |
01e8850d | 107 | |
9d59cdb3 JM |
108 | GOSUB POP_Q:B=Q: REM pop B |
109 | GOSUB POP_Q:F=Q: REM pop F | |
110 | GOSUB POP_Q: REM pop apply args and release them | |
111 | AY=Q:GOSUB RELEASE | |
01e8850d | 112 | |
d7a6c2d6 JM |
113 | REM main value is result of apply |
114 | M=R | |
115 | ||
116 | B=Z%(B+1): REM go to the next element | |
c7330b3d | 117 | |
9d59cdb3 JM |
118 | REM if error, release the unattached element |
119 | IF ER<>-2 THEN AY=R:GOSUB RELEASE:GOTO DO_MAP_DONE | |
01e8850d | 120 | |
9d59cdb3 JM |
121 | REM update the return sequence structure |
122 | REM release N since list takes full ownership | |
123 | C=1:T=6:GOSUB MAP_LOOP_UPDATE | |
01e8850d JM |
124 | |
125 | GOTO DO_MAP_LOOP | |
126 | ||
127 | DO_MAP_DONE: | |
9d59cdb3 JM |
128 | REM cleanup stack and get return value |
129 | GOSUB MAP_LOOP_DONE | |
af621e3a | 130 | GOTO DO_TCO_FUNCTION_DONE |
01e8850d | 131 | |
01e8850d | 132 | DO_SWAP_BANG: |
037815e0 | 133 | F=B |
01e8850d JM |
134 | |
135 | REM add atom to front of the args list | |
d7a6c2d6 | 136 | T=6:L=Z%(Z%(AR+1)+1):M=Z%(A+1):GOSUB ALLOC: REM cons |
01e8850d JM |
137 | AR=R |
138 | ||
139 | REM push args for release after | |
93593012 | 140 | Q=AR:GOSUB PUSH_Q |
01e8850d JM |
141 | |
142 | REM push atom | |
4202ef7b | 143 | GOSUB PUSH_A |
01e8850d | 144 | |
af621e3a | 145 | CALL APPLY |
01e8850d JM |
146 | |
147 | REM pop atom | |
4202ef7b | 148 | GOSUB POP_A |
01e8850d JM |
149 | |
150 | REM pop and release args | |
93593012 JM |
151 | GOSUB POP_Q:AY=Q |
152 | GOSUB RELEASE | |
01e8850d JM |
153 | |
154 | REM use reset to update the value | |
037815e0 | 155 | B=R:GOSUB DO_RESET_BANG |
01e8850d JM |
156 | |
157 | REM but decrease ref cnt of return by 1 (not sure why) | |
158 | AY=R:GOSUB RELEASE | |
159 | ||
af621e3a | 160 | GOTO DO_TCO_FUNCTION_DONE |
01e8850d | 161 | |
af621e3a JM |
162 | DO_TCO_FUNCTION_DONE: |
163 | END SUB | |
01e8850d | 164 | |
cc9dbd92 | 165 | REM DO_FUNCTION(F, AR) |
241d5d57 JM |
166 | DO_FUNCTION: |
167 | REM Get the function number | |
d7a6c2d6 | 168 | G=Z%(F+1) |
241d5d57 JM |
169 | |
170 | REM Get argument values | |
4202ef7b JM |
171 | A=Z%(AR+2):A1=Z%(A+1) |
172 | B=Z%(Z%(AR+1)+2):B1=Z%(B+1) | |
241d5d57 JM |
173 | |
174 | REM Switch on the function number | |
7895453b JM |
175 | REM MEMORY DEBUGGING: |
176 | REM IF G>59 THEN ER=-1:E$="unknown function"+STR$(G):RETURN | |
5bbc7a1f | 177 | ON INT(G/10)+1 GOTO DO_1_9,DO_10_19,DO_20_29,DO_30_39,DO_40_49,DO_50_59,DO_60_69 |
a742287e JM |
178 | |
179 | DO_1_9: | |
c756af81 | 180 | ON G GOTO DO_EQUAL_Q,DO_THROW,DO_NIL_Q,DO_TRUE_Q,DO_FALSE_Q,DO_STRING_Q,DO_SYMBOL,DO_SYMBOL_Q,DO_KEYWORD |
a742287e | 181 | DO_10_19: |
5bbc7a1f | 182 | ON G-9 GOTO DO_KEYWORD_Q,DO_NUMBER_Q,DO_FN_Q,DO_MACRO_Q,DO_PR_STR,DO_STR,DO_PRN,DO_PRINTLN,DO_READ_STRING,DO_READLINE |
a742287e | 183 | DO_20_29: |
5bbc7a1f | 184 | ON G-19 GOTO DO_SLURP,DO_LT,DO_LTE,DO_GT,DO_GTE,DO_ADD,DO_SUB,DO_MULT,DO_DIV,DO_TIME_MS |
a742287e | 185 | DO_30_39: |
5bbc7a1f | 186 | ON G-29 GOTO DO_LIST,DO_LIST_Q,DO_VECTOR,DO_VECTOR_Q,DO_HASH_MAP,DO_MAP_Q,DO_ASSOC,DO_THROW,DO_GET,DO_CONTAINS |
a742287e | 187 | DO_40_49: |
5bbc7a1f | 188 | ON G-39 GOTO DO_KEYS,DO_VALS,DO_SEQUENTIAL_Q,DO_CONS,DO_CONCAT,DO_NTH,DO_FIRST,DO_REST,DO_EMPTY_Q,DO_COUNT |
c7330b3d | 189 | DO_50_59: |
5bbc7a1f JM |
190 | ON G-49 GOTO DO_CONJ,DO_SEQ,DO_WITH_META,DO_META,DO_ATOM,DO_ATOM_Q,DO_DEREF,DO_RESET_BANG,DO_EVAL,DO_READ_FILE |
191 | DO_60_69: | |
192 | ON G-59 GOTO DO_PR_MEMORY_SUMMARY | |
241d5d57 JM |
193 | |
194 | DO_EQUAL_Q: | |
037815e0 | 195 | GOSUB EQUAL_Q |
9d59cdb3 | 196 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 197 | DO_THROW: |
037815e0 | 198 | ER=A |
d7a6c2d6 | 199 | Z%(ER)=Z%(ER)+32 |
9d59cdb3 | 200 | R=-1 |
5e5ca0d4 JM |
201 | RETURN |
202 | DO_NIL_Q: | |
9d59cdb3 JM |
203 | R=A=0 |
204 | GOTO RETURN_TRUE_FALSE | |
5e5ca0d4 | 205 | DO_TRUE_Q: |
d7a6c2d6 | 206 | R=A=4 |
9d59cdb3 | 207 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 208 | DO_FALSE_Q: |
d7a6c2d6 | 209 | R=A=2 |
9d59cdb3 | 210 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 211 | DO_STRING_Q: |
9d59cdb3 | 212 | R=0 |
4202ef7b JM |
213 | GOSUB TYPE_A |
214 | IF T<>4 THEN GOTO RETURN_TRUE_FALSE | |
215 | IF MID$(S$(A1),1,1)=CHR$(127) THEN GOTO RETURN_TRUE_FALSE | |
cc9dbd92 | 216 | R=1 |
9d59cdb3 | 217 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 218 | DO_SYMBOL: |
4202ef7b | 219 | B$=S$(A1) |
6420f327 | 220 | T=5:GOSUB STRING |
5e5ca0d4 JM |
221 | RETURN |
222 | DO_SYMBOL_Q: | |
4202ef7b JM |
223 | GOSUB TYPE_A |
224 | R=T=5 | |
9d59cdb3 | 225 | GOTO RETURN_TRUE_FALSE |
a742287e | 226 | DO_KEYWORD: |
4202ef7b | 227 | B$=S$(A1) |
c756af81 | 228 | IF MID$(B$,1,1)<>CHR$(127) THEN B$=CHR$(127)+B$ |
6420f327 | 229 | T=4:GOSUB STRING |
a742287e JM |
230 | RETURN |
231 | DO_KEYWORD_Q: | |
9d59cdb3 | 232 | R=0 |
4202ef7b JM |
233 | GOSUB TYPE_A |
234 | IF T<>4 THEN GOTO RETURN_TRUE_FALSE | |
235 | IF MID$(S$(A1),1,1)<>CHR$(127) THEN GOTO RETURN_TRUE_FALSE | |
a742287e | 236 | R=1 |
9d59cdb3 | 237 | GOTO RETURN_TRUE_FALSE |
5bbc7a1f JM |
238 | DO_NUMBER_Q: |
239 | GOSUB TYPE_A | |
240 | R=T=2 | |
241 | GOTO RETURN_TRUE_FALSE | |
242 | DO_FN_Q: | |
243 | GOSUB TYPE_A | |
244 | R=T=9 OR T=10 | |
245 | GOTO RETURN_TRUE_FALSE | |
246 | DO_MACRO_Q: | |
247 | GOSUB TYPE_A | |
248 | R=T=11 | |
249 | GOTO RETURN_TRUE_FALSE | |
241d5d57 JM |
250 | |
251 | DO_PR_STR: | |
f9f1cec9 | 252 | AZ=AR:B=1:B$=" ":GOSUB PR_STR_SEQ |
c756af81 | 253 | B$=R$:T=4:GOSUB STRING |
241d5d57 JM |
254 | RETURN |
255 | DO_STR: | |
f9f1cec9 | 256 | AZ=AR:B=0:B$="":GOSUB PR_STR_SEQ |
c756af81 | 257 | B$=R$:T=4:GOSUB STRING |
241d5d57 JM |
258 | RETURN |
259 | DO_PRN: | |
f9f1cec9 | 260 | AZ=AR:B=1:B$=" ":GOSUB PR_STR_SEQ |
241d5d57 | 261 | PRINT R$ |
cc9dbd92 | 262 | R=0 |
4202ef7b | 263 | GOTO INC_REF_R |
241d5d57 | 264 | DO_PRINTLN: |
f9f1cec9 | 265 | AZ=AR:B=0:B$=" ":GOSUB PR_STR_SEQ |
241d5d57 | 266 | PRINT R$ |
cc9dbd92 | 267 | R=0 |
4202ef7b | 268 | GOTO INC_REF_R |
85d70fb7 | 269 | DO_READ_STRING: |
4202ef7b | 270 | A$=S$(A1) |
85d70fb7 JM |
271 | GOSUB READ_STR |
272 | RETURN | |
30a3d828 | 273 | DO_READLINE: |
4202ef7b | 274 | A$=S$(A1):GOSUB READLINE |
e0bcd3fb | 275 | IF EZ>0 THEN EZ=0:R=0:GOTO INC_REF_R |
c756af81 | 276 | B$=R$:T=4:GOSUB STRING |
30a3d828 | 277 | RETURN |
85d70fb7 JM |
278 | DO_SLURP: |
279 | R$="" | |
e0bcd3fb JM |
280 | EZ=0 |
281 | #cbm OPEN 2,8,0,S$(A1) | |
4202ef7b | 282 | #qbasic A$=S$(A1) |
c756af81 | 283 | #qbasic IF NOT _FILEEXISTS(A$) THEN ER=-1:E$="File not found":RETURN |
e0bcd3fb | 284 | #qbasic OPEN A$ FOR INPUT AS #2 |
85d70fb7 | 285 | DO_SLURP_LOOP: |
e0bcd3fb JM |
286 | C$="" |
287 | RJ=1:GOSUB READ_FILE_CHAR | |
115e430d JM |
288 | #cbm IF ASC(C$)=10 THEN R$=R$+CHR$(13) |
289 | #qbasic IF ASC(C$)=10 THEN R$=R$+CHR$(10) | |
e0bcd3fb JM |
290 | IF (ASC(C$)<>10) AND (C$<>"") THEN R$=R$+C$ |
291 | IF EZ>0 THEN GOTO DO_SLURP_DONE | |
85d70fb7 JM |
292 | GOTO DO_SLURP_LOOP |
293 | DO_SLURP_DONE: | |
e0bcd3fb JM |
294 | CLOSE 2 |
295 | IF ER>-2 THEN RETURN | |
c756af81 | 296 | B$=R$:T=4:GOSUB STRING |
85d70fb7 | 297 | RETURN |
241d5d57 JM |
298 | |
299 | DO_LT: | |
4202ef7b | 300 | R=A1<B1 |
9d59cdb3 | 301 | GOTO RETURN_TRUE_FALSE |
241d5d57 | 302 | DO_LTE: |
4202ef7b | 303 | R=A1<=B1 |
9d59cdb3 | 304 | GOTO RETURN_TRUE_FALSE |
241d5d57 | 305 | DO_GT: |
4202ef7b | 306 | R=A1>B1 |
9d59cdb3 | 307 | GOTO RETURN_TRUE_FALSE |
241d5d57 | 308 | DO_GTE: |
4202ef7b | 309 | R=A1>=B1 |
9d59cdb3 | 310 | GOTO RETURN_TRUE_FALSE |
241d5d57 JM |
311 | |
312 | DO_ADD: | |
4202ef7b | 313 | T=2:L=A1+B1:GOSUB ALLOC |
241d5d57 JM |
314 | RETURN |
315 | DO_SUB: | |
4202ef7b | 316 | T=2:L=A1-B1:GOSUB ALLOC |
241d5d57 JM |
317 | RETURN |
318 | DO_MULT: | |
4202ef7b | 319 | T=2:L=A1*B1:GOSUB ALLOC |
241d5d57 JM |
320 | RETURN |
321 | DO_DIV: | |
4202ef7b | 322 | T=2:L=A1/B1:GOSUB ALLOC |
241d5d57 | 323 | RETURN |
60ef223c | 324 | DO_TIME_MS: |
47bcc4c0 JM |
325 | #cbm T=2:L=INT((TI-BT)*16.667):GOSUB ALLOC |
326 | #qbasic T=2:L=INT((TIMER(0.001)-BT#)*1000):GOSUB ALLOC | |
60ef223c | 327 | RETURN |
241d5d57 JM |
328 | |
329 | DO_LIST: | |
cc9dbd92 | 330 | R=AR |
4202ef7b | 331 | GOTO INC_REF_R |
241d5d57 | 332 | DO_LIST_Q: |
037815e0 | 333 | GOSUB LIST_Q |
9d59cdb3 | 334 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 335 | DO_VECTOR: |
a742287e | 336 | A=AR:T=7:GOSUB FORCE_SEQ_TYPE |
5e5ca0d4 JM |
337 | RETURN |
338 | DO_VECTOR_Q: | |
4202ef7b JM |
339 | GOSUB TYPE_A |
340 | R=T=7 | |
9d59cdb3 | 341 | GOTO RETURN_TRUE_FALSE |
5e5ca0d4 | 342 | DO_HASH_MAP: |
9d59cdb3 JM |
343 | REM setup the stack for the loop |
344 | T=8:GOSUB MAP_LOOP_START | |
345 | ||
346 | A=AR | |
347 | DO_HASH_MAP_LOOP: | |
d7a6c2d6 | 348 | IF Z%(A+1)=0 THEN GOTO DO_HASH_MAP_LOOP_DONE |
9d59cdb3 | 349 | |
d7a6c2d6 JM |
350 | M=Z%(A+2) |
351 | N=Z%(Z%(A+1)+2) | |
9d59cdb3 | 352 | |
d7a6c2d6 | 353 | A=Z%(Z%(A+1)+1): REM skip two |
9d59cdb3 JM |
354 | |
355 | REM update the return sequence structure | |
356 | REM do not release M and N since we are pulling them from the | |
357 | REM arguments (and not creating them here) | |
358 | C=0:GOSUB MAP_LOOP_UPDATE | |
359 | ||
360 | GOTO DO_HASH_MAP_LOOP | |
361 | ||
362 | DO_HASH_MAP_LOOP_DONE: | |
363 | REM cleanup stack and get return value | |
364 | GOSUB MAP_LOOP_DONE | |
365 | RETURN | |
366 | ||
5e5ca0d4 | 367 | DO_MAP_Q: |
4202ef7b JM |
368 | GOSUB TYPE_A |
369 | R=T=8 | |
9d59cdb3 | 370 | GOTO RETURN_TRUE_FALSE |
bbab5c5d | 371 | DO_ASSOC: |
037815e0 | 372 | H=A |
d7a6c2d6 | 373 | AR=Z%(AR+1) |
bbab5c5d | 374 | DO_ASSOC_LOOP: |
d7a6c2d6 JM |
375 | K=Z%(AR+2) |
376 | C=Z%(Z%(AR+1)+2) | |
377 | Z%(H)=Z%(H)+32 | |
bbab5c5d | 378 | GOSUB ASSOC1:H=R |
d7a6c2d6 JM |
379 | AR=Z%(Z%(AR+1)+1) |
380 | IF AR=0 OR Z%(AR+1)=0 THEN RETURN | |
bbab5c5d JM |
381 | GOTO DO_ASSOC_LOOP |
382 | DO_GET: | |
4202ef7b | 383 | IF A=0 THEN R=0:GOTO INC_REF_R |
037815e0 | 384 | H=A:K=B:GOSUB HASHMAP_GET |
4202ef7b | 385 | GOTO INC_REF_R |
bbab5c5d | 386 | DO_CONTAINS: |
037815e0 | 387 | H=A:K=B:GOSUB HASHMAP_CONTAINS |
9d59cdb3 | 388 | GOTO RETURN_TRUE_FALSE |
bbab5c5d | 389 | DO_KEYS: |
9d59cdb3 | 390 | T1=0 |
bbab5c5d JM |
391 | GOTO DO_KEYS_VALS |
392 | DO_VALS: | |
9d59cdb3 | 393 | T1=1 |
bbab5c5d | 394 | DO_KEYS_VALS: |
9d59cdb3 JM |
395 | REM setup the stack for the loop |
396 | T=6:GOSUB MAP_LOOP_START | |
bbab5c5d JM |
397 | |
398 | DO_KEYS_VALS_LOOP: | |
d7a6c2d6 | 399 | IF Z%(A+1)=0 THEN GOTO DO_KEYS_VALS_LOOP_DONE |
bbab5c5d | 400 | |
d7a6c2d6 JM |
401 | IF T1=0 THEN M=Z%(A+2) |
402 | IF T1=1 THEN M=Z%(A+3) | |
bbab5c5d | 403 | |
d7a6c2d6 | 404 | A=Z%(A+1): REM next element |
bbab5c5d | 405 | |
9d59cdb3 JM |
406 | REM update the return sequence structure |
407 | REM do not release N since we are pulling it from the | |
408 | REM hash-map (and not creating them here) | |
409 | C=0:GOSUB MAP_LOOP_UPDATE | |
bbab5c5d JM |
410 | |
411 | GOTO DO_KEYS_VALS_LOOP | |
241d5d57 | 412 | |
9d59cdb3 JM |
413 | DO_KEYS_VALS_LOOP_DONE: |
414 | REM cleanup stack and get return value | |
415 | GOSUB MAP_LOOP_DONE | |
416 | RETURN | |
417 | ||
5e5ca0d4 | 418 | DO_SEQUENTIAL_Q: |
4202ef7b JM |
419 | GOSUB TYPE_A |
420 | R=T=6 OR T=7 | |
9d59cdb3 | 421 | GOTO RETURN_TRUE_FALSE |
85d70fb7 | 422 | DO_CONS: |
d7a6c2d6 | 423 | T=6:L=B:M=A:GOSUB ALLOC |
85d70fb7 | 424 | RETURN |
9e8f5211 | 425 | DO_CONCAT: |
7895453b JM |
426 | REM always a list |
427 | R=6:GOSUB INC_REF_R | |
428 | GOSUB PUSH_R: REM current value | |
429 | GOSUB PUSH_R: REM return value | |
9e8f5211 | 430 | |
7895453b JM |
431 | DO_CONCAT_LOOP: |
432 | IF AR<16 THEN GOTO DO_CONCAT_DONE: REM no more elements | |
433 | ||
434 | REM slice/copy current element to a list | |
435 | A=Z%(AR+2) | |
436 | IF A<16 THEN GOTO DO_CONCAT_LOOP_NEXT: REM skip empty elements | |
437 | B=0:C=-1:GOSUB SLICE | |
9e8f5211 | 438 | |
7895453b JM |
439 | GOSUB PEEK_Q: REM return value |
440 | REM if this is the first element, set return element | |
441 | IF Q=6 THEN Q=R:GOSUB PUT_Q:GOTO DO_CONCAT_LOOP_AGAIN | |
442 | REM otherwise Q<>6, so attach current to sliced | |
443 | GOSUB PEEK_Q_1 | |
444 | Z%(Q+1)=R | |
445 | ||
446 | DO_CONCAT_LOOP_AGAIN: | |
447 | REM update current to end of sliced list | |
448 | Q=R6:GOSUB PUT_Q_1 | |
449 | REM dec empty since no longer part of slice | |
450 | AY=6:GOSUB RELEASE | |
451 | DO_CONCAT_LOOP_NEXT: | |
452 | REM next list element | |
d7a6c2d6 | 453 | AR=Z%(AR+1) |
7895453b JM |
454 | GOTO DO_CONCAT_LOOP |
455 | ||
456 | DO_CONCAT_DONE: | |
457 | GOSUB POP_R: REM pop return value | |
458 | GOSUB POP_Q: REM pop current | |
459 | RETURN | |
9e8f5211 | 460 | |
60ef223c | 461 | DO_NTH: |
4202ef7b | 462 | B=B1 |
037815e0 | 463 | GOSUB COUNT |
9d59cdb3 | 464 | IF R<=B THEN R=-1:ER=-1:E$="nth: index out of range":RETURN |
70f29a2b | 465 | DO_NTH_LOOP: |
cc9dbd92 JM |
466 | IF B=0 THEN GOTO DO_NTH_DONE |
467 | B=B-1 | |
d7a6c2d6 | 468 | A=Z%(A+1) |
70f29a2b JM |
469 | GOTO DO_NTH_LOOP |
470 | DO_NTH_DONE: | |
d7a6c2d6 | 471 | R=Z%(A+2) |
4202ef7b | 472 | GOTO INC_REF_R |
85d70fb7 | 473 | DO_FIRST: |
9d59cdb3 | 474 | R=0 |
4202ef7b JM |
475 | IF A=0 THEN GOTO INC_REF_R |
476 | IF A1<>0 THEN R=Z%(A+2) | |
477 | GOTO INC_REF_R | |
85d70fb7 | 478 | DO_REST: |
4202ef7b JM |
479 | IF A=0 THEN R=6:GOTO INC_REF_R |
480 | IF A1<>0 THEN A=A1: REM get the next sequence element | |
a742287e | 481 | T=6:GOSUB FORCE_SEQ_TYPE |
85d70fb7 | 482 | RETURN |
241d5d57 | 483 | DO_EMPTY_Q: |
4202ef7b | 484 | R=A1=0 |
9d59cdb3 | 485 | GOTO RETURN_TRUE_FALSE |
241d5d57 | 486 | DO_COUNT: |
037815e0 | 487 | GOSUB COUNT |
a742287e | 488 | T=2:L=R:GOSUB ALLOC |
241d5d57 | 489 | RETURN |
4e7d8a1b JM |
490 | DO_CONJ: |
491 | R=0 | |
4202ef7b | 492 | GOTO INC_REF_R |
4e7d8a1b JM |
493 | DO_SEQ: |
494 | R=0 | |
4202ef7b | 495 | GOTO INC_REF_R |
241d5d57 | 496 | |
bbab5c5d | 497 | DO_WITH_META: |
4202ef7b | 498 | GOSUB TYPE_A |
bbab5c5d | 499 | REM remove existing metadata first |
4202ef7b | 500 | IF T=14 THEN A=A1:GOTO DO_WITH_META |
d7a6c2d6 | 501 | T=14:L=A:M=B:GOSUB ALLOC |
bbab5c5d JM |
502 | RETURN |
503 | DO_META: | |
9d59cdb3 | 504 | R=0 |
4202ef7b JM |
505 | GOSUB TYPE_A |
506 | IF T=14 THEN R=Z%(A+2) | |
507 | GOTO INC_REF_R | |
85d70fb7 | 508 | DO_ATOM: |
037815e0 | 509 | T=12:L=A:GOSUB ALLOC |
85d70fb7 JM |
510 | RETURN |
511 | DO_ATOM_Q: | |
4202ef7b JM |
512 | GOSUB TYPE_A |
513 | R=T=12 | |
9d59cdb3 | 514 | GOTO RETURN_TRUE_FALSE |
85d70fb7 | 515 | DO_DEREF: |
4202ef7b JM |
516 | R=A1 |
517 | GOTO INC_REF_R | |
85d70fb7 | 518 | DO_RESET_BANG: |
037815e0 | 519 | R=B |
85d70fb7 | 520 | REM release current value |
4202ef7b | 521 | REM can't use A1 here because DO_RESET_BANG is called from swap! |
d7a6c2d6 | 522 | AY=Z%(A+1):GOSUB RELEASE |
85d70fb7 | 523 | REM inc ref by 2 for atom ownership and since we are returning it |
d7a6c2d6 | 524 | Z%(R)=Z%(R)+64 |
85d70fb7 | 525 | REM update value |
d7a6c2d6 | 526 | Z%(A+1)=R |
85d70fb7 | 527 | RETURN |
85d70fb7 | 528 | |
85d70fb7 | 529 | DO_EVAL: |
93593012 | 530 | Q=E:GOSUB PUSH_Q: REM push/save environment |
037815e0 | 531 | E=D:CALL EVAL |
93593012 | 532 | GOSUB POP_Q:E=Q |
85d70fb7 JM |
533 | RETURN |
534 | ||
0e508fa5 | 535 | DO_READ_FILE: |
4202ef7b | 536 | A$=S$(A1) |
0e508fa5 JM |
537 | GOSUB READ_FILE |
538 | RETURN | |
539 | ||
5bbc7a1f JM |
540 | REM DO_PR_MEMORY: |
541 | REM P1=ZT:P2=-1:GOSUB PR_MEMORY | |
542 | REM RETURN | |
543 | DO_PR_MEMORY_SUMMARY: | |
544 | REM GOSUB PR_MEMORY_SUMMARY | |
545 | GOSUB PR_MEMORY_SUMMARY_SMALL | |
546 | R=0 | |
547 | GOTO INC_REF_R | |
548 | RETURN | |
549 | ||
241d5d57 | 550 | INIT_CORE_SET_FUNCTION: |
4202ef7b | 551 | T=9:L=A:GOSUB ALLOC: REM native function |
c756af81 | 552 | C=R:GOSUB ENV_SET_S |
f9f1cec9 | 553 | A=A+1 |
241d5d57 JM |
554 | RETURN |
555 | ||
cc9dbd92 | 556 | REM INIT_CORE_NS(E) |
241d5d57 JM |
557 | INIT_CORE_NS: |
558 | REM create the environment mapping | |
559 | REM must match DO_FUNCTION mappings | |
560 | ||
f9f1cec9 | 561 | A=1 |
037815e0 JM |
562 | B$="=":GOSUB INIT_CORE_SET_FUNCTION: REM A=1 |
563 | B$="throw":GOSUB INIT_CORE_SET_FUNCTION: REM A=2 | |
564 | B$="nil?":GOSUB INIT_CORE_SET_FUNCTION: REM A=3 | |
565 | B$="true?":GOSUB INIT_CORE_SET_FUNCTION: REM A=4 | |
566 | B$="false?":GOSUB INIT_CORE_SET_FUNCTION: REM A=5 | |
567 | B$="string?":GOSUB INIT_CORE_SET_FUNCTION: REM A=6 | |
568 | B$="symbol":GOSUB INIT_CORE_SET_FUNCTION: REM A=7 | |
569 | B$="symbol?":GOSUB INIT_CORE_SET_FUNCTION: REM A=8 | |
570 | B$="keyword":GOSUB INIT_CORE_SET_FUNCTION: REM A=9 | |
571 | B$="keyword?":GOSUB INIT_CORE_SET_FUNCTION: REM A=10 | |
5bbc7a1f JM |
572 | B$="number?":GOSUB INIT_CORE_SET_FUNCTION: REM A=11 |
573 | B$="fn?":GOSUB INIT_CORE_SET_FUNCTION: REM A=12 | |
574 | B$="macro?":GOSUB INIT_CORE_SET_FUNCTION: REM A=13 | |
575 | ||
576 | B$="pr-str":GOSUB INIT_CORE_SET_FUNCTION: REM A=14 | |
577 | B$="str":GOSUB INIT_CORE_SET_FUNCTION: REM A=15 | |
578 | B$="prn":GOSUB INIT_CORE_SET_FUNCTION: REM A=16 | |
579 | B$="println":GOSUB INIT_CORE_SET_FUNCTION: REM A=17 | |
580 | B$="read-string":GOSUB INIT_CORE_SET_FUNCTION: REM A=18 | |
581 | B$="readline":GOSUB INIT_CORE_SET_FUNCTION: REM A=19 | |
582 | B$="slurp":GOSUB INIT_CORE_SET_FUNCTION: REM A=20 | |
583 | ||
584 | B$="<":GOSUB INIT_CORE_SET_FUNCTION: REM A=21 | |
585 | B$="<=":GOSUB INIT_CORE_SET_FUNCTION: REM A=22 | |
586 | B$=">":GOSUB INIT_CORE_SET_FUNCTION: REM A=23 | |
587 | B$=">=":GOSUB INIT_CORE_SET_FUNCTION: REM A=24 | |
588 | B$="+":GOSUB INIT_CORE_SET_FUNCTION: REM A=25 | |
589 | B$="-":GOSUB INIT_CORE_SET_FUNCTION: REM A=26 | |
590 | B$="*":GOSUB INIT_CORE_SET_FUNCTION: REM A=27 | |
591 | B$="/":GOSUB INIT_CORE_SET_FUNCTION: REM A=28 | |
592 | B$="time-ms":GOSUB INIT_CORE_SET_FUNCTION: REM A=29 | |
593 | ||
594 | B$="list":GOSUB INIT_CORE_SET_FUNCTION: REM A=30 | |
595 | B$="list?":GOSUB INIT_CORE_SET_FUNCTION: REM A=31 | |
596 | B$="vector":GOSUB INIT_CORE_SET_FUNCTION: REM A=32 | |
597 | B$="vector?":GOSUB INIT_CORE_SET_FUNCTION: REM A=33 | |
598 | B$="hash-map":GOSUB INIT_CORE_SET_FUNCTION: REM A=34 | |
599 | B$="map?":GOSUB INIT_CORE_SET_FUNCTION: REM A=35 | |
600 | B$="assoc":GOSUB INIT_CORE_SET_FUNCTION: REM A=36 | |
601 | B$="dissoc":GOSUB INIT_CORE_SET_FUNCTION: REM A=37 | |
602 | B$="get":GOSUB INIT_CORE_SET_FUNCTION: REM A=38 | |
603 | B$="contains?":GOSUB INIT_CORE_SET_FUNCTION: REM A=39 | |
604 | B$="keys":GOSUB INIT_CORE_SET_FUNCTION: REM A=40 | |
605 | B$="vals":GOSUB INIT_CORE_SET_FUNCTION: REM A=41 | |
606 | ||
607 | B$="sequential?":GOSUB INIT_CORE_SET_FUNCTION: REM A=42 | |
608 | B$="cons":GOSUB INIT_CORE_SET_FUNCTION: REM A=43 | |
609 | B$="concat":GOSUB INIT_CORE_SET_FUNCTION: REM A=44 | |
610 | B$="nth":GOSUB INIT_CORE_SET_FUNCTION: REM A=45 | |
611 | B$="first":GOSUB INIT_CORE_SET_FUNCTION: REM A=46 | |
612 | B$="rest":GOSUB INIT_CORE_SET_FUNCTION: REM A=47 | |
613 | B$="empty?":GOSUB INIT_CORE_SET_FUNCTION: REM A=48 | |
614 | B$="count":GOSUB INIT_CORE_SET_FUNCTION: REM A=49 | |
615 | ||
616 | B$="conj":GOSUB INIT_CORE_SET_FUNCTION: REM A=50 | |
617 | B$="seq":GOSUB INIT_CORE_SET_FUNCTION: REM A=51 | |
618 | ||
619 | B$="with-meta":GOSUB INIT_CORE_SET_FUNCTION: REM A=52 | |
620 | B$="meta":GOSUB INIT_CORE_SET_FUNCTION: REM A=53 | |
621 | B$="atom":GOSUB INIT_CORE_SET_FUNCTION: REM A=54 | |
622 | B$="atom?":GOSUB INIT_CORE_SET_FUNCTION: REM A=55 | |
623 | B$="deref":GOSUB INIT_CORE_SET_FUNCTION: REM A=56 | |
624 | B$="reset!":GOSUB INIT_CORE_SET_FUNCTION: REM A=57 | |
625 | ||
626 | B$="eval":GOSUB INIT_CORE_SET_FUNCTION: REM A=58 | |
627 | B$="read-file":GOSUB INIT_CORE_SET_FUNCTION: REM A=59 | |
628 | B$="pr-memory-summary":GOSUB INIT_CORE_SET_FUNCTION: REM A=60 | |
241d5d57 | 629 | |
01e8850d | 630 | REM these are in DO_TCO_FUNCTION |
5bbc7a1f JM |
631 | A=65 |
632 | B$="apply":GOSUB INIT_CORE_SET_FUNCTION: REM A=65 | |
633 | B$="map":GOSUB INIT_CORE_SET_FUNCTION: REM A=66 | |
634 | B$="swap!":GOSUB INIT_CORE_SET_FUNCTION: REM A=67 | |
0e508fa5 | 635 | |
241d5d57 | 636 | RETURN |