Skip to content

mateeeeeee/Ola

Repository files navigation

Ola is a toy programming language with both LLVM backend and a work-in-progress custom backend.

Dependencies

  • LLVM 17.0 for LLVM backend (optional)
    • Note: You can disable the LLVM backend even though you might have LLVM 17.0 installed by generating project with ENABLE_LLVM=OFF:
      cmake -DENABLE_LLVM=OFF -B build

Features

  • classes
    • access modifiers: public, private
    • constructors
    • single inheritance: :
    • polymorphism using vtables: virtual, pure, final
    • this and super keywords
  • reference type: ref
  • automatic type deduction: auto
  • operators:
    • additive: +, -, +=, -=, ++, --
    • multiplicative: *, /, %, *=, /=, %=
    • relation: ==, !=, >, >=, <, <=
    • shift: >>, <<, >>=, <<=
    • bitwise: &, |, ^, ~, &=, |=, ^=
    • logic: &&, ||, !
  • control statements: if else, switch, goto, ?:
  • loop statements: for,foreach, while, do while, break, continue
  • enums
  • functions
    • overloading
    • attributes: inline, noinline, nomangling (equivalent to C++'s extern "C")
  • arrays
  • misc: alias, sizeof, length operators, strings, floats, implicit casts, scopes, import
  • LLVM Backend
  • Custom Backend (Work in Progress)

Structure

The project consists of the following parts:

  1. Ola Library:

    • A standard library for the Ola language, implemented in C and built as a static library to be used by the compiler. It includes essential components like:
      • olaio.h, olamath.h, olaassert.h, olastring.h, olamemory.h
  2. Ola Compiler:

    • The core of the Ola project, implemented as a static library (OlaCompiler) with the following components:
      • Lexer: Tokenizes the source code.
      • Import Processor: Processes import statements from the tokenized input.
      • Parser: A recursive descent parser that constructs an Abstract Syntax Tree (AST) from processed tokens.
      • Sema: Performs semantic analysis on the AST to ensure code correctness.
      • Backend: After frontend processing, the compilation process diverges into two backend paths:
        • LLVM:
          • LLVMIR Visitor: Transforms the AST into LLVM IR.
          • LLVMIR Pass Manager: Applies LLVM optimization passes to the IR.
          • Compilation to assembly is done using the clang -S command.
        • Custom Backend:
          • IR Visitor: Transforms the AST into Ola's custom IR.
          • IR Pass Manager: Applies custom optimizations at the IR level.
          • MachineModule: Responsible for lowering IR to MIR and finally to assembly.
  3. Ola Driver:

    • An executable (OlaDriver) that serves as the main entry point for compiling Ola code. It links to the OlaCompiler library and calls compiler's API.
  4. Ola Playground:

    • A separate executable that links to the OlaCompiler static library. It provides a development environment for experimenting with the compiler and Ola code, without directly invoking the OlaDriver.
  5. Ola Tests:

    • A set of unit tests built with GoogleTest, covering Ola language features. These tests are organized into two main folders:
      • LLVM Tests: Unit tests that use the LLVM backend of the compiler.
      • Custom Backend Tests: Unit tests that use the custom backend.
      • The tests rely on the Assert function from the std.assert import.
      • OlaDriver executable is used in the tests via system calls, allowing the tests to invoke the compiled executable to verify correct behavior.

Usage

Command line options

  • --ast: Dump AST to output/log
  • --cfg: Dump CFGs to .dot files and visualize them
  • --callgraph: Dump Call Graphs to .dot files and visualize them
  • --domtree: Dump Dominator Trees to .dot files and visualize them
  • --emit-ir: Emit (i.e. don't delete) IR file
  • --emit-asm: Emit (i.e. don't delete) ASM file
  • --domfrontier: Print dominance frontiers to standard output
  • --nollvm: Use custom backend instead of LLVM backend
  • --test: Used for running g-tests
  • --timeout: Used for detecting infinite loops during tests
  • --Od: No optimizations
  • --O0: Same as --Od
  • --O1: Optimize
  • --O2: Optimize more
  • --O3: Optimize even more
  • -i ... : Input files
  • -o : Output file
  • --directory: Directory of input files

Visualizations

private int min(int a, int b) 
{
    int c;
    if (a < b) 
    {
        c = a;
    } 
    else
    {
        c = b;
    }
    return c;
}

public int main()
{
    return min(3,4);
}

CFG

LLVM backend

Without optimizations

CFG without optimizations in LLVM backend

With optimizations

CFG with optimizations in LLVM backend

Custom backend

Without optimizations

CFG without optimizations in custom backend

With optimizations

CFG with optimizations in custom backend

Dominator Tree

LLVM backend

Without optimizations

Dominator tree without optimizations in LLVM backend

With optimizations

Dominator tree with optimizations in LLVM backend

Custom backend

With and without optimizations

Dominator tree in custom backend

Samples

Currently to see the samples you can check the test folder: OlaTests/Tests/.