From 15ba5bc54e286fb64d67e38857ede4b0dac9c841 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 10 Dec 2015 17:42:47 -0700 Subject: [PATCH] provide std.zig and add it to import paths --- CMakeLists.txt | 1 + example/hello_world/hello2.zig | 7 ++----- src/analyze.hpp | 2 ++ src/codegen.cpp | 35 ++++++++++++++++++++++++++++------ std/std.zig | 23 ++++++++++++++++++++++ test/run_tests.cpp | 2 +- 6 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 std/std.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index ffdc252b0e..8114f4315a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,7 @@ set(C_HEADERS set(ZIG_STD_SRC "${CMAKE_SOURCE_DIR}/std/bootstrap.zig" + "${CMAKE_SOURCE_DIR}/std/std.zig" ) set(C_HEADERS_DEST "lib/zig/include") diff --git a/example/hello_world/hello2.zig b/example/hello_world/hello2.zig index b31d0542bc..45756a3b1d 100644 --- a/example/hello_world/hello2.zig +++ b/example/hello_world/hello2.zig @@ -1,11 +1,8 @@ export executable "hello"; -#link("c") -extern { - fn printf(__format: *const u8, ...) -> i32; -} +use "std.zig"; export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { - printf("argc = %zu\n", argc); + print_str("Hello, world!", 13); return 0; } diff --git a/src/analyze.hpp b/src/analyze.hpp index cf719edbe5..2f9bb209d4 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -108,6 +108,8 @@ struct CodeGen { LLVMZigDIBuilder *dbuilder; LLVMZigDICompileUnit *compile_unit; + ZigList lib_search_paths; + // reminder: hash tables must be initialized before use HashMap fn_table; HashMap str_table; diff --git a/src/codegen.cpp b/src/codegen.cpp index 5a177792b4..b03c769a0d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -26,6 +26,7 @@ CodeGen *codegen_create(Buf *root_source_dir) { g->import_table.init(32); g->build_type = CodeGenBuildTypeDebug; g->root_source_dir = root_source_dir; + return g; } @@ -1066,6 +1067,9 @@ static void define_primitive_types(CodeGen *g) { static void init(CodeGen *g, Buf *source_path) { + g->lib_search_paths.append(g->root_source_dir); + g->lib_search_paths.append(buf_create_from_str(ZIG_STD_DIR)); + LLVMInitializeAllTargets(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllAsmPrinters(); @@ -1188,17 +1192,34 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); if (top_level_decl->type == NodeTypeUse) { - auto entry = g->import_table.maybe_get(&top_level_decl->data.use.path); + Buf *import_target_path = &top_level_decl->data.use.path; + auto entry = g->import_table.maybe_get(import_target_path); if (!entry) { Buf full_path = BUF_INIT; - os_path_join(g->root_source_dir, &top_level_decl->data.use.path, &full_path); Buf *import_code = buf_alloc(); - if ((err = os_fetch_file_path(&full_path, import_code))) { - add_node_error(g, top_level_decl, - buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); + bool found_it = false; + + for (int path_i = 0; path_i < g->lib_search_paths.length; path_i += 1) { + Buf *search_path = g->lib_search_paths.at(path_i); + os_path_join(search_path, import_target_path, &full_path); + + if ((err = os_fetch_file_path(&full_path, import_code))) { + if (err == ErrorFileNotFound) { + continue; + } else { + add_node_error(g, top_level_decl, + buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); + goto done_looking_at_imports; + } + } + codegen_add_code(g, &top_level_decl->data.use.path, import_code); + found_it = true; break; } - codegen_add_code(g, &top_level_decl->data.use.path, import_code); + if (!found_it) { + add_node_error(g, top_level_decl, + buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); + } } } else if (top_level_decl->type == NodeTypeFnDef) { AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; @@ -1213,6 +1234,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou } } +done_looking_at_imports: + return import_entry; } diff --git a/std/std.zig b/std/std.zig new file mode 100644 index 0000000000..3bcf9e4783 --- /dev/null +++ b/std/std.zig @@ -0,0 +1,23 @@ +fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize { + let mut result : isize; + asm volatile ( + "mov %[number], %%rax\n" + "mov %[arg1], %%rdi\n" + "mov %[arg2], %%rsi\n" + "mov %[arg3], %%rdx\n" + "syscall\n" + "mov %%rax, %[ret]\n" + : [ret] "=r" (result) + : [number] "r" (number), [arg1] "r" (arg1), [arg2] "r" (arg2), [arg3] "r" (arg3) + : "rcx", "r11", "rax", "rdi", "rsi", "rdx"); + return result; +} + +// TODO error handling +// TODO zig strings instead of C strings +// TODO handle buffering and flushing +pub print_str(str : *const u8, len: isize) { + let SYS_write = 1; + let stdout_fileno = 1; + syscall3(SYS_write, stdout_fileno, str as isize, str_len); +} diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 2ea6befd0d..5d28e54ebf 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -461,7 +461,7 @@ export executable "test"; add_compile_fail_case("bad import", R"SOURCE( use "bogus-does-not-exist.zig"; - )SOURCE", 1, ".tmp_source.zig:2:1: error: unable to open './bogus-does-not-exist.zig': file not found"); + )SOURCE", 1, ".tmp_source.zig:2:1: error: unable to find 'bogus-does-not-exist.zig'"); add_compile_fail_case("undeclared identifier", R"SOURCE( fn a() {