| author | |
| committer | |
| log | 15ba5bc54e286fb64d67e38857ede4b0dac9c841 |
| tree | 994b49126657dd38831d4a937e25f5fde4a8cff2 |
| parent | 0dbee2300ed28c18ecccaf71f10f68eb2da71266 |
6 files changed, 58 insertions(+), 12 deletions(-)
CMakeLists.txt+1| ... | @@ -117,6 +117,7 @@ set(C_HEADERS | ... | @@ -117,6 +117,7 @@ set(C_HEADERS |
| 117 | 117 | ||
| 118 | set(ZIG_STD_SRC | 118 | set(ZIG_STD_SRC |
| 119 | "${CMAKE_SOURCE_DIR}/std/bootstrap.zig" | 119 | "${CMAKE_SOURCE_DIR}/std/bootstrap.zig" |
| 120 | "${CMAKE_SOURCE_DIR}/std/std.zig" | ||
| 120 | ) | 121 | ) |
| 121 | 122 | ||
| 122 | set(C_HEADERS_DEST "lib/zig/include") | 123 | set(C_HEADERS_DEST "lib/zig/include") |
example/hello_world/hello2.zig+2-5| ... | @@ -1,11 +1,8 @@ | ... | @@ -1,11 +1,8 @@ |
| 1 | export executable "hello"; | 1 | export executable "hello"; |
| 2 | 2 | ||
| 3 | #link("c") | 3 | use "std.zig"; |
| 4 | extern { | ||
| 5 | fn printf(__format: *const u8, ...) -> i32; | ||
| 6 | } | ||
| 7 | 4 | ||
| 8 | export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { | 5 | export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { |
| 9 | printf("argc = %zu\n", argc); | 6 | print_str("Hello, world!", 13); |
| 10 | return 0; | 7 | return 0; |
| 11 | } | 8 | } |
src/analyze.hpp+2| ... | @@ -108,6 +108,8 @@ struct CodeGen { | ... | @@ -108,6 +108,8 @@ struct CodeGen { |
| 108 | LLVMZigDIBuilder *dbuilder; | 108 | LLVMZigDIBuilder *dbuilder; |
| 109 | LLVMZigDICompileUnit *compile_unit; | 109 | LLVMZigDICompileUnit *compile_unit; |
| 110 | 110 | ||
| 111 | ZigList<Buf *> lib_search_paths; | ||
| 112 | |||
| 111 | // reminder: hash tables must be initialized before use | 113 | // reminder: hash tables must be initialized before use |
| 112 | HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table; | 114 | HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table; |
| 113 | HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table; | 115 | HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table; |
src/codegen.cpp+29-6| ... | @@ -26,6 +26,7 @@ CodeGen *codegen_create(Buf *root_source_dir) { | ... | @@ -26,6 +26,7 @@ CodeGen *codegen_create(Buf *root_source_dir) { |
| 26 | g->import_table.init(32); | 26 | g->import_table.init(32); |
| 27 | g->build_type = CodeGenBuildTypeDebug; | 27 | g->build_type = CodeGenBuildTypeDebug; |
| 28 | g->root_source_dir = root_source_dir; | 28 | g->root_source_dir = root_source_dir; |
| 29 | |||
| 29 | return g; | 30 | return g; |
| 30 | } | 31 | } |
| 31 | 32 | ||
| ... | @@ -1066,6 +1067,9 @@ static void define_primitive_types(CodeGen *g) { | ... | @@ -1066,6 +1067,9 @@ static void define_primitive_types(CodeGen *g) { |
| 1066 | 1067 | ||
| 1067 | 1068 | ||
| 1068 | static void init(CodeGen *g, Buf *source_path) { | 1069 | static void init(CodeGen *g, Buf *source_path) { |
| 1070 | g->lib_search_paths.append(g->root_source_dir); | ||
| 1071 | g->lib_search_paths.append(buf_create_from_str(ZIG_STD_DIR)); | ||
| 1072 | |||
| 1069 | LLVMInitializeAllTargets(); | 1073 | LLVMInitializeAllTargets(); |
| 1070 | LLVMInitializeAllTargetMCs(); | 1074 | LLVMInitializeAllTargetMCs(); |
| 1071 | LLVMInitializeAllAsmPrinters(); | 1075 | LLVMInitializeAllAsmPrinters(); |
| ... | @@ -1188,17 +1192,34 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou | ... | @@ -1188,17 +1192,34 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou |
| 1188 | AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); | 1192 | AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); |
| 1189 | 1193 | ||
| 1190 | if (top_level_decl->type == NodeTypeUse) { | 1194 | if (top_level_decl->type == NodeTypeUse) { |
| 1191 | auto entry = g->import_table.maybe_get(&top_level_decl->data.use.path); | 1195 | Buf *import_target_path = &top_level_decl->data.use.path; |
| 1196 | auto entry = g->import_table.maybe_get(import_target_path); | ||
| 1192 | if (!entry) { | 1197 | if (!entry) { |
| 1193 | Buf full_path = BUF_INIT; | 1198 | Buf full_path = BUF_INIT; |
| 1194 | os_path_join(g->root_source_dir, &top_level_decl->data.use.path, &full_path); | ||
| 1195 | Buf *import_code = buf_alloc(); | 1199 | Buf *import_code = buf_alloc(); |
| 1196 | if ((err = os_fetch_file_path(&full_path, import_code))) { | 1200 | bool found_it = false; |
| 1197 | add_node_error(g, top_level_decl, | 1201 | |
| 1198 | buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); | 1202 | for (int path_i = 0; path_i < g->lib_search_paths.length; path_i += 1) { |
| 1203 | Buf *search_path = g->lib_search_paths.at(path_i); | ||
| 1204 | os_path_join(search_path, import_target_path, &full_path); | ||
| 1205 | |||
| 1206 | if ((err = os_fetch_file_path(&full_path, import_code))) { | ||
| 1207 | if (err == ErrorFileNotFound) { | ||
| 1208 | continue; | ||
| 1209 | } else { | ||
| 1210 | add_node_error(g, top_level_decl, | ||
| 1211 | buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); | ||
| 1212 | goto done_looking_at_imports; | ||
| 1213 | } | ||
| 1214 | } | ||
| 1215 | codegen_add_code(g, &top_level_decl->data.use.path, import_code); | ||
| 1216 | found_it = true; | ||
| 1199 | break; | 1217 | break; |
| 1200 | } | 1218 | } |
| 1201 | codegen_add_code(g, &top_level_decl->data.use.path, import_code); | 1219 | if (!found_it) { |
| 1220 | add_node_error(g, top_level_decl, | ||
| 1221 | buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); | ||
| 1222 | } | ||
| 1202 | } | 1223 | } |
| 1203 | } else if (top_level_decl->type == NodeTypeFnDef) { | 1224 | } else if (top_level_decl->type == NodeTypeFnDef) { |
| 1204 | AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; | 1225 | 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 | ... | @@ -1213,6 +1234,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou |
| 1213 | } | 1234 | } |
| 1214 | } | 1235 | } |
| 1215 | 1236 | ||
| 1237 | done_looking_at_imports: | ||
| 1238 | |||
| 1216 | return import_entry; | 1239 | return import_entry; |
| 1217 | } | 1240 | } |
| 1218 | 1241 |
std/std.zig created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize { | ||
| 2 | let mut result : isize; | ||
| 3 | asm volatile ( | ||
| 4 | "mov %[number], %%rax\n" | ||
| 5 | "mov %[arg1], %%rdi\n" | ||
| 6 | "mov %[arg2], %%rsi\n" | ||
| 7 | "mov %[arg3], %%rdx\n" | ||
| 8 | "syscall\n" | ||
| 9 | "mov %%rax, %[ret]\n" | ||
| 10 | : [ret] "=r" (result) | ||
| 11 | : [number] "r" (number), [arg1] "r" (arg1), [arg2] "r" (arg2), [arg3] "r" (arg3) | ||
| 12 | : "rcx", "r11", "rax", "rdi", "rsi", "rdx"); | ||
| 13 | return result; | ||
| 14 | } | ||
| 15 | |||
| 16 | // TODO error handling | ||
| 17 | // TODO zig strings instead of C strings | ||
| 18 | // TODO handle buffering and flushing | ||
| 19 | pub print_str(str : *const u8, len: isize) { | ||
| 20 | let SYS_write = 1; | ||
| 21 | let stdout_fileno = 1; | ||
| 22 | syscall3(SYS_write, stdout_fileno, str as isize, str_len); | ||
| 23 | } | ||
test/run_tests.cpp+1-1| ... | @@ -461,7 +461,7 @@ export executable "test"; | ... | @@ -461,7 +461,7 @@ export executable "test"; |
| 461 | 461 | ||
| 462 | add_compile_fail_case("bad import", R"SOURCE( | 462 | add_compile_fail_case("bad import", R"SOURCE( |
| 463 | use "bogus-does-not-exist.zig"; | 463 | use "bogus-does-not-exist.zig"; |
| 464 | )SOURCE", 1, ".tmp_source.zig:2:1: error: unable to open './bogus-does-not-exist.zig': file not found"); | 464 | )SOURCE", 1, ".tmp_source.zig:2:1: error: unable to find 'bogus-does-not-exist.zig'"); |
| 465 | 465 | ||
| 466 | add_compile_fail_case("undeclared identifier", R"SOURCE( | 466 | add_compile_fail_case("undeclared identifier", R"SOURCE( |
| 467 | fn a() { | 467 | fn a() { |