Compare commits
No commits in common. "d83ade33d2c7af26c9fde377666064ca276ccff7" and "5d6b1abefc266c7ef377ceb958306dbce4923107" have entirely different histories.
d83ade33d2
...
5d6b1abefc
@ -170,6 +170,9 @@ 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
|
||||||
|
@ -73,7 +73,7 @@ class EliminateUnusedLocalsFnPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private markUsed(local: RValue) {
|
private markUsed(local: RValue) {
|
||||||
if (local.type !== "copy" && local.type !== "move") {
|
if (local.type !== "local") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.locals = this.locals.filter((lid) => lid !== local.id);
|
this.locals = this.locals.filter((lid) => lid !== local.id);
|
||||||
|
@ -13,7 +13,7 @@ class LocalExpliciter {
|
|||||||
private copyable: boolean;
|
private copyable: boolean;
|
||||||
|
|
||||||
public constructor(private fn: Fn, private local: Local) {
|
public constructor(private fn: Fn, private local: Local) {
|
||||||
this.copyable = copyableIsType(this.local.vtype);
|
this.copyable = copyableIsType(local.vtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
public pass() {
|
public pass() {
|
||||||
@ -23,7 +23,7 @@ class LocalExpliciter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private explicitSrc(src: RValue): RValue {
|
private explicitSrc(src: RValue): RValue {
|
||||||
if (src.type !== "move" || src.id !== this.local.id) {
|
if (src.type !== "local") {
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
return this.copyable
|
return this.copyable
|
||||||
@ -41,10 +41,8 @@ function copyableIsType(vtype: VType): boolean {
|
|||||||
case "int":
|
case "int":
|
||||||
case "bool":
|
case "bool":
|
||||||
case "string":
|
case "string":
|
||||||
return true;
|
|
||||||
case "ref":
|
case "ref":
|
||||||
case "ref_mut":
|
case "ref_mut":
|
||||||
return false;
|
|
||||||
case "ptr":
|
case "ptr":
|
||||||
case "ptr_mut":
|
case "ptr_mut":
|
||||||
return true;
|
return true;
|
||||||
|
@ -509,5 +509,5 @@ class FnAstLowerer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function local(id: LocalId): RValue {
|
function local(id: LocalId): RValue {
|
||||||
return { type: "move", id };
|
return { type: "local", id };
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ 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 }
|
||||||
@ -66,6 +67,7 @@ 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" }
|
||||||
@ -121,6 +123,7 @@ 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);
|
||||||
@ -187,6 +190,7 @@ 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);
|
||||||
@ -303,6 +307,9 @@ 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;
|
||||||
@ -365,6 +372,8 @@ 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":
|
||||||
|
@ -1,164 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user