aboutsummaryrefslogtreecommitdiff
path: root/src/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/program.c')
-rw-r--r--src/program.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/program.c b/src/program.c
index 862931a..3ec6f85 100644
--- a/src/program.c
+++ b/src/program.c
@@ -1,10 +1,12 @@
#include "../include/program.h"
#include "../include/bytecode.h"
#include <stdio.h>
+#include <assert.h>
void tsl_program_init(TslProgram *self) {
tsl_buffer_init(&self->function_bytecode_list);
tsl_hash_map_init(&self->variables);
+ self->stack_index = 0;
}
void tsl_program_deinit(TslProgram *self) {
@@ -18,7 +20,27 @@ void tsl_program_deinit(TslProgram *self) {
tsl_hash_map_deinit(&self->variables);
}
+static uint64_t hash_string_view(const void *data, size_t size) {
+ uint64_t result = 0xdec05eba;
+ const uint8_t *p = data;
+ while(size) {
+ result = ((result << 5) + result) + *p;
+ ++p;
+ --size;
+ }
+ return result;
+}
+
TslProgramResult tsl_program_run(TslProgram *self) {
+ #define push(value, type_enum, value_field) \
+ do { \
+ if(self->stack_index == TSL_STACK_MAX_SIZE) \
+ return TSL_PROGRAM_RESULT_ERR; \
+ self->stack_values[self->stack_index].data.value_field = (value); \
+ self->stack_values[self->stack_index].type = (type_enum); \
+ ++self->stack_index; \
+ } while(0)
+
TslBytecode *file_scope_bytecode = tsl_buffer_begin(&self->function_bytecode_list);
char *instruction = tsl_buffer_begin(&file_scope_bytecode->buffer);
char *instruction_end = tsl_buffer_end(&file_scope_bytecode->buffer);
@@ -33,11 +55,13 @@ TslProgramResult tsl_program_run(TslProgram *self) {
switch(opcode) {
case TSL_OPCODE_LOADN: {
printf("loadn %f\n", instruction_type2->value);
+ push(instruction_type2->value, TSL_TYPE_NUMBER, number);
instruction += sizeof(TslInstructionType2);
break;
}
case TSL_OPCODE_LOADB: {
printf("loadb %s\n", instruction_type3->value ? "true" : "false");
+ push(instruction_type3->value, TSL_TYPE_BOOL, boolean);
instruction += sizeof(TslInstructionType3);
break;
}
@@ -62,7 +86,14 @@ TslProgramResult tsl_program_run(TslProgram *self) {
break;
}
case TSL_OPCODE_SETV: {
+ TslValue stack_value;
+ TslValue *value;
printf("setv \"%.*s\"\n", (int)instruction_type4->value.size, instruction_type4->value.data);
+ assert(self->stack_index > 0);
+ stack_value = self->stack_values[--self->stack_index];
+ if(!tsl_hash_map_get_or_create(&self->variables, &instruction_type4->value, sizeof(TslValue), hash_string_view, (void**)&value))
+ return TSL_PROGRAM_RESULT_ERR;
+ *value = stack_value;
instruction += sizeof(TslInstructionType4);
break;
}