start multiple file support

This commit is contained in:
SimonFJ20 2024-12-12 12:04:57 +01:00
parent 242d5b16eb
commit ed279f7998
4 changed files with 110 additions and 84 deletions

View File

@ -1,6 +1,13 @@
import { Pos } from "./token.ts";
import { VType } from "./vtype.ts";
export type Ast = File[];
export type File = {
path: string;
stmts: Stmt[];
};
export type UnaryType = "not";
export type BinaryType =
| "+"
@ -31,6 +38,7 @@ export type Stmt = {
export type StmtKind =
| { type: "error" }
| { type: "import"; path: Expr }
| { type: "break"; expr?: Expr }
| { type: "return"; expr?: Expr }
| {

View File

@ -43,6 +43,8 @@ export class Lexer {
return this.token("else", pos);
case "struct":
return this.token("struct", pos);
case "import":
return this.token("import", pos);
default:
return { ...this.token("ident", pos), identValue: value };
}

View File

@ -1,3 +1,4 @@
import { Ast, File } from "./ast.ts";
import { Checker } from "./checker.ts";
import { Reporter } from "./info.ts";
import { Lexer } from "./lexer.ts";
@ -5,6 +6,16 @@ import { Lowerer } from "./lowerer.ts";
import { Parser } from "./parser.ts";
import { Resolver } from "./resolver.ts";
class Compilation {
private files: File[] = [];
public constructor(private startFile: string) {}
public compile(): Ast {
throw new Error();
}
}
//const text = await Deno.readTextFile("example.slg");
const text = await Deno.readTextFile(Deno.args[0]);
@ -13,7 +24,7 @@ const reporter = new Reporter();
const lexer = new Lexer(text, reporter);
const parser = new Parser(lexer, reporter);
const ast = parser.parseStmts();
const ast = parser.parse();
// console.log(JSON.stringify(ast, null, 4));

View File

@ -21,51 +21,29 @@ export class Parser {
this.currentToken = lexer.next();
}
private step() {
this.currentToken = this.lexer.next();
public parse(): Stmt[] {
return this.parseStmts();
}
public done(): boolean {
return this.currentToken == null;
}
private current(): Token {
return this.currentToken!;
}
private pos(): Pos {
if (this.done()) {
return this.lexer.currentPos();
private parseStmts(): Stmt[] {
const stmts: Stmt[] = [];
while (!this.done()) {
if (this.test("fn")) {
stmts.push(this.parseFn());
} else if (
this.test("let") || this.test("return") || this.test("break")
) {
stmts.push(this.parseSingleLineBlockStmt());
this.eatSemicolon();
} else if (this.test("{") || this.test("if") || this.test("loop")) {
const expr = this.parseMultiLineBlockExpr();
stmts.push(this.stmt({ type: "expr", expr }, expr.pos));
} else {
stmts.push(this.parseAssign());
this.eatSemicolon();
}
}
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, pos: Pos): Stmt {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
}
private expr(kind: ExprKind, pos: Pos): Expr {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
}
private etype(kind: ETypeKind, pos: Pos): EType {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
return stmts;
}
private parseMultiLineBlockExpr(): Expr {
@ -108,11 +86,11 @@ export class Parser {
this.step();
}
public parseExpr(): Expr {
private parseExpr(): Expr {
return this.parsePrefix();
}
public parseBlock(): Expr {
private parseBlock(): Expr {
const pos = this.pos();
this.step();
let stmts: Stmt[] = [];
@ -163,28 +141,7 @@ export class Parser {
return this.expr({ type: "error" }, pos);
}
public parseStmts(): Stmt[] {
let stmts: Stmt[] = [];
while (!this.done()) {
if (this.test("fn")) {
stmts.push(this.parseFn());
} else if (
this.test("let") || this.test("return") || this.test("break")
) {
stmts.push(this.parseSingleLineBlockStmt());
this.eatSemicolon();
} else if (this.test("{") || this.test("if") || this.test("loop")) {
const expr = this.parseMultiLineBlockExpr();
stmts.push(this.stmt({ type: "expr", expr }, expr.pos));
} else {
stmts.push(this.parseAssign());
this.eatSemicolon();
}
}
return stmts;
}
public parseFn(): Stmt {
private parseFn(): Stmt {
const pos = this.pos();
this.step();
if (!this.test("ident")) {
@ -226,7 +183,7 @@ export class Parser {
);
}
public parseAnnoArgs(): Expr[] {
private parseAnnoArgs(): Expr[] {
this.step();
if (!this.test("(")) {
this.report("expected '('");
@ -252,7 +209,7 @@ export class Parser {
return annoArgs;
}
public parseAnno(): Anno | null {
private parseAnno(): Anno | null {
const pos = this.pos();
this.step();
if (!this.test("[")) {
@ -274,7 +231,7 @@ export class Parser {
return { ident, pos, values };
}
public parseFnParams(): Param[] {
private parseFnParams(): Param[] {
this.step();
if (this.test(")")) {
this.step();
@ -305,7 +262,7 @@ export class Parser {
return params;
}
public parseParam(): { ok: true; value: Param } | { ok: false } {
private parseParam(): { ok: true; value: Param } | { ok: false } {
const pos = this.pos();
if (this.test("ident")) {
const ident = this.current().identValue!;
@ -321,7 +278,7 @@ export class Parser {
return { ok: false };
}
public parseLet(): Stmt {
private parseLet(): Stmt {
const pos = this.pos();
this.step();
const paramResult = this.parseParam();
@ -337,7 +294,7 @@ export class Parser {
const value = this.parseExpr();
return this.stmt({ type: "let", param, value }, pos);
}
public parseAssign(): Stmt {
private parseAssign(): Stmt {
const pos = this.pos();
const subject = this.parseExpr();
if (!this.test("=")) {
@ -348,7 +305,7 @@ export class Parser {
return this.stmt({ type: "assign", subject, value }, pos);
}
public parseReturn(): Stmt {
private parseReturn(): Stmt {
const pos = this.pos();
this.step();
if (this.test(";")) {
@ -358,7 +315,7 @@ export class Parser {
return this.stmt({ type: "return", expr }, pos);
}
public parseBreak(): Stmt {
private parseBreak(): Stmt {
const pos = this.pos();
this.step();
if (this.test(";")) {
@ -368,7 +325,7 @@ export class Parser {
return this.stmt({ type: "break", expr }, pos);
}
public parseLoop(): Expr {
private parseLoop(): Expr {
const pos = this.pos();
this.step();
if (!this.test("{")) {
@ -379,7 +336,7 @@ export class Parser {
return this.expr({ type: "loop", body }, pos);
}
public parseIf(): Expr {
private parseIf(): Expr {
const pos = this.pos();
this.step();
const cond = this.parseExpr();
@ -404,7 +361,7 @@ export class Parser {
return this.expr({ type: "if", cond, truthy, falsy }, pos);
}
public parsePrefix(): Expr {
private parsePrefix(): Expr {
const pos = this.pos();
if (this.test("not")) {
this.step();
@ -435,7 +392,7 @@ export class Parser {
return this.parsePostfix();
}
public parseBinary(binaryType: BinaryType, pos: Pos): Expr | null {
private parseBinary(binaryType: BinaryType, pos: Pos): Expr | null {
if (this.test(binaryType)) {
this.step();
const left = this.parsePrefix();
@ -445,7 +402,7 @@ export class Parser {
return null;
}
public parsePostfix(): Expr {
private parsePostfix(): Expr {
let subject = this.parseOperand();
while (true) {
const pos = this.pos();
@ -497,7 +454,7 @@ export class Parser {
return subject;
}
public parseOperand(): Expr {
private parseOperand(): Expr {
const pos = this.pos();
if (this.test("ident")) {
const value = this.current().identValue!;
@ -551,7 +508,7 @@ export class Parser {
return this.expr({ type: "error" }, pos);
}
public parseEType(): EType {
private parseEType(): EType {
const pos = this.pos();
if (this.test("ident")) {
const ident = this.current().identValue!;
@ -581,7 +538,7 @@ export class Parser {
return this.etype({ type: "error" }, pos);
}
public parseETypeStructFields(): Param[] {
private parseETypeStructFields(): Param[] {
this.step();
if (this.test("}")) {
this.step();
@ -611,4 +568,52 @@ export class Parser {
this.step();
return params;
}
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()) {
console.log(`Parser: ${msg} at ${pos.line}:${pos.col}`);
this.reporter.reportError({
msg,
pos,
reporter: "Parser",
});
printStackTrace();
}
private stmt(kind: StmtKind, pos: Pos): Stmt {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
}
private expr(kind: ExprKind, pos: Pos): Expr {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
}
private etype(kind: ETypeKind, pos: Pos): EType {
const id = this.nextNodeId;
this.nextNodeId += 1;
return { kind, pos, id };
}
}