2024-12-29 05:39:22 +01:00
|
|
|
import type { Syms } from "./resolver_syms.ts";
|
2024-12-10 21:42:15 +01:00
|
|
|
import { Pos } from "./token.ts";
|
2024-12-26 03:56:59 +01:00
|
|
|
import { GenericArgsMap, VType } from "./vtype.ts";
|
2024-11-15 15:20:49 +01:00
|
|
|
|
2024-12-29 05:39:22 +01:00
|
|
|
export type Mod = {
|
|
|
|
filePath: string;
|
2024-12-30 21:12:43 +01:00
|
|
|
ast: Stmt[];
|
2024-12-29 05:39:22 +01:00
|
|
|
};
|
|
|
|
|
2024-11-15 15:20:49 +01:00
|
|
|
export type Stmt = {
|
2024-12-06 14:17:52 +01:00
|
|
|
kind: StmtKind;
|
|
|
|
pos: Pos;
|
2024-12-31 00:12:34 +01:00
|
|
|
details?: StmtDetails;
|
2024-12-06 14:17:52 +01:00
|
|
|
id: number;
|
2024-11-15 15:20:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export type StmtKind =
|
|
|
|
| { type: "error" }
|
2024-12-30 21:12:43 +01:00
|
|
|
| { type: "mod_block"; ident: string; stmts: Stmt[] }
|
2024-12-29 05:39:22 +01:00
|
|
|
| { type: "mod_file"; ident: string; filePath: string }
|
|
|
|
| { type: "mod"; ident: string; mod: Mod }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "break"; expr?: Expr }
|
|
|
|
| { type: "return"; expr?: Expr }
|
2025-01-02 17:54:46 +01:00
|
|
|
| FnStmtKind
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "let"; param: Param; value: Expr }
|
2024-12-31 05:32:41 +01:00
|
|
|
| { type: "type_alias"; param: Param }
|
2024-12-14 02:53:58 +01:00
|
|
|
| { type: "assign"; assignType: AssignType; subject: Expr; value: Expr }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "expr"; expr: Expr };
|
2024-11-15 15:20:49 +01:00
|
|
|
|
2025-01-02 17:54:46 +01:00
|
|
|
export type FnStmtKind = {
|
|
|
|
type: "fn";
|
|
|
|
ident: string;
|
|
|
|
genericParams?: GenericParam[];
|
|
|
|
params: Param[];
|
|
|
|
returnType?: EType;
|
|
|
|
body: Expr;
|
|
|
|
sym?: Sym;
|
|
|
|
vtype?: VType;
|
|
|
|
};
|
|
|
|
|
2024-12-14 02:53:58 +01:00
|
|
|
export type AssignType = "=" | "+=" | "-=";
|
|
|
|
|
2024-12-31 00:12:34 +01:00
|
|
|
export type StmtDetails = {
|
|
|
|
pub: boolean;
|
|
|
|
annos: Anno[];
|
|
|
|
};
|
|
|
|
|
2024-11-15 15:20:49 +01:00
|
|
|
export type Expr = {
|
2024-12-06 14:17:52 +01:00
|
|
|
kind: ExprKind;
|
|
|
|
pos: Pos;
|
|
|
|
vtype?: VType;
|
|
|
|
id: number;
|
2024-11-15 15:20:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export type ExprKind =
|
|
|
|
| { type: "error" }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "int"; value: number }
|
|
|
|
| { type: "string"; value: string }
|
2024-12-23 03:15:43 +01:00
|
|
|
| { type: "ident"; ident: string }
|
|
|
|
| {
|
|
|
|
type: "sym";
|
|
|
|
ident: string;
|
|
|
|
sym: Sym;
|
|
|
|
}
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "group"; expr: Expr }
|
2025-01-17 07:44:53 +01:00
|
|
|
| { type: "ref"; subject: Expr }
|
|
|
|
| { type: "ref_mut"; subject: Expr }
|
|
|
|
| { type: "deref"; subject: Expr }
|
2024-12-31 03:38:38 +01:00
|
|
|
| { type: "array"; exprs: Expr[] }
|
|
|
|
| { type: "struct"; fields: Field[] }
|
2024-12-23 03:15:43 +01:00
|
|
|
| { type: "field"; subject: Expr; ident: string }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "index"; subject: Expr; value: Expr }
|
2024-12-26 03:56:59 +01:00
|
|
|
| {
|
|
|
|
type: "call";
|
|
|
|
subject: Expr;
|
|
|
|
args: Expr[];
|
|
|
|
genericArgs?: GenericArgsMap;
|
|
|
|
}
|
2024-12-23 03:15:43 +01:00
|
|
|
| { type: "path"; subject: Expr; ident: string }
|
|
|
|
| { type: "etype_args"; subject: Expr; etypeArgs: EType[] }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "unary"; unaryType: UnaryType; subject: Expr }
|
|
|
|
| { type: "binary"; binaryType: BinaryType; left: Expr; right: Expr }
|
2024-12-17 10:24:18 +01:00
|
|
|
| { type: "if"; cond: Expr; truthy: Expr; falsy?: Expr; elsePos?: Pos }
|
2024-12-06 14:17:52 +01:00
|
|
|
| { type: "bool"; value: boolean }
|
|
|
|
| { type: "null" }
|
|
|
|
| { type: "loop"; body: Expr }
|
|
|
|
| { type: "block"; stmts: Stmt[]; expr?: Expr }
|
2024-12-14 02:53:58 +01:00
|
|
|
| { 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;
|
2024-12-06 14:17:52 +01:00
|
|
|
};
|
2024-11-22 14:06:28 +01:00
|
|
|
|
2024-12-16 21:56:36 +01:00
|
|
|
export type UnaryType = "not" | "-";
|
2024-12-13 10:26:34 +01:00
|
|
|
export type BinaryType =
|
|
|
|
| "+"
|
|
|
|
| "*"
|
|
|
|
| "=="
|
|
|
|
| "-"
|
|
|
|
| "/"
|
|
|
|
| "!="
|
|
|
|
| "<"
|
|
|
|
| ">"
|
|
|
|
| "<="
|
|
|
|
| ">="
|
|
|
|
| "or"
|
|
|
|
| "and";
|
|
|
|
|
2024-12-31 03:38:38 +01:00
|
|
|
export type Field = {
|
|
|
|
ident: string;
|
|
|
|
expr: Expr;
|
|
|
|
pos: Pos;
|
|
|
|
};
|
|
|
|
|
2024-12-13 10:26:34 +01:00
|
|
|
export type Param = {
|
2025-01-02 04:40:09 +01:00
|
|
|
id: number;
|
|
|
|
index?: number;
|
2024-12-13 10:26:34 +01:00
|
|
|
ident: string;
|
2025-01-17 07:44:53 +01:00
|
|
|
mut: boolean;
|
2024-12-13 10:26:34 +01:00
|
|
|
etype?: EType;
|
|
|
|
pos: Pos;
|
2025-01-02 17:54:46 +01:00
|
|
|
sym?: Sym;
|
2024-12-13 10:26:34 +01:00
|
|
|
vtype?: VType;
|
|
|
|
};
|
|
|
|
|
2024-11-22 14:06:28 +01:00
|
|
|
export type Sym = {
|
2024-12-06 14:17:52 +01:00
|
|
|
ident: string;
|
2025-01-02 17:54:46 +01:00
|
|
|
fullPath: string;
|
2024-12-06 14:17:52 +01:00
|
|
|
pos?: Pos;
|
2024-12-10 14:36:41 +01:00
|
|
|
} & SymKind;
|
|
|
|
|
|
|
|
export type SymKind =
|
|
|
|
| { type: "let"; stmt: Stmt; param: Param }
|
|
|
|
| { type: "let_static"; stmt: Stmt; param: Param }
|
2024-12-31 05:32:41 +01:00
|
|
|
| { type: "type_alias"; stmt: Stmt; param: Param }
|
2024-12-10 14:36:41 +01:00
|
|
|
| { type: "fn"; stmt: Stmt }
|
|
|
|
| { type: "fn_param"; param: Param }
|
|
|
|
| { type: "closure"; inner: Sym }
|
2024-12-29 05:39:22 +01:00
|
|
|
| { type: "generic"; stmt: Stmt; genericParam: GenericParam }
|
|
|
|
| { type: "mod"; syms: Syms };
|
2024-12-06 14:17:52 +01:00
|
|
|
|
|
|
|
export type EType = {
|
|
|
|
kind: ETypeKind;
|
|
|
|
pos: Pos;
|
|
|
|
id: number;
|
|
|
|
};
|
2024-11-22 14:06:28 +01:00
|
|
|
|
2024-12-06 14:17:52 +01:00
|
|
|
export type ETypeKind =
|
|
|
|
| { type: "error" }
|
2024-12-23 03:15:43 +01:00
|
|
|
| { type: "null" }
|
|
|
|
| { type: "int" }
|
|
|
|
| { type: "bool" }
|
|
|
|
| { type: "string" }
|
|
|
|
| { type: "ident"; ident: string }
|
|
|
|
| {
|
|
|
|
type: "sym";
|
|
|
|
ident: string;
|
|
|
|
sym: Sym;
|
|
|
|
}
|
2025-01-17 07:44:53 +01:00
|
|
|
| { type: "ref"; subject: EType }
|
|
|
|
| { type: "ref_mut"; subject: EType }
|
|
|
|
| { type: "ptr"; subject: EType }
|
|
|
|
| { type: "ptr_mut"; subject: EType }
|
|
|
|
| { type: "array"; subject: EType }
|
2024-12-31 03:38:38 +01:00
|
|
|
| { type: "struct"; fields: Param[] }
|
|
|
|
| { type: "type_of"; expr: Expr };
|
2024-12-11 12:36:19 +01:00
|
|
|
|
2024-12-23 03:15:43 +01:00
|
|
|
export type GenericParam = {
|
2024-12-26 01:51:05 +01:00
|
|
|
id: number;
|
2025-01-02 04:40:09 +01:00
|
|
|
index: number;
|
2024-12-13 10:26:34 +01:00
|
|
|
ident: string;
|
|
|
|
pos: Pos;
|
|
|
|
vtype?: VType;
|
|
|
|
};
|
|
|
|
|
2024-12-11 12:36:19 +01:00
|
|
|
export type Anno = {
|
|
|
|
ident: string;
|
2024-12-31 00:12:34 +01:00
|
|
|
args: Expr[];
|
2024-12-11 12:36:19 +01:00
|
|
|
pos: Pos;
|
|
|
|
};
|
2024-12-14 02:53:58 +01:00
|
|
|
|
|
|
|
export class AstCreator {
|
|
|
|
private nextNodeId = 0;
|
|
|
|
|
2024-12-31 00:12:34 +01:00
|
|
|
public stmt(kind: StmtKind, pos: Pos, details?: StmtDetails): Stmt {
|
2025-01-02 04:40:09 +01:00
|
|
|
const id = this.genId();
|
2024-12-31 00:12:34 +01:00
|
|
|
return { kind, pos, details, id };
|
2024-12-14 02:53:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public expr(kind: ExprKind, pos: Pos): Expr {
|
2025-01-02 04:40:09 +01:00
|
|
|
const id = this.genId();
|
2024-12-14 02:53:58 +01:00
|
|
|
return { kind, pos, id };
|
|
|
|
}
|
|
|
|
|
|
|
|
public etype(kind: ETypeKind, pos: Pos): EType {
|
2025-01-02 04:40:09 +01:00
|
|
|
const id = this.genId();
|
|
|
|
return { kind, pos, id };
|
|
|
|
}
|
|
|
|
|
|
|
|
public param(val: Omit<Param, "id">): Param {
|
|
|
|
const id = this.genId();
|
|
|
|
return { ...val, id };
|
|
|
|
}
|
|
|
|
|
|
|
|
public genericParam(val: Omit<GenericParam, "id">): GenericParam {
|
|
|
|
const id = this.genId();
|
|
|
|
return { ...val, id };
|
|
|
|
}
|
|
|
|
|
|
|
|
private genId(): number {
|
2024-12-14 02:53:58 +01:00
|
|
|
const id = this.nextNodeId;
|
|
|
|
this.nextNodeId += 1;
|
2025-01-02 04:40:09 +01:00
|
|
|
return id;
|
2024-12-14 02:53:58 +01:00
|
|
|
}
|
|
|
|
}
|
2024-12-31 00:12:34 +01:00
|
|
|
|
|
|
|
export class AnnoView {
|
|
|
|
public constructor(private details?: StmtDetails) {}
|
|
|
|
|
|
|
|
public has(...idents: string[]): boolean {
|
|
|
|
return this.details?.annos.some((anno) =>
|
|
|
|
idents.some((ident) => anno.ident === ident)
|
|
|
|
) ?? false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get(ident: string): Anno {
|
|
|
|
const anno = this.details?.annos.find((anno) => anno.ident === ident);
|
|
|
|
if (!anno) {
|
|
|
|
throw new Error();
|
|
|
|
}
|
|
|
|
return anno;
|
|
|
|
}
|
|
|
|
}
|
2025-01-17 07:44:53 +01:00
|
|
|
|
|
|
|
export function forceType(v: unknown): { type: string } {
|
|
|
|
return v as { type: string };
|
|
|
|
}
|