Implement set!
This commit is contained in:
@@ -3,7 +3,8 @@ SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
|||||||
pushd $SCRIPTPATH > /dev/null
|
pushd $SCRIPTPATH > /dev/null
|
||||||
|
|
||||||
# _DEBUG
|
# _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 ""
|
echo ""
|
||||||
pushd ./bin > /dev/null
|
pushd ./bin > /dev/null
|
||||||
|
|||||||
@@ -445,6 +445,28 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
*target = *source;
|
*target = *source;
|
||||||
return target;
|
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 {
|
defun("if", "TODO", __LINE__, cLambda {
|
||||||
try arguments_length = list_length(arguments);
|
try arguments_length = list_length(arguments);
|
||||||
try assert_arguments_length_greater_equal(2, arguments_length);
|
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) {
|
if (env->next_index == env->capacity) {
|
||||||
env->capacity *= 2;
|
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*));
|
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;
|
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* {
|
proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||||
// first check current environment
|
// first check current environment
|
||||||
String* identifier = node->value.symbol.identifier;
|
String* identifier = node->value.symbol.identifier;
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@ enum struct Lisp_Object_Type {
|
|||||||
String,
|
String,
|
||||||
Pair,
|
Pair,
|
||||||
Continuation,
|
Continuation,
|
||||||
Pointer,
|
// Pointer,
|
||||||
OwningPointer,
|
// OwningPointer,
|
||||||
Function,
|
Function,
|
||||||
CFunction,
|
CFunction,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user