2 REM DO_FUNCTION(F%, AR%)
4 REM Get the function number
7 REM Get argument values
8 R
%=AR
%+1:GOSUB DEREF_R
:AA
%=R
%
9 R
%=Z
%(AR
%,1)+1:GOSUB DEREF_R
:AB
%=R
%
11 REM Switch on the function number
12 IF FF
%>=61 THEN ER
%=-1:ER
$="unknown function"+STR$(FF%):RETURN
19 ON FF% GOTO DO_EQUAL_Q,DO_THROW,DO_NIL_Q,DO_TRUE_Q,DO_FALSE_Q,DO_STRING_Q,DO_SYMBOL,DO_SYMBOL_Q
21 ON FF%-10 GOTO DO_PR_STR,DO_STR,DO_PRN,DO_PRINTLN,DO_READ_STRING,DO_READLINE,DO_SLURP
23 ON FF%-17 GOTO DO_LT,DO_LTE,DO_GT,DO_GTE,DO_ADD,DO_SUB,DO_MULT,DO_DIV,DO_TIME_MS
25 ON FF%-26 GOTO DO_LIST,DO_LIST_Q,DO_VECTOR,DO_VECTOR_Q,DO_HASH_MAP,DO_MAP_Q
27 ON FF%-38 GOTO DO_SEQUENTIAL_Q,DO_CONS,DO_CONCAT,DO_NTH,DO_FIRST,DO_REST,DO_EMPTY_Q,DO_COUNT,DO_APPLY,DO_MAP
29 ON FF%-52 GOTO DO_ATOM,DO_ATOM_Q,DO_DEREF,DO_RESET_BANG,DO_SWAP_BANG,DO_PR_MEMORY,DO_PR_MEMORY_SUMMARY,DO_EVAL
32 A%=AA%:B%=AB%:GOSUB EQUAL_Q
37 Z%(ER%,0)=Z%(ER%,0)+16
54 IF (Z%(AA%,0)AND15)=4 THEN R%=2
61 IF (Z%(AA%,0)AND15)=5 THEN R%=2
65 AZ%=AR%:PR%=1:SE$=" ":GOSUB PR_STR_SEQ
66 AS$=R$:T%=4+16:GOSUB STRING
69 AZ
%=AR
%:PR
%=0:SE
$="":GOSUB PR_STR_SEQ
70 AS$=R$:T%=4+16:GOSUB STRING
73 AZ
%=AR
%:PR
%=1:SE
$=" ":GOSUB PR_STR_SEQ
78 AZ%=AR%:PR%=0:SE$=" ":GOSUB PR_STR_SEQ
87 A
$=ZS$(Z%(AA%,1)):GOSUB READLINE
88 IF EOF
=1 THEN EOF
=0:R
%=0:RETURN
89 AS$=R$:T%=4:GOSUB STRING
94 REM OPEN 1,8,2,ZS$(Z%(AA%,1))+",SEQ,R"
95 REM OPEN 1,8,2,ZS$(Z%(AA%,1))
96 OPEN
1,8,0,ZS
$(Z%(AA%,1))
100 IF ASC(A
$)=10 THEN R
$=R$+CHR$(13)
101 IF (ASC(A
$)<>10) AND (A
$<>"") THEN R
$=R$+A$
102 IF (ST
AND 64) THEN GOTO DO_SLURP_DONE
103 IF (ST
AND 255) THEN ER
%=-1:ER
$="File read
error "+STR$(ST):RETURN
107 AS$=R$:T%=4+16:GOSUB STRING
112 IF Z%(AA%,1)<Z%(AB%,1) THEN R%=2
116 IF Z%(AA%,1)<=Z%(AB%,1) THEN R%=2
120 IF Z%(AA%,1)>Z%(AB%,1) THEN R%=2
124 IF Z%(AA%,1)>=Z%(AB%,1) THEN R%=2
130 Z%(R%,1)=Z%(AA%,1)+Z%(AB%,1)
135 Z%(R%,1)=Z%(AA%,1)-Z%(AB%,1)
140 Z%(R%,1)=Z%(AA%,1)*Z%(AB%,1)
145 Z%(R%,1)=Z%(AA%,1)/Z%(AB%,1)
157 R%=R%+1: REM map to mal false/true
164 IF (Z%(AA%,0)AND15)=7 THEN R%=2
171 IF (Z%(AA%,0)AND15)=8 THEN R%=2
176 IF (Z%(AA%,0)AND15)=6 OR (Z%(AA%,0)AND15)=7 THEN R%=2
179 A%=AA%:B%=AB%:GOSUB CONS
182 REM if empty arguments, return empty list
183 IF Z%(AR%,1)=0 THEN R%=3:Z%(R%,0)=Z%(R%,0)+16:RETURN
186 IF Z%(Z%(AR%,1),1)<>0 THEN GOTO DO_CONCAT_MULT
187 REM if single argument and it's a list, return it
188 IF (Z%(AA%,0)AND15)=6 THEN R%=AA%:Z%(R%,0)=Z%(R%,0)+16:RETURN
189 REM otherwise, copy first element to turn it into a list
190 B%=AA%+1:GOSUB DEREF_B: REM value to copy
192 Z%(R%,0)=6+16:Z%(R%,1)=Z%(AA%,1)
193 Z%(R%+1,0)=14:Z%(R%+1,1)=B%
194 REM inc ref count of trailing list part and of copied value
195 Z%(Z%(AA%,1),0)=Z%(Z%(AA%,1),0)+16
199 REM multiple arguments
201 CZ%=ZL%: REM save current stack position
202 REM push arguments onto the stack
204 R%=AR%+1:GOSUB DEREF_R
205 ZL%=ZL%+1:ZZ%(ZL%)=R%: REM push sequence
207 IF Z%(AR%,1)<>0 THEN GOTO DO_CONCAT_STACK
209 REM pop last argument as our seq to prepend to
210 AB%=ZZ%(ZL%):ZL%=ZL%-1
211 REM last arg/seq is not copied so we need to inc ref to it
212 Z%(AB%,0)=Z%(AB%,0)+16
214 IF ZL%=CZ% THEN R%=AB%:RETURN
215 AA%=ZZ%(ZL%):ZL%=ZL%-1: REM pop off next seq to prepend
216 IF Z%(AA%,1)=0 THEN GOTO DO_CONCAT_LOOP: REM skip empty seqs
217 A%=AA%:B%=0:C%=-1:GOSUB SLICE
219 REM release the terminator of new list (we skip over it)
220 AY%=Z%(R6%,1):GOSUB RELEASE
221 REM attach new list element before terminator (last actual
222 REM element to the next sequence
230 IF R%<=B% THEN R%=0:ER%=-1:ER$="nth: index out of range":RETURN
232 IF B
%=0 THEN GOTO DO_NTH_DONE
241 IF Z
%(AA
%,1)=0 THEN R
%=0
242 IF Z
%(AA
%,1)<>0 THEN R
%=AA
%+1:GOSUB DEREF_R
243 IF R
%<>0 THEN Z
%(R
%,0)=Z
%(R
%,0)+16
246 IF Z
%(AA
%,1)=0 THEN R
%=AA
%
247 IF Z
%(AA
%,1)<>0 THEN R
%=Z
%(AA
%,1)
252 IF Z
%(AA
%,1)=0 THEN R
%=2
255 A
%=AA
%:GOSUB COUNT
:R4
%=R
%
263 A
%=AR
%:GOSUB COUNT
:R4
%=R
%
265 REM no intermediate args, just call APPLY directly
266 IF R4
%<=1 THEN AR
%=Z
%(AR
%+1,1):GOSUB APPLY
:RETURN
268 REM prepend intermediate args to final args element
269 A
%=AR
%:B
%=0:C
%=R4
%-1:GOSUB SLICE
270 REM release the terminator of new list (we skip over it)
271 AY
%=Z
%(R6
%,1):GOSUB RELEASE
272 REM attach end of slice to final args element
274 Z
%(Z
%(A
%+1,1),0)=Z
%(Z
%(A
%+1,1),0)+16
276 ZL
%=ZL
%+1:ZZ
%(ZL
%)=R
%: REM push/save new args for release
278 AY
%=ZZ
%(ZL
%):ZL
%=ZL
%-1:GOSUB RELEASE
: REM pop/release new args
283 REM first result list element
286 REM push future return val, prior entry, F% and AB%
287 ZL
%=ZL
%+4:ZZ
%(ZL
%-3)=R
%:ZZ
%(ZL
%-2)=0:ZZ
%(ZL
%-1)=F
%:ZZ
%(ZL
%)=AB
%
291 Z
%(R
%,0)=6+16:Z
%(R
%,1)=0
292 Z
%(R
%+1,0)=14:Z
%(R
%+1,1)=0
294 REM set previous to current if not the first element
295 IF ZZ
%(ZL
%-2)<>0 THEN Z
%(ZZ
%(ZL
%-2),1)=R
%
296 REM update previous reference to current
299 IF Z
%(AB
%,1)=0 THEN GOTO DO_MAP_DONE
301 REM create argument list for apply call
303 Z
%(R
%,0)=6+16:Z
%(R
%,1)=0
304 Z
%(R
%+1,0)=14:Z
%(R
%+1,1)=0
305 AR
%=R
%: REM save end of list temporarily
307 Z
%(R
%,0)=6+16:Z
%(R
%,1)=AR
%
308 REM inc ref cnt of referred argument
309 A
%=Z
%(AB
%+1,1): Z
%(A
%,0)=Z
%(A
%,0)+16
310 Z
%(R
%+1,0)=14:Z
%(R
%+1,1)=A
%
312 REM push argument list
313 ZL
%=ZL
%+1:ZZ
%(ZL
%)=R
%
317 REM pop apply args are release them
318 AY
%=ZZ
%(ZL
%):ZL
%=ZL
%-1:GOSUB RELEASE
320 REM set the result value
321 Z
%(ZZ
%(ZL
%-2)+1,1)=R
%
326 REM update AB% to next source element
327 ZZ
%(ZL
%)=Z
%(ZZ
%(ZL
%),1)
330 REM allocate next element
338 REM pop everything off stack
344 Z
%(AA
%,0)=Z
%(AA
%,0)+16: REM inc ref cnt of contained value
350 IF (Z
%(AA
%,0)AND15
)=12 THEN R
%=2
353 R
%=Z
%(AA
%,1):GOSUB DEREF_R
358 REM release current value
359 AY
%=Z
%(AA
%,1):GOSUB RELEASE
360 REM inc ref by 2 for atom ownership and since we are returning it
368 REM add atom to front of the args list
369 A
%=Z
%(AA
%,1):B
%=Z
%(Z
%(AR
%,1),1):GOSUB CONS
372 REM push args for release after
373 ZL
%=ZL
%+1:ZZ
%(ZL
%)=AR
%
376 ZL
%=ZL
%+1:ZZ
%(ZL
%)=AA
%
381 AA
%=ZZ
%(ZL
%):ZL
%=ZL
%-1
383 REM pop and release args
384 AY
%=ZZ
%(ZL
%):ZL
%=ZL
%-1:GOSUB RELEASE
386 REM use reset to update the value
387 AB
%=R
%:GOSUB DO_RESET_BANG
389 REM but decrease ref cnt of return by 1 (not sure why)
395 P1
%=ZT
%:P2
%=-1:GOSUB PR_MEMORY
397 DO_PR_MEMORY_SUMMARY:
398 GOSUB PR_MEMORY_SUMMARY
402 A
%=AA
%:E
%=RE
%:GOSUB EVAL
405 INIT_CORE_SET_FUNCTION:
406 GOSUB NATIVE_FUNCTION
407 V
%=R
%:GOSUB ENV_SET_S
412 REM create the environment mapping
413 REM must match DO_FUNCTION mappings
415 K
$="=":A%=1:GOSUB INIT_CORE_SET_FUNCTION
416 K
$="throw":A%=2:GOSUB INIT_CORE_SET_FUNCTION
417 K
$="nil?":A%=3:GOSUB INIT_CORE_SET_FUNCTION
418 K
$="true?":A%=4:GOSUB INIT_CORE_SET_FUNCTION
419 K
$="false?":A%=5:GOSUB INIT_CORE_SET_FUNCTION
420 K
$="string?":A%=6:GOSUB INIT_CORE_SET_FUNCTION
421 K
$="symbol":A%=7:GOSUB INIT_CORE_SET_FUNCTION
422 K
$="symbol?":A%=8:GOSUB INIT_CORE_SET_FUNCTION
424 K
$="pr-str":A%=11:GOSUB INIT_CORE_SET_FUNCTION
425 K
$="str":A%=12:GOSUB INIT_CORE_SET_FUNCTION
426 K
$="prn":A%=13:GOSUB INIT_CORE_SET_FUNCTION
427 K
$="println":A%=14:GOSUB INIT_CORE_SET_FUNCTION
428 K
$="read-string":A%=15:GOSUB INIT_CORE_SET_FUNCTION
429 K
$="readline":A%=16:GOSUB INIT_CORE_SET_FUNCTION
430 K
$="slurp":A%=17:GOSUB INIT_CORE_SET_FUNCTION
432 K
$="<":A%=18:GOSUB INIT_CORE_SET_FUNCTION
433 K
$="<=":A%=19:GOSUB INIT_CORE_SET_FUNCTION
434 K
$=">":A%=20:GOSUB INIT_CORE_SET_FUNCTION
435 K
$=">=":A%=21:GOSUB INIT_CORE_SET_FUNCTION
436 K
$="+":A%=22:GOSUB INIT_CORE_SET_FUNCTION
437 K
$="-":A%=23:GOSUB INIT_CORE_SET_FUNCTION
438 K
$="*":A%=24:GOSUB INIT_CORE_SET_FUNCTION
439 K
$="/":A%=25:GOSUB INIT_CORE_SET_FUNCTION
440 K
$="time-ms":A%=26:GOSUB INIT_CORE_SET_FUNCTION
442 K
$="list":A%=27:GOSUB INIT_CORE_SET_FUNCTION
443 K
$="list?":A%=28:GOSUB INIT_CORE_SET_FUNCTION
444 K
$="vector":A%=29:GOSUB INIT_CORE_SET_FUNCTION
445 K
$="vector?":A%=30:GOSUB INIT_CORE_SET_FUNCTION
446 K
$="hash-map":A%=31:GOSUB INIT_CORE_SET_FUNCTION
447 K
$="map?":A%=32:GOSUB INIT_CORE_SET_FUNCTION
449 K
$="sequential?":A%=39:GOSUB INIT_CORE_SET_FUNCTION
450 K
$="cons":A%=40:GOSUB INIT_CORE_SET_FUNCTION
451 K
$="concat":A%=41:GOSUB INIT_CORE_SET_FUNCTION
452 K
$="nth":A%=42:GOSUB INIT_CORE_SET_FUNCTION
453 K
$="first":A%=43:GOSUB INIT_CORE_SET_FUNCTION
454 K
$="rest":A%=44:GOSUB INIT_CORE_SET_FUNCTION
455 K
$="empty?":A%=45:GOSUB INIT_CORE_SET_FUNCTION
456 K
$="count":A%=46:GOSUB INIT_CORE_SET_FUNCTION
457 K
$="apply":A%=47:GOSUB INIT_CORE_SET_FUNCTION
458 K
$="map":A%=48:GOSUB INIT_CORE_SET_FUNCTION
460 K
$="atom":A%=53:GOSUB INIT_CORE_SET_FUNCTION
461 K
$="atom?":A%=54:GOSUB INIT_CORE_SET_FUNCTION
462 K
$="deref":A%=55:GOSUB INIT_CORE_SET_FUNCTION
463 K
$="reset!":A%=56:GOSUB INIT_CORE_SET_FUNCTION
464 K
$="swap!":A%=57:GOSUB INIT_CORE_SET_FUNCTION
466 K
$="pr-memory":A%=58:GOSUB INIT_CORE_SET_FUNCTION
467 K
$="pr-memory-summary":A%=59:GOSUB INIT_CORE_SET_FUNCTION
468 K
$="eval":A%=60:GOSUB INIT_CORE_SET_FUNCTION