Grim, a small interpreted and imperative language.
An identifier can start with [a-z_] and then can contain any character in [a-zA-Z0-9_].
Below a list of supported statements with their syntax.
A variable can be declared using let
keyword.
A variable name must be declared with [a-zA-Z], after it, it can contain any alphanumeric character.
A declared variable must be initialized, the type is currently inferred.
Some examples:
let a = 0;
let b = 120.0;
let c = true;
let d = c && !c;
let e = "Test";
Tip
Grim is locally scoped.
A block is defined by:
if
/if-else
,while
function call
A block can see every variable declared in the father blocks, father blocks cannot see locally declared variables.
Variables overshadowing is currently not supported.
A value is assigned simply with =
.
An example:
let a = 0;
a = 1;
If and if-else are supported.
An example:
let a = true;
let b = false;
if a || b {
b = true;
}
if a && !b {
b = false;
} else {
let c = 0.0;
}
While is supported.
An example:
let a = true;
let b = false;
while a || b {
b = true;
}
To print a variable, an expression or a string:
let a = "test";
print (a);
print ("Example");
If you want to go to a new line you can use printl
.
To input interactively a value in a variable:
let a = 0;
input(a);
A function is declared with the following syntax:
fn fun_name (arg1, arg2) -> { return arg1 + arg2; }
A function must end with an explicit return.
Calling a function without assigning the return value means that the value is discarded after call.
A function can be called simply by:
let a = 0;
let b = 1;
let c = fun_name(a, b);
fun_name(a, b);
Pass is only by value.
To view a precise management of types compatibility see expression_evaluator.rs.
In general the only casting that can happen is int -> float if, for instance, an int is summed with a float.
You need Rust and Cargo installed.
First you will have to build the project with:
cargo build
To run, while in the terminal:
cargo run -- path_to_grim_script
You can add features to the language:
- Define the tokens into
lexer.rs
, - Define the grammar rules (BNF grammar) using tokens into
grammar.lalrpop
, - Define the interpreter rules into
interpreter.rs
.
Eventually you may want to add more arithmetical/logic operators, to do so you have to edit expression_evaluator.rs
.
Future features:
- Lambda functions
- REPL
- Fancier error messages