Merge pull request #378 from asarhaddon/test-macro-not-changing-function
[jackhill/mal.git] / basic / printer.in.bas
1 REM PR_STR(AZ, B) -> R$
2 PR_STR:
3 R$=""
4 PR_STR_RECUR:
5 T=Z%(AZ)AND 31
6 U=Z%(AZ+1)
7 REM PRINT "AZ: "+STR$(AZ)+", T: "+STR$(T)+", U: "+STR$(U)
8 IF T=0 THEN R$="nil":RETURN
9 REM if metadata, then get actual object
10 IF T>=14 THEN AZ=U:GOTO PR_STR_RECUR
11 ON T GOTO PR_BOOLEAN,PR_INTEGER,PR_UNKNOWN,PR_STRING_MAYBE,PR_SYMBOL,PR_SEQ,PR_SEQ,PR_SEQ,PR_FUNCTION,PR_MAL_FUNCTION,PR_MAL_FUNCTION,PR_ATOM,PR_ENV,PR_RECUR,PR_FREE
12
13 PR_UNKNOWN:
14 REM MEMORY DEBUGGING:
15 REM R$="#<unknown>"
16 RETURN
17 PR_RECUR:
18 AZ=U
19 GOTO PR_STR_RECUR
20 PR_BOOLEAN:
21 R$="true"
22 IF U=0 THEN R$="false"
23 RETURN
24 PR_INTEGER:
25 T$=STR$(U)
26 REM Remove initial space
27 IF U>=0 THEN T$=RIGHT$(T$,LEN(T$)-1)
28 R$=R$+T$
29 RETURN
30 PR_STRING_MAYBE:
31 R$=S$(U)
32 IF LEN(R$)=0 THEN GOTO PR_STRING
33 IF MID$(R$,1,1)=CHR$(127) THEN R$=":"+MID$(R$,2,LEN(R$)-1):RETURN
34 PR_STRING:
35 IF B=1 THEN GOTO PR_STRING_READABLY
36 RETURN
37 PR_STRING_READABLY:
38 S1$="\":S2$="\\":GOSUB REPLACE: REM escape backslash "
39 S1$=CHR$(34):S2$="\"+CHR$(34):GOSUB REPLACE: REM escape quotes "
40 #cbm S1$=CHR$(13):S2$="\n":GOSUB REPLACE: REM escape newlines
41 #qbasic S1$=CHR$(10):S2$="\n":GOSUB REPLACE: REM escape newlines
42 R$=CHR$(34)+R$+CHR$(34)
43 RETURN
44 PR_SYMBOL:
45 R$=S$(U)
46 RETURN
47 PR_SEQ:
48 REM push the type and where we are in the sequence
49 Q=T:GOSUB PUSH_Q
50 Q=AZ:GOSUB PUSH_Q
51 REM save the current rendered string
52 S$(S)=R$:S=S+1
53 PR_SEQ_LOOP:
54 IF Z%(AZ+1)=0 THEN GOTO PR_SEQ_DONE
55 AZ=Z%(AZ+2):GOSUB PR_STR:GOSUB PEEK_Q_1:T=Q
56 REM append what we just rendered it
57 S$(S-1)=S$(S-1)+R$
58
59 REM if this is a hash-map, print the next element
60 IF T=8 THEN GOSUB PEEK_Q:AZ=Z%(Q+3):GOSUB PR_STR:S$(S-1)=S$(S-1)+" "+R$
61
62 REM restore current seq type
63 GOSUB PEEK_Q_1:T=Q
64 REM Go to next list element
65 GOSUB PEEK_Q
66 AZ=Z%(Q+1)
67 Q=AZ:GOSUB PUT_Q
68 IF Z%(AZ+1)<>0 THEN S$(S-1)=S$(S-1)+" "
69 GOTO PR_SEQ_LOOP
70 PR_SEQ_DONE:
71 REM restore the current string
72 S=S-1:R$=S$(S)
73 REM pop where we are the sequence and type
74 GOSUB POP_Q
75 GOSUB POP_Q:T=Q: REM get type
76 IF T=6 THEN R$="("+R$+")"
77 IF T=7 THEN R$="["+R$+"]"
78 IF T=8 THEN R$="{"+R$+"}"
79 RETURN
80 PR_FUNCTION:
81 R$="#<fn"+STR$(U)+">"
82 RETURN
83 PR_MAL_FUNCTION:
84 T1=AZ
85 AZ=Z%(T1+2):GOSUB PR_STR
86 REM append what we just rendered it
87 S$(S)="(fn* "+R$:S=S+1
88 AZ=Z%(T1+1):GOSUB PR_STR
89 S=S-1
90 R$=S$(S)+" "+R$+")"
91 RETURN
92 PR_ATOM:
93 AZ=U:GOSUB PR_STR
94 R$="(atom "+R$+")"
95 RETURN
96 PR_ENV:
97 R$="#<env"+STR$(AZ)+", data"+STR$(U)+">"
98 RETURN
99 PR_FREE:
100 R$="#<free"+STR$(AZ)+", next"+STR$(U)+">"
101 RETURN
102
103 REM PR_STR_SEQ(AZ, B, B$) -> R$
104 REM - B is print_readably
105 REM - B$ is the separator
106 PR_STR_SEQ:
107 V=AZ
108 S$(S)="":S=S+1
109 PR_STR_SEQ_LOOP:
110 IF Z%(V+1)=0 THEN S=S-1:R$=S$(S):RETURN
111 AZ=Z%(V+2):GOSUB PR_STR
112 REM goto the next sequence element
113 V=Z%(V+1)
114 IF Z%(V+1)=0 THEN S$(S-1)=S$(S-1)+R$
115 IF Z%(V+1)<>0 THEN S$(S-1)=S$(S-1)+R$+B$
116 GOTO PR_STR_SEQ_LOOP