|
- proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void {
- // 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 = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*));
- }
-
- env->keys [env->next_index] = Memory::get_c_str(symbol->value.identifier);
- env->values[env->next_index] = value;
- ++env->next_index;
- }
-
- proc lookup_symbol_in_this_envt(String* identifier, Environment* env) -> Lisp_Object* {
- for (int i = env->next_index - 1; i >= 0; --i)
- if (string_equal(env->keys[i], Memory::get_c_str(identifier)))
- return env->values[i];
- return nullptr;
- }
-
- proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
- // first check current environment
- String* identifier = node->value.identifier;
- Lisp_Object* result;
- result = lookup_symbol_in_this_envt(identifier, env);
- if (result)
- return result;
-
- for (int i = 0; i < env->parents->next_index; ++i) {
- result = try_lookup_symbol(node, env->parents->data[i]);
-
- if (result)
- return result;
- }
-
- if (string_equal(Memory::get_c_str(identifier), "nil")) {
- return Memory::nil;
- }
- if (string_equal(Memory::get_c_str(identifier), "t")) {
- return Memory::t;
- }
-
- return nullptr;
- }
-
- proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
- Lisp_Object* result = try_lookup_symbol(node, env);
-
- if (result)
- return result;
-
- String* identifier = node->value.identifier;
- create_symbol_undefined_error("The symbol '%s' is not defined.", &identifier->data);
- print_environment(env);
- return nullptr;
- }
-
-
- proc print_indent(int indent) -> void {
- for (int i = 0; i < indent; ++i) {
- printf(" ");
- }
- }
-
- proc print_environment_indent(Environment* env, int indent) -> void {
- for (int i = 0; i < env->next_index; ++i) {
- print_indent(indent);
- print(env->values[i]);
- printf(" %s", env->keys[i]);
- puts("");
- }
- for (int i = 0; i < env->parents->next_index; ++i) {
- print_indent(indent);
- printf("parent (%lld)", (long long)env->parents->data[i]);
- puts(":");
- print_environment_indent(env->parents->data[i], indent+4);
- }
- }
-
- proc print_environment(Environment* env) -> void {
- printf("\n=== Environment ===\n");
- print_environment_indent(env, 0);
- }
|