diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index e84afb62..96125051 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -419,6 +419,14 @@ B makeRand_c1(B t, B x) { ns_set(r, rand_subsetName, m_nfn(rand_subsetDesc, inc(r))); return r; } +static B randNS; +B getRandNS() { + if (randNS.u == 0) { + randNS = c1(bi_makeRand,m_f64(RANDSEED)); + gc_add(randNS); + } + return inc(randNS); +} extern B replPath; // defined in main.c static NFnDesc* reBQNDesc; B reBQN_c1(B t, B x) { @@ -531,15 +539,27 @@ B list_c1(B d, B x) { return file_list(path_resolve(nfn_objU(d), x)); } +B unixTime_c1(B t, B x) { + dec(x); + return m_i32(time(NULL)); +} +B monoTime_c1(B t, B x) { + dec(x); + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return m_i32(ts.tv_sec); +} B delay_c1(B t, B x) { f64 sf = o2f(x); if (sf<0 || sf>1ULL<<63) thrF("•Delay: Bad argument: %f", sf); - struct timespec ts; + struct timespec ts,ts0; u64 s = (u64)sf; ts.tv_sec = (u64)sf; ts.tv_nsec = (u64)((sf-s)*1e9); + clock_gettime(CLOCK_MONOTONIC, &ts0); nanosleep(&ts, &ts); - return x; // TODO figure out how to return an actually correct thing + clock_gettime(CLOCK_MONOTONIC, &ts); + return m_f64(ts.tv_sec-ts0.tv_sec+(ts.tv_nsec-ts0.tv_nsec)*1e-9); } B exit_c1(B t, B x) { bqn_exit(q_i32(x)? o2i(x) : 0); @@ -672,6 +692,8 @@ B sys_c1(B t, B x) { else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd); else if (eqStr(c, U"bqn")) r.a[i] = inc(bi_bqn); else if (eqStr(c, U"cmp")) r.a[i] = inc(bi_cmp); + else if (eqStr(c, U"unixtime")) r.a[i] = inc(bi_unixTime); + else if (eqStr(c, U"monotime")) r.a[i] = inc(bi_monoTime); else if (eqStr(c, U"timed")) r.a[i] = inc(bi_timed); else if (eqStr(c, U"delay")) r.a[i] = inc(bi_delay); else if (eqStr(c, U"hash")) r.a[i] = inc(bi_hash); @@ -679,6 +701,7 @@ B sys_c1(B t, B x) { else if (eqStr(c, U"fmt")) r.a[i] = inc(bi_fmt); else if (eqStr(c, U"glyph")) r.a[i] = inc(bi_glyph); else if (eqStr(c, U"makerand")) r.a[i] = inc(bi_makeRand); + else if (eqStr(c, U"rand")) r.a[i] = getRandNS(); else if (eqStr(c, U"rebqn")) r.a[i] = inc(bi_reBQN); else if (eqStr(c, U"fromutf8")) r.a[i] = inc(bi_fromUtf8); else if (eqStr(c, U"path")) r.a[i] = inc(REQ_PATH); diff --git a/src/h.h b/src/h.h index 4e590910..79f68220 100644 --- a/src/h.h +++ b/src/h.h @@ -36,6 +36,9 @@ #ifndef FORMATTER #define FORMATTER 1 // use self-hosted formatter for output #endif +#ifndef RANDSEED + #define RANDSEED 1 // random seed used to make •rand +#endif // #define HEAP_VERIFY // enable usage of heapVerify() // #define ALLOC_STAT // store basic allocation statistics diff --git a/src/utils/builtins.h b/src/utils/builtins.h index 0e2c5c7e..e978163b 100644 --- a/src/utils/builtins.h +++ b/src/utils/builtins.h @@ -9,7 +9,7 @@ /* everything before the definition of •Type is defined to be pure, and everything after is not */ \ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \ /* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") M(sh,"•SH") M(fromUtf8,"•FromUTF8") \ -/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \ +/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(unixTime,"•UnixTime") M(monoTime,"•MonoTime") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \ /*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare")