Implement set!
This commit is contained in:
@@ -445,6 +445,28 @@ proc load_built_ins_into_environment() -> void {
|
||||
*target = *source;
|
||||
return target;
|
||||
});
|
||||
defun("set!", "TODO", __LINE__, cLambda {
|
||||
try assert_arguments_length(2, list_length(arguments));
|
||||
Lisp_Object* target_symbol = arguments->value.pair.first;
|
||||
try assert(target_symbol);
|
||||
try assert(arguments->value.pair.rest->value.pair.first);
|
||||
Lisp_Object* source = eval_expr(arguments->value.pair.rest->value.pair.first);
|
||||
|
||||
try assert(source);
|
||||
try assert_type(target_symbol, Lisp_Object_Type::Symbol);
|
||||
|
||||
Environment* target_env = find_binding_environment(target_symbol->value.symbol.identifier, get_current_environment());
|
||||
assert(target_env);
|
||||
|
||||
push_environment(target_env);
|
||||
defer {
|
||||
pop_environment();
|
||||
};
|
||||
|
||||
define_symbol(target_symbol, source);
|
||||
|
||||
return source;
|
||||
});
|
||||
defun("if", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length_greater_equal(2, arguments_length);
|
||||
|
||||
+15
-1
@@ -8,7 +8,7 @@ proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void {
|
||||
|
||||
if (env->next_index == env->capacity) {
|
||||
env->capacity *= 2;
|
||||
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
|
||||
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
|
||||
env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,20 @@ proc lookup_symbol_in_this_envt(String* identifier, Environment* env) -> Lisp_Ob
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
proc environment_binds_symbol(String* identifier, Environment* env) -> bool {
|
||||
return lookup_symbol_in_this_envt(identifier, env) != nullptr;
|
||||
}
|
||||
|
||||
proc find_binding_environment(String* identifier, Environment* env) -> Environment* {
|
||||
if (environment_binds_symbol(identifier, env))
|
||||
return env;
|
||||
for (int i = 0; i < env->parents->next_index; ++i) {
|
||||
if (environment_binds_symbol(identifier, env->parents->data[i]))
|
||||
return env->parents->data[i];
|
||||
}
|
||||
return get_root_environment();
|
||||
}
|
||||
|
||||
proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||
// first check current environment
|
||||
String* identifier = node->value.symbol.identifier;
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@ enum struct Lisp_Object_Type {
|
||||
String,
|
||||
Pair,
|
||||
Continuation,
|
||||
Pointer,
|
||||
OwningPointer,
|
||||
// Pointer,
|
||||
// OwningPointer,
|
||||
Function,
|
||||
CFunction,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user