-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added documentation in a series of README.md files.
- Loading branch information
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Basic Evaluator Interpreter source code | ||
|
||
The grammar for the programming language being implemented is in the file | ||
[BasicEvaluator.g4](BasicEvaluator.g4). | ||
|
||
After any changes to the grammar file, the lexer and parser code needs to be | ||
rebuilt using the following command in Linux: | ||
|
||
``` | ||
antlr4 -no-listener -visitor -Dlanguage=CSharp BasicEvaluator.g4 | ||
``` | ||
|
||
The command antlr4 is an alias in Linux set to: | ||
``` | ||
java -jar /usr/local/lib/antlr-4.9.3-complete.jar | ||
``` | ||
|
||
The antlr4 command will rebuild the Lexer and Parser, | ||
consisting of the following files: | ||
- [BasicEvaluator.interp](BasicEvaluator.interp) | ||
- [BasicEvaluator.tokens](BasicEvaluator.tokens) | ||
- [BasicEvaluatorBaseVisitor.cs](BasicEvaluatorBaseVisitor.cs) | ||
- [BasicEvaluatorLexer.cs](BasicEvaluatorLexer.cs) | ||
- [BasicEvaluatorLexer.interp](BasicEvaluatorLexer.interp) | ||
- [BasicEvaluatorLexer.tokens](BasicEvaluatorLexer.tokens) | ||
- [BasicEvaluatorParser.cs](BasicEvaluatorParser.cs) | ||
- [BasicEvaluatorVisitor.cs](BasicEvaluatorVisitor.cs) | ||
|
||
The following files were created to implement the Interpreter: | ||
- [BasicEvaluatorVisitorImpl.cs](BasicEvaluatorVisitorImpl.cs) - the | ||
implementation of the visitor which implements the main part of the Interpreter. The class inherits from the auto-generated generic BasicEvaluatorBaseVisitor class. | ||
- [BasicEvaluatorInfo.cs](BasicEvaluatorInfo.cs) - the class of the object that | ||
is returned from each visitor function, consisting of either the name of the | ||
function definition or the value of the expression being evaluated | ||
- [Memory.cs](Memory.cs) - contains the collections of variable values for | ||
both the global and local environments (as a stack), as well as the function | ||
definitions | ||
- [ValueEnvironment.cs](ValueEnvironment.cs) - the class containing the Map of | ||
variable names to values for a single environment | ||
- [FunctionDefinition.cs](FunctionDefinition.cs) - the class containing a | ||
function definition | ||
- [Value.cs](Value.cs) - the class containing a value (an Integer) | ||
- [Parser.cs](Parser.cs) - the entry-point into the parser and interpreter, providing the functions parseDefinition method, which returns the function definition name, and the parseExpression method, which returns the evaluated value of the expression. | ||
|
||
The BasicEvaluator programming language consists of values and function | ||
definitions. It only supports one type of value and that is an Integer. Variables | ||
are stored in the global environment. Variable names can contain any character | ||
except spaces, open and close parentheses, a semicolon, or tabs, carriage returns, | ||
or line feeds. Parentheses are used to delimit expressions and function | ||
expressions, much like it does in the family of programming languages based on LISP. | ||
Semicolons are used to start a comment which goes to the end of the current line. | ||
When a function is called, the actual arguments passed to the function are | ||
evaluated to a value, and then the formal arguments of the function are set to | ||
these actual argument values inside a local environment for that function. The | ||
**visitFunctionExpr** method in the [BasicEvaluatorVisitorImpl.java](BasicEvaluatorVisitorImpl.java) | ||
file shows this logic, which is the only complicated part of the Interpreter. | ||
All other visitor functions used to implement the Interpreter are pretty | ||
straightforward. The use of a stack for the local environments fully support | ||
recursive function calls. The last function definition in the [test01.lp](test01.lp) | ||
file is a recursive function definition for the Greatest Common Divisor | ||
algorithm (gcd). | ||
|
||
### TODO | ||
1. Better handling of parser errors | ||
2. Add a **read** function to the language that reads input from the prompt | ||
3. Add a **for** loop operation to the language | ||
4. Experiment with passing values by reference during function calls, instead | ||
of by value, as it currently does. | ||
5. Add a **load** function to the REPL that loads a file to be evaluated | ||
6. Add local variables to functions | ||
7. Add real numbers to the language | ||
8. Implement static type-checking to the language as well as type-checking to | ||
distinguish between *statements* and *expressions* and between *procedures* | ||
and *functions* | ||
9. Updates to the REPL: a) history of commands and use of up/down arrow keys to | ||
go through history, b) auto-indent, c) better editing capabilities for multi- | ||
line command entry to edit lines above or below current line in command. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Basic Evaluator Read-Eval-Print Loop source code | ||
|
||
The function main is located in the file [BasicEvaluatorRepl.cs](BasicEvaluatorRepl.cs). | ||
This file contains the main Read-Eval-Print Loop which gets input from the user, | ||
that consists of a set of lines containing one expression or function definition. | ||
The expressions or function definitions entered by the user are then parsed and | ||
evaluated. See the methods named **parseDefinition**, **parseExpression**, in the Parser.cs file in the BasicEvaluatorInterpreter project to see how to use ANTLR to parse this language from the | ||
string entered by the user at the REPL prompt. | ||
|
||
Expressions are evaluated to a single Integer value and displayed as | ||
output. Function definitions are parsed and then added to a list of function | ||
definitions available to subsequent expressions entered, and its name is displayed | ||
as output. | ||
|
||
To run the evaluator from the Rider terminal, run the following command from | ||
the **bin/Debug/net6.0** folder, after building the project from | ||
within the IDE: | ||
``` | ||
./BasicEvaluator | ||
``` | ||
|
||
This will then display a prompt for the user to enter a function definition or | ||
an expression to be evaluated. The file [test01.lp](test01.lp) contains a set | ||
of expressions and function definitions that can be entered at the prompt to | ||
test the Interpreter. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
3 | ||
(+ 4 7) | ||
(set x 4) | ||
(+ x x) | ||
(print x) | ||
(set y 5) | ||
(begin (print x) (print y) (* x y)) | ||
(if (> y 0) 5 10) | ||
(while (> y 0) (begin (set x (+ x x)) (set y (- y 1)))) | ||
x | ||
(define +1 (x) (+ x 1)) | ||
(+1 4) | ||
(define double (x) (+ x x)) | ||
(double 4) | ||
x | ||
(define setx (x y) (begin (set x (+ x y)) x)) | ||
(setx x 1) | ||
x | ||
(define not (boolval) (if boolval 0 1)) | ||
(define <> (x y) (not (= x y))) | ||
(define mod (m n) (- m (* n (/ m n)))) | ||
(define gcd (m n) | ||
(begin | ||
(set r (mod m n)) | ||
(while (<> r 0) | ||
(begin | ||
(set m n) | ||
(set n r) | ||
(set r (mod m n)))) | ||
n)) | ||
(gcd 6 15) | ||
(define gcd (m n) | ||
(if (= n 0) m (gcd n (mod m n)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Basic Evaluator | ||
|
||
This project is a rewrite, using C# and ANTLR, of the **Basic Evaluator** | ||
presented in Chapter 1 of the book **Programming Languages: An Interpreter-Based | ||
Approach (PLAIBA)**, by Samuel N. Kamin, originally written in ISO Pascal. | ||
|
||
The following tools were used in the implementation: | ||
- JetBrains Rider 2021.3.2 | ||
- .NET Core 6 | ||
- ANTLR 4.9.3 | ||
- Antlr4.Runtime.Standard 4.9.3 NuGet package | ||
- Ubuntu Linux 21.10 | ||
|
||
The project was configured using the following libraries: | ||
- .NET Core 6 | ||
- Antlr4.Runtime.Standard 4.9.3 NuGet package | ||
|
||
The source code and grammar for the parser and interpreter is located in the | ||
**BasicEvaluatorInterpreter** project folder. When the project is compiled from Rider, | ||
the output assemblies are located in the **bin/Debug/net6.0** folder of the BasicEvaluatorRepl | ||
project. |