This commit is contained in:
SimonFJ20 2024-12-12 15:37:56 +01:00
parent 454b658082
commit 472aec6005
7 changed files with 121 additions and 44 deletions

View File

@ -87,7 +87,7 @@ export class Parser {
} }
private parseExpr(): Expr { private parseExpr(): Expr {
return this.parsePrefix(); return this.parseBinary();
} }
private parseBlock(): Expr { private parseBlock(): Expr {
@ -361,6 +361,114 @@ export class Parser {
return this.expr({ type: "if", cond, truthy, falsy }, pos); return this.expr({ type: "if", cond, truthy, falsy }, pos);
} }
private parseBinary(): Expr {
return this.parseOr();
}
private parseOr(): Expr {
const pos = this.pos();
let left = this.parseAnd();
while (true) {
if (this.test("or")) {
left = this.parBinTail(left, pos, this.parseAnd, "or");
} else {
break;
}
}
return left;
}
private parseAnd(): Expr {
const pos = this.pos();
let left = this.parseEquality();
while (true) {
if (this.test("and")) {
left = this.parBinTail(left, pos, this.parseEquality, "and");
} else {
break;
}
}
return left;
}
private parseEquality(): Expr {
const pos = this.pos();
const left = this.parseComparison();
if (this.test("==")) {
return this.parBinTail(left, pos, this.parseComparison, "==");
}
if (this.test("!=")) {
return this.parBinTail(left, pos, this.parseComparison, "!=");
}
return left;
}
private parseComparison(): Expr {
const pos = this.pos();
const left = this.parseAddSub();
if (this.test("<")) {
return this.parBinTail(left, pos, this.parseAddSub, "<");
}
if (this.test(">")) {
return this.parBinTail(left, pos, this.parseAddSub, ">");
}
if (this.test("<=")) {
return this.parBinTail(left, pos, this.parseAddSub, "<=");
}
if (this.test(">=")) {
return this.parBinTail(left, pos, this.parseAddSub, ">=");
}
return left;
}
private parseAddSub(): Expr {
const pos = this.pos();
let left = this.parseMulDiv();
while (true) {
if (this.test("+")) {
left = this.parBinTail(left, pos, this.parseMulDiv, "+");
continue;
}
if (this.test(".")) {
left = this.parBinTail(left, pos, this.parseMulDiv, "-");
continue;
}
break;
}
return left;
}
private parseMulDiv(): Expr {
const pos = this.pos();
let left = this.parsePrefix();
while (true) {
if (this.test("*")) {
left = this.parBinTail(left, pos, this.parsePrefix, "*");
continue;
}
if (this.test("/")) {
left = this.parBinTail(left, pos, this.parsePrefix, "/");
continue;
}
break;
}
return left;
}
private parBinTail(
left: Expr,
pos: Pos,
parseRight: (this: Parser) => Expr,
binaryType: BinaryType,
): Expr {
this.step();
const right = parseRight.call(this);
return this.expr(
{ type: "binary", binaryType, left, right },
pos,
);
}
private parsePrefix(): Expr { private parsePrefix(): Expr {
const pos = this.pos(); const pos = this.pos();
if (this.test("not")) { if (this.test("not")) {
@ -368,40 +476,9 @@ export class Parser {
const subject = this.parsePrefix(); const subject = this.parsePrefix();
return this.expr({ type: "unary", unaryType: "not", subject }, pos); return this.expr({ type: "unary", unaryType: "not", subject }, pos);
} }
for (
const binaryType of [
"+",
"*",
"==",
"-",
"/",
"!=",
"<",
">",
"<=",
">=",
"or",
"and",
]
) {
const subject = this.parseBinary(binaryType as BinaryType, pos);
if (subject !== null) {
return subject;
}
}
return this.parsePostfix(); return this.parsePostfix();
} }
private 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;
}
private parsePostfix(): Expr { private parsePostfix(): Expr {
let subject = this.parseOperand(); let subject = this.parseOperand();
while (true) { while (true) {

View File

@ -8,7 +8,7 @@ fn add(a: int, b: int) -> int {
let d = b; let d = b;
{ {
let a = c; let a = c;
+ a d a + d
} }
} }

View File

@ -1,5 +1,5 @@
fn main() -> int { fn main() -> int {
+ 1 2 1 + 2
} }

View File

@ -2,6 +2,6 @@
fn main() -> int { fn main() -> int {
let a = 5; let a = 5;
let b = 3; let b = 3;
+ a b a + b
} }

View File

@ -1,5 +1,5 @@
fn print(msg: string) #[builtin(print)] { fn print(msg: string) #[builtin(print)] {
+ "hello" 0 "hello" + 0
} }
fn main() { fn main() {

View File

@ -1,7 +1,7 @@
fn print(msg: string) #[builtin(print)] {} fn print(msg: string) #[builtin(print)] {}
fn sum(a: int, b: int) -> int { fn sum(a: int, b: int) -> int {
+ a b a + b
} }
fn main() { fn main() {
@ -11,9 +11,9 @@ fn main() {
let b = "world"; let b = "world";
print(+ + + a " " b "!\n"); // -> "Hello world!" print(a + " " + b + "!\n"); // -> "Hello world!"
if == a b { if a == b {
print("whaaaat\n"); print("whaaaat\n");
} }
else { else {
@ -23,10 +23,10 @@ fn main() {
loop { loop {
let i = 0; let i = 0;
if >= i 10 { if i >= 10 {
break; break;
} }
i = + i 1; i = i + 1;
} }
} }

View File

@ -1,16 +1,16 @@
fn add(a: int, b: int) -> int { fn add(a: int, b: int) -> int {
+ a b a + b
} }
fn main() -> int { fn main() -> int {
let result = 0; let result = 0;
let i = 0; let i = 0;
loop { loop {
if >= i 10 { if i >= 10 {
break; break;
} }
result = add(result, 5); result = add(result, 5);
i = + i 1; i = i + 1;
} }
result result
} }