diff options
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 9d8e90347..c57fe7365 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -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); + 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 { + filepaths = array_make<Token>(heap_allocator(), 0, 1); + Token path = expect_token(f, Token_String); + array_add(&filepaths, path); + } + 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); + 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, file_path, lib_name, docs, f->line_comment); + 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:; } } |