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.
326 lines
15 KiB
326 lines
15 KiB
import swc from "npm:@swc/wasm@1.3.35";
|
|
|
|
export default function VariableDeclaration(
|
|
node: swc.Node,
|
|
variablesTable: VariablesTableType,
|
|
variableModificationThings: VariablesThingType,
|
|
prc: { count: number },
|
|
instructions: string[],
|
|
) {
|
|
const typedNode = node as swc.VariableDeclaration;
|
|
switch (typedNode.declarations[0].init?.type) {
|
|
case "StringLiteral": {
|
|
const typedValue = typedNode.declarations[0]
|
|
.init as swc.StringLiteral;
|
|
variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
] = {
|
|
memorySize: typedValue.value.length,
|
|
memoryLocation: variableModificationThings
|
|
.getVariableMemoryOffset(typedValue.value.length),
|
|
memoryType: "string",
|
|
};
|
|
for (let i = 0; i < typedValue.value.length; i++) {
|
|
const char = typedValue.value[i];
|
|
const charCode = char.charCodeAt(0);
|
|
instructions.push(
|
|
`LOL ${charCode.toString(16).padStart(2, "0")} ${
|
|
(variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier)
|
|
.value
|
|
].memoryLocation + i).toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 4;
|
|
}
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const typedValue = typedNode.declarations[0]
|
|
.init as swc.NumericLiteral;
|
|
if (typedValue.value > 255) {
|
|
// TODO: implement 16-bit etc.
|
|
throw new Error("only 8-bit integers allowed");
|
|
}
|
|
if (
|
|
!variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
]
|
|
) {
|
|
variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
] = {
|
|
memorySize: 1,
|
|
memoryLocation: variableModificationThings
|
|
.getVariableMemoryOffset(1),
|
|
memoryType: "int",
|
|
};
|
|
}
|
|
instructions.push(
|
|
`LOL ${typedValue.value.toString(16).padStart(2, "0")} ${
|
|
variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
].memoryLocation.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
case "BooleanLiteral": {
|
|
const typedValue = typedNode.declarations[0]
|
|
.init as swc.BooleanLiteral;
|
|
if (
|
|
!variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
]
|
|
) {
|
|
variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
] = {
|
|
memorySize: 1,
|
|
memoryLocation: variableModificationThings
|
|
.getVariableMemoryOffset(1),
|
|
memoryType: "bool",
|
|
};
|
|
}
|
|
instructions.push(
|
|
`LOL ${typedValue.value ? "01" : "00"} ${
|
|
variablesTable[
|
|
(typedNode.declarations[0].id as swc.Identifier).value
|
|
].memoryLocation.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 4;
|
|
break;
|
|
}
|
|
// FIXME: this should be impled elsewhere, especially because recursion
|
|
case "BinaryExpression": {
|
|
const typedValue = typedNode.declarations[0]
|
|
.init as swc.BinaryExpression;
|
|
switch (typedValue.operator) {
|
|
case "+": {
|
|
switch (typedValue.left.type) {
|
|
case "Identifier": {
|
|
switch (typedValue.right.type) {
|
|
case "Identifier": {
|
|
const leftVar = variablesTable[
|
|
typedValue.left.value
|
|
];
|
|
const rightVar = variablesTable[
|
|
typedValue.right.value
|
|
];
|
|
instructions.push(
|
|
`AAA ${
|
|
leftVar.memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
rightVar.memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 5;
|
|
if (
|
|
!variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
]
|
|
) {
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
] = {
|
|
memorySize: 1,
|
|
memoryLocation:
|
|
variableModificationThings
|
|
.getVariableMemoryOffset(1),
|
|
memoryType: "int",
|
|
};
|
|
}
|
|
instructions.push(
|
|
`STA ${
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
].memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 3;
|
|
break;
|
|
}
|
|
case "NumericLiteral": {
|
|
const leftVar = variablesTable[
|
|
typedValue.left.value
|
|
];
|
|
const rightVal = typedValue.right.value;
|
|
instructions.push(
|
|
`LOL ${
|
|
rightVal.toString(16).padStart(
|
|
2,
|
|
"0",
|
|
)
|
|
} 00F0`,
|
|
);
|
|
prc.count += 4;
|
|
instructions.push(
|
|
`AAA ${
|
|
leftVar.memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} 00F0`,
|
|
);
|
|
prc.count += 5;
|
|
if (
|
|
!variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
]
|
|
) {
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
] = {
|
|
memorySize: 1,
|
|
memoryLocation:
|
|
variableModificationThings
|
|
.getVariableMemoryOffset(1),
|
|
memoryType: "int",
|
|
};
|
|
}
|
|
instructions.push(
|
|
`STA ${
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
].memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 3;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Arithmetic on ${typedValue.right.type} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Arithmetic on ${typedValue.left.type} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
case "-": {
|
|
switch (typedValue.left.type) {
|
|
case "Identifier": {
|
|
switch (typedValue.right.type) {
|
|
case "Identifier": {
|
|
const leftVar = variablesTable[
|
|
typedValue.left.value
|
|
];
|
|
const rightVar = variablesTable[
|
|
typedValue.right.value
|
|
];
|
|
instructions.push(
|
|
`SAA ${
|
|
leftVar.memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
} ${
|
|
rightVar.memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 5;
|
|
if (
|
|
!variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
]
|
|
) {
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
] = {
|
|
memorySize: 1,
|
|
memoryLocation:
|
|
variableModificationThings
|
|
.getVariableMemoryOffset(1),
|
|
memoryType: "int",
|
|
};
|
|
}
|
|
instructions.push(
|
|
`STA ${
|
|
variablesTable[
|
|
(typedNode.declarations[0]
|
|
.id as swc.Identifier).value
|
|
].memoryLocation
|
|
.toString(16).padStart(
|
|
4,
|
|
"0",
|
|
)
|
|
}`,
|
|
);
|
|
prc.count += 3;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Arithmetic on ${typedValue.right.type} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Arithmetic on ${typedValue.left.type} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Operator type ${typedValue.operator} not implemented`,
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(
|
|
`Variable type ${typedNode.declarations[0].init
|
|
?.type} not implemented`,
|
|
);
|
|
}
|
|
}
|