Skip to content

Commit

Permalink
Fix label generation for recursive sub functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
quisar committed Dec 29, 2023
1 parent 8cff47f commit 3b0791e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 49 deletions.
87 changes: 38 additions & 49 deletions decompile/disasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,19 @@ import { RawInstruction } from "./RawInstruction";
import { instructions } from "./dsinstr";
import { DesyncedStringToObject } from "../dsconvert";

interface Work<T> {
t: T;
done: boolean;
}

export class Dissasembler {
output: string[] = [];
extraBehaviors: Work<RawBehavior>[] = [];
subs: Work<RawBehavior>[] = [];
bps: Work<RawBlueprint>[] = [];
mainBehavior?: RawBehavior;
extraBehaviors: RawBehavior[] = [];
bps: RawBlueprint[] = [];
nextLabel = 0;

constructor(obj: Record<string, unknown>) {
this.#label("main");
if ("frame" in obj) {
this.blueprint(obj as unknown as RawBlueprint);
} else {
this.disasemble(obj as unknown as RawBehavior);
this.mainBehavior = obj as unknown as RawBehavior;
}
this.#doExtras();
}
Expand Down Expand Up @@ -62,7 +57,7 @@ export class Dissasembler {
if (obj.components) {
for (const [v, k, code] of obj.components) {
if (code) {
this.extraBehaviors.push({ t: code, done: false });
this.extraBehaviors.push(code);
this.#emit(
`.component`,
k,
Expand All @@ -76,7 +71,7 @@ export class Dissasembler {
}
}

disasemble(obj: RawBehavior, main = "main") {
disasemble(obj: RawBehavior, main = "main", subOffset = 0) {
if (obj.name) {
this.#emit(".name", obj.name);
}
Expand All @@ -90,12 +85,6 @@ export class Dissasembler {
this.#emit(".out", reg);
}
});
const subOffset = this.subs.length;
if (obj.subs) {
for (const sub of obj.subs) {
this.subs.push({ t: sub, done: false });
}
}
const labels = this.#buildLabels(obj);
for (let i = 0; `${i}` in obj; i++) {
this.#emitInstr(obj[`${i}`], i, labels, subOffset, main);
Expand Down Expand Up @@ -158,7 +147,7 @@ export class Dissasembler {
if (typeof inst.bp == "string") {
inst.bp = DesyncedStringToObject("DSB" + inst.bp) as RawBlueprint;
}
this.bps.push({ t: inst.bp, done: false });
this.bps.push(inst.bp);
args.push({ id: `$bp=:bp${this.bps.length}` });
}
if (inst.nx != null && inst.ny != null) {
Expand Down Expand Up @@ -199,39 +188,39 @@ export class Dissasembler {
}

#doExtras() {
let count = 0;
do {
count = 0;
this.extraBehaviors.forEach((w, i) => {
if (!w.done) {
this.#nl(2);
this.#label(`behavior${i + 1}`);
this.#emit(".behavior");
this.disasemble(w.t, `behavior${i + 1}`);
w.done = true;
count++;
}
});
this.subs.forEach((w, i) => {
if (!w.done) {
this.#nl(2);
this.#label(`sub${i + 1}`);
this.#emit(".sub");
this.disasemble(w.t);
w.done = true;
count++;
}
if (this.mainBehavior) {
this.disasemble(this.mainBehavior);
this.mainBehavior.subs?.forEach((sub, i) => {
this.#nl(2);
this.#label(`sub${i + 1}`);
this.#emit(".sub");
this.disasemble(sub);
});
this.bps.forEach((w, i) => {
if (!w.done) {
this.#nl(2);
this.#label(`bp${i + 1}`);
this.blueprint(w.t);
w.done = true;
count++;
}
}

let subOffset = 0;
this.extraBehaviors.forEach((behavior, i) => {
let mainName = `behavior${i + 1}`;

this.#nl(2);
this.#label(mainName);
this.#emit(".behavior");
this.disasemble(behavior, mainName, subOffset);

behavior.subs?.forEach((sub, i) => {
this.#nl(2);
this.#label(`sub${i + subOffset + 1}`);
this.#emit(".sub");
this.disasemble(sub, mainName, subOffset);
});
} while (count);
subOffset += behavior.subs?.length || 0;
});

this.bps.forEach((bp, i) => {
this.#nl(2);
this.#label(`bp${i + 1}`);
this.blueprint(bp);
});
}

#nl(count = 1) {
Expand Down
43 changes: 43 additions & 0 deletions tests/__snapshots__/disas.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,9 +1,52 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`bp_multi_behavior.txt 1`] = `
"main:
.blueprint "f_building1x1d"
.component 2, c_behavior, :behavior1
.component 3, c_behavior, :behavior2
behavior1:
.behavior
.name "Call sub1"
call $sub=:sub1
sub1:
.sub
.name "sub1"
behavior2:
.behavior
.name "Call sub2"
call $sub=:sub2
sub2:
.sub
.name "sub2""
`;

exports[`issue2.txt 1`] = `
"main:
.name "foo"
label0:
set_reg goto, goto
jump :label0"
`;

exports[`recurse.txt 1`] = `
"main:
.name "foo"
call $sub=:sub1
.ret
sub1:
.sub
.name "bar"
call $sub=:sub1
.ret "
`;
1 change: 1 addition & 0 deletions tests/bp_multi_behavior.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DSB7c47wZia0ojrO40gBQMf0KrwDF1Z8gYF36DAbJ2oAQfp3AlOO11PlQrM2g6NRs0PUAgV0tHPAj1Pd9O20EeuWY1d3FA40LVkEI0hFzYB0oI4Im3fl0IM1oPuiG2OUTl90jpKTA10t1qY0dk4vv491mUO2fv13g4SYQyy4Syf1n2X1Bcg3cPVpB4DbAaV32MbnY32aLH902ShHY2XoyoT0Vi71b
1 change: 1 addition & 0 deletions tests/recurse.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DSC3o1r9XCa1mbcCg0ffnYQ2QawfP1nmBRx4cqQm63cYPmE0Dwzqv2oOsnz1MW5bE2dsPxX2qfFxQ1Xm7qs0knnqO1j3MRt3ZamrS318qgc3JGVyE0felf24AeyHfGWfe

0 comments on commit 3b0791e

Please sign in to comment.