| @@ -40,7 +40,7 @@ | |||
| (error "key was not found in alist")) | |||
| ((= (caar associations) key) | |||
| (cdar associations)) | |||
| (else (alist-get-intern (rest alist) key)))) | |||
| (else (alist-get-intern (rest associations) key)))) | |||
| (alist-get-intern associations key))) | |||
| @@ -18,7 +18,7 @@ | |||
| (car (caar seq))) | |||
| (define (caadr seq) | |||
| (caar (cdr seq))) | |||
| (car (cadr seq))) | |||
| (define (cadar seq) | |||
| (car (cdr (car seq)))) | |||
| @@ -33,7 +33,7 @@ | |||
| (cdr (car (cdr seq)))) | |||
| (define (cddar seq) | |||
| (cddr (car seq))) | |||
| (cdr (cdar seq))) | |||
| (define (cdddr seq) | |||
| (cdr (cddr seq))) | |||
| @@ -37,7 +37,6 @@ | |||
| ;; key1: value1) | |||
| (assert (= (length (first a)) 3)) | |||
| (pprint-alist a) | |||
| (assert (= (alist-get a 'key1) 'value4)) | |||
| (alist-remove! a 'key1) | |||
| @@ -923,7 +923,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| return Memory::create_lisp_object_number((u64)&(evaluated_arguments->value.pair.first->value)); | |||
| return Memory::create_lisp_object_number((float)((u64)&(evaluated_arguments->value.pair.first->value))); | |||
| }); | |||
| defun("generate-docs", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| @@ -1,15 +1,15 @@ | |||
| proc generate_docs(Environment* env, String* path) -> void { | |||
| // save the current working directory | |||
| char cwd[1024]; | |||
| getcwd(cwd, 1024); | |||
| char* cwd = get_cwd(); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| chdir(exe_path); | |||
| free(exe_path); | |||
| change_cwd(exe_path); | |||
| defer { | |||
| // switch back to the users directory | |||
| chdir(cwd); | |||
| change_cwd(cwd); | |||
| free(exe_path); | |||
| free(cwd); | |||
| }; | |||
| FILE *f = fopen(Memory::get_c_str(path), "w"); | |||
| @@ -388,63 +388,103 @@ proc log_error() -> void { | |||
| } | |||
| proc exe_dir() -> char* { | |||
| size_t size = 512, i, n; | |||
| char *path, *temp; | |||
| if_linux { | |||
| size_t size = 512, i, n; | |||
| char *path, *temp; | |||
| while (1) { | |||
| ssize_t used; | |||
| while (1) { | |||
| size_t used; | |||
| path = (char*)malloc(size); | |||
| if (!path) { | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| } | |||
| path = (char*)malloc(size); | |||
| if (!path) { | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| } | |||
| used = readlink("/proc/self/exe", path, size); | |||
| used = readlink("/proc/self/exe", path, size); | |||
| if (used == -1) { | |||
| const int saved_errno = errno; | |||
| free(path); | |||
| errno = saved_errno; | |||
| return NULL; | |||
| } else | |||
| if (used < 1) { | |||
| if (used == -1) { | |||
| const int saved_errno = errno; | |||
| free(path); | |||
| errno = EIO; | |||
| errno = saved_errno; | |||
| return NULL; | |||
| } else | |||
| if (used < 1) { | |||
| free(path); | |||
| errno = EIO; | |||
| return NULL; | |||
| } | |||
| if ((size_t)used >= size) { | |||
| free(path); | |||
| size = (size | 2047) + 2049; | |||
| continue; | |||
| } | |||
| if ((size_t)used >= size) { | |||
| free(path); | |||
| size = (size | 2047) + 2049; | |||
| continue; | |||
| size = (size_t)used; | |||
| break; | |||
| } | |||
| size = (size_t)used; | |||
| break; | |||
| } | |||
| /* Find final slash. */ | |||
| n = 0; | |||
| for (i = 0; i < size; i++) | |||
| if (path[i] == '/') | |||
| n = i; | |||
| /* Optimize allocated size, | |||
| ensuring there is room for | |||
| a final slash and a | |||
| string-terminating '\0', */ | |||
| temp = path; | |||
| path = (char*)realloc(temp, n + 2); | |||
| if (!path) { | |||
| free(temp); | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| } | |||
| /* Find final slash. */ | |||
| n = 0; | |||
| for (i = 0; i < size; i++) | |||
| if (path[i] == '/') | |||
| n = i; | |||
| /* Optimize allocated size, | |||
| ensuring there is room for | |||
| a final slash and a | |||
| string-terminating '\0', */ | |||
| temp = path; | |||
| path = (char*)realloc(temp, n + 2); | |||
| if (!path) { | |||
| free(temp); | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| /* and properly trim and terminate the path string. */ | |||
| path[n+0] = '/'; | |||
| path[n+1] = '\0'; | |||
| return path; | |||
| } | |||
| /* and properly trim and terminate the path string. */ | |||
| path[n+0] = '/'; | |||
| path[n+1] = '\0'; | |||
| if_windows { | |||
| DWORD last_error; | |||
| DWORD result; | |||
| DWORD path_size = 1024; | |||
| char* path = (char*)malloc(1024); | |||
| while (true) { | |||
| memset(path, 0, path_size); | |||
| result = GetModuleFileName(0, path, path_size - 1); | |||
| last_error = GetLastError(); | |||
| return path; | |||
| if (0 == result) { | |||
| free(path); | |||
| path = 0; | |||
| break; | |||
| } | |||
| else if (result == path_size - 1) { | |||
| free(path); | |||
| /* May need to also check for ERROR_SUCCESS here if XP/2K */ | |||
| if (ERROR_INSUFFICIENT_BUFFER != last_error) { | |||
| path = 0; | |||
| break; | |||
| } | |||
| path_size = path_size * 2; | |||
| path = (char*)malloc(path_size); | |||
| } | |||
| else | |||
| break; | |||
| } | |||
| if (!path) { | |||
| fprintf(stderr, "Failure: %d\n", last_error); | |||
| return ""; | |||
| } | |||
| else | |||
| return path; | |||
| } | |||
| } | |||
| @@ -357,17 +357,19 @@ namespace Memory { | |||
| Parser::environment_for_macros = ret; | |||
| // save the current working directory | |||
| char cwd[1024]; | |||
| getcwd(cwd, 1024); | |||
| char* cwd = get_cwd(); | |||
| defer { | |||
| free(cwd); | |||
| }; | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| chdir(exe_path); | |||
| change_cwd(exe_path); | |||
| free(exe_path); | |||
| built_in_load(Memory::create_string("pre.slime"), ret); | |||
| chdir(cwd); | |||
| change_cwd(cwd); | |||
| return ret; | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| inline proc get_cwd() -> char* { | |||
| const int buf_size = 2048; | |||
| char* res = (char*)malloc(buf_size * sizeof(char)); | |||
| if_linux { | |||
| getcwd(res, buf_size); | |||
| } | |||
| if_windows { | |||
| _getcwd(res, buf_size); | |||
| } | |||
| return res; | |||
| } | |||
| inline proc change_cwd(char* dir) -> void { | |||
| if_linux { | |||
| chdir(dir); | |||
| } | |||
| if_windows { | |||
| _chdir(dir); | |||
| } | |||
| } | |||
| @@ -3,7 +3,14 @@ | |||
| #define _CRT_SECURE_NO_WARNINGS | |||
| #define _CRT_SECURE_NO_DEPRECATE | |||
| #include <stdlib.h> | |||
| #include <unistd.h> | |||
| #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) | |||
| # include <direct.h> | |||
| # include <windows.h> | |||
| size_t readlink(char*, char*, size_t); | |||
| #else | |||
| # include <unistd.h> | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <time.h> | |||
| #include <string.h> | |||
| @@ -19,6 +26,7 @@ namespace Slime { | |||
| # include "./defines.cpp" | |||
| # include "./structs.cpp" | |||
| # include "./forward_decls.cpp" | |||
| # include "./platform.cpp" | |||
| # include "./memory.cpp" | |||
| # include "./lisp_object.cpp" | |||
| # include "./error.cpp" | |||
| @@ -596,7 +596,7 @@ proc run_all_tests() -> bool { | |||
| char* exe_path = exe_dir(); | |||
| // switch to the exe directory for loading pre.slime | |||
| chdir(exe_path); | |||
| change_cwd(exe_path); | |||
| free(exe_path); | |||
| bool result = true; | |||
| @@ -1,17 +1,18 @@ | |||
| proc visualize_lisp_machine() -> void { | |||
| // save the current working directory | |||
| char cwd[1024]; | |||
| getcwd(cwd, 1024); | |||
| char* cwd = get_cwd(); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| // switch to the exe directory for loading pre.slime | |||
| chdir(exe_path); | |||
| change_cwd(exe_path); | |||
| free(exe_path); | |||
| defer { | |||
| // switch back to the users directory | |||
| chdir(cwd); | |||
| change_cwd(cwd); | |||
| free(cwd); | |||
| }; | |||
| struct Drawn_Area { | |||
| @@ -180,7 +181,7 @@ proc visualize_lisp_machine() -> void { | |||
| case Lisp_Object_Type::T: return draw_text("t"); | |||
| case Lisp_Object_Type::Nil: return draw_text("()"); | |||
| case Lisp_Object_Type::Pair: return draw_pair(obj); | |||
| case Lisp_Object_Type::Number: return draw_float(obj->value.number); | |||
| case Lisp_Object_Type::Number: return draw_float((float)obj->value.number); | |||
| case Lisp_Object_Type::Symbol: return draw_text(&obj->value.string->data); | |||
| case Lisp_Object_Type::Keyword: { | |||
| Drawn_Area colon = draw_text(":", "#c61b6e"); | |||
| @@ -303,7 +304,7 @@ proc visualize_lisp_machine() -> void { | |||
| // ------------------- | |||
| draw_new_line(); | |||
| int free_string_memory = Memory::next_free_spot_in_string_memory - Memory::string_memory; | |||
| int free_string_memory = (int)(Memory::next_free_spot_in_string_memory - Memory::string_memory); | |||
| for (int i = 0; i < Memory::free_spots_in_string_memory->next_index; ++i) { | |||
| free_string_memory += ((String*)(Memory::free_spots_in_string_memory->data[i]))->length; | |||
| } | |||
| @@ -491,7 +492,7 @@ proc visualize_lisp_machine() -> void { | |||
| draw_new_line(); | |||
| write_x = start_x + 600; | |||
| draw_float(numbers->data[i]->value.number); | |||
| draw_float((float)(numbers->data[i]->value.number)); | |||
| } | |||
| write_x = start_x + 900; | |||