export type Block = { id: number; lineEntry: number; lineExit: number; stmts: Stmt[]; }; export type Stmt = { id: number; line: number; kind: StmtKind; }; export type StmtKind = | { tag: "error" } | { tag: "fn" } & FnStmt | { tag: "let" } & LetStmt | { tag: "loop"; body: Block } | { tag: "while"; expr: Expr; body: Block } | { tag: "if"; expr: Expr; truthy: Block; falsy?: Block } | { tag: "return"; expr?: Expr } | { tag: "break" } | { tag: "assign"; subject: Expr; expr: Expr } | { tag: "expr"; expr: Expr }; export type FnStmt = { ident: string; attrs: Attr[]; params: Param[]; returnTy: Ty; body: Block; }; export type LetStmt = { ident: string; ty?: Ty; expr?: Expr; }; export type Param = { ident: string; line: number; ty: Ty; }; export type Expr = { id: number; line: number; kind: ExprKind; }; export type ExprKind = | { tag: "error" } | { tag: "ident"; ident: string } | { tag: "int"; val: number } | { tag: "str"; val: string } | { tag: "call"; expr: Expr; args: Expr[] } | { tag: "not"; expr: Expr } | { tag: "negate"; expr: Expr } | { tag: "binary"; op: BinaryOp; left: Expr; right: Expr }; export type BinaryOp = | "or" | "xor" | "and" | "<" | ">" | "<=" | ">=" | "==" | "!=" | "+" | "-" | "*" | "/" | "%"; export type Ty = { id: number; line: number; kind: TyKind; }; export type TyKind = | { tag: "error" } | { tag: "void" } | { tag: "ident"; ident: string } | { tag: "ptr"; ty: Ty }; export type Attr = { ident: string; args: Expr[]; };