diff --git a/compiler/middle/borrow_checker.ts b/compiler/middle/borrow_checker.ts index 8cb536d..fc58f99 100644 --- a/compiler/middle/borrow_checker.ts +++ b/compiler/middle/borrow_checker.ts @@ -170,9 +170,6 @@ class LocalChecker { } private markSrc(src: RValue) { - if (src.type === "local") { - throw new Error("should be 'copy' or 'move'"); - } if ( (src.type !== "copy" && src.type !== "move") || src.id !== this.local.id diff --git a/compiler/middle/elim_unused_local.ts b/compiler/middle/elim_unused_local.ts index 67b551a..3feca87 100644 --- a/compiler/middle/elim_unused_local.ts +++ b/compiler/middle/elim_unused_local.ts @@ -73,7 +73,7 @@ class EliminateUnusedLocalsFnPass { } private markUsed(local: RValue) { - if (local.type !== "local") { + if (local.type !== "copy" && local.type !== "move") { return; } this.locals = this.locals.filter((lid) => lid !== local.id); diff --git a/compiler/middle/explicit_move_copy.ts b/compiler/middle/explicit_move_copy.ts index 533bec4..6927220 100644 --- a/compiler/middle/explicit_move_copy.ts +++ b/compiler/middle/explicit_move_copy.ts @@ -23,7 +23,7 @@ class LocalExpliciter { } private explicitSrc(src: RValue): RValue { - if (src.type !== "local" || src.id !== this.local.id) { + if (src.type !== "move" || src.id !== this.local.id) { return src; } return this.copyable diff --git a/compiler/middle/lower_ast.ts b/compiler/middle/lower_ast.ts index 8c1b408..c0ae402 100644 --- a/compiler/middle/lower_ast.ts +++ b/compiler/middle/lower_ast.ts @@ -509,5 +509,5 @@ class FnAstLowerer { } function local(id: LocalId): RValue { - return { type: "local", id }; + return { type: "move", id }; } diff --git a/compiler/middle/mir.ts b/compiler/middle/mir.ts index 128e384..d6585cc 100644 --- a/compiler/middle/mir.ts +++ b/compiler/middle/mir.ts @@ -45,7 +45,6 @@ export type OpKind = | { type: "ref_mut"; dst: L; src: L } | { type: "ptr"; dst: L; src: L } | { type: "ptr_mut"; dst: L; src: L } - | { type: "drop"; src: L } | { type: "deref"; dst: L; src: R } | { type: "assign_deref"; subject: R; src: R } | { type: "field"; dst: L; subject: R; ident: string } @@ -67,7 +66,6 @@ export type TerKind = export type RValue = | { type: "error" } - | { type: "local"; id: BlockId } | { type: "copy"; id: BlockId } | { type: "move"; id: BlockId } | { type: "null" } @@ -123,7 +121,6 @@ export function replaceBlockSrcs( case "ref_mut": case "ptr": case "ptr_mut": - case "drop": break; case "deref": ok.src = replace(ok.src); @@ -190,7 +187,6 @@ export function visitBlockSrcs( case "ref_mut": case "ptr": case "ptr_mut": - case "drop": break; case "deref": visitor(ok.src, op, i); @@ -307,9 +303,6 @@ export function printMir(mir: Mir) { case "ptr_mut": l(`_${k.dst} = *mut _${k.src};`); break; - case "drop": - l(`drop _${k.src};`); - break; case "deref": l(`_${k.dst} = *${r(k.src)};`); break; @@ -372,8 +365,6 @@ export function rvalueToString(rvalue: RValue): string { switch (rvalue.type) { case "error": return ``; - case "local": - return `_${rvalue.id}`; case "copy": return `copy _${rvalue.id}`; case "move": diff --git a/examples/calculator.slg b/examples/calculator.slg new file mode 100644 index 0000000..d9021e1 --- /dev/null +++ b/examples/calculator.slg @@ -0,0 +1,164 @@ +mod std; + +type_alias Tok: struct { + type: string, + value: string, +}; + +fn lex(text: string) -> [Tok] { + let i = 0; + let len = std::string_length(text); + + let toks = std::array_new::(); + + while i < len { + if std::string_contains(" \t\n", text[i]) { + i += 1; + if i >= len { + break; + } + } + if text[i] >= '1' and text[i] <= '9' { + let value = std::ctos(text[i]); + i += 1; + while i < len and text[i] >= '0' and text[i] <= '9' { + value = std::string_push_char(value, text[i]); + i += 1; + } + let tok = struct { type: "int", value: value }; + std::array_push(toks, tok); + } else if text[i] == '0' { + i += 1; + let tok = struct { type: "int", value: "0" }; + std::array_push(toks, tok); + } else if text[i] == '+' { + i += 1; + let tok = struct { type: "+", value: "+" }; + std::array_push(toks, tok); + } else if text[i] == '-' { + i += 1; + let tok = struct { type: "-", value: "-" }; + std::array_push(toks, tok); + } else if text[i] == '*' { + i += 1; + let tok = struct { type: "*", value: "*" }; + std::array_push(toks, tok); + } else if text[i] == '/' { + i += 1; + let tok = struct { type: "/", value: "/" }; + std::array_push(toks, tok); + } else if text[i] == '(' { + i += 1; + let tok = struct { type: "(", value: "(" }; + std::array_push(toks, tok); + } else if text[i] == ')' { + i += 1; + let tok = struct { type: ")", value: ")" }; + std::array_push(toks, tok); + } else { + std::println("error: illegal character '" + std::ctos(text[i]) + "'"); + i += 1; + } + } + + toks +} + +type_alias Calc: struct { + toks: [Tok], + toks_len: int, + i: int, +}; + +fn calc_new(text: string) -> Calc { + let toks = lex(text); + let toks_len = std::array_length(toks); + struct { toks: toks, toks_len: toks_len, i: 0 } +} + +fn calc_expr(self: Calc) -> int { + calc_add_sub(self) +} + +fn calc_add_sub(self: Calc) -> int { + let left = calc_mul_div(self); + loop { + if self.toks[self.i].type == "+" { + self.i += 1; + let right = calc_mul_div(self); + left = left + right; + } else if self.toks[self.i].type == "-" { + self.i += 1; + let right = calc_mul_div(self); + left = left - right; + } else { + break; + } + } + left +} + +fn calc_mul_div(self: Calc) -> int { + let left = calc_unary(self); + loop { + if self.toks[self.i].type == "*" { + self.i += 1; + let right = calc_unary(self); + left = left * right; + } else if self.toks[self.i].type == "/" { + self.i += 1; + let right = calc_unary(self); + left = left / right; + } else { + break; + } + } + left + +} + +fn calc_unary(self: Calc) -> int { + if self.toks[self.i].type == "-" { + self.i += 1; + let subject = calc_unary(self); + -subject + } else { + calc_operand(self) + } +} + +fn calc_operand(self: Calc) -> int { + if self.i >= self.toks_len { + std::println("error: expected expr"); + 0 + } else if self.toks[self.i].type == "int" { + let val = std::stoi(self.toks[self.i].value); + self.i += 1; + val + } else if self.toks[self.i].type == "(" { + self.i += 1; + let val = calc_expr(self); + if self.i >= self.toks_len or self.toks[self.i].type != ")" { + std::println("error: missing ')'"); + return 0; + } + self.i += 1; + val + } else { + std::println("error: expected expr"); + self.i += 1; + 0 + } +} + +fn main() { + loop { + let line = std::input("> "); + if line == "exit" { + break; + } + let calc = calc_new(line); + let val = calc_expr(calc); + std::println(line); + } +}