forked from DualBrain/QB64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
intrprtr.bas
346 lines (311 loc) · 6.61 KB
/
intrprtr.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
DECLARE SUB LLISTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB INITGETSYM (N AS INTEGER)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB GETSYM ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION EXPRESSION% ()
DECLARE FUNCTION ADDEXPR% ()
DECLARE FUNCTION TERM% ()
DECLARE FUNCTION FACTOR% ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
DIM SHARED CH$, THELIN$, PGM$(2000), TOK$
DIM SHARED VARS(26) AS INTEGER, CURLINE AS INTEGER, NUM AS INTEGER
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
DO
ERRORS = 0
LINE INPUT "> ", PGM$(0)
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
FUNCTION ACCEPT% (S AS STRING)
ACCEPT% = 0
IF TOK$ = S THEN ACCEPT% = 1: CALL GETSYM
END FUNCTION
FUNCTION ADDEXPR%
DIM N
N = TERM%
ADDEL:
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM%: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM%: GOTO ADDEL
ADDEXPR% = N
END FUNCTION
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO 26
VARS(I) = 0
NEXT I
END SUB
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= 1999 THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO 1999
PGM$(I) = ""
NEXT I
EXIT SUB
END IF
IF ACCEPT("BYE") THEN END
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION%
DIM N
N = ADDEXPR%
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR%: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR%: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR%: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR%: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR%: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR%: GOTO EXPRL
EXPRESSION% = N
END FUNCTION
FUNCTION FACTOR%
IF ACCEPT("-") THEN
FACTOR% = -FACTOR%
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR% = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
FACTOR% = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR% = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR": ERRORS = 1
END FUNCTION
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ >= "A" AND CH$ <= "Z" THEN CALL READIDENT: EXIT SUB
IF CH$ >= "0" AND CH$ <= "9" THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$: ERRORS = 1
END SUB
FUNCTION GETVARINDEX%
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE": ERRORS = 1: EXIT FUNCTION
END IF
GETVARINDEX% = ASC(LEFT$(TOK$, 1)) - ASC("A")
CALL GETSYM
END FUNCTION
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(NUM)
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO": ERRORS = 1
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF TOK$ = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
CALL EXPECT(",")
ELSE
PRINT "? ";
END IF
VAR = GETVARINDEX
INPUT VARS(VAR)
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LLISTSTMT
OPEN "LPT1" FOR OUTPUT AS #1
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN PRINT #1, I; " "; PGM$(I)
NEXT I
PRINT
CLOSE #1
END SUB
SUB LPRINTSTMT
OPEN "LPT1" FOR OUTPUT AS #1
DIM LPRINTNL AS INTEGER
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT #1, MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT #1, EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT #1, ""
CLOSE #1
END SUB
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB READIDENT
TOK$ = ""
WHILE CH$ >= "A" AND CH$ <= "Z"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED": ERRORS = 1: EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION TERM%
DIM N
N = FACTOR%
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * FACTOR%: GOTO TERML
IF TOK$ = "/" THEN CALL GETSYM: N = N / FACTOR%: GOTO TERML
TERM% = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= 1999 THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE": ERRORS = 1
END SUB