diff --git a/compiler/ast/ast.ts b/compiler/ast/ast.ts index 4fe94be..e384660 100644 --- a/compiler/ast/ast.ts +++ b/compiler/ast/ast.ts @@ -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; +}; diff --git a/compiler/ast/visitor.ts b/compiler/ast/visitor.ts index 17b9bd0..d6ad0d0 100644 --- a/compiler/ast/visitor.ts +++ b/compiler/ast/visitor.ts @@ -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;