summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2014-02-02 16:29:22 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2014-02-02 16:32:25 -0500
commit209f22b69cfa5b04c00f75aceaecfdb313a880bb (patch)
tree88f62ee56c3d565a3782738faa162c44d821f5f2
parent1fed2a7fe0e5f69ca1b3b89959846c499926628e (diff)
Spaghetti stack
-rw-r--r--interpret.c154
1 files 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, &current->binop);
+ stack = interpret_binary_operator (stack, &current->binop);
break;
case NODE_UNARY:
- interpret_unary_operator (stack, &current->unary);
+ stack = interpret_unary_operator (stack, &current->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);
}