racheljn / ael-ohm

A compiler for Ael using Ohm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Logo

Ael

This is a compiler for the language Ael written with the help of the amazing Ohm language library.

Ael stands for (A)rithmetic (E)xpression (L)anguage. It’s the language of arithmetic expressions with +, -, *, /, abs, sqrt, and parentheses, together with declarations, assignments, and print statements. The language wants to be just simple enough for the compiler writer to (1) experience the difference between statements and expressions, (2) have something to do during semantic analysis, and (3) provide a handful of optimization opportunities.

In the spirit of an introductory tutorial, this compiler features multiple backends: it can generate JavaScript, C, and LLVM. Why not a real assembly language? It’s fair to say LLVM these days takes things plenty far enough along for an introductory example. One can learn about register allocation and hardware-specific optimizations elsewhere.

Sample Program

Here is a sample program in the language:

let x = 3 * 9
let y = 793 + (2 / abs 80 + x) * x
print 8 * x - (-y)
x = y
print y / sqrt 3

Grammar

Here is the grammar in Ohm notation:

Ael {
  Program   = Statement+
  Statement = let id "=" Exp                  --declare
            | id "=" Exp                      --assign
            | print Exp                       --print
  Exp       = Exp ("+" | "-") Term            --binary
            | Term
  Term      = Term ("*"| "/") Factor          --binary
            | Factor
  Factor    = id
            | num
            | "(" Exp ")"                     --parens
            | ("-" | abs | sqrt) Factor       --unary
  num       = digit+ ("." digit+)?
  let       = "let" ~alnum
  print     = "print" ~alnum
  abs       = "abs" ~alnum
  sqrt      = "sqrt" ~alnum
  keyword   = let | print | abs | sqrt
  id        = ~keyword letter alnum*
  space    += "//" (~"\n" any)* ("\n" | end)  --comment
}

Running

The compiler is written in modern JavaScript.

Because this application was written as a tutorial, the compiler exposes what each phase does, as well as providing multiple translations:

src/aelc.js <filename> <outputType>

The output type argument tells the compiler what to print to standard output:

  • ast    the abstract syntax tree
  • analyzed    the semantically analyzed representation
  • optimized    the optimized semantically analyzed representation
  • js    the translation to JavaScript
  • c    the translation to C
  • llvm    the translation to LLVM

To keep things simple, the compiler will halt on the first error it finds.

Contributing

I’m happy to take PRs. As usual, be nice when filing issues and contributing. Do remember the idea is to keep the language tiny; if you’d like to extend the language, you’re probably better forking into a new project. However, I would love to see any improvements you might have for the implementation or the pedagogy.

To contribute, make sure you have a modern version of Node.js, since the code has some ES2020 features. Clone the repo and run npm install as usual.

You can run tests with:

npm test

This project is so small that npm test is configured to always run a coverage report. I used mocha for the test runner and c8 for the coverage.

About

A compiler for Ael using Ohm

License:MIT License


Languages

Language:JavaScript 100.0%