From 09582f96692b03eaa985677e0a2f614e41840779 Mon Sep 17 00:00:00 2001 From: FelixBrendel Date: Sun, 14 Apr 2019 16:48:54 +0200 Subject: [PATCH] hello --- .dir-locals.el | 25 +++---------- src/built_ins.cpp | 37 ++++++++----------- src/defines.cpp | 4 +-- src/env.cpp | 1 - src/error.cpp | 5 +-- src/eval.cpp | 8 ++--- src/forward_decls.cpp | 6 +++- src/io.cpp | 79 +++++++++++++++++++++------------------- src/main.cpp | 14 ++++---- src/slime.h | 4 +-- src/testing.cpp | 84 +++++++++++++++++++++---------------------- 11 files changed, 128 insertions(+), 139 deletions(-) diff --git a/.dir-locals.el b/.dir-locals.el index a6f2577..e82376c 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -8,34 +8,19 @@ context-mode-map) (context-mode 1) - ;; additional scripts - (defun save-and-find-test-script-and-compile () - (interactive) - (let ((build-script-name "test.bat")) - (save-and-find-build-script-and-compile))) - (defun save-and-find-run-script-and-compile () - (interactive) - (let ((build-script-name "run.bat")) - (save-and-find-build-script-and-compile))) - (defun save-and-find-debug-script-and-compile () - (interactive) - (let ((build-script-name "debug.bat")) - (save-and-find-build-script-and-compile))) - (defhydra hydra-context (context-mode-map "") "Context Actions:" ("b" save-and-find-build-script-and-compile "build" :color blue) - ("r" save-and-find-run-script-and-compile "run" :color blue) - ("d" save-and-find-debug-script-and-compile "debug" :color blue) - ("t" save-and-find-test-script-and-compile "test" :color blue) ("o" browse-file-directory "open" :color blue) ("q" nil "quit" :color blue)) (define-key context-mode-map (kbd "") 'hydra-context/body) - (font-lock-add-keywords 'c++-mode - '(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" . - font-lock-keyword-face))))))) + (font-lock-add-keywords + 'c++-mode + '(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" . + font-lock-keyword-face))))))) + (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) (eval . (flycheck-mode 0)) (eval . (rainbow-mode 0)) diff --git a/src/built_ins.cpp b/src/built_ins.cpp index bf87eb9..aba179f 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -5,31 +5,24 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { return false; switch (n1->type) { - case Lisp_Object_Type::CFunction: - // TODO(Felix): make comparing work again. - return false; - /* return n1->value.built_in_function->type */ - /* == n2->value.built_in_function->type; */ - case Lisp_Object_Type::Function: - // if they have the same pointer, true is - // returned a few lines above - return false; + + case Lisp_Object_Type::CFunction: // if they have the same + // pointer, true is returned a + // few lines above + case Lisp_Object_Type::Function: return false; + 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.identifier, - n2->value.identifier); - case Lisp_Object_Type::T: - case Lisp_Object_Type::Nil: - return true; - case Lisp_Object_Type::Number: - return n1->value.number == n2->value.number; + return string_equal(n1->value.identifier, n2->value.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: create_not_yet_implemented_error(); return false; - case Lisp_Object_Type::String: - return string_equal(n1->value.string, n2->value.string); - case Lisp_Object_Type::Symbol: - return string_equal(n1->value.identifier, n2->value.identifier); } // we should never reach here @@ -916,7 +909,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { Lisp_Object* result; result = eval_expr(try_part, env); - if (error) { + if (Globals::error) { delete_error(); try { result = eval_expr(catch_part, env); diff --git a/src/defines.cpp b/src/defines.cpp index 9375f44..578ef82 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -28,7 +28,7 @@ constexpr bool is_debug_build = false; else \ while (1) \ if (1) { \ - if(error) { \ + if(Globals::error) { \ if (log_level == Log_Level::Debug) { \ printf("in %s:%d\n", __FILE__, __LINE__); \ } \ @@ -44,7 +44,7 @@ constexpr bool is_debug_build = false; else \ while (1) \ if (1) { \ - if(error) { \ + if(Globals::error) { \ if (log_level == Log_Level::Debug) { \ printf("in %s:%d\n", __FILE__, __LINE__); \ } \ diff --git a/src/env.cpp b/src/env.cpp index 35c028e..b3a7733 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1,4 +1,3 @@ - proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void { // NOTE(Felix): right now we are simply adding the symol at the // back of the list without checking if it already exists but are diff --git a/src/error.cpp b/src/error.cpp index 127a033..906a81c 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -1,6 +1,6 @@ -Error* error; - proc delete_error() -> void { + using Globals::error; + if (error) { free(error); error = nullptr; @@ -15,6 +15,7 @@ proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, S delete_error(); debug_break(); + using Globals::error; error = new(Error); error->type = type; error->message = message; diff --git a/src/eval.cpp b/src/eval.cpp index 3120d35..bfe3e94 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -387,7 +387,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { return symbol; } case Lisp_Object_Type::Pair: { - current_source_code = node; + Globals::current_source_code = node; Lisp_Object* lispOperator; if (node->value.pair.first->type != Lisp_Object_Type::CFunction && @@ -486,7 +486,7 @@ proc interprete_stdin() -> void { built_in_load(Memory::create_string("pre.slime"), env); - if (error) { + if (Globals::error) { log_error(); delete_error(); } @@ -497,13 +497,13 @@ proc interprete_stdin() -> void { line = read_expression(); parsed = Parser::parse_single_expression(line); free(line); - if (error) { + if (Globals::error) { log_error(); delete_error(); continue; } evaluated = eval_expr(parsed, env); - if (error) { + if (Globals::error) { log_error(); delete_error(); continue; diff --git a/src/forward_decls.cpp b/src/forward_decls.cpp index 1b39434..72fbdf8 100644 --- a/src/forward_decls.cpp +++ b/src/forward_decls.cpp @@ -12,8 +12,12 @@ proc parse_argument_list(Lisp_Object*, Function*) -> void; proc print_environment(Environment*) -> void; proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*; + namespace Memory { proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*; } -Lisp_Object* current_source_code = nullptr; +namespace Globals { + Lisp_Object* current_source_code = nullptr; + Error* error; +} diff --git a/src/io.cpp b/src/io.cpp index d76ed4a..2f71504 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -119,16 +119,17 @@ proc read_entire_file(char* filename) -> char* { proc read_expression() -> char* { char* line = (char*)malloc(100); + + if(line == nullptr) + return nullptr; + char* linep = line; size_t lenmax = 100, len = lenmax; int c; int nesting = 0; - if(line == NULL) - return NULL; - - for(;;) { + while (true) { c = fgetc(stdin); if(c == EOF) break; @@ -137,9 +138,9 @@ proc read_expression() -> char* { len = lenmax; char * linen = (char*)realloc(linep, lenmax *= 2); - if(linen == NULL) { + if(linen == nullptr) { free(linep); - return NULL; + return nullptr; } line = linen + (line - linep); linep = linen; @@ -168,8 +169,8 @@ proc read_line() -> char* { int nesting = 0; - if(line == NULL) - return NULL; + if(line == nullptr) + return nullptr; for(;;) { c = fgetc(stdin); @@ -180,9 +181,9 @@ proc read_line() -> char* { len = lenmax; char* linen = (char*)realloc(linep, lenmax *= 2); - if(linen == NULL) { + if(linen == nullptr) { free(linep); - return NULL; + return nullptr; } line = linen + (line - linep); linep = linen; @@ -230,31 +231,34 @@ proc panic(char* message) -> void { proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> void { switch (node->type) { - case (Lisp_Object_Type::Nil): fprintf(file, "()"); break; - case (Lisp_Object_Type::T): fprintf(file, "t"); break; - case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break; - case (Lisp_Object_Type::Symbol): fprintf(file, "%s", Memory::get_c_str(node->value.identifier)); break; - case (Lisp_Object_Type::Keyword): fprintf(file, ":%s", Memory::get_c_str(node->value.identifier)); break; - case (Lisp_Object_Type::CFunction): fprintf(file, "[C-function]"); break; + case (Lisp_Object_Type::Nil): fputs("()", file); break; + case (Lisp_Object_Type::T): fputs("t", file); break; + case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break; + case (Lisp_Object_Type::Keyword): fputs(":", file); // NOTE(Felix): intentionall fallthough + case (Lisp_Object_Type::Symbol): fprintf(file, Memory::get_c_str(node->value.identifier)); break; + case (Lisp_Object_Type::CFunction): fputs("[C-function]", file); break; case (Lisp_Object_Type::String): { - if (print_quotes) - fprintf(file, "\"%s\"", Memory::get_c_str(node->value.string)); + if (print_quotes) { + putc('\"', file); + fputs(Memory::get_c_str(node->value.string), file); + putc('\"', file); + } else - fprintf(file, "%s", Memory::get_c_str(node->value.string)); + fputs(Memory::get_c_str(node->value.string), file); } break; case (Lisp_Object_Type::Function): { if (node->value.function.type == Function_Type::Lambda) - fprintf(file, "[lambda]"); + fputs("[lambda]", file); else if (node->value.function.type == Function_Type::Special_Lambda) - fprintf(file, "[special-lambda]"); + fputs("[special-lambda]", file); else if (node->value.function.type == Function_Type::Macro) - fprintf(file, "[macro]"); + fputs("[macro]", file); else assert(false); } break; case (Lisp_Object_Type::Pair): { Lisp_Object* head = node; - fprintf(file, "("); + putc('(', file); // NOTE(Felix): We cold do a while true here, however in case // we want to print a broken list (for logging the error) we @@ -266,38 +270,39 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> return; if (head->type != Lisp_Object_Type::Pair) break; - fprintf(file, " "); + putc(' ', file); } if (head->type != Lisp_Object_Type::Nil) { - fprintf(file, " . "); + fputs(" . ", file); print(head); } - fprintf(file, ")"); + putc(')', file); } break; } } proc print_error_location() -> void { - if (current_source_code) { + if (Globals::current_source_code) { printf("%s (line %d, position %d) code:" console_red "\n ", Memory::get_c_str( - current_source_code->sourceCodeLocation->file), - current_source_code->sourceCodeLocation->line, - current_source_code->sourceCodeLocation->column); - print(current_source_code); + Globals::current_source_code->sourceCodeLocation->file), + Globals::current_source_code->sourceCodeLocation->line, + Globals::current_source_code->sourceCodeLocation->column); + print(Globals::current_source_code); } else { - printf("no source code location avaliable"); + fputs("no source code location avaliable", stdout); } } proc log_error() -> void { - printf("%s%s%s\n", console_red, - Memory::get_c_str(error->message), - console_normal); - printf(" in: %s", console_cyan); + fputs(console_red, stdout); + fputs(Memory::get_c_str(Globals::error->message), stdout); + puts(console_normal); + + fputs(" in: " console_cyan, stdout); print_error_location(); - printf("%s\n", console_normal); + puts(console_normal); } diff --git a/src/main.cpp b/src/main.cpp index 5f1ea2e..67a7393 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,17 +1,19 @@ #include "slime.h" +// using namespace Slime; + int main(int argc, char* argv[]) { if (argc > 1) { - if (Slime::string_equal(argv[1], "--run-tests")) { - return Slime::run_all_tests() ? 0 : 1; + if (string_equal(argv[1], "--run-tests")) { + return run_all_tests() ? 0 : 1; } - Slime::interprete_file(argv[1]); - if (Slime::error) { - Slime::log_error(); + interprete_file(argv[1]); + if (Globals::error) { + log_error(); return 1; } } else { - Slime::interprete_stdin(); + interprete_stdin(); } } diff --git a/src/slime.h b/src/slime.h index 9e32f1a..e8db174 100644 --- a/src/slime.h +++ b/src/slime.h @@ -12,7 +12,7 @@ #undef _CRT_SECURE_NO_DEPRECATE #undef _CRT_SECURE_NO_WARNINGS -namespace Slime { +// namespace Slime { # include "./defines.cpp" # include "./structs.cpp" # include "./forward_decls.cpp" @@ -26,4 +26,4 @@ namespace Slime { # include "./built_ins.cpp" # include "./testing.cpp" # include "./undefines.cpp" -} +// } diff --git a/src/testing.cpp b/src/testing.cpp index 8fccd81..4cb9767 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -29,20 +29,20 @@ } #define assert_no_error() \ - if (error) { \ - print_assert_equal_fail(error, 0, size_t, "%zd"); \ + if (Globals::error) { \ + print_assert_equal_fail(Globals::error, 0, size_t, "%zd"); \ printf("\nExpected no error to occur," \ " but an error occured anyways:\n"); \ log_error(); \ return fail; \ } \ -#define assert_error() \ - if (!error) { \ - print_assert_not_equal_fail(error, 0, size_t, "%zd"); \ - printf("\nExpected an error to occur," \ - " but no error occured:\n"); \ - return fail; \ +#define assert_error() \ + if (!Globals::error) { \ + print_assert_not_equal_fail(Globals::error, 0, size_t, "%zd"); \ + printf("\nExpected an error to occur," \ + " but no error occured:\n"); \ + return fail; \ } \ #define assert_equal_double(variable, value) \ @@ -77,40 +77,40 @@ #define assert_not_null(variable) \ assert_not_equal_int(variable, nullptr) -#define invoke_test(name) \ - printf("" #name ":"); \ - if (name() == pass) { \ - for(size_t i = strlen(#name); i < 70; ++i) \ - printf((i%3==1)? "." : " "); \ - printf("%spassed%s\n", console_green, console_normal); \ - } \ - else { \ - result = false; \ - for(int i = -1; i < 70; ++i) \ - printf((i%3==1)? "." : " "); \ - printf("%sfailed%s\n", console_red, console_normal); \ - if(error) { \ - free(error); \ - error = nullptr; \ - } \ - } \ +#define invoke_test(name) \ + fputs("" #name ":", stdout); \ + if (name() == pass) { \ + for(size_t i = strlen(#name); i < 70; ++i) \ + fputs((i%3==1)? "." : " ", stdout); \ + fputs(console_green "passed\n" console_normal, stdout); \ + } \ + else { \ + result = false; \ + for(int i = -1; i < 70; ++i) \ + fputs((i%3==1)? "." : " ", stdout); \ + fputs(console_red "failed\n" console_normal, stdout); \ + if(Globals::error) { \ + free(Globals::error); \ + Globals::error = nullptr; \ + } \ + } \ -#define invoke_test_script(name) \ - printf("" name ":"); \ - if (test_file("tests/" name ".slime") == pass) { \ - for(size_t i = strlen(name); i < 70; ++i) \ - printf((i%3==1)? "." : " "); \ - printf("%spassed%s\n", console_green, console_normal); \ - } \ - else { \ - result = false; \ - for(int i = -1; i < 70; ++i) \ - printf((i%3==1)? "." : " "); \ - printf("%sfailed%s\n", console_red, console_normal); \ - if(error) { \ - free(error); \ - error = nullptr; \ - } \ +#define invoke_test_script(name) \ + fputs("" name ":", stdout); \ + if (test_file("tests/" name ".slime") == pass) { \ + for(size_t i = strlen(name); i < 70; ++i) \ + fputs((i%3==1)? "." : " ", stdout); \ + fputs(console_green "passed\n" console_normal, stdout); \ + } \ + else { \ + result = false; \ + for(int i = -1; i < 70; ++i) \ + fputs((i%3==1)? "." : " ", stdout); \ + fputs(console_red "failed\n" console_normal, stdout); \ + if(Globals::error) { \ + free(Globals::error); \ + Globals::error = nullptr; \ + } \ } proc test_eval_operands() -> testresult { @@ -480,7 +480,7 @@ proc test_singular_t_and_nil() -> testresult { proc test_file(const char* file) -> testresult { Memory::reset(); - static Environment* env = Memory::create_built_ins_environment(); + Environment* env = Memory::create_built_ins_environment(); Parser::init(env);