| @@ -1,12 +1,13 @@ | |||
| TIMEFORMAT=%3lR | |||
| SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" | |||
| pushd $SCRIPTPATH/src > /dev/null | |||
| pushd $SCRIPTPATH > /dev/null | |||
| clang++ main.cpp -g -o ../bin/slime --std=c++17 || exit 1 | |||
| time clang++ src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| echo "" | |||
| echo "--- Output Start ---" | |||
| pushd ../bin > /dev/null | |||
| ./slime --run-tests | |||
| pushd ./bin > /dev/null | |||
| time ./slime --run-tests | |||
| popd > /dev/null | |||
| echo "--- Output End ---" | |||
| popd > /dev/null | |||
| unset TIMEFORMAT | |||
| @@ -43,7 +43,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | |||
| proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { | |||
| char* file_content = read_entire_file(Memory::get_c_str(file_name)); | |||
| if (file_content) { | |||
| Lisp_Object* result = Memory::create_lisp_object_nil(); | |||
| Lisp_Object* result = Memory::nil; | |||
| Lisp_Object_Array_List* program; | |||
| try { | |||
| program = Parser::parse_program(file_name, file_content); | |||
| @@ -72,7 +72,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| proc defun = [&](const char* name, auto fun) { | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(name), | |||
| Memory::get_or_create_lisp_object_symbol(name), | |||
| Memory::create_lisp_object_cfunction(fun), | |||
| env); | |||
| }; | |||
| @@ -84,17 +84,17 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| if (arguments->type == Lisp_Object_Type::Nil) | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| Lisp_Object* first = arguments->value.pair->first; | |||
| while (arguments->type == Lisp_Object_Type::Pair) { | |||
| if (!lisp_object_equal(arguments->value.pair->first, first)) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| arguments = arguments->value.pair->rest; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun(">", cLambda { | |||
| int arguments_length; | |||
| @@ -110,13 +110,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| if (arguments->value.pair->first->value.number->value >= last_number) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| last_number = arguments->value.pair->first->value.number->value; | |||
| arguments = arguments->value.pair->rest; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun(">=", cLambda { | |||
| int arguments_length; | |||
| @@ -132,13 +132,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| if (arguments->value.pair->first->value.number->value > last_number) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| last_number = arguments->value.pair->first->value.number->value; | |||
| arguments = arguments->value.pair->rest; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun("<", cLambda { | |||
| int arguments_length; | |||
| @@ -154,13 +154,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| if (arguments->value.pair->first->value.number->value <= last_number) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| last_number = arguments->value.pair->first->value.number->value; | |||
| arguments = arguments->value.pair->rest; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun("<=", cLambda { | |||
| int arguments_length; | |||
| @@ -176,13 +176,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| if (arguments->value.pair->first->value.number->value < last_number) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| last_number = arguments->value.pair->first->value.number->value; | |||
| arguments = arguments->value.pair->rest; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun("+", cLambda { | |||
| int arguments_length; | |||
| @@ -407,7 +407,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| try { | |||
| result = eval_expr(else_part->value.pair->first, env); | |||
| } | |||
| else return Memory::create_lisp_object_nil(); | |||
| else return Memory::nil; | |||
| return result; | |||
| }); | |||
| defun("quote", cLambda { | |||
| @@ -474,7 +474,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| newPairHead = newPairHead->value.pair->rest; | |||
| head = head->value.pair->rest; | |||
| } | |||
| newPairHead->value.pair->rest = Memory::create_lisp_object_nil(); | |||
| newPairHead->value.pair->rest = Memory::nil; | |||
| return newPair; | |||
| }; | |||
| @@ -496,10 +496,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| arguments = arguments->value.pair->rest; | |||
| if (!result) return Memory::create_lisp_object_nil(); | |||
| if (!result) return Memory::nil; | |||
| } | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun("or", cLambda { | |||
| bool result = false; | |||
| @@ -512,10 +512,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| arguments = arguments->value.pair->rest; | |||
| if (result) return Memory::create_lisp_object_t(); | |||
| if (result) return Memory::t; | |||
| } | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("not", cLambda { | |||
| try { | |||
| @@ -530,8 +530,8 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| truthy = is_truthy(arguments->value.pair->first, env); | |||
| } | |||
| if (truthy) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::nil; | |||
| return Memory::t; | |||
| }); | |||
| defun("while", cLambda { | |||
| try { | |||
| @@ -544,7 +544,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| Lisp_Object* condition_part = arguments->value.pair->first; | |||
| Lisp_Object* condition; | |||
| Lisp_Object* then_part = arguments->value.pair->rest; | |||
| Lisp_Object* result = Memory::create_lisp_object_nil(); | |||
| Lisp_Object* result = Memory::nil; | |||
| while (true) { | |||
| try { | |||
| @@ -659,7 +659,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| // we are now in the function body, just wrap it in an | |||
| // implicit prog | |||
| function->body = Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("prog"), | |||
| Memory::get_or_create_lisp_object_symbol("prog"), | |||
| arguments); | |||
| Lisp_Object* ret = Memory::create_lisp_object(); | |||
| @@ -709,7 +709,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| // we are now in the function body, just wrap it in an | |||
| // implicit prog | |||
| function->body = Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("prog"), | |||
| Memory::get_or_create_lisp_object_symbol("prog"), | |||
| arguments); | |||
| Lisp_Object* ret = Memory::create_lisp_object(); | |||
| @@ -774,7 +774,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||
| } | |||
| if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) | |||
| report_error(Error_Type::Type_Missmatch); | |||
| @@ -788,7 +788,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||
| } | |||
| if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) | |||
| report_error(Error_Type::Type_Missmatch); | |||
| @@ -821,7 +821,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||
| } | |||
| evaluated_arguments->value.pair->first->userType = nullptr; | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| }); | |||
| defun("type", cLambda { | |||
| try { | |||
| @@ -837,26 +837,26 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| Lisp_Object_Type type = evaluated_arguments->value.pair->first->type; | |||
| switch (type) { | |||
| case Lisp_Object_Type::CFunction: return Memory::create_lisp_object_keyword("cfunction"); | |||
| case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction"); | |||
| case Lisp_Object_Type::Function: { | |||
| Function* fun = evaluated_arguments->value.pair->first->value.function; | |||
| if (fun->type == Function_Type::Lambda) | |||
| return Memory::create_lisp_object_keyword("lambda"); | |||
| return Memory::get_or_create_lisp_object_keyword("lambda"); | |||
| else if (fun->type == Function_Type::Special_Lambda) | |||
| return Memory::create_lisp_object_keyword("special-lambda"); | |||
| return Memory::get_or_create_lisp_object_keyword("special-lambda"); | |||
| else if (fun->type == Function_Type::Macro) | |||
| return Memory::create_lisp_object_keyword("macro"); | |||
| else return Memory::create_lisp_object_keyword("unknown"); | |||
| } | |||
| case Lisp_Object_Type::Keyword: return Memory::create_lisp_object_keyword("keyword"); | |||
| case Lisp_Object_Type::Nil: return Memory::create_lisp_object_keyword("nil"); | |||
| case Lisp_Object_Type::T: return Memory::create_lisp_object_keyword("t"); | |||
| case Lisp_Object_Type::Number: return Memory::create_lisp_object_keyword("number"); | |||
| case Lisp_Object_Type::Pair: return Memory::create_lisp_object_keyword("pair"); | |||
| case Lisp_Object_Type::String: return Memory::create_lisp_object_keyword("string"); | |||
| case Lisp_Object_Type::Symbol: return Memory::create_lisp_object_keyword("symbol"); | |||
| } | |||
| return Memory::create_lisp_object_keyword("unknown"); | |||
| return Memory::get_or_create_lisp_object_keyword("macro"); | |||
| else return Memory::get_or_create_lisp_object_keyword("unknown"); | |||
| } | |||
| case Lisp_Object_Type::Keyword: return Memory::get_or_create_lisp_object_keyword("keyword"); | |||
| case Lisp_Object_Type::Nil: return Memory::get_or_create_lisp_object_keyword("nil"); | |||
| case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t"); | |||
| case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number"); | |||
| case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair"); | |||
| case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string"); | |||
| case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol"); | |||
| } | |||
| return Memory::get_or_create_lisp_object_keyword("unknown"); | |||
| }); | |||
| defun("info", cLambda { | |||
| try { | |||
| @@ -871,8 +871,8 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| Lisp_Object* type = eval_expr( | |||
| Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("type"), | |||
| Memory::create_lisp_object_pair(arguments->value.pair->first, Memory::create_lisp_object_nil())), | |||
| Memory::get_or_create_lisp_object_symbol("type"), | |||
| Memory::create_lisp_object_pair(arguments->value.pair->first, Memory::nil)), | |||
| env); | |||
| if (type) { | |||
| @@ -936,7 +936,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| delete_error(); | |||
| } | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("print", cLambda { | |||
| try { | |||
| @@ -947,7 +947,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| print(evaluated_arguments->value.pair->first); | |||
| // printf("\n"); | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("read", cLambda { | |||
| try { | |||
| @@ -991,11 +991,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| defun("break", cLambda { | |||
| print_environment(env); | |||
| debug_break(); | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("memstat", cLambda { | |||
| Memory::print_status(); | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("try", cLambda { | |||
| try { | |||
| @@ -1089,7 +1089,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| report_error(Error_Type::Type_Missmatch); | |||
| } | |||
| return Memory::create_lisp_object_symbol(Memory::duplicate_string(source->value.string)); | |||
| return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string)); | |||
| }); | |||
| defun("symbol->string", cLambda { | |||
| try { | |||
| @@ -39,10 +39,10 @@ proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { | |||
| } | |||
| if (string_equal(Memory::get_c_str(sym->identifier), "nil")) { | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| } | |||
| if (string_equal(Memory::get_c_str(sym->identifier), "t")) { | |||
| return Memory::create_lisp_object_t(); | |||
| return Memory::t; | |||
| } | |||
| create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); | |||
| @@ -8,7 +8,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||
| // their identifiers but before we converted them to | |||
| // strings from symbols... Wo maybe just use the symbols? | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(function->positional_arguments->identifiers[i]), | |||
| Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]), | |||
| arguments->value.pair->first, new_env); | |||
| } else { | |||
| @@ -69,7 +69,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||
| // if not set it and then add it to the array list | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier), | |||
| Memory::get_or_create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier), | |||
| arguments->value.pair->rest->value.pair->first, | |||
| new_env); | |||
| @@ -108,7 +108,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||
| // to use it or if the user supplied his own | |||
| if (!was_set) { | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(defined_keyword), | |||
| Memory::get_or_create_lisp_object_symbol(defined_keyword), | |||
| Memory::copy_lisp_object(function->keyword_arguments->values->data[i]), new_env); | |||
| } | |||
| } | |||
| @@ -118,13 +118,13 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||
| if (arguments->type == Lisp_Object_Type::Nil) { | |||
| if (function->rest_argument) { | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(function->rest_argument), | |||
| Memory::create_lisp_object_nil(), new_env); | |||
| Memory::get_or_create_lisp_object_symbol(function->rest_argument), | |||
| Memory::nil, new_env); | |||
| } | |||
| } else { | |||
| if (function->rest_argument) { | |||
| define_symbol( | |||
| Memory::create_lisp_object_symbol(function->rest_argument), | |||
| Memory::get_or_create_lisp_object_symbol(function->rest_argument), | |||
| arguments, new_env); | |||
| } else { | |||
| // rest was not declared but additional arguments were found | |||
| @@ -353,12 +353,12 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { | |||
| return nullptr; \ | |||
| } | |||
| if (error) | |||
| return nullptr; | |||
| switch (node->type) { | |||
| case Lisp_Object_Type::T: | |||
| case Lisp_Object_Type::Nil: | |||
| case Lisp_Object_Type::Number: | |||
| case Lisp_Object_Type::Keyword: | |||
| case Lisp_Object_Type::String: | |||
| return node; | |||
| case Lisp_Object_Type::Symbol: { | |||
| Lisp_Object* symbol; | |||
| @@ -367,10 +367,6 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { | |||
| } | |||
| return symbol; | |||
| } | |||
| case Lisp_Object_Type::Number: | |||
| case Lisp_Object_Type::Keyword: | |||
| case Lisp_Object_Type::String: | |||
| return node; | |||
| case Lisp_Object_Type::Pair: { | |||
| Lisp_Object* lispOperator; | |||
| if (node->value.pair->first->type != Lisp_Object_Type::CFunction && | |||
| @@ -448,7 +444,7 @@ proc interprete_file (char* file_name) -> Lisp_Object* { | |||
| Memory::create_string(file_name), file_content); | |||
| } | |||
| Lisp_Object* result = Memory::create_lisp_object_nil(); | |||
| Lisp_Object* result = Memory::nil; | |||
| for (int i = 0; i < program->next_index; ++i) { | |||
| try { | |||
| result = eval_expr(program->data[i], env); | |||
| @@ -19,15 +19,12 @@ namespace Memory { | |||
| String* string_memory; | |||
| String* next_free_spot_in_string_memory; | |||
| proc init() { | |||
| free_spots_in_object_memory = create_Int_array_list(); | |||
| free_spots_in_string_memory = create_Void_Ptr_array_list(); | |||
| object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object)); | |||
| string_memory = (String*)malloc(object_memory_size * sizeof(Lisp_Object)); | |||
| next_free_spot_in_string_memory = string_memory; | |||
| } | |||
| // ------------------ | |||
| // immutables | |||
| // ------------------ | |||
| Lisp_Object* nil = nullptr; | |||
| Lisp_Object* t = nullptr; | |||
| proc print_status() { | |||
| printf("Memory Status:\n" | |||
| @@ -99,20 +96,40 @@ namespace Memory { | |||
| return object; | |||
| } | |||
| proc create_lisp_object_nil() -> Lisp_Object* { | |||
| Lisp_Object* node = create_lisp_object(); | |||
| node->type = Lisp_Object_Type::Nil; | |||
| node->value.pair = nullptr; | |||
| return node; | |||
| } | |||
| proc init() { | |||
| free_spots_in_object_memory = create_Int_array_list(); | |||
| free_spots_in_string_memory = create_Void_Ptr_array_list(); | |||
| proc create_lisp_object_t() -> Lisp_Object* { | |||
| Lisp_Object* node = create_lisp_object(); | |||
| node->type = Lisp_Object_Type::T; | |||
| node->value.pair = nullptr; | |||
| return node; | |||
| object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object)); | |||
| string_memory = (String*)malloc(object_memory_size * sizeof(Lisp_Object)); | |||
| next_free_spot_in_string_memory = string_memory; | |||
| // init nil | |||
| nil = create_lisp_object(); | |||
| nil->type = Lisp_Object_Type::Nil; | |||
| nil->value.pair = nullptr; | |||
| // init t | |||
| t = create_lisp_object(); | |||
| t->type = Lisp_Object_Type::T; | |||
| t->value.pair = nullptr; | |||
| } | |||
| // proc get_lisp_object_nil() -> Lisp_Object* { | |||
| // Lisp_Object* node = create_lisp_object(); | |||
| // node->type = Lisp_Object_Type::Nil; | |||
| // node->value.pair = nullptr; | |||
| // return node; | |||
| // } | |||
| // proc get_lisp_object_t() -> Lisp_Object* { | |||
| // Lisp_Object* node = create_lisp_object(); | |||
| // node->type = Lisp_Object_Type::T; | |||
| // node->value.pair = nullptr; | |||
| // return node; | |||
| // } | |||
| proc create_lisp_object_number(double number) -> Lisp_Object* { | |||
| Lisp_Object* node = create_lisp_object(); | |||
| node->type = Lisp_Object_Type::Number; | |||
| @@ -128,7 +145,9 @@ namespace Memory { | |||
| return node; | |||
| } | |||
| proc create_lisp_object_symbol(String* identifier) -> Lisp_Object* { | |||
| proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* { | |||
| // TODO(Felix): if we already have it stored somewhere then | |||
| // reuse it and dont create new one | |||
| Lisp_Object* node = create_lisp_object(); | |||
| node->type = Lisp_Object_Type::Symbol; | |||
| node->value.symbol = new(Symbol); | |||
| @@ -136,12 +155,14 @@ namespace Memory { | |||
| return node; | |||
| } | |||
| proc create_lisp_object_symbol(const char* identifier) -> Lisp_Object* { | |||
| return create_lisp_object_symbol( | |||
| proc get_or_create_lisp_object_symbol(const char* identifier) -> Lisp_Object* { | |||
| return get_or_create_lisp_object_symbol( | |||
| Memory::create_string(identifier)); | |||
| } | |||
| proc create_lisp_object_keyword(String* keyword) -> Lisp_Object* { | |||
| proc get_or_create_lisp_object_keyword(String* keyword) -> Lisp_Object* { | |||
| // TODO(Felix): if we already have it stored somewhere then | |||
| // reuse it and dont create new one | |||
| Lisp_Object* node = create_lisp_object(); | |||
| node->type = Lisp_Object_Type::Keyword; | |||
| node->value.keyword = new(Keyword); | |||
| @@ -149,8 +170,8 @@ namespace Memory { | |||
| return node; | |||
| } | |||
| proc create_lisp_object_keyword(const char* keyword) -> Lisp_Object* { | |||
| return create_lisp_object_keyword( | |||
| proc get_or_create_lisp_object_keyword(const char* keyword) -> Lisp_Object* { | |||
| return get_or_create_lisp_object_keyword( | |||
| Memory::create_string(keyword)); | |||
| } | |||
| @@ -119,7 +119,7 @@ namespace Parser { | |||
| ++(*index_in_text); | |||
| ++parser_col; | |||
| String* str_keyword = read_atom(text, index_in_text); | |||
| Lisp_Object* ret = Memory::create_lisp_object_keyword(str_keyword); | |||
| Lisp_Object* ret = Memory::get_or_create_lisp_object_keyword(str_keyword); | |||
| inject_scl(ret); | |||
| return ret; | |||
| @@ -128,7 +128,7 @@ namespace Parser { | |||
| proc parse_symbol(char* text, int* index_in_text) -> Lisp_Object* { | |||
| // we are now at the first char of the symbol | |||
| String* str_symbol = read_atom(text, index_in_text); | |||
| Lisp_Object* ret = Memory::create_lisp_object_symbol(str_symbol); | |||
| Lisp_Object* ret = Memory::get_or_create_lisp_object_symbol(str_symbol); | |||
| inject_scl(ret); | |||
| return ret; | |||
| } | |||
| @@ -243,16 +243,16 @@ namespace Parser { | |||
| if (quoteType == '\'') | |||
| return Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("quote"), | |||
| Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil())); | |||
| Memory::get_or_create_lisp_object_symbol("quote"), | |||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||
| else if (quoteType == '`') | |||
| return Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("quasiquote"), | |||
| Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil())); | |||
| Memory::get_or_create_lisp_object_symbol("quasiquote"), | |||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||
| // it has to be an unquote | |||
| return Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("unquote"), | |||
| Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil())); | |||
| Memory::get_or_create_lisp_object_symbol("unquote"), | |||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||
| } | |||
| @@ -267,7 +267,7 @@ namespace Parser { | |||
| if (text[(*index_in_text)] == ')') { | |||
| ++(*index_in_text); | |||
| ++parser_col; | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| } | |||
| // okay there is something | |||
| @@ -299,7 +299,7 @@ namespace Parser { | |||
| if (text[(*index_in_text)] == ')') { | |||
| head->value.pair->rest = Memory::create_lisp_object_nil(); | |||
| head->value.pair->rest = Memory::nil; | |||
| ++parser_col; | |||
| ++(*index_in_text); | |||
| break; | |||
| @@ -384,7 +384,7 @@ namespace Parser { | |||
| // we are now in the function body, just wrap it in an | |||
| // implicit prog | |||
| function->body = Memory::create_lisp_object_pair( | |||
| Memory::create_lisp_object_symbol("prog"), | |||
| Memory::get_or_create_lisp_object_symbol("prog"), | |||
| arguments); | |||
| Lisp_Object* macro = Memory::create_lisp_object(); | |||
| @@ -393,7 +393,7 @@ namespace Parser { | |||
| define_symbol(symbol_for_macro, macro, environment_for_macros); | |||
| // print_environment(environment_for_macros); | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| } else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) { | |||
| /* --- deleting an existing macro --- */ | |||
| @@ -449,7 +449,7 @@ namespace Parser { | |||
| Lisp_Object* result; | |||
| eat_until_code(text, &index_in_text); | |||
| if (text[(index_in_text)] == '\0') | |||
| return Memory::create_lisp_object_nil(); | |||
| return Memory::nil; | |||
| if (text[index_in_text] == '(' || | |||
| text[index_in_text] == '\'' || | |||
| text[index_in_text] == '`' || | |||
| @@ -425,6 +425,41 @@ proc test_built_in_type() -> testresult { | |||
| return pass; | |||
| } | |||
| proc test_singular_t_and_nil() -> testresult { | |||
| Environment* env = Memory::create_built_ins_environment(); | |||
| // nil testing | |||
| char exp_string1[] = "()"; | |||
| char exp_string2[] = "nil"; | |||
| Lisp_Object* expression = Parser::parse_single_expression(exp_string1); | |||
| Lisp_Object* result = eval_expr(expression, env); | |||
| assert_no_error(); | |||
| assert_not_null(result); | |||
| assert_equal_type(result, Lisp_Object_Type::Nil); | |||
| assert_equal_int(expression, result); | |||
| Lisp_Object* expression2 = Parser::parse_single_expression(exp_string2); | |||
| Lisp_Object* result2 = eval_expr(expression2, env); | |||
| assert_no_error(); | |||
| assert_not_null(result); | |||
| assert_equal_type(result, Lisp_Object_Type::Nil); | |||
| assert_equal_int(result, result2); | |||
| assert_equal_int(expression, Memory::nil); | |||
| // t testing | |||
| char exp_string3[] = "t"; | |||
| Lisp_Object* expression3 = Parser::parse_single_expression(exp_string3); | |||
| Lisp_Object* result3 = eval_expr(expression3, env); | |||
| assert_no_error(); | |||
| assert_not_null(result3); | |||
| assert_equal_int(result3, Memory::t); | |||
| return pass; | |||
| } | |||
| proc run_all_tests() -> void { | |||
| log_level = Log_Level::None; | |||
| Memory::init(); | |||
| @@ -449,6 +484,8 @@ proc run_all_tests() -> void { | |||
| invoke_test(test_built_in_type); | |||
| printf("\n-- Memory management --\n"); | |||
| invoke_test(test_singular_t_and_nil); | |||
| printf("\n-- Lexical scope --\n"); | |||
| printf("\n-- Macros --\n"); | |||