| @@ -1,5 +1,4 @@ | |||
| /vs/*/* | |||
| /build | |||
| *.ilk | |||
| *.aux | |||
| *.fls | |||
| @@ -7,6 +6,7 @@ | |||
| *.toc | |||
| *.fdb_latexmk | |||
| *.pdb | |||
| *.obj | |||
| *.exe | |||
| *.user | |||
| *.psess | |||
| @@ -1 +0,0 @@ | |||
| (define-syntax (e x) `(+ 1 ,x)) | |||
| @@ -1,6 +0,0 @@ | |||
| (import "a.slime") | |||
| (define (f) (e 2)) | |||
| (show f) | |||
| (f) | |||
| (show f) | |||
| @@ -1,3 +0,0 @@ | |||
| (import "b.slime") | |||
| (printf (e 3)) | |||
| @@ -3,27 +3,23 @@ | |||
| pushd %~dp0 | |||
| set exeName=slime.exe | |||
| set binDir=bin | |||
| mkdir build 2>nul | |||
| pushd build | |||
| pushd bin | |||
| taskkill /F /IM %exeName% > NUL 2> NUL | |||
| echo ---------- Compiling ---------- | |||
| call timecmd cl ../src/main.cpp /std:c++latest /Fe%exeName% /W3 /Zi /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib | |||
| popd | |||
| if %errorlevel% == 0 ( | |||
| echo. | |||
| echo Done | |||
| echo. | |||
| pushd ..\bin | |||
| call timecmd ..\build\slime.exe --run-tests | |||
| popd | |||
| call timecmd bin\slime.exe --run-tests | |||
| ) else ( | |||
| echo. | |||
| echo Fuckin' ell | |||
| ) | |||
| popd | |||
| popd | |||
| @@ -41,14 +41,14 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { | |||
| // save the current working directory | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| char* exe_path = get_exe_dir(); | |||
| defer { | |||
| free(exe_path); | |||
| }; | |||
| fullpath[0] = '\0'; | |||
| sprintf(fullpath, "%s%s", exe_path, Memory::get_c_str(file_name)); | |||
| // printf("Fullpath: %s\n", fullpath); | |||
| printf("Fullpath: %s\n", fullpath); | |||
| file_content = read_entire_file(fullpath); | |||
| if (!file_content) { | |||
| @@ -14,7 +14,6 @@ constexpr bool is_debug_build = false; | |||
| # define if_linux if constexpr (0) | |||
| # define debug_break() if_debug __debugbreak() | |||
| #else | |||
| # include <signal.h> | |||
| # define debug_break() if_debug raise(SIGTRAP) | |||
| # define if_windows if (0) | |||
| # define if_linux if (1) | |||
| @@ -2,7 +2,7 @@ proc generate_docs(Environment* env, String* path) -> void { | |||
| // save the current working directory | |||
| char* cwd = get_cwd(); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| char* exe_path = get_exe_dir(); | |||
| change_cwd(exe_path); | |||
| defer { | |||
| @@ -12,7 +12,7 @@ proc load_built_ins_into_environment(Environment*) -> void; | |||
| proc parse_argument_list(Lisp_Object*, Function*) -> void; | |||
| proc print_environment(Environment*) -> void; | |||
| proc exe_dir() -> char*; | |||
| // proc get_exe_dir() -> char*; | |||
| proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*; | |||
| @@ -387,104 +387,3 @@ proc log_error() -> void { | |||
| puts(console_normal); | |||
| } | |||
| proc exe_dir() -> char* { | |||
| if_linux { | |||
| size_t size = 512, i, n; | |||
| char *path, *temp; | |||
| while (1) { | |||
| size_t used; | |||
| path = (char*)malloc(size); | |||
| if (!path) { | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| } | |||
| 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) { | |||
| free(path); | |||
| errno = EIO; | |||
| return NULL; | |||
| } | |||
| if ((size_t)used >= size) { | |||
| free(path); | |||
| size = (size | 2047) + 2049; | |||
| continue; | |||
| } | |||
| 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; | |||
| } | |||
| /* and properly trim and terminate the path string. */ | |||
| path[n+0] = '/'; | |||
| path[n+1] = '\0'; | |||
| return path; | |||
| } | |||
| 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(); | |||
| 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; | |||
| } | |||
| } | |||
| @@ -363,7 +363,7 @@ namespace Memory { | |||
| }; | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| char* exe_path = get_exe_dir(); | |||
| change_cwd(exe_path); | |||
| free(exe_path); | |||
| @@ -2,22 +2,134 @@ 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); | |||
| } | |||
| #ifdef _MSC_VER | |||
| _getcwd(res, buf_size); | |||
| #else | |||
| getcwd(res, buf_size); | |||
| #endif | |||
| return res; | |||
| } | |||
| inline proc change_cwd(char* dir) -> void { | |||
| if_linux { | |||
| chdir(dir); | |||
| #ifdef _MSC_VER | |||
| _chdir(dir); | |||
| #else | |||
| chdir(dir); | |||
| #endif | |||
| } | |||
| proc get_exe_dir() -> char* { | |||
| #ifdef _MSC_VER | |||
| 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(); | |||
| 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_windows { | |||
| _chdir(dir); | |||
| if (!path) { | |||
| fprintf(stderr, "Failure: %d\n", last_error); | |||
| return ""; | |||
| } | |||
| else { | |||
| // remove the exe name, so we are only left with the path | |||
| int index_in_path = -1; | |||
| int last_backslash = -1; | |||
| char c; | |||
| while ((c = path[++index_in_path]) != '\0') { | |||
| if (c == '\\') | |||
| last_backslash = index_in_path; | |||
| } | |||
| // we are assuming there are some backslashes | |||
| path[last_backslash+1] = '\0'; | |||
| return path; | |||
| } | |||
| #else | |||
| ssize_t size = 512, i, n; | |||
| char *path, *temp; | |||
| while (1) { | |||
| size_t used; | |||
| path = (char*)malloc(size); | |||
| if (!path) { | |||
| errno = ENOMEM; | |||
| return NULL; | |||
| } | |||
| 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) { | |||
| free(path); | |||
| errno = EIO; | |||
| return NULL; | |||
| } | |||
| if ((size_t)used >= size) { | |||
| free(path); | |||
| size = (size | 2047) + 2049; | |||
| continue; | |||
| } | |||
| 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; | |||
| } | |||
| /* and properly trim and terminate the path string. */ | |||
| path[n+0] = '/'; | |||
| path[n+1] = '\0'; | |||
| return path; | |||
| #endif | |||
| } | |||
| @@ -2,15 +2,8 @@ | |||
| #define _CRT_SECURE_NO_WARNINGS | |||
| #define _CRT_SECURE_NO_DEPRECATE | |||
| #include <stdlib.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 <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <time.h> | |||
| #include <string.h> | |||
| @@ -19,14 +12,23 @@ size_t readlink(char*, char*, size_t); | |||
| #include <stdarg.h> | |||
| #include <functional> | |||
| #ifdef _MSC_VER | |||
| # include <direct.h> | |||
| # include <windows.h> | |||
| #else | |||
| # include <unistd.h> | |||
| # include <signal.h> | |||
| #endif | |||
| #undef _CRT_SECURE_NO_DEPRECATE | |||
| #undef _CRT_SECURE_NO_WARNINGS | |||
| namespace Slime { | |||
| # include "./defines.cpp" | |||
| # include "./platform.cpp" | |||
| # include "./structs.cpp" | |||
| # include "./forward_decls.cpp" | |||
| # include "./platform.cpp" | |||
| # include "./memory.cpp" | |||
| # include "./lisp_object.cpp" | |||
| # include "./error.cpp" | |||
| @@ -593,7 +593,7 @@ proc run_all_tests() -> bool { | |||
| Memory::init(4096 * 2000, 1024 * 32, 4096 * 16 * 10); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| char* exe_path = get_exe_dir(); | |||
| // switch to the exe directory for loading pre.slime | |||
| change_cwd(exe_path); | |||
| @@ -4,15 +4,15 @@ proc visualize_lisp_machine() -> void { | |||
| char* cwd = get_cwd(); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| char* exe_path = get_exe_dir(); | |||
| // switch to the exe directory for loading pre.slime | |||
| change_cwd(exe_path); | |||
| free(exe_path); | |||
| defer { | |||
| // switch back to the users directory | |||
| change_cwd(cwd); | |||
| free(cwd); | |||
| free(exe_path); | |||
| }; | |||
| struct Drawn_Area { | |||