Compiler (LLVM frontend) for very minimal C-like language. Compiles to LLVM IR.
<statement_list> | "{" { <statement> } "}"
<statement> ::= <assignment> ";"
| <func_call> ";"
| <return> ";"
| <conditional>
| <for_loop>
| <var_declaration> ";"
| ";"
<return> ::= "return" [<expression>]
<conditional> ::= "if" "(" <expression> ")" <statement_list> ["else" <statement_list>]
<for_loop> ::= "for" "(" [<assignment>] ";" [<expression>] ";" [<assignment>] ")" <statement_list>
<assignment> ::= identifier "=" <expression>
<func_call> ::= identifier <expression_list>
<expression_list> ::= "(" { <expression> "," } <expression> ")"
| "()"
<expression> ::= <expr_no_comp> [("=="|"!="|"<"|"<="|">"|">=") <expr_no_comp>]
<expr_no_comp> ::= ["+"|"-"] <term> { ("+"|"-") <term> }
<term> ::= <factor> { ("*"|"/") <factor> }
<factor> ::= identifier
| number
| <func_call>
| "(" <expression> ")"
<var_declaration> ::= <type> identifier
// (no unsigned integers for now)
<type> ::= { "ptr" } ("i8"|"i16"|"i32"|"i64")
<func_param_list> ::= "(" { <type> identifier "," } <type> identifier ")"
| "()"
<func_definition> ::= (<type> | "void") identifier <func_param_list> <statement_list>
<global_decl_def> ::= <func_declaration>
// | <global_variable>
<master_list> ::= { <global_decl_def }
Didn't bother with inheritance (AST node is just a list of children).
STATEMENT: ONE CHILD ONLY:ASSIGN,FUNC_CALL,RETURNorCONDITIONALEXPRESSION: IF COMPARISON, (EXPR_NO_COMP, comparator,EXPR_NO_COMP), IF NOT, (EXPR_NO_COMP).EXPR_NO_COMP:TERM, plus/minus,TERM, plus/minus,TERM, etc etc.TERM:FACTOR, star/slash,FACTOR, star/slash,FACTOR, etc etc.FACTOR: identifier, number orEXPRESSION.ASSIGN: identifier,EXPRESSION.FUNC_CALL: identifier,EXPR_LISTIN ALL CASES, IF PARAMS ARE VOID THENEXPR_LISTLENGTH 0.EXPR_LIST: list ofEXPRESSION. LENGTH 0 IF PARAMS ARE VOID.CONDITIONAL:EXPRESSION,STMT_LIST, (IF NO ELSE, NO MORE, IF THERE IS ELSE:EXPRESSION).FOR:ASSIGNMENT(initial),CONDITIONAL(termination condition),ASSIGNMENT(every cycle),STMT_LISTALWAYS HAS 4 CHILDREN, CHILDREN HAVE NO CHILDREN IF LEFT EMPTY.CONTINUE/BREAK: no childrenVAR_DECLARATION: type, identifierFUNC_PARAM_LIST: type, identifier, type, identifier, etcFUNC_DEFINITION: (type OR "void"), identifier,FUNC_PARAM_LIST,STMT_LIST
- Numerical literals are 64 bit by default, need to be casted explicitly
- Assumes 64-bit architecture (pointer arithmetic is 64 bit)
- No void pointers
- Comparisons must be between two variables of the same type, returns an integer of that type
- Variable declared in for loop (
for (i = 0; ...)) not removed after loop
- https://www.owenstephens.co.uk/blog/2018/09/25/getting-started-with-the-newer-llvm-c-api.html
- https://pauladamsmith.com/blog/2015/01/how-to-get-started-with-llvm-c-api.html
- https://llvm.org/docs/tutorial/
- https://github.com/benbjohnson/llvm-c-kaleidoscope (very useful)
- https://www.javaadvent.com/2025/12/java-hello-world-llvm-edition.html