aboutsummaryrefslogtreecommitdiff
path: root/src/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/program.c')
-rw-r--r--src/program.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/src/program.c b/src/program.c
index 2f0a9df..3be7c67 100644
--- a/src/program.c
+++ b/src/program.c
@@ -235,6 +235,41 @@ static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslS
return TSL_PROGRAM_RESULT_OK;
}
+static TslProgramResult tsl_program_perform_operation(TslProgram *self, TslNumber(*operation_func)(TslNumber lhs, TslNumber rhs)) {
+ TslStackValue *args = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * 2);
+ TslValue lhs_value;
+ TslValue rhs_value;
+ TslStackValue stack_value;
+
+ return_if_error(tsl_value_create_from_stack_value(self, args + 1, &rhs_value));
+ return_if_error(tsl_value_create_from_stack_value(self, args, &lhs_value));
+
+ if(lhs_value.type != TSL_TYPE_NUMBER) {
+ fprintf(stderr, "Error: Unable to perform operation '+' between a TODO and a TODO\n");
+ return TSL_PROGRAM_RESULT_ERR;
+ }
+ if(rhs_value.type != TSL_TYPE_NUMBER) {
+ fprintf(stderr, "Error: Unable to perform operation '+' between a TODO and a TODO\n");
+ return TSL_PROGRAM_RESULT_ERR;
+ }
+
+ stack_value.data.number = operation_func(lhs_value.data.number, rhs_value.data.number);
+ stack_value.type = TSL_STACK_VALUE_TYPE_NUMBER;
+ return tsl_buffer_append(&self->stack_values, &stack_value, sizeof(stack_value));
+}
+
+static TslNumber number_operation_sub(TslNumber lhs, TslNumber rhs) {
+ return lhs + rhs;
+}
+
+static TslNumber number_operation_mul(TslNumber lhs, TslNumber rhs) {
+ return lhs * rhs;
+}
+
+static TslNumber number_operation_div(TslNumber lhs, TslNumber rhs) {
+ return lhs / rhs;
+}
+
TslProgramResult tsl_program_run(TslProgram *self) {
TslProgramResult result = TSL_PROGRAM_RESULT_OK;
TslBytecode *file_scope_bytecode = tsl_buffer_begin(&self->function_bytecode_list);
@@ -379,25 +414,19 @@ TslProgramResult tsl_program_run(TslProgram *self) {
break;
}
case TSL_OPCODE_SUB: {
- TslStackValue *args = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * 2);
- (void)args;
- /* TODO: Implement this */
+ cleanup_if_error(tsl_program_perform_operation(self, number_operation_sub));
printf("sub\n");
instruction += sizeof(TslInstructionType5);
break;
}
case TSL_OPCODE_MUL: {
- TslStackValue *args = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * 2);
- (void)args;
- /* TODO: Implement this */
+ cleanup_if_error(tsl_program_perform_operation(self, number_operation_mul));
printf("mul\n");
instruction += sizeof(TslInstructionType5);
break;
}
case TSL_OPCODE_DIV: {
- TslStackValue *args = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * 2);
- (void)args;
- /* TODO: Implement this */
+ cleanup_if_error(tsl_program_perform_operation(self, number_operation_div));
printf("div\n");
instruction += sizeof(TslInstructionType5);
break;