| @@ -29,7 +29,7 @@ | |||||
| (font-lock-add-keywords | (font-lock-add-keywords | ||||
| 'c++-mode | 'c++-mode | ||||
| '(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\|try\\|try_void\\|for_array_list\\|for_hash_map\\|for_lisp_list\\|for_lisp_vector\\|in_caller_env\\|ignore_logging\\|dont_break_on_errors\\)\\>" . | |||||
| '(("\\<\\(if_debug\\|if_unicode\\|if_windows\\|if_linux\\|defer\\|proc\\|try\\|try_void\\|for_array_list\\|for_hash_map\\|for_lisp_list\\|for_lisp_vector\\|in_caller_env\\|ignore_logging\\|dont_break_on_errors\\)\\>" . | |||||
| font-lock-keyword-face))))))) | font-lock-keyword-face))))))) | ||||
| (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) | (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) | ||||
| @@ -1 +1 @@ | |||||
| Subproject commit 07e89f384155abd4ec231edc173ce0d03244b1cf | |||||
| Subproject commit 39dbfa3db926c78eda8ab086b93e8be8c2828b99 | |||||
| @@ -1,17 +1,21 @@ | |||||
| (define-module math | (define-module math | ||||
| :imports ("oo.slime") | :imports ("oo.slime") | ||||
| :exports (pi abs sqrt make-vector3) | |||||
| :exports (pi tau abs sqrt make-vector3) | |||||
| (define pi | (define pi | ||||
| :doc "Tha famous circle constant." | |||||
| "The famous circle constant." | |||||
| 3.14159265) | 3.14159265) | ||||
| (define tau | |||||
| "The second famous circle constant." | |||||
| (* 2 pi)) | |||||
| (define (abs x) | (define (abs x) | ||||
| :doc "Accepts one argument and returns the absoulte value of it" | |||||
| "Accepts one argument and returns the absoulte value of it" | |||||
| (if (> x 0) x (- x))) | (if (> x 0) x (- x))) | ||||
| (define (sqrt x) | (define (sqrt x) | ||||
| :doc "Accepts one argument and returns the square root of it" | |||||
| "Accepts one argument and returns the square root of it" | |||||
| (** x 0.5)) | (** x 0.5)) | ||||
| (define-class (vector3 x y z) | (define-class (vector3 x y z) | ||||
| @@ -7,7 +7,7 @@ set exeName=slime.exe | |||||
| taskkill /F /IM %exeName% > NUL 2> NUL | taskkill /F /IM %exeName% > NUL 2> NUL | ||||
| echo ---------- Compiling ---------- | echo ---------- Compiling ---------- | ||||
| call clang-cl ^ | |||||
| call cl ^ | |||||
| ../src/main.cpp^ | ../src/main.cpp^ | ||||
| /I../3rd/ ^ | /I../3rd/ ^ | ||||
| /D_PROFILING /D_DEBUG /D_DONT_BREAK_ON_ERRORS ^ | /D_PROFILING /D_DEBUG /D_DONT_BREAK_ON_ERRORS ^ | ||||
| @@ -0,0 +1,5 @@ | |||||
| * Steps to init the system | |||||
| 1. call =Memory::init= | |||||
| 2. call =add_to_load_path= as often as wanted | |||||
| 3. call =Memory::load_pre= | |||||
| 4. call =Memory::push_user_environment= | |||||
| @@ -33,7 +33,7 @@ | |||||
| do { \ | do { \ | ||||
| if (_node->type != _type) { \ | if (_node->type != _type) { \ | ||||
| char* t = lisp_object_to_string(_node); \ | char* t = lisp_object_to_string(_node); \ | ||||
| defer { free(t); }; \ | |||||
| defer_free(t); \ | |||||
| create_type_missmatch_error( \ | create_type_missmatch_error( \ | ||||
| lisp_object_type_to_string(_type), \ | lisp_object_type_to_string(_type), \ | ||||
| lisp_object_type_to_string(_node->type), \ | lisp_object_type_to_string(_node->type), \ | ||||
| @@ -47,7 +47,7 @@ | |||||
| do { \ | do { \ | ||||
| if (!(condition)) { \ | if (!(condition)) { \ | ||||
| create_generic_error("Assertion-error: %s\n" \ | create_generic_error("Assertion-error: %s\n" \ | ||||
| " for: %s\n" \ | |||||
| " condition: %s\n" \ | |||||
| " in: %s:%d", \ | " in: %s:%d", \ | ||||
| message, #condition, __FILE__, __LINE__); \ | message, #condition, __FILE__, __LINE__); \ | ||||
| } \ | } \ | ||||
| @@ -62,23 +62,39 @@ namespace Slime { | |||||
| return false; | return false; | ||||
| } | } | ||||
| proc add_to_load_path(const char* path) -> void { | |||||
| proc add_to_load_path(const path_char* path) -> void { | |||||
| using Globals::load_path; | using Globals::load_path; | ||||
| load_path.append((void*)path); | |||||
| load_path.append((path_char*)path); | |||||
| } | } | ||||
| 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; | ||||
| char fullpath[4096]; | |||||
| path_char fullpath[MAX_PATH]; | |||||
| #ifdef UNICODE | |||||
| path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | |||||
| swprintf(fullpath, L"%s", temp); | |||||
| file_content = read_entire_file(temp); | |||||
| free(temp); | |||||
| #else | |||||
| sprintf(fullpath, "%s", Memory::get_c_str(file_name)); | sprintf(fullpath, "%s", Memory::get_c_str(file_name)); | ||||
| file_content = read_entire_file(Memory::get_c_str(file_name)); | file_content = read_entire_file(Memory::get_c_str(file_name)); | ||||
| #endif | |||||
| if (!file_content) { | if (!file_content) { | ||||
| for (auto it: Globals::load_path) { | for (auto it: Globals::load_path) { | ||||
| #ifdef UNICODE | |||||
| fullpath[0] = L'\0'; | |||||
| path_char* temp = char_to_path_char(Memory::get_c_str(file_name)); | |||||
| swprintf(fullpath, L"%s%s", it, temp); | |||||
| free(temp); | |||||
| #else | |||||
| fullpath[0] = '\0'; | fullpath[0] = '\0'; | ||||
| sprintf(fullpath, "%s%s", (char*)it, Memory::get_c_str(file_name)); | |||||
| sprintf(fullpath, "%s%s", it, Memory::get_c_str(file_name)); | |||||
| #endif | |||||
| file_content = read_entire_file(fullpath); | file_content = read_entire_file(fullpath); | ||||
| if (file_content) | if (file_content) | ||||
| break; | break; | ||||
| @@ -98,7 +114,13 @@ namespace Slime { | |||||
| Lisp_Object* result = Memory::nil; | Lisp_Object* result = Memory::nil; | ||||
| Array_List<Lisp_Object*>* program; | Array_List<Lisp_Object*>* program; | ||||
| #ifdef UNICODE | |||||
| char* temp_c = path_char_to_char(fullpath); | |||||
| String spath = Memory::create_string(temp_c); | |||||
| free(temp_c); | |||||
| #else | |||||
| String spath = Memory::create_string(fullpath); | String spath = Memory::create_string(fullpath); | ||||
| #endif | |||||
| defer { | defer { | ||||
| free(spath.data); | free(spath.data); | ||||
| }; | }; | ||||
| @@ -121,9 +143,12 @@ namespace Slime { | |||||
| proc built_in_import(String file_name) -> Lisp_Object* { | proc built_in_import(String file_name) -> Lisp_Object* { | ||||
| profile_this(); | profile_this(); | ||||
| Environment* new_env; | Environment* new_env; | ||||
| try assert("You cannot use import inside of the root-env (parent cycle)", | |||||
| get_root_environment() != get_current_environment()); | |||||
| new_env = Memory::file_to_env_map.get_object(Memory::get_c_str(file_name)); | new_env = Memory::file_to_env_map.get_object(Memory::get_c_str(file_name)); | ||||
| if (!new_env) { | if (!new_env) { | ||||
| // create new empty environment | // create new empty environment | ||||
| try new_env = Memory::create_child_environment(get_root_environment()); | try new_env = Memory::create_child_environment(get_root_environment()); | ||||
| @@ -1,12 +1,15 @@ | |||||
| #define proc auto | #define proc auto | ||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||
| # define SLIME_DEBUG | |||||
| # define if_debug if constexpr (true) | # define if_debug if constexpr (true) | ||||
| #else | #else | ||||
| # define if_debug if constexpr (false) | # define if_debug if constexpr (false) | ||||
| #endif | #endif | ||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||
| # define SLIME_WINDOWS | |||||
| # define debug_break() if_debug __debugbreak() | # define debug_break() if_debug __debugbreak() | ||||
| # define if_windows if constexpr (true) | # define if_windows if constexpr (true) | ||||
| # define if_linux if constexpr (false) | # define if_linux if constexpr (false) | ||||
| @@ -37,7 +37,10 @@ namespace Slime { | |||||
| if (result) | if (result) | ||||
| return result; | return result; | ||||
| for (u32 i = 0; i < env->parents.next_index; ++i) { | |||||
| // NOTE(Felix): We have to traverse the parents in reverse | |||||
| // order of adding them. The thing we imported last, should | |||||
| // overshadow the things imported earlier | |||||
| for (s32 i = (s32)env->parents.next_index-1; i >= 0; --i) { | |||||
| result = try_lookup_symbol(node, env->parents.data[i]); | result = try_lookup_symbol(node, env->parents.data[i]); | ||||
| if (result) | if (result) | ||||
| @@ -95,11 +98,11 @@ namespace Slime { | |||||
| } | } | ||||
| }; | }; | ||||
| if(env == get_root_environment()) { | |||||
| print_indent(); | |||||
| printf("[built-ins]-Environment (0x%p)\n", env); | |||||
| return; | |||||
| } | |||||
| // if(env == get_root_environment()) { | |||||
| // print_indent(); | |||||
| // printf("[built-ins]-Environment (0x%p)\n", env); | |||||
| // return; | |||||
| // } | |||||
| for_hash_map (env->hm) { | for_hash_map (env->hm) { | ||||
| print_indent(); | print_indent(); | ||||
| @@ -566,6 +566,7 @@ namespace Slime { | |||||
| proc interprete_file (char* file_name) -> Lisp_Object* { | proc interprete_file (char* file_name) -> Lisp_Object* { | ||||
| try Memory::init(); | try Memory::init(); | ||||
| try Memory::load_pre(); | try Memory::load_pre(); | ||||
| try Memory::push_user_environment(); | |||||
| defer { | defer { | ||||
| if_debug { | if_debug { | ||||
| Slime::Memory::free_everything(); | Slime::Memory::free_everything(); | ||||
| @@ -582,6 +583,7 @@ namespace Slime { | |||||
| proc interprete_stdin() -> void { | proc interprete_stdin() -> void { | ||||
| try_void Memory::init(); | try_void Memory::init(); | ||||
| try_void Memory::load_pre(); | try_void Memory::load_pre(); | ||||
| try_void Memory::push_user_environment(); | |||||
| defer { | defer { | ||||
| if_debug { | if_debug { | ||||
| Slime::Memory::free_everything(); | Slime::Memory::free_everything(); | ||||
| @@ -1,5 +1,5 @@ | |||||
| namespace Slime { | namespace Slime { | ||||
| void add_to_load_path(const char*); | |||||
| void add_to_load_path(const path_char*); | |||||
| bool lisp_object_equal(Lisp_Object*,Lisp_Object*); | bool lisp_object_equal(Lisp_Object*,Lisp_Object*); | ||||
| Lisp_Object* built_in_load(String); | Lisp_Object* built_in_load(String); | ||||
| Lisp_Object* built_in_import(String); | Lisp_Object* built_in_import(String); | ||||
| @@ -21,6 +21,11 @@ namespace Slime { | |||||
| void print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout); | void print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout); | ||||
| void print_environment(Environment*); | void print_environment(Environment*); | ||||
| char* char_to_wchar(const wchar_t* c); | |||||
| wchar_t* char_to_wchar(const char* c); | |||||
| path_char* char_to_path_char(const char* c); | |||||
| char* path_char_to_char(const path_char* c); | |||||
| inline char* duplicate_c_string(const char* str); | inline char* duplicate_c_string(const char* str); | ||||
| bool run_all_tests(); | bool run_all_tests(); | ||||
| @@ -81,7 +86,7 @@ namespace Slime { | |||||
| extern bool debug_log; | extern bool debug_log; | ||||
| extern char* bin_path; | extern char* bin_path; | ||||
| extern Log_Level log_level; | extern Log_Level log_level; | ||||
| extern Array_List<void*> load_path; | |||||
| extern Array_List<path_char*> load_path; | |||||
| // namespace Current_Execution { | // namespace Current_Execution { | ||||
| // extern Array_List<Lisp_Object*> call_stack; | // extern Array_List<Lisp_Object*> call_stack; | ||||
| // extern Array_List<Environment*> envi_stack; | // extern Array_List<Environment*> envi_stack; | ||||
| @@ -18,7 +18,7 @@ namespace Slime::Globals { | |||||
| char* bin_path = nullptr; | char* bin_path = nullptr; | ||||
| Log_Level log_level = Log_Level::Debug; | Log_Level log_level = Log_Level::Debug; | ||||
| bool debug_log = false; | bool debug_log = false; | ||||
| Array_List<void*> load_path; | |||||
| Array_List<path_char*> load_path; | |||||
| Hash_Map<void*, char*> docs; | Hash_Map<void*, char*> docs; | ||||
| Hash_Map<void*, Source_Code_Location> source_code_locations; | Hash_Map<void*, Source_Code_Location> source_code_locations; | ||||
| @@ -117,10 +117,14 @@ namespace Slime { | |||||
| return (s32)(out - in); | return (s32)(out - in); | ||||
| } | } | ||||
| proc read_entire_file(char* filename) -> char* { | |||||
| profile_with_comment(filename); | |||||
| proc read_entire_file(path_char* filename) -> char* { | |||||
| profile_this(); | |||||
| char *fileContent = nullptr; | char *fileContent = nullptr; | ||||
| #if defined(UNICODE) && defined(SLIME_WINDOWS) | |||||
| FILE *fp = _wfopen(filename, L"r"); | |||||
| #else | |||||
| FILE *fp = fopen(filename, "r"); | FILE *fp = fopen(filename, "r"); | ||||
| #endif | |||||
| if (fp) { | if (fp) { | ||||
| /* Go to the end of the file. */ | /* Go to the end of the file. */ | ||||
| if (fseek(fp, 0L, SEEK_END) == 0) { | if (fseek(fp, 0L, SEEK_END) == 0) { | ||||
| @@ -292,7 +296,7 @@ namespace Slime { | |||||
| return filePathC; | return filePathC; | ||||
| } | } | ||||
| const wchar_t* char_to_wchar(const char* c) { | |||||
| wchar_t* char_to_wchar(const char* c) { | |||||
| const size_t cSize = strlen(c)+1; | const size_t cSize = strlen(c)+1; | ||||
| wchar_t* wc = new wchar_t[cSize]; | wchar_t* wc = new wchar_t[cSize]; | ||||
| mbstowcs (wc, c, cSize); | mbstowcs (wc, c, cSize); | ||||
| @@ -300,6 +304,23 @@ namespace Slime { | |||||
| return wc; | return wc; | ||||
| } | } | ||||
| path_char* char_to_path_char(const char* c) { | |||||
| #ifdef UNICODE | |||||
| return char_to_wchar(c); | |||||
| #else | |||||
| return duplicate_c_string(c); | |||||
| #endif | |||||
| } | |||||
| char* path_char_to_char(const path_char* c) { | |||||
| #ifdef UNICODE | |||||
| return wchar_to_char(c); | |||||
| #else | |||||
| return duplicate_c_string(c); | |||||
| #endif | |||||
| } | |||||
| proc string_buider_to_string(Array_List<char*> string_builder) -> char* { | proc string_buider_to_string(Array_List<char*> string_builder) -> char* { | ||||
| size_t len = 1; | size_t len = 1; | ||||
| for (auto str : string_builder) { | for (auto str : string_builder) { | ||||
| @@ -16,6 +16,8 @@ s32 main(s32 argc, char* argv[]) { | |||||
| return res ? 0 : 1; | return res ? 0 : 1; | ||||
| } else if (Slime::string_equal(argv[1], "--generate-docs-file")) { | } else if (Slime::string_equal(argv[1], "--generate-docs-file")) { | ||||
| Slime::Memory::init(); | Slime::Memory::init(); | ||||
| Slime::Memory::load_pre(); | |||||
| Slime::Memory::push_user_environment(); | |||||
| defer { | defer { | ||||
| if_debug { | if_debug { | ||||
| Slime::Memory::free_everything(); | Slime::Memory::free_everything(); | ||||
| @@ -128,7 +128,7 @@ namespace Slime::Memory { | |||||
| // free the exe dir: | // free the exe dir: | ||||
| free(Globals::load_path.data[0]); | free(Globals::load_path.data[0]); | ||||
| // Globals::load_path.dealloc(); | |||||
| Globals::load_path.dealloc(); | |||||
| Globals::user_types.dealloc(); | Globals::user_types.dealloc(); | ||||
| Globals::docs.dealloc(); | Globals::docs.dealloc(); | ||||
| Globals::Current_Execution.envi_stack.dealloc(); | Globals::Current_Execution.envi_stack.dealloc(); | ||||
| @@ -172,12 +172,21 @@ namespace Slime::Memory { | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| proc load_pre() -> void { | |||||
| inline proc load_pre() -> void { | |||||
| String file_name = Memory::create_string("pre.slime"); | String file_name = Memory::create_string("pre.slime"); | ||||
| defer_free(file_name.data); | defer_free(file_name.data); | ||||
| try_void built_in_load(file_name); | try_void built_in_load(file_name); | ||||
| } | } | ||||
| inline proc push_user_environment() -> void { | |||||
| // NOTE(Felix): We create a user environment, so when the user | |||||
| // imports stuff, they don't import in the root env, because | |||||
| // that leads to a parent-cycle | |||||
| Environment* env; | |||||
| try_void env = create_child_environment(get_current_environment()); | |||||
| push_environment(env); | |||||
| } | |||||
| proc init() -> void { | proc init() -> void { | ||||
| profile_this(); | profile_this(); | ||||
| @@ -185,7 +194,7 @@ namespace Slime::Memory { | |||||
| environment_memory.alloc(1024, 8); | environment_memory.alloc(1024, 8); | ||||
| hashmap_memory.alloc(256, 8); | hashmap_memory.alloc(256, 8); | ||||
| char* exe_path = get_exe_dir(); | |||||
| path_char* exe_path = get_exe_dir(); | |||||
| global_symbol_table.alloc(); | global_symbol_table.alloc(); | ||||
| @@ -202,9 +211,9 @@ namespace Slime::Memory { | |||||
| Globals::docs.alloc(); | Globals::docs.alloc(); | ||||
| Globals::user_types.alloc(); | Globals::user_types.alloc(); | ||||
| // Globals::load_path.alloc(); | |||||
| Globals::load_path.alloc(); | |||||
| add_to_load_path(exe_path); | add_to_load_path(exe_path); | ||||
| add_to_load_path("../bin/"); | |||||
| add_to_load_path((path_char*)char_to_path_char("../bin/")); | |||||
| // init nil | // init nil | ||||
| @@ -221,8 +230,6 @@ namespace Slime::Memory { | |||||
| Environment* env; | Environment* env; | ||||
| try_void env = create_built_ins_environment(); | try_void env = create_built_ins_environment(); | ||||
| push_environment(env); | push_environment(env); | ||||
| } | } | ||||
| @@ -61,12 +61,12 @@ namespace Slime { | |||||
| } | } | ||||
| #endif | #endif | ||||
| proc get_exe_dir() -> char* { | |||||
| proc get_exe_dir() -> path_char* { | |||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||
| DWORD last_error; | DWORD last_error; | ||||
| DWORD result; | DWORD result; | ||||
| DWORD path_size = 1024; | |||||
| char* path = (char*)malloc(1024); | |||||
| DWORD path_size = MAX_PATH; | |||||
| path_char* path = (path_char*)malloc(sizeof(path_char)*path_size); | |||||
| while (true) { | while (true) { | ||||
| memset(path, 0, path_size); | memset(path, 0, path_size); | ||||
| @@ -86,7 +86,7 @@ namespace Slime { | |||||
| break; | break; | ||||
| } | } | ||||
| path_size = path_size * 2; | path_size = path_size * 2; | ||||
| path = (char*)malloc(path_size); | |||||
| path = (path_char*)malloc((sizeof(path_char)) * path_size); | |||||
| } | } | ||||
| else | else | ||||
| break; | break; | ||||
| @@ -102,7 +102,7 @@ namespace Slime { | |||||
| s32 index_in_path = -1; | s32 index_in_path = -1; | ||||
| s32 last_backslash = -1; | s32 last_backslash = -1; | ||||
| char c; | |||||
| path_char c; | |||||
| while ((c = path[++index_in_path]) != '\0') { | while ((c = path[++index_in_path]) != '\0') { | ||||
| if (c == '\\') | if (c == '\\') | ||||
| last_backslash = index_in_path; | last_backslash = index_in_path; | ||||
| @@ -537,8 +537,6 @@ namespace Slime { | |||||
| proc test_file(const char* file) -> testresult { | proc test_file(const char* file) -> testresult { | ||||
| profile_with_name(file); | profile_with_name(file); | ||||
| // Memory::reset(); | |||||
| // assert_no_error(); | |||||
| push_environment(Memory::create_child_environment(get_current_environment())); | push_environment(Memory::create_child_environment(get_current_environment())); | ||||
| String name = Memory::create_string(file); | String name = Memory::create_string(file); | ||||
| @@ -556,6 +554,7 @@ namespace Slime { | |||||
| bool result = true; | bool result = true; | ||||
| try Memory::init(); | try Memory::init(); | ||||
| try Memory::load_pre(); | try Memory::load_pre(); | ||||
| try Memory::push_user_environment(); | |||||
| defer { | defer { | ||||
| if_debug { | if_debug { | ||||
| Slime::Memory::free_everything(); | Slime::Memory::free_everything(); | ||||
| @@ -5,7 +5,7 @@ namespace Slime { | |||||
| // char* cwd = get_cwd(); | // char* cwd = get_cwd(); | ||||
| // // get the direction of the exe | // // get the direction of the exe | ||||
| // char* exe_path = get_exe_dir(); | |||||
| // path_char* exe_path = get_exe_dir(); | |||||
| // // switch to the exe directory for loading pre.slime | // // switch to the exe directory for loading pre.slime | ||||
| // change_cwd(exe_path); | // change_cwd(exe_path); | ||||
| @@ -37,8 +37,14 @@ | |||||
| CLOSED: [2020-03-31 Di 11:58] | CLOSED: [2020-03-31 Di 11:58] | ||||
| * DONE update header files | * DONE update header files | ||||
| CLOSED: [2020-03-31 Di 11:58] | CLOSED: [2020-03-31 Di 11:58] | ||||
| * TODO incorporate the print library for slime objects | |||||
| - define a =%lo= to print =Lisp_Objects= | |||||
| print("The value of node is: %lo", node); // 이렇게 | |||||
| * TODO Make specific SLIME macros | * TODO Make specific SLIME macros | ||||
| - =SLIME_UNICODE= | |||||
| - =SLIME_WINDOWS= | - =SLIME_WINDOWS= | ||||
| - =SLIME_LINUX= | |||||
| - =SLIME_DEBUG= | - =SLIME_DEBUG= | ||||
| - =SLIME_RELEASE= | - =SLIME_RELEASE= | ||||
| - =SLIME_DISTRIBUTE= | - =SLIME_DISTRIBUTE= | ||||
| @@ -49,7 +55,7 @@ | |||||
| * TODO define-syntax-shorthand | * TODO define-syntax-shorthand | ||||
| (define-syntax-shorthand [ vector ] ) | (define-syntax-shorthand [ vector ] ) | ||||
| (define-syntax-shorthand { hash-map } ) | (define-syntax-shorthand { hash-map } ) | ||||
| * TODO revert ats to use funciton pointers if capturs are not working anyways | |||||
| * TODO revert ats to use function pointers if capturs are not working anyways | |||||
| use the stack to store immediate results, so no captures are necessary | use the stack to store immediate results, so no captures are necessary | ||||
| * TODO continuation test2 | * TODO continuation test2 | ||||
| let a cont have a not expanded macro in cs and before calling the cont, expand the macro and let it | let a cont have a not expanded macro in cs and before calling the cont, expand the macro and let it | ||||