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

View File

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

View File

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