authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-06 04:41:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-06 04:41:11-07:00
log5e64c4d92f109638111d78b6ab97feb645ee0a01
treee0bede139e1ef7ffb7f6478f7a8c69bb4a2c8781
parentf1eafe4ebb2e1258ee398641d0537e227fe2ea0d

support pub structs. move rand to std lib.

guess number example prints the answer now

10 files changed, 201 insertions(+), 308 deletions(-)

CMakeLists.txt+1
...@@ -118,6 +118,7 @@ set(C_HEADERS...@@ -118,6 +118,7 @@ set(C_HEADERS
118set(ZIG_STD_SRC118set(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 "${CMAKE_SOURCE_DIR}/std/std.zig"
121 "${CMAKE_SOURCE_DIR}/std/rand.zig"
121)122)
122123
123set(C_HEADERS_DEST "lib/zig/include")124set(C_HEADERS_DEST "lib/zig/include")
doc/langref.md+1-1
...@@ -36,7 +36,7 @@ TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | Variabl...@@ -36,7 +36,7 @@ TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | Variabl
3636
37VariableDeclaration : option(FnVisibleMod) (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))37VariableDeclaration : option(FnVisibleMod) (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
3838
39StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)39StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
4040
41StructMember: StructField | FnDecl41StructMember: StructField | FnDecl
4242
example/guess_number/main.zig+5-4
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1export executable "guess_number";1export executable "guess_number";
22
3use "std.zig";3use "std.zig";
4use "rand.zig";
45
5// TODO don't duplicate these; implement pub const6// TODO don't duplicate these; implement pub const
6const stdout_fileno : isize = 1;7const stdout_fileno : isize = 1;
...@@ -11,16 +12,16 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {...@@ -11,16 +12,16 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
1112
12 var seed : u32;13 var seed : u32;
13 var err : isize;14 var err : isize;
14 // TODO #sizeof(u32) instead of 415 if ({err = os_get_random_bytes(&seed as &u8, #sizeof(u32)); err != #sizeof(u32)}) {
15 if ({err = os_get_random_bytes(&seed as &u8, 4); err != 4}) {
16 // TODO full error message16 // TODO full error message
17 fprint_str(stderr_fileno, "unable to get random bytes");17 fprint_str(stderr_fileno, "unable to get random bytes");
18 return 1;18 return 1;
19 }19 }
2020
21 var rand_state = rand_init(seed);21 var rand : Rand;
22 rand.init(seed);
2223
23 const answer = rand_u64(&rand_state, 0, 100) + 1;24 const answer = rand.range_u64(0, 100) + 1;
2425
25 print_str("Answer: ");26 print_str("Answer: ");
26 print_u64(answer);27 print_u64(answer);
example/rand/main.zig deleted-120
...@@ -1,120 +0,0 @@
1export executable "rand";
2
3use "std.zig";
4
5// Mersenne Twister
6const ARRAY_SIZE : u16 = 624;
7
8/// Use `rand_init` to initialize this state.
9struct Rand {
10 // TODO use ARRAY_SIZE here
11 array: [624]u32,
12 // TODO use #typeof(ARRAY_SIZE) here
13 index: u16,
14
15 /// Get 32 bits of randomness.
16 pub fn get_u32(r: &Rand) -> u32 {
17 if (r.index == 0) {
18 r.generate_numbers();
19 }
20
21 // temper the number
22 var y : u32 = r.array[r.index];
23 y ^= y >> 11;
24 y ^= (y >> 7) & 0x9d2c5680;
25 y ^= (y >> 15) & 0xefc60000;
26 y ^= y >> 18;
27
28 r.index = (r.index + 1) % ARRAY_SIZE;
29 return y;
30 }
31
32 /// Fill `buf` with randomness.
33 pub fn get_bytes(r: &Rand, buf: []u8) {
34 var bytes_left = r.get_bytes_aligned(buf);
35 if (bytes_left > 0) {
36 var rand_val_array : [#sizeof(u32)]u8;
37 *(rand_val_array.ptr as &u32) = r.get_u32();
38 while (bytes_left > 0) {
39 // TODO array index operator so we can remove the .ptr
40 buf.ptr[buf.len - bytes_left] = rand_val_array[#sizeof(u32) - bytes_left];
41 bytes_left -= 1;
42 }
43 }
44 }
45
46 /// Get a random unsigned integer with even distribution between `start`
47 /// inclusive and `end` exclusive.
48 pub fn range_u64(r: &Rand, start: u64, end: u64) -> u64 {
49 const range = end - start;
50 const leftover = #max_value(u64) % range;
51 const upper_bound = #max_value(u64) - leftover;
52 var rand_val_array : [#sizeof(u64)]u8;
53
54 while (true) {
55 r.get_bytes_aligned(rand_val_array);
56 const rand_val = *(rand_val_array.ptr as &u64);
57 if (rand_val < upper_bound) {
58 return start + (rand_val % range);
59 }
60 }
61 // TODO detect simple constant in while loop and no breaks and turn it into unreachable
62 // type. then we can remove this unreachable.
63 unreachable;
64 }
65
66 fn generate_numbers(r: &Rand) {
67 var i : #typeof(ARRAY_SIZE) = 0;
68 while (i < ARRAY_SIZE) {
69 const y : u32 = (r.array[i] & 0x80000000) + (r.array[(i + 1) % ARRAY_SIZE] & 0x7fffffff);
70 const untempered : u32 = r.array[(i + 397) % ARRAY_SIZE] ^ (y >> 1);
71 r.array[i] = if ((y % 2) == 0) {
72 untempered
73 } else {
74 // y is odd
75 untempered ^ 0x9908b0df
76 };
77 i += 1;
78 }
79 }
80
81 // does not populate the remaining (buf.len % 4) bytes
82 fn get_bytes_aligned(r: &Rand, buf: []u8) -> usize {
83 var bytes_left = buf.len;
84 while (bytes_left >= 4) {
85 // TODO: array access so we can remove .ptr
86 *(&buf.ptr[buf.len - bytes_left] as &u32) = r.get_u32();
87 bytes_left -= #sizeof(u32);
88 }
89 return bytes_left;
90 }
91}
92
93/// Initialize random state with the given seed.
94pub fn rand_init(r: &Rand, seed: u32) {
95 r.index = 0;
96 r.array[0] = seed;
97 var i : #typeof(ARRAY_SIZE) = 1;
98 while (i < ARRAY_SIZE) {
99 const prev_value : u64 = r.array[i - 1];
100 r.array[i] = ((prev_value ^ (prev_value << 30)) * 0x6c078965 + i) as u32;
101 i += 1;
102 }
103}
104
105pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
106 var rand : Rand;
107 var i : u8 = 0;
108 while (i < 20) {
109 rand_init(&rand, i);
110 var j : u8 = 0;
111 while (j < 20) {
112 print_u64(rand.range_u64(0, 100) + 1);
113 print_str(" ");
114 j += 1;
115 }
116 print_str("\n");
117 i += 1;
118 }
119 return 0;
120}
src/analyze.cpp+31-5
...@@ -474,7 +474,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t...@@ -474,7 +474,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
474 add_node_error(g, child->data.param_decl.type,474 add_node_error(g, child->data.param_decl.type,
475 buf_sprintf("parameter of type 'unreachable' not allowed"));475 buf_sprintf("parameter of type 'unreachable' not allowed"));
476 } else if (type_entry->id == TypeTableEntryIdVoid) {476 } else if (type_entry->id == TypeTableEntryIdVoid) {
477 if (node->data.fn_proto.visib_mod == FnProtoVisibModExport) {477 if (node->data.fn_proto.visib_mod == VisibModExport) {
478 add_node_error(g, child->data.param_decl.type,478 add_node_error(g, child->data.param_decl.type,
479 buf_sprintf("parameter of type 'void' not allowed on exported functions"));479 buf_sprintf("parameter of type 'void' not allowed on exported functions"));
480 }480 }
...@@ -599,8 +599,8 @@ static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node,...@@ -599,8 +599,8 @@ static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node,
599599
600 auto entry = fn_table->maybe_get(proto_name);600 auto entry = fn_table->maybe_get(proto_name);
601 bool skip = false;601 bool skip = false;
602 bool is_internal = (proto_node->data.fn_proto.visib_mod != FnProtoVisibModExport);602 bool is_internal = (proto_node->data.fn_proto.visib_mod != VisibModExport);
603 bool is_pub = (proto_node->data.fn_proto.visib_mod != FnProtoVisibModPrivate);603 bool is_pub = (proto_node->data.fn_proto.visib_mod != VisibModPrivate);
604 if (entry) {604 if (entry) {
605 add_node_error(g, node,605 add_node_error(g, node,
606 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));606 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
...@@ -2199,7 +2199,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -2199,7 +2199,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
2199 node->codegen_node->data.fn_def_node.block_context = context;2199 node->codegen_node->data.fn_def_node.block_context = context;
22002200
2201 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;2201 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;
2202 bool is_exported = (fn_proto->visib_mod == FnProtoVisibModExport);2202 bool is_exported = (fn_proto->visib_mod == VisibModExport);
2203 for (int i = 0; i < fn_proto->params.length; i += 1) {2203 for (int i = 0; i < fn_proto->params.length; i += 1) {
2204 AstNode *param_decl_node = fn_proto->params.at(i);2204 AstNode *param_decl_node = fn_proto->params.at(i);
2205 assert(param_decl_node->type == NodeTypeParamDecl);2205 assert(param_decl_node->type == NodeTypeParamDecl);
...@@ -2293,7 +2293,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -2293,7 +2293,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
2293 break;2293 break;
22942294
2295 FnTableEntry *fn_entry = entry->value;2295 FnTableEntry *fn_entry = entry->value;
2296 bool is_pub = (fn_entry->proto_node->data.fn_proto.visib_mod != FnProtoVisibModPrivate);2296 bool is_pub = (fn_entry->proto_node->data.fn_proto.visib_mod != VisibModPrivate);
2297 if (is_pub) {2297 if (is_pub) {
2298 auto existing_entry = import->fn_table.maybe_get(entry->key);2298 auto existing_entry = import->fn_table.maybe_get(entry->key);
2299 if (existing_entry) {2299 if (existing_entry) {
...@@ -2306,6 +2306,32 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -2306,6 +2306,32 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
2306 }2306 }
2307 }2307 }
2308 }2308 }
2309
2310 // import all the public types
2311 {
2312 auto it = target_import->type_table.entry_iterator();
2313 for (;;) {
2314 auto *entry = it.next();
2315 if (!entry)
2316 break;
2317
2318 TypeTableEntry *type_entry = entry->value;
2319 if (type_entry->id == TypeTableEntryIdStruct) {
2320 AstNode *decl_node = type_entry->data.structure.decl_node;
2321 bool is_pub = (decl_node->data.struct_decl.visib_mod != VisibModPrivate);
2322 if (is_pub) {
2323 auto existing_entry = import->type_table.maybe_get(entry->key);
2324 if (existing_entry) {
2325 add_node_error(g, node,
2326 buf_sprintf("import of type '%s' overrides existing definition",
2327 buf_ptr(&type_entry->name)));
2328 } else {
2329 import->type_table.put(entry->key, entry->value);
2330 }
2331 }
2332 }
2333 }
2334 }
2309 break;2335 break;
2310 }2336 }
2311 case NodeTypeStructDecl:2337 case NodeTypeStructDecl:
src/codegen.cpp+2-2
...@@ -2164,7 +2164,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -2164,7 +2164,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
2164 assert(proto_node->type == NodeTypeFnProto);2164 assert(proto_node->type == NodeTypeFnProto);
2165 Buf *proto_name = &proto_node->data.fn_proto.name;2165 Buf *proto_name = &proto_node->data.fn_proto.name;
21662166
2167 bool is_private = (proto_node->data.fn_proto.visib_mod == FnProtoVisibModPrivate);2167 bool is_private = (proto_node->data.fn_proto.visib_mod == VisibModPrivate);
21682168
2169 if (buf_eql_str(proto_name, "main") && !is_private) {2169 if (buf_eql_str(proto_name, "main") && !is_private) {
2170 g->have_exported_main = true;2170 g->have_exported_main = true;
...@@ -2287,7 +2287,7 @@ static void generate_h_file(CodeGen *g) {...@@ -2287,7 +2287,7 @@ static void generate_h_file(CodeGen *g) {
2287 assert(proto_node->type == NodeTypeFnProto);2287 assert(proto_node->type == NodeTypeFnProto);
2288 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;2288 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
22892289
2290 if (fn_proto->visib_mod != FnProtoVisibModExport)2290 if (fn_proto->visib_mod != VisibModExport)
2291 continue;2291 continue;
22922292
2293 Buf return_type_c = BUF_INIT;2293 Buf return_type_c = BUF_INIT;
src/parser.cpp+54-25
...@@ -2387,34 +2387,40 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato...@@ -2387,34 +2387,40 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
2387FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type)2387FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type)
2388*/2388*/
2389static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory) {2389static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory) {
2390 Token *token = &pc->tokens->at(*token_index);2390 Token *first_token = &pc->tokens->at(*token_index);
2391
2392 FnProtoVisibMod visib_mod;
2393
2394 if (token->id == TokenIdKeywordPub) {
2395 visib_mod = FnProtoVisibModPub;
2396 *token_index += 1;
23972391
2398 Token *fn_token = &pc->tokens->at(*token_index);2392 VisibMod visib_mod;
2399 *token_index += 1;
2400 ast_expect_token(pc, fn_token, TokenIdKeywordFn);
2401 } else if (token->id == TokenIdKeywordExport) {
2402 visib_mod = FnProtoVisibModExport;
2403 *token_index += 1;
24042393
2405 Token *fn_token = &pc->tokens->at(*token_index);2394 if (first_token->id == TokenIdKeywordPub) {
2406 *token_index += 1;2395 Token *next_token = &pc->tokens->at(*token_index + 1);
2407 ast_expect_token(pc, fn_token, TokenIdKeywordFn);2396 if (next_token->id == TokenIdKeywordFn) {
2408 } else if (token->id == TokenIdKeywordFn) {2397 visib_mod = VisibModPub;
2409 visib_mod = FnProtoVisibModPrivate;2398 *token_index += 2;
2399 } else if (mandatory) {
2400 ast_invalid_token_error(pc, first_token);
2401 } else {
2402 return nullptr;
2403 }
2404 } else if (first_token->id == TokenIdKeywordExport) {
2405 Token *next_token = &pc->tokens->at(*token_index + 1);
2406 if (next_token->id == TokenIdKeywordFn) {
2407 visib_mod = VisibModExport;
2408 *token_index += 2;
2409 } else if (mandatory) {
2410 ast_invalid_token_error(pc, first_token);
2411 } else {
2412 return nullptr;
2413 }
2414 } else if (first_token->id == TokenIdKeywordFn) {
2415 visib_mod = VisibModPrivate;
2410 *token_index += 1;2416 *token_index += 1;
2411 } else if (mandatory) {2417 } else if (mandatory) {
2412 ast_invalid_token_error(pc, token);2418 ast_invalid_token_error(pc, first_token);
2413 } else {2419 } else {
2414 return nullptr;2420 return nullptr;
2415 }2421 }
24162422
2417 AstNode *node = ast_create_node(pc, NodeTypeFnProto, token);2423 AstNode *node = ast_create_node(pc, NodeTypeFnProto, first_token);
2418 node->data.fn_proto.visib_mod = visib_mod;2424 node->data.fn_proto.visib_mod = visib_mod;
2419 node->data.fn_proto.directives = pc->directive_list;2425 node->data.fn_proto.directives = pc->directive_list;
2420 pc->directive_list = nullptr;2426 pc->directive_list = nullptr;
...@@ -2584,22 +2590,45 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {...@@ -2584,22 +2590,45 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {
2584}2590}
25852591
2586/*2592/*
2587StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)2593StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
2588StructMember: StructField | FnDecl2594StructMember: StructField | FnDecl
2589StructField : token(Symbol) token(Colon) Type token(Comma)2595StructField : token(Symbol) token(Colon) Type token(Comma)
2590*/2596*/
2591static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {2597static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
2592 Token *struct_kw = &pc->tokens->at(*token_index);2598 Token *first_token = &pc->tokens->at(*token_index);
2593 if (struct_kw->id != TokenIdKeywordStruct)2599
2600 VisibMod visib_mod;
2601
2602 if (first_token->id == TokenIdKeywordPub) {
2603 Token *next_token = &pc->tokens->at(*token_index + 1);
2604 if (next_token->id == TokenIdKeywordStruct) {
2605 visib_mod = VisibModPub;
2606 *token_index += 2;
2607 } else {
2608 return nullptr;
2609 }
2610 } else if (first_token->id == TokenIdKeywordExport) {
2611 Token *next_token = &pc->tokens->at(*token_index + 1);
2612 if (next_token->id == TokenIdKeywordStruct) {
2613 visib_mod = VisibModExport;
2614 *token_index += 2;
2615 } else {
2616 return nullptr;
2617 }
2618 } else if (first_token->id == TokenIdKeywordStruct) {
2619 visib_mod = VisibModPrivate;
2620 *token_index += 1;
2621 } else {
2594 return nullptr;2622 return nullptr;
2595 *token_index += 1;2623 }
25962624
2597 Token *struct_name = &pc->tokens->at(*token_index);2625 Token *struct_name = &pc->tokens->at(*token_index);
2598 *token_index += 1;2626 *token_index += 1;
2599 ast_expect_token(pc, struct_name, TokenIdSymbol);2627 ast_expect_token(pc, struct_name, TokenIdSymbol);
26002628
2601 AstNode *node = ast_create_node(pc, NodeTypeStructDecl, struct_kw);2629 AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token);
2602 ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name);2630 ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name);
2631 node->data.struct_decl.visib_mod = visib_mod;
26032632
2604 ast_eat_token(pc, token_index, TokenIdLBrace);2633 ast_eat_token(pc, token_index, TokenIdLBrace);
26052634
src/parser.hpp+6-5
...@@ -65,15 +65,15 @@ struct AstNodeRoot {...@@ -65,15 +65,15 @@ struct AstNodeRoot {
65 ZigList<AstNode *> top_level_decls;65 ZigList<AstNode *> top_level_decls;
66};66};
6767
68enum FnProtoVisibMod {68enum VisibMod {
69 FnProtoVisibModPrivate,69 VisibModPrivate,
70 FnProtoVisibModPub,70 VisibModPub,
71 FnProtoVisibModExport,71 VisibModExport,
72};72};
7373
74struct AstNodeFnProto {74struct AstNodeFnProto {
75 ZigList<AstNode *> *directives;75 ZigList<AstNode *> *directives;
76 FnProtoVisibMod visib_mod;76 VisibMod visib_mod;
77 Buf name;77 Buf name;
78 ZigList<AstNode *> params;78 ZigList<AstNode *> params;
79 AstNode *return_type;79 AstNode *return_type;
...@@ -284,6 +284,7 @@ struct AstNodeStructDecl {...@@ -284,6 +284,7 @@ struct AstNodeStructDecl {
284 ZigList<AstNode *> fields;284 ZigList<AstNode *> fields;
285 ZigList<AstNode *> fns;285 ZigList<AstNode *> fns;
286 ZigList<AstNode *> *directives;286 ZigList<AstNode *> *directives;
287 VisibMod visib_mod;
287};288};
288289
289struct AstNodeStructField {290struct AstNodeStructField {
std/errno.zig deleted-146
...@@ -1,146 +0,0 @@
1pub const EPERM = 1; // Operation not permitted
2pub const ENOENT = 2; // No such file or directory
3pub const ESRCH = 3; // No such process
4pub const EINTR = 4; // Interrupted system call
5pub const EIO = 5; // I/O error
6pub const ENXIO = 6; // No such device or address
7pub const E2BIG = 7; // Arg list too long
8pub const ENOEXEC = 8; // Exec format error
9pub const EBADF = 9; // Bad file number
10pub const ECHILD = 10; // No child processes
11pub const EAGAIN = 11; // Try again
12pub const ENOMEM = 12; // Out of memory
13pub const EACCES = 13; // Permission denied
14pub const EFAULT = 14; // Bad address
15pub const ENOTBLK = 15; // Block device required
16pub const EBUSY = 16; // Device or resource busy
17pub const EEXIST = 17; // File exists
18pub const EXDEV = 18; // Cross-device link
19pub const ENODEV = 19; // No such device
20pub const ENOTDIR = 20; // Not a directory
21pub const EISDIR = 21; // Is a directory
22pub const EINVAL = 22; // Invalid argument
23pub const ENFILE = 23; // File table overflow
24pub const EMFILE = 24; // Too many open files
25pub const ENOTTY = 25; // Not a typewriter
26pub const ETXTBSY = 26; // Text file busy
27pub const EFBIG = 27; // File too large
28pub const ENOSPC = 28; // No space left on device
29pub const ESPIPE = 29; // Illegal seek
30pub const EROFS = 30; // Read-only file system
31pub const EMLINK = 31; // Too many links
32pub const EPIPE = 32; // Broken pipe
33pub const EDOM = 33; // Math argument out of domain of func
34pub const ERANGE = 34; // Math result not representable
35pub const EDEADLK = 35; // Resource deadlock would occur
36pub const ENAMETOOLONG = 36; // File name too long
37pub const ENOLCK = 37; // No record locks available
38pub const ENOSYS = 38; // Function not implemented
39pub const ENOTEMPTY = 39; // Directory not empty
40pub const ELOOP = 40; // Too many symbolic links encountered
41pub const EWOULDBLOCK = EAGAIN; // Operation would block
42pub const ENOMSG = 42; // No message of desired type
43pub const EIDRM = 43; // Identifier removed
44pub const ECHRNG = 44; // Channel number out of range
45pub const EL2NSYNC = 45; // Level 2 not synchronized
46pub const EL3HLT = 46; // Level 3 halted
47pub const EL3RST = 47; // Level 3 reset
48pub const ELNRNG = 48; // Link number out of range
49pub const EUNATCH = 49; // Protocol driver not attached
50pub const ENOCSI = 50; // No CSI structure available
51pub const EL2HLT = 51; // Level 2 halted
52pub const EBADE = 52; // Invalid exchange
53pub const EBADR = 53; // Invalid request descriptor
54pub const EXFULL = 54; // Exchange full
55pub const ENOANO = 55; // No anode
56pub const EBADRQC = 56; // Invalid request code
57pub const EBADSLT = 57; // Invalid slot
58
59pub const EBFONT = 59; // Bad font file format
60pub const ENOSTR = 60; // Device not a stream
61pub const ENODATA = 61; // No data available
62pub const ETIME = 62; // Timer expired
63pub const ENOSR = 63; // Out of streams resources
64pub const ENONET = 64; // Machine is not on the network
65pub const ENOPKG = 65; // Package not installed
66pub const EREMOTE = 66; // Object is remote
67pub const ENOLINK = 67; // Link has been severed
68pub const EADV = 68; // Advertise error
69pub const ESRMNT = 69; // Srmount error
70pub const ECOMM = 70; // Communication error on send
71pub const EPROTO = 71; // Protocol error
72pub const EMULTIHOP = 72; // Multihop attempted
73pub const EDOTDOT = 73; // RFS specific error
74pub const EBADMSG = 74; // Not a data message
75pub const EOVERFLOW = 75; // Value too large for defined data type
76pub const ENOTUNIQ = 76; // Name not unique on network
77pub const EBADFD = 77; // File descriptor in bad state
78pub const EREMCHG = 78; // Remote address changed
79pub const ELIBACC = 79; // Can not access a needed shared library
80pub const ELIBBAD = 80; // Accessing a corrupted shared library
81pub const ELIBSCN = 81; // .lib section in a.out corrupted
82pub const ELIBMAX = 82; // Attempting to link in too many shared libraries
83pub const ELIBEXEC = 83; // Cannot exec a shared library directly
84pub const EILSEQ = 84; // Illegal byte sequence
85pub const ERESTART = 85; // Interrupted system call should be restarted
86pub const ESTRPIPE = 86; // Streams pipe error
87pub const EUSERS = 87; // Too many users
88pub const ENOTSOCK = 88; // Socket operation on non-socket
89pub const EDESTADDRREQ = 89; // Destination address required
90pub const EMSGSIZE = 90; // Message too long
91pub const EPROTOTYPE = 91; // Protocol wrong type for socket
92pub const ENOPROTOOPT = 92; // Protocol not available
93pub const EPROTONOSUPPORT = 93; // Protocol not supported
94pub const ESOCKTNOSUPPORT = 94; // Socket type not supported
95pub const EOPNOTSUPP = 95; // Operation not supported on transport endpoint
96pub const EPFNOSUPPORT = 96; // Protocol family not supported
97pub const EAFNOSUPPORT = 97; // Address family not supported by protocol
98pub const EADDRINUSE = 98; // Address already in use
99pub const EADDRNOTAVAIL = 99; // Cannot assign requested address
100pub const ENETDOWN = 100; // Network is down
101pub const ENETUNREACH = 101; // Network is unreachable
102pub const ENETRESET = 102; // Network dropped connection because of reset
103pub const ECONNABORTED = 103; // Software caused connection abort
104pub const ECONNRESET = 104; // Connection reset by peer
105pub const ENOBUFS = 105; // No buffer space available
106pub const EISCONN = 106; // Transport endpoint is already connected
107pub const ENOTCONN = 107; // Transport endpoint is not connected
108pub const ESHUTDOWN = 108; // Cannot send after transport endpoint shutdown
109pub const ETOOMANYREFS = 109; // Too many references: cannot splice
110pub const ETIMEDOUT = 110; // Connection timed out
111pub const ECONNREFUSED = 111; // Connection refused
112pub const EHOSTDOWN = 112; // Host is down
113pub const EHOSTUNREACH = 113; // No route to host
114pub const EALREADY = 114; // Operation already in progress
115pub const EINPROGRESS = 115; // Operation now in progress
116pub const ESTALE = 116; // Stale NFS file handle
117pub const EUCLEAN = 117; // Structure needs cleaning
118pub const ENOTNAM = 118; // Not a XENIX named type file
119pub const ENAVAIL = 119; // No XENIX semaphores available
120pub const EISNAM = 120; // Is a named type file
121pub const EREMOTEIO = 121; // Remote I/O error
122pub const EDQUOT = 122; // Quota exceeded
123
124pub const ENOMEDIUM = 123; // No medium found
125pub const EMEDIUMTYPE = 124; // Wrong medium type
126
127// nameserver query return codes
128pub const ENSROK = 0; // DNS server returned answer with no data
129pub const ENSRNODATA = 160; // DNS server returned answer with no data
130pub const ENSRFORMERR = 161; // DNS server claims query was misformatted
131pub const ENSRSERVFAIL = 162; // DNS server returned general failure
132pub const ENSRNOTFOUND = 163; // Domain name not found
133pub const ENSRNOTIMP = 164; // DNS server does not implement requested operation
134pub const ENSRREFUSED = 165; // DNS server refused query
135pub const ENSRBADQUERY = 166; // Misformatted DNS query
136pub const ENSRBADNAME = 167; // Misformatted domain name
137pub const ENSRBADFAMILY = 168; // Unsupported address family
138pub const ENSRBADRESP = 169; // Misformatted DNS reply
139pub const ENSRCONNREFUSED = 170; // Could not contact DNS servers
140pub const ENSRTIMEOUT = 171; // Timeout while contacting DNS servers
141pub const ENSROF = 172; // End of file
142pub const ENSRFILE = 173; // Error reading file
143pub const ENSRNOMEM = 174; // Out of memory
144pub const ENSRDESTRUCTION = 175; // Application terminated lookup
145pub const ENSRQUERYDOMAINTOOLONG = 176; // Domain name is too long
146pub const ENSRCNAMELOOP = 177; // Domain name is too long
std/rand.zig created+101
...@@ -0,0 +1,101 @@
1// Mersenne Twister
2const ARRAY_SIZE : u16 = 624;
3
4/// Use `rand_init` to initialize this state.
5pub struct Rand {
6 // TODO use ARRAY_SIZE here
7 array: [624]u32,
8 // TODO use #typeof(ARRAY_SIZE) here
9 index: u16,
10
11 /// Initialize random state with the given seed.
12 pub fn init(r: &Rand, seed: u32) {
13 r.index = 0;
14 r.array[0] = seed;
15 var i : #typeof(ARRAY_SIZE) = 1;
16 while (i < ARRAY_SIZE) {
17 const prev_value : u64 = r.array[i - 1];
18 r.array[i] = ((prev_value ^ (prev_value << 30)) * 0x6c078965 + i) as u32;
19 i += 1;
20 }
21 }
22
23
24 /// Get 32 bits of randomness.
25 pub fn get_u32(r: &Rand) -> u32 {
26 if (r.index == 0) {
27 r.generate_numbers();
28 }
29
30 // temper the number
31 var y : u32 = r.array[r.index];
32 y ^= y >> 11;
33 y ^= (y >> 7) & 0x9d2c5680;
34 y ^= (y >> 15) & 0xefc60000;
35 y ^= y >> 18;
36
37 r.index = (r.index + 1) % ARRAY_SIZE;
38 return y;
39 }
40
41 /// Fill `buf` with randomness.
42 pub fn get_bytes(r: &Rand, buf: []u8) {
43 var bytes_left = r.get_bytes_aligned(buf);
44 if (bytes_left > 0) {
45 var rand_val_array : [#sizeof(u32)]u8;
46 *(rand_val_array.ptr as &u32) = r.get_u32();
47 while (bytes_left > 0) {
48 // TODO array index operator so we can remove the .ptr
49 buf.ptr[buf.len - bytes_left] = rand_val_array[#sizeof(u32) - bytes_left];
50 bytes_left -= 1;
51 }
52 }
53 }
54
55 /// Get a random unsigned integer with even distribution between `start`
56 /// inclusive and `end` exclusive.
57 pub fn range_u64(r: &Rand, start: u64, end: u64) -> u64 {
58 const range = end - start;
59 const leftover = #max_value(u64) % range;
60 const upper_bound = #max_value(u64) - leftover;
61 var rand_val_array : [#sizeof(u64)]u8;
62
63 while (true) {
64 r.get_bytes_aligned(rand_val_array);
65 const rand_val = *(rand_val_array.ptr as &u64);
66 if (rand_val < upper_bound) {
67 return start + (rand_val % range);
68 }
69 }
70 // TODO detect simple constant in while loop and no breaks and turn it into unreachable
71 // type. then we can remove this unreachable.
72 unreachable;
73 }
74
75 fn generate_numbers(r: &Rand) {
76 var i : #typeof(ARRAY_SIZE) = 0;
77 while (i < ARRAY_SIZE) {
78 const y : u32 = (r.array[i] & 0x80000000) + (r.array[(i + 1) % ARRAY_SIZE] & 0x7fffffff);
79 const untempered : u32 = r.array[(i + 397) % ARRAY_SIZE] ^ (y >> 1);
80 r.array[i] = if ((y % 2) == 0) {
81 untempered
82 } else {
83 // y is odd
84 untempered ^ 0x9908b0df
85 };
86 i += 1;
87 }
88 }
89
90 // does not populate the remaining (buf.len % 4) bytes
91 fn get_bytes_aligned(r: &Rand, buf: []u8) -> usize {
92 var bytes_left = buf.len;
93 while (bytes_left >= 4) {
94 // TODO: array access so we can remove .ptr
95 *(&buf.ptr[buf.len - bytes_left] as &u32) = r.get_u32();
96 bytes_left -= #sizeof(u32);
97 }
98 return bytes_left;
99 }
100}
101