I began by writing a grammar for the rukky procedural programming language which I then developed an interpreter for. This invented language is quite simple and borrows features and concepts from multiple programming languages, with a few syntactical tweaks here and there. I didn't create the language or the interpreter with speed, efficiency or novelty in mind, just as a fun mini-project.
The interpreter utilises a predictive top-down parsing technique called a recursive descent parser. The parser is LL(1) in most cases, but not all.
- Comments
$ ... $ - Real, Boolean and String Literals
- Arithmetic Operations
+, -, *, /, //, %, ^ - Comparison Operations
==, <>, >, >=, <, <=- Membership Condition
"r" ? "rukky"
- Membership Condition
- Logical Operations
~, &&, || - Types
real, bool, str, void, obj - Variables
x := 10 - Maps
- Arrays
- Indexing
- Retrieve
lst[0] - Update
lst@0 := x
- Retrieve
- Appending
lst << x
- Indexing
- If Statement
if:: elif:: else:: - Delete Statement
del:: - Loop Statements
for:: while:: give:: - Reserved Keywords
null, pi, eul - Functions
- Function Calls
func:x:: - Branching Statements
return:: break:: continue:: - Reserved Functions
display, len, type, min, max, rand, floor, ceil, sqrt, log, sin, cos, tan, getStr, getReal - Classes
class::- Inheritance
Child : Parent- Super Keyword
super::
- Super Keyword
- Inheritance
> python rukky -f path/to/rukky/tests/files/factorial.rk
result: 120.0
> python rukky --help
usage: rukky [-h] (-s | -f FILE) [-t | -a | -g | -d]
Interpreter for the "rukky" programming language. Interprets code and outputs result.
options:
-h, --help show this help message and exit
-s, --shell run interpreter in shell mode. Directly enter input into the REPL to be interpreted
-f FILE run interpreter in file mode. Pass path to file to be interpreted
-t, --tokens outputs list of all tokens returned by lexer
-a, --ast outputs AST returned by parser
-g, --global outputs global symbol tables returned by interpreter, along with the result
-d, --duration outputs time it takes to interpret inputted program, along with the result
python_version >= '3.10'
:: real factorial := (real n) {
real i
real factorial
factorial := 1
i := 1
while:: i <= n {
factorial := factorial * i
i := i + 1
}
return:: factorial
}
real fac := factorial:5::
display:"result: " + getStr:fac::::
Can find more example files here.
Sources and tutorials I used to help with the development of this project:
Make Your Own Programming Language in Python - David Callanan
Let's Build A Simple Interpreter - Ruslan Spivak
A Simple Interpreter From Scratch In Python - Jay Conrad