aboutsummaryrefslogtreecommitdiff
path: root/src/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/program.c')
-rw-r--r--src/program.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/program.c b/src/program.c
index 78533f6..2f0a9df 100644
--- a/src/program.c
+++ b/src/program.c
@@ -47,6 +47,29 @@ static int program_output_temp(char *data, int size, void *userdata) {
return 1;
}
+static void tsl_string_to_ref(const TslString *self, TslStringView *result) {
+ result->data = self->data;
+ result->size = self->size;
+}
+
+static TslProgramResult tsl_string_ref_get_item_at_index(const TslStringView *self, const TslValue *key, TslValue *result) {
+ TslValue *list_item;
+ if(key->type != TSL_TYPE_NUMBER) {
+ /* TODO: Print type as string */
+ fprintf(stderr, "Error: Unable to index string %s using a variable of type %d. The index has to be a number\n", "TODO", key->type);
+ return TSL_PROGRAM_RESULT_ERR;
+ }
+
+ list_item = tsl_string_ref_get(self, key->data.number);
+ if(list_item) {
+ *result = *list_item;
+ } else {
+ result->type = TSL_TYPE_NULL;
+ }
+
+ return TSL_PROGRAM_RESULT_OK;
+}
+
static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslStackValue *src, TslValue *dst) {
tsl_value_clear(dst);
switch(src->type) {
@@ -93,7 +116,7 @@ static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslS
dst->type = TSL_TYPE_FUNCTION;
break;
}
- case TSL_STACK_VALUE_TYPE_VARIABLE: {
+ case TSL_STACK_VALUE_TYPE_VARIABLE_NAME: {
TslValue *var;
TslValue map_key;
map_key.type = TSL_TYPE_STRING_REF;
@@ -108,6 +131,10 @@ static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslS
*dst = *var;
break;
}
+ case TSL_STACK_VALUE_TYPE_VARIABLE: {
+ *dst = src->data.variable;
+ break;
+ }
case TSL_STACK_VALUE_TYPE_LIST: {
TslStackValue *items_begin = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * src->data.integer);
TslStackValue *items_end = items_begin + src->data.integer;
@@ -174,6 +201,7 @@ static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslS
} else {
dst->type = TSL_TYPE_NULL;
}
+ return TSL_PROGRAM_RESULT_OK;
} else if(var.type == TSL_TYPE_MAP) {
TslValue *map_value = tsl_hash_map_get(var.data.map, &key);
if(map_value) {
@@ -181,12 +209,18 @@ static TslProgramResult tsl_value_create_from_stack_value(TslProgram *self, TslS
} else {
dst->type = TSL_TYPE_NULL;
}
+ return TSL_PROGRAM_RESULT_OK;
+ } else if(var.type == TSL_TYPE_STRING) {
+ TslStringView str_ref;
+ tsl_string_to_ref(var.data.string, &str_ref);
+ return tsl_string_ref_get_item_at_index(&str_ref, &key, dst);
+ } else if(var.type == TSL_TYPE_STRING_REF) {
+ return tsl_string_ref_get_item_at_index(&var.data.string_ref, &key, dst);
} else {
/* TODO: Print type as string */
fprintf(stderr, "Error: Unable to index data of type %d. Expected list or map\n", var.type);
return TSL_PROGRAM_RESULT_ERR;
}
- break;
}
case TSL_STACK_VALUE_TYPE_NULL: {
dst->type = TSL_TYPE_NULL;
@@ -264,7 +298,7 @@ TslProgramResult tsl_program_run(TslProgram *self) {
case TSL_OPCODE_LOADV: {
TslStackValue stack_value;
stack_value.data.str = instruction_type4->value;
- stack_value.type = TSL_STACK_VALUE_TYPE_VARIABLE;
+ stack_value.type = TSL_STACK_VALUE_TYPE_VARIABLE_NAME;
cleanup_if_error(tsl_buffer_append(&self->stack_values, &stack_value, sizeof(stack_value)));
printf("loadv \"%.*s\"\n", (int)instruction_type4->value.size, instruction_type4->value.data);
instruction += sizeof(TslInstructionType4);
@@ -330,8 +364,16 @@ TslProgramResult tsl_program_run(TslProgram *self) {
}
case TSL_OPCODE_ADD: {
TslStackValue *args = tsl_buffer_pop(&self->stack_values, sizeof(TslStackValue) * 2);
- (void)args;
- /* TODO: Implement this */
+ TslValue lhs_value;
+ TslValue rhs_value;
+ TslStackValue stack_value;
+
+ cleanup_if_error(tsl_value_create_from_stack_value(self, args + 1, &rhs_value));
+ cleanup_if_error(tsl_value_create_from_stack_value(self, args, &lhs_value));
+ cleanup_if_error(tsl_value_add(&lhs_value, &rhs_value, &stack_value.data.variable));
+
+ stack_value.type = TSL_STACK_VALUE_TYPE_VARIABLE;
+ cleanup_if_error(tsl_buffer_append(&self->stack_values, &stack_value, sizeof(stack_value)));
printf("add\n");
instruction += sizeof(TslInstructionType5);
break;