/Villie

Interpreter of a very small subset of SML like language written in Java

Primary LanguageJavaMIT LicenseMIT

Villie

Interpreter of a very small subset of SML like language written in Java

Language basics

For logical expressions 0 means false and anything else means true.
The division is integer. All intermediate results should be between -231 and 231 - 1.
E := (E)
      | E < E | E > E | E = E | E <= E | E >= E (these result in true / false expression)
      | E + E | E - E | E * E | E / E
      | if E then E else E
      | funcName(args, ...)
      | NUM | ID

Function declarations have the form fun funcName(args, ...) = E; all in one line.

The parameters names are consisted of one letter.
The function names have two or more letters.

A function can be called from anywhere in the program as long as it is defined somewhere else in the same file.
If one line of the source file contains E; the expression is evaluated numerically and printed on the standard output.

LL(1) parser is used. LR was expected to produce too many states.
Removing left-recursion grammar refactoring leads to:

Nonterminal Rule Rule Rule Rule Rule Rule
E := E1E'1
E'1 := < E1 > E1 <= E1 >= E1 = E1 ε
E1 := E2E'2
E'2 := + E2E'2 - E2E'2 ε
E2 := E3E'3
E'3 := * E3E'3 / E3E'3 ε
E3 := ID NUM (E) if E then E else E

Usage

java -jar Villie.jar [--argument] <source.code>
where --argument can be one of --recursive or --stackBased.
The default abstract machine is stack based since the recursive one is prone to StackOverflow errors.

Running Tests

The direcrory tests contains a bunch of tests. More tests can be added and they can be ran by executing run_tests.py.

Acknowledgements

Courtesy goes to Georgi Gyurchev for assembling the task and the test cases back in 2012.
I would like to thank Dr Timothy Griffin for teaching the Compiler Construction course in my Part IB year in Cambridge and Alex Chadwick for supervising me for this course (and a couple more) and encouraging me to complete this long-pending toy project.

I don't pretend that the implementation is perfect or the most efficient possible at all. In fact, by choosing Java as a main development language it must be clear that the level of abstraction is (much) higher than usual for a standard compiler/interpreter. However, the goal to implement a stack based interpreter that deals with simple expressions and recursive functions was successfully accomplished.