| @@ -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); | ||||
| @@ -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; | ||||
| @@ -17,8 +17,8 @@ enum struct Lisp_Object_Type { | |||||
| String, | String, | ||||
| Pair, | Pair, | ||||
| Continuation, | Continuation, | ||||
| Pointer, | |||||
| OwningPointer, | |||||
| // Pointer, | |||||
| // OwningPointer, | |||||
| Function, | Function, | ||||
| CFunction, | CFunction, | ||||
| }; | }; | ||||