7.10.7. PEG-07 — C64 BASIC Interpreter
This tutorial builds a Commodore 64-style BASIC interpreter — a complete parser-to-interpreter pipeline with 15+ grammar rules. You will learn:
Building a parser -> interpreter pipeline
A grammar with many statement types
Runtime expression evaluation using PEG
Keyword disambiguation with negative lookahead
Line-number-based program storage with
GOTO/GOSUBFOR/NEXTloops,IF/THENbranching
Prerequisites: Tutorials PEG-01 through PEG-06.
7.10.7.1. Architecture
The interpreter has three layers:
Line parser — PEG grammar that parses BASIC statements into a
Stmtvariant. Expression text is captured as strings, not evaluated.Expression evaluator — a second PEG grammar that parses and evaluates arithmetic expressions at runtime, with access to the current variable table.
Interpreter loop — walks stored program lines, dispatching each statement type.
7.10.7.2. Statement Types
Statements are represented as a variant:
variant Stmt {
print_expr : string // PRINT <expr>
print_str : string // PRINT "literal"
print_semi : string // PRINT <expr>; (no newline)
print_nl : bool // bare PRINT
let_stmt : tuple<string; string> // LET var = <expr>
if_goto : tuple<string; int> // IF <cond> THEN linenum
goto_stmt : int
gosub_stmt : int
return_stmt : bool
for_stmt : tuple<string; string; string; string> // var, from, to, step
next_stmt : string
rem_stmt : string
end_stmt : bool
nop : bool
}
Expression text is stored as strings and re-parsed each time the statement executes — just like classic BASIC.
7.10.7.3. Keyword Disambiguation
Variable names must not match keywords. Negative lookahead (!)
prevents TO, STEP, or THEN from being parsed as identifiers:
var primary : double
rule(!"TO", !"STEP", !"THEN", "{+ident_ch}" as name) {
return eval_vars?[name] ?? 0.0lf
}
7.10.7.4. Text Capture for Deferred Evaluation
The line parser captures expression text without evaluating it.
Helper rules like until_then match everything up to a keyword:
var until_then : void?
rule(!"THEN", any) {
return null
}
Then in the statement rule:
rule("IF", WS, "{+until_then}" as cond, WS, "THEN", WS, number as target) {
return Stmt(if_goto = (cond, target))
}
At runtime, the captured text is passed to the expression evaluator.
7.10.7.5. Demo Programs
The tutorial runs four BASIC programs:
Hello World + FOR loop:
10 PRINT "HELLO WORLD"
20 FOR I = 1 TO 5
30 PRINT I;
35 PRINT " ";
40 NEXT I
50 PRINT
60 END
Countdown with IF/GOTO:
10 I = 5
20 PRINT I
30 I = I - 1
40 IF I >= 0 THEN 20
50 PRINT "LIFTOFF!"
GOSUB/RETURN:
10 X = 5
20 GOSUB 100
30 X = 10
40 GOSUB 100
50 END
100 REM Print X * X
110 PRINT X * X
120 RETURN
Fibonacci sequence:
10 A = 0
20 B = 1
30 FOR I = 1 TO 10
40 PRINT A;
50 PRINT " ";
60 C = A + B
70 A = B
80 B = C
90 NEXT I
100 PRINT
Output:
0 1 1 2 3 5 8 13 21 34
See also
Full source: tutorials/dasPEG/07_basic.das