From 209f22b69cfa5b04c00f75aceaecfdb313a880bb Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sun, 2 Feb 2014 16:29:22 -0500 Subject: Spaghetti stack --- interpret.c | 154 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 74 insertions(+), 80 deletions(-) diff --git a/interpret.c b/interpret.c index 80956a9..7815e80 100644 --- a/interpret.c +++ b/interpret.c @@ -101,49 +101,33 @@ write_value (gpointer address, ast_type_spec_t *type, value_t *value) } } -/* Called vstack_t because there is already a stack_t in /usr/include/bits/sigstack.h */ - -typedef struct vstack_t vstack_t; -struct vstack_t +typedef struct stack_node_t stack_node_t; +struct stack_node_t { - GArray *a; + value_t value; + stack_node_t *next; }; -vstack_t * -stack_new (void) +__attribute__((warn_unused_result)) +static stack_node_t * +stack_pop (stack_node_t *stack, value_t *value) { - vstack_t *stack = g_new0 (vstack_t, 1); - - stack->a = g_array_new (FALSE, FALSE, sizeof (value_t)); + *value = stack->value; - return stack; + return stack->next; } -static value_t -stack_pop (vstack_t *stack) +__attribute__((warn_unused_result)) +static stack_node_t * +stack_push (stack_node_t *stack, value_t val) { - int idx = stack->a->len - 1; - value_t val; + stack_node_t *new; -#if 0 - g_print (" popping\n"); -#endif - - g_assert (stack->a->len > 0); - - val = g_array_index (stack->a, value_t, idx); - g_array_remove_index (stack->a, idx); - - return val; -} + new = gc_alloc (sizeof (stack_node_t)); + new->value = val; + new->next = stack; -static void -stack_push (vstack_t *stack, value_t val) -{ -#if 0 - g_print (" pushing\n"); -#endif - g_array_append_val (stack->a, val); + return new; } static gpointer @@ -169,34 +153,41 @@ var_address (ast_variable_definition_t *var, return var->offset + get_outer (env, level, var->level); } -static void -interpret_binary_operator (vstack_t *stack, - binop_node_t *binop) +__attribute__((warn_unused_result)) +static stack_node_t * +interpret_binary_operator (stack_node_t *stack, + binop_node_t *binop) { - value_t right = stack_pop (stack); - value_t left = stack_pop (stack); + value_t right; + value_t left; value_t result; + stack = stack_pop (stack, &right); + stack = stack_pop (stack, &left); + evaluate_binary_operator (binop->operator, binop->left_type, &left, binop->right_type, &right, binop->type_spec, &result); - stack_push (stack, result); + return stack_push (stack, result); } -static void -interpret_unary_operator (vstack_t *stack, +__attribute__((warn_unused_result)) +static stack_node_t * +interpret_unary_operator (stack_node_t *stack, unary_node_t *unary) { - value_t child = stack_pop (stack); + value_t child; value_t result; + stack = stack_pop (stack, &child); + evaluate_unary_operator (unary->operator, unary->child_type, &child, unary->type_spec, &result); - stack_push (stack, result); + return stack_push (stack, result); } void @@ -205,7 +196,7 @@ interpret (ast_t *ast) ast_program_t *program = &ast->program; guchar *env; node_t *current, *old_next; - vstack_t *stack = stack_new (); + stack_node_t *stack = NULL; value_t val; closure_t *closure; guchar *old_env; @@ -231,28 +222,28 @@ interpret (ast_t *ast) break; case NODE_DYN_GOTO: - val = stack_pop (stack); + stack = stack_pop (stack, &val); env = val.label_val.env; next = (node_t *)val.label_val.label; break; case NODE_IF: - val = stack_pop (stack); + stack = stack_pop (stack, &val); if (val.bool_val == current->if_.sense) next = (node_t *)current->if_.taken; break; case NODE_BINOP: - interpret_binary_operator (stack, ¤t->binop); + stack = interpret_binary_operator (stack, ¤t->binop); break; case NODE_UNARY: - interpret_unary_operator (stack, ¤t->unary); + stack = interpret_unary_operator (stack, ¤t->unary); break; case NODE_LITERAL: - stack_push (stack, current->literal.value); + stack = stack_push (stack, current->literal.value); break; case NODE_CLOSURE: @@ -260,7 +251,7 @@ interpret (ast_t *ast) val.closure_val.env = get_outer (env, current->closure.expression->common.level, current->closure.function->level); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_DYN_LABEL: @@ -269,11 +260,11 @@ interpret (ast_t *ast) get_outer (env, current->dyn_label.expression->common.level, current->dyn_label.definition->level); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_DYN_CLOSURE: - val = stack_pop (stack); + stack = stack_pop (stack, &val); #if 0 g_print ("obj: %p\n", val.pointer_val); @@ -281,21 +272,22 @@ interpret (ast_t *ast) val.closure_val.env = val.pointer_val; val.closure_val.function = current->dyn_closure.function; - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_TO_STRING: - val = stack_pop (stack); + stack = stack_pop (stack, &val); - val.pointer_val = value_to_string (&val, current->to_string.type_spec); + val.pointer_val = value_to_string ( + &val, current->to_string.type_spec); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_PRINT: for (i = 0; i < current->print.n_exprs; ++i) { - val = stack_pop (stack); + stack = stack_pop (stack, &val); g_print ("%s", (char *)val.pointer_val); if (i < current->print.n_exprs - 1) @@ -305,16 +297,16 @@ interpret (ast_t *ast) break; case NODE_POP: - stack_pop (stack); + stack = stack_pop (stack, &val); break; case NODE_DUP: #if 0 g_print ("dup\n"); #endif - val = stack_pop (stack); - stack_push (stack, val); - stack_push (stack, val); + stack = stack_pop (stack, &val); + stack = stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_INIT: @@ -334,7 +326,7 @@ interpret (ast_t *ast) old_next = next; /* Make new environment */ - val = stack_pop (stack); + stack = stack_pop (stack, &val); closure = &val.closure_val; if (!closure->function) @@ -354,7 +346,9 @@ interpret (ast_t *ast) for (i = 0; closure->function->parameters[i]; ++i) { ast_variable_definition_t *parameter = closure->function->parameters[i]; - value_t value = stack_pop (stack); + value_t value; + + stack = stack_pop (stack, &value); write_value (env + parameter->offset, parameter->type_spec, &value); } @@ -369,13 +363,13 @@ interpret (ast_t *ast) current->new.class->level); val.pointer_val = obj; - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_NEW_ARRAY: - val = stack_pop (stack); + stack = stack_pop (stack, &val); val.pointer_val = gc_alloc (val.int32_val * current->new_array.element_size); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_RETURN: @@ -396,14 +390,14 @@ interpret (ast_t *ast) read_value (location, current->this.expression->common.type_spec, &val); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_STORE: location = var_address (current->store.definition, current->store.expression->common.level, env); - val = stack_pop (stack); + stack = stack_pop (stack, &val); write_value (location, current->store.definition->type_spec, &val); break; @@ -411,26 +405,26 @@ interpret (ast_t *ast) #if 0 g_print ("store ind\n"); #endif - val = stack_pop (stack); /* env */ + stack = stack_pop (stack, &val); /* env */ /* No need to compute the environment, since it's already * computed for us in the val.pointer_val */ location = val.pointer_val + current->load.definition->offset; - val = stack_pop (stack); /* value */ + stack = stack_pop (stack, &val); /* value */ write_value (location, current->store_ind.definition->type_spec, &val); break; case NODE_STORE_ARRAY: - val = stack_pop (stack); /* array */ + stack = stack_pop (stack, &val); /* array */ location = val.pointer_val; - val = stack_pop (stack); /* index */ + stack = stack_pop (stack, &val); /* index */ location += ast_type_spec_get_size (current->store_array.array->child_type) * val.int32_val; - val = stack_pop (stack); /* value */ + stack = stack_pop (stack, &val); /* value */ write_value (location, current->store_array.array->child_type, &val); break; @@ -450,15 +444,15 @@ interpret (ast_t *ast) current->load.definition->name, location); #endif read_value (location, current->load.definition->type_spec, &val); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_LOAD_ARRAY: - val = stack_pop (stack); /* array */ + stack = stack_pop (stack, &val); /* array */ location = val.pointer_val; - val = stack_pop (stack); + stack = stack_pop (stack, &val); if (location == NULL) { g_print ("array is NULL exception\n"); @@ -469,7 +463,7 @@ interpret (ast_t *ast) read_value (location, current->load_array.array->child_type, &val); - stack_push (stack, val); + stack = stack_push (stack, val); break; case NODE_LOAD_IND: @@ -477,7 +471,7 @@ interpret (ast_t *ast) g_print ("loading %s indirectly\n", current->load_ind.definition->name); #endif - val = stack_pop (stack); + stack = stack_pop (stack, &val); if (val.pointer_val == NULL) { g_print ("NULL pointer exception\n"); @@ -490,12 +484,12 @@ interpret (ast_t *ast) location = val.pointer_val + current->load.definition->offset; read_value (location, current->load_ind.definition->type_spec, &val); - stack_push (stack, val); + stack = stack_push (stack, val); break; } current = next; } - g_assert (stack->a->len == 0); + g_assert (stack == NULL); } -- cgit v1.2.3