116 lines
2.5 KiB
C
116 lines
2.5 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include "BinCmdMap.h"
|
|
#include "OperandStack.h"
|
|
|
|
void runV1Program(FILE* program);
|
|
void add(OperandStack* stack);
|
|
void sub(OperandStack* stack);
|
|
void mult(OperandStack* stack);
|
|
void div(OperandStack* stack);
|
|
|
|
int main() {
|
|
FILE* program = fopen("./test.bin", "r");
|
|
if (program == NULL) {
|
|
// TODO: check for errors (e.g. file not found)
|
|
return -1;
|
|
}
|
|
|
|
uint8_t version;
|
|
size_t nread = fread(&version, 1, 1, program);
|
|
|
|
switch (version) {
|
|
case 1:
|
|
runV1Program(program);
|
|
break;
|
|
default:
|
|
printf("Unkown binary version: %i.\n \
|
|
Probably the program was compiled with a more recent \
|
|
version.", version);
|
|
}
|
|
|
|
fclose(program);
|
|
return 0;
|
|
}
|
|
|
|
void runV1Program(FILE* program) {
|
|
OperandStack stack = {};
|
|
uint8_t opcode;
|
|
|
|
while (fread(&opcode, sizeof(opcode), 1, program) == 1) {
|
|
|
|
switch (opcode) {
|
|
case CMD_CONST:
|
|
int32_t val;
|
|
fread(&val, sizeof(int32_t), 1, program);
|
|
// TODO: check for errors
|
|
OStackPush(&stack, val);
|
|
break;
|
|
case CMD_ADD:
|
|
add(&stack);
|
|
break;
|
|
case CMD_SUB:
|
|
sub(&stack);
|
|
break;
|
|
case CMD_MULT:
|
|
mult(&stack);
|
|
break;
|
|
case CMD_DIV:
|
|
div(&stack);
|
|
break;
|
|
default:
|
|
printf("Unkown command");
|
|
}
|
|
}
|
|
// TODO check for errors
|
|
// (feof(program) == 0);
|
|
|
|
int result;
|
|
OStackPop(&stack, &result);
|
|
printf("%i\n", result);
|
|
}
|
|
|
|
void add(OperandStack* stack) {
|
|
int operandA;
|
|
int operandB;
|
|
|
|
OStackPop(stack, &operandA);
|
|
OStackPop(stack, &operandB);
|
|
|
|
int result = operandA + operandB;
|
|
OStackPush(stack, result);
|
|
}
|
|
|
|
void sub(OperandStack* stack) {
|
|
int operandA;
|
|
int operandB;
|
|
|
|
OStackPop(stack, &operandA);
|
|
OStackPop(stack, &operandB);
|
|
|
|
int result = operandA - operandB;
|
|
OStackPush(stack, result);
|
|
}
|
|
|
|
void mult(OperandStack* stack) {
|
|
int operandA;
|
|
int operandB;
|
|
|
|
OStackPop(stack, &operandA);
|
|
OStackPop(stack, &operandB);
|
|
|
|
int result = operandA * operandB;
|
|
OStackPush(stack, result);
|
|
}
|
|
|
|
void div(OperandStack* stack) {
|
|
int operandA;
|
|
int operandB;
|
|
|
|
OStackPop(stack, &operandA);
|
|
OStackPop(stack, &operandB);
|
|
|
|
int result = operandA / operandB;
|
|
OStackPush(stack, result);
|
|
}
|