| @@ -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 | 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 | rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc | ||||
| if %errorlevel% == 0 ( | if %errorlevel% == 0 ( | ||||
| echo. | echo. | ||||
| echo ---- Running Tests ---- | echo ---- Running Tests ---- | ||||
| @@ -45,7 +45,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | |||||
| proc add_to_load_path(const char* path) -> void { | proc add_to_load_path(const char* path) -> void { | ||||
| using Globals::load_path; | 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* { | 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)); | file_content = read_entire_file(Memory::get_c_str(file_name)); | ||||
| if (!file_content) { | if (!file_content) { | ||||
| for_array_list (Globals::load_path) { | |||||
| for (auto it: Globals::load_path) { | |||||
| fullpath[0] = '\0'; | fullpath[0] = '\0'; | ||||
| sprintf(fullpath, "%s%s", (char*)it, Memory::get_c_str(file_name)); | sprintf(fullpath, "%s%s", (char*)it, Memory::get_c_str(file_name)); | ||||
| file_content = read_entire_file(fullpath); | file_content = read_entire_file(fullpath); | ||||
| @@ -65,7 +65,7 @@ proc built_in_load(String* file_name) -> Lisp_Object* { | |||||
| } | } | ||||
| if (!file_content) { | if (!file_content) { | ||||
| printf("Load path:\n"); | printf("Load path:\n"); | ||||
| for_array_list (Globals::load_path) { | |||||
| for (auto it : Globals::load_path) { | |||||
| printf(" - %s\n", (char*) it); | printf(" - %s\n", (char*) it); | ||||
| } | } | ||||
| create_generic_error("The file to load '%s' was not found in the load path.", | 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* result = Memory::nil; | ||||
| Lisp_Object_Array_List program; | |||||
| Array_List<Lisp_Object*> program; | |||||
| try program = Parser::parse_program(Memory::create_string(fullpath), file_content); | try program = Parser::parse_program(Memory::create_string(fullpath), file_content); | ||||
| for (int i = 0; i < program.next_index; ++i) { | 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 | // create new empty environment | ||||
| Environment* new_env; | Environment* new_env; | ||||
| try new_env = Memory::create_child_environment(get_root_environment()); | 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); | push_environment(new_env); | ||||
| defer { | defer { | ||||
| @@ -422,6 +422,9 @@ proc load_built_ins_into_environment() -> void { | |||||
| try func = Memory::create_lisp_object(); | try func = Memory::create_lisp_object(); | ||||
| Memory::set_type(func, Lisp_Object_Type::Function); | Memory::set_type(func, Lisp_Object_Type::Function); | ||||
| func->value.function.type = Function_Type::Macro; | func->value.function.type = Function_Type::Macro; | ||||
| new((&func->value.function.args.positional.symbols)) Array_List<Environment*>(16); | |||||
| new((&func->value.function.args.keyword.keywords)) Array_List<Environment*>(16); | |||||
| new((&func->value.function.args.keyword.values)) Array_List<Environment*>(16); | |||||
| if (doc) func->docstring = doc->value.string; | if (doc) func->docstring = doc->value.string; | ||||
| @@ -470,6 +473,9 @@ proc load_built_ins_into_environment() -> void { | |||||
| try func = Memory::create_lisp_object(); | try func = Memory::create_lisp_object(); | ||||
| Memory::set_type(func, Lisp_Object_Type::Function); | Memory::set_type(func, Lisp_Object_Type::Function); | ||||
| func->value.function.type = Function_Type::Lambda; | func->value.function.type = Function_Type::Lambda; | ||||
| new((&func->value.function.args.positional.symbols)) Array_List<Environment*>(16); | |||||
| new((&func->value.function.args.keyword.keywords)) Array_List<Environment*>(16); | |||||
| new((&func->value.function.args.keyword.values)) Array_List<Environment*>(16); | |||||
| if (doc) | if (doc) | ||||
| func->docstring = doc->value.string; | func->docstring = doc->value.string; | ||||
| @@ -834,7 +840,7 @@ proc load_built_ins_into_environment() -> void { | |||||
| fetch(hm, key); | fetch(hm, key); | ||||
| try assert_type(hm, Lisp_Object_Type::HashMap); | 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) | if (!ret) | ||||
| create_symbol_undefined_error("The key was not set in the hashmap"); | 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") { | define((hash-map-set! hm key value), "TODO") { | ||||
| fetch(hm, key, value); | fetch(hm, key, value); | ||||
| try assert_type(hm, Lisp_Object_Type::HashMap); | 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; | return Memory::nil; | ||||
| }; | }; | ||||
| define((hash-map-delete! hm key), "TODO") { | define((hash-map-delete! hm key), "TODO") { | ||||
| fetch(hm, key); | fetch(hm, key); | ||||
| try assert_type(hm, Lisp_Object_Type::HashMap); | try assert_type(hm, Lisp_Object_Type::HashMap); | ||||
| hm_delete_object(hm->value.hashMap, key); | |||||
| hm->value.hashMap.delete_object(key); | |||||
| return Memory::nil; | return Memory::nil; | ||||
| }; | }; | ||||
| define((vector . args), "TODO") { | define((vector . args), "TODO") { | ||||
| @@ -45,113 +45,15 @@ | |||||
| #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) | #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) | ||||
| #define ignore_logging fluid_let(Globals::log_level, Log_Level::None) | #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 | * 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 | * iterate over lisp vectors | ||||
| @@ -1,10 +1,10 @@ | |||||
| proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void { | proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void { | ||||
| Environment* env = get_current_environment(); | 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* { | 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 { | 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* { | proc find_binding_environment(Lisp_Object* sym, Environment* env) -> Environment* { | ||||
| if (environment_binds_symbol(sym, env)) | if (environment_binds_symbol(sym, env)) | ||||
| return env; | return env; | ||||
| for_array_list (env->parents) { | |||||
| for (auto it : env->parents) { | |||||
| if (Environment* ret = find_binding_environment(sym, it)) | if (Environment* ret = find_binding_environment(sym, it)) | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -50,7 +50,7 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { | |||||
| inline proc push_environment(Environment* env) -> void { | inline proc push_environment(Environment* env) -> void { | ||||
| using namespace Globals::Current_Execution; | using namespace Globals::Current_Execution; | ||||
| append_to_array_list(&envi_stack, env); | |||||
| envi_stack.append(env); | |||||
| } | } | ||||
| inline proc pop_environment() -> void { | inline proc pop_environment() -> void { | ||||
| @@ -98,7 +98,7 @@ proc print_environment_indent(Environment* env, int indent) -> void { | |||||
| // return; | // return; | ||||
| // } | // } | ||||
| for_ptr_hash_map (env->hm) { | |||||
| for_LO_to_LO_hash_map (env->hm) { | |||||
| print_indent(indent); | print_indent(indent); | ||||
| printf("-> %s :: ", &(((Lisp_Object*)key)->value.symbol.identifier->data)); | printf("-> %s :: ", &(((Lisp_Object*)key)->value.symbol.identifier->data)); | ||||
| print((Lisp_Object*)value); | print((Lisp_Object*)value); | ||||
| @@ -38,7 +38,7 @@ proc create_extended_environment_for_function_application( | |||||
| // for the function call | // for the function call | ||||
| Lisp_Object* sym, *val; // used as temp storage to use `try` | Lisp_Object* sym, *val; // used as temp storage to use `try` | ||||
| Lisp_Object_Array_List read_in_keywords; | |||||
| Array_List<Lisp_Object*> read_in_keywords; | |||||
| int obligatory_keywords_count = 0; | int obligatory_keywords_count = 0; | ||||
| int read_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 | // added ones (array list), if end of parameters in encountered or | ||||
| // something that is not a keyword is encountered or a keyword | // something that is not a keyword is encountered or a keyword | ||||
| // that is not recognized is encoutered, jump out of the loop. | // that is not recognized is encoutered, jump out of the loop. | ||||
| read_in_keywords = create_Lisp_Object_array_list(); | |||||
| if (arguments == Memory::nil) | if (arguments == Memory::nil) | ||||
| return; | 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)); | 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; | ++read_obligatory_keywords_count; | ||||
| // overstep both for next one | // overstep both for next one | ||||
| @@ -253,7 +252,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Lisp_Object* function, | |||||
| filling it in | filling it in | ||||
| */ | */ | ||||
| proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void { | 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) { | if (Memory::get_type(function) == Lisp_Object_Type::CFunction) { | ||||
| result = &function->value.cFunction->args; | result = &function->value.cFunction->args; | ||||
| } else { | } else { | ||||
| @@ -261,8 +260,8 @@ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_O | |||||
| } | } | ||||
| // first init the fields | // 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; | result->rest = nullptr; | ||||
| // okay let's try to read some positional arguments | // okay let's try to read some positional arguments | ||||
| @@ -393,7 +392,7 @@ proc eval_expr(Lisp_Object* node) -> Lisp_Object* { | |||||
| profile_this; | profile_this; | ||||
| using namespace Globals::Current_Execution; | using namespace Globals::Current_Execution; | ||||
| append_to_array_list(&call_stack, node); | |||||
| call_stack.append(node); | |||||
| defer { | defer { | ||||
| // NOTE(Felix): We only delete the current entry from the call | // NOTE(Felix): We only delete the current entry from the call | ||||
| // stack, if we did not encounter an error, otherwise we neet | // stack, if we did not encounter an error, otherwise we neet | ||||
| @@ -29,6 +29,8 @@ namespace Memory { | |||||
| proc create_built_ins_environment() -> Environment*; | proc create_built_ins_environment() -> Environment*; | ||||
| proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*; | proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*; | ||||
| inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type; | inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type; | ||||
| proc init(int, int, int) -> void; | |||||
| proc free_everything() -> void; | |||||
| } | } | ||||
| namespace Parser { | namespace Parser { | ||||
| @@ -46,10 +48,10 @@ namespace Globals { | |||||
| char* bin_path = nullptr; | char* bin_path = nullptr; | ||||
| Log_Level log_level = Log_Level::Debug; | Log_Level log_level = Log_Level::Debug; | ||||
| Void_Ptr_Array_List load_path = create_Void_Ptr_array_list(); | |||||
| Array_List<void*> load_path; | |||||
| namespace Current_Execution { | 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<Lisp_Object*> call_stack; | |||||
| Array_List<Environment*> envi_stack; | |||||
| } | } | ||||
| #ifdef _DONT_BREAK_ON_ERRORS | #ifdef _DONT_BREAK_ON_ERRORS | ||||
| @@ -60,21 +62,20 @@ namespace Globals { | |||||
| Error* error = nullptr; | 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; | 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; | return a == b; | ||||
| } | } | ||||
| u32 hm_hash(void* ptr) { | |||||
| unsigned int hm_hash(void* ptr) { | |||||
| return ((unsigned long long)ptr * 2654435761) % 4294967296; | 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; | int i = 0; | ||||
| while (str[i]) { | while (str[i]) { | ||||
| value = (10000003 * value) ^ str[i++]; | value = (10000003 * value) ^ str[i++]; | ||||
| @@ -82,7 +83,7 @@ u32 hm_hash(char* str) { | |||||
| return value ^ i; | 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); | return lisp_object_equal(a, b); | ||||
| } | } | ||||
| @@ -1 +1 @@ | |||||
| Subproject commit 9c5512b1825ad838af7926587922f2083273a601 | |||||
| Subproject commit 7e47157a5f47c6a7ff3d27e665aaa1a9d48efe2f | |||||
| @@ -3,10 +3,10 @@ namespace GC { | |||||
| int current_mark; | 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<Lisp_Object*> marked_objects; | |||||
| Array_List<String*> marked_strings; | |||||
| Array_List<Environment*> marked_environments; | |||||
| Array_List<Environment*> protected_environments; | |||||
| proc marked(Lisp_Object* node) -> bool { | proc marked(Lisp_Object* node) -> bool { | ||||
| return false; | return false; | ||||
| @@ -21,11 +21,11 @@ namespace GC { | |||||
| return; | return; | ||||
| // mark object itself | // mark object itself | ||||
| append_to_array_list(&marked_objects, node); | |||||
| marked_objects.append(node); | |||||
| // mark docstring | // mark docstring | ||||
| if (node->docstring) | if (node->docstring) | ||||
| append_to_array_list(&marked_strings, node->docstring); | |||||
| marked_strings.append(node->docstring); | |||||
| // mark type specific data | // mark type specific data | ||||
| switch (Memory::get_type(node)) { | switch (Memory::get_type(node)) { | ||||
| @@ -40,7 +40,7 @@ namespace GC { | |||||
| } | } | ||||
| } break; | } break; | ||||
| case Lisp_Object_Type::String: { | case Lisp_Object_Type::String: { | ||||
| append_to_array_list(&marked_strings, node->value.string); | |||||
| marked_strings.append(node->value.string); | |||||
| } break; | } break; | ||||
| case Lisp_Object_Type::Function: { | case Lisp_Object_Type::Function: { | ||||
| // NOTE(Felix): We dont have to mark the symbols, keywords | // 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.parent_environment); | ||||
| maybe_mark(node->value.function.body); | maybe_mark(node->value.function.body); | ||||
| // mark the default arguemnt values: | // 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; | } break; | ||||
| default: break; | default: break; | ||||
| @@ -62,10 +63,10 @@ namespace GC { | |||||
| if (marked(env)) | if (marked(env)) | ||||
| return; | 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]; | // Lisp_Object* it = env->values[0]; | ||||
| @@ -78,14 +79,12 @@ namespace GC { | |||||
| profile_this; | profile_this; | ||||
| ++current_mark; | ++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 { | proc gc_init_and_go() -> void { | ||||
| current_mark = 0; | current_mark = 0; | ||||
| marked_objects = create_Lisp_Object_array_list(1024); | |||||
| marked_environments = create_Environment_array_list(1024); | |||||
| while (1) { | while (1) { | ||||
| garbage_collect(); | garbage_collect(); | ||||
| @@ -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::CFunction): fputs("[C-function]", file); break; | ||||
| case (Lisp_Object_Type::Pointer): fputs("[pointer]", file); break; | case (Lisp_Object_Type::Pointer): fputs("[pointer]", file); break; | ||||
| case (Lisp_Object_Type::HashMap): { | case (Lisp_Object_Type::HashMap): { | ||||
| for_lisp_obj_hash_map (node->value.hashMap) { | |||||
| for_LO_to_LO_hash_map (node->value.hashMap) { | |||||
| fputs(" ", file); | fputs(" ", file); | ||||
| print(key, true, file); | print(key, true, file); | ||||
| fputs(" -> ", file); | fputs(" -> ", file); | ||||
| @@ -28,27 +28,14 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* { | |||||
| return "unknown"; | 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 { | 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, | proc append_to_keyword_argument_list(Keyword_Arguments* args, | ||||
| Lisp_Object* keyword, | Lisp_Object* keyword, | ||||
| Lisp_Object* default_value) -> void | 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); | |||||
| } | } | ||||
| @@ -3,14 +3,14 @@ namespace Memory { | |||||
| // ------------------ | // ------------------ | ||||
| // global symbol / keyword table | // global symbol / keyword table | ||||
| // ------------------ | // ------------------ | ||||
| String_Hash_Map* global_symbol_table; | |||||
| String_Hash_Map* global_keyword_table; | |||||
| Hash_Map<char*, Lisp_Object*> global_symbol_table; | |||||
| Hash_Map<char*, Lisp_Object*> global_keyword_table; | |||||
| // ------------------ | // ------------------ | ||||
| // lisp_objects | // lisp_objects | ||||
| // ------------------ | // ------------------ | ||||
| int object_memory_size; | int object_memory_size; | ||||
| Int_Array_List free_spots_in_object_memory; | |||||
| Array_List<int> free_spots_in_object_memory; | |||||
| Lisp_Object* object_memory; | Lisp_Object* object_memory; | ||||
| int next_index_in_object_memory = 0; | int next_index_in_object_memory = 0; | ||||
| @@ -18,7 +18,7 @@ namespace Memory { | |||||
| // environments | // environments | ||||
| // ------------------ | // ------------------ | ||||
| int environment_memory_size; | int environment_memory_size; | ||||
| Environment_Array_List free_spots_in_environment_memory; | |||||
| Array_List<Environment*> free_spots_in_environment_memory; | |||||
| Environment* environment_memory; | Environment* environment_memory; | ||||
| int next_index_in_environment_memory = 0; | int next_index_in_environment_memory = 0; | ||||
| @@ -29,7 +29,7 @@ namespace Memory { | |||||
| // free_spots_in_string_memory is an arraylist of pointers into | // free_spots_in_string_memory is an arraylist of pointers into | ||||
| // the string_memory, where dead String objects live (which give | // the string_memory, where dead String objects live (which give | ||||
| // information about their size) | // information about their size) | ||||
| Void_Ptr_Array_List free_spots_in_string_memory; | |||||
| Array_List<void*> free_spots_in_string_memory; | |||||
| String* string_memory; | String* string_memory; | ||||
| String* next_free_spot_in_string_memory; | String* next_free_spot_in_string_memory; | ||||
| @@ -112,7 +112,7 @@ namespace Memory { | |||||
| } | } | ||||
| proc delete_string(String* str) { | 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* { | proc duplicate_string(String* str) -> String* { | ||||
| @@ -165,32 +165,29 @@ namespace Memory { | |||||
| return object; | 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(object_memory); | ||||
| free(environment_memory); | free(environment_memory); | ||||
| free(string_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(); | char* exe_path = get_exe_dir(); | ||||
| defer {free(exe_path);}; | defer {free(exe_path);}; | ||||
| add_to_load_path(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; | object_memory_size = oms; | ||||
| environment_memory_size = ems; | environment_memory_size = ems; | ||||
| string_memory_size = sms; | 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)); | 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)); | string_memory = (String*)malloc(string_memory_size * sizeof(char)); | ||||
| next_free_spot_in_string_memory = string_memory; | 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_environment_memory.next_index = 0; | ||||
| free_spots_in_string_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<char*, Lisp_Object*>; | |||||
| ::new((&global_keyword_table)) Hash_Map<char*, Lisp_Object*>; | |||||
| try_void Parser::standard_in = create_string("stdin"); | try_void Parser::standard_in = create_string("stdin"); | ||||
| @@ -241,7 +239,7 @@ namespace Memory { | |||||
| Lisp_Object* node; | Lisp_Object* node; | ||||
| try node = create_lisp_object(); | try node = create_lisp_object(); | ||||
| set_type(node, Lisp_Object_Type::HashMap); | set_type(node, Lisp_Object_Type::HashMap); | ||||
| node->value.hashMap = create_Lisp_Obj_hashmap(); | |||||
| ::new((&node->value.hashMap)) Hash_Map<Lisp_Object*, Lisp_Object*>; | |||||
| return node; | return node; | ||||
| } | } | ||||
| @@ -315,7 +313,7 @@ namespace Memory { | |||||
| set_type(node, Lisp_Object_Type::Symbol); | set_type(node, Lisp_Object_Type::Symbol); | ||||
| node->value.symbol.identifier = identifier; | node->value.symbol.identifier = identifier; | ||||
| node->value.symbol.hash = hash(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; | return node; | ||||
| } | } | ||||
| @@ -325,19 +323,19 @@ namespace Memory { | |||||
| set_type(node, Lisp_Object_Type::Keyword); | set_type(node, Lisp_Object_Type::Keyword); | ||||
| node->value.symbol.identifier = keyword; | node->value.symbol.identifier = keyword; | ||||
| node->value.symbol.hash = hash(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; | return node; | ||||
| } | } | ||||
| proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* { | 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; | return (Lisp_Object*)ret; | ||||
| else | else | ||||
| return create_new_lisp_object_symbol(identifier); | return create_new_lisp_object_symbol(identifier); | ||||
| } | } | ||||
| proc get_or_create_lisp_object_symbol(const char* identifier) -> Lisp_Object* { | 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; | return (Lisp_Object*)ret; | ||||
| else { | else { | ||||
| String* str; | String* str; | ||||
| @@ -347,14 +345,14 @@ namespace Memory { | |||||
| } | } | ||||
| proc get_or_create_lisp_object_keyword(String* keyword) -> Lisp_Object* { | 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; | return (Lisp_Object*)ret; | ||||
| else | else | ||||
| return create_new_lisp_object_keyword(keyword); | return create_new_lisp_object_keyword(keyword); | ||||
| } | } | ||||
| proc get_or_create_lisp_object_keyword(const char* keyword) -> Lisp_Object* { | 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; | return (Lisp_Object*)ret; | ||||
| else { | else { | ||||
| String* str; | String* str; | ||||
| @@ -370,6 +368,9 @@ namespace Memory { | |||||
| // node->value.lambdaWrapper = new Lambda_Wrapper(function); | // node->value.lambdaWrapper = new Lambda_Wrapper(function); | ||||
| node->value.cFunction = new(cFunction); | node->value.cFunction = new(cFunction); | ||||
| node->value.cFunction->args = {}; | node->value.cFunction->args = {}; | ||||
| new((&node->value.cFunction->args.positional.symbols)) Array_List<Environment*>(16); | |||||
| new((&node->value.cFunction->args.keyword.keywords)) Array_List<Environment*>(16); | |||||
| new((&node->value.cFunction->args.keyword.values)) Array_List<Environment*>(16); | |||||
| node->value.cFunction->is_special_form = is_special; | node->value.cFunction->is_special_form = is_special; | ||||
| return node; | return node; | ||||
| } | } | ||||
| @@ -429,14 +430,14 @@ namespace Memory { | |||||
| env = free_spots_in_environment_memory.data[--free_spots_in_environment_memory.next_index]; | 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<Environment*>; | |||||
| if (parent) | if (parent) | ||||
| append_to_array_list(&env->parents, parent); | |||||
| env->parents.append(parent); | |||||
| env->hm = create_Void_Ptr_hashmap(); | |||||
| ::new((&env->hm)) Hash_Map<Lisp_Object*, Lisp_Object*>; | |||||
| return env; | return env; | ||||
| } | } | ||||
| @@ -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<Lisp_Object*> program) -> void { | |||||
| const char* ext = ".expanded"; | const char* ext = ".expanded"; | ||||
| char* newName = (char*)calloc(10 + file_name->length, sizeof(char)); | char* newName = (char*)calloc(10 + file_name->length, sizeof(char)); | ||||
| strcpy(newName, Memory::get_c_str(file_name)); | 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<Lisp_Object*> { | |||||
| parser_file = file_name; | parser_file = file_name; | ||||
| parser_line = 1; | parser_line = 1; | ||||
| parser_col = 0; | parser_col = 0; | ||||
| Lisp_Object_Array_List program = create_Lisp_Object_array_list(); | |||||
| Array_List<Lisp_Object*> program; | |||||
| int index_in_text = 0; | int index_in_text = 0; | ||||
| @@ -485,7 +485,7 @@ namespace Parser { | |||||
| try_struct { | try_struct { | ||||
| parsed = parse_expression(text, &index_in_text); | parsed = parse_expression(text, &index_in_text); | ||||
| } | } | ||||
| append_to_array_list(&program, parsed); | |||||
| program.append(parsed); | |||||
| } break; | } break; | ||||
| case ';': | case ';': | ||||
| case ' ': | case ' ': | ||||
| @@ -0,0 +1,45 @@ | |||||
| #define _CRT_SECURE_NO_WARNINGS | |||||
| #define _CRT_SECURE_NO_DEPRECATE | |||||
| #include <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #include <time.h> | |||||
| #include <string.h> | |||||
| #include <cmath> | |||||
| #include <ctype.h> | |||||
| #include <stdarg.h> | |||||
| #include <functional> | |||||
| #ifdef _MSC_VER | |||||
| # include <direct.h> | |||||
| # include <windows.h> | |||||
| #else | |||||
| # include <unistd.h> | |||||
| # include <signal.h> | |||||
| #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" | |||||
| } | |||||
| @@ -21,9 +21,20 @@ | |||||
| # include <signal.h> | # include <signal.h> | ||||
| #endif | #endif | ||||
| #include "./ftb/types.hpp" | |||||
| #include "./ftb/macros.hpp" | #include "./ftb/macros.hpp" | ||||
| #include "./ftb/profiler.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/hashmap.hpp" | ||||
| #include "./ftb/arraylist.hpp" | |||||
| namespace Slime { | namespace Slime { | ||||
| # include "./defines.cpp" | # include "./defines.cpp" | ||||
| @@ -42,5 +53,5 @@ namespace Slime { | |||||
| # include "./docgeneration.cpp" | # include "./docgeneration.cpp" | ||||
| # include "./built_ins.cpp" | # include "./built_ins.cpp" | ||||
| # include "./testing.cpp" | # include "./testing.cpp" | ||||
| // # include "./undefines.cpp" | |||||
| # include "./undefines.cpp" | |||||
| } | } | ||||
| @@ -0,0 +1,11 @@ | |||||
| #include <functional> | |||||
| #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" | |||||
| } | |||||
| @@ -2,20 +2,21 @@ struct Lisp_Object; | |||||
| struct String; | struct String; | ||||
| struct Environment; | 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 | // 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 | // STRUCTS | ||||
| enum struct Thread_Type { | enum struct Thread_Type { | ||||
| @@ -23,7 +24,6 @@ enum struct Thread_Type { | |||||
| GarbageCollection | GarbageCollection | ||||
| }; | }; | ||||
| enum struct Lisp_Object_Type { | enum struct Lisp_Object_Type { | ||||
| Nil, | Nil, | ||||
| T, | T, | ||||
| @@ -65,8 +65,8 @@ enum struct Log_Level { | |||||
| }; | }; | ||||
| struct Continuation { | struct Continuation { | ||||
| Lisp_Object_Array_List* call_stack; | |||||
| Environment_Array_List* envi_stack; | |||||
| Array_List<Lisp_Object*> call_stack; | |||||
| Array_List<Environment*> envi_stack; | |||||
| }; | }; | ||||
| struct String { | struct String { | ||||
| @@ -101,15 +101,15 @@ struct Vector { | |||||
| }; | }; | ||||
| struct Positional_Arguments { | struct Positional_Arguments { | ||||
| Lisp_Object_Array_List symbols; | |||||
| Array_List<Lisp_Object*> symbols; | |||||
| }; | }; | ||||
| struct Keyword_Arguments { | struct Keyword_Arguments { | ||||
| // Array of Pointers to Lisp_Object<Keyword> | // Array of Pointers to Lisp_Object<Keyword> | ||||
| Lisp_Object_Array_List keywords; | |||||
| Array_List<Lisp_Object*> keywords; | |||||
| // NOTE(Felix): values[i] will be nullptr if no defalut value was | // NOTE(Felix): values[i] will be nullptr if no defalut value was | ||||
| // declared for key identifiers[i] | // declared for key identifiers[i] | ||||
| Lisp_Object_Array_List values; | |||||
| Array_List<Lisp_Object*> values; | |||||
| }; | }; | ||||
| struct Arguments { | struct Arguments { | ||||
| @@ -121,8 +121,8 @@ struct Arguments { | |||||
| }; | }; | ||||
| struct Environment { | struct Environment { | ||||
| Environment_Array_List parents; | |||||
| Void_Ptr_Hash_Map* hm; | |||||
| Array_List<Environment*> parents; | |||||
| Hash_Map<Lisp_Object*, Lisp_Object*> hm; | |||||
| }; | }; | ||||
| struct Function { | struct Function { | ||||
| @@ -153,7 +153,7 @@ struct Lisp_Object { | |||||
| cFunction* cFunction; | cFunction* cFunction; | ||||
| void* pointer; | void* pointer; | ||||
| Continuation continuation; | Continuation continuation; | ||||
| Lisp_Obj_Hash_Map* hashMap; | |||||
| Hash_Map<Lisp_Object*, Lisp_Object*> hashMap; | |||||
| } value; | } value; | ||||
| }; | }; | ||||
| @@ -115,79 +115,78 @@ | |||||
| proc test_array_lists_adding_and_removing() -> testresult { | proc test_array_lists_adding_and_removing() -> testresult { | ||||
| // test adding and removing | // 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<int> list; | |||||
| list.append(1); | |||||
| list.append(2); | |||||
| list.append(3); | |||||
| list.append(4); | |||||
| assert_equal_int(list.next_index, 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.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.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; | return pass; | ||||
| } | } | ||||
| proc test_array_lists_sorting() -> testresult { | proc test_array_lists_sorting() -> testresult { | ||||
| // test adding and removing | // 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<int> 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.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); | 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; | return pass; | ||||
| } | } | ||||
| proc test_array_lists_searching() -> testresult { | 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<int> 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); | assert_equal_int(index, 2); | ||||
| index = sorted_array_list_find(&list, 1); | |||||
| index = list.sorted_find(1); | |||||
| assert_equal_int(index, 0); | assert_equal_int(index, 0); | ||||
| index = sorted_array_list_find(&list, 5); | |||||
| index = list.sorted_find(5); | |||||
| assert_equal_int(index, -1); | assert_equal_int(index, -1); | ||||
| return pass; | return pass; | ||||
| @@ -359,12 +359,12 @@ proc visualize_lisp_machine() -> void { | |||||
| draw_new_line(3); | draw_new_line(3); | ||||
| }; | }; | ||||
| proc draw_symbols_keywords_and_numbers = [&]() { | 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<Lisp_Object*> symbols; | |||||
| Array_List<Lisp_Object*> keywords; | |||||
| Array_List<Lisp_Object*> numbers; | |||||
| Array_List<Lisp_Object*> strings; | |||||
| Array_List<Lisp_Object*> pairs; | |||||
| Array_List<Lisp_Object*> lists; | |||||
| // loop over all used memory | // loop over all used memory | ||||
| for (int i = 0; i < Memory::next_index_in_object_memory; ++i) { | 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)) { | 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; | default: break; | ||||
| } | } | ||||
| @@ -386,36 +386,36 @@ proc visualize_lisp_machine() -> void { | |||||
| } | } | ||||
| // create the lists-list by filtering the pairs-list. | // create the lists-list by filtering the pairs-list. | ||||
| Lisp_Object_Array_List pairs_to_filter = create_Lisp_Object_array_list(); | |||||
| Array_List<Lisp_Object*> pairs_to_filter; | |||||
| // helper lambda: | // 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<Lisp_Object*> list) -> void { | |||||
| if (list.next_index == 0) | if (list.next_index == 0) | ||||
| return; | return; | ||||
| sort_array_list(&list); | |||||
| Int_Array_List indices_to_filter = create_Int_array_list(); | |||||
| list.sort(); | |||||
| Array_List<int> indices_to_filter; | |||||
| size_t last = (size_t)list.data[0]; | size_t last = (size_t)list.data[0]; | ||||
| for (int i = 1; i < list.next_index; ++i) { | for (int i = 1; i < list.next_index; ++i) { | ||||
| if ((size_t)list.data[i] == last) | if ((size_t)list.data[i] == last) | ||||
| append_to_array_list(&indices_to_filter, i); | |||||
| indices_to_filter.append(i); | |||||
| else | else | ||||
| last = (size_t)list.data[i]; | last = (size_t)list.data[i]; | ||||
| } | } | ||||
| for (int i = indices_to_filter.next_index; i >= 0; --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 again as removing items destroys the order | ||||
| sort_array_list(&list); | |||||
| list.sort(); | |||||
| }; | }; | ||||
| // recursive lambda | // recursive lambda | ||||
| std::function<void(Lisp_Object*)> filter_pair_and_children; | std::function<void(Lisp_Object*)> filter_pair_and_children; | ||||
| filter_pair_and_children = [&](Lisp_Object* pair) { | 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) | if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair) | ||||
| filter_pair_and_children(pair->value.pair.first); | 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 | // okay, so pairs_to_filter now only the pairs once each that | ||||
| // we want to filter from the pairs list | // we want to filter from the pairs list | ||||
| for (int i = 0; i < pairs.next_index; ++i) { | 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]); | |||||
| } | } | ||||
| } | } | ||||