Skip to content

Commit

Permalink
Fix calling main recursively
Browse files Browse the repository at this point in the history
  • Loading branch information
quisar committed Dec 29, 2023
1 parent f66b346 commit 8cff47f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
21 changes: 16 additions & 5 deletions assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface AsmInstr {
type NamedInstrs = Map<string, AsmInstr[]>;

interface Program {
mainLabel?: string;
main: AsmInstr[];
subs: NamedInstrs;
others: NamedInstrs; // Other behavriors for use in blueprints
Expand Down Expand Up @@ -139,7 +140,9 @@ export async function assemble(
code: string
): Promise<RawBehavior | RawBlueprint> {
let instructions = parseAssembly(code);
const mainLabel = instructions[0]?.labels[0];
const program: Program = {
mainLabel,
main: instructions,
subs: new Map(),
others: new Map(),
Expand Down Expand Up @@ -189,7 +192,7 @@ class Assembler {
params: boolean[] = []; // true if parameter is modified, false if read only

constructor(public program: Program) {
this.subs = findReferencedSubs(program.main, program.subs);
this.subs = findReferencedSubs(program);
}

assembleBlueprint(): RawBlueprint {
Expand Down Expand Up @@ -613,8 +616,12 @@ class Assembler {
} else if (a == "nil") {
return undefined;
} else if (key == "sub") {
let subName = a.substring(1);
if (subName === this.program.mainLabel) {
return 0;
}
return (
this.subs.find((v) => v.name == a.substring(1))?.label ?? undefined
this.subs.find((v) => v.name == subName)?.label ?? undefined
);
} else if (key == "txt") {
return a;
Expand Down Expand Up @@ -661,14 +668,18 @@ class Assembler {
}
}

function findReferencedSubs(code: AsmInstr[], subs: NamedInstrs): SubInfo[] {
function findReferencedSubs(program: Program): SubInfo[] {
const result = new Map<string, SubInfo>();
code.forEach((i) => {
program.main.forEach((i) => {
if (i.op == "call") {
const subArg = i.args.find((a) => a.startsWith("$sub="))?.substring(5);
if (!subArg) return;
const subName = subArg.substring(1);
const sub = subs.get(subName);
if (subName === program.mainLabel) {
// This is a recursive call to the initial function.
return;
}
const sub = program.subs.get(subName);
if (!sub || !subArg.startsWith(":")) {
throw new Error(`Sub ${subArg} not found at line ${i.lineno}`);
}
Expand Down
12 changes: 12 additions & 0 deletions tests/__snapshots__/assembler.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,15 @@ exports[`empty.asm 1`] = `
"parameters": [],
}
`

exports[`recurse_main.asm 1`] = `
{
"0": {
"next": false,
"op": "call",
"sub": 0,
},
"name": "foo",
"parameters": [],
}
`;
4 changes: 4 additions & 0 deletions tests/recurse_main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
foo:
.name "foo"
call $sub=:foo
.ret

0 comments on commit 8cff47f

Please sign in to comment.