slige-mirror/compiler/middle/hir.ts
2025-01-28 15:15:30 +01:00

279 lines
6.3 KiB
TypeScript

import { Span } from "../diagnostics.ts";
export type StmtId = { key: number; readonly unique: unique symbol };
export type Stmt = {
kind: StmtKind;
span: Span;
};
export type StmtKind =
| { tag: "error" }
| { tag: "item" } & ItemStmt
| { tag: "let" } & LetStmt
| { tag: "return" } & ReturnStmt
| { tag: "break" } & BreakStmt
| { tag: "continue" }
| { tag: "assign" } & AssignStmt
| { tag: "expr" } & ExprStmt;
export type ItemStmt = { item: ItemId };
export type LetStmt = {
pat: PatId;
ty?: TyId;
expr?: ExprId;
};
export type ReturnStmt = { expr?: ExprId };
export type BreakStmt = { expr?: ExprId };
export type AssignStmt = {
assignType: AssignType;
subject: ExprId;
value: ExprId;
};
export type AssignType = "=" | "+=" | "-=";
export type ExprStmt = { expr: ExprId };
export type ItemId = { key: number; readonly unique: unique symbol };
export type Item = {
kind: ItemKind;
span: Span;
ident: Ident;
pub: boolean;
};
export type ItemKind =
| { tag: "error" }
| { tag: "mod_block" } & ModBlockItem
| { tag: "mod_file" } & ModFileItem
| { tag: "enum" } & EnumItem
| { tag: "struct" } & StructItem
| { tag: "fn" } & FnItem
| { tag: "use" } & UseItem
| { tag: "type_alias" } & TypeAliasItem;
export type ModBlockItem = { block: BlockId };
export type ModFileItem = { filePath: string };
export type EnumItem = { variants: Variant[] };
export type StructItem = { data: VariantData };
export type FnItem = {
generics?: Generics;
params: Param[];
returnTy?: TyId;
body: BlockId;
};
export type UseItem = { _: 0 };
export type TypeAliasItem = { ty: TyId };
export type Variant = {
ident: Ident;
data: VariantData;
pub: boolean;
span: Span;
};
export type VariantData = {
kind: VariantDataKind;
span: Span;
};
export type VariantDataKind =
| { tag: "error" }
| { tag: "unit" }
| { tag: "tuple" } & TupleVariantData
| { tag: "struct" } & StructVariantData;
export type TupleVariantData = { elems: VariantData[] };
export type StructVariantData = { fields: FieldDef[] };
export type FieldDef = {
ident: Ident;
ty: TyId;
pub: boolean;
span: Span;
};
export type Param = {
pat: PatId;
ty: TyId;
span: Span;
};
export type Generics = {
params: GenericParam[];
};
export type GenericParam = {
ident: Ident;
span: Span;
};
export type ExprId = { key: number; readonly unique: unique symbol };
export type Expr = {
kind: ExprKind;
span: Span;
};
export type ExprKind =
| { tag: "error" }
| { tag: "path" } & PathExpr
| { tag: "null" }
| { tag: "int" } & IntExpr
| { tag: "bool" } & BoolExpr
| { tag: "str" } & StringExpr
| { tag: "group" } & GroupExpr
| { tag: "array" } & ArrayExpr
| { tag: "repeat" } & RepeatExpr
| { tag: "struct" } & StructExpr
| { tag: "ref" } & RefExpr
| { tag: "deref" } & DerefExpr
| { tag: "elem" } & ElemExpr
| { tag: "field" } & FieldExpr
| { tag: "index" } & IndexExpr
| { tag: "call" } & CallExpr
| { tag: "unary" } & UnaryExpr
| { tag: "binary" } & BinaryExpr
| { tag: "block" } & BlockExpr
| { tag: "if" } & IfExpr
| { tag: "loop" } & LoopExpr
| { tag: "while" } & WhileExpr
| { tag: "for" } & ForExpr
| { tag: "c_for" } & CForExpr;
export type PathExpr = { path: Path };
export type IntExpr = { value: number };
export type BoolExpr = { value: boolean };
export type StringExpr = { value: string };
export type GroupExpr = { expr: ExprId };
export type ArrayExpr = { exprs: ExprId[] };
export type RepeatExpr = { expr: ExprId; length: ExprId };
export type StructExpr = { path?: Path; fields: ExprField[] };
export type RefExpr = { expr: ExprId; refType: RefType; mut: boolean };
export type DerefExpr = { expr: ExprId };
export type ElemExpr = { expr: ExprId; elem: number };
export type FieldExpr = { expr: ExprId; ident: Ident };
export type IndexExpr = { expr: ExprId; index: ExprId };
export type CallExpr = { expr: ExprId; args: ExprId[] };
export type UnaryExpr = { unaryType: UnaryType; expr: ExprId };
export type BinaryExpr = {
binaryType: BinaryType;
left: ExprId;
right: ExprId;
};
export type BlockExpr = { block: BlockId };
export type IfExpr = { cond: ExprId; truthy: BlockId; falsy?: ExprId };
export type LoopExpr = { body: BlockId };
export type WhileExpr = { cond: ExprId; body: BlockId };
export type ForExpr = { pat: PatId; expr: ExprId; body: BlockId };
export type CForExpr = {
decl?: StmtId;
cond?: ExprId;
incr?: StmtId;
body: BlockId;
};
export type RefType = "ref" | "ptr";
export type UnaryType = "not" | "-";
export type BinaryType =
| "+"
| "*"
| "=="
| "-"
| "/"
| "!="
| "<"
| ">"
| "<="
| ">="
| "or"
| "and";
export type ExprField = {
ident: Ident;
expr: ExprId;
span: Span;
};
export type BlockId = { key: number; readonly unique: unique symbol };
export type Block = {
stmts: StmtId[];
expr?: ExprId;
span: Span;
};
export type PatId = { key: number; readonly unique: unique symbol };
export type Pat = {
kind: PatKind;
span: Span;
};
export type PatKind =
| { tag: "error" }
| { tag: "bind" } & BindPat;
export type BindPat = {
ident: Ident;
mut: boolean;
};
export type TyId = { key: number; readonly unique: unique symbol };
export type Ty = {
kind: TyKind;
span: Span;
};
export type TyKind =
| { tag: "error" }
| { tag: "null" }
| { tag: "int" }
| { tag: "bool" }
| { tag: "str" }
| { tag: "path" } & PathTy
| { tag: "ref" } & RefTy
| { tag: "ptr" } & PtrTy
| { tag: "slice" } & SliceTy
| { tag: "array" } & ArrayTy
| { tag: "anon_struct" } & AnonStructTy;
export type PathTy = { path: Path };
export type RefTy = { ty: TyId; mut: boolean };
export type PtrTy = { ty: TyId; mut: boolean };
export type SliceTy = { ty: TyId };
export type ArrayTy = { ty: TyId; length: ExprId };
export type TupleTy = { elems: TyId[] };
export type AnonStructTy = { fields: AnonFieldDef[] };
export type AnonFieldDef = {
ident: Ident;
ty: TyId;
span: Span;
};
export type Path = {
segments: PathSegment[];
span: Span;
};
export type PathSegment = {
ident: Ident;
genericArgs?: TyId[];
span: Span;
};
export type Ident = {
internId: number;
span: Span;
};