Implement set!
This commit is contained in:
@@ -3,7 +3,8 @@ SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||
pushd $SCRIPTPATH > /dev/null
|
||||
|
||||
# _DEBUG
|
||||
time g++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1
|
||||
# time g++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1
|
||||
time clang++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1
|
||||
|
||||
echo ""
|
||||
pushd ./bin > /dev/null
|
||||
|
||||
@@ -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);
|
||||
|
||||
+14
@@ -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