A simple Pascal interpreter based on Let's Build a Simple Interpreter series by Ruslan Spivak with usage of EBNF grammar tester by mdkrajnak, TatSu and railroad diagrams.
.github/workflows
- workflows for running testsbase
- files for building the interpreter at its current statepart [1-9][0-9]*( - [a-zA-Z ]*)?
- part that reflects the state of the interpreter at the end of the corresponding part of the seriessrc
- images for this READMEtest
- test modules and test files for the interpreter in each part
- Implemented all parts of the series (part 19 implemented in part 18)
- Additionally implemented:
- Procedures can access non-local variables
- UI with following output:
- Standard and error output
- Table with scopes
- Activation records for each scope
Sample program
program Main;
procedure Alpha(a : integer; b : integer); { 4, 2 / 1, 3 }
var x : integer;
procedure Beta(a : integer; c : integer); { 12, 2 / 8, 3 }
var x : integer;
begin
x := a * 10 + b * 2 + c; { 66 / 49 }
writeln(a);
writeln(x);
end;
begin
x := (a + b ) * 2; { 12 / 8 }
Beta(x, b);
end;
begin { Main }
Alpha(2 + 2, 2);
Alpha(1, 3);
end. { Main }
# Program
<program> ::= <PROGRAM> <variable> <SEMI> <block> <DOT>
# Block
<block> ::= <declarations> <compound_statement>
# Declaration
<declarations> ::= <VAR> { <variable_declaration> <SEMI> }+
| { <PROCEDURE> <ID> <SEMI> <block> <SEMI> }*
| <empty>
<variable_declaration> ::= <ID> { <COMMA> <ID> }* <COLON> <type_spec>
<type_spec> ::= <INTEGER_TYPE> | <REAL_TYPE>
# Statement
<compound_statement> ::= <BEGIN> <statement_list> <END>
<statement_list> ::= <statement> { <SEMI> <statement_list> }*
<statement> ::= <compound_statement>
| <procedure_call_statement>
| <assignment_statement>
| <empty>
<assignment_statement> ::= <variable> <ASSIGN> <expression>
<procedure_call_statement> ::= <ID> <LPAREN> [ <expression> { <COMMA> <expression> }* ] <RPAREN>
<empty> ::= ''
# Mathemathical Expression
<expression> ::= <term> { (<PLUS> | <MINUS>) <term> }*
<term> ::= <factor> { (<MUL> | <INTEGER_DIV> | <FLOAT_DIV>) <factor> }*
<factor> ::= <PLUS> <factor>
| <MINUS> <factor>
| <INTEGER>
| <REAL>
| <LPAREN> <expression> <RPAREN>
| <variable>
# Variables
<variable> ::= <ID>
<ID> ::= [a-zA-Z_][a-zA-Z0-9_]*
# Numerical Values
<INTEGER> ::= <digit>+
<REAL> ::= <digit>+ [ <DOT> <digit>+ ]
<digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
# Reserved words
<PROGRAM> ::= 'PROGRAM'
<BEGIN> ::= 'BEGIN'
<END> ::= 'END'
<VAR> ::= 'VAR'
<INTEGER_TYPE> ::= 'INTEGER'
<REAL_TYPE> ::= 'REAL'
# Symbols
<DOT> ::= '.'
<SEMI> ::= ';'
<COMMA> ::= ','
<COLON> ::= ':'
<LPAREN> ::= '('
<RPAREN> ::= ')'
# Operators
<ASSIGN> ::= ':='
<PLUS> ::= '+'
<MINUS> ::= '-'
<MUL> ::= '*'
<FLOAT_DIV> ::= '/'
<INTEGER_DIV> ::= 'DIV'