Compiler(s) of Racket based on Jeremy Siek's "Teaching and Learning Compilers Incrementally"
Find a file
2025-11-16 11:28:49 +03:00
bin Tail recursion fixed 2025-10-26 13:40:09 +03:00
lib Temporary rearrangement (OCaml LSP sucks) 2025-11-16 11:28:49 +03:00
test More sources. Now with LISP flavor 2025-10-26 12:33:28 +03:00
.gitignore Added README and tested some function examples 2025-10-19 21:07:46 +03:00
.ocamlformat move files 2025-11-02 18:54:53 +03:00
CompilerCourse.opam Init 2025-08-29 23:36:59 +03:00
dune-project Init 2025-08-29 23:36:59 +03:00
LICENSE Initial commit 2025-08-29 23:33:46 +03:00
map.h Garbage collector implemented (not tested though) 2025-11-02 21:52:55 +03:00
README.md Temporary rearrangement (OCaml LSP sucks) 2025-11-16 11:28:49 +03:00
runtime.c Garbage collector implemented (not tested though) 2025-11-02 21:52:55 +03:00
set.h Garbage collector implemented (not tested though) 2025-11-02 21:52:55 +03:00

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.