import source_location, token type CallingConvention* = enum ccDefault ccWin64 IntrinsicKind* = enum ikLine ikColumn ikFile ikFunction ikDate ikTime ikModule UseKind* = enum ukSingle ukGlob ukMulti # --------------------------------------------------------------------------- # Type expressions # --------------------------------------------------------------------------- TypeExprKind* = enum tekNamed tekPath tekSlice tekPointer tekOwn ## own T — owned value (gradual ownership) tekRef ## &T — shared reference (gradual ownership) tekMutRef ## &mut T — mutable reference tekDynRef ## &dyn Trait — trait object (fat pointer) tekTuple tekSelf tekFunc TypeExpr* = ref object loc*: SourceLocation case kind*: TypeExprKind of tekNamed: typeName*: string typeArgs*: seq[TypeExpr] of tekPath: pathSegments*: seq[string] of tekSlice: sliceElement*: TypeExpr sliceSize*: Expr ## nil for unsized slices T[] of tekOwn, tekPointer, tekRef, tekMutRef: pointerPointee*: TypeExpr refLifetime*: string ## only meaningful for tekRef/tekMutRef of tekDynRef: dynInterface*: string of tekTuple: tupleElements*: seq[TypeExpr] of tekSelf: discard of tekFunc: funcParams*: seq[TypeExpr] funcRet*: TypeExpr # --------------------------------------------------------------------------- # Patterns # --------------------------------------------------------------------------- PatternKind* = enum pkWildcard pkLiteral pkIdent pkRange pkEnum pkStruct pkTuple pkGuarded Pattern* = ref object loc*: SourceLocation case kind*: PatternKind of pkWildcard: discard of pkLiteral: patLit*: Token of pkIdent: patIdent*: string of pkRange: patRangeLo*: Pattern patRangeHi*: Pattern patRangeInclusive*: bool of pkEnum: patEnumPath*: seq[string] patEnumArgs*: seq[Pattern] patEnumNamed*: seq[tuple[name: string, pattern: Pattern]] of pkStruct: patStructName*: string patStructFields*: seq[tuple[name: string, pattern: Pattern]] of pkTuple: patTupleElements*: seq[Pattern] of pkGuarded: patGuardedInner*: Pattern patGuardedExpr*: Expr # --------------------------------------------------------------------------- # Expressions # --------------------------------------------------------------------------- ExprKind* = enum ekLiteral ekIdent ekSelf ekPath ekSizeOf ekIntrinsic ekUnary ekPostfix ekBinary ekAssign ekTernary ekRange ekCall ekGenericCall ekIndex ekField ekStructInit ekSlice ekSpread ekTuple ekCast ekIs ekTry ekUnwrap ## expr! — unwrap or panic ekSpawn ## spawn expr — create a new task ekAwait ## expr.await — suspend until future resolves ekBorrow ## borrow &mut expr — explicit borrow expression ekBlock ekMatch ekStringInterp ekClosure MatchArm* = object loc*: SourceLocation pattern*: Pattern body*: Expr Expr* = ref object loc*: SourceLocation case kind*: ExprKind of ekLiteral: exprLit*: Token of ekIdent: exprIdent*: string of ekSelf: discard of ekPath: exprPath*: seq[string] of ekSizeOf: exprSizeOfType*: TypeExpr of ekIntrinsic: exprIntrinsic*: IntrinsicKind of ekUnary: exprUnaryOp*: TokenKind exprUnaryOperand*: Expr of ekPostfix: exprPostfixOp*: TokenKind exprPostfixOperand*: Expr of ekBinary: exprBinaryOp*: TokenKind exprBinaryLeft*: Expr exprBinaryRight*: Expr of ekAssign: exprAssignOp*: TokenKind exprAssignTarget*: Expr exprAssignValue*: Expr of ekTernary: exprTernaryCond*: Expr exprTernaryThen*: Expr exprTernaryElse*: Expr of ekRange: exprRangeLo*: Expr exprRangeHi*: Expr exprRangeInclusive*: bool of ekCall: exprCallCallee*: Expr exprCallArgs*: seq[Expr] exprCallArgNames*: seq[string] ## empty = positional, non-empty = named arg exprCallInferredTypeArgs*: seq[TypeExpr] ## filled by sema for inferred generic calls of ekGenericCall: exprGenericCallee*: string exprGenericTypeArgs*: seq[TypeExpr] of ekIndex: exprIndexObj*: Expr exprIndexIdx*: Expr exprIndexBoundsCheck*: bool of ekField: exprFieldObj*: Expr exprFieldName*: string of ekStructInit: exprStructInitName*: string exprStructInitTypeArgs*: seq[TypeExpr] exprStructInitFields*: seq[tuple[name: string, value: Expr]] of ekSlice: exprSliceElements*: seq[Expr] of ekSpread: exprSpreadOperand*: Expr of ekTuple: exprTupleElements*: seq[Expr] of ekCast: exprCastOperand*: Expr exprCastType*: TypeExpr of ekIs: exprIsOperand*: Expr exprIsType*: TypeExpr of ekTry: exprTryOperand*: Expr exprTryType*: TypeExpr # nil for Result?, or explicit target type of ekUnwrap: exprUnwrapOperand*: Expr of ekSpawn: exprSpawnCallee*: Expr exprSpawnArgs*: seq[Expr] exprSpawnAsync*: bool of ekAwait: exprAwaitOperand*: Expr of ekBorrow: exprBorrowOperand*: Expr exprBorrowMutable*: bool of ekBlock: exprBlock*: Block of ekMatch: exprMatchSubject*: Expr exprMatchArms*: seq[MatchArm] of ekStringInterp: exprInterpTexts*: seq[string] exprInterpExprs*: seq[Expr] of ekClosure: exprClosureParams*: seq[Param] exprClosureBody*: Block exprClosureReturnType*: TypeExpr captureCount*: int captureNames*: seq[string] captureTypeKinds*: seq[int] # --------------------------------------------------------------------------- # Statements # --------------------------------------------------------------------------- StmtKind* = enum skExpr skLet skIf skWhile skDoWhile skLoop skFor skMatch skReturn skBreak skContinue skStaticAssert skComptime skEmit skDefer skSwitch skDecl ElseIf* = object loc*: SourceLocation cond*: Expr blk*: Block SwitchCase* = object loc*: SourceLocation caseValue*: Expr caseBody*: Block Block* = ref object loc*: SourceLocation stmts*: seq[Stmt] Stmt* = ref object loc*: SourceLocation case kind*: StmtKind of skExpr: stmtExpr*: Expr of skLet: stmtLetMut*: bool stmtLetName*: string stmtLetPattern*: Pattern stmtLetType*: TypeExpr ## nil if inferred stmtLetInit*: Expr of skIf: stmtIfCond*: Expr stmtIfThen*: Block stmtIfElseIfs*: seq[ElseIf] stmtIfElse*: Block ## nil if no else of skWhile: stmtWhileLabel*: string stmtWhileCond*: Expr stmtWhileBody*: Block of skDoWhile: stmtDoWhileLabel*: string stmtDoWhileBody*: Block stmtDoWhileCond*: Expr of skLoop: stmtLoopLabel*: string stmtLoopBody*: Block of skFor: stmtForLabel*: string stmtForVar*: string stmtForIter*: Expr stmtForBody*: Block of skMatch: stmtMatchSubject*: Expr stmtMatchArms*: seq[MatchArm] of skReturn: stmtReturnValue*: Expr ## nil for bare return of skBreak: stmtBreakLabel*: string of skContinue: stmtContinueLabel*: string of skStaticAssert: stmtStaticAssertCond*: Expr stmtStaticAssertMsg*: Expr of skComptime: stmtComptimeBlock*: Block of skEmit: stmtEmitExpr*: Expr stmtEmitEvaluated*: string ## filled by sema CTFE of skDefer: stmtDeferBody*: Expr of skSwitch: stmtSwitchExpr*: Expr stmtSwitchCases*: seq[SwitchCase] stmtSwitchDefault*: Block of skDecl: stmtDecl*: Decl # --------------------------------------------------------------------------- # Type Parameters (for generics with trait bounds) # --------------------------------------------------------------------------- TypeParam* = object name*: string bounds*: seq[string] ## e.g. ["Comparable"] for isLifetime*: bool ## true for lifetime params like 'a # --------------------------------------------------------------------------- # Declarations # --------------------------------------------------------------------------- DeclKind* = enum dkFunc dkStruct dkEnum dkUnion dkInterface dkImpl dkModule dkUse dkConst dkTypeAlias dkExternFunc dkExternVar dkExternBlock Param* = object loc*: SourceLocation name*: string ptype*: TypeExpr isVariadic*: bool defaultValue*: Expr StructField* = object loc*: SourceLocation isPublic*: bool name*: string ftype*: TypeExpr EnumVariant* = object loc*: SourceLocation name*: string fields*: seq[TypeExpr] namedFields*: seq[tuple[name: string, ftype: TypeExpr]] discriminant*: string UnionField* = object loc*: SourceLocation name*: string ftype*: TypeExpr Decl* = ref object loc*: SourceLocation isPublic*: bool declAttrs*: seq[string] ## attributes: @[Checked], @[Inline], etc. case kind*: DeclKind of dkFunc: declFuncAsm*: bool declFuncCallConv*: CallingConvention declFuncConst*: bool ## const func — evaluable at compile time declFuncIsAsync*: bool ## async func — returns Future declFuncName*: string declFuncTypeParams*: seq[TypeParam] declFuncParams*: seq[Param] declFuncReturnType*: TypeExpr ## nil if void/inferred declFuncBody*: Block ## nil for signature-only of dkStruct: declStructName*: string declStructTypeParams*: seq[TypeParam] declStructFields*: seq[StructField] of dkEnum: declEnumName*: string declEnumBaseType*: TypeExpr declEnumVariants*: seq[EnumVariant] of dkUnion: declUnionName*: string declUnionFields*: seq[UnionField] of dkInterface: declInterfaceName*: string declInterfaceAssocTypes*: seq[string] ## associated type names: type Output; declInterfaceMethods*: seq[Decl] ## FuncDecl signatures only of dkImpl: declImplTypeName*: string declImplTypeParams*: seq[TypeParam] ## type parameters for generic impl: extend Box declImplInterface*: string ## empty if not for interface declImplAssocTypes*: seq[tuple[name: string, typ: TypeExpr]] ## type Output = int; declImplMethods*: seq[Decl] of dkModule: declModuleName*: string declModulePath*: seq[string] declModuleItems*: seq[Decl] of dkUse: declUsePath*: seq[string] declUseKind*: UseKind declUseNames*: seq[string] ## for multi-import declUseTargetOs*: string of dkConst: declConstName*: string declConstType*: TypeExpr declConstValue*: Expr of dkTypeAlias: declAliasName*: string declAliasType*: TypeExpr of dkExternFunc: declExtFuncName*: string declExtFuncDll*: string declExtFuncCallConv*: CallingConvention declExtFuncParams*: seq[Param] declExtFuncVariadic*: bool declExtFuncReturnType*: TypeExpr of dkExternVar: declExtVarName*: string declExtVarType*: TypeExpr of dkExternBlock: declExtBlockDll*: string declExtBlockCallConv*: CallingConvention declExtBlockItems*: seq[Decl] # --------------------------------------------------------------------------- # Module (AST root) # --------------------------------------------------------------------------- Module* = ref object name*: string path*: seq[string] items*: seq[Decl] # Convenience constructors proc newModule*(name: string, path: seq[string] = @[]): Module = result = Module(name: name, path: path) proc newBlock*(loc: SourceLocation): Block = result = Block(loc: loc) proc newLiteralExpr*(tok: Token): Expr = result = Expr(kind: ekLiteral, loc: tok.loc, exprLit: tok) proc newIdentExpr*(name: string, loc: SourceLocation): Expr = result = Expr(kind: ekIdent, loc: loc, exprIdent: name) proc newBinaryExpr*(op: TokenKind, left, right: Expr, loc: SourceLocation): Expr = result = Expr(kind: ekBinary, loc: loc, exprBinaryOp: op, exprBinaryLeft: left, exprBinaryRight: right) proc newUnaryExpr*(op: TokenKind, operand: Expr, loc: SourceLocation): Expr = result = Expr(kind: ekUnary, loc: loc, exprUnaryOp: op, exprUnaryOperand: operand) proc newStringInterpExpr*(texts: seq[string], exprs: seq[Expr], loc: SourceLocation): Expr = result = Expr(kind: ekStringInterp, loc: loc, exprInterpTexts: texts, exprInterpExprs: exprs)