import type { Syms } from "./resolver_syms.ts"; import { Pos } from "./token.ts"; import { GenericArgsMap, VType } from "./vtype.ts"; export type Mod = { filePath: string; ast: Stmt[]; }; export type Stmt = { kind: StmtKind; pos: Pos; id: number; }; export type StmtKind = | { type: "error" } | { type: "mod_block"; ident: string; stmts: Stmt[] } | { type: "mod_file"; ident: string; filePath: string } | { type: "mod"; ident: string; mod: Mod } | { type: "break"; expr?: Expr } | { type: "return"; expr?: Expr } | { type: "fn"; ident: string; genericParams?: GenericParam[]; params: Param[]; returnType?: EType; body: Expr; anno?: Anno; vtype?: VType; } | { type: "let"; param: Param; value: Expr } | { type: "assign"; assignType: AssignType; subject: Expr; value: Expr } | { type: "expr"; expr: Expr }; export type AssignType = "=" | "+=" | "-="; export type Expr = { kind: ExprKind; pos: Pos; vtype?: VType; id: number; }; export type ExprKind = | { type: "error" } | { type: "int"; value: number } | { type: "string"; value: string } | { type: "ident"; ident: string } | { type: "sym"; ident: string; sym: Sym; } | { type: "group"; expr: Expr } | { type: "field"; subject: Expr; ident: string } | { type: "index"; subject: Expr; value: Expr } | { type: "call"; subject: Expr; args: Expr[]; genericArgs?: GenericArgsMap; } | { type: "path"; subject: Expr; ident: string } | { type: "etype_args"; subject: Expr; etypeArgs: EType[] } | { type: "unary"; unaryType: UnaryType; subject: Expr } | { type: "binary"; binaryType: BinaryType; left: Expr; right: Expr } | { type: "if"; cond: Expr; truthy: Expr; falsy?: Expr; elsePos?: Pos } | { type: "bool"; value: boolean } | { type: "null" } | { type: "loop"; body: Expr } | { type: "block"; stmts: Stmt[]; expr?: Expr } | { type: "while"; cond: Expr; body: Expr } | { type: "for_in"; param: Param; value: Expr; body: Expr } | { type: "for"; decl?: Stmt; cond?: Expr; incr?: Stmt; body: Expr; }; export type UnaryType = "not" | "-"; export type BinaryType = | "+" | "*" | "==" | "-" | "/" | "!=" | "<" | ">" | "<=" | ">=" | "or" | "and"; export type Param = { ident: string; etype?: EType; pos: Pos; vtype?: VType; }; export type Sym = { ident: string; pos?: Pos; } & SymKind; export type SymKind = | { type: "let"; stmt: Stmt; param: Param } | { type: "let_static"; stmt: Stmt; param: Param } | { type: "fn"; stmt: Stmt } | { type: "fn_param"; param: Param } | { type: "closure"; inner: Sym } | { type: "generic"; stmt: Stmt; genericParam: GenericParam } | { type: "mod"; syms: Syms }; export type EType = { kind: ETypeKind; pos: Pos; id: number; }; export type ETypeKind = | { type: "error" } | { type: "null" } | { type: "int" } | { type: "bool" } | { type: "string" } | { type: "ident"; ident: string } | { type: "sym"; ident: string; sym: Sym; } | { type: "array"; inner: EType } | { type: "struct"; fields: Param[] }; export type GenericParam = { id: number; ident: string; pos: Pos; vtype?: VType; }; export type Anno = { ident: string; values: Expr[]; pos: Pos; }; export class AstCreator { private nextNodeId = 0; public stmt(kind: StmtKind, pos: Pos): Stmt { const id = this.nextNodeId; this.nextNodeId += 1; return { kind, pos, id }; } public expr(kind: ExprKind, pos: Pos): Expr { const id = this.nextNodeId; this.nextNodeId += 1; return { kind, pos, id }; } public etype(kind: ETypeKind, pos: Pos): EType { const id = this.nextNodeId; this.nextNodeId += 1; return { kind, pos, id }; } }