This commit is contained in:
sfja 2025-01-20 02:17:05 +01:00
parent 9cb145d97e
commit d83ade33d2
6 changed files with 167 additions and 15 deletions

View File

@ -170,9 +170,6 @@ class LocalChecker {
} }
private markSrc(src: RValue) { private markSrc(src: RValue) {
if (src.type === "local") {
throw new Error("should be 'copy' or 'move'");
}
if ( if (
(src.type !== "copy" && src.type !== "move") || (src.type !== "copy" && src.type !== "move") ||
src.id !== this.local.id src.id !== this.local.id

View File

@ -73,7 +73,7 @@ class EliminateUnusedLocalsFnPass {
} }
private markUsed(local: RValue) { private markUsed(local: RValue) {
if (local.type !== "local") { if (local.type !== "copy" && local.type !== "move") {
return; return;
} }
this.locals = this.locals.filter((lid) => lid !== local.id); this.locals = this.locals.filter((lid) => lid !== local.id);

View File

@ -23,7 +23,7 @@ class LocalExpliciter {
} }
private explicitSrc(src: RValue): RValue { 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 src;
} }
return this.copyable return this.copyable

View File

@ -509,5 +509,5 @@ class FnAstLowerer {
} }
function local(id: LocalId): RValue { function local(id: LocalId): RValue {
return { type: "local", id }; return { type: "move", id };
} }

View File

@ -45,7 +45,6 @@ export type OpKind =
| { type: "ref_mut"; dst: L; src: L } | { type: "ref_mut"; dst: L; src: L }
| { type: "ptr"; dst: L; src: L } | { type: "ptr"; dst: L; src: L }
| { type: "ptr_mut"; dst: L; src: L } | { type: "ptr_mut"; dst: L; src: L }
| { type: "drop"; src: L }
| { type: "deref"; dst: L; src: R } | { type: "deref"; dst: L; src: R }
| { type: "assign_deref"; subject: R; src: R } | { type: "assign_deref"; subject: R; src: R }
| { type: "field"; dst: L; subject: R; ident: string } | { type: "field"; dst: L; subject: R; ident: string }
@ -67,7 +66,6 @@ export type TerKind =
export type RValue = export type RValue =
| { type: "error" } | { type: "error" }
| { type: "local"; id: BlockId }
| { type: "copy"; id: BlockId } | { type: "copy"; id: BlockId }
| { type: "move"; id: BlockId } | { type: "move"; id: BlockId }
| { type: "null" } | { type: "null" }
@ -123,7 +121,6 @@ export function replaceBlockSrcs(
case "ref_mut": case "ref_mut":
case "ptr": case "ptr":
case "ptr_mut": case "ptr_mut":
case "drop":
break; break;
case "deref": case "deref":
ok.src = replace(ok.src); ok.src = replace(ok.src);
@ -190,7 +187,6 @@ export function visitBlockSrcs(
case "ref_mut": case "ref_mut":
case "ptr": case "ptr":
case "ptr_mut": case "ptr_mut":
case "drop":
break; break;
case "deref": case "deref":
visitor(ok.src, op, i); visitor(ok.src, op, i);
@ -307,9 +303,6 @@ export function printMir(mir: Mir) {
case "ptr_mut": case "ptr_mut":
l(`_${k.dst} = *mut _${k.src};`); l(`_${k.dst} = *mut _${k.src};`);
break; break;
case "drop":
l(`drop _${k.src};`);
break;
case "deref": case "deref":
l(`_${k.dst} = *${r(k.src)};`); l(`_${k.dst} = *${r(k.src)};`);
break; break;
@ -372,8 +365,6 @@ export function rvalueToString(rvalue: RValue): string {
switch (rvalue.type) { switch (rvalue.type) {
case "error": case "error":
return `<error>`; return `<error>`;
case "local":
return `_${rvalue.id}`;
case "copy": case "copy":
return `copy _${rvalue.id}`; return `copy _${rvalue.id}`;
case "move": case "move":

164
examples/calculator.slg Normal file
View File

@ -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::<Tok>();
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);
}
}