improved pointers
All checks were successful
Check / Explore-Gitea-Actions (push) Successful in 7s

This commit is contained in:
sfja 2026-03-11 23:48:04 +01:00
parent cf36151115
commit 21e569e9ff
3 changed files with 26 additions and 16 deletions

View File

@ -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 };

View File

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

View File

@ -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 --"