define more ast stuff

This commit is contained in:
sfja 2025-01-24 00:46:03 +01:00
parent ab5a830f66
commit 7ca864d5a9
2 changed files with 154 additions and 25 deletions

View File

@ -15,6 +15,7 @@ export type StmtKind =
| { tag: "let" } & LetStmt
| { tag: "return" } & ReturnStmt
| { tag: "break" } & BreakStmt
| { tag: "continue" }
| { tag: "assign" } & AssignStmt
| { tag: "expr" } & ExprStmt;
@ -53,25 +54,15 @@ export type ItemKind =
| { tag: "struct" } & StructItem
| { tag: "fn" } & FnItem
| { tag: "use" } & UseItem
| { tag: "static" } & StaticItem
| { tag: "type_alias" } & TypeAliasItem;
export type ModBlockItem = {
ident: Ident;
stmts: Stmt[];
};
export type ModFileItem = {
ident: Ident;
filePath: string;
};
export type ModBlockItem = { ident: Ident; stmts: Stmt[] };
export type ModFileItem = { ident: Ident; filePath: string };
export type EnumItem = { variants: Variant[] };
export type StructItem = { data: VariantData };
export type FnItem = { _: 0 };
export type UseItem = { _: 0 };
export type StaticItem = { _: 0 };
export type TypeAliasItem = { _: 0 };
export type TypeAliasItem = { ty: Ty };
export type Variant = {
ident: Ident;
@ -108,7 +99,78 @@ export type Expr = {
export type ExprKind =
| { tag: "error" }
| { tag: "ident" } & Ident;
| { tag: "path" } & Path
| { tag: "null" }
| { tag: "int" } & IntExpr
| { tag: "bool" } & BoolExpr
| { tag: "string" } & 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" } & Block
| { tag: "if" } & IfExpr
| { tag: "loop" } & LoopExpr
| { tag: "while" } & WhileExpr
| { tag: "for" } & ForExpr
| { tag: "c_for" } & CForExpr;
export type IntExpr = { value: number };
export type BoolExpr = { value: boolean };
export type StringExpr = { value: string };
export type GroupExpr = { expr: Expr };
export type ArrayExpr = { exprs: Expr[] };
export type RepeatExpr = { expr: Expr; length: Expr };
export type StructExpr = { path?: Path; field: ExprField[] };
export type RefExpr = { expr: Expr; refType: RefType; mut: boolean };
export type DerefExpr = { expr: Expr };
export type ElemExpr = { expr: Expr; elem: number };
export type FieldExpr = { expr: Expr; ident: Ident };
export type IndexExpr = { expr: Expr; index: Expr };
export type CallExpr = { expr: Expr; args: Expr };
export type UnaryExpr = { unaryType: UnaryType; expr: Expr };
export type BinaryExpr = { unaryType: UnaryType; left: Expr; right: Expr };
export type IfExpr = { cond: Expr; truthy: Block; falsy?: Block };
export type LoopExpr = { body: Block };
export type WhileExpr = { cond: Expr; body: Block };
export type ForExpr = { pat: Pat; expr: Expr; body: Block };
export type CForExpr = { decl?: Stmt; cond?: Expr; incr?: Stmt; body: Block };
export type RefType = "ref" | "ptr";
export type UnaryType = "not" | "-";
export type BinaryType =
| "+"
| "*"
| "=="
| "-"
| "/"
| "!="
| "<"
| ">"
| "<="
| ">="
| "or"
| "and";
export type ExprField = {
ident: Ident;
expr: Expr;
span: Span;
};
export type Block = {
stmts: Stmt[];
expr?: Expr;
span: Span;
};
export type Pat = {
kind: PatKind;
@ -131,18 +193,19 @@ export type Ty = {
export type TyKind =
| { tag: "error" }
| { tag: "ident" } & Ident
| { tag: "path" } & Path
| { tag: "ref" } & RefTy
| { tag: "ptr" } & PtrTy
| { tag: "slice" } & SliceTy
| { tag: "array" } & ArrayTy;
| { tag: "array" } & ArrayTy
| { tag: "anon_struct" } & AnonStructTy;
export type RefTy = { ty: Ty; mut: boolean };
export type PtrTy = { ty: Ty; mut: boolean };
export type SliceTy = { ty: Ty };
export type ArrayTy = { ty: Ty; length: Expr };
export type TupleTy = { elems: Ty[] };
export type StructTy = { fields: FieldDef[] };
export type AnonStructTy = { fields: AnonFieldDef[] };
export type AnonFieldDef = {
ident: Ident;
@ -150,4 +213,18 @@ export type AnonFieldDef = {
span: Span;
};
export type Ident = { text: string; span: Span };
export type Path = {
segments: PathSegment[];
span: Span;
};
export type PathSegment = {
ident: Ident;
genericArgs?: Ty[];
span: Span;
};
export type Ident = {
text: string;
span: Span;
};

View File

@ -1,31 +1,53 @@
import { exhausted } from "../util.ts";
import {
AnonStructTy,
ArrayExpr,
ArrayTy,
AssignStmt,
BinaryExpr,
BindPat,
BoolExpr,
BreakStmt,
CallExpr,
CForExpr,
DerefExpr,
ElemExpr,
EnumItem,
Expr,
ExprStmt,
FieldExpr,
File,
FnItem,
ForExpr,
GroupExpr,
Ident,
IfExpr,
IndexExpr,
IntExpr,
Item,
ItemStmt,
LetStmt,
LoopExpr,
ModBlockItem,
ModFileItem,
Pat,
Path,
PtrTy,
RefExpr,
RefTy,
RepeatExpr,
ReturnStmt,
SliceTy,
StaticItem,
Stmt,
StringExpr,
StructExpr,
StructItem,
TupleTy,
Ty,
TypeAliasItem,
UnaryExpr,
UseItem,
WhileExpr,
} from "./ast.ts";
export type VisitRes = "stop" | void;
@ -37,14 +59,17 @@ export interface Visitor<
P extends PM = [],
> {
visitFile?(file: File, ...p: P): R;
visitStmt?(stmt: Stmt, ...p: P): R;
visitErrorStmt?(stmt: Stmt, ...p: P): R;
visitItemStmt?(stmt: Stmt, kind: ItemStmt, ...p: P): R;
visitLetStmt?(stmt: Stmt, kind: LetStmt, ...p: P): R;
visitReturnStmt?(stmt: Stmt, kind: ReturnStmt, ...p: P): R;
visitBreakStmt?(stmt: Stmt, kind: BreakStmt, ...p: P): R;
visitContinueStmt?(stmt: Stmt, ...p: P): R;
visitAssignStmt?(stmt: Stmt, kind: AssignStmt, ...p: P): R;
visitExprStmt?(stmt: Stmt, kind: ExprStmt, ...p: P): R;
visitItem?(item: Item, ...p: P): R;
visitErrorItem?(item: Item, ...p: P): R;
visitModBlockItem?(item: Item, kind: ModBlockItem, ...p: P): R;
@ -53,21 +78,48 @@ export interface Visitor<
visitStructItem?(item: Item, kind: StructItem, ...p: P): R;
visitFnItem?(item: Item, kind: FnItem, ...p: P): R;
visitUseItem?(item: Item, kind: UseItem, ...p: P): R;
visitStaticItem?(item: Item, kind: StaticItem, ...p: P): R;
visitTypeAliasItem?(item: Item, kind: TypeAliasItem, ...p: P): R;
visitExpr?(expr: Expr, ...p: P): R;
visitErrorExpr?(expr: Expr, ...p: P): R;
visitIdentExpr?(expr: Expr, kind: Ident, ...p: P): R;
visitPathExpr?(expr: Expr, kind: Path, ...p: P): R;
visitNullExpr?(expr: Expr, ...p: P): R;
visitIntExpr?(expr: Expr, kind: IntExpr, ...p: P): R;
visitBoolExpr?(expr: Expr, kind: BoolExpr, ...p: P): R;
visitStringExpr?(expr: Expr, kind: StringExpr, ...p: P): R;
visitGroupExpr?(expr: Expr, kind: GroupExpr, ...p: P): R;
visitArrayExpr?(expr: Expr, kind: ArrayExpr, ...p: P): R;
visitRepeatExpr?(expr: Expr, kind: RepeatExpr, ...p: P): R;
visitStructExpr?(expr: Expr, kind: StructExpr, ...p: P): R;
visitRefExpr?(expr: Expr, kind: RefExpr, ...p: P): R;
visitDerefExpr?(expr: Expr, kind: DerefExpr, ...p: P): R;
visitElemExpr?(expr: Expr, kind: ElemExpr, ...p: P): R;
visitFieldExpr?(expr: Expr, kind: FieldExpr, ...p: P): R;
visitIndexExpr?(expr: Expr, kind: IndexExpr, ...p: P): R;
visitCallExpr?(expr: Expr, kind: CallExpr, ...p: P): R;
visitUnaryExpr?(expr: Expr, kind: UnaryExpr, ...p: P): R;
visitBinaryExpr?(expr: Expr, kind: BinaryExpr, ...p: P): R;
visitIfExpr?(expr: Expr, kind: IfExpr, ...p: P): R;
visitLoopExpr?(expr: Expr, kind: LoopExpr, ...p: P): R;
visitWhileExpr?(expr: Expr, kind: WhileExpr, ...p: P): R;
visitForExpr?(expr: Expr, kind: ForExpr, ...p: P): R;
visitCForExpr?(expr: Expr, kind: CForExpr, ...p: P): R;
visitPat?(pat: Pat, ...p: P): R;
visitErrorPat?(pat: Pat, ...p: P): R;
visitBindPat?(pat: Pat, kind: BindPat, ...p: P): R;
visitTy?(ty: Ty, ...p: P): R;
visitErrorTy?(ty: Ty, ...p: P): R;
visitIdentTy?(ty: Ty, kind: Ident, ...p: P): R;
visitPathTy?(ty: Ty, kind: Path, ...p: P): R;
visitRefTy?(ty: Ty, kind: RefTy, ...p: P): R;
visitPtrTy?(ty: Ty, kind: PtrTy, ...p: P): R;
visitSliceTy?(ty: Ty, kind: SliceTy, ...p: P): R;
visitArrayTy?(ty: Ty, kind: ArrayTy, ...p: P): R;
visitTupleTy?(ty: Ty, kind: TupleTy, ...p: P): R;
visitAnonStructTy?(ty: Ty, kind: AnonStructTy, ...p: P): R;
visitPath?(path: Path, ...p: P): R;
visitIdent?(ident: Ident, ...p: P): R;
}
@ -118,6 +170,9 @@ export function visitStmt<
case "break":
if (v.visitBreakStmt?.(stmt, kind, ...p) === "stop") return;
return;
case "continue":
if (v.visitContinueStmt?.(stmt, ...p) === "stop") return;
return;
case "assign":
if (v.visitAssignStmt?.(stmt, kind, ...p) === "stop") return;
return;
@ -158,9 +213,6 @@ export function visitItem<
case "use":
if (v.visitUseItem?.(item, kind, ...p) === "stop") return;
return;
case "static":
if (v.visitStaticItem?.(item, kind, ...p) === "stop") return;
return;
case "type_alias":
if (v.visitTypeAliasItem?.(item, kind, ...p) === "stop") return;
return;