Jadon's Compiler Project

This is my compiler project. It is opened sourced on GitHub & licensed under MPL 2. ANTLR is used for lexing and parsing the language.


What works?

Global variables, Functions, Classes, Methods, Automatic Memory Management, Type Inference, Calling External Functions, Modules, etc. An example file below shows some of these features.


import io

@extern rand() : Int32 0

let initialAccountId = 7 + 11

class Account
    var id : Int32

    setId(i : Int32)
        id = i,
        id
;

incrementId(a : Account, amount : Int32)
    a.id = a.id + amount

main ()
    let account = new Account(),
    let i = account.setId(initialAccountId),
    printInt(i),
    incrementId(account, rand()),
    printInt(account.id),
    0
    

This example, when put through the LLVM backend, will produce LLVM IR and an executable.


%Account = type { i32 }

declare i32 @rand()

@initialAccountId = constant i32 18

define i32 @Account_setId(%Account*, i32) {
entry:
  %id = getelementptr inbounds %Account, %Account* %0, i64 0, i32 0
  store i32 %1, i32* %id, align 4
  ret i32 %1
}

define void @incrementId(%Account*, i32) {
entry:
  %a = getelementptr inbounds %Account, %Account* %0, i64 0, i32 0
  %a.id = load i32, i32* %a, align 4
  %"(a.id + amount)" = add i32 %a.id, %1
  store i32 %"(a.id + amount)", i32* %a, align 4
  ret void
}

define i32 @real_main() {
entry:
  %"malloc(4)" = call i8* @malloc(i64 4)
  %castToAccount = bitcast i8* %"malloc(4)" to %Account*
  %"account.setId(initialAccountId)" = call i32 @Account_setId(%Account* %castToAccount, i32 18)
  %"printInt(i)" = call i32 @printInt(i32 %"account.setId(initialAccountId)")
  %"rand()" = call i32 @rand()
  call void @incrementId(%Account* %castToAccount, i32 %"rand()")
  %account = bitcast i8* %"malloc(4)" to i32*
  %account.id = load i32, i32* %account, align 4
  %"printInt(account.id)" = call i32 @printInt(i32 %account.id)
  call void @free(i8* %"malloc(4)")
  ret i32 0
}