struct Environment { struct Environment* parent; int capacity; int next_index; // TODO(Felix): Use a hashmap here. char** keys; Ast_Node** values; }; typedef struct Environment Environment; Environment* create_child_environment(Environment* parent) { Environment* env = new(Environment); int start_capacity = 16; env->parent = parent; env->capacity = start_capacity; env->next_index = 0; env->keys = (char**)malloc(start_capacity * sizeof(char*)); env->values = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*)); return env; } Environment* create_empty_environment() { return create_child_environment(nullptr); } void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { // NOTE(Felix): right now we are simply adding the symol at the // back of the list without checking if it already exists but are // also searching for thesymbol from the back, so we will find the // latest defined one first, but a bit messy. Later we should use // a hashmap here. @refactor if (env->next_index == env->capacity) { env->capacity *= 2; env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*)); env->values = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*)); } env->keys [env->next_index] = symbol->value.symbol->identifier; env->values[env->next_index] = value; ++env->next_index; } Ast_Node* lookup_symbol(Symbol* sym, Environment* env) { for (int i = env->next_index - 1; i >= 0; --i) if (string_equal(env->keys[i], sym->identifier)) return env->values[i]; if (env->parent) return lookup_symbol(sym, env->parent); Ast_Node* built_in = create_ast_node_built_in_function(sym->identifier); if (built_in) return built_in; create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil()); printf("%s\n", sym->identifier); return nullptr; }