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