diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 605a368..f90534f 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -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 // reached since they are memory unique 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::String: return string_equal(n1->value.string, n2->value.string); case Lisp_Object_Type::Pair: @@ -591,6 +586,8 @@ proc load_built_ins_into_environment() -> void { }; define_special((quasiquote expr), "TODO") { 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!! */ // NOTE(Felix): first we have to initialize the variable // 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! 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 @@ -634,8 +629,7 @@ proc load_built_ins_into_environment() -> void { // if it is ,@ we have to actually do more work // and inline the result 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); diff --git a/src/env.cpp b/src/env.cpp index f34fc6d..622a861 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -22,6 +22,8 @@ proc find_binding_environment(String* identifier, Environment* env) -> Environme } 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 String* identifier = node->value.symbol.identifier; Lisp_Object* result; @@ -36,10 +38,10 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { return result; } - if (string_equal(Memory::get_c_str(identifier), "nil")) { + if (node == nil_sym) { return Memory::nil; } - if (string_equal(Memory::get_c_str(identifier), "t")) { + if (node == t_sym) { return Memory::t; } diff --git a/src/eval.cpp b/src/eval.cpp index 03fc33d..17c6ff3 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -42,7 +42,7 @@ proc create_extended_environment_for_function_application( // for the function call 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 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 // something that is not a keyword is encountered or a keyword // 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) return; @@ -91,9 +91,7 @@ proc create_extended_environment_for_function_application( // check if this one is even an accepted keyword bool accepted = false; 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; break; @@ -116,9 +114,7 @@ proc create_extended_environment_for_function_application( // check if it was already read in 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 // 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)); } - 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; // overstep both for next one @@ -169,13 +165,11 @@ proc create_extended_environment_for_function_application( proc check_keyword_args = [&]() -> void { // check if all necessary keywords have been read in 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; for (int j = 0; j < read_in_keywords.next_index; ++j) { // 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; break; @@ -187,14 +181,14 @@ proc create_extended_environment_for_function_application( create_generic_error( "There was no value supplied for the required " "keyword argument ':%s'.", - &defined_keyword->data); + &defined_keyword->value.symbol.identifier->data); return; } } else { // this one does have a default value, lets see if we have // to use it or if the user supplied his own 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) { try_void val = arg_spec->keyword.values.data[i]; } else { diff --git a/src/io.cpp b/src/io.cpp index 8bcb24f..b0c11a0 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -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) { 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); @@ -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); break; } - else if (string_equal(identifier, "quasiquote")) { + else if (symbol == quasiquote_sym) { putc('`', file); assert_type(head->value.pair.rest, Lisp_Object_Type::Pair); print(head->value.pair.rest->value.pair.first, print_repr, file);