This commit is contained in:
parent
cf36151115
commit
21e569e9ff
@ -2,7 +2,6 @@ import * as mir from "./middle.ts";
|
||||
|
||||
export class FnInterpreter {
|
||||
private regs = new Map<mir.Inst, Val>();
|
||||
private locals: (Val | null)[] = [];
|
||||
private bb: mir.BasicBlock;
|
||||
private instIdx = 0;
|
||||
|
||||
@ -42,33 +41,31 @@ export class FnInterpreter {
|
||||
break;
|
||||
}
|
||||
case "Alloca": {
|
||||
const localIdx = this.locals.length;
|
||||
this.locals.push(null);
|
||||
this.regs.set(
|
||||
inst,
|
||||
new Val({ tag: "LocalPtr", localIdx, mutable: true }),
|
||||
new Val({
|
||||
tag: "Ptr",
|
||||
mutable: true,
|
||||
value: new Val({ tag: "Null" }),
|
||||
}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "Load": {
|
||||
const source = this.regs.get(k.source);
|
||||
if (!source || source.kind.tag !== "LocalPtr") {
|
||||
const source = this.regs.get(k.source)!;
|
||||
if (source.kind.tag !== "Ptr") {
|
||||
throw new Error();
|
||||
}
|
||||
const value = this.locals[source.kind.localIdx];
|
||||
if (!value) {
|
||||
throw new Error();
|
||||
}
|
||||
this.regs.set(inst, value);
|
||||
this.regs.set(inst, source.kind.value);
|
||||
break;
|
||||
}
|
||||
case "Store": {
|
||||
const target = this.regs.get(k.target)!;
|
||||
if (target.kind.tag !== "LocalPtr") {
|
||||
if (target.kind.tag !== "Ptr") {
|
||||
throw new Error();
|
||||
}
|
||||
const source = this.regs.get(k.source)!;
|
||||
this.locals[target.kind.localIdx] = source;
|
||||
target.kind.value = source;
|
||||
break;
|
||||
}
|
||||
case "Jump": {
|
||||
@ -207,12 +204,14 @@ class Val {
|
||||
pretty() {
|
||||
const k = this.kind;
|
||||
switch (k.tag) {
|
||||
case "Null":
|
||||
return "<null>";
|
||||
case "Void":
|
||||
return "void";
|
||||
case "Int":
|
||||
case "Bool":
|
||||
return `${k.value}`;
|
||||
case "LocalPtr":
|
||||
case "Ptr":
|
||||
return `<pointer>`;
|
||||
case "Fn":
|
||||
return `<${k.fn.ty.pretty()}>`;
|
||||
@ -223,8 +222,9 @@ class Val {
|
||||
}
|
||||
|
||||
type ValKind =
|
||||
| { tag: "Null" }
|
||||
| { tag: "Void" }
|
||||
| { tag: "Int"; value: number }
|
||||
| { tag: "Bool"; value: boolean }
|
||||
| { tag: "LocalPtr"; mutable: boolean; localIdx: number }
|
||||
| { tag: "Ptr"; mutable: boolean; value: Val }
|
||||
| { tag: "Fn"; fn: mir.Fn };
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
|
||||
fn change_to(place: *mut int, value: int)
|
||||
{
|
||||
*place = value;
|
||||
}
|
||||
|
||||
fn main()
|
||||
{
|
||||
let a = 1;
|
||||
@ -19,5 +24,10 @@ fn main()
|
||||
print_int(a);
|
||||
// expect: 3
|
||||
print_int(*c);
|
||||
|
||||
change_to(&mut a, 4);
|
||||
|
||||
// expect: 4
|
||||
print_int(a);
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ run_test_file() {
|
||||
then
|
||||
if grep -q '// expect:' $file
|
||||
then
|
||||
expected=$(grep '// expect:' $file | sed -E 's/\s*\/\/\s+expect: (.*?)/\1/g')
|
||||
expected=$(grep '// expect:' $file | sed -E 's/\s*\/\/\s+expect:\s*(.*?)\s*/\1/g')
|
||||
if [[ $output != $expected ]]
|
||||
then
|
||||
echo "-- failed: incorrect output --"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user