programming language interpreter based on Reverse Polish Notation just for fun ;)
In RPNlang, there is no need to use horribles and ugly curly brackets or parentheses. Instead, you use the most beautiful syntax you can imagine: the reverse polish notation (RPN for the insiders).
You must download this repository:
git clone http https://github.com/Robotechnic/RPNlang.git
Then you can make the project:
cd RPNlang
mkdir build
cd build
mkdir RPNmodules
cmake ..
make -j$(nproc)
Exemples are better than words so, there are some just here waiting for your beautiful eyes:
Comments:
# comment a line
Display "5 + 6 = 11":
5 6 5 6 + f"{} + {} = {}" :print
Calculate first four pi decimal and display them:
3.0 8.0 60.0 / + 29.0 60.0 2 ^ / + 44.0 60.0 3 ^ / + :print
Boolean operators:
a b :and false :not c :and :or :print
will always output "true"
Conditions:
a b == if
"hello world" :print
else
"nope" :print
fi
Loops:
a 10 =
b 0 =
a b > while
"hello world" :print
b b 1 + =
elihw
i 0 10 1 for
"hello world" :print
rof
Functions:
hello a string -> none fun
a f"hello {a}" :print
nuf
pow float a int b -> float fun
b 0 == if
1 return
fi
result a =
i 0 b 1 for
b b a * =
rof
b return
nuf
divide nb float -> float fun
nb .5 / return
nuf
You can also define functions signatures to allow to pass them as function arguments:
# define a function signature
process int -> int funsig
# define a function that take a function as argument
map list[int] listToMap $process mapFunction -> list[int] fun
newList 0 list[int] =
0 newList :len 1 for
newList listToMap i get :mapFunction :append
rof
newList return
nuf
addOne int number -> int fun
number 1 + return
nuf
a 1 2 3 4 5 6 7 8 9 10 list[int] =
a addOne :map f"{}\n" :print
Functions call:
"yeye" :hello
Module import: By default, RPNlang modules are namespaced with the module name (or file name in case of custom module)
"math" import
math.pi :print
5 :math.sqrt :print
math.pi 2 / math.cos :print
But you can also import a module with a custom namespace:
"math" "mymath" importAs
mymath.pi :print
5 :mymath.sqrt :print
mymath.pi 2 / mymath.cos :print
Lists:
a 1 2 3 4 5 6 7 8 9 10 list[int] =
a 0 get f"{}\n" :print
a 9 get f"{}\n" :print
a 5 get 7 =
Structs:
"math" :import
Vector struct
x -> float
y -> float
tcurts
normalise Vector v -> none fun
len v->x 2 ^ v->y 2 ^ + :math.sqrt =
v->x v->x len / =
v->y v->y len / =
nuf
v 10 10 Vector =
v->x f"{}\n" :print
v->y f"{}\n" :print
More exemples here
This language use a stack to store the things that you type. Each time that you use a function or a math operator, the required arguments are poped from the stack, processed and the result is pushed back to the stack. After each line of instructions, the stack must contain no more than one element (it can be empty), else the program will crash. RPNlang is also a strongly typed language, each variable has a type (if you define a variable it will be implicitly typed). All the types can be implicitly casted to another if they are compatible (for instance, an integer can be converted to a float).
In this languages there are just a few language specific keywords, everithing else is a literal.
Keyword | Description |
---|---|
if |
If the condition is true, execute the block of instruction after it. Else skip it |
else |
If the previous condition is false, execute the block of instruction after it. |
fi |
End of an if/else block |
for |
Execute the block of instruction for each increment in a given range |
rof |
End of a for loop |
while |
Execute the block of instruction while the condition is true |
elihw |
End of a while loop |
fun |
Define a function |
nuf |
End of a function block |
try |
start of a try catch block |
catch |
start of catch block |
finally |
start of a finally block |
yrt |
end of try catch block |
import |
import the given module |
importAs |
import the given module and rename it |
There are a few types in this language:
Type | Description |
---|---|
int |
Integer number |
float |
Floating point number |
string |
String |
bool |
Boolean value |
function |
Function |
none |
Empty value |
list |
list of values |
struct |
Custom datatype that allow to agregate multiple values |