From cb58c6b6da72e3b95aaf7389e6782492e3e22ec9 Mon Sep 17 00:00:00 2001 From: FelixBrendel Date: Thu, 17 Oct 2019 12:34:33 +0200 Subject: [PATCH] =?UTF-8?q?linker=20error=20f=C3=BCr=20sven?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.bat | 1 - src/built_ins.cpp | 22 +++++---- src/defines.cpp | 108 ++---------------------------------------- src/env.cpp | 10 ++-- src/eval.cpp | 13 +++-- src/forward_decls.cpp | 21 ++++---- src/ftb | 2 +- src/gc.cpp | 31 ++++++------ src/io.cpp | 2 +- src/lisp_object.cpp | 19 ++------ src/memory.cpp | 65 ++++++++++++------------- src/parse.cpp | 8 ++-- src/slime.cpp | 45 ++++++++++++++++++ src/slime.h | 13 ++++- src/slime_new.h | 11 +++++ src/structs.cpp | 42 ++++++++-------- src/testing.cpp | 79 +++++++++++++++--------------- src/visualization.cpp | 42 ++++++++-------- 18 files changed, 247 insertions(+), 287 deletions(-) create mode 100644 src/slime.cpp create mode 100644 src/slime_new.h diff --git a/build.bat b/build.bat index 435a8c6..3f7e54a 100644 --- a/build.bat +++ b/build.bat @@ -10,7 +10,6 @@ echo ---------- Compiling ---------- call ..\timecmd cl ../src/main.cpp /D_PROFILING /D_DEBUG /D_DONT_BREAK_ON_ERRORS /Zi /std:c++latest /Fe%exeName% /W3 /wd4003 /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc - if %errorlevel% == 0 ( echo. echo ---- Running Tests ---- diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 22ee8b8..ce3e92f 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -45,7 +45,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { proc add_to_load_path(const char* path) -> void { using Globals::load_path; - append_to_array_list(&load_path, (void*)path); + load_path.append((void*)path); } proc built_in_load(String* file_name) -> Lisp_Object* { @@ -56,7 +56,7 @@ proc built_in_load(String* file_name) -> Lisp_Object* { file_content = read_entire_file(Memory::get_c_str(file_name)); if (!file_content) { - for_array_list (Globals::load_path) { + for (auto it: Globals::load_path) { fullpath[0] = '\0'; sprintf(fullpath, "%s%s", (char*)it, Memory::get_c_str(file_name)); file_content = read_entire_file(fullpath); @@ -65,7 +65,7 @@ proc built_in_load(String* file_name) -> Lisp_Object* { } if (!file_content) { printf("Load path:\n"); - for_array_list (Globals::load_path) { + for (auto it : Globals::load_path) { printf(" - %s\n", (char*) it); } create_generic_error("The file to load '%s' was not found in the load path.", @@ -76,7 +76,7 @@ proc built_in_load(String* file_name) -> Lisp_Object* { Lisp_Object* result = Memory::nil; - Lisp_Object_Array_List program; + Array_List program; try program = Parser::parse_program(Memory::create_string(fullpath), file_content); for (int i = 0; i < program.next_index; ++i) { @@ -89,7 +89,7 @@ proc built_in_import(String* file_name) -> Lisp_Object* { // create new empty environment Environment* new_env; try new_env = Memory::create_child_environment(get_root_environment()); - append_to_array_list(&get_current_environment()->parents, new_env); + get_current_environment()->parents.append(new_env); push_environment(new_env); defer { @@ -422,6 +422,9 @@ proc load_built_ins_into_environment() -> void { try func = Memory::create_lisp_object(); Memory::set_type(func, Lisp_Object_Type::Function); func->value.function.type = Function_Type::Macro; + new((&func->value.function.args.positional.symbols)) Array_List(16); + new((&func->value.function.args.keyword.keywords)) Array_List(16); + new((&func->value.function.args.keyword.values)) Array_List(16); if (doc) func->docstring = doc->value.string; @@ -470,6 +473,9 @@ proc load_built_ins_into_environment() -> void { try func = Memory::create_lisp_object(); Memory::set_type(func, Lisp_Object_Type::Function); func->value.function.type = Function_Type::Lambda; + new((&func->value.function.args.positional.symbols)) Array_List(16); + new((&func->value.function.args.keyword.keywords)) Array_List(16); + new((&func->value.function.args.keyword.values)) Array_List(16); if (doc) func->docstring = doc->value.string; @@ -834,7 +840,7 @@ proc load_built_ins_into_environment() -> void { fetch(hm, key); try assert_type(hm, Lisp_Object_Type::HashMap); - Lisp_Object* ret = (Lisp_Object*)hm_get_object(hm->value.hashMap, key); + Lisp_Object* ret = (Lisp_Object*)hm->value.hashMap.get_object(key); if (!ret) create_symbol_undefined_error("The key was not set in the hashmap"); @@ -843,13 +849,13 @@ proc load_built_ins_into_environment() -> void { define((hash-map-set! hm key value), "TODO") { fetch(hm, key, value); try assert_type(hm, Lisp_Object_Type::HashMap); - hm_set(hm->value.hashMap, key, value); + hm->value.hashMap.set_object(key, value); return Memory::nil; }; define((hash-map-delete! hm key), "TODO") { fetch(hm, key); try assert_type(hm, Lisp_Object_Type::HashMap); - hm_delete_object(hm->value.hashMap, key); + hm->value.hashMap.delete_object(key); return Memory::nil; }; define((vector . args), "TODO") { diff --git a/src/defines.cpp b/src/defines.cpp index 20c41ba..1a25821 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -45,113 +45,15 @@ #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) #define ignore_logging fluid_let(Globals::log_level, Log_Level::None) -#define define_array_list(type, name) \ - \ - struct name##_Array_List { \ - type* data; \ - int length; \ - int next_index; \ - }; \ - \ - proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \ - arraylist->data[index] = \ - arraylist->data[--(arraylist->next_index)]; \ - } \ - \ - proc append_to_array_list(name##_Array_List* arraylist, type element) -> void { \ - if (arraylist->next_index == arraylist->length) { \ - arraylist->length *= 2; \ - arraylist->data = \ - (type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \ - } \ - arraylist->data[arraylist->next_index] = element; \ - arraylist->next_index++; \ - } \ - \ - proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \ - int start2 = mid + 1; \ - \ - /* If the direct merge is already sorted */ \ - if ((size_t)arr->data[mid] <= (size_t)arr->data[start2]) { \ - return; \ - } \ - \ - /* Two pointers to maintain start of both arrays to merge */ \ - while (start <= mid && start2 <= end) { \ - if ((size_t)arr->data[start] <= (size_t)arr->data[start2]) { \ - start++; \ - } \ - else { \ - type value = arr->data[start2]; \ - int index = start2; \ - \ - /* Shift all the elements between element 1; element 2, right by 1. */ \ - while (index != start) { \ - arr->data[index] = arr->data[index - 1]; \ - index--; \ - } \ - arr->data[start] = value; \ - \ - /* Update all the pointers */ \ - start++; \ - mid++; \ - start2++; \ - } \ - } \ - } \ - \ - proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \ - if (left == -1) { \ - sort_array_list(arraylist, 0, arraylist->next_index - 1); \ - return; \ - } else if (left == right) { \ - return; \ - } \ - \ - int middle = left + (right-left) / 2; \ - \ - sort_array_list(arraylist, left, middle); \ - sort_array_list(arraylist, middle+1, right); \ - \ - _merge_array_lists(arraylist, left, middle, right); \ - } \ - \ - proc sorted_array_list_find(name##_Array_List* arraylist, type elem, int left=-1, int right=-1) -> int { \ - if (left == -1) { \ - return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \ - } else if (left == right) { \ - if ((size_t)arraylist->data[left] == (size_t)elem) \ - return left; \ - return -1; \ - } else if (right < left) \ - return -1; \ - \ - int middle = left + (right-left) / 2; \ - \ - if ((size_t)arraylist->data[middle] < (size_t)elem) \ - return sorted_array_list_find(arraylist, elem, middle+1, right); \ - if ((size_t)arraylist->data[middle] > (size_t)elem) \ - return sorted_array_list_find(arraylist, elem, left, middle-1); \ - return middle; \ - } \ - \ - proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List { \ - name##_Array_List ret; \ - ret.data = (type*)malloc(initial_capacity * sizeof(type)); \ - ret.next_index = 0; \ - ret.length = initial_capacity; \ - return ret; \ - } - /* * iterate over array lists */ -#define for_array_list(l) \ - if (int it_index = 0); else \ - for (auto it = (l).data[0]; \ - it_index < (l).next_index; \ - it=(l).data[++it_index]) +// #define for_array_list(l) \ +// if (int it_index = 0); else \ +// for (auto it = (l).data[0]; \ +// it_index < (l).next_index; \ +// it=(l).data[++it_index]) /* * iterate over lisp vectors diff --git a/src/env.cpp b/src/env.cpp index 812d6ad..dfd9911 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1,10 +1,10 @@ proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void { Environment* env = get_current_environment(); - hm_set(env->hm, symbol, value); + env->hm.set_object(symbol, value); } inline proc lookup_symbol_in_this_envt(Lisp_Object* sym, Environment* env) -> Lisp_Object* { - return (Lisp_Object*)hm_get_object(env->hm, sym); + return (Lisp_Object*)env->hm.get_object(sym); } proc environment_binds_symbol(Lisp_Object* sym, Environment* env) -> bool { @@ -14,7 +14,7 @@ proc environment_binds_symbol(Lisp_Object* sym, Environment* env) -> bool { proc find_binding_environment(Lisp_Object* sym, Environment* env) -> Environment* { if (environment_binds_symbol(sym, env)) return env; - for_array_list (env->parents) { + for (auto it : env->parents) { if (Environment* ret = find_binding_environment(sym, it)) return ret; } @@ -50,7 +50,7 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { inline proc push_environment(Environment* env) -> void { using namespace Globals::Current_Execution; - append_to_array_list(&envi_stack, env); + envi_stack.append(env); } inline proc pop_environment() -> void { @@ -98,7 +98,7 @@ proc print_environment_indent(Environment* env, int indent) -> void { // return; // } - for_ptr_hash_map (env->hm) { + for_LO_to_LO_hash_map (env->hm) { print_indent(indent); printf("-> %s :: ", &(((Lisp_Object*)key)->value.symbol.identifier->data)); print((Lisp_Object*)value); diff --git a/src/eval.cpp b/src/eval.cpp index 2bd7b56..5b20b4f 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -38,7 +38,7 @@ proc create_extended_environment_for_function_application( // for the function call Lisp_Object* sym, *val; // used as temp storage to use `try` - Lisp_Object_Array_List read_in_keywords; + Array_List read_in_keywords; int obligatory_keywords_count = 0; int read_obligatory_keywords_count = 0; @@ -69,7 +69,6 @@ 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_Lisp_Object_array_list(); if (arguments == Memory::nil) return; @@ -146,7 +145,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); + read_in_keywords.append(arguments->value.pair.first); ++read_obligatory_keywords_count; // overstep both for next one @@ -253,7 +252,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Lisp_Object* function, filling it in */ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void { - Arguments* result; + Arguments* result;; if (Memory::get_type(function) == Lisp_Object_Type::CFunction) { result = &function->value.cFunction->args; } else { @@ -261,8 +260,8 @@ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_O } // first init the fields - result->positional = create_positional_argument_list(16); - result->keyword = create_keyword_argument_list(16); + // result->positional = create_positional_argument_list(16); + // result->keyword = create_keyword_argument_list(16); result->rest = nullptr; // okay let's try to read some positional arguments @@ -393,7 +392,7 @@ proc eval_expr(Lisp_Object* node) -> Lisp_Object* { profile_this; using namespace Globals::Current_Execution; - append_to_array_list(&call_stack, node); + call_stack.append(node); defer { // NOTE(Felix): We only delete the current entry from the call // stack, if we did not encounter an error, otherwise we neet diff --git a/src/forward_decls.cpp b/src/forward_decls.cpp index f4c8298..ba2e3c7 100644 --- a/src/forward_decls.cpp +++ b/src/forward_decls.cpp @@ -29,6 +29,8 @@ namespace Memory { proc create_built_ins_environment() -> Environment*; proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*; inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type; + proc init(int, int, int) -> void; + proc free_everything() -> void; } namespace Parser { @@ -46,10 +48,10 @@ namespace Globals { char* bin_path = nullptr; Log_Level log_level = Log_Level::Debug; - Void_Ptr_Array_List load_path = create_Void_Ptr_array_list(); + Array_List load_path; namespace Current_Execution { - Lisp_Object_Array_List call_stack = create_Lisp_Object_array_list(); - Environment_Array_List envi_stack = create_Environment_array_list(); + Array_List call_stack; + Array_List envi_stack; } #ifdef _DONT_BREAK_ON_ERRORS @@ -60,21 +62,20 @@ namespace Globals { Error* error = nullptr; } - -inline bool hm_objects_match(char* a, char* b) { +bool hm_objects_match(char* a, char* b) { return strcmp(a, b) == 0; } -inline bool hm_objects_match(void* a, void* b) { +bool hm_objects_match(void* a, void* b) { return a == b; } -u32 hm_hash(void* ptr) { +unsigned int hm_hash(void* ptr) { return ((unsigned long long)ptr * 2654435761) % 4294967296; } -u32 hm_hash(char* str) { - u32 value = str[0] << 7; +unsigned int hm_hash(char* str) { + unsigned int value = str[0] << 7; int i = 0; while (str[i]) { value = (10000003 * value) ^ str[i++]; @@ -82,7 +83,7 @@ u32 hm_hash(char* str) { return value ^ i; } -inline bool hm_objects_match(Lisp_Object* a, Lisp_Object* b) { +bool hm_objects_match(Lisp_Object* a, Lisp_Object* b) { return lisp_object_equal(a, b); } diff --git a/src/ftb b/src/ftb index 9c5512b..7e47157 160000 --- a/src/ftb +++ b/src/ftb @@ -1 +1 @@ -Subproject commit 9c5512b1825ad838af7926587922f2083273a601 +Subproject commit 7e47157a5f47c6a7ff3d27e665aaa1a9d48efe2f diff --git a/src/gc.cpp b/src/gc.cpp index 108510a..ff4dcf2 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -3,10 +3,10 @@ namespace GC { int current_mark; - Lisp_Object_Array_List marked_objects; - String_Array_List marked_strings; - Environment_Array_List marked_environments; - Environment_Array_List protected_environments; + Array_List marked_objects; + Array_List marked_strings; + Array_List marked_environments; + Array_List protected_environments; proc marked(Lisp_Object* node) -> bool { return false; @@ -21,11 +21,11 @@ namespace GC { return; // mark object itself - append_to_array_list(&marked_objects, node); + marked_objects.append(node); // mark docstring if (node->docstring) - append_to_array_list(&marked_strings, node->docstring); + marked_strings.append(node->docstring); // mark type specific data switch (Memory::get_type(node)) { @@ -40,7 +40,7 @@ namespace GC { } } break; case Lisp_Object_Type::String: { - append_to_array_list(&marked_strings, node->value.string); + marked_strings.append(node->value.string); } break; case Lisp_Object_Type::Function: { // NOTE(Felix): We dont have to mark the symbols, keywords @@ -49,8 +49,9 @@ namespace GC { maybe_mark(node->value.function.parent_environment); maybe_mark(node->value.function.body); // mark the default arguemnt values: - for_array_list (node->value.function.args.keyword.values) { - if (it) maybe_mark(it); + for (auto it : node->value.function.args.keyword.values) { + if (it) + maybe_mark(it); } } break; default: break; @@ -62,10 +63,10 @@ namespace GC { if (marked(env)) return; - append_to_array_list(&marked_environments, env); + marked_environments.append(env); - for_array_list (env->parents) { - maybe_mark(it); + for (auto p : env->parents) { + maybe_mark(p); } // Lisp_Object* it = env->values[0]; @@ -78,14 +79,12 @@ namespace GC { profile_this; ++current_mark; - for_array_list (protected_environments) maybe_mark(it); - for_array_list (Globals::Current_Execution::envi_stack) maybe_mark(it); + for (auto it : protected_environments) maybe_mark(it); + for (auto it : Globals::Current_Execution::envi_stack) maybe_mark(it); } proc gc_init_and_go() -> void { current_mark = 0; - marked_objects = create_Lisp_Object_array_list(1024); - marked_environments = create_Environment_array_list(1024); while (1) { garbage_collect(); diff --git a/src/io.cpp b/src/io.cpp index 9fd7042..6ccacc3 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -285,7 +285,7 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v case (Lisp_Object_Type::CFunction): fputs("[C-function]", file); break; case (Lisp_Object_Type::Pointer): fputs("[pointer]", file); break; case (Lisp_Object_Type::HashMap): { - for_lisp_obj_hash_map (node->value.hashMap) { + for_LO_to_LO_hash_map (node->value.hashMap) { fputs(" ", file); print(key, true, file); fputs(" -> ", file); diff --git a/src/lisp_object.cpp b/src/lisp_object.cpp index 872a775..e3248a6 100644 --- a/src/lisp_object.cpp +++ b/src/lisp_object.cpp @@ -28,27 +28,14 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* { return "unknown"; } -proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments { - Positional_Arguments ret; - ret.symbols = create_Lisp_Object_array_list(initial_capacity); - return ret; -} - proc append_to_positional_argument_list(Positional_Arguments* args, Lisp_Object* sym) -> void { - append_to_array_list(&args->symbols, sym); -} - -proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments { - Keyword_Arguments ret; - ret.keywords = create_Lisp_Object_array_list(initial_capacity); - ret.values = create_Lisp_Object_array_list(initial_capacity); - return ret; + args->symbols.append(sym); } proc append_to_keyword_argument_list(Keyword_Arguments* args, Lisp_Object* keyword, Lisp_Object* default_value) -> void { - append_to_array_list(&args->keywords, keyword); - append_to_array_list(&args->values, default_value); + args->keywords.append(keyword); + args->values.append(default_value); } diff --git a/src/memory.cpp b/src/memory.cpp index 1ee27c3..baeb345 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -3,14 +3,14 @@ namespace Memory { // ------------------ // global symbol / keyword table // ------------------ - String_Hash_Map* global_symbol_table; - String_Hash_Map* global_keyword_table; + Hash_Map global_symbol_table; + Hash_Map global_keyword_table; // ------------------ // lisp_objects // ------------------ int object_memory_size; - Int_Array_List free_spots_in_object_memory; + Array_List free_spots_in_object_memory; Lisp_Object* object_memory; int next_index_in_object_memory = 0; @@ -18,7 +18,7 @@ namespace Memory { // environments // ------------------ int environment_memory_size; - Environment_Array_List free_spots_in_environment_memory; + Array_List free_spots_in_environment_memory; Environment* environment_memory; int next_index_in_environment_memory = 0; @@ -29,7 +29,7 @@ namespace Memory { // free_spots_in_string_memory is an arraylist of pointers into // the string_memory, where dead String objects live (which give // information about their size) - Void_Ptr_Array_List free_spots_in_string_memory; + Array_List free_spots_in_string_memory; String* string_memory; String* next_free_spot_in_string_memory; @@ -112,7 +112,7 @@ namespace Memory { } proc delete_string(String* str) { - append_to_array_list(&free_spots_in_string_memory, (void*)str); + free_spots_in_string_memory.append((void*)str); } proc duplicate_string(String* str) -> String* { @@ -165,32 +165,29 @@ namespace Memory { return object; } - proc free_everything() { - free(global_symbol_table); - free(global_keyword_table); + proc free_everything() -> void { + // free(global_symbol_table); + // free(global_keyword_table); free(object_memory); free(environment_memory); free(string_memory); } - proc init(int oms, int ems, int sms) { + proc init(int oms, int ems, int sms) -> void { char* exe_path = get_exe_dir(); defer {free(exe_path);}; add_to_load_path(exe_path); + add_to_load_path("../bin/"); - global_symbol_table = create_String_hashmap(); - global_keyword_table = create_String_hashmap(); + // global_symbol_table = create_String_hashmap(); + // global_keyword_table = create_String_hashmap(); object_memory_size = oms; environment_memory_size = ems; string_memory_size = sms; - free_spots_in_object_memory = create_Int_array_list(); - free_spots_in_environment_memory = create_Environment_array_list(); - free_spots_in_string_memory = create_Void_Ptr_array_list(); - object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object)); - environment_memory = (Environment*)malloc(environment_memory_size * sizeof(Environment)); + environment_memory = (Environment*)calloc(environment_memory_size, sizeof(Environment)); string_memory = (String*)malloc(string_memory_size * sizeof(char)); next_free_spot_in_string_memory = string_memory; @@ -215,8 +212,9 @@ namespace Memory { free_spots_in_environment_memory.next_index = 0; free_spots_in_string_memory.next_index = 0; - global_symbol_table = create_String_hashmap(); - global_keyword_table = create_String_hashmap(); + + ::new((&global_symbol_table)) Hash_Map; + ::new((&global_keyword_table)) Hash_Map; try_void Parser::standard_in = create_string("stdin"); @@ -241,7 +239,7 @@ namespace Memory { Lisp_Object* node; try node = create_lisp_object(); set_type(node, Lisp_Object_Type::HashMap); - node->value.hashMap = create_Lisp_Obj_hashmap(); + ::new((&node->value.hashMap)) Hash_Map; return node; } @@ -315,7 +313,7 @@ namespace Memory { set_type(node, Lisp_Object_Type::Symbol); node->value.symbol.identifier = identifier; node->value.symbol.hash = hash(identifier); - hm_set(global_symbol_table, get_c_str(identifier), node); + global_symbol_table.set_object(get_c_str(identifier), node); return node; } @@ -325,19 +323,19 @@ namespace Memory { set_type(node, Lisp_Object_Type::Keyword); node->value.symbol.identifier = keyword; node->value.symbol.hash = hash(keyword); - hm_set(global_keyword_table, get_c_str(keyword), node); + global_keyword_table.set_object(get_c_str(keyword), node); return node; } proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* { - if (auto ret = hm_get_object(global_symbol_table, get_c_str(identifier))) + if (auto ret = global_symbol_table.get_object(get_c_str(identifier))) return (Lisp_Object*)ret; else return create_new_lisp_object_symbol(identifier); } proc get_or_create_lisp_object_symbol(const char* identifier) -> Lisp_Object* { - if (auto ret = hm_get_object(global_symbol_table, (char*)identifier)) + if (auto ret = global_symbol_table.get_object((char*)identifier)) return (Lisp_Object*)ret; else { String* str; @@ -347,14 +345,14 @@ namespace Memory { } proc get_or_create_lisp_object_keyword(String* keyword) -> Lisp_Object* { - if (auto ret = hm_get_object(global_keyword_table, get_c_str(keyword))) + if (auto ret = global_keyword_table.get_object(get_c_str(keyword))) return (Lisp_Object*)ret; else return create_new_lisp_object_keyword(keyword); } proc get_or_create_lisp_object_keyword(const char* keyword) -> Lisp_Object* { - if (auto ret = hm_get_object(global_keyword_table, (char*)keyword)) + if (auto ret = global_keyword_table.get_object((char*)keyword)) return (Lisp_Object*)ret; else { String* str; @@ -370,6 +368,9 @@ namespace Memory { // node->value.lambdaWrapper = new Lambda_Wrapper(function); node->value.cFunction = new(cFunction); node->value.cFunction->args = {}; + new((&node->value.cFunction->args.positional.symbols)) Array_List(16); + new((&node->value.cFunction->args.keyword.keywords)) Array_List(16); + new((&node->value.cFunction->args.keyword.values)) Array_List(16); node->value.cFunction->is_special_form = is_special; return node; } @@ -429,14 +430,14 @@ namespace Memory { env = free_spots_in_environment_memory.data[--free_spots_in_environment_memory.next_index]; } - int start_capacity = 16; - - env->parents = create_Environment_array_list(); - + // inject a new array list; + if (env->parents.data) + free(env->parents.data); + ::new((&env->parents)) Array_List; if (parent) - append_to_array_list(&env->parents, parent); + env->parents.append(parent); - env->hm = create_Void_Ptr_hashmap(); + ::new((&env->hm)) Hash_Map; return env; } diff --git a/src/parse.cpp b/src/parse.cpp index 84f7a65..9132e20 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -443,7 +443,7 @@ namespace Parser { } - proc write_expanded_file(String* file_name, Lisp_Object_Array_List program) -> void { + proc write_expanded_file(String* file_name, Array_List program) -> void { const char* ext = ".expanded"; char* newName = (char*)calloc(10 + file_name->length, sizeof(char)); strcpy(newName, Memory::get_c_str(file_name)); @@ -469,12 +469,12 @@ namespace Parser { } } - proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List { + proc parse_program(String* file_name, char* text) -> Array_List { parser_file = file_name; parser_line = 1; parser_col = 0; - Lisp_Object_Array_List program = create_Lisp_Object_array_list(); + Array_List program; int index_in_text = 0; @@ -485,7 +485,7 @@ namespace Parser { try_struct { parsed = parse_expression(text, &index_in_text); } - append_to_array_list(&program, parsed); + program.append(parsed); } break; case ';': case ' ': diff --git a/src/slime.cpp b/src/slime.cpp new file mode 100644 index 0000000..b856a48 --- /dev/null +++ b/src/slime.cpp @@ -0,0 +1,45 @@ +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_DEPRECATE + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# include +# include + +#else +# include +# include +#endif + +#include "./ftb/arraylist.hpp" +#include "./ftb/macros.hpp" +#include "./ftb/profiler.hpp" +#include "./ftb/hashmap.hpp" + +namespace Slime { +# include "./defines.cpp" +# include "./platform.cpp" +# include "./structs.cpp" +# include "./forward_decls.cpp" +# include "./memory.cpp" +# include "./gc.cpp" +# include "./lisp_object.cpp" +# include "./error.cpp" +# include "./io.cpp" +# include "./env.cpp" +# include "./parse.cpp" +# include "./eval.cpp" +# include "./visualization.cpp" +# include "./docgeneration.cpp" +# include "./built_ins.cpp" +# include "./testing.cpp" +# include "./undefines.cpp" +} diff --git a/src/slime.h b/src/slime.h index a458f87..730cc8f 100644 --- a/src/slime.h +++ b/src/slime.h @@ -21,9 +21,20 @@ # include #endif +#include "./ftb/types.hpp" #include "./ftb/macros.hpp" #include "./ftb/profiler.hpp" + +struct Lisp_Object; +u32 hm_hash(Lisp_Object* obj); +u32 hm_hash(char* obj); +u32 hm_hash(void* obj); +bool hm_objects_match(void* a, void* b); +bool hm_objects_match(char* a, char* b); +bool hm_objects_match(Lisp_Object* a, Lisp_Object* b); + #include "./ftb/hashmap.hpp" +#include "./ftb/arraylist.hpp" namespace Slime { # include "./defines.cpp" @@ -42,5 +53,5 @@ namespace Slime { # include "./docgeneration.cpp" # include "./built_ins.cpp" # include "./testing.cpp" -// # include "./undefines.cpp" +# include "./undefines.cpp" } diff --git a/src/slime_new.h b/src/slime_new.h new file mode 100644 index 0000000..1fcbc67 --- /dev/null +++ b/src/slime_new.h @@ -0,0 +1,11 @@ +#include +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_DEPRECATE +namespace Slime { +# include "./defines.cpp" +# include "./ftb/hashmap.hpp" +# include "./ftb/arraylist.hpp" +# include "./structs.cpp" +# include "./forward_decls.cpp" +# include "./undefines.cpp" +} diff --git a/src/structs.cpp b/src/structs.cpp index 1cab21f..1b949b5 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -2,20 +2,21 @@ struct Lisp_Object; struct String; struct Environment; -// ARRAY LISTS -define_array_list(Lisp_Object*, Lisp_Object); -define_array_list(Environment*, Environment); -define_array_list(String*, String); -define_array_list(int, Int); -define_array_list(void*, Void_Ptr); +unsigned int hm_hash(char* str); +unsigned int hm_hash(void* str); +unsigned int hm_hash(Lisp_Object* str); + +bool hm_objects_match(char* a, char* b); +bool hm_objects_match(void* a, void* b); +bool hm_objects_match(Lisp_Object* a, Lisp_Object* b); // HASH MAPS -define_hash_map(char*, String); -define_hash_map(Lisp_Object*, Lisp_Obj); -define_hash_map(void*, Void_Ptr); -#define for_str_hash_map(hm) __for_hm_generator(char*, hm) -#define for_ptr_hash_map(hm) __for_hm_generator(void*, hm) -#define for_lisp_obj_hash_map(hm) __for_hm_generator(Lisp_Object*, hm) +// define_hash_map(char*, String); +// define_hash_map(Lisp_Object*, Lisp_Obj); +// define_hash_map(void*, Void_Ptr); +#define for_str_to_LO_hash_map(hm) __for_hm_generator(char*, Lisp_Object*, hm) +// #define for_ptr_hash_map(hm) __for_hm_generator(void*, hm) +#define for_LO_to_LO_hash_map(hm) __for_hm_generator(Lisp_Object*, Lisp_Object*, hm) // STRUCTS enum struct Thread_Type { @@ -23,7 +24,6 @@ enum struct Thread_Type { GarbageCollection }; - enum struct Lisp_Object_Type { Nil, T, @@ -65,8 +65,8 @@ enum struct Log_Level { }; struct Continuation { - Lisp_Object_Array_List* call_stack; - Environment_Array_List* envi_stack; + Array_List call_stack; + Array_List envi_stack; }; struct String { @@ -101,15 +101,15 @@ struct Vector { }; struct Positional_Arguments { - Lisp_Object_Array_List symbols; + Array_List symbols; }; struct Keyword_Arguments { // Array of Pointers to Lisp_Object - Lisp_Object_Array_List keywords; + Array_List keywords; // NOTE(Felix): values[i] will be nullptr if no defalut value was // declared for key identifiers[i] - Lisp_Object_Array_List values; + Array_List values; }; struct Arguments { @@ -121,8 +121,8 @@ struct Arguments { }; struct Environment { - Environment_Array_List parents; - Void_Ptr_Hash_Map* hm; + Array_List parents; + Hash_Map hm; }; struct Function { @@ -153,7 +153,7 @@ struct Lisp_Object { cFunction* cFunction; void* pointer; Continuation continuation; - Lisp_Obj_Hash_Map* hashMap; + Hash_Map hashMap; } value; }; diff --git a/src/testing.cpp b/src/testing.cpp index 31ca7e6..8247b51 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -115,79 +115,78 @@ proc test_array_lists_adding_and_removing() -> testresult { // test adding and removing - Int_Array_List list = create_Int_array_list(); - append_to_array_list(&list, 1); - append_to_array_list(&list, 2); - append_to_array_list(&list, 3); - append_to_array_list(&list, 4); + Array_List list; + list.append(1); + list.append(2); + list.append(3); + list.append(4); assert_equal_int(list.next_index, 4); - remove_index_from_array_list(&list, 0); + list.remove_index(0); assert_equal_int(list.next_index, 3); - assert_equal_int(list.data[0], 4); - assert_equal_int(list.data[1], 2); - assert_equal_int(list.data[2], 3); + assert_equal_int(list[0], 4); + assert_equal_int(list[1], 2); + assert_equal_int(list[2], 3); - remove_index_from_array_list(&list, 2); + list.remove_index(2); assert_equal_int(list.next_index, 2); - assert_equal_int(list.data[0], 4); - assert_equal_int(list.data[1], 2); + assert_equal_int(list[0], 4); + assert_equal_int(list[1], 2); return pass; } proc test_array_lists_sorting() -> testresult { // test adding and removing - Int_Array_List list = create_Int_array_list(); - append_to_array_list(&list, 1); - append_to_array_list(&list, 2); - append_to_array_list(&list, 3); - append_to_array_list(&list, 4); + Array_List list; + list.append(1); + list.append(2); + list.append(3); + list.append(4); - sort_array_list(&list); + list.sort(); assert_equal_int(list.next_index, 4); - assert_equal_int(list.data[0], 1); - assert_equal_int(list.data[1], 2); - assert_equal_int(list.data[2], 3); - assert_equal_int(list.data[3], 4); + assert_equal_int(list[0], 1); + assert_equal_int(list[1], 2); + assert_equal_int(list[2], 3); + assert_equal_int(list[3], 4); - append_to_array_list(&list, 0); - append_to_array_list(&list, 5); + list.append(0); + list.append(5); assert_equal_int(list.next_index, 6); - sort_array_list(&list); - - assert_equal_int(list.data[0], 0); - assert_equal_int(list.data[1], 1); - assert_equal_int(list.data[2], 2); - assert_equal_int(list.data[3], 3); - assert_equal_int(list.data[4], 4); - assert_equal_int(list.data[5], 5); + list.sort(); + assert_equal_int(list[0], 0); + assert_equal_int(list[1], 1); + assert_equal_int(list[2], 2); + assert_equal_int(list[3], 3); + assert_equal_int(list[4], 4); + assert_equal_int(list[5], 5); return pass; } proc test_array_lists_searching() -> testresult { - Int_Array_List list = create_Int_array_list(); - append_to_array_list(&list, 1); - append_to_array_list(&list, 2); - append_to_array_list(&list, 3); - append_to_array_list(&list, 4); + Array_List list; + list.append(1); + list.append(2); + list.append(3); + list.append(4); - int index = sorted_array_list_find(&list, 3); + int index = list.sorted_find(3); assert_equal_int(index, 2); - index = sorted_array_list_find(&list, 1); + index = list.sorted_find(1); assert_equal_int(index, 0); - index = sorted_array_list_find(&list, 5); + index = list.sorted_find(5); assert_equal_int(index, -1); return pass; diff --git a/src/visualization.cpp b/src/visualization.cpp index 988bec8..5627af8 100644 --- a/src/visualization.cpp +++ b/src/visualization.cpp @@ -359,12 +359,12 @@ proc visualize_lisp_machine() -> void { draw_new_line(3); }; proc draw_symbols_keywords_and_numbers = [&]() { - Lisp_Object_Array_List symbols = create_Lisp_Object_array_list(); - Lisp_Object_Array_List keywords = create_Lisp_Object_array_list(); - Lisp_Object_Array_List numbers = create_Lisp_Object_array_list(); - Lisp_Object_Array_List strings = create_Lisp_Object_array_list(); - Lisp_Object_Array_List pairs = create_Lisp_Object_array_list(); - Lisp_Object_Array_List lists = create_Lisp_Object_array_list(); + Array_List symbols; + Array_List keywords; + Array_List numbers; + Array_List strings; + Array_List pairs; + Array_List lists; // loop over all used memory for (int i = 0; i < Memory::next_index_in_object_memory; ++i) { @@ -374,11 +374,11 @@ proc visualize_lisp_machine() -> void { } switch (Memory::get_type(Memory::object_memory+i)) { - case Lisp_Object_Type::Symbol: append_to_array_list(&symbols, Memory::object_memory+i); break; - case Lisp_Object_Type::String: append_to_array_list(&strings, Memory::object_memory+i); break; - case Lisp_Object_Type::Keyword: append_to_array_list(&keywords, Memory::object_memory+i); break; - case Lisp_Object_Type::Number : append_to_array_list(&numbers, Memory::object_memory+i); break; - case Lisp_Object_Type::Pair : append_to_array_list(&pairs, Memory::object_memory+i); break; + case Lisp_Object_Type::Symbol: symbols .append(Memory::object_memory+i); break; + case Lisp_Object_Type::String: strings .append(Memory::object_memory+i); break; + case Lisp_Object_Type::Keyword: keywords.append(Memory::object_memory+i); break; + case Lisp_Object_Type::Number : numbers .append(Memory::object_memory+i); break; + case Lisp_Object_Type::Pair : pairs .append(Memory::object_memory+i); break; default: break; } @@ -386,36 +386,36 @@ proc visualize_lisp_machine() -> void { } // create the lists-list by filtering the pairs-list. - Lisp_Object_Array_List pairs_to_filter = create_Lisp_Object_array_list(); + Array_List pairs_to_filter; // helper lambda: - proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List list) -> void { + proc remove_doubles_from_lisp_object_array_list = [&](Array_List list) -> void { if (list.next_index == 0) return; - sort_array_list(&list); - Int_Array_List indices_to_filter = create_Int_array_list(); + list.sort(); + Array_List indices_to_filter; size_t last = (size_t)list.data[0]; for (int i = 1; i < list.next_index; ++i) { if ((size_t)list.data[i] == last) - append_to_array_list(&indices_to_filter, i); + indices_to_filter.append(i); else last = (size_t)list.data[i]; } for (int i = indices_to_filter.next_index; i >= 0; --i) { - remove_index_from_array_list(&list, indices_to_filter.data[i]); + list.remove_index(indices_to_filter.data[i]); } // sort again as removing items destroys the order - sort_array_list(&list); + list.sort(); }; // recursive lambda std::function filter_pair_and_children; filter_pair_and_children = [&](Lisp_Object* pair) { - append_to_array_list(&pairs_to_filter, pair); + pairs_to_filter.append(pair); if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair) filter_pair_and_children(pair->value.pair.first); @@ -437,8 +437,8 @@ proc visualize_lisp_machine() -> void { // okay, so pairs_to_filter now only the pairs once each that // we want to filter from the pairs list for (int i = 0; i < pairs.next_index; ++i) { - if (sorted_array_list_find(&pairs_to_filter, pairs.data[i]) == -1) { - append_to_array_list(&lists, pairs.data[i]); + if (pairs_to_filter.sorted_find(pairs.data[i]) == -1) { + lists.append(pairs.data[i]); } }