Skip to content

kennipj/wabbit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wabbit

A very simple progamming language from David Beazley's compiler course

func fib(n int) int {
    if n < 2 {
        return 1;
    } else {
        return fib(n-1) + fib(n-2);
    }
    return 0;
}

print fib(10);

This repo implements:

  • Lexer and Parser
  • Compiler via LLVM
  • Formatter
  • Type checker

How It Works

Source code moves through a sequence of independent AST passes before reaching native code:

Source
  │
  ├─ Tokenizer        — hand-written lexer; produces a flat token stream
  ├─ Brace checker    — validates balanced braces before parsing
  ├─ Parser           — recursive-descent; builds an untyped AST
  │
  ├─ AST validator    — checks structural invariants
  ├─ Type annotation  — decorates every node with its Wabbit type
  ├─ Type checker     — enforces type compatibility across the whole tree
  ├─ Constant folding — evaluates compile-time arithmetic (e.g. 2 * 3 → 6)
  ├─ Deinit           — removes redundant initializations
  ├─ Scope resolution — rewrites Name nodes to typed LocalName / GlobalName variants
  ├─ Unscript         — lifts top-level expressions into an implicit main function
  │
  ├─ LLVM IR emitter  — walks the simplified AST and emits .ll text
  └─ clang            — compiles .ll + runtime.c to a native binary

Error Messages

Errors point directly at the offending token with a source excerpt and caret underline.

Type mismatch in binary operation

var x int = 1.0 + true;
File "example.wb" line 1
  var x int = 1.0 + true;
              ^^^^^^^^^^^
WabbitTypeError: Operator + not supported for types "float" and "bool"

Return type mismatch

func square(n int) int {
    return 3.14;
}
File "example.wb" line 2
      return 3.14;
             ^^^^
WabbitTypeError: Expression of type "float" cannot be assigned to return type "int".

Undeclared variable

print foo;
File "example.wb" line 1
  print foo;
        ^^^
WabbitSyntaxError: Undeclared variable: `foo`.

break outside a loop

break;
File "example.wb" line 1
  break;
  ^^^^^
WabbitTypeError: "break" can only be used within a loop

Usage

Install dependencies:

poetry install

Run the compiler CLI:

poetry run wabbit [COMMAND] [OPTIONS] FILE

Commands

Command Description
tokenize <file> Print the token stream
ast <file> Print the AST (supports --validate, --typed, --fold, --type-check, --deinit, --resolve, --unscript)
source <file> Pretty-print formatted Wabbit source (--optimize to simplify first)
llvm <file> Emit LLVM IR (--output <file> to write to a file)
compile <file> <output> Compile to a native binary via clang

Example

poetry run wabbit compile examples/fib.wb fib
./wabbit/bin/fib

Development

poetry run task test        # run tests
poetry run task lint        # lint with ruff
poetry run task fmt         # format and auto-fix
poetry run task check_types # type-check with pyright

Requirements

  • Python 3.10+
  • clang (only required for the compile command)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors