diff --git a/src/mir_interpreter.ts b/src/mir_interpreter.ts index 18097e3..f5369c4 100644 --- a/src/mir_interpreter.ts +++ b/src/mir_interpreter.ts @@ -2,7 +2,6 @@ import * as mir from "./middle.ts"; export class FnInterpreter { private regs = new Map(); - 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 ""; case "Void": return "void"; case "Int": case "Bool": return `${k.value}`; - case "LocalPtr": + case "Ptr": return ``; 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 }; diff --git a/tests/pointer.ethlang b/tests/pointer.ethlang index b78af91..a693c72 100644 --- a/tests/pointer.ethlang +++ b/tests/pointer.ethlang @@ -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); } diff --git a/tests/test.sh b/tests/test.sh index 7432ac7..0b42ad5 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -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 --"