import { Expr, ExprKind, File, Ident, Item, ItemKind, Pat, PatKind, Stmt, StmtKind, Ty, TyKind, } from "../ast/ast.ts"; import { Ctx, File as CtxFile } from "../ctx.ts"; import { Span } from "../diagnostics.ts"; import { todo } from "../util.ts"; import { Lexer } from "./lexer.ts"; import { Token } from "./token.ts"; export class Parser { private lexer: Lexer; private currentToken: Token | null; public constructor( private ctx: Ctx, private file: CtxFile, ) { this.lexer = new Lexer(this.ctx, this.file); this.currentToken = this.lexer.next(); } public parse(): File { return this.parseStmts(); } private parseStmts(): Stmt[] { const stmts: Stmt[] = []; while (!this.done()) { stmts.push(this.parseStmt()); } return stmts; } private step() { this.currentToken = this.lexer.next(); } private done(): boolean { return this.currentToken == null; } private current(): Token { return this.currentToken!; } private pos(): Pos { if (this.done()) { return this.lexer.currentPos(); } return this.current().pos; } private test(type: string): boolean { return !this.done() && this.current().type === type; } private report(msg: string, pos = this.pos()) { this.reporter.reportError({ msg, pos, reporter: "Parser", }); printStackTrace(); } private stmt(kind: StmtKind, span: Span): Stmt { return { kind, span }; } private item( kind: ItemKind, span: Span, ident: Ident, pub: boolean, ): Item { return { kind, span, ident, pub }; } private expr(kind: ExprKind, span: Span): Expr { return { kind, span }; } private pat(kind: PatKind, span: Span): Pat { return { kind, span }; } private ty(kind: TyKind, span: Span): Ty { return { kind, span }; } }