You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
14 KiB
355 lines
14 KiB
import swc from "npm:@swc/wasm@1.3.35";
|
|
import { resolveNode } from "../index.ts";
|
|
|
|
export default function WhileStatement(
|
|
node: swc.Node,
|
|
variablesTable: VariablesTableType,
|
|
variableModificationThings: VariablesThingType,
|
|
prc: { count: number },
|
|
mainInstructions: string[],
|
|
) {
|
|
const typedNode = node as swc.WhileStatement;
|
|
switch (typedNode.test.type) {
|
|
case "BinaryExpression": {
|
|
const typedExpr = typedNode.test as swc.BinaryExpression;
|
|
switch (typedExpr.operator) {
|
|
case "==":
|
|
case "===": {
|
|
let addr1: number;
|
|
let addr2: number;
|
|
switch (typedExpr.left.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.left;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr1 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
"probably something idk i don't feel like writing error messages anymore",
|
|
);
|
|
}
|
|
switch (typedExpr.right.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.right;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr2 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
"probably something idk i don't feel like writing error messages anymore",
|
|
);
|
|
}
|
|
let ourInsts = [`JMP TODO`];
|
|
prc.count += 3;
|
|
const oldPRC = prc;
|
|
for (
|
|
const node of (typedNode.body as swc.BlockStatement)
|
|
.stmts
|
|
) {
|
|
ourInsts = ourInsts.concat(
|
|
resolveNode(
|
|
node,
|
|
prc,
|
|
variableModificationThings,
|
|
variablesTable,
|
|
),
|
|
);
|
|
}
|
|
ourInsts[0] = ourInsts[0].replace(
|
|
"TODO",
|
|
prc.count.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
),
|
|
);
|
|
|
|
ourInsts.push(`JEA ${
|
|
oldPRC.count.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr1.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr2.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`);
|
|
prc.count += 7;
|
|
|
|
for (const inst of ourInsts) {
|
|
mainInstructions.push(inst);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case "!=":
|
|
case "!==": {
|
|
let addr1: number;
|
|
let addr2: number;
|
|
switch (typedExpr.left.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.left;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr1 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const value = typedExpr.left.value;
|
|
mainInstructions.push(
|
|
`LOL ${
|
|
value.toString(16).padStart(
|
|
2,
|
|
"0",
|
|
)
|
|
} 00F1`,
|
|
);
|
|
addr1 = 0x00F1;
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
"probably something idk i don't feel like writing error messages anymore",
|
|
);
|
|
}
|
|
switch (typedExpr.right.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.right;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr2 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const value = typedExpr.right.value;
|
|
mainInstructions.push(
|
|
`LOL ${
|
|
value.toString(16).padStart(
|
|
2,
|
|
"0",
|
|
)
|
|
} 00F2`,
|
|
);
|
|
addr2 = 0x00F2;
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`probably something to do with ${typedExpr.right.type} idk i don't feel like writing error messages anymore`,
|
|
);
|
|
}
|
|
let ourInsts = [`JML TODO`];
|
|
prc.count += 3;
|
|
const oldPRC = prc.count;
|
|
for (
|
|
const node of (typedNode.body as swc.BlockStatement)
|
|
.stmts
|
|
) {
|
|
ourInsts = ourInsts.concat(
|
|
resolveNode(
|
|
node,
|
|
prc,
|
|
variableModificationThings,
|
|
variablesTable,
|
|
),
|
|
);
|
|
}
|
|
ourInsts[0] = ourInsts[0].replace(
|
|
"TODO",
|
|
prc.count.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
),
|
|
);
|
|
|
|
ourInsts.push(`JNA ${
|
|
oldPRC.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr1.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr2.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`);
|
|
prc.count += 7;
|
|
|
|
for (const inst of ourInsts) {
|
|
mainInstructions.push(inst);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case ">": {
|
|
let addr1: number;
|
|
let addr2: number;
|
|
switch (typedExpr.left.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.left;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr1 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const value = typedExpr.left.value;
|
|
mainInstructions.push(
|
|
`LOL ${
|
|
value.toString(16).padStart(
|
|
2,
|
|
"0",
|
|
)
|
|
} 00F1`,
|
|
);
|
|
addr1 = 0x00F1;
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
"probably something idk i don't feel like writing error messages anymore",
|
|
);
|
|
}
|
|
switch (typedExpr.right.type) {
|
|
case "Identifier": {
|
|
const typedValue = typedExpr.right;
|
|
const variableInfo =
|
|
variablesTable[typedValue.value];
|
|
if (variableInfo.memoryType === "string") {
|
|
// TODO: implement string comparisons
|
|
throw new Error(
|
|
"i would rather pipi in pampers than implement string comparisons",
|
|
);
|
|
}
|
|
addr2 = variableInfo.memoryLocation;
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const value = typedExpr.right.value;
|
|
mainInstructions.push(
|
|
`LOL ${
|
|
value.toString(16).padStart(
|
|
2,
|
|
"0",
|
|
)
|
|
} 00F2`,
|
|
);
|
|
addr2 = 0x00F2;
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`probably something to do with ${typedExpr.right.type} idk i don't feel like writing error messages anymore`,
|
|
);
|
|
}
|
|
let ourInsts = [`JML TODO`];
|
|
prc.count += 3;
|
|
const oldPRC = prc.count;
|
|
for (
|
|
const node of (typedNode.body as swc.BlockStatement)
|
|
.stmts
|
|
) {
|
|
ourInsts = ourInsts.concat(
|
|
resolveNode(
|
|
node,
|
|
prc,
|
|
variableModificationThings,
|
|
variablesTable,
|
|
),
|
|
);
|
|
}
|
|
|
|
ourInsts[0] = ourInsts[0].replace(
|
|
"TODO",
|
|
prc.count.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
),
|
|
);
|
|
|
|
ourInsts.push(`JGT ${
|
|
oldPRC.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr1.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
addr2.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`);
|
|
prc.count += 7;
|
|
|
|
for (const inst of ourInsts) {
|
|
mainInstructions.push(inst);
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`comparison operator ${typedExpr.operator} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`if statement test with node type ${typedNode.test.type} not implemented`,
|
|
);
|
|
}
|
|
}
|