feat: add HIR, C backend, and end-to-end compilation
- Phase 3: High-Level IR (HIR) with lowering from AST - Method call desugaring (obj.method() → Type_method(obj)) - if/else, while, loop, break, continue lowering - struct, enum, function lowering - 8 HIR tests passing - Phase 5A: C backend code generation - Type mapping (Bux types → C11 types) - Expression and statement emission - Struct, enum, function generation - C main() wrapper for Bux Main() - Runtime shim (stdlib/runtime.c) - bux_alloc, bux_free, bux_print, bux_panic - BuxString, BuxSlice types - Bounds checking, division by zero - Build integration - bux build: lex → parse → sema → HIR → C → cc - bux run: build + execute - bux clean: remove build directory - Parser fixes - Newline handling in struct, enum, extend, interface blocks - self keyword as expression and parameter name - Sema improvements - Method resolution (extend blocks) - Interface conformance checking - collectGlobals made public - All 70 tests passing (25 lexer + 16 parser + 21 sema + 8 HIR) - End-to-end: Bux programs compile to native ELF64 binaries
This commit is contained in:
+165
@@ -0,0 +1,165 @@
|
||||
import ast, types, token, source_location
|
||||
|
||||
type
|
||||
HirKind* = enum
|
||||
# Literals
|
||||
hLit
|
||||
hVar
|
||||
hSelf
|
||||
# Operations
|
||||
hUnary
|
||||
hBinary
|
||||
hAssign
|
||||
# Control flow
|
||||
hIf
|
||||
hWhile
|
||||
hLoop
|
||||
hBreak
|
||||
hContinue
|
||||
hReturn
|
||||
# Memory
|
||||
hAlloca
|
||||
hLoad
|
||||
hStore
|
||||
hFieldPtr
|
||||
hIndexPtr
|
||||
# Functions
|
||||
hCall
|
||||
hCallIndirect
|
||||
# Type operations
|
||||
hCast
|
||||
hIs
|
||||
# Composite
|
||||
hBlock
|
||||
hStructInit
|
||||
hSliceInit
|
||||
hTupleInit
|
||||
# Match (desugared to switch/branch later)
|
||||
hMatch
|
||||
|
||||
HirNode* = ref object
|
||||
loc*: SourceLocation
|
||||
typ*: Type
|
||||
case kind*: HirKind
|
||||
of hLit:
|
||||
litToken*: Token
|
||||
of hVar:
|
||||
varName*: string
|
||||
of hSelf:
|
||||
discard
|
||||
of hUnary:
|
||||
unaryOp*: TokenKind
|
||||
unaryOperand*: HirNode
|
||||
of hBinary:
|
||||
binaryOp*: TokenKind
|
||||
binaryLeft*: HirNode
|
||||
binaryRight*: HirNode
|
||||
of hAssign:
|
||||
assignOp*: TokenKind
|
||||
assignTarget*: HirNode
|
||||
assignValue*: HirNode
|
||||
of hIf:
|
||||
ifCond*: HirNode
|
||||
ifThen*: HirNode
|
||||
ifElse*: HirNode
|
||||
of hWhile:
|
||||
whileCond*: HirNode
|
||||
whileBody*: HirNode
|
||||
of hLoop:
|
||||
loopBody*: HirNode
|
||||
of hBreak:
|
||||
breakLabel*: string
|
||||
of hContinue:
|
||||
continueLabel*: string
|
||||
of hReturn:
|
||||
returnValue*: HirNode
|
||||
of hAlloca:
|
||||
allocaType*: Type
|
||||
allocaName*: string
|
||||
of hLoad:
|
||||
loadPtr*: HirNode
|
||||
of hStore:
|
||||
storePtr*: HirNode
|
||||
storeValue*: HirNode
|
||||
of hFieldPtr:
|
||||
fieldPtrBase*: HirNode
|
||||
fieldName*: string
|
||||
of hIndexPtr:
|
||||
indexPtrBase*: HirNode
|
||||
indexPtrIndex*: HirNode
|
||||
of hCall:
|
||||
callCallee*: string
|
||||
callArgs*: seq[HirNode]
|
||||
of hCallIndirect:
|
||||
callIndirectCallee*: HirNode
|
||||
callIndirectArgs*: seq[HirNode]
|
||||
of hCast:
|
||||
castOperand*: HirNode
|
||||
castType*: Type
|
||||
of hIs:
|
||||
isOperand*: HirNode
|
||||
isType*: Type
|
||||
of hBlock:
|
||||
blockStmts*: seq[HirNode]
|
||||
blockExpr*: HirNode
|
||||
of hStructInit:
|
||||
structInitName*: string
|
||||
structInitFields*: seq[tuple[name: string, value: HirNode]]
|
||||
of hSliceInit:
|
||||
sliceInitElements*: seq[HirNode]
|
||||
of hTupleInit:
|
||||
tupleInitElements*: seq[HirNode]
|
||||
of hMatch:
|
||||
matchSubject*: HirNode
|
||||
matchArms*: seq[HirMatchArm]
|
||||
|
||||
HirMatchArm* = object
|
||||
pattern*: Pattern
|
||||
body*: HirNode
|
||||
|
||||
HirFunc* = object
|
||||
name*: string
|
||||
params*: seq[tuple[name: string, typ: Type]]
|
||||
retType*: Type
|
||||
body*: HirNode
|
||||
isPublic*: bool
|
||||
|
||||
HirModule* = object
|
||||
funcs*: seq[HirFunc]
|
||||
structs*: seq[tuple[name: string, fields: seq[tuple[name: string, typ: Type]]]]
|
||||
enums*: seq[tuple[name: string, variants: seq[string]]]
|
||||
consts*: seq[tuple[name: string, typ: Type, value: HirNode]]
|
||||
|
||||
# Constructor helpers
|
||||
proc hirLit*(tok: Token, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hLit, litToken: tok, typ: typ, loc: loc)
|
||||
|
||||
proc hirVar*(name: string, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hVar, varName: name, typ: typ, loc: loc)
|
||||
|
||||
proc hirSelf*(typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hSelf, typ: typ, loc: loc)
|
||||
|
||||
proc hirUnary*(op: TokenKind, operand: HirNode, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hUnary, unaryOp: op, unaryOperand: operand, typ: typ, loc: loc)
|
||||
|
||||
proc hirBinary*(op: TokenKind, left, right: HirNode, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hBinary, binaryOp: op, binaryLeft: left, binaryRight: right, typ: typ, loc: loc)
|
||||
|
||||
proc hirCall*(callee: string, args: seq[HirNode], typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hCall, callCallee: callee, callArgs: args, typ: typ, loc: loc)
|
||||
|
||||
proc hirReturn*(value: HirNode, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hReturn, returnValue: value, typ: makeVoid(), loc: loc)
|
||||
|
||||
proc hirBlock*(stmts: seq[HirNode], expr: HirNode, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hBlock, blockStmts: stmts, blockExpr: expr, typ: typ, loc: loc)
|
||||
|
||||
proc hirAlloca*(name: string, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hAlloca, allocaType: typ, allocaName: name, typ: makePointer(typ), loc: loc)
|
||||
|
||||
proc hirStore*(ptrNode, value: HirNode, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hStore, storePtr: ptrNode, storeValue: value, typ: makeVoid(), loc: loc)
|
||||
|
||||
proc hirLoad*(ptrNode: HirNode, typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hLoad, loadPtr: ptrNode, typ: typ, loc: loc)
|
||||
Reference in New Issue
Block a user