added #library_path to specify where libraries are
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Dec 2021 17:36:56 +0000 (11:36 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Dec 2021 17:36:56 +0000 (11:36 -0600)
include/astnodes.h
include/utils.h
src/astnodes.c
src/entities.c
src/onyx.c
src/parser.c
src/utils.c
src/wasm_emit.c
src/wasm_runtime.c

index f2eb464a4139898cb9c90afa662dca5035b40469..d31f57e8150401c2b0bbc022a859e720ffdb48ff 100644 (file)
@@ -124,6 +124,7 @@ typedef enum AstKind {
     Ast_Kind_Package,
     Ast_Kind_Load_File,
     Ast_Kind_Load_Path,
+    Ast_Kind_Library_Path,
     Ast_Kind_Memres,
 
     Ast_Kind_Binding,
@@ -1467,6 +1468,7 @@ struct CompileOptions {
     Runtime runtime;
 
     bh_arr(const char *) included_folders;
+    bh_arr(const char *) included_library_folders;
     bh_arr(const char *) files;
     const char* target_file;
     const char* documentation_file;
index b209ed81c96aee6c10e3054510d17a89eb051398..a53b983dc3531c5199729301fb4e39393c635f2d 100644 (file)
@@ -37,7 +37,7 @@ i32 string_process_escape_seqs(char* dest, char* src, i32 len);
 // This function can return a static variable which will change if this is called
 // another time.                                        -brendanfh 2020/10/09
 // :RelativeFiles This should lookup for the file relative to "relative_to"
-char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders);
+char* lookup_included_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, bh_arr(const char *) included_folders, b32 search_included_folders);
 
 u32 levenshtein_distance(const char *str1, const char *str2);
 char *find_closest_symbol_in_node(AstNode *node, char *sym);
index 61325053c735e1984d37ed356d9622ddc90607fe..9961813eb67cdaad6e128c9282039272fffa6eb8 100644 (file)
@@ -7,6 +7,7 @@ static const char* ast_node_names[] = {
     "PACKAGE",
     "INCLUDE FILE",
     "INCLUDE FOLDER",
+    "INCLUDE LIBRARY PATH",
     "MEMORY RESERVATION",
 
     "BINDING",
index 876ca6efc34a8847389adf253dcf2323ef65a5df..8f53ede28c2138228d99cab2e2cb3c326338dc89 100644 (file)
@@ -169,6 +169,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s
             break;
         }
 
+        case Ast_Kind_Library_Path:
         case Ast_Kind_Load_Path: {
             ent.state = Entity_State_Parse;
             ent.type = Entity_Type_Load_Path;
index 03e82d29cf541d8e9c4a81c5340a174c3aff269b..30cb9b616219f286f66276c6f8a43c0eaf42dca3 100644 (file)
@@ -86,6 +86,7 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
 
     bh_arr_new(alloc, options.files, 2);
     bh_arr_new(alloc, options.included_folders, 2);
+    bh_arr_new(alloc, options.included_library_folders, 2);
 
     // NOTE: Add the current folder
     bh_arr_push(options.included_folders, CORE_INSTALLATION);
@@ -315,13 +316,16 @@ static void process_load_entity(Entity* ent) {
 
         char* parent_folder = bh_path_get_parent(parent_file, global_scratch_allocator);
         
-        char* filename = lookup_included_file(include->name, parent_folder, 1, 1);
+        char* filename = lookup_included_file(include->name, parent_folder, ".onyx", 1, context.options->included_folders, 1);
         char* formatted_name = bh_strdup(global_heap_allocator, filename);
 
         process_source_file(formatted_name, include->token->pos);
 
     } else if (include->kind == Ast_Kind_Load_Path) {
         bh_arr_push(context.options->included_folders, include->name);
+
+    } else if (include->kind == Ast_Kind_Library_Path) {
+        bh_arr_push(context.options->included_library_folders, include->name);
     }
 }
 
index 49f4ee5a6cc0a5b64743d6bf2011318129a4ca73..c7d7a2e65893a3cda4c3a6f84393e66b4005ec7b 100644 (file)
@@ -2966,6 +2966,20 @@ static void parse_top_level_statement(OnyxParser* parser) {
                 ENTITY_SUBMIT(include);
                 return;
             }
+            else if (parse_possible_directive(parser, "library_path")) {
+                AstInclude* include = make_node(AstInclude, Ast_Kind_Library_Path);
+                include->token = dir_token;
+                
+                OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
+                if (str_token != NULL) {
+                    token_toggle_end(str_token);
+                    include->name = bh_strdup(parser->allocator, str_token->text);
+                    token_toggle_end(str_token);
+                }
+
+                ENTITY_SUBMIT(include);
+                return;
+            }
             else if (parse_possible_directive(parser, "error")) {
                 AstDirectiveError *error = make_node(AstDirectiveError, Ast_Kind_Directive_Error);
                 error->token = dir_token;
index 18f1569f24056af14bb3d976218fb4e841d22cbd..109bded28f9a0197bd47e983fdf779d2e3748cc4 100644 (file)
@@ -955,7 +955,7 @@ i32 string_process_escape_seqs(char* dest, char* src, i32 len) {
     return total_len;
 }
 
-char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders) {
+char* lookup_included_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, bh_arr(const char *) included_folders, b32 search_included_folders) {
     assert(relative_to != NULL);
 
     static char path[256];
@@ -964,8 +964,8 @@ char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffi
     static char fn[128];
     fori (i, 0, 128) fn[i] = 0;
 
-    if (!bh_str_ends_with(filename, ".onyx") && add_onyx_suffix) {
-        bh_snprintf(fn, 128, "%s.onyx", filename);
+    if (!bh_str_ends_with(filename, suffix) && add_suffix) {
+        bh_snprintf(fn, 128, "%s%s", filename, suffix);
     } else {
         bh_snprintf(fn, 128, "%s", filename);
     }
@@ -990,7 +990,7 @@ char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffi
     }
 
     if (search_included_folders) {
-        bh_arr_each(const char *, folder, context.options->included_folders) {
+        bh_arr_each(const char *, folder, included_folders) {
             if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR)
                 bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn);
             else
index ffdaec2200ac7a674ba48bae265f92131dfe7a28..d8cd5c6813c62901a09897629fd4ed1e6325524d 100644 (file)
@@ -3652,7 +3652,7 @@ static void emit_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {
 
         char* temp_fn     = bh_alloc_array(global_scratch_allocator, char, fc->filename_token->length);
         i32   temp_fn_len = string_process_escape_seqs(temp_fn, fc->filename_token->text, fc->filename_token->length);
-        char* filename    = lookup_included_file(temp_fn, parent_folder, 0, 0);
+        char* filename    = lookup_included_file(temp_fn, parent_folder, "", 0, NULL, 0);
         fc->filename      = bh_strdup(global_heap_allocator, filename);
     }
 
index 64017cc85994d3c0487fe8743022a7bb23197a40..74d98f77ce0f0cbfdd7ef0ea647246c5297159a2 100644 (file)
@@ -521,7 +521,7 @@ static void onyx_load_library(char *name) {
     LibraryLinker library_load;
 
     #ifdef _BH_LINUX
-    char *library_name = bh_aprintf(global_scratch_allocator, "%s.so", name);
+    char *library_name = lookup_included_file(name, ".", ".so", 1, context.options->included_library_folders, 1);
     void* handle = dlopen(library_name, RTLD_LAZY);
     if (handle == NULL) {
         printf("ERROR LOADING LIBRARY %s: %s\n", name, dlerror());
@@ -536,7 +536,7 @@ static void onyx_load_library(char *name) {
     #endif
 
     #ifdef _BH_WINDOWS
-    char *library_name = bh_aprintf(global_scratch_allocator, "%s.dll", name);
+    char *library_name = lookup_included_file(name, ".", ".dll", 1, context.options->included_library_folders, 1);
     HMODULE handle = LoadLibraryA(library_name);
     if (handle == NULL) {
         printf("ERROR LOADING LIBRARY %s: %d\n", name, GetLastError());