import type { Span } from "./lexer.js"; export type { Span }; // ---------- Type expressions ---------- export type TypeExpr = | { kind: "named"; name: string; args: TypeExpr[]; span: Span } | { kind: "optional"; inner: TypeExpr; span: Span } | { kind: "result"; inner: TypeExpr; span: Span } | { kind: "list"; elem: TypeExpr; span: Span } | { kind: "map"; key: TypeExpr; value: TypeExpr; span: Span } | { kind: "set"; elem: TypeExpr; span: Span } | { kind: "tuple"; items: TypeExpr[]; span: Span } | { kind: "fun"; params: { name: string; type: TypeExpr; span: Span }[]; ret: TypeExpr; span: Span }; // ---------- Patterns ---------- export type Pattern = | { kind: "ident"; name: string; span: Span } | { kind: "wild"; span: Span } | { kind: "literal"; value: string | number | boolean; lit: string; span: Span } | { kind: "some"; inner: Pattern; span: Span } | { kind: "none"; span: Span } | { kind: "ok"; inner: Pattern; span: Span } | { kind: "err"; inner: Pattern | null; span: Span } | { kind: "variant"; name: string; args: Pattern[] | null; span: Span } | { kind: "is"; type: TypeExpr; span: Span } | { kind: "tuple"; items: Pattern[]; span: Span } | { kind: "alt"; items: Pattern[]; span: Span }; // ---------- Expressions ---------- export type InterpPart = | { kind: "text"; text: string } | { kind: "expr"; expr: Expr }; export type Expr = | { kind: "int"; value: number; text: string; span: Span } | { kind: "float"; value: number; text: string; span: Span } | { kind: "string"; parts: InterpPart[]; span: Span } | { kind: "char"; value: string; span: Span } | { kind: "bool"; value: boolean; span: Span } | { kind: "undefined"; span: Span } | { kind: "ident"; name: string; span: Span } | { kind: "unary"; op: "-" | "not"; operand: Expr; span: Span } | { kind: "binary"; op: string; left: Expr; right: Expr; span: Span } | { kind: "is"; left: Expr; type: TypeExpr; span: Span } | { kind: "range"; start: Expr; end: Expr; inclusive: boolean; span: Span } | { kind: "assign"; op: string; target: Expr; value: Expr; span: Span } | { kind: "call"; callee: Expr; args: Expr[]; span: Span } | { kind: "index"; target: Expr; index: Expr; span: Span } | { kind: "member"; target: Expr; name: string; span: Span } | { kind: "optaccess"; target: Expr; name: string; span: Span } | { kind: "propagate"; target: Expr; span: Span } | { kind: "if"; cond: Expr; then: Block; else: Expr | Block | null; span: Span } | { kind: "match"; value: Expr; arms: MatchArm[]; span: Span } | { kind: "lambda"; params: Param[]; retType: TypeExpr | null; body: FunBody; async: boolean; span: Span } | { kind: "await"; target: Expr; span: Span } | { kind: "list"; items: Expr[]; span: Span } | { kind: "map"; entries: MapEntry[]; span: Span } | { kind: "tuple"; items: Expr[]; span: Span } | { kind: "struct"; name: string; entries: StructEntry[]; positional: boolean; span: Span } | { kind: "ok"; value: Expr | null; span: Span } | { kind: "err"; value: Expr; span: Span } | { kind: "raise"; value: Expr; span: Span } | { kind: "some"; value: Expr; span: Span } | { kind: "none"; span: Span }; export interface MapEntry { key: string; value: Expr; span: Span; } export interface StructEntry { name: string; value: Expr; span: Span; } export interface MatchArm { pattern: Pattern; body: Expr | Block; span: Span; } // ---------- Statements ---------- export type Block = { kind: "block"; stmts: Stmt[]; span: Span }; export type Stmt = | { kind: "let"; name: string; mut: boolean; type: TypeExpr | null; init: Expr | null; span: Span } | { kind: "expr"; expr: Expr; span: Span } | { kind: "return"; value: Expr | null; span: Span } | { kind: "raise"; value: Expr; span: Span } | { kind: "if"; cond: Expr; then: Block; else: Block | null; span: Span } | { kind: "iflet"; pattern: Pattern; value: Expr; then: Block; else: Block | null; span: Span } | { kind: "match"; value: Expr; arms: MatchArm[]; span: Span } | { kind: "for"; pattern: Pattern; iterable: Expr; body: Block; span: Span } | { kind: "while"; cond: Expr; body: Block; span: Span } | { kind: "try"; body: Block; catchVar: string; handler: Block; span: Span } | { kind: "with"; name: string; init: Expr; body: Block; span: Span }; // ---------- Declarations ---------- export interface Param { name: string; type: TypeExpr; span: Span; } export type FunBody = Block | { kind: "expr"; expr: Expr; span: Span }; export interface FunDecl { kind: "fun"; name: string; async: boolean; params: Param[]; retType: TypeExpr | null; body: FunBody; exported: boolean; span: Span; file: string; } export interface LetDecl { kind: "let"; name: string; mut: boolean; type: TypeExpr | null; init: Expr; exported: boolean; span: Span; file: string; } export interface StructField { name: string; type: TypeExpr; span: Span; } export interface StructDecl { kind: "struct"; name: string; fields: StructField[]; exported: boolean; span: Span; file: string; } export interface EnumDecl { kind: "enum"; name: string; variants: string[]; exported: boolean; span: Span; file: string; } export interface VariantDef { name: string; params: Param[] | null; span: Span; } export interface TypeDecl { kind: "type"; name: string; variants: VariantDef[]; exported: boolean; span: Span; file: string; } export interface ContractMethod { name: string; params: Param[]; retType: TypeExpr; span: Span; } export interface ContractDecl { kind: "contract"; name: string; typeParams: string[]; methods: ContractMethod[]; exported: boolean; span: Span; file: string; } export interface SchemaField { name: string; type: TypeExpr; constraints: { name: string; value: Expr; span: Span }[]; span: Span; } export interface SchemaDecl { kind: "schema"; name: string; fields: SchemaField[]; exported: boolean; span: Span; file: string; } export interface ClassField { name: string; mut: boolean; type: TypeExpr; init: Expr | null; exported: boolean; span: Span; } export interface ClassDecl { kind: "class"; name: string; fields: ClassField[]; methods: FunDecl[]; exported: boolean; span: Span; file: string; } export type Decl = | FunDecl | LetDecl | StructDecl | EnumDecl | TypeDecl | ContractDecl | SchemaDecl | ClassDecl; export interface ImportDecl { kind: "import"; module: ModuleRef; alias: string | null; names: { name: string; alias: string | null }[]; span: Span; file: string; } export type ModuleRef = | { kind: "std"; segments: string[]; span: Span } | { kind: "pkg"; name: string; span: Span } | { kind: "js"; name: string; span: Span } | { kind: "rel"; path: string; span: Span }; export interface TestDecl { kind: "test"; name: string; body: Block; span: Span; file: string; } export interface Program { kind: "program"; imports: ImportDecl[]; decls: Decl[]; tests: TestDecl[]; span: Span; file: string; }