+static void set_context(context_t *new_context)
+{
+ context = new_context;
+
+ declaration_t *declaration = new_context->declarations;
+ if(declaration != NULL) {
+ while(1) {
+ if(declaration->next == NULL)
+ break;
+ declaration = declaration->next;
+ }
+ }
+
+ last_declaration = declaration;
+}
+
+/**
+ * called when we find a 2nd declarator for an identifier we already have a
+ * declarator for
+ */
+static int is_compatible_declaration (declaration_t *declaration,
+ declaration_t *previous)
+{
+ /* TODO: not correct yet */
+ return declaration->type == previous->type;
+}
+
+/**
+ * pushs an environment_entry on the environment stack and links the
+ * corresponding symbol to the new entry
+ */
+static inline
+declaration_t *environment_push(declaration_t *declaration, const void *context)
+{
+ environment_entry_t *entry
+ = obstack_alloc(&environment_obstack, sizeof(entry[0]));
+ memset(entry, 0, sizeof(entry[0]));
+
+ int top = ARR_LEN(environment_stack);
+ ARR_RESIZE(environment_stack, top + 1);
+ environment_stack[top] = entry;
+
+ assert(declaration->source_position.input_name != NULL);
+
+ symbol_t *symbol = declaration->symbol;
+ assert(declaration != symbol->declaration);
+
+ if(symbol->context == context) {
+ declaration_t *previous_declaration = symbol->declaration;
+ if(symbol->declaration != NULL) {
+ if(!is_compatible_declaration(declaration, previous_declaration)) {
+ parser_print_error_prefix_pos(declaration->source_position);
+ fprintf(stderr, "definition of symbol '%s' with type ",
+ declaration->symbol->string);
+ print_type(declaration->type, NULL);
+ fputc('\n', stderr);
+ parser_print_error_prefix_pos(
+ previous_declaration->source_position);
+ fprintf(stderr, "is incompatible with previous declaration "
+ "of type ");
+ print_type(previous_declaration->type, NULL);
+ fputc('\n', stderr);
+ }
+ return previous_declaration;
+ }
+ }
+
+ entry->old_declaration = symbol->declaration;
+ entry->old_context = symbol->context;
+ entry->symbol = symbol;
+ symbol->declaration = declaration;
+ symbol->context = context;
+
+ return declaration;
+}
+
+/**
+ * pops symbols from the environment stack until @p new_top is the top element
+ */
+static inline
+void environment_pop_to(size_t new_top)
+{
+ environment_entry_t *entry = NULL;
+ size_t top = ARR_LEN(environment_stack);
+ size_t i;
+
+ if(new_top == top)
+ return;
+
+ assert(new_top < top);
+ i = top;
+ do {
+ entry = environment_stack[i - 1];
+
+ symbol_t *symbol = entry->symbol;
+
+ symbol->declaration = entry->old_declaration;
+ symbol->context = entry->old_context;
+
+ --i;
+ } while(i != new_top);
+ obstack_free(&environment_obstack, entry);
+
+ ARR_SHRINKLEN(environment_stack, (int) new_top);
+}
+
+
+