XSLT impl: Limit jvm memory to 2GB
[jackhill/mal.git] / impls / basic / core.in.bas
CommitLineData
01e8850d 1REM APPLY should really be in types.in.bas but it is here because it
af621e3a
JM
2REM calls DO_TCO_FUNCTION so it will cause syntax errors for steps1-3
3REM if it is in types.in.bas because there are unresolved labels.
01e8850d
JM
4
5REM APPLY(F, AR) -> R
6REM - restores E
7REM - call using GOTO and with return label/address on the stack
af621e3a 8SUB 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 36END SUB
01e8850d
JM
37
38
39REM DO_TCO_FUNCTION(F, AR)
af621e3a 40SUB 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 47REM 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:
163END SUB
01e8850d 164
cc9dbd92 165REM DO_FUNCTION(F, AR)
241d5d57
JM
166DO_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 550INIT_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 556REM INIT_CORE_NS(E)
241d5d57
JM
557INIT_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