summaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-08-14 01:41:15 -0700
committerOri Bernstein <ori@eigenstate.org>2017-08-14 01:41:15 -0700
commitc76314e97ddc2e5d9ca2784c1e8333ce25c4ee77 (patch)
tree775fcd9f00f56488eb0521de84b6fae6b0351dca /lib/std
parentae172a3d21abd7c52f6d1ec827e0c03c25ef35a6 (diff)
parentbd96cb6a0a361a62871f70c07fc350bc2264b087 (diff)
downloadmc-c76314e97ddc2e5d9ca2784c1e8333ce25c4ee77.tar.gz
Merge branch 'master' into qbe
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/alloc.myr5
-rw-r--r--lib/std/bigint.myr2
-rw-r--r--lib/std/bitset.myr6
-rw-r--r--lib/std/bytealloc.myr3
-rw-r--r--lib/std/dial+posixy.myr1
-rw-r--r--lib/std/endian.myr8
-rw-r--r--lib/std/env+posixy.myr4
-rw-r--r--lib/std/execvp.myr4
-rw-r--r--lib/std/fltbits.myr10
-rw-r--r--lib/std/fmt.myr21
-rw-r--r--lib/std/hashfuncs.myr8
-rw-r--r--lib/std/intparse.myr4
-rw-r--r--lib/std/iterutil.myr2
-rw-r--r--lib/std/memops-impl+plan9-x64.s33
-rw-r--r--lib/std/memops-impl+posixy-x64.s43
-rw-r--r--lib/std/memops-impl.myr14
-rw-r--r--lib/std/memops.myr1
-rw-r--r--lib/std/optparse.myr8
-rw-r--r--lib/std/pathjoin.myr2
-rw-r--r--lib/std/resolve+posixy.myr6
-rw-r--r--lib/std/sleq.myr16
-rw-r--r--lib/std/slpush.myr6
-rw-r--r--lib/std/syswrap+plan9.myr8
-rw-r--r--lib/std/syswrap-ss+plan9.myr2
-rw-r--r--lib/std/test/bitset.myr10
-rw-r--r--lib/std/test/bytealloc.myr4
-rw-r--r--lib/std/test/fmt.myr2
-rw-r--r--lib/std/test/hashfuncs.myr2
-rw-r--r--lib/std/test/ipparse.myr4
-rw-r--r--lib/std/test/iterutil.myr6
-rw-r--r--lib/std/test/striter.myr4
-rw-r--r--lib/std/wait+plan9.myr55
-rw-r--r--lib/std/wait+posixy.myr32
33 files changed, 225 insertions, 111 deletions
diff --git a/lib/std/alloc.myr b/lib/std/alloc.myr
index aefa179..ac32ce5 100644
--- a/lib/std/alloc.myr
+++ b/lib/std/alloc.myr
@@ -6,6 +6,7 @@ use "threadhooks"
use "types"
use "units"
use "bytealloc"
+use "memops"
/*
The allocator implementation here is based on Bonwick's slab allocator.
@@ -142,9 +143,7 @@ generic slgrow = {sl : @a[:]#, len
new = slalloc(cap)
n = min(len, sl#.len)
- for var i = 0; i < n; i++
- new[i] = sl#[i]
- ;;
+ memblit((new : byte#), (sl# : byte#), n * sizeof(@a))
if sl#.len > 0
slfree(sl#)
;;
diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr
index f66659e..45170dd 100644
--- a/lib/std/bigint.myr
+++ b/lib/std/bigint.myr
@@ -252,7 +252,7 @@ const bigparse = {str
fit in one digit.
*/
v = mkbigint(1)
- for c in std.bychar(str)
+ for c : std.bychar(str)
if c == '_'
continue
;;
diff --git a/lib/std/bitset.myr b/lib/std/bitset.myr
index 937e65b..b173d87 100644
--- a/lib/std/bitset.myr
+++ b/lib/std/bitset.myr
@@ -38,7 +38,7 @@ pkg std =
;;
impl iterable bsiter -> size
- generic bybsvalue : (bs : bitset# -> bsiter)
+ const bybsvalue : (bs : bitset# -> bsiter)
;;
const mkbs = {
@@ -67,7 +67,7 @@ const bscount = {bs
var n
n = 0
- for v in bybsvalue(bs)
+ for v : bybsvalue(bs)
n++
;;
-> n
@@ -179,7 +179,7 @@ const eqsz = {a, b
ensurelen(b, sz)
}
-generic bybsvalue = {bs
+const bybsvalue = {bs
-> [.idx=0, .bs=bs]
}
diff --git a/lib/std/bytealloc.myr b/lib/std/bytealloc.myr
index 19f8477..51c0a34 100644
--- a/lib/std/bytealloc.myr
+++ b/lib/std/bytealloc.myr
@@ -54,7 +54,8 @@ type slab = struct
nfree : size /* the number of free nodes */
;;
-type chunk = struct /* NB: must be smaller than sizeof(slab) */
+/* NB: must be smaller than sizeof(slab) */
+type chunk = struct
next : chunk# /* the next chunk in the free list */
;;
diff --git a/lib/std/dial+posixy.myr b/lib/std/dial+posixy.myr
index 15fc58f..386dac5 100644
--- a/lib/std/dial+posixy.myr
+++ b/lib/std/dial+posixy.myr
@@ -22,6 +22,7 @@ pkg std =
a map from service name to a list of (port,proto)
pairs in order of preference
*/
+
/* FIXME: implement
var services : htab(byte[:], [int, byte[:]][:])#
var inited = false
diff --git a/lib/std/endian.myr b/lib/std/endian.myr
index 8bac74f..874ab71 100644
--- a/lib/std/endian.myr
+++ b/lib/std/endian.myr
@@ -1,6 +1,6 @@
pkg std =
- generic hosttonet : (v : @a -> @a)
- generic nettohost : (v : @a -> @a)
+ generic hosttonet : (v : @a::(integral,numeric) -> @a::(integral,numeric))
+ generic nettohost : (v : @a::(integral,numeric) -> @a::(integral,numeric))
;;
/* FIXME: we only support little endian platforms right now,
@@ -10,7 +10,7 @@ generic hosttonet = {v : @a::(integral,numeric)
var ret
ret = 0
- for i = 0; i < sizeof(@a); i++
+ for i = 0; i < sizeof(@a::(integral,numeric)); i++
ret <<= 8
ret |= v & 0xff
v >>= 8
@@ -23,7 +23,7 @@ generic nettohost = {v : @a::(integral,numeric)
var ret
ret = 0
- for i = 0; i < sizeof(@a); i++
+ for i = 0; i < sizeof(@a::(integral,numeric)); i++
ret <<= 8
ret |= v & 0xff
v >>= 8
diff --git a/lib/std/env+posixy.myr b/lib/std/env+posixy.myr
index 3919388..fe73c7e 100644
--- a/lib/std/env+posixy.myr
+++ b/lib/std/env+posixy.myr
@@ -26,7 +26,7 @@ const getenv = {name
var n, env
envinit()
- for envp in environ
+ for envp : environ
env = cstrconvp(envp)
n = min(name.len, env.len)
if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
@@ -48,7 +48,7 @@ const setenv = {name, val
envdup()
idx = 0
- for envp in environ
+ for envp : environ
env = cstrconvp(envp)
n = min(name.len, env.len)
if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
diff --git a/lib/std/execvp.myr b/lib/std/execvp.myr
index c719e5c..f6696e3 100644
--- a/lib/std/execvp.myr
+++ b/lib/std/execvp.myr
@@ -21,7 +21,7 @@ const execvp = {cmd, args
-> execv(cmd, args)
| `None:
paths = getpaths()
- for p in paths
+ for p : paths
binpath = bfmt(buf[:], "{}/{}", p, cmd)
execv(binpath, args)
;;
@@ -39,7 +39,7 @@ const execvpe = {cmd, args, env
-> execve(cmd, args, env)
| `None:
paths = getpaths()
- for p in paths
+ for p : paths
binpath = bfmt(buf[:], "{}/{}", p, cmd)
execve(binpath, args, env)
;;
diff --git a/lib/std/fltbits.myr b/lib/std/fltbits.myr
index 2a9e8cf..f9afd7a 100644
--- a/lib/std/fltbits.myr
+++ b/lib/std/fltbits.myr
@@ -24,9 +24,9 @@ const flt64explode = {flt
var bits, isneg, mant, exp
bits = flt64bits(flt)
- isneg = (bits >> 63) != 0 /* msb is sign bit */
+ isneg = (bits >> 63) != 0 /* msb is sign bit */
exp = (bits >> 52) & 0x7ff /* exp is in bits [52..63] */
- mant = bits & ((1l << 52) - 1) /* msb is in bits [..51] */
+ mant = bits & ((1l << 52) - 1) /* msb is in bits [..51] */
/* add back the implicit bit if this is not a denormal */
if exp != 0
@@ -47,9 +47,9 @@ const flt32explode = {flt
var bits, isneg, mant, exp
bits = flt32bits(flt)
- isneg = (bits >> 31) != 0 /* msb is sign bit */
- exp = (bits >> 22) & 0xff /* exp is in bits [23..30] */
- mant = bits & ((1 << 22) - 1) /* msb is in bits [0..22] */
+ isneg = (bits >> 31) != 0 /* msb is sign bit */
+ exp = (bits >> 22) & 0xff /* exp is in bits [23..30] */
+ mant = bits & ((1 << 22) - 1) /* msb is in bits [0..22] */
/* add back the implicit bit if this is not a denormal */
if exp != 0
diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr
index 92782d3..11268e4 100644
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -216,7 +216,7 @@ const parseparams = {paramstr, optdesc
std.fatal("invalid format options {}\n")
;;
params = strsplit(paramstr, ",")
- for p in params
+ for p : params
/* parse out the key/value pair */
match std.strfind(p, "=")
| `std.Some idx:
@@ -231,7 +231,7 @@ const parseparams = {paramstr, optdesc
found = false
/* verify and add the arg */
- for (opt, hasarg) in optdesc
+ for (opt, hasarg) : optdesc
if !std.sleq(opt, o)
continue
;;
@@ -245,10 +245,11 @@ const parseparams = {paramstr, optdesc
;;
if !found
std.put("options: \n")
- for (opt, hasarg) in optdesc
+ for (opt, hasarg) : optdesc
std.put("\t'{}', hasarg={}\n", opt, hasarg)
;;
- std.fatal("invalid option '{}' ", o)
+ std.put("invalid option '{}' ", o)
+ std.die("dying")
;;
;;
slfree(params)
@@ -427,7 +428,7 @@ const fmtslice = {sb, subap, params
][:])
join = ", "
joined = false
- for o in opts
+ for o : opts
match o
| ("j", j):
joined = true
@@ -483,7 +484,7 @@ const intparams = {params
("x", false),
("w", true),
("p", true)][:])
- for o in opts
+ for o : opts
match o
| ("x", ""): ip.base = 16
| ("w", wid): ip.padto = getint(wid, "fmt: width must be integer")
@@ -511,7 +512,7 @@ const strfmt = {sb, str, params
("e", false),
][:])
- for o in opts
+ for o : opts
match o
| ("w", wid): w = getint(wid, "fmt: width must be integer")
| ("p", pad): p = decode(pad)
@@ -523,14 +524,14 @@ const strfmt = {sb, str, params
iassert(p >= 0, "pad must be >= 0")
std.slfree(opts)
if raw
- for b in str
+ for b : str
if esc
sbputs(sb, "\\x")
;;
intfmt(sb, [.padto=2, .padfill='0', .base=16], false, b)
;;
elif esc
- for b in str
+ for b : str
if isprint(b)
sbputb(sb, b)
else
@@ -594,7 +595,7 @@ generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric)
;;
else
val = (bits : uint64)
- val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a)))
+ val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a::(integral,numeric))))
isneg = false
;;
diff --git a/lib/std/hashfuncs.myr b/lib/std/hashfuncs.myr
index 565ddcc..3046377 100644
--- a/lib/std/hashfuncs.myr
+++ b/lib/std/hashfuncs.myr
@@ -121,17 +121,19 @@ const murmurhash2 = {data, seed
match data.len
| 3:
h ^= (data[2] : uint32) << 16
- h ^= (data[1] : uint32) <<8
+ h ^= (data[1] : uint32) << 8
h ^= (data[0] : uint32)
+ h *= m
| 2:
- h ^= (data[1] : uint32) <<8
+ h ^= (data[1] : uint32) << 8
h ^= (data[0] : uint32)
+ h *= m
| 1:
h ^= (data[0] : uint32)
+ h *= m
| 0: /* nothing */
| _: die("0 < len < 4 must be true")
;;
- h *= m
h ^= h >> 13
h *= m
diff --git a/lib/std/intparse.myr b/lib/std/intparse.myr
index 405e6c3..18cc478 100644
--- a/lib/std/intparse.myr
+++ b/lib/std/intparse.myr
@@ -47,12 +47,12 @@ generic intparsebase = {s, base
-> doparse(s, isneg, base)
}
-generic doparse = {s, isneg, base
+generic doparse = {s, isneg, base -> option(@a::(integral,numeric))
var v
var cv : int32
v = 0
- for c in std.bychar(s)
+ for c : std.bychar(s)
if c == '_'
continue
;;
diff --git a/lib/std/iterutil.myr b/lib/std/iterutil.myr
index ad45e0b..79b0e80 100644
--- a/lib/std/iterutil.myr
+++ b/lib/std/iterutil.myr
@@ -38,7 +38,7 @@ pkg std =
generic byzip : (a : @a[:], b : @b[:] -> zipiter(@a, @b))
generic byenum : (a : @a[:] -> enumiter(@a))
generic byreverse : (sl : @a[:] -> reverseiter(@a))
- generic byref : (sl : @a[:] -> reverseiter(@a))
+ generic byref : (sl : @a[:] -> refiter(@a))
generic bychunk : (a : @a[:], chunk : size -> chunkiter(@a))
;;
diff --git a/lib/std/memops-impl+plan9-x64.s b/lib/std/memops-impl+plan9-x64.s
index 088ee22..2d216ed 100644
--- a/lib/std/memops-impl+plan9-x64.s
+++ b/lib/std/memops-impl+plan9-x64.s
@@ -42,3 +42,36 @@ TEXT std$memfill+0(SB),$0
ANDQ $7,CX
REP; STOSB
RET
+
+TEXT std$memeq+0(SB),$0
+ MOVQ DX,R8
+ ANDQ $~0x7,R8
+ JZ .dotail
+.nextquad:
+ MOVQ (DI),R9
+ MOVQ (SI),R10
+ XORQ R10,R9
+ JNZ .unequal
+ ADDQ $8,SI
+ ADDQ $8,DI
+ SUBQ $8,R8
+ JNZ .nextquad
+.dotail:
+ ANDQ $0x7,DX
+ TESTQ DX,DX
+ JZ .equal
+.nextbyte:
+ MOVBLZX (DI),R9
+ MOVBLZX (SI),R10
+ XORL R10,R9
+ JNZ .unequal
+ ADDQ $1,SI
+ ADDQ $1,DI
+ SUBQ $1,DX
+ JNZ .nextbyte
+.equal:
+ MOVQ $1,AX
+ RET
+.unequal:
+ MOVQ $0,AX
+ RET
diff --git a/lib/std/memops-impl+posixy-x64.s b/lib/std/memops-impl+posixy-x64.s
index c2a3d14..899aaca 100644
--- a/lib/std/memops-impl+posixy-x64.s
+++ b/lib/std/memops-impl+posixy-x64.s
@@ -1,7 +1,4 @@
-/*
-std.memblit : (dst : byte#, src : byte#, len : std.size -> void)
-std.memfill : (dst : byte#, val : byte, len : std.size -> void)
-*/
+/* std.memblit : (dst : byte#, src : byte#, len : std.size -> void) */
.globl _std$memblit
.globl std$memblit
_std$memblit:
@@ -30,6 +27,7 @@ std$memblit:
.done:
ret
+/* std.memfill : (dst : byte#, val : byte, len : std.size -> void) */
.globl _std$memfill
.globl std$memfill
_std$memfill:
@@ -47,3 +45,40 @@ std$memfill:
andq $7,%rcx
rep stosb
ret
+
+/* std.memeq : (a : byte#, b : byte#, len : std.size -> bool) */
+.globl _std$memeq
+.globl std$memeq
+_std$memeq:
+std$memeq:
+ movq %rdx,%r8
+ andq $~0x7,%r8
+ jz .dotail
+.nextquad:
+ movq (%rdi),%r9
+ movq (%rsi),%r10
+ xorq %r10,%r9
+ jnz .unequal
+ addq $8,%rsi
+ addq $8,%rdi
+ subq $8,%r8
+ jnz .nextquad
+.dotail:
+ andq $0x7,%rdx
+ testq %rdx,%rdx
+ jz .equal
+.nextbyte:
+ movzbl (%rdi),%r9d
+ movzbl (%rsi),%r10d
+ xorl %r10d,%r9d
+ jnz .unequal
+ addq $1,%rsi
+ addq $1,%rdi
+ subq $1,%rdx
+ jnz .nextbyte
+.equal:
+ movq $1,%rax
+ ret
+.unequal:
+ movq $0,%rax
+ ret
diff --git a/lib/std/memops-impl.myr b/lib/std/memops-impl.myr
index 7a84945..67c67d3 100644
--- a/lib/std/memops-impl.myr
+++ b/lib/std/memops-impl.myr
@@ -3,6 +3,7 @@ use "types"
pkg std =
pkglocal const memblit : (dst : byte#, src : byte#, len : std.size -> void)
pkglocal const memfill : (dst : byte#, val : byte, len : std.size -> void)
+ pkglocal const memeq : (a : byte#, b : byte#, len : std.size -> bool)
;;
@@ -37,3 +38,16 @@ const memfill = {dst, val, len
;;
}
+const memeq = {a, b, len
+ var sa, sb
+
+ sa = a[:len]
+ sb = b[:len]
+ for i = 0; i < len; i++
+ if sa[i] != sb[i]
+ -> false
+ ;;
+ ;;
+ -> true
+}
+
diff --git a/lib/std/memops.myr b/lib/std/memops.myr
index a5b5b4a..7eb7e8f 100644
--- a/lib/std/memops.myr
+++ b/lib/std/memops.myr
@@ -3,5 +3,6 @@ use "types"
pkg std =
pkglocal extern const memblit : (dst : byte#, src : byte#, len : std.size -> void)
pkglocal extern const memfill : (dst : byte#, val : byte, len : std.size -> void)
+ pkglocal extern const memeq : (a : byte#, b : byte#, len : std.size -> bool)
;;
diff --git a/lib/std/optparse.myr b/lib/std/optparse.myr
index a2cf06c..0569dfc 100644
--- a/lib/std/optparse.myr
+++ b/lib/std/optparse.myr
@@ -153,7 +153,7 @@ const optdone = {ctx
}
const optinfo = {ctx, opt
- for o in ctx.optdef.opts
+ for o : ctx.optdef.opts
if o.opt == opt
-> `Some (o.arg.len != 0, !o.optional, o.dest)
;;
@@ -189,13 +189,13 @@ const optusage = {prog, def
sb = mksb()
std.sbfmt(sb, "usage: {} [-h?", prog)
- for o in def.opts
+ for o : def.opts
if o.arg.len == 0
std.sbfmt(sb, "{}", o.opt)
;;
;;
std.sbfmt(sb, "] ")
- for o in def.opts
+ for o : def.opts
if o.arg.len != 0
std.sbfmt(sb, "[-{} {}] ", o.opt, o.arg)
;;
@@ -203,7 +203,7 @@ const optusage = {prog, def
std.sbfmt(sb, "{}\n", def.argdesc)
std.sbfmt(sb, "\t-h\tprint this help message\n")
std.sbfmt(sb, "\t-?\tprint this help message\n")
- for o in def.opts
+ for o : def.opts
std.sbfmt(sb, "\t-{}{}{}\t{}\n", o.opt, sep(o.arg), o.arg, o.desc)
;;
s = sbfin(sb)
diff --git a/lib/std/pathjoin.myr b/lib/std/pathjoin.myr
index 2cc2340..eb5e6fd 100644
--- a/lib/std/pathjoin.myr
+++ b/lib/std/pathjoin.myr
@@ -42,7 +42,7 @@ const pathnorm = {p
/*
"." is a no-op component, so we drop it. In order
to drop a component, we set it to the empty string,
- and remove it later on in the code.
+ and remove it later on.
*/
for i = 0; i < comps.len; i++
if sleq(comps[i], ".")
diff --git a/lib/std/resolve+posixy.myr b/lib/std/resolve+posixy.myr
index 50962a7..06250d5 100644
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -123,7 +123,7 @@ const loadhosts = {
;;
lines = strsplit(h, "\n")
- for l in lines
+ for l : lines
/* trim comment */
match strfind(l, "#")
| `Some idx: l = l[:idx]
@@ -190,7 +190,7 @@ const loadresolv = {
;;
lines = strsplit(h, "\n")
- for l in lines
+ for l : lines
match strfind(l, "#")
| `Some _idx: l = l[:_idx]
| `None:
@@ -247,7 +247,7 @@ const dnsresolve = {host, rt
-> `Err (`Badhost)
;;
/* FIXME: Assumption: nameservers is not modified by other threads */
- for ns in nameservers
+ for ns : nameservers
nsrv = dnsconnect(ns)
if nsrv >= 0
r = dnsquery(nsrv, host, rt)
diff --git a/lib/std/sleq.myr b/lib/std/sleq.myr
index cfc60b4..e913cd6 100644
--- a/lib/std/sleq.myr
+++ b/lib/std/sleq.myr
@@ -1,18 +1,14 @@
+use "types"
+use "memops"
+
pkg std =
generic sleq : (a : @a[:], b : @a[:] -> bool)
;;
generic sleq = {a, b
- var i
-
- if a.len != b.len
+ if a.len == b.len
+ -> memeq((a : byte#), (b : byte#), a.len)
+ else
-> false
;;
-
- for i = 0; i < a.len; i++
- if a[i] != b[i]
- -> false
- ;;
- ;;
- -> true
}
diff --git a/lib/std/slpush.myr b/lib/std/slpush.myr
index 1790073..b09069c 100644
--- a/lib/std/slpush.myr
+++ b/lib/std/slpush.myr
@@ -10,9 +10,9 @@ generic slpush = {sl, elt
slpush relies on implementation details
of slgrow for efficiency. Because bucket
sizes come in powers of two for all buckets
- <= 32k, and we only reallocate when we hit
- a bucket boundary, this is effectively
- growing the slice by powers of two.
+ <= 32k, and by powers of 1.5 for larger
+ slices, this is effectively growing the
+ slice by powers of two.
*/
slgrow(sl, sl#.len + 1)
sl#[sl#.len - 1] = elt
diff --git a/lib/std/syswrap+plan9.myr b/lib/std/syswrap+plan9.myr
index 17b1f39..ddf37ab 100644
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -135,7 +135,7 @@ const fmtime = {path
if sys.stat(path, buf[:]) < Stringsoff
-> `Err Emisc
;;
- -> `Ok (_getle32(buf[Mtimeoff:Mtimeoff + 8]) : time)
+ -> `Ok ((_getle32(buf[Mtimeoff:Mtimeoff + 8]) : time)*1_000_000)
}
const fsize = {path
@@ -270,19 +270,19 @@ generic check = {e : @a::(integral, numeric) -> result(@b, errno)
}
/* duplicated code to break dependency cycle */
-generic _getle16 = {buf
+generic _getle16 = {buf -> @a::(numeric,integral)
-> ((buf[0] : @a::(numeric,integral)) << 0) | \
((buf[1] : @a::(numeric,integral)) << 8)
}
-generic _getle32 = {buf
+generic _getle32 = {buf -> @a::(numeric,integral)
-> ((buf[0] : @a::(numeric,integral)) << 0) | \
((buf[1] : @a::(numeric,integral)) << 8) | \
((buf[2] : @a::(numeric,integral)) << 16) | \
((buf[3] : @a::(numeric,integral)) << 24)
}
-generic _getle64 = {buf
+generic _getle64 = {buf -> @a::(numeric,integral)
-> ((buf[0] : @a::(numeric,integral)) << 0) | \
((buf[1] : @a::(numeric,integral)) << 8) | \
((buf[2] : @a::(numeric,integral)) << 16) | \
diff --git a/lib/std/syswrap-ss+plan9.myr b/lib/std/syswrap-ss+plan9.myr
index 7a86564..96a2973 100644
--- a/lib/std/syswrap-ss+plan9.myr
+++ b/lib/std/syswrap-ss+plan9.myr
@@ -74,7 +74,7 @@ const lasterr = {
err = cstrconv(errbuf[:])
if strhas(err, "no error")
-> Enone
- elif strhas(err, "already exists")
+ elif strhas(err, "already exists") || strhas(err, "is a directory")
-> Eexist
elif strhas(err, "read or write too large")
-> Erange
diff --git a/lib/std/test/bitset.myr b/lib/std/test/bitset.myr
index 0415be8..9112537 100644
--- a/lib/std/test/bitset.myr
+++ b/lib/std/test/bitset.myr
@@ -36,7 +36,7 @@ const main = {
std.bsput(bs, 16)
std.bsput(bs, 7)
std.bsput(bs, 3)
- for e in std.bybsvalue(bs)
+ for e : std.bybsvalue(bs)
testr.check(ctx, e == expected[i], "expected[{}] ({}) != {}", i, e, expected[i])
i++
;;
@@ -49,11 +49,11 @@ const main = {
}],
[.name="hash", .fn={ctx
var bs = mkset([][:])
- testr.check(ctx, std.bshash(bs) == 493832887, "wrong hash, expected {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 2580988821, "wrong hash, got {}", std.bshash(bs))
std.bsput(bs, 123456)
- testr.check(ctx, std.bshash(bs) == 746495367, "wrong hash, expected {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 2020624217, "wrong hash, got {}", std.bshash(bs))
std.bsdel(bs, 123456)
- testr.check(ctx, std.bshash(bs) == 493832887, "wrong hash, expected {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 2580988821, "wrong hash, got {}", std.bshash(bs))
std.bsfree(bs)
}]
][:])
@@ -63,7 +63,7 @@ const mkset = {elts
var bs
bs = std.mkbs()
- for e in elts
+ for e : elts
std.bsput(bs, e)
;;
-> bs
diff --git a/lib/std/test/bytealloc.myr b/lib/std/test/bytealloc.myr
index e6d87d6..7da7de8 100644
--- a/lib/std/test/bytealloc.myr
+++ b/lib/std/test/bytealloc.myr
@@ -3,9 +3,9 @@ use std
const main = {
var a : byte#[1000]
- for sz in [10, 100, 1000, 10000, 10000]
+ for sz : [10, 100, 1000, 10000, 10000]
std.put("sz: {}\n", sz)
- for cnt in [1, 10, 100]
+ for cnt : [1, 10, 100]
std.put("cnt: {}\n", cnt)
/* alloc forwards, dealloc forwards */
for var i = 0; i < cnt; i++
diff --git a/lib/std/test/fmt.myr b/lib/std/test/fmt.myr
index e8e3f22..67ba2e4 100644
--- a/lib/std/test/fmt.myr
+++ b/lib/std/test/fmt.myr
@@ -154,7 +154,7 @@ const pairfmt = {sb, ap, opts
x = std.vanext(ap)
std.sbfmt(sb, "formatted a pair: [{}, {}]", x.x, x.y)
- for opt in opts
+ for opt : opts
std.sbputc(sb, ' ')
match opt
| ("x", val): std.sbfmt(sb, "x={}", val)
diff --git a/lib/std/test/hashfuncs.myr b/lib/std/test/hashfuncs.myr
index 9132f2b..d2b1161 100644
--- a/lib/std/test/hashfuncs.myr
+++ b/lib/std/test/hashfuncs.myr
@@ -15,7 +15,7 @@ const main = {
std.assert(std.ptreq(&x, &x), "equal pointers not equal")
std.assert(!std.ptreq(&x, &y), "unequal pointers are equal")
- std.assert(std.inthash(123) == 2379201998, "wrong int hash")
+ std.assert(std.inthash(123) == 3497506805, "wrong int hash")
std.assert(std.inteq(123, 123), "equal integers not equal")
std.assert(!std.inteq(123, 456), "unequal integers are equal")
diff --git a/lib/std/test/ipparse.myr b/lib/std/test/ipparse.myr
index 1ea14db..fd6140a 100644
--- a/lib/std/test/ipparse.myr
+++ b/lib/std/test/ipparse.myr
@@ -69,11 +69,11 @@ const eq = {ip, expected
if !std.sleq(p, e)
std.fput(1, "misparsed ip {}\n", ip)
std.put("parsed: ")
- for b in p
+ for b : p
std.put("{x}, ", b)
;;
std.put("\nexpected: ")
- for b in e
+ for b : e
std.put("{x}, ", b)
;;
std.put("\n")
diff --git a/lib/std/test/iterutil.myr b/lib/std/test/iterutil.myr
index dfa46fa..1d45a4d 100644
--- a/lib/std/test/iterutil.myr
+++ b/lib/std/test/iterutil.myr
@@ -4,21 +4,21 @@ const main = {
var n
n = 0
- for (x, i) in std.byenum([1,3,5,7,9][:])
+ for (x, i) : std.byenum([1,3,5,7,9][:])
std.assert(x == n, "invalid enum idx {}", x)
std.assert(i == n*2 + 1, "invalid enum val {}", i)
n++
;;
n = 0
- for (a, b) in std.byzip([0,2,4,6,8][:], [2,4][:])
+ for (a, b) : std.byzip([0,2,4,6,8][:], [2,4][:])
std.assert(a == n*2, "invalid val from a: {}", a)
std.assert(b == n*2 + 2, "invalid val from b: {}", b)
n++
;;
n = 0
- for x in std.byreverse([3, 2, 1, 0][:])
+ for x : std.byreverse([3, 2, 1, 0][:])
std.assert(x == n, "invalid reversed value {}, expected {}", x, n)
n++
;;
diff --git a/lib/std/test/striter.myr b/lib/std/test/striter.myr
index 2684f8d..90b38ed 100644
--- a/lib/std/test/striter.myr
+++ b/lib/std/test/striter.myr
@@ -6,13 +6,13 @@ const main = {
var i
i = 0
- for c in std.bychar("abc")
+ for c : std.bychar("abc")
std.assert(chars[i++] == c, "wrong char")
;;
std.assert(i == chars.len, "wrong split count")
i = 0
- for sp in std.bysplit("foo+++bar", "++")
+ for sp : std.bysplit("foo+++bar", "++")
std.assert(std.streq(splits[i++], sp), "wrong split {}", sp)
;;
std.assert(i == splits.len, "wrong split count")
diff --git a/lib/std/wait+plan9.myr b/lib/std/wait+plan9.myr
index 720b66b..44177db 100644
--- a/lib/std/wait+plan9.myr
+++ b/lib/std/wait+plan9.myr
@@ -15,6 +15,7 @@ use "syswrap"
use "utf"
use "sleq"
use "fmt"
+use "threadhooks"
pkg std =
type waitstatus = union
@@ -25,53 +26,73 @@ pkg std =
;;
const wait : (pid : pid -> waitstatus)
+ const waitany : (-> (pid, waitstatus))
;;
-var statusinit : bool = false
var statusmap : htab(pid, waitstatus)#
+const __init__ = {
+ statusmap = mkht(inthash, inteq)
+}
+
+const waitany = {
+ var buf : byte[512]
+ var ret, it
+
+ lock(envlck)
+ if htcount(statusmap) == 0
+ unlock(envlck)
+ match sys.await(buf[:])
+ | -1: -> (-1, `Waiterror)
+ | n: -> parsestatus(buf[:n])
+ ;;
+ else
+ it = std.byhtkeyvals(statusmap)
+ __iternext__(&it, &ret)
+ unlock(envlck)
+ -> ret
+ ;;
+}
+
const wait = {pid
var buf : byte[512]
var xpid, status
- var n
- if !statusinit
- statusmap = mkht(inthash, inteq)
- statusinit = true
- ;;
-
+ lock(envlck)
match htget(statusmap, pid)
+ | `None:
| `Some st:
+ unlock(envlck)
htdel(statusmap, pid)
-> st
- | `None: /* nothing */
;;
+ unlock(envlck)
while true
- n = sys.await(buf[:])
- if n < 0
- -> `Waiterror
+ match sys.await(buf[:])
+ | -1: -> `Waiterror
+ | n: (xpid, status) = parsestatus(buf[:n])
;;
-
- (status, xpid) = parsestatus(buf[:n])
if xpid == pid
-> status
else
- htput(statusmap, pid, status)
+ lock(envlck)
+ htput(statusmap, xpid, status)
+ unlock(envlck)
;;
;;
/* impossible */
-> `Waiterror
}
-const parsestatus = {status -> (waitstatus, pid)
+const parsestatus = {status -> (pid, waitstatus)
var st : waitstatus
var spbuf : byte[:][5]
var xpid, sp
sp = bstrsplit(spbuf[:], status, " ")
if sp.len == 0
- -> (`Wfailure, -1)
+ -> (-1, `Wfailure)
;;
match intparse(sp[0])
@@ -90,7 +111,7 @@ const parsestatus = {status -> (waitstatus, pid)
st = `Waiterror
;;
- -> (st, xpid)
+ -> (xpid, st)
}
diff --git a/lib/std/wait+posixy.myr b/lib/std/wait+posixy.myr
index bd9ae31..b04aab4 100644
--- a/lib/std/wait+posixy.myr
+++ b/lib/std/wait+posixy.myr
@@ -12,13 +12,27 @@ pkg std =
;;
const wait : (pid : pid -> waitstatus)
+ const waitany : (-> (pid, waitstatus))
;;
+const waitany = {
+ match dowait(-1)
+ | (p, st): -> ((p : pid), st)
+ ;;
+}
+
const wait = {pid
- var st
+ match dowait(pid)
+ | (_, st): -> st
+ ;;
+}
+
+const dowait = {pid
+ var st, p
:again
- if sys.waitpid((pid : sys.pid), &st, 0) > 0
+ p = sys.waitpid((pid : sys.pid), &st, 0)
+ if p > 0
match sys.waitstatus(st)
/*
when a process stops, eg, if paused by a debugger,
@@ -26,16 +40,12 @@ const wait = {pid
a process exits. Loop instead.
*/
| `sys.Waitstop sig: goto again
- | `sys.Waitfail fail: -> `Waiterror
- | `sys.Waitsig sig: -> `Wsignalled
- | `sys.Waitexit status:
- if status == 0
- -> `Wsuccess
- else
- -> `Wfailure
- ;;
+ | `sys.Waitfail fail: -> (p, `Waiterror)
+ | `sys.Waitsig sig: -> (p, `Wsignalled)
+ | `sys.Waitexit 0: -> (p, `Wsuccess)
+ | `sys.Waitexit _: -> (p, `Wfailure)
;;
;;
- -> `Waiterror
+ -> (-1, `Waiterror)
}