feat: restructure repo, borrow checker, expanded stdlib
- Reorganize repository to Rust-style layout: compiler/bootstrap/ compiler/selfhost/ compiler/tests/ library/std/ library/runtime/ tests/ tools/ - Add buxs/ Windows-compatible project root - Add borrow checker tests and implement: - Alias analysis (double mutable borrow detection) - Use-after-move detection for own T - Expand standard library: - Std::Os: Args, Env, Cwd, Chdir - Std::Time: NowMs, NowUs, SleepMs - Std::Process: Run, Output - Std::Io: PrintInt64 (fixes 32-bit truncation bug) - Add examples: os_time.bux, process.bux - Fix PrintInt to use int64_t in C runtime
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
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
|
||||
hArrowField
|
||||
hIndexPtr
|
||||
hSliceIndex
|
||||
# Functions
|
||||
hCall
|
||||
hCallIndirect
|
||||
# Type operations
|
||||
hCast
|
||||
hIs
|
||||
hSizeOf
|
||||
# Concurrency
|
||||
hSpawn
|
||||
# Compile-time code generation
|
||||
hEmit
|
||||
# Trait objects (dynamic dispatch)
|
||||
hDynRef
|
||||
hDynCall
|
||||
# Composite
|
||||
hBlock
|
||||
hStructInit
|
||||
hSliceInit
|
||||
hRange
|
||||
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 hArrowField:
|
||||
arrowFieldBase*: HirNode
|
||||
arrowFieldName*: 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 hSizeOf:
|
||||
sizeOfType*: Type
|
||||
of hSpawn:
|
||||
spawnCallee*: string
|
||||
spawnArgs*: seq[HirNode]
|
||||
spawnAsync*: bool
|
||||
of hEmit:
|
||||
emitCode*: string
|
||||
of hDynRef:
|
||||
dynRefData*: HirNode
|
||||
dynRefInterface*: string
|
||||
dynRefConcreteType*: string
|
||||
of hDynCall:
|
||||
dynCallReceiver*: HirNode
|
||||
dynCallMethod*: string
|
||||
dynCallArgs*: seq[HirNode]
|
||||
of hBlock:
|
||||
blockStmts*: seq[HirNode]
|
||||
blockExpr*: HirNode
|
||||
isScope*: bool
|
||||
of hStructInit:
|
||||
structInitName*: string
|
||||
structInitFields*: seq[tuple[name: string, value: HirNode]]
|
||||
of hSliceInit:
|
||||
sliceInitElements*: seq[HirNode]
|
||||
sliceInitLen*: int
|
||||
of hSliceIndex:
|
||||
sliceIndexBase*: HirNode
|
||||
sliceIndexIndex*: HirNode
|
||||
sliceIndexBoundsCheck*: bool
|
||||
of hRange:
|
||||
rangeLo*: HirNode
|
||||
rangeHi*: HirNode
|
||||
rangeInclusive*: bool
|
||||
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
|
||||
|
||||
HirEnumVariant* = object
|
||||
name*: string
|
||||
fields*: seq[Type] # Positional fields for algebraic enums
|
||||
namedFields*: seq[tuple[name: string, typ: Type]] # Named fields
|
||||
|
||||
HirModule* = object
|
||||
funcs*: seq[HirFunc]
|
||||
externFuncs*: seq[HirFunc] # Functions declared with extern (no body)
|
||||
structs*: seq[tuple[name: string, fields: seq[tuple[name: string, typ: Type]]]]
|
||||
enums*: seq[tuple[name: string, variants: seq[HirEnumVariant]]]
|
||||
consts*: seq[tuple[name: string, typ: Type, value: HirNode]]
|
||||
interfaces*: seq[tuple[name: string, hasAssocTypes: bool, methods: seq[tuple[name: string, params: seq[Type], ret: Type]]]]
|
||||
vtables*: seq[tuple[interfaceName: string, concreteType: string, methodNames: seq[string], hasAssocTypes: bool]]
|
||||
|
||||
# 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, isScope: bool = false): HirNode =
|
||||
HirNode(kind: hBlock, blockStmts: stmts, blockExpr: expr, typ: typ, loc: loc, isScope: isScope)
|
||||
|
||||
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)
|
||||
|
||||
proc hirEmit*(code: string, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hEmit, emitCode: code, typ: makeVoid(), loc: loc)
|
||||
|
||||
proc hirDynRef*(data: HirNode, interfaceName, concreteType: string, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hDynRef, dynRefData: data, dynRefInterface: interfaceName,
|
||||
dynRefConcreteType: concreteType, typ: makeDynRef(interfaceName), loc: loc)
|
||||
|
||||
proc hirDynCall*(receiver: HirNode, methodName: string, args: seq[HirNode], typ: Type, loc: SourceLocation): HirNode =
|
||||
HirNode(kind: hDynCall, dynCallReceiver: receiver, dynCallMethod: methodName,
|
||||
dynCallArgs: args, typ: typ, loc: loc)
|
||||
Reference in New Issue
Block a user