GOTO MAIN REM $INCLUDE: 'mem.in.bas' REM $INCLUDE: 'types.in.bas' REM $INCLUDE: 'readline.in.bas' REM $INCLUDE: 'reader.in.bas' REM $INCLUDE: 'printer.in.bas' REM $INCLUDE: 'debug.in.bas' REM READ is inlined in RE REM EVAL_AST(A, E) -> R SUB EVAL_AST REM push A on the stack GOSUB PUSH_A IF ER<>-2 THEN GOTO EVAL_AST_RETURN GOSUB TYPE_A IF T<6 OR 88 THEN A=Z%(A+2) IF T=8 THEN A=Z%(A+3) Q=T:GOSUB PUSH_Q: REM push/save type CALL EVAL GOSUB POP_Q:T=Q: REM pop/restore type GOSUB POP_A M=R REM if error, release the unattached element REM TODO: is R=0 correct? IF ER<>-2 THEN AY=R:GOSUB RELEASE:R=0:GOTO EVAL_AST_SEQ_LOOP_DONE REM for hash-maps, copy the key (inc ref since we are going to REM release it below) IF T=8 THEN N=M:M=Z%(A+2):Z%(M)=Z%(M)+32 REM update the return sequence structure REM release N (and M if T=8) since seq takes full ownership C=1:GOSUB MAP_LOOP_UPDATE REM process the next sequence entry from source list A=Z%(A+1) GOTO EVAL_AST_SEQ_LOOP EVAL_AST_SEQ_LOOP_DONE: REM cleanup stack and get return value GOSUB MAP_LOOP_DONE GOTO EVAL_AST_RETURN EVAL_AST_RETURN: REM pop A off the stack GOSUB POP_A END SUB REM EVAL(A, E) -> R SUB EVAL LV=LV+1: REM track basic return stack level REM push A on the stack GOSUB PUSH_A REM PRINT "EVAL A:"+STR$(A)+",X:"+STR$(X)+",LV:"+STR$(LV)+",FRE:"+STR$(FRE(0)) IF ER<>-2 THEN GOTO EVAL_RETURN REM AZ=A:B=1:GOSUB PR_STR REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]" GOSUB TYPE_A T=T-4 IF 0-2 THEN GOTO EVAL_RETURN AR=Z%(R+1): REM rest F=Z%(R+2) GOSUB TYPE_F T=T-8 IF 0 R REM Assume D has repl_env REM caller must release result RE: R1=-1 GOSUB READ_STR: REM inlined READ R1=R IF ER<>-2 THEN GOTO RE_DONE A=R:E=D:CALL EVAL RE_DONE: REM Release memory from READ AY=R1:GOSUB RELEASE RETURN: REM caller must release result of EVAL REM REP(A$) -> R$ REM Assume D has repl_env SUB REP R2=-1 GOSUB RE R2=R IF ER<>-2 THEN GOTO REP_DONE AZ=R:B=1:GOSUB PR_STR: REM inlined PRINT REP_DONE: REM Release memory from EVAL AY=R2:GOSUB RELEASE END SUB REM MAIN program MAIN: GOSUB INIT_MEMORY LV=0 REM create repl_env GOSUB HASHMAP:D=R REM + function T=9:L=1:GOSUB ALLOC: REM native function H=D:B$="+":C=R:GOSUB ASSOC1_S:D=R REM - function T=9:L=2:GOSUB ALLOC: REM native function H=D:B$="-":C=R:GOSUB ASSOC1_S:D=R REM * function T=9:L=3:GOSUB ALLOC: REM native function H=D:B$="*":C=R:GOSUB ASSOC1_S:D=R REM / function T=9:L=4:GOSUB ALLOC: REM native function H=D:B$="/":C=R:GOSUB ASSOC1_S:D=R ZT=ZI: REM top of memory after base repl_env REPL_LOOP: A$="user> ":GOSUB READLINE: REM call input parser IF EZ=1 THEN GOTO QUIT IF R$="" THEN GOTO REPL_LOOP A$=R$:CALL REP IF ER<>-2 THEN GOSUB PRINT_ERROR:GOTO REPL_LOOP PRINT R$ GOTO REPL_LOOP QUIT: REM GOSUB PR_MEMORY_SUMMARY_SMALL REM GOSUB PR_MEMORY_MAP REM P1=0:P2=ZI:GOSUB PR_MEMORY REM P1=D:GOSUB PR_OBJECT REM P1=ZK:GOSUB PR_OBJECT #cbm END #qbasic SYSTEM PRINT_ERROR: PRINT "Error: "+E$ ER=-2:E$="" RETURN