diff --git a/compiler/Lexer.ts b/compiler/Lexer.ts index 01d003c..4067057 100644 --- a/compiler/Lexer.ts +++ b/compiler/Lexer.ts @@ -25,6 +25,16 @@ export class Lexer { this.step(); } switch (value) { + case "break": + return this.token("break", pos); + case "return": + return this.token("return", pos); + case "let": + return this.token("let", pos); + case "fn": + return this.token("fn", pos); + case "loop": + return this.token("loop", pos); case "if": return this.token("if", pos); case "else": diff --git a/compiler/Parser.ts b/compiler/Parser.ts index 750315c..6a37e9b 100644 --- a/compiler/Parser.ts +++ b/compiler/Parser.ts @@ -25,6 +25,14 @@ export class Parser { private report(msg: string, pos = this.pos()) { console.log(`Parser: ${msg} at ${pos.line}:${pos.col}`); + class ReportNotAnError extends Error { constructor() { super("ReportNotAnError"); } } + try { + throw new ReportNotAnError(); + } catch (error) { + if (!(error instanceof ReportNotAnError)) + throw error; + console.log(error) + } } private stmt(kind: StmtKind, pos: Pos): Stmt { @@ -65,7 +73,7 @@ export class Parser { private eatSemicolon() { if (!this.test(";")) { - this.report("expected ';'"); + this.report(`expected ';', got '${this.currentToken?.type ?? "eof"}'`); return; } this.step(); @@ -285,20 +293,23 @@ export class Parser { const subject = this.parsePrefix(); return this.expr({ type: "unary", unaryType: "not", subject }, pos); } - ["+", "*", "==", "-", "/", "!=", "<", ">", "<=", ">=", "or", "and"].forEach((binaryType) => { - this.parseBinary(binaryType as BinaryType, pos) - - }) + for (const binaryType of ["+", "*", "==", "-", "/", "!=", "<", ">", "<=", ">=", "or", "and"]) { + const subject = this.parseBinary(binaryType as BinaryType, pos) + if (subject !== null) { + return subject + } + } return this.parsePostfix(); } - public parseBinary(binaryType: BinaryType, pos: Pos) { + public parseBinary(binaryType: BinaryType, pos: Pos): Expr | null { if (this.test(binaryType)) { this.step(); const left = this.parsePrefix(); const right = this.parsePrefix(); return this.expr({ type: "binary", binaryType, left, right }, pos); } + return null } public parsePostfix(): Expr { diff --git a/compiler/example-no-types.slg b/compiler/example-no-types.slg index 4b002c7..a9f9b31 100644 --- a/compiler/example-no-types.slg +++ b/compiler/example-no-types.slg @@ -1,30 +1,29 @@ - -fn add(a, b) { - + a b +fn sum(a, b) { + + a b; } -// -// add(2,3); // -> 5 -// -// let a = "Hello"; -// -// let b = "world"; -// -// println(a + " " + b + "!"); // -> "Hello world!" -// -// if a == b { -// println("whaaaat"); -// } -// else { -// println(":o"); -// } -// -// loop { -// let i = 0; -// -// if i >= 10 { -// break; -// } -// -// i = i + 1; -// } \ No newline at end of file + +add(2,3); // -> 5 + +let a = "Hello"; + +let b = "world"; + +//println(+ (+ a " ") (+ b "!")); // -> "Hello world!" + +if == a b { + println("whaaaat"); +} +else { + println(":o"); +} + +loop { +// let i = 0; +// +// if >= i 10 { +// break; +// } +// +// i = i + 1; +} \ No newline at end of file diff --git a/compiler/main.ts b/compiler/main.ts index 37bd9db..e140e76 100644 --- a/compiler/main.ts +++ b/compiler/main.ts @@ -5,20 +5,13 @@ import { Parser } from "./Parser.ts"; const text = await Deno.readTextFile("example.slg"); const lexer = new Lexer(text); -console.log("type\tindex\tline:col"); -let current = lexer.next(); -while (current) { - console.log( - `${ - current.identValue ?? current.type - }\t${current.pos.index}\t${current.pos.line}:${current.pos.col}`, - ); - current = lexer.next(); -} -const pos = lexer.currentPos(); -console.log(`eof\t${pos.index}\t${pos.line}:${pos.col}`); -//const parser = new Parser(lexer); -//while (!parser.done()) { -// const result = parser.parseExpr(); -// console.log(result); -//} + +// while (token !== null) { +// const value = token.identValue ?? token.intValue ?? token.stringValue ?? ""; +// console.log(`${token.type}\t${value}`) +// token = lexer.next(); +// } + +const parser = new Parser(lexer) +const result = parser.parseStmts() +console.log(JSON.stringify(result, null, 4))