UNICODE support and fixed a bug where top level imports did noit work

This commit is contained in:
FelixBrendel
2020-04-05 23:06:46 +02:00
parent 12e743f57b
commit ffc576eae3
20 changed files with 123 additions and 41 deletions
+2 -2
View File
@@ -33,7 +33,7 @@
do { \
if (_node->type != _type) { \
char* t = lisp_object_to_string(_node); \
defer { free(t); }; \
defer_free(t); \
create_type_missmatch_error( \
lisp_object_type_to_string(_type), \
lisp_object_type_to_string(_node->type), \
@@ -47,7 +47,7 @@
do { \
if (!(condition)) { \
create_generic_error("Assertion-error: %s\n" \
" for: %s\n" \
" condition: %s\n" \
" in: %s:%d", \
message, #condition, __FILE__, __LINE__); \
} \
+29 -4
View File
@@ -62,23 +62,39 @@ namespace Slime {
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;
load_path.append((void*)path);
load_path.append((path_char*)path);
}
proc built_in_load(String file_name) -> Lisp_Object* {
profile_with_comment(file_name.data);
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));
file_content = read_entire_file(Memory::get_c_str(file_name));
#endif
if (!file_content) {
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';
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);
if (file_content)
break;
@@ -98,7 +114,13 @@ namespace Slime {
Lisp_Object* result = Memory::nil;
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);
#endif
defer {
free(spath.data);
};
@@ -121,9 +143,12 @@ namespace Slime {
proc built_in_import(String file_name) -> Lisp_Object* {
profile_this();
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));
if (!new_env) {
// create new empty environment
try new_env = Memory::create_child_environment(get_root_environment());
+3
View File
@@ -1,12 +1,15 @@
#define proc auto
#ifdef _DEBUG
# define SLIME_DEBUG
# define if_debug if constexpr (true)
#else
# define if_debug if constexpr (false)
#endif
#ifdef _MSC_VER
# define SLIME_WINDOWS
# define debug_break() if_debug __debugbreak()
# define if_windows if constexpr (true)
# define if_linux if constexpr (false)
+9 -6
View File
@@ -37,7 +37,10 @@ namespace Slime {
if (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]);
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) {
print_indent();
+2
View File
@@ -566,6 +566,7 @@ namespace Slime {
proc interprete_file (char* file_name) -> Lisp_Object* {
try Memory::init();
try Memory::load_pre();
try Memory::push_user_environment();
defer {
if_debug {
Slime::Memory::free_everything();
@@ -582,6 +583,7 @@ namespace Slime {
proc interprete_stdin() -> void {
try_void Memory::init();
try_void Memory::load_pre();
try_void Memory::push_user_environment();
defer {
if_debug {
Slime::Memory::free_everything();
+7 -2
View File
@@ -1,5 +1,5 @@
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*);
Lisp_Object* built_in_load(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_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);
bool run_all_tests();
@@ -81,7 +86,7 @@ namespace Slime {
extern bool debug_log;
extern char* bin_path;
extern Log_Level log_level;
extern Array_List<void*> load_path;
extern Array_List<path_char*> load_path;
// namespace Current_Execution {
// extern Array_List<Lisp_Object*> call_stack;
// extern Array_List<Environment*> envi_stack;
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Slime::Globals {
char* bin_path = nullptr;
Log_Level log_level = Log_Level::Debug;
bool debug_log = false;
Array_List<void*> load_path;
Array_List<path_char*> load_path;
Hash_Map<void*, char*> docs;
Hash_Map<void*, Source_Code_Location> source_code_locations;
+24 -3
View File
@@ -117,10 +117,14 @@ namespace Slime {
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;
#if defined(UNICODE) && defined(SLIME_WINDOWS)
FILE *fp = _wfopen(filename, L"r");
#else
FILE *fp = fopen(filename, "r");
#endif
if (fp) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
@@ -292,7 +296,7 @@ namespace Slime {
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;
wchar_t* wc = new wchar_t[cSize];
mbstowcs (wc, c, cSize);
@@ -300,6 +304,23 @@ namespace Slime {
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* {
size_t len = 1;
for (auto str : string_builder) {
+2
View File
@@ -16,6 +16,8 @@ s32 main(s32 argc, char* argv[]) {
return res ? 0 : 1;
} else if (Slime::string_equal(argv[1], "--generate-docs-file")) {
Slime::Memory::init();
Slime::Memory::load_pre();
Slime::Memory::push_user_environment();
defer {
if_debug {
Slime::Memory::free_everything();
+14 -7
View File
@@ -128,7 +128,7 @@ namespace Slime::Memory {
// free the exe dir:
free(Globals::load_path.data[0]);
// Globals::load_path.dealloc();
Globals::load_path.dealloc();
Globals::user_types.dealloc();
Globals::docs.dealloc();
Globals::Current_Execution.envi_stack.dealloc();
@@ -172,12 +172,21 @@ namespace Slime::Memory {
return ret;
}
proc load_pre() -> void {
inline proc load_pre() -> void {
String file_name = Memory::create_string("pre.slime");
defer_free(file_name.data);
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 {
profile_this();
@@ -185,7 +194,7 @@ namespace Slime::Memory {
environment_memory.alloc(1024, 8);
hashmap_memory.alloc(256, 8);
char* exe_path = get_exe_dir();
path_char* exe_path = get_exe_dir();
global_symbol_table.alloc();
@@ -202,9 +211,9 @@ namespace Slime::Memory {
Globals::docs.alloc();
Globals::user_types.alloc();
// Globals::load_path.alloc();
Globals::load_path.alloc();
add_to_load_path(exe_path);
add_to_load_path("../bin/");
add_to_load_path((path_char*)char_to_path_char("../bin/"));
// init nil
@@ -221,8 +230,6 @@ namespace Slime::Memory {
Environment* env;
try_void env = create_built_ins_environment();
push_environment(env);
}
+5 -5
View File
@@ -61,12 +61,12 @@ namespace Slime {
}
#endif
proc get_exe_dir() -> char* {
proc get_exe_dir() -> path_char* {
#ifdef _MSC_VER
DWORD last_error;
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) {
memset(path, 0, path_size);
@@ -86,7 +86,7 @@ namespace Slime {
break;
}
path_size = path_size * 2;
path = (char*)malloc(path_size);
path = (path_char*)malloc((sizeof(path_char)) * path_size);
}
else
break;
@@ -102,7 +102,7 @@ namespace Slime {
s32 index_in_path = -1;
s32 last_backslash = -1;
char c;
path_char c;
while ((c = path[++index_in_path]) != '\0') {
if (c == '\\')
last_backslash = index_in_path;
+1 -2
View File
@@ -537,8 +537,6 @@ namespace Slime {
proc test_file(const char* file) -> testresult {
profile_with_name(file);
// Memory::reset();
// assert_no_error();
push_environment(Memory::create_child_environment(get_current_environment()));
String name = Memory::create_string(file);
@@ -556,6 +554,7 @@ namespace Slime {
bool result = true;
try Memory::init();
try Memory::load_pre();
try Memory::push_user_environment();
defer {
if_debug {
Slime::Memory::free_everything();
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Slime {
// char* cwd = get_cwd();
// // 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
// change_cwd(exe_path);