// ast.bux — AST node types (Expr, Stmt, Decl, Pattern, TypeExpr)
module Ast {

// ---------------------------------------------------------------------------
// SourceLocation (inline for convenience)
// ---------------------------------------------------------------------------
struct SourceLoc {
    line: uint32,
    column: uint32,
}

// ---------------------------------------------------------------------------
// Token (lightweight inline)
// ---------------------------------------------------------------------------
struct AstToken {
    kind: int,
    text: String,
    line: uint32,
    column: uint32,
}

// ---------------------------------------------------------------------------
// TypeExpr — type expressions
// ---------------------------------------------------------------------------
const tekNamed: int = 0;
const tekPath: int = 1;
const tekSlice: int = 2;
const tekPointer: int = 3;
const tekTuple: int = 4;
const tekSelf: int = 5;

struct TypeExpr {
    kind: int,
    line: uint32,
    column: uint32,
    typeName: String,        // for tekNamed
    pathStr: String,         // for tekPath (segments joined with ::)
    pathCount: int,          // number of path segments
    typeArgName0: String,    // up to 2 type args
    typeArgName1: String,
    typeArgCount: int,
    sliceElement: *TypeExpr, // for tekSlice
    pointerPointee: *TypeExpr, // for tekPointer
}

// ---------------------------------------------------------------------------
// Pattern — match patterns
// ---------------------------------------------------------------------------
const pkWildcard: int = 0;
const pkLiteral: int = 1;
const pkIdent: int = 2;
const pkRange: int = 3;
const pkEnum: int = 4;
const pkStruct: int = 5;
const pkTuple: int = 6;

struct Pattern {
    kind: int,
    line: uint32,
    column: uint32,
    patIdent: String,        // for pkIdent
    patLitKind: int,         // for pkLiteral (token kind)
    patLitText: String,      // for pkLiteral (token text)
    patRangeInclusive: bool, // for pkRange
    patEnumPath: String,     // for pkEnum (path joined)
    patStructName: String,   // for pkStruct
}

// ---------------------------------------------------------------------------
// Expr — expressions (tagged union)
// ---------------------------------------------------------------------------
const ekLiteral: int = 0;
const ekIdent: int = 1;
const ekSelf: int = 2;
const ekPath: int = 3;
const ekSizeOf: int = 4;
const ekUnary: int = 5;
const ekPostfix: int = 6;
const ekBinary: int = 7;
const ekAssign: int = 8;
const ekTernary: int = 9;
const ekRange: int = 10;
const ekCall: int = 11;
const ekGenericCall: int = 12;
const ekIndex: int = 13;
const ekField: int = 14;
const ekStructInit: int = 15;
const ekSlice: int = 16;
const ekTuple: int = 17;
const ekCast: int = 18;
const ekIs: int = 19;
const ekTry: int = 20;
const ekUnwrap: int = 23;
const ekBlock: int = 21;
const ekMatch: int = 22;
const ekSpawn: int = 24;
const ekAwait: int = 25;

struct ExprList {
    expr: *Expr,
    next: *ExprList,
}

struct Expr {
    kind: int,
    line: uint32,
    column: uint32,
    // Common fields
    strValue: String,        // ident name, path segments, field name, callee
    intValue: int,           // operator kind, intrinsic kind
    boolValue: bool,         // range inclusive
    tokKind: int,            // literal token kind
    tokText: String,         // literal token text
    // Children (up to 3 sub-expressions)
    child1: *Expr,           // left, operand, callee, cond, subject
    child2: *Expr,           // right, index, then, value
    child3: *Expr,           // else, third
    // Extra references
    refType: *TypeExpr,      // cast type, is type, sizeof type
    refBlock: *Block,        // for ekBlock
    // Generic call
    genericCallee: String,
    genericTypeArg0: String,
    genericTypeArg1: String,
    genericTypeArgCount: int,
    // Struct init fields
    structName: String,
    structFieldCount: int,
    // Call arguments (linked list for multi-arg support)
    callArgs: *ExprList,
    callArgCount: int,
}

// ---------------------------------------------------------------------------
// Block — sequence of statements
// ---------------------------------------------------------------------------
struct Block {
    line: uint32,
    column: uint32,
    stmtCount: int,
    firstStmt: *Stmt,
    lastStmt: *Stmt,
}

// ---------------------------------------------------------------------------
// Stmt — statements
// ---------------------------------------------------------------------------
const skExpr: int = 0;
const skLet: int = 1;
const skIf: int = 2;
const skWhile: int = 3;
const skDoWhile: int = 4;
const skLoop: int = 5;
const skFor: int = 6;
const skMatch: int = 7;
const skReturn: int = 8;
const skBreak: int = 9;
const skContinue: int = 10;
const skDecl: int = 11;

struct ElseIf {
    line: uint32;
    column: uint32;
    cond: *Expr;
    block: *Block;
}

struct Stmt {
    kind: int,
    line: uint32,
    column: uint32,
    // Common fields
    strValue: String,        // let name, pattern ident, label, for var
    boolValue: bool,         // let mutable
    // Children
    child1: *Expr,           // init expr, condition, iter expr, return value
    child2: *Expr,           // match subject
    child3: *Expr,           // extra
    refStmtType: *TypeExpr,  // let type annotation
    refStmtPattern: *Pattern,// let pattern
    refStmtDecl: *Decl,     // for skDecl
    refStmtBlock: *Block,    // then/body block
    refStmtElse: *Block,     // else block
    // Else-if chain
    elseIfCount: int,
    // Linked list
    nextStmt: *Stmt,
}

// ---------------------------------------------------------------------------
// Decl — declarations
// ---------------------------------------------------------------------------
const dkFunc: int = 0;
const dkStruct: int = 1;
const dkEnum: int = 2;
const dkUnion: int = 3;
const dkInterface: int = 4;
const dkImpl: int = 5;
const dkModule: int = 6;
const dkUse: int = 7;
const dkConst: int = 8;
const dkTypeAlias: int = 9;
const dkExternFunc: int = 10;
const dkExternVar: int = 11;

struct Param {
    line: uint32;
    column: uint32;
    name: String;
    refParamType: *TypeExpr;
    isVariadic: bool;
}

struct StructField {
    line: uint32;
    column: uint32;
    isPublic: bool;
    name: String;
    refFieldType: *TypeExpr;
}

struct EnumVariant {
    line: uint32;
    column: uint32;
    name: String;
    fieldCount: int;
    fieldTypeName0: String;
    fieldTypeName1: String;
}

struct Decl {
    kind: int,
    line: uint32,
    column: uint32,
    isPublic: bool,
    isAsync: bool,
    // Names
    strValue: String,        // decl name
    strValue2: String,       // interface name, dll name, module path
    // Type params (up to 2)
    typeParam0: String,
    typeParam1: String,
    typeParamCount: int,
    // Params (for functions)
    paramCount: int,
    param0: Param,
    param1: Param,
    param2: Param,
    param3: Param,
    param4: Param,
    param5: Param,
    param6: Param,
    param7: Param,
    param8: Param,
    retType: *TypeExpr,
    // Body
    refBody: *Block,
    // Enum variants (up to 8)
    variantCount: int,
    variant0: EnumVariant,
    variant1: EnumVariant,
    variant2: EnumVariant,
    variant3: EnumVariant,
    variant4: EnumVariant,
    variant5: EnumVariant,
    variant6: EnumVariant,
    variant7: EnumVariant,
    // Impl methods (up to 4)
    methodCount: int,
    // Use/import
    useKind: int,
    usePath: String,
    useNames: String,        // joined names for multi-import
    // Const
    constType: *TypeExpr,
    constValue: *Expr,
    // Type alias
    aliasType: *TypeExpr,
    // Extern func
    extFuncDll: String,
    extFuncVariadic: bool,
    extFuncRetType: *TypeExpr,
    // Children
    childDecl1: *Decl,       // linked list of decls (for module items, impl methods)
    childDecl2: *Decl,
    // Struct fields (up to 256)
    fieldCount: int,
    field0: StructField,
    field1: StructField,
    field2: StructField,
    field3: StructField,
    field4: StructField,
    field5: StructField,
    field6: StructField,
    field7: StructField,
    field8: StructField,
    field9: StructField,
    field10: StructField,
    field11: StructField,
    field12: StructField,
    field13: StructField,
    field14: StructField,
    field15: StructField,
    field16: StructField,
    field17: StructField,
    field18: StructField,
    field19: StructField,
    field20: StructField,
    field21: StructField,
    field22: StructField,
    field23: StructField,
    field24: StructField,
    field25: StructField,
    field26: StructField,
    field27: StructField,
    field28: StructField,
    field29: StructField,
    field30: StructField,
    field31: StructField,
    field32: StructField,
    field33: StructField,
    field34: StructField,
    field35: StructField,
    field36: StructField,
    field37: StructField,
    field38: StructField,
    field39: StructField,
    field40: StructField,
    field41: StructField,
    field42: StructField,
    field43: StructField,
    field44: StructField,
    field45: StructField,
    field46: StructField,
    field47: StructField,
    field48: StructField,
    field49: StructField,
    field50: StructField,
    field51: StructField,
    field52: StructField,
    field53: StructField,
    field54: StructField,
    field55: StructField,
    field56: StructField,
    field57: StructField,
    field58: StructField,
    field59: StructField,
    field60: StructField,
    field61: StructField,
    field62: StructField,
    field63: StructField,
    field64: StructField,
    field65: StructField,
    field66: StructField,
    field67: StructField,
    field68: StructField,
    field69: StructField,
    field70: StructField,
    field71: StructField,
    field72: StructField,
    field73: StructField,
    field74: StructField,
    field75: StructField,
    field76: StructField,
    field77: StructField,
    field78: StructField,
    field79: StructField,
    field80: StructField,
    field81: StructField,
    field82: StructField,
    field83: StructField,
    field84: StructField,
    field85: StructField,
    field86: StructField,
    field87: StructField,
    field88: StructField,
    field89: StructField,
    field90: StructField,
    field91: StructField,
    field92: StructField,
    field93: StructField,
    field94: StructField,
    field95: StructField,
    field96: StructField,
    field97: StructField,
    field98: StructField,
    field99: StructField,
    field100: StructField,
    field101: StructField,
    field102: StructField,
    field103: StructField,
    field104: StructField,
    field105: StructField,
    field106: StructField,
    field107: StructField,
    field108: StructField,
    field109: StructField,
    field110: StructField,
    field111: StructField,
    field112: StructField,
    field113: StructField,
    field114: StructField,
    field115: StructField,
    field116: StructField,
    field117: StructField,
    field118: StructField,
    field119: StructField,
    field120: StructField,
    field121: StructField,
    field122: StructField,
    field123: StructField,
    field124: StructField,
    field125: StructField,
    field126: StructField,
    field127: StructField,
    field128: StructField,
    field129: StructField,
    field130: StructField,
    field131: StructField,
    field132: StructField,
    field133: StructField,
    field134: StructField,
    field135: StructField,
    field136: StructField,
    field137: StructField,
    field138: StructField,
    field139: StructField,
    field140: StructField,
    field141: StructField,
    field142: StructField,
    field143: StructField,
    field144: StructField,
    field145: StructField,
    field146: StructField,
    field147: StructField,
    field148: StructField,
    field149: StructField,
    field150: StructField,
    field151: StructField,
    field152: StructField,
    field153: StructField,
    field154: StructField,
    field155: StructField,
    field156: StructField,
    field157: StructField,
    field158: StructField,
    field159: StructField,
    field160: StructField,
    field161: StructField,
    field162: StructField,
    field163: StructField,
    field164: StructField,
    field165: StructField,
    field166: StructField,
    field167: StructField,
    field168: StructField,
    field169: StructField,
    field170: StructField,
    field171: StructField,
    field172: StructField,
    field173: StructField,
    field174: StructField,
    field175: StructField,
    field176: StructField,
    field177: StructField,
    field178: StructField,
    field179: StructField,
    field180: StructField,
    field181: StructField,
    field182: StructField,
    field183: StructField,
    field184: StructField,
    field185: StructField,
    field186: StructField,
    field187: StructField,
    field188: StructField,
    field189: StructField,
    field190: StructField,
    field191: StructField,
    field192: StructField,
    field193: StructField,
    field194: StructField,
    field195: StructField,
    field196: StructField,
    field197: StructField,
    field198: StructField,
    field199: StructField,
    field200: StructField,
    field201: StructField,
    field202: StructField,
    field203: StructField,
    field204: StructField,
    field205: StructField,
    field206: StructField,
    field207: StructField,
    field208: StructField,
    field209: StructField,
    field210: StructField,
    field211: StructField,
    field212: StructField,
    field213: StructField,
    field214: StructField,
    field215: StructField,
    field216: StructField,
    field217: StructField,
    field218: StructField,
    field219: StructField,
    field220: StructField,
    field221: StructField,
    field222: StructField,
    field223: StructField,
    field224: StructField,
    field225: StructField,
    field226: StructField,
    field227: StructField,
    field228: StructField,
    field229: StructField,
    field230: StructField,
    field231: StructField,
    field232: StructField,
    field233: StructField,
    field234: StructField,
    field235: StructField,
    field236: StructField,
    field237: StructField,
    field238: StructField,
    field239: StructField,
    field240: StructField,
    field241: StructField,
    field242: StructField,
    field243: StructField,
    field244: StructField,
    field245: StructField,
    field246: StructField,
    field247: StructField,
    field248: StructField,
    field249: StructField,
    field250: StructField,
    field251: StructField,
    field252: StructField,
    field253: StructField,
    field254: StructField,
    field255: StructField,
}

// ---------------------------------------------------------------------------
// Module — AST root
// ---------------------------------------------------------------------------
struct Module {
    name: String,
    path: String,            // path segments joined
    itemCount: int,
    firstItem: *Decl,
}

// ---------------------------------------------------------------------------
// Constructor helpers
// ---------------------------------------------------------------------------

func Ast_MakeExpr(kind: int, line: uint32, col: uint32) -> Expr {
    return Expr { kind: kind, line: line, column: col,
        strValue: "", intValue: 0, boolValue: false,
        tokKind: 0, tokText: "",
        child1: null as *Expr, child2: null as *Expr, child3: null as *Expr,
        refType: null as *TypeExpr, refBlock: null as *Block,
        genericCallee: "", genericTypeArg0: "", genericTypeArg1: "", genericTypeArgCount: 0,
        structName: "", structFieldCount: 0,
        callArgs: null as *ExprList, callArgCount: 0 };
}

func Ast_MakeIdent(name: String, line: uint32, col: uint32) -> Expr {
    var e: Expr = Ast_MakeExpr(ekIdent, line, col);
    e.strValue = name;
    return e;
}

func Ast_MakeLiteral(tokKind: int, text: String, line: uint32, col: uint32) -> Expr {
    var e: Expr = Ast_MakeExpr(ekLiteral, line, col);
    e.tokKind = tokKind;
    e.tokText = text;
    return e;
}

func Ast_MakeBinary(op: int, left: *Expr, right: *Expr, line: uint32, col: uint32) -> Expr {
    var e: Expr = Ast_MakeExpr(ekBinary, line, col);
    e.intValue = op;
    e.child1 = left;
    e.child2 = right;
    return e;
}

func Ast_MakeCall(callee: *Expr, line: uint32, col: uint32) -> Expr {
    var e: Expr = Ast_MakeExpr(ekCall, line, col);
    e.child1 = callee;
    return e;
}

func Ast_MakeStmt(kind: int, line: uint32, col: uint32) -> Stmt {
    return Stmt { kind: kind, line: line, column: col,
        strValue: "", boolValue: false,
        child1: null as *Expr, child2: null as *Expr, child3: null as *Expr,
        refStmtType: null as *TypeExpr, refStmtPattern: null as *Pattern,
        refStmtDecl: null as *Decl, refStmtBlock: null as *Block, refStmtElse: null as *Block,
        elseIfCount: 0 };
}

func Ast_MakeDecl(kind: int, line: uint32, col: uint32) -> Decl {
    return Decl { kind: kind, line: line, column: col, isPublic: false,
        strValue: "", strValue2: "",
        typeParam0: "", typeParam1: "", typeParamCount: 0,
        paramCount: 0,
        retType: null as *TypeExpr,
        refBody: null as *Block,
        fieldCount: 0,
        variantCount: 0,
        methodCount: 0,
        useKind: 0, usePath: "", useNames: "",
        constType: null as *TypeExpr, constValue: null as *Expr,
        aliasType: null as *TypeExpr,
        extFuncDll: "", extFuncVariadic: false, extFuncRetType: null as *TypeExpr,
        childDecl1: null as *Decl, childDecl2: null as *Decl };
}
}
