| @@ -1 +1 @@ | |||||
| Subproject commit a20539587c9547084629fb730e12dab21ea8ccca | |||||
| Subproject commit 43da71f8094e24c544c12352e02eb76c746e1c93 | |||||
| @@ -0,0 +1,4 @@ | |||||
| (define a 10) | |||||
| (define (get-a-1) | |||||
| a) | |||||
| @@ -0,0 +1,8 @@ | |||||
| (import "import1.slime") | |||||
| (define (set-a-2 s) | |||||
| (set! a s)) | |||||
| (define (get-a-2) | |||||
| a) | |||||
| @@ -88,7 +88,7 @@ | |||||
| (define (range (:from 0) :to) :doc "Returns a sequence of numbers starting with the number defined\nby the key =from= and ends with the number defined in =to=." (when (< from to) (pair from (range :from (+ 1 from) :to to)))) | (define (range (:from 0) :to) :doc "Returns a sequence of numbers starting with the number defined\nby the key =from= and ends with the number defined in =to=." (when (< from to) (pair from (range :from (+ 1 from) :to to)))) | ||||
| (define (range-while (:from 0) to) :doc "Returns a sequence of numbers starting with the number defined\nby the key 'from' and ends with the number defined in 'to'." (define result (list (copy from))) (define head result) (mutate from (increment from)) (while (< from to) (begin (mutate head (pair (first head) (pair (copy from) nil))) (define head (rest head)) (mutate from (increment from)))) result) | |||||
| (define (range-while (:from 0) :to) :doc "Returns a sequence of numbers starting with the number defined\nby the key 'from' and ends with the number defined in 'to'." (define result (list (copy from))) (define head result) (set! from (increment from)) (while (< from to) (begin (mutate head (pair (first head) (pair (copy from) nil))) (define head (rest head)) (set! from (increment from)))) result) | |||||
| (define (map fun seq) :doc "Takes a function and a sequence as arguments and returns a new\nsequence which contains the results of using the first sequences\nelemens as argument to that function." (if (null? seq) seq (pair (fun (first seq)) (map fun (rest seq))))) | (define (map fun seq) :doc "Takes a function and a sequence as arguments and returns a new\nsequence which contains the results of using the first sequences\nelemens as argument to that function." (if (null? seq) seq (pair (fun (first seq)) (map fun (rest seq))))) | ||||
| @@ -89,13 +89,13 @@ | |||||
| ;; :key2 value2, | ;; :key2 value2, | ||||
| ;; :key1 value1)) | ;; :key1 value1)) | ||||
| (assert (= (length (first p)) 6)) | |||||
| (assert (= (ds::plist::get p :key1) 'value4)) | |||||
| ;; (assert (= (length (first p)) 6)) | |||||
| ;; (assert (= (ds::plist::get p :key1) 'value4)) | |||||
| (ds::plist::remove! p :key1) | |||||
| ;; p == ((:key2 value2, | |||||
| ;; :key1 value1)) | |||||
| ;; (ds::plist::remove! p :key1) | |||||
| ;; ;; p == ((:key2 value2, | |||||
| ;; ;; :key1 value1)) | |||||
| (assert (= (length (first p)) 4)) | |||||
| (assert (= (ds::plist::get p :key1) 'value1)) | |||||
| (assert (= (ds::plist::get p :key2) 'value2)) | |||||
| ;; (assert (= (length (first p)) 4)) | |||||
| ;; (assert (= (ds::plist::get p :key1) 'value1)) | |||||
| ;; (assert (= (ds::plist::get p :key2) 'value2)) | |||||
| @@ -0,0 +1,17 @@ | |||||
| (import "import1.slime") | |||||
| (assert (= a 10)) | |||||
| (assert (= (get-a-1) 10)) | |||||
| (import "import2.slime") | |||||
| (assert (= a 10)) | |||||
| (assert (= (get-a-1) 10)) | |||||
| (assert (= (get-a-2) 10)) | |||||
| (set-a-2 11) | |||||
| (assert (= a 11)) | |||||
| (assert (= (get-a-1) 11)) | |||||
| (assert (= (get-a-2) 11)) | |||||
| @@ -7,7 +7,13 @@ set exeName=slime.exe | |||||
| taskkill /F /IM %exeName% > NUL 2> NUL | taskkill /F /IM %exeName% > NUL 2> NUL | ||||
| echo ---------- Compiling ---------- | 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 ^ | |||||
| /I../3rd/ ^ | |||||
| /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 ( | ||||
| @@ -128,3 +128,24 @@ | |||||
| #define in_caller_env fluid_let( \ | #define in_caller_env fluid_let( \ | ||||
| Globals::Current_Execution::envi_stack.next_index, \ | Globals::Current_Execution::envi_stack.next_index, \ | ||||
| Globals::Current_Execution::envi_stack.next_index-1) | Globals::Current_Execution::envi_stack.next_index-1) | ||||
| /* | |||||
| * iterate over lisp vectors | |||||
| */ | |||||
| #define for_lisp_vector(v) \ | |||||
| if (!v); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (auto it = v->value.vector.data; \ | |||||
| it_index < v->value.vector.length; \ | |||||
| it=v->value.vector.data+(++it_index)) | |||||
| /* | |||||
| * iterate over lisp lists | |||||
| */ | |||||
| #define for_lisp_list(l) \ | |||||
| if (!l); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (Lisp_Object* head = l, *it; \ | |||||
| Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \ | |||||
| head = head->value.pair.rest, ++it_index) | |||||
| @@ -1,3 +1,5 @@ | |||||
| #pragma once | |||||
| #include <functional> | #include <functional> | ||||
| #include "ftb/arraylist.hpp" | #include "ftb/arraylist.hpp" | ||||
| #include "ftb/hashmap.hpp" | #include "ftb/hashmap.hpp" | ||||
| @@ -182,11 +184,13 @@ namespace Slime { | |||||
| void visualize_lisp_machine(); | void visualize_lisp_machine(); | ||||
| void generate_docs(String* path); | void generate_docs(String* path); | ||||
| void log_error(); | |||||
| namespace Memory { | namespace Memory { | ||||
| extern Lisp_Object* nil; | extern Lisp_Object* nil; | ||||
| extern Lisp_Object* t; | extern Lisp_Object* t; | ||||
| Environment* create_child_environment(Environment* parent); | |||||
| Environment* create_built_ins_environment(); | Environment* create_built_ins_environment(); | ||||
| Lisp_Object* create_lisp_object_cfunction(bool is_special); | Lisp_Object* create_lisp_object_cfunction(bool is_special); | ||||
| Lisp_Object* get_or_create_lisp_object_keyword(const char* identifier); | Lisp_Object* get_or_create_lisp_object_keyword(const char* identifier); | ||||
| @@ -196,6 +200,7 @@ namespace Slime { | |||||
| void free_everything(); | void free_everything(); | ||||
| String* create_string(const char*); | String* create_string(const char*); | ||||
| Lisp_Object* create_lisp_object_number(double); | Lisp_Object* create_lisp_object_number(double); | ||||
| Lisp_Object* create_lisp_object_pointer(void*); | |||||
| Lisp_Object* get_or_create_lisp_object_symbol(String* identifier); | Lisp_Object* get_or_create_lisp_object_symbol(String* identifier); | ||||
| Lisp_Object* get_or_create_lisp_object_symbol(const char*); | Lisp_Object* get_or_create_lisp_object_symbol(const char*); | ||||
| Lisp_Object* get_or_create_lisp_object_keyword(String* identifier); | Lisp_Object* get_or_create_lisp_object_keyword(String* identifier); | ||||
| @@ -0,0 +1,36 @@ | |||||
| * mallocs | |||||
| |------------------------------------------+------------------------| | |||||
| | location | always freed | | |||||
| |------------------------------------------+------------------------| | |||||
| | [[file:3rd\ftb\arraylist.hpp::11]]: | yes | | |||||
| | [[file:.\3rd\ftb\bucket_allocator.hpp::17]]: | yes | | |||||
| | [[file:.\3rd\ftb\bucket_allocator.hpp::44]]: | yes | | |||||
| | [[file:.\3rd\ftb\bucket_allocator.hpp::46]]: | yes | | |||||
| | [[file:.\src\io.cpp::49]]: | yes | | |||||
| | [[file:.\src\io.cpp::164]]: | yes | | |||||
| | [[file:.\src\io.cpp::209]]: | yes | | |||||
| | [[file:.\src\io.cpp::285]]: | yes | | |||||
| | [[file:.\src\memory.cpp::158]]: | yes in free_everything | | |||||
| | [[file:.\src\platform.cpp::3]]: | yes | | |||||
| | [[file:.\src\platform.cpp::27]]: | yes | | |||||
| | [[file:.\src\platform.cpp::47]]: | yes | | |||||
| | [[file:.\src\platform.cpp::81]]: | yes | | |||||
| |------------------------------------------+------------------------| | |||||
| * news | |||||
| |----------------------------------+-------------------------------------------------------------------------------------| | |||||
| | location | always deleted | | |||||
| |----------------------------------+-------------------------------------------------------------------------------------| | |||||
| | [[file:.\src\eval.cpp::262]]: | ::new (&(result->positional.symbols)) Array_List<Lisp_Object*>; | | |||||
| | [[file:.\src\eval.cpp::263]]: | ::new (&(result->keyword.keywords)) Array_List<Lisp_Object*>; | | |||||
| | [[file:.\src\eval.cpp:264]]: | ::new (&(result->keyword.values)) Array_List<Lisp_Object*>; | | |||||
| | [[file:.\src\io.cpp:284]]: | // allocate a new block of memory size char (1 byte) instead of wide char (2 bytes) | | |||||
| | [[file:.\src\io.cpp:306]]: | wchar_t* wc = new wchar_t[cSize]; | | |||||
| | [[file:.\src\memory.cpp:336]]: | // node->value.lambdaWrapper = new Lambda_Wrapper(function); | | |||||
| | [[file:.\src\memory.cpp:383]]: | // inject a new array list; | | |||||
| | [[file:.\src\parse.cpp:195]]: | // better for keeping track of the encountered new lines and | | |||||
| | [[file:.\src\parse.cpp:196]]: | // characters since last new line so we can update the parser | | |||||
| | [[file:.\src\parse.cpp:208]]: | /* new col = (count chars since last \n) + 1 */ | | |||||
| |----------------------------------+-------------------------------------------------------------------------------------| | |||||
| @@ -69,35 +69,47 @@ proc built_in_load(String* file_name) -> Lisp_Object* { | |||||
| } | } | ||||
| 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.", | ||||
| Memory::get_c_str(file_name)); | Memory::get_c_str(file_name)); | ||||
| return nullptr; | |||||
| } | } | ||||
| } | } | ||||
| Lisp_Object* result = Memory::nil; | Lisp_Object* result = Memory::nil; | ||||
| Array_List<Lisp_Object*> 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) { | |||||
| try result = eval_expr(program.data[i]); | |||||
| for (int i = 0; i < program->next_index; ++i) { | |||||
| try result = eval_expr(program->data[i]); | |||||
| } | } | ||||
| delete program; | |||||
| return result; | return result; | ||||
| } | } | ||||
| proc built_in_import(String* file_name) -> Lisp_Object* { | proc built_in_import(String* file_name) -> Lisp_Object* { | ||||
| // create new empty environment | |||||
| Environment* new_env; | Environment* new_env; | ||||
| try new_env = Memory::create_child_environment(get_root_environment()); | |||||
| get_current_environment()->parents.append(new_env); | |||||
| push_environment(new_env); | |||||
| defer { | |||||
| pop_environment(); | |||||
| }; | |||||
| new_env = Memory::file_to_env_map.get_object(Memory::get_c_str(file_name)); | |||||
| if (!new_env) { | |||||
| // create new empty environment | |||||
| try new_env = Memory::create_child_environment(get_root_environment()); | |||||
| // TODO(Felix): check absoulute paths in the map, not just | |||||
| // relative ones | |||||
| Memory::file_to_env_map.set_object(Memory::get_c_str(file_name), new_env); | |||||
| push_environment(new_env); | |||||
| defer { | |||||
| pop_environment(); | |||||
| }; | |||||
| Lisp_Object* res; | |||||
| try res = built_in_load(file_name); | |||||
| } | |||||
| Lisp_Object* res = built_in_load(file_name); | |||||
| get_current_environment()->parents.append(new_env); | |||||
| return res; | |||||
| return Memory::nil; | |||||
| } | } | ||||
| proc load_built_ins_into_environment() -> void { | proc load_built_ins_into_environment() -> void { | ||||
| @@ -128,3 +128,24 @@ | |||||
| #define in_caller_env fluid_let( \ | #define in_caller_env fluid_let( \ | ||||
| Globals::Current_Execution::envi_stack.next_index, \ | Globals::Current_Execution::envi_stack.next_index, \ | ||||
| Globals::Current_Execution::envi_stack.next_index-1) | Globals::Current_Execution::envi_stack.next_index-1) | ||||
| /* | |||||
| * iterate over lisp vectors | |||||
| */ | |||||
| #define for_lisp_vector(v) \ | |||||
| if (!v); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (auto it = v->value.vector.data; \ | |||||
| it_index < v->value.vector.length; \ | |||||
| it=v->value.vector.data+(++it_index)) | |||||
| /* | |||||
| * iterate over lisp lists | |||||
| */ | |||||
| #define for_lisp_list(l) \ | |||||
| if (!l); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (Lisp_Object* head = l, *it; \ | |||||
| Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \ | |||||
| head = head->value.pair.rest, ++it_index) | |||||
| @@ -16,41 +16,6 @@ | |||||
| # define if_linux if constexpr (true) | # define if_linux if constexpr (true) | ||||
| #endif | #endif | ||||
| /* | |||||
| * iterate over lisp vectors | |||||
| */ | |||||
| #define for_lisp_vector(v) \ | |||||
| if (!v); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (auto it = v->value.vector.data; \ | |||||
| it_index < v->value.vector.length; \ | |||||
| it=v->value.vector.data+(++it_index)) | |||||
| /* | |||||
| * iterate over lisp lists | |||||
| */ | |||||
| #define for_lisp_list(l) \ | |||||
| if (!l); else \ | |||||
| if (int it_index = 0); else \ | |||||
| for (Lisp_Object* head = l, *it; \ | |||||
| Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \ | |||||
| head = head->value.pair.rest, ++it_index) | |||||
| /* | |||||
| #define assert(cond) \ | |||||
| if_debug { \ | |||||
| if (!cond) { \ | |||||
| if (log_level == Log_Level::Debug) { \ | |||||
| printf("Assertion failed: %s %d", __FILE__, __LINE__); \ | |||||
| } \ | |||||
| debug_break(); \ | |||||
| } \ | |||||
| } else {} \ | |||||
| */ | |||||
| #define console_normal "\x1B[0m" | #define console_normal "\x1B[0m" | ||||
| #define console_red "\x1B[31m" | #define console_red "\x1B[31m" | ||||
| #define console_green "\x1B[32m" | #define console_green "\x1B[32m" | ||||
| @@ -259,9 +259,9 @@ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_O | |||||
| result = &function->value.function.args; | result = &function->value.function.args; | ||||
| } | } | ||||
| ::new (&(result->positional.symbols)) Array_List<Lisp_Object*>; | |||||
| ::new (&(result->keyword.keywords)) Array_List<Lisp_Object*>; | |||||
| ::new (&(result->keyword.values)) Array_List<Lisp_Object*>; | |||||
| ::new (&result->positional.symbols) Array_List<Lisp_Object*>; | |||||
| ::new (&result->keyword.keywords) Array_List<Lisp_Object*>; | |||||
| ::new (&result->keyword.values) Array_List<Lisp_Object*>; | |||||
| // first init the fields | // first init the fields | ||||
| // result->positional = create_positional_argument_list(16); | // result->positional = create_positional_argument_list(16); | ||||
| @@ -1,7 +1,10 @@ | |||||
| #define _CRT_SECURE_NO_WARNINGS | #define _CRT_SECURE_NO_WARNINGS | ||||
| #define _CRT_SECURE_NO_DEPRECATE | #define _CRT_SECURE_NO_DEPRECATE | ||||
| #define _CRTDBG_MAP_ALLOC | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <crtdbg.h> | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <time.h> | #include <time.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| @@ -39,3 +39,9 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args, | |||||
| args->keywords.append(keyword); | args->keywords.append(keyword); | ||||
| args->values.append(default_value); | args->values.append(default_value); | ||||
| } | } | ||||
| Lisp_Object::~Lisp_Object() { | |||||
| if (Memory::get_type(this) == Lisp_Object_Type::HashMap) { | |||||
| this->value.hashMap.~Hash_Map(); | |||||
| } | |||||
| } | |||||
| @@ -1,10 +1,13 @@ | |||||
| #include "libslime.cpp" | #include "libslime.cpp" | ||||
| int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||||
| if (argc > 1) { | if (argc > 1) { | ||||
| if (Slime::string_equal(argv[1], "--run-tests")) { | if (Slime::string_equal(argv[1], "--run-tests")) { | ||||
| int res = Slime::run_all_tests(); | int res = Slime::run_all_tests(); | ||||
| // Slime::interprete_file((char*)"generate-docs.slime"); | // Slime::interprete_file((char*)"generate-docs.slime"); | ||||
| _CrtDumpMemoryLeaks(); | |||||
| return res ? 0 : 1; | return res ? 0 : 1; | ||||
| } | } | ||||
| @@ -6,6 +6,8 @@ namespace Memory { | |||||
| Hash_Map<char*, Lisp_Object*> global_symbol_table; | Hash_Map<char*, Lisp_Object*> global_symbol_table; | ||||
| Hash_Map<char*, Lisp_Object*> global_keyword_table; | Hash_Map<char*, Lisp_Object*> global_keyword_table; | ||||
| Hash_Map<char*, Environment*> file_to_env_map; | |||||
| // ------------------ | // ------------------ | ||||
| // lisp_objects | // lisp_objects | ||||
| // ------------------ | // ------------------ | ||||
| @@ -177,13 +179,23 @@ namespace Memory { | |||||
| free_spots_in_string_memory.next_index = 0; | free_spots_in_string_memory.next_index = 0; | ||||
| ::new((&global_symbol_table)) Hash_Map<char*, Lisp_Object*>; | |||||
| ::new((&global_keyword_table)) Hash_Map<char*, Lisp_Object*>; | |||||
| global_symbol_table.~Hash_Map(); | |||||
| global_keyword_table.~Hash_Map(); | |||||
| file_to_env_map.~Hash_Map(); | |||||
| ::new(&global_symbol_table) Hash_Map<char*, Lisp_Object*>; | |||||
| ::new(&global_keyword_table) Hash_Map<char*, Lisp_Object*>; | |||||
| ::new(&file_to_env_map) Hash_Map<char*, Lisp_Object*>; | |||||
| try_void Parser::standard_in = create_string("stdin"); | try_void Parser::standard_in = create_string("stdin"); | ||||
| object_memory.reset(); | |||||
| environment_memory.reset(); | |||||
| object_memory.~Bucket_Allocator(); | |||||
| // environment_memory.~Bucket_Allocator(); | |||||
| ::new(&object_memory) Bucket_Allocator<Lisp_Object, 1024>; | |||||
| ::new(&environment_memory) Bucket_Allocator<Environment, 1024>; | |||||
| next_free_spot_in_string_memory = string_memory; | next_free_spot_in_string_memory = string_memory; | ||||
| @@ -373,7 +385,7 @@ namespace Memory { | |||||
| return copy_lisp_object(n); | return copy_lisp_object(n); | ||||
| } | } | ||||
| proc create_child_environment(Environment* parent) -> Environment* { | |||||
| proc create_child_environment(Environment* parent) -> Environment* { | |||||
| Environment* env = environment_memory.allocate(); | Environment* env = environment_memory.allocate(); | ||||
| @@ -404,7 +416,7 @@ namespace Memory { | |||||
| try load_built_ins_into_environment(); | try load_built_ins_into_environment(); | ||||
| built_in_load(Memory::create_string("pre.slime")); | |||||
| try built_in_load(Memory::create_string("pre.slime")); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -98,7 +98,6 @@ namespace Parser { | |||||
| // get the atom | // get the atom | ||||
| String* ret = Memory::create_string("", atom_length); | String* ret = Memory::create_string("", atom_length); | ||||
| // char* atom = (char*)malloc(atom_length*sizeof(char)+1); // plus null char | |||||
| strcpy(&ret->data, text+(*index_in_text)); | strcpy(&ret->data, text+(*index_in_text)); | ||||
| // restore the original string | // restore the original string | ||||
| @@ -448,7 +447,7 @@ namespace Parser { | |||||
| } | } | ||||
| proc write_expanded_file(String* file_name, Array_List<Lisp_Object*> 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)); | ||||
| @@ -465,21 +464,21 @@ namespace Parser { | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| for (int i = 0; i < program.next_index; ++i) { | |||||
| for (int i = 0; i < program->next_index; ++i) { | |||||
| // a macro will parse as nil for now, so we skip those | // a macro will parse as nil for now, so we skip those | ||||
| if (program.data[i] == Memory::nil) | |||||
| if (program->data[i] == Memory::nil) | |||||
| continue; | continue; | ||||
| print(program.data[i], true, f); | |||||
| print(program->data[i], true, f); | |||||
| fprintf(f, "\n\n"); | fprintf(f, "\n\n"); | ||||
| } | } | ||||
| } | } | ||||
| proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*> { | |||||
| 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; | ||||
| Array_List<Lisp_Object*> program; | |||||
| Array_List<Lisp_Object*>* program = new Array_List<Lisp_Object*>; | |||||
| int index_in_text = 0; | int index_in_text = 0; | ||||
| @@ -490,7 +489,7 @@ namespace Parser { | |||||
| try_struct { | try_struct { | ||||
| parsed = parse_expression(text, &index_in_text); | parsed = parse_expression(text, &index_in_text); | ||||
| } | } | ||||
| program.append(parsed); | |||||
| program->append(parsed); | |||||
| } break; | } break; | ||||
| case ';': | case ';': | ||||
| case ' ': | case ' ': | ||||
| @@ -103,6 +103,11 @@ struct Arguments { | |||||
| struct Environment { | struct Environment { | ||||
| Array_List<Environment*> parents; | Array_List<Environment*> parents; | ||||
| Hash_Map<void*, Lisp_Object*> hm; | Hash_Map<void*, Lisp_Object*> hm; | ||||
| ~Environment() { | |||||
| parents.~Array_List(); | |||||
| hm.~Hash_Map(); | |||||
| } | |||||
| }; | }; | ||||
| struct Function { | struct Function { | ||||
| @@ -123,7 +128,7 @@ struct Lisp_Object { | |||||
| u64 flags; | u64 flags; | ||||
| Lisp_Object* userType; // keyword | Lisp_Object* userType; // keyword | ||||
| String* docstring; | String* docstring; | ||||
| union { | |||||
| union value { | |||||
| Symbol symbol; // used for symbols and keywords | Symbol symbol; // used for symbols and keywords | ||||
| double number; | double number; | ||||
| String* string; | String* string; | ||||
| @@ -134,7 +139,9 @@ struct Lisp_Object { | |||||
| void* pointer; | void* pointer; | ||||
| Continuation continuation; | Continuation continuation; | ||||
| Hash_Map<Lisp_Object*, Lisp_Object*> hashMap; | Hash_Map<Lisp_Object*, Lisp_Object*> hashMap; | ||||
| ~value() {} | |||||
| } value; | } value; | ||||
| ~Lisp_Object(); | |||||
| }; | }; | ||||
| struct Error { | struct Error { | ||||
| @@ -596,7 +596,7 @@ proc test_file(const char* file) -> testresult { | |||||
| pop_environment(); | pop_environment(); | ||||
| }; | }; | ||||
| built_in_load(Memory::create_string(file)); | |||||
| try built_in_load(Memory::create_string(file)); | |||||
| assert_no_error(); | assert_no_error(); | ||||
| return pass; | return pass; | ||||
| @@ -654,6 +654,7 @@ proc run_all_tests() -> bool { | |||||
| invoke_test_script("automata"); | invoke_test_script("automata"); | ||||
| invoke_test_script("sicp"); | invoke_test_script("sicp"); | ||||
| invoke_test_script("hashmaps"); | invoke_test_script("hashmaps"); | ||||
| invoke_test_script("singular_imports"); | |||||
| // Memory::print_status(); | // Memory::print_status(); | ||||