From 1bd77be7f65f7eea164827bf5fc6d888718d0533 Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Sun, 24 Feb 2019 14:44:23 +0100 Subject: [PATCH] singulat t and nil --- build.sh | 13 ++++--- src/built_ins.cpp | 98 +++++++++++++++++++++++------------------------ src/env.cpp | 4 +- src/eval.cpp | 24 +++++------- src/memory.cpp | 71 ++++++++++++++++++++++------------ src/parse.cpp | 26 ++++++------- src/testing.cpp | 37 ++++++++++++++++++ 7 files changed, 164 insertions(+), 109 deletions(-) diff --git a/build.sh b/build.sh index c3a7f5b..6f5a012 100755 --- a/build.sh +++ b/build.sh @@ -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 diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 03aac16..c61a695 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -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 { diff --git a/src/env.cpp b/src/env.cpp index 35b377e..56d1989 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -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); diff --git a/src/eval.cpp b/src/eval.cpp index 854ffc3..4f28ea8 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -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); diff --git a/src/memory.cpp b/src/memory.cpp index 2d7d562..91deb1c 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -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)); } diff --git a/src/parse.cpp b/src/parse.cpp index c13f74f..b2fbfae 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -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] == '`' || diff --git a/src/testing.cpp b/src/testing.cpp index 01b492c..43b142e 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -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");