foreign import x {"foo.lib", "bar.lib"}

This commit is contained in:
gingerBill
2018-07-29 20:56:09 +01:00
parent dc5da7933a
commit a6fe656f21
7 changed files with 97 additions and 55 deletions
+4
View File
@@ -69,6 +69,10 @@ compare_byte_ptrs :: proc "contextless" (a, b: ^byte, n: int) -> int {
return 0;
}
compare_ptrs :: inline proc "contextless" (a, b: rawptr, n: int) -> int {
return compare_byte_ptrs((^byte)(a), (^byte)(b), n);
}
ptr_offset :: proc "contextless" (ptr: $P/^$T, n: int) -> P {
new := int(uintptr(ptr)) + size_of(T)*n;
return P(uintptr(new));
+21 -19
View File
@@ -2615,37 +2615,39 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
Scope *parent_scope = ctx->scope;
GB_ASSERT(parent_scope->flags&ScopeFlag_File);
String fullpath = fl->fullpath;
GB_ASSERT(fl->fullpaths.count > 0);
String fullpath = fl->fullpaths[0];
String library_name = path_to_entity_name(fl->library_name.string, fullpath);
if (is_blank_ident(library_name)) {
error(fl->token, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
return;
}
if (fl->collection_name != "system") {
char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
defer (gb_free(heap_allocator(), c_str));
gb_memmove(c_str, fullpath.text, fullpath.len);
c_str[fullpath.len] = '\0';
// if (fl->collection_name != "system") {
// char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
// defer (gb_free(heap_allocator(), c_str));
// gb_memmove(c_str, fullpath.text, fullpath.len);
// c_str[fullpath.len] = '\0';
gbFile f = {};
gbFileError file_err = gb_file_open(&f, c_str);
defer (gb_file_close(&f));
// gbFile f = {};
// gbFileError file_err = gb_file_open(&f, c_str);
// defer (gb_file_close(&f));
switch (file_err) {
case gbFileError_Invalid:
error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath));
return;
case gbFileError_NotExists:
error(decl, "File cannot be found ('%.*s')", LIT(fullpath));
return;
}
}
// switch (file_err) {
// case gbFileError_Invalid:
// error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath));
// return;
// case gbFileError_NotExists:
// error(decl, "File cannot be found ('%.*s')", LIT(fullpath));
// return;
// }
// }
GB_ASSERT(fl->library_name.pos.line != 0);
fl->library_name.string = library_name;
Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid,
fl->fullpath, library_name);
fl->fullpaths, library_name);
add_entity(ctx->checker, parent_scope, nullptr, e);
}
+3 -3
View File
@@ -124,7 +124,7 @@ struct Entity {
Scope *scope;
} ImportName;
struct {
String path;
Array<String> paths;
String name;
} LibraryName;
i32 Nil;
@@ -278,9 +278,9 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
}
Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
String path, String name) {
Array<String> paths, String name) {
Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
entity->LibraryName.path = path;
entity->LibraryName.paths = paths;
entity->LibraryName.name = name;
entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
return entity;
+16 -14
View File
@@ -1332,22 +1332,24 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
GB_ASSERT(e->kind == Entity_LibraryName);
GB_ASSERT(e->flags & EntityFlag_Used);
String library_path = e->LibraryName.path;
if (library_path.len == 0) {
return;
}
for_array(path_index, m->foreign_library_paths) {
String path = m->foreign_library_paths[path_index];
#if defined(GB_SYSTEM_WINDOWS)
if (str_eq_ignore_case(path, library_path)) {
#else
if (str_eq(path, library_path)) {
#endif
return;
for_array(i, e->LibraryName.paths) {
String library_path = e->LibraryName.paths[i];
if (library_path.len == 0) {
continue;
}
for_array(path_index, m->foreign_library_paths) {
String path = m->foreign_library_paths[path_index];
#if defined(GB_SYSTEM_WINDOWS)
if (str_eq_ignore_case(path, library_path)) {
#else
if (str_eq(path, library_path)) {
#endif
continue;
}
}
array_add(&m->foreign_library_paths, library_path);
}
array_add(&m->foreign_library_paths, library_path);
}
+1 -2
View File
@@ -253,7 +253,6 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_CrossLibDir, str_lit("cross-lib-dir"), BuildFlagParam_String);
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None);
GB_ASSERT(args.count >= 3);
Array<String> flag_args = array_slice(args, 3, args.count);
@@ -877,9 +876,9 @@ int main(int arg_count, char **arg_ptr) {
gbString lib_str = gb_string_make(heap_allocator(), "");
defer (gb_string_free(lib_str));
char lib_str_buf[1024] = {0};
for_array(i, ir_gen.module.foreign_library_paths) {
String lib = ir_gen.module.foreign_library_paths[i];
// gb_printf_err("Linking lib: %.*s\n", LIT(lib));
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf);
+50 -15
View File
@@ -999,11 +999,11 @@ Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Toke
return result;
}
Ast *ast_foreign_import_decl(AstFile *f, Token token, Token filepath, Token library_name,
Ast *ast_foreign_import_decl(AstFile *f, Token token, Array<Token> filepaths, Token library_name,
CommentGroup *docs, CommentGroup *comment) {
Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl);
result->ForeignImportDecl.token = token;
result->ForeignImportDecl.filepath = filepath;
result->ForeignImportDecl.filepaths = filepaths;
result->ForeignImportDecl.library_name = library_name;
result->ForeignImportDecl.docs = docs;
result->ForeignImportDecl.comment = comment;
@@ -3491,15 +3491,38 @@ Ast *parse_foreign_decl(AstFile *f) {
break;
}
if (is_blank_ident(lib_name)) {
syntax_error(lib_name, "Illegal foreign_library name: '_'");
syntax_error(lib_name, "Illegal foreign import name: '_'");
}
Token file_path = expect_token(f, Token_String);
Ast *s = nullptr;
if (f->curr_proc != nullptr) {
syntax_error(lib_name, "You cannot use foreign_library within a procedure. This must be done at the file scope");
s = ast_bad_decl(f, lib_name, file_path);
Array<Token> filepaths = {};
if (allow_token(f, Token_OpenBrace)) {
array_init(&filepaths, heap_allocator());
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_EOF) {
Token path = expect_token(f, Token_String);
array_add(&filepaths, path);
if (!allow_token(f, Token_Comma)) {
break;
}
}
expect_token(f, Token_CloseBrace);
} else {
s = ast_foreign_import_decl(f, token, file_path, lib_name, docs, f->line_comment);
filepaths = array_make<Token>(heap_allocator(), 0, 1);
Token path = expect_token(f, Token_String);
array_add(&filepaths, path);
}
Ast *s = nullptr;
if (filepaths.count == 0) {
syntax_error(lib_name, "foreign import without any paths");
s = ast_bad_decl(f, lib_name, f->curr_token);
} else if (f->curr_proc != nullptr) {
syntax_error(lib_name, "You cannot use foreign import within a procedure. This must be done at the file scope");
s = ast_bad_decl(f, lib_name, filepaths[0]);
} else {
s = ast_foreign_import_decl(f, token, filepaths, lib_name, docs, f->line_comment);
}
expect_semicolon(f, s);
return s;
@@ -4129,22 +4152,34 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<Ast *>
} else if (node->kind == Ast_ForeignImportDecl) {
ast_node(fl, ForeignImportDecl, node);
String file_str = fl->filepath.string;
fl->fullpath = file_str;
fl->fullpaths.allocator = heap_allocator();
array_reserve(&fl->fullpaths, fl->filepaths.count);
for_array(fp_idx, fl->filepaths) {
String file_str = fl->filepaths[fp_idx].string;
String fullpath = file_str;
if (fl->collection_name != "system") {
String foreign_path = {};
bool ok = determine_path_from_string(p, node, base_dir, file_str, &foreign_path);
if (!ok) {
decls[i] = ast_bad_decl(f, fl->filepath, fl->filepath);
continue;
decls[i] = ast_bad_decl(f, fl->filepaths[fp_idx], fl->filepaths[fl->filepaths.count-1]);
goto end;
}
fl->fullpath = foreign_path;
fullpath = foreign_path;
array_add(&fl->fullpaths, fullpath);
}
if (fl->fullpaths.count == 0) {
error(decls[i], "No foreign paths found");
decls[i] = ast_bad_decl(f, fl->filepaths[0], fl->filepaths[fl->filepaths.count-1]);
goto end;
}
} else if (node->kind == Ast_WhenStmt) {
ast_node(ws, WhenStmt, node);
parse_setup_file_when_stmt(p, f, base_dir, ws);
}
end:;
}
}
+2 -2
View File
@@ -391,10 +391,10 @@ AST_KIND(_DeclBegin, "", bool) \
}) \
AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \
Token token; \
Token filepath; \
Array<Token> filepaths; \
Token library_name; \
String collection_name; \
String fullpath; \
Array<String> fullpaths; \
CommentGroup *docs; \
CommentGroup *comment; \
}) \