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

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`,
);
}
}