| bin | ||
| lib | ||
| test | ||
| .gitignore | ||
| .ocamlformat | ||
| CompilerCourse.opam | ||
| dune-project | ||
| LICENSE | ||
| map.h | ||
| README.md | ||
| runtime.c | ||
| set.h | ||
Compiler course language
This repo contains compiler, that supports (should support) several syntaxes. Right now Lama syntax is implemented.
Lama syntax
Types
Type is either:
<name>
<type> * <type> * ... * <type>
()
(<type>)
<type> -> <type> -> ... -> <type>
Tuple type has more priority over function. Stars work simultaneously (a * b * c != a * (b * c)), arrows are right-associative
You can define your own types with type keyword:
type <name> = <type>
Types with different names but same signatures are same types.
Functions
Function declaration should have function name, parameter names with types, function type and body.
define <name> (<name> : <type>) (<name> : <type>) <...> : <type> = <expr>
Sample:
define fib2 (n : int) (a : int) (b : int) : int =
if n <= 1 then
b
else
fib2 (n - 1) b (a + b)
define main : int =
let x = read in
print_int x;
print_int (fib2 x 1 1);
0
Expression can be either:
- literal (integer or Boolean constant (true/false))
- variable/parameter
- application (as in Metalanguage)
- operator application (only binary operators are supported now);
- sequence of expressions divided by semicolon (any sequence or operator has more priority than let-binding or branching, but less than application)
- tuple of values divided by commas. Commas have more priority than sequence,
and also work simultaneously (
a, b, c!=a, (b, c)) - conditional branching if then else
- variable creation:
let <name> = <expr> in <expr> - parentheses with expression inside
- empty parentheses
Operators
Built-in operators are: Priority 1: * / Priority 2: + - Priority 3: < > <= >= Priority 4: == != Priority 5: && and Priority 6: || or Priority 7: ^ xor
You can define your own operators with defop
defop <operator> <left | right> <level : int>
(<lhs_name> : <lhs_type>)
(<rhs_name> : <rhs_type>)
: <result_type>
= <expression>
Interpretation
Unit type generated by built-in functions is zero in assembly. If main function returns unit, exit code is zero. If main function returns integer, exit code is returned integer.