|
-
- 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;
- }
|