| @@ -24,11 +24,6 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | |||||
| case Lisp_Object_Type::T: // code for t and nil should never be | case Lisp_Object_Type::T: // code for t and nil should never be | ||||
| // reached since they are memory unique | // reached since they are memory unique | ||||
| case Lisp_Object_Type::Nil: return true; | case Lisp_Object_Type::Nil: return true; | ||||
| case Lisp_Object_Type::Symbol: // NOTE(Felix): this will be | |||||
| // unnecessary once symbols and | |||||
| // keywords are memory unique | |||||
| case Lisp_Object_Type::Keyword: | |||||
| return string_equal(n1->value.symbol.identifier, n2->value.symbol.identifier); | |||||
| case Lisp_Object_Type::Number: return n1->value.number == n2->value.number; | case Lisp_Object_Type::Number: return n1->value.number == n2->value.number; | ||||
| case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string); | case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string); | ||||
| case Lisp_Object_Type::Pair: | case Lisp_Object_Type::Pair: | ||||
| @@ -591,6 +586,8 @@ proc load_built_ins_into_environment() -> void { | |||||
| }; | }; | ||||
| define_special((quasiquote expr), "TODO") { | define_special((quasiquote expr), "TODO") { | ||||
| fetch(expr); | fetch(expr); | ||||
| static auto unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote"); | |||||
| static auto unquote_splicing_sym = Memory::get_or_create_lisp_object_symbol("unquote-splicing"); | |||||
| /* recursive lambdas in lambdas yay!! */ | /* recursive lambdas in lambdas yay!! */ | ||||
| // NOTE(Felix): first we have to initialize the variable | // NOTE(Felix): first we have to initialize the variable | ||||
| // with a garbage lambda, so that we can then overwrite it | // with a garbage lambda, so that we can then overwrite it | ||||
| @@ -603,9 +600,7 @@ proc load_built_ins_into_environment() -> void { | |||||
| // it is a pair! | // it is a pair! | ||||
| Lisp_Object* originalPair = expr->value.pair.first; | Lisp_Object* originalPair = expr->value.pair.first; | ||||
| if (Memory::get_type(originalPair) == Lisp_Object_Type::Symbol && | |||||
| (string_equal(originalPair->value.symbol.identifier, "unquote") || | |||||
| string_equal(originalPair->value.symbol.identifier, "unquote-splicing"))) | |||||
| if (originalPair == unquote_sym || originalPair == unquote_splicing_sym) | |||||
| { | { | ||||
| // eval replace the stuff | // eval replace the stuff | ||||
| @@ -634,8 +629,7 @@ proc load_built_ins_into_environment() -> void { | |||||
| // if it is ,@ we have to actually do more work | // if it is ,@ we have to actually do more work | ||||
| // and inline the result | // and inline the result | ||||
| if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Pair && | if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Pair && | ||||
| Memory::get_type(head->value.pair.first->value.pair.first) == Lisp_Object_Type::Symbol && | |||||
| string_equal(head->value.pair.first->value.pair.first->value.symbol.identifier, "unquote-splicing")) | |||||
| head->value.pair.first->value.pair.first == unquote_splicing_sym) | |||||
| { | { | ||||
| Lisp_Object* spliced = unquoteSomeExpressions(head->value.pair.first); | Lisp_Object* spliced = unquoteSomeExpressions(head->value.pair.first); | ||||
| @@ -22,6 +22,8 @@ proc find_binding_environment(String* identifier, Environment* env) -> Environme | |||||
| } | } | ||||
| proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { | proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { | ||||
| static auto nil_sym = Memory::get_or_create_lisp_object_symbol("nil"); | |||||
| static auto t_sym = Memory::get_or_create_lisp_object_symbol("t"); | |||||
| // first check current environment | // first check current environment | ||||
| String* identifier = node->value.symbol.identifier; | String* identifier = node->value.symbol.identifier; | ||||
| Lisp_Object* result; | Lisp_Object* result; | ||||
| @@ -36,10 +38,10 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { | |||||
| return result; | return result; | ||||
| } | } | ||||
| if (string_equal(Memory::get_c_str(identifier), "nil")) { | |||||
| if (node == nil_sym) { | |||||
| return Memory::nil; | return Memory::nil; | ||||
| } | } | ||||
| if (string_equal(Memory::get_c_str(identifier), "t")) { | |||||
| if (node == t_sym) { | |||||
| return Memory::t; | return Memory::t; | ||||
| } | } | ||||
| @@ -42,7 +42,7 @@ proc create_extended_environment_for_function_application( | |||||
| // for the function call | // for the function call | ||||
| Lisp_Object* sym, *val; // used as temp storage to use `try` | Lisp_Object* sym, *val; // used as temp storage to use `try` | ||||
| String_Array_List read_in_keywords; | |||||
| Lisp_Object_Array_List read_in_keywords; | |||||
| int obligatory_keywords_count = 0; | int obligatory_keywords_count = 0; | ||||
| int read_obligatory_keywords_count = 0; | int read_obligatory_keywords_count = 0; | ||||
| @@ -73,7 +73,7 @@ proc create_extended_environment_for_function_application( | |||||
| // added ones (array list), if end of parameters in encountered or | // added ones (array list), if end of parameters in encountered or | ||||
| // something that is not a keyword is encountered or a keyword | // something that is not a keyword is encountered or a keyword | ||||
| // that is not recognized is encoutered, jump out of the loop. | // that is not recognized is encoutered, jump out of the loop. | ||||
| read_in_keywords = create_String_array_list(); | |||||
| read_in_keywords = create_Lisp_Object_array_list(); | |||||
| if (arguments == Memory::nil) | if (arguments == Memory::nil) | ||||
| return; | return; | ||||
| @@ -91,9 +91,7 @@ proc create_extended_environment_for_function_application( | |||||
| // check if this one is even an accepted keyword | // check if this one is even an accepted keyword | ||||
| bool accepted = false; | bool accepted = false; | ||||
| for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) { | for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) { | ||||
| if (string_equal( | |||||
| arguments->value.pair.first->value.symbol.identifier, | |||||
| arg_spec->keyword.keywords.data[i]->value.symbol.identifier)) | |||||
| if (arguments->value.pair.first == arg_spec->keyword.keywords.data[i]) | |||||
| { | { | ||||
| accepted = true; | accepted = true; | ||||
| break; | break; | ||||
| @@ -116,9 +114,7 @@ proc create_extended_environment_for_function_application( | |||||
| // check if it was already read in | // check if it was already read in | ||||
| for (int i = 0; i < read_in_keywords.next_index; ++i) { | for (int i = 0; i < read_in_keywords.next_index; ++i) { | ||||
| if (string_equal( | |||||
| arguments->value.pair.first->value.symbol.identifier, | |||||
| read_in_keywords.data[i])) | |||||
| if (arguments->value.pair.first == read_in_keywords.data[i]) | |||||
| { | { | ||||
| // NOTE(Felix): if we are actually done with all the | // NOTE(Felix): if we are actually done with all the | ||||
| // necessary keywords then we have to count the rest | // necessary keywords then we have to count the rest | ||||
| @@ -154,7 +150,7 @@ proc create_extended_environment_for_function_application( | |||||
| Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first)); | Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first)); | ||||
| } | } | ||||
| append_to_array_list(&read_in_keywords, arguments->value.pair.first->value.symbol.identifier); | |||||
| append_to_array_list(&read_in_keywords, arguments->value.pair.first); | |||||
| ++read_obligatory_keywords_count; | ++read_obligatory_keywords_count; | ||||
| // overstep both for next one | // overstep both for next one | ||||
| @@ -169,13 +165,11 @@ proc create_extended_environment_for_function_application( | |||||
| proc check_keyword_args = [&]() -> void { | proc check_keyword_args = [&]() -> void { | ||||
| // check if all necessary keywords have been read in | // check if all necessary keywords have been read in | ||||
| for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) { | for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) { | ||||
| String* defined_keyword = arg_spec->keyword.keywords.data[i]->value.symbol.identifier; | |||||
| auto defined_keyword = arg_spec->keyword.keywords.data[i]; | |||||
| bool was_set = false; | bool was_set = false; | ||||
| for (int j = 0; j < read_in_keywords.next_index; ++j) { | for (int j = 0; j < read_in_keywords.next_index; ++j) { | ||||
| // TODO(Felix): Later compare the keywords, not their strings!! | // TODO(Felix): Later compare the keywords, not their strings!! | ||||
| if (string_equal( | |||||
| read_in_keywords.data[j], | |||||
| defined_keyword)) | |||||
| if (read_in_keywords.data[j] == defined_keyword) | |||||
| { | { | ||||
| was_set = true; | was_set = true; | ||||
| break; | break; | ||||
| @@ -187,14 +181,14 @@ proc create_extended_environment_for_function_application( | |||||
| create_generic_error( | create_generic_error( | ||||
| "There was no value supplied for the required " | "There was no value supplied for the required " | ||||
| "keyword argument ':%s'.", | "keyword argument ':%s'.", | ||||
| &defined_keyword->data); | |||||
| &defined_keyword->value.symbol.identifier->data); | |||||
| return; | return; | ||||
| } | } | ||||
| } else { | } else { | ||||
| // this one does have a default value, lets see if we have | // this one does have a default value, lets see if we have | ||||
| // to use it or if the user supplied his own | // to use it or if the user supplied his own | ||||
| if (!was_set) { | if (!was_set) { | ||||
| try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword); | |||||
| try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword->value.symbol.identifier); | |||||
| if (is_c_function) { | if (is_c_function) { | ||||
| try_void val = arg_spec->keyword.values.data[i]; | try_void val = arg_spec->keyword.values.data[i]; | ||||
| } else { | } else { | ||||
| @@ -327,12 +327,14 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v | |||||
| if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Symbol) { | if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Symbol) { | ||||
| String* identifier = head->value.pair.first->value.symbol.identifier; | String* identifier = head->value.pair.first->value.symbol.identifier; | ||||
| // TODO(Felix): Lisp_Node* symbol = head->value.pair.first; | |||||
| // TODO(Felix): if (symbol == Memory::get_or_create_symbol("quote")) | |||||
| if (string_equal(identifier, "quote") || | |||||
| string_equal(identifier, "unquote")) | |||||
| auto symbol = head->value.pair.first; | |||||
| static auto quote_sym = Memory::get_or_create_lisp_object_symbol("quote"); | |||||
| static auto unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote"); | |||||
| static auto quasiquote_sym = Memory::get_or_create_lisp_object_symbol("quasiquote"); | |||||
| if (symbol == quote_sym || symbol == unquote_sym) | |||||
| { | { | ||||
| putc((string_equal(identifier, "quote")) | |||||
| putc(symbol == quote_sym | |||||
| ? '\'' | ? '\'' | ||||
| : ',', file); | : ',', file); | ||||
| @@ -342,7 +344,7 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v | |||||
| print(head->value.pair.rest->value.pair.first, print_repr, file); | print(head->value.pair.rest->value.pair.first, print_repr, file); | ||||
| break; | break; | ||||
| } | } | ||||
| else if (string_equal(identifier, "quasiquote")) { | |||||
| else if (symbol == quasiquote_sym) { | |||||
| putc('`', file); | putc('`', file); | ||||
| assert_type(head->value.pair.rest, Lisp_Object_Type::Pair); | assert_type(head->value.pair.rest, Lisp_Object_Type::Pair); | ||||
| print(head->value.pair.rest->value.pair.first, print_repr, file); | print(head->value.pair.rest->value.pair.first, print_repr, file); | ||||