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 hDefer # Memory hAlloca hLoad hStore hFieldPtr hFieldAccess 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 hDefer: deferBody*: HirNode of hAlloca: allocaType*: Type allocaName*: string of hLoad: loadPtr*: HirNode of hStore: storePtr*: HirNode storeValue*: HirNode of hFieldPtr: fieldPtrBase*: HirNode fieldName*: string of hFieldAccess: fieldAccessBase*: HirNode fieldAccessName*: 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 # Closure capture metadata captureNames*: seq[string] captureTypes*: seq[Type] envStructName*: string envInstanceName*: string 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 hirDefer*(body: HirNode, loc: SourceLocation): HirNode = HirNode(kind: hDefer, deferBody: body, 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 hirIf*(cond, thenBranch, elseBranch: HirNode, loc: SourceLocation): HirNode = HirNode(kind: hIf, ifCond: cond, ifThen: thenBranch, ifElse: elseBranch, typ: makeVoid(), 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 hirAssign*(target, value: HirNode, loc: SourceLocation): HirNode = HirNode(kind: hAssign, assignOp: tkAssign, assignTarget: target, assignValue: 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)