support pub structs. move rand to std lib.
guess number example prints the answer nowmaster
parent
f1eafe4ebb
commit
5e64c4d92f
|
@ -118,6 +118,7 @@ set(C_HEADERS
|
|||
set(ZIG_STD_SRC
|
||||
"${CMAKE_SOURCE_DIR}/std/bootstrap.zig"
|
||||
"${CMAKE_SOURCE_DIR}/std/std.zig"
|
||||
"${CMAKE_SOURCE_DIR}/std/rand.zig"
|
||||
)
|
||||
|
||||
set(C_HEADERS_DEST "lib/zig/include")
|
||||
|
|
|
@ -36,7 +36,7 @@ TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | Variabl
|
|||
|
||||
VariableDeclaration : option(FnVisibleMod) (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
|
||||
StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
|
||||
StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
|
||||
|
||||
StructMember: StructField | FnDecl
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export executable "guess_number";
|
||||
|
||||
use "std.zig";
|
||||
use "rand.zig";
|
||||
|
||||
// TODO don't duplicate these; implement pub const
|
||||
const stdout_fileno : isize = 1;
|
||||
|
@ -11,16 +12,16 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
|||
|
||||
var seed : u32;
|
||||
var err : isize;
|
||||
// TODO #sizeof(u32) instead of 4
|
||||
if ({err = os_get_random_bytes(&seed as &u8, 4); err != 4}) {
|
||||
if ({err = os_get_random_bytes(&seed as &u8, #sizeof(u32)); err != #sizeof(u32)}) {
|
||||
// TODO full error message
|
||||
fprint_str(stderr_fileno, "unable to get random bytes");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var rand_state = rand_init(seed);
|
||||
var rand : Rand;
|
||||
rand.init(seed);
|
||||
|
||||
const answer = rand_u64(&rand_state, 0, 100) + 1;
|
||||
const answer = rand.range_u64(0, 100) + 1;
|
||||
|
||||
print_str("Answer: ");
|
||||
print_u64(answer);
|
||||
|
|
|
@ -474,7 +474,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
|
|||
add_node_error(g, child->data.param_decl.type,
|
||||
buf_sprintf("parameter of type 'unreachable' not allowed"));
|
||||
} else if (type_entry->id == TypeTableEntryIdVoid) {
|
||||
if (node->data.fn_proto.visib_mod == FnProtoVisibModExport) {
|
||||
if (node->data.fn_proto.visib_mod == VisibModExport) {
|
||||
add_node_error(g, child->data.param_decl.type,
|
||||
buf_sprintf("parameter of type 'void' not allowed on exported functions"));
|
||||
}
|
||||
|
@ -599,8 +599,8 @@ static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node,
|
|||
|
||||
auto entry = fn_table->maybe_get(proto_name);
|
||||
bool skip = false;
|
||||
bool is_internal = (proto_node->data.fn_proto.visib_mod != FnProtoVisibModExport);
|
||||
bool is_pub = (proto_node->data.fn_proto.visib_mod != FnProtoVisibModPrivate);
|
||||
bool is_internal = (proto_node->data.fn_proto.visib_mod != VisibModExport);
|
||||
bool is_pub = (proto_node->data.fn_proto.visib_mod != VisibModPrivate);
|
||||
if (entry) {
|
||||
add_node_error(g, node,
|
||||
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
|
|||
node->codegen_node->data.fn_def_node.block_context = context;
|
||||
|
||||
AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;
|
||||
bool is_exported = (fn_proto->visib_mod == FnProtoVisibModExport);
|
||||
bool is_exported = (fn_proto->visib_mod == VisibModExport);
|
||||
for (int i = 0; i < fn_proto->params.length; i += 1) {
|
||||
AstNode *param_decl_node = fn_proto->params.at(i);
|
||||
assert(param_decl_node->type == NodeTypeParamDecl);
|
||||
|
@ -2293,7 +2293,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
|
|||
break;
|
||||
|
||||
FnTableEntry *fn_entry = entry->value;
|
||||
bool is_pub = (fn_entry->proto_node->data.fn_proto.visib_mod != FnProtoVisibModPrivate);
|
||||
bool is_pub = (fn_entry->proto_node->data.fn_proto.visib_mod != VisibModPrivate);
|
||||
if (is_pub) {
|
||||
auto existing_entry = import->fn_table.maybe_get(entry->key);
|
||||
if (existing_entry) {
|
||||
|
@ -2306,6 +2306,32 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// import all the public types
|
||||
{
|
||||
auto it = target_import->type_table.entry_iterator();
|
||||
for (;;) {
|
||||
auto *entry = it.next();
|
||||
if (!entry)
|
||||
break;
|
||||
|
||||
TypeTableEntry *type_entry = entry->value;
|
||||
if (type_entry->id == TypeTableEntryIdStruct) {
|
||||
AstNode *decl_node = type_entry->data.structure.decl_node;
|
||||
bool is_pub = (decl_node->data.struct_decl.visib_mod != VisibModPrivate);
|
||||
if (is_pub) {
|
||||
auto existing_entry = import->type_table.maybe_get(entry->key);
|
||||
if (existing_entry) {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("import of type '%s' overrides existing definition",
|
||||
buf_ptr(&type_entry->name)));
|
||||
} else {
|
||||
import->type_table.put(entry->key, entry->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NodeTypeStructDecl:
|
||||
|
|
|
@ -2164,7 +2164,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
|
|||
assert(proto_node->type == NodeTypeFnProto);
|
||||
Buf *proto_name = &proto_node->data.fn_proto.name;
|
||||
|
||||
bool is_private = (proto_node->data.fn_proto.visib_mod == FnProtoVisibModPrivate);
|
||||
bool is_private = (proto_node->data.fn_proto.visib_mod == VisibModPrivate);
|
||||
|
||||
if (buf_eql_str(proto_name, "main") && !is_private) {
|
||||
g->have_exported_main = true;
|
||||
|
@ -2287,7 +2287,7 @@ static void generate_h_file(CodeGen *g) {
|
|||
assert(proto_node->type == NodeTypeFnProto);
|
||||
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
|
||||
|
||||
if (fn_proto->visib_mod != FnProtoVisibModExport)
|
||||
if (fn_proto->visib_mod != VisibModExport)
|
||||
continue;
|
||||
|
||||
Buf return_type_c = BUF_INIT;
|
||||
|
|
|
@ -2387,34 +2387,40 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
|
|||
FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type)
|
||||
*/
|
||||
static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
Token *first_token = &pc->tokens->at(*token_index);
|
||||
|
||||
FnProtoVisibMod visib_mod;
|
||||
VisibMod visib_mod;
|
||||
|
||||
if (token->id == TokenIdKeywordPub) {
|
||||
visib_mod = FnProtoVisibModPub;
|
||||
*token_index += 1;
|
||||
|
||||
Token *fn_token = &pc->tokens->at(*token_index);
|
||||
*token_index += 1;
|
||||
ast_expect_token(pc, fn_token, TokenIdKeywordFn);
|
||||
} else if (token->id == TokenIdKeywordExport) {
|
||||
visib_mod = FnProtoVisibModExport;
|
||||
*token_index += 1;
|
||||
|
||||
Token *fn_token = &pc->tokens->at(*token_index);
|
||||
*token_index += 1;
|
||||
ast_expect_token(pc, fn_token, TokenIdKeywordFn);
|
||||
} else if (token->id == TokenIdKeywordFn) {
|
||||
visib_mod = FnProtoVisibModPrivate;
|
||||
if (first_token->id == TokenIdKeywordPub) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdKeywordFn) {
|
||||
visib_mod = VisibModPub;
|
||||
*token_index += 2;
|
||||
} else if (mandatory) {
|
||||
ast_invalid_token_error(pc, first_token);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (first_token->id == TokenIdKeywordExport) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdKeywordFn) {
|
||||
visib_mod = VisibModExport;
|
||||
*token_index += 2;
|
||||
} else if (mandatory) {
|
||||
ast_invalid_token_error(pc, first_token);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (first_token->id == TokenIdKeywordFn) {
|
||||
visib_mod = VisibModPrivate;
|
||||
*token_index += 1;
|
||||
} else if (mandatory) {
|
||||
ast_invalid_token_error(pc, token);
|
||||
ast_invalid_token_error(pc, first_token);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeFnProto, token);
|
||||
AstNode *node = ast_create_node(pc, NodeTypeFnProto, first_token);
|
||||
node->data.fn_proto.visib_mod = visib_mod;
|
||||
node->data.fn_proto.directives = pc->directive_list;
|
||||
pc->directive_list = nullptr;
|
||||
|
@ -2584,22 +2590,45 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {
|
|||
}
|
||||
|
||||
/*
|
||||
StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
|
||||
StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
|
||||
StructMember: StructField | FnDecl
|
||||
StructField : token(Symbol) token(Colon) Type token(Comma)
|
||||
*/
|
||||
static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
|
||||
Token *struct_kw = &pc->tokens->at(*token_index);
|
||||
if (struct_kw->id != TokenIdKeywordStruct)
|
||||
Token *first_token = &pc->tokens->at(*token_index);
|
||||
|
||||
VisibMod visib_mod;
|
||||
|
||||
if (first_token->id == TokenIdKeywordPub) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdKeywordStruct) {
|
||||
visib_mod = VisibModPub;
|
||||
*token_index += 2;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (first_token->id == TokenIdKeywordExport) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdKeywordStruct) {
|
||||
visib_mod = VisibModExport;
|
||||
*token_index += 2;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (first_token->id == TokenIdKeywordStruct) {
|
||||
visib_mod = VisibModPrivate;
|
||||
*token_index += 1;
|
||||
} else {
|
||||
return nullptr;
|
||||
*token_index += 1;
|
||||
}
|
||||
|
||||
Token *struct_name = &pc->tokens->at(*token_index);
|
||||
*token_index += 1;
|
||||
ast_expect_token(pc, struct_name, TokenIdSymbol);
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeStructDecl, struct_kw);
|
||||
AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token);
|
||||
ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name);
|
||||
node->data.struct_decl.visib_mod = visib_mod;
|
||||
|
||||
ast_eat_token(pc, token_index, TokenIdLBrace);
|
||||
|
||||
|
|
|
@ -65,15 +65,15 @@ struct AstNodeRoot {
|
|||
ZigList<AstNode *> top_level_decls;
|
||||
};
|
||||
|
||||
enum FnProtoVisibMod {
|
||||
FnProtoVisibModPrivate,
|
||||
FnProtoVisibModPub,
|
||||
FnProtoVisibModExport,
|
||||
enum VisibMod {
|
||||
VisibModPrivate,
|
||||
VisibModPub,
|
||||
VisibModExport,
|
||||
};
|
||||
|
||||
struct AstNodeFnProto {
|
||||
ZigList<AstNode *> *directives;
|
||||
FnProtoVisibMod visib_mod;
|
||||
VisibMod visib_mod;
|
||||
Buf name;
|
||||
ZigList<AstNode *> params;
|
||||
AstNode *return_type;
|
||||
|
@ -284,6 +284,7 @@ struct AstNodeStructDecl {
|
|||
ZigList<AstNode *> fields;
|
||||
ZigList<AstNode *> fns;
|
||||
ZigList<AstNode *> *directives;
|
||||
VisibMod visib_mod;
|
||||
};
|
||||
|
||||
struct AstNodeStructField {
|
||||
|
|
146
std/errno.zig
146
std/errno.zig
|
@ -1,146 +0,0 @@
|
|||
pub const EPERM = 1; // Operation not permitted
|
||||
pub const ENOENT = 2; // No such file or directory
|
||||
pub const ESRCH = 3; // No such process
|
||||
pub const EINTR = 4; // Interrupted system call
|
||||
pub const EIO = 5; // I/O error
|
||||
pub const ENXIO = 6; // No such device or address
|
||||
pub const E2BIG = 7; // Arg list too long
|
||||
pub const ENOEXEC = 8; // Exec format error
|
||||
pub const EBADF = 9; // Bad file number
|
||||
pub const ECHILD = 10; // No child processes
|
||||
pub const EAGAIN = 11; // Try again
|
||||
pub const ENOMEM = 12; // Out of memory
|
||||
pub const EACCES = 13; // Permission denied
|
||||
pub const EFAULT = 14; // Bad address
|
||||
pub const ENOTBLK = 15; // Block device required
|
||||
pub const EBUSY = 16; // Device or resource busy
|
||||
pub const EEXIST = 17; // File exists
|
||||
pub const EXDEV = 18; // Cross-device link
|
||||
pub const ENODEV = 19; // No such device
|
||||
pub const ENOTDIR = 20; // Not a directory
|
||||
pub const EISDIR = 21; // Is a directory
|
||||
pub const EINVAL = 22; // Invalid argument
|
||||
pub const ENFILE = 23; // File table overflow
|
||||
pub const EMFILE = 24; // Too many open files
|
||||
pub const ENOTTY = 25; // Not a typewriter
|
||||
pub const ETXTBSY = 26; // Text file busy
|
||||
pub const EFBIG = 27; // File too large
|
||||
pub const ENOSPC = 28; // No space left on device
|
||||
pub const ESPIPE = 29; // Illegal seek
|
||||
pub const EROFS = 30; // Read-only file system
|
||||
pub const EMLINK = 31; // Too many links
|
||||
pub const EPIPE = 32; // Broken pipe
|
||||
pub const EDOM = 33; // Math argument out of domain of func
|
||||
pub const ERANGE = 34; // Math result not representable
|
||||
pub const EDEADLK = 35; // Resource deadlock would occur
|
||||
pub const ENAMETOOLONG = 36; // File name too long
|
||||
pub const ENOLCK = 37; // No record locks available
|
||||
pub const ENOSYS = 38; // Function not implemented
|
||||
pub const ENOTEMPTY = 39; // Directory not empty
|
||||
pub const ELOOP = 40; // Too many symbolic links encountered
|
||||
pub const EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
pub const ENOMSG = 42; // No message of desired type
|
||||
pub const EIDRM = 43; // Identifier removed
|
||||
pub const ECHRNG = 44; // Channel number out of range
|
||||
pub const EL2NSYNC = 45; // Level 2 not synchronized
|
||||
pub const EL3HLT = 46; // Level 3 halted
|
||||
pub const EL3RST = 47; // Level 3 reset
|
||||
pub const ELNRNG = 48; // Link number out of range
|
||||
pub const EUNATCH = 49; // Protocol driver not attached
|
||||
pub const ENOCSI = 50; // No CSI structure available
|
||||
pub const EL2HLT = 51; // Level 2 halted
|
||||
pub const EBADE = 52; // Invalid exchange
|
||||
pub const EBADR = 53; // Invalid request descriptor
|
||||
pub const EXFULL = 54; // Exchange full
|
||||
pub const ENOANO = 55; // No anode
|
||||
pub const EBADRQC = 56; // Invalid request code
|
||||
pub const EBADSLT = 57; // Invalid slot
|
||||
|
||||
pub const EBFONT = 59; // Bad font file format
|
||||
pub const ENOSTR = 60; // Device not a stream
|
||||
pub const ENODATA = 61; // No data available
|
||||
pub const ETIME = 62; // Timer expired
|
||||
pub const ENOSR = 63; // Out of streams resources
|
||||
pub const ENONET = 64; // Machine is not on the network
|
||||
pub const ENOPKG = 65; // Package not installed
|
||||
pub const EREMOTE = 66; // Object is remote
|
||||
pub const ENOLINK = 67; // Link has been severed
|
||||
pub const EADV = 68; // Advertise error
|
||||
pub const ESRMNT = 69; // Srmount error
|
||||
pub const ECOMM = 70; // Communication error on send
|
||||
pub const EPROTO = 71; // Protocol error
|
||||
pub const EMULTIHOP = 72; // Multihop attempted
|
||||
pub const EDOTDOT = 73; // RFS specific error
|
||||
pub const EBADMSG = 74; // Not a data message
|
||||
pub const EOVERFLOW = 75; // Value too large for defined data type
|
||||
pub const ENOTUNIQ = 76; // Name not unique on network
|
||||
pub const EBADFD = 77; // File descriptor in bad state
|
||||
pub const EREMCHG = 78; // Remote address changed
|
||||
pub const ELIBACC = 79; // Can not access a needed shared library
|
||||
pub const ELIBBAD = 80; // Accessing a corrupted shared library
|
||||
pub const ELIBSCN = 81; // .lib section in a.out corrupted
|
||||
pub const ELIBMAX = 82; // Attempting to link in too many shared libraries
|
||||
pub const ELIBEXEC = 83; // Cannot exec a shared library directly
|
||||
pub const EILSEQ = 84; // Illegal byte sequence
|
||||
pub const ERESTART = 85; // Interrupted system call should be restarted
|
||||
pub const ESTRPIPE = 86; // Streams pipe error
|
||||
pub const EUSERS = 87; // Too many users
|
||||
pub const ENOTSOCK = 88; // Socket operation on non-socket
|
||||
pub const EDESTADDRREQ = 89; // Destination address required
|
||||
pub const EMSGSIZE = 90; // Message too long
|
||||
pub const EPROTOTYPE = 91; // Protocol wrong type for socket
|
||||
pub const ENOPROTOOPT = 92; // Protocol not available
|
||||
pub const EPROTONOSUPPORT = 93; // Protocol not supported
|
||||
pub const ESOCKTNOSUPPORT = 94; // Socket type not supported
|
||||
pub const EOPNOTSUPP = 95; // Operation not supported on transport endpoint
|
||||
pub const EPFNOSUPPORT = 96; // Protocol family not supported
|
||||
pub const EAFNOSUPPORT = 97; // Address family not supported by protocol
|
||||
pub const EADDRINUSE = 98; // Address already in use
|
||||
pub const EADDRNOTAVAIL = 99; // Cannot assign requested address
|
||||
pub const ENETDOWN = 100; // Network is down
|
||||
pub const ENETUNREACH = 101; // Network is unreachable
|
||||
pub const ENETRESET = 102; // Network dropped connection because of reset
|
||||
pub const ECONNABORTED = 103; // Software caused connection abort
|
||||
pub const ECONNRESET = 104; // Connection reset by peer
|
||||
pub const ENOBUFS = 105; // No buffer space available
|
||||
pub const EISCONN = 106; // Transport endpoint is already connected
|
||||
pub const ENOTCONN = 107; // Transport endpoint is not connected
|
||||
pub const ESHUTDOWN = 108; // Cannot send after transport endpoint shutdown
|
||||
pub const ETOOMANYREFS = 109; // Too many references: cannot splice
|
||||
pub const ETIMEDOUT = 110; // Connection timed out
|
||||
pub const ECONNREFUSED = 111; // Connection refused
|
||||
pub const EHOSTDOWN = 112; // Host is down
|
||||
pub const EHOSTUNREACH = 113; // No route to host
|
||||
pub const EALREADY = 114; // Operation already in progress
|
||||
pub const EINPROGRESS = 115; // Operation now in progress
|
||||
pub const ESTALE = 116; // Stale NFS file handle
|
||||
pub const EUCLEAN = 117; // Structure needs cleaning
|
||||
pub const ENOTNAM = 118; // Not a XENIX named type file
|
||||
pub const ENAVAIL = 119; // No XENIX semaphores available
|
||||
pub const EISNAM = 120; // Is a named type file
|
||||
pub const EREMOTEIO = 121; // Remote I/O error
|
||||
pub const EDQUOT = 122; // Quota exceeded
|
||||
|
||||
pub const ENOMEDIUM = 123; // No medium found
|
||||
pub const EMEDIUMTYPE = 124; // Wrong medium type
|
||||
|
||||
// nameserver query return codes
|
||||
pub const ENSROK = 0; // DNS server returned answer with no data
|
||||
pub const ENSRNODATA = 160; // DNS server returned answer with no data
|
||||
pub const ENSRFORMERR = 161; // DNS server claims query was misformatted
|
||||
pub const ENSRSERVFAIL = 162; // DNS server returned general failure
|
||||
pub const ENSRNOTFOUND = 163; // Domain name not found
|
||||
pub const ENSRNOTIMP = 164; // DNS server does not implement requested operation
|
||||
pub const ENSRREFUSED = 165; // DNS server refused query
|
||||
pub const ENSRBADQUERY = 166; // Misformatted DNS query
|
||||
pub const ENSRBADNAME = 167; // Misformatted domain name
|
||||
pub const ENSRBADFAMILY = 168; // Unsupported address family
|
||||
pub const ENSRBADRESP = 169; // Misformatted DNS reply
|
||||
pub const ENSRCONNREFUSED = 170; // Could not contact DNS servers
|
||||
pub const ENSRTIMEOUT = 171; // Timeout while contacting DNS servers
|
||||
pub const ENSROF = 172; // End of file
|
||||
pub const ENSRFILE = 173; // Error reading file
|
||||
pub const ENSRNOMEM = 174; // Out of memory
|
||||
pub const ENSRDESTRUCTION = 175; // Application terminated lookup
|
||||
pub const ENSRQUERYDOMAINTOOLONG = 176; // Domain name is too long
|
||||
pub const ENSRCNAMELOOP = 177; // Domain name is too long
|
|
@ -1,17 +1,26 @@
|
|||
export executable "rand";
|
||||
|
||||
use "std.zig";
|
||||
|
||||
// Mersenne Twister
|
||||
const ARRAY_SIZE : u16 = 624;
|
||||
|
||||
/// Use `rand_init` to initialize this state.
|
||||
struct Rand {
|
||||
pub struct Rand {
|
||||
// TODO use ARRAY_SIZE here
|
||||
array: [624]u32,
|
||||
// TODO use #typeof(ARRAY_SIZE) here
|
||||
index: u16,
|
||||
|
||||
/// Initialize random state with the given seed.
|
||||
pub fn init(r: &Rand, seed: u32) {
|
||||
r.index = 0;
|
||||
r.array[0] = seed;
|
||||
var i : #typeof(ARRAY_SIZE) = 1;
|
||||
while (i < ARRAY_SIZE) {
|
||||
const prev_value : u64 = r.array[i - 1];
|
||||
r.array[i] = ((prev_value ^ (prev_value << 30)) * 0x6c078965 + i) as u32;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Get 32 bits of randomness.
|
||||
pub fn get_u32(r: &Rand) -> u32 {
|
||||
if (r.index == 0) {
|
||||
|
@ -90,31 +99,3 @@ struct Rand {
|
|||
}
|
||||
}
|
||||
|
||||
/// Initialize random state with the given seed.
|
||||
pub fn rand_init(r: &Rand, seed: u32) {
|
||||
r.index = 0;
|
||||
r.array[0] = seed;
|
||||
var i : #typeof(ARRAY_SIZE) = 1;
|
||||
while (i < ARRAY_SIZE) {
|
||||
const prev_value : u64 = r.array[i - 1];
|
||||
r.array[i] = ((prev_value ^ (prev_value << 30)) * 0x6c078965 + i) as u32;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
||||
var rand : Rand;
|
||||
var i : u8 = 0;
|
||||
while (i < 20) {
|
||||
rand_init(&rand, i);
|
||||
var j : u8 = 0;
|
||||
while (j < 20) {
|
||||
print_u64(rand.range_u64(0, 100) + 1);
|
||||
print_str(" ");
|
||||
j += 1;
|
||||
}
|
||||
print_str("\n");
|
||||
i += 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue