authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-08 13:13:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-08 16:21:30-07:00
log5dbc21b511790ff6bfbd8f597e2a8eb875142299
treead3b1771e21b7ffcd4629dc5d765ef704f6a7438
parentf6edba4a872e2c5781bb6cb05f66a57e16455f15

update cat example, refactor std

partial implementation of @err_name

12 files changed, 398 insertions(+), 302 deletions(-)

CMakeLists.txt+2
...@@ -198,6 +198,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/errno.zig" DESTINATION "${ZIG_STD_DEST}")...@@ -198,6 +198,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/errno.zig" DESTINATION "${ZIG_STD_DEST}")
198install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")198install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
199install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")199install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")
200install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}")200install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}")
201install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}")
202install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}")
201203
202add_executable(run_tests ${TEST_SOURCES})204add_executable(run_tests ${TEST_SOURCES})
203target_link_libraries(run_tests)205target_link_libraries(run_tests)
example/cat/main.zig+24-21
...@@ -1,58 +1,61 @@...@@ -1,58 +1,61 @@
1export executable "cat";1use @import("std");
22
3import "std.zig";3// TODO var args printing
4
5// Things to do to make this work:
6// * var args printing
7// * cast err type to string
8// * string equality
94
10pub fn main(args: [][]u8) -> %void {5pub fn main(args: [][]u8) -> %void {
11 const exe = args[0];6 const exe = args[0];
12 var catted_anything = false;7 var catted_anything = false;
13 for (arg, args[1...]) {8 for (args[1...]) |arg| {
14 if (arg == "-") {9 if (str_eql(arg, "-")) {
15 catted_anything = true;10 catted_anything = true;
16 cat_stream(stdin) %% |err| return err;11 cat_stream(io.stdin) %% |err| return err;
17 } else if (arg[0] == '-') {12 } else if (arg[0] == '-') {
18 return usage(exe);13 return usage(exe);
19 } else {14 } else {
20 var is = input_stream_open(arg, OpenReadOnly) %% |err| {15 var is = io.InStream.open(arg) %% |err| {
21 %%stderr.print("Unable to open file: {}", ([]u8)(err));16 %%io.stderr.write("Unable to open file: ");
17 %%io.stderr.write(@err_name(err));
18 %%io.stderr.write("\n");
22 return err;19 return err;
23 };20 };
24 defer is.close();21 defer %%is.close();
2522
26 catted_anything = true;23 catted_anything = true;
27 cat_stream(is) %% |err| return err;24 cat_stream(is) %% |err| return err;
28 }25 }
29 }26 }
30 if (!catted_anything) {27 if (!catted_anything) {
31 cat_stream(stdin) %% |err| return err;28 cat_stream(io.stdin) %% |err| return err;
32 }29 }
33}30}
3431
35fn usage(exe: []u8) -> %void {32fn usage(exe: []u8) -> %void {
36 %%stderr.print("Usage: {} [FILE]...\n", exe);33 %%io.stderr.write("Usage: ");
34 %%io.stderr.write(exe);
35 %%io.stderr.write(" [FILE]...\n");
37 return error.Invalid;36 return error.Invalid;
38}37}
3938
40fn cat_stream(is: InputStream) -> %void {39fn cat_stream(is: io.InStream) -> %void {
41 var buf: [1024 * 4]u8 = undefined;40 var buf: [1024 * 4]u8 = undefined;
4241
43 while (true) {42 while (true) {
44 const bytes_read = is.read(buf) %% |err| {43 const bytes_read = is.read(buf) %% |err| {
45 %%stderr.print("Unable to read from stream: {}", ([]u8)(err));44 %%io.stderr.write("Unable to read from stream: ");
45 %%io.stderr.write(@err_name(err));
46 %%io.stderr.write("\n");
46 return err;47 return err;
47 }48 };
4849
49 if (bytes_read == 0) {50 if (bytes_read == 0) {
50 break;51 break;
51 }52 }
5253
53 stdout.write(buf[0...bytes_read]) %% |err| {54 io.stdout.write(buf[0...bytes_read]) %% |err| {
54 %%stderr.print("Unable to write to stdout: {}", ([]u8)(err));55 %%io.stderr.write("Unable to write to stdout: ");
56 %%io.stderr.write(@err_name(err));
57 %%io.stderr.write("\n");
55 return err;58 return err;
56 }59 };
57 }60 }
58}61}
src/all_types.hpp+4-1
...@@ -1044,6 +1044,7 @@ enum BuiltinFnId {...@@ -1044,6 +1044,7 @@ enum BuiltinFnId {
1044 BuiltinFnIdClz,1044 BuiltinFnIdClz,
1045 BuiltinFnIdImport,1045 BuiltinFnIdImport,
1046 BuiltinFnIdCImport,1046 BuiltinFnIdCImport,
1047 BuiltinFnIdErrName,
1047};1048};
10481049
1049struct BuiltinFnEntry {1050struct BuiltinFnEntry {
...@@ -1177,7 +1178,7 @@ struct CodeGen {...@@ -1177,7 +1178,7 @@ struct CodeGen {
1177 LLVMValueRef trap_fn_val;1178 LLVMValueRef trap_fn_val;
1178 bool error_during_imports;1179 bool error_during_imports;
1179 uint32_t next_node_index;1180 uint32_t next_node_index;
1180 uint32_t error_value_count;1181 ZigList<AstNode *> error_decls;
1181 TypeTableEntry *err_tag_type;1182 TypeTableEntry *err_tag_type;
1182 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]1183 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
1183 LLVMValueRef int_builtin_fns[2][4]; // [0-ctz,1-clz][0-8,1-16,2-32,3-64]1184 LLVMValueRef int_builtin_fns[2][4]; // [0-ctz,1-clz][0-8,1-16,2-32,3-64]
...@@ -1189,6 +1190,8 @@ struct CodeGen {...@@ -1189,6 +1190,8 @@ struct CodeGen {
1189 uint32_t test_fn_count;1190 uint32_t test_fn_count;
11901191
1191 bool check_unused;1192 bool check_unused;
1193
1194 bool generate_error_name_table;
1192};1195};
11931196
1194struct VariableTableEntry {1197struct VariableTableEntry {
src/analyze.cpp+26-5
...@@ -1415,9 +1415,10 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {...@@ -1415,9 +1415,10 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1415 // duplicate error definitions allowed and they get the same value1415 // duplicate error definitions allowed and they get the same value
1416 err->value = existing_entry->value->value;1416 err->value = existing_entry->value->value;
1417 } else {1417 } else {
1418 assert(g->error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count));1418 int error_value_count = g->error_decls.length;
1419 err->value = g->error_value_count;1419 assert(error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count));
1420 g->error_value_count += 1;1420 err->value = error_value_count;
1421 g->error_decls.append(node);
1421 g->error_table.put(&err->name, err);1422 g->error_table.put(&err->name, err);
1422 }1423 }
14231424
...@@ -4084,7 +4085,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -4084,7 +4085,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
4084 wanted_type->id == TypeTableEntryIdInt)4085 wanted_type->id == TypeTableEntryIdInt)
4085 {4086 {
4086 BigNum bn;4087 BigNum bn;
4087 bignum_init_unsigned(&bn, g->error_value_count);4088 bignum_init_unsigned(&bn, g->error_decls.length);
4088 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,4089 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
4089 wanted_type->data.integral.is_signed))4090 wanted_type->data.integral.is_signed))
4090 {4091 {
...@@ -4242,6 +4243,25 @@ static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_imp...@@ -4242,6 +4243,25 @@ static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_imp
4242 return resolve_expr_const_val_as_import(g, node, child_import);4243 return resolve_expr_const_val_as_import(g, node, child_import);
4243}4244}
42444245
4246static TypeTableEntry *analyze_err_name(CodeGen *g, ImportTableEntry *import,
4247 BlockContext *context, AstNode *node)
4248{
4249 assert(node->type == NodeTypeFnCallExpr);
4250
4251 AstNode *err_value = node->data.fn_call_expr.params.at(0);
4252 TypeTableEntry *resolved_type = analyze_expression(g, import, context,
4253 g->builtin_types.entry_pure_error, err_value);
4254
4255 if (resolved_type->id == TypeTableEntryIdInvalid) {
4256 return resolved_type;
4257 }
4258
4259 g->generate_error_name_table = true;
4260
4261 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
4262 return str_type;
4263}
4264
4245static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,4265static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4246 TypeTableEntry *expected_type, AstNode *node)4266 TypeTableEntry *expected_type, AstNode *node)
4247{4267{
...@@ -4570,7 +4590,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -4570,7 +4590,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
4570 return analyze_import(g, import, context, node);4590 return analyze_import(g, import, context, node);
4571 case BuiltinFnIdCImport:4591 case BuiltinFnIdCImport:
4572 return analyze_c_import(g, import, context, node);4592 return analyze_c_import(g, import, context, node);
45734593 case BuiltinFnIdErrName:
4594 return analyze_err_name(g, import, context, node);
4574 }4595 }
4575 zig_unreachable();4596 zig_unreachable();
4576}4597}
src/codegen.cpp+14-1
...@@ -65,7 +65,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -65,7 +65,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
65 g->generic_table.init(16);65 g->generic_table.init(16);
66 g->is_release_build = false;66 g->is_release_build = false;
67 g->is_test_build = false;67 g->is_test_build = false;
68 g->error_value_count = 1;68
69 // the error.Ok value
70 g->error_decls.append(nullptr);
6971
70 g->root_package = new_package(buf_ptr(root_source_dir), "");72 g->root_package = new_package(buf_ptr(root_source_dir), "");
71 g->std_package = new_package(ZIG_STD_DIR, "index.zig");73 g->std_package = new_package(ZIG_STD_DIR, "index.zig");
...@@ -328,6 +330,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValue...@@ -328,6 +330,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValue
328 }330 }
329}331}
330332
333static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) {
334 zig_panic("TODO");
335 //assert(node->type == NodeTypeFnCallExpr);
336 //AstNode *err_val_node = node->data.fn_call_expr.params.at(0);
337 //LLVMValueRef err_val = gen_expr(g, err_val_node);
338 //arg
339}
340
331static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {341static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
332 assert(node->type == NodeTypeFnCallExpr);342 assert(node->type == NodeTypeFnCallExpr);
333 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;343 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
...@@ -467,6 +477,8 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -467,6 +477,8 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
467 zig_unreachable();477 zig_unreachable();
468 case BuiltinFnIdCompileVar:478 case BuiltinFnIdCompileVar:
469 return nullptr;479 return nullptr;
480 case BuiltinFnIdErrName:
481 return gen_err_name(g, node);
470 }482 }
471 zig_unreachable();483 zig_unreachable();
472}484}
...@@ -3739,6 +3751,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -3739,6 +3751,7 @@ static void define_builtin_fns(CodeGen *g) {
3739 create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2);3751 create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2);
3740 create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1);3752 create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1);
3741 create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1);3753 create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1);
3754 create_builtin_fn_with_arg_count(g, BuiltinFnIdErrName, "err_name", 1);
3742}3755}
37433756
3744static void init(CodeGen *g, Buf *source_path) {3757static void init(CodeGen *g, Buf *source_path) {
std/index.zig+21
...@@ -2,3 +2,24 @@ pub const Rand = @import("rand.zig").Rand;...@@ -2,3 +2,24 @@ pub const Rand = @import("rand.zig").Rand;
2pub const io = @import("io.zig");2pub const io = @import("io.zig");
3pub const os = @import("os.zig");3pub const os = @import("os.zig");
4pub const math = @import("math.zig");4pub const math = @import("math.zig");
5
6pub fn assert(b: bool) {
7 if (!b) unreachable{}
8}
9
10pub const str_eql = slice_eql(u8);
11
12pub fn slice_eql(T: type)(a: []T, b: []T) -> bool {
13 if (a.len != b.len) return false;
14 for (a) |item, index| {
15 if (b[index] != item) return false;
16 }
17 return true;
18}
19
20#attribute("test")
21fn string_equality() {
22 assert(str_eql("abcd", "abcd"));
23 assert(!str_eql("abcdef", "abZdef"));
24 assert(!str_eql("abcdefg", "abcdef"));
25}
std/io.zig+47-6
...@@ -39,37 +39,51 @@ pub error NoSpaceLeft;...@@ -39,37 +39,51 @@ pub error NoSpaceLeft;
39pub error BadPerm;39pub error BadPerm;
40pub error PipeFail;40pub error PipeFail;
41pub error BadFd;41pub error BadFd;
42pub error IsDir;
43pub error NotDir;
44pub error SymLinkLoop;
45pub error ProcessFdQuotaExceeded;
46pub error SystemFdQuotaExceeded;
47pub error NameTooLong;
48pub error NoDevice;
49pub error PathNotFound;
50pub error NoMem;
4251
43const buffer_size = 4 * 1024;52const buffer_size = 4 * 1024;
44const max_u64_base10_digits = 20;53const max_u64_base10_digits = 20;
45const max_f64_digits = 65;54const max_f64_digits = 65;
4655
56pub const OpenRead = 0b0001;
57pub const OpenWrite = 0b0010;
58pub const OpenCreate = 0b0100;
59pub const OpenTruncate = 0b1000;
60
47pub struct OutStream {61pub struct OutStream {
48 fd: isize,62 fd: isize,
49 buffer: [buffer_size]u8,63 buffer: [buffer_size]u8,
50 index: isize,64 index: isize,
5165
52 pub fn print_str(os: &OutStream, str: []const u8) -> %isize {66 pub fn write(os: &OutStream, bytes: []const u8) -> %isize {
53 var src_bytes_left = str.len;67 var src_bytes_left = bytes.len;
54 var src_index: @typeof(str.len) = 0;68 var src_index: @typeof(bytes.len) = 0;
55 const dest_space_left = os.buffer.len - os.index;69 const dest_space_left = os.buffer.len - os.index;
5670
57 while (src_bytes_left > 0) {71 while (src_bytes_left > 0) {
58 const copy_amt = math.min_isize(dest_space_left, src_bytes_left);72 const copy_amt = math.min_isize(dest_space_left, src_bytes_left);
59 @memcpy(&os.buffer[os.index], &str[src_index], copy_amt);73 @memcpy(&os.buffer[os.index], &bytes[src_index], copy_amt);
60 os.index += copy_amt;74 os.index += copy_amt;
61 if (os.index == os.buffer.len) {75 if (os.index == os.buffer.len) {
62 %return os.flush();76 %return os.flush();
63 }77 }
64 src_bytes_left -= copy_amt;78 src_bytes_left -= copy_amt;
65 }79 }
66 return str.len;80 return bytes.len;
67 }81 }
6882
69 /// Prints a byte buffer, flushes the buffer, then returns the number of83 /// Prints a byte buffer, flushes the buffer, then returns the number of
70 /// bytes printed. The "f" is for "flush".84 /// bytes printed. The "f" is for "flush".
71 pub fn printf(os: &OutStream, str: []const u8) -> %isize {85 pub fn printf(os: &OutStream, str: []const u8) -> %isize {
72 const byte_count = %return os.print_str(str);86 const byte_count = %return os.write(str);
73 %return os.flush();87 %return os.flush();
74 return byte_count;88 return byte_count;
75 }89 }
...@@ -138,6 +152,33 @@ pub struct OutStream {...@@ -138,6 +152,33 @@ pub struct OutStream {
138pub struct InStream {152pub struct InStream {
139 fd: isize,153 fd: isize,
140154
155 pub fn open(path: []u8) -> %InStream {
156 const fd = linux.open(path, linux.O_LARGEFILE|linux.O_RDONLY, 0);
157 if (fd < 0) {
158 return switch (-fd) {
159 errno.EFAULT => unreachable{},
160 errno.EINVAL => unreachable{},
161 errno.EACCES => error.BadPerm,
162 errno.EFBIG, errno.EOVERFLOW => error.FileTooBig,
163 errno.EINTR => error.SigInterrupt,
164 errno.EISDIR => error.IsDir,
165 errno.ELOOP => error.SymLinkLoop,
166 errno.EMFILE => error.ProcessFdQuotaExceeded,
167 errno.ENAMETOOLONG => error.NameTooLong,
168 errno.ENFILE => error.SystemFdQuotaExceeded,
169 errno.ENODEV => error.NoDevice,
170 errno.ENOENT => error.PathNotFound,
171 errno.ENOMEM => error.NoMem,
172 errno.ENOSPC => error.NoSpaceLeft,
173 errno.ENOTDIR => error.NotDir,
174 errno.EPERM => error.BadPerm,
175 else => error.Unexpected,
176 }
177 }
178
179 return InStream { .fd = fd, };
180 }
181
141 pub fn read(is: &InStream, buf: []u8) -> %isize {182 pub fn read(is: &InStream, buf: []u8) -> %isize {
142 const amt_read = linux.read(is.fd, &buf[0], buf.len);183 const amt_read = linux.read(is.fd, &buf[0], buf.len);
143 if (amt_read < 0) {184 if (amt_read < 0) {
std/linux.zig+45-250
...@@ -1,86 +1,6 @@...@@ -1,86 +1,6 @@
1const SYS_read = switch (@compile_var("arch")) {1const arch = switch (@compile_var("arch")) {
2 x86_64 => 0,2 x86_64 => @import("linux_x86_64.zig"),
3 i386 => 3,3 i386 => @import("linux_i386.zig"),
4 else => unreachable{},
5};
6const SYS_write = switch (@compile_var("arch")) {
7 x86_64 => 1,
8 i386 => 4,
9 else => unreachable{},
10};
11const SYS_open = switch (@compile_var("arch")) {
12 x86_64 => 2,
13 i386 => 5,
14 else => unreachable{},
15};
16const SYS_close = switch (@compile_var("arch")) {
17 x86_64 => 3,
18 i386 => 6,
19 else => unreachable{},
20};
21const SYS_creat = switch (@compile_var("arch")) {
22 x86_64 => 85,
23 i386 => 8,
24 else => unreachable{},
25};
26const SYS_lseek = switch (@compile_var("arch")) {
27 x86_64 => 8,
28 i386 => 19,
29 else => unreachable{},
30};
31const SYS_mmap = switch (@compile_var("arch")) {
32 x86_64 => 9,
33 i386 => 90,
34 else => unreachable{},
35};
36const SYS_munmap = switch (@compile_var("arch")) {
37 x86_64 => 11,
38 i386 => 91,
39 else => unreachable{},
40};
41const SYS_rt_sigprocmask = switch (@compile_var("arch")) {
42 x86_64 => 14,
43 i386 => 175,
44 else => unreachable{},
45};
46const SYS_exit = switch (@compile_var("arch")) {
47 x86_64 => 60,
48 i386 => 1,
49 else => unreachable{},
50};
51const SYS_kill = switch (@compile_var("arch")) {
52 x86_64 => 62,
53 i386 => 37,
54 else => unreachable{},
55};
56const SYS_getgid = switch (@compile_var("arch")) {
57 x86_64 => 104,
58 i386 => 47,
59 else => unreachable{},
60};
61const SYS_gettid = switch (@compile_var("arch")) {
62 x86_64 => 186,
63 i386 => 224,
64 else => unreachable{},
65};
66const SYS_tkill = switch (@compile_var("arch")) {
67 x86_64 => 200,
68 i386 => 238,
69 else => unreachable{},
70};
71const SYS_tgkill = switch (@compile_var("arch")) {
72 x86_64 => 234,
73 i386 => 270,
74 else => unreachable{},
75};
76const SYS_openat = switch (@compile_var("arch")) {
77 x86_64 => 257,
78 i386 => 295,
79 else => unreachable{},
80};
81const SYS_getrandom = switch (@compile_var("arch")) {
82 x86_64 => 318,
83 i386 => 355,
84 else => unreachable{},4 else => unreachable{},
85};5};
866
...@@ -95,15 +15,6 @@ pub const MMAP_MAP_PRIVATE = 2;...@@ -95,15 +15,6 @@ pub const MMAP_MAP_PRIVATE = 2;
95pub const MMAP_MAP_FIXED = 16;15pub const MMAP_MAP_FIXED = 16;
96pub const MMAP_MAP_ANON = 32;16pub const MMAP_MAP_ANON = 32;
9717
98pub const O_RDONLY = 0x0;
99pub const O_WRONLY = 0x1;
100pub const O_RDWR = 0x2;
101pub const O_CREAT = 0x40;
102pub const O_EXCL = 0x80;
103pub const O_TRUNC = 0x200;
104pub const O_APPEND = 0x400;
105pub const O_SYNC = 0x101000;
106
107pub const SIGHUP = 1;18pub const SIGHUP = 1;
108pub const SIGINT = 2;19pub const SIGINT = 2;
109pub const SIGQUIT = 3;20pub const SIGQUIT = 3;
...@@ -139,209 +50,93 @@ pub const SIGPWR = 30;...@@ -139,209 +50,93 @@ pub const SIGPWR = 30;
139pub const SIGSYS = 31;50pub const SIGSYS = 31;
140pub const SIGUNUSED = SIGSYS;51pub const SIGUNUSED = SIGSYS;
14152
53pub const O_RDONLY = 0o0;
54pub const O_WRONLY = 0o1;
55pub const O_RDWR = 0o2;
56
57pub const O_CREAT = arch.O_CREAT;
58pub const O_EXCL = arch.O_EXCL;
59pub const O_NOCTTY = arch.O_NOCTTY;
60pub const O_TRUNC = arch.O_TRUNC;
61pub const O_APPEND = arch.O_APPEND;
62pub const O_NONBLOCK = arch.O_NONBLOCK;
63pub const O_DSYNC = arch.O_DSYNC;
64pub const O_SYNC = arch.O_SYNC;
65pub const O_RSYNC = arch.O_RSYNC;
66pub const O_DIRECTORY = arch.O_DIRECTORY;
67pub const O_NOFOLLOW = arch.O_NOFOLLOW;
68pub const O_CLOEXEC = arch.O_CLOEXEC;
69
70pub const O_ASYNC = arch.O_ASYNC;
71pub const O_DIRECT = arch.O_DIRECT;
72pub const O_LARGEFILE = arch.O_LARGEFILE;
73pub const O_NOATIME = arch.O_NOATIME;
74pub const O_PATH = arch.O_PATH;
75pub const O_TMPFILE = arch.O_TMPFILE;
76pub const O_NDELAY = arch.O_NDELAY;
77
142const SIG_BLOCK = 0;78const SIG_BLOCK = 0;
143const SIG_UNBLOCK = 1;79const SIG_UNBLOCK = 1;
144const SIG_SETMASK = 2;80const SIG_SETMASK = 2;
14581
146const syscall0 = switch (@compile_var("arch")) {
147 x86_64 => x86_64_syscall0,
148 i386 => i386_syscall0,
149 else => unreachable{},
150};
151const syscall1 = switch (@compile_var("arch")) {
152 x86_64 => x86_64_syscall1,
153 i386 => i386_syscall1,
154 else => unreachable{},
155};
156const syscall2 = switch (@compile_var("arch")) {
157 x86_64 => x86_64_syscall2,
158 i386 => i386_syscall2,
159 else => unreachable{},
160};
161const syscall3 = switch (@compile_var("arch")) {
162 x86_64 => x86_64_syscall3,
163 i386 => i386_syscall3,
164 else => unreachable{},
165};
166const syscall4 = switch (@compile_var("arch")) {
167 x86_64 => x86_64_syscall4,
168 i386 => i386_syscall4,
169 else => unreachable{},
170};
171const syscall6 = switch (@compile_var("arch")) {
172 x86_64 => x86_64_syscall6,
173 i386 => i386_syscall6,
174 else => unreachable{},
175};
176
177fn x86_64_syscall0(number: isize) -> isize {
178 asm volatile ("syscall"
179 : [ret] "={rax}" (-> isize)
180 : [number] "{rax}" (number)
181 : "rcx", "r11")
182}
183
184fn x86_64_syscall1(number: isize, arg1: isize) -> isize {
185 asm volatile ("syscall"
186 : [ret] "={rax}" (-> isize)
187 : [number] "{rax}" (number),
188 [arg1] "{rdi}" (arg1)
189 : "rcx", "r11")
190}
191
192fn x86_64_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
193 asm volatile ("syscall"
194 : [ret] "={rax}" (-> isize)
195 : [number] "{rax}" (number),
196 [arg1] "{rdi}" (arg1),
197 [arg2] "{rsi}" (arg2)
198 : "rcx", "r11")
199}
200
201fn x86_64_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
202 asm volatile ("syscall"
203 : [ret] "={rax}" (-> isize)
204 : [number] "{rax}" (number),
205 [arg1] "{rdi}" (arg1),
206 [arg2] "{rsi}" (arg2),
207 [arg3] "{rdx}" (arg3)
208 : "rcx", "r11")
209}
210
211fn x86_64_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
212 asm volatile ("syscall"
213 : [ret] "={rax}" (-> isize)
214 : [number] "{rax}" (number),
215 [arg1] "{rdi}" (arg1),
216 [arg2] "{rsi}" (arg2),
217 [arg3] "{rdx}" (arg3),
218 [arg4] "{r10}" (arg4)
219 : "rcx", "r11")
220}
221
222fn x86_64_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
223 asm volatile ("syscall"
224 : [ret] "={rax}" (-> isize)
225 : [number] "{rax}" (number),
226 [arg1] "{rdi}" (arg1),
227 [arg2] "{rsi}" (arg2),
228 [arg3] "{rdx}" (arg3),
229 [arg4] "{r10}" (arg4),
230 [arg5] "{r8}" (arg5),
231 [arg6] "{r9}" (arg6)
232 : "rcx", "r11")
233}
234
235fn i386_syscall0(number: isize) -> isize {
236 asm volatile ("int $0x80"
237 : [ret] "={eax}" (-> isize)
238 : [number] "{eax}" (number))
239}
240
241fn i386_syscall1(number: isize, arg1: isize) -> isize {
242 asm volatile ("int $0x80"
243 : [ret] "={eax}" (-> isize)
244 : [number] "{eax}" (number),
245 [arg1] "{ebx}" (arg1))
246}
247
248fn i386_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
249 asm volatile ("int $0x80"
250 : [ret] "={eax}" (-> isize)
251 : [number] "{eax}" (number),
252 [arg1] "{ebx}" (arg1),
253 [arg2] "{ecx}" (arg2))
254}
255
256fn i386_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
257 asm volatile ("int $0x80"
258 : [ret] "={eax}" (-> isize)
259 : [number] "{eax}" (number),
260 [arg1] "{ebx}" (arg1),
261 [arg2] "{ecx}" (arg2),
262 [arg3] "{edx}" (arg3))
263}
264
265fn i386_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
266 asm volatile ("int $0x80"
267 : [ret] "={eax}" (-> isize)
268 : [number] "{eax}" (number),
269 [arg1] "{ebx}" (arg1),
270 [arg2] "{ecx}" (arg2),
271 [arg3] "{edx}" (arg3),
272 [arg4] "{esi}" (arg4))
273}
274
275fn i386_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
276 asm volatile ("int $0x80"
277 : [ret] "={eax}" (-> isize)
278 : [number] "{eax}" (number),
279 [arg1] "{ebx}" (arg1),
280 [arg2] "{ecx}" (arg2),
281 [arg3] "{edx}" (arg3),
282 [arg4] "{esi}" (arg4),
283 [arg5] "{edi}" (arg5),
284 [arg6] "{ebp}" (arg6))
285}
286
287pub fn mmap(address: ?&u8, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize {82pub fn mmap(address: ?&u8, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize {
288 // TODO ability to cast maybe pointer to isize83 // TODO ability to cast maybe pointer to isize
289 const addr = if (const unwrapped ?= address) isize(unwrapped) else 0;84 const addr = if (const unwrapped ?= address) isize(unwrapped) else 0;
290 syscall6(SYS_mmap, addr, length, prot, flags, fd, offset)85 arch.syscall6(arch.SYS_mmap, addr, length, prot, flags, fd, offset)
291}86}
29287
293pub fn munmap(address: &u8, length: isize) -> isize {88pub fn munmap(address: &u8, length: isize) -> isize {
294 syscall2(SYS_munmap, isize(address), length)89 arch.syscall2(arch.SYS_munmap, isize(address), length)
295}90}
29691
297pub fn read(fd: isize, buf: &u8, count: isize) -> isize {92pub fn read(fd: isize, buf: &u8, count: isize) -> isize {
298 syscall3(SYS_read, isize(fd), isize(buf), count)93 arch.syscall3(arch.SYS_read, isize(fd), isize(buf), count)
299}94}
30095
301pub fn write(fd: isize, buf: &const u8, count: isize) -> isize {96pub fn write(fd: isize, buf: &const u8, count: isize) -> isize {
302 syscall3(SYS_write, isize(fd), isize(buf), count)97 arch.syscall3(arch.SYS_write, isize(fd), isize(buf), count)
303}98}
30499
305pub fn open(path: []u8, flags: isize, perm: isize) -> isize {100pub fn open(path: []u8, flags: isize, perm: isize) -> isize {
306 var buf: [path.len + 1]u8 = undefined;101 var buf: [path.len + 1]u8 = undefined;
307 @memcpy(&buf[0], &path[0], path.len);102 @memcpy(&buf[0], &path[0], path.len);
308 buf[path.len] = 0;103 buf[path.len] = 0;
309 syscall3(SYS_open, isize(&buf[0]), flags, perm)104 arch.syscall3(arch.SYS_open, isize(&buf[0]), flags, perm)
310}105}
311106
312pub fn create(path: []u8, perm: isize) -> isize {107pub fn create(path: []u8, perm: isize) -> isize {
313 var buf: [path.len + 1]u8 = undefined;108 var buf: [path.len + 1]u8 = undefined;
314 @memcpy(&buf[0], &path[0], path.len);109 @memcpy(&buf[0], &path[0], path.len);
315 buf[path.len] = 0;110 buf[path.len] = 0;
316 syscall2(SYS_creat, isize(&buf[0]), perm)111 arch.syscall2(arch.SYS_creat, isize(&buf[0]), perm)
317}112}
318113
319pub fn openat(dirfd: isize, path: []u8, flags: isize, mode: isize) -> isize {114pub fn openat(dirfd: isize, path: []u8, flags: isize, mode: isize) -> isize {
320 var buf: [path.len + 1]u8 = undefined;115 var buf: [path.len + 1]u8 = undefined;
321 @memcpy(&buf[0], &path[0], path.len);116 @memcpy(&buf[0], &path[0], path.len);
322 buf[path.len] = 0;117 buf[path.len] = 0;
323 syscall4(SYS_openat, dirfd, isize(&buf[0]), flags, mode)118 arch.syscall4(arch.SYS_openat, dirfd, isize(&buf[0]), flags, mode)
324}119}
325120
326pub fn close(fd: isize) -> isize {121pub fn close(fd: isize) -> isize {
327 syscall1(SYS_close, fd)122 arch.syscall1(arch.SYS_close, fd)
328}123}
329124
330pub fn lseek(fd: isize, offset: isize, ref_pos: isize) -> isize {125pub fn lseek(fd: isize, offset: isize, ref_pos: isize) -> isize {
331 syscall3(SYS_lseek, fd, offset, ref_pos)126 arch.syscall3(arch.SYS_lseek, fd, offset, ref_pos)
332}127}
333128
334pub fn exit(status: i32) -> unreachable {129pub fn exit(status: i32) -> unreachable {
335 syscall1(SYS_exit, isize(status));130 arch.syscall1(arch.SYS_exit, isize(status));
336 unreachable{}131 unreachable{}
337}132}
338133
339pub fn getrandom(buf: &u8, count: isize, flags: u32) -> isize {134pub fn getrandom(buf: &u8, count: isize, flags: u32) -> isize {
340 syscall3(SYS_getrandom, isize(buf), count, isize(flags))135 arch.syscall3(arch.SYS_getrandom, isize(buf), count, isize(flags))
341}136}
342137
343pub fn kill(pid: i32, sig: i32) -> i32 {138pub fn kill(pid: i32, sig: i32) -> i32 {
344 i32(syscall2(SYS_kill, pid, sig))139 i32(arch.syscall2(arch.SYS_kill, pid, sig))
345}140}
346141
347const NSIG = 65;142const NSIG = 65;
...@@ -352,20 +147,20 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };...@@ -352,20 +147,20 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };
352pub fn raise(sig: i32) -> i32 {147pub fn raise(sig: i32) -> i32 {
353 var set: sigset_t = undefined;148 var set: sigset_t = undefined;
354 block_app_signals(&set);149 block_app_signals(&set);
355 const tid = i32(syscall0(SYS_gettid));150 const tid = i32(arch.syscall0(arch.SYS_gettid));
356 const ret = i32(syscall2(SYS_tkill, tid, sig));151 const ret = i32(arch.syscall2(arch.SYS_tkill, tid, sig));
357 restore_signals(&set);152 restore_signals(&set);
358 return ret;153 return ret;
359}154}
360155
361fn block_all_signals(set: &sigset_t) {156fn block_all_signals(set: &sigset_t) {
362 syscall4(SYS_rt_sigprocmask, SIG_BLOCK, isize(&all_mask), isize(set), NSIG/8);157 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, isize(&all_mask), isize(set), NSIG/8);
363}158}
364159
365fn block_app_signals(set: &sigset_t) {160fn block_app_signals(set: &sigset_t) {
366 syscall4(SYS_rt_sigprocmask, SIG_BLOCK, isize(&app_mask), isize(set), NSIG/8);161 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, isize(&app_mask), isize(set), NSIG/8);
367}162}
368163
369fn restore_signals(set: &sigset_t) {164fn restore_signals(set: &sigset_t) {
370 syscall4(SYS_rt_sigprocmask, SIG_SETMASK, isize(set), 0, NSIG/8);165 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, isize(set), 0, NSIG/8);
371}166}
std/linux_i386.zig created+92
...@@ -0,0 +1,92 @@
1pub const O_CREAT = 0o100;
2pub const O_EXCL = 0o200;
3pub const O_NOCTTY = 0o400;
4pub const O_TRUNC = 0o1000;
5pub const O_APPEND = 0o2000;
6pub const O_NONBLOCK = 0o4000;
7pub const O_DSYNC = 0o10000;
8pub const O_SYNC = 0o4010000;
9pub const O_RSYNC = 0o4010000;
10pub const O_DIRECTORY = 0o200000;
11pub const O_NOFOLLOW = 0o400000;
12pub const O_CLOEXEC = 0o2000000;
13
14pub const O_ASYNC = 0o20000;
15pub const O_DIRECT = 0o40000;
16pub const O_LARGEFILE = 0o100000;
17pub const O_NOATIME = 0o1000000;
18pub const O_PATH = 0o10000000;
19pub const O_TMPFILE = 0o20200000;
20pub const O_NDELAY = O_NONBLOCK;
21
22pub const F_DUPFD = 0;
23pub const F_GETFD = 1;
24pub const F_SETFD = 2;
25pub const F_GETFL = 3;
26pub const F_SETFL = 4;
27
28pub const F_SETOWN = 8;
29pub const F_GETOWN = 9;
30pub const F_SETSIG = 10;
31pub const F_GETSIG = 11;
32
33pub const F_GETLK = 12;
34pub const F_SETLK = 13;
35pub const F_SETLKW = 14;
36
37pub const F_SETOWN_EX = 15;
38pub const F_GETOWN_EX = 16;
39
40pub const F_GETOWNER_UIDS = 17;
41
42pub fn syscall0(number: isize) -> isize {
43 asm volatile ("int $0x80"
44 : [ret] "={eax}" (-> isize)
45 : [number] "{eax}" (number))
46}
47
48pub fn syscall1(number: isize, arg1: isize) -> isize {
49 asm volatile ("int $0x80"
50 : [ret] "={eax}" (-> isize)
51 : [number] "{eax}" (number),
52 [arg1] "{ebx}" (arg1))
53}
54
55pub fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
56 asm volatile ("int $0x80"
57 : [ret] "={eax}" (-> isize)
58 : [number] "{eax}" (number),
59 [arg1] "{ebx}" (arg1),
60 [arg2] "{ecx}" (arg2))
61}
62
63pub fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
64 asm volatile ("int $0x80"
65 : [ret] "={eax}" (-> isize)
66 : [number] "{eax}" (number),
67 [arg1] "{ebx}" (arg1),
68 [arg2] "{ecx}" (arg2),
69 [arg3] "{edx}" (arg3))
70}
71
72pub fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
73 asm volatile ("int $0x80"
74 : [ret] "={eax}" (-> isize)
75 : [number] "{eax}" (number),
76 [arg1] "{ebx}" (arg1),
77 [arg2] "{ecx}" (arg2),
78 [arg3] "{edx}" (arg3),
79 [arg4] "{esi}" (arg4))
80}
81
82pub fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
83 asm volatile ("int $0x80"
84 : [ret] "={eax}" (-> isize)
85 : [number] "{eax}" (number),
86 [arg1] "{ebx}" (arg1),
87 [arg2] "{ecx}" (arg2),
88 [arg3] "{edx}" (arg3),
89 [arg4] "{esi}" (arg4),
90 [arg5] "{edi}" (arg5),
91 [arg6] "{ebp}" (arg6))
92}
std/linux_x86_64.zig created+116
...@@ -0,0 +1,116 @@
1pub const SYS_read = 0;
2pub const SYS_write = 1;
3pub const SYS_open = 2;
4pub const SYS_close = 3;
5pub const SYS_creat = 85;
6pub const SYS_lseek = 8;
7pub const SYS_mmap = 9;
8pub const SYS_munmap = 11;
9pub const SYS_rt_sigprocmask = 14;
10pub const SYS_exit = 60;
11pub const SYS_kill = 62;
12pub const SYS_getgid = 104;
13pub const SYS_gettid = 186;
14pub const SYS_tkill = 200;
15pub const SYS_tgkill = 234;
16pub const SYS_openat = 257;
17pub const SYS_getrandom = 318;
18
19pub const O_CREAT = 0o100;
20pub const O_EXCL = 0o200;
21pub const O_NOCTTY = 0o400;
22pub const O_TRUNC = 0o1000;
23pub const O_APPEND = 0o2000;
24pub const O_NONBLOCK = 0o4000;
25pub const O_DSYNC = 0o10000;
26pub const O_SYNC = 0o4010000;
27pub const O_RSYNC = 0o4010000;
28pub const O_DIRECTORY = 0o200000;
29pub const O_NOFOLLOW = 0o400000;
30pub const O_CLOEXEC = 0o2000000;
31
32pub const O_ASYNC = 0o20000;
33pub const O_DIRECT = 0o40000;
34pub const O_LARGEFILE = 0;
35pub const O_NOATIME = 0o1000000;
36pub const O_PATH = 0o10000000;
37pub const O_TMPFILE = 0o20200000;
38pub const O_NDELAY = O_NONBLOCK;
39
40pub const F_DUPFD = 0;
41pub const F_GETFD = 1;
42pub const F_SETFD = 2;
43pub const F_GETFL = 3;
44pub const F_SETFL = 4;
45
46pub const F_SETOWN = 8;
47pub const F_GETOWN = 9;
48pub const F_SETSIG = 10;
49pub const F_GETSIG = 11;
50
51pub const F_GETLK = 5;
52pub const F_SETLK = 6;
53pub const F_SETLKW = 7;
54
55pub const F_SETOWN_EX = 15;
56pub const F_GETOWN_EX = 16;
57
58pub const F_GETOWNER_UIDS = 17;
59
60pub fn syscall0(number: isize) -> isize {
61 asm volatile ("syscall"
62 : [ret] "={rax}" (-> isize)
63 : [number] "{rax}" (number)
64 : "rcx", "r11")
65}
66
67pub fn syscall1(number: isize, arg1: isize) -> isize {
68 asm volatile ("syscall"
69 : [ret] "={rax}" (-> isize)
70 : [number] "{rax}" (number),
71 [arg1] "{rdi}" (arg1)
72 : "rcx", "r11")
73}
74
75pub fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
76 asm volatile ("syscall"
77 : [ret] "={rax}" (-> isize)
78 : [number] "{rax}" (number),
79 [arg1] "{rdi}" (arg1),
80 [arg2] "{rsi}" (arg2)
81 : "rcx", "r11")
82}
83
84pub fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
85 asm volatile ("syscall"
86 : [ret] "={rax}" (-> isize)
87 : [number] "{rax}" (number),
88 [arg1] "{rdi}" (arg1),
89 [arg2] "{rsi}" (arg2),
90 [arg3] "{rdx}" (arg3)
91 : "rcx", "r11")
92}
93
94pub fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
95 asm volatile ("syscall"
96 : [ret] "={rax}" (-> isize)
97 : [number] "{rax}" (number),
98 [arg1] "{rdi}" (arg1),
99 [arg2] "{rsi}" (arg2),
100 [arg3] "{rdx}" (arg3),
101 [arg4] "{r10}" (arg4)
102 : "rcx", "r11")
103}
104
105pub fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
106 asm volatile ("syscall"
107 : [ret] "={rax}" (-> isize)
108 : [number] "{rax}" (number),
109 [arg1] "{rdi}" (arg1),
110 [arg2] "{rsi}" (arg2),
111 [arg3] "{rdx}" (arg3),
112 [arg4] "{r10}" (arg4),
113 [arg5] "{r8}" (arg5),
114 [arg6] "{r9}" (arg6)
115 : "rcx", "r11")
116}
std/test_runner.zig+6-6
...@@ -9,19 +9,19 @@ extern var zig_test_fn_list: []TestFn;...@@ -9,19 +9,19 @@ extern var zig_test_fn_list: []TestFn;
99
10pub fn run_tests() -> %void {10pub fn run_tests() -> %void {
11 for (zig_test_fn_list) |test_fn, i| {11 for (zig_test_fn_list) |test_fn, i| {
12 %%io.stderr.print_str("Test ");12 %%io.stderr.write("Test ");
13 %%io.stderr.print_i64(i + 1);13 %%io.stderr.print_i64(i + 1);
14 %%io.stderr.print_str("/");14 %%io.stderr.write("/");
15 %%io.stderr.print_i64(zig_test_fn_list.len);15 %%io.stderr.print_i64(zig_test_fn_list.len);
16 %%io.stderr.print_str(" ");16 %%io.stderr.write(" ");
17 %%io.stderr.print_str(test_fn.name);17 %%io.stderr.write(test_fn.name);
18 %%io.stderr.print_str("...");18 %%io.stderr.write("...");
19 %%io.stderr.flush();19 %%io.stderr.flush();
2020
21 test_fn.func();21 test_fn.func();
2222
2323
24 %%io.stderr.print_str("OK\n");24 %%io.stderr.write("OK\n");
25 %%io.stderr.flush();25 %%io.stderr.flush();
26 }26 }
27}27}
test/self_hosted.zig+1-12
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// test std library1// test std library
2const std = @import("std");2use @import("std");
33
4#attribute("test")4#attribute("test")
5fn empty_function() {}5fn empty_function() {}
...@@ -554,14 +554,3 @@ fn mem_alloc(T: type)(n: isize) -> %[]T {...@@ -554,14 +554,3 @@ fn mem_alloc(T: type)(n: isize) -> %[]T {
554fn mem_free(T: type)(mem: []T) { }554fn mem_free(T: type)(mem: []T) { }
555555
556556
557fn assert(b: bool) {
558 if (!b) unreachable{}
559}
560
561fn str_eql(s1: []u8, s2: []u8) -> bool {
562 if (s1.len != s2.len) return false;
563 for (s1) |c, i| {
564 if (s2[i] != c) return false;
565 }
566 return true;
567}