| @@ -0,0 +1,45 @@ | |||||
| default: | |||||
| artifacts: | |||||
| paths: | |||||
| - ./bin/slime | |||||
| - ./bin/slime_d | |||||
| expire_in: 1 week | |||||
| variables: | |||||
| GIT_SUBMODULE_STRATEGY: recursive | |||||
| stages: | |||||
| - build_debug | |||||
| - build_release | |||||
| - test | |||||
| build_clang++_d: | |||||
| image: warchantua/dev-essential | |||||
| stage: build_debug | |||||
| script: clang++ -D_DEBUG -D_DONT_BREAK_ON_ERRORS src/main.cpp -gfull -gdwarf -o ./bin/slime_d --std=c++17 -I3rd/ | |||||
| build_g++_d: | |||||
| stage: build_debug | |||||
| script: g++ -D_DEBUG -D_DONT_BREAK_ON_ERRORS src/main.cpp -g -o ./bin/slime_d --std=c++17 -I3rd/ | |||||
| build_clang++_r: | |||||
| image: warchantua/dev-essential | |||||
| stage: build_release | |||||
| script: clang++ -D_DONT_BREAK_ON_ERRORS -O3 src/main.cpp -g -o ./bin/slime --std=c++17 -I3rd/ || exit 1 | |||||
| build_g++_r: | |||||
| stage: build_release | |||||
| script: g++ -D_DONT_BREAK_ON_ERRORS -O3 src/main.cpp -g -o ./bin/slime --std=c++17 -I3rd/ || exit 1 | |||||
| tests_d: | |||||
| stage: test | |||||
| script: ./bin/slime_d --run-tests | |||||
| tests_r: | |||||
| stage: test | |||||
| script: ./bin/slime --run-tests | |||||
| valgrind: | |||||
| image: warchantua/dev-essential | |||||
| stage: test | |||||
| script: valgrind --error-exitcode=123 -q --track-origins=yes --leak-check=full --show-leak-kinds=all ./bin/slime_d --run-tests | |||||
| @@ -18,13 +18,13 @@ time clang++ -D_DEBUG -D_DONT_BREAK_ON_ERRORS \ | |||||
| src/main.cpp -gfull -gdwarf -o ./bin/slime_d --std=c++17 \ | src/main.cpp -gfull -gdwarf -o ./bin/slime_d --std=c++17 \ | ||||
| -I3rd/ || exit 1 | -I3rd/ || exit 1 | ||||
| # echo "" | |||||
| # echo "--------------------------------" | |||||
| # echo " compiling fullslime (release) " | |||||
| # echo "--------------------------------" | |||||
| # time clang++ -D_DONT_BREAK_ON_ERRORS -O3 \ | |||||
| # src/main.cpp -g -o ./bin/slime --std=c++17 \ | |||||
| # -I3rd/ || exit 1 | |||||
| echo "" | |||||
| echo "--------------------------------" | |||||
| echo " compiling fullslime (release) " | |||||
| echo "--------------------------------" | |||||
| time clang++ -D_DONT_BREAK_ON_ERRORS -O3 \ | |||||
| src/main.cpp -g -o ./bin/slime --std=c++17 \ | |||||
| -I3rd/ || exit 1 | |||||
| echo "" | echo "" | ||||
| echo "------------------------------" | echo "------------------------------" | ||||
| @@ -71,10 +71,10 @@ namespace Slime { | |||||
| proc built_in_load(String file_name) -> Lisp_Object* { | proc built_in_load(String file_name) -> Lisp_Object* { | ||||
| profile_with_comment(file_name.data); | profile_with_comment(file_name.data); | ||||
| char* file_content; | char* file_content; | ||||
| path_char fullpath[MAX_PATH]; | |||||
| path_char fullpath[max_path_len]; | |||||
| #ifdef UNICODE | #ifdef UNICODE | ||||
| path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | ||||
| swprintf(fullpath, MAX_PATH,L"%s", temp); | |||||
| swprintf(fullpath, max_path_len,L"%s", temp); | |||||
| file_content = read_entire_file(temp); | file_content = read_entire_file(temp); | ||||
| free(temp); | free(temp); | ||||
| #else | #else | ||||
| @@ -89,7 +89,7 @@ namespace Slime { | |||||
| #ifdef UNICODE | #ifdef UNICODE | ||||
| fullpath[0] = L'\0'; | fullpath[0] = L'\0'; | ||||
| path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | ||||
| swprintf(fullpath, MAX_PATH, L"%s%s", it, temp); | |||||
| swprintf(fullpath, max_path_leno, L"%s%s", it, temp); | |||||
| free(temp); | free(temp); | ||||
| #else | #else | ||||
| fullpath[0] = '\0'; | fullpath[0] = '\0'; | ||||
| @@ -1319,7 +1319,9 @@ namespace Slime { | |||||
| // example, numbers are not valid symbols. | // example, numbers are not valid symbols. | ||||
| try assert_type(str, Lisp_Object_Type::String); | try assert_type(str, Lisp_Object_Type::String); | ||||
| return Memory::get_symbol(Memory::duplicate_string(str->value.string)); | |||||
| // TODO(Felix): It was like this: why did we have to copy it? | |||||
| // return Memory::get_symbol(Memory::duplicate_string(str->value.string)); | |||||
| return Memory::get_symbol(str->value.string); | |||||
| }; | }; | ||||
| define((concat-strings . strings), "TODO") { | define((concat-strings . strings), "TODO") { | ||||
| profile_with_name("(concat-strings)"); | profile_with_name("(concat-strings)"); | ||||
| @@ -445,6 +445,9 @@ namespace Slime { | |||||
| Globals::Current_Execution.cs.clear(); | Globals::Current_Execution.cs.clear(); | ||||
| Globals::Current_Execution.ams.clear(); | Globals::Current_Execution.ams.clear(); | ||||
| Globals::Current_Execution.pcs.clear(); | Globals::Current_Execution.pcs.clear(); | ||||
| for (auto it: Globals::Current_Execution.nass) { | |||||
| it.dealloc(); | |||||
| } | |||||
| Globals::Current_Execution.nass.clear(); | Globals::Current_Execution.nass.clear(); | ||||
| Globals::Current_Execution.envi_stack.clear(); | Globals::Current_Execution.envi_stack.clear(); | ||||
| Globals::Current_Execution.ats.clear(); | Globals::Current_Execution.ats.clear(); | ||||
| @@ -356,7 +356,7 @@ namespace Slime { | |||||
| if (abs(node->value.number - (s32)node->value.number) < 0.000001f) | if (abs(node->value.number - (s32)node->value.number) < 0.000001f) | ||||
| asprintf(&temp, "%d", (s32)node->value.number); | asprintf(&temp, "%d", (s32)node->value.number); | ||||
| else | else | ||||
| asprintf(&temp, "%f", node->value.number); | |||||
| asprintf(&temp, "%Lf", node->value.number); | |||||
| return temp; | return temp; | ||||
| } | } | ||||
| case (Lisp_Object_Type::Keyword): { | case (Lisp_Object_Type::Keyword): { | ||||
| @@ -17,6 +17,7 @@ | |||||
| # include <direct.h> | # include <direct.h> | ||||
| # include <windows.h> | # include <windows.h> | ||||
| #else | #else | ||||
| # include <limits.h> | |||||
| # include <unistd.h> | # include <unistd.h> | ||||
| # include <signal.h> | # include <signal.h> | ||||
| #endif | #endif | ||||
| @@ -100,6 +100,20 @@ namespace Slime::Memory { | |||||
| proc free_everything() -> void { | proc free_everything() -> void { | ||||
| object_memory.for_each([](Lisp_Object* lo){ | object_memory.for_each([](Lisp_Object* lo){ | ||||
| switch (lo->type) { | switch (lo->type) { | ||||
| case Lisp_Object_Type::Continuation: { | |||||
| lo->value.continuation->cs.dealloc(); | |||||
| lo->value.continuation->pcs.dealloc(); | |||||
| lo->value.continuation->ams.dealloc(); | |||||
| lo->value.continuation->ats.dealloc(); | |||||
| lo->value.continuation->mes.dealloc(); | |||||
| lo->value.continuation->envi_stack.dealloc(); | |||||
| for (auto it : lo->value.continuation->nass) { | |||||
| it.dealloc(); | |||||
| } | |||||
| lo->value.continuation->nass.dealloc(); | |||||
| free(lo->value.continuation); | |||||
| } break; | |||||
| case Lisp_Object_Type::Function: { | case Lisp_Object_Type::Function: { | ||||
| lo->value.function->args.positional.symbols.dealloc(); | lo->value.function->args.positional.symbols.dealloc(); | ||||
| lo->value.function->args.keyword.keywords.dealloc(); | lo->value.function->args.keyword.keywords.dealloc(); | ||||
| @@ -126,8 +140,12 @@ namespace Slime::Memory { | |||||
| free(value); | free(value); | ||||
| } | } | ||||
| // free the exe dir: | |||||
| free(Globals::load_path.data[0]); | |||||
| // free paths in load path | |||||
| for (u32 i = 0; i < Globals::load_path.next_index; ++i) { | |||||
| free(Globals::load_path.data[i]); | |||||
| } | |||||
| Globals::load_path.dealloc(); | Globals::load_path.dealloc(); | ||||
| Globals::user_types.dealloc(); | Globals::user_types.dealloc(); | ||||
| Globals::docs.dealloc(); | Globals::docs.dealloc(); | ||||
| @@ -136,6 +154,9 @@ namespace Slime::Memory { | |||||
| Globals::Current_Execution.ams.dealloc(); | Globals::Current_Execution.ams.dealloc(); | ||||
| Globals::Current_Execution.pcs.dealloc(); | Globals::Current_Execution.pcs.dealloc(); | ||||
| Globals::Current_Execution.nass.dealloc(); | Globals::Current_Execution.nass.dealloc(); | ||||
| for (auto it: Globals::Current_Execution.nass) { | |||||
| it.dealloc(); | |||||
| } | |||||
| Globals::Current_Execution.ats.dealloc(); | Globals::Current_Execution.ats.dealloc(); | ||||
| Globals::Current_Execution.mes.dealloc(); | Globals::Current_Execution.mes.dealloc(); | ||||
| @@ -274,24 +295,28 @@ namespace Slime::Memory { | |||||
| return node; | return node; | ||||
| } | } | ||||
| inline proc full_clone_continuation(Continuation* c) -> Continuation* { | |||||
| Continuation* res = (Continuation*)malloc(sizeof(Continuation)); | |||||
| res->cs = c->cs.clone(); | |||||
| res->pcs = c->pcs.clone(); | |||||
| res->ams = c->ams.clone(); | |||||
| res->ats = c->ats.clone(); | |||||
| res->mes = c->mes.clone(); | |||||
| res->envi_stack = c->envi_stack.clone(); | |||||
| res->nass = c->nass.clone(); | |||||
| for (u32 i = 0; i < res->nass.next_index; ++i) { | |||||
| res->nass.data[i] = c->nass.data[i].clone(); | |||||
| } | |||||
| return res; | |||||
| } | |||||
| proc create_lisp_object_continuation() -> Lisp_Object* { | proc create_lisp_object_continuation() -> Lisp_Object* { | ||||
| using Globals::Current_Execution; | |||||
| Lisp_Object* node; | Lisp_Object* node; | ||||
| try node = create_lisp_object(); | try node = create_lisp_object(); | ||||
| node->type = Lisp_Object_Type::Continuation; | node->type = Lisp_Object_Type::Continuation; | ||||
| node->value.continuation = (Continuation*)malloc(sizeof(Continuation)); | |||||
| node->value.continuation->cs = Current_Execution.cs.clone(); | |||||
| node->value.continuation->pcs = Current_Execution.pcs.clone(); | |||||
| node->value.continuation->ams = Current_Execution.ams.clone(); | |||||
| node->value.continuation->ats = Current_Execution.ats.clone(); | |||||
| node->value.continuation->mes = Current_Execution.mes.clone(); | |||||
| node->value.continuation->envi_stack = Current_Execution.envi_stack.clone(); | |||||
| node->value.continuation->nass = Current_Execution.nass.clone(); | |||||
| for (u32 i = 0; i < node->value.continuation->nass.next_index; ++i) { | |||||
| node->value.continuation->nass.data[i] = node->value.continuation->nass.data[i].clone(); | |||||
| } | |||||
| node->value.continuation = full_clone_continuation(&Globals::Current_Execution); | |||||
| return node; | return node; | ||||
| } | } | ||||
| @@ -450,25 +475,32 @@ namespace Slime::Memory { | |||||
| if (n == Memory::nil || n == Memory::t) { | if (n == Memory::nil || n == Memory::t) { | ||||
| return n; | return n; | ||||
| } else { | } else { | ||||
| Lisp_Object_Type type = n->type; | |||||
| if (type == Lisp_Object_Type::Symbol || | |||||
| type == Lisp_Object_Type::Keyword || | |||||
| type == Lisp_Object_Type::Function) | |||||
| { | |||||
| switch(n->type) { | |||||
| case Lisp_Object_Type::Symbol: | |||||
| case Lisp_Object_Type::Keyword: | |||||
| case Lisp_Object_Type::Function: | |||||
| return n; | return n; | ||||
| } else if (type == Lisp_Object_Type::String) { | |||||
| case Lisp_Object_Type::String: { | |||||
| Lisp_Object* target; | Lisp_Object* target; | ||||
| try target = create_lisp_object(); | try target = create_lisp_object(); | ||||
| *target = *n; | *target = *n; | ||||
| target->value.string = create_string(target->value.string.data); | target->value.string = create_string(target->value.string.data); | ||||
| return target; | return target; | ||||
| } else { | |||||
| } | |||||
| case Lisp_Object_Type::Continuation: | |||||
| Lisp_Object* target; | |||||
| try target = create_lisp_object(); | |||||
| *target = *n; | |||||
| target->value.continuation = full_clone_continuation(n->value.continuation); | |||||
| return target; | |||||
| default: { | |||||
| Lisp_Object* target; | Lisp_Object* target; | ||||
| try target = create_lisp_object(); | try target = create_lisp_object(); | ||||
| *target = *n; | *target = *n; | ||||
| return target; | return target; | ||||
| } | } | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,5 +1,12 @@ | |||||
| namespace Slime { | namespace Slime { | ||||
| #ifdef SLIME_WINDOWS | |||||
| constexpr u32 max_path_len = MAX_PATH; | |||||
| #else | |||||
| constexpr u32 max_path_len = PATH_MAX; | |||||
| #endif | |||||
| inline proc get_cwd() -> char* { | inline proc get_cwd() -> char* { | ||||
| const u32 buf_size = 2048; | const u32 buf_size = 2048; | ||||
| char* res = (char*)malloc(buf_size * sizeof(char)); | char* res = (char*)malloc(buf_size * sizeof(char)); | ||||
| @@ -46,13 +46,13 @@ namespace Slime { | |||||
| } \ | } \ | ||||
| #define assert_equal_f64(variable, value) \ | #define assert_equal_f64(variable, value) \ | ||||
| if (fabs((f64)variable - (f64)value) > epsilon) { \ | |||||
| if (fabsl((f64)variable - (f64)value) > epsilon) { \ | |||||
| print_assert_equal_fail(variable, value, f64, "%Lf"); \ | print_assert_equal_fail(variable, value, f64, "%Lf"); \ | ||||
| return fail; \ | return fail; \ | ||||
| } | } | ||||
| #define assert_not_equal_f64(variable, value) \ | #define assert_not_equal_f64(variable, value) \ | ||||
| if (fabs((f64)variable - (f64)value) <= epsilon) { \ | |||||
| if (fabsl((f64)variable - (f64)value) <= epsilon) { \ | |||||
| print_assert_not_equal_fail(variable, value, f64, "L%f"); \ | print_assert_not_equal_fail(variable, value, f64, "L%f"); \ | ||||
| return fail; \ | return fail; \ | ||||
| } | } | ||||