feat: lifetime elision, tooling CI, registry, and LSP locals
Ship the QUALITY_PLAN stretch from ownership through ecosystem: C.1 lifetime elision (bootstrap + selfhost), bux fmt/test/doc CI hooks, stdlib goldens, package registry (bux search/add), and LSP 0.4 position-sensitive locals with inferred let types. Full-tree format pass plus Map/Set remove double-free fix.
This commit is contained in:
+434
-433
@@ -1,437 +1,438 @@
|
||||
// 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 tekRef: int = 7; // &T — shared reference
|
||||
const tekMutRef: int = 8; // &mut T — mutable reference
|
||||
const tekTuple: int = 4;
|
||||
const tekSelf: int = 5;
|
||||
const tekFunc: int = 6;
|
||||
|
||||
struct TypeExprList {
|
||||
te: *TypeExpr,
|
||||
next: *TypeExprList,
|
||||
}
|
||||
|
||||
struct TypeExpr {
|
||||
kind: int,
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
typeName: String, // for tekNamed / diagnostic name for tekFunc
|
||||
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
|
||||
funcParams: *TypeExprList, // for tekFunc
|
||||
funcRet: *TypeExpr, // for tekFunc
|
||||
funcParamCount: int, // for tekFunc
|
||||
tupleElems: *TypeExprList, // for tekTuple
|
||||
tupleCount: int, // for tekTuple
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
const pkGuarded: int = 7; // `p if cond` — patChild1 = inner, patGuardExpr = condition
|
||||
|
||||
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: "Enum::Variant"
|
||||
patStructName: String, // for pkStruct (type name)
|
||||
patFieldName: String, // for struct field entry: field name in Point { x: a }
|
||||
patChild1: *Pattern, // range lo / nested / guarded inner
|
||||
patChild2: *Pattern, // range hi / nested
|
||||
patArgs: *Pattern, // pkEnum/pkTuple/pkStruct field list (head)
|
||||
patNext: *Pattern, // next sibling in patArgs list
|
||||
patGuardExpr: *Expr, // for pkGuarded: the `if` condition
|
||||
}
|
||||
|
||||
// Match arm: pattern => body
|
||||
struct MatchArm {
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
pattern: *Pattern,
|
||||
body: *Expr,
|
||||
next: *MatchArm,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
const ekStringInterp: int = 26;
|
||||
const ekClosure: int = 27;
|
||||
|
||||
struct ExprList {
|
||||
expr: *Expr,
|
||||
next: *ExprList,
|
||||
argName: String,
|
||||
}
|
||||
|
||||
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,
|
||||
// Closure params (for ekClosure)
|
||||
closureParams: *Decl,
|
||||
// Captures (for ekClosure)
|
||||
captureCount: int,
|
||||
captureName0: String,
|
||||
captureName1: String,
|
||||
captureName2: String,
|
||||
captureName3: String,
|
||||
captureName4: String,
|
||||
captureName5: String,
|
||||
captureName6: String,
|
||||
captureName7: String,
|
||||
captureType0: int,
|
||||
captureType1: int,
|
||||
captureType2: int,
|
||||
captureType3: int,
|
||||
captureType4: int,
|
||||
captureType5: int,
|
||||
captureType6: int,
|
||||
captureType7: int,
|
||||
// Call arguments (linked list for multi-arg support)
|
||||
callArgs: *ExprList,
|
||||
callArgCount: int,
|
||||
// Match arms (for ekMatch)
|
||||
matchArms: *MatchArm,
|
||||
matchArmCount: 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;
|
||||
const skDefer: int = 12;
|
||||
const skSwitch: int = 13;
|
||||
|
||||
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;
|
||||
defaultExpr: *Expr;
|
||||
}
|
||||
|
||||
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 {
|
||||
fieldCount: int,
|
||||
fields: *StructField,
|
||||
kind: int,
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
isPublic: bool,
|
||||
isAsync: bool,
|
||||
isChecked: int, // @[Checked] attribute (0/1)
|
||||
isDrop: int, // @[Drop] attribute (0/1)
|
||||
isRelease: int, // @[Release] attribute (0/1)
|
||||
isConst: int, // const func (0/1)
|
||||
// Names
|
||||
strValue: String, // decl name
|
||||
strValue2: String, // interface name, dll name, module path
|
||||
// Type params (up to 2)
|
||||
typeParam0: String,
|
||||
typeParam1: String,
|
||||
typeParamCount: int,
|
||||
// Trait bounds for type params (e.g. <T: Comparable>)
|
||||
typeParam0Bound: String,
|
||||
typeParam1Bound: String,
|
||||
// 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,
|
||||
variant8: 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)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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,
|
||||
isAsync: false, isChecked: 0, isDrop: 0, isRelease: 0, isConst: 0,
|
||||
strValue: "", strValue2: "",
|
||||
typeParam0: "", typeParam1: "", typeParamCount: 0,
|
||||
typeParam0Bound: "", typeParam1Bound: ""
|
||||
,
|
||||
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 };
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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 tekRef: int = 7; // &T — shared reference
|
||||
const tekMutRef: int = 8; // &mut T — mutable reference
|
||||
const tekTuple: int = 4;
|
||||
const tekSelf: int = 5;
|
||||
const tekFunc: int = 6;
|
||||
|
||||
struct TypeExprList {
|
||||
te: *TypeExpr,
|
||||
next: *TypeExprList,
|
||||
}
|
||||
|
||||
struct TypeExpr {
|
||||
kind: int,
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
typeName: String, // for tekNamed / diagnostic name for tekFunc
|
||||
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 / tekRef / tekMutRef
|
||||
refLifetime: String, // for tekRef / tekMutRef: "'a" or "" (elided)
|
||||
funcParams: *TypeExprList, // for tekFunc
|
||||
funcRet: *TypeExpr, // for tekFunc
|
||||
funcParamCount: int, // for tekFunc
|
||||
tupleElems: *TypeExprList, // for tekTuple
|
||||
tupleCount: int, // for tekTuple
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
const pkGuarded: int = 7; // `p if cond` — patChild1 = inner, patGuardExpr = condition
|
||||
|
||||
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: "Enum::Variant"
|
||||
patStructName: String, // for pkStruct (type name)
|
||||
patFieldName: String, // for struct field entry: field name in Point { x: a }
|
||||
patChild1: *Pattern, // range lo / nested / guarded inner
|
||||
patChild2: *Pattern, // range hi / nested
|
||||
patArgs: *Pattern, // pkEnum/pkTuple/pkStruct field list (head)
|
||||
patNext: *Pattern, // next sibling in patArgs list
|
||||
patGuardExpr: *Expr, // for pkGuarded: the `if` condition
|
||||
}
|
||||
|
||||
// Match arm: pattern => body
|
||||
struct MatchArm {
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
pattern: *Pattern,
|
||||
body: *Expr,
|
||||
next: *MatchArm,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
const ekStringInterp: int = 26;
|
||||
const ekClosure: int = 27;
|
||||
|
||||
struct ExprList {
|
||||
expr: *Expr,
|
||||
next: *ExprList,
|
||||
argName: String,
|
||||
}
|
||||
|
||||
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,
|
||||
// Closure params (for ekClosure)
|
||||
closureParams: *Decl,
|
||||
// Captures (for ekClosure)
|
||||
captureCount: int,
|
||||
captureName0: String,
|
||||
captureName1: String,
|
||||
captureName2: String,
|
||||
captureName3: String,
|
||||
captureName4: String,
|
||||
captureName5: String,
|
||||
captureName6: String,
|
||||
captureName7: String,
|
||||
captureType0: int,
|
||||
captureType1: int,
|
||||
captureType2: int,
|
||||
captureType3: int,
|
||||
captureType4: int,
|
||||
captureType5: int,
|
||||
captureType6: int,
|
||||
captureType7: int,
|
||||
// Call arguments (linked list for multi-arg support)
|
||||
callArgs: *ExprList,
|
||||
callArgCount: int,
|
||||
// Match arms (for ekMatch)
|
||||
matchArms: *MatchArm,
|
||||
matchArmCount: 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;
|
||||
const skDefer: int = 12;
|
||||
const skSwitch: int = 13;
|
||||
|
||||
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;
|
||||
defaultExpr: *Expr;
|
||||
}
|
||||
|
||||
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 {
|
||||
fieldCount: int,
|
||||
fields: *StructField,
|
||||
kind: int,
|
||||
line: uint32,
|
||||
column: uint32,
|
||||
isPublic: bool,
|
||||
isAsync: bool,
|
||||
isChecked: int, // @[Checked] attribute (0/1)
|
||||
isDrop: int, // @[Drop] attribute (0/1)
|
||||
isRelease: int, // @[Release] attribute (0/1)
|
||||
isConst: int, // const func (0/1)
|
||||
// Names
|
||||
strValue: String, // decl name
|
||||
strValue2: String, // interface name, dll name, module path
|
||||
// Type params (up to 2)
|
||||
typeParam0: String,
|
||||
typeParam1: String,
|
||||
typeParamCount: int,
|
||||
// Trait bounds for type params (e.g. <T: Comparable>)
|
||||
typeParam0Bound: String,
|
||||
typeParam1Bound: String,
|
||||
// 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,
|
||||
variant8: 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)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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,
|
||||
isAsync: false, isChecked: 0, isDrop: 0, isRelease: 0, isConst: 0,
|
||||
strValue: "", strValue2: "",
|
||||
typeParam0: "", typeParam1: "", typeParamCount: 0,
|
||||
typeParam0Bound: "", typeParam1Bound: ""
|
||||
,
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user