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