Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / Libraries / Sapphire / sail / tableGen.bas
CommitLineData
c1b567d8
MW
1REM >tableGen
2REM
3REM Generates a lex table for BASIC keywords, and outputs it in
4REM objasm syntax
5REM
6REM © 1995 Straylight
7REM
8:
9PROCinit
10tab$=CHR$(9)
11PROCgetClasses
12PROCoutputTokens
13PROCoutputNames
14PROCoutputTable
15END
16:
17DEFPROCinit
18ONERROR PRINTREPORT$;" [";STR$(ERL);"]":CLOSE#0:END
19DIM block% 20240
20DIM tokenClass%(256)
21DIM classNames$(256)
22DIM tokenCount%(256)
23tokenClass%()=-1
24nClass%=1
25ptr%=block%
26ptr%!0=0
27ptr%!4=0
28ptr%!8=0
29ntable%=1
30ENDPROC
31:
32DEFPROCgetClasses
33LOCAL i%,k$,c$,c%,t%,this%,C
34RESTORE
35READ k$,c$
36t%=128
37WHILE k$<>"***"
38 c%=-1
39 FOR i%=0 TO nClass%
40 IF classNames$(i%)=c$ THEN c%=i%
41 NEXT
42 IF c%=-1 THEN
43 c%=nClass%
44 nClass%+=1
45 classNames$(c%)=c$
46 ENDIF
47 IF LEN(k$)=1 THEN
48 this%=ASC(k$)
49 ELSE
50 this%=t%
51 t%+=1
52 ENDIF
53 tokenClass%(this%)=c%+(tokenCount%(c%)<<16)
54 tokenCount%(c%)+=1
55 READ k$,c$
56ENDWHILE
57
58C=OPENOUT("sh.tokClasses")
59BPUT#C,";"
60BPUT#C,"; tokClasses.sh"
61BPUT#C,";"
62BPUT#C,"; Token class and index tables (generated)"
63BPUT#C,";"
64BPUT#C,"; © 1995 Straylight"
65BPUT#C,";"
66BPUT#C,""
67BPUT#C,tab$+tab$+"["+tab$+":LNOT::DEF:tokClasses__dfn"
68BPUT#C,tab$+tab$+"GBLL"+tab$+"tokClasses__dfn"
69BPUT#C,""
70BPUT#C,"tokClasses"
71FOR i%=0 TO 255
72 IF tokenClass%(i%)=-1 THEN
73 BPUT#C,tab$+tab$+"DCB"+tab$+"0,0"
74 ELSE
75 BPUT#C,tab$+tab$+"DCB"+tab$+STR$(tokenClass%(i%) AND &FFFF)+",";
76 BPUT#C,STR$(tokenClass%(i%) >> 16)
77 ENDIF
78NEXT
79BPUT#C,""
80BPUT#C,tab$+tab$+"]"
81BPUT#C,""
82BPUT#C,tab$+tab$+"END"
83CLOSE#C
84OSCLI "SetType sh.tokClasses text"
85ENDPROC
86:
87DEFPROCoutputTokens
88LOCAL C,key$
89C=OPENOUT("sh.tokens")
90BPUT#C,";"
91BPUT#C,"; tokens.sh"
92BPUT#C,";"
93BPUT#C,"; Define constants for the tokens (generated)"
94BPUT#C,";"
95BPUT#C,"; © 1995 Straylight"
96BPUT#C,";"
97BPUT#C,""
98BPUT#C,tab$+tab$+"["+tab$+":LNOT::DEF:tokens__dfn"
99BPUT#C,tab$+tab$+"GBLL"+tab$+"tokens__dfn"
100BPUT#C,""
101BPUT#C,tab$+tab$+"^"+tab$+"&80"
102RESTORE
103READ key$,c$
104WHILE key$<>"***"
105 IF LEN(key$)>1 THEN
106 key$=FNnice(key$)
107 BPUT#C,key$;
108 IF LEN(key$)>7 THEN BPUT#C,tab$; ELSE BPUT#C,tab$+tab$;
109 BPUT#C,"#"+tab$+"1"
110 ENDIF
111 READ key$,c$
112ENDWHILE
113BPUT#C,""
114BPUT#C,tab$+tab$+"^"+tab$+"1"
115FOR i%=1 TO nClass%-1
116 c$="tClass_"+classNames$(i%)
117 BPUT#C,c$;
118 IF LEN(c$)<8 THEN BPUT#C,tab$+tab$; ELSE BPUT#C,tab$;
119 BPUT#C,"#"+tab$+"1"
120NEXT
121BPUT#C,""
122BPUT#C,tab$+tab$+"]"
123BPUT#C,""
124BPUT#C,tab$+tab$+"END"
125CLOSE#C
126OSCLI("Settype sh.tokens text")
127ENDPROC
128:
129DEFPROCoutputNames
130LOCAL C,key$,i%
131C=OPENOUT("sh.tokNames")
132BPUT#C,";"
133BPUT#C,"; tokNames.sh"
134BPUT#C,";"
135BPUT#C,"; Number-to-name table for tokens (generated)"
136BPUT#C,";"
137BPUT#C,"; © 1995 Straylight"
138BPUT#C,";"
139BPUT#C,""
140BPUT#C,tab$+tab$+"["+tab$+":LNOT::DEF:tokNames__dfn"
141BPUT#C,tab$+tab$+"GBLL"+tab$+"tokNames__dfn"
142BPUT#C,""
143BPUT#C,"tokNames";
144
145i%=0
146RESTORE
147READ key$,c$
148WHILE key$<>"***"
149 IF LEN(key$)>1 THEN
150 IF i%=0 THEN BPUT#C,tab$; ELSE BPUT#C,tab$+tab$;
151 BPUT#C,"DCD"+tab$+"tn__"+STR$(i%)
152 i%+=1
153 ENDIF
154 READ key$,c$
155ENDWHILE
156BPUT#C,""
157RESTORE
158READ key$,c$
159i%=0
160WHILE key$<>"***"
161 IF LEN(key$)>1 THEN
162 BPUT#C,"tn__"+STR$(i%)+tab$+tab$+"DCB"+tab$+""""+key$+""",0"
163 i%+=1
164 ENDIF
165 READ key$,c$
166ENDWHILE
167BPUT#C,""
168BPUT#C,tab$+tab$+"]"
169BPUT#C,""
170BPUT#C,tab$+tab$+"END"
171CLOSE#C
172OSCLI("Settype sh.tokNames text")
173ENDPROC
174:
175DEFPROCoutputTable
176RESTORE
177READ key$,c$
178root%=0
179WHILE key$<>"***"
180 PROCaddAcross(root%,key$)
181 READ key$,c$
182ENDWHILE
183C=OPENOUT"sh.tokTable"
184BPUT#C,";"
185BPUT#C,"; tokTable.sh"
186BPUT#C,";"
187BPUT#C,"; State table for lexical analysis (generated)"
188BPUT#C,";"
189BPUT#C,"; © 1995 Straylight"
190BPUT#C,";"
191BPUT#C,""
192BPUT#C,tab$+tab$+"["+tab$+":LNOT::DEF:tokTable__dfn"
193BPUT#C,tab$+tab$+"GBLL"+tab$+"tokTable__dfn"
194BPUT#C,""
195BPUT#C,tab$+tab$+"MACRO"
196BPUT#C,"$label"+tab$+tab$+"TOKTBL"+tab$+"$char,$next,$token"
197BPUT#C,"$label"
198BPUT#C,tab$+tab$+"["+tab$+"""$next""=""0"""
199BPUT#C,tab$+tab$+"DCW"+tab$+"0"
200BPUT#C,tab$+tab$+"|"
201BPUT#C,tab$+tab$+"DCW"+tab$+"$next-kt0"
202BPUT#C,tab$+tab$+"]"
203BPUT#C,tab$+tab$+"["+tab$+"""$token""<>"""""
204BPUT#C,tab$+tab$+"DCB"+tab$+"$token"
205BPUT#C,tab$+tab$+"|"
206BPUT#C,tab$+tab$+"DCB"+tab$+"0"
207BPUT#C,tab$+tab$+"]"
208BPUT#C,tab$+tab$+"DCB"+tab$+"$char"
209BPUT#C,tab$+tab$+"MEND"
210BPUT#C,""
211BPUT#C,"tokTable"
212PROCoutputBlock(C,block%,0,"")
213BPUT#C,tab$+tab$+"]"
214BPUT#C,""
215BPUT#C,tab$+tab$+"END"
216CLOSE#C
217OSCLI("Settype sh.tokTable text")
218ENDPROC
219:
220DEFFNnice(s$)
221LOCAL nice$,c%
222IF LEN(s$)=1 THEN ="'"+s$+"'"
223nice$="tok_"
224WHILE s$<>""
225 c%=ASC(LEFT$(s$,1))
226 c%=c% OR &20
227 IF c%>&60 AND c%<&7B THEN
228 nice$+=CHR$(c%)
229 ELSE
230 CASE CHR$(c%) OF
231 WHEN "+": nice$+="P"
232 WHEN "-": nice$+="M"
233 WHEN "*": nice$+="T"
234 WHEN "/": nice$+="D"
235 WHEN "=": nice$+="E"
236 WHEN "<": nice$+="L"
237 WHEN ">": nice$+="G"
238 WHEN "$": nice$+="S"
239 WHEN "#": nice$+="H"
240 ENDCASE
241 ENDIF
242 s$=MID$(s$,2)
243ENDWHILE
244=nice$
245:
246DEF PROCaddAcross(p%,s$)
247old%=0
248last%=0
249WHILE s$<>""
250 c%=ASC(LEFT$(s$,1))
251 IF p%=0 THEN
252 IF old% THEN old%!0=ptr% ELSE root%=ptr%
253 p%=ptr%
254 ptr%!0=c%
255 ptr%!4=0
256 ptr%!8=0
257 ptr%+=12
258 s$=MID$(s$,2)
259 old%=p%+8
260 last%=p%
261 p%=p%!8
262 ELSE
263 IF c%=?p% THEN
264 old%=p%+8
265 last%=p%
266 p%=p%!8
267 s$=MID$(s$,2)
268 ELSE
269 old%=p%+4
270 p%=p%!4
271 ENDIF
272 ENDIF
273ENDWHILE
274last%!0=last%!0 OR (1<<31)
275ENDPROC
276:
277DEFPROCdisplayBlock(blk%,indent%)
278IF blk%<>0 THEN
279 PRINT CHR$(blk%!0);
280 PROCdisplayBlock(blk%!8,indent%+1)
281 IF blk%!4 THEN
282 PRINT SPC(indent%);
283 PROCdisplayBlock(blk%!4,indent%)
284 ENDIF
285ELSE
286 PRINT
287ENDIF
288ENDPROC
289:
290DEFPROCoutputBlock(C,blk%,n%,prefix$)
291BPUT#C,"kt"+STR$(n%);
292PROCoutputAcross(C,blk%,prefix$)
293ENDPROC
294:
295DEFPROCoutputAcross(C,p%,prefix$)
296LOCAL n%
297n%=ntable%
298IF p%<>0 THEN
299 BPUT#C,tab$+tab$+"TOKTBL"+tab$+"'"+CHR$(p%?0)+"'";
300 IF p%!8 THEN
301 BPUT#C,",kt"+STR$(n%);
302 ntable%+=1
303 ELSE
304 BPUT#C,",0";
305 ENDIF
306 IF (p%!0 AND (1<<31)) THEN
307 BPUT#C,","+FNnice(prefix$+CHR$(?p%));
308 ENDIF
309 BPUT#C,""
310 PROCoutputAcross(C,p%!4,prefix$)
311 IF p%!8 THEN PROCoutputBlock(C,p%!8,n%,prefix$+CHR$(?p%))
312ELSE
313 BPUT#C,tab$+tab$+"TOKTBL"+tab$+"0,0"
314 BPUT#C,""
315ENDIF
316ENDPROC
317:
318DATA AND,andOp,ABS,fn,ASC,fn
319DATA BGET,streamOp,BPUT,instr,
320DATA CASE,instr,CHR$,fn,CLOSE,instr
321DATA CALL,instr
322DATA DATA,instr,DEF,instr,DIV,multOp,DIM,instr
323DATA END,instr,ENDPROC,instr,ENDWHILE,instr,ENDIF,instr,ENDCASE,instr
324DATA ELSE,instr,EVAL,fn,ERROR,instr,EOF,streamOp,EOR,orOp
325DATA EXT,streamOp
326DATA FOR,instr,FALSE,pseud,FN,odd,GOTO,instr
327DATA GET$,streamOp,GOSUB,instr
328DATA IF,instr,INSTR(,multArg,LEFT$(,multArg,LEN,fn
329DATA LET,instr
330DATA LOCAL,instr
331DATA MID$(,multArg,MOD,multOp
332DATA NEXT,instr,NOT,fn
333DATA OF,noise,OFF,option,ON,noise,OR,orOp,OPENIN,fn,OPENOUT,fn,OPENUP,fn
334DATA OSCLI,instr,OTHERWISE,instr
335DATA PTR,streamOp,PROC,instr
336DATA RETURN,instr,REPEAT,instr,READ,instr
337DATA REM,noise,RESTORE,instr
338DATA RIGHT$(,multArg,RND,odd
339DATA STEP,noise,SGN,fn,STR$,fn,STRING$(,multArg,SWAP,instr
340DATA SYS,instr
341DATA THEN,noise,TIME,pseud,TIME$,pseud,TO,noise,TRUE,pseud
342DATA UNTIL,instr
343DATA VAL,fn
344DATA WHILE,instr,WHEN,instr
345DATA =,relOp,<,relOp,<=,relOp,<>,relOp,>,relOp,>=,relOp
346DATA <<,relOp,>>,relOp,>>>,relOp
347DATA /,multOp,/*,noise,//,noise
348DATA +,addOp,-,addOp,*,multOp,+=,assign,-=,assign,*=,assign,^,powOp
349DATA /=,assign
350DATA ***,***