slige-mirror/compiler/parser/parser.ts
2025-01-27 14:47:13 +01:00

99 lines
2.1 KiB
TypeScript

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 };
}
}