authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-15 12:44:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-15 12:44:42-07:00
logf5a32818773835bdeaa8f0db1d036a1506c69982
treecec14b3ed641e3916613e5ff24f9db7943177c18
parentf2a9b40231f982b10c4d098c60b47da890396c1f

when linking with libc use the C runtime library


9 files changed, 151 insertions(+), 114 deletions(-)

README.md+2-2
...@@ -61,7 +61,7 @@ compromises backward compatibility....@@ -61,7 +61,7 @@ compromises backward compatibility.
61```61```
62mkdir build62mkdir build
63cd build63cd build
64cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd)64cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_DIR=path/to/libc/dir
65make65make
66make install66make install
67./run_tests67./run_tests
...@@ -72,7 +72,7 @@ make install...@@ -72,7 +72,7 @@ make install
72```72```
73mkdir build73mkdir build
74cd build74cd build
75cmake .. -DCMAKE_BUILD_TYPE=Release75cmake .. -DCMAKE_BUILD_TYPE=Release -DZIG_LIBC_DIR=path/to/libc/dir
76make76make
77sudo make install77sudo make install
78```78```
example/hello_world/hello_libc.zig+2-2
...@@ -6,7 +6,7 @@ extern {...@@ -6,7 +6,7 @@ extern {
6 fn exit(__status: i32) -> unreachable;6 fn exit(__status: i32) -> unreachable;
7}7}
88
9export fn _start() -> unreachable {9export fn main(argc: i32, argv: &&u8, env: &&u8) -> i32 {
10 printf(c"Hello, world!\n");10 printf(c"Hello, world!\n");
11 exit(0);11 return 0;
12}12}
src/analyze.hpp+3-1
...@@ -164,7 +164,9 @@ struct CodeGen {...@@ -164,7 +164,9 @@ struct CodeGen {
164 unsigned pointer_size_bytes;164 unsigned pointer_size_bytes;
165 bool is_static;165 bool is_static;
166 bool strip_debug_symbols;166 bool strip_debug_symbols;
167 bool insert_bootstrap_code;167 bool have_exported_main;
168 bool link_libc;
169 Buf *libc_path;
168 CodeGenBuildType build_type;170 CodeGenBuildType build_type;
169 LLVMTargetMachineRef target_machine;171 LLVMTargetMachineRef target_machine;
170 LLVMZigDIFile *dummy_di_file;172 LLVMZigDIFile *dummy_di_file;
src/codegen.cpp+76-5
...@@ -58,6 +58,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {...@@ -58,6 +58,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {
58 g->root_out_name = out_name;58 g->root_out_name = out_name;
59}59}
6060
61void codegen_set_libc_path(CodeGen *g, Buf *libc_path) {
62 g->libc_path = libc_path;
63}
64
61static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node);65static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node);
62 66
6367
...@@ -1517,6 +1521,18 @@ static void init(CodeGen *g, Buf *source_path) {...@@ -1517,6 +1521,18 @@ static void init(CodeGen *g, Buf *source_path) {
15171521
1518}1522}
15191523
1524static bool directives_contains_link_libc(ZigList<AstNode*> *directives) {
1525 for (int i = 0; i < directives->length; i += 1) {
1526 AstNode *directive_node = directives->at(i);
1527 if (buf_eql_str(&directive_node->data.directive.name, "link") &&
1528 buf_eql_str(&directive_node->data.directive.param, "c"))
1529 {
1530 return true;
1531 }
1532 }
1533 return false;
1534}
1535
1520static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {1536static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {
1521 int err;1537 int err;
1522 Buf *full_path = buf_alloc();1538 Buf *full_path = buf_alloc();
...@@ -1613,11 +1629,13 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src...@@ -1613,11 +1629,13 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src
1613 assert(proto_node->type == NodeTypeFnProto);1629 assert(proto_node->type == NodeTypeFnProto);
1614 Buf *proto_name = &proto_node->data.fn_proto.name;1630 Buf *proto_name = &proto_node->data.fn_proto.name;
16151631
1616 bool is_exported = (proto_node->data.fn_proto.visib_mod != FnProtoVisibModPrivate);1632 bool is_private = (proto_node->data.fn_proto.visib_mod == FnProtoVisibModPrivate);
16171633
1618 if (buf_eql_str(proto_name, "main") && is_exported) {1634 if (buf_eql_str(proto_name, "main") && !is_private) {
1619 g->insert_bootstrap_code = true;1635 g->have_exported_main = true;
1620 }1636 }
1637 } else if (top_level_decl->type == NodeTypeExternBlock) {
1638 g->link_libc = directives_contains_link_libc(top_level_decl->data.extern_block.directives);
1621 }1639 }
1622 }1640 }
16231641
...@@ -1633,7 +1651,7 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou...@@ -1633,7 +1651,7 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
16331651
1634 g->root_import = codegen_add_code(g, src_dir, src_basename, source_code);1652 g->root_import = codegen_add_code(g, src_dir, src_basename, source_code);
16351653
1636 if (g->insert_bootstrap_code) {1654 if (g->have_exported_main && !g->link_libc && g->out_type != OutTypeLib) {
1637 Buf *bootstrap_dir = buf_create_from_str(ZIG_STD_DIR);1655 Buf *bootstrap_dir = buf_create_from_str(ZIG_STD_DIR);
1638 Buf *bootstrap_basename = buf_create_from_str("bootstrap.zig");1656 Buf *bootstrap_basename = buf_create_from_str("bootstrap.zig");
1639 Buf path_to_bootstrap_src = BUF_INIT;1657 Buf path_to_bootstrap_src = BUF_INIT;
...@@ -1788,6 +1806,22 @@ static void generate_h_file(CodeGen *g) {...@@ -1788,6 +1806,22 @@ static void generate_h_file(CodeGen *g) {
1788 zig_panic("unable to close h file: %s", strerror(errno));1806 zig_panic("unable to close h file: %s", strerror(errno));
1789}1807}
17901808
1809static void find_libc_path(CodeGen *g) {
1810 if (g->libc_path && buf_len(g->libc_path))
1811 return;
1812 g->libc_path = buf_create_from_str(ZIG_LIBC_DIR);
1813 if (g->libc_path && buf_len(g->libc_path))
1814 return;
1815 fprintf(stderr, "Unable to determine libc path. Consider using `--libc-path [path]`\n");
1816 exit(1);
1817}
1818
1819static const char *get_libc_file(CodeGen *g, const char *file) {
1820 Buf *out_buf = buf_alloc();
1821 os_path_join(g->libc_path, buf_create_from_str(file), out_buf);
1822 return buf_ptr(out_buf);
1823}
1824
1791void codegen_link(CodeGen *g, const char *out_file) {1825void codegen_link(CodeGen *g, const char *out_file) {
1792 bool is_optimized = (g->build_type == CodeGenBuildTypeRelease);1826 bool is_optimized = (g->build_type == CodeGenBuildTypeRelease);
1793 if (is_optimized) {1827 if (is_optimized) {
...@@ -1826,6 +1860,9 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -1826,6 +1860,9 @@ void codegen_link(CodeGen *g, const char *out_file) {
1826 }1860 }
18271861
1828 if (g->out_type == OutTypeObj) {1862 if (g->out_type == OutTypeObj) {
1863 if (g->verbose) {
1864 fprintf(stderr, "OK\n");
1865 }
1829 return;1866 return;
1830 }1867 }
18311868
...@@ -1840,8 +1877,12 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -1840,8 +1877,12 @@ void codegen_link(CodeGen *g, const char *out_file) {
18401877
1841 // invoke `ld`1878 // invoke `ld`
1842 ZigList<const char *> args = {0};1879 ZigList<const char *> args = {0};
1880 const char *crt1o;
1843 if (g->is_static) {1881 if (g->is_static) {
1844 args.append("-static");1882 args.append("-static");
1883 crt1o = "crt1.o";
1884 } else {
1885 crt1o = "Scrt1.o";
1845 }1886 }
18461887
1847 char *ZIG_NATIVE_DYNAMIC_LINKER = getenv("ZIG_NATIVE_DYNAMIC_LINKER");1888 char *ZIG_NATIVE_DYNAMIC_LINKER = getenv("ZIG_NATIVE_DYNAMIC_LINKER");
...@@ -1868,8 +1909,21 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -1868,8 +1909,21 @@ void codegen_link(CodeGen *g, const char *out_file) {
1868 args.append("-o");1909 args.append("-o");
1869 args.append(out_file);1910 args.append(out_file);
18701911
1912 bool link_in_crt = (g->link_libc && g->out_type == OutTypeExe);
1913
1914 if (link_in_crt) {
1915 find_libc_path(g);
1916
1917 args.append(get_libc_file(g, crt1o));
1918 args.append(get_libc_file(g, "crti.o"));
1919 }
1920
1871 args.append((const char *)buf_ptr(&out_file_o));1921 args.append((const char *)buf_ptr(&out_file_o));
18721922
1923 if (link_in_crt) {
1924 args.append(get_libc_file(g, "crtn.o"));
1925 }
1926
1873 auto it = g->link_table.entry_iterator();1927 auto it = g->link_table.entry_iterator();
1874 for (;;) {1928 for (;;) {
1875 auto *entry = it.next();1929 auto *entry = it.next();
...@@ -1880,7 +1934,24 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -1880,7 +1934,24 @@ void codegen_link(CodeGen *g, const char *out_file) {
1880 args.append(buf_ptr(arg));1934 args.append(buf_ptr(arg));
1881 }1935 }
18821936
1883 os_spawn_process("ld", args, false);1937 if (g->verbose) {
1938 fprintf(stderr, "ld");
1939 for (int i = 0; i < args.length; i += 1) {
1940 fprintf(stderr, " %s", args.at(i));
1941 }
1942 fprintf(stderr, "\n");
1943 }
1944
1945 int return_code;
1946 Buf ld_stderr = BUF_INIT;
1947 Buf ld_stdout = BUF_INIT;
1948 os_exec_process("ld", args, &return_code, &ld_stderr, &ld_stdout);
1949
1950 if (return_code != 0) {
1951 fprintf(stderr, "ld failed with return code %d\n", return_code);
1952 fprintf(stderr, "%s\n", buf_ptr(&ld_stderr));
1953 exit(1);
1954 }
18841955
1885 if (g->out_type == OutTypeLib) {1956 if (g->out_type == OutTypeLib) {
1886 generate_h_file(g);1957 generate_h_file(g);
src/codegen.hpp+1
...@@ -33,6 +33,7 @@ void codegen_set_verbose(CodeGen *codegen, bool verbose);...@@ -33,6 +33,7 @@ void codegen_set_verbose(CodeGen *codegen, bool verbose);
33void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);33void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
34void codegen_set_out_type(CodeGen *codegen, OutType out_type);34void codegen_set_out_type(CodeGen *codegen, OutType out_type);
35void codegen_set_out_name(CodeGen *codegen, Buf *out_name);35void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
36void codegen_set_libc_path(CodeGen *codegen, Buf *libc_path);
3637
37void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);38void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
3839
src/config.h.in+1
...@@ -8,5 +8,6 @@...@@ -8,5 +8,6 @@
88
9#define ZIG_HEADERS_DIR "@CMAKE_INSTALL_PREFIX@/@C_HEADERS_DEST@"9#define ZIG_HEADERS_DIR "@CMAKE_INSTALL_PREFIX@/@C_HEADERS_DEST@"
10#define ZIG_STD_DIR "@CMAKE_INSTALL_PREFIX@/@ZIG_STD_DEST@"10#define ZIG_STD_DIR "@CMAKE_INSTALL_PREFIX@/@ZIG_STD_DEST@"
11#define ZIG_LIBC_DIR "@ZIG_LIBC_DIR@"
1112
12#endif13#endif
src/main.cpp+6
...@@ -29,6 +29,7 @@ static int usage(const char *arg0) {...@@ -29,6 +29,7 @@ static int usage(const char *arg0) {
29 " --output [file] override destination path\n"29 " --output [file] override destination path\n"
30 " --verbose turn on compiler debug output\n"30 " --verbose turn on compiler debug output\n"
31 " --color [auto|off|on] enable or disable colored error messages\n"31 " --color [auto|off|on] enable or disable colored error messages\n"
32 " --libc-path [path] set the C compiler data path\n"
32 "Command: parseh target\n"33 "Command: parseh target\n"
33 " -isystem [dir] add additional search path for other .h files\n"34 " -isystem [dir] add additional search path for other .h files\n"
34 " -dirafter [dir] same as -isystem but do it last\n"35 " -dirafter [dir] same as -isystem but do it last\n"
...@@ -52,6 +53,7 @@ struct Build {...@@ -52,6 +53,7 @@ struct Build {
52 const char *out_name;53 const char *out_name;
53 bool verbose;54 bool verbose;
54 ErrColor color;55 ErrColor color;
56 const char *libc_path;
55};57};
5658
57static int build(const char *arg0, int argc, char **argv) {59static int build(const char *arg0, int argc, char **argv) {
...@@ -99,6 +101,8 @@ static int build(const char *arg0, int argc, char **argv) {...@@ -99,6 +101,8 @@ static int build(const char *arg0, int argc, char **argv) {
99 }101 }
100 } else if (strcmp(arg, "--name") == 0) {102 } else if (strcmp(arg, "--name") == 0) {
101 b.out_name = argv[i];103 b.out_name = argv[i];
104 } else if (strcmp(arg, "--libc-path") == 0) {
105 b.libc_path = argv[i];
102 } else {106 } else {
103 return usage(arg0);107 return usage(arg0);
104 }108 }
...@@ -142,6 +146,8 @@ static int build(const char *arg0, int argc, char **argv) {...@@ -142,6 +146,8 @@ static int build(const char *arg0, int argc, char **argv) {
142 codegen_set_out_type(g, b.out_type);146 codegen_set_out_type(g, b.out_type);
143 if (b.out_name)147 if (b.out_name)
144 codegen_set_out_name(g, buf_create_from_str(b.out_name));148 codegen_set_out_name(g, buf_create_from_str(b.out_name));
149 if (b.libc_path)
150 codegen_set_libc_path(g, buf_create_from_str(b.libc_path));
145 codegen_set_verbose(g, b.verbose);151 codegen_set_verbose(g, b.verbose);
146 codegen_set_errmsg_color(g, b.color);152 codegen_set_errmsg_color(g, b.color);
147 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);153 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);
src/os.cpp+3-1
...@@ -77,7 +77,9 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) {...@@ -77,7 +77,9 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) {
7777
78void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {78void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
79 buf_init_from_buf(out_full_path, dirname);79 buf_init_from_buf(out_full_path, dirname);
80 buf_append_char(out_full_path, '/');80 uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);
81 if (c != '/')
82 buf_append_char(out_full_path, '/');
81 buf_append_buf(out_full_path, basename);83 buf_append_buf(out_full_path, basename);
82}84}
8385
test/run_tests.cpp+57-103
...@@ -100,43 +100,34 @@ static void add_compiling_test_cases(void) {...@@ -100,43 +100,34 @@ static void add_compiling_test_cases(void) {
100 #link("c")100 #link("c")
101 extern {101 extern {
102 fn puts(s: &const u8) -> i32;102 fn puts(s: &const u8) -> i32;
103 fn exit(code: i32) -> unreachable;
104 }103 }
105104
106 export fn _start() -> unreachable {105 export fn main(argc: i32, argv: &&u8, env: &&u8) -> i32 {
107 puts(c"Hello, world!");106 puts(c"Hello, world!");
108 exit(0);107 return 0;
109 }108 }
110 )SOURCE", "Hello, world!\n");109 )SOURCE", "Hello, world!\n");
111110
112 add_simple_case("function call", R"SOURCE(111 add_simple_case("function call", R"SOURCE(
113 #link("c")112 use "std.zig";
114 extern {
115 fn puts(s: &const u8) -> i32;
116 fn exit(code: i32) -> unreachable;
117 }
118113
119 fn empty_function_1() {}114 fn empty_function_1() {}
120 fn empty_function_2() { return; }115 fn empty_function_2() { return; }
121116
122 export fn _start() -> unreachable {117 pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
123 empty_function_1();118 empty_function_1();
124 empty_function_2();119 empty_function_2();
125 this_is_a_function();120 this_is_a_function();
126 }121 }
127122
128 fn this_is_a_function() -> unreachable {123 fn this_is_a_function() -> unreachable {
129 puts(c"OK");124 print_str("OK\n" as string);
130 exit(0);125 exit(0);
131 }126 }
132 )SOURCE", "OK\n");127 )SOURCE", "OK\n");
133128
134 add_simple_case("comments", R"SOURCE(129 add_simple_case("comments", R"SOURCE(
135 #link("c")130 use "std.zig";
136 extern {
137 fn puts(s: &const u8) -> i32;
138 fn exit(code: i32) -> unreachable;
139 }
140131
141 /**132 /**
142 * multi line doc comment133 * multi line doc comment
...@@ -145,9 +136,9 @@ static void add_compiling_test_cases(void) {...@@ -145,9 +136,9 @@ static void add_compiling_test_cases(void) {
145136
146 /// this is a documentation comment137 /// this is a documentation comment
147 /// doc comment line 2138 /// doc comment line 2
148 export fn _start() -> unreachable {139 pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
149 puts(/* mid-line comment /* nested */ */ c"OK");140 print_str(/* mid-line comment /* nested */ */ "OK\n" as string);
150 exit(0);141 return 0;
151 }142 }
152 )SOURCE", "OK\n");143 )SOURCE", "OK\n");
153144
...@@ -156,7 +147,7 @@ static void add_compiling_test_cases(void) {...@@ -156,7 +147,7 @@ static void add_compiling_test_cases(void) {
156 use "libc.zig";147 use "libc.zig";
157 use "foo.zig";148 use "foo.zig";
158149
159 export fn _start() -> unreachable {150 export fn main(argc: i32, argv: &&u8, env: &&u8) -> i32 {
160 private_function();151 private_function();
161 }152 }
162153
...@@ -190,180 +181,144 @@ static void add_compiling_test_cases(void) {...@@ -190,180 +181,144 @@ static void add_compiling_test_cases(void) {
190 }181 }
191182
192 add_simple_case("if statements", R"SOURCE(183 add_simple_case("if statements", R"SOURCE(
193 #link("c")184 use "std.zig";
194 extern {
195 fn puts(s: &const u8) -> i32;
196 fn exit(code: i32) -> unreachable;
197 }
198185
199 export fn _start() -> unreachable {186 pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
200 if 1 != 0 {187 if 1 != 0 {
201 puts(c"1 is true");188 print_str("1 is true\n" as string);
202 } else {189 } else {
203 puts(c"1 is false");190 print_str("1 is false\n" as string);
204 }191 }
205 if 0 != 0 {192 if 0 != 0 {
206 puts(c"0 is true");193 print_str("0 is true\n" as string);
207 } else if 1 - 1 != 0 {194 } else if 1 - 1 != 0 {
208 puts(c"1 - 1 is true");195 print_str("1 - 1 is true\n" as string);
209 }196 }
210 if !(0 != 0) {197 if !(0 != 0) {
211 puts(c"!0 is true");198 print_str("!0 is true\n" as string);
212 }199 }
213 exit(0);200 return 0;
214 }201 }
215 )SOURCE", "1 is true\n!0 is true\n");202 )SOURCE", "1 is true\n!0 is true\n");
216203
217 add_simple_case("params", R"SOURCE(204 add_simple_case("params", R"SOURCE(
218 #link("c")205 use "std.zig";
219 extern {
220 fn puts(s: &const u8) -> i32;
221 fn exit(code: i32) -> unreachable;
222 }
223206
224 fn add(a: i32, b: i32) -> i32 {207 fn add(a: i32, b: i32) -> i32 {
225 a + b208 a + b
226 }209 }
227210
228 export fn _start() -> unreachable {211 pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
229 if add(22, 11) == 33 {212 if add(22, 11) == 33 {
230 puts(c"pass");213 print_str("pass\n" as string);
231 }214 }
232 exit(0);215 return 0;
233 }216 }
234 )SOURCE", "pass\n");217 )SOURCE", "pass\n");
235218
236 add_simple_case("goto", R"SOURCE(219 add_simple_case("goto", R"SOURCE(
237 #link("c")220 use "std.zig";
238 extern {
239 fn puts(s: &const u8) -> i32;
240 fn exit(code: i32) -> unreachable;
241 }
242221
243 fn loop(a : i32) {222 fn loop(a : i32) {
244 if a == 0 {223 if a == 0 {
245 goto done;224 goto done;
246 }225 }
247 puts(c"loop");226 print_str("loop\n" as string);
248 loop(a - 1);227 loop(a - 1);
249228
250 done:229 done:
251 return;230 return;
252 }231 }
253232
254 export fn _start() -> unreachable {233 pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
255 loop(3);234 loop(3);
256 exit(0);235 return 0;
257 }236 }
258 )SOURCE", "loop\nloop\nloop\n");237 )SOURCE", "loop\nloop\nloop\n");
259238
260 add_simple_case("local variables", R"SOURCE(239 add_simple_case("local variables", R"SOURCE(
261#link("c")240use "std.zig";
262extern {
263 fn puts(s: &const u8) -> i32;
264 fn exit(code: i32) -> unreachable;
265}
266241
267export fn _start() -> unreachable {242pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
268 const a : i32 = 1;243 const a : i32 = 1;
269 const b = 2 as i32;244 const b = 2 as i32;
270 if (a + b == 3) {245 if (a + b == 3) {
271 puts(c"OK");246 print_str("OK\n" as string);
272 }247 }
273 exit(0);248 return 0;
274}249}
275 )SOURCE", "OK\n");250 )SOURCE", "OK\n");
276251
277 add_simple_case("bool literals", R"SOURCE(252 add_simple_case("bool literals", R"SOURCE(
278#link("c")253use "std.zig";
279extern {
280 fn puts(s: &const u8) -> i32;
281 fn exit(code: i32) -> unreachable;
282}
283254
284export fn _start() -> unreachable {255pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
285 if (true) { puts(c"OK 1"); }256 if (true) { print_str("OK 1\n" as string); }
286 if (false) { puts(c"BAD 1"); }257 if (false) { print_str("BAD 1\n" as string); }
287 if (!true) { puts(c"BAD 2"); }258 if (!true) { print_str("BAD 2\n" as string); }
288 if (!false) { puts(c"OK 2"); }259 if (!false) { print_str("OK 2\n" as string); }
289 exit(0);260 return 0;
290}261}
291 )SOURCE", "OK 1\nOK 2\n");262 )SOURCE", "OK 1\nOK 2\n");
292263
293 add_simple_case("separate block scopes", R"SOURCE(264 add_simple_case("separate block scopes", R"SOURCE(
294#link("c")265use "std.zig";
295extern {
296 fn puts(s: &const u8) -> i32;
297 fn exit(code: i32) -> unreachable;
298}
299266
300export fn _start() -> unreachable {267pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
301 if (true) {268 if (true) {
302 const no_conflict : i32 = 5;269 const no_conflict : i32 = 5;
303 if (no_conflict == 5) { puts(c"OK 1"); }270 if (no_conflict == 5) { print_str("OK 1\n" as string); }
304 }271 }
305272
306 const c = {273 const c = {
307 const no_conflict = 10 as i32;274 const no_conflict = 10 as i32;
308 no_conflict275 no_conflict
309 };276 };
310 if (c == 10) { puts(c"OK 2"); }277 if (c == 10) { print_str("OK 2\n" as string); }
311 exit(0);278 return 0;
312}279}
313 )SOURCE", "OK 1\nOK 2\n");280 )SOURCE", "OK 1\nOK 2\n");
314281
315 add_simple_case("void parameters", R"SOURCE(282 add_simple_case("void parameters", R"SOURCE(
316#link("c")283use "std.zig";
317extern {
318 fn puts(s: &const u8) -> i32;
319 fn exit(code: i32) -> unreachable;
320}
321284
322export fn _start() -> unreachable {285pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
323 void_fun(1, void, 2);286 void_fun(1, void, 2);
324 exit(0);287 return 0;
325}288}
326289
327fn void_fun(a : i32, b : void, c : i32) {290fn void_fun(a : i32, b : void, c : i32) {
328 const v = b;291 const v = b;
329 const vv : void = if (a == 1) {v} else {};292 const vv : void = if (a == 1) {v} else {};
330 if (a + c == 3) { puts(c"OK"); }293 if (a + c == 3) { print_str("OK\n" as string); }
331 return vv;294 return vv;
332}295}
333 )SOURCE", "OK\n");296 )SOURCE", "OK\n");
334297
335 add_simple_case("mutable local variables", R"SOURCE(298 add_simple_case("mutable local variables", R"SOURCE(
336#link("c")299use "std.zig";
337extern {
338 fn puts(s: &const u8) -> i32;
339 fn exit(code: i32) -> unreachable;
340}
341300
342export fn _start() -> unreachable {301pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
343 var zero : i32;302 var zero : i32;
344 if (zero == 0) { puts(c"zero"); }303 if (zero == 0) { print_str("zero\n" as string); }
345304
346 var i = 0 as i32;305 var i = 0 as i32;
347loop_start:306loop_start:
348 if i == 3 {307 if i == 3 {
349 goto done;308 goto done;
350 }309 }
351 puts(c"loop");310 print_str("loop\n" as string);
352 i = i + 1;311 i = i + 1;
353 goto loop_start;312 goto loop_start;
354done:313done:
355 exit(0);314 return 0;
356}315}
357 )SOURCE", "zero\nloop\nloop\nloop\n");316 )SOURCE", "zero\nloop\nloop\nloop\n");
358317
359 add_simple_case("arrays", R"SOURCE(318 add_simple_case("arrays", R"SOURCE(
360#link("c")319use "std.zig";
361extern {
362 fn puts(s: &const u8) -> i32;
363 fn exit(code: i32) -> unreachable;
364}
365320
366export fn _start() -> unreachable {321pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
367 var array : [i32; 5];322 var array : [i32; 5];
368323
369 var i : i32 = 0;324 var i : i32 = 0;
...@@ -391,10 +346,10 @@ loop_2_start:...@@ -391,10 +346,10 @@ loop_2_start:
391loop_2_end:346loop_2_end:
392347
393 if accumulator == 15 {348 if accumulator == 15 {
394 puts(c"OK");349 print_str("OK\n" as string);
395 }350 }
396351
397 exit(0);352 return 0;
398}353}
399 )SOURCE", "OK\n");354 )SOURCE", "OK\n");
400355
...@@ -481,12 +436,11 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {...@@ -481,12 +436,11 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
481#link("c")436#link("c")
482extern {437extern {
483 fn printf(__format: &const u8, ...) -> i32;438 fn printf(__format: &const u8, ...) -> i32;
484 fn exit(__status: i32) -> unreachable;
485}439}
486440
487export fn _start() -> unreachable {441export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
488 printf(c"0=%d\n", 0 as i32); // TODO: more tests442 printf(c"0=%d\n", 0 as i32); // TODO: more tests
489 exit(0);443 return 0;
490}444}
491 )SOURCE", "0=0\n");445 )SOURCE", "0=0\n");
492446