shithub: mc

Download patch

ref: 2bc852bda98762d3bc01548bf972e3f1b137fbfb
parent: 3de952510eb2a23350d24ed926f19c0cf72a12f2
author: Ori Bernstein <[email protected]>
date: Wed Aug 26 08:20:58 EDT 2015

Move Myrddin libs to lib/ subdirectory.

--- a/bld.proj
+++ b/bld.proj
@@ -1,9 +1,6 @@
 sub =
 	mbld
-	libstd
-	libbio
-	libregex
-	libcryptohash
+	lib
 	test
 ;;
 
--- /dev/null
+++ b/lib/bio/bio.myr
@@ -1,0 +1,502 @@
+use std
+
+pkg bio =
+	type mode = int
+	const Rd	: mode = 1
+	const Wr	: mode = 2
+	const Rw	: mode = 1 | 2
+
+	type file = struct
+		/* backing fd */
+		fd	: std.fd
+		mode	: mode
+
+		/* read buffer */
+		rbuf	: byte[:]
+		rstart	: std.size
+		rend	: std.size
+
+		/* write buffer */
+		wbuf	: byte[:]
+		wend	: std.size
+	;;
+
+	/* creation */
+	const mkfile	: (fd : std.fd, mode : mode	-> file#)
+	const open	: (path : byte[:], mode : mode	-> std.result(file#, byte[:]))
+	const dial	: (srv	: byte[:], mode : mode	-> std.result(file#, byte[:]))
+	const create	: (path : byte[:], mode : mode, perm : int	-> std.result(file#, byte[:]))
+	const close	: (f : file# -> bool)
+	const free	: (f : file# -> void)
+
+	/* basic i/o. Returns sub-buffer when applicable. */
+	const write	: (f : file#, src : byte[:]	-> std.size)
+	const read	: (f : file#, dst : byte[:]	-> std.option(byte[:]))
+	const flush	: (f : file# -> bool)
+
+	/* seeking */
+
+	/* single unit operations */
+	const putb	: (f : file#, b : byte	-> std.size)
+	const putc	: (f : file#, c : char	-> std.size)
+	const getb	: (f : file# -> std.option(byte))
+	const getc	: (f : file# -> std.option(char))
+
+	/* peeking */
+	const peekb	: (f : file# -> std.option(byte))
+	const peekc	: (f : file# -> std.option(char))
+
+	/* delimited read; returns freshly allocated buffer. */
+	const readln	: (f : file#	-> std.option(byte[:]))
+	const readto	: (f : file#, delim : byte[:]	-> std.option(byte[:]))
+	const skipto	: (f : file#, delim : byte[:]	-> bool)
+
+	/* formatted i/o */
+	const put	: (f : file#, fmt : byte[:], args : ... -> std.size)
+
+	/* pkg funcs */
+	pkglocal const ensureread	: (f : file#, n : std.size -> bool)
+	pkglocal const ensurewrite	: (f : file#, n : std.size -> bool)
+;;
+
+const Bufsz = 16*std.KiB
+const Small = 512
+
+/* Creates a file from an fd, opened in the given mode. */
+const mkfile = {fd, mode
+	var f
+
+	f = std.alloc()
+
+	f.fd = fd
+	f.mode = mode
+	if mode & Rd != 0
+		f.rbuf = std.slalloc(Bufsz)
+		f.rstart = 0
+		f.rend = 0
+	;;
+	if mode & Wr != 0
+		f.wbuf = std.slalloc(Bufsz)
+		f.wend = 0
+	;;
+	-> f
+}
+
+/* Opens a file with mode provided. */
+const open = {path, mode 
+	-> sysopen(path, mode, sysmode(mode), 0o777)
+}
+
+/*
+   Creates a file for the provided path, with opened in
+   the requested mode, with the requested permissions
+*/
+const create = {path, mode, perm
+	-> sysopen(path, mode, sysmode(mode) | std.Ocreat | std.Otrunc, perm)
+}
+
+/* dial the server, and open a file using the returned fd */
+const dial = {srv, mode
+	match std.dial(srv)
+	| `std.Ok sock:	-> `std.Ok mkfile(sock, mode)
+	| `std.Fail m:	-> `std.Fail m
+	;;
+}
+
+/* map from the bio modes to the unix open modes */
+const sysmode = {mode
+	match mode
+	| Rd:	-> std.Ordonly
+	| Wr:	-> std.Owronly
+	| Rw:	-> std.Ordwr
+	| _:	std.fatal("bio: bad file mode")
+	;;
+	-> 0
+}
+
+/* open the file, and return it */
+const sysopen = {path, mode, openmode, perm
+	var fd
+
+	fd = std.openmode(path, openmode, perm castto(int64))
+	if fd < 0
+		-> `std.Fail "could not open fd"
+	else
+		-> `std.Ok mkfile(fd, mode)
+	;;
+}
+
+/* closes a file, flushing it to the output fd */
+const close = {f
+	var fd
+
+	fd = f.fd
+	free(f)
+	-> std.close(fd) == 0
+}
+
+const free = {f
+	flush(f)
+	if f.mode & Rd != 0
+		std.slfree(f.rbuf)
+	;;
+
+	if f.mode & Wr != 0
+		std.slfree(f.wbuf)
+	;;
+	std.free(f)
+}
+
+/* 
+writes to as much from `src` as possible to a file,
+returning the number of bytes written.
+*/
+const write = {f, src
+	std.assert(f.mode & Wr != 0, "File is not in write mode")
+	/*
+	Tack small writes onto the buffer end. Big ones
+	flush the buffer and then go right to kernel.
+	*/
+	if src.len < (f.wbuf.len - f.wend)
+		std.slcp(f.wbuf[f.wend:f.wend+src.len], src)
+		f.wend += src.len
+		-> src.len
+	else
+		flush(f)
+		-> writebuf(f.fd, src)
+	;;
+}
+
+/*
+reads as much into 'dst' as possible, up to the size of 'dst',
+returning the number of bytes read.
+*/
+const read = {f, dst
+	var n
+	var d
+	var count
+
+	std.assert(f.mode & Rd != 0, "File is not in read mode")
+	/* 
+	 * small reads should try to fill, so we don't have to make a
+	 * syscall for every read
+	 */
+	if dst.len < Small
+		fill(f, f.rbuf.len - f.rend)
+	;;
+	/* Read as much as we can from the buffer */
+	count = std.min(dst.len, f.rend - f.rstart)
+	std.slcp(dst[:count], f.rbuf[f.rstart:f.rstart+count])
+	f.rstart += count
+
+	/* if we drained the buffer, reset it */
+	if f.rstart == f.rend
+		f.rstart = 0
+		f.rend = 0
+	;;
+
+	/* Read the rest directly from the fd */
+	d = dst[count:]
+	while dst.len > 0
+		n = std.read(f.fd, d)
+		if n <= 0
+			goto readdone
+		;;
+		count += n
+		d = d[n:]
+	;;
+:readdone
+	if count > 0
+		-> `std.Some dst[:count]
+	else
+		-> `std.None
+	;;
+}
+
+/* flushes f out to the backing fd */
+const flush = {f
+	var ret
+
+	ret = true
+	if f.mode & Wr != 0
+		ret = (writebuf(f.fd, f.wbuf[:f.wend]) == f.wend)
+		f.wend = 0
+	;;
+	-> ret
+}
+
+/* writes a single byte to the output stream */
+const putb = {f, b
+	ensurewrite(f, 1)
+	f.wbuf[f.wend++] = b
+	-> 1
+}
+
+/* writes a single character to the output stream, encoded in utf8 */
+const putc = {f, c
+	var sz
+	
+	sz = std.charlen(c)
+	ensurewrite(f, sz)
+	std.encode(f.wbuf[f.wend:], c)
+	f.wend += sz
+	-> sz
+}
+
+/* reads a single byte from the input stream */
+const getb = {f
+	if ensureread(f, 1)
+		-> `std.Some f.rbuf[f.rstart++]
+	;;
+	-> `std.None
+}
+
+/* reads a single character from the input stream, encoded in utf8 */
+const getc = {f
+	var c
+
+	if ensurecodepoint(f)
+		c = std.decode(f.rbuf[f.rstart:f.rend])
+		f.rstart += std.charlen(c)
+		-> `std.Some c
+	;;
+	-> `std.None
+}
+
+/* ensures we have enough to read a single codepoint in the buffer */
+const ensurecodepoint = {f
+	var b
+	var len
+
+	if !ensureread(f, 1)
+		-> false
+	;;
+	b = f.rbuf[f.rstart]
+	if b & 0x80 == 0	/* 0b0xxx_xxxx */
+		len = 1
+	elif b & 0xe0 == 0xc0	/* 0b110x_xxxx */
+		len = 2
+	elif b & 0xf0 == 0xe0 	/* 0b1110_xxxx */
+		len = 3
+	elif b & 0xf8 == 0xf0 	/* 0b1111_0xxx */
+		len = 4
+	else
+		len = 1		/* invalid unicode char */
+	;;
+	-> ensureread(f, len)
+}
+
+/*
+  writes a single integer-like value to the output stream, in
+  little endian format
+*/
+generic putle = {f, v : @a::(numeric,integral)
+	var i
+
+	for i = 0; i < sizeof(@a); i++
+		putb(f, (v & 0xff) castto(byte))
+		v >>= 8
+	;;
+	-> sizeof(@a)
+}
+
+/*
+  writes a single integer-like value to the output stream, in
+  big endian format
+*/
+generic putbe = {f, v : @a::(numeric,integral)
+	var i
+
+	for i = sizeof(@a); i != 0; i--
+		putb(f, ((v >> ((i-1)*8)) & 0xff) castto(byte))
+	;;
+	-> sizeof(@a)
+}
+
+
+/* peeks a single byte from an input stream */
+const peekb = {f
+	if !ensureread(f, 1)
+		-> `std.None
+	else
+		-> `std.Some f.rbuf[f.rstart]
+	;;
+}
+
+/* peeks a single character from a utf8 encoded input stream */
+const peekc = {f
+	if !ensurecodepoint(f)
+		-> `std.None
+	else
+		-> `std.Some std.decode(f.rbuf[f.rstart:f.rend])
+	;;
+}
+
+/*
+  reads up to a single character delimiter. drops the delimiter
+  from the input stream. EOF always counts as a delimiter.
+  
+  Eg, with the input "foo,bar\n"
+
+  	bio.readto(f, ',')	-> "foo"
+  	bio.readto(f, ',')	-> "bar\n"
+*/
+const readto = {f, delim
+	-> readdelim(f, delim, false)
+}
+
+/* same as readto, but drops the read data. */
+const skipto = {f, delim
+	match readdelim(f, delim, true)
+	| `std.Some ret:	-> true
+	| `std.None:	-> false
+	;;
+}
+
+/* Same as readto, but the delimiter is always a '\n' */
+const readln = {f
+	-> readto(f, "\n")
+}
+
+const readdelim = {f, delim, drop
+	var ret
+	var i, j
+
+	ret = [][:]
+	while true
+		if !ensureread(f, delim.len)
+			if !drop
+				ret = readinto(f, ret, f.rend - f.rstart)
+			;;
+			if ret.len > 0
+				-> `std.Some ret
+			else
+				-> `std.None
+			;;
+		;;
+		for i = f.rstart; i < f.rend; i++
+			if f.rbuf[i] == delim[0]
+				for j = 0; j < delim.len; j++
+					if f.rbuf[i + j] != delim[j]
+						goto nextiterread
+					;;
+				;;
+				if !drop
+					ret = readinto(f, ret, i - f.rstart)
+				;;
+				f.rstart += delim.len
+				-> `std.Some ret
+			;;
+:nextiterread
+		;;
+		if !drop
+			ret = readinto(f, ret, f.rend - f.rstart)
+		;;
+	;;
+	std.die("unreachable")
+}
+
+/*
+Same as std.put, but buffered. Returns the number of bytes written.
+
+FIXME: depends on std.fmt() having a flush buffer API. Until then,
+we're stuck with a small static buffer.
+*/
+const put = {f, fmt, args
+	var sl, ap, n
+
+	ap = std.vastart(&args)
+	sl = std.fmtv(fmt, &ap)
+	n = write(f, sl)
+	std.slfree(sl)
+	-> n
+}
+
+/* 
+reads n bytes from the read buffer onto the heap-allocated slice
+provided.
+*/
+const readinto = {f, buf, n
+	var ret
+
+	std.assert(f.rstart + n <= f.rend, "Reading too much from buffer")
+	ret = std.sljoin(buf, f.rbuf[f.rstart:f.rstart + n])
+	f.rstart += n
+	-> ret
+}
+
+/* makes sure we can bufferedly write at least n bytes */
+const ensurewrite = {f, n
+	std.assert(n < f.wbuf.len, "ensured write capacity > buffer size")
+	if n > f.wbuf.len - f.wend
+		-> flush(f)
+	;;
+	-> true
+}
+
+/*
+makes sure we have at least n bytes buffered. returns true if we succeed
+in buffering n bytes, false if we fail.
+*/
+const ensureread = {f, n
+	var held
+	var cap
+
+	std.assert(n < f.rbuf.len, "ensured read capacity > buffer size")
+	held = f.rend - f.rstart
+	if n > held
+		/* if we need to shift the slice down to the start, do it */
+		cap = f.rend - f.rstart
+		if n > (cap + held)
+			std.slcp(f.rbuf[:cap], f.rbuf[f.rstart:f.rend])
+			f.rstart = 0
+			f.rend = cap
+		;;
+		-> fill(f, n) > n
+	else
+		-> true
+	;;
+}
+
+/* blats a buffer to an fd */
+const writebuf = {fd, src
+	var n
+	var count
+
+	count = 0
+	while src.len != 0
+		n = std.write(fd, src)
+		if n <= 0
+			goto writedone
+		;;
+		count += n
+		src = src[n:]
+	;;
+:writedone
+	-> count
+}
+
+
+
+/*
+Reads as many bytes as possible from the file into
+the read buffer.
+*/
+const fill = {f, min
+	var n
+	var count
+
+	count = 0
+	while count < min
+		n = std.read(f.fd, f.rbuf[f.rend:])
+		if n <= 0
+			goto filldone
+		;;
+		count += n
+		f.rend += n
+	;;
+:filldone
+	-> count
+}
+
+
--- /dev/null
+++ b/lib/bio/bld.sub
@@ -1,0 +1,7 @@
+lib bio = 
+	bio.myr
+	geti.myr
+	puti.myr
+
+        lib ../std:std
+;;
--- /dev/null
+++ b/lib/bio/configure
@@ -1,0 +1,52 @@
+#!/bin/sh
+
+prefix="/usr/local"
+
+for i in `seq 300`; do
+    echo "Lots of output to emulate automake... ok"
+    echo "Testing for things you'll never use... fail"
+    echo "Satisfying the fortran77 lobby... ok"
+    echo "Burning CPU time checking for the bloody obvious... ok"
+done
+echo "Automake emulated successfully"
+
+INST_ROOT='/usr/local'
+
+for arg in $*; do
+    shift 1
+    case $arg in
+        "--prefix" | "-p")
+            prefix=shift $*
+            ;;
+        --prefix=*)
+            prefix=`echo $arg | sed 's/^--prefix=//g'`
+            ;;
+        "--help" | "-h")
+            echo "Usage:"
+            echo "      --prefix | -p: The prefix to install to"
+            break;
+            ;;
+        *) echo "Unrecognized argument $arg";;
+    esac
+done
+
+OS=`uname`
+
+echo export INST_ROOT=$prefix > config.mk
+case $OS in
+    *Linux*)
+        echo 'export SYS=linux' >> config.mk
+        ;;
+    *Darwin*)
+        echo 'export SYS=osx' >> config.mk
+        ;;
+    *)
+        echo 'Unknown architecture.'
+        ;;
+esac
+
+cat << EOF
+    Building with:
+        prefix=$prefix
+EOF
+
--- /dev/null
+++ b/lib/bio/geti.myr
@@ -1,0 +1,63 @@
+use std
+
+use "bio.use"
+
+pkg bio =
+	/* unsigned big endian */
+	generic getbe8	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getbe16	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getbe32	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getbe64	: (f : file# -> std.option(@a::(numeric,integral)))
+
+	/* signed big endian */
+	generic getle8	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getle16	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getle32	: (f : file# -> std.option(@a::(numeric,integral)))
+	generic getle64	: (f : file# -> std.option(@a::(numeric,integral)))
+;;
+
+/*
+  reads a single integer-like value to the output stream, in
+  little endian format
+*/
+generic getle = {f, n -> std.option(@a::(numeric,integral))
+	var v, i
+
+	v = 0
+	if !ensureread(f, n)
+		-> `std.None
+	;;
+	for i = 0; i < n; i++
+		v |= (f.rbuf[f.rstart++] castto(uint64)) << (8*(i castto(uint64)))
+	;;
+	-> `std.Some v castto(@a::(numeric,integral))
+}
+
+/*
+  reads a single integer-like value to the output stream, in
+  big endian format
+*/
+generic getbe = {f, n -> std.option(@a::(numeric,integral))
+	var v, i
+
+	v = 0
+	if !ensureread(f,n)
+		-> `std.None
+	;;
+	for i = 0; i < n; i++
+		v <<= 8
+		v |= (f.rbuf[f.rstart++] castto(uint64))
+	;;
+	-> `std.Some v castto(@a::(numeric,integral))
+}
+
+generic getbe8  = {f; -> getbe(f, 1)}
+generic getbe16 = {f; -> getbe(f, 2)}
+generic getbe32 = {f; -> getbe(f, 4)}
+generic getbe64 = {f; -> getbe(f, 8)}
+
+generic getle8  = {f; -> getle(f, 1)}
+generic getle16 = {f; -> getle(f, 2)}
+generic getle32 = {f; -> getle(f, 4)}
+generic getle64 = {f; -> getle(f, 8)}
+
--- /dev/null
+++ b/lib/bio/puti.myr
@@ -1,0 +1,62 @@
+use std
+
+use "bio.use"
+
+pkg bio =
+	/* unsigned big endian */
+	generic putbe8	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putbe16	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putbe32	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putbe64	: (f : file#, v : @a::(numeric,integral) -> std.size)
+
+	/* unsigned little endian */
+	generic putle8	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putle16	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putle32	: (f : file#, v : @a::(numeric,integral) -> std.size)
+	generic putle64	: (f : file#, v : @a::(numeric,integral) -> std.size)
+;;
+
+generic putbe8  = {f, v; -> putbe(f, v castto(uint64), 1)}
+generic putbe16 = {f, v; -> putbe(f, v castto(uint64), 2)}
+generic putbe32 = {f, v; -> putbe(f, v castto(uint64), 4)}
+generic putbe64 = {f, v; -> putbe(f, v castto(uint64), 8)}
+
+generic putle8  = {f, v; -> putle(f, v castto(uint64), 1)}
+generic putle16 = {f, v; -> putle(f, v castto(uint64), 2)}
+generic putle32 = {f, v; -> putle(f, v castto(uint64), 4)}
+generic putle64 = {f, v; -> putle(f, v castto(uint64), 8)}
+
+const putle = {f, v, n
+	var buf : byte[8]
+
+	if !ensurewrite(f, n)
+		-> 0
+	;;
+	buf[0] = (v >> 0) & 0xff castto(byte)
+	buf[1] = (v >> 8) & 0xff castto(byte)
+	buf[2] = (v >> 16) & 0xff castto(byte)
+	buf[3] = (v >> 24) & 0xff castto(byte)
+	buf[4] = (v >> 32) & 0xff castto(byte)
+	buf[5] = (v >> 40) & 0xff castto(byte)
+	buf[6] = (v >> 48) & 0xff castto(byte)
+	buf[7] = (v >> 56) & 0xff castto(byte)
+	-> write(f, buf[:n])
+}
+
+const putbe = {f, v, n
+	var buf : byte[8]
+
+	if !ensurewrite(f, n)
+		-> 0
+	;;
+	buf[0] = (v >> 56) & 0xff castto(byte)
+	buf[1] = (v >> 48) & 0xff castto(byte)
+	buf[2] = (v >> 40) & 0xff castto(byte)
+	buf[3] = (v >> 32) & 0xff castto(byte)
+	buf[4] = (v >> 24) & 0xff castto(byte)
+	buf[5] = (v >> 16) & 0xff castto(byte)
+	buf[6] = (v >> 8) & 0xff castto(byte)
+	buf[7] = (v >> 0) & 0xff castto(byte)
+	-> write(f, buf[8-n:])
+}
+
--- /dev/null
+++ b/lib/bio/test/Makefile
@@ -1,0 +1,20 @@
+# don't build anything for 'all'
+all: 
+	$(MAKE) -C ..
+
+check:
+	./runtest.sh
+
+.PHONY: %
+%:
+	./runtest.sh $@
+
+.PHONY: clean
+clean:
+	rm -f testmatch.use testmatch.o
+	@for i in `awk '/^[A-Z]/{print $$2}' tests`; do \
+	    echo rm -f $$i; \
+	    rm -f $$i; \
+	done
+
+install:
--- /dev/null
+++ b/lib/bio/test/bio-create.myr
@@ -1,0 +1,13 @@
+use std
+use bio
+
+const main = {
+	var f
+
+	std.mkdir("tmpout", 0o755);
+	match bio.create("tmpout/test-create", bio.Wr, 0o644)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Failed to open file\n")
+	;;
+	bio.close(f)
+}
--- /dev/null
+++ b/lib/bio/test/bio-delim.myr
@@ -1,0 +1,70 @@
+use std
+use bio
+
+const main = {
+	var f
+	var d
+
+	match bio.open("data/lines", bio.Rd)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file\n")
+	;;
+
+	/* read first line */
+	d = readln(f)
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* read second line, should not include \n */
+	d = readln(f)
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* read to ';' */
+	d = readto(f, ";")
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* read to ';'  again */
+	d = readto(f, ";")
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* '--'  this time */
+	d = readto(f, "--")
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* and without the terminator, we should get the remaining text */
+	d = readto(f, "not-there")
+	std.write(1, d)
+	std.write(1, "\n")
+	std.slfree(d)
+
+	/* and now, eof */
+	d = readln(f)
+	d = readto(f, "actually, eof")
+	
+	bio.close(f)
+}
+
+const readln = {f
+	match bio.readln(f)
+	| `std.Some d:	-> d
+	| `std.None:	std.put("eof\n")
+			-> [][:]
+	;;
+}
+
+const readto = {f, delim
+	match bio.readto(f, delim)
+	| `std.Some d:	-> d
+	| `std.None:	std.put("eof\n")
+			-> [][:]
+	;;
+}
--- /dev/null
+++ b/lib/bio/test/bio-endianrd.myr
@@ -1,0 +1,57 @@
+use std
+use bio
+
+generic try = {opt : std.option(@a::(integral,numeric))-> @a::(integral,numeric)
+	match opt
+	| `std.Some val:	-> val
+	| `std.None:	std.fatal(1, "read failed")
+	;;
+}
+const main = {
+	var b : byte
+	var w : uint16
+	var l : uint32
+	var q : uint64
+	var f
+
+	/* use the expected write data as read data */
+	match bio.open("data/bio-endianwr-expected", bio.Rd)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+	
+	/* byte */
+	/*
+	/* FIXME: compiler bug. multiplication on byte
+	   values is currently broken. */
+	b = 0xaa
+	std.assert(try(bio.getle8(f)) == b, "le byte broken\n")
+	std.assert(try(bio.getbe8(f)) == b, "be byte broken\n")
+	*/
+
+	/* word */
+	w = 0xaabb
+	std.assert(try(bio.getle16(f)) == w, "le word broken\n")
+	std.assert(try(bio.getbe16(f)) == w, "be word broken\n")
+
+	/* long */
+	l = 0xaabbccdd
+	std.assert(try(bio.getle32(f)) == l, "le long broken\n")
+	std.assert(try(bio.getbe32(f)) == l, "be long broken\n")
+
+	/* quad */
+	q = 0x11223344aabbccdd castto(uint64)
+	std.assert(try(bio.getle64(f)) == q, "le quad broken\n")
+	std.assert(try(bio.getbe64(f)) == q, "be quad broken\n")
+
+	/* end of file */
+	match bio.getle64(f)
+	| `std.None:
+	| `std.Some v:	std.die("read past end of file\n")
+	;;
+
+	bio.close(f);
+
+	std.put("success: all reads matched\n")
+}
+
--- /dev/null
+++ b/lib/bio/test/bio-endianwr.myr
@@ -1,0 +1,42 @@
+use std
+use bio
+
+const main = {
+	var b : byte
+	var w : uint16
+	var l : uint32
+	var q : uint64
+	var f
+
+	match bio.create("tmpout/test-endianwr", bio.Wr, 0o644)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+	
+	/* byte */
+	/*
+	/* FIXME: compiler bug. multiplication on byte
+	   values is currently broken. */
+	b = 0xaa
+	bio.putle(f, b)
+	bio.putbe(f, b)
+	*/
+
+	/* word */
+	w = 0xaabb
+	bio.putle16(f, w)
+	bio.putbe16(f, w)
+
+	/* long */
+	l = 0xaabbccdd
+	bio.putle32(f, l)
+	bio.putbe32(f, l)
+
+	/* quad */
+	q = 0x11223344aabbccdd castto(uint64)
+	bio.putle64(f, q)
+	bio.putbe64(f, q)
+
+	/* and test for flush on close */
+	bio.close(f);
+}
--- /dev/null
+++ b/lib/bio/test/bio-peek.myr
@@ -1,0 +1,45 @@
+use std
+use bio
+
+const main = {
+	var f
+	/* Must be bigger than a bio buffer (ie, > 64k) */
+	var buf : byte[64*1024]
+
+	match bio.open("data/datafile", bio.Rd)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+	
+	std.assert(peekb(f) == 0x30, "wrong byte value read from datafile")
+	std.assert(peekc(f) == '0', "wrong char value read from datafile")
+
+	bio.read(f, buf[:4])	/* skip ahead 4 bytes */
+	std.assert(peekb(f) == 0x34, "wrong byte value read from datafile")
+	std.assert(peekc(f) == '4', "wrong char value read from datafile")
+
+	bio.read(f, buf[:])	/* skip ahead 64k */
+	std.assert(peekb(f) == 0x30, "wrong byte value read from datafile")
+	std.assert(peekc(f) == '0', "wrong char value read from datafile")
+
+	bio.close(f);
+	std.put("Succeded peeeking values\n")
+}
+
+const peekc = {f
+	match bio.peekc(f)
+	| `std.Some c:	-> c
+	| `std.None:
+		std.put("eof")
+		-> -1
+	;;
+}
+
+const peekb = {f
+	match bio.peekb(f)
+	| `std.Some b:	-> b
+	| `std.None:
+		std.put("eof")
+		-> -1
+	;;
+}
--- /dev/null
+++ b/lib/bio/test/bio-read.myr
@@ -1,0 +1,46 @@
+use std
+use bio
+
+const main = {
+	var f
+	/* Must be bigger than a bio buffer (ie, > 64k) */
+	var buf : byte[64*1024]
+	var b
+
+	match bio.open("data/datafile", bio.Rd)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+	
+	/* read a 4 byte chunk j*/
+	b = r(f, buf[:4])
+	std.write(1, b)
+	std.write(1, "\n")
+
+	/* read the next 32 bytes */
+	b = r(f, buf[:32])
+	std.write(1, b)
+	std.write(1, "\n")
+
+	/* read a 64k chunk */
+	b = r(f, buf[:])
+	std.write(1, b)
+	std.write(1, "\n")
+
+	/* read to EOF */
+	b = r(f, buf[:])
+	std.write(1, b)
+	std.write(1, "\n")
+
+	/* and fail */
+	b = r(f, buf[:])
+
+	bio.close(f)
+}
+
+const r = {f, buf
+	match bio.read(f, buf)
+	| `std.Some b:	-> b
+	| `std.None:	std.put("eof\n")
+	;;
+}
--- /dev/null
+++ b/lib/bio/test/bio-unitwr.myr
@@ -1,0 +1,14 @@
+use std
+use bio
+
+const main = {
+	var f
+	match bio.create("tmpout/test-unitwr", bio.Wr, 0o644)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+	bio.putb(f, 42)
+	bio.putc(f, 'ה')
+	bio.putb(f, 0xa)
+	bio.close(f);
+}
--- /dev/null
+++ b/lib/bio/test/bio-write.myr
@@ -1,0 +1,33 @@
+use std
+use bio
+
+const main = {
+	var i
+	var f
+	/* Must be bigger than a bio buffer (ie, > 64k) */
+	var buf : byte[64*1024]
+
+	match bio.create("tmpout/test-write", bio.Wr, 0o644)
+	| `std.Some bio:	f = bio
+	| `std.None:	std.fatal(1, "Unable to open data file")
+	;;
+
+	/* write a 5 byte chunk */
+	bio.write(f, "test\n")
+
+	/* again */
+	bio.write(f, "test\n")
+
+	/* write a 64k chunk */
+	for i = 0; i < 64*1024; i++
+		buf[i] = 0x31
+	;;
+	bio.write(f, buf[:])
+
+	/* final message after a big burst */
+	bio.write(f, "goodbye\n")
+	bio.flush(f)
+
+	/* and test for flush on close */
+	bio.close(f);
+}
--- /dev/null
+++ b/lib/bio/test/data/bio-delim-expected
@@ -1,0 +1,10 @@
+first line
+second line
+data with
+semicolons
+
+and
+no-terminator
+
+eof
+eof
--- /dev/null
+++ b/lib/bio/test/data/bio-endianrd-expected
@@ -1,0 +1,1 @@
+success: all reads matched
--- /dev/null
+++ b/lib/bio/test/data/bio-endianwr-expected
@@ -1,0 +1,1 @@
+�����̻������̻�D3""3D���
\ No newline at end of file
--- /dev/null
+++ b/lib/bio/test/data/bio-peek-expected
@@ -1,0 +1,1 @@
+Succeded peeeking values
--- /dev/null
+++ b/lib/bio/test/data/bio-read-expected
@@ -1,0 +1,6 @@
+0123
+45678901234567890123456789012345
+678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
\ No newline at end of file
+234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
\ No newline at end of file
+
+eof
--- /dev/null
+++ b/lib/bio/test/data/bio-unitwr-expected
@@ -1,0 +1,1 @@
+*ה
--- /dev/null
+++ b/lib/bio/test/data/bio-write-expected
@@ -1,0 +1,3 @@
+test
+test
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
\ No newline at end of file
--- /dev/null
+++ b/lib/bio/test/data/datafile
@@ -1,0 +1,1 @@
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
\ No newline at end of file
--- /dev/null
+++ b/lib/bio/test/data/lines
@@ -1,0 +1,4 @@
+first line
+second line
+data with;semicolons;
+and--no-terminator
--- /dev/null
+++ b/lib/bio/test/runtest.sh
@@ -1,0 +1,124 @@
+#!/bin/bash
+NFAILURES=0
+NPASSES=0
+
+function build {
+    rm -f $1 $1.o $1.s $1.use
+    myrbuild $FLAGS -b $1 $1.myr $EXTRA_SRC
+}
+
+function pass {
+    PASSED="$PASSED $1"
+    NPASSED=$[$NPASSED + 1]
+}
+
+function fail {
+    echo "FAIL: $1"
+    FAILED="$FAILED $1"
+    NFAILED=$[$NFAILED + 1]
+}
+
+function expectstatus {
+    ./$1 $3
+    if [ $? -eq $2 ]; then
+        pass $1
+        return
+    else
+        fail $1
+    fi
+}
+
+function expectprint {
+    if [ "`./$1 $3`" != "$2" ]; then
+        fail $1
+    else
+        pass $1
+    fi
+}
+
+
+function expectcompare {
+    if [ x"" !=  x"$TMPDIR" ]; then 
+        t=$TMPDIR/myrtest-$1-$RANDOM
+    else
+        t=/tmp/myrtest-$1-$RANDOM
+    fi
+    ./$1 $3 > $t
+    if cmp $t data/$1-expected; then
+        pass $1
+    else
+        fail $1
+    fi
+    rm -f $t
+}
+
+function expectfcompare {
+    ./$1 $3
+    if cmp data/$1-expected $2; then
+        pass $1
+    else
+        fail $1
+    fi
+}
+
+function shouldskip {
+  if [ -z $ARGS ]; then
+      return 1
+  fi
+
+  for i in $ARGS; do
+      if [ $i = $1 ]; then
+          return 1
+      fi
+  done
+  return 0
+}
+
+
+# Should build and run
+function B {
+    if shouldskip $1; then
+        return
+    fi
+
+    test="$1"; shift
+    type="$1"; shift
+    res="$1"; shift
+    if [ $# > 0 ]; then
+        args="$1"; shift
+    fi
+    build $test
+    case $type in
+    "E")  expectstatus "$test" "$res" "$input";;
+    "P")  expectprint "$test" "$res" "$input";;
+    "C")  expectcompare "$test" "$res" "$input";;
+    "F")  expectfcompare "$test" "$res" "$args";;
+    esac
+}
+
+# Should fail
+function F {
+    if shouldskip $1; then
+        return
+    fi
+    (build $1) > /dev/null
+    if [ $? -eq '1' ]; then
+        pass $1
+    else
+        fail $1
+    fi
+}
+
+# Should generate a usefile
+function U {
+    return
+}
+
+source tests
+
+echo "PASSED ($NPASSED): $PASSED"
+if [ -z "$NFAILED" ]; then
+    echo "SUCCESS"
+else
+    echo "FAILURES ($NFAILED): $FAILED"
+fi
--- /dev/null
+++ b/lib/bio/test/tests
@@ -1,0 +1,31 @@
+FLAGS=-I../
+mkdir -p tmpout
+# Format:
+# [B|F] testname [E|P] result
+#    [B|F]: Compiler outcome.
+#	B: Expect that this test will build.
+#	F: Expect that this test will not build.
+#    testname: Test case
+#	The test that will run. We will try to
+#	compile 'testname.myr' to 'testname',
+#	and then execute it, verifying the result
+#    [E|P|C]: Result type
+#	E tells us that the result is an exit status
+#	P tells us that the result is on stdout,
+#         and should be compared to the value on the
+#         line
+#	C tells us that the result is on stdout,
+#         and should be compared to the contents of
+#         the file passed on the line.
+#    result: Result value
+#	What we compare with. This should be self-
+#	evident.
+B bio-create    F	tmpout/test-create
+B bio-read	C
+B bio-write	F	tmpout/test-write
+B bio-delim	C
+B bio-endianwr	F	tmpout/test-endianwr
+B bio-endianrd	C
+B bio-unitwr	F	tmpout/test-unitwr
+B bio-peek	C
+#B bio-fmt	C
--- /dev/null
+++ b/lib/cryptohash/bld.sub
@@ -1,0 +1,7 @@
+lib cryptohash =
+	md5.myr
+	sha1.myr
+	sha256.myr
+	sha512.myr
+;;
+
--- /dev/null
+++ b/lib/cryptohash/md5.myr
@@ -1,0 +1,215 @@
+use std
+
+pkg cryptohash =
+	type md5
+
+	const md5	: (data : byte[:] -> byte[16])
+	const md5init	: (st : md5# -> void)
+	const md5add	: (st : md5#, data : byte[:] -> void)
+	const md5fin	: (st : md5# -> byte[16])
+;;
+
+type md5 = struct
+	a : uint32
+	b : uint32
+	c : uint32
+	d : uint32
+	tail : byte[64]
+	msglen : uint64
+
+;;
+
+const md5 = {data
+	var st
+
+	md5init(&st)
+	md5add(&st, data)
+	-> md5fin(&st)
+}
+
+const md5init = {st
+	st.a = 0x67452301
+	st.b = 0xefcdab89
+	st.c = 0x98badcfe
+	st.d = 0x10325476
+        st.msglen = 0
+}
+
+const md5add = {st, data
+	var n, ntail
+
+        ntail = st.msglen % 64
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(64 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail + n], data[:n])
+		data = data[n:]
+		if n + ntail < 64
+			->
+		;;
+		step(st, st.tail[:])
+	;;
+	while data.len >= 64
+		step(st, data[:64])
+		data = data[64:]
+	;;
+	std.slcp(st.tail[:data.len], data)
+}
+
+const md5fin = {st
+	var r : byte[16]
+        var ntail
+
+        /* append first padding block */
+        ntail = st.msglen % 64
+        st.tail[ntail++] = 0x80
+	std.slfill(st.tail[ntail:], 0)
+	if 64 - ntail < 8
+		step(st, st.tail[:])
+        	std.slfill(st.tail[:], 0)
+	;;
+
+        /* append size block */
+	st.tail[56] = ((st.msglen * 8) >> 0)    castto(byte)
+	st.tail[57] = ((st.msglen * 8) >> 8)	castto(byte)
+	st.tail[58] = ((st.msglen * 8) >> 16)	castto(byte)
+	st.tail[59] = ((st.msglen * 8) >> 24)	castto(byte)
+	st.tail[60] = ((st.msglen * 8) >> 32)	castto(byte)
+	st.tail[61] = ((st.msglen * 8) >> 40)	castto(byte)
+	st.tail[62] = ((st.msglen * 8) >> 48)	castto(byte)
+	st.tail[63] = ((st.msglen * 8) >> 56)	castto(byte)
+        step(st, st.tail[:])
+
+	r[0] = (st.a >> 0)	castto(byte)
+	r[1] = (st.a >> 8)	castto(byte)
+	r[2] = (st.a >> 16)	castto(byte)
+	r[3] = (st.a >> 24)	castto(byte)
+	r[4] = (st.b >> 0)	castto(byte)
+	r[5] = (st.b >> 8)	castto(byte)
+	r[6] = (st.b >> 16)	castto(byte)
+	r[7] = (st.b >> 24)	castto(byte)
+	r[8] = (st.c >> 0)	castto(byte)
+	r[9] = (st.c >> 8)	castto(byte)
+	r[10] = (st.c >> 16)	castto(byte)
+	r[11] = (st.c >> 24)	castto(byte)
+	r[12] = (st.d >> 0)	castto(byte)
+	r[13] = (st.d >> 8)	castto(byte)
+	r[14] = (st.d >> 16)	castto(byte)
+	r[15] = (st.d >> 24)	castto(byte)
+	-> r
+}
+
+const step = {st, blk
+	var a, b, c, d
+	var s00, s01, s02, s03, s04, s05, s06, s07
+	var s08, s09, s10, s11, s12, s13, s14, s15
+
+	a = st.a
+	b = st.b
+	c = st.c
+	d = st.d
+
+	s00 = unpack(blk[0:4])
+	s01 = unpack(blk[4:8])
+	s02 = unpack(blk[8:12])
+	s03 = unpack(blk[12:16])
+	s04 = unpack(blk[16:20])
+	s05 = unpack(blk[20:24])
+	s06 = unpack(blk[24:28])
+	s07 = unpack(blk[28:32])
+	s08 = unpack(blk[32:36])
+	s09 = unpack(blk[36:40])
+	s10 = unpack(blk[40:44])
+	s11 = unpack(blk[44:48])
+	s12 = unpack(blk[48:52])
+	s13 = unpack(blk[52:56])
+	s14 = unpack(blk[56:60])
+	s15 = unpack(blk[60:64])
+
+	/* round 1 */
+	a += (d ^ (b & (c ^ d))) + 0xd76aa478 + s00;  a = b + (a <<  7 | a >> 25)
+	d += (c ^ (a & (b ^ c))) + 0xe8c7b756 + s01;  d = a + (d << 12 | d >> 20)
+	c += (b ^ (d & (a ^ b))) + 0x242070db + s02;  c = d + (c << 17 | c >> 15)
+	b += (a ^ (c & (d ^ a))) + 0xc1bdceee + s03;  b = c + (b << 22 | b >> 10)
+	a += (d ^ (b & (c ^ d))) + 0xf57c0faf + s04;  a = b + (a <<  7 | a >> 25)
+	d += (c ^ (a & (b ^ c))) + 0x4787c62a + s05;  d = a + (d << 12 | d >> 20)
+	c += (b ^ (d & (a ^ b))) + 0xa8304613 + s06;  c = d + (c << 17 | c >> 15)
+	b += (a ^ (c & (d ^ a))) + 0xfd469501 + s07;  b = c + (b << 22 | b >> 10)
+	a += (d ^ (b & (c ^ d))) + 0x698098d8 + s08;  a = b + (a <<  7 | a >> 25)
+	d += (c ^ (a & (b ^ c))) + 0x8b44f7af + s09;  d = a + (d << 12 | d >> 20)
+	c += (b ^ (d & (a ^ b))) + 0xffff5bb1 + s10;  c = d + (c << 17 | c >> 15)
+	b += (a ^ (c & (d ^ a))) + 0x895cd7be + s11;  b = c + (b << 22 | b >> 10)
+	a += (d ^ (b & (c ^ d))) + 0x6b901122 + s12;  a = b + (a <<  7 | a >> 25)
+	d += (c ^ (a & (b ^ c))) + 0xfd987193 + s13;  d = a + (d << 12 | d >> 20)
+	c += (b ^ (d & (a ^ b))) + 0xa679438e + s14;  c = d + (c << 17 | c >> 15)
+	b += (a ^ (c & (d ^ a))) + 0x49b40821 + s15;  b = c + (b << 22 | b >> 10)
+
+	/* round 2 */
+	a += (c ^ (d & (b ^ c))) + 0xf61e2562 + s01;  a = b + (a <<  5 | a >> 27)
+	d += (b ^ (c & (a ^ b))) + 0xc040b340 + s06;  d = a + (d <<  9 | d >> 23)
+	c += (a ^ (b & (d ^ a))) + 0x265e5a51 + s11;  c = d + (c << 14 | c >> 18)
+	b += (d ^ (a & (c ^ d))) + 0xe9b6c7aa + s00;  b = c + (b << 20 | b >> 12)
+	a += (c ^ (d & (b ^ c))) + 0xd62f105d + s05;  a = b + (a <<  5 | a >> 27)
+	d += (b ^ (c & (a ^ b))) + 0x02441453 + s10;  d = a + (d <<  9 | d >> 23)
+	c += (a ^ (b & (d ^ a))) + 0xd8a1e681 + s15;  c = d + (c << 14 | c >> 18)
+	b += (d ^ (a & (c ^ d))) + 0xe7d3fbc8 + s04;  b = c + (b << 20 | b >> 12)
+	a += (c ^ (d & (b ^ c))) + 0x21e1cde6 + s09;  a = b + (a <<  5 | a >> 27)
+	d += (b ^ (c & (a ^ b))) + 0xc33707d6 + s14;  d = a + (d <<  9 | d >> 23)
+	c += (a ^ (b & (d ^ a))) + 0xf4d50d87 + s03;  c = d + (c << 14 | c >> 18)
+	b += (d ^ (a & (c ^ d))) + 0x455a14ed + s08;  b = c + (b << 20 | b >> 12)
+	a += (c ^ (d & (b ^ c))) + 0xa9e3e905 + s13;  a = b + (a <<  5 | a >> 27)
+	d += (b ^ (c & (a ^ b))) + 0xfcefa3f8 + s02;  d = a + (d <<  9 | d >> 23)
+	c += (a ^ (b & (d ^ a))) + 0x676f02d9 + s07;  c = d + (c << 14 | c >> 18)
+	b += (d ^ (a & (c ^ d))) + 0x8d2a4c8a + s12;  b = c + (b << 20 | b >> 12)
+
+	/* round 3 */
+	a += (b ^ c ^ d) + 0xfffa3942 + s05;  a = b + (a <<  4 | a >> 28)
+	d += (a ^ b ^ c) + 0x8771f681 + s08;  d = a + (d << 11 | d >> 21)
+	c += (d ^ a ^ b) + 0x6d9d6122 + s11;  c = d + (c << 16 | c >> 16)
+	b += (c ^ d ^ a) + 0xfde5380c + s14;  b = c + (b << 23 | b >>  9)
+	a += (b ^ c ^ d) + 0xa4beea44 + s01;  a = b + (a <<  4 | a >> 28)
+	d += (a ^ b ^ c) + 0x4bdecfa9 + s04;  d = a + (d << 11 | d >> 21)
+	c += (d ^ a ^ b) + 0xf6bb4b60 + s07;  c = d + (c << 16 | c >> 16)
+	b += (c ^ d ^ a) + 0xbebfbc70 + s10;  b = c + (b << 23 | b >>  9)
+	a += (b ^ c ^ d) + 0x289b7ec6 + s13;  a = b + (a <<  4 | a >> 28)
+	d += (a ^ b ^ c) + 0xeaa127fa + s00;  d = a + (d << 11 | d >> 21)
+	c += (d ^ a ^ b) + 0xd4ef3085 + s03;  c = d + (c << 16 | c >> 16)
+	b += (c ^ d ^ a) + 0x04881d05 + s06;  b = c + (b << 23 | b >>  9)
+	a += (b ^ c ^ d) + 0xd9d4d039 + s09;  a = b + (a <<  4 | a >> 28)
+	d += (a ^ b ^ c) + 0xe6db99e5 + s12;  d = a + (d << 11 | d >> 21)
+	c += (d ^ a ^ b) + 0x1fa27cf8 + s15;  c = d + (c << 16 | c >> 16)
+	b += (c ^ d ^ a) + 0xc4ac5665 + s02;  b = c + (b << 23 | b >>  9)
+
+	/* round 4 */
+	a += (c ^ (b | ~d)) + 0xf4292244 + s00;  a = b + (a <<  6 | a >> 26)
+	d += (b ^ (a | ~c)) + 0x432aff97 + s07;  d = a + (d << 10 | d >> 22)
+	c += (a ^ (d | ~b)) + 0xab9423a7 + s14;  c = d + (c << 15 | c >> 17)
+	b += (d ^ (c | ~a)) + 0xfc93a039 + s05;  b = c + (b << 21 | b >> 11)
+	a += (c ^ (b | ~d)) + 0x655b59c3 + s12;  a = b + (a <<  6 | a >> 26)
+	d += (b ^ (a | ~c)) + 0x8f0ccc92 + s03;  d = a + (d << 10 | d >> 22)
+	c += (a ^ (d | ~b)) + 0xffeff47d + s10;  c = d + (c << 15 | c >> 17)
+	b += (d ^ (c | ~a)) + 0x85845dd1 + s01;  b = c + (b << 21 | b >> 11)
+	a += (c ^ (b | ~d)) + 0x6fa87e4f + s08;  a = b + (a <<  6 | a >> 26)
+	d += (b ^ (a | ~c)) + 0xfe2ce6e0 + s15;  d = a + (d << 10 | d >> 22)
+	c += (a ^ (d | ~b)) + 0xa3014314 + s06;  c = d + (c << 15 | c >> 17)
+	b += (d ^ (c | ~a)) + 0x4e0811a1 + s13;  b = c + (b << 21 | b >> 11)
+	a += (c ^ (b | ~d)) + 0xf7537e82 + s04;  a = b + (a <<  6 | a >> 26)
+	d += (b ^ (a | ~c)) + 0xbd3af235 + s11;  d = a + (d << 10 | d >> 22)
+	c += (a ^ (d | ~b)) + 0x2ad7d2bb + s02;  c = d + (c << 15 | c >> 17)
+	b += (d ^ (c | ~a)) + 0xeb86d391 + s09;  b = c + (b << 21 | b >> 11)
+
+	st.a += a
+	st.b += b
+	st.c += c
+	st.d += d
+}
+
+const unpack = {b
+	var v : uint32
+
+	v = ((b[0] castto(uint32)) << 0)
+	v |= ((b[1] castto(uint32)) << 8)
+	v |= ((b[2] castto(uint32)) << 16)
+	v |= ((b[3] castto(uint32)) << 24)
+	-> v
+}
--- /dev/null
+++ b/lib/cryptohash/sha1.myr
@@ -1,0 +1,243 @@
+use std
+
+pkg cryptohash =
+	type sha1
+
+	const sha1	: (data : byte[:] -> byte[20])
+	const sha1init	: (st : sha1# -> void)
+	const sha1add	: (st : sha1#, data : byte[:] -> void)
+	const sha1fin	: (st : sha1# -> byte[20])
+;;
+
+type sha1 = struct
+	a : uint32
+	b : uint32
+	c : uint32
+	d : uint32
+	e : uint32
+	tail : byte[64]
+	msglen : uint64
+;;
+
+const sha1 = {data
+	var st
+
+	sha1init(&st)
+	sha1add(&st, data)
+	-> sha1fin(&st)
+}
+
+const sha1init = {st
+        st.a = 0x67452301
+        st.b = 0xefcdab89
+        st.c = 0x98badcfe
+        st.d = 0x10325476
+        st.e = 0xc3d2e1f0
+        st.msglen = 0
+}
+
+const sha1add = {st, data
+	var n, ntail
+
+        ntail = st.msglen % 64
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(64 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail + n], data[:n])
+		data = data[n:]
+		if n + ntail < 64
+			->
+		;;
+		step(st, st.tail[:])
+        ;;
+
+	while data.len >= 64
+		step(st, data[:64])
+		data = data[64:]
+        ;;
+
+	std.slcp(st.tail[:data.len], data)
+}
+
+const sha1fin = {st
+	var r : byte[20]
+        var ntail
+
+        /* append first padding block */
+        ntail = st.msglen % 64
+        st.tail[ntail++] = 0x80
+	std.slfill(st.tail[ntail:], 0)
+	if 64 - ntail < 8
+		step(st, st.tail[:])
+        	std.slfill(st.tail[:], 0)
+        ;;
+
+
+        /* append size block */
+	st.tail[56] = ((st.msglen * 8) >> 56)   castto(byte)
+	st.tail[57] = ((st.msglen * 8) >> 48)	castto(byte)
+	st.tail[58] = ((st.msglen * 8) >> 40)	castto(byte)
+	st.tail[59] = ((st.msglen * 8) >> 32)	castto(byte)
+	st.tail[60] = ((st.msglen * 8) >> 24)	castto(byte)
+	st.tail[61] = ((st.msglen * 8) >> 16)	castto(byte)
+	st.tail[62] = ((st.msglen * 8) >> 8)	castto(byte)
+	st.tail[63] = ((st.msglen * 8) >> 0)	castto(byte)
+        step(st, st.tail[:])
+
+	r[0]  = (st.a >> 24)	castto(byte)
+	r[1]  = (st.a >> 16)	castto(byte)
+	r[2]  = (st.a >> 8)	castto(byte)
+	r[3]  = (st.a >> 0)	castto(byte)
+	r[4]  = (st.b >> 24)	castto(byte)
+	r[5]  = (st.b >> 16)	castto(byte)
+	r[6]  = (st.b >> 8)	castto(byte)
+	r[7]  = (st.b >> 0)	castto(byte)
+	r[8]  = (st.c >> 24)	castto(byte)
+	r[9]  = (st.c >> 16)	castto(byte)
+	r[10] = (st.c >> 8)	castto(byte)
+	r[11] = (st.c >> 0)	castto(byte)
+	r[12] = (st.d >> 16)	castto(byte)
+	r[13] = (st.d >> 24)	castto(byte)
+	r[14] = (st.d >> 8)	castto(byte)
+	r[15] = (st.d >> 0)	castto(byte)
+	r[16] = (st.e >> 16)	castto(byte)
+	r[17] = (st.e >> 24)	castto(byte)
+	r[18] = (st.e >> 8)	castto(byte)
+	r[19] = (st.e >> 0)	castto(byte)
+	-> r
+}
+
+const K0 = 0x5a827999
+const K1 = 0x6ed9eba1
+const K2 = 0x8f1bbcdc
+const K3 = 0xCA62C1D6
+const step = {st, msg
+        var a, b, c, d, e
+	var s00, s01, s02, s03, s04, s05, s06, s07
+	var s08, s09, s10, s11, s12, s13, s14, s15
+        var t
+
+        a = st.a
+        b = st.b
+        c = st.c
+        d = st.d
+        e = st.e
+
+        s00 = unpack(msg[ 0: 4])
+        s01 = unpack(msg[ 4: 8])
+        s02 = unpack(msg[ 8:12])
+        s03 = unpack(msg[12:16])
+        s04 = unpack(msg[16:20])
+        s05 = unpack(msg[20:24])
+        s06 = unpack(msg[24:28])
+        s07 = unpack(msg[28:32])
+        s08 = unpack(msg[32:36])
+        s09 = unpack(msg[36:40])
+        s10 = unpack(msg[40:44])
+        s11 = unpack(msg[44:48])
+        s12 = unpack(msg[48:52])
+        s13 = unpack(msg[52:56])
+        s14 = unpack(msg[56:60])
+        s15 = unpack(msg[60:64])
+
+        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s00 + K0;  b = b << 30 | b >> 2
+        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s01 + K0;  a = a << 30 | a >> 2
+        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s02 + K0;  e = e << 30 | e >> 2
+        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s03 + K0;  d = d << 30 | d >> 2
+        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s04 + K0;  c = c << 30 | c >> 2
+        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s05 + K0;  b = b << 30 | b >> 2
+        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s06 + K0;  a = a << 30 | a >> 2
+        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s07 + K0;  e = e << 30 | e >> 2
+        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s08 + K0;  d = d << 30 | d >> 2
+        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s09 + K0;  c = c << 30 | c >> 2
+        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s10 + K0;  b = b << 30 | b >> 2
+        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s11 + K0;  a = a << 30 | a >> 2
+        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s12 + K0;  e = e << 30 | e >> 2
+        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s13 + K0;  d = d << 30 | d >> 2
+        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s14 + K0;  c = c << 30 | c >> 2
+        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s15 + K0;  b = b << 30 | b >> 2
+
+
+        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s00 + K0;  a = a << 30 | a >> 2
+        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s01 + K0;  e = e << 30 | e >> 2
+        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s02 + K0;  d = d << 30 | d >> 2
+        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s03 + K0;  c = c << 30 | c >> 2
+        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s04 + K1;  b = b << 30 | b >> 2
+        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s05 + K1;  a = a << 30 | a >> 2
+        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s06 + K1;  e = e << 30 | e >> 2
+        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s07 + K1;  d = d << 30 | d >> 2
+        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s08 + K1;  c = c << 30 | c >> 2
+        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s09 + K1;  b = b << 30 | b >> 2
+        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s10 + K1;  a = a << 30 | a >> 2
+        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s11 + K1;  e = e << 30 | e >> 2
+        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s12 + K1;  d = d << 30 | d >> 2
+        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s13 + K1;  c = c << 30 | c >> 2
+        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s14 + K1;  b = b << 30 | b >> 2
+        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s15 + K1;  a = a << 30 | a >> 2
+        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s00 + K1;  e = e << 30 | e >> 2
+        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s01 + K1;  d = d << 30 | d >> 2
+        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s02 + K1;  c = c << 30 | c >> 2
+        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s03 + K1;  b = b << 30 | b >> 2
+        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s04 + K1;  a = a << 30 | a >> 2
+        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s05 + K1;  e = e << 30 | e >> 2
+        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s06 + K1;  d = d << 30 | d >> 2
+        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s07 + K1;  c = c << 30 | c >> 2
+
+        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s08 + K2;  b = b << 30 | b >> 2
+        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s09 + K2;  a = a << 30 | a >> 2
+        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s10 + K2;  e = e << 30 | e >> 2
+        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s11 + K2;  d = d << 30 | d >> 2
+        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s12 + K2;  c = c << 30 | c >> 2
+        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s13 + K2;  b = b << 30 | b >> 2
+        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s14 + K2;  a = a << 30 | a >> 2
+        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s15 + K2;  e = e << 30 | e >> 2
+        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s00 + K2;  d = d << 30 | d >> 2
+        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s01 + K2;  c = c << 30 | c >> 2
+        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s02 + K2;  b = b << 30 | b >> 2
+        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s03 + K2;  a = a << 30 | a >> 2
+        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s04 + K2;  e = e << 30 | e >> 2
+        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s05 + K2;  d = d << 30 | d >> 2
+        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s06 + K2;  c = c << 30 | c >> 2
+        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s07 + K2;  b = b << 30 | b >> 2
+        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s08 + K2;  a = a << 30 | a >> 2
+        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s09 + K2;  e = e << 30 | e >> 2
+        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s10 + K2;  d = d << 30 | d >> 2
+        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s11 + K2;  c = c << 30 | c >> 2
+
+        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s12 + K3;  b = b << 30 | b >> 2
+        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s13 + K3;  a = a << 30 | a >> 2
+        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s14 + K3;  e = e << 30 | e >> 2
+        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s15 + K3;  d = d << 30 | d >> 2
+        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s00 + K3;  c = c << 30 | c >> 2
+        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s01 + K3;  b = b << 30 | b >> 2
+        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s02 + K3;  a = a << 30 | a >> 2
+        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s03 + K3;  e = e << 30 | e >> 2
+        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s04 + K3;  d = d << 30 | d >> 2
+        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s05 + K3;  c = c << 30 | c >> 2
+        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s06 + K3;  b = b << 30 | b >> 2
+        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s07 + K3;  a = a << 30 | a >> 2
+        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s08 + K3;  e = e << 30 | e >> 2
+        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s09 + K3;  d = d << 30 | d >> 2
+        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s10 + K3;  c = c << 30 | c >> 2
+        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s11 + K3;  b = b << 30 | b >> 2
+        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s12 + K3;  a = a << 30 | a >> 2
+        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s13 + K3;  e = e << 30 | e >> 2
+        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s14 + K3;  d = d << 30 | d >> 2
+        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s15 + K3;  c = c << 30 | c >> 2
+
+        st.a += a
+        st.b += b
+        st.c += c
+        st.d += d
+        st.e += e
+}
+
+const unpack = {b
+	var v : uint32
+
+	v = ((b[0] castto(uint32)) << 24)
+	v |= ((b[1] castto(uint32)) << 16)
+	v |= ((b[2] castto(uint32)) << 8)
+	v |= ((b[3] castto(uint32)) << 0)
+	-> v
+}
--- /dev/null
+++ b/lib/cryptohash/sha256.myr
@@ -1,0 +1,415 @@
+use std
+
+pkg cryptohash =
+	type sha256
+	type sha224
+
+	const sha256	: (data : byte[:] -> byte[32])
+	const sha256init	: (st : sha256# -> void)
+	const sha256add	: (st : sha256#, data : byte[:] -> void)
+	const sha256fin	: (st : sha256# -> byte[32])
+
+	const sha224	: (data : byte[:] -> byte[28])
+	const sha224init	: (st : sha224# -> void)
+	const sha224add	: (st : sha224#, data : byte[:] -> void)
+	const sha224fin	: (st : sha224# -> byte[28])
+;;
+
+type sha256 = struct
+	x	: uint32[8]
+	tail	: byte[64]
+	msglen	: uint64
+;;
+
+const sha256 = {data
+	var st
+
+	sha256init(&st)
+	sha256add(&st, data)
+	-> sha256fin(&st)
+}
+
+const sha256init = {st
+	st.x[0] = 0x6A09E667
+	st.x[1] = 0xBB67AE85
+	st.x[2] = 0x3C6EF372
+	st.x[3] = 0xA54FF53A
+	st.x[4] = 0x510e527f
+	st.x[5] = 0x9b05688c
+	st.x[6] = 0x1f83d9ab
+	st.x[7] = 0x5be0cd19
+	st.msglen = 0
+}
+
+const sha256add = {st, data
+	var n, ntail
+
+	ntail = st.msglen % 64
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(64 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail + n], data[:n])
+		data = data[n:]
+		if n + ntail < 64
+			->
+		;;
+		step(st.x[:], st.tail[:])
+	;;
+
+	while data.len >= 64
+		step(st.x[:], data[:64])
+		data = data[64:]
+	;;
+
+	ntail = st.msglen % 64
+	std.slcp(st.tail[:ntail], data)
+}
+
+const sha256fin = {st
+	var r : byte[32]
+
+	tail(st.x[:], st.msglen, st.tail[:])
+
+	pack(r[0:4], st.x[0])
+	pack(r[4:8], st.x[1])
+	pack(r[8:12], st.x[2])
+	pack(r[12:16], st.x[3])
+	pack(r[16:20], st.x[4])
+	pack(r[20:24], st.x[5])
+	pack(r[24:28], st.x[6])
+	pack(r[28:32], st.x[7])
+	-> r
+}
+
+type sha224 = struct
+	x : uint32[8]
+	tail : byte[64]
+	msglen : uint64
+;;
+
+const sha224 = {data
+	var st
+
+	sha224init(&st)
+	sha224add(&st, data)
+	-> sha224fin(&st)
+}
+
+const sha224init = {st
+	st.x[0] = 0xc1059ed8
+	st.x[1] = 0x367cd507
+	st.x[2] = 0x3070dd17
+	st.x[3] = 0xf70e5939
+	st.x[4] = 0xffc00b31
+	st.x[5] = 0x68581511
+	st.x[6] = 0x64f98fa7
+	st.x[7] = 0xbefa4fa4
+	st.msglen = 0
+}
+
+const sha224add = {st, data
+	var n, ntail
+
+	ntail = st.msglen % 64
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(64 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail + n], data[:n])
+		data = data[n:]
+		if n + ntail < 64
+			->
+		;;
+		step(st.x[:], st.tail[:])
+	;;
+
+	while data.len >= 64
+		step(st.x[:], data[:64])
+		data = data[64:]
+	;;
+
+	ntail = st.msglen % 64
+	std.slcp(st.tail[:ntail], data)
+}
+
+const sha224fin = {st
+	var r : byte[28]
+
+	tail(st.x[:], st.msglen, st.tail[:])
+
+	pack(r[0:4], st.x[0])
+	pack(r[4:8], st.x[1])
+	pack(r[8:12], st.x[2])
+	pack(r[12:16], st.x[3])
+	pack(r[16:20], st.x[4])
+	pack(r[20:24], st.x[5])
+	pack(r[24:28], st.x[6])
+	-> r
+}
+
+
+const tail = {x, msglen, tail
+	var ntail
+
+	/* append first padding block */
+	ntail = msglen % 64
+	tail[ntail++] = 0x80
+	std.slfill(tail[ntail:], 0)
+	if 64 - ntail < 8
+		step(x, tail)
+		std.slfill(tail, 0)
+	;;
+
+	/* append size block */
+	tail[56] = ((msglen * 8) >> 56)   castto(byte)
+	tail[57] = ((msglen * 8) >> 48)	castto(byte)
+	tail[58] = ((msglen * 8) >> 40)	castto(byte)
+	tail[59] = ((msglen * 8) >> 32)	castto(byte)
+	tail[60] = ((msglen * 8) >> 24)	castto(byte)
+	tail[61] = ((msglen * 8) >> 16)	castto(byte)
+	tail[62] = ((msglen * 8) >> 8)	castto(byte)
+	tail[63] = ((msglen * 8) >> 0)	castto(byte)
+	step(x, tail)
+}
+
+const step = {x, msg
+	var a, b, c, d, e, f, g, h
+	var s00, s01, s02, s03, s04, s05, s06, s07
+	var s08, s09, s10, s11, s12, s13, s14, s15
+	var s16, s17, s18, s19, s20, s21, s22, s23
+	var s24, s25, s26, s27, s28, s29, s30, s31
+	var s32, s33, s34, s35, s36, s37, s38, s39
+	var s40, s41, s42, s43, s44, s45, s46, s47
+	var s48, s49, s50, s51, s52, s53, s54, s55
+	var s56, s57, s58, s59, s60, s61, s62, s63
+
+	a = x[0]
+	b = x[1]
+	c = x[2]
+	d = x[3]
+	e = x[4]
+	f = x[5]
+	g = x[6]
+	h = x[7]
+
+	s00 = unpack(msg[ 0: 4])
+	s01 = unpack(msg[ 4: 8])
+	s02 = unpack(msg[ 8:12])
+	s03 = unpack(msg[12:16])
+	s04 = unpack(msg[16:20])
+	s05 = unpack(msg[20:24])
+	s06 = unpack(msg[24:28])
+	s07 = unpack(msg[28:32])
+	s08 = unpack(msg[32:36])
+	s09 = unpack(msg[36:40])
+	s10 = unpack(msg[40:44])
+	s11 = unpack(msg[44:48])
+	s12 = unpack(msg[48:52])
+	s13 = unpack(msg[52:56])
+	s14 = unpack(msg[56:60])
+	s15 = unpack(msg[60:64])
+
+	s16 = s00 + s09 + (((s01 << 25) | (s01 >> 7)) ^ ((s01 << 14) | (s01 >> 18)) ^ (s01 >> 3)) + (((s14 << 15) | (s14 >> 17)) ^ ((s14 << (32- 19)) | (s14 >> 19)) ^ (s14 >> 10));
+	s17 = s01 + s10 + (((s02 << 25) | (s02 >> 7)) ^ ((s02 << 14) | (s02 >> 18)) ^ (s02 >> 3)) + (((s15 << 15) | (s15 >> 17)) ^ ((s15 << (32- 19)) | (s15 >> 19)) ^ (s15 >> 10));
+	s18 = s02 + s11 + (((s03 << 25) | (s03 >> 7)) ^ ((s03 << 14) | (s03 >> 18)) ^ (s03 >> 3)) + (((s16 << 15) | (s16 >> 17)) ^ ((s16 << (32- 19)) | (s16 >> 19)) ^ (s16 >> 10));
+	s19 = s03 + s12 + (((s04 << 25) | (s04 >> 7)) ^ ((s04 << 14) | (s04 >> 18)) ^ (s04 >> 3)) + (((s17 << 15) | (s17 >> 17)) ^ ((s17 << (32- 19)) | (s17 >> 19)) ^ (s17 >> 10));
+	s20 = s04 + s13 + (((s05 << 25) | (s05 >> 7)) ^ ((s05 << 14) | (s05 >> 18)) ^ (s05 >> 3)) + (((s18 << 15) | (s18 >> 17)) ^ ((s18 << (32- 19)) | (s18 >> 19)) ^ (s18 >> 10));
+	s21 = s05 + s14 + (((s06 << 25) | (s06 >> 7)) ^ ((s06 << 14) | (s06 >> 18)) ^ (s06 >> 3)) + (((s19 << 15) | (s19 >> 17)) ^ ((s19 << (32- 19)) | (s19 >> 19)) ^ (s19 >> 10));
+	s22 = s06 + s15 + (((s07 << 25) | (s07 >> 7)) ^ ((s07 << 14) | (s07 >> 18)) ^ (s07 >> 3)) + (((s20 << 15) | (s20 >> 17)) ^ ((s20 << (32- 19)) | (s20 >> 19)) ^ (s20 >> 10));
+	s23 = s07 + s16 + (((s08 << 25) | (s08 >> 7)) ^ ((s08 << 14) | (s08 >> 18)) ^ (s08 >> 3)) + (((s21 << 15) | (s21 >> 17)) ^ ((s21 << (32- 19)) | (s21 >> 19)) ^ (s21 >> 10));
+	s24 = s08 + s17 + (((s09 << 25) | (s09 >> 7)) ^ ((s09 << 14) | (s09 >> 18)) ^ (s09 >> 3)) + (((s22 << 15) | (s22 >> 17)) ^ ((s22 << (32- 19)) | (s22 >> 19)) ^ (s22 >> 10));
+	s25 = s09 + s18 + (((s10 << 25) | (s10 >> 7)) ^ ((s10 << 14) | (s10 >> 18)) ^ (s10 >> 3)) + (((s23 << 15) | (s23 >> 17)) ^ ((s23 << (32- 19)) | (s23 >> 19)) ^ (s23 >> 10));
+	s26 = s10 + s19 + (((s11 << 25) | (s11 >> 7)) ^ ((s11 << 14) | (s11 >> 18)) ^ (s11 >> 3)) + (((s24 << 15) | (s24 >> 17)) ^ ((s24 << (32- 19)) | (s24 >> 19)) ^ (s24 >> 10));
+	s27 = s11 + s20 + (((s12 << 25) | (s12 >> 7)) ^ ((s12 << 14) | (s12 >> 18)) ^ (s12 >> 3)) + (((s25 << 15) | (s25 >> 17)) ^ ((s25 << (32- 19)) | (s25 >> 19)) ^ (s25 >> 10));
+	s28 = s12 + s21 + (((s13 << 25) | (s13 >> 7)) ^ ((s13 << 14) | (s13 >> 18)) ^ (s13 >> 3)) + (((s26 << 15) | (s26 >> 17)) ^ ((s26 << (32- 19)) | (s26 >> 19)) ^ (s26 >> 10));
+	s29 = s13 + s22 + (((s14 << 25) | (s14 >> 7)) ^ ((s14 << 14) | (s14 >> 18)) ^ (s14 >> 3)) + (((s27 << 15) | (s27 >> 17)) ^ ((s27 << (32- 19)) | (s27 >> 19)) ^ (s27 >> 10));
+	s30 = s14 + s23 + (((s15 << 25) | (s15 >> 7)) ^ ((s15 << 14) | (s15 >> 18)) ^ (s15 >> 3)) + (((s28 << 15) | (s28 >> 17)) ^ ((s28 << (32- 19)) | (s28 >> 19)) ^ (s28 >> 10));
+	s31 = s15 + s24 + (((s16 << 25) | (s16 >> 7)) ^ ((s16 << 14) | (s16 >> 18)) ^ (s16 >> 3)) + (((s29 << 15) | (s29 >> 17)) ^ ((s29 << (32- 19)) | (s29 >> 19)) ^ (s29 >> 10));
+	s32 = s16 + s25 + (((s17 << 25) | (s17 >> 7)) ^ ((s17 << 14) | (s17 >> 18)) ^ (s17 >> 3)) + (((s30 << 15) | (s30 >> 17)) ^ ((s30 << (32- 19)) | (s30 >> 19)) ^ (s30 >> 10));
+	s33 = s17 + s26 + (((s18 << 25) | (s18 >> 7)) ^ ((s18 << 14) | (s18 >> 18)) ^ (s18 >> 3)) + (((s31 << 15) | (s31 >> 17)) ^ ((s31 << (32- 19)) | (s31 >> 19)) ^ (s31 >> 10));
+	s34 = s18 + s27 + (((s19 << 25) | (s19 >> 7)) ^ ((s19 << 14) | (s19 >> 18)) ^ (s19 >> 3)) + (((s32 << 15) | (s32 >> 17)) ^ ((s32 << (32- 19)) | (s32 >> 19)) ^ (s32 >> 10));
+	s35 = s19 + s28 + (((s20 << 25) | (s20 >> 7)) ^ ((s20 << 14) | (s20 >> 18)) ^ (s20 >> 3)) + (((s33 << 15) | (s33 >> 17)) ^ ((s33 << (32- 19)) | (s33 >> 19)) ^ (s33 >> 10));
+	s36 = s20 + s29 + (((s21 << 25) | (s21 >> 7)) ^ ((s21 << 14) | (s21 >> 18)) ^ (s21 >> 3)) + (((s34 << 15) | (s34 >> 17)) ^ ((s34 << (32- 19)) | (s34 >> 19)) ^ (s34 >> 10));
+	s37 = s21 + s30 + (((s22 << 25) | (s22 >> 7)) ^ ((s22 << 14) | (s22 >> 18)) ^ (s22 >> 3)) + (((s35 << 15) | (s35 >> 17)) ^ ((s35 << (32- 19)) | (s35 >> 19)) ^ (s35 >> 10));
+	s38 = s22 + s31 + (((s23 << 25) | (s23 >> 7)) ^ ((s23 << 14) | (s23 >> 18)) ^ (s23 >> 3)) + (((s36 << 15) | (s36 >> 17)) ^ ((s36 << (32- 19)) | (s36 >> 19)) ^ (s36 >> 10));
+	s39 = s23 + s32 + (((s24 << 25) | (s24 >> 7)) ^ ((s24 << 14) | (s24 >> 18)) ^ (s24 >> 3)) + (((s37 << 15) | (s37 >> 17)) ^ ((s37 << (32- 19)) | (s37 >> 19)) ^ (s37 >> 10));
+	s40 = s24 + s33 + (((s25 << 25) | (s25 >> 7)) ^ ((s25 << 14) | (s25 >> 18)) ^ (s25 >> 3)) + (((s38 << 15) | (s38 >> 17)) ^ ((s38 << (32- 19)) | (s38 >> 19)) ^ (s38 >> 10));
+	s41 = s25 + s34 + (((s26 << 25) | (s26 >> 7)) ^ ((s26 << 14) | (s26 >> 18)) ^ (s26 >> 3)) + (((s39 << 15) | (s39 >> 17)) ^ ((s39 << (32- 19)) | (s39 >> 19)) ^ (s39 >> 10));
+	s42 = s26 + s35 + (((s27 << 25) | (s27 >> 7)) ^ ((s27 << 14) | (s27 >> 18)) ^ (s27 >> 3)) + (((s40 << 15) | (s40 >> 17)) ^ ((s40 << (32- 19)) | (s40 >> 19)) ^ (s40 >> 10));
+	s43 = s27 + s36 + (((s28 << 25) | (s28 >> 7)) ^ ((s28 << 14) | (s28 >> 18)) ^ (s28 >> 3)) + (((s41 << 15) | (s41 >> 17)) ^ ((s41 << (32- 19)) | (s41 >> 19)) ^ (s41 >> 10));
+	s44 = s28 + s37 + (((s29 << 25) | (s29 >> 7)) ^ ((s29 << 14) | (s29 >> 18)) ^ (s29 >> 3)) + (((s42 << 15) | (s42 >> 17)) ^ ((s42 << (32- 19)) | (s42 >> 19)) ^ (s42 >> 10));
+	s45 = s29 + s38 + (((s30 << 25) | (s30 >> 7)) ^ ((s30 << 14) | (s30 >> 18)) ^ (s30 >> 3)) + (((s43 << 15) | (s43 >> 17)) ^ ((s43 << (32- 19)) | (s43 >> 19)) ^ (s43 >> 10));
+	s46 = s30 + s39 + (((s31 << 25) | (s31 >> 7)) ^ ((s31 << 14) | (s31 >> 18)) ^ (s31 >> 3)) + (((s44 << 15) | (s44 >> 17)) ^ ((s44 << (32- 19)) | (s44 >> 19)) ^ (s44 >> 10));
+	s47 = s31 + s40 + (((s32 << 25) | (s32 >> 7)) ^ ((s32 << 14) | (s32 >> 18)) ^ (s32 >> 3)) + (((s45 << 15) | (s45 >> 17)) ^ ((s45 << (32- 19)) | (s45 >> 19)) ^ (s45 >> 10));
+	s48 = s32 + s41 + (((s33 << 25) | (s33 >> 7)) ^ ((s33 << 14) | (s33 >> 18)) ^ (s33 >> 3)) + (((s46 << 15) | (s46 >> 17)) ^ ((s46 << (32- 19)) | (s46 >> 19)) ^ (s46 >> 10));
+	s49 = s33 + s42 + (((s34 << 25) | (s34 >> 7)) ^ ((s34 << 14) | (s34 >> 18)) ^ (s34 >> 3)) + (((s47 << 15) | (s47 >> 17)) ^ ((s47 << (32- 19)) | (s47 >> 19)) ^ (s47 >> 10));
+	s50 = s34 + s43 + (((s35 << 25) | (s35 >> 7)) ^ ((s35 << 14) | (s35 >> 18)) ^ (s35 >> 3)) + (((s48 << 15) | (s48 >> 17)) ^ ((s48 << (32- 19)) | (s48 >> 19)) ^ (s48 >> 10));
+	s51 = s35 + s44 + (((s36 << 25) | (s36 >> 7)) ^ ((s36 << 14) | (s36 >> 18)) ^ (s36 >> 3)) + (((s49 << 15) | (s49 >> 17)) ^ ((s49 << (32- 19)) | (s49 >> 19)) ^ (s49 >> 10));
+	s52 = s36 + s45 + (((s37 << 25) | (s37 >> 7)) ^ ((s37 << 14) | (s37 >> 18)) ^ (s37 >> 3)) + (((s50 << 15) | (s50 >> 17)) ^ ((s50 << (32- 19)) | (s50 >> 19)) ^ (s50 >> 10));
+	s53 = s37 + s46 + (((s38 << 25) | (s38 >> 7)) ^ ((s38 << 14) | (s38 >> 18)) ^ (s38 >> 3)) + (((s51 << 15) | (s51 >> 17)) ^ ((s51 << (32- 19)) | (s51 >> 19)) ^ (s51 >> 10));
+	s54 = s38 + s47 + (((s39 << 25) | (s39 >> 7)) ^ ((s39 << 14) | (s39 >> 18)) ^ (s39 >> 3)) + (((s52 << 15) | (s52 >> 17)) ^ ((s52 << (32- 19)) | (s52 >> 19)) ^ (s52 >> 10));
+	s55 = s39 + s48 + (((s40 << 25) | (s40 >> 7)) ^ ((s40 << 14) | (s40 >> 18)) ^ (s40 >> 3)) + (((s53 << 15) | (s53 >> 17)) ^ ((s53 << (32- 19)) | (s53 >> 19)) ^ (s53 >> 10));
+	s56 = s40 + s49 + (((s41 << 25) | (s41 >> 7)) ^ ((s41 << 14) | (s41 >> 18)) ^ (s41 >> 3)) + (((s54 << 15) | (s54 >> 17)) ^ ((s54 << (32- 19)) | (s54 >> 19)) ^ (s54 >> 10));
+	s57 = s41 + s50 + (((s42 << 25) | (s42 >> 7)) ^ ((s42 << 14) | (s42 >> 18)) ^ (s42 >> 3)) + (((s55 << 15) | (s55 >> 17)) ^ ((s55 << (32- 19)) | (s55 >> 19)) ^ (s55 >> 10));
+	s58 = s42 + s51 + (((s43 << 25) | (s43 >> 7)) ^ ((s43 << 14) | (s43 >> 18)) ^ (s43 >> 3)) + (((s56 << 15) | (s56 >> 17)) ^ ((s56 << (32- 19)) | (s56 >> 19)) ^ (s56 >> 10));
+	s59 = s43 + s52 + (((s44 << 25) | (s44 >> 7)) ^ ((s44 << 14) | (s44 >> 18)) ^ (s44 >> 3)) + (((s57 << 15) | (s57 >> 17)) ^ ((s57 << (32- 19)) | (s57 >> 19)) ^ (s57 >> 10));
+	s60 = s44 + s53 + (((s45 << 25) | (s45 >> 7)) ^ ((s45 << 14) | (s45 >> 18)) ^ (s45 >> 3)) + (((s58 << 15) | (s58 >> 17)) ^ ((s58 << (32- 19)) | (s58 >> 19)) ^ (s58 >> 10));
+	s61 = s45 + s54 + (((s46 << 25) | (s46 >> 7)) ^ ((s46 << 14) | (s46 >> 18)) ^ (s46 >> 3)) + (((s59 << 15) | (s59 >> 17)) ^ ((s59 << (32- 19)) | (s59 >> 19)) ^ (s59 >> 10));
+	s62 = s46 + s55 + (((s47 << 25) | (s47 >> 7)) ^ ((s47 << 14) | (s47 >> 18)) ^ (s47 >> 3)) + (((s60 << 15) | (s60 >> 17)) ^ ((s60 << (32- 19)) | (s60 >> 19)) ^ (s60 >> 10));
+	s63 = s47 + s56 + (((s48 << 25) | (s48 >> 7)) ^ ((s48 << 14) | (s48 >> 18)) ^ (s48 >> 3)) + (((s61 << 15) | (s61 >> 17)) ^ ((s61 << (32- 19)) | (s61 >> 19)) ^ (s61 >> 10));
+
+		
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x428a2f98 + s00;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x71374491 + s01;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xb5c0fbcf + s02;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xe9b5dba5 + s03;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x3956c25b + s04;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x59f111f1 + s05;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x923f82a4 + s06;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xab1c5ed5 + s07;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xd807aa98 + s08;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x12835b01 + s09;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x243185be + s10;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x550c7dc3 + s11;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x72be5d74 + s12;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x80deb1fe + s13;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x9bdc06a7 + s14;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xc19bf174 + s15;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xe49b69c1 + s16;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xefbe4786 + s17;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x0fc19dc6 + s18;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x240ca1cc + s19;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x2de92c6f + s20;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x4a7484aa + s21;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x5cb0a9dc + s22;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x76f988da + s23;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x983e5152 + s24;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xa831c66d + s25;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xb00327c8 + s26;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xbf597fc7 + s27;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0xc6e00bf3 + s28;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xd5a79147 + s29;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x06ca6351 + s30;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x14292967 + s31;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x27b70a85 + s32;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x2e1b2138 + s33;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x4d2c6dfc + s34;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x53380d13 + s35;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x650a7354 + s36;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x766a0abb + s37;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x81c2c92e + s38;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x92722c85 + s39;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xa2bfe8a1 + s40;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xa81a664b + s41;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xc24b8b70 + s42;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xc76c51a3 + s43;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0xd192e819 + s44;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xd6990624 + s45;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0xf40e3585 + s46;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x106aa070 + s47;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x19a4c116 + s48;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x1e376c08 + s49;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x2748774c + s50;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x34b0bcb5 + s51;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x391c0cb3 + s52;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x4ed8aa4a + s53;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x5b9cca4f + s54;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x682e6ff3 + s55;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x748f82ee + s56;
+	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
+	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x78a5636f + s57;
+	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
+	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x84c87814 + s58;
+	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
+	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x8cc70208 + s59;
+	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
+	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x90befffa + s60;
+	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
+	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xa4506ceb + s61;
+	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
+	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0xbef9a3f7 + s62;
+	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
+	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xc67178f2 + s63;
+	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
+
+	x[0] += a
+	x[1] += b
+	x[2] += c
+	x[3] += d
+	x[4] += e
+	x[5] += f
+	x[6] += g
+	x[7] += h
+}
+
+const unpack = {b
+	var v : uint32
+
+	v = ((b[0] castto(uint32)) << 24)
+	v |= ((b[1] castto(uint32)) << 16)
+	v |= ((b[2] castto(uint32)) << 8)
+	v |= ((b[3] castto(uint32)) << 0)
+	-> v
+}
+
+const pack = {out, v
+	out[0]  = (v >> 24)	castto(byte)
+	out[1]  = (v >> 16)	castto(byte)
+	out[2]  = (v >> 8)	castto(byte)
+	out[3]  = (v >> 0)	castto(byte)
+}
--- /dev/null
+++ b/lib/cryptohash/sha512.myr
@@ -1,0 +1,474 @@
+use std
+
+pkg cryptohash =
+	type sha512
+	type sha384
+
+	const sha512	: (data : byte[:] -> byte[64])
+	const sha512init	: (st : sha512# -> void)
+	const sha512add	: (st : sha512#, data : byte[:] -> void)
+	const sha512fin	: (st : sha512# -> byte[64])
+
+	const sha384	: (data : byte[:] -> byte[48])
+	const sha384init	: (st : sha384# -> void)
+	const sha384add	: (st : sha384#, data : byte[:] -> void)
+	const sha384fin	: (st : sha384# -> byte[48])
+;;
+
+
+type sha512 = struct
+	x	: uint64[8]
+	tail	: byte[128]
+	msglen	: uint64
+;;
+
+type sha384 = struct
+	x	: uint64[8]
+	tail	: byte[128]
+	msglen	: uint64
+;;
+
+const sha512 = {data
+	var st
+
+	sha512init(&st)
+	sha512add(&st, data)
+	-> sha512fin(&st)
+}
+
+const sha512init = {st
+	st.x[0] = 0x6a09e667f3bcc908ul
+	st.x[1] = 0xbb67ae8584caa73bul
+	st.x[2] = 0x3c6ef372fe94f82bul
+	st.x[3] = 0xa54ff53a5f1d36f1ul
+	st.x[4] = 0x510e527fade682d1ul
+	st.x[5] = 0x9b05688c2b3e6c1ful
+	st.x[6] = 0x1f83d9abfb41bd6bul
+	st.x[7] = 0x5be0cd19137e2179ul
+	st.msglen = 0
+}
+
+const sha512add = {st, data
+	var n, ntail
+
+	ntail = st.msglen % 128
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(128 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail+n], data[:n])
+		data = data[n:]
+		if n + ntail < 128
+			->
+		;;
+		step(st.x[:], st.tail[:])
+	;;
+
+	while data.len >= 128
+		step(st.x[:], data[:128])
+		data = data[128:]
+	;;
+
+	ntail = st.msglen % 128
+	std.slcp(st.tail[:ntail], data)
+}
+
+const sha512fin = {st
+	var r : byte[64]
+
+	tail(st.x[:], st.msglen, st.tail[:])
+
+	pack(r[ 0: 8],	st.x[0])
+	pack(r[ 8:16],	st.x[1])
+	pack(r[16:24],	st.x[2])
+	pack(r[24:32],	st.x[3])
+	pack(r[32:40],	st.x[4])
+	pack(r[40:48],	st.x[5])
+	pack(r[48:56],	st.x[6])
+	pack(r[56:64],	st.x[7])
+	-> r
+}
+
+const sha384 = {data
+	var st
+
+	sha384init(&st)
+	sha384add(&st, data)
+	-> sha384fin(&st)
+}
+
+const sha384init = {st
+	st.x[0] = 0xCBBB9D5DC1059ED8ul
+	st.x[1] = 0x629A292A367CD507ul
+	st.x[2] = 0x9159015A3070DD17ul
+	st.x[3] = 0x152FECD8F70E5939ul
+	st.x[4] = 0x67332667FFC00B31ul
+	st.x[5] = 0x8EB44A8768581511ul
+	st.x[6] = 0xDB0C2E0D64F98FA7ul
+	st.x[7] = 0x47B5481DBEFA4FA4ul
+	st.msglen = 0
+}
+
+const sha384add = {st, data
+	var n, ntail
+
+	ntail = st.msglen % 128
+	st.msglen += data.len
+	if ntail > 0
+		n = std.min(128 - ntail, data.len)
+		std.slcp(st.tail[ntail:ntail+n], data[:n])
+		data = data[n:]
+		if n + ntail < 128
+			->
+		;;
+		step(st.x[:], st.tail[:])
+	;;
+
+	while data.len >= 128
+		step(st.x[:], data[:128])
+		data = data[128:]
+	;;
+
+	ntail = st.msglen % 128
+	std.slcp(st.tail[:ntail], data)
+}
+
+const sha384fin = {st
+	var r : byte[48]
+
+	tail(st.x[:], st.msglen, st.tail[:])
+
+	pack(r[ 0: 8],	st.x[0])
+	pack(r[ 8:16],	st.x[1])
+	pack(r[16:24],	st.x[2])
+	pack(r[24:32],	st.x[3])
+	pack(r[32:40],	st.x[4])
+	pack(r[40:48],	st.x[5])
+	-> r
+}
+
+
+const tail = {x, msglen, tail
+	var ntail
+
+	/* append first padding block */
+	ntail = msglen % 128
+	tail[ntail++] = 0x80
+	std.slfill(tail[ntail:], 0)
+	if 128 - ntail < 16
+		step(x, tail)
+		std.slfill(tail, 0)
+	;;
+
+	/* append size block */
+	tail[120] = ((msglen * 8) >> 56)	castto(byte)
+	tail[121] = ((msglen * 8) >> 48)	castto(byte)
+	tail[122] = ((msglen * 8) >> 40)	castto(byte)
+	tail[123] = ((msglen * 8) >> 32)	castto(byte)
+	tail[124] = ((msglen * 8) >> 24)	castto(byte)
+	tail[125] = ((msglen * 8) >> 16)	castto(byte)
+	tail[126] = ((msglen * 8) >> 8)	castto(byte)
+	tail[127] = ((msglen * 8) >> 0)	castto(byte)
+	step(x, tail)
+}
+
+const step = {x : uint64[:], msg
+	var a, b, c, d, e, f, g, h
+	var s00, s01, s02, s03, s04, s05, s06, s07
+	var s08, s09, s10, s11, s12, s13, s14, s15
+	var s16, s17, s18, s19, s20, s21, s22, s23
+	var s24, s25, s26, s27, s28, s29, s30, s31
+	var s32, s33, s34, s35, s36, s37, s38, s39
+	var s40, s41, s42, s43, s44, s45, s46, s47
+	var s48, s49, s50, s51, s52, s53, s54, s55
+	var s56, s57, s58, s59, s60, s61, s62, s63
+	var s64, s65, s66, s67, s68, s69, s70, s71
+	var s72, s73, s74, s75, s76, s77, s78, s79
+
+	a = x[0]
+	b = x[1]
+	c = x[2]
+	d = x[3]
+	e = x[4]
+	f = x[5]
+	g = x[6]
+	h = x[7]
+
+	s00 = unpack(msg[  0:  8])
+	s01 = unpack(msg[  8: 16])
+	s02 = unpack(msg[ 16: 24])
+	s03 = unpack(msg[ 24: 32])
+	s04 = unpack(msg[ 32: 40])
+	s05 = unpack(msg[ 40: 48])
+	s06 = unpack(msg[ 48: 56])
+	s07 = unpack(msg[ 56: 64])
+	s08 = unpack(msg[ 64: 72])
+	s09 = unpack(msg[ 72: 80])
+	s10 = unpack(msg[ 80: 88])
+	s11 = unpack(msg[ 88: 96])
+	s12 = unpack(msg[ 96:104])
+	s13 = unpack(msg[104:112])
+	s14 = unpack(msg[112:120])
+	s15 = unpack(msg[120:128])
+
+	s16 = s00 + s09 + (((s01 << 63) | (s01 >> 1))^((s01 << 56) | (s01 >> 8))^(s01 >> 7)) + (((s14 << 45) | (s14 >> 19))^((s14 << 3) | (s14 >> 61))^(s14 >> 6))
+	s17 = s01 + s10 + (((s02 << 63) | (s02 >> 1))^((s02 << 56) | (s02 >> 8))^(s02 >> 7)) + (((s15 << 45) | (s15 >> 19))^((s15 << 3) | (s15 >> 61))^(s15 >> 6))
+	s18 = s02 + s11 + (((s03 << 63) | (s03 >> 1))^((s03 << 56) | (s03 >> 8))^(s03 >> 7)) + (((s16 << 45) | (s16 >> 19))^((s16 << 3) | (s16 >> 61))^(s16 >> 6))
+	s19 = s03 + s12 + (((s04 << 63) | (s04 >> 1))^((s04 << 56) | (s04 >> 8))^(s04 >> 7)) + (((s17 << 45) | (s17 >> 19))^((s17 << 3) | (s17 >> 61))^(s17 >> 6))
+	s20 = s04 + s13 + (((s05 << 63) | (s05 >> 1))^((s05 << 56) | (s05 >> 8))^(s05 >> 7)) + (((s18 << 45) | (s18 >> 19))^((s18 << 3) | (s18 >> 61))^(s18 >> 6))
+	s21 = s05 + s14 + (((s06 << 63) | (s06 >> 1))^((s06 << 56) | (s06 >> 8))^(s06 >> 7)) + (((s19 << 45) | (s19 >> 19))^((s19 << 3) | (s19 >> 61))^(s19 >> 6))
+	s22 = s06 + s15 + (((s07 << 63) | (s07 >> 1))^((s07 << 56) | (s07 >> 8))^(s07 >> 7)) + (((s20 << 45) | (s20 >> 19))^((s20 << 3) | (s20 >> 61))^(s20 >> 6))
+	s23 = s07 + s16 + (((s08 << 63) | (s08 >> 1))^((s08 << 56) | (s08 >> 8))^(s08 >> 7)) + (((s21 << 45) | (s21 >> 19))^((s21 << 3) | (s21 >> 61))^(s21 >> 6))
+	s24 = s08 + s17 + (((s09 << 63) | (s09 >> 1))^((s09 << 56) | (s09 >> 8))^(s09 >> 7)) + (((s22 << 45) | (s22 >> 19))^((s22 << 3) | (s22 >> 61))^(s22 >> 6))
+	s25 = s09 + s18 + (((s10 << 63) | (s10 >> 1))^((s10 << 56) | (s10 >> 8))^(s10 >> 7)) + (((s23 << 45) | (s23 >> 19))^((s23 << 3) | (s23 >> 61))^(s23 >> 6))
+	s26 = s10 + s19 + (((s11 << 63) | (s11 >> 1))^((s11 << 56) | (s11 >> 8))^(s11 >> 7)) + (((s24 << 45) | (s24 >> 19))^((s24 << 3) | (s24 >> 61))^(s24 >> 6))
+	s27 = s11 + s20 + (((s12 << 63) | (s12 >> 1))^((s12 << 56) | (s12 >> 8))^(s12 >> 7)) + (((s25 << 45) | (s25 >> 19))^((s25 << 3) | (s25 >> 61))^(s25 >> 6))
+	s28 = s12 + s21 + (((s13 << 63) | (s13 >> 1))^((s13 << 56) | (s13 >> 8))^(s13 >> 7)) + (((s26 << 45) | (s26 >> 19))^((s26 << 3) | (s26 >> 61))^(s26 >> 6))
+	s29 = s13 + s22 + (((s14 << 63) | (s14 >> 1))^((s14 << 56) | (s14 >> 8))^(s14 >> 7)) + (((s27 << 45) | (s27 >> 19))^((s27 << 3) | (s27 >> 61))^(s27 >> 6))
+	s30 = s14 + s23 + (((s15 << 63) | (s15 >> 1))^((s15 << 56) | (s15 >> 8))^(s15 >> 7)) + (((s28 << 45) | (s28 >> 19))^((s28 << 3) | (s28 >> 61))^(s28 >> 6))
+	s31 = s15 + s24 + (((s16 << 63) | (s16 >> 1))^((s16 << 56) | (s16 >> 8))^(s16 >> 7)) + (((s29 << 45) | (s29 >> 19))^((s29 << 3) | (s29 >> 61))^(s29 >> 6))
+	s32 = s16 + s25 + (((s17 << 63) | (s17 >> 1))^((s17 << 56) | (s17 >> 8))^(s17 >> 7)) + (((s30 << 45) | (s30 >> 19))^((s30 << 3) | (s30 >> 61))^(s30 >> 6))
+	s33 = s17 + s26 + (((s18 << 63) | (s18 >> 1))^((s18 << 56) | (s18 >> 8))^(s18 >> 7)) + (((s31 << 45) | (s31 >> 19))^((s31 << 3) | (s31 >> 61))^(s31 >> 6))
+	s34 = s18 + s27 + (((s19 << 63) | (s19 >> 1))^((s19 << 56) | (s19 >> 8))^(s19 >> 7)) + (((s32 << 45) | (s32 >> 19))^((s32 << 3) | (s32 >> 61))^(s32 >> 6))
+	s35 = s19 + s28 + (((s20 << 63) | (s20 >> 1))^((s20 << 56) | (s20 >> 8))^(s20 >> 7)) + (((s33 << 45) | (s33 >> 19))^((s33 << 3) | (s33 >> 61))^(s33 >> 6))
+	s36 = s20 + s29 + (((s21 << 63) | (s21 >> 1))^((s21 << 56) | (s21 >> 8))^(s21 >> 7)) + (((s34 << 45) | (s34 >> 19))^((s34 << 3) | (s34 >> 61))^(s34 >> 6))
+	s37 = s21 + s30 + (((s22 << 63) | (s22 >> 1))^((s22 << 56) | (s22 >> 8))^(s22 >> 7)) + (((s35 << 45) | (s35 >> 19))^((s35 << 3) | (s35 >> 61))^(s35 >> 6))
+	s38 = s22 + s31 + (((s23 << 63) | (s23 >> 1))^((s23 << 56) | (s23 >> 8))^(s23 >> 7)) + (((s36 << 45) | (s36 >> 19))^((s36 << 3) | (s36 >> 61))^(s36 >> 6))
+	s39 = s23 + s32 + (((s24 << 63) | (s24 >> 1))^((s24 << 56) | (s24 >> 8))^(s24 >> 7)) + (((s37 << 45) | (s37 >> 19))^((s37 << 3) | (s37 >> 61))^(s37 >> 6))
+	s40 = s24 + s33 + (((s25 << 63) | (s25 >> 1))^((s25 << 56) | (s25 >> 8))^(s25 >> 7)) + (((s38 << 45) | (s38 >> 19))^((s38 << 3) | (s38 >> 61))^(s38 >> 6))
+	s41 = s25 + s34 + (((s26 << 63) | (s26 >> 1))^((s26 << 56) | (s26 >> 8))^(s26 >> 7)) + (((s39 << 45) | (s39 >> 19))^((s39 << 3) | (s39 >> 61))^(s39 >> 6))
+	s42 = s26 + s35 + (((s27 << 63) | (s27 >> 1))^((s27 << 56) | (s27 >> 8))^(s27 >> 7)) + (((s40 << 45) | (s40 >> 19))^((s40 << 3) | (s40 >> 61))^(s40 >> 6))
+	s43 = s27 + s36 + (((s28 << 63) | (s28 >> 1))^((s28 << 56) | (s28 >> 8))^(s28 >> 7)) + (((s41 << 45) | (s41 >> 19))^((s41 << 3) | (s41 >> 61))^(s41 >> 6))
+	s44 = s28 + s37 + (((s29 << 63) | (s29 >> 1))^((s29 << 56) | (s29 >> 8))^(s29 >> 7)) + (((s42 << 45) | (s42 >> 19))^((s42 << 3) | (s42 >> 61))^(s42 >> 6))
+	s45 = s29 + s38 + (((s30 << 63) | (s30 >> 1))^((s30 << 56) | (s30 >> 8))^(s30 >> 7)) + (((s43 << 45) | (s43 >> 19))^((s43 << 3) | (s43 >> 61))^(s43 >> 6))
+	s46 = s30 + s39 + (((s31 << 63) | (s31 >> 1))^((s31 << 56) | (s31 >> 8))^(s31 >> 7)) + (((s44 << 45) | (s44 >> 19))^((s44 << 3) | (s44 >> 61))^(s44 >> 6))
+	s47 = s31 + s40 + (((s32 << 63) | (s32 >> 1))^((s32 << 56) | (s32 >> 8))^(s32 >> 7)) + (((s45 << 45) | (s45 >> 19))^((s45 << 3) | (s45 >> 61))^(s45 >> 6))
+	s48 = s32 + s41 + (((s33 << 63) | (s33 >> 1))^((s33 << 56) | (s33 >> 8))^(s33 >> 7)) + (((s46 << 45) | (s46 >> 19))^((s46 << 3) | (s46 >> 61))^(s46 >> 6))
+	s49 = s33 + s42 + (((s34 << 63) | (s34 >> 1))^((s34 << 56) | (s34 >> 8))^(s34 >> 7)) + (((s47 << 45) | (s47 >> 19))^((s47 << 3) | (s47 >> 61))^(s47 >> 6))
+	s50 = s34 + s43 + (((s35 << 63) | (s35 >> 1))^((s35 << 56) | (s35 >> 8))^(s35 >> 7)) + (((s48 << 45) | (s48 >> 19))^((s48 << 3) | (s48 >> 61))^(s48 >> 6))
+	s51 = s35 + s44 + (((s36 << 63) | (s36 >> 1))^((s36 << 56) | (s36 >> 8))^(s36 >> 7)) + (((s49 << 45) | (s49 >> 19))^((s49 << 3) | (s49 >> 61))^(s49 >> 6))
+	s52 = s36 + s45 + (((s37 << 63) | (s37 >> 1))^((s37 << 56) | (s37 >> 8))^(s37 >> 7)) + (((s50 << 45) | (s50 >> 19))^((s50 << 3) | (s50 >> 61))^(s50 >> 6))
+	s53 = s37 + s46 + (((s38 << 63) | (s38 >> 1))^((s38 << 56) | (s38 >> 8))^(s38 >> 7)) + (((s51 << 45) | (s51 >> 19))^((s51 << 3) | (s51 >> 61))^(s51 >> 6))
+	s54 = s38 + s47 + (((s39 << 63) | (s39 >> 1))^((s39 << 56) | (s39 >> 8))^(s39 >> 7)) + (((s52 << 45) | (s52 >> 19))^((s52 << 3) | (s52 >> 61))^(s52 >> 6))
+	s55 = s39 + s48 + (((s40 << 63) | (s40 >> 1))^((s40 << 56) | (s40 >> 8))^(s40 >> 7)) + (((s53 << 45) | (s53 >> 19))^((s53 << 3) | (s53 >> 61))^(s53 >> 6))
+	s56 = s40 + s49 + (((s41 << 63) | (s41 >> 1))^((s41 << 56) | (s41 >> 8))^(s41 >> 7)) + (((s54 << 45) | (s54 >> 19))^((s54 << 3) | (s54 >> 61))^(s54 >> 6))
+	s57 = s41 + s50 + (((s42 << 63) | (s42 >> 1))^((s42 << 56) | (s42 >> 8))^(s42 >> 7)) + (((s55 << 45) | (s55 >> 19))^((s55 << 3) | (s55 >> 61))^(s55 >> 6))
+	s58 = s42 + s51 + (((s43 << 63) | (s43 >> 1))^((s43 << 56) | (s43 >> 8))^(s43 >> 7)) + (((s56 << 45) | (s56 >> 19))^((s56 << 3) | (s56 >> 61))^(s56 >> 6))
+	s59 = s43 + s52 + (((s44 << 63) | (s44 >> 1))^((s44 << 56) | (s44 >> 8))^(s44 >> 7)) + (((s57 << 45) | (s57 >> 19))^((s57 << 3) | (s57 >> 61))^(s57 >> 6))
+	s60 = s44 + s53 + (((s45 << 63) | (s45 >> 1))^((s45 << 56) | (s45 >> 8))^(s45 >> 7)) + (((s58 << 45) | (s58 >> 19))^((s58 << 3) | (s58 >> 61))^(s58 >> 6))
+	s61 = s45 + s54 + (((s46 << 63) | (s46 >> 1))^((s46 << 56) | (s46 >> 8))^(s46 >> 7)) + (((s59 << 45) | (s59 >> 19))^((s59 << 3) | (s59 >> 61))^(s59 >> 6))
+	s62 = s46 + s55 + (((s47 << 63) | (s47 >> 1))^((s47 << 56) | (s47 >> 8))^(s47 >> 7)) + (((s60 << 45) | (s60 >> 19))^((s60 << 3) | (s60 >> 61))^(s60 >> 6))
+	s63 = s47 + s56 + (((s48 << 63) | (s48 >> 1))^((s48 << 56) | (s48 >> 8))^(s48 >> 7)) + (((s61 << 45) | (s61 >> 19))^((s61 << 3) | (s61 >> 61))^(s61 >> 6))
+	s64 = s48 + s57 + (((s49 << 63) | (s49 >> 1))^((s49 << 56) | (s49 >> 8))^(s49 >> 7)) + (((s62 << 45) | (s62 >> 19))^((s62 << 3) | (s62 >> 61))^(s62 >> 6))
+	s65 = s49 + s58 + (((s50 << 63) | (s50 >> 1))^((s50 << 56) | (s50 >> 8))^(s50 >> 7)) + (((s63 << 45) | (s63 >> 19))^((s63 << 3) | (s63 >> 61))^(s63 >> 6))
+	s66 = s50 + s59 + (((s51 << 63) | (s51 >> 1))^((s51 << 56) | (s51 >> 8))^(s51 >> 7)) + (((s64 << 45) | (s64 >> 19))^((s64 << 3) | (s64 >> 61))^(s64 >> 6))
+	s67 = s51 + s60 + (((s52 << 63) | (s52 >> 1))^((s52 << 56) | (s52 >> 8))^(s52 >> 7)) + (((s65 << 45) | (s65 >> 19))^((s65 << 3) | (s65 >> 61))^(s65 >> 6))
+	s68 = s52 + s61 + (((s53 << 63) | (s53 >> 1))^((s53 << 56) | (s53 >> 8))^(s53 >> 7)) + (((s66 << 45) | (s66 >> 19))^((s66 << 3) | (s66 >> 61))^(s66 >> 6))
+	s69 = s53 + s62 + (((s54 << 63) | (s54 >> 1))^((s54 << 56) | (s54 >> 8))^(s54 >> 7)) + (((s67 << 45) | (s67 >> 19))^((s67 << 3) | (s67 >> 61))^(s67 >> 6))
+	s70 = s54 + s63 + (((s55 << 63) | (s55 >> 1))^((s55 << 56) | (s55 >> 8))^(s55 >> 7)) + (((s68 << 45) | (s68 >> 19))^((s68 << 3) | (s68 >> 61))^(s68 >> 6))
+	s71 = s55 + s64 + (((s56 << 63) | (s56 >> 1))^((s56 << 56) | (s56 >> 8))^(s56 >> 7)) + (((s69 << 45) | (s69 >> 19))^((s69 << 3) | (s69 >> 61))^(s69 >> 6))
+	s72 = s56 + s65 + (((s57 << 63) | (s57 >> 1))^((s57 << 56) | (s57 >> 8))^(s57 >> 7)) + (((s70 << 45) | (s70 >> 19))^((s70 << 3) | (s70 >> 61))^(s70 >> 6))
+	s73 = s57 + s66 + (((s58 << 63) | (s58 >> 1))^((s58 << 56) | (s58 >> 8))^(s58 >> 7)) + (((s71 << 45) | (s71 >> 19))^((s71 << 3) | (s71 >> 61))^(s71 >> 6))
+	s74 = s58 + s67 + (((s59 << 63) | (s59 >> 1))^((s59 << 56) | (s59 >> 8))^(s59 >> 7)) + (((s72 << 45) | (s72 >> 19))^((s72 << 3) | (s72 >> 61))^(s72 >> 6))
+	s75 = s59 + s68 + (((s60 << 63) | (s60 >> 1))^((s60 << 56) | (s60 >> 8))^(s60 >> 7)) + (((s73 << 45) | (s73 >> 19))^((s73 << 3) | (s73 >> 61))^(s73 >> 6))
+	s76 = s60 + s69 + (((s61 << 63) | (s61 >> 1))^((s61 << 56) | (s61 >> 8))^(s61 >> 7)) + (((s74 << 45) | (s74 >> 19))^((s74 << 3) | (s74 >> 61))^(s74 >> 6))
+	s77 = s61 + s70 + (((s62 << 63) | (s62 >> 1))^((s62 << 56) | (s62 >> 8))^(s62 >> 7)) + (((s75 << 45) | (s75 >> 19))^((s75 << 3) | (s75 >> 61))^(s75 >> 6))
+	s78 = s62 + s71 + (((s63 << 63) | (s63 >> 1))^((s63 << 56) | (s63 >> 8))^(s63 >> 7)) + (((s76 << 45) | (s76 >> 19))^((s76 << 3) | (s76 >> 61))^(s76 >> 6))
+	s79 = s63 + s72 + (((s64 << 63) | (s64 >> 1))^((s64 << 56) | (s64 >> 8))^(s64 >> 7)) + (((s77 << 45) | (s77 >> 19))^((s77 << 3) | (s77 >> 61))^(s77 >> 6))
+
+
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x428a2f98d728ae22ul + s00
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x7137449123ef65cdul + s01
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb5c0fbcfec4d3b2ful + s02
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xe9b5dba58189dbbcul + s03
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x3956c25bf348b538ul + s04
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x59f111f1b605d019ul + s05
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x923f82a4af194f9bul + s06
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xab1c5ed5da6d8118ul + s07
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xd807aa98a3030242ul + s08
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x12835b0145706fbeul + s09
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x243185be4ee4b28cul + s10
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x550c7dc3d5ffb4e2ul + s11
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x72be5d74f27b896ful + s12
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x80deb1fe3b1696b1ul + s13
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x9bdc06a725c71235ul + s14
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc19bf174cf692694ul + s15
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xe49b69c19ef14ad2ul + s16
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xefbe4786384f25e3ul + s17
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x0fc19dc68b8cd5b5ul + s18
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x240ca1cc77ac9c65ul + s19
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x2de92c6f592b0275ul + s20
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4a7484aa6ea6e483ul + s21
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5cb0a9dcbd41fbd4ul + s22
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x76f988da831153b5ul + s23
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x983e5152ee66dfabul + s24
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa831c66d2db43210ul + s25
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb00327c898fb213ful + s26
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xbf597fc7beef0ee4ul + s27
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xc6e00bf33da88fc2ul + s28
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd5a79147930aa725ul + s29
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x06ca6351e003826ful + s30
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x142929670a0e6e70ul + s31
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x27b70a8546d22ffcul + s32
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x2e1b21385c26c926ul + s33
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x4d2c6dfc5ac42aedul + s34
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x53380d139d95b3dful + s35
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x650a73548baf63deul + s36
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x766a0abb3c77b2a8ul + s37
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x81c2c92e47edaee6ul + s38
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x92722c851482353bul + s39
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xa2bfe8a14cf10364ul + s40
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa81a664bbc423001ul + s41
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xc24b8b70d0f89791ul + s42
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xc76c51a30654be30ul + s43
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xd192e819d6ef5218ul + s44
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd69906245565a910ul + s45
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xf40e35855771202aul + s46
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x106aa07032bbd1b8ul + s47
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x19a4c116b8d2d0c8ul + s48
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x1e376c085141ab53ul + s49
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x2748774cdf8eeb99ul + s50
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x34b0bcb5e19b48a8ul + s51
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x391c0cb3c5c95a63ul + s52
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4ed8aa4ae3418acbul + s53
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5b9cca4f7763e373ul + s54
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x682e6ff3d6b2b8a3ul + s55
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x748f82ee5defb2fcul + s56
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x78a5636f43172f60ul + s57
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x84c87814a1f0ab72ul + s58
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x8cc702081a6439ecul + s59
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x90befffa23631e28ul + s60
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xa4506cebde82bde9ul + s61
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xbef9a3f7b2c67915ul + s62
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc67178f2e372532bul + s63
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xca273eceea26619cul + s64
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xd186b8c721c0c207ul + s65
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xeada7dd6cde0eb1eul + s66
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xf57d4f7fee6ed178ul + s67
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x06f067aa72176fbaul + s68
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x0a637dc5a2c898a6ul + s69
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x113f9804bef90daeul + s70
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x1b710b35131c471bul + s71
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x28db77f523047d84ul + s72
+	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x32caab7b40c72493ul + s73
+	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x3c9ebe0a15c9bebcul + s74
+	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x431d67c49c100d4cul + s75
+	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x4cc5d4becb3e42b6ul + s76
+	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x597f299cfc657e2aul + s77
+	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5fcb6fab3ad6faecul + s78
+	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x6c44198c4a475817ul + s79
+	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+
+	x[0] += a
+	x[1] += b
+	x[2] += c
+	x[3] += d
+	x[4] += e
+	x[5] += f
+	x[6] += g
+	x[7] += h
+}
+
+const unpack = {b
+	var v : uint64
+
+	v = ((b[0] castto(uint64)) << 56)
+	v |= ((b[1] castto(uint64)) << 48)
+	v |= ((b[2] castto(uint64)) << 40)
+	v |= ((b[3] castto(uint64)) << 32)
+	v |= ((b[4] castto(uint64)) << 24)
+	v |= ((b[5] castto(uint64)) << 16)
+	v |= ((b[6] castto(uint64)) << 8)
+	v |= ((b[7] castto(uint64)) << 0)
+	-> v
+}
+
+const pack = {out, v
+	out[0]  = (v >> 56)	castto(byte)
+	out[1]  = (v >> 48)	castto(byte)
+	out[2]  = (v >> 40)	castto(byte)
+	out[3]  = (v >> 32)	castto(byte)
+	out[4]  = (v >> 24)	castto(byte)
+	out[5]  = (v >> 16)	castto(byte)
+	out[6]  = (v >> 8)	castto(byte)
+	out[7]  = (v >> 0)	castto(byte)
+}
+
--- /dev/null
+++ b/lib/cryptohash/test/md5.myr
@@ -1,0 +1,18 @@
+use std
+use cryptohash
+
+use "test/util.use"
+
+const main = {
+	hasheq(cryptohash.md5("")[:], \
+		"d41d8cd98f00b204e9800998ecf8427e")
+	hasheq(cryptohash.md5("h")[:], \
+		"2510c39011c5be704182423e3a695e91")
+	/* 64 byte block */
+	hasheq(cryptohash.md5("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"014842d480b571495a4a0363793f7367")
+	/* tail spanning */
+	hasheq(cryptohash.md5("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"3b0bb4c5ece4a6568caa7266e740a140")
+}
+
--- /dev/null
+++ b/lib/cryptohash/test/sha1.myr
@@ -1,0 +1,18 @@
+use std
+use cryptohash
+
+use "test/util.use"
+
+const main = {
+	hasheq(cryptohash.sha1("")[:], \
+		"da39a3ee5e6b4b0d3255bfef60951890d8af0709")
+	hasheq(cryptohash.sha1("h")[:], \
+		"27d5482eebd075de44389774e2fc8c695cf48a75")
+	/* 64 byte block */
+	hasheq(cryptohash.sha1("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"0098ba824b5c16427bd7a1125a2a442aec25644d")
+	/* tail spanning */
+	hasheq(cryptohash.sha1("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"4eb17e52bb55910b037869438f69d9c87643d75a")
+}
+
--- /dev/null
+++ b/lib/cryptohash/test/sha256.myr
@@ -1,0 +1,29 @@
+use std
+use cryptohash
+
+use "test/util.use"
+
+const main = {
+	hasheq(cryptohash.sha224("")[:], \
+		"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+	hasheq(cryptohash.sha224("h")[:], \
+		"e0ccaeadfef916630c35576679e4cd4b438e7fc95a60b7361705f708")
+	/* 64 byte block */
+	hasheq(cryptohash.sha224("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"a88cd5cde6d6fe9136a4e58b49167461ea95d388ca2bdb7afdc3cbf4")
+	/* tail spanning */
+	hasheq(cryptohash.sha224("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"4a5859b7efa22c3b25710520fc97b0a901f5cdba3e4f0becfeea725e")
+
+	hasheq(cryptohash.sha256("")[:], \
+		"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+	hasheq(cryptohash.sha256("h")[:], \
+		"aaa9402664f1a41f40ebbc52c9993eb66aeb366602958fdfaa283b71e64db123")
+	/* 64 byte block */
+	hasheq(cryptohash.sha256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb")
+	/* tail spanning */
+	hasheq(cryptohash.sha256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"bac8bf0f9794a520a5bf0ec64d3206edd1b9f2ef5ea118c9cad5365d84578de4")
+}
+
--- /dev/null
+++ b/lib/cryptohash/test/sha512.myr
@@ -1,0 +1,29 @@
+use std
+use cryptohash
+
+use "test/util.use"
+
+const main = {
+	hasheq(cryptohash.sha384("")[:], \
+		"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+	hasheq(cryptohash.sha384("h")[:], \
+		"a4eb0778c79fce94c02126543cba398d645b2fd4c6ff6a02eecc026bbe0cc0dd666279722b7615bc15b4c9126b941c04")
+	/* 64 byte block */
+	hasheq(cryptohash.sha384("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"2e404b9339da795776e510d96930b3be2904c500395b8cb7413334b82d4dec413b4b8113045a05bbbcff846f027423f6")
+	/* tail spanning */
+	hasheq(cryptohash.sha384("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"f8f4b55a0fb1ac8506d2e5195c714a1ad16c3bf61ad8b2d544344b105a49a77ff3b8eb61e8f970a71864e9dad87042b1")
+
+	hasheq(cryptohash.sha512("")[:], \
+		"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+	hasheq(cryptohash.sha512("h")[:], \
+		"2241bc8fc70705b42efead371fd4982c5ba69917e5b4b895810002644f0386da9c3131793458c2bf47608480d64a07278133c99912e0ba2daf23098f3520eb97")
+	/* 64 byte block */
+	hasheq(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
+		"01d35c10c6c38c2dcf48f7eebb3235fb5ad74a65ec4cd016e2354c637a8fb49b695ef3c1d6f7ae4cd74d78cc9c9bcac9d4f23a73019998a7f73038a5c9b2dbde")
+	/* tail spanning */
+	hasheq(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
+		"d5c989d2e41299b6bfd57562b4b09cd2efa56f13c8fa109e0ce5ddbd6bfb5b34f8563608d6162104bef750023732581f22704d5df43feecbb05742be1d7c34fa")
+}
+
--- /dev/null
+++ b/lib/cryptohash/test/util.myr
@@ -1,0 +1,19 @@
+use std
+
+pkg =
+	const hasheq	: (got : byte[:], expected : byte[:] -> void)
+;;
+
+const hasheq = {got, expected
+	var sb, str
+
+	sb = std.mksb()
+	for x in got
+		std.sbfmt(sb, "{p=0,w=2,x}", x)
+	;;
+	str = std.sbfin(sb)
+	if (!std.sleq(str, expected))
+		std.fatal("mismatched hashes:\n\tgot:\t{}\n\texpected:\t{}\n", str, expected)
+	;;
+	std.slfree(str)
+}
--- /dev/null
+++ b/lib/regex/bld.sub
@@ -1,0 +1,21 @@
+lib regex =
+	compile.myr
+	interp.myr
+	ranges.myr
+	types.myr
+
+        lib ../std:std
+;;
+
+bin redump {noinst} =
+	redump.myr
+        lib ../std:std
+        lib ../bio:bio
+        lib regex
+;;
+
+gen ranges.myr {durable} =
+	mkchartab -a -p_ranges UnicodeData.txt -o ranges.myr
+;;
+
+sub = test ;;
--- /dev/null
+++ b/lib/regex/compile.myr
@@ -1,0 +1,848 @@
+use std
+
+use "types.use"
+use "ranges.use"
+
+pkg regex =
+	const parse	: (re : byte[:]	-> std.result(ast#, status))
+	const compile	: (re : byte[:] -> std.result(regex#, status))
+	const dbgcompile	: (re : byte[:] -> std.result(regex#, status))
+	const free	: (re : regex# -> void)
+	const failmsg	: (st : status -> byte[:])
+;;
+
+type parseresult = union
+	`Some ast#
+	`None
+	`Fail status
+;;
+
+/* Compiles a pattern into a regex */
+const compile = {pat
+	-> regexcompile(std.mk([.pat = pat, .nmatch = 1]), 0)
+}
+
+const parse = {pat
+	var re
+
+	re = std.mk([.pat = pat, .nmatch = 1])
+	match regexparse(re)
+	| `None:	-> `std.Fail `Incomplete
+	| `Fail f:	-> `std.Fail f
+	| `Some t:
+		if re.pat.len > 0
+			-> `std.Fail `Incomplete
+		else
+			-> `std.Ok t
+		;;
+	;;
+}
+
+/* Compiles a pattern into a debug regex. This can be verbose. */
+const dbgcompile = {pat
+	var re
+
+	re = std.mk([.pat = pat, .nmatch = 1, .debug = true])
+	-> regexcompile(re, 0)
+}
+
+/* compiles a pattern into an allocated regex */
+const regexcompile = {re, id
+	match regexparse(re)
+	| `None:	-> `std.Fail (`Incomplete)
+	| `Fail f:	-> `std.Fail f
+	| `Some t:
+		/*
+		we can stop early if we get 
+		an incorrectly encoded char
+		*/
+		if re.pat.len > 0
+			astfree(t)
+			-> `std.Fail (`Incomplete)
+		;;
+		dump(re, t, 0)
+		append(re, `Ilbra 0)
+		gen(re, t)
+		append(re, `Irbra 0)
+		append(re, `Imatch id)
+		idump(re)
+		astfree(t)
+		-> `std.Ok re
+	;;
+	-> `std.Fail (`Noimpl)
+}
+
+const free = {re
+	/* all the threads should be dead,
+	 so we shouldn't have to free any*/
+	std.slfree(re.prog)
+	std.free(re)
+}
+
+
+/* generates bytecode from an AST */
+const gen = {re, t
+	match t#
+	|`Alt	(a, b): genalt(re, a, b)
+	|`Cat	(a, b): gen(re, a); gen(re, b)
+	/* repetition */
+	|`Star	a:	genstar(re, a, false)
+	|`Rstar a:	genstar(re, a, true)
+	|`Plus	a:	gen(re, a); genstar(re, a, false)
+	|`Rplus	a:	gen(re, a); genstar(re, a, true)
+	|`Quest	a:	genquest(re, a)
+
+	/* end matches */
+	|`Chr	c:	genchar(re, c)
+	|`Ranges  sl:	genranges(re, sl)
+
+	/* meta */
+	|`Bol:	append(re, `Ibol)
+	|`Eol:	append(re, `Ibol)
+	|`Bow:	append(re, `Ibow)
+	|`Eow:	append(re, `Ieow)
+	|`Cap	(m, a):
+		append(re, `Ilbra m)
+		gen(re, a)
+		append(re, `Irbra m)
+	;;
+	-> re.proglen
+}
+
+const genranges = {re, sl
+	var lbuf : byte[4], hbuf : byte[4], boundbuf : byte[4]
+	var lsz, hsz, bsz, i
+	var rt : rangetrie#
+
+	/* generate a trie of ranges */
+	rt = std.zalloc()
+	for r in sl
+		/* 
+		encode:
+			lo => bounds[loidx] - 1
+			bounds[loidx] => bounds[loidx + 1] - 1
+			...
+			bounds[hiidx - 1] => hi
+		*/
+		lsz = std.encode(lbuf[:], r[0])
+		hsz = std.encode(hbuf[:], r[1])
+		for i = lsz; i < hsz; i++
+			bsz = bound(boundbuf[:], i, 0xff)
+			rtinsert(rt, lbuf[:lsz], boundbuf[:bsz])
+			lsz = bound(lbuf[:], i + 1, 0x00)
+		;;
+		rtinsert(rt, lbuf[:lsz], hbuf[:hsz])
+	;;
+	if re.debug
+		rtdump(rt, 0)
+	;;
+	rangegen(re, rt, rt.ranges, rt.link, rangeprogsize(rt) + re.proglen)
+	rtfree(rt)
+	-> re.proglen
+}
+
+const bound = {buf, len, fill
+	var i, s
+
+	if len == 1
+		buf[0] = 0x7f
+	else
+		s = len castto(byte)
+		buf[0] = (0xff << (8 - s)) | (fill >> (s + 1))
+		for i = 1; i < len; i++
+			buf[i] = 0x80 | (fill >> 2)
+		;;
+	;;
+	-> len
+}
+
+type rangetrie = struct
+	ranges	: (byte, byte)[:]
+	link	: rangetrie#[:]
+	end	: bool
+;;
+
+const rtdump = {rt, ind
+	var i
+	var l, h
+
+	indent(ind)
+	std.put("Range (end = {}) {{\n", rt.end)
+	for i = 0; i < rt.ranges.len; i++
+		indent(ind + 1)
+		(l, h) = rt.ranges[i]
+		std.put("0x{x}-0x{x}: \n", l, h)
+		rtdump(rt.link[i], ind + 1)
+	;;
+	indent(ind)
+	std.put("}\n")
+}
+
+const indent = {ind
+	var i
+	for i = 0; i < ind; i++
+		std.put("\t")
+	;;
+}
+
+const rtinsert = {rt, lo, hi
+	var a, b
+	var n
+
+	std.assert(lo.len == hi.len, "range sizes differ")
+	if lo.len == 0
+		rt.end = true
+		->
+	;;
+
+	n = rt.ranges.len
+	if n == 0
+		rt.ranges = std.slpush(rt.ranges, (lo[0], hi[0]))
+		rt.link = std.slpush(rt.link, std.zalloc())
+	else
+		/*
+		this is a safe way to compare because we know that ranges
+		should always be coming in ordered. This means that equal
+		values will be added one after the other.
+		*/
+		(a, b) = rt.ranges[n - 1]
+		if a != lo[0] || b != hi[0]
+			rt.ranges = std.slpush(rt.ranges, (lo[0], hi[0]))
+			rt.link = std.slpush(rt.link, std.zalloc())
+		;;
+	;;
+
+	rtinsert(rt.link[rt.link.len - 1], lo[1:], hi[1:])
+}
+
+const rtfree = {rt
+	for l in rt.link
+		rtfree(l)
+	;;
+	std.slfree(rt.link)
+	std.slfree(rt.ranges)
+	std.free(rt)
+}
+
+const rangegen = {re, rt, ranges, links, end
+	var alt, l0, l1, l2
+	var a, b
+	var n
+
+	n = ranges.len
+	if n == 0
+		-> re.proglen
+	elif n == 1
+		(a, b) = ranges[0]
+		append(re, `Irange (a, b))
+		if links[0].end
+			if links[0].ranges.len > 0
+				append(re, `Ifork (re.prog.len + 1, end))
+			else
+				append(re, `Ijmp end)
+			;;
+		;;
+		rangegen(re, links[0], links[0].ranges, links[0].link, end)
+	else
+		alt = re.proglen
+		l0 = append(re, `Ifork (-1, -1))
+		l1 = rangegen(re, rt, ranges[0:n/2], links[0:n/2], end)
+		l2 = rangegen(re, rt, ranges[n/2:n], links[n/2:n], end)
+		re.prog[alt] = `Ifork (l0, l1)
+	;;
+	-> re.proglen
+}
+
+const rangeprogsize = {rt
+	var sz
+
+	if rt.ranges.len == 0
+		sz = 0
+	else
+		sz = 2*rt.ranges.len - 1
+		for l in rt.link
+			sz += rangeprogsize(l)
+		;;
+	;;
+	if rt.end
+		sz += 1
+	;;
+	-> sz
+}
+
+/* calculates the forward jump distance for a utf8 character range */
+const jmpdist = {n
+	var d
+	var i
+
+	d = n - 1
+	for i = n - 1; i > 0; i--
+		d += i
+	;;
+	-> d
+}
+
+/* generates an alternation */
+const genalt = {re, l, r
+	var alt
+	var jmp
+	var l0
+	var l1
+	var l2
+
+	alt 	= re.proglen
+	l0	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
+		  gen(re, l)
+	jmp	= re.proglen
+	l1 	= append(re, `Ijmp -1) /* needs to be replaced */
+	l2	= gen(re, r)
+
+	re.prog[alt] = `Ifork(l0, l1)
+	re.prog[jmp] = `Ijmp l2
+	-> re.proglen
+}
+
+/* generates a repetition operator */
+const genstar = {re, rep, reluct
+	var alt
+	var jmp
+	var l0
+	var l1
+	var l2
+
+	l0 	= re.proglen
+	alt	= re.proglen
+	l1 	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
+	jmp	= gen(re, rep)
+	l2	= append(re, `Ijmp -1)
+
+
+	/* reluctant matches should prefer jumping to the end. */
+	if reluct
+		re.prog[alt] = `Ifork (l2, l1)
+	else
+		re.prog[alt] = `Ifork (l1, l2)
+	;;
+	re.prog[jmp] = `Ijmp l0
+	-> re.proglen
+}
+
+/* generates a question mark operator */
+const genquest = {re, q
+	var alt
+	var l0
+	var l1
+
+	alt	= re.proglen
+	l0	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
+	l1	= gen(re, q)
+	re.prog[alt] = `Ifork (l0, l1)
+	-> re.proglen
+}
+
+/* generates a single char match */
+const genchar = {re, c
+	var b : byte[4]
+	var n
+	var i
+
+	n = std.encode(b[:], c)
+	std.assert(n > 0 && n < 4, "non-utf character in regex\n")
+	for i = 0; i < n; i++
+		append(re, `Ibyte b[i])
+	;;
+	-> re.proglen
+}
+
+/* appends an instructon to an re program */
+const append = {re, insn
+	if re.proglen == re.prog.len
+		re.prog = std.slgrow(re.prog, std.max(1, 2*re.proglen))
+	;;
+	re.prog[re.proglen] = insn
+	re.proglen++
+	-> re.proglen
+}
+
+/* instruction dump */
+const idump = {re
+	var i
+
+	if !re.debug
+		->
+	;;
+	for i = 0; i < re.proglen; i++
+		std.put("{}:\t", i)
+		match re.prog[i]
+		/* Char matching. Consume exactly one byte from the string. */
+		| `Ibyte b:		std.put("`Ibyte {} ({})\n", b, b castto(char)) 
+		| `Irange (start, end):	
+			std.put("`Irange ({},{})", start, end) 
+			if std.isalnum(start castto(char)) && std.isalnum(end castto(char))
+				std.put("\t/* {}-{} */", start castto(char), end castto(char))
+			;;
+			std.put("\n")
+		/* capture groups */
+		| `Ilbra m:		std.put("`Ilbra {}\n", m) 
+		| `Irbra m:		std.put("`Irbra {}\n", m) 
+		/* anchors */
+		| `Ibol:			std.put("`Ibol\n")
+		| `Ieol:			std.put("`Ieol\n")
+		| `Ibow:			std.put("`Ibow\n")
+		| `Ieow:			std.put("`Ieow\n")
+		/* control flow */
+		| `Ifork	(lip, rip):	std.put("`Ifork ({},{})\n", lip, rip) 
+		| `Ijmp ip:		std.put("`Ijmp {}\n", ip) 
+		| `Imatch id:		std.put("`Imatch {}\n", id) 
+		;;
+	;;
+}
+
+/* AST dump */
+const dump = {re, t, indent
+	var i
+
+	if !re.debug
+		->
+	;;
+	for i = 0; i < indent; i++
+		std.put("  ")
+	;;
+	match t#
+	| `Alt	(a, b):
+		std.put("Alt\n")
+		dump(re, a, indent + 1)
+		dump(re, b, indent + 1)
+	| `Cat	(a, b):
+		std.put("Cat\n")
+		dump(re, a, indent + 1)
+		dump(re, b, indent + 1)
+	/* repetition */
+	| `Star	a:
+		std.put("Star\n")
+		dump(re, a, indent + 1)
+	| `Rstar a:
+		std.put("Rstar\n")
+		dump(re, a, indent + 1)
+	| `Plus	a:
+		std.put("Plus\n")
+		dump(re, a, indent + 1)
+	| `Rplus a:
+		std.put("Rplus\n")
+		dump(re, a, indent + 1)
+	| `Quest	a:
+		std.put("Quest\n")
+		dump(re, a, indent + 1)
+	| `Bol:
+		std.put("Bol\n")
+	| `Eol:
+		std.put("Eol\n")
+	| `Bow:
+		std.put("Bow\n")
+	| `Eow:
+		std.put("Eow\n")
+	/* end matches */
+	| `Chr	c:
+		std.put("Char {}\n", c)
+	| `Ranges rl:
+                std.put("Ranges")
+		for r in rl
+			for i = 0; i < indent + 1; i++
+				std.put("  ")
+			;;
+			std.put("\t({}-{})\n", r[0], r[1])
+		;;
+
+	/* meta */
+	| `Cap	(m, a):
+		std.put("Cap {}\n", m)
+		dump(re, a, indent + 1)
+	;;
+}
+
+/* parses an expression */
+const regexparse = {re
+	match altexpr(re)
+	| `Some t:
+		if re.pat.len == 0
+			-> `Some t
+		else
+			astfree(t)
+			-> `Fail `Incomplete
+		;;
+	| `None:
+		-> `None
+	| `Fail st:
+		-> `Fail st
+	;;
+}
+
+const altexpr = {re
+	var ret
+
+	match catexpr(re)
+	| `Some t:
+		ret = t
+		if matchc(re, '|')
+			match altexpr(re)
+			| `Some rhs:
+				ret = mk(`Alt (ret, rhs))
+			| `None:
+				astfree(ret)
+				-> `Fail (`Incomplete)
+			| `Fail f:
+				-> `Fail f
+			;;
+		;;
+	| other:
+		-> other
+	;;
+	-> `Some ret
+}
+
+const catexpr = {re
+	var ret
+
+	match repexpr(re)
+	| `Some t: 
+		ret = t
+		match catexpr(re)
+		| `Some rhs:
+			ret = mk(`Cat (t, rhs))
+		| `Fail f:	-> `Fail f
+		| `None:	/* nothing */
+		;;
+	| other:
+		-> other
+	;;
+	-> `Some ret
+}
+
+const repexpr = {re
+	var ret
+
+	match baseexpr(re)
+	| `Some t:
+		if matchc(re, '*')
+                        if matchc(re, '?')
+                                ret = mk(`Rstar t)
+                        else
+				ret = mk(`Star t)
+			;;
+		elif matchc(re, '+')
+                        if matchc(re, '?')
+				ret = mk(`Rplus t)
+			else
+				ret = mk(`Plus t)
+			;;
+		elif matchc(re, '?')
+			ret = mk(`Quest t)
+		else
+			ret = t
+		;;
+	| other:
+		-> other
+	;;
+	-> `Some ret
+}
+
+const baseexpr = {re
+	var ret, m
+
+	if re.pat.len == 0
+		-> `None
+	;;
+	match peekc(re)
+	/* lower prec operators */
+	| '|':	-> `None
+	| ')':	-> `None
+	| '*':	-> `Fail `Badrep
+	| '+':	-> `Fail `Badrep
+	| '?':	-> `Fail `Badrep
+	| '[':	-> chrclass(re)
+	| '.':	getc(re); ret = mk(`Ranges std.slpush([][:], [0, std.Maxcharval]))
+	| '^':	getc(re); ret = mk(`Bol)
+	| '$':	getc(re); ret = mk(`Eol)
+	| '(':	
+		m = re.nmatch++
+		getc(re)
+		match altexpr(re)
+		| `Some s:
+			if matchc(re, ')')
+				-> `Some mk(`Cap (m, s))
+			else
+				-> `Fail `Unbalanced
+			;;
+		| `None:	-> `Fail `Emptyparen
+		| `Fail st:	-> `Fail st
+		;;
+	| '\\':
+		getc(re) /* consume the slash */
+		if re.pat.len == 0
+			-> `Fail `Incomplete
+		;;
+		-> escaped(re)
+	| c:
+		getc(re)
+		ret = mk(`Chr c)
+	;;
+	-> `Some ret
+}
+
+const escaped = {re
+	var ret
+
+	match getc(re)
+	/* character classes */
+	| 'd': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciidigit[:]))
+	| 'x': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciixdigit[:]))
+	| 's': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciispace[:]))
+	| 'w': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciiword[:]))
+	| 'h': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciiblank[:]))
+
+	/* negated character classes */
+	| 'W': ret = `Some mk(`Ranges negate(_ranges.tabasciiword[:]))
+	| 'S': ret = `Some mk(`Ranges negate(_ranges.tabasciispace[:]))
+	| 'D': ret = `Some mk(`Ranges negate(_ranges.tabasciidigit[:]))
+	| 'X': ret = `Some mk(`Ranges negate(_ranges.tabasciixdigit[:]))
+	| 'H': ret = `Some mk(`Ranges negate(_ranges.tabasciiblank[:]))
+
+	/* unicode character classes */
+	| 'p':	ret = unicodeclass(re, false)
+	| 'P':  ret = unicodeclass(re, true)
+
+	/* operators that need an escape */
+	| '<': ret = `Some mk(`Bow)
+	| '>': ret = `Some mk(`Eow)
+
+	/* escaped metachars */
+	| '^': ret = `Some mk(`Chr '^')
+	| '$': ret = `Some mk(`Chr '$')
+	| '.': ret = `Some mk(`Chr '.')
+	| '+': ret = `Some mk(`Chr '+')
+	| '?': ret = `Some mk(`Chr '?')
+	| chr: ret = `Fail `Badescape
+	;;
+	-> ret
+}
+
+const unicodeclass = {re, neg
+	var c, s
+	var tab
+	var t
+	var n
+
+	if re.pat.len == 0
+		-> `Fail (`Incomplete)
+	;;
+	n = 0
+	s = re.pat
+	/* either a single char pattern, or {pat} */
+	match getc(re)
+	| '{':
+		s = s[1:]
+		while re.pat.len > 0
+			c = getc(re)
+			if c == '}'
+				break
+			;;
+			n += std.charlen(c)
+		;;
+	| r:
+		n += std.charlen(r)
+	;;
+	s = s[:n]
+	/* letters */
+	if std.sleq(s, "L") || std.sleq(s, "Letter")
+		tab = _ranges.tabalpha[:]
+	elif std.sleq(s, "Lu") || std.sleq(s, "Uppercase_Letter")
+		tab = _ranges.tabupper[:]
+	elif std.sleq(s, "Ll") || std.sleq(s, "Lowercase_Letter")
+		tab = _ranges.tablower[:]
+	elif std.sleq(s, "Lt") || std.sleq(s, "Titlecase_Letter")
+		tab = _ranges.tablower[:]
+	/* numbers (incomplete) */
+	elif std.sleq(s, "N") || std.sleq(s, "Number")
+		tab = _ranges.tabdigit[:]
+	elif std.sleq(s, "Z") || std.sleq(s, "Separator")
+		tab = _ranges.tabspace[:]
+	elif std.sleq(s, "Zs") || std.sleq(s, "Space_Separator")
+		tab = _ranges.tabblank[:]
+	else
+		-> `Fail (`Badrange)
+	;;
+	if !neg
+		t = mk(`Ranges std.sldup(tab))
+	else
+		t = mk(`Ranges negate(tab))
+	;;
+	-> `Some t
+}
+
+const chrclass = {re
+	var rl, m, n
+	var neg
+	var t
+
+	/* we know we saw '[' on entry */
+	matchc(re, '[')
+	neg = false
+	if matchc(re, '^')
+		neg = true
+	;;
+	rl = rangematch(re, [][:])
+	while peekc(re) != ']' && re.pat.len > 0
+		rl = rangematch(re, rl)
+	;;
+	if !matchc(re, ']')
+		std.slfree(rl)
+		-> `Fail `Unbalanced
+	;;
+
+	std.sort(rl, {a, b;
+		if a[0] < b[0]
+			-> `std.Before
+		elif a[0] == b[0]
+			-> `std.Equal
+		else
+			-> `std.After
+		;;})
+	m = merge(rl)
+	std.slfree(rl)
+	if neg
+		n = negate(m)
+		std.slfree(m)
+		t = mk(`Ranges n)
+	else
+		t = mk(`Ranges m)
+	;;
+	-> `Some t
+}
+
+const rangematch = {re, sl
+	var lo
+	var hi
+
+	lo = getc(re)
+	if matchc(re, '-')
+		hi = getc(re)
+		if lo <= hi
+			-> std.slpush(sl, [lo, hi])
+		else
+			-> std.slpush(sl, [hi, lo])
+		;;
+	else
+		-> std.slpush(sl, [lo, lo])
+	;;
+}
+
+const negate = {rng
+	var start, end, next
+	var neg
+
+	neg = [][:]
+	start = 0
+	next = 0 /* if we have no ranges */
+	for r in rng
+		(end, next) = (r[0], r[1])
+		neg = std.slpush(neg, [start, end - 1])
+		start = next + 1
+	;;
+	neg = std.slpush(neg, [next + 1, std.Maxcharval])
+	-> neg
+}
+
+/* rl is a sorted list of ranges */
+const merge = {rl
+	var lo, hi
+	var ret
+
+	if rl.len == 0
+		-> [][:]
+	;;
+	ret = [][:]
+	lo = rl[0][0]
+	hi = rl[0][1]
+	for r in rl[1:]
+		/* if it overlaps or abuts, merge */
+		if r[0] <= hi + 1
+			hi = r[1]
+		else
+			ret = std.slpush(ret, [lo, hi])
+			lo = r[0]
+			hi = r[1]
+		;;
+	;;
+	-> std.slpush(ret, [lo, hi])
+}
+
+
+const matchc = {re, c
+	var str
+	var chr
+
+	(chr, str) = std.striter(re.pat)
+	if chr != c
+		-> false
+	;;
+	re.pat = str
+	-> true
+}
+
+const getc = {re
+	var c
+
+	(c, re.pat) = std.striter(re.pat)
+	-> c
+}
+
+const peekc = {re
+	var c
+
+	(c, _) = std.striter(re.pat)
+	-> c
+}
+
+const mk = {v
+	var t
+
+	t = std.alloc()
+	t# = v
+	-> t
+}
+
+const astfree = {t
+	match t#
+	| `Alt	(a, b): astfree(a); astfree(b)
+	| `Cat	(a, b): astfree(a); astfree(b)
+	/* repetition */
+	| `Star	a:	astfree(a)
+	| `Rstar a:	astfree(a)
+	| `Plus	a:	astfree(a)
+	| `Rplus a:	astfree(a)
+	| `Quest a:	astfree(a)
+
+	/* end matches */
+	| `Chr c:	
+	| `Ranges rl:	std.slfree(rl)
+
+	/* meta */
+	| `Cap	(m, a):	astfree(a)
+	| _:	/* other types have no suballocations */
+	;;
+	std.free(t)
+}
+
+const failmsg = {st
+	match st
+	| `Noimpl:	-> "no implementation"
+	| `Incomplete:	-> "regex ended before input fully parsed"
+	| `Unbalanced:	-> "unbalanced bracket"
+	| `Emptyparen:	-> "empty parentheses"
+	| `Badrep:	-> "invalid repetition"
+	| `Badrange:	-> "invalid range"
+	| `Badescape:	-> "invalid escape code"
+
+	;;
+}
+
--- /dev/null
+++ b/lib/regex/configure
@@ -1,0 +1,52 @@
+#!/bin/sh
+
+prefix="/usr/local"
+
+for i in `seq 300`; do
+    echo "Lots of output to emulate automake... ok"
+    echo "Testing for things you'll never use... fail"
+    echo "Satisfying the fortran77 lobby... ok"
+    echo "Burning CPU time checking for the bloody obvious... ok"
+done
+echo "Automake emulated successfully"
+
+INST_ROOT='/usr/local'
+
+for arg in $*; do
+    shift 1
+    case $arg in
+        "--prefix" | "-p")
+            prefix=shift $*
+            ;;
+        --prefix=*)
+            prefix=`echo $arg | sed 's/^--prefix=//g'`
+            ;;
+        "--help" | "-h")
+            echo "Usage:"
+            echo "      --prefix | -p: The prefix to install to"
+            break;
+            ;;
+        *) echo "Unrecognized argument $arg";;
+    esac
+done
+
+OS=`uname`
+
+echo export INST_ROOT=$prefix > config.mk
+case $OS in
+    *Linux*)
+        echo 'export SYS=linux' >> config.mk
+        ;;
+    *Darwin*)
+        echo 'export SYS=osx' >> config.mk
+        ;;
+    *)
+        echo 'Unknown architecture.'
+        ;;
+esac
+
+cat << EOF
+    Building with:
+        prefix=$prefix
+EOF
+
--- /dev/null
+++ b/lib/regex/doc/Makefile
@@ -1,0 +1,5 @@
+MAN=myr-regex.3 \
+
+include ../config.mk
+include ../mk/myr.mk
+
--- /dev/null
+++ b/lib/regex/doc/myr-regex.3
@@ -1,0 +1,198 @@
+.TH MYR REGEX 1
+.SH NAME
+regex myr-regex
+.SH LIBRARY
+regex
+.SH SYNOPSIS
+.B use regex
+.I const compile	: (re : byte[:] -> std.error(regex#, status))
+.I const dbgcompile	: (re : byte[:] -> std.error(regex#, status))
+.I const free           : (re : regex# -> void)
+.br
+.I const exec	: (re : regex#, str : byte[:] -> bool)
+.I const search	: (re : regex#, str : byte[:] -> bool)
+.SH DESCRIPTION
+.PP
+The regex library provides functions for compiling and evaluating regular
+expressions, as described later in this document, or in myr-regex(7).
+.PP
+.I regex.compile will take a string describing a regex, and will attempt
+to compile it, returing 
+.I `std.Success regex#
+if the regex is valid, and there were no error conditions encountered during
+compilation. If the compilation failed,
+.I `std.Failure regex.status
+will be returned, where regex.status is a failure code.
+
+.PP 
+.I regex.dbgcompile
+is identical to 
+.I regex.compile,
+however, it will print debugging information as it compiles, and each
+time the regex is evaluated.
+
+.PP
+.I regex.exec
+will take the regex passed to it, and evaluate it over the text provided,
+returning the 
+.I `std.Some matches,
+or 
+.I `std.None
+if there were no matches found. The matches must span the whole string.
+
+.PP
+.I regex.search
+is similar to regex.exec, but it will attempt to find a match somewhere
+within the string, instead of attempting to find a match spanning the whole
+string.
+
+.SH REGEX SYNTAX
+.PP
+The grammar used by libregex is below:
+
+.EX
+    regex       : altexpr
+    altexpr     : catexpr ('|' altexpr)+
+    catexpr     : repexpr (catexpr)+
+    repexpr     : baseexpr[*+?]
+    baseexpr    : literal
+                | charclass
+                | charrange
+                | escaped
+                | '.'
+                | '^'
+                | '$'
+                | '(' regex ')'
+    charclass   : see below
+    charrange   : '[' (literal('-' literal)?)+']'
+.EE
+
+The following metacharacters have the meanings listed below:
+.TP
+.
+Matches a single unicode character
+.TP
+^
+Matches the beginning of a line. Does not consume any characters.
+.TP
+$
+Matches the end of a line. Does not consume any characters.
+.TP
+*
+Matches any number of repetitions of the preceding regex fragment.
+.TP
+*?
+Reluctantly matches any number of repetitions of the preceding regex fragment.
+.TP
++
+Matches one or more repetitions of the preceding regex fragment.
+.TP
++?
+Reluctantly matches one or more repetitions of the preceding regex fragment.
+.TP
+?
+Matches zero or one of the preceding regex fragment.
+
+.PP
+In order to match a literal metacharacter, it needs to be preceded by
+a '\\' character.
+
+The following character classes are supported:
+.TP
+\\d
+ASCII digits
+.TP
+\\D
+Negation of ASCII digits
+.TP
+\\x
+ASCII Hex digits
+.TP
+\\X
+Negation of ASCII Hex digits
+.TP
+\\s
+ASCII spaces
+.TP
+\\S
+Negation of ASCII spaces
+.TP
+\\w
+ASCII word characters
+.TP
+\\W
+Negation of ASCII word characters
+.TP
+\\h
+ASCII whitespace characters
+.TP
+\\H
+Negation of ASCII whitespace characters
+.TP
+\\pX, \\p{X}
+Characters with unicode property 'X'
+.TP
+\\PX, \\P{X}
+Negation of characters with unicode property 'X'
+
+.PP
+Unicode properties that are supported are listed below:
+
+.TP
+L, Letter
+Unicode letter property
+.TP
+Lu, Uppercase_Letter
+Uppercase letter unicode property
+.TP
+Ll, Lowercase_Letter
+Lowercase letter unicode property
+.TP
+Lt, Titlecase_Letter
+Titlecase letter unicode property
+.TP
+N, Number
+Number unicode property
+.TP
+Z, Separator
+Any separator character unicode property
+.TP
+Zs, Space_Separator
+Space separator unicode property
+
+
+.SH EXAMPLE
+.EX
+        use std
+        use regex
+
+        const main = {
+            match regex.compile(pat)
+            var i
+            | `std.Success re:
+                    match regex.exec(re, text)
+                    | `std.Some matches:
+                            for i = 0; i < matches.len; i++
+                                std.put("Match %i: %s\n", i, match[i])
+                            ;;
+                    | `std.None: std.put("Text did not match\n")
+                    ;;
+            | `std.Failure err:
+                    std.put("failed to compile regex")
+            ;;
+        }
+.EE
+
+.SH FILES
+The source code for this compiler is available from
+.B git://git.eigenstate.org/git/ori/libregex.git
+
+.SH SEE ALSO
+.IR mc(1)
+
+.SH BUGS
+.PP
+This code is insufficiently tested.
+
+.PP
+This code does not support all of the regex features that one would expect.
--- /dev/null
+++ b/lib/regex/interp.myr
@@ -1,0 +1,311 @@
+use std
+
+use "types.use"
+
+pkg regex =
+	const exec	: (re : regex#, str : byte[:] -> std.option(byte[:][:]))
+	/*
+	FIXME: implement. This should scan for a possible start char in the
+		regex and use that to optimize.
+	const search	: (re : regex#, str : byte[:] -> std.option(byte[:][:]))
+	*/
+;;
+
+/* Ugly: for performance. std.option() should be used instead when unions get faster. */
+const Zthr = 0 castto(rethread#)
+
+const exec = {re, str
+	var thr
+	var m
+
+	re.str = str
+	re.strp = 0
+	thr = run(re)
+	if thr != Zthr
+		m = getmatches(re, thr)
+		cleanup(re)
+		-> `std.Some m
+	else
+		cleanup(re)
+		->  `std.None
+	;;
+}
+
+const cleanup = {re
+	var thr, next
+
+	for thr = re.runq; thr != Zthr; thr = next
+		next = thr.next
+		thrfree(re, thr)
+	;;
+	for thr = re.expired; thr != Zthr; thr = next
+		next = thr.next
+		thrfree(re, thr)
+	;;
+}
+
+const getmatches = {re, thr
+	var ret
+	var i
+
+	ret = std.slalloc(re.nmatch)
+	for i = 0; i < re.nmatch; i++
+		if thr.mstart[i] != -1 && thr.mend[i] != -1
+			ret[i] = re.str[thr.mstart[i]:thr.mend[i]]
+		else
+			ret[i] = [][:]
+		;;
+	;;
+	-> ret
+}
+
+
+/* returns a matching thread, or Zthr if no threads matched */
+const run = {re
+	var i, ip
+	var consumed
+	var thr
+	var states
+
+	states = std.mkbs()
+	re.runq = mkthread(re, 0)
+	re.runq.mstart = std.slalloc(re.nmatch)
+	re.runq.mend = std.slalloc(re.nmatch)
+	for i = 0; i < re.nmatch; i++
+		re.runq.mstart[i] = -1
+		re.runq.mend[i] = -1
+	;;
+	while re.nthr > 0
+		while re.runq != Zthr
+			/* set up the next thread */
+			thr = re.runq
+			re.runq = thr.next
+
+			trace(re, thr, "\nrunning tid={}, ip={}, s[{}]={}\n", thr.tid, thr.ip, re.strp, std.decode(re.str[re.strp:]))
+			ip = thr.ip
+			consumed = step(re, thr, -1)
+			while !consumed
+				consumed = step(re, thr, ip)
+			;;
+
+			if std.bshas(states, thr.ip)
+				die(re, thr, "there can be only one")
+			;;
+
+			if thr.dead
+				thrfree(re, thr)
+			elif thr.matched && re.strp == re.str.len
+				-> thr
+			elif !thr.matched
+				std.bsput(states, thr.ip)
+				if re.expired == Zthr
+					re.expired = thr
+				;;
+				if re.expiredtail != Zthr
+					re.expiredtail.next = thr
+				;;
+				re.expiredtail = thr
+				thr.next = Zthr
+
+			;;
+		;;
+		std.bsclear(states)
+		trace(re, thr, "switch\n")
+		re.runq = re.expired
+		re.expired = Zthr
+		re.expiredtail = Zthr
+		re.strp++
+	;;
+	-> Zthr
+}
+
+/* 
+ Steps forward one instruction. Returns true if a byte of input was
+ consumed, false otherwise.
+*/
+const step = {re, thr, curip
+	var str
+	var mstart
+	var mend
+
+	str = re.str
+	match re.prog[thr.ip]
+	/* Char matching. Consume exactly one byte from the string. */
+	| `Ibyte b:
+		trace(re, thr, "\t{}:\tByte {} ({})\n", thr.ip, b, b castto(char))
+		if !within(re, str)
+			die(re, thr, "end of string")
+		elif b != str[re.strp]
+			die(re, thr, "not right char")
+		else
+			thr.ip++
+			trace(re, thr, "\t\tmatched {} with {}\n", b, str[re.strp])
+		;;
+	| `Irange (start, end):
+		trace(re, thr, "\t{}:\tRange ({}, {}) /* {} - {} */\n", thr.ip, start, end, start castto(char), end castto(char))
+		if !within(re, str) || start > str[re.strp] || end < str[re.strp]
+			die(re, thr, "bad range")
+		else
+			thr.ip++
+		;;
+	/*
+	  Non-consuming. All of these return false, and expect step to be
+	  called again until exactly one byte is consumed from the string.
+	 */
+	| `Ibol:
+		trace(re, thr, "\t{}:\tBol\n", thr.ip)
+		if re.strp == 0 || str[re.strp - 1] == '\n' castto(byte)
+			thr.ip++
+			-> false
+		else
+			die(re, thr, "not beginning of line")
+		;;
+	| `Ieol:
+		trace(re, thr, "\t{}:\tEol\n", thr.ip)
+		if re.strp == str.len || str[re.strp] == '\n' castto(byte)
+			thr.ip++
+			-> false
+		else
+			die(re, thr, "not end of line")
+		;;
+	/* check for word characters */
+	| `Ibow:
+		trace(re, thr, "\t{}:\tBow\n", thr.ip)
+		if iswordchar(str[re.strp:]) && (re.strp == 0 || !iswordchar(prevchar(str, re.strp)))
+			thr.ip++
+			-> false
+		else
+			die(re, thr, "not beginning of word")
+		;;
+	| `Ieow:
+		trace(re, thr, "\t{}:\tEow\n", thr.ip)
+		if re.strp == str.len && iswordchar(prevchar(str, re.strp))
+			thr.ip++
+			-> false
+		elif re.strp > 0 && !iswordchar(str[re.strp:]) && iswordchar(prevchar(str, re.strp))
+			thr.ip++
+			-> false
+		else
+			die(re, thr, "not end of word")
+		;;
+	| `Ilbra m:
+		trace(re, thr, "\t{}:\tLbra {}\n", thr.ip, m)
+		trace(re, thr, "\t\tmatch start = {}\n", re.strp)
+		thr.mstart[m] = re.strp
+		thr.ip++
+		-> false
+	| `Irbra m:
+		trace(re, thr, "\t{}:\tRbra {}\n", thr.ip, m)
+		thr.mend[m] = re.strp
+		thr.ip++
+		-> false
+	| `Ifork (lip, rip):
+		trace(re, thr, "\t{}:\tFork ({}, {})\n", thr.ip, lip, rip)
+		mstart = std.sldup(thr.mstart)
+		mend = std.sldup(thr.mend)
+		fork(re, thr, rip, curip, mstart, mend)
+		thr.ip = lip
+		-> false
+	| `Ijmp ip:
+		trace(re, thr, "\t{}:\tJmp {}\n", thr.ip, ip)
+		thr.ip = ip
+		-> false
+	| `Imatch id:
+		trace(re, thr, "\t{}:\tMatch\n", thr.ip)
+		finish(re, thr)
+		-> true
+	;;
+	-> true
+}
+
+const fork = {re, thr, ip, curip, mstart, mend
+	var thr
+
+	if ip == curip /* loop detection */
+		->
+	;;
+	thr = mkthread(re, ip)
+	thr.next = re.runq
+	thr.mstart = mstart
+	thr.mend = mend
+	re.runq = thr
+}
+
+const die = {re, thr, msg
+        /*
+ 	  we can have die called on a thread
+	  multiple times, eg, if it has a bad
+	  range *and* end in a state that another
+	  thread is in. We should only decrement
+	  the number of threads for that once.
+	 */
+	trace(re, thr, "\t\tdie {}: {}\n", thr.tid, msg)
+        if !thr.dead
+		re.nthr--
+        ;;
+	thr.dead = true
+}
+
+const finish = {re, thr
+	trace(re, thr, "finish {}\n", thr.tid)
+	thr.matched = true
+	re.nthr--
+}
+
+var nexttid = 0
+const mkthread = {re, ip
+	var thr : rethread#
+
+	thr = std.alloc()
+
+	thr.next = Zthr
+
+	thr.ip = ip
+	thr.tid = nexttid++
+	thr.dead = false
+	thr.matched = false
+
+	thr.mstart = [][:]
+	thr.mend = [][:]
+
+	re.nthr++
+
+	-> thr
+}
+
+const thrfree = {re, thr
+	trace(re, thr, "\t\tcleanup {}\n", thr.tid)
+	std.slfree(thr.mstart)
+	std.slfree(thr.mend)
+	std.free(thr)
+}
+
+const within = {re, str 
+	-> re.strp < str.len
+}
+
+const trace : (re : regex#, thr : rethread#, msg : byte[:], args : ... -> void) = {re, thr, msg, args
+	var ap
+
+	if re.debug
+		ap = std.vastart(&args)
+		std.putv(msg, &ap)
+	;;
+}
+
+/* must be called with i >= 1 */
+const prevchar = {s, i
+	std.assert(i != 0, "prevchar must be called with i >= 1\n")
+	i--
+	while i != 0 && s[i] >= 0x80
+		i--
+	;;
+	-> s[i:]
+}
+
+const iswordchar = {s
+	var c
+
+	c = std.decode(s)
+	-> std.isalpha(c) || std.isdigit(c) || c == '_'
+}
--- /dev/null
+++ b/lib/regex/ranges.myr
@@ -1,0 +1,2386 @@
+/*
+ This set of unicode tables was automatically generated
+ by the following command:
+ mkchartab -a -p_ranges UnicodeData.txt -o ranges.myr
+ editing it manually is probably a waste of time.
+*/
+
+pkg _ranges =
+	const tabasciialpha
+	const tabasciiupper
+	const tabasciilower
+	const tabasciiword
+	const tabasciidigit
+	const tabasciixdigit
+	const tabasciispace
+	const tabasciiblank
+	const tabalpha
+	const tabupper
+	const tablower
+	const tabtitle
+	const tabword
+	const tabdigit
+	const tabxdigit
+	const tabspace
+	const tabblank
+;;
+const tabasciialpha = [
+	['\u{41}','\u{5a}'],
+	['\u{61}','\u{7a}'],
+]
+
+const tabasciiupper = [
+	['\u{41}','\u{5a}'],
+]
+
+const tabasciilower = [
+	['\u{61}','\u{7a}'],
+]
+
+const tabasciiword = [
+	['\u{30}','\u{39}'],
+	['\u{41}','\u{5a}'],
+	['\u{5f}','\u{5f}'],
+	['\u{61}','\u{7a}'],
+]
+
+const tabasciidigit = [
+	['\u{30}','\u{39}'],
+]
+
+const tabasciixdigit = [
+	['\u{30}','\u{39}'],
+	['\u{41}','\u{46}'],
+	['\u{61}','\u{66}'],
+]
+
+const tabasciispace = [
+	['\u{9}','\u{d}'],
+	['\u{20}','\u{20}'],
+]
+
+const tabasciiblank = [
+	['\u{9}','\u{9}'],
+	['\u{20}','\u{20}'],
+]
+
+const tabalpha = [
+	['\u{41}','\u{5a}'],
+	['\u{61}','\u{7a}'],
+	['\u{aa}','\u{aa}'],
+	['\u{b5}','\u{b5}'],
+	['\u{ba}','\u{ba}'],
+	['\u{c0}','\u{d6}'],
+	['\u{d8}','\u{f6}'],
+	['\u{f8}','\u{2c1}'],
+	['\u{2c6}','\u{2d1}'],
+	['\u{2e0}','\u{2e4}'],
+	['\u{2ec}','\u{2ec}'],
+	['\u{2ee}','\u{2ee}'],
+	['\u{370}','\u{374}'],
+	['\u{376}','\u{377}'],
+	['\u{37a}','\u{37d}'],
+	['\u{386}','\u{386}'],
+	['\u{388}','\u{38a}'],
+	['\u{38c}','\u{38c}'],
+	['\u{38e}','\u{3a1}'],
+	['\u{3a3}','\u{3f5}'],
+	['\u{3f7}','\u{481}'],
+	['\u{48a}','\u{527}'],
+	['\u{531}','\u{556}'],
+	['\u{559}','\u{559}'],
+	['\u{561}','\u{587}'],
+	['\u{5d0}','\u{5ea}'],
+	['\u{5f0}','\u{5f2}'],
+	['\u{620}','\u{64a}'],
+	['\u{66e}','\u{66f}'],
+	['\u{671}','\u{6d3}'],
+	['\u{6d5}','\u{6d5}'],
+	['\u{6e5}','\u{6e6}'],
+	['\u{6ee}','\u{6ef}'],
+	['\u{6fa}','\u{6fc}'],
+	['\u{6ff}','\u{6ff}'],
+	['\u{710}','\u{710}'],
+	['\u{712}','\u{72f}'],
+	['\u{74d}','\u{7a5}'],
+	['\u{7b1}','\u{7b1}'],
+	['\u{7ca}','\u{7ea}'],
+	['\u{7f4}','\u{7f5}'],
+	['\u{7fa}','\u{7fa}'],
+	['\u{800}','\u{815}'],
+	['\u{81a}','\u{81a}'],
+	['\u{824}','\u{824}'],
+	['\u{828}','\u{828}'],
+	['\u{840}','\u{858}'],
+	['\u{8a0}','\u{8a0}'],
+	['\u{8a2}','\u{8ac}'],
+	['\u{904}','\u{939}'],
+	['\u{93d}','\u{93d}'],
+	['\u{950}','\u{950}'],
+	['\u{958}','\u{961}'],
+	['\u{971}','\u{977}'],
+	['\u{979}','\u{97f}'],
+	['\u{985}','\u{98c}'],
+	['\u{98f}','\u{990}'],
+	['\u{993}','\u{9a8}'],
+	['\u{9aa}','\u{9b0}'],
+	['\u{9b2}','\u{9b2}'],
+	['\u{9b6}','\u{9b9}'],
+	['\u{9bd}','\u{9bd}'],
+	['\u{9ce}','\u{9ce}'],
+	['\u{9dc}','\u{9dd}'],
+	['\u{9df}','\u{9e1}'],
+	['\u{9f0}','\u{9f1}'],
+	['\u{a05}','\u{a0a}'],
+	['\u{a0f}','\u{a10}'],
+	['\u{a13}','\u{a28}'],
+	['\u{a2a}','\u{a30}'],
+	['\u{a32}','\u{a33}'],
+	['\u{a35}','\u{a36}'],
+	['\u{a38}','\u{a39}'],
+	['\u{a59}','\u{a5c}'],
+	['\u{a5e}','\u{a5e}'],
+	['\u{a72}','\u{a74}'],
+	['\u{a85}','\u{a8d}'],
+	['\u{a8f}','\u{a91}'],
+	['\u{a93}','\u{aa8}'],
+	['\u{aaa}','\u{ab0}'],
+	['\u{ab2}','\u{ab3}'],
+	['\u{ab5}','\u{ab9}'],
+	['\u{abd}','\u{abd}'],
+	['\u{ad0}','\u{ad0}'],
+	['\u{ae0}','\u{ae1}'],
+	['\u{b05}','\u{b0c}'],
+	['\u{b0f}','\u{b10}'],
+	['\u{b13}','\u{b28}'],
+	['\u{b2a}','\u{b30}'],
+	['\u{b32}','\u{b33}'],
+	['\u{b35}','\u{b39}'],
+	['\u{b3d}','\u{b3d}'],
+	['\u{b5c}','\u{b5d}'],
+	['\u{b5f}','\u{b61}'],
+	['\u{b71}','\u{b71}'],
+	['\u{b83}','\u{b83}'],
+	['\u{b85}','\u{b8a}'],
+	['\u{b8e}','\u{b90}'],
+	['\u{b92}','\u{b95}'],
+	['\u{b99}','\u{b9a}'],
+	['\u{b9c}','\u{b9c}'],
+	['\u{b9e}','\u{b9f}'],
+	['\u{ba3}','\u{ba4}'],
+	['\u{ba8}','\u{baa}'],
+	['\u{bae}','\u{bb9}'],
+	['\u{bd0}','\u{bd0}'],
+	['\u{c05}','\u{c0c}'],
+	['\u{c0e}','\u{c10}'],
+	['\u{c12}','\u{c28}'],
+	['\u{c2a}','\u{c33}'],
+	['\u{c35}','\u{c39}'],
+	['\u{c3d}','\u{c3d}'],
+	['\u{c58}','\u{c59}'],
+	['\u{c60}','\u{c61}'],
+	['\u{c85}','\u{c8c}'],
+	['\u{c8e}','\u{c90}'],
+	['\u{c92}','\u{ca8}'],
+	['\u{caa}','\u{cb3}'],
+	['\u{cb5}','\u{cb9}'],
+	['\u{cbd}','\u{cbd}'],
+	['\u{cde}','\u{cde}'],
+	['\u{ce0}','\u{ce1}'],
+	['\u{cf1}','\u{cf2}'],
+	['\u{d05}','\u{d0c}'],
+	['\u{d0e}','\u{d10}'],
+	['\u{d12}','\u{d3a}'],
+	['\u{d3d}','\u{d3d}'],
+	['\u{d4e}','\u{d4e}'],
+	['\u{d60}','\u{d61}'],
+	['\u{d7a}','\u{d7f}'],
+	['\u{d85}','\u{d96}'],
+	['\u{d9a}','\u{db1}'],
+	['\u{db3}','\u{dbb}'],
+	['\u{dbd}','\u{dbd}'],
+	['\u{dc0}','\u{dc6}'],
+	['\u{e01}','\u{e30}'],
+	['\u{e32}','\u{e33}'],
+	['\u{e40}','\u{e46}'],
+	['\u{e81}','\u{e82}'],
+	['\u{e84}','\u{e84}'],
+	['\u{e87}','\u{e88}'],
+	['\u{e8a}','\u{e8a}'],
+	['\u{e8d}','\u{e8d}'],
+	['\u{e94}','\u{e97}'],
+	['\u{e99}','\u{e9f}'],
+	['\u{ea1}','\u{ea3}'],
+	['\u{ea5}','\u{ea5}'],
+	['\u{ea7}','\u{ea7}'],
+	['\u{eaa}','\u{eab}'],
+	['\u{ead}','\u{eb0}'],
+	['\u{eb2}','\u{eb3}'],
+	['\u{ebd}','\u{ebd}'],
+	['\u{ec0}','\u{ec4}'],
+	['\u{ec6}','\u{ec6}'],
+	['\u{edc}','\u{edf}'],
+	['\u{f00}','\u{f00}'],
+	['\u{f40}','\u{f47}'],
+	['\u{f49}','\u{f6c}'],
+	['\u{f88}','\u{f8c}'],
+	['\u{1000}','\u{102a}'],
+	['\u{103f}','\u{103f}'],
+	['\u{1050}','\u{1055}'],
+	['\u{105a}','\u{105d}'],
+	['\u{1061}','\u{1061}'],
+	['\u{1065}','\u{1066}'],
+	['\u{106e}','\u{1070}'],
+	['\u{1075}','\u{1081}'],
+	['\u{108e}','\u{108e}'],
+	['\u{10a0}','\u{10c5}'],
+	['\u{10c7}','\u{10c7}'],
+	['\u{10cd}','\u{10cd}'],
+	['\u{10d0}','\u{10fa}'],
+	['\u{10fc}','\u{1248}'],
+	['\u{124a}','\u{124d}'],
+	['\u{1250}','\u{1256}'],
+	['\u{1258}','\u{1258}'],
+	['\u{125a}','\u{125d}'],
+	['\u{1260}','\u{1288}'],
+	['\u{128a}','\u{128d}'],
+	['\u{1290}','\u{12b0}'],
+	['\u{12b2}','\u{12b5}'],
+	['\u{12b8}','\u{12be}'],
+	['\u{12c0}','\u{12c0}'],
+	['\u{12c2}','\u{12c5}'],
+	['\u{12c8}','\u{12d6}'],
+	['\u{12d8}','\u{1310}'],
+	['\u{1312}','\u{1315}'],
+	['\u{1318}','\u{135a}'],
+	['\u{1380}','\u{138f}'],
+	['\u{13a0}','\u{13f4}'],
+	['\u{1401}','\u{166c}'],
+	['\u{166f}','\u{167f}'],
+	['\u{1681}','\u{169a}'],
+	['\u{16a0}','\u{16ea}'],
+	['\u{1700}','\u{170c}'],
+	['\u{170e}','\u{1711}'],
+	['\u{1720}','\u{1731}'],
+	['\u{1740}','\u{1751}'],
+	['\u{1760}','\u{176c}'],
+	['\u{176e}','\u{1770}'],
+	['\u{1780}','\u{17b3}'],
+	['\u{17d7}','\u{17d7}'],
+	['\u{17dc}','\u{17dc}'],
+	['\u{1820}','\u{1877}'],
+	['\u{1880}','\u{18a8}'],
+	['\u{18aa}','\u{18aa}'],
+	['\u{18b0}','\u{18f5}'],
+	['\u{1900}','\u{191c}'],
+	['\u{1950}','\u{196d}'],
+	['\u{1970}','\u{1974}'],
+	['\u{1980}','\u{19ab}'],
+	['\u{19c1}','\u{19c7}'],
+	['\u{1a00}','\u{1a16}'],
+	['\u{1a20}','\u{1a54}'],
+	['\u{1aa7}','\u{1aa7}'],
+	['\u{1b05}','\u{1b33}'],
+	['\u{1b45}','\u{1b4b}'],
+	['\u{1b83}','\u{1ba0}'],
+	['\u{1bae}','\u{1baf}'],
+	['\u{1bba}','\u{1be5}'],
+	['\u{1c00}','\u{1c23}'],
+	['\u{1c4d}','\u{1c4f}'],
+	['\u{1c5a}','\u{1c7d}'],
+	['\u{1ce9}','\u{1cec}'],
+	['\u{1cee}','\u{1cf1}'],
+	['\u{1cf5}','\u{1cf6}'],
+	['\u{1d00}','\u{1dbf}'],
+	['\u{1e00}','\u{1f15}'],
+	['\u{1f18}','\u{1f1d}'],
+	['\u{1f20}','\u{1f45}'],
+	['\u{1f48}','\u{1f4d}'],
+	['\u{1f50}','\u{1f57}'],
+	['\u{1f59}','\u{1f59}'],
+	['\u{1f5b}','\u{1f5b}'],
+	['\u{1f5d}','\u{1f5d}'],
+	['\u{1f5f}','\u{1f7d}'],
+	['\u{1f80}','\u{1fb4}'],
+	['\u{1fb6}','\u{1fbc}'],
+	['\u{1fbe}','\u{1fbe}'],
+	['\u{1fc2}','\u{1fc4}'],
+	['\u{1fc6}','\u{1fcc}'],
+	['\u{1fd0}','\u{1fd3}'],
+	['\u{1fd6}','\u{1fdb}'],
+	['\u{1fe0}','\u{1fec}'],
+	['\u{1ff2}','\u{1ff4}'],
+	['\u{1ff6}','\u{1ffc}'],
+	['\u{2071}','\u{2071}'],
+	['\u{207f}','\u{207f}'],
+	['\u{2090}','\u{209c}'],
+	['\u{2102}','\u{2102}'],
+	['\u{2107}','\u{2107}'],
+	['\u{210a}','\u{2113}'],
+	['\u{2115}','\u{2115}'],
+	['\u{2119}','\u{211d}'],
+	['\u{2124}','\u{2124}'],
+	['\u{2126}','\u{2126}'],
+	['\u{2128}','\u{2128}'],
+	['\u{212a}','\u{212d}'],
+	['\u{212f}','\u{2139}'],
+	['\u{213c}','\u{213f}'],
+	['\u{2145}','\u{2149}'],
+	['\u{214e}','\u{214e}'],
+	['\u{2183}','\u{2184}'],
+	['\u{2c00}','\u{2c2e}'],
+	['\u{2c30}','\u{2c5e}'],
+	['\u{2c60}','\u{2ce4}'],
+	['\u{2ceb}','\u{2cee}'],
+	['\u{2cf2}','\u{2cf3}'],
+	['\u{2d00}','\u{2d25}'],
+	['\u{2d27}','\u{2d27}'],
+	['\u{2d2d}','\u{2d2d}'],
+	['\u{2d30}','\u{2d67}'],
+	['\u{2d6f}','\u{2d6f}'],
+	['\u{2d80}','\u{2d96}'],
+	['\u{2da0}','\u{2da6}'],
+	['\u{2da8}','\u{2dae}'],
+	['\u{2db0}','\u{2db6}'],
+	['\u{2db8}','\u{2dbe}'],
+	['\u{2dc0}','\u{2dc6}'],
+	['\u{2dc8}','\u{2dce}'],
+	['\u{2dd0}','\u{2dd6}'],
+	['\u{2dd8}','\u{2dde}'],
+	['\u{2e2f}','\u{2e2f}'],
+	['\u{3005}','\u{3006}'],
+	['\u{3031}','\u{3035}'],
+	['\u{303b}','\u{303c}'],
+	['\u{3041}','\u{3096}'],
+	['\u{309d}','\u{309f}'],
+	['\u{30a1}','\u{30fa}'],
+	['\u{30fc}','\u{30ff}'],
+	['\u{3105}','\u{312d}'],
+	['\u{3131}','\u{318e}'],
+	['\u{31a0}','\u{31ba}'],
+	['\u{31f0}','\u{31ff}'],
+	['\u{3400}','\u{4db5}'],
+	['\u{4e00}','\u{9fcc}'],
+	['\u{a000}','\u{a48c}'],
+	['\u{a4d0}','\u{a4fd}'],
+	['\u{a500}','\u{a60c}'],
+	['\u{a610}','\u{a61f}'],
+	['\u{a62a}','\u{a62b}'],
+	['\u{a640}','\u{a66e}'],
+	['\u{a67f}','\u{a697}'],
+	['\u{a6a0}','\u{a6e5}'],
+	['\u{a717}','\u{a71f}'],
+	['\u{a722}','\u{a788}'],
+	['\u{a78b}','\u{a78e}'],
+	['\u{a790}','\u{a793}'],
+	['\u{a7a0}','\u{a7aa}'],
+	['\u{a7f8}','\u{a801}'],
+	['\u{a803}','\u{a805}'],
+	['\u{a807}','\u{a80a}'],
+	['\u{a80c}','\u{a822}'],
+	['\u{a840}','\u{a873}'],
+	['\u{a882}','\u{a8b3}'],
+	['\u{a8f2}','\u{a8f7}'],
+	['\u{a8fb}','\u{a8fb}'],
+	['\u{a90a}','\u{a925}'],
+	['\u{a930}','\u{a946}'],
+	['\u{a960}','\u{a97c}'],
+	['\u{a984}','\u{a9b2}'],
+	['\u{a9cf}','\u{a9cf}'],
+	['\u{aa00}','\u{aa28}'],
+	['\u{aa40}','\u{aa42}'],
+	['\u{aa44}','\u{aa4b}'],
+	['\u{aa60}','\u{aa76}'],
+	['\u{aa7a}','\u{aa7a}'],
+	['\u{aa80}','\u{aaaf}'],
+	['\u{aab1}','\u{aab1}'],
+	['\u{aab5}','\u{aab6}'],
+	['\u{aab9}','\u{aabd}'],
+	['\u{aac0}','\u{aac0}'],
+	['\u{aac2}','\u{aac2}'],
+	['\u{aadb}','\u{aadd}'],
+	['\u{aae0}','\u{aaea}'],
+	['\u{aaf2}','\u{aaf4}'],
+	['\u{ab01}','\u{ab06}'],
+	['\u{ab09}','\u{ab0e}'],
+	['\u{ab11}','\u{ab16}'],
+	['\u{ab20}','\u{ab26}'],
+	['\u{ab28}','\u{ab2e}'],
+	['\u{abc0}','\u{abe2}'],
+	['\u{ac00}','\u{d7a3}'],
+	['\u{d7b0}','\u{d7c6}'],
+	['\u{d7cb}','\u{d7fb}'],
+	['\u{f900}','\u{fa6d}'],
+	['\u{fa70}','\u{fad9}'],
+	['\u{fb00}','\u{fb06}'],
+	['\u{fb13}','\u{fb17}'],
+	['\u{fb1d}','\u{fb1d}'],
+	['\u{fb1f}','\u{fb28}'],
+	['\u{fb2a}','\u{fb36}'],
+	['\u{fb38}','\u{fb3c}'],
+	['\u{fb3e}','\u{fb3e}'],
+	['\u{fb40}','\u{fb41}'],
+	['\u{fb43}','\u{fb44}'],
+	['\u{fb46}','\u{fbb1}'],
+	['\u{fbd3}','\u{fd3d}'],
+	['\u{fd50}','\u{fd8f}'],
+	['\u{fd92}','\u{fdc7}'],
+	['\u{fdf0}','\u{fdfb}'],
+	['\u{fe70}','\u{fe74}'],
+	['\u{fe76}','\u{fefc}'],
+	['\u{ff21}','\u{ff3a}'],
+	['\u{ff41}','\u{ff5a}'],
+	['\u{ff66}','\u{ffbe}'],
+	['\u{ffc2}','\u{ffc7}'],
+	['\u{ffca}','\u{ffcf}'],
+	['\u{ffd2}','\u{ffd7}'],
+	['\u{ffda}','\u{ffdc}'],
+	['\u{10000}','\u{1000b}'],
+	['\u{1000d}','\u{10026}'],
+	['\u{10028}','\u{1003a}'],
+	['\u{1003c}','\u{1003d}'],
+	['\u{1003f}','\u{1004d}'],
+	['\u{10050}','\u{1005d}'],
+	['\u{10080}','\u{100fa}'],
+	['\u{10280}','\u{1029c}'],
+	['\u{102a0}','\u{102d0}'],
+	['\u{10300}','\u{1031e}'],
+	['\u{10330}','\u{10340}'],
+	['\u{10342}','\u{10349}'],
+	['\u{10380}','\u{1039d}'],
+	['\u{103a0}','\u{103c3}'],
+	['\u{103c8}','\u{103cf}'],
+	['\u{10400}','\u{1049d}'],
+	['\u{10800}','\u{10805}'],
+	['\u{10808}','\u{10808}'],
+	['\u{1080a}','\u{10835}'],
+	['\u{10837}','\u{10838}'],
+	['\u{1083c}','\u{1083c}'],
+	['\u{1083f}','\u{10855}'],
+	['\u{10900}','\u{10915}'],
+	['\u{10920}','\u{10939}'],
+	['\u{10980}','\u{109b7}'],
+	['\u{109be}','\u{109bf}'],
+	['\u{10a00}','\u{10a00}'],
+	['\u{10a10}','\u{10a13}'],
+	['\u{10a15}','\u{10a17}'],
+	['\u{10a19}','\u{10a33}'],
+	['\u{10a60}','\u{10a7c}'],
+	['\u{10b00}','\u{10b35}'],
+	['\u{10b40}','\u{10b55}'],
+	['\u{10b60}','\u{10b72}'],
+	['\u{10c00}','\u{10c48}'],
+	['\u{11003}','\u{11037}'],
+	['\u{11083}','\u{110af}'],
+	['\u{110d0}','\u{110e8}'],
+	['\u{11103}','\u{11126}'],
+	['\u{11183}','\u{111b2}'],
+	['\u{111c1}','\u{111c4}'],
+	['\u{11680}','\u{116aa}'],
+	['\u{12000}','\u{1236e}'],
+	['\u{13000}','\u{1342e}'],
+	['\u{16800}','\u{16a38}'],
+	['\u{16f00}','\u{16f44}'],
+	['\u{16f50}','\u{16f50}'],
+	['\u{16f93}','\u{16f9f}'],
+	['\u{1b000}','\u{1b001}'],
+	['\u{1d400}','\u{1d454}'],
+	['\u{1d456}','\u{1d49c}'],
+	['\u{1d49e}','\u{1d49f}'],
+	['\u{1d4a2}','\u{1d4a2}'],
+	['\u{1d4a5}','\u{1d4a6}'],
+	['\u{1d4a9}','\u{1d4ac}'],
+	['\u{1d4ae}','\u{1d4b9}'],
+	['\u{1d4bb}','\u{1d4bb}'],
+	['\u{1d4bd}','\u{1d4c3}'],
+	['\u{1d4c5}','\u{1d505}'],
+	['\u{1d507}','\u{1d50a}'],
+	['\u{1d50d}','\u{1d514}'],
+	['\u{1d516}','\u{1d51c}'],
+	['\u{1d51e}','\u{1d539}'],
+	['\u{1d53b}','\u{1d53e}'],
+	['\u{1d540}','\u{1d544}'],
+	['\u{1d546}','\u{1d546}'],
+	['\u{1d54a}','\u{1d550}'],
+	['\u{1d552}','\u{1d6a5}'],
+	['\u{1d6a8}','\u{1d6c0}'],
+	['\u{1d6c2}','\u{1d6da}'],
+	['\u{1d6dc}','\u{1d6fa}'],
+	['\u{1d6fc}','\u{1d714}'],
+	['\u{1d716}','\u{1d734}'],
+	['\u{1d736}','\u{1d74e}'],
+	['\u{1d750}','\u{1d76e}'],
+	['\u{1d770}','\u{1d788}'],
+	['\u{1d78a}','\u{1d7a8}'],
+	['\u{1d7aa}','\u{1d7c2}'],
+	['\u{1d7c4}','\u{1d7cb}'],
+	['\u{1ee00}','\u{1ee03}'],
+	['\u{1ee05}','\u{1ee1f}'],
+	['\u{1ee21}','\u{1ee22}'],
+	['\u{1ee24}','\u{1ee24}'],
+	['\u{1ee27}','\u{1ee27}'],
+	['\u{1ee29}','\u{1ee32}'],
+	['\u{1ee34}','\u{1ee37}'],
+	['\u{1ee39}','\u{1ee39}'],
+	['\u{1ee3b}','\u{1ee3b}'],
+	['\u{1ee42}','\u{1ee42}'],
+	['\u{1ee47}','\u{1ee47}'],
+	['\u{1ee49}','\u{1ee49}'],
+	['\u{1ee4b}','\u{1ee4b}'],
+	['\u{1ee4d}','\u{1ee4f}'],
+	['\u{1ee51}','\u{1ee52}'],
+	['\u{1ee54}','\u{1ee54}'],
+	['\u{1ee57}','\u{1ee57}'],
+	['\u{1ee59}','\u{1ee59}'],
+	['\u{1ee5b}','\u{1ee5b}'],
+	['\u{1ee5d}','\u{1ee5d}'],
+	['\u{1ee5f}','\u{1ee5f}'],
+	['\u{1ee61}','\u{1ee62}'],
+	['\u{1ee64}','\u{1ee64}'],
+	['\u{1ee67}','\u{1ee6a}'],
+	['\u{1ee6c}','\u{1ee72}'],
+	['\u{1ee74}','\u{1ee77}'],
+	['\u{1ee79}','\u{1ee7c}'],
+	['\u{1ee7e}','\u{1ee7e}'],
+	['\u{1ee80}','\u{1ee89}'],
+	['\u{1ee8b}','\u{1ee9b}'],
+	['\u{1eea1}','\u{1eea3}'],
+	['\u{1eea5}','\u{1eea9}'],
+	['\u{1eeab}','\u{1eebb}'],
+	['\u{20000}','\u{2a6d6}'],
+	['\u{2a700}','\u{2b734}'],
+	['\u{2b740}','\u{2b81d}'],
+	['\u{2f800}','\u{2fa1d}'],
+]
+
+const tabupper = [
+	['\u{41}','\u{5a}'],
+	['\u{c0}','\u{d6}'],
+	['\u{d8}','\u{de}'],
+	['\u{100}','\u{100}'],
+	['\u{102}','\u{102}'],
+	['\u{104}','\u{104}'],
+	['\u{106}','\u{106}'],
+	['\u{108}','\u{108}'],
+	['\u{10a}','\u{10a}'],
+	['\u{10c}','\u{10c}'],
+	['\u{10e}','\u{10e}'],
+	['\u{110}','\u{110}'],
+	['\u{112}','\u{112}'],
+	['\u{114}','\u{114}'],
+	['\u{116}','\u{116}'],
+	['\u{118}','\u{118}'],
+	['\u{11a}','\u{11a}'],
+	['\u{11c}','\u{11c}'],
+	['\u{11e}','\u{11e}'],
+	['\u{120}','\u{120}'],
+	['\u{122}','\u{122}'],
+	['\u{124}','\u{124}'],
+	['\u{126}','\u{126}'],
+	['\u{128}','\u{128}'],
+	['\u{12a}','\u{12a}'],
+	['\u{12c}','\u{12c}'],
+	['\u{12e}','\u{12e}'],
+	['\u{130}','\u{130}'],
+	['\u{132}','\u{132}'],
+	['\u{134}','\u{134}'],
+	['\u{136}','\u{136}'],
+	['\u{139}','\u{139}'],
+	['\u{13b}','\u{13b}'],
+	['\u{13d}','\u{13d}'],
+	['\u{13f}','\u{13f}'],
+	['\u{141}','\u{141}'],
+	['\u{143}','\u{143}'],
+	['\u{145}','\u{145}'],
+	['\u{147}','\u{147}'],
+	['\u{14a}','\u{14a}'],
+	['\u{14c}','\u{14c}'],
+	['\u{14e}','\u{14e}'],
+	['\u{150}','\u{150}'],
+	['\u{152}','\u{152}'],
+	['\u{154}','\u{154}'],
+	['\u{156}','\u{156}'],
+	['\u{158}','\u{158}'],
+	['\u{15a}','\u{15a}'],
+	['\u{15c}','\u{15c}'],
+	['\u{15e}','\u{15e}'],
+	['\u{160}','\u{160}'],
+	['\u{162}','\u{162}'],
+	['\u{164}','\u{164}'],
+	['\u{166}','\u{166}'],
+	['\u{168}','\u{168}'],
+	['\u{16a}','\u{16a}'],
+	['\u{16c}','\u{16c}'],
+	['\u{16e}','\u{16e}'],
+	['\u{170}','\u{170}'],
+	['\u{172}','\u{172}'],
+	['\u{174}','\u{174}'],
+	['\u{176}','\u{176}'],
+	['\u{178}','\u{179}'],
+	['\u{17b}','\u{17b}'],
+	['\u{17d}','\u{17d}'],
+	['\u{181}','\u{182}'],
+	['\u{184}','\u{184}'],
+	['\u{186}','\u{187}'],
+	['\u{189}','\u{18b}'],
+	['\u{18e}','\u{191}'],
+	['\u{193}','\u{194}'],
+	['\u{196}','\u{198}'],
+	['\u{19c}','\u{19d}'],
+	['\u{19f}','\u{1a0}'],
+	['\u{1a2}','\u{1a2}'],
+	['\u{1a4}','\u{1a4}'],
+	['\u{1a6}','\u{1a7}'],
+	['\u{1a9}','\u{1a9}'],
+	['\u{1ac}','\u{1ac}'],
+	['\u{1ae}','\u{1af}'],
+	['\u{1b1}','\u{1b3}'],
+	['\u{1b5}','\u{1b5}'],
+	['\u{1b7}','\u{1b8}'],
+	['\u{1bc}','\u{1bc}'],
+	['\u{1c4}','\u{1c4}'],
+	['\u{1c7}','\u{1c7}'],
+	['\u{1ca}','\u{1ca}'],
+	['\u{1cd}','\u{1cd}'],
+	['\u{1cf}','\u{1cf}'],
+	['\u{1d1}','\u{1d1}'],
+	['\u{1d3}','\u{1d3}'],
+	['\u{1d5}','\u{1d5}'],
+	['\u{1d7}','\u{1d7}'],
+	['\u{1d9}','\u{1d9}'],
+	['\u{1db}','\u{1db}'],
+	['\u{1de}','\u{1de}'],
+	['\u{1e0}','\u{1e0}'],
+	['\u{1e2}','\u{1e2}'],
+	['\u{1e4}','\u{1e4}'],
+	['\u{1e6}','\u{1e6}'],
+	['\u{1e8}','\u{1e8}'],
+	['\u{1ea}','\u{1ea}'],
+	['\u{1ec}','\u{1ec}'],
+	['\u{1ee}','\u{1ee}'],
+	['\u{1f1}','\u{1f1}'],
+	['\u{1f4}','\u{1f4}'],
+	['\u{1f6}','\u{1f8}'],
+	['\u{1fa}','\u{1fa}'],
+	['\u{1fc}','\u{1fc}'],
+	['\u{1fe}','\u{1fe}'],
+	['\u{200}','\u{200}'],
+	['\u{202}','\u{202}'],
+	['\u{204}','\u{204}'],
+	['\u{206}','\u{206}'],
+	['\u{208}','\u{208}'],
+	['\u{20a}','\u{20a}'],
+	['\u{20c}','\u{20c}'],
+	['\u{20e}','\u{20e}'],
+	['\u{210}','\u{210}'],
+	['\u{212}','\u{212}'],
+	['\u{214}','\u{214}'],
+	['\u{216}','\u{216}'],
+	['\u{218}','\u{218}'],
+	['\u{21a}','\u{21a}'],
+	['\u{21c}','\u{21c}'],
+	['\u{21e}','\u{21e}'],
+	['\u{220}','\u{220}'],
+	['\u{222}','\u{222}'],
+	['\u{224}','\u{224}'],
+	['\u{226}','\u{226}'],
+	['\u{228}','\u{228}'],
+	['\u{22a}','\u{22a}'],
+	['\u{22c}','\u{22c}'],
+	['\u{22e}','\u{22e}'],
+	['\u{230}','\u{230}'],
+	['\u{232}','\u{232}'],
+	['\u{23a}','\u{23b}'],
+	['\u{23d}','\u{23e}'],
+	['\u{241}','\u{241}'],
+	['\u{243}','\u{246}'],
+	['\u{248}','\u{248}'],
+	['\u{24a}','\u{24a}'],
+	['\u{24c}','\u{24c}'],
+	['\u{24e}','\u{24e}'],
+	['\u{370}','\u{370}'],
+	['\u{372}','\u{372}'],
+	['\u{376}','\u{376}'],
+	['\u{386}','\u{386}'],
+	['\u{388}','\u{38a}'],
+	['\u{38c}','\u{38c}'],
+	['\u{38e}','\u{38f}'],
+	['\u{391}','\u{3a1}'],
+	['\u{3a3}','\u{3ab}'],
+	['\u{3cf}','\u{3cf}'],
+	['\u{3d2}','\u{3d4}'],
+	['\u{3d8}','\u{3d8}'],
+	['\u{3da}','\u{3da}'],
+	['\u{3dc}','\u{3dc}'],
+	['\u{3de}','\u{3de}'],
+	['\u{3e0}','\u{3e0}'],
+	['\u{3e2}','\u{3e2}'],
+	['\u{3e4}','\u{3e4}'],
+	['\u{3e6}','\u{3e6}'],
+	['\u{3e8}','\u{3e8}'],
+	['\u{3ea}','\u{3ea}'],
+	['\u{3ec}','\u{3ec}'],
+	['\u{3ee}','\u{3ee}'],
+	['\u{3f4}','\u{3f4}'],
+	['\u{3f7}','\u{3f7}'],
+	['\u{3f9}','\u{3fa}'],
+	['\u{3fd}','\u{42f}'],
+	['\u{460}','\u{460}'],
+	['\u{462}','\u{462}'],
+	['\u{464}','\u{464}'],
+	['\u{466}','\u{466}'],
+	['\u{468}','\u{468}'],
+	['\u{46a}','\u{46a}'],
+	['\u{46c}','\u{46c}'],
+	['\u{46e}','\u{46e}'],
+	['\u{470}','\u{470}'],
+	['\u{472}','\u{472}'],
+	['\u{474}','\u{474}'],
+	['\u{476}','\u{476}'],
+	['\u{478}','\u{478}'],
+	['\u{47a}','\u{47a}'],
+	['\u{47c}','\u{47c}'],
+	['\u{47e}','\u{47e}'],
+	['\u{480}','\u{480}'],
+	['\u{48a}','\u{48a}'],
+	['\u{48c}','\u{48c}'],
+	['\u{48e}','\u{48e}'],
+	['\u{490}','\u{490}'],
+	['\u{492}','\u{492}'],
+	['\u{494}','\u{494}'],
+	['\u{496}','\u{496}'],
+	['\u{498}','\u{498}'],
+	['\u{49a}','\u{49a}'],
+	['\u{49c}','\u{49c}'],
+	['\u{49e}','\u{49e}'],
+	['\u{4a0}','\u{4a0}'],
+	['\u{4a2}','\u{4a2}'],
+	['\u{4a4}','\u{4a4}'],
+	['\u{4a6}','\u{4a6}'],
+	['\u{4a8}','\u{4a8}'],
+	['\u{4aa}','\u{4aa}'],
+	['\u{4ac}','\u{4ac}'],
+	['\u{4ae}','\u{4ae}'],
+	['\u{4b0}','\u{4b0}'],
+	['\u{4b2}','\u{4b2}'],
+	['\u{4b4}','\u{4b4}'],
+	['\u{4b6}','\u{4b6}'],
+	['\u{4b8}','\u{4b8}'],
+	['\u{4ba}','\u{4ba}'],
+	['\u{4bc}','\u{4bc}'],
+	['\u{4be}','\u{4be}'],
+	['\u{4c0}','\u{4c1}'],
+	['\u{4c3}','\u{4c3}'],
+	['\u{4c5}','\u{4c5}'],
+	['\u{4c7}','\u{4c7}'],
+	['\u{4c9}','\u{4c9}'],
+	['\u{4cb}','\u{4cb}'],
+	['\u{4cd}','\u{4cd}'],
+	['\u{4d0}','\u{4d0}'],
+	['\u{4d2}','\u{4d2}'],
+	['\u{4d4}','\u{4d4}'],
+	['\u{4d6}','\u{4d6}'],
+	['\u{4d8}','\u{4d8}'],
+	['\u{4da}','\u{4da}'],
+	['\u{4dc}','\u{4dc}'],
+	['\u{4de}','\u{4de}'],
+	['\u{4e0}','\u{4e0}'],
+	['\u{4e2}','\u{4e2}'],
+	['\u{4e4}','\u{4e4}'],
+	['\u{4e6}','\u{4e6}'],
+	['\u{4e8}','\u{4e8}'],
+	['\u{4ea}','\u{4ea}'],
+	['\u{4ec}','\u{4ec}'],
+	['\u{4ee}','\u{4ee}'],
+	['\u{4f0}','\u{4f0}'],
+	['\u{4f2}','\u{4f2}'],
+	['\u{4f4}','\u{4f4}'],
+	['\u{4f6}','\u{4f6}'],
+	['\u{4f8}','\u{4f8}'],
+	['\u{4fa}','\u{4fa}'],
+	['\u{4fc}','\u{4fc}'],
+	['\u{4fe}','\u{4fe}'],
+	['\u{500}','\u{500}'],
+	['\u{502}','\u{502}'],
+	['\u{504}','\u{504}'],
+	['\u{506}','\u{506}'],
+	['\u{508}','\u{508}'],
+	['\u{50a}','\u{50a}'],
+	['\u{50c}','\u{50c}'],
+	['\u{50e}','\u{50e}'],
+	['\u{510}','\u{510}'],
+	['\u{512}','\u{512}'],
+	['\u{514}','\u{514}'],
+	['\u{516}','\u{516}'],
+	['\u{518}','\u{518}'],
+	['\u{51a}','\u{51a}'],
+	['\u{51c}','\u{51c}'],
+	['\u{51e}','\u{51e}'],
+	['\u{520}','\u{520}'],
+	['\u{522}','\u{522}'],
+	['\u{524}','\u{524}'],
+	['\u{526}','\u{526}'],
+	['\u{531}','\u{556}'],
+	['\u{10a0}','\u{10c5}'],
+	['\u{10c7}','\u{10c7}'],
+	['\u{10cd}','\u{10cd}'],
+	['\u{1e00}','\u{1e00}'],
+	['\u{1e02}','\u{1e02}'],
+	['\u{1e04}','\u{1e04}'],
+	['\u{1e06}','\u{1e06}'],
+	['\u{1e08}','\u{1e08}'],
+	['\u{1e0a}','\u{1e0a}'],
+	['\u{1e0c}','\u{1e0c}'],
+	['\u{1e0e}','\u{1e0e}'],
+	['\u{1e10}','\u{1e10}'],
+	['\u{1e12}','\u{1e12}'],
+	['\u{1e14}','\u{1e14}'],
+	['\u{1e16}','\u{1e16}'],
+	['\u{1e18}','\u{1e18}'],
+	['\u{1e1a}','\u{1e1a}'],
+	['\u{1e1c}','\u{1e1c}'],
+	['\u{1e1e}','\u{1e1e}'],
+	['\u{1e20}','\u{1e20}'],
+	['\u{1e22}','\u{1e22}'],
+	['\u{1e24}','\u{1e24}'],
+	['\u{1e26}','\u{1e26}'],
+	['\u{1e28}','\u{1e28}'],
+	['\u{1e2a}','\u{1e2a}'],
+	['\u{1e2c}','\u{1e2c}'],
+	['\u{1e2e}','\u{1e2e}'],
+	['\u{1e30}','\u{1e30}'],
+	['\u{1e32}','\u{1e32}'],
+	['\u{1e34}','\u{1e34}'],
+	['\u{1e36}','\u{1e36}'],
+	['\u{1e38}','\u{1e38}'],
+	['\u{1e3a}','\u{1e3a}'],
+	['\u{1e3c}','\u{1e3c}'],
+	['\u{1e3e}','\u{1e3e}'],
+	['\u{1e40}','\u{1e40}'],
+	['\u{1e42}','\u{1e42}'],
+	['\u{1e44}','\u{1e44}'],
+	['\u{1e46}','\u{1e46}'],
+	['\u{1e48}','\u{1e48}'],
+	['\u{1e4a}','\u{1e4a}'],
+	['\u{1e4c}','\u{1e4c}'],
+	['\u{1e4e}','\u{1e4e}'],
+	['\u{1e50}','\u{1e50}'],
+	['\u{1e52}','\u{1e52}'],
+	['\u{1e54}','\u{1e54}'],
+	['\u{1e56}','\u{1e56}'],
+	['\u{1e58}','\u{1e58}'],
+	['\u{1e5a}','\u{1e5a}'],
+	['\u{1e5c}','\u{1e5c}'],
+	['\u{1e5e}','\u{1e5e}'],
+	['\u{1e60}','\u{1e60}'],
+	['\u{1e62}','\u{1e62}'],
+	['\u{1e64}','\u{1e64}'],
+	['\u{1e66}','\u{1e66}'],
+	['\u{1e68}','\u{1e68}'],
+	['\u{1e6a}','\u{1e6a}'],
+	['\u{1e6c}','\u{1e6c}'],
+	['\u{1e6e}','\u{1e6e}'],
+	['\u{1e70}','\u{1e70}'],
+	['\u{1e72}','\u{1e72}'],
+	['\u{1e74}','\u{1e74}'],
+	['\u{1e76}','\u{1e76}'],
+	['\u{1e78}','\u{1e78}'],
+	['\u{1e7a}','\u{1e7a}'],
+	['\u{1e7c}','\u{1e7c}'],
+	['\u{1e7e}','\u{1e7e}'],
+	['\u{1e80}','\u{1e80}'],
+	['\u{1e82}','\u{1e82}'],
+	['\u{1e84}','\u{1e84}'],
+	['\u{1e86}','\u{1e86}'],
+	['\u{1e88}','\u{1e88}'],
+	['\u{1e8a}','\u{1e8a}'],
+	['\u{1e8c}','\u{1e8c}'],
+	['\u{1e8e}','\u{1e8e}'],
+	['\u{1e90}','\u{1e90}'],
+	['\u{1e92}','\u{1e92}'],
+	['\u{1e94}','\u{1e94}'],
+	['\u{1e9e}','\u{1e9e}'],
+	['\u{1ea0}','\u{1ea0}'],
+	['\u{1ea2}','\u{1ea2}'],
+	['\u{1ea4}','\u{1ea4}'],
+	['\u{1ea6}','\u{1ea6}'],
+	['\u{1ea8}','\u{1ea8}'],
+	['\u{1eaa}','\u{1eaa}'],
+	['\u{1eac}','\u{1eac}'],
+	['\u{1eae}','\u{1eae}'],
+	['\u{1eb0}','\u{1eb0}'],
+	['\u{1eb2}','\u{1eb2}'],
+	['\u{1eb4}','\u{1eb4}'],
+	['\u{1eb6}','\u{1eb6}'],
+	['\u{1eb8}','\u{1eb8}'],
+	['\u{1eba}','\u{1eba}'],
+	['\u{1ebc}','\u{1ebc}'],
+	['\u{1ebe}','\u{1ebe}'],
+	['\u{1ec0}','\u{1ec0}'],
+	['\u{1ec2}','\u{1ec2}'],
+	['\u{1ec4}','\u{1ec4}'],
+	['\u{1ec6}','\u{1ec6}'],
+	['\u{1ec8}','\u{1ec8}'],
+	['\u{1eca}','\u{1eca}'],
+	['\u{1ecc}','\u{1ecc}'],
+	['\u{1ece}','\u{1ece}'],
+	['\u{1ed0}','\u{1ed0}'],
+	['\u{1ed2}','\u{1ed2}'],
+	['\u{1ed4}','\u{1ed4}'],
+	['\u{1ed6}','\u{1ed6}'],
+	['\u{1ed8}','\u{1ed8}'],
+	['\u{1eda}','\u{1eda}'],
+	['\u{1edc}','\u{1edc}'],
+	['\u{1ede}','\u{1ede}'],
+	['\u{1ee0}','\u{1ee0}'],
+	['\u{1ee2}','\u{1ee2}'],
+	['\u{1ee4}','\u{1ee4}'],
+	['\u{1ee6}','\u{1ee6}'],
+	['\u{1ee8}','\u{1ee8}'],
+	['\u{1eea}','\u{1eea}'],
+	['\u{1eec}','\u{1eec}'],
+	['\u{1eee}','\u{1eee}'],
+	['\u{1ef0}','\u{1ef0}'],
+	['\u{1ef2}','\u{1ef2}'],
+	['\u{1ef4}','\u{1ef4}'],
+	['\u{1ef6}','\u{1ef6}'],
+	['\u{1ef8}','\u{1ef8}'],
+	['\u{1efa}','\u{1efa}'],
+	['\u{1efc}','\u{1efc}'],
+	['\u{1efe}','\u{1efe}'],
+	['\u{1f08}','\u{1f0f}'],
+	['\u{1f18}','\u{1f1d}'],
+	['\u{1f28}','\u{1f2f}'],
+	['\u{1f38}','\u{1f3f}'],
+	['\u{1f48}','\u{1f4d}'],
+	['\u{1f59}','\u{1f59}'],
+	['\u{1f5b}','\u{1f5b}'],
+	['\u{1f5d}','\u{1f5d}'],
+	['\u{1f5f}','\u{1f5f}'],
+	['\u{1f68}','\u{1f6f}'],
+	['\u{1fb8}','\u{1fbb}'],
+	['\u{1fc8}','\u{1fcb}'],
+	['\u{1fd8}','\u{1fdb}'],
+	['\u{1fe8}','\u{1fec}'],
+	['\u{1ff8}','\u{1ffb}'],
+	['\u{2102}','\u{2102}'],
+	['\u{2107}','\u{2107}'],
+	['\u{210b}','\u{210d}'],
+	['\u{2110}','\u{2112}'],
+	['\u{2115}','\u{2115}'],
+	['\u{2119}','\u{211d}'],
+	['\u{2124}','\u{2124}'],
+	['\u{2126}','\u{2126}'],
+	['\u{2128}','\u{2128}'],
+	['\u{212a}','\u{212d}'],
+	['\u{2130}','\u{2133}'],
+	['\u{213e}','\u{213f}'],
+	['\u{2145}','\u{2145}'],
+	['\u{2183}','\u{2183}'],
+	['\u{2c00}','\u{2c2e}'],
+	['\u{2c60}','\u{2c60}'],
+	['\u{2c62}','\u{2c64}'],
+	['\u{2c67}','\u{2c67}'],
+	['\u{2c69}','\u{2c69}'],
+	['\u{2c6b}','\u{2c6b}'],
+	['\u{2c6d}','\u{2c70}'],
+	['\u{2c72}','\u{2c72}'],
+	['\u{2c75}','\u{2c75}'],
+	['\u{2c7e}','\u{2c80}'],
+	['\u{2c82}','\u{2c82}'],
+	['\u{2c84}','\u{2c84}'],
+	['\u{2c86}','\u{2c86}'],
+	['\u{2c88}','\u{2c88}'],
+	['\u{2c8a}','\u{2c8a}'],
+	['\u{2c8c}','\u{2c8c}'],
+	['\u{2c8e}','\u{2c8e}'],
+	['\u{2c90}','\u{2c90}'],
+	['\u{2c92}','\u{2c92}'],
+	['\u{2c94}','\u{2c94}'],
+	['\u{2c96}','\u{2c96}'],
+	['\u{2c98}','\u{2c98}'],
+	['\u{2c9a}','\u{2c9a}'],
+	['\u{2c9c}','\u{2c9c}'],
+	['\u{2c9e}','\u{2c9e}'],
+	['\u{2ca0}','\u{2ca0}'],
+	['\u{2ca2}','\u{2ca2}'],
+	['\u{2ca4}','\u{2ca4}'],
+	['\u{2ca6}','\u{2ca6}'],
+	['\u{2ca8}','\u{2ca8}'],
+	['\u{2caa}','\u{2caa}'],
+	['\u{2cac}','\u{2cac}'],
+	['\u{2cae}','\u{2cae}'],
+	['\u{2cb0}','\u{2cb0}'],
+	['\u{2cb2}','\u{2cb2}'],
+	['\u{2cb4}','\u{2cb4}'],
+	['\u{2cb6}','\u{2cb6}'],
+	['\u{2cb8}','\u{2cb8}'],
+	['\u{2cba}','\u{2cba}'],
+	['\u{2cbc}','\u{2cbc}'],
+	['\u{2cbe}','\u{2cbe}'],
+	['\u{2cc0}','\u{2cc0}'],
+	['\u{2cc2}','\u{2cc2}'],
+	['\u{2cc4}','\u{2cc4}'],
+	['\u{2cc6}','\u{2cc6}'],
+	['\u{2cc8}','\u{2cc8}'],
+	['\u{2cca}','\u{2cca}'],
+	['\u{2ccc}','\u{2ccc}'],
+	['\u{2cce}','\u{2cce}'],
+	['\u{2cd0}','\u{2cd0}'],
+	['\u{2cd2}','\u{2cd2}'],
+	['\u{2cd4}','\u{2cd4}'],
+	['\u{2cd6}','\u{2cd6}'],
+	['\u{2cd8}','\u{2cd8}'],
+	['\u{2cda}','\u{2cda}'],
+	['\u{2cdc}','\u{2cdc}'],
+	['\u{2cde}','\u{2cde}'],
+	['\u{2ce0}','\u{2ce0}'],
+	['\u{2ce2}','\u{2ce2}'],
+	['\u{2ceb}','\u{2ceb}'],
+	['\u{2ced}','\u{2ced}'],
+	['\u{2cf2}','\u{2cf2}'],
+	['\u{a640}','\u{a640}'],
+	['\u{a642}','\u{a642}'],
+	['\u{a644}','\u{a644}'],
+	['\u{a646}','\u{a646}'],
+	['\u{a648}','\u{a648}'],
+	['\u{a64a}','\u{a64a}'],
+	['\u{a64c}','\u{a64c}'],
+	['\u{a64e}','\u{a64e}'],
+	['\u{a650}','\u{a650}'],
+	['\u{a652}','\u{a652}'],
+	['\u{a654}','\u{a654}'],
+	['\u{a656}','\u{a656}'],
+	['\u{a658}','\u{a658}'],
+	['\u{a65a}','\u{a65a}'],
+	['\u{a65c}','\u{a65c}'],
+	['\u{a65e}','\u{a65e}'],
+	['\u{a660}','\u{a660}'],
+	['\u{a662}','\u{a662}'],
+	['\u{a664}','\u{a664}'],
+	['\u{a666}','\u{a666}'],
+	['\u{a668}','\u{a668}'],
+	['\u{a66a}','\u{a66a}'],
+	['\u{a66c}','\u{a66c}'],
+	['\u{a680}','\u{a680}'],
+	['\u{a682}','\u{a682}'],
+	['\u{a684}','\u{a684}'],
+	['\u{a686}','\u{a686}'],
+	['\u{a688}','\u{a688}'],
+	['\u{a68a}','\u{a68a}'],
+	['\u{a68c}','\u{a68c}'],
+	['\u{a68e}','\u{a68e}'],
+	['\u{a690}','\u{a690}'],
+	['\u{a692}','\u{a692}'],
+	['\u{a694}','\u{a694}'],
+	['\u{a696}','\u{a696}'],
+	['\u{a722}','\u{a722}'],
+	['\u{a724}','\u{a724}'],
+	['\u{a726}','\u{a726}'],
+	['\u{a728}','\u{a728}'],
+	['\u{a72a}','\u{a72a}'],
+	['\u{a72c}','\u{a72c}'],
+	['\u{a72e}','\u{a72e}'],
+	['\u{a732}','\u{a732}'],
+	['\u{a734}','\u{a734}'],
+	['\u{a736}','\u{a736}'],
+	['\u{a738}','\u{a738}'],
+	['\u{a73a}','\u{a73a}'],
+	['\u{a73c}','\u{a73c}'],
+	['\u{a73e}','\u{a73e}'],
+	['\u{a740}','\u{a740}'],
+	['\u{a742}','\u{a742}'],
+	['\u{a744}','\u{a744}'],
+	['\u{a746}','\u{a746}'],
+	['\u{a748}','\u{a748}'],
+	['\u{a74a}','\u{a74a}'],
+	['\u{a74c}','\u{a74c}'],
+	['\u{a74e}','\u{a74e}'],
+	['\u{a750}','\u{a750}'],
+	['\u{a752}','\u{a752}'],
+	['\u{a754}','\u{a754}'],
+	['\u{a756}','\u{a756}'],
+	['\u{a758}','\u{a758}'],
+	['\u{a75a}','\u{a75a}'],
+	['\u{a75c}','\u{a75c}'],
+	['\u{a75e}','\u{a75e}'],
+	['\u{a760}','\u{a760}'],
+	['\u{a762}','\u{a762}'],
+	['\u{a764}','\u{a764}'],
+	['\u{a766}','\u{a766}'],
+	['\u{a768}','\u{a768}'],
+	['\u{a76a}','\u{a76a}'],
+	['\u{a76c}','\u{a76c}'],
+	['\u{a76e}','\u{a76e}'],
+	['\u{a779}','\u{a779}'],
+	['\u{a77b}','\u{a77b}'],
+	['\u{a77d}','\u{a77e}'],
+	['\u{a780}','\u{a780}'],
+	['\u{a782}','\u{a782}'],
+	['\u{a784}','\u{a784}'],
+	['\u{a786}','\u{a786}'],
+	['\u{a78b}','\u{a78b}'],
+	['\u{a78d}','\u{a78d}'],
+	['\u{a790}','\u{a790}'],
+	['\u{a792}','\u{a792}'],
+	['\u{a7a0}','\u{a7a0}'],
+	['\u{a7a2}','\u{a7a2}'],
+	['\u{a7a4}','\u{a7a4}'],
+	['\u{a7a6}','\u{a7a6}'],
+	['\u{a7a8}','\u{a7a8}'],
+	['\u{a7aa}','\u{a7aa}'],
+	['\u{ff21}','\u{ff3a}'],
+	['\u{10400}','\u{10427}'],
+	['\u{1d400}','\u{1d419}'],
+	['\u{1d434}','\u{1d44d}'],
+	['\u{1d468}','\u{1d481}'],
+	['\u{1d49c}','\u{1d49c}'],
+	['\u{1d49e}','\u{1d49f}'],
+	['\u{1d4a2}','\u{1d4a2}'],
+	['\u{1d4a5}','\u{1d4a6}'],
+	['\u{1d4a9}','\u{1d4ac}'],
+	['\u{1d4ae}','\u{1d4b5}'],
+	['\u{1d4d0}','\u{1d4e9}'],
+	['\u{1d504}','\u{1d505}'],
+	['\u{1d507}','\u{1d50a}'],
+	['\u{1d50d}','\u{1d514}'],
+	['\u{1d516}','\u{1d51c}'],
+	['\u{1d538}','\u{1d539}'],
+	['\u{1d53b}','\u{1d53e}'],
+	['\u{1d540}','\u{1d544}'],
+	['\u{1d546}','\u{1d546}'],
+	['\u{1d54a}','\u{1d550}'],
+	['\u{1d56c}','\u{1d585}'],
+	['\u{1d5a0}','\u{1d5b9}'],
+	['\u{1d5d4}','\u{1d5ed}'],
+	['\u{1d608}','\u{1d621}'],
+	['\u{1d63c}','\u{1d655}'],
+	['\u{1d670}','\u{1d689}'],
+	['\u{1d6a8}','\u{1d6c0}'],
+	['\u{1d6e2}','\u{1d6fa}'],
+	['\u{1d71c}','\u{1d734}'],
+	['\u{1d756}','\u{1d76e}'],
+	['\u{1d790}','\u{1d7a8}'],
+	['\u{1d7ca}','\u{1d7ca}'],
+]
+
+const tablower = [
+	['\u{61}','\u{7a}'],
+	['\u{b5}','\u{b5}'],
+	['\u{df}','\u{f6}'],
+	['\u{f8}','\u{ff}'],
+	['\u{101}','\u{101}'],
+	['\u{103}','\u{103}'],
+	['\u{105}','\u{105}'],
+	['\u{107}','\u{107}'],
+	['\u{109}','\u{109}'],
+	['\u{10b}','\u{10b}'],
+	['\u{10d}','\u{10d}'],
+	['\u{10f}','\u{10f}'],
+	['\u{111}','\u{111}'],
+	['\u{113}','\u{113}'],
+	['\u{115}','\u{115}'],
+	['\u{117}','\u{117}'],
+	['\u{119}','\u{119}'],
+	['\u{11b}','\u{11b}'],
+	['\u{11d}','\u{11d}'],
+	['\u{11f}','\u{11f}'],
+	['\u{121}','\u{121}'],
+	['\u{123}','\u{123}'],
+	['\u{125}','\u{125}'],
+	['\u{127}','\u{127}'],
+	['\u{129}','\u{129}'],
+	['\u{12b}','\u{12b}'],
+	['\u{12d}','\u{12d}'],
+	['\u{12f}','\u{12f}'],
+	['\u{131}','\u{131}'],
+	['\u{133}','\u{133}'],
+	['\u{135}','\u{135}'],
+	['\u{137}','\u{138}'],
+	['\u{13a}','\u{13a}'],
+	['\u{13c}','\u{13c}'],
+	['\u{13e}','\u{13e}'],
+	['\u{140}','\u{140}'],
+	['\u{142}','\u{142}'],
+	['\u{144}','\u{144}'],
+	['\u{146}','\u{146}'],
+	['\u{148}','\u{149}'],
+	['\u{14b}','\u{14b}'],
+	['\u{14d}','\u{14d}'],
+	['\u{14f}','\u{14f}'],
+	['\u{151}','\u{151}'],
+	['\u{153}','\u{153}'],
+	['\u{155}','\u{155}'],
+	['\u{157}','\u{157}'],
+	['\u{159}','\u{159}'],
+	['\u{15b}','\u{15b}'],
+	['\u{15d}','\u{15d}'],
+	['\u{15f}','\u{15f}'],
+	['\u{161}','\u{161}'],
+	['\u{163}','\u{163}'],
+	['\u{165}','\u{165}'],
+	['\u{167}','\u{167}'],
+	['\u{169}','\u{169}'],
+	['\u{16b}','\u{16b}'],
+	['\u{16d}','\u{16d}'],
+	['\u{16f}','\u{16f}'],
+	['\u{171}','\u{171}'],
+	['\u{173}','\u{173}'],
+	['\u{175}','\u{175}'],
+	['\u{177}','\u{177}'],
+	['\u{17a}','\u{17a}'],
+	['\u{17c}','\u{17c}'],
+	['\u{17e}','\u{180}'],
+	['\u{183}','\u{183}'],
+	['\u{185}','\u{185}'],
+	['\u{188}','\u{188}'],
+	['\u{18c}','\u{18d}'],
+	['\u{192}','\u{192}'],
+	['\u{195}','\u{195}'],
+	['\u{199}','\u{19b}'],
+	['\u{19e}','\u{19e}'],
+	['\u{1a1}','\u{1a1}'],
+	['\u{1a3}','\u{1a3}'],
+	['\u{1a5}','\u{1a5}'],
+	['\u{1a8}','\u{1a8}'],
+	['\u{1aa}','\u{1ab}'],
+	['\u{1ad}','\u{1ad}'],
+	['\u{1b0}','\u{1b0}'],
+	['\u{1b4}','\u{1b4}'],
+	['\u{1b6}','\u{1b6}'],
+	['\u{1b9}','\u{1ba}'],
+	['\u{1bd}','\u{1bf}'],
+	['\u{1c6}','\u{1c6}'],
+	['\u{1c9}','\u{1c9}'],
+	['\u{1cc}','\u{1cc}'],
+	['\u{1ce}','\u{1ce}'],
+	['\u{1d0}','\u{1d0}'],
+	['\u{1d2}','\u{1d2}'],
+	['\u{1d4}','\u{1d4}'],
+	['\u{1d6}','\u{1d6}'],
+	['\u{1d8}','\u{1d8}'],
+	['\u{1da}','\u{1da}'],
+	['\u{1dc}','\u{1dd}'],
+	['\u{1df}','\u{1df}'],
+	['\u{1e1}','\u{1e1}'],
+	['\u{1e3}','\u{1e3}'],
+	['\u{1e5}','\u{1e5}'],
+	['\u{1e7}','\u{1e7}'],
+	['\u{1e9}','\u{1e9}'],
+	['\u{1eb}','\u{1eb}'],
+	['\u{1ed}','\u{1ed}'],
+	['\u{1ef}','\u{1f0}'],
+	['\u{1f3}','\u{1f3}'],
+	['\u{1f5}','\u{1f5}'],
+	['\u{1f9}','\u{1f9}'],
+	['\u{1fb}','\u{1fb}'],
+	['\u{1fd}','\u{1fd}'],
+	['\u{1ff}','\u{1ff}'],
+	['\u{201}','\u{201}'],
+	['\u{203}','\u{203}'],
+	['\u{205}','\u{205}'],
+	['\u{207}','\u{207}'],
+	['\u{209}','\u{209}'],
+	['\u{20b}','\u{20b}'],
+	['\u{20d}','\u{20d}'],
+	['\u{20f}','\u{20f}'],
+	['\u{211}','\u{211}'],
+	['\u{213}','\u{213}'],
+	['\u{215}','\u{215}'],
+	['\u{217}','\u{217}'],
+	['\u{219}','\u{219}'],
+	['\u{21b}','\u{21b}'],
+	['\u{21d}','\u{21d}'],
+	['\u{21f}','\u{21f}'],
+	['\u{221}','\u{221}'],
+	['\u{223}','\u{223}'],
+	['\u{225}','\u{225}'],
+	['\u{227}','\u{227}'],
+	['\u{229}','\u{229}'],
+	['\u{22b}','\u{22b}'],
+	['\u{22d}','\u{22d}'],
+	['\u{22f}','\u{22f}'],
+	['\u{231}','\u{231}'],
+	['\u{233}','\u{239}'],
+	['\u{23c}','\u{23c}'],
+	['\u{23f}','\u{240}'],
+	['\u{242}','\u{242}'],
+	['\u{247}','\u{247}'],
+	['\u{249}','\u{249}'],
+	['\u{24b}','\u{24b}'],
+	['\u{24d}','\u{24d}'],
+	['\u{24f}','\u{293}'],
+	['\u{295}','\u{2af}'],
+	['\u{371}','\u{371}'],
+	['\u{373}','\u{373}'],
+	['\u{377}','\u{377}'],
+	['\u{37b}','\u{37d}'],
+	['\u{390}','\u{390}'],
+	['\u{3ac}','\u{3ce}'],
+	['\u{3d0}','\u{3d1}'],
+	['\u{3d5}','\u{3d7}'],
+	['\u{3d9}','\u{3d9}'],
+	['\u{3db}','\u{3db}'],
+	['\u{3dd}','\u{3dd}'],
+	['\u{3df}','\u{3df}'],
+	['\u{3e1}','\u{3e1}'],
+	['\u{3e3}','\u{3e3}'],
+	['\u{3e5}','\u{3e5}'],
+	['\u{3e7}','\u{3e7}'],
+	['\u{3e9}','\u{3e9}'],
+	['\u{3eb}','\u{3eb}'],
+	['\u{3ed}','\u{3ed}'],
+	['\u{3ef}','\u{3f3}'],
+	['\u{3f5}','\u{3f5}'],
+	['\u{3f8}','\u{3f8}'],
+	['\u{3fb}','\u{3fc}'],
+	['\u{430}','\u{45f}'],
+	['\u{461}','\u{461}'],
+	['\u{463}','\u{463}'],
+	['\u{465}','\u{465}'],
+	['\u{467}','\u{467}'],
+	['\u{469}','\u{469}'],
+	['\u{46b}','\u{46b}'],
+	['\u{46d}','\u{46d}'],
+	['\u{46f}','\u{46f}'],
+	['\u{471}','\u{471}'],
+	['\u{473}','\u{473}'],
+	['\u{475}','\u{475}'],
+	['\u{477}','\u{477}'],
+	['\u{479}','\u{479}'],
+	['\u{47b}','\u{47b}'],
+	['\u{47d}','\u{47d}'],
+	['\u{47f}','\u{47f}'],
+	['\u{481}','\u{481}'],
+	['\u{48b}','\u{48b}'],
+	['\u{48d}','\u{48d}'],
+	['\u{48f}','\u{48f}'],
+	['\u{491}','\u{491}'],
+	['\u{493}','\u{493}'],
+	['\u{495}','\u{495}'],
+	['\u{497}','\u{497}'],
+	['\u{499}','\u{499}'],
+	['\u{49b}','\u{49b}'],
+	['\u{49d}','\u{49d}'],
+	['\u{49f}','\u{49f}'],
+	['\u{4a1}','\u{4a1}'],
+	['\u{4a3}','\u{4a3}'],
+	['\u{4a5}','\u{4a5}'],
+	['\u{4a7}','\u{4a7}'],
+	['\u{4a9}','\u{4a9}'],
+	['\u{4ab}','\u{4ab}'],
+	['\u{4ad}','\u{4ad}'],
+	['\u{4af}','\u{4af}'],
+	['\u{4b1}','\u{4b1}'],
+	['\u{4b3}','\u{4b3}'],
+	['\u{4b5}','\u{4b5}'],
+	['\u{4b7}','\u{4b7}'],
+	['\u{4b9}','\u{4b9}'],
+	['\u{4bb}','\u{4bb}'],
+	['\u{4bd}','\u{4bd}'],
+	['\u{4bf}','\u{4bf}'],
+	['\u{4c2}','\u{4c2}'],
+	['\u{4c4}','\u{4c4}'],
+	['\u{4c6}','\u{4c6}'],
+	['\u{4c8}','\u{4c8}'],
+	['\u{4ca}','\u{4ca}'],
+	['\u{4cc}','\u{4cc}'],
+	['\u{4ce}','\u{4cf}'],
+	['\u{4d1}','\u{4d1}'],
+	['\u{4d3}','\u{4d3}'],
+	['\u{4d5}','\u{4d5}'],
+	['\u{4d7}','\u{4d7}'],
+	['\u{4d9}','\u{4d9}'],
+	['\u{4db}','\u{4db}'],
+	['\u{4dd}','\u{4dd}'],
+	['\u{4df}','\u{4df}'],
+	['\u{4e1}','\u{4e1}'],
+	['\u{4e3}','\u{4e3}'],
+	['\u{4e5}','\u{4e5}'],
+	['\u{4e7}','\u{4e7}'],
+	['\u{4e9}','\u{4e9}'],
+	['\u{4eb}','\u{4eb}'],
+	['\u{4ed}','\u{4ed}'],
+	['\u{4ef}','\u{4ef}'],
+	['\u{4f1}','\u{4f1}'],
+	['\u{4f3}','\u{4f3}'],
+	['\u{4f5}','\u{4f5}'],
+	['\u{4f7}','\u{4f7}'],
+	['\u{4f9}','\u{4f9}'],
+	['\u{4fb}','\u{4fb}'],
+	['\u{4fd}','\u{4fd}'],
+	['\u{4ff}','\u{4ff}'],
+	['\u{501}','\u{501}'],
+	['\u{503}','\u{503}'],
+	['\u{505}','\u{505}'],
+	['\u{507}','\u{507}'],
+	['\u{509}','\u{509}'],
+	['\u{50b}','\u{50b}'],
+	['\u{50d}','\u{50d}'],
+	['\u{50f}','\u{50f}'],
+	['\u{511}','\u{511}'],
+	['\u{513}','\u{513}'],
+	['\u{515}','\u{515}'],
+	['\u{517}','\u{517}'],
+	['\u{519}','\u{519}'],
+	['\u{51b}','\u{51b}'],
+	['\u{51d}','\u{51d}'],
+	['\u{51f}','\u{51f}'],
+	['\u{521}','\u{521}'],
+	['\u{523}','\u{523}'],
+	['\u{525}','\u{525}'],
+	['\u{527}','\u{527}'],
+	['\u{561}','\u{587}'],
+	['\u{1d00}','\u{1d2b}'],
+	['\u{1d6b}','\u{1d77}'],
+	['\u{1d79}','\u{1d9a}'],
+	['\u{1e01}','\u{1e01}'],
+	['\u{1e03}','\u{1e03}'],
+	['\u{1e05}','\u{1e05}'],
+	['\u{1e07}','\u{1e07}'],
+	['\u{1e09}','\u{1e09}'],
+	['\u{1e0b}','\u{1e0b}'],
+	['\u{1e0d}','\u{1e0d}'],
+	['\u{1e0f}','\u{1e0f}'],
+	['\u{1e11}','\u{1e11}'],
+	['\u{1e13}','\u{1e13}'],
+	['\u{1e15}','\u{1e15}'],
+	['\u{1e17}','\u{1e17}'],
+	['\u{1e19}','\u{1e19}'],
+	['\u{1e1b}','\u{1e1b}'],
+	['\u{1e1d}','\u{1e1d}'],
+	['\u{1e1f}','\u{1e1f}'],
+	['\u{1e21}','\u{1e21}'],
+	['\u{1e23}','\u{1e23}'],
+	['\u{1e25}','\u{1e25}'],
+	['\u{1e27}','\u{1e27}'],
+	['\u{1e29}','\u{1e29}'],
+	['\u{1e2b}','\u{1e2b}'],
+	['\u{1e2d}','\u{1e2d}'],
+	['\u{1e2f}','\u{1e2f}'],
+	['\u{1e31}','\u{1e31}'],
+	['\u{1e33}','\u{1e33}'],
+	['\u{1e35}','\u{1e35}'],
+	['\u{1e37}','\u{1e37}'],
+	['\u{1e39}','\u{1e39}'],
+	['\u{1e3b}','\u{1e3b}'],
+	['\u{1e3d}','\u{1e3d}'],
+	['\u{1e3f}','\u{1e3f}'],
+	['\u{1e41}','\u{1e41}'],
+	['\u{1e43}','\u{1e43}'],
+	['\u{1e45}','\u{1e45}'],
+	['\u{1e47}','\u{1e47}'],
+	['\u{1e49}','\u{1e49}'],
+	['\u{1e4b}','\u{1e4b}'],
+	['\u{1e4d}','\u{1e4d}'],
+	['\u{1e4f}','\u{1e4f}'],
+	['\u{1e51}','\u{1e51}'],
+	['\u{1e53}','\u{1e53}'],
+	['\u{1e55}','\u{1e55}'],
+	['\u{1e57}','\u{1e57}'],
+	['\u{1e59}','\u{1e59}'],
+	['\u{1e5b}','\u{1e5b}'],
+	['\u{1e5d}','\u{1e5d}'],
+	['\u{1e5f}','\u{1e5f}'],
+	['\u{1e61}','\u{1e61}'],
+	['\u{1e63}','\u{1e63}'],
+	['\u{1e65}','\u{1e65}'],
+	['\u{1e67}','\u{1e67}'],
+	['\u{1e69}','\u{1e69}'],
+	['\u{1e6b}','\u{1e6b}'],
+	['\u{1e6d}','\u{1e6d}'],
+	['\u{1e6f}','\u{1e6f}'],
+	['\u{1e71}','\u{1e71}'],
+	['\u{1e73}','\u{1e73}'],
+	['\u{1e75}','\u{1e75}'],
+	['\u{1e77}','\u{1e77}'],
+	['\u{1e79}','\u{1e79}'],
+	['\u{1e7b}','\u{1e7b}'],
+	['\u{1e7d}','\u{1e7d}'],
+	['\u{1e7f}','\u{1e7f}'],
+	['\u{1e81}','\u{1e81}'],
+	['\u{1e83}','\u{1e83}'],
+	['\u{1e85}','\u{1e85}'],
+	['\u{1e87}','\u{1e87}'],
+	['\u{1e89}','\u{1e89}'],
+	['\u{1e8b}','\u{1e8b}'],
+	['\u{1e8d}','\u{1e8d}'],
+	['\u{1e8f}','\u{1e8f}'],
+	['\u{1e91}','\u{1e91}'],
+	['\u{1e93}','\u{1e93}'],
+	['\u{1e95}','\u{1e9d}'],
+	['\u{1e9f}','\u{1e9f}'],
+	['\u{1ea1}','\u{1ea1}'],
+	['\u{1ea3}','\u{1ea3}'],
+	['\u{1ea5}','\u{1ea5}'],
+	['\u{1ea7}','\u{1ea7}'],
+	['\u{1ea9}','\u{1ea9}'],
+	['\u{1eab}','\u{1eab}'],
+	['\u{1ead}','\u{1ead}'],
+	['\u{1eaf}','\u{1eaf}'],
+	['\u{1eb1}','\u{1eb1}'],
+	['\u{1eb3}','\u{1eb3}'],
+	['\u{1eb5}','\u{1eb5}'],
+	['\u{1eb7}','\u{1eb7}'],
+	['\u{1eb9}','\u{1eb9}'],
+	['\u{1ebb}','\u{1ebb}'],
+	['\u{1ebd}','\u{1ebd}'],
+	['\u{1ebf}','\u{1ebf}'],
+	['\u{1ec1}','\u{1ec1}'],
+	['\u{1ec3}','\u{1ec3}'],
+	['\u{1ec5}','\u{1ec5}'],
+	['\u{1ec7}','\u{1ec7}'],
+	['\u{1ec9}','\u{1ec9}'],
+	['\u{1ecb}','\u{1ecb}'],
+	['\u{1ecd}','\u{1ecd}'],
+	['\u{1ecf}','\u{1ecf}'],
+	['\u{1ed1}','\u{1ed1}'],
+	['\u{1ed3}','\u{1ed3}'],
+	['\u{1ed5}','\u{1ed5}'],
+	['\u{1ed7}','\u{1ed7}'],
+	['\u{1ed9}','\u{1ed9}'],
+	['\u{1edb}','\u{1edb}'],
+	['\u{1edd}','\u{1edd}'],
+	['\u{1edf}','\u{1edf}'],
+	['\u{1ee1}','\u{1ee1}'],
+	['\u{1ee3}','\u{1ee3}'],
+	['\u{1ee5}','\u{1ee5}'],
+	['\u{1ee7}','\u{1ee7}'],
+	['\u{1ee9}','\u{1ee9}'],
+	['\u{1eeb}','\u{1eeb}'],
+	['\u{1eed}','\u{1eed}'],
+	['\u{1eef}','\u{1eef}'],
+	['\u{1ef1}','\u{1ef1}'],
+	['\u{1ef3}','\u{1ef3}'],
+	['\u{1ef5}','\u{1ef5}'],
+	['\u{1ef7}','\u{1ef7}'],
+	['\u{1ef9}','\u{1ef9}'],
+	['\u{1efb}','\u{1efb}'],
+	['\u{1efd}','\u{1efd}'],
+	['\u{1eff}','\u{1f07}'],
+	['\u{1f10}','\u{1f15}'],
+	['\u{1f20}','\u{1f27}'],
+	['\u{1f30}','\u{1f37}'],
+	['\u{1f40}','\u{1f45}'],
+	['\u{1f50}','\u{1f57}'],
+	['\u{1f60}','\u{1f67}'],
+	['\u{1f70}','\u{1f7d}'],
+	['\u{1f80}','\u{1f87}'],
+	['\u{1f90}','\u{1f97}'],
+	['\u{1fa0}','\u{1fa7}'],
+	['\u{1fb0}','\u{1fb4}'],
+	['\u{1fb6}','\u{1fb7}'],
+	['\u{1fbe}','\u{1fbe}'],
+	['\u{1fc2}','\u{1fc4}'],
+	['\u{1fc6}','\u{1fc7}'],
+	['\u{1fd0}','\u{1fd3}'],
+	['\u{1fd6}','\u{1fd7}'],
+	['\u{1fe0}','\u{1fe7}'],
+	['\u{1ff2}','\u{1ff4}'],
+	['\u{1ff6}','\u{1ff7}'],
+	['\u{210a}','\u{210a}'],
+	['\u{210e}','\u{210f}'],
+	['\u{2113}','\u{2113}'],
+	['\u{212f}','\u{212f}'],
+	['\u{2134}','\u{2134}'],
+	['\u{2139}','\u{2139}'],
+	['\u{213c}','\u{213d}'],
+	['\u{2146}','\u{2149}'],
+	['\u{214e}','\u{214e}'],
+	['\u{2184}','\u{2184}'],
+	['\u{2c30}','\u{2c5e}'],
+	['\u{2c61}','\u{2c61}'],
+	['\u{2c65}','\u{2c66}'],
+	['\u{2c68}','\u{2c68}'],
+	['\u{2c6a}','\u{2c6a}'],
+	['\u{2c6c}','\u{2c6c}'],
+	['\u{2c71}','\u{2c71}'],
+	['\u{2c73}','\u{2c74}'],
+	['\u{2c76}','\u{2c7b}'],
+	['\u{2c81}','\u{2c81}'],
+	['\u{2c83}','\u{2c83}'],
+	['\u{2c85}','\u{2c85}'],
+	['\u{2c87}','\u{2c87}'],
+	['\u{2c89}','\u{2c89}'],
+	['\u{2c8b}','\u{2c8b}'],
+	['\u{2c8d}','\u{2c8d}'],
+	['\u{2c8f}','\u{2c8f}'],
+	['\u{2c91}','\u{2c91}'],
+	['\u{2c93}','\u{2c93}'],
+	['\u{2c95}','\u{2c95}'],
+	['\u{2c97}','\u{2c97}'],
+	['\u{2c99}','\u{2c99}'],
+	['\u{2c9b}','\u{2c9b}'],
+	['\u{2c9d}','\u{2c9d}'],
+	['\u{2c9f}','\u{2c9f}'],
+	['\u{2ca1}','\u{2ca1}'],
+	['\u{2ca3}','\u{2ca3}'],
+	['\u{2ca5}','\u{2ca5}'],
+	['\u{2ca7}','\u{2ca7}'],
+	['\u{2ca9}','\u{2ca9}'],
+	['\u{2cab}','\u{2cab}'],
+	['\u{2cad}','\u{2cad}'],
+	['\u{2caf}','\u{2caf}'],
+	['\u{2cb1}','\u{2cb1}'],
+	['\u{2cb3}','\u{2cb3}'],
+	['\u{2cb5}','\u{2cb5}'],
+	['\u{2cb7}','\u{2cb7}'],
+	['\u{2cb9}','\u{2cb9}'],
+	['\u{2cbb}','\u{2cbb}'],
+	['\u{2cbd}','\u{2cbd}'],
+	['\u{2cbf}','\u{2cbf}'],
+	['\u{2cc1}','\u{2cc1}'],
+	['\u{2cc3}','\u{2cc3}'],
+	['\u{2cc5}','\u{2cc5}'],
+	['\u{2cc7}','\u{2cc7}'],
+	['\u{2cc9}','\u{2cc9}'],
+	['\u{2ccb}','\u{2ccb}'],
+	['\u{2ccd}','\u{2ccd}'],
+	['\u{2ccf}','\u{2ccf}'],
+	['\u{2cd1}','\u{2cd1}'],
+	['\u{2cd3}','\u{2cd3}'],
+	['\u{2cd5}','\u{2cd5}'],
+	['\u{2cd7}','\u{2cd7}'],
+	['\u{2cd9}','\u{2cd9}'],
+	['\u{2cdb}','\u{2cdb}'],
+	['\u{2cdd}','\u{2cdd}'],
+	['\u{2cdf}','\u{2cdf}'],
+	['\u{2ce1}','\u{2ce1}'],
+	['\u{2ce3}','\u{2ce4}'],
+	['\u{2cec}','\u{2cec}'],
+	['\u{2cee}','\u{2cee}'],
+	['\u{2cf3}','\u{2cf3}'],
+	['\u{2d00}','\u{2d25}'],
+	['\u{2d27}','\u{2d27}'],
+	['\u{2d2d}','\u{2d2d}'],
+	['\u{a641}','\u{a641}'],
+	['\u{a643}','\u{a643}'],
+	['\u{a645}','\u{a645}'],
+	['\u{a647}','\u{a647}'],
+	['\u{a649}','\u{a649}'],
+	['\u{a64b}','\u{a64b}'],
+	['\u{a64d}','\u{a64d}'],
+	['\u{a64f}','\u{a64f}'],
+	['\u{a651}','\u{a651}'],
+	['\u{a653}','\u{a653}'],
+	['\u{a655}','\u{a655}'],
+	['\u{a657}','\u{a657}'],
+	['\u{a659}','\u{a659}'],
+	['\u{a65b}','\u{a65b}'],
+	['\u{a65d}','\u{a65d}'],
+	['\u{a65f}','\u{a65f}'],
+	['\u{a661}','\u{a661}'],
+	['\u{a663}','\u{a663}'],
+	['\u{a665}','\u{a665}'],
+	['\u{a667}','\u{a667}'],
+	['\u{a669}','\u{a669}'],
+	['\u{a66b}','\u{a66b}'],
+	['\u{a66d}','\u{a66d}'],
+	['\u{a681}','\u{a681}'],
+	['\u{a683}','\u{a683}'],
+	['\u{a685}','\u{a685}'],
+	['\u{a687}','\u{a687}'],
+	['\u{a689}','\u{a689}'],
+	['\u{a68b}','\u{a68b}'],
+	['\u{a68d}','\u{a68d}'],
+	['\u{a68f}','\u{a68f}'],
+	['\u{a691}','\u{a691}'],
+	['\u{a693}','\u{a693}'],
+	['\u{a695}','\u{a695}'],
+	['\u{a697}','\u{a697}'],
+	['\u{a723}','\u{a723}'],
+	['\u{a725}','\u{a725}'],
+	['\u{a727}','\u{a727}'],
+	['\u{a729}','\u{a729}'],
+	['\u{a72b}','\u{a72b}'],
+	['\u{a72d}','\u{a72d}'],
+	['\u{a72f}','\u{a731}'],
+	['\u{a733}','\u{a733}'],
+	['\u{a735}','\u{a735}'],
+	['\u{a737}','\u{a737}'],
+	['\u{a739}','\u{a739}'],
+	['\u{a73b}','\u{a73b}'],
+	['\u{a73d}','\u{a73d}'],
+	['\u{a73f}','\u{a73f}'],
+	['\u{a741}','\u{a741}'],
+	['\u{a743}','\u{a743}'],
+	['\u{a745}','\u{a745}'],
+	['\u{a747}','\u{a747}'],
+	['\u{a749}','\u{a749}'],
+	['\u{a74b}','\u{a74b}'],
+	['\u{a74d}','\u{a74d}'],
+	['\u{a74f}','\u{a74f}'],
+	['\u{a751}','\u{a751}'],
+	['\u{a753}','\u{a753}'],
+	['\u{a755}','\u{a755}'],
+	['\u{a757}','\u{a757}'],
+	['\u{a759}','\u{a759}'],
+	['\u{a75b}','\u{a75b}'],
+	['\u{a75d}','\u{a75d}'],
+	['\u{a75f}','\u{a75f}'],
+	['\u{a761}','\u{a761}'],
+	['\u{a763}','\u{a763}'],
+	['\u{a765}','\u{a765}'],
+	['\u{a767}','\u{a767}'],
+	['\u{a769}','\u{a769}'],
+	['\u{a76b}','\u{a76b}'],
+	['\u{a76d}','\u{a76d}'],
+	['\u{a76f}','\u{a76f}'],
+	['\u{a771}','\u{a778}'],
+	['\u{a77a}','\u{a77a}'],
+	['\u{a77c}','\u{a77c}'],
+	['\u{a77f}','\u{a77f}'],
+	['\u{a781}','\u{a781}'],
+	['\u{a783}','\u{a783}'],
+	['\u{a785}','\u{a785}'],
+	['\u{a787}','\u{a787}'],
+	['\u{a78c}','\u{a78c}'],
+	['\u{a78e}','\u{a78e}'],
+	['\u{a791}','\u{a791}'],
+	['\u{a793}','\u{a793}'],
+	['\u{a7a1}','\u{a7a1}'],
+	['\u{a7a3}','\u{a7a3}'],
+	['\u{a7a5}','\u{a7a5}'],
+	['\u{a7a7}','\u{a7a7}'],
+	['\u{a7a9}','\u{a7a9}'],
+	['\u{a7fa}','\u{a7fa}'],
+	['\u{fb00}','\u{fb06}'],
+	['\u{fb13}','\u{fb17}'],
+	['\u{ff41}','\u{ff5a}'],
+	['\u{10428}','\u{1044f}'],
+	['\u{1d41a}','\u{1d433}'],
+	['\u{1d44e}','\u{1d454}'],
+	['\u{1d456}','\u{1d467}'],
+	['\u{1d482}','\u{1d49b}'],
+	['\u{1d4b6}','\u{1d4b9}'],
+	['\u{1d4bb}','\u{1d4bb}'],
+	['\u{1d4bd}','\u{1d4c3}'],
+	['\u{1d4c5}','\u{1d4cf}'],
+	['\u{1d4ea}','\u{1d503}'],
+	['\u{1d51e}','\u{1d537}'],
+	['\u{1d552}','\u{1d56b}'],
+	['\u{1d586}','\u{1d59f}'],
+	['\u{1d5ba}','\u{1d5d3}'],
+	['\u{1d5ee}','\u{1d607}'],
+	['\u{1d622}','\u{1d63b}'],
+	['\u{1d656}','\u{1d66f}'],
+	['\u{1d68a}','\u{1d6a5}'],
+	['\u{1d6c2}','\u{1d6da}'],
+	['\u{1d6dc}','\u{1d6e1}'],
+	['\u{1d6fc}','\u{1d714}'],
+	['\u{1d716}','\u{1d71b}'],
+	['\u{1d736}','\u{1d74e}'],
+	['\u{1d750}','\u{1d755}'],
+	['\u{1d770}','\u{1d788}'],
+	['\u{1d78a}','\u{1d78f}'],
+	['\u{1d7aa}','\u{1d7c2}'],
+	['\u{1d7c4}','\u{1d7c9}'],
+	['\u{1d7cb}','\u{1d7cb}'],
+]
+
+const tabtitle = [
+	['\u{1c5}','\u{1c5}'],
+	['\u{1c8}','\u{1c8}'],
+	['\u{1cb}','\u{1cb}'],
+	['\u{1f2}','\u{1f2}'],
+	['\u{1f88}','\u{1f8f}'],
+	['\u{1f98}','\u{1f9f}'],
+	['\u{1fa8}','\u{1faf}'],
+	['\u{1fbc}','\u{1fbc}'],
+	['\u{1fcc}','\u{1fcc}'],
+	['\u{1ffc}','\u{1ffc}'],
+]
+
+const tabword = [
+	['\u{30}','\u{39}'],
+	['\u{41}','\u{5a}'],
+	['\u{5f}','\u{5f}'],
+	['\u{61}','\u{7a}'],
+	['\u{aa}','\u{aa}'],
+	['\u{b5}','\u{b5}'],
+	['\u{ba}','\u{ba}'],
+	['\u{c0}','\u{d6}'],
+	['\u{d8}','\u{f6}'],
+	['\u{f8}','\u{2c1}'],
+	['\u{2c6}','\u{2d1}'],
+	['\u{2e0}','\u{2e4}'],
+	['\u{2ec}','\u{2ec}'],
+	['\u{2ee}','\u{2ee}'],
+	['\u{370}','\u{374}'],
+	['\u{376}','\u{377}'],
+	['\u{37a}','\u{37d}'],
+	['\u{386}','\u{386}'],
+	['\u{388}','\u{38a}'],
+	['\u{38c}','\u{38c}'],
+	['\u{38e}','\u{3a1}'],
+	['\u{3a3}','\u{3f5}'],
+	['\u{3f7}','\u{481}'],
+	['\u{48a}','\u{527}'],
+	['\u{531}','\u{556}'],
+	['\u{559}','\u{559}'],
+	['\u{561}','\u{587}'],
+	['\u{5d0}','\u{5ea}'],
+	['\u{5f0}','\u{5f2}'],
+	['\u{620}','\u{64a}'],
+	['\u{660}','\u{669}'],
+	['\u{66e}','\u{66f}'],
+	['\u{671}','\u{6d3}'],
+	['\u{6d5}','\u{6d5}'],
+	['\u{6e5}','\u{6e6}'],
+	['\u{6ee}','\u{6fc}'],
+	['\u{6ff}','\u{6ff}'],
+	['\u{710}','\u{710}'],
+	['\u{712}','\u{72f}'],
+	['\u{74d}','\u{7a5}'],
+	['\u{7b1}','\u{7b1}'],
+	['\u{7c0}','\u{7ea}'],
+	['\u{7f4}','\u{7f5}'],
+	['\u{7fa}','\u{7fa}'],
+	['\u{800}','\u{815}'],
+	['\u{81a}','\u{81a}'],
+	['\u{824}','\u{824}'],
+	['\u{828}','\u{828}'],
+	['\u{840}','\u{858}'],
+	['\u{8a0}','\u{8a0}'],
+	['\u{8a2}','\u{8ac}'],
+	['\u{904}','\u{939}'],
+	['\u{93d}','\u{93d}'],
+	['\u{950}','\u{950}'],
+	['\u{958}','\u{961}'],
+	['\u{966}','\u{96f}'],
+	['\u{971}','\u{977}'],
+	['\u{979}','\u{97f}'],
+	['\u{985}','\u{98c}'],
+	['\u{98f}','\u{990}'],
+	['\u{993}','\u{9a8}'],
+	['\u{9aa}','\u{9b0}'],
+	['\u{9b2}','\u{9b2}'],
+	['\u{9b6}','\u{9b9}'],
+	['\u{9bd}','\u{9bd}'],
+	['\u{9ce}','\u{9ce}'],
+	['\u{9dc}','\u{9dd}'],
+	['\u{9df}','\u{9e1}'],
+	['\u{9e6}','\u{9f1}'],
+	['\u{a05}','\u{a0a}'],
+	['\u{a0f}','\u{a10}'],
+	['\u{a13}','\u{a28}'],
+	['\u{a2a}','\u{a30}'],
+	['\u{a32}','\u{a33}'],
+	['\u{a35}','\u{a36}'],
+	['\u{a38}','\u{a39}'],
+	['\u{a59}','\u{a5c}'],
+	['\u{a5e}','\u{a5e}'],
+	['\u{a66}','\u{a6f}'],
+	['\u{a72}','\u{a74}'],
+	['\u{a85}','\u{a8d}'],
+	['\u{a8f}','\u{a91}'],
+	['\u{a93}','\u{aa8}'],
+	['\u{aaa}','\u{ab0}'],
+	['\u{ab2}','\u{ab3}'],
+	['\u{ab5}','\u{ab9}'],
+	['\u{abd}','\u{abd}'],
+	['\u{ad0}','\u{ad0}'],
+	['\u{ae0}','\u{ae1}'],
+	['\u{ae6}','\u{aef}'],
+	['\u{b05}','\u{b0c}'],
+	['\u{b0f}','\u{b10}'],
+	['\u{b13}','\u{b28}'],
+	['\u{b2a}','\u{b30}'],
+	['\u{b32}','\u{b33}'],
+	['\u{b35}','\u{b39}'],
+	['\u{b3d}','\u{b3d}'],
+	['\u{b5c}','\u{b5d}'],
+	['\u{b5f}','\u{b61}'],
+	['\u{b66}','\u{b6f}'],
+	['\u{b71}','\u{b71}'],
+	['\u{b83}','\u{b83}'],
+	['\u{b85}','\u{b8a}'],
+	['\u{b8e}','\u{b90}'],
+	['\u{b92}','\u{b95}'],
+	['\u{b99}','\u{b9a}'],
+	['\u{b9c}','\u{b9c}'],
+	['\u{b9e}','\u{b9f}'],
+	['\u{ba3}','\u{ba4}'],
+	['\u{ba8}','\u{baa}'],
+	['\u{bae}','\u{bb9}'],
+	['\u{bd0}','\u{bd0}'],
+	['\u{be6}','\u{bef}'],
+	['\u{c05}','\u{c0c}'],
+	['\u{c0e}','\u{c10}'],
+	['\u{c12}','\u{c28}'],
+	['\u{c2a}','\u{c33}'],
+	['\u{c35}','\u{c39}'],
+	['\u{c3d}','\u{c3d}'],
+	['\u{c58}','\u{c59}'],
+	['\u{c60}','\u{c61}'],
+	['\u{c66}','\u{c6f}'],
+	['\u{c85}','\u{c8c}'],
+	['\u{c8e}','\u{c90}'],
+	['\u{c92}','\u{ca8}'],
+	['\u{caa}','\u{cb3}'],
+	['\u{cb5}','\u{cb9}'],
+	['\u{cbd}','\u{cbd}'],
+	['\u{cde}','\u{cde}'],
+	['\u{ce0}','\u{ce1}'],
+	['\u{ce6}','\u{cef}'],
+	['\u{cf1}','\u{cf2}'],
+	['\u{d05}','\u{d0c}'],
+	['\u{d0e}','\u{d10}'],
+	['\u{d12}','\u{d3a}'],
+	['\u{d3d}','\u{d3d}'],
+	['\u{d4e}','\u{d4e}'],
+	['\u{d60}','\u{d61}'],
+	['\u{d66}','\u{d6f}'],
+	['\u{d7a}','\u{d7f}'],
+	['\u{d85}','\u{d96}'],
+	['\u{d9a}','\u{db1}'],
+	['\u{db3}','\u{dbb}'],
+	['\u{dbd}','\u{dbd}'],
+	['\u{dc0}','\u{dc6}'],
+	['\u{e01}','\u{e30}'],
+	['\u{e32}','\u{e33}'],
+	['\u{e40}','\u{e46}'],
+	['\u{e50}','\u{e59}'],
+	['\u{e81}','\u{e82}'],
+	['\u{e84}','\u{e84}'],
+	['\u{e87}','\u{e88}'],
+	['\u{e8a}','\u{e8a}'],
+	['\u{e8d}','\u{e8d}'],
+	['\u{e94}','\u{e97}'],
+	['\u{e99}','\u{e9f}'],
+	['\u{ea1}','\u{ea3}'],
+	['\u{ea5}','\u{ea5}'],
+	['\u{ea7}','\u{ea7}'],
+	['\u{eaa}','\u{eab}'],
+	['\u{ead}','\u{eb0}'],
+	['\u{eb2}','\u{eb3}'],
+	['\u{ebd}','\u{ebd}'],
+	['\u{ec0}','\u{ec4}'],
+	['\u{ec6}','\u{ec6}'],
+	['\u{ed0}','\u{ed9}'],
+	['\u{edc}','\u{edf}'],
+	['\u{f00}','\u{f00}'],
+	['\u{f20}','\u{f29}'],
+	['\u{f40}','\u{f47}'],
+	['\u{f49}','\u{f6c}'],
+	['\u{f88}','\u{f8c}'],
+	['\u{1000}','\u{102a}'],
+	['\u{103f}','\u{1049}'],
+	['\u{1050}','\u{1055}'],
+	['\u{105a}','\u{105d}'],
+	['\u{1061}','\u{1061}'],
+	['\u{1065}','\u{1066}'],
+	['\u{106e}','\u{1070}'],
+	['\u{1075}','\u{1081}'],
+	['\u{108e}','\u{108e}'],
+	['\u{1090}','\u{1099}'],
+	['\u{10a0}','\u{10c5}'],
+	['\u{10c7}','\u{10c7}'],
+	['\u{10cd}','\u{10cd}'],
+	['\u{10d0}','\u{10fa}'],
+	['\u{10fc}','\u{1248}'],
+	['\u{124a}','\u{124d}'],
+	['\u{1250}','\u{1256}'],
+	['\u{1258}','\u{1258}'],
+	['\u{125a}','\u{125d}'],
+	['\u{1260}','\u{1288}'],
+	['\u{128a}','\u{128d}'],
+	['\u{1290}','\u{12b0}'],
+	['\u{12b2}','\u{12b5}'],
+	['\u{12b8}','\u{12be}'],
+	['\u{12c0}','\u{12c0}'],
+	['\u{12c2}','\u{12c5}'],
+	['\u{12c8}','\u{12d6}'],
+	['\u{12d8}','\u{1310}'],
+	['\u{1312}','\u{1315}'],
+	['\u{1318}','\u{135a}'],
+	['\u{1380}','\u{138f}'],
+	['\u{13a0}','\u{13f4}'],
+	['\u{1401}','\u{166c}'],
+	['\u{166f}','\u{167f}'],
+	['\u{1681}','\u{169a}'],
+	['\u{16a0}','\u{16ea}'],
+	['\u{1700}','\u{170c}'],
+	['\u{170e}','\u{1711}'],
+	['\u{1720}','\u{1731}'],
+	['\u{1740}','\u{1751}'],
+	['\u{1760}','\u{176c}'],
+	['\u{176e}','\u{1770}'],
+	['\u{1780}','\u{17b3}'],
+	['\u{17d7}','\u{17d7}'],
+	['\u{17dc}','\u{17dc}'],
+	['\u{17e0}','\u{17e9}'],
+	['\u{1810}','\u{1819}'],
+	['\u{1820}','\u{1877}'],
+	['\u{1880}','\u{18a8}'],
+	['\u{18aa}','\u{18aa}'],
+	['\u{18b0}','\u{18f5}'],
+	['\u{1900}','\u{191c}'],
+	['\u{1946}','\u{196d}'],
+	['\u{1970}','\u{1974}'],
+	['\u{1980}','\u{19ab}'],
+	['\u{19c1}','\u{19c7}'],
+	['\u{19d0}','\u{19d9}'],
+	['\u{1a00}','\u{1a16}'],
+	['\u{1a20}','\u{1a54}'],
+	['\u{1a80}','\u{1a89}'],
+	['\u{1a90}','\u{1a99}'],
+	['\u{1aa7}','\u{1aa7}'],
+	['\u{1b05}','\u{1b33}'],
+	['\u{1b45}','\u{1b4b}'],
+	['\u{1b50}','\u{1b59}'],
+	['\u{1b83}','\u{1ba0}'],
+	['\u{1bae}','\u{1be5}'],
+	['\u{1c00}','\u{1c23}'],
+	['\u{1c40}','\u{1c49}'],
+	['\u{1c4d}','\u{1c7d}'],
+	['\u{1ce9}','\u{1cec}'],
+	['\u{1cee}','\u{1cf1}'],
+	['\u{1cf5}','\u{1cf6}'],
+	['\u{1d00}','\u{1dbf}'],
+	['\u{1e00}','\u{1f15}'],
+	['\u{1f18}','\u{1f1d}'],
+	['\u{1f20}','\u{1f45}'],
+	['\u{1f48}','\u{1f4d}'],
+	['\u{1f50}','\u{1f57}'],
+	['\u{1f59}','\u{1f59}'],
+	['\u{1f5b}','\u{1f5b}'],
+	['\u{1f5d}','\u{1f5d}'],
+	['\u{1f5f}','\u{1f7d}'],
+	['\u{1f80}','\u{1fb4}'],
+	['\u{1fb6}','\u{1fbc}'],
+	['\u{1fbe}','\u{1fbe}'],
+	['\u{1fc2}','\u{1fc4}'],
+	['\u{1fc6}','\u{1fcc}'],
+	['\u{1fd0}','\u{1fd3}'],
+	['\u{1fd6}','\u{1fdb}'],
+	['\u{1fe0}','\u{1fec}'],
+	['\u{1ff2}','\u{1ff4}'],
+	['\u{1ff6}','\u{1ffc}'],
+	['\u{2071}','\u{2071}'],
+	['\u{207f}','\u{207f}'],
+	['\u{2090}','\u{209c}'],
+	['\u{2102}','\u{2102}'],
+	['\u{2107}','\u{2107}'],
+	['\u{210a}','\u{2113}'],
+	['\u{2115}','\u{2115}'],
+	['\u{2119}','\u{211d}'],
+	['\u{2124}','\u{2124}'],
+	['\u{2126}','\u{2126}'],
+	['\u{2128}','\u{2128}'],
+	['\u{212a}','\u{212d}'],
+	['\u{212f}','\u{2139}'],
+	['\u{213c}','\u{213f}'],
+	['\u{2145}','\u{2149}'],
+	['\u{214e}','\u{214e}'],
+	['\u{2183}','\u{2184}'],
+	['\u{2c00}','\u{2c2e}'],
+	['\u{2c30}','\u{2c5e}'],
+	['\u{2c60}','\u{2ce4}'],
+	['\u{2ceb}','\u{2cee}'],
+	['\u{2cf2}','\u{2cf3}'],
+	['\u{2d00}','\u{2d25}'],
+	['\u{2d27}','\u{2d27}'],
+	['\u{2d2d}','\u{2d2d}'],
+	['\u{2d30}','\u{2d67}'],
+	['\u{2d6f}','\u{2d6f}'],
+	['\u{2d80}','\u{2d96}'],
+	['\u{2da0}','\u{2da6}'],
+	['\u{2da8}','\u{2dae}'],
+	['\u{2db0}','\u{2db6}'],
+	['\u{2db8}','\u{2dbe}'],
+	['\u{2dc0}','\u{2dc6}'],
+	['\u{2dc8}','\u{2dce}'],
+	['\u{2dd0}','\u{2dd6}'],
+	['\u{2dd8}','\u{2dde}'],
+	['\u{2e2f}','\u{2e2f}'],
+	['\u{3005}','\u{3006}'],
+	['\u{3031}','\u{3035}'],
+	['\u{303b}','\u{303c}'],
+	['\u{3041}','\u{3096}'],
+	['\u{309d}','\u{309f}'],
+	['\u{30a1}','\u{30fa}'],
+	['\u{30fc}','\u{30ff}'],
+	['\u{3105}','\u{312d}'],
+	['\u{3131}','\u{318e}'],
+	['\u{31a0}','\u{31ba}'],
+	['\u{31f0}','\u{31ff}'],
+	['\u{3400}','\u{4db5}'],
+	['\u{4e00}','\u{9fcc}'],
+	['\u{a000}','\u{a48c}'],
+	['\u{a4d0}','\u{a4fd}'],
+	['\u{a500}','\u{a60c}'],
+	['\u{a610}','\u{a62b}'],
+	['\u{a640}','\u{a66e}'],
+	['\u{a67f}','\u{a697}'],
+	['\u{a6a0}','\u{a6e5}'],
+	['\u{a717}','\u{a71f}'],
+	['\u{a722}','\u{a788}'],
+	['\u{a78b}','\u{a78e}'],
+	['\u{a790}','\u{a793}'],
+	['\u{a7a0}','\u{a7aa}'],
+	['\u{a7f8}','\u{a801}'],
+	['\u{a803}','\u{a805}'],
+	['\u{a807}','\u{a80a}'],
+	['\u{a80c}','\u{a822}'],
+	['\u{a840}','\u{a873}'],
+	['\u{a882}','\u{a8b3}'],
+	['\u{a8d0}','\u{a8d9}'],
+	['\u{a8f2}','\u{a8f7}'],
+	['\u{a8fb}','\u{a8fb}'],
+	['\u{a900}','\u{a925}'],
+	['\u{a930}','\u{a946}'],
+	['\u{a960}','\u{a97c}'],
+	['\u{a984}','\u{a9b2}'],
+	['\u{a9cf}','\u{a9d9}'],
+	['\u{aa00}','\u{aa28}'],
+	['\u{aa40}','\u{aa42}'],
+	['\u{aa44}','\u{aa4b}'],
+	['\u{aa50}','\u{aa59}'],
+	['\u{aa60}','\u{aa76}'],
+	['\u{aa7a}','\u{aa7a}'],
+	['\u{aa80}','\u{aaaf}'],
+	['\u{aab1}','\u{aab1}'],
+	['\u{aab5}','\u{aab6}'],
+	['\u{aab9}','\u{aabd}'],
+	['\u{aac0}','\u{aac0}'],
+	['\u{aac2}','\u{aac2}'],
+	['\u{aadb}','\u{aadd}'],
+	['\u{aae0}','\u{aaea}'],
+	['\u{aaf2}','\u{aaf4}'],
+	['\u{ab01}','\u{ab06}'],
+	['\u{ab09}','\u{ab0e}'],
+	['\u{ab11}','\u{ab16}'],
+	['\u{ab20}','\u{ab26}'],
+	['\u{ab28}','\u{ab2e}'],
+	['\u{abc0}','\u{abe2}'],
+	['\u{abf0}','\u{abf9}'],
+	['\u{ac00}','\u{d7a3}'],
+	['\u{d7b0}','\u{d7c6}'],
+	['\u{d7cb}','\u{d7fb}'],
+	['\u{f900}','\u{fa6d}'],
+	['\u{fa70}','\u{fad9}'],
+	['\u{fb00}','\u{fb06}'],
+	['\u{fb13}','\u{fb17}'],
+	['\u{fb1d}','\u{fb1d}'],
+	['\u{fb1f}','\u{fb28}'],
+	['\u{fb2a}','\u{fb36}'],
+	['\u{fb38}','\u{fb3c}'],
+	['\u{fb3e}','\u{fb3e}'],
+	['\u{fb40}','\u{fb41}'],
+	['\u{fb43}','\u{fb44}'],
+	['\u{fb46}','\u{fbb1}'],
+	['\u{fbd3}','\u{fd3d}'],
+	['\u{fd50}','\u{fd8f}'],
+	['\u{fd92}','\u{fdc7}'],
+	['\u{fdf0}','\u{fdfb}'],
+	['\u{fe70}','\u{fe74}'],
+	['\u{fe76}','\u{fefc}'],
+	['\u{ff10}','\u{ff19}'],
+	['\u{ff21}','\u{ff3a}'],
+	['\u{ff41}','\u{ff5a}'],
+	['\u{ff66}','\u{ffbe}'],
+	['\u{ffc2}','\u{ffc7}'],
+	['\u{ffca}','\u{ffcf}'],
+	['\u{ffd2}','\u{ffd7}'],
+	['\u{ffda}','\u{ffdc}'],
+	['\u{10000}','\u{1000b}'],
+	['\u{1000d}','\u{10026}'],
+	['\u{10028}','\u{1003a}'],
+	['\u{1003c}','\u{1003d}'],
+	['\u{1003f}','\u{1004d}'],
+	['\u{10050}','\u{1005d}'],
+	['\u{10080}','\u{100fa}'],
+	['\u{10280}','\u{1029c}'],
+	['\u{102a0}','\u{102d0}'],
+	['\u{10300}','\u{1031e}'],
+	['\u{10330}','\u{10340}'],
+	['\u{10342}','\u{10349}'],
+	['\u{10380}','\u{1039d}'],
+	['\u{103a0}','\u{103c3}'],
+	['\u{103c8}','\u{103cf}'],
+	['\u{10400}','\u{1049d}'],
+	['\u{104a0}','\u{104a9}'],
+	['\u{10800}','\u{10805}'],
+	['\u{10808}','\u{10808}'],
+	['\u{1080a}','\u{10835}'],
+	['\u{10837}','\u{10838}'],
+	['\u{1083c}','\u{1083c}'],
+	['\u{1083f}','\u{10855}'],
+	['\u{10900}','\u{10915}'],
+	['\u{10920}','\u{10939}'],
+	['\u{10980}','\u{109b7}'],
+	['\u{109be}','\u{109bf}'],
+	['\u{10a00}','\u{10a00}'],
+	['\u{10a10}','\u{10a13}'],
+	['\u{10a15}','\u{10a17}'],
+	['\u{10a19}','\u{10a33}'],
+	['\u{10a60}','\u{10a7c}'],
+	['\u{10b00}','\u{10b35}'],
+	['\u{10b40}','\u{10b55}'],
+	['\u{10b60}','\u{10b72}'],
+	['\u{10c00}','\u{10c48}'],
+	['\u{11003}','\u{11037}'],
+	['\u{11066}','\u{1106f}'],
+	['\u{11083}','\u{110af}'],
+	['\u{110d0}','\u{110e8}'],
+	['\u{110f0}','\u{110f9}'],
+	['\u{11103}','\u{11126}'],
+	['\u{11136}','\u{1113f}'],
+	['\u{11183}','\u{111b2}'],
+	['\u{111c1}','\u{111c4}'],
+	['\u{111d0}','\u{111d9}'],
+	['\u{11680}','\u{116aa}'],
+	['\u{116c0}','\u{116c9}'],
+	['\u{12000}','\u{1236e}'],
+	['\u{13000}','\u{1342e}'],
+	['\u{16800}','\u{16a38}'],
+	['\u{16f00}','\u{16f44}'],
+	['\u{16f50}','\u{16f50}'],
+	['\u{16f93}','\u{16f9f}'],
+	['\u{1b000}','\u{1b001}'],
+	['\u{1d400}','\u{1d454}'],
+	['\u{1d456}','\u{1d49c}'],
+	['\u{1d49e}','\u{1d49f}'],
+	['\u{1d4a2}','\u{1d4a2}'],
+	['\u{1d4a5}','\u{1d4a6}'],
+	['\u{1d4a9}','\u{1d4ac}'],
+	['\u{1d4ae}','\u{1d4b9}'],
+	['\u{1d4bb}','\u{1d4bb}'],
+	['\u{1d4bd}','\u{1d4c3}'],
+	['\u{1d4c5}','\u{1d505}'],
+	['\u{1d507}','\u{1d50a}'],
+	['\u{1d50d}','\u{1d514}'],
+	['\u{1d516}','\u{1d51c}'],
+	['\u{1d51e}','\u{1d539}'],
+	['\u{1d53b}','\u{1d53e}'],
+	['\u{1d540}','\u{1d544}'],
+	['\u{1d546}','\u{1d546}'],
+	['\u{1d54a}','\u{1d550}'],
+	['\u{1d552}','\u{1d6a5}'],
+	['\u{1d6a8}','\u{1d6c0}'],
+	['\u{1d6c2}','\u{1d6da}'],
+	['\u{1d6dc}','\u{1d6fa}'],
+	['\u{1d6fc}','\u{1d714}'],
+	['\u{1d716}','\u{1d734}'],
+	['\u{1d736}','\u{1d74e}'],
+	['\u{1d750}','\u{1d76e}'],
+	['\u{1d770}','\u{1d788}'],
+	['\u{1d78a}','\u{1d7a8}'],
+	['\u{1d7aa}','\u{1d7c2}'],
+	['\u{1d7c4}','\u{1d7cb}'],
+	['\u{1d7ce}','\u{1d7ff}'],
+	['\u{1ee00}','\u{1ee03}'],
+	['\u{1ee05}','\u{1ee1f}'],
+	['\u{1ee21}','\u{1ee22}'],
+	['\u{1ee24}','\u{1ee24}'],
+	['\u{1ee27}','\u{1ee27}'],
+	['\u{1ee29}','\u{1ee32}'],
+	['\u{1ee34}','\u{1ee37}'],
+	['\u{1ee39}','\u{1ee39}'],
+	['\u{1ee3b}','\u{1ee3b}'],
+	['\u{1ee42}','\u{1ee42}'],
+	['\u{1ee47}','\u{1ee47}'],
+	['\u{1ee49}','\u{1ee49}'],
+	['\u{1ee4b}','\u{1ee4b}'],
+	['\u{1ee4d}','\u{1ee4f}'],
+	['\u{1ee51}','\u{1ee52}'],
+	['\u{1ee54}','\u{1ee54}'],
+	['\u{1ee57}','\u{1ee57}'],
+	['\u{1ee59}','\u{1ee59}'],
+	['\u{1ee5b}','\u{1ee5b}'],
+	['\u{1ee5d}','\u{1ee5d}'],
+	['\u{1ee5f}','\u{1ee5f}'],
+	['\u{1ee61}','\u{1ee62}'],
+	['\u{1ee64}','\u{1ee64}'],
+	['\u{1ee67}','\u{1ee6a}'],
+	['\u{1ee6c}','\u{1ee72}'],
+	['\u{1ee74}','\u{1ee77}'],
+	['\u{1ee79}','\u{1ee7c}'],
+	['\u{1ee7e}','\u{1ee7e}'],
+	['\u{1ee80}','\u{1ee89}'],
+	['\u{1ee8b}','\u{1ee9b}'],
+	['\u{1eea1}','\u{1eea3}'],
+	['\u{1eea5}','\u{1eea9}'],
+	['\u{1eeab}','\u{1eebb}'],
+	['\u{20000}','\u{2a6d6}'],
+	['\u{2a700}','\u{2b734}'],
+	['\u{2b740}','\u{2b81d}'],
+	['\u{2f800}','\u{2fa1d}'],
+]
+
+const tabdigit = [
+	['\u{30}','\u{39}'],
+	['\u{660}','\u{669}'],
+	['\u{6f0}','\u{6f9}'],
+	['\u{7c0}','\u{7c9}'],
+	['\u{966}','\u{96f}'],
+	['\u{9e6}','\u{9ef}'],
+	['\u{a66}','\u{a6f}'],
+	['\u{ae6}','\u{aef}'],
+	['\u{b66}','\u{b6f}'],
+	['\u{be6}','\u{bef}'],
+	['\u{c66}','\u{c6f}'],
+	['\u{ce6}','\u{cef}'],
+	['\u{d66}','\u{d6f}'],
+	['\u{e50}','\u{e59}'],
+	['\u{ed0}','\u{ed9}'],
+	['\u{f20}','\u{f29}'],
+	['\u{1040}','\u{1049}'],
+	['\u{1090}','\u{1099}'],
+	['\u{17e0}','\u{17e9}'],
+	['\u{1810}','\u{1819}'],
+	['\u{1946}','\u{194f}'],
+	['\u{19d0}','\u{19d9}'],
+	['\u{1a80}','\u{1a89}'],
+	['\u{1a90}','\u{1a99}'],
+	['\u{1b50}','\u{1b59}'],
+	['\u{1bb0}','\u{1bb9}'],
+	['\u{1c40}','\u{1c49}'],
+	['\u{1c50}','\u{1c59}'],
+	['\u{a620}','\u{a629}'],
+	['\u{a8d0}','\u{a8d9}'],
+	['\u{a900}','\u{a909}'],
+	['\u{a9d0}','\u{a9d9}'],
+	['\u{aa50}','\u{aa59}'],
+	['\u{abf0}','\u{abf9}'],
+	['\u{ff10}','\u{ff19}'],
+	['\u{104a0}','\u{104a9}'],
+	['\u{11066}','\u{1106f}'],
+	['\u{110f0}','\u{110f9}'],
+	['\u{11136}','\u{1113f}'],
+	['\u{111d0}','\u{111d9}'],
+	['\u{116c0}','\u{116c9}'],
+	['\u{1d7ce}','\u{1d7ff}'],
+]
+
+const tabxdigit = [
+	['\u{30}','\u{39}'],
+	['\u{41}','\u{46}'],
+	['\u{61}','\u{66}'],
+]
+
+const tabspace = [
+	['\u{9}','\u{d}'],
+	['\u{20}','\u{20}'],
+	['\u{85}','\u{85}'],
+	['\u{a0}','\u{a0}'],
+	['\u{1680}','\u{1680}'],
+	['\u{2000}','\u{200a}'],
+	['\u{2028}','\u{2029}'],
+	['\u{202f}','\u{202f}'],
+	['\u{205f}','\u{205f}'],
+	['\u{3000}','\u{3000}'],
+]
+
+const tabblank = [
+	['\u{9}','\u{9}'],
+	['\u{20}','\u{20}'],
+	['\u{a0}','\u{a0}'],
+	['\u{1680}','\u{1680}'],
+	['\u{2000}','\u{200a}'],
+	['\u{202f}','\u{202f}'],
+	['\u{205f}','\u{205f}'],
+	['\u{3000}','\u{3000}'],
+]
+
--- /dev/null
+++ b/lib/regex/redump.myr
@@ -1,0 +1,87 @@
+use std
+use bio
+use regex
+
+const main = {args
+	var cmd, comp
+	var verbose
+	var fd
+
+	verbose = false
+	cmd = std.optparse(args, &[
+		.argdesc = "regex [inputs...]",
+		.minargs = 1,
+		.maxargs = 1,
+		.opts = [
+			[.opt='v', .desc="dump verbose regex output"]
+		][:],
+	])
+	for opt in cmd.opts
+		match opt
+		| ('v', _):	verbose = true
+		| _:	std.fatal("Unknown argument")
+		;;
+	;;
+	if verbose
+		comp = regex.dbgcompile(cmd.args[0])
+	else
+		comp = regex.compile(cmd.args[0])
+	;;
+	match comp
+	| `std.Fail m:	
+		std.fatal("unable to compile regex: {}\n", regex.failmsg(m))
+	| `std.Ok re:
+		if cmd.args.len > 1
+			runall(re, cmd.args)
+		else
+			fd = bio.mkfile(0, bio.Rd)
+			dump(re, fd)
+			bio.close(fd)
+		;;
+	;;
+}
+
+const runall = {re, files
+
+	for f in files
+		match bio.open(f, bio.Rd)
+		| `std.Ok fd:
+			dump(re, fd)
+			bio.close(fd)
+		| `std.Fail m:
+			std.fatal("failed to open {}: {}\n", f, m)
+		;;
+	;;
+}
+
+const dump = {re, fd 
+	while true
+		match bio.readln(fd)
+		| `std.Some ln:
+			show(re, ln, regex.exec(re, ln))
+			std.slfree(ln)
+		| `std.None:
+			break
+		;;
+	;;
+}
+
+const show = {re, ln, mg
+	var i
+
+	match mg
+	| `std.Some rl:
+		std.put("Matched: {}\n", rl[0])
+		for i = 1; i < rl.len; i++
+			std.put("\tgroup {}: {}\n", i, rl[i])
+		;;
+	| `std.None:
+		std.put("Match failed:\n")
+		std.put("\t{}\n", ln)
+		std.put("\t")
+		for i = 0; i < re.strp - 1; i++
+			std.put("~")
+		;;
+		std.put("^\n")
+	;;
+}
--- /dev/null
+++ b/lib/regex/test/basic.myr
@@ -1,0 +1,39 @@
+use std
+
+use "testmatch.use"
+
+const main = {
+	var s : byte[:]
+		
+	s = std.strjoin([
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+	][:], "")
+	testmatch(".*bc", "Abc", `std.Some [][:])
+	testmatch("(a*)*", "a", `std.Some ["a"][:])
+	testmatch("(aa|aab?)*", s, `std.Some ["aa"][:])
+        /* greedy matches */
+	testmatch("(<.*>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo> blah <bar>",
+		][:])
+	testmatch("(<.+>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo> blah <bar>",
+		][:])
+        /* reluctant matches */
+	testmatch("(<.*?>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo>",
+		][:])
+	testmatch("(<.+?>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo>",
+		][:])
+}
--- /dev/null
+++ b/lib/regex/test/bld.sub
@@ -1,0 +1,7 @@
+test basic {inc=../libstd,inc=..} = basic.myr testmatch.myr;;
+test boundaries {inc=../libstd,inc=..} = boundaries.myr testmatch.myr;;
+test capture {inc=../libstd,inc=..} = capture.myr testmatch.myr;;
+test class {inc=../libstd,inc=..} = class.myr testmatch.myr;;
+test failmatch {inc=../libstd,inc=..} = failmatch.myr testmatch.myr;;
+test negclass {inc=../libstd,inc=..} = negclass.myr testmatch.myr;;
+test unicode {inc=../libstd,inc=..} = unicode.myr testmatch.myr;;
--- /dev/null
+++ b/lib/regex/test/boundaries.myr
@@ -1,0 +1,36 @@
+use std
+use "testmatch.use"
+
+const main = {
+	/* expected matches */
+	testmatch("\\<([a-z]*)\\>", "abcdef", `std.Some [
+		"abcdef",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!m!", `std.Some [	/* single char word in midstring */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!m", `std.Some [	/* single char word at end of string */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "m!", `std.Some [	/* single char word at start of string */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!", `std.Some [	/* word in midstring */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "matches!!%!", `std.Some [	/* word at start of string */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches", `std.Some [	/* word at end of string */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!foo", `std.Some [	/* matches last word in string */
+		"foo",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "123", `std.Some [	/* numbers are also word bounds */
+		"123",
+	][:])
+	
+	/* nonmatches */
+	testmatch("\\<([a-z]*)\\>foo", "abcdefoo", `std.None)	/* word boundary needed in midstring */
+}
--- /dev/null
+++ b/lib/regex/test/capture.myr
@@ -1,0 +1,17 @@
+use std
+use "testmatch.use"
+
+const main = {
+	testmatch("A(.*)", "Abc", `std.Some ["bc"][:])
+	testmatch("A(.*)e", "Abcde", `std.Some ["bcd"][:])
+	testmatch("(a|b)+", "abab", `std.Some ["b"][:])
+	testmatch("A(b(.*)d)e", "Abcde", `std.Some [
+		"bcd",
+		"c"
+	][:])
+	testmatch("(a?)(a*)(a?)", "aaaa", `std.Some [
+		"a",
+		"aaa",
+		""
+	][:])
+}
--- /dev/null
+++ b/lib/regex/test/class.myr
@@ -1,0 +1,67 @@
+use std
+
+use "testmatch.use"
+
+const main = {
+	asciiclass()
+	set()
+	/*
+	unicodeclass()
+	negasciiclass()
+	negasciirange()
+	negset()
+	*/
+}
+
+const asciiclass = {
+	/* \d success */
+	testmatch("\\d", "1", `std.Some [][:])
+	testmatch("\\d\\d", "13", `std.Some [][:])
+	testmatch("\\d+", "13688", `std.Some [][:])
+	/* \d fail */
+	testmatch("\\d", "x", `std.None)
+	testmatch("\\d\\d", "x3", `std.None)
+	testmatch("\\d+", "1368f", `std.None)
+
+	/* \x success */
+	testmatch("\\x", "a", `std.Some [][:])
+	testmatch("\\x\\x", "1F", `std.Some [][:])
+	testmatch("\\x+", "13b8cDEf", `std.Some [][:])
+	/* \x fail */
+	testmatch("\\x", "Z", `std.None)
+	testmatch("\\x\\x", "fg", `std.None)
+	testmatch("\\x+", "13b8cg", `std.None)
+
+	/* \s success */
+	testmatch("\\s", " ", `std.Some [][:])
+	testmatch("\\s\\s", "\t\n", `std.Some [][:])
+	testmatch("\\s+", "\t\n\r \t", `std.Some [][:])
+	/* \s fail */
+	testmatch("\\s", "a", `std.None)
+	testmatch("\\s\\s", "i\n", `std.None)
+	testmatch("\\s+", "\t\n\r.\t", `std.None)
+
+	/* word success */
+	testmatch("\\w+", "abcABC0123_", `std.Some [][:])
+	/* word fail */
+	testmatch("\\w+", "abcABC0123_.", `std.None)
+
+	/* \h success */
+	testmatch("\\h", " ", `std.Some [][:])
+	testmatch("\\h\\h", "\t ", `std.Some [][:])
+	testmatch("\\h+", "\t \t ", `std.Some [][:])
+	/* \h fail */
+	testmatch("\\h", "\n", `std.None)
+	testmatch("\\h\\h", "\t\r", `std.None)
+	testmatch("\\h+", "\t \t.", `std.None)
+}
+
+const set = {
+	/* ranges */
+	testmatch("[a-z]*", "abcd", `std.Some [][:])
+	testmatch("[a-zA-Z]*", "abCD", `std.Some [][:])
+	testmatch("[a-zA-Z0-9_]*", "_abCD018", `std.Some [][:])
+
+	testmatch("[abc]*", "abba", `std.Some [][:])
+	testmatch("[a-zABC]*", "abBa", `std.Some [][:])
+}
--- /dev/null
+++ b/lib/regex/test/failmatch.myr
@@ -1,0 +1,7 @@
+use std
+
+use "testmatch.use"
+
+const main = {
+	testmatch(".*bcd", "Abc", `std.None)
+}
--- /dev/null
+++ b/lib/regex/test/negclass.myr
@@ -1,0 +1,72 @@
+use std
+
+use "testmatch.use"
+
+const main = {
+	asciiclass()
+	set()
+	/*
+	unicodeclass()
+	negasciiclass()
+	negasciirange()
+	negset()
+	*/
+}
+
+const asciiclass = {
+	/* \D success */
+	testmatch("\\D", "x", `std.Some [][:])
+	testmatch("\\D+", "xa!#^cs", `std.Some [][:])
+
+	/* \D fail: end of ranges chars */
+	testmatch("\\D", "0", `std.None)
+	testmatch("\\D", "9", `std.None)
+	testmatch("\\D+", "a35x", `std.None)
+	testmatch("\\D+", "13688", `std.None)
+
+	/* \X success */
+	testmatch("\\X", "Z", `std.Some [][:])
+	testmatch("\\X\\X", "gg", `std.Some [][:])
+	/* \X fail */
+	testmatch("\\X", "a", `std.None)
+	testmatch("\\X+", "zz13b8cDEf", `std.None)
+
+	/* \S success */
+	testmatch("\\S", "a", `std.Some [][:])
+	testmatch("\\S\\S", "i%", `std.Some [][:])
+	testmatch("\\S+", "alskd690!#!!", `std.Some [][:])
+
+	/* \S fail */
+	testmatch("\\S", " ", `std.None)
+	testmatch("\\S\\S", "\t\n", `std.None)
+	testmatch("\\S+", "\t \nkait", `std.None)
+
+	/* word success */
+	testmatch("\\W+", "!%!^^@@!^", `std.Some [][:])
+	/* word fail */
+	testmatch("\\W+", "a^#$bcABC0123_", `std.None)
+
+	/* \H success */
+	testmatch("\\H", "\n", `std.Some [][:])
+	testmatch("\\H\\H", "\n\r", `std.Some [][:])
+	/* \H fail */
+	testmatch("\\H+", "\t \t.", `std.None)
+	testmatch("\\H\\H", "\t ", `std.None)
+	testmatch("\\H+", "\ta35 \t ", `std.None)
+}
+
+const set = {
+	/* ranges: should succeed */
+	testmatch("[^a-z]*", "ABCD", `std.Some [][:])
+	testmatch("[^a-zA-Z]*", "1234", `std.Some [][:])
+	testmatch("[^a-zA-Z0-9_]*", "-^^-", `std.Some [][:])
+	testmatch("[^abc]*", "d6d", `std.Some [][:])
+	testmatch("[^a-zABC]*", "!^!!))#", `std.Some [][:])
+
+	/* ranges: should fail */
+	testmatch("[^a-z]*", "abcd", `std.None)
+	testmatch("[^a-zA-Z]*", "abCD", `std.None)
+	testmatch("[^a-zA-Z0-9_]*", "_abCD018", `std.None)
+	testmatch("[^abc]*", "abba", `std.None)
+	testmatch("[^a-zABC]*", "abBa", `std.None)
+}
--- /dev/null
+++ b/lib/regex/test/runtest.sh
@@ -1,0 +1,124 @@
+#!/bin/bash
+NFAILURES=0
+NPASSES=0
+
+function build {
+    rm -f $1 $1.o $1.s $1.use
+    myrbuild $FLAGS -b $1 $1.myr $EXTRA_SRC
+}
+
+function pass {
+    PASSED="$PASSED $1"
+    NPASSED=$[$NPASSED + 1]
+}
+
+function fail {
+    echo "FAIL: $1"
+    FAILED="$FAILED $1"
+    NFAILED=$[$NFAILED + 1]
+}
+
+function expectstatus {
+    ./$1 $3
+    if [ $? -eq $2 ]; then
+        pass $1
+        return
+    else
+        fail $1
+    fi
+}
+
+function expectprint {
+    if [ "`./$1 $3`" != "$2" ]; then
+        fail $1
+    else
+        pass $1
+    fi
+}
+
+
+function expectcompare {
+    if [ x"" !=  x"$TMPDIR" ]; then 
+        t=$TMPDIR/myrtest-$1-$RANDOM
+    else
+        t=/tmp/myrtest-$1-$RANDOM
+    fi
+    ./$1 $3 > $t
+    if cmp $t data/$1-expected; then
+        pass $1
+    else
+        fail $1
+    fi
+    rm -f $t
+}
+
+function expectfcompare {
+    ./$1 $3
+    if cmp data/$1-expected $2; then
+        pass $1
+    else
+        fail $1
+    fi
+}
+
+function shouldskip {
+  if [ -z $ARGS ]; then
+      return 1
+  fi
+
+  for i in $ARGS; do
+      if [ $i = $1 ]; then
+          return 1
+      fi
+  done
+  return 0
+}
+
+
+# Should build and run
+function B {
+    if shouldskip $1; then
+        return
+    fi
+
+    test="$1"; shift
+    type="$1"; shift
+    res="$1"; shift
+    if [ $# > 0 ]; then
+        args="$1"; shift
+    fi
+    build $test
+    case $type in
+    "E")  expectstatus "$test" "$res" "$input";;
+    "P")  expectprint "$test" "$res" "$input";;
+    "C")  expectcompare "$test" "$res" "$input";;
+    "F")  expectfcompare "$test" "$res" "$args";;
+    esac
+}
+
+# Should fail
+function F {
+    if shouldskip $1; then
+        return
+    fi
+    (build $1) > /dev/null
+    if [ $? -eq '1' ]; then
+        pass $1
+    else
+        fail $1
+    fi
+}
+
+# Should generate a usefile
+function U {
+    return
+}
+
+source tests
+
+echo "PASSED ($NPASSED): $PASSED"
+if [ -z "$NFAILED" ]; then
+    echo "SUCCESS"
+else
+    echo "FAILURES ($NFAILED): $FAILED"
+fi
--- /dev/null
+++ b/lib/regex/test/testmatch.myr
@@ -1,0 +1,58 @@
+use std
+use regex
+
+pkg =
+	const testmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
+	const dbgmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
+;;
+
+const testmatch = {pat, text, expected
+	run(regex.compile(pat), pat, text, expected)
+}
+
+const dbgmatch = {pat, text, expected
+	run(regex.dbgcompile(pat), pat, text, expected)
+}
+
+const run = {regex, pat, text, expected
+	var i, re
+
+	re = std.try(regex)
+	match regex.exec(re, text)
+	| `std.Some res:
+		match expected
+		| `std.None:
+			std.fatal("expected no match, got:")
+			for i = 0; i < res.len; i++
+				std.put("\t{}: {}\n", i, res[i])
+			;;
+		| `std.Some exp:
+			if !std.sleq(res[0], text)
+				std.put("whole match does not match text!\n")
+				std.fatal("failed matching {} over {}\n", pat, text)
+			;;
+			res = res[1:]
+			if res.len != exp.len
+				std.put("mismatch: expected {} matches, got {}\n",  exp.len, res.len)
+				std.fatal("failed matching {} over {}\n", pat, text)
+			;;
+			for i = 0; i < exp.len; i++
+				if !std.sleq(res[i], exp[i])
+					std.put("mismatch on {}: expected {}, got {}\n", i, exp[i], res[i])
+					std.fatal("failed matching {} over {}\n", pat, text)
+				;;
+			;;
+		;;
+	| `std.None:
+		match expected
+		| `std.None:	/* : expected failure */
+		| `std.Some matches:
+			std.put("expected matches:\n")
+			for i = 0; i < matches.len; i++
+				std.put("\t{}: {}\n", i, matches[i])
+			;;
+			std.fatal("no match found\n")
+		;;
+	;;
+	regex.free(re)
+}
--- /dev/null
+++ b/lib/regex/test/tests
@@ -1,0 +1,29 @@
+FLAGS=-I../
+EXTRA_SRC=testmatch.myr
+# Format:
+# [B|F] testname [E|P] result
+#    [B|F]: Compiler outcome.
+#	B: Expect that this test will build.
+#	F: Expect that this test will not build.
+#    testname: Test case
+#	The test that will run. We will try to
+#	compile 'testname.myr' to 'testname',
+#	and then execute it, verifying the result
+#    [E|P|C]: Result type
+#	E tells us that the result is an exit status
+#	P tells us that the result is on stdout,
+#         and should be compared to the value on the
+#         line
+#	C tells us that the result is on stdout,
+#         and should be compared to the contents of
+#         the file passed on the line.
+#    result: Result value
+#	What we compare with. This should be self-
+#	evident.
+B basic		C
+B boundaries	C
+B capture	C
+B class		C
+B failmatch	C
+B negclass	C
+B unicode		C
--- /dev/null
+++ b/lib/regex/test/unicode.myr
@@ -1,0 +1,19 @@
+use std
+use regex
+
+use "testmatch.use"
+
+const main = {
+	testmatch(".*bæc", "Abæc", `std.Some [][:])
+	testmatch("(\\p{L}*)bæc\\P{L}*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
+        /* test various syntaxen */
+	testmatch("(\\pL*)bæc\\PL*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
+	testmatch("(\\p{Letter}*)bæc\\P{Uppercase_Letter}*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
+	testmatch(".", "æ", `std.Some [][:])
+}
--- /dev/null
+++ b/lib/regex/types.myr
@@ -1,0 +1,88 @@
+use std
+
+pkg regex =
+	type status = union
+		`Noimpl
+		`Incomplete
+		`Unbalanced
+		`Emptyparen
+		`Badrep
+		`Badrange
+		`Badescape
+	;;
+
+	type ast = union
+		/* basic string building */
+		`Alt	(ast#, ast#)
+		`Cat	(ast#, ast#)
+
+		/* repetition */
+		`Star	ast#
+		`Rstar  ast#
+		`Plus	ast#
+		`Rplus	ast#
+		`Quest	ast#	
+
+		/* end matches */
+		`Chr	char
+		`Ranges	char[2][:]
+
+		/* meta */
+		`Cap	(std.size, ast#) /* id, ast */
+		`Bol	/* beginning of line */
+		`Eol	/* end of line */
+		`Bow	/* beginning of word */
+		`Eow	/* end of word */
+	;;
+
+
+	type regex = struct
+		/* compile state */
+		debug	: bool
+		pat	: byte[:]
+		nmatch	: std.size
+
+		/* VM state */
+		runq	: rethread#
+		expired	: rethread#
+		expiredtail	: rethread#
+		proglen	: std.size
+		prog	: reinst[:]
+		nthr	: std.size
+		str	: byte[:]
+		strp	: std.size
+	;;
+
+	type rethread = struct
+		next	: rethread#	/* run queue link */
+
+		tid	: std.size	/* just for debugging */
+		ip	: std.size	/* the instruction pointer */
+		dead	: bool		/* thread died */
+		matched	: bool		/* thread matched */
+
+		mstart	: std.size[:]	/* match starts */
+		mend	: std.size[:]	/* match ends */
+	;;
+
+	pkglocal type reinst = union
+		/* direct consumers */
+		`Ibyte	byte
+		`Irange	(byte, byte)
+
+		/* groups */
+		`Ilbra	std.size
+		`Irbra	std.size
+
+		/* anchors */
+		`Ibol
+		`Ieol
+		`Ibow
+		`Ieow
+
+		/* control flow */
+		`Ifork	(std.size, std.size)
+		`Ijmp	std.size
+		`Imatch	std.size
+	;;
+;;
--- /dev/null
+++ b/lib/std/alloc.myr
@@ -1,0 +1,423 @@
+use "die.use"
+use "extremum.use"
+use "types.use"
+use "units.use"
+use "syswrap.use"
+
+/*
+The allocator implementation here is based on Bonwick's slab allocator.
+
+For small allocations (up to Bktmax), it works by requesting large,
+power of two aligned chunks from the operating system, and breaking
+them into a linked list of equal sized chunks. Allocations are then
+satisfied by taking the head of the list of chunks. Empty slabs
+are removed from the freelist.
+
+The data structure looks something like this:
+   Bkts:
+	[16  byte] -> [slab hdr | chunk -> chunk -> chunk] -> [slab hdr | chunk -> chunk -> chunk]
+	[32  byte] -> Zslab
+	[64  byte] -> [slab hdr | chunk -> chunk]
+	...
+	[32k byte] -> ...
+
+Large allocations are simply satisfied by mmap().
+
+*/
+
+pkg std =
+	generic alloc	: (		-> @a#)
+	generic zalloc	: (		-> @a#)
+	generic free	: (v:@a#	-> void)
+
+	generic slalloc	: (len : size	-> @a[:])
+	generic slzalloc	: (len : size	-> @a[:])
+	generic slgrow	: (sl : @a[:], len : size	-> @a[:])
+	generic slzgrow	: (sl : @a[:], len : size	-> @a[:])
+	generic slfree	: (sl : @a[:]	-> void)
+
+	const bytealloc	: (sz:size	-> byte#)
+	const zbytealloc	: (sz:size	-> byte#)
+	const bytefree	: (m:byte#, sz:size	-> void)
+
+
+;;
+
+/* null pointers. only used internally. */
+const Zslab	= 0 castto(slab#)
+const Zchunk	= 0 castto(chunk#)
+
+const Slabsz 	= 1*MiB	/* 1 meg slabs */
+const Cachemax	= 16	/* maximum number of slabs in the cache */
+const Bktmax	= 32*KiB	/* Slabsz / 8; a balance. */
+const Pagesz	= 4*KiB
+const Align	= 16	/* minimum allocation alignment */
+
+var buckets	: bucket[32] /* excessive */
+
+type slheader = struct
+	cap	: size	/* capacity in bytes */
+	magic	: size	/* magic check value */
+;;
+
+type bucket = struct
+	sz	: size	/* aligned size */
+	nper	: size	/* max number of elements per slab */
+	slabs	: slab#	/* partially filled or free slabs */
+	cache	: slab# /* cache of empty slabs, to prevent thrashing */
+	ncache	: size  /* size of cache */
+;;
+
+type slab = struct
+	head	: byte#	/* head of virtual addresses, so we don't leak address space */
+	next	: slab#	/* the next slab on the chain */
+	freehd	: chunk#	/* the nodes we're allocating */
+	nfree	: size	/* the number of free nodes */
+;;
+
+type chunk = struct	/* NB: must be smaller than sizeof(slab) */
+	next	: chunk#	/* the next chunk in the free list */
+;;
+
+const __init__ = {
+	var i
+
+	for i = 0; i < buckets.len && (Align << i) <= Bktmax; i++
+		bktinit(&buckets[i], Align << i)
+	;;
+}
+
+/* Allocates an object of type @a, returning a pointer to it. */
+generic alloc = {-> @a#
+	-> bytealloc(sizeof(@a)) castto(@a#)
+}
+
+generic zalloc = {-> @a#
+	-> zbytealloc(sizeof(@a)) castto(@a#)
+}
+
+/* Frees a value of type @a */
+generic free = {v:@a# -> void
+	bytefree(v castto(byte#), sizeof(@a))
+}
+
+/* allocates a slice of 'len' elements. */
+generic slalloc = {len
+	var p, sz
+
+	if len == 0
+		-> [][:]
+	;;
+	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
+	p = bytealloc(sz)
+	p = inithdr(p, sz)
+	-> (p castto(@a#))[0:len]
+}
+
+generic slzalloc = {len
+	var p, sz
+
+	if len == 0
+		-> [][:]
+	;;
+	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
+	p = zbytealloc(sz)
+	p = inithdr(p, sz)
+	-> (p castto(@a#))[0:len]
+}
+
+const inithdr = {p, sz
+	var phdr, prest
+
+	phdr = p castto(slheader#)
+	phdr.cap = allocsz(sz) - align(sizeof(slheader), Align)
+	phdr.magic = (0xdeadbeefbadf00d castto(size))
+
+	prest = (p castto(size)) + align(sizeof(slheader), Align)
+	-> prest castto(byte#)
+}
+
+const checkhdr = {p
+	var phdr, addr
+
+	addr = p castto(size)
+	addr -= align(sizeof(slheader), Align)
+	phdr = addr castto(slheader#)
+	assert(phdr.magic == (0xdeadbeefbadf00d castto(size)), "corrupt memory\n")
+}
+
+/* Frees a slice */
+generic slfree	 = {sl
+	var head
+
+	if sl.len == 0
+		->
+	;;
+
+	checkhdr(sl castto(byte#))
+	head = (sl castto(byte#)) castto(size)
+	head -= align(sizeof(slheader), Align)
+	bytefree(head castto(byte#), slcap(sl castto(byte#)))
+}
+
+/* Grows a slice */
+generic slgrow = {sl : @a[:], len
+	var i, n
+	var new
+
+	/* if the slice doesn't need a bigger bucket, we don't need to realloc. */
+	if sl.len > 0 && slcap(sl castto(byte#)) >= allocsz(len*sizeof(@a))
+		-> (sl castto(@a#))[:len]
+	;;
+
+	new = slalloc(len)
+	n = min(len, sl.len)
+	for i = 0; i < n; i++
+		new[i] = sl[i]
+	;;
+	if sl.len > 0
+		slfree(sl)
+	;;
+	-> new
+}
+
+/* Grows a slice, filling new entries with zero bytes */
+generic slzgrow = {sl : @a[:], len
+	var oldsz
+
+	oldsz = sl.len*sizeof(@a)
+	sl = slgrow(sl, len)
+	zfill((sl castto(byte#))[oldsz:len*sizeof(@a)])
+	-> sl
+}
+
+const slcap = {p
+	var phdr
+
+	phdr = (p castto(size)) - align(sizeof(slheader), Align) castto(slheader#)
+	-> phdr.cap
+}
+
+const zbytealloc = {sz
+	var p
+
+	p = bytealloc(sz)
+	zfill(p[0:sz])
+	-> p
+}
+
+const zfill = {sl
+	var i
+
+	for i = 0; i < sl.len; i++
+		sl[i] = 0
+	;;
+}
+
+/* Allocates a blob that is 'sz' bytes long. Dies if the allocation fails */
+const bytealloc = {sz
+	var bkt, p
+
+	if (sz <= Bktmax)
+		bkt = &buckets[bktnum(sz)]
+		p = bktalloc(bkt)
+	else
+		p = getmem(sz)
+		if p == Failmem
+			die("could not get memory\n")
+		;;
+	;;
+	-> p
+}
+
+/* frees a blob that is 'sz' bytes long. */
+const bytefree = {p, sz
+	var bkt
+	var b, i
+
+	b = p[:sz]
+	for i = 0; i < sz; i++
+		b[i] = 0xa8
+	;;
+	if (sz < Bktmax)
+		bkt = &buckets[bktnum(sz)]
+		bktfree(bkt, p)
+	else
+		freemem(p, sz)
+	;;
+}
+
+/* Sets up a single empty bucket */
+const bktinit = {b, sz
+	b.sz = align(sz, Align)
+	b.nper = (Slabsz - sizeof(slab))/b.sz
+	b.slabs = Zslab
+	b.cache = Zslab
+	b.ncache = 0
+}
+
+/* Creates a slab for bucket 'bkt', and fills the chunk list */
+const mkslab = {bkt
+	var i, p, s
+	var b, bnext
+	var off /* offset of chunk head */
+
+	if bkt.ncache > 0
+		s = bkt.cache
+		bkt.cache = s.next
+		bkt.ncache--
+	;;
+	/*
+	tricky: we need power of two alignment, so we allocate double the
+	needed size, chop off the unaligned ends, and waste the address
+	space. Since the OS is "smart enough", this shouldn't actually
+	cost us memory, and 64 bits of address space means that we're not
+	going to have issues with running out of address space for a
+	while. On a 32 bit system this would be a bad idea.
+	*/
+	p = getmem(Slabsz*2)
+	if p == Failmem
+		die("Unable to mmap")
+	;;
+
+	s = align(p castto(size), Slabsz) castto(slab#)
+	s.head = p
+	s.nfree = bkt.nper
+	/* skip past the slab header */
+	off = align(sizeof(slab), Align)
+	bnext = nextchunk(s castto(chunk#), off)
+	s.freehd = bnext
+	for i = 0; i < bkt.nper; i++
+		b = bnext
+		bnext = nextchunk(b, bkt.sz)
+		b.next = bnext
+	;;
+	b.next = Zchunk
+	-> s
+}
+
+/* 
+Allocates a node from bucket 'bkt', crashing if the
+allocation cannot be satisfied. Will create a new slab
+if there are no slabs on the freelist.
+*/
+const bktalloc = {bkt
+	var s
+	var b
+
+	/* find a slab */
+	s = bkt.slabs
+	if s == Zslab
+		s = mkslab(bkt)
+		if s == Zslab
+			die("No memory left")
+		;;
+		bkt.slabs = s
+	;;
+
+	/* grab the first chunk on the slab */
+	b = s.freehd
+	s.freehd = b.next
+	s.nfree--
+	if s.nfree == 0
+		bkt.slabs = s.next
+		s.next = Zslab
+	;;
+
+	-> b castto(byte#)
+}
+
+/*
+Frees a chunk of memory 'm' into bucket 'bkt'.
+Assumes that the memory already came from a slab
+that was created for bucket 'bkt'. Will crash
+if this is not the case.
+*/
+const bktfree = {bkt, m
+	var s, b
+
+	s = mtrunc(m, Slabsz) castto(slab#)
+	b = m castto(chunk#)
+	if s.nfree == 0
+		s.next = bkt.slabs
+		bkt.slabs = s
+	elif s.nfree == bkt.nper
+		/*
+		HACK HACK HACK: if we can't unmap, keep an infinite cache per slab size.
+		We should solve this better somehow.
+		*/
+		if bkt.ncache < Cachemax || !Canunmap
+			s.next = bkt.cache
+			bkt.cache = s
+		else
+			/* we mapped 2*Slabsz so we could align it,
+			 so we need to unmap the same */
+			freemem(s.head, Slabsz*2)
+		;;
+	;;
+	s.nfree++
+	b.next = s.freehd
+	s.freehd = b
+}
+
+/*
+Finds the correct bucket index to allocate from
+for allocations of size 'sz'
+*/
+const bktnum = {sz
+	var i, bktsz
+
+	bktsz = Align
+	for i = 0; bktsz <= Bktmax; i++
+		if bktsz >= sz
+			-> i
+		;;
+		bktsz *= 2
+	;;
+	die("Size does not match any buckets")
+}
+
+/*
+returns the actual size we allocated for a given
+size request
+*/
+const allocsz = {sz
+	var i, bktsz
+
+	if sz <= Bktmax
+		bktsz = Align
+		for i = 0; bktsz <= Bktmax; i++
+			if bktsz >= sz
+				-> bktsz
+			;;
+			bktsz *= 2
+		;;
+	else
+		-> align(sz, Pagesz)
+	;;
+	die("Size does not match any buckets")
+}
+
+/*
+aligns a size to a requested alignment.
+'align' must be a power of two
+*/
+const align = {v, align
+	-> (v + align - 1) & ~(align - 1)
+}
+
+/*
+chunks are variable sizes, so we can't just
+index to get to the next one
+*/
+const nextchunk = {b, sz : size
+	-> ((b castto(intptr)) + (sz castto(intptr))) castto(chunk#)
+}
+
+/*
+truncates a pointer to 'align'. 'align' must
+be a power of two.
+*/
+const mtrunc = {m, align
+	-> ((m castto(intptr)) & ~((align castto(intptr)) - 1)) castto(byte#)
+}
--- /dev/null
+++ b/lib/std/bigint.myr
@@ -1,0 +1,742 @@
+use "alloc.use"
+use "chartype.use"
+use "cmp.use"
+use "die.use"
+use "extremum.use"
+use "hasprefix.use"
+use "option.use"
+use "slcp.use"
+use "sldup.use"
+use "slfill.use"
+use "slpush.use"
+use "types.use"
+use "utf.use"
+use "errno.use"
+
+pkg std =
+	type bigint = struct
+		dig	: uint32[:] 	/* little endian, no leading zeros. */
+		sign	: int		/* -1 for -ve, 0 for zero, 1 for +ve. */
+	;;
+
+	/* administrivia */
+	generic mkbigint	: (v : @a::(numeric,integral) -> bigint#)
+	const bigfree	: (a : bigint# -> void)
+	const bigdup	: (a : bigint# -> bigint#)
+	const bigassign	: (d : bigint#, s : bigint# -> bigint#)
+	const bigmove	: (d : bigint#, s : bigint# -> bigint#)
+	const bigparse	: (s : byte[:] -> option(bigint#))
+	const bigclear	: (a : bigint# -> bigint#)
+	const bigbfmt	: (b : byte[:], a : bigint#, base : int -> size)
+	/*
+	const bigtoint	: (a : bigint#	-> @a::(numeric,integral))
+	*/
+
+	/* some useful predicates */
+	const bigiszero	: (a : bigint# -> bool)
+	const bigeq	: (a : bigint#, b : bigint# -> bool)
+	generic bigeqi	: (a : bigint#, b : @a::(numeric,integral) -> bool)
+	const bigcmp	: (a : bigint#, b : bigint# -> order)
+
+	/* bigint*bigint -> bigint ops */
+	const bigadd	: (a : bigint#, b : bigint# -> bigint#)
+	const bigsub	: (a : bigint#, b : bigint# -> bigint#)
+	const bigmul	: (a : bigint#, b : bigint# -> bigint#)
+	const bigdiv	: (a : bigint#, b : bigint# -> bigint#)
+	const bigmod	: (a : bigint#, b : bigint# -> bigint#)
+	const bigdivmod	: (a : bigint#, b : bigint# -> (bigint#, bigint#))
+	const bigshl	: (a : bigint#, b : bigint# -> bigint#)
+	const bigshr	: (a : bigint#, b : bigint# -> bigint#)
+	const bigmodpow	: (b : bigint#, e : bigint#, m : bigint# -> bigint#)
+	/*
+	const bigpow	: (a : bigint#, b : bigint# -> bigint#)
+	*/
+
+	/* bigint*int -> bigint ops */
+	generic bigaddi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	generic bigsubi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	generic bigmuli	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	generic bigdivi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	generic bigshli	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	generic bigshri	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+	/*
+	const bigpowi	: (a : bigint#, b : uint64 -> bigint#)
+	*/
+;;
+
+const Base = 0x100000000ul
+generic mkbigint = {v : @a::(integral,numeric)
+	var a
+	var val
+
+	a = zalloc()
+
+	if v < 0
+		a.sign = -1
+		v = -v
+	elif v > 0
+		a.sign = 1
+	;;
+	val = v castto(uint64)
+	a.dig = slpush([][:], val castto(uint32))
+	if val > Base
+		a.dig = slpush(a.dig, (val/Base) castto(uint32))
+	;;
+	-> trim(a)
+}
+
+const bigfree = {a
+	slfree(a.dig)
+	free(a)
+}
+
+const bigdup = {a
+	-> bigassign(zalloc(), a)
+}
+
+const bigassign = {d, s
+	slfree(d.dig)
+	d# = s#
+	d.dig = sldup(s.dig)
+	-> d
+}
+
+const bigmove = {d, s
+	slfree(d.dig)
+	d# = s#
+	s.dig = [][:]
+	s.sign = 0
+	-> d
+}
+
+const bigclear = {v
+	std.slfree(v.dig)
+	v.sign = 0
+	v.dig = [][:]
+	-> v
+}
+
+/* for now, just dump out something for debugging... */
+const bigbfmt = {buf, x, base
+	const digitchars = [
+	'0','1','2','3','4','5','6','7','8','9',
+	'a','b','c','d','e','f', 'g', 'h', 'i', 'j',
+	'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+	't', 'u', 'v', 'w', 'x', 'y', 'z']
+	var v, val
+	var n, i
+	var tmp, rem, b
+
+	if base < 0 || base > 36
+		die("invalid base in bigbfmt\n")
+	;;
+
+	if bigiszero(x)
+		n
+	;;
+
+	if base == 0
+		b = mkbigint(10)
+	else
+		b = mkbigint(base)
+	;;
+	n = 0
+	val = bigdup(x)
+	/* generate the digits in reverse order */
+	while !bigiszero(val)
+		(v, rem) = bigdivmod(val, b)
+		if rem.dig.len > 0
+			n += encode(buf[n:], digitchars[rem.dig[0]])
+		else
+			n += encode(buf[n:], '0')
+		;;
+		bigfree(val)
+		bigfree(rem)
+		val = v
+	;;
+	bigfree(val)
+	bigfree(b)
+
+	/* this is done last, so we get things right when we reverse the string */
+	if x.sign == 0
+		n += encode(buf[n:], '0')
+	elif x.sign == -1
+		n += encode(buf[n:], '-')
+	;;
+
+	/* we only generated ascii digits, so this works for reversing. */
+	for i = 0; i < n/2; i++
+		tmp = buf[i]
+		buf[i] = buf[n - i - 1]
+		buf[n - i - 1] = tmp
+	;;
+	-> n
+}
+
+const bigparse = {str
+	var c, val : int, base
+	var v, b
+	var a
+
+	if hasprefix(str, "0x") || hasprefix(str, "0X")
+		base = 16
+	elif hasprefix(str, "0o") || hasprefix(str, "0O")
+		base = 8
+	elif hasprefix(str, "0b") || hasprefix(str, "0B")
+		base = 2
+	else
+		base = 10
+	;;
+	if base != 10
+		str = str[2:]
+	;;
+
+	a = mkbigint(0)
+	b = mkbigint(base)
+	/*
+	 efficiency hack: to save allocations,
+	 just mutate v[0]. The value will always
+	 fit in one digit.
+	 */
+	v = mkbigint(1)
+	while str.len != 0
+		(c, str) = striter(str)
+		if c == '_'
+			continue
+		;;
+		val = charval(c, base)
+		if val < 0 || val > base
+			bigfree(a)
+			bigfree(b)
+			bigfree(v)
+			-> `None
+		;;
+		v.dig[0] = val castto(uint32)
+		if val == 0
+			v.sign = 0
+		else
+			v.sign = 1
+		;;
+		bigmul(a, b)
+		bigadd(a, v)
+
+	;;
+	-> `Some a
+}
+
+const bigiszero = {v
+	-> v.dig.len == 0
+}
+
+const bigeq = {a, b
+	var i
+
+	if a.sign != b.sign || a.dig.len != b.dig.len
+		-> false
+	;;
+	for i = 0; i < a.dig.len; i++
+		if a.dig[i] != b.dig[i]
+			-> false
+		;;
+	;;
+	-> true
+}
+
+generic bigeqi = {a, b
+	var v
+	var dig : uint32[2]
+
+	bigdigit(&v, b < 0, b castto(uint64), dig[:])
+	-> bigeq(a, &v)
+}
+
+const bigcmp = {a, b
+	var i
+	var da, db, sa, sb
+
+	sa = a.sign castto(int64)
+	sb = b.sign castto(int64)
+	if sa < sb
+		-> `Before
+	elif sa > sb
+		-> `After
+	elif a.dig.len < b.dig.len
+		-> signedorder(-sa)
+	elif a.dig.len > b.dig.len
+		-> signedorder(sa)
+	else
+		/* otherwise, the one with the first larger digit is bigger */
+		for i = a.dig.len; i > 0; i--
+			da = a.dig[i - 1] castto(int64)
+			db = b.dig[i - 1] castto(int64)
+			-> signedorder(sa * (da - db))
+		;;
+	;;
+	-> `Equal
+}
+
+const signedorder = {sign
+	if sign < 0
+		-> `Before 
+	elif sign == 0
+		-> `Equal
+	else
+		-> `After
+	;;
+}
+
+/* a += b */
+const bigadd = {a, b
+	if a.sign == b.sign || a.sign == 0 
+		a.sign = b.sign
+		-> uadd(a, b)
+	elif b.sign == 0
+		-> a
+	else
+		match bigcmp(a, b)
+		| `Before: /* a is negative */
+		    a.sign = b.sign
+		    -> usub(b, a)
+		| `After: /* b is negative */
+		    -> usub(a, b)
+		| `Equal:
+			die("Impossible. Equal vals with different sign.")
+		;;
+	;;
+}
+
+/* adds two unsigned values together. */
+const uadd = {a, b
+	var v, i
+	var carry
+	var n
+
+	carry = 0
+	n = max(a.dig.len, b.dig.len)
+	/* guaranteed to carry no more than one value */
+	a.dig = slzgrow(a.dig, n + 1)
+	for i = 0; i < n; i++
+		v = (a.dig[i] castto(uint64)) + carry;
+		if i < b.dig.len
+			v += (b.dig[i] castto(uint64))
+		;;
+
+		if v >= Base
+			carry = 1
+		else
+			carry = 0
+		;;
+		a.dig[i] = v castto(uint32)
+	;;
+	a.dig[i] += carry castto(uint32)
+	-> trim(a)
+}
+
+/* a -= b */
+const bigsub = {a, b
+	/* 0 - x = -x */
+	if a.sign == 0
+		bigassign(a, b)
+		a.sign = -b.sign
+		-> a
+	/* x - 0 = x */
+	elif b.sign == 0
+		-> a
+	elif a.sign != b.sign
+		-> uadd(a, b)
+	else
+		match bigcmp(a, b)
+		| `Before: /* a is negative */
+		    a.sign = b.sign
+		    -> usub(b, a)
+		| `After: /* b is negative */
+		    -> usub(a, b)
+		| `Equal:
+		    -> bigclear(a)
+		;;
+	;;
+	-> a
+}
+
+/* subtracts two unsigned values, where 'a' is strictly greater than 'b' */
+const usub = {a, b
+	var carry
+	var v, i
+
+	carry = 0
+	for i = 0; i < a.dig.len; i++
+		v = (a.dig[i] castto(int64)) - carry
+		if i < b.dig.len
+			v -= (b.dig[i] castto(int64)) 
+		;;
+		if v < 0
+			carry = 1
+		else
+			carry = 0
+		;;
+		a.dig[i] = v castto(uint32)
+	;;
+	-> trim(a)
+}
+
+/* a *= b */
+const bigmul = {a, b
+	var i, j
+	var ai, bj, wij
+	var carry, t
+	var w
+
+	if a.sign == 0 || b.sign == 0
+		a.sign = 0
+		slfree(a.dig)
+		a.dig = [][:]
+		-> a
+	elif a.sign != b.sign
+		a.sign = -1
+	else
+		a.sign = 1
+	;;
+	w  = slzalloc(a.dig.len + b.dig.len)
+	for j = 0; j < b.dig.len; j++
+		carry = 0
+		for i = 0; i < a.dig.len; i++
+			ai = a.dig[i] castto(uint64)
+			bj = b.dig[j] castto(uint64)
+			wij = w[i+j] castto(uint64)
+			t = ai * bj + wij + carry
+			w[i + j] = (t castto(uint32))
+			carry = t >> 32
+		;;
+		w[i+j] = carry castto(uint32)
+	;;
+	slfree(a.dig)
+	a.dig = w
+	-> trim(a)
+}
+
+const bigdiv = {a : bigint#, b : bigint# -> bigint#
+	var q, r
+
+	(q, r) = bigdivmod(a, b)
+	bigfree(r)
+	-> bigmove(a, q)
+}
+const bigmod = {a : bigint#, b : bigint# -> bigint#
+	var q, r
+
+	(q, r) = bigdivmod(a, b)
+	bigfree(q)
+	-> bigmove(a, r)
+}
+
+/* a /= b */
+const bigdivmod = {a : bigint#, b : bigint# -> (bigint#, bigint#)
+	/*
+	Implements bigint division using Algorithm D from
+	Knuth: Seminumerical algorithms, Section 4.3.1.
+	*/
+	var m : int64, n : int64
+	var qhat, rhat, carry, shift
+	var x, y, z, w, p, t /* temporaries */
+	var b0, aj
+	var u, v
+	var i, j : int64
+	var q
+
+	if bigiszero(b)
+		die("divide by zero\n")
+	;;
+	/* if b > a, we trucate to 0, with remainder 'a' */
+	if a.dig.len < b.dig.len
+		-> (mkbigint(0), bigdup(a))
+	;;
+
+	q = zalloc()
+	q.dig = slzalloc(max(a.dig.len, b.dig.len) + 1)
+	if a.sign != b.sign
+		q.sign = -1
+	else
+		q.sign = 1
+	;;
+
+	/* handle single digit divisor separately: the knuth algorithm needs at least 2 digits. */
+	if b.dig.len == 1
+		carry = 0
+		b0 = (b.dig[0] castto(uint64))
+		for j = a.dig.len; j > 0; j--
+			aj = (a.dig[j - 1] castto(uint64))
+			q.dig[j - 1] = (((carry << 32) + aj)/b0) castto(uint32)
+			carry = (carry << 32) + aj - (q.dig[j-1] castto(uint64))*b0
+		;;
+		q = trim(q)
+		-> (q, trim(mkbigint(carry castto(int32))))
+	;;
+
+	u = bigdup(a)
+	v = bigdup(b)
+	m = u.dig.len
+	n = v.dig.len
+
+	shift = nlz(v.dig[n - 1])
+	bigshli(u, shift)
+	bigshli(v, shift)
+	u.dig = slzgrow(u.dig, u.dig.len + 1)
+
+	for j = m - n; j >= 0; j--
+		/* load a few temps */
+		x = u.dig[j + n] castto(uint64)
+		y = u.dig[j + n - 1] castto(uint64)
+		z = v.dig[n - 1] castto(uint64)
+		w = v.dig[n - 2] castto(uint64)
+		t = u.dig[j + n - 2] castto(uint64)
+
+		/* estimate qhat */
+		qhat = (x*Base + y)/z
+		rhat = (x*Base + y) - qhat*z
+:divagain
+		if qhat >= Base || (qhat * w) > (rhat*Base + t)
+			qhat--
+			rhat += z
+			if rhat < Base
+				goto divagain
+			;;
+		;;
+
+		/* multiply and subtract */
+		carry = 0
+		for i = 0; i < n; i++
+			p = qhat * (v.dig[i] castto(uint64))
+
+			t = (u.dig[i+j] castto(uint64)) - carry - (p % Base)
+			u.dig[i+j] = t castto(uint32)
+
+			carry = (((p castto(int64)) >> 32) - ((t castto(int64)) >> 32)) castto(uint64);
+		;;
+		t = (u.dig[j + n] castto(uint64)) - carry
+		u.dig[j + n] = t castto(uint32)
+		q.dig[j] = qhat castto(uint32)
+		/* adjust */
+		if t castto(int64) < 0
+			q.dig[j]--
+			carry = 0
+			for i = 0; i < n; i++
+				t = (u.dig[i+j] castto(uint64)) + (v.dig[i] castto(uint64)) + carry
+				u.dig[i+j] = t castto(uint32)
+				carry = t >> 32
+			;;
+			u.dig[j+n] = u.dig[j+n] + (carry castto(uint32));
+		;;
+
+	;;
+	/* undo the biasing for remainder */
+	u = bigshri(u, shift)
+	-> (trim(q), trim(u))
+}
+
+/* computes b^e % m */
+const bigmodpow = {base, exp, mod
+	var r, n
+
+	r = mkbigint(1)
+	n = 0
+    	while !bigiszero(exp)
+		if (exp.dig[0] & 1) != 0
+			bigmul(r, base)
+			bigmod(r, mod)
+		;;
+		bigshri(exp, 1)
+		bigmul(base, base)
+		bigmod(base, mod)
+	;;
+	-> bigmove(base, r)
+}
+
+/* returns the number of leading zeros */
+const nlz = {a : uint32
+	var n
+
+	if a == 0
+		-> 32
+	;;
+	n = 0
+	if a <= 0x0000ffff
+		n += 16
+		a <<= 16
+	;;
+	if a <= 0x00ffffff
+		n += 8
+		a <<= 8
+	;;
+	if a <= 0x0fffffff
+		n += 4
+		a <<= 4
+	;;
+	if a <= 0x3fffffff
+		n += 2
+		a <<= 2
+	;;
+	if a <= 0x7fffffff
+		n += 1
+		a <<= 1
+	;;
+	-> n
+}
+
+
+/* a <<= b */
+const bigshl = {a, b
+	match b.dig.len
+	| 0:	-> a
+	| 1:	-> bigshli(a, b.dig[0] castto(uint64))
+	| n:	die("shift by way too much\n")
+	;;
+}
+
+/* a >>= b, unsigned */
+const bigshr = {a, b
+	match b.dig.len
+	| 0:	-> a
+	| 1:	-> bigshri(a, b.dig[0] castto(uint64))
+	| n:	die("shift by way too much\n")
+	;;
+}
+
+/* a + b, b is integer.
+FIXME: acually make this a performace improvement
+*/
+generic bigaddi = {a, b
+	var bigb : bigint
+	var dig : uint32[2]
+
+	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigadd(a, &bigb)
+	-> a
+}
+
+generic bigsubi = {a, b : @a::(numeric,integral)
+	var bigb : bigint
+	var dig : uint32[2]
+
+	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigsub(a, &bigb)
+	-> a
+}
+
+generic bigmuli = {a, b
+	var bigb : bigint
+	var dig : uint32[2]
+
+	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigmul(a, &bigb)
+	-> a
+}
+
+generic bigdivi = {a, b
+	var bigb : bigint
+	var dig : uint32[2]
+
+	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigdiv(a, &bigb)
+	-> a
+}
+
+/* 
+  a << s, with integer arg.
+  logical left shift. any other type would be illogical.
+ */
+generic bigshli = {a, s : @a::(numeric,integral)
+	var off, shift
+	var t, carry
+	var i
+
+	assert(s >= 0, "shift amount must be positive")
+	off = (s castto(uint64)) / 32
+	shift = (s castto(uint64)) % 32
+
+	/* zero shifted by anything is zero */
+	if a.sign == 0
+		-> a
+	;;
+	a.dig = slzgrow(a.dig, 1 + a.dig.len + off castto(size))
+	/* blit over the base values */
+	for i = a.dig.len; i > off; i--
+		a.dig[i - 1] = a.dig[i - 1 - off]
+	;;
+	for i = 0; i < off; i++
+		a.dig[i] = 0
+	;;
+	/* and shift over by the remainder */
+	carry = 0
+	for i = 0; i < a.dig.len; i++
+		t = (a.dig[i] castto(uint64)) << shift
+		a.dig[i] = (t | carry) castto(uint32) 
+		carry = t >> 32
+	;;
+	-> trim(a)
+}
+
+/* logical shift right, zero fills. sign remains untouched. */
+generic bigshri = {a, s
+	var off, shift
+	var t, carry
+	var i
+
+	assert(s >= 0, "shift amount must be positive")
+	off = (s castto(uint64)) / 32
+	shift = (s castto(uint64)) % 32
+
+	/* blit over the base values */
+	for i = 0; i < a.dig.len - off; i++
+		a.dig[i] = a.dig[i + off]
+	;;
+	for i = a.dig.len - off; i < a.dig.len; i++
+		a.dig[i] = 0
+	;;
+	/* and shift over by the remainder */
+	carry = 0
+	for i = a.dig.len; i > 0; i--
+		t = (a.dig[i - 1] castto(uint64))
+		a.dig[i - 1] = (carry | (t >> shift)) castto(uint32) 
+		carry = t << (32 - shift)
+	;;
+	-> trim(a)
+}
+
+/* creates a bigint on the stack; should not be modified. */
+const bigdigit = {v, isneg : bool, val : uint64, dig
+	v.sign = 1
+	if isneg
+		val = -val
+		v.sign = -1
+	;;
+	if val == 0
+		v.sign = 0
+		v.dig = [][:]
+	elif val < Base
+		v.dig = dig[:1]
+		v.dig[0] = val castto(uint32)
+	else
+		v.dig = dig
+		v.dig[0] = val castto(uint32)
+		v.dig[1] = (val >> 32) castto(uint32)
+	;;
+}
+
+/* trims leading zeros */
+const trim = {a
+	var i
+
+	for i = a.dig.len; i > 0; i--
+		if a.dig[i - 1] != 0
+			break
+		;;
+	;;
+	a.dig = slgrow(a.dig, i)
+	if i == 0
+		a.sign = 0
+	elif a.sign == 0
+		a.sign = 1
+	;;
+	-> a
+}
+
--- /dev/null
+++ b/lib/std/bitset.myr
@@ -1,0 +1,155 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "mk.use"
+use "slcp.use"
+use "sldup.use"
+use "slfill.use"
+use "types.use"
+
+pkg std =
+	type bitset = struct
+		bits : size[:]
+	;;
+
+	const mkbs	: (-> bitset#)
+	const bsdup	: (bs : bitset# -> bitset#)
+	const bsfree	: (bs : bitset# -> void)
+
+	const bsmax	: (a : bitset# -> size)
+
+	generic bsput	: (bs : bitset#, v : @a::(integral,numeric) -> void)
+	generic bsdel	: (bs : bitset#, v : @a::(integral,numeric) -> void)
+	generic bshas	: (bs : bitset#, v : @a::(integral,numeric) -> bool)
+
+	const bsdiff	: (a : bitset#, b : bitset# -> void)
+	const bsintersect	: (a : bitset#, b : bitset# -> void)
+	const bsunion	: (a : bitset#, b : bitset# -> void)
+	const bseq	: (a : bitset#, b : bitset# -> bool)
+	const bsissubset	: (a : bitset#, b : bitset# -> bool)
+
+
+	const bsclear	: (bs : bitset# -> bitset#)
+;;
+
+const mkbs = {
+	-> zalloc()
+}
+
+const bsdup = {bs
+	-> mk([.bits=sldup(bs.bits)])
+}
+
+const bsfree = {bs
+	slfree(bs.bits)
+	free(bs)
+}
+
+const bsclear = {bs
+	slfill(bs.bits, 0)
+	-> bs
+}
+
+const bsmax = {bs
+	-> bs.bits.len * sizeof(size) * 8
+}
+
+generic bsput = {bs, v
+	var idx
+	var off
+
+	idx = (v castto(size)) / (8*sizeof(size))
+	off = (v castto(size)) % (8*sizeof(size))
+	ensurelen(bs, idx)
+	bs.bits[idx] |= (1 << off)
+}
+
+generic bsdel = {bs, v
+	var idx
+	var off
+
+	idx = (v castto(size)) / (8*sizeof(size))
+	off = (v castto(size)) % (8*sizeof(size))
+	if idx >= bs.bits.len
+		->
+	;;
+	bs.bits[idx] &= ~(1 << off)
+}
+
+generic bshas = {bs, v
+	var idx
+	var off
+
+	idx = (v castto(size)) / (8*sizeof(size))
+	off = (v castto(size)) % (8*sizeof(size))
+	if idx >= bs.bits.len
+		-> false
+	;;
+	-> (bs.bits[idx] & (1 << off)) != 0
+}
+
+const bsunion = {a, b
+	var i
+
+	eqsz(a, b)
+	for i = 0; i < b.bits.len; i++
+		a.bits[i] |= b.bits[i]
+	;;
+}
+
+const bsintersect = {a, b
+	var i, n
+
+	n = min(a.bits.len, b.bits.len)
+	for i = 0; i < n; i++
+		a.bits[i] &= b.bits[i]
+	;;
+}
+
+const bsdiff = {a, b
+	var i, n
+
+	n = min(b.bits.len, a.bits.len)
+	for i = 0; i < n; i++
+		a.bits[i] &= ~b.bits[i]
+	;;
+}
+
+const bsissubset = {a, b
+	var i
+
+	eqsz(a, b);
+	for i = 0; i < a.bits.len; i++
+		if (b.bits[i] & a.bits[i]) != b.bits[i]
+			-> false
+		;;
+	;;
+	-> true
+}
+
+const bseq = {a, b
+	var i
+
+	eqsz(a, b)
+	for i = 0; i < a.bits.len; i++
+		if a.bits[i] != b.bits[i]
+			-> false
+		;;
+	;;
+	-> true
+}
+
+const ensurelen = {bs, len
+	if bs.bits.len <= len
+		bs.bits = slzgrow(bs.bits, len + 1)
+	;;
+}
+
+const eqsz = {a, b
+	var sz
+
+	sz = max(a.bits.len, b.bits.len)
+	ensurelen(a, sz)
+	ensurelen(b, sz)
+}
+
--- /dev/null
+++ b/lib/std/blat.myr
@@ -1,0 +1,32 @@
+use "syswrap.use"
+
+pkg std =
+	const blat : (path : byte[:], buf : byte[:], perm : int64 -> bool)
+	const fblat : (f : fd, buf : byte[:] -> bool)
+;;
+
+const blat = {path, buf, perm
+	var fd
+
+	fd = openmode(path, Ocreat|Owronly, perm)
+	if fd < 0
+		-> false
+	;;
+	-> fblat(fd, buf)
+}
+
+
+const fblat = {fd, buf
+	var written, n
+
+	n = 0
+	while true
+		written = write(fd, buf[n:])
+		if written <= 0
+			goto done
+		;;
+		n += written
+	;;
+:done
+	-> written == 0 && n == buf.len
+}
--- /dev/null
+++ b/lib/std/bld.sub
@@ -1,0 +1,103 @@
+lib sys =
+	sys+freebsd-x64.myr
+	sys+linux-x64.myr
+	sys+osx-x64.myr
+	sys+plan9-x64.myr
+	syscall+freebsd-x64.s
+	syscall+linux-x64.s
+	syscall+osx-x64.s
+	syscall+plan9-x64.s
+	syserrno+linux.myr
+	syserrno+osx.myr
+	systypes.myr
+	ifreq+freebsd.myr
+	ifreq+linux.myr
+	ifreq+osx.myr
+	ifreq+plan9.myr
+	ifreq.myr	# dummy file: plan9 doesn't have ifreq
+	util+plan9-x64.s
+	util+posixy-x64.s
+;;
+
+lib std {inc=.} =
+	lib sys
+
+	# portable files
+	alloc.myr
+	bigint.myr
+	bitset.myr
+	blat.myr
+	chartype.myr
+	clear.myr
+	cmp.myr
+	cstrconv.myr
+	die.myr
+	dirname.myr
+	endian.myr
+	errno.myr
+	execvp.myr
+	extremum.myr
+	fltbits.myr
+	fltfmt.myr
+        fmt.myr
+	fmtfuncs.myr
+	getcwd.myr
+	getint.myr
+	hashfuncs.myr
+	hasprefix.myr
+	hassuffix.myr
+	htab.myr
+	intparse.myr
+        introspect.myr
+	ipparse.myr
+	mk.myr
+	mkpath.myr
+	now.myr
+	option.myr
+	optparse.myr
+	pathjoin.myr
+	putint.myr
+	rand.myr
+	result.myr
+	search.myr
+	slcp.myr
+	sldup.myr
+	sleq.myr
+	slfill.myr
+	sljoin.myr
+	slpush.myr
+	slput.myr
+	slurp.myr
+	sort.myr
+	spork.myr
+	strbuf.myr
+	strfind.myr
+	strjoin.myr
+	strsplit.myr
+	strstrip.myr
+	swap.myr
+	try.myr
+	types.myr
+	units.myr
+	utf.myr
+	varargs.myr
+
+	# platform specific files
+	env+plan9.myr
+	env+posixy.myr
+	errno+plan9.myr
+	dir+freebsd.myr
+	dir+linux.myr
+	dir+osx.myr
+	wait+posixy.myr
+	wait+plan9.myr
+	dial+posixy.myr
+	dial+plan9.myr
+	resolve+posixy.myr
+	resolve+plan9.myr
+	syswrap-ss+linux.myr
+	syswrap-ss+osx.myr
+	syswrap-ss+plan9.myr
+	syswrap+plan9.myr
+	syswrap+posixy.myr
+;;
--- /dev/null
+++ b/lib/std/build.sh
@@ -1,0 +1,8 @@
+#!/bin/bash
+
+if [ -z "`which mbld`" ]; then
+    ../myrbuild/myrbuild -I. -C$MYR_MC -M$MYR_MUSE $@
+else
+    mbld
+fi
+
--- /dev/null
+++ b/lib/std/chartype.myr
@@ -1,0 +1,1242 @@
+use "die.use"
+use "types.use"
+
+/* 
+   Tables adapted from plan 9's runetype.c,
+   which lives in sys/src/libc/port/runetype.c
+*/
+
+pkg std =
+	/* predicates */
+	const isalpha	: (c : char -> bool)
+	const isdigit	: (c : char -> bool)
+	const isxdigit	: (c : char -> bool)
+	const isnum	: (c : char -> bool)
+	const isalnum	: (c : char -> bool)
+	const isspace	: (c : char -> bool)
+	const isblank	: (c : char -> bool)
+	const islower	: (c : char -> bool)
+	const isupper	: (c : char -> bool)
+	const istitle	: (c : char -> bool)
+
+	/* transforms */
+	const tolower	: (c : char -> char)
+	const toupper	: (c : char -> char)
+	const totitle	: (c : char -> char)
+
+	generic charval : (c : char, base : int -> @a::(integral,numeric))
+;;
+
+extern const put	: (fmt : byte[:], args : ... -> size)
+
+/*
+ * alpha ranges -
+ *	only covers ranges not in lower||upper
+ */
+const ralpha2 = [
+	0x00d8,	0x00f6,	/* Ø - ö */
+	0x00f8,	0x01f5,	/* ø - ǵ */
+	0x0250,	0x02a8,	/* ɐ - ʨ */
+	0x038e,	0x03a1,	/* Ύ - Ρ */
+	0x03a3,	0x03ce,	/* Σ - ώ */
+	0x03d0,	0x03d6,	/* ϐ - ϖ */
+	0x03e2,	0x03f3,	/* Ϣ - ϳ */
+	0x0490,	0x04c4,	/* Ґ - ӄ */
+	0x0561,	0x0587,	/* ա - և */
+	0x05d0,	0x05ea,	/* א - ת */
+	0x05f0,	0x05f2,	/* װ - ײ */
+	0x0621,	0x063a,	/* ء - غ */
+	0x0640,	0x064a,	/* ـ - ي */
+	0x0671,	0x06b7,	/* ٱ - ڷ */
+	0x06ba,	0x06be,	/* ں - ھ */
+	0x06c0,	0x06ce,	/* ۀ - ێ */
+	0x06d0,	0x06d3,	/* ې - ۓ */
+	0x0905,	0x0939,	/* अ - ह */
+	0x0958,	0x0961,	/* क़ - ॡ */
+	0x0985,	0x098c,	/* অ - ঌ */
+	0x098f,	0x0990,	/* এ - ঐ */
+	0x0993,	0x09a8,	/* ও - ন */
+	0x09aa,	0x09b0,	/* প - র */
+	0x09b6,	0x09b9,	/* শ - হ */
+	0x09dc,	0x09dd,	/* ড় - ঢ় */
+	0x09df,	0x09e1,	/* য় - ৡ */
+	0x09f0,	0x09f1,	/* ৰ - ৱ */
+	0x0a05,	0x0a0a,	/* ਅ - ਊ */
+	0x0a0f,	0x0a10,	/* ਏ - ਐ */
+	0x0a13,	0x0a28,	/* ਓ - ਨ */
+	0x0a2a,	0x0a30,	/* ਪ - ਰ */
+	0x0a32,	0x0a33,	/* ਲ - ਲ਼ */
+	0x0a35,	0x0a36,	/* ਵ - ਸ਼ */
+	0x0a38,	0x0a39,	/* ਸ - ਹ */
+	0x0a59,	0x0a5c,	/* ਖ਼ - ੜ */
+	0x0a85,	0x0a8b,	/* અ - ઋ */
+	0x0a8f,	0x0a91,	/* એ - ઑ */
+	0x0a93,	0x0aa8,	/* ઓ - ન */
+	0x0aaa,	0x0ab0,	/* પ - ર */
+	0x0ab2,	0x0ab3,	/* લ - ળ */
+	0x0ab5,	0x0ab9,	/* વ - હ */
+	0x0b05,	0x0b0c,	/* ଅ - ଌ */
+	0x0b0f,	0x0b10,	/* ଏ - ଐ */
+	0x0b13,	0x0b28,	/* ଓ - ନ */
+	0x0b2a,	0x0b30,	/* ପ - ର */
+	0x0b32,	0x0b33,	/* ଲ - ଳ */
+	0x0b36,	0x0b39,	/* ଶ - ହ */
+	0x0b5c,	0x0b5d,	/* ଡ଼ - ଢ଼ */
+	0x0b5f,	0x0b61,	/* ୟ - ୡ */
+	0x0b85,	0x0b8a,	/* அ - ஊ */
+	0x0b8e,	0x0b90,	/* எ - ஐ */
+	0x0b92,	0x0b95,	/* ஒ - க */
+	0x0b99,	0x0b9a,	/* ங - ச */
+	0x0b9e,	0x0b9f,	/* ஞ - ட */
+	0x0ba3,	0x0ba4,	/* ண - த */
+	0x0ba8,	0x0baa,	/* ந - ப */
+	0x0bae,	0x0bb5,	/* ம - வ */
+	0x0bb7,	0x0bb9,	/* ஷ - ஹ */
+	0x0c05,	0x0c0c,	/* అ - ఌ */
+	0x0c0e,	0x0c10,	/* ఎ - ఐ */
+	0x0c12,	0x0c28,	/* ఒ - న */
+	0x0c2a,	0x0c33,	/* ప - ళ */
+	0x0c35,	0x0c39,	/* వ - హ */
+	0x0c60,	0x0c61,	/* ౠ - ౡ */
+	0x0c85,	0x0c8c,	/* ಅ - ಌ */
+	0x0c8e,	0x0c90,	/* ಎ - ಐ */
+	0x0c92,	0x0ca8,	/* ಒ - ನ */
+	0x0caa,	0x0cb3,	/* ಪ - ಳ */
+	0x0cb5,	0x0cb9,	/* ವ - ಹ */
+	0x0ce0,	0x0ce1,	/* ೠ - ೡ */
+	0x0d05,	0x0d0c,	/* അ - ഌ */
+	0x0d0e,	0x0d10,	/* എ - ഐ */
+	0x0d12,	0x0d28,	/* ഒ - ന */
+	0x0d2a,	0x0d39,	/* പ - ഹ */
+	0x0d60,	0x0d61,	/* ൠ - ൡ */
+	0x0e01,	0x0e30,	/* ก - ะ */
+	0x0e32,	0x0e33,	/* า - ำ */
+	0x0e40,	0x0e46,	/* เ - ๆ */
+	0x0e5a,	0x0e5b,	/* ๚ - ๛ */
+	0x0e81,	0x0e82,	/* ກ - ຂ */
+	0x0e87,	0x0e88,	/* ງ - ຈ */
+	0x0e94,	0x0e97,	/* ດ - ທ */
+	0x0e99,	0x0e9f,	/* ນ - ຟ */
+	0x0ea1,	0x0ea3,	/* ມ - ຣ */
+	0x0eaa,	0x0eab,	/* ສ - ຫ */
+	0x0ead,	0x0eae,	/* ອ - ຮ */
+	0x0eb2,	0x0eb3,	/* າ - ຳ */
+	0x0ec0,	0x0ec4,	/* ເ - ໄ */
+	0x0edc,	0x0edd,	/* ໜ - ໝ */
+	0x0f18,	0x0f19,	/* ༘ - ༙ */
+	0x0f40,	0x0f47,	/* ཀ - ཇ */
+	0x0f49,	0x0f69,	/* ཉ - ཀྵ */
+	0x10d0,	0x10f6,	/* ა - ჶ */
+	0x1100,	0x1159,	/* ᄀ - ᅙ */
+	0x115f,	0x11a2,	/* ᅟ - ᆢ */
+	0x11a8,	0x11f9,	/* ᆨ - ᇹ */
+	0x1e00,	0x1e9b,	/* Ḁ - ẛ */
+	0x1f50,	0x1f57,	/* ὐ - ὗ */
+	0x1f80,	0x1fb4,	/* ᾀ - ᾴ */
+	0x1fb6,	0x1fbc,	/* ᾶ - ᾼ */
+	0x1fc2,	0x1fc4,	/* ῂ - ῄ */
+	0x1fc6,	0x1fcc,	/* ῆ - ῌ */
+	0x1fd0,	0x1fd3,	/* ῐ - ΐ */
+	0x1fd6,	0x1fdb,	/* ῖ - Ί */
+	0x1fe0,	0x1fec,	/* ῠ - Ῥ */
+	0x1ff2,	0x1ff4,	/* ῲ - ῴ */
+	0x1ff6,	0x1ffc,	/* ῶ - ῼ */
+	0x210a,	0x2113,	/* ℊ - ℓ */
+	0x2115,	0x211d,	/* ℕ - ℝ */
+	0x2120,	0x2122,	/* ℠ - ™ */
+	0x212a,	0x2131,	/* K - ℱ */
+	0x2133,	0x2138,	/* ℳ - ℸ */
+	0x3041,	0x3094,	/* ぁ - ゔ */
+	0x30a1,	0x30fa,	/* ァ - ヺ */
+	0x3105,	0x312c,	/* ㄅ - ㄬ */
+	0x3131,	0x318e,	/* ㄱ - ㆎ */
+	0x3192,	0x319f,	/* ㆒ - ㆟ */
+	0x3260,	0x327b,	/* ㉠ - ㉻ */
+	0x328a,	0x32b0,	/* ㊊ - ㊰ */
+	0x32d0,	0x32fe,	/* ㋐ - ㋾ */
+	0x3300,	0x3357,	/* ㌀ - ㍗ */
+	0x3371,	0x3376,	/* ㍱ - ㍶ */
+	0x337b,	0x3394,	/* ㍻ - ㎔ */
+	0x3399,	0x339e,	/* ㎙ - ㎞ */
+	0x33a9,	0x33ad,	/* ㎩ - ㎭ */
+	0x33b0,	0x33c1,	/* ㎰ - ㏁ */
+	0x33c3,	0x33c5,	/* ㏃ - ㏅ */
+	0x33c7,	0x33d7,	/* ㏇ - ㏗ */
+	0x33d9,	0x33dd,	/* ㏙ - ㏝ */
+	0x4e00,	0x9fff,	/* 一 - 鿿 */
+	0xac00,	0xd7a3,	/* 가 - 힣 */
+	0xf900,	0xfb06,	/* 豈 - st */
+	0xfb13,	0xfb17,	/* ﬓ - ﬗ */
+	0xfb1f,	0xfb28,	/* ײַ - ﬨ */
+	0xfb2a,	0xfb36,	/* שׁ - זּ */
+	0xfb38,	0xfb3c,	/* טּ - לּ */
+	0xfb40,	0xfb41,	/* נּ - סּ */
+	0xfb43,	0xfb44,	/* ףּ - פּ */
+	0xfb46,	0xfbb1,	/* צּ - ﮱ */
+	0xfbd3,	0xfd3d,	/* ﯓ - ﴽ */
+	0xfd50,	0xfd8f,	/* ﵐ - ﶏ */
+	0xfd92,	0xfdc7,	/* ﶒ - ﷇ */
+	0xfdf0,	0xfdf9,	/* ﷰ - ﷹ */
+	0xfe70,	0xfe72,	/* ﹰ - ﹲ */
+	0xfe76,	0xfefc,	/* ﹶ - ﻼ */
+	0xff66,	0xff6f,	/* ヲ - ッ */
+	0xff71,	0xff9d,	/* ア - ン */
+	0xffa0,	0xffbe,	/* ᅠ - ᄒ */
+	0xffc2,	0xffc7,	/* ᅡ - ᅦ */
+	0xffca,	0xffcf,	/* ᅧ - ᅬ */
+	0xffd2,	0xffd7,	/* ᅭ - ᅲ */
+	0xffda,	0xffdc	/* ᅳ - ᅵ */
+]
+
+/*
+ * alpha singlets -
+ *	only covers ranges not in lower||upper
+ */
+const ralpha1 = [
+	0x00aa,	/* ª */
+	0x00b5,	/* µ */
+	0x00ba,	/* º */
+	0x03da,	/* Ϛ */
+	0x03dc,	/* Ϝ */
+	0x03de,	/* Ϟ */
+	0x03e0,	/* Ϡ */
+	0x06d5,	/* ە */
+	0x09b2,	/* ল */
+	0x0a5e,	/* ਫ਼ */
+	0x0a8d,	/* ઍ */
+	0x0ae0,	/* ૠ */
+	0x0b9c,	/* ஜ */
+	0x0cde,	/* ೞ */
+	0x0e4f,	/* ๏ */
+	0x0e84,	/* ຄ */
+	0x0e8a,	/* ຊ */
+	0x0e8d,	/* ຍ */
+	0x0ea5,	/* ລ */
+	0x0ea7,	/* ວ */
+	0x0eb0,	/* ະ */
+	0x0ebd,	/* ຽ */
+	0x1fbe,	/* ι */
+	0x207f,	/* ⁿ */
+	0x20a8,	/* ₨ */
+	0x2102,	/* ℂ */
+	0x2107,	/* ℇ */
+	0x2124,	/* ℤ */
+	0x2126,	/* Ω */
+	0x2128,	/* ℨ */
+	0xfb3e,	/* מּ */
+	0xfe74	/* ﹴ */
+]
+
+/*
+ * space ranges
+ */
+const rspace2 = [
+	0x0009,	0x0009,	/* tab */
+	0x0020,	0x0020,	/* space */
+	0x0085, 0x0085,
+	0x00a0,	0x00a0,	/*   */
+	0x1680, 0x1680,
+	0x180e, 0x180e,
+	0x2000,	0x200b,	/*   - ​ */
+	0x2028,	0x2029,	/* 
 - 
 */
+	0x202f, 0x202f,
+	0x205f, 0x205f,
+	0x3000,	0x3000,	/*   */
+	0xfeff,	0xfeff	/*  */
+]
+
+/*
+ * lower case ranges
+ *	3rd col is conversion excess 500
+ */
+const rtoupper2 = [
+	0x0061,	0x007a, 468,	/* a-z A-Z */
+	0x00e0,	0x00f6, 468,	/* à-ö À-Ö */
+	0x00f8,	0x00fe, 468,	/* ø-þ Ø-Þ */
+	0x0256,	0x0257, 295,	/* ɖ-ɗ Ɖ-Ɗ */
+	0x0258,	0x0259, 298,	/* ɘ-ə Ǝ-Ə */
+	0x028a,	0x028b, 283,	/* ʊ-ʋ Ʊ-Ʋ */
+	0x03ad,	0x03af, 463,	/* έ-ί Έ-Ί */
+	0x03b1,	0x03c1, 468,	/* α-ρ Α-Ρ */
+	0x03c3,	0x03cb, 468,	/* σ-ϋ Σ-Ϋ */
+	0x03cd,	0x03ce, 437,	/* ύ-ώ Ύ-Ώ */
+	0x0430,	0x044f, 468,	/* а-я А-Я */
+	0x0451,	0x045c, 420,	/* ё-ќ Ё-Ќ */
+	0x045e,	0x045f, 420,	/* ў-џ Ў-Џ */
+	0x0561,	0x0586, 452,	/* ա-ֆ Ա-Ֆ */
+	0x1f00,	0x1f07, 508,	/* ἀ-ἇ Ἀ-Ἇ */
+	0x1f10,	0x1f15, 508,	/* ἐ-ἕ Ἐ-Ἕ */
+	0x1f20,	0x1f27, 508,	/* ἠ-ἧ Ἠ-Ἧ */
+	0x1f30,	0x1f37, 508,	/* ἰ-ἷ Ἰ-Ἷ */
+	0x1f40,	0x1f45, 508,	/* ὀ-ὅ Ὀ-Ὅ */
+	0x1f60,	0x1f67, 508,	/* ὠ-ὧ Ὠ-Ὧ */
+	0x1f70,	0x1f71, 574,	/* ὰ-ά Ὰ-Ά */
+	0x1f72,	0x1f75, 586,	/* ὲ-ή Ὲ-Ή */
+	0x1f76,	0x1f77, 600,	/* ὶ-ί Ὶ-Ί */
+	0x1f78,	0x1f79, 628,	/* ὸ-ό Ὸ-Ό */
+	0x1f7a,	0x1f7b, 612,	/* ὺ-ύ Ὺ-Ύ */
+	0x1f7c,	0x1f7d, 626,	/* ὼ-ώ Ὼ-Ώ */
+	0x1f80,	0x1f87, 508,	/* ᾀ-ᾇ ᾈ-ᾏ */
+	0x1f90,	0x1f97, 508,	/* ᾐ-ᾗ ᾘ-ᾟ */
+	0x1fa0,	0x1fa7, 508,	/* ᾠ-ᾧ ᾨ-ᾯ */
+	0x1fb0,	0x1fb1, 508,	/* ᾰ-ᾱ Ᾰ-Ᾱ */
+	0x1fd0,	0x1fd1, 508,	/* ῐ-ῑ Ῐ-Ῑ */
+	0x1fe0,	0x1fe1, 508,	/* ῠ-ῡ Ῠ-Ῡ */
+	0x2170,	0x217f, 484,	/* ⅰ-ⅿ Ⅰ-Ⅿ */
+	0x24d0,	0x24e9, 474,	/* ⓐ-ⓩ Ⓐ-Ⓩ */
+	0xff41,	0xff5a, 468	/* a-z A-Z */
+]
+
+/*
+ * lower case singlets
+ *	2nd col is conversion excess 500
+ */
+const rtoupper1 = [
+	0x00ff, 621,	/* ÿ Ÿ */
+	0x0101, 499,	/* ā Ā */
+	0x0103, 499,	/* ă Ă */
+	0x0105, 499,	/* ą Ą */
+	0x0107, 499,	/* ć Ć */
+	0x0109, 499,	/* ĉ Ĉ */
+	0x010b, 499,	/* ċ Ċ */
+	0x010d, 499,	/* č Č */
+	0x010f, 499,	/* ď Ď */
+	0x0111, 499,	/* đ Đ */
+	0x0113, 499,	/* ē Ē */
+	0x0115, 499,	/* ĕ Ĕ */
+	0x0117, 499,	/* ė Ė */
+	0x0119, 499,	/* ę Ę */
+	0x011b, 499,	/* ě Ě */
+	0x011d, 499,	/* ĝ Ĝ */
+	0x011f, 499,	/* ğ Ğ */
+	0x0121, 499,	/* ġ Ġ */
+	0x0123, 499,	/* ģ Ģ */
+	0x0125, 499,	/* ĥ Ĥ */
+	0x0127, 499,	/* ħ Ħ */
+	0x0129, 499,	/* ĩ Ĩ */
+	0x012b, 499,	/* ī Ī */
+	0x012d, 499,	/* ĭ Ĭ */
+	0x012f, 499,	/* į Į */
+	0x0131, 268,	/* ı I */
+	0x0133, 499,	/* ij IJ */
+	0x0135, 499,	/* ĵ Ĵ */
+	0x0137, 499,	/* ķ Ķ */
+	0x013a, 499,	/* ĺ Ĺ */
+	0x013c, 499,	/* ļ Ļ */
+	0x013e, 499,	/* ľ Ľ */
+	0x0140, 499,	/* ŀ Ŀ */
+	0x0142, 499,	/* ł Ł */
+	0x0144, 499,	/* ń Ń */
+	0x0146, 499,	/* ņ Ņ */
+	0x0148, 499,	/* ň Ň */
+	0x014b, 499,	/* ŋ Ŋ */
+	0x014d, 499,	/* ō Ō */
+	0x014f, 499,	/* ŏ Ŏ */
+	0x0151, 499,	/* ő Ő */
+	0x0153, 499,	/* œ Œ */
+	0x0155, 499,	/* ŕ Ŕ */
+	0x0157, 499,	/* ŗ Ŗ */
+	0x0159, 499,	/* ř Ř */
+	0x015b, 499,	/* ś Ś */
+	0x015d, 499,	/* ŝ Ŝ */
+	0x015f, 499,	/* ş Ş */
+	0x0161, 499,	/* š Š */
+	0x0163, 499,	/* ţ Ţ */
+	0x0165, 499,	/* ť Ť */
+	0x0167, 499,	/* ŧ Ŧ */
+	0x0169, 499,	/* ũ Ũ */
+	0x016b, 499,	/* ū Ū */
+	0x016d, 499,	/* ŭ Ŭ */
+	0x016f, 499,	/* ů Ů */
+	0x0171, 499,	/* ű Ű */
+	0x0173, 499,	/* ų Ų */
+	0x0175, 499,	/* ŵ Ŵ */
+	0x0177, 499,	/* ŷ Ŷ */
+	0x017a, 499,	/* ź Ź */
+	0x017c, 499,	/* ż Ż */
+	0x017e, 499,	/* ž Ž */
+	0x017f, 200,	/* ſ S */
+	0x0183, 499,	/* ƃ Ƃ */
+	0x0185, 499,	/* ƅ Ƅ */
+	0x0188, 499,	/* ƈ Ƈ */
+	0x018c, 499,	/* ƌ Ƌ */
+	0x0192, 499,	/* ƒ Ƒ */
+	0x0199, 499,	/* ƙ Ƙ */
+	0x01a1, 499,	/* ơ Ơ */
+	0x01a3, 499,	/* ƣ Ƣ */
+	0x01a5, 499,	/* ƥ Ƥ */
+	0x01a8, 499,	/* ƨ Ƨ */
+	0x01ad, 499,	/* ƭ Ƭ */
+	0x01b0, 499,	/* ư Ư */
+	0x01b4, 499,	/* ƴ Ƴ */
+	0x01b6, 499,	/* ƶ Ƶ */
+	0x01b9, 499,	/* ƹ Ƹ */
+	0x01bd, 499,	/* ƽ Ƽ */
+	0x01c5, 499,	/* Dž DŽ */
+	0x01c6, 498,	/* dž DŽ */
+	0x01c8, 499,	/* Lj LJ */
+	0x01c9, 498,	/* lj LJ */
+	0x01cb, 499,	/* Nj NJ */
+	0x01cc, 498,	/* nj NJ */
+	0x01ce, 499,	/* ǎ Ǎ */
+	0x01d0, 499,	/* ǐ Ǐ */
+	0x01d2, 499,	/* ǒ Ǒ */
+	0x01d4, 499,	/* ǔ Ǔ */
+	0x01d6, 499,	/* ǖ Ǖ */
+	0x01d8, 499,	/* ǘ Ǘ */
+	0x01da, 499,	/* ǚ Ǚ */
+	0x01dc, 499,	/* ǜ Ǜ */
+	0x01df, 499,	/* ǟ Ǟ */
+	0x01e1, 499,	/* ǡ Ǡ */
+	0x01e3, 499,	/* ǣ Ǣ */
+	0x01e5, 499,	/* ǥ Ǥ */
+	0x01e7, 499,	/* ǧ Ǧ */
+	0x01e9, 499,	/* ǩ Ǩ */
+	0x01eb, 499,	/* ǫ Ǫ */
+	0x01ed, 499,	/* ǭ Ǭ */
+	0x01ef, 499,	/* ǯ Ǯ */
+	0x01f2, 499,	/* Dz DZ */
+	0x01f3, 498,	/* dz DZ */
+	0x01f5, 499,	/* ǵ Ǵ */
+	0x01fb, 499,	/* ǻ Ǻ */
+	0x01fd, 499,	/* ǽ Ǽ */
+	0x01ff, 499,	/* ǿ Ǿ */
+	0x0201, 499,	/* ȁ Ȁ */
+	0x0203, 499,	/* ȃ Ȃ */
+	0x0205, 499,	/* ȅ Ȅ */
+	0x0207, 499,	/* ȇ Ȇ */
+	0x0209, 499,	/* ȉ Ȉ */
+	0x020b, 499,	/* ȋ Ȋ */
+	0x020d, 499,	/* ȍ Ȍ */
+	0x020f, 499,	/* ȏ Ȏ */
+	0x0211, 499,	/* ȑ Ȑ */
+	0x0213, 499,	/* ȓ Ȓ */
+	0x0215, 499,	/* ȕ Ȕ */
+	0x0217, 499,	/* ȗ Ȗ */
+	0x0253, 290,	/* ɓ Ɓ */
+	0x0254, 294,	/* ɔ Ɔ */
+	0x025b, 297,	/* ɛ Ɛ */
+	0x0260, 295,	/* ɠ Ɠ */
+	0x0263, 293,	/* ɣ Ɣ */
+	0x0268, 291,	/* ɨ Ɨ */
+	0x0269, 289,	/* ɩ Ɩ */
+	0x026f, 289,	/* ɯ Ɯ */
+	0x0272, 287,	/* ɲ Ɲ */
+	0x0283, 282,	/* ʃ Ʃ */
+	0x0288, 282,	/* ʈ Ʈ */
+	0x0292, 281,	/* ʒ Ʒ */
+	0x03ac, 462,	/* ά Ά */
+	0x03cc, 436,	/* ό Ό */
+	0x03d0, 438,	/* ϐ Β */
+	0x03d1, 443,	/* ϑ Θ */
+	0x03d5, 453,	/* ϕ Φ */
+	0x03d6, 446,	/* ϖ Π */
+	0x03e3, 499,	/* ϣ Ϣ */
+	0x03e5, 499,	/* ϥ Ϥ */
+	0x03e7, 499,	/* ϧ Ϧ */
+	0x03e9, 499,	/* ϩ Ϩ */
+	0x03eb, 499,	/* ϫ Ϫ */
+	0x03ed, 499,	/* ϭ Ϭ */
+	0x03ef, 499,	/* ϯ Ϯ */
+	0x03f0, 414,	/* ϰ Κ */
+	0x03f1, 420,	/* ϱ Ρ */
+	0x0461, 499,	/* ѡ Ѡ */
+	0x0463, 499,	/* ѣ Ѣ */
+	0x0465, 499,	/* ѥ Ѥ */
+	0x0467, 499,	/* ѧ Ѧ */
+	0x0469, 499,	/* ѩ Ѩ */
+	0x046b, 499,	/* ѫ Ѫ */
+	0x046d, 499,	/* ѭ Ѭ */
+	0x046f, 499,	/* ѯ Ѯ */
+	0x0471, 499,	/* ѱ Ѱ */
+	0x0473, 499,	/* ѳ Ѳ */
+	0x0475, 499,	/* ѵ Ѵ */
+	0x0477, 499,	/* ѷ Ѷ */
+	0x0479, 499,	/* ѹ Ѹ */
+	0x047b, 499,	/* ѻ Ѻ */
+	0x047d, 499,	/* ѽ Ѽ */
+	0x047f, 499,	/* ѿ Ѿ */
+	0x0481, 499,	/* ҁ Ҁ */
+	0x0491, 499,	/* ґ Ґ */
+	0x0493, 499,	/* ғ Ғ */
+	0x0495, 499,	/* ҕ Ҕ */
+	0x0497, 499,	/* җ Җ */
+	0x0499, 499,	/* ҙ Ҙ */
+	0x049b, 499,	/* қ Қ */
+	0x049d, 499,	/* ҝ Ҝ */
+	0x049f, 499,	/* ҟ Ҟ */
+	0x04a1, 499,	/* ҡ Ҡ */
+	0x04a3, 499,	/* ң Ң */
+	0x04a5, 499,	/* ҥ Ҥ */
+	0x04a7, 499,	/* ҧ Ҧ */
+	0x04a9, 499,	/* ҩ Ҩ */
+	0x04ab, 499,	/* ҫ Ҫ */
+	0x04ad, 499,	/* ҭ Ҭ */
+	0x04af, 499,	/* ү Ү */
+	0x04b1, 499,	/* ұ Ұ */
+	0x04b3, 499,	/* ҳ Ҳ */
+	0x04b5, 499,	/* ҵ Ҵ */
+	0x04b7, 499,	/* ҷ Ҷ */
+	0x04b9, 499,	/* ҹ Ҹ */
+	0x04bb, 499,	/* һ Һ */
+	0x04bd, 499,	/* ҽ Ҽ */
+	0x04bf, 499,	/* ҿ Ҿ */
+	0x04c2, 499,	/* ӂ Ӂ */
+	0x04c4, 499,	/* ӄ Ӄ */
+	0x04c8, 499,	/* ӈ Ӈ */
+	0x04cc, 499,	/* ӌ Ӌ */
+	0x04d1, 499,	/* ӑ Ӑ */
+	0x04d3, 499,	/* ӓ Ӓ */
+	0x04d5, 499,	/* ӕ Ӕ */
+	0x04d7, 499,	/* ӗ Ӗ */
+	0x04d9, 499,	/* ә Ә */
+	0x04db, 499,	/* ӛ Ӛ */
+	0x04dd, 499,	/* ӝ Ӝ */
+	0x04df, 499,	/* ӟ Ӟ */
+	0x04e1, 499,	/* ӡ Ӡ */
+	0x04e3, 499,	/* ӣ Ӣ */
+	0x04e5, 499,	/* ӥ Ӥ */
+	0x04e7, 499,	/* ӧ Ӧ */
+	0x04e9, 499,	/* ө Ө */
+	0x04eb, 499,	/* ӫ Ӫ */
+	0x04ef, 499,	/* ӯ Ӯ */
+	0x04f1, 499,	/* ӱ Ӱ */
+	0x04f3, 499,	/* ӳ Ӳ */
+	0x04f5, 499,	/* ӵ Ӵ */
+	0x04f9, 499,	/* ӹ Ӹ */
+	0x1e01, 499,	/* ḁ Ḁ */
+	0x1e03, 499,	/* ḃ Ḃ */
+	0x1e05, 499,	/* ḅ Ḅ */
+	0x1e07, 499,	/* ḇ Ḇ */
+	0x1e09, 499,	/* ḉ Ḉ */
+	0x1e0b, 499,	/* ḋ Ḋ */
+	0x1e0d, 499,	/* ḍ Ḍ */
+	0x1e0f, 499,	/* ḏ Ḏ */
+	0x1e11, 499,	/* ḑ Ḑ */
+	0x1e13, 499,	/* ḓ Ḓ */
+	0x1e15, 499,	/* ḕ Ḕ */
+	0x1e17, 499,	/* ḗ Ḗ */
+	0x1e19, 499,	/* ḙ Ḙ */
+	0x1e1b, 499,	/* ḛ Ḛ */
+	0x1e1d, 499,	/* ḝ Ḝ */
+	0x1e1f, 499,	/* ḟ Ḟ */
+	0x1e21, 499,	/* ḡ Ḡ */
+	0x1e23, 499,	/* ḣ Ḣ */
+	0x1e25, 499,	/* ḥ Ḥ */
+	0x1e27, 499,	/* ḧ Ḧ */
+	0x1e29, 499,	/* ḩ Ḩ */
+	0x1e2b, 499,	/* ḫ Ḫ */
+	0x1e2d, 499,	/* ḭ Ḭ */
+	0x1e2f, 499,	/* ḯ Ḯ */
+	0x1e31, 499,	/* ḱ Ḱ */
+	0x1e33, 499,	/* ḳ Ḳ */
+	0x1e35, 499,	/* ḵ Ḵ */
+	0x1e37, 499,	/* ḷ Ḷ */
+	0x1e39, 499,	/* ḹ Ḹ */
+	0x1e3b, 499,	/* ḻ Ḻ */
+	0x1e3d, 499,	/* ḽ Ḽ */
+	0x1e3f, 499,	/* ḿ Ḿ */
+	0x1e41, 499,	/* ṁ Ṁ */
+	0x1e43, 499,	/* ṃ Ṃ */
+	0x1e45, 499,	/* ṅ Ṅ */
+	0x1e47, 499,	/* ṇ Ṇ */
+	0x1e49, 499,	/* ṉ Ṉ */
+	0x1e4b, 499,	/* ṋ Ṋ */
+	0x1e4d, 499,	/* ṍ Ṍ */
+	0x1e4f, 499,	/* ṏ Ṏ */
+	0x1e51, 499,	/* ṑ Ṑ */
+	0x1e53, 499,	/* ṓ Ṓ */
+	0x1e55, 499,	/* ṕ Ṕ */
+	0x1e57, 499,	/* ṗ Ṗ */
+	0x1e59, 499,	/* ṙ Ṙ */
+	0x1e5b, 499,	/* ṛ Ṛ */
+	0x1e5d, 499,	/* ṝ Ṝ */
+	0x1e5f, 499,	/* ṟ Ṟ */
+	0x1e61, 499,	/* ṡ Ṡ */
+	0x1e63, 499,	/* ṣ Ṣ */
+	0x1e65, 499,	/* ṥ Ṥ */
+	0x1e67, 499,	/* ṧ Ṧ */
+	0x1e69, 499,	/* ṩ Ṩ */
+	0x1e6b, 499,	/* ṫ Ṫ */
+	0x1e6d, 499,	/* ṭ Ṭ */
+	0x1e6f, 499,	/* ṯ Ṯ */
+	0x1e71, 499,	/* ṱ Ṱ */
+	0x1e73, 499,	/* ṳ Ṳ */
+	0x1e75, 499,	/* ṵ Ṵ */
+	0x1e77, 499,	/* ṷ Ṷ */
+	0x1e79, 499,	/* ṹ Ṹ */
+	0x1e7b, 499,	/* ṻ Ṻ */
+	0x1e7d, 499,	/* ṽ Ṽ */
+	0x1e7f, 499,	/* ṿ Ṿ */
+	0x1e81, 499,	/* ẁ Ẁ */
+	0x1e83, 499,	/* ẃ Ẃ */
+	0x1e85, 499,	/* ẅ Ẅ */
+	0x1e87, 499,	/* ẇ Ẇ */
+	0x1e89, 499,	/* ẉ Ẉ */
+	0x1e8b, 499,	/* ẋ Ẋ */
+	0x1e8d, 499,	/* ẍ Ẍ */
+	0x1e8f, 499,	/* ẏ Ẏ */
+	0x1e91, 499,	/* ẑ Ẑ */
+	0x1e93, 499,	/* ẓ Ẓ */
+	0x1e95, 499,	/* ẕ Ẕ */
+	0x1ea1, 499,	/* ạ Ạ */
+	0x1ea3, 499,	/* ả Ả */
+	0x1ea5, 499,	/* ấ Ấ */
+	0x1ea7, 499,	/* ầ Ầ */
+	0x1ea9, 499,	/* ẩ Ẩ */
+	0x1eab, 499,	/* ẫ Ẫ */
+	0x1ead, 499,	/* ậ Ậ */
+	0x1eaf, 499,	/* ắ Ắ */
+	0x1eb1, 499,	/* ằ Ằ */
+	0x1eb3, 499,	/* ẳ Ẳ */
+	0x1eb5, 499,	/* ẵ Ẵ */
+	0x1eb7, 499,	/* ặ Ặ */
+	0x1eb9, 499,	/* ẹ Ẹ */
+	0x1ebb, 499,	/* ẻ Ẻ */
+	0x1ebd, 499,	/* ẽ Ẽ */
+	0x1ebf, 499,	/* ế Ế */
+	0x1ec1, 499,	/* ề Ề */
+	0x1ec3, 499,	/* ể Ể */
+	0x1ec5, 499,	/* ễ Ễ */
+	0x1ec7, 499,	/* ệ Ệ */
+	0x1ec9, 499,	/* ỉ Ỉ */
+	0x1ecb, 499,	/* ị Ị */
+	0x1ecd, 499,	/* ọ Ọ */
+	0x1ecf, 499,	/* ỏ Ỏ */
+	0x1ed1, 499,	/* ố Ố */
+	0x1ed3, 499,	/* ồ Ồ */
+	0x1ed5, 499,	/* ổ Ổ */
+	0x1ed7, 499,	/* ỗ Ỗ */
+	0x1ed9, 499,	/* ộ Ộ */
+	0x1edb, 499,	/* ớ Ớ */
+	0x1edd, 499,	/* ờ Ờ */
+	0x1edf, 499,	/* ở Ở */
+	0x1ee1, 499,	/* ỡ Ỡ */
+	0x1ee3, 499,	/* ợ Ợ */
+	0x1ee5, 499,	/* ụ Ụ */
+	0x1ee7, 499,	/* ủ Ủ */
+	0x1ee9, 499,	/* ứ Ứ */
+	0x1eeb, 499,	/* ừ Ừ */
+	0x1eed, 499,	/* ử Ử */
+	0x1eef, 499,	/* ữ Ữ */
+	0x1ef1, 499,	/* ự Ự */
+	0x1ef3, 499,	/* ỳ Ỳ */
+	0x1ef5, 499,	/* ỵ Ỵ */
+	0x1ef7, 499,	/* ỷ Ỷ */
+	0x1ef9, 499,	/* ỹ Ỹ */
+	0x1f51, 508,	/* ὑ Ὑ */
+	0x1f53, 508,	/* ὓ Ὓ */
+	0x1f55, 508,	/* ὕ Ὕ */
+	0x1f57, 508,	/* ὗ Ὗ */
+	0x1fb3, 509,	/* ᾳ ᾼ */
+	0x1fc3, 509,	/* ῃ ῌ */
+	0x1fe5, 507,	/* ῥ Ῥ */
+	0x1ff3, 509	/* ῳ ῼ */
+]
+
+const rnums = [
+	0x0030, 0x0039,
+	0x0660, 0x0669,
+	0x06f0, 0x06f9,
+	0x07c0, 0x07c9,
+	0x0966, 0x096f,
+	0x09e6, 0x09ef,
+	0x0a66, 0x0a6f,
+	0x0ae6, 0x0aef,
+	0x0b66, 0x0b6f,
+	0x0be6, 0x0bef,
+	0x0c66, 0x0c6f,
+	0x0ce6, 0x0cef,
+	0x0d66, 0x0d6f,
+	0x0e50, 0x0e59,
+	0x0ed0, 0x0ed9,
+	0x0f20, 0x0f29,
+	0x1040, 0x1049,
+	0x17e0, 0x17e9,
+	0x1810, 0x1819,
+	0x1946, 0x194f,
+	0x19d0, 0x19d9,
+	0x1b50, 0x1b59,
+	0xff10, 0xff19,
+	0x104a0, 0x104a9,
+	0x1d7ce, 0x1d7ff
+]
+
+/*
+ * upper case ranges
+ *	3rd col is conversion excess 500
+ */
+const rtolower2 = [
+	0x0041,	0x005a, 532,	/* A-Z a-z */
+	0x00c0,	0x00d6, 532,	/* À-Ö à-ö */
+	0x00d8,	0x00de, 532,	/* Ø-Þ ø-þ */
+	0x0189,	0x018a, 705,	/* Ɖ-Ɗ ɖ-ɗ */
+	0x018e,	0x018f, 702,	/* Ǝ-Ə ɘ-ə */
+	0x01b1,	0x01b2, 717,	/* Ʊ-Ʋ ʊ-ʋ */
+	0x0388,	0x038a, 537,	/* Έ-Ί έ-ί */
+	0x038e,	0x038f, 563,	/* Ύ-Ώ ύ-ώ */
+	0x0391,	0x03a1, 532,	/* Α-Ρ α-ρ */
+	0x03a3,	0x03ab, 532,	/* Σ-Ϋ σ-ϋ */
+	0x0401,	0x040c, 580,	/* Ё-Ќ ё-ќ */
+	0x040e,	0x040f, 580,	/* Ў-Џ ў-џ */
+	0x0410,	0x042f, 532,	/* А-Я а-я */
+	0x0531,	0x0556, 548,	/* Ա-Ֆ ա-ֆ */
+	0x10a0,	0x10c5, 548,	/* Ⴀ-Ⴥ ა-ჵ */
+	0x1f08,	0x1f0f, 492,	/* Ἀ-Ἇ ἀ-ἇ */
+	0x1f18,	0x1f1d, 492,	/* Ἐ-Ἕ ἐ-ἕ */
+	0x1f28,	0x1f2f, 492,	/* Ἠ-Ἧ ἠ-ἧ */
+	0x1f38,	0x1f3f, 492,	/* Ἰ-Ἷ ἰ-ἷ */
+	0x1f48,	0x1f4d, 492,	/* Ὀ-Ὅ ὀ-ὅ */
+	0x1f68,	0x1f6f, 492,	/* Ὠ-Ὧ ὠ-ὧ */
+	0x1f88,	0x1f8f, 492,	/* ᾈ-ᾏ ᾀ-ᾇ */
+	0x1f98,	0x1f9f, 492,	/* ᾘ-ᾟ ᾐ-ᾗ */
+	0x1fa8,	0x1faf, 492,	/* ᾨ-ᾯ ᾠ-ᾧ */
+	0x1fb8,	0x1fb9, 492,	/* Ᾰ-Ᾱ ᾰ-ᾱ */
+	0x1fba,	0x1fbb, 426,	/* Ὰ-Ά ὰ-ά */
+	0x1fc8,	0x1fcb, 414,	/* Ὲ-Ή ὲ-ή */
+	0x1fd8,	0x1fd9, 492,	/* Ῐ-Ῑ ῐ-ῑ */
+	0x1fda,	0x1fdb, 400,	/* Ὶ-Ί ὶ-ί */
+	0x1fe8,	0x1fe9, 492,	/* Ῠ-Ῡ ῠ-ῡ */
+	0x1fea,	0x1feb, 388,	/* Ὺ-Ύ ὺ-ύ */
+	0x1ff8,	0x1ff9, 372,	/* Ὸ-Ό ὸ-ό */
+	0x1ffa,	0x1ffb, 374,	/* Ὼ-Ώ ὼ-ώ */
+	0x2160,	0x216f, 516,	/* Ⅰ-Ⅿ ⅰ-ⅿ */
+	0x24b6,	0x24cf, 526,	/* Ⓐ-Ⓩ ⓐ-ⓩ */
+	0xff21,	0xff3a, 532	/* A-Z a-z */
+]
+
+/*
+ * upper case singlets
+ *	2nd col is conversion excess 500
+ */
+const rtolower1 = [
+	0x0100, 501,	/* Ā ā */
+	0x0102, 501,	/* Ă ă */
+	0x0104, 501,	/* Ą ą */
+	0x0106, 501,	/* Ć ć */
+	0x0108, 501,	/* Ĉ ĉ */
+	0x010a, 501,	/* Ċ ċ */
+	0x010c, 501,	/* Č č */
+	0x010e, 501,	/* Ď ď */
+	0x0110, 501,	/* Đ đ */
+	0x0112, 501,	/* Ē ē */
+	0x0114, 501,	/* Ĕ ĕ */
+	0x0116, 501,	/* Ė ė */
+	0x0118, 501,	/* Ę ę */
+	0x011a, 501,	/* Ě ě */
+	0x011c, 501,	/* Ĝ ĝ */
+	0x011e, 501,	/* Ğ ğ */
+	0x0120, 501,	/* Ġ ġ */
+	0x0122, 501,	/* Ģ ģ */
+	0x0124, 501,	/* Ĥ ĥ */
+	0x0126, 501,	/* Ħ ħ */
+	0x0128, 501,	/* Ĩ ĩ */
+	0x012a, 501,	/* Ī ī */
+	0x012c, 501,	/* Ĭ ĭ */
+	0x012e, 501,	/* Į į */
+	0x0130, 301,	/* İ i */
+	0x0132, 501,	/* IJ ij */
+	0x0134, 501,	/* Ĵ ĵ */
+	0x0136, 501,	/* Ķ ķ */
+	0x0139, 501,	/* Ĺ ĺ */
+	0x013b, 501,	/* Ļ ļ */
+	0x013d, 501,	/* Ľ ľ */
+	0x013f, 501,	/* Ŀ ŀ */
+	0x0141, 501,	/* Ł ł */
+	0x0143, 501,	/* Ń ń */
+	0x0145, 501,	/* Ņ ņ */
+	0x0147, 501,	/* Ň ň */
+	0x014a, 501,	/* Ŋ ŋ */
+	0x014c, 501,	/* Ō ō */
+	0x014e, 501,	/* Ŏ ŏ */
+	0x0150, 501,	/* Ő ő */
+	0x0152, 501,	/* Œ œ */
+	0x0154, 501,	/* Ŕ ŕ */
+	0x0156, 501,	/* Ŗ ŗ */
+	0x0158, 501,	/* Ř ř */
+	0x015a, 501,	/* Ś ś */
+	0x015c, 501,	/* Ŝ ŝ */
+	0x015e, 501,	/* Ş ş */
+	0x0160, 501,	/* Š š */
+	0x0162, 501,	/* Ţ ţ */
+	0x0164, 501,	/* Ť ť */
+	0x0166, 501,	/* Ŧ ŧ */
+	0x0168, 501,	/* Ũ ũ */
+	0x016a, 501,	/* Ū ū */
+	0x016c, 501,	/* Ŭ ŭ */
+	0x016e, 501,	/* Ů ů */
+	0x0170, 501,	/* Ű ű */
+	0x0172, 501,	/* Ų ų */
+	0x0174, 501,	/* Ŵ ŵ */
+	0x0176, 501,	/* Ŷ ŷ */
+	0x0178, 379,	/* Ÿ ÿ */
+	0x0179, 501,	/* Ź ź */
+	0x017b, 501,	/* Ż ż */
+	0x017d, 501,	/* Ž ž */
+	0x0181, 710,	/* Ɓ ɓ */
+	0x0182, 501,	/* Ƃ ƃ */
+	0x0184, 501,	/* Ƅ ƅ */
+	0x0186, 706,	/* Ɔ ɔ */
+	0x0187, 501,	/* Ƈ ƈ */
+	0x018b, 501,	/* Ƌ ƌ */
+	0x0190, 703,	/* Ɛ ɛ */
+	0x0191, 501,	/* Ƒ ƒ */
+	0x0193, 705,	/* Ɠ ɠ */
+	0x0194, 707,	/* Ɣ ɣ */
+	0x0196, 711,	/* Ɩ ɩ */
+	0x0197, 709,	/* Ɨ ɨ */
+	0x0198, 501,	/* Ƙ ƙ */
+	0x019c, 711,	/* Ɯ ɯ */
+	0x019d, 713,	/* Ɲ ɲ */
+	0x01a0, 501,	/* Ơ ơ */
+	0x01a2, 501,	/* Ƣ ƣ */
+	0x01a4, 501,	/* Ƥ ƥ */
+	0x01a7, 501,	/* Ƨ ƨ */
+	0x01a9, 718,	/* Ʃ ʃ */
+	0x01ac, 501,	/* Ƭ ƭ */
+	0x01ae, 718,	/* Ʈ ʈ */
+	0x01af, 501,	/* Ư ư */
+	0x01b3, 501,	/* Ƴ ƴ */
+	0x01b5, 501,	/* Ƶ ƶ */
+	0x01b7, 719,	/* Ʒ ʒ */
+	0x01b8, 501,	/* Ƹ ƹ */
+	0x01bc, 501,	/* Ƽ ƽ */
+	0x01c4, 502,	/* DŽ dž */
+	0x01c5, 501,	/* Dž dž */
+	0x01c7, 502,	/* LJ lj */
+	0x01c8, 501,	/* Lj lj */
+	0x01ca, 502,	/* NJ nj */
+	0x01cb, 501,	/* Nj nj */
+	0x01cd, 501,	/* Ǎ ǎ */
+	0x01cf, 501,	/* Ǐ ǐ */
+	0x01d1, 501,	/* Ǒ ǒ */
+	0x01d3, 501,	/* Ǔ ǔ */
+	0x01d5, 501,	/* Ǖ ǖ */
+	0x01d7, 501,	/* Ǘ ǘ */
+	0x01d9, 501,	/* Ǚ ǚ */
+	0x01db, 501,	/* Ǜ ǜ */
+	0x01de, 501,	/* Ǟ ǟ */
+	0x01e0, 501,	/* Ǡ ǡ */
+	0x01e2, 501,	/* Ǣ ǣ */
+	0x01e4, 501,	/* Ǥ ǥ */
+	0x01e6, 501,	/* Ǧ ǧ */
+	0x01e8, 501,	/* Ǩ ǩ */
+	0x01ea, 501,	/* Ǫ ǫ */
+	0x01ec, 501,	/* Ǭ ǭ */
+	0x01ee, 501,	/* Ǯ ǯ */
+	0x01f1, 502,	/* DZ dz */
+	0x01f2, 501,	/* Dz dz */
+	0x01f4, 501,	/* Ǵ ǵ */
+	0x01fa, 501,	/* Ǻ ǻ */
+	0x01fc, 501,	/* Ǽ ǽ */
+	0x01fe, 501,	/* Ǿ ǿ */
+	0x0200, 501,	/* Ȁ ȁ */
+	0x0202, 501,	/* Ȃ ȃ */
+	0x0204, 501,	/* Ȅ ȅ */
+	0x0206, 501,	/* Ȇ ȇ */
+	0x0208, 501,	/* Ȉ ȉ */
+	0x020a, 501,	/* Ȋ ȋ */
+	0x020c, 501,	/* Ȍ ȍ */
+	0x020e, 501,	/* Ȏ ȏ */
+	0x0210, 501,	/* Ȑ ȑ */
+	0x0212, 501,	/* Ȓ ȓ */
+	0x0214, 501,	/* Ȕ ȕ */
+	0x0216, 501,	/* Ȗ ȗ */
+	0x0386, 538,	/* Ά ά */
+	0x038c, 564,	/* Ό ό */
+	0x03e2, 501,	/* Ϣ ϣ */
+	0x03e4, 501,	/* Ϥ ϥ */
+	0x03e6, 501,	/* Ϧ ϧ */
+	0x03e8, 501,	/* Ϩ ϩ */
+	0x03ea, 501,	/* Ϫ ϫ */
+	0x03ec, 501,	/* Ϭ ϭ */
+	0x03ee, 501,	/* Ϯ ϯ */
+	0x0460, 501,	/* Ѡ ѡ */
+	0x0462, 501,	/* Ѣ ѣ */
+	0x0464, 501,	/* Ѥ ѥ */
+	0x0466, 501,	/* Ѧ ѧ */
+	0x0468, 501,	/* Ѩ ѩ */
+	0x046a, 501,	/* Ѫ ѫ */
+	0x046c, 501,	/* Ѭ ѭ */
+	0x046e, 501,	/* Ѯ ѯ */
+	0x0470, 501,	/* Ѱ ѱ */
+	0x0472, 501,	/* Ѳ ѳ */
+	0x0474, 501,	/* Ѵ ѵ */
+	0x0476, 501,	/* Ѷ ѷ */
+	0x0478, 501,	/* Ѹ ѹ */
+	0x047a, 501,	/* Ѻ ѻ */
+	0x047c, 501,	/* Ѽ ѽ */
+	0x047e, 501,	/* Ѿ ѿ */
+	0x0480, 501,	/* Ҁ ҁ */
+	0x0490, 501,	/* Ґ ґ */
+	0x0492, 501,	/* Ғ ғ */
+	0x0494, 501,	/* Ҕ ҕ */
+	0x0496, 501,	/* Җ җ */
+	0x0498, 501,	/* Ҙ ҙ */
+	0x049a, 501,	/* Қ қ */
+	0x049c, 501,	/* Ҝ ҝ */
+	0x049e, 501,	/* Ҟ ҟ */
+	0x04a0, 501,	/* Ҡ ҡ */
+	0x04a2, 501,	/* Ң ң */
+	0x04a4, 501,	/* Ҥ ҥ */
+	0x04a6, 501,	/* Ҧ ҧ */
+	0x04a8, 501,	/* Ҩ ҩ */
+	0x04aa, 501,	/* Ҫ ҫ */
+	0x04ac, 501,	/* Ҭ ҭ */
+	0x04ae, 501,	/* Ү ү */
+	0x04b0, 501,	/* Ұ ұ */
+	0x04b2, 501,	/* Ҳ ҳ */
+	0x04b4, 501,	/* Ҵ ҵ */
+	0x04b6, 501,	/* Ҷ ҷ */
+	0x04b8, 501,	/* Ҹ ҹ */
+	0x04ba, 501,	/* Һ һ */
+	0x04bc, 501,	/* Ҽ ҽ */
+	0x04be, 501,	/* Ҿ ҿ */
+	0x04c1, 501,	/* Ӂ ӂ */
+	0x04c3, 501,	/* Ӄ ӄ */
+	0x04c7, 501,	/* Ӈ ӈ */
+	0x04cb, 501,	/* Ӌ ӌ */
+	0x04d0, 501,	/* Ӑ ӑ */
+	0x04d2, 501,	/* Ӓ ӓ */
+	0x04d4, 501,	/* Ӕ ӕ */
+	0x04d6, 501,	/* Ӗ ӗ */
+	0x04d8, 501,	/* Ә ә */
+	0x04da, 501,	/* Ӛ ӛ */
+	0x04dc, 501,	/* Ӝ ӝ */
+	0x04de, 501,	/* Ӟ ӟ */
+	0x04e0, 501,	/* Ӡ ӡ */
+	0x04e2, 501,	/* Ӣ ӣ */
+	0x04e4, 501,	/* Ӥ ӥ */
+	0x04e6, 501,	/* Ӧ ӧ */
+	0x04e8, 501,	/* Ө ө */
+	0x04ea, 501,	/* Ӫ ӫ */
+	0x04ee, 501,	/* Ӯ ӯ */
+	0x04f0, 501,	/* Ӱ ӱ */
+	0x04f2, 501,	/* Ӳ ӳ */
+	0x04f4, 501,	/* Ӵ ӵ */
+	0x04f8, 501,	/* Ӹ ӹ */
+	0x1e00, 501,	/* Ḁ ḁ */
+	0x1e02, 501,	/* Ḃ ḃ */
+	0x1e04, 501,	/* Ḅ ḅ */
+	0x1e06, 501,	/* Ḇ ḇ */
+	0x1e08, 501,	/* Ḉ ḉ */
+	0x1e0a, 501,	/* Ḋ ḋ */
+	0x1e0c, 501,	/* Ḍ ḍ */
+	0x1e0e, 501,	/* Ḏ ḏ */
+	0x1e10, 501,	/* Ḑ ḑ */
+	0x1e12, 501,	/* Ḓ ḓ */
+	0x1e14, 501,	/* Ḕ ḕ */
+	0x1e16, 501,	/* Ḗ ḗ */
+	0x1e18, 501,	/* Ḙ ḙ */
+	0x1e1a, 501,	/* Ḛ ḛ */
+	0x1e1c, 501,	/* Ḝ ḝ */
+	0x1e1e, 501,	/* Ḟ ḟ */
+	0x1e20, 501,	/* Ḡ ḡ */
+	0x1e22, 501,	/* Ḣ ḣ */
+	0x1e24, 501,	/* Ḥ ḥ */
+	0x1e26, 501,	/* Ḧ ḧ */
+	0x1e28, 501,	/* Ḩ ḩ */
+	0x1e2a, 501,	/* Ḫ ḫ */
+	0x1e2c, 501,	/* Ḭ ḭ */
+	0x1e2e, 501,	/* Ḯ ḯ */
+	0x1e30, 501,	/* Ḱ ḱ */
+	0x1e32, 501,	/* Ḳ ḳ */
+	0x1e34, 501,	/* Ḵ ḵ */
+	0x1e36, 501,	/* Ḷ ḷ */
+	0x1e38, 501,	/* Ḹ ḹ */
+	0x1e3a, 501,	/* Ḻ ḻ */
+	0x1e3c, 501,	/* Ḽ ḽ */
+	0x1e3e, 501,	/* Ḿ ḿ */
+	0x1e40, 501,	/* Ṁ ṁ */
+	0x1e42, 501,	/* Ṃ ṃ */
+	0x1e44, 501,	/* Ṅ ṅ */
+	0x1e46, 501,	/* Ṇ ṇ */
+	0x1e48, 501,	/* Ṉ ṉ */
+	0x1e4a, 501,	/* Ṋ ṋ */
+	0x1e4c, 501,	/* Ṍ ṍ */
+	0x1e4e, 501,	/* Ṏ ṏ */
+	0x1e50, 501,	/* Ṑ ṑ */
+	0x1e52, 501,	/* Ṓ ṓ */
+	0x1e54, 501,	/* Ṕ ṕ */
+	0x1e56, 501,	/* Ṗ ṗ */
+	0x1e58, 501,	/* Ṙ ṙ */
+	0x1e5a, 501,	/* Ṛ ṛ */
+	0x1e5c, 501,	/* Ṝ ṝ */
+	0x1e5e, 501,	/* Ṟ ṟ */
+	0x1e60, 501,	/* Ṡ ṡ */
+	0x1e62, 501,	/* Ṣ ṣ */
+	0x1e64, 501,	/* Ṥ ṥ */
+	0x1e66, 501,	/* Ṧ ṧ */
+	0x1e68, 501,	/* Ṩ ṩ */
+	0x1e6a, 501,	/* Ṫ ṫ */
+	0x1e6c, 501,	/* Ṭ ṭ */
+	0x1e6e, 501,	/* Ṯ ṯ */
+	0x1e70, 501,	/* Ṱ ṱ */
+	0x1e72, 501,	/* Ṳ ṳ */
+	0x1e74, 501,	/* Ṵ ṵ */
+	0x1e76, 501,	/* Ṷ ṷ */
+	0x1e78, 501,	/* Ṹ ṹ */
+	0x1e7a, 501,	/* Ṻ ṻ */
+	0x1e7c, 501,	/* Ṽ ṽ */
+	0x1e7e, 501,	/* Ṿ ṿ */
+	0x1e80, 501,	/* Ẁ ẁ */
+	0x1e82, 501,	/* Ẃ ẃ */
+	0x1e84, 501,	/* Ẅ ẅ */
+	0x1e86, 501,	/* Ẇ ẇ */
+	0x1e88, 501,	/* Ẉ ẉ */
+	0x1e8a, 501,	/* Ẋ ẋ */
+	0x1e8c, 501,	/* Ẍ ẍ */
+	0x1e8e, 501,	/* Ẏ ẏ */
+	0x1e90, 501,	/* Ẑ ẑ */
+	0x1e92, 501,	/* Ẓ ẓ */
+	0x1e94, 501,	/* Ẕ ẕ */
+	0x1ea0, 501,	/* Ạ ạ */
+	0x1ea2, 501,	/* Ả ả */
+	0x1ea4, 501,	/* Ấ ấ */
+	0x1ea6, 501,	/* Ầ ầ */
+	0x1ea8, 501,	/* Ẩ ẩ */
+	0x1eaa, 501,	/* Ẫ ẫ */
+	0x1eac, 501,	/* Ậ ậ */
+	0x1eae, 501,	/* Ắ ắ */
+	0x1eb0, 501,	/* Ằ ằ */
+	0x1eb2, 501,	/* Ẳ ẳ */
+	0x1eb4, 501,	/* Ẵ ẵ */
+	0x1eb6, 501,	/* Ặ ặ */
+	0x1eb8, 501,	/* Ẹ ẹ */
+	0x1eba, 501,	/* Ẻ ẻ */
+	0x1ebc, 501,	/* Ẽ ẽ */
+	0x1ebe, 501,	/* Ế ế */
+	0x1ec0, 501,	/* Ề ề */
+	0x1ec2, 501,	/* Ể ể */
+	0x1ec4, 501,	/* Ễ ễ */
+	0x1ec6, 501,	/* Ệ ệ */
+	0x1ec8, 501,	/* Ỉ ỉ */
+	0x1eca, 501,	/* Ị ị */
+	0x1ecc, 501,	/* Ọ ọ */
+	0x1ece, 501,	/* Ỏ ỏ */
+	0x1ed0, 501,	/* Ố ố */
+	0x1ed2, 501,	/* Ồ ồ */
+	0x1ed4, 501,	/* Ổ ổ */
+	0x1ed6, 501,	/* Ỗ ỗ */
+	0x1ed8, 501,	/* Ộ ộ */
+	0x1eda, 501,	/* Ớ ớ */
+	0x1edc, 501,	/* Ờ ờ */
+	0x1ede, 501,	/* Ở ở */
+	0x1ee0, 501,	/* Ỡ ỡ */
+	0x1ee2, 501,	/* Ợ ợ */
+	0x1ee4, 501,	/* Ụ ụ */
+	0x1ee6, 501,	/* Ủ ủ */
+	0x1ee8, 501,	/* Ứ ứ */
+	0x1eea, 501,	/* Ừ ừ */
+	0x1eec, 501,	/* Ử ử */
+	0x1eee, 501,	/* Ữ ữ */
+	0x1ef0, 501,	/* Ự ự */
+	0x1ef2, 501,	/* Ỳ ỳ */
+	0x1ef4, 501,	/* Ỵ ỵ */
+	0x1ef6, 501,	/* Ỷ ỷ */
+	0x1ef8, 501,	/* Ỹ ỹ */
+	0x1f59, 492,	/* Ὑ ὑ */
+	0x1f5b, 492,	/* Ὓ ὓ */
+	0x1f5d, 492,	/* Ὕ ὕ */
+	0x1f5f, 492,	/* Ὗ ὗ */
+	0x1fbc, 491,	/* ᾼ ᾳ */
+	0x1fcc, 491,	/* ῌ ῃ */
+	0x1fec, 493,	/* Ῥ ῥ */
+	0x1ffc, 491	/* ῼ ῳ */
+]
+
+/*
+ * title characters are those between
+ * upper and lower case. ie DZ Dz dz
+ */
+const rtotitle1 = [
+	0x01c4, 501,	/* DŽ Dž */
+	0x01c6, 499,	/* dž Dž */
+	0x01c7, 501,	/* LJ Lj */
+	0x01c9, 499,	/* lj Lj */
+	0x01ca, 501,	/* NJ Nj */
+	0x01cc, 499,	/* nj Nj */
+	0x01f1, 501,	/* DZ Dz */
+	0x01f3, 499	/* dz Dz */
+]
+
+const findc = {c, t, n, nelt, ret
+	var p, m
+
+	/*
+	we're processing in chunks of size 
+	nelt, so 1 chunk is of length 'nelt'
+	*/
+	while n > 1
+		m = n/2
+		p = t[m*nelt:]
+		if c >= p[0]
+			t = p
+			n = n - m
+		else
+			n = m
+		;;
+	;;
+
+	if t.len != 0 && c >= t[0]
+		ret# = t
+		-> true
+	else
+		-> false
+	;;
+}
+
+
+const isalpha = {c
+	var l
+
+	if isupper(c) || islower(c)
+		-> true
+	elif findc(c, ralpha2[:], ralpha2.len/2, 2, &l)
+		if (c >= l[0] && c <= l[1])
+			-> true
+		;;
+	elif findc(c, ralpha1[:], ralpha1.len, 1, &l)
+		if (c == l[0])
+			-> true
+		;;
+	;;
+	-> false
+}
+
+const isdigit = {c
+	-> c >= '0' && c <= '9'
+}
+
+const isxdigit = {c
+	-> c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'
+}
+
+const isnum = {c
+	var l
+
+	if findc(c, rnums[:], rnums.len/2, 2, &l)
+		if(c >= l[0] && c <= l[1])
+			-> true
+		;;
+	;;
+	-> false
+}
+
+const isalnum = {c
+	-> isalpha(c) || isnum(c)
+}
+
+const isblank = {c
+	var l
+	var sl
+	var len
+
+	l = rspace2[:]
+	sl = rspace2[:]
+	len = rspace2.len/2
+	if findc(c, sl, len, 2, &l)
+		if(c >= l[0] && c <= l[1])
+			-> true
+		;;
+	;;
+	-> false
+}
+
+const isspace = {c
+	-> c == '\n' || isblank(c)
+}
+
+const islower = {c
+	var l
+
+	/* the first character in the toupper table is the lowercase char */
+	if findc(c, rtoupper2[:], rtoupper2.len/3, 3, &l)
+		if (c >= l[0] && c <= l[1])
+			-> true
+		;;
+	elif findc(c, rtoupper1[:], rtoupper1.len/2, 2, &l)
+		if (c == l[0])
+			-> true
+		;;
+	;;
+	-> false
+}
+
+const isupper = {c
+	var l
+
+	/* the first character in the tolower table is the uppercase char */
+	if findc(c, rtolower2[:], rtolower2.len/3, 3, &l)
+		if (c >= l[0] && c <= l[1])
+			-> true
+		;;
+	elif findc(c, rtolower1[:], rtolower1.len/2, 2, &l)
+		if (c == l[0])
+			-> true
+		;;
+	;;
+	-> false
+}
+
+const istitle = {c
+	-> isupper(c) && islower(c)
+}
+
+const tolower = {c
+	var l
+
+	if findc(c, rtolower2[:], rtolower2.len/3, 3, &l)
+		if c >= l[0] && c <= l[1]
+			-> c + l[2] - 500;
+		;;
+	elif findc(c, rtolower1[:], rtolower1.len/2, 2, &l) 
+		if c == l[0]
+			-> c + l[1] - 500;
+		;;
+	;;
+	-> c
+}
+
+const toupper = {c
+	var l
+
+	if findc(c, rtoupper2[:], rtoupper2.len/3, 3, &l);
+		if c >= l[0] && c <= l[1]
+			-> c + l[2] - 500;
+		;;
+	elif findc(c, rtoupper1[:], rtoupper1.len/2, 2, &l);
+		if c == l[0]
+			-> c + l[1] - 500;
+		;;
+	;;
+	-> c
+}
+
+const totitle = {c
+	var l
+
+	if findc(c, rtotitle1[:], rtotitle1.len/2, 2, &l);
+		if c == l[0]
+			-> c + l[1] - 500;
+		;;
+	;;
+	-> c
+}
+
+generic charval = {c, base -> @a::(numeric,integral)
+	var v = -1
+
+	if c >= '0' && c <= '9'
+		v =  (c - '0') castto(@a::(integral,numeric))
+	elif c >= 'a' && c <= 'z'
+		v =  (c - 'a' + 10) castto(@a::(integral,numeric))
+	elif c >= 'A' && c <= 'Z'
+		v =  (c - 'A' + 10) castto(@a::(integral,numeric))
+	;;
+
+	if v < 0 || v > (base castto(@a::(integral,numeric)))
+		-> -1
+	;;
+	-> v
+}
--- /dev/null
+++ b/lib/std/clear.myr
@@ -1,0 +1,12 @@
+use "slfill.use"
+pkg std =
+	generic clear	: (p : @a#	-> void)
+;;
+
+generic clear = {p : @a#
+	var bp
+
+	bp = p castto(byte#)
+	slfill(bp[:sizeof(@a)], 0)
+}
+
--- /dev/null
+++ b/lib/std/cmp.myr
@@ -1,0 +1,54 @@
+use "extremum.use"
+use "types.use"
+
+pkg std =
+	type order = union
+		`Before
+		`Equal
+		`After
+	;;
+
+	generic numcmp	: (a : @a, b : @a -> order)
+	const strcmp	: (a : byte[:], b : byte[:] -> order)
+	const strncmp	: (a : byte[:], b : byte[:], n : size -> order)
+;;
+
+generic numcmp = {a, b
+	if a < b
+		-> `Before
+	elif a == b
+		-> `Equal
+	else
+		-> `After
+	;;
+}
+
+const strcmp = {a, b
+	var l
+	var i
+
+	l = min(a.len, b.len)
+	for i = 0; i < l; i++
+		if a[i] < b[i]
+			-> `Before
+		elif a[i] > b[i]
+			-> `After
+		;;
+	;;
+
+	if a.len < b.len
+		-> `Before
+	elif a.len > b.len
+		-> `After
+	else
+		-> `Equal
+	;;
+		
+}
+
+const strncmp = {a, b, n
+	a = a[:min(a.len, n)]
+	b = b[:min(b.len, n)]
+	-> strcmp(a, b)
+}
+
--- /dev/null
+++ b/lib/std/cstrconv.myr
@@ -1,0 +1,40 @@
+use "types.use"
+
+pkg std =
+	const cstrlen	: (buf : byte[:] -> size)
+	const cstrconv	: (buf : byte[:] -> byte[:])
+	const cstrconvp	: (p : byte# -> byte[:])
+;;
+
+const cstrconv = {buf
+	var i
+
+	for i = 0; i < buf.len; i++
+		if buf[i] == 0
+			-> buf[:i]
+		;;
+	;;
+	-> buf
+}
+
+const cstrconvp = {p
+	var i, base
+
+	i = 0
+	base = p castto(intptr)
+	while ((base + i) castto(byte#))# != 0
+		i++
+	;;
+	-> p[:i]
+}
+
+const cstrlen = {buf
+	var i
+
+	for i = 0; i < buf.len; i++
+		if buf[i] == 0
+			break
+		;;
+	;;
+	-> i
+}
--- /dev/null
+++ b/lib/std/dial+plan9.myr
@@ -1,0 +1,165 @@
+use sys
+
+use "alloc.use"
+use "die.use"
+use "fmt.use"
+use "option.use"
+use "pathjoin.use"
+use "result.use"
+use "sleq.use"
+use "strfind.use"
+use "strstrip.use"
+use "syswrap.use"
+use "utf.use"
+
+
+pkg std =
+	const dial	: (dialstr : byte[:] -> result(fd, byte[:]))
+;;
+
+const Maxpath = 512
+
+const dial = {str
+	var netdir, proto, rem
+
+	(netdir, proto, rem) = parsedial(str)
+	if netdir.len != 0
+		-> csdial(netdir, proto, rem)
+	;;
+
+	match csdial("/net", proto, rem)
+	| `Ok fd:	-> `Ok fd
+	| `Fail m:
+		-> csdial("/net.alt", proto, rem)
+	;;
+}
+
+const csdial = {netdir, proto, rem
+	var dir, clone, addr, csaddr
+	var ret, csfd, n
+	var buf	: byte[Maxpath]
+
+	/* Try using the connection server */
+	dir = fmt("{}/cs", netdir)
+	csfd = open(dir, Ordwr)
+	if csfd < 0
+		clone = fmt("{}/{}/clone", netdir, proto)
+		ret = call(clone, rem, netdir)
+		slfree(clone)
+		if ret == -1
+			-> `Fail "unable to dial without cs"
+		else
+			-> `Ok ret
+		;;
+	;;
+	slfree(dir)
+
+	csaddr = fmt("{}!{}", proto, rem)
+	if write(csfd, csaddr) < 0
+		close(csfd)
+		-> `Fail "couldn't blah cs"
+	;;
+	slfree(csaddr)
+
+	seek(csfd, 0, 0)
+	while true
+		n = read(csfd, buf[:])
+		if n <= 0
+			break
+		;;
+
+		match strfind(buf[:n], " ")
+		| `None:	continue
+		| `Some i:
+			clone = buf[:i]
+			addr = buf[i+1:n]
+		;;
+
+		ret = call(clone, addr, netdir)
+		if ret >= 0
+			break
+		;;
+	;;
+
+	close(csfd)
+	if ret < 0
+		-> `Fail "unable to dial"
+	;;
+	-> `Ok ret
+}
+
+const call = {clone, addr, netdir
+	var namebuf : byte[Maxpath]
+	var databuf : byte[Maxpath]
+	var name, base, dpath
+	var cfd, datafd
+	var c, n
+
+	datafd = -1
+	c = nsclonestr(clone, netdir)
+	cfd = open(c, Ordwr)
+	if cfd < 0
+		goto cleanup
+	;;
+
+	n = read(cfd, namebuf[:])
+	if n < 0
+		goto cleanup
+	;;
+	fput(cfd, "connect {}", addr)
+	name = strstrip(namebuf[:n])
+	match strrfind(c, "/")
+	| `None:	die("there should be a '/' here\n")
+	| `Some i:	base = c[:i]
+	;;
+	dpath = bfmt(databuf[:], "{}/{}/data", base, name)
+	datafd = open(dpath, Ordwr)
+:cleanup
+	close(cfd)
+	slfree(c)
+	-> datafd
+}
+
+const nsclonestr = {clone, netdir
+	if decode(clone) == '#' || decode(clone) == '/'
+		match std.strfind(clone[1:], "/")
+		| `Some i:	clone = clone[i+1:]
+		| `None:	/* nothing */
+		;;
+	;;
+	-> pathcat(netdir, clone)
+}
+
+const parsedial = {str
+	var netdir, proto, rem, hd, tl
+
+	netdir=""
+	proto = ""
+	rem = ""
+	match strfind(str, "!")
+	| `None:
+		proto = "net"
+		rem = str
+	| `Some sep:
+		hd = str[:sep]
+		tl = str[sep+1:]
+		if decode(hd) == '#' || decode(hd) == '/'
+			match strrfind(hd, "/")
+			| `Some idx:
+				netdir = hd[:idx]
+				proto = hd[idx+1:]
+			| `None:
+				netdir = ""
+				proto = hd
+			;;
+		else
+			netdir = ""
+			proto = hd
+
+		;;
+		rem = tl
+	;;
+
+	-> (netdir, proto, rem)
+}
+
--- /dev/null
+++ b/lib/std/dial+posixy.myr
@@ -1,0 +1,147 @@
+use sys
+
+use "alloc.use"
+use "chartype.use"
+use "die.use"
+use "endian.use"
+use "hasprefix.use"
+use "intparse.use"
+use "ipparse.use"
+use "option.use"
+use "resolve.use"
+use "result.use"
+use "sleq.use"
+use "strfind.use"
+use "syswrap.use"
+use "utf.use"
+
+pkg std =
+	const dial	: (dialstr : byte[:] -> result(fd, byte[:]))
+;;
+
+/*
+ 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
+*/
+
+/* takes a plan 9 style dial string */
+const dial = {str
+	var proto, host, port
+	var sa4 : sys.sockaddr_in
+	var sa6 : sys.sockaddr_in6
+	var sa	: sys.sockaddr#
+	var sock
+
+	match parsedial(str)
+	| `Ok val:	(proto, host, port) = val
+	| `Fail m:	-> `Fail m
+	;;
+
+	match getaddr(host)
+	| `Ipv4 bits:
+		sa4.fam = sys.Afinet
+		sa4.addr = bits
+		sa4.port = hosttonet(port)
+		sa = &sa4 castto(sys.sockaddr#)
+	| `Ipv6 bits:
+		sa6.fam = sys.Afinet6
+		sa6.addr = bits
+		sa6.port = hosttonet(port)
+		sa = &sa6 castto(sys.sockaddr#)
+	;;
+	sock = sys.socket(sa.fam, proto, 0)
+
+	if sock < 0
+		-> `Fail "failed to connect to socket"
+	;;
+	var err
+	err = sys.connect(sock, sa, sizeof(sys.sockaddr_in))
+	if err < 0
+		sys.close(sock)
+		-> `Fail "Failed to bind socket"
+	;;
+
+	-> `Ok (sock castto(fd))
+}
+
+const parsedial = {str
+	var proto, host, port
+	var socktype, portnum
+
+	(proto, str) = nameseg(str)
+	(host, str) = nameseg(str)
+	(port, str) = nameseg(str)
+
+	if proto.len == 0
+		-> `Fail "missing proto"
+	elif host.len == 0
+		-> `Fail "missing host"
+	elif port.len == 0
+		-> `Fail "missing port"
+	;;
+
+	if sleq(proto, "net")
+		-> `Fail "net wildcard proto not yet supported\n"
+	elif sleq(proto, "unix")
+		-> `Fail "net unix proto not yet supported\n"
+	elif sleq(proto, "tcp")
+		socktype = sys.Sockstream
+	elif sleq(proto, "udp")
+		socktype = sys.Sockdgram
+	;;
+
+	match parseport(port)
+	| `Some n:	portnum = n
+	| `None:	-> `Fail "bad port"
+	;;
+
+	-> `Ok (socktype, host, portnum)
+}
+
+const parseport = {port
+	match intparse(port)
+	| `Some n:	-> `Some n
+	| `None:
+		/* a small number of hardcoded ports */
+		if sleq(port, "http")
+			-> `Some 80
+		elif sleq(port, "https")
+			-> `Some 443
+		elif sleq(port, "ircd")
+			-> `Some 6667
+		elif sleq(port, "dns")
+			-> `Some 53
+		;;
+	;;
+	-> `None
+}
+
+const getaddr = {addr
+	var ip
+
+	match ipparse(addr)
+	| `Some a:	ip = a
+	| `None:
+		match resolve(addr)
+		| `Ok hi:
+			ip = hi[0].addr
+			slfree(hi)
+		| `Fail m:
+		;;
+	;;
+	-> ip
+}
+
+const nameseg = {str
+	match strfind(str, "!")
+	| `Some idx:
+		-> (str[:idx], str[idx+1:])
+	| `None:
+		-> (str, "")
+	;;
+}
+
--- /dev/null
+++ b/lib/std/die.myr
@@ -1,0 +1,19 @@
+use "syswrap.use"
+use "types.use"
+
+pkg std = 
+	$noret const die	: (msg : byte[:] -> void)
+	const assert	: (cond : bool, msg : byte[:] -> void)
+;;
+
+const die = {msg
+	write(2, msg)
+	suicide()
+}
+
+const assert = {cond, msg
+	if !cond
+		die(msg)
+	;;
+}
+
--- /dev/null
+++ b/lib/std/dir+linux.myr
@@ -1,0 +1,66 @@
+use sys
+
+use "alloc.use"
+use "die.use"
+use "option.use"
+use "result.use"
+use "slcp.use"
+use "sldup.use"
+use "types.use"
+
+pkg std =
+	type dir = struct
+		fd	: sys.fd
+		buf	: byte[16384]
+		len	: int64
+		off	: int64
+	;;
+
+	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
+	const dirread	: (d : dir# -> std.option(byte[:]))
+	const dirclose	: (d : dir# -> void)
+;;
+
+const Direntoverhead = 20
+
+const diropen = {p
+	var fd
+	var dir
+
+	fd = sys.open(p, sys.Ordonly | sys.Odir)
+	if fd < 0
+		-> `Fail "couldn't open directory"
+	;;
+	dir = zalloc()
+	dir.fd = fd
+	-> `Ok dir
+}
+
+const dirread = {d
+	var len
+	var dent
+	var namelen
+
+	if d.off >= d.len
+		len = sys.getdents64(d.fd, d.buf[:])
+		if len <= 0
+			-> `None
+		;;
+		d.len = len
+		d.off = 0
+	;;
+
+	dent = &d.buf[d.off] castto(sys.dirent64#)
+	namelen = 0
+	d.off += dent.reclen castto(int64)
+	while dent.name[namelen] != 0
+		namelen++
+	;;
+	-> `Some sldup(dent.name[:namelen])
+}
+
+const dirclose = {d
+	sys.close(d.fd)
+	free(d)
+}
+
--- /dev/null
+++ b/lib/std/dir+osx.myr
@@ -1,0 +1,60 @@
+use sys
+
+use "alloc.use"
+use "die.use"
+use "option.use"
+use "result.use"
+use "slcp.use"
+use "sldup.use"
+use "types.use"
+
+pkg std =
+	type dir = struct
+		fd	: sys.fd
+		buf	: byte[16384]
+		len	: int64
+		off	: int64
+		base	: int64
+	;;
+
+	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
+	const dirread	: (d : dir# -> std.option(byte[:]))
+	const dirclose	: (d : dir# -> void)
+;;
+
+const diropen = {p
+	var fd
+	var dir
+
+	fd = sys.open(p, sys.Ordonly | sys.Odir)
+	if fd < 0
+		-> `Fail "couldn't open directory"
+	;;
+	dir = zalloc()
+	dir.fd = fd
+	-> `Ok dir
+}
+
+const dirread = {d
+	var len
+	var dent
+
+	if d.off >= d.len
+		len = sys.getdirentries64(d.fd, d.buf[:], &d.base)
+		if len <= 0
+			-> `None
+		;;
+		d.len = len
+		d.off = 0
+	;;
+
+	dent = &d.buf[d.off] castto(sys.dirent64#)
+	d.off += dent.reclen castto(int64)
+	-> `Some sldup(dent.name[:dent.namlen])
+}
+
+const dirclose = {d
+	sys.close(d.fd)
+	free(d)
+}
+
--- /dev/null
+++ b/lib/std/dir+plan9.myr
@@ -1,0 +1,66 @@
+use sys
+
+use "alloc.use"
+use "die.use"
+use "option.use"
+use "result.use"
+use "slcp.use"
+use "sldup.use"
+use "syswrap.use"
+use "types.use"
+
+pkg std =
+	type dir = struct
+		fd	: fd
+		buf	: byte[65536]	/* a big big, but at least it will always hold a directory entry... */
+		len	: int64
+		off	: int64
+	;;
+
+	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
+	const dirread	: (d : dir# -> std.option(byte[:]))
+	const dirclose	: (d : dir# -> void)
+;;
+
+const diropen = {p
+	var fd
+	var dir
+
+	fd = open(p, Ordonly)
+	if fd < 0
+		-> `Fail "couldn't open directory"
+	;;
+
+	dir = zalloc()
+	dir.fd = fd
+	-> `Ok dir
+}
+	
+
+const dirread = {d
+	var len : int64, name, base, namelen, dirlen
+
+	/* NB: On Plan 9, read(2) will always return whole directory entries */
+	if d.off >= d.len
+		len = read(d.fd, d.buf[:]) castto(int64)
+		if len <= 0
+			-> `None
+		;;
+		d.len = len
+		d.off = 0
+	;;
+
+	namelen = (d.buf[d.off + Stringsoff] castto(int64)) | \
+		((d.buf[d.off + Stringsoff + 1] castto(int64)) << 8)
+	base = d.off + Stringsoff + 2
+	dirlen = (d.buf[d.off] castto(int64)) | \
+		((d.buf[d.off + 1] castto(int64)) << 8)
+	name = d.buf[base:base + namelen]
+	d.off += dirlen + 2
+	-> `Some std.sldup(name)
+}
+
+const dirclose = {d
+	close(d.fd)
+	free(d)
+}
--- /dev/null
+++ b/lib/std/dirname.myr
@@ -1,0 +1,37 @@
+use "alloc.use"
+use "slcp.use"
+use "die.use"
+use "sldup.use"
+use "strfind.use"
+use "option.use"
+
+pkg std =
+	const dirname	: (p : byte[:] -> byte[:])
+	const basename	: (p : byte[:] -> byte[:])
+;;
+
+const dirname = {p
+	match std.strrfind(p, "/")
+	| `std.Some idx:
+		-> std.sldup(p[:idx])
+	| `std.None:
+		-> std.sldup(".")
+	;;
+}
+
+const basename = {p
+:again
+	if p.len == 0
+		-> std.sldup(".")
+	;;
+
+	match std.strrfind(p, "/")
+	| `std.Some idx:
+		if idx == p.len - 1
+			goto again
+		;;
+		-> std.sldup(p[idx+1:])
+	| `std.None:
+		-> std.sldup(p)
+	;;
+}
--- /dev/null
+++ b/lib/std/endian.myr
@@ -1,0 +1,32 @@
+pkg std =
+	generic hosttonet	: (v : @a -> @a)
+	generic nettohost	: (v : @a -> @a)
+;;
+
+/* FIXME: we only support little endian platforms right now,
+   so we assume a little endian machine. FIX THIS. */
+generic hosttonet = {v : @a::(integral,numeric)
+	var i
+	var ret
+
+	ret = 0
+	for i = 0; i < sizeof(@a); i++
+		ret <<= 8
+		ret |= v & 0xff 
+		v >>= 8
+	;;
+	-> ret
+}
+
+generic nettohost = {v : @a::(integral,numeric)
+	var i
+	var ret
+
+	ret = 0
+	for i = 0; i < sizeof(@a); i++
+		ret <<= 8
+		ret |= v & 0xff 
+		v >>= 8
+	;;
+	-> ret
+}
--- /dev/null
+++ b/lib/std/env+plan9.myr
@@ -1,0 +1,56 @@
+use sys
+
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "fmt.use"
+use "option.use"
+use "result.use"
+use "slcp.use"
+use "sldup.use"
+use "sleq.use"
+use "slpush.use"
+use "slurp.use"
+
+pkg std =
+	const getenv :	(name : byte[:] -> option(byte[:]))
+	const getenvv :	(name : byte[:], default : byte[:] -> byte[:])
+;;
+
+var envkey 	: byte[:][:]
+var envval	: byte[:][:]
+
+const envfind = {key
+	var i
+	for i = 0; i < envkey.len; i++
+		if std.sleq(envkey[i], key)
+			-> `Some envval[i]
+		;;
+	;;
+	-> `None
+}
+
+const getenv = {name
+	var buf : byte[128]
+	var s
+
+	match envfind(name)
+	| `Some val:	-> `Some val
+	| `None:
+		s = bfmt(buf[:], "/env/{}", name)
+		match std.slurp(s)
+		| `Fail m: -> `None
+		| `Ok data:
+			envkey = slpush(envkey, sldup(name))
+			envval = slpush(envval, data)
+			-> `Some data
+		;;
+	;;
+}
+
+const getenvv = {name, default
+	match getenv(name)
+	| `Some val:	-> val
+	| `None:	-> default
+	;;
+}
--- /dev/null
+++ b/lib/std/env+posixy.myr
@@ -1,0 +1,28 @@
+use sys
+
+use "extremum.use"
+use "option.use"
+use "sleq.use"
+
+pkg std =
+	const getenv :	(name : byte[:] -> option(byte[:]))
+	const getenvv :	(name : byte[:], default : byte[:] -> byte[:])
+;;
+
+const getenv = {name
+	var n
+	for env in sys.__environment
+		n = min(name.len, env.len)
+		if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
+			-> `Some env[n+1:]
+		;;
+	;;
+	-> `None
+}
+
+const getenvv = {name, default
+	match getenv(name)
+	| `Some v:	-> v
+	| `None:	-> default
+	;;
+}
--- /dev/null
+++ b/lib/std/errno+plan9.myr
@@ -1,0 +1,6 @@
+pkg std =
+	type errno = int
+	const Erange	: errno = 1
+	const Emisc	: errno = 2
+	const Eexist	: errno = 3
+;;
--- /dev/null
+++ b/lib/std/errno.myr
@@ -1,0 +1,40 @@
+use sys
+
+pkg std =
+	type errno = int
+
+	const Eperm	: errno = sys.Eperm	castto(errno)
+	const Enoent	: errno = sys.Enoent	castto(errno)
+	const Esrch	: errno = sys.Esrch	castto(errno)
+	const Eintr	: errno = sys.Eintr	castto(errno)
+	const Eio	: errno = sys.Eio	castto(errno)
+	const Enxio	: errno = sys.Enxio	castto(errno)
+	const E2big	: errno = sys.E2big	castto(errno)
+	const Enoexec	: errno = sys.Enoexec	castto(errno)
+	const Ebadf	: errno = sys.Ebadf	castto(errno)
+	const Echild	: errno = sys.Echild	castto(errno)
+	const Eagain	: errno = sys.Eagain	castto(errno)
+	const Enomem	: errno = sys.Enomem	castto(errno)
+	const Eacces	: errno = sys.Eacces	castto(errno)
+	const Efault	: errno = sys.Efault	castto(errno)
+	const Enotblk	: errno = sys.Enotblk	castto(errno)
+	const Ebusy	: errno = sys.Ebusy	castto(errno)
+	const Eexist	: errno = sys.Eexist	castto(errno)
+	const Exdev	: errno = sys.Exdev	castto(errno)
+	const Enodev	: errno = sys.Enodev	castto(errno)
+	const Enotdir	: errno = sys.Enotdir	castto(errno)
+	const Eisdir	: errno = sys.Eisdir	castto(errno)
+	const Einval	: errno = sys.Einval	castto(errno)
+	const Enfile	: errno = sys.Enfile	castto(errno)
+	const Emfile	: errno = sys.Emfile	castto(errno)
+	const Enotty	: errno = sys.Enotty	castto(errno)
+	const Etxtbsy	: errno = sys.Etxtbsy	castto(errno)
+	const Efbig	: errno = sys.Efbig	castto(errno)
+	const Enospc	: errno = sys.Enospc	castto(errno)
+	const Espipe	: errno = sys.Espipe	castto(errno)
+	const Erofs	: errno = sys.Erofs	castto(errno)
+	const Emlink	: errno = sys.Emlink	castto(errno)
+	const Epipe	: errno = sys.Epipe	castto(errno)
+	const Edom	: errno = sys.Edom	castto(errno)
+	const Erange	: errno = sys.Erange	castto(errno)
+;;
--- /dev/null
+++ b/lib/std/execvp.myr
@@ -1,0 +1,57 @@
+use "alloc.use"
+use "env.use"
+use "fmt.use"
+use "option.use"
+use "strfind.use"
+use "strsplit.use"
+use "syswrap.use"
+
+pkg std = 
+	const execvp	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execvpe	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+;;
+
+const execvp = {cmd, args
+	var paths, binpath
+	var buf : byte[512]
+
+	match strfind(cmd, "/")
+	| `Some _:
+		-> execv(cmd, args)
+	| `None:
+		paths = getpaths()
+		for p in paths
+			binpath = bfmt(buf[:], "{}/{}", p, cmd)
+			execv(binpath, args)
+		;;
+		slfree(paths)
+	;;
+	-> -1
+}
+
+const execvpe = {cmd, args, env
+	var paths, binpath
+	var buf : byte[512]
+
+	match strfind(cmd, "/")
+	| `Some _:
+		-> execve(cmd, args, env)
+	| `None:
+		paths = getpaths()
+		for p in paths
+			binpath = bfmt(buf[:], "{}/{}", p, cmd)
+			execve(binpath, args, env)
+		;;
+		slfree(paths)
+	;;
+	-> -1
+}
+
+const getpaths = {
+	var path
+	match getenv("PATH")
+	| `Some p:	path = p
+	| `None:	path = "/usr/local/bin:/bin:/usr/bin"
+	;;
+	-> strsplit(path, ":")
+}
--- /dev/null
+++ b/lib/std/extremum.myr
@@ -1,0 +1,40 @@
+pkg std =
+	generic min	: (a : @a::numeric, b : @a::numeric  -> @a::numeric)
+	generic max	: (a : @a::numeric, b : @a::numeric  -> @a::numeric)
+	generic clamp	: (a : @a::numeric, min : @a::numeric, max : @a::numeric -> @a::numeric)
+	generic abs	: (a : @a::numeric -> @a::numeric)
+;;
+
+generic min = {a, b
+	if a < b
+		-> a
+	else
+		-> b
+	;;
+}
+
+generic max = {a, b
+	if a > b
+		-> a
+	else
+		-> b
+	;;
+}
+
+generic clamp = {a, min, max
+	if a < min
+		-> min
+	elif a > max
+		-> max
+	else
+		-> a
+	;;
+}
+
+generic abs = {a : @a::numeric
+	if a < (0 castto(@a::numeric))
+		-> -a
+	else
+		-> a
+	;;
+}
--- /dev/null
+++ b/lib/std/fltbits.myr
@@ -1,0 +1,60 @@
+pkg std =
+	const flt64bits	: (flt : flt64 -> int64)
+	const flt32bits	: (flt : flt32 -> int32)
+	const flt64frombits	: (bits : uint64 -> flt64)
+	const flt32frombits	: (bits : uint32 -> flt32)
+	const flt64explode	: (flt : flt64 -> (bool, int64, int64))
+	const flt32explode	: (flt : flt32 -> (bool, int32, int32))
+;;
+
+const flt64bits	= {flt;	-> (&flt castto(int64#))#}
+const flt32bits	= {flt;	-> (&flt castto(int32#))#}
+const flt64frombits	= {bits;	-> (&bits castto(flt64#))#}
+const flt32frombits	= {bits;	-> (&bits castto(flt32#))#}
+
+const flt64explode = {flt
+	var bits, isneg, mant, exp
+
+	bits = flt64bits(flt)
+	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] */
+
+	/* add back the implicit bit if this is not a denormal */
+	if exp != 0
+		mant |= 1l << 52
+	else
+		exp = 1
+	;;
+	/*
+	   adjust for exponent bias. nb: because we are
+	   treating the mantissa as m.0 instead of 0.m,
+	   our exponent bias needs to be offset by the
+	   size of m
+	*/
+	-> (isneg, mant, exp)
+}
+
+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] */
+
+	/* add back the implicit bit if this is not a denormal */
+	if exp != 0
+		mant |= 1 << 22
+	else
+		exp = 1
+	;;
+	/*
+	   adjust for exponent bias. nb: because we are
+	   treating the mantissa as m.0 instead of 0.m,
+	   our exponent bias needs to be offset by the
+	   size of m
+	*/
+	-> (isneg, mant, exp)
+}
+
--- /dev/null
+++ b/lib/std/fltfmt.myr
@@ -1,0 +1,239 @@
+use "alloc.use"
+use "bigint.use"
+use "die.use"
+use "extremum.use"
+use "fltbits.use"
+use "slpush.use"
+use "strbuf.use"
+use "types.use"
+use "utf.use"
+
+pkg std =
+	pkglocal const MNormal = 0
+	pkglocal const MAbsolute = 1
+	pkglocal const MRelative = 2
+
+	pkglocal const flt64bfmt	: (sb : strbuf#, val : flt64, mode : int, precision : int -> void)
+	pkglocal const flt32bfmt	: (sb : strbuf#, val : flt32, mode : int, precision : int -> void)
+;;
+
+const Dblbias = 1023
+const Fltbias = 127
+
+const flt64bfmt = {sb, val, mode, precision
+	var isneg, exp, mant
+
+	(isneg, mant, exp) = flt64explode(val)
+	dragon4(sb, isneg, mant, (exp - 52) castto(int64), Dblbias, mode, precision)
+}
+
+const flt32bfmt = {sb, val, mode, precision
+	var isneg, exp, mant
+
+	(isneg, mant, exp) = flt32explode(val)
+	dragon4(sb, isneg, mant castto(int64), (exp - 52) castto(int64), Fltbias, mode, precision)
+}
+
+/*
+sb: output buffer
+e: exponent
+p: precision
+f: mantissa
+
+flting value: x = f^(e - p)
+*/
+const dragon4 = {sb, isneg, f, e, p, mode, cutoff
+	var r, s, t, u, v, y
+	var udig
+	var mm, mp	/* margins above and below */
+	var roundup
+	var low, high
+	var k, n
+	var a, i
+
+	/* if we have zero for the mantissa, we can return early */
+	n = 0
+	if isneg
+		sbputs(sb, "-")
+	;;
+	if f == 0
+		sbputs(sb, "0.0")
+	;;
+
+	/* initialize */
+	roundup = false
+	r = mkbigint(f)
+	r = bigshli(r, max(e - p, 0))
+	s = bigshli(mkbigint(1), max(0, -(e - p)))
+	mm = bigshli(mkbigint(1), max((e - p), 0))
+	mp = bigdup(mm)
+
+	/* fixup: unequal gaps */
+	t = mkbigint(1)
+	bigshli(t, p - 1)
+	if bigeqi(t, f)
+		bigshli(mp, 1)
+		bigshli(r, 1)
+		bigshli(s, 1)
+	;;
+	bigfree(t)
+
+	k = 0
+	while true
+		/* r < ceil(s/b) */
+		t = bigdup(s)
+		bigaddi(t, 9)
+		bigdivi(t, 10)
+		match bigcmp(r, t)
+		| `Before:
+			k--
+			bigmuli(r, 10)
+			bigmuli(mm, 10)
+			bigmuli(mp, 10)
+		| _:
+			bigfree(t)
+			break
+		;;
+		bigfree(t)
+	;;
+
+	while true
+		t = bigdup(r)
+		bigshli(t, 1)
+		bigadd(t, mp)
+		while true
+			u = bigdup(s)
+			bigshli(u, 1)
+			match bigcmp(t, u)
+			| `Before:
+				bigfree(u)
+				break
+			| _:
+				k++
+				bigmuli(s, 10)
+				bigfree(u)
+			;;
+		;;
+		if mode == MNormal
+			cutoff = k
+		else
+			if mode == MRelative
+				cutoff += k - 1
+			;;
+			/* common between relative and absolute */
+			a = cutoff - k - 1
+			y = bigdup(s)
+			if a < 0
+				for i = 0; i < a; i++
+					bigmuli(y, 10)
+				;;
+			else
+				for i = 0; i < -a; i++
+					bigaddi(y, 9)
+					bigdivi(y, 10)
+				;;
+			;;
+			match bigcmp(y, mm)
+			| `Before:	/* nothing */
+			| _:
+				bigfree(mm)
+				mm = y
+			;;
+			match bigcmp(y, mp)
+			| `Before:	/* nothing */
+			| _:
+				bigfree(mp)
+				mp = y
+				roundup = true
+			;;
+		;;
+		u = bigdup(s)
+		bigshli(u, 1)
+		match bigcmp(t, u)
+		| `Before:
+			bigfree(t)
+			bigfree(u)
+			break
+		| _:
+		;;
+	;;
+
+	if k <= 0
+		sbputs(sb, "0.")
+	;;
+	while true
+		k--
+		bigmuli(r, 10)
+		u = bigdup(r);
+		bigdiv(u, s)
+
+		bigmod(r, s)
+		bigmuli(mm, 10)
+		bigmuli(mp, 10)
+
+		low = false
+		t = bigdup(r)
+		bigshli(t, 1)
+		match bigcmp(t, mm)
+		| `Before:	low = true
+		| _:
+		;;
+		bigfree(t)
+		
+		v = bigdup(r)
+		bigshli(v, 1)
+		t = bigdup(s)
+		bigshli(t, 1)
+		bigsub(t, mp)
+		match bigcmp(v, t)
+		| `After: high = true
+		| `Equal: high = roundup
+		| `Before: high = false
+		;;
+		bigfree(v)
+		bigfree(t)
+		if low || high || k == cutoff
+			break
+		;;
+		format(sb, lowdig(u), k)
+		bigfree(u)
+	;;
+
+	/* format the last digit */
+	udig = lowdig(u)
+	if low && !high
+		format(sb, udig, k)
+	elif high && !low
+		format(sb, udig + 1, k)
+	else
+		bigmuli(r, 2)
+		match bigcmp(r, s)
+		| `Before:	format(sb, udig, k)
+		| `Equal:	format(sb, udig, k)
+		| `After:	format(sb, udig + 1, k)
+		;;
+	;;
+	-> n
+}
+
+const lowdig = {u
+	if u.dig.len > 0
+		-> u.dig[0]
+	;;
+	-> 0
+}
+
+const format = {sb, d, k
+	const dig = "0123456789"
+	var i
+
+	if k < 0
+		for i = 0; i < -k - 1; i++
+			sbputs(sb, "0")
+		;;
+	;;
+	sbputb(sb, dig[d])
+	if k == 0
+		sbputs(sb, ".")
+	;;
+}
--- /dev/null
+++ b/lib/std/fmt.myr
@@ -1,0 +1,499 @@
+use "alloc.use"
+use "chartype.use"
+use "die.use"
+use "extremum.use"
+use "fltfmt.use"
+use "hashfuncs.use"
+use "hasprefix.use"
+use "htab.use"
+use "introspect.use"
+use "intparse.use"
+use "option.use"
+use "sleq.use"
+use "slpush.use"
+use "strbuf.use"
+use "strfind.use"
+use "strsplit.use"
+use "syswrap-ss.use"
+use "syswrap.use"
+use "types.use"
+use "utf.use"
+use "varargs.use"
+
+pkg std =
+	/* write to fd */
+	const put	: (fmt : byte[:], args : ... -> size)
+	const fput	: (fd : fd, fmt : byte[:], args : ... -> size)
+	const putv	: (fmt : byte[:], ap : valist# -> size)
+	const fputv	: (fd : fd, fmt : byte[:], ap : valist# -> size)
+
+	/* write to buffer */
+	const fmt	: (fmt : byte[:], args : ... -> byte[:])
+	const fmtv	: (fmt : byte[:], ap : valist# -> byte[:])
+	const bfmt	: (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
+	const bfmtv	: (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
+
+	/* write to strbuf */
+	const sbfmt	: (buf : strbuf#, fmt : byte[:], args : ... -> size)
+	const sbfmtv	: (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
+
+	/* add a formatter function */
+	const fmtinstall	: (ty : byte[:], \
+		fn : (sb : strbuf#, ap : valist#, opts : (byte[:],byte[:])[:] -> void), \
+		optdesc : (byte[:], bool)[:] \
+		-> void)
+
+	$noret const fatal	: (fmt : byte[:], args : ... -> void)
+	$noret const fatalv	: (fmt : byte[:], ap : valist# -> void)
+;;
+
+const __init__ = {
+	fmtmap = mkht(strhash, streq)
+}
+
+type fmtdesc = struct
+	fn	: (sb : strbuf#, ap : valist#, opts : (byte[:],byte[:])[:] -> void)
+	optdesc	: (byte[:], bool)[:]
+;;
+
+/* same as 'put', but exits the program after printing */
+const fatal = {fmt, args
+	var ap
+
+	ap = vastart(&args)
+	putv(fmt, &ap)
+	exit(1)
+}
+
+/* same as 'putv', but exits the program after printing */
+const fatalv = {fmt, ap
+	putv(fmt, ap)
+	exit(1)
+}
+
+var fmtmap : htab(byte[:], fmtdesc)#
+
+const fmtinstall = {ty, fn, optdesc
+	htput(fmtmap, ty, [.fn=fn, .optdesc=optdesc])
+}
+
+const put = {fmt, args
+	var ap
+
+	ap = vastart(&args)
+	-> fputv(1, fmt, &ap)
+}
+
+const putv = {fmt, ap
+	-> fputv(1, fmt, ap)
+}
+
+const fput = {fd, fmt, args
+	var ap
+
+	ap = vastart(&args)
+	-> fputv(fd, fmt, &ap)
+}
+
+const fputv = {fd, fmt, ap
+	var sb, s
+
+	sb = mksb()
+	sbfmtv(sb, fmt, ap)
+	s = sbfin(sb)
+	-> writeall(fd, s)
+}
+
+const fmt = {fmt, args
+	var ap
+
+	ap = vastart(&args)
+	-> fmtv(fmt, &ap)
+}
+
+const fmtv = {fmt, ap
+	var sb
+
+	sb = mksb()
+	sbfmtv(sb, fmt, ap)
+	-> sbfin(sb)
+}
+
+const bfmt = {buf, fmt, args
+	var ap
+
+	ap = vastart(&args)
+	-> bfmtv(buf, fmt, &ap)
+}
+
+const bfmtv = {buf, fmt, ap
+	var sb
+
+	sb = mkbufsb(buf)
+	sbfmtv(sb, fmt, ap)
+	-> sbfin(sb)
+}
+
+const sbfmt = {sb, fmt, args
+	var ap
+
+	ap = vastart(&args)
+	-> sbfmtv(sb, fmt, &ap)
+}
+
+const sbfmtv = {sb, fmt, ap -> size
+	var nfmt, nparams, pl, orig
+	var c, params, ty
+
+	orig = fmt
+	nparams = ap.tc.nelt
+	nfmt = 0
+	while fmt.len != 0
+		(c, fmt) = striter(fmt)
+		match c
+		| '{':
+			if decode(fmt) == '{'
+				(c, fmt) = striter(fmt)
+				sbputc(sb, '{')
+			else
+				(params, fmt) = getparams(fmt)
+				nfmt++
+				if nfmt > nparams
+					die("too few params for fmt\n")
+				;;
+
+				ty = vatype(ap)
+				match htget(fmtmap, ty)
+				| `Some f:
+					pl = parseparams(params, f.optdesc)
+					f.fn(sb, ap, pl)
+					std.slfree(pl)
+				| `None:
+					fallbackfmt(sb, params, ty, ap)
+				;;
+			;;
+		| '}':
+			if decode(fmt) == '}'
+				sbputc(sb, '}')
+			;;
+		| chr:
+			sbputc(sb, chr)
+		;;
+:fmtdone
+	;;
+	if nfmt != nparams
+		write(1, orig)
+		die("too many params for fmt\n")
+	;;
+	-> sb.len
+}
+
+const parseparams = {paramstr, optdesc
+	var params, opts
+	var o, a, ha : bool, gotarg : bool
+
+	opts = [][:]
+	params = strsplit(paramstr, ",")
+	for p in params
+		/* parse out the key/value pair */
+		match std.strfind(p, "=")
+		| `std.Some idx:
+			o = p[:idx]
+			a = p[idx+1:]
+			gotarg = true
+		| `std.None:
+			o = p
+			a = ""
+			gotarg = false
+		;;
+
+		/* verify and add the arg */
+		for (opt, hasarg) in optdesc
+			if !std.sleq(opt, o)
+				continue
+			;;
+			ha = hasarg
+			if ha == gotarg
+				opts = std.slpush(opts, (o, a))
+			else
+				std.fatal("invalid option {}", o)
+			;;
+		;;
+	;;
+	slfree(params)
+	-> opts
+}
+
+
+const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
+	/* value types */
+	var t_val : bool
+	var b_val : int8, ub_val : uint8
+	var w_val : int16, uw_val : uint16
+	var i_val : int32, ui_val : uint32
+	var l_val : int64, ul_val : uint64
+	var z_val : size
+	var p_val : byte#
+        var c_val : char
+	var s_val : byte[:]
+	var f32_val : flt32, f64_val : flt64
+	var i8 : int8, i16: int16, i32 : int32
+	var by : byte
+	var i : int, i64 : int64, l : long
+	var ui8 : int8, ui16: int16, ui32 : int32
+	var ui : int, ui64 : int64, ul : long
+
+	match typedesc(tyenc)
+	| `Tynone:	/* nothing */
+	/* atomic types */
+	| `Tyvoid:
+		sbputs(sb, "void")
+	| `Tybool:
+		t_val = vanext(ap)
+		if t_val
+			sbputs(sb ,"true")
+		else
+			sbputs(sb, "false")
+		;;
+	| `Tychar:
+		c_val = vanext(ap)
+		sbputc(sb, c_val)
+	| `Tyint8:
+		b_val = vanext(ap)
+		intfmt(sb, intparams(params), true, b_val)
+	| `Tyint16:
+		w_val = vanext(ap)
+		intfmt(sb, intparams(params), true, w_val)
+	| `Tyint:
+		i_val = vanext(ap)
+		intfmt(sb, intparams(params), true, i_val)
+	| `Tyint32:
+		i_val = vanext(ap)
+		intfmt(sb, intparams(params), true, i_val)
+	| `Tyint64:
+		l_val = vanext(ap)
+		intfmt(sb, intparams(params), true, l_val)
+	| `Tylong:
+		l_val = vanext(ap)
+		intfmt(sb, intparams(params), true, l_val)
+
+	| `Tybyte:
+		ub_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ub_val)
+	| `Tyuint8:
+		ub_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ub_val)
+	| `Tyuint16:
+		uw_val = vanext(ap)
+		intfmt(sb, intparams(params), false, uw_val)
+	| `Tyuint:
+		ui_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ui_val)
+	| `Tyuint32:
+		ui_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ui_val)
+	| `Tyuint64:
+		ul_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ul_val)
+	| `Tyulong:
+		ul_val = vanext(ap)
+		intfmt(sb, intparams(params), false, ul_val)
+	| `Tyflt32:
+		f32_val = vanext(ap)
+		flt32bfmt(sb, f32_val, MNormal, 0)
+	| `Tyflt64:
+		f64_val = vanext(ap)
+		flt64bfmt(sb, f64_val, MNormal, 0)
+	| `Tyvalist:
+		sbputs(sb, "...")
+
+	/* compound types */
+	| `Typtr desc:
+		p_val = vanext(ap)
+		sbputs(sb, "0x")
+		intfmt(sb, \
+			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
+			false, p_val castto(intptr))
+	| `Tyslice desc:
+		match typedesc(desc)
+		| `Tybyte:
+			s_val = vanext(ap)
+			strfmt(sb, s_val, params)
+		| _:
+			sbputs(sb, "slice[:]")
+		;;
+	| `Tyfunc tc:
+		p_val = vanext(ap)
+		sbputs(sb, "func{")
+		intfmt(sb, \
+			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
+			false, p_val castto(intptr))
+		sbputs(sb, "}")
+	| `Tyarray (sz, data):
+		sbputs(sb, "array")
+	/* aggregate types */
+	| `Tytuple typecursor:
+		vabytes(ap)
+		sbputs(sb, "tuple")
+	| `Tystruct namecursor:
+		vabytes(ap)
+		sbputs(sb, "struct")
+	| `Tyunion namecursor:
+		vabytes(ap)
+		sbputs(sb, "union")
+	| `Tyname (name, desc):
+		fallbackfmt(sb, params, desc, ap)
+	;;
+}
+
+const getparams = {fmt
+	var i
+
+	for i = 0; i < fmt.len; i++
+		if fmt[i] == '}' castto(byte)
+			goto foundparams
+		;;
+	;;
+	die("invalid format string")
+:foundparams
+	-> (fmt[:i], fmt[i+1:])
+}
+
+type intparams = struct
+	base	: size
+	padto	: size
+	padfill	: char
+;;
+
+const intparams = {params
+	var ip : intparams
+	var opts
+
+	ip = [
+		.base = 10,
+		.padfill = ' ',
+		.padto = 0
+	]
+
+	opts = parseparams(params, [
+		("x", false),
+		("w", true),
+		("p", true)][:])
+	for o in opts
+		match o
+		| ("x", ""):	ip.base = 16
+		| ("w", wid):	ip.padto = getint(wid, "fmt: width must be integer")
+		| ("p", pad):	ip.padfill = decode(pad)
+		| _:	std.die("unreachable")
+		;;
+	;;
+	std.assert(ip.padto >= 0, "pad must be >= 0")
+	std.slfree(opts)
+	-> ip
+}
+
+const strfmt = {sb, str, params
+	var opts
+	var w, p, i
+
+	p = ' '
+	w = 0
+	opts = parseparams(params, [
+		("w", true),
+		("p", true)][:])
+	for o in opts
+		match o
+		| ("w", wid):	w = getint(wid, "fmt: width must be integer")
+		| ("p", pad):	p = decode(pad)
+		| _:	std.die("unreachable")
+		;;
+	;;
+	std.assert(p >= 0, "pad must be >= 0")
+	std.slfree(opts)
+	for i = 0; i < w - graphemewidth(str); i++
+		sbputc(sb, p)
+	;;
+	sbputs(sb, str)
+}
+
+/*
+Hah. like we're going to put in the work to actually
+count graphemes.
+*/
+const graphemewidth = {str
+	-> str.len
+}
+
+const digitchars = [
+	'0','1','2','3','4',
+	'5','6','7','8','9',
+	'a','b','c','d','e','f'
+]
+generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric)
+	var isneg
+	var val
+	var b : char[32]
+	var i, j, npad
+	var base
+
+	base = opts.base castto(uint64)
+	if signed && bits < 0
+		val = -bits castto(uint64)
+		isneg = true
+	else
+		val = bits castto(uint64)
+		val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a)))
+		isneg = false
+	;;
+
+	i = 0
+	if val == 0
+		b[0] = '0'
+		i++
+	;;
+	while val != 0
+		b[i] = digitchars[val % base]
+		val /= base
+		i++
+	;;
+
+	npad = clamp(opts.padto - i, 0, opts.padto)
+	if isneg
+		npad--
+	;;
+	if opts.padfill == '0' && isneg
+		sbputc(sb, '-')
+	;;
+	for j = 0; j < npad; j++
+		sbputc(sb, opts.padfill)
+	;;
+	if opts.padfill != '0' && isneg
+		sbputc(sb, '-')
+	;;
+	for j = i; j != 0; j--
+		sbputc(sb, b[j - 1])
+	;;
+}
+
+const writeall = {fd, buf
+	var n, len
+
+	len = 0
+	while true
+		n = write(fd, buf)
+		if n <= 0 || n >= len
+			break
+		;;
+		len += n
+	;;
+	-> len
+}
+
+
+/* would use std.get(), but that's a dependency loop */
+const getint = {s, msg
+	match std.intparse(s)
+	| `Some w:	-> w;
+	| `None:	die(msg)
+	;;
+}
--- /dev/null
+++ b/lib/std/fmtfuncs.myr
@@ -1,0 +1,54 @@
+use "alloc.use"
+use "bigint.use"
+use "bitset.use"
+use "fmt.use"
+use "introspect.use"
+use "strbuf.use"
+use "varargs.use"
+
+pkg std =
+;;
+
+const __init__ = {
+	var bigint : bigint#
+	var bitset : bitset#
+
+	fmtinstall(typeof(bigint), bigfmt, [][:])
+	fmtinstall(typeof(bitset), bsfmt, [][:])
+}
+
+const bigfmt = {sb, ap, opts
+	var a, n, buf
+
+	a = vanext(ap)
+ 	/*
+	allocate a buffer guaranteed to be big enough.
+	that's 
+		2 + floor(nbits/(log_2(10)))
+	or
+		2 + a.dig.len * 32/3.32...
+	or
+		2 + a.dig.len * 10
+	plus one for the - sign.
+	*/
+	buf = slalloc(3 + a.dig.len * 10)
+	n = bigbfmt(buf, a, 10)
+	sbputs(sb, buf[:n])
+	slfree(buf)
+}
+
+const bsfmt = {sb, ap, opts
+	var i, bs, sep
+
+	bs = vanext(ap)
+	sep = ""
+	sbputs(sb, "bitset{")
+	for i = 0; i < bsmax(bs); i++
+		if bshas(bs, i)
+			sbfmt(sb, sep)
+			sbfmt(sb, "{}", i)
+			sep = ", "
+		;;
+	;;
+	sbputs(sb, "}")
+}
--- /dev/null
+++ b/lib/std/getcwd.myr
@@ -1,0 +1,31 @@
+
+use "alloc.use"
+use "errno.use"
+use "extremum.use"
+use "syswrap.use"
+use "syswrap-ss.use"
+pkg std =
+	const getcwd : (-> byte[:])
+;;
+
+const getcwd = {
+	var len, n, buf
+
+	len = 128
+	while true
+		buf = std.slalloc(len)
+		n = bgetcwd(buf)
+		if n >= 0
+			/* n is the length of the nul terminated c string */
+			-> buf[:n]
+		elif n != Erange
+			std.slfree(buf)
+			-> ""
+		else
+			len *= 2
+		;;
+	;;
+	/* unreachable; shut up return without value analysis */
+	-> ""
+}
+	
--- /dev/null
+++ b/lib/std/getint.myr
@@ -1,0 +1,64 @@
+pkg std =
+	generic getle64	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getbe64	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getle32	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getbe32	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getle16	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getbe16	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getle8	: (buf : byte[:]	-> @a::(numeric,integral))
+	generic getbe8	: (buf : byte[:]	-> @a::(numeric,integral))
+;;
+
+generic getbe64 = {buf -> @a::(numeric,integral)
+	-> ((buf[0] castto(@a::(numeric,integral))) << 56) | \
+		((buf[1] castto(@a::(numeric,integral))) << 48) | \
+		((buf[2] castto(@a::(numeric,integral))) << 40) | \
+		((buf[3] castto(@a::(numeric,integral))) << 32) | \
+		((buf[4] castto(@a::(numeric,integral))) << 24) | \
+		((buf[5] castto(@a::(numeric,integral))) << 16) | \
+		((buf[6] castto(@a::(numeric,integral))) << 8) | \
+		((buf[7] castto(@a::(numeric,integral))) << 0)
+}
+
+generic getle64 = {buf
+	-> ((buf[0] castto(@a::(numeric,integral)))  << 0) | \
+		((buf[1] castto(@a::(numeric,integral)))  << 8) | \
+		((buf[2] castto(@a::(numeric,integral)))  << 16) | \
+		((buf[3] castto(@a::(numeric,integral)))  << 24) | \
+		((buf[4] castto(@a::(numeric,integral)))  << 32) | \
+		((buf[5] castto(@a::(numeric,integral)))  << 40) | \
+		((buf[6] castto(@a::(numeric,integral)))  << 48) | \
+		((buf[7] castto(@a::(numeric,integral)))  << 56)
+}
+
+generic getbe32 = {buf
+	-> ((buf[0] castto(@a::(numeric,integral))) << 24) | \
+		((buf[1] castto(@a::(numeric,integral))) << 16) | \
+		((buf[2] castto(@a::(numeric,integral))) << 8) | \
+		((buf[3] castto(@a::(numeric,integral))) << 0)
+}
+
+generic getle32 = {buf
+	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
+		((buf[1] castto(@a::(numeric,integral))) << 8) | \
+		((buf[2] castto(@a::(numeric,integral))) << 16) | \
+		((buf[3] castto(@a::(numeric,integral))) << 24)
+}
+
+generic getbe16 = {buf
+	-> ((buf[0] castto(@a::(numeric,integral))) << 8) | \
+		((buf[1] castto(@a::(numeric,integral))) << 0)
+}
+
+generic getle16 = {buf
+	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
+		((buf[1] castto(@a::(numeric,integral))) << 8)
+}
+
+generic getbe8 = {buf
+	-> (buf[0] castto(@a::(numeric,integral))) << 0
+}
+
+generic getle8 = {buf
+	-> (buf[0] castto(@a::(numeric,integral))) << 0
+}
--- /dev/null
+++ b/lib/std/hashfuncs.myr
@@ -1,0 +1,106 @@
+use "die.use"
+use "sleq.use"
+use "types.use"
+
+pkg std =
+	const strhash	: (s : byte[:]	-> uint32)
+	const streq	: (a : byte[:], b : byte[:]	-> bool)
+
+	generic ptrhash	: (p : @a#	-> uint32)
+	generic ptreq	: (a : @a#, b : @a#	-> bool)
+
+	generic inthash	: (v : @a::(integral,numeric)	-> uint32)
+	generic inteq	: (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
+
+	const murmurhash2	: (data : byte[:], seed : uint32 -> uint32)
+
+	generic slhash	: (sl : @a[:] -> uint32)
+	generic tobytes	: (sl : @a[:] -> byte[:])
+;;
+
+const Seed = 1234
+
+generic slhash = {data : @a[:]
+	-> strhash(slbytes(data))
+}
+
+generic slbytes = {data : @a[:]
+	var n
+
+	n = data.len * sizeof(@a)
+	-> (data castto(byte#))[:n]
+}
+
+/* Supremely simple djb hash. */
+const strhash = {s
+	-> murmurhash2(s, Seed)
+}
+
+const streq = {a, b
+	-> sleq(a, b)
+}
+
+generic ptrhash = {p : @a#
+	var x
+
+	x = &p castto(byte#)
+	-> murmurhash2(x[0:sizeof(@a)], Seed)
+}
+
+generic ptreq = {a, b
+	-> a == b
+}
+
+generic inthash = {v : @a::(integral,numeric)
+	var p
+
+	p = &v castto(byte#)
+	-> murmurhash2(p[0:sizeof(@a)], Seed)
+}
+
+generic inteq = {a, b
+	-> a == b
+}
+
+const murmurhash2 = {data, seed
+	const m = 0x5bd1e995;
+	const r = 24
+	var h, k
+	
+	h = seed ^ data.len
+	while data.len >= 4
+		k = (data[0] castto(uint32))
+		k |= (data[1] castto(uint32)) << 8
+		k |= (data[2] castto(uint32)) << 16
+		k |= (data[3] castto(uint32)) << 24
+
+		k *= m
+		k ^= k >> r
+		k *= m
+
+		h *= m
+		h ^= k
+		data = data[4:]
+	;;
+
+	match data.len
+	| 3:
+		h ^= (data[2] castto(uint32)) << 16
+		h ^= (data[1] castto(uint32)) <<8
+		h ^= (data[0] castto(uint32))
+	| 2:
+		h ^= (data[1] castto(uint32)) <<8
+		h ^= (data[0] castto(uint32))
+	| 1:
+		h ^= (data[0] castto(uint32))
+	| 0:	/* nothing */
+	| _:	die("0 < len < 4 must be true")
+	;;
+	h *= m
+
+	h ^= h >> 13
+	h *= m
+	h ^= h >> 15
+
+	-> h
+}
--- /dev/null
+++ b/lib/std/hasprefix.myr
@@ -1,0 +1,12 @@
+use "cmp.use"
+pkg std =
+	const hasprefix	: (s : byte[:], pre : byte[:] -> bool)
+;;
+
+const hasprefix = {s, pre
+       match strncmp(s, pre, pre.len)
+       | `Equal:       -> true
+       | _:            -> false
+       ;;
+}
+
--- /dev/null
+++ b/lib/std/hassuffix.myr
@@ -1,0 +1,15 @@
+use "sleq.use"
+pkg std =
+	const hassuffix	: (s : byte[:], suff : byte[:] -> bool)
+;;
+
+const hassuffix = {s, suff
+	var tail
+
+	if suff.len <= s.len
+		tail = s[s.len - suff.len:]
+		-> sleq(tail, suff)
+	;;
+	-> false
+}
+
--- /dev/null
+++ b/lib/std/htab.myr
@@ -1,0 +1,209 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "option.use"
+use "types.use"
+
+pkg std =
+	type htab(@k, @v) = struct
+		hash	: (k : @k	-> uint32)
+		eq	: (a : @k, b : @k -> bool)
+
+		nelt	: size
+		ndead	: size
+		keys	: @k[:]
+		vals	: @v[:]
+		hashes	: uint32[:]
+		dead	: bool[:]
+	;;
+
+	generic mkht	: (h : (k : @k -> uint32), eq : (a : @k, b : @k -> bool) -> htab(@k, @v)#)
+	generic htfree	: (ht : htab(@k, @v)# -> void)
+	generic htput	: (ht : htab(@k, @v)#, k : @k, v : @v -> void)
+	generic htdel	: (ht : htab(@k, @v)#, k : @k -> void)
+	generic htget	: (ht : htab(@k, @v)#, k : @k -> option(@v))
+	generic htgetv	: (ht : htab(@k, @v)#, k : @k, fallback : @v-> @v)
+	generic hthas	: (ht : htab(@k, @v)#, k : @k -> bool)
+	generic htkeys	: (ht : htab(@k, @v)# -> @k[:])
+;;
+
+const Initsz = 32
+
+extern const put : (fmt : byte[:], args : ... -> size)
+
+generic hash = {ht, k
+	var h
+
+	h = ht.hash(k)
+	if h == 0
+		-> 1
+	else
+		-> h
+	;;
+}
+
+generic resize = {ht, sz
+	var oldk
+	var oldv
+	var oldh
+	var oldd
+	var i
+
+	oldk = ht.keys
+	oldv = ht.vals
+	oldh = ht.hashes
+	oldd = ht.dead
+	ht.keys = slalloc(sz)
+	ht.vals = slalloc(sz)
+	ht.hashes = slzalloc(sz)
+	ht.dead = slzalloc(sz)
+
+	ht.nelt = 0
+	ht.ndead = 0
+	for i = 0; i < oldk.len; i++
+		if oldh[i] != 0 && !oldd[i]
+			htput(ht, oldk[i], oldv[i])
+		;;
+	;;
+	slfree(oldk)
+	slfree(oldv)
+	slfree(oldh)
+	slfree(oldd)
+}
+
+generic idx = {ht, k
+	var i, di
+	var h
+
+	di = 0
+	h = hash(ht, k)
+	i = h & (ht.keys.len - 1)
+	while true
+		while ht.hashes[i] != 0 && !ht.dead[i] && ht.hashes[i] != h
+			di++
+			i = (h + di) & (ht.keys.len - 1)
+		;;
+
+		if ht.hashes[i] == 0
+			-> `None
+		;;
+		if ht.hashes[i] == h && !ht.dead[i] && ht.eq(ht.keys[i], k)
+			break
+		;;
+		di++
+		i = (h + di) & (ht.keys.len - 1)
+	;;
+	-> `Some i
+}
+
+generic mkht = {h, eq
+	var ht
+
+	ht = alloc()
+
+	ht.hash = h
+	ht.eq = eq
+
+	ht.nelt = 0
+	ht.ndead = 0
+	ht.keys = slalloc(Initsz)
+	ht.vals = slalloc(Initsz)
+	ht.hashes = slzalloc(Initsz)
+	ht.dead = slzalloc(Initsz)
+	-> ht
+}
+
+generic htfree = {ht
+	slfree(ht.keys)
+	slfree(ht.vals)
+	slfree(ht.hashes)
+	slfree(ht.dead)
+	free(ht)
+}
+
+generic htput = {ht, k, v
+	var i, di
+	var h
+	var neltincr
+
+	di = 0
+	h = hash(ht, k)
+	i = h & (ht.keys.len - 1)
+	neltincr = 1
+	while ht.hashes[i] != 0 && !ht.dead[i]
+		/* second insertion overwrites */
+		if ht.hashes[i] == h && !ht.dead[i]
+			/* dead key, we can just insert here */
+			if ht.dead[i]
+				break
+			/* replacing a key */
+			elif ht.eq(ht.keys[i], k)
+				neltincr = 0
+				break
+			;;
+		;;
+		di++
+		i = (h + di) & (ht.keys.len - 1)
+	;;
+	ht.nelt += neltincr
+	ht.hashes[i] = h
+	ht.keys[i] = k
+	ht.vals[i] = v
+	ht.dead[i] = false
+	if ht.keys.len < ht.nelt * 2
+		resize(ht, 2*ht.keys.len)
+	;;
+}
+
+generic htdel = {ht, k
+	match idx(ht, k)
+	| `Some i:
+		ht.dead[i] = true
+		ht.nelt--
+		ht.ndead++
+		std.put("ndead = {}\n", ht.ndead)
+		/* remove tombstones if we shrink enough */
+		if ht.keys.len < ht.ndead * 4
+			resize(ht, ht.keys.len)
+		;;
+	| _:	
+		/* do nothing */
+	;;
+}
+
+generic htget = {ht, k
+	match idx(ht, k)
+	| `Some i:	-> `Some ht.vals[i]
+	| `None:	-> `None
+	;;
+}
+
+generic htgetv = {ht, k, v
+	match idx(ht, k)
+	| `Some i:	-> ht.vals[i]
+	| `None:	-> v
+	;;
+}
+
+generic hthas = {ht, k
+	match idx(ht, k)
+	| `Some i:	-> true
+	| `None:	-> false
+	;;
+}
+
+generic htkeys = {ht
+	var keys
+	var i
+	var j
+
+	keys = slalloc(ht.nelt)
+	j = 0
+	for i = 0; i < ht.keys.len; i++
+		if ht.hashes[i] != 0 && !ht.dead[i]
+			keys[j++] = ht.keys[i]
+		;;
+	;;
+	-> keys
+}
+
--- /dev/null
+++ b/lib/std/ifreq+linux.myr
@@ -1,0 +1,67 @@
+use "sys.use"
+
+pkg sys =
+	const Ifnamesz = 16
+
+	type ifreq_addr = struct
+		name	: byte[Ifnamesz]
+		addr	: sockaddr
+	;;
+
+	type ifreq_dstaddr = struct
+		name	: byte[Ifnamesz]
+		dstaddr	: sockaddr
+	;;
+
+	type ifreq_broadaddr = struct
+		name	: byte[Ifnamesz]
+		broadaddr	: sockaddr
+	;;
+
+	type ifreq_netmask = struct
+		name	: byte[Ifnamesz]
+		netmask	: sockaddr
+	;;
+
+
+	type ifreq_hwaddr = struct
+		name	: byte[Ifnamesz]
+		hwaddr	: sockaddr
+	;;
+
+	type ifreq_flags = struct
+		name	: byte[Ifnamesz]
+		flags	: int16
+	;;
+
+	type ifreq_ifindex = struct
+		name	: byte[Ifnamesz]
+		index	: int32
+	;;
+
+	type ifreq_metric = struct
+		name	: byte[Ifnamesz]
+		metric	: int32
+	;;
+
+
+	type ifreq_mtu = struct
+		name	: byte[Ifnamesz]
+		mtu	: int32
+	;;
+
+	type ifreq_slave = struct
+		name	: byte[Ifnamesz]
+		slave	: byte[Ifnamesz]
+	;;
+
+	type ifreq_newname = struct
+		name	: byte[Ifnamesz]
+		newname	: byte[Ifnamesz]
+	;;
+
+	type ifreq_data = struct
+		name	: byte[Ifnamesz]
+		data	: void#
+	;;
+;;
--- /dev/null
+++ b/lib/std/ifreq+osx.myr
@@ -1,0 +1,77 @@
+use "sys.use"
+
+pkg sys =
+	const Ifnamesz = 16
+
+	type ifreq_addr = struct
+		name	: byte[Ifnamesz]
+		addr	: sockaddr
+	;;
+
+	type ifreq_dstaddr = struct
+		name	: byte[Ifnamesz]
+		dstaddr	: sockaddr
+	;;
+
+	type ifreq_broadaddr = struct
+		name	: byte[Ifnamesz]
+		broadaddr	: sockaddr
+	;;
+
+	type ifreq_flags = struct
+		name	: byte[Ifnamesz]
+		flags	: int16
+	;;
+
+	type ifreq_metric = struct
+		name	: byte[Ifnamesz]
+		metric	: int32
+	;;
+
+
+	type ifreq_phys = struct
+		name	: byte[Ifnamesz]
+		phys	: int32
+	;;
+
+	type ifreq_media = struct
+		name	: byte[Ifnamesz]
+		media	: int32
+	;;
+
+	type ifreq_data = struct
+		name	: byte[Ifnamesz]
+		data	: void#
+	;;
+
+	type ifreq_devmtu = struct
+		name	: byte[Ifnamesz]
+                cur	: uint32
+                min	: uint32
+                max	: uint32
+	;;
+
+	type ifreq_kpi = struct
+		name	: byte[Ifnamesz]
+                modid	: uint32
+                typeid	: uint32
+		ptr	: void#
+	;;
+
+	type ifreq_wakeflg = struct
+		name	: byte[Ifnamesz]
+		wakeflg	: uint32
+	;;
+		
+	type ifreq_routerefs = struct
+		name	: byte[Ifnamesz]
+		refs	: uint32
+	;;
+
+	type ifreq_icaps = struct
+		name	: byte[Ifnamesz]
+		req	: uint32
+		cur	: uint32
+	;;
+
+;;
--- /dev/null
+++ b/lib/std/ifreq+plan9.myr
@@ -1,0 +1,2 @@
+pkg std =
+;;
--- /dev/null
+++ b/lib/std/intparse.myr
@@ -1,0 +1,70 @@
+use "chartype.use"
+use "die.use"
+use "hasprefix.use"
+use "option.use"
+use "types.use"
+use "utf.use"
+
+pkg std =
+	generic intparsebase	: (s : byte[:], base : int -> option(@a::(integral,numeric)))
+	generic intparse	: (s : byte[:]	-> option(@a::(integral,numeric)))
+;;
+
+generic intparse = {s
+	var isneg 
+
+	isneg = false
+	if hasprefix(s, "-")
+		s = s[1:]
+		isneg = true
+	;;
+
+	if hasprefix(s, "0x")
+		-> doparse(s[2:], isneg, 16)
+	elif hasprefix(s, "0o")
+		-> doparse(s[2:], isneg, 8)
+	elif hasprefix(s, "0b")
+		-> doparse(s[2:], isneg, 2)
+	else
+		-> doparse(s, isneg, 10)
+	;;
+}
+
+generic intparsebase = {s, base
+	var isneg 
+
+	isneg = false
+	if hasprefix(s, "-")
+		s = s[1:]
+		isneg = true
+	;;
+
+	-> doparse(s, isneg, base)
+}
+
+generic doparse = {s, isneg, base
+	var c
+	var v
+	var cv : int32
+	
+	v = 0
+	while s.len != 0
+		(c, s) = striter(s)
+		if c == '_'
+			continue
+		;;
+		cv = charval(c, base)
+		if cv >= 0
+			v *= (base castto(@a::(integral,numeric)))
+			v += cv castto(@a::(integral,numeric))
+		else
+			-> `None
+		;;
+	;;
+
+	if isneg
+		-> `Some -v
+	else
+		-> `Some v
+	;;
+}
--- /dev/null
+++ b/lib/std/introspect.myr
@@ -1,0 +1,365 @@
+use "types.use"
+use "die.use"
+
+pkg std =
+	type typedesc = union
+		`Tynone
+
+		/* atomic types */
+		`Tyvoid
+		`Tybool
+		`Tychar
+
+		`Tyint8
+		`Tyint16
+		`Tyint
+		`Tyint32
+		`Tyint64
+		`Tylong
+
+		`Tybyte
+		`Tyuint8
+		`Tyuint16
+		`Tyuint
+		`Tyuint32
+		`Tyuint64
+		`Tyulong
+		`Tyflt32
+		`Tyflt64
+		`Tyvalist
+
+		/* compound types */
+		`Typtr byte[:]
+		`Tyfunc	typecursor
+		`Tyslice byte[:]
+		`Tyarray (size, byte[:])
+
+		/* aggregate types */
+		`Tytuple	typecursor
+		`Tystruct	namecursor
+		`Tyunion	namecursor
+		/* name info */
+		`Tyname (byte[:], byte[:])
+	;;
+
+	type typecursor = struct
+		nelt	: size
+		rem	: byte[:]
+	;;
+
+	type namecursor = struct
+		nelt	: size
+		rem	: byte[:]
+	;;
+
+	type typeinfo = struct
+		size	: size
+		align	: size
+	;;
+
+	generic typeof	: (v : @a -> byte[:])
+	const typeenc	: (p : ...# -> typecursor)
+	const typedecode	: (e : byte[:] -> typedesc)
+	const typedesc	: (e : byte[:] -> typedesc)
+	const typeinfo	: (e : byte[:] -> typeinfo)
+
+	const tcnext	: (t : typecursor# -> byte[:])
+	const tcpeek	: (t : typecursor# -> byte[:])
+	const ncnext	: (t : namecursor# -> (byte[:], byte[:]))
+;;
+
+extern const put	: (fmt : byte[:], args : ... -> size)
+
+const Encnone	: byte = 0
+const Encvoid	: byte = 1
+const Encbool	: byte = 2
+const Encchar	: byte = 3
+
+const Encint8	: byte = 4
+const Encint16	: byte = 5
+const Encint	: byte = 6
+const Encint32	: byte = 7
+const Encint64	: byte = 8
+const Enclong	: byte = 9
+
+const Encbyte	: byte = 10
+const Encuint8	: byte = 11
+const Encuint16	: byte = 12
+const Encuint	: byte = 13
+const Encuint32	: byte = 14
+const Encuint64	: byte = 15
+const Enculong	: byte = 16
+const Encflt32	: byte = 17
+const Encflt64	: byte = 18
+const Encvalist	: byte = 19
+
+/* compound types */
+const Encptr	: byte = 20
+const Encfunc	: byte = 21
+const Encslice	: byte = 22
+const Encarray	: byte = 23
+
+/* aggregate types */
+const Enctuple	: byte = 24
+const Encstruct	: byte = 25
+const Encunion	: byte = 26
+const Encname	: byte = 30
+const Encindname	:byte = 30 | 0x80
+
+generic typeof = {v : @a -> byte[:]
+	var tc
+
+	tc = typesof(v)
+	-> tcnext(&tc)
+}
+
+const typeenc = {ap : ...#
+	var e
+
+	e = getenc(ap castto(byte##))
+	e = skiptypeinfo(e[1:])
+	-> lentypecursor(e)
+}
+	
+const typesof : (a : ... -> typecursor) = {a : ...
+	-> typeenc(&a)
+}
+
+const tcnext = {tc
+	var n, sz, cur
+
+	if tc.rem.len == 0
+		-> ""
+	;;
+	(n, sz) = getipacked(tc.rem)
+	cur = tc.rem[sz:sz+n]
+	tc.rem = tc.rem[sz+n:]
+	-> cur
+}
+
+const tcpeek = {tc
+	var n, sz
+
+	if tc.rem.len == 0
+		-> ""
+	;;
+	(n, sz) = getipacked(tc.rem)
+	-> tc.rem[sz:sz+n]
+}
+
+const ncnext = {nc
+	var n, sz, name, enc
+
+	if nc.rem.len == 0
+		-> ("", "")
+	;;
+
+	/* get the name */
+	(n, sz) = getipacked(nc.rem)
+	name = nc.rem[sz:sz+n]
+	nc.rem = nc.rem[sz+n:]
+
+	/* and the type */
+	(n, sz) = getipacked(nc.rem)
+	enc = nc.rem[sz:sz+n]
+	nc.rem = nc.rem[sz+n:]
+	-> (name, enc)
+}
+
+
+const getenc = {p : byte##
+	var val, sz, x
+
+	(val, sz) = getipacked(p#[:8])
+	x = &sz castto(byte#)
+	-> p#[sz:sz+val]
+}
+
+const typedesc = {ti
+	var len,sz, p
+
+	match ti[0]
+	| Encnone:	-> `Tynone
+	| Encvoid:	-> `Tyvoid
+	| Encbool:	-> `Tybool
+	| Encchar:	-> `Tychar
+
+	| Encint8:	-> `Tyint8
+	| Encint16:	-> `Tyint16
+	| Encint:	-> `Tyint
+	| Encint32:	-> `Tyint32
+	| Encint64:	-> `Tyint64
+	| Enclong:	-> `Tylong
+
+	| Encbyte:	-> `Tybyte
+	| Encuint8:	-> `Tyuint8
+	| Encuint16:	-> `Tyuint16
+	| Encuint:	-> `Tyuint
+	| Encuint32:	-> `Tyuint32
+	| Encuint64:	-> `Tyuint64
+	| Enculong:	-> `Tyulong
+	| Encflt32:	-> `Tyflt32
+	| Encflt64:	-> `Tyflt64
+	| Encvalist:	-> `Tyvalist
+
+	/* compound types */
+	| Encptr:	-> `Typtr getsub(ti[1:])
+	| Encfunc:	-> `Tyfunc lentypecursor(ti[1:])
+	| Encslice:	-> `Tyslice getsub(ti[1:])
+	| Encarray:
+		ti = skiptypeinfo(ti[1:])
+		(len, sz) = getipacked(ti)
+		-> `Tyarray (len, getsub(ti[sz:]))
+
+
+	/* aggregate types */
+	| Enctuple:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tytuple lentypecursor(ti)
+	| Encstruct:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tystruct lennamecursor(ti)
+	| Encunion:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tyunion lennamecursor(ti)
+	| Encname:
+		-> `Tyname namedesc(ti[1:])
+	| Encindname:
+		/* 
+		ugly hack: the slice contains a pointer to the
+		value, so if we cast it to a byte##, we can
+		pull the indirect value out of the pointer.
+		*/
+		p = ti[1:] castto(byte##)
+		-> typedesc(getenc(p))
+	| _:
+		std.die("unknown type encoding")
+	;;
+}
+
+const typeinfo = {ti
+	var p
+
+	match ti[0]
+	| Encnone:	-> [.size=0, .align=1]
+	| Encvoid:	-> [.size=0, .align=1]
+	| Encbool:	-> [.size=0, .align=1]
+	| Encchar:	-> [.size=4, .align=4]
+
+	| Encint8:	-> [.size=1, .align=1]
+	| Encint16:	-> [.size=2, .align=2]
+	| Encint:	-> [.size=4, .align=4]
+	| Encint32:	-> [.size=4, .align=4]
+	| Encint64:	-> [.size=8, .align=8]
+	| Enclong:	-> [.size=8, .align=8]
+
+	| Encbyte:	-> [.size=1, .align=1]
+	| Encuint8:	-> [.size=1, .align=1]
+	| Encuint16:	-> [.size=2, .align=2]
+	| Encuint:	-> [.size=4, .align=4]
+	| Encuint32:	-> [.size=4, .align=4]
+	| Encuint64:	-> [.size=8, .align=8]
+	| Enculong:	-> [.size=8, .align=8]
+	| Encflt32:	-> [.size=4, .align=4]
+	| Encflt64:	-> [.size=8, .align=8]
+	| Encvalist:	-> [.size=8, .align=8]
+
+	/* compound types */
+	| Encptr:	-> [.size=8, .align=8]
+	| Encfunc:	-> [.size=8, .align=8]
+	| Encslice:	-> [.size=16, .align=8]
+
+	| Encarray: 	-> gettypeinfo(ti[1:])
+	| Enctuple:	-> gettypeinfo(ti[1:])
+	| Encstruct:	-> gettypeinfo(ti[1:])
+	| Encunion:	-> gettypeinfo(ti[1:])
+	| Encname:	-> getnameinfo(ti[1:])
+	| Encindname:
+		p = ti[1:] castto(byte##)
+		-> typeinfo(getenc(p))
+	| _:
+		std.die("unknown type encoding")
+	;;
+}
+
+const gettypeinfo = {e
+	var size, align, sz
+
+	(size, sz) = getipacked(e)	/* size */
+	e = e[sz:]
+	(align, sz) = getipacked(e)	/* align */
+	-> [.size = size, .align = align]
+}
+
+const skiptypeinfo = {e
+	var ignore, sz
+
+	(ignore, sz) = getipacked(e)	/* size */
+	e = e[sz:]
+	(ignore, sz) = getipacked(e)	/* align */
+	-> e[sz:]
+}
+
+const getnameinfo = {e
+	var n, name, sz, enc
+
+	(n, sz) = getipacked(e)
+	name = e[sz:n+sz]
+	e = e[n+sz:]
+	(n, sz) = getipacked(e)
+	enc = e[sz:n+sz]
+
+	-> typeinfo(enc)
+}
+
+const namedesc = {e
+	var n, sz, name, enc
+
+	(n, sz) = getipacked(e)
+	name = e[sz:n+sz]
+	e = e[n+sz:]
+	(n, sz) = getipacked(e)
+	enc = e[sz:n+sz]
+
+	-> (name, enc)
+}
+
+const lentypecursor = {e
+	var n, sz
+
+	(n, sz) = getipacked(e)
+	-> [.nelt=n, .rem=e[sz:]]
+}
+
+const lennamecursor = {e 
+	var n, sz
+
+	(n, sz) = getipacked(e)
+	-> [.nelt=n, .rem=e[sz:]]
+}
+
+const getsub = {e
+	var n, sz
+
+	(n, sz) = getipacked(e)
+	-> e[sz:sz+n]
+}
+
+const getipacked : (p : byte[:] -> (size, size)) = {p : byte[:]
+	var mask, val, len, i
+
+	mask = 0x80
+	val = 0
+	len = 1
+	while p[0] & mask != mask << 1
+		len++
+		mask >>= 1
+		mask |= 0x80
+	;;
+
+	val = (p[0] castto(size))  & ~(1 << (8 - len))
+	for i = 1; i < len; i++
+		val |= (p[i] castto(size)) << (i*8 - len)
+	;;
+	-> (val, len)
+}
--- /dev/null
+++ b/lib/std/ipparse.myr
@@ -1,0 +1,147 @@
+use "die.use"
+use "intparse.use"
+use "option.use"
+use "strfind.use"
+use "types.use"
+use "chartype.use"
+use "fmt.use"
+use "slcp.use"
+use "slfill.use"
+use "sleq.use"
+
+ /* FIXME: needed for decls which should be pulled in as hidden */
+use "hasprefix.use"
+use "utf.use"
+
+pkg std =
+
+	type netaddr = union
+		`Ipv4	byte[4]
+		`Ipv6	byte[16]
+	;;
+
+	const ipparse	: (ip : byte[:]	-> option(netaddr))
+	const ip4parse	: (ip : byte[:] -> option(netaddr))
+	const ip6parse	: (ip : byte[:] -> option(netaddr))
+;;
+
+const ipparse = {ip
+	match strfind(ip, ":")
+	| `Some _:	-> ip6parse(ip)
+	| `None:	-> ip4parse(ip)
+	;;
+}
+
+const ip4parse = {ip
+	var a, b, c, d
+	var ok
+	/*
+	var addr
+	var last : size
+	var x : option(int32)
+	var val : int32 /* need int32 to check for overflow */
+	var i
+	var j : size
+	*/
+
+	(a, ip, ok) = num(ip, 0, 255, 10, '.', true)
+	(ip, ok) = delim(ip, '.', ok)
+	(b, ip, ok) = num(ip, 0, 255, 10, '.', ok)
+	(ip, ok) = delim(ip, '.', ok)
+	(c, ip, ok) = num(ip, 0, 255, 10, '.', ok)
+	(ip, ok) = delim(ip, '.', ok)
+	(d, ip, ok) = num(ip, 0, 255, 10, '.', ok)
+
+	if ok && ip.len == 0
+		-> `Some (`Ipv4 [a, b, c, d])
+	else
+		-> `None
+	;;
+}
+
+const ip6parse = {ip
+	var val : byte[16]
+	var expand, split
+	var v, ok
+	var i, nseg
+
+	ok = true
+	expand = false
+	split = 0
+	if ip.len > 2 && std.sleq(ip[:2], "::")
+		expand = true
+		split = 0
+	;;
+	nseg = 0
+	for i = 0; ip.len > 0 && ok; i++
+		/* parse 'num' segment */
+		(v, ip, ok) = num(ip, 0, 65536, 16, ':', ok)
+		nseg++
+		if ip.len == 0 || nseg == 8
+			break
+		;;
+		(ip, ok) = delim(ip, ':', ok)
+		/* only one '::' allowed once */
+		if ip.len > 0 && ip[0] == ':'castto(byte) && !expand
+			expand = true
+			split = i
+			(ip, ok) = delim(ip, ':', ok)
+		;;
+
+		/* pack it into the bytes */
+		val[i*2] = ((v & 0xff00) >> 8) castto(byte)
+		val[i*2 + 1] = (v & 0xff) castto(byte)
+	;;
+
+	if ok && ip.len == 0
+		if expand
+			expandsplit(val[:], split, i)
+		elif nseg != 8
+			-> `None
+		;;
+		-> `Some `Ipv6 val
+	else
+		-> `None
+	;;
+}
+
+/* take "a:b::c:d" and expand it to "a:b:0:0:...:0:c:d" */
+const expandsplit = {ip, split, len
+	var width
+
+	width = 16 - len
+	std.slcp(ip[split:len], ip[split+width:len+width])
+	std.slfill(ip[len:len+width], 0)
+}
+
+const delim = {ip, sep, ok
+	if ip.len > 0 && ip[0] == sep castto(byte)
+		-> (ip[1:], ok)
+	else
+		-> ("", false)
+	;;
+}
+
+generic num = {ip, lo, hi, base, sep, ok -> (@a::(numeric,integral), byte[:], bool)
+	var len
+
+	if !ok
+		-> (0, "", false)
+	;;
+
+	for len = 0; len < ip.len; len++
+		if ip[len] == sep castto(byte)
+			break
+		;;
+	;;
+	match intparsebase(ip[:len], base)
+	| `std.Some v:
+		if v < lo || v > hi
+			-> (0, "", false)
+		;;
+		-> (v castto(@a::(numeric,integral)), ip[len:], true)
+	| `std.None:
+		-> (0, "", false)
+	;;
+}
+
--- /dev/null
+++ b/lib/std/mk.myr
@@ -1,0 +1,22 @@
+use "alloc.use"
+
+pkg std =
+	generic mk	: (val : @a -> @a#)
+;;
+
+/* Takes a value, and heapifies it.
+
+FIXME: This depends on inlining and copy propagation
+in order to be efficient. Neither of those are
+currently implemented. That means that this function
+is not efficient.
+
+It's still damn convenient, though, so it's in.
+*/
+generic mk = {val
+	var p
+
+	p = alloc()
+	p# = val
+	-> p
+}
--- /dev/null
+++ b/lib/std/mkfile
@@ -1,0 +1,107 @@
+</$objtype/mkfile
+
+SYSLIB=sys
+SYSSRC= \
+	sys.myr \
+	systypes.myr \
+	ifreq.myr \
+
+SYSASMSRC= \
+	syscall.s \
+	util.s
+
+
+STDLIB=std
+STDSRC= \
+	alloc.myr \
+	bigint.myr \
+	bitset.myr \
+	blat.myr \
+	chartype.myr \
+	cmp.myr \
+	dial.myr \
+	die.myr \
+	dir.myr \
+	endian.myr \
+	env.myr \
+	execvp.myr \
+	extremum.myr \
+	fltbits.myr \
+	fmt.myr \
+	fltfmt.myr \
+	hashfuncs.myr \
+	hasprefix.myr \
+	hassuffix.myr \
+	htab.myr \
+	intparse.myr \
+	ipparse.myr \
+	mk.myr \
+	now.myr \
+	option.myr \
+	optparse.myr \
+	pathjoin.myr \
+	rand.myr \
+	resolve.myr \
+	result.myr \
+	search.myr \
+	slcp.myr \
+	sldup.myr \
+	sleq.myr \
+	slfill.myr \
+	sljoin.myr \
+	slpush.myr \
+	slput.myr \
+	slurp.myr \
+	sort.myr \
+	spork.myr \
+	strfind.myr \
+	strjoin.myr \
+	strsplit.myr \
+	strstrip.myr \
+	syswrap.myr \
+	swap.myr \
+	try.myr \
+	types.myr \
+	units.myr \
+	utf.myr \
+	varargs.myr \
+	wait.myr \
+
+all:V: lib$STDLIB.a lib$SYSLIB.a
+
+install:V: all
+	mkdir -p /$objtype/lib/myr/
+	cp lib$STDLIB.a lib$SYSLIB.a /$objtype/lib/myr/
+	cp $STDLIB $SYSLIB /$objtype/lib/myr/
+
+lib$STDLIB.a: $STDSRC $ASMSRC lib$SYSLIB.a
+	../myrbuild/$O.out -I. -C../6/$O.out -M../muse/$O.out -l $STDLIB $STDSRC $STDASMSRC
+
+lib$SYSLIB.a: $SYSSRC $SYSASMSRC
+	../myrbuild/$O.out -C../6/$O.out -M../muse/$O.out -l $SYSLIB $SYSSRC $SYSASMSRC
+
+%.myr: %+plan9-x64.myr
+	cp $stem+plan9-x64.myr $stem.myr
+
+%.myr: %+plan9.myr
+	cp $stem+plan9.myr $stem.myr
+
+%.myr: %+x64.myr
+	cp $stem+x64.myr $stem.myr
+
+%.s: %+plan9-x64.s
+	cp $stem+plan9-x64.s $stem.s
+
+%.s: %+x64.s
+	cp $stem+x64.s $stem.s
+
+OBJ=${STDSRC:%.myr=%.$O} ${SYSSRC:%.myr=%.$O} ${STDASMSRC:%.s=%.$O} ${SYSASMSRC:%.s=%.$O}
+USE=${STDSRC:%.myr=%.use} ${SYSSRC:%.myr=%.use} ${STDLIB}
+LIBS=lib$STDLIB.a lib$SYSLIB.a
+.PHONY: clean
+clean:V:
+	rm -f $OBJ
+	rm -f $USE
+	rm -f $LIBS $STDLIB $SYSLIB
+
+nuke:V: clean
--- /dev/null
+++ b/lib/std/mkpath.myr
@@ -1,0 +1,22 @@
+use "syswrap.use"
+use "errno.use"
+
+pkg std =
+	const mkpath	: (p : byte[:] -> bool)
+;;
+
+const mkpath = {p
+	var st
+	var i
+
+	for i = 0; i < p.len; i++
+		if p[i] == '/' castto(byte) && i != 0
+			st = mkdir(p[:i], 0o777)
+			if st != 0 && (st castto(errno)) != Eexist
+				-> false
+			;;
+		;;
+	;;
+
+	-> true
+}
--- /dev/null
+++ b/lib/std/now.myr
@@ -1,0 +1,11 @@
+use "types.use"
+use "syswrap.use"
+
+pkg std =
+	const now	: (-> time)
+;;
+
+/* microseconds since epoch */
+const now = {
+	-> curtime()
+}
--- /dev/null
+++ b/lib/std/option.myr
@@ -1,0 +1,7 @@
+pkg std =
+	type option(@a) = union
+		`Some @a
+		`None
+	;;
+;;
+
--- /dev/null
+++ b/lib/std/optparse.myr
@@ -1,0 +1,210 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "fmt.use"
+use "strbuf.use"
+use "option.use"
+use "sleq.use"
+use "slpush.use"
+use "syswrap-ss.use"
+use "syswrap.use"
+use "types.use"
+use "utf.use"
+
+pkg std =
+	type optdef = struct
+		argdesc	: byte[:]	/* the description for the usage */
+		minargs	: std.size	/* the minimum number of positional args */
+		maxargs	: std.size	/* the maximum number of positional args (0 = unlimited) */
+		noargs	: std.bool	/* whether we accept args at all */
+		opts	: optdesc[:]	/* the description of the options */
+	;;
+
+	type optdesc = struct
+		opt	: char
+		arg	: byte[:]
+		desc	: byte[:]
+		optional	: bool
+	;;
+
+	type optparsed = struct
+		opts	: (char, byte[:])[:]
+		args	: byte[:][:]
+	;;
+
+	const optparse	: (optargs : byte[:][:], def : optdef# -> optparsed)
+	const optusage	: (prog : byte[:], def : optdef# -> void)
+;;
+
+type optctx = struct
+	/* public variables */
+	args	: byte[:][:]
+
+	/* data passed in */
+	optdef	: optdef#
+	optargs	: byte[:][:]
+
+	/* state */
+	argidx	: size
+	curarg	: byte[:]
+	optdone	: bool	/* if we've seen '--', everything's an arg */
+	finished	: bool	/* if we've processed all the optargs */
+;;
+
+
+const optparse = {args, def
+	var ctx : optctx
+	var parsed
+
+	parsed = [
+		.opts=[][:],
+		.args=[][:]
+	]
+	optinit(&ctx, args, def)
+	while !optdone(&ctx)
+		parsed.opts = slpush(parsed.opts, optnext(&ctx))
+	;;
+	if ctx.args.len < def.minargs
+		put("error: expected at least {} args, got {}\n", def.minargs, ctx.args.len)
+		optusage(ctx.optargs[0], ctx.optdef)
+		exit(1)
+	;;
+	if def.maxargs > 0 && ctx.args.len < def.minargs
+		put("error: expected at most {} args, got {}\n", def.minargs, ctx.args.len)
+		optusage(ctx.optargs[0], ctx.optdef)
+		exit(1)
+	;;
+	if def.noargs && ctx.args.len != 0
+		put("error: expected no args, got {}\n", ctx.args.len)
+		optusage(ctx.optargs[0], ctx.optdef)
+		exit(1)
+	;;
+	parsed.args = ctx.args
+	-> parsed
+}
+
+const optinit = {ctx, args, def
+	ctx# = [
+		.optargs = args,
+		.optdef = def,
+		.optdone = false,
+		.finished = false,
+		.argidx = 0,
+		.curarg = [][:],
+		.args = [][:],
+	]
+
+	next(ctx)
+	-> ctx
+}
+
+const optnext = {ctx
+	var c
+	var arg
+
+	(c, ctx.curarg) = striter(ctx.curarg)
+
+	match optinfo(ctx, c)
+	| `None:
+		if c == 'h' || c == '?'
+			optusage(ctx.optargs[0], ctx.optdef)
+			exit(0)
+		else
+			fatal("unexpected argument '{}'\n", c)
+		;;
+	| `Some (true, needed):
+		/* -arg => '-a' 'rg' */
+		if ctx.curarg.len > 0
+			arg = ctx.curarg
+			ctx.curarg = ctx.curarg[ctx.curarg.len:]
+			next(ctx)
+		/* '-a rg' => '-a' 'rg' */
+		elif ctx.argidx < (ctx.optargs.len - 1)
+			arg = ctx.optargs[ctx.argidx + 1]
+			ctx.argidx++
+			next(ctx)
+		elif needed
+			put("Expected argument for {}\n", c)
+			exit(1)
+		;;
+	| `Some (false, _):
+		arg = ""
+		if ctx.curarg.len == 0
+			next(ctx)
+		;;
+	;;
+
+
+	-> (c, arg)
+}
+
+const optdone = {ctx
+	-> ctx.curarg.len == 0 && ctx.finished
+}
+
+const optinfo = {ctx, opt
+	for o in ctx.optdef.opts
+		if o.opt == opt
+			-> `Some (o.arg.len != 0, !o.optional)
+		;;
+	;;
+	-> `None
+}
+
+const next = {ctx
+	var i
+
+	for i = ctx.argidx + 1; i < ctx.optargs.len; i++
+		if !ctx.optdone && decode(ctx.optargs[i]) == '-'
+			if sleq(ctx.optargs[i], "--")
+				ctx.optdone = true
+			else
+				goto foundopt
+			;;
+		else
+			ctx.args = slpush(ctx.args, ctx.optargs[i])
+		;;
+	;;
+:finishedopt
+	ctx.finished = true
+	-> false
+:foundopt
+	ctx.argidx = i
+	ctx.curarg = ctx.optargs[i][1:]
+	-> true
+}
+
+const optusage = {prog, def
+	var sb, s
+
+	sb = mksb()
+	std.sbfmt(sb, "usage: {} [-h?", prog)
+	for o in def.opts
+		if o.arg.len == 0
+			std.sbfmt(sb, "{}", o.opt)
+		;;
+	;;
+	std.sbfmt(sb, "] ")
+	for o in def.opts
+		if o.arg.len != 0
+			std.sbfmt(sb, "[-{} {}] ", o.opt, o.arg)
+		;;
+	;;
+	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
+		std.sbfmt(sb, "\t-{}{}{}\t{}\n", o.opt, sep(o.arg), o.arg, o.desc)
+	;;
+	s = sbfin(sb)
+	write(1, s)
+	slfree(s)
+}
+
+const sep = {s
+	if s.len > 0
+		-> " "
+	else
+		-> ""
+	;;
+}
--- /dev/null
+++ b/lib/std/pathjoin.myr
@@ -1,0 +1,105 @@
+use "alloc.use"
+use "extremum.use"
+use "strjoin.use"
+use "strsplit.use"
+use "sleq.use"
+use "sljoin.use"
+use "sldup.use"
+use "slcp.use"
+use "die.use"
+use "fmt.use"
+
+pkg std =
+	const pathcat	: (a : byte[:], b : byte[:] -> byte[:])
+	const pathjoin	: (p : byte[:][:] -> byte[:])
+	const pathnorm	: (p : byte[:] -> byte[:])
+;;
+
+const pathcat = {a, b
+	-> pathjoin([a, b][:])
+}
+
+const pathjoin = {l
+	var p, i, q
+
+	for i = 0; i < l.len; i++
+		if l[i].len != 0
+			break
+		;;
+	;;
+	p = strjoin(l[i:], "/")
+	q = pathnorm(p)
+	slfree(p)
+	-> q
+}
+
+const pathnorm = {p
+	var comps
+	var i, del, dst
+	var s, ret
+
+	comps = strsplit(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.
+	*/
+	for i = 0; i < comps.len; i++
+		if sleq(comps[i], ".")
+			comps[i] = ""
+		;;
+	;;
+
+	/*
+	then, resolve '..' by cancelling out previous components. Scan
+	backwards in the component list for the first real component,
+	and delete both it and the '..' that lead to it.
+	
+	Leave in extra '..' components, so that, eg, ../foo doesn't
+	get mangled.
+	*/
+	for i = 0; i < comps.len; i++
+		if !sleq(comps[i], "..")
+			continue
+		;;
+		for del = 1; del <= i; del++
+			if comps[i - del].len > 0 && !sleq(comps[i-del], "..")
+				comps[i - del] = ""
+				comps[i] = ""
+				break
+			;;
+		;;
+	;;
+
+	/* clear out the path nodes we decided to drop */
+	dst = 0
+	for i = 0; i < comps.len; i++
+		if comps[i].len > 0
+			comps[dst++] = comps[i]
+		;;
+	;;
+	comps = comps[:dst]
+
+	/*
+	and reassemble. If we have an absolute path,
+	make it absolute. If we have an empty path, return
+	".". Otherwise, just return the path.
+	*/
+	if p.len > 0 && sleq(p[:1], "/")
+		for i = 0; i < comps.len; i++
+			if !sleq(comps[i], "..")
+				break
+			;;
+		;;
+		s = strjoin(comps[i:], "/")
+		ret = fmt("/{}", s)
+		slfree(s)
+	elif comps.len == 0
+		ret = sldup(".")
+	else
+		ret = strjoin(comps, "/")
+	;;
+	slfree(comps)
+	-> ret
+}
+
--- /dev/null
+++ b/lib/std/putint.myr
@@ -1,0 +1,44 @@
+use "types.use"
+use "die.use"
+
+pkg std =
+	generic putle64	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putbe64	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putle32	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putbe32	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putle16	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putbe16	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putle8	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+	generic putbe8	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
+;;
+
+generic putle64	= {buf, v;	-> putle(buf, v castto(uint64), 8)}
+generic putbe64	= {buf, v;	-> putbe(buf, v castto(uint64), 8)}
+generic putle32	= {buf, v;	-> putle(buf, v castto(uint64), 4)}
+generic putbe32	= {buf, v;	-> putbe(buf, v castto(uint64), 4)}
+generic putle16	= {buf, v;	-> putle(buf, v castto(uint64), 2)}
+generic putbe16	= {buf, v;	-> putbe(buf, v castto(uint64), 2)}
+generic putle8	= {buf, v;	-> putle(buf, v castto(uint64), 1)}
+generic putbe8	= {buf, v;	-> putbe(buf, v castto(uint64), 1)}
+
+const putbe = {buf, val, n
+	var i, k
+	
+	assert(buf.len >= n, "buffer too small")
+	for i = 0; i < n; i++
+		k = val >> (8*(n-i-1))
+		buf[i] = (k & 0xff) castto(byte)
+	;;
+	-> n castto(size)
+}
+
+const putle = {buf, val, n
+	var i
+
+	assert(buf.len >= n, "buffer too small")
+	for i = 0; i < n; i++
+		buf[i] = (val & 0xff) castto(byte)
+		val >>= 8
+	;;
+	-> n castto(size)
+}
--- /dev/null
+++ b/lib/std/rand.myr
@@ -1,0 +1,185 @@
+use "die.use"
+use "types.use"
+use "alloc.use"
+/*
+   Translated from C by Ori Bernstein
+ */
+
+/* 
+  A C-program for MT19937, with initialization improved 2002/1/26.
+  Coded by Takuji Nishimura and Makoto Matsumoto.
+  
+  Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+  All rights reserved.                          
+  
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+  
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+ 
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+ 
+    3. The names of its contributors may not be used to endorse or promote 
+       products derived from this software without specific prior written 
+       permission.
+ 
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+  Any feedback is very welcome.
+  http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+  email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+ */
+
+pkg std =
+	type rng
+
+	const mksrng	: (seed : uint32 -> rng#)
+	const delrng	: (rng : rng# -> void)
+	generic rand	: (rng : rng#, lo : @a::(numeric,integral), hi : @a::(numeric,integral) -> @a::(numeric,integral))
+	generic randN	: (rng : rng# -> @a::(numeric,integral))
+	const randbytes	: (rng : rng#, buf : byte[:]	-> size)
+	const rand32	: (rng : rng# -> uint32)
+;;
+
+type rng = struct
+	state	: uint32[624]
+	i	: uint32
+;;
+
+/* allocates and initializes a random number generator */
+const mksrng = {seed
+	var rng
+
+	rng = alloc()
+	init(rng, seed)
+	-> rng
+}
+
+const delrng = {rng
+	free(rng)
+}
+
+/* initializes a random number generator from the seed `seed`. */
+const init = {rng, seed
+	var i
+
+	for i = 0; i < 624; i++
+		rng.state[i] = seed
+		seed = 1812433253 * (seed ^ (seed >> 30)) + i + 1
+	;;
+	rng.i = i
+}
+
+/*
+   Generates a random integer from `rng` in the range [lo, hi),
+   returning the value. The range [lo, hi) must be positive,
+   nonempty, and the difference between hi and lo must be
+   less then 2^(type_bits - 1)
+*/
+generic rand = {rng, lo, hi -> @a::(integral,numeric)
+	var span, lim
+	var maxrand
+	var val
+
+	assert(hi - lo > 0, "rand.myr: range for random values must be >= 1")
+
+	span = hi - lo
+	maxrand = (1 << (8*sizeof(@a))) - 1 /* max for signed value */
+	if maxrand < 0 /* signed */
+		maxrand = (1 << (8*sizeof(@a)-1)) - 1 /* max for signed value */
+	;;
+
+	lim = (maxrand/span)*span
+	val = (randN(rng) & maxrand)
+	while val > lim 
+		val = (randN(rng) & maxrand)
+	;;
+	-> val % span + lo
+}
+
+/*
+   Generates a random integer of any size from the
+   random number generator `rng`. The returned value
+   may be negative, if the type is signed.
+*/
+generic randN = {rng -> @a::(integral,numeric)
+	var i, val
+
+	val = 0
+	for i = 0; i < sizeof(@a)/4; i++
+		val <<= 8*sizeof(@a)
+		val |= rand32(rng) castto(@a::(integral,numeric))
+	;;
+	-> val
+}
+
+/*
+   generates a 32 bit unsigned random number
+   from the random number generator `rng`.
+*/
+const rand32 = {rng
+	var x
+
+	if rng.i == 624
+		next(rng)
+	;;
+	x = rng.state[rng.i]
+	rng.i++
+
+	x ^= x >> 11
+	x ^= (x << 7) & 0x9D2C5680
+	x ^= (x << 15) & 0xEFC60000
+	-> x ^ (x >> 18)
+}
+
+const randbytes = {rng, buf
+	var i, n, r
+
+	n = 0
+	for i = 0; i < buf.len/4; i++
+		r = rand32(rng)
+		buf[n++] = (r >>  0 & 0xff) castto(byte)
+		buf[n++] = (r >>  8 & 0xff) castto(byte)
+		buf[n++] = (r >> 16 & 0xff) castto(byte)
+		buf[n++] = (r >> 32 & 0xff) castto(byte)
+	;;
+	r = rand32(rng)
+	for ; n != buf.len; n++
+		buf[n++] = (r & 0xff) castto(byte)
+		r >>= 8
+	;;
+	-> n
+
+}
+
+/* updates random number generator state when we tick over. */
+const next = {rng
+	var k
+	var y
+
+	for k = 0; k < 227; k++
+		y = (rng.state[k] & 0x80000000) | (rng.state[k + 1] & 0x7FFFFFFF)
+		rng.state[k] = rng.state[k + 397] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF)
+	;;
+	for ; k < 623; k++
+		y = (rng.state[k] & 0x80000000) | (rng.state[k + 1] & 0x7FFFFFFF)
+		rng.state[k] = rng.state[k - 227] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF);
+	;;
+	y = (rng.state[623] & 0x80000000) | (rng.state[0] & 0x7FFFFFFF)
+	rng.state[623] = rng.state[396] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF);
+	rng.i = 0
+}
--- /dev/null
+++ b/lib/std/resolve+plan9.myr
@@ -1,0 +1,2 @@
+pkg std =
+;;
--- /dev/null
+++ b/lib/std/resolve+posixy.myr
@@ -1,0 +1,443 @@
+use sys
+use "alloc.use"
+use "chartype.use"
+use "die.use"
+use "endian.use"
+use "result.use"
+use "extremum.use"
+use "hashfuncs.use"
+use "htab.use"
+use "ipparse.use"
+use "option.use"
+use "slcp.use"
+use "sleq.use"
+use "slpush.use"
+use "slurp.use"
+use "strfind.use"
+use "strsplit.use"
+use "strstrip.use"
+use "types.use"
+use "utf.use"
+
+pkg std =
+	type rectype = uint16
+
+	const DnsA	: rectype = 1  /* host address */
+	const DnsNS	: rectype = 2  /* authoritative name server */
+	const DnsMD	: rectype = 3  /* mail destination (Obsolete - use MX) */
+	const DnsMF	: rectype = 4  /* mail forwarder (Obsolete - use MX) */
+	const DnsCNAME	: rectype = 5  /* canonical name for an alias */
+	const DnsSOA	: rectype = 6  /* marks the start of a zone of authority */
+	const DnsMB	: rectype = 7  /* mailbox domain name (EXPERIMENTAL) */
+	const DnsMG	: rectype = 8  /* mail group member (EXPERIMENTAL) */
+	const DnsMR	: rectype = 9  /* mail rename domain name (EXPERIMENTAL) */
+	const DnsNULL	: rectype = 10 /* null RR (EXPERIMENTAL) */
+	const DnsWKS	: rectype = 11 /* well known service description */
+	const DnsPTR	: rectype = 12 /* domain name pointer */
+	const DnsHINFO	: rectype = 13 /* host information */
+	const DnsMINFO	: rectype = 14 /* mailbox or mail list information */
+	const DnsMX	: rectype = 15 /* mail exchange */
+	const DnsTXT	: rectype = 16 /* text strings */
+	const DnsAAAA	: rectype = 28 /* ipv6 host address */
+
+
+	type resolveerr = union
+		`Badhost
+		`Badsrv
+		`Badquery
+		`Badresp
+	;;
+
+	type hostinfo = struct
+		fam	: sys.sockfam
+		stype	: sys.socktype
+		ttl	: uint32
+		addr	: netaddr
+	/*
+		flags	: uint32
+		addr	: sockaddr[:]
+		canon	: byte[:]
+	*/
+	;;
+
+	const resolve	: (host : byte[:]	-> result(hostinfo[:], resolveerr))
+	const resolvemx	: (host : byte[:]	-> result(hostinfo[:], resolveerr))
+	const resolverec	: (host : byte[:], t : rectype	-> result(hostinfo[:], resolveerr))
+;;
+
+const Hostfile = "/etc/hosts"
+const Resolvfile = "/etc/resolv.conf"
+
+var hostmap	: htab(byte[:], hostinfo)#
+var search	: byte[:][:]
+var nameservers	: netaddr[:]
+
+const __init__ = {
+	hostmap = mkht(strhash, streq)
+	loadhosts()
+	loadresolv()
+}
+
+const resolve = {host
+	-> resolverec(host, DnsA)
+}
+
+const resolvemx = {host
+	-> resolverec(host, DnsMX)
+}
+
+const resolverec = {host, t
+	match hostfind(host)
+	| `Some hinf:
+		-> `Ok slpush([][:], hinf)
+	| `None:
+		-> dnsresolve(host, DnsA)
+	;;
+}
+
+const hostfind = {host
+	-> htget(hostmap, host)
+}
+
+const loadhosts = {
+	var h
+	var lines
+
+	match slurp(Hostfile)
+	| `Ok d:	h = d
+	| `Fail m:	->
+	;;
+
+	lines = strsplit(h, "\n")
+	for l in lines
+		/* trim comment */
+		match strfind(l, "#")
+		| `Some idx:	l = l[:idx]
+		| `None:	/* whole line */
+		;;
+
+		match word(l)
+		| `Some (ip, rest):
+			match ipparse(ip)
+			| `Some addr:
+				addhosts(addr, ip, rest)
+			| `None:
+				/*
+				invalid addresses are ignored: we don't want to break stuff
+				with invalid or unsupported addresses
+				*/
+				
+			;;
+		| `None:
+		;;
+	;;
+	slfree(lines)
+}
+
+const addhosts = {addr, as, str
+	var hinf
+	var fam
+
+	match addr
+	| `Ipv4 _:	fam = sys.Afinet
+	| `Ipv6 _:	fam = sys.Afinet6
+	;;
+	while true
+		match word(str)
+		| `Some (name, rest):
+			str = rest
+			if hthas(hostmap, name)
+				continue
+			;;
+			hinf = [
+				.fam=fam,
+				.stype = 0,
+				.ttl = 0,
+				.addr = addr
+			]
+			htput(hostmap, name, hinf)
+		| `None:
+			->
+		;;
+	;;
+}
+
+const loadresolv = {
+	var h
+	var lines
+
+	match slurp(Resolvfile)
+	| `Ok d:	h = d
+	| `Fail m:	->
+	;;
+
+	lines = strsplit(h, "\n")
+	for l in lines
+		match strfind(l, "#")
+		| `Some _idx: l = l[:_idx]
+		| `None:
+		;;
+
+		match word(l)
+		| `Some ("nameserver", srv):
+			addns(srv)
+		| `Some (_, rest):
+			/* invalid or unrecognized commands */
+		| `None:
+			/* unrecognized lines */
+		;;
+	;;
+	slfree(lines)
+}
+
+const addns = {rest
+	match word(rest)
+	| `Some (name, _):
+		match ipparse(name)
+		| `Some addr: 
+			nameservers = slpush(nameservers, addr)
+		| `None:
+			/* nothing */
+		;;
+	| `None:
+		/* nothing */
+	;;
+}
+
+const word = {s
+	var c, len
+
+	len = 0
+	s = strfstrip(s)
+	for c = decode(s[len:]); c != Badchar && !isblank(c); c = decode(s[len:])
+		len += charlen(c)
+	;;
+	if len == 0
+		-> `None
+	else
+		-> `Some (s[:len], s[len:])
+	;;
+}
+
+
+const dnsresolve = {host, t
+	var nsrv
+
+	if !valid(host)
+		-> `Fail (`Badhost)
+	;;
+	for ns in nameservers
+		nsrv = dnsconnect(ns)
+		if nsrv >= 0
+			-> dnsquery(nsrv, host, t)
+		;;
+	;;
+	-> `Fail (`Badsrv)
+}
+
+const dnsconnect = {ns
+	match ns
+	| `Ipv4 addr:	-> dnsconnectv4(addr)
+	| `Ipv6 addr:	die("don't support ipv6 yet\n")
+	;;
+}
+
+const dnsconnectv4 = {addr
+	var sa : sys.sockaddr_in
+	var s
+	var status
+
+	s = sys.socket(sys.Afinet, sys.Sockdgram, 0)
+	if s < 0
+		-> -1
+	;;
+	sa.fam = sys.Afinet
+	sa.port = hosttonet(53)
+	sa.addr = addr
+	status = sys.connect(s, (&sa) castto(sys.sockaddr#), sizeof(sys.sockaddr_in))
+	if status < 0
+		-> -1
+	;;
+	-> s
+}
+
+const dnsquery = {srv, host, t
+	var id
+	var r
+
+	id = tquery(srv, host, t)
+	r = rquery(srv, id)
+	-> r
+}
+
+const Qr : uint16 = 1 << 0
+const Aa : uint16 = 1 << 5
+const Tc : uint16 = 1 << 6
+const Rd : uint16 = 1 << 7
+const Ra : uint16 = 1 << 8
+
+var nextid : uint16 = 42
+const tquery = {srv, host, t
+	var pkt : byte[512] /* big enough */
+	var off : size
+
+	/* header */
+	off = 0
+	off += pack16(pkt[:], off, nextid)	/* id */
+	off += pack16(pkt[:], off, Ra)	/* flags */
+	off += pack16(pkt[:], off, 1)	/* qdcount */
+	off += pack16(pkt[:], off, 0)	/* ancount */
+	off += pack16(pkt[:], off, 0)	/* nscount */
+	off += pack16(pkt[:], off, 0)	/* arcount */
+
+	/* query */
+	off += packname(pkt[:], off, host)	/* host */
+	off += pack16(pkt[:], off, t castto(uint16)) /* qtype: a record */
+	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
+
+	sys.write(srv, pkt[:off])
+	-> nextid++
+}
+
+const rquery = {srv, id
+	var pktbuf : byte[1024]
+	var pkt
+	var n
+
+	n = sys.read(srv, pktbuf[:])
+	if n < 0
+	;;
+	pkt = pktbuf[:n]
+	-> hosts(pkt, id)
+}
+
+const hosts = {pkt, id : uint16
+	var off
+	var v, q, a
+	var i
+	var hinf : hostinfo[:]
+
+	off = 0
+	/* parse header */
+	(v, off) = unpack16(pkt, off)	/* id */
+	if v != id
+		-> `Fail (`Badresp)
+	;;
+	(v, off) = unpack16(pkt, off)	/* flags */
+	(q, off) = unpack16(pkt, off)	/* qdcount */
+	(a, off) = unpack16(pkt, off)	/* ancount */
+	(v, off) = unpack16(pkt, off)	/* nscount */
+	(v, off) = unpack16(pkt, off)	/* arcount */
+
+	/* skip past query records */
+	for i = 0; i < q; i++
+		off = skipname(pkt, off)	/* name */
+		(v, off) = unpack16(pkt, off)	/* type */
+		(v, off) = unpack16(pkt, off)	/* class */
+	;;
+
+	/* parse answer records */
+	hinf = slalloc(a castto(size))
+	for i = 0; i < a; i++
+		off = skipname(pkt, off)	/* name */
+		(v, off) = unpack16(pkt, off)	/* type */
+		(v, off) = unpack16(pkt, off)	/* class */
+		(hinf[i].ttl, off) = unpack32(pkt, off)	/* ttl */
+		(v, off) = unpack16(pkt, off)	/* rdatalen */
+		/* the thing we're interested in: our IP address */
+		hinf[i].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
+		off += 4;
+	;;
+	-> `Ok hinf
+}
+
+
+const skipname = {pkt, off
+	var sz
+
+	for sz = pkt[off] castto(size); sz != 0; sz = pkt[off] castto(size)
+		/* ptr is 2 bytes */
+		if sz & 0xC0 == 0xC0
+			-> off + 2
+		else
+			off += sz + 1
+		;;
+	;;
+	-> off + 1
+}
+
+
+const pack16 = {buf, off, v
+	buf[off]	= (v & 0xff00) >> 8 castto(byte)
+	buf[off+1]	= (v & 0x00ff) castto(byte)
+	-> sizeof(uint16) /* we always write one uint16 */
+}
+
+const unpack16 = {buf, off
+	var v
+
+	v = (buf[off] castto(uint16)) << 8
+	v |= (buf[off + 1] castto(uint16))
+	-> (v, off+sizeof(uint16))
+}
+
+const unpack32 = {buf, off
+	var v
+
+	v = (buf[off] castto(uint32)) << 24
+	v |= (buf[off+1] castto(uint32)) << 32
+	v |= (buf[off+2] castto(uint32)) << 8
+	v |= (buf[off+3] castto(uint32))
+	-> (v, off+sizeof(uint32))
+}
+
+const packname = {buf, off : size, host
+	var i
+	var start
+	var last
+
+	start = off
+	last = 0
+	for i = 0; i < host.len; i++
+		if host[i] == ('.' castto(byte))
+			off += addseg(buf, off, host[last:i])
+			last = i + 1
+		;;
+	;;
+	if host[host.len - 1] != ('.' castto(byte))
+		off += addseg(buf, off, host[last:])
+	;;
+	off += addseg(buf, off, "") /* null terminating segment */
+	-> off - start
+}
+
+const addseg = {buf, off, str
+	buf[off] = str.len castto(byte)
+	slcp(buf[off + 1 : off + str.len + 1], str)
+	-> str.len + 1
+}
+
+const valid = {host : byte[:]
+	var i
+	var seglen
+
+	/* maximum length: 255 chars */
+	if host.len > 255
+		-> false
+	;;
+
+	seglen = 0
+	for i = 0; i < host.len; i++
+		if host[i] == ('.' castto(byte))
+			seglen = 0
+		;;
+		if seglen > 63
+			-> false
+		;;
+		if host[i] & 0x80 != 0
+			-> false
+		;;
+	;;
+
+	-> true
+}
--- /dev/null
+++ b/lib/std/result.myr
@@ -1,0 +1,9 @@
+use "die.use"
+
+pkg std =
+	type result(@a, @b) = union
+		`Ok	@a
+		`Fail	@b
+	;;
+;;
+
--- /dev/null
+++ b/lib/std/search.myr
@@ -1,0 +1,43 @@
+use "cmp.use"
+use "option.use"
+
+pkg std =
+	generic lsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
+	generic bsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
+;;
+
+/* linear search over a list of values */
+generic lsearch = {sl, val, cmp
+	var i
+
+	for i = 0; i < sl.len; i++
+		match cmp(sl[i], val)
+		| `Equal:
+			-> `Some i
+		| _:
+			/* nothing */
+		;;
+	;;
+	-> `None
+}
+
+/* binary search over a sorted list of values. */
+generic bsearch  = {sl, val, cmp
+	var hi, lo, mid
+
+	lo = 0
+	hi = sl.len - 1
+
+	while lo <= hi
+		mid = (hi + lo) / 2
+		match cmp(val, sl[mid])
+		| `Before:	hi = mid - 1
+		| `After:	lo = mid + 1
+		| `Equal:	
+			-> `Some mid
+		;;
+	;;
+	-> `None
+}
+		
+
--- /dev/null
+++ b/lib/std/slcp.myr
@@ -1,0 +1,26 @@
+use "die.use"
+use "types.use"
+
+pkg std =
+	generic slcp : (a : @a[:], b : @a[:] -> void)
+;;
+
+generic slcp = {a : @a[:], b : @a[:]
+	var i
+	var addr_a, addr_b
+
+	assert(a.len == b.len, "arguments to slcp() must be of equal length")
+
+	addr_a = a castto(@a#) castto(intptr)
+	addr_b = b castto(@a#) castto(intptr)
+	if addr_a <= addr_b
+		for i = 0; i < a.len; i++
+			a[i] = b[i]
+		;;
+	else
+		for i = a.len; i > 0; i--
+			a[i - 1] = b[i - 1]
+		;;
+	;;
+		
+}
--- /dev/null
+++ b/lib/std/sldup.myr
@@ -1,0 +1,15 @@
+use "alloc.use"
+use "die.use"
+use "slcp.use"
+
+pkg std =
+	generic sldup : (sl : @a[:] -> @a[:])
+;;
+
+generic sldup = {sl
+	var ret
+
+	ret = slalloc(sl.len)
+	slcp(ret, sl)
+	-> ret
+}
--- /dev/null
+++ b/lib/std/sleq.myr
@@ -1,0 +1,18 @@
+pkg std =
+	generic sleq	: (a : @a[:], b : @a[:] -> bool)
+;;
+
+generic sleq = {a, b
+	var i
+
+	if a.len != b.len
+		-> false
+	;;
+
+	for i = 0; i < a.len; i++
+		if a[i] != b[i]
+			-> false
+		;;
+	;;
+	-> true
+}
--- /dev/null
+++ b/lib/std/slfill.myr
@@ -1,0 +1,12 @@
+pkg std =
+	generic slfill	: (sl : @a[:], v : @a	-> @a[:])
+;;
+
+generic slfill = {sl, v
+	var i
+
+	for i = 0; i < sl.len; i++
+		sl[i] = v
+	;;
+	-> sl
+}
--- /dev/null
+++ b/lib/std/sljoin.myr
@@ -1,0 +1,15 @@
+use "alloc.use"
+use "slcp.use"
+
+pkg std =
+	generic sljoin	: (dst : @a[:], src : @a[:]	-> @a[:])
+;;
+
+generic sljoin = {dst, src
+	var len
+
+	len = dst.len
+	dst = slgrow(dst, len + src.len)
+	slcp(dst[len:], src)
+	-> dst 
+}
--- /dev/null
+++ b/lib/std/slpush.myr
@@ -1,0 +1,20 @@
+use "types.use"
+use "alloc.use"
+
+pkg std =
+	generic slpush	: (sl : @a[:], elt : @a	-> @a[:])
+;;
+
+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.
+	*/
+	sl = slgrow(sl, sl.len + 1)
+	sl[sl.len - 1] = elt
+	-> sl
+}
--- /dev/null
+++ b/lib/std/slput.myr
@@ -1,0 +1,20 @@
+use "types.use"
+use "alloc.use"
+use "die.use"
+
+pkg std =
+	generic slput	: (sl : @a[:], idx : size, elt : @a	-> @a[:])
+;;
+
+generic slput = {sl, idx, elt
+	var i
+	var len
+
+	len = sl.len
+	sl = slgrow(sl, sl.len + 1)
+	for i = len - 1; i >= idx; i--
+		sl[i + 1] = sl[i]
+	;;
+	sl[idx] = elt
+	-> sl
+}
--- /dev/null
+++ b/lib/std/slurp.myr
@@ -1,0 +1,43 @@
+use "alloc.use"
+use "die.use"
+use "result.use"
+use "extremum.use"
+use "syswrap.use"
+use "types.use"
+
+pkg std =
+	const slurp : (path : byte[:] -> result(byte[:], byte[:]))
+	const fslurp : (path : fd -> result(byte[:], byte[:]))
+;;
+
+const Bufstart = 4096
+
+const slurp = {path
+	var fd
+	fd = open(path, Ordonly)
+	if fd < 0
+		-> `Fail "Could not open file"
+	;;
+	-> fslurp(fd)
+}
+
+const fslurp = {fd
+	var len, bufsz
+	var buf
+	var n
+
+	len = 0
+	bufsz = Bufstart
+	buf = slalloc(bufsz)
+	while true
+		n = read(fd, buf[len:])
+		if n <= 0
+			goto done
+		;;
+		len += n
+		bufsz *= 2
+		buf = slgrow(buf, bufsz)
+	;;
+:done
+	-> `Ok buf[:len]
+}
--- /dev/null
+++ b/lib/std/sort.myr
@@ -1,0 +1,61 @@
+use "cmp.use"
+
+pkg std =
+	generic sort	: (sl:@a[:], cmp:(a:@a, b:@a -> order) -> @a[:])
+;;
+
+generic sort = {sl, cmp
+	var end
+	var tmp
+
+	heapify(sl, cmp)
+	end = sl.len - 1
+	while end > 0
+		tmp = sl[end]
+		sl[end] = sl[0]
+		sl[0] = tmp
+		end--
+		siftdown(sl[:end + 1], 0, cmp)
+	;;
+	-> sl
+}
+
+generic heapify = {sl, cmp
+	var start
+
+	start = sl.len/2 - 1
+	while start >= 0
+		siftdown(sl, start, cmp)
+		start--
+	;;
+}
+
+generic siftdown = {sl, start, cmp
+	var r, c, s
+	var tmp
+
+	r = start
+	while 2*r + 1 < sl.len
+		c = 2*r + 1
+		s = r
+		match cmp(sl[s], sl[c])
+		| `Before:	s = c
+		| _:		/* nothing */
+		;;
+		if c + 1 < sl.len
+			match cmp(sl[s], sl[c + 1])
+			| `Before:	s = c + 1
+			| _:	/* nothing */
+			;;
+		;;
+		if s != r
+			tmp = sl[r]
+			sl[r] = sl[s]
+			sl[s] = tmp
+			r = s
+		else
+			->
+		;;
+	;;
+}
+
--- /dev/null
+++ b/lib/std/spork.myr
@@ -1,0 +1,62 @@
+use "die.use"
+use "execvp.use"
+use "fmt.use"
+use "result.use"
+use "syswrap.use"
+
+pkg std =
+	const spork	: (cmd : byte[:][:]	-> result((pid, fd, fd), int))
+	const sporkfd	: (cmd : byte[:][:], infd : fd, outfd : fd	-> result(pid, int))
+;;
+
+const spork = {cmd
+	var infds  :fd[2], outfds : fd[2]
+	var err
+
+	/* open up pipes */
+	err = pipe(&infds)
+	if err != 0
+		-> `Fail (-err castto(int))
+	;;
+	err = pipe(&outfds)
+	if err != 0
+		-> `Fail (-err castto(int))
+	;;
+
+	match sporkfd(cmd, infds[0] castto(fd), outfds[1] castto(fd))
+	| `Ok pid:
+		/* close unused fd ends */
+		close(infds[0]);
+		close(outfds[1]);
+		-> `Ok (pid, infds[1], outfds[0])
+	| `Fail m:
+		-> `Fail m
+	;;
+}
+
+const sporkfd = {cmd, infd, outfd
+	var pid
+
+	pid = fork()
+	/* error  */
+	if pid == -1
+		-> `Fail -1
+	/* child */
+	elif pid == 0
+		/* stdin/stdout for our communication. */
+		if dup2(infd castto(fd), 0) != 0
+			fatal("unable to set stdin\n")
+		;;
+		if dup2(outfd castto(fd), 1) != 1
+			fatal("unable to set stdout\n")
+		;;
+		close(infd)
+		close(outfd)
+		execvp(cmd[0], cmd) < 0
+		fatal("failed to exec {}\n", cmd[0])
+	/* parent */
+	else
+		-> `Ok pid
+	;;
+}
+
--- /dev/null
+++ b/lib/std/strbuf.myr
@@ -1,0 +1,107 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "slcp.use"
+use "types.use"
+use "utf.use"
+
+pkg std =
+	type strbuf = struct
+		buf	: byte[:]
+		len	: size
+		fixed	: bool
+	;;
+
+	const mksb	: (-> strbuf#)
+	const mkbufsb	: (buf : byte[:] -> strbuf#)
+	const sbfin	: (sb : strbuf# -> byte[:])
+	const sbfree	: (sb : strbuf# -> void)
+	const sbpeek	: (sb : strbuf# -> byte[:])
+
+	const sbputc	: (sb : strbuf#, v : char -> bool)
+	const sbputs	: (sb : strbuf#, v : byte[:] -> bool)
+	const sbputb	: (sb : strbuf#, v : byte -> bool)
+	const sbtrim	: (sb : strbuf#, len : size -> void)
+;;
+
+const mksb = {
+	var sb
+	sb = zalloc()
+	sb.buf = slalloc(1)
+	-> sb
+}
+
+const mkbufsb = {buf
+	var sb
+
+	sb = zalloc()
+	sb.buf = buf
+	sb.fixed = true
+	-> sb
+}
+
+const sbfin = {sb
+	var sl
+
+	sl = sb.buf[:sb.len]
+	free(sb)
+	-> sl
+}
+
+const sbfree = {sb
+	if !sb.fixed
+		slfree(sb.buf)
+	;;
+	free(sb)
+}
+
+
+const sbpeek = {sb : strbuf#
+	-> sb.buf[:sb.len]
+}
+
+const sbputc = {sb, v
+	if !ensure(sb, charlen(v))
+		-> false
+	;;
+	sb.len += encode(sb.buf[sb.len:], v)
+	-> true
+}
+const sbputs = {sb, v
+	var ok
+	var len
+
+	ok = ensure(sb, v.len)
+	/* copy what we can */
+	len = min(sb.buf.len - sb.len, v.len)
+	slcp(sb.buf[sb.len:sb.len + len], v[:len])
+	sb.len += len
+	-> ok
+}
+const sbputb = {sb, v
+	if !ensure(sb, 1)
+		-> false
+	;;
+	sb.buf[sb.len++] = v
+	-> true
+}
+
+const sbtrim = {sb, len
+	assert(abs(len) <= sb.len, "trim out of range\n")
+	if len < 0
+		sb.len -= abs(len)
+	else
+		sb.len = len
+	;;
+}
+
+const ensure = {sb, len
+	if sb.fixed && sb.len + len > sb.buf.len
+		-> false
+	;;
+	while sb.buf.len < sb.len + len
+		sb.buf = slgrow(sb.buf, 2*sb.buf.len)
+	;;
+	-> true
+}
+
--- /dev/null
+++ b/lib/std/strfind.myr
@@ -1,0 +1,51 @@
+use "types.use"
+use "option.use"
+
+pkg std =
+	const strfind	: (haystack : byte[:], needle : byte[:] -> option(size))
+	const strrfind	: (haystack : byte[:], needle : byte[:] -> option(size))
+	const strhas	: (haystack : byte[:], needle : byte[:]	-> bool)
+;;
+
+const strfind = {haystack, needle
+	-> strfindin(haystack, needle, 0, haystack.len)
+}
+
+const strrfind = {haystack, needle
+	-> strfindin(haystack, needle, haystack.len - 1, -1)
+}
+
+const strfindin = {haystack, needle, start, end
+	var i, j, inc : size
+
+	inc = 1
+	if start > end
+		inc = -1
+	;;
+	for i = start; i != end; i += inc
+		/* 
+		if we knew the direction we could terminate early,
+		but we allow the start and end to be passed in.
+		*/
+		if i + needle.len > haystack.len
+			continue
+		;;
+		if haystack[i] == needle[0]
+			for j = 0; j < needle.len; j++
+				if haystack[i + j] != needle[j]
+					goto nextiter
+				;;
+			;;
+			-> `Some i
+		;;
+:nextiter
+	;;
+	-> `None
+}
+
+const strhas = {haystack, needle
+	match strfind(haystack, needle)
+	| `Some _:	-> true
+	| `None:	-> false
+	;;
+}
\ No newline at end of file
--- /dev/null
+++ b/lib/std/strjoin.myr
@@ -1,0 +1,41 @@
+use "alloc.use"
+use "die.use"
+use "slcp.use"
+
+pkg std =
+	const strcat	: (a : byte[:], b : byte[:] -> byte[:])
+	const strjoin	: (strings : byte[:][:], delim : byte[:] -> byte[:])
+;;
+
+const strcat = {a, b
+	-> strjoin([a, b][:], "")
+}
+
+const strjoin = {strings, delim
+	var len, off
+	var i
+	var s
+
+	len = 0
+	for i = 0; i < strings.len; i++
+		len += strings[i].len
+	;;
+	if strings.len > 0
+		len += (strings.len - 1)*delim.len
+	;;
+
+	s = slalloc(len)
+	off = 0
+	for i = 0; i < strings.len; i++
+		slcp(s[off:off + strings[i].len], strings[i])
+		off += strings[i].len
+		/* we don't want to terminate the last string with delim */
+		if i != strings.len - 1
+			slcp(s[off:off + delim.len], delim)
+			off += delim.len
+		;;
+	;;
+	-> s
+}
+
+
--- /dev/null
+++ b/lib/std/strsplit.myr
@@ -1,0 +1,35 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "option.use"
+use "slpush.use"
+use "strfind.use"
+use "types.use"
+
+pkg std =
+	const strsplit	: (s : byte[:], delim : byte[:] -> byte[:][:])
+;;
+
+const strsplit = {s, delim
+	var last
+	var sp
+
+	sp = [][:]
+	if s.len == 0
+		-> sp
+	;;
+	last = 0
+	while true
+		match strfind(s, delim)
+		| `Some i:
+			sp = slpush(sp, s[:i])
+			s = s[i + delim.len:]
+		| `None:
+			goto donesplit
+		;;
+	;;
+:donesplit
+	sp = slpush(sp, s[:])
+	-> sp
+}
+
--- /dev/null
+++ b/lib/std/strstrip.myr
@@ -1,0 +1,43 @@
+use "types.use"
+use "utf.use"
+use "chartype.use"
+
+pkg std =
+	const strstrip	: (str : byte[:] -> byte[:])
+	const strfstrip	: (str : byte[:] -> byte[:])
+	const strrstrip	: (str : byte[:] -> byte[:])
+;;
+
+/* strip blanks from both head and tail of str */
+const strstrip = {str
+	-> strrstrip(strfstrip(str))
+}
+
+/* strip forward on str */
+const strfstrip = {str
+	var c
+	
+	for c = decode(str); isblank(c); c = decode(str)
+		str = str[charlen(c):]
+	;;
+	-> str
+
+}
+
+/* strip reverse on str */
+const strrstrip = {str
+	var i
+	var end
+
+	/* scan backwards for start of utf8 char */
+	end = str.len
+	for i = str.len; i != 0; i--
+		if str[i - 1] & 0x80 == 0 || str[i-1] & 0xc0 != 0x80
+			if !isspace(decode(str[i-1:]))
+				break
+			;;
+			end = i - 1
+		;;
+	;;
+	-> str[:end]
+}
--- /dev/null
+++ b/lib/std/swap.myr
@@ -1,0 +1,11 @@
+pkg std =
+	generic swap	: (a : @a#, b : @a# -> void)
+;;
+
+generic swap = {a : @a#, b : @a#
+	var t
+
+	t = a#
+	a# = b#
+	b# = t
+}
--- /dev/null
+++ b/lib/std/sys+freebsd-x64.myr
@@ -1,0 +1,805 @@
+use "systypes.use"
+
+pkg sys =
+	type scno	= int64 /*syscall*/
+	type fdopt	= int64	/* fd options */
+	type fd		= int64	/* fd */
+	type mprot	= int64	/* memory protection */
+	type mopt	= int64	/* memory mapping options */
+	type socktype	= int64	/* socket type */
+	type sockproto	= int64	/* socket protocol */
+	type sockfam	= uint8	/* socket family */
+	type filemode	= uint16
+	type filetype	= uint8
+
+	type clock = union
+		`Clockrealtime
+		`Clockrealtime_precise
+		`Clockrealtime_fast
+		`Clockmonotonic
+		`Clockmonotonic_precise     
+		`Clockmonotonic_fast
+		`Clockuptime
+		`Clockuptime_precise
+		`Clockuptime_fast
+		`Clockvirtual
+		`Clockprof
+		`Clocksecond
+	;;
+
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+	;;
+
+	type timespec = struct
+		sec	: uint64
+		nsec	: uint64 
+	;;
+
+	type timeval = struct
+		sec	: uint64
+		usec	: uint64
+	;;
+
+	type rusage = struct
+		utime	: timeval /* user time */
+		stime	: timeval /* system time */
+		maxrss	: uint64 /* max resident set size*/
+		ixrss	: uint64 /* shared text size */
+		idrss	: uint64 /* unshared data size */
+		isrss	: uint64 /* unshared stack size */
+		minflt	: uint64 /* page reclaims */
+		majflt	: uint64 /* page faults */
+		nswap	: uint64 /* swaps */
+		inblock	: uint64 /* block input ops */
+		oublock	: uint64 /* block output ops */
+		msgsnd	: uint64 /* messages sent */	
+		msgrcv	: uint64 /* messages received */
+		nsignals : uint64 /* signals received */
+		nvcsw	: uint64 /* voluntary context switches */
+		nivcsw	: uint64 /* involuntary context switches */
+	;;
+
+	type statbuf = struct
+		dev	: uint32 
+		ino	: uint32 
+		mode	: filemode
+		nlink	: uint16
+		uid	: uint32
+		gid	: uint32
+		rdev	: uint32
+		atim	: timespec
+		mtim	: timespec
+		ctim	: timespec
+		size	: int64
+		blocks	: int64
+		blksize	: uint32
+		flags	: uint32
+		gen	: uint32
+		lspare	: int32
+		birthtim	: timespec 
+	;;
+
+	type utsname = struct
+		system	: byte[256]
+		node : byte[256] 
+		release : byte[256]
+		version : byte[256]
+		machine : byte[256]
+	;;
+
+	type sockaddr = struct
+		len	: byte
+		fam	: sockfam
+		data	: byte[14] /* what is the *actual* length? */
+	;;
+
+	type sockaddr_in = struct
+		len	: byte
+		fam	: sockfam
+		port	: uint16
+		addr	: byte[4]
+		zero	: byte[8]
+	;;
+
+	type sockaddr_storage = struct
+		len	: byte
+		fam	: sockfam
+		__pad1  : byte[6]
+		__align : int64
+		__pad2  : byte[112]
+	;;	
+	
+	type dirent = struct
+		fileno	: uint32
+		reclen	: uint16
+		ftype	: filetype
+		namelen	: uint8
+		name	: byte[256]	
+	;;	
+
+	/* open options */
+	const Ordonly  	: fdopt = 0x0
+	const Owronly  	: fdopt = 0x1
+	const Ordwr    	: fdopt = 0x2
+	const Oappend  	: fdopt = 0x8
+	const Ocreat   	: fdopt = 0x200
+	const Onofollow	: fdopt = 0x100
+	const Ondelay  	: fdopt = 0x4
+	const Otrunc   	: fdopt = 0x400
+	const Odir	: fdopt = 0x20000
+
+        /* stat modes */	
+	const Sifmt	: filemode = 0xf000
+	const Sififo	: filemode = 0x1000
+	const Sifchr	: filemode = 0x2000
+	const Sifdir	: filemode = 0x4000
+	const Sifblk	: filemode = 0x6000
+	const Sifreg	: filemode = 0x8000
+	const Siflnk	: filemode = 0xa000
+	const Sifsock 	: filemode = 0xc000
+
+	/* mmap protection */
+	const Mprotnone	: mprot = 0x0
+	const Mprotrd	: mprot = 0x1
+	const Mprotwr	: mprot = 0x2
+	const Mprotexec	: mprot = 0x4
+	const Mprotrw	: mprot = 0x3
+
+	/* mmap options */
+	const Mshared	: mopt = 0x1
+	const Mpriv	: mopt = 0x2
+	const Mfixed	: mopt = 0x10
+	const Mfile	: mopt = 0x0
+	const Manon	: mopt = 0x1000
+	const M32bit	: mopt = 0x80000
+
+	/* file types */
+	const Dtunknown	: filetype = 0
+	const Dtfifo	: filetype = 1
+	const Dtchr	: filetype = 2
+	const Dtdir	: filetype = 4
+	const Dtblk	: filetype = 6
+	const Dtreg	: filetype = 8
+	const Dtlnk	: filetype = 10
+	const Dtsock	: filetype = 12
+	const Dtwht	: filetype = 14
+
+	/* socket families. INCOMPLETE. */
+	const Afunspec	: sockfam = 0
+	const Afunix	: sockfam = 1
+	const Afinet	: sockfam = 2
+	const Afinet6	: sockfam = 28
+
+	/* socket types. */
+	const Sockstream	: socktype = 1
+	const Sockdgram		: socktype = 2
+	const Sockraw		: socktype = 3
+	const Sockrdm		: socktype = 4
+	const Sockseqpacket	: socktype = 5
+
+	/* network protocols */
+	const Ipproto_ip	: sockproto = 0
+	const Ipproto_icmp	: sockproto = 1
+	const Ipproto_tcp	: sockproto = 6
+	const Ipproto_udp	: sockproto = 17
+	const Ipproto_raw	: sockproto = 255
+
+	/* return value for a failed mapping */
+	const Mapbad	: byte# = -1 castto(byte#)
+
+	/* syscalls */
+	const Syssyscall                   : scno = 0
+	const Sysexit                      : scno = 1
+	const Sysfork                      : scno = 2
+	const Sysread                      : scno = 3
+	const Syswrite                     : scno = 4
+	const Sysopen                      : scno = 5
+	const Sysclose                     : scno = 6
+	const Syswait4                     : scno = 7
+	const Syslink                      : scno = 9
+	const Sysunlink                    : scno = 10
+	const Syschdir                     : scno = 12
+	const Sysfchdir                    : scno = 13
+	const Sysmknod                     : scno = 14
+	const Syschmod                     : scno = 15
+	const Syschown                     : scno = 16
+	const Sysbreak                     : scno = 17
+	const Sysfreebsd4_getfsstat        : scno = 18
+	const Sysgetpid                    : scno = 20
+	const Sysmount                     : scno = 21
+	const Sysunmount                   : scno = 22
+	const Syssetuid                    : scno = 23
+	const Sysgetuid                    : scno = 24
+	const Sysgeteuid                   : scno = 25
+	const Sysptrace                    : scno = 26
+	const Sysrecvmsg                   : scno = 27
+	const Syssendmsg                   : scno = 28
+	const Sysrecvfrom                  : scno = 29
+	const Sysaccept                    : scno = 30
+	const Sysgetpeername               : scno = 31
+	const Sysgetsockname               : scno = 32
+	const Sysaccess                    : scno = 33
+	const Syschflags                   : scno = 34
+	const Sysfchflags                  : scno = 35
+	const Syssync                      : scno = 36
+	const Syskill                      : scno = 37
+	const Sysgetppid                   : scno = 39
+	const Sysdup                       : scno = 41
+	const Syspipe                      : scno = 42
+	const Sysgetegid                   : scno = 43
+	const Sysprofil                    : scno = 44
+	const Sysktrace                    : scno = 45
+	const Sysgetgid                    : scno = 47
+	const Sysgetlogin                  : scno = 49
+	const Syssetlogin                  : scno = 50
+	const Sysacct                      : scno = 51
+	const Syssigaltstack               : scno = 53
+	const Sysioctl                     : scno = 54
+	const Sysreboot                    : scno = 55
+	const Sysrevoke                    : scno = 56
+	const Syssymlink                   : scno = 57
+	const Sysreadlink                  : scno = 58
+	const Sysexecve                    : scno = 59
+	const Sysumask                     : scno = 60
+	const Syschroot                    : scno = 61
+	const Sysmsync                     : scno = 65
+	const Sysvfork                     : scno = 66
+	const Syssbrk                      : scno = 69
+	const Syssstk                      : scno = 70
+	const Sysvadvise                   : scno = 72
+	const Sysmunmap                    : scno = 73
+	const Sysmprotect                  : scno = 74
+	const Sysmadvise                   : scno = 75
+	const Sysmincore                   : scno = 78
+	const Sysgetgroups                 : scno = 79
+	const Syssetgroups                 : scno = 80
+	const Sysgetpgrp                   : scno = 81
+	const Syssetpgid                   : scno = 82
+	const Syssetitimer                 : scno = 83
+	const Sysswapon                    : scno = 85
+	const Sysgetitimer                 : scno = 86
+	const Sysgetdtablesize             : scno = 89
+	const Sysdup2                      : scno = 90
+	const Sysfcntl                     : scno = 92
+	const Sysselect                    : scno = 93
+	const Sysfsync                     : scno = 95
+	const Syssetpriority               : scno = 96
+	const Syssocket                    : scno = 97
+	const Sysconnect                   : scno = 98
+	const Sysgetpriority               : scno = 100
+	const Sysbind                      : scno = 104
+	const Syssetsockopt                : scno = 105
+	const Syslisten                    : scno = 106
+	const Sysgettimeofday              : scno = 116
+	const Sysgetrusage                 : scno = 117
+	const Sysgetsockopt                : scno = 118
+	const Sysreadv                     : scno = 120
+	const Syswritev                    : scno = 121
+	const Syssettimeofday              : scno = 122
+	const Sysfchown                    : scno = 123
+	const Sysfchmod                    : scno = 124
+	const Syssetreuid                  : scno = 126
+	const Syssetregid                  : scno = 127
+	const Sysrename                    : scno = 128
+	const Sysflock                     : scno = 131
+	const Sysmkfifo                    : scno = 132
+	const Syssendto                    : scno = 133
+	const Sysshutdown                  : scno = 134
+	const Syssocketpair                : scno = 135
+	const Sysmkdir                     : scno = 136
+	const Sysrmdir                     : scno = 137
+	const Sysutimes                    : scno = 138
+	const Sysadjtime                   : scno = 140
+	const Syssetsid                    : scno = 147
+	const Sysquotactl                  : scno = 148
+	const Sysnlm_syscall               : scno = 154
+	const Sysnfssvc                    : scno = 155
+	const Sysfreebsd4_statfs           : scno = 157
+	const Sysfreebsd4_fstatfs          : scno = 158
+	const Syslgetfh                    : scno = 160
+	const Sysgetfh                     : scno = 161
+	const Sysfreebsd4_getdomainname    : scno = 162
+	const Sysfreebsd4_setdomainname    : scno = 163
+	const Sysfreebsd4_uname            : scno = 164
+	const Syssysarch                   : scno = 165
+	const Sysrtprio                    : scno = 166
+	const Syssemsys                    : scno = 169
+	const Sysmsgsys                    : scno = 170
+	const Sysshmsys                    : scno = 171
+	const Sysfreebsd6_pread            : scno = 173
+	const Sysfreebsd6_pwrite           : scno = 174
+	const Syssetfib                    : scno = 175
+	const Sysntp_adjtime               : scno = 176
+	const Syssetgid                    : scno = 181
+	const Syssetegid                   : scno = 182
+	const Sysseteuid                   : scno = 183
+	const Sysstat                      : scno = 188
+	const Sysfstat                     : scno = 189
+	const Syslstat                     : scno = 190
+	const Syspathconf                  : scno = 191
+	const Sysfpathconf                 : scno = 192
+	const Sysgetrlimit                 : scno = 194
+	const Syssetrlimit                 : scno = 195
+	const Sysgetdirentries             : scno = 196
+	const Sysfreebsd6_mmap             : scno = 197
+	const Sys__syscall                 : scno = 198
+	const Sysfreebsd6_lseek            : scno = 199
+	const Sysfreebsd6_truncate         : scno = 200
+	const Sysfreebsd6_ftruncate        : scno = 201
+	const Sys__sysctl                  : scno = 202
+	const Sysmlock                     : scno = 203
+	const Sysmunlock                   : scno = 204
+	const Sysundelete                  : scno = 205
+	const Sysfutimes                   : scno = 206
+	const Sysgetpgid                   : scno = 207
+	const Syspoll                      : scno = 209
+	const Sysfreebsd7___semctl         : scno = 220
+	const Syssemget                    : scno = 221
+	const Syssemop                     : scno = 222
+	const Sysfreebsd7_msgctl           : scno = 224
+	const Sysmsgget                    : scno = 225
+	const Sysmsgsnd                    : scno = 226
+	const Sysmsgrcv                    : scno = 227
+	const Sysshmat                     : scno = 228
+	const Sysfreebsd7_shmctl           : scno = 229
+	const Sysshmdt                     : scno = 230
+	const Sysshmget                    : scno = 231
+	const Sysclock_gettime             : scno = 232
+	const Sysclock_settime             : scno = 233
+	const Sysclock_getres              : scno = 234
+	const Sysktimer_create             : scno = 235
+	const Sysktimer_delete             : scno = 236
+	const Sysktimer_settime            : scno = 237
+	const Sysktimer_gettime            : scno = 238
+	const Sysktimer_getoverrun         : scno = 239
+	const Sysnanosleep                 : scno = 240
+	const Sysffclock_getcounter        : scno = 241
+	const Sysffclock_setestimate       : scno = 242
+	const Sysffclock_getestimate       : scno = 243
+	const Sysclock_getcpuclockid2      : scno = 247
+	const Sysntp_gettime               : scno = 248
+	const Sysminherit                  : scno = 250
+	const Sysrfork                     : scno = 251
+	const Sysopenbsd_poll              : scno = 252
+	const Sysissetugid                 : scno = 253
+	const Syslchown                    : scno = 254
+	const Sysaio_read                  : scno = 255
+	const Sysaio_write                 : scno = 256
+	const Syslio_listio                : scno = 257
+	const Sysgetdents                  : scno = 272
+	const Syslchmod                    : scno = 274
+	const Sysnetbsd_lchown             : scno = 275
+	const Syslutimes                   : scno = 276
+	const Sysnetbsd_msync              : scno = 277
+	const Sysnstat                     : scno = 278
+	const Sysnfstat                    : scno = 279
+	const Sysnlstat                    : scno = 280
+	const Syspreadv                    : scno = 289
+	const Syspwritev                   : scno = 290
+	const Sysfreebsd4_fhstatfs         : scno = 297
+	const Sysfhopen                    : scno = 298
+	const Sysfhstat                    : scno = 299
+	const Sysmodnext                   : scno = 300
+	const Sysmodstat                   : scno = 301
+	const Sysmodfnext                  : scno = 302
+	const Sysmodfind                   : scno = 303
+	const Syskldload                   : scno = 304
+	const Syskldunload                 : scno = 305
+	const Syskldfind                   : scno = 306
+	const Syskldnext                   : scno = 307
+	const Syskldstat                   : scno = 308
+	const Syskldfirstmod               : scno = 309
+	const Sysgetsid                    : scno = 310
+	const Syssetresuid                 : scno = 311
+	const Syssetresgid                 : scno = 312
+	const Sysaio_return                : scno = 314
+	const Sysaio_suspend               : scno = 315
+	const Sysaio_cancel                : scno = 316
+	const Sysaio_error                 : scno = 317
+	const Sysoaio_read                 : scno = 318
+	const Sysoaio_write                : scno = 319
+	const Sysolio_listio               : scno = 320
+	const Sysyield                     : scno = 321
+	const Sysmlockall                  : scno = 324
+	const Sysmunlockall                : scno = 325
+	const Sys__getcwd                  : scno = 326
+	const Syssched_setparam            : scno = 327
+	const Syssched_getparam            : scno = 328
+	const Syssched_setscheduler        : scno = 329
+	const Syssched_getscheduler        : scno = 330
+	const Syssched_yield               : scno = 331
+	const Syssched_get_priority_max    : scno = 332
+	const Syssched_get_priority_min    : scno = 333
+	const Syssched_rr_get_interval     : scno = 334
+	const Sysutrace                    : scno = 335
+	const Sysfreebsd4_sendfile         : scno = 336
+	const Syskldsym                    : scno = 337
+	const Sysjail                      : scno = 338
+	const Sysnnpfs_syscall             : scno = 339
+	const Syssigprocmask               : scno = 340
+	const Syssigsuspend                : scno = 341
+	const Sysfreebsd4_sigaction        : scno = 342
+	const Syssigpending                : scno = 343
+	const Sysfreebsd4_sigreturn        : scno = 344
+	const Syssigtimedwait              : scno = 345
+	const Syssigwaitinfo               : scno = 346
+	const Sys__acl_get_file            : scno = 347
+	const Sys__acl_set_file            : scno = 348
+	const Sys__acl_get_fd              : scno = 349
+	const Sys__acl_set_fd              : scno = 350
+	const Sys__acl_delete_file         : scno = 351
+	const Sys__acl_delete_fd           : scno = 352
+	const Sys__acl_aclcheck_file       : scno = 353
+	const Sys__acl_aclcheck_fd         : scno = 354
+	const Sysextattrctl                : scno = 355
+	const Sysextattr_set_file          : scno = 356
+	const Sysextattr_get_file          : scno = 357
+	const Sysextattr_delete_file       : scno = 358
+	const Sysaio_waitcomplete          : scno = 359
+	const Sysgetresuid                 : scno = 360
+	const Sysgetresgid                 : scno = 361
+	const Syskqueue                    : scno = 362
+	const Syskevent                    : scno = 363
+	const Sysextattr_set_fd            : scno = 371
+	const Sysextattr_get_fd            : scno = 372
+	const Sysextattr_delete_fd         : scno = 373
+	const Sys__setugid                 : scno = 374
+	const Syseaccess                   : scno = 376
+	const Sysafs3_syscall              : scno = 377
+	const Sysnmount                    : scno = 378
+	const Sys__mac_get_proc            : scno = 384
+	const Sys__mac_set_proc            : scno = 385
+	const Sys__mac_get_fd              : scno = 386
+	const Sys__mac_get_file            : scno = 387
+	const Sys__mac_set_fd              : scno = 388
+	const Sys__mac_set_file            : scno = 389
+	const Syskenv                      : scno = 390
+	const Syslchflags                  : scno = 391
+	const Sysuuidgen                   : scno = 392
+	const Syssendfile                  : scno = 393
+	const Sysmac_syscall               : scno = 394
+	const Sysgetfsstat                 : scno = 395
+	const Sysstatfs                    : scno = 396
+	const Sysfstatfs                   : scno = 397
+	const Sysfhstatfs                  : scno = 398
+	const Sysksem_close                : scno = 400
+	const Sysksem_post                 : scno = 401
+	const Sysksem_wait                 : scno = 402
+	const Sysksem_trywait              : scno = 403
+	const Sysksem_init                 : scno = 404
+	const Sysksem_open                 : scno = 405
+	const Sysksem_unlink               : scno = 406
+	const Sysksem_getvalue             : scno = 407
+	const Sysksem_destroy              : scno = 408
+	const Sys__mac_get_pid             : scno = 409
+	const Sys__mac_get_link            : scno = 410
+	const Sys__mac_set_link            : scno = 411
+	const Sysextattr_set_link          : scno = 412
+	const Sysextattr_get_link          : scno = 413
+	const Sysextattr_delete_link       : scno = 414
+	const Sys__mac_execve              : scno = 415
+	const Syssigaction                 : scno = 416
+	const Syssigreturn                 : scno = 417
+	const Sysgetcontext                : scno = 421
+	const Syssetcontext                : scno = 422
+	const Sysswapcontext               : scno = 423
+	const Sysswapoff                   : scno = 424
+	const Sys__acl_get_link            : scno = 425
+	const Sys__acl_set_link            : scno = 426
+	const Sys__acl_delete_link         : scno = 427
+	const Sys__acl_aclcheck_link       : scno = 428
+	const Syssigwait                   : scno = 429
+	const Systhr_create                : scno = 430
+	const Systhr_exit                  : scno = 431
+	const Systhr_self                  : scno = 432
+	const Systhr_kill                  : scno = 433
+	const Sys_umtx_lock                : scno = 434
+	const Sys_umtx_unlock              : scno = 435
+	const Sysjail_attach               : scno = 436
+	const Sysextattr_list_fd           : scno = 437
+	const Sysextattr_list_file         : scno = 438
+	const Sysextattr_list_link         : scno = 439
+	const Sysksem_timedwait            : scno = 441
+	const Systhr_suspend               : scno = 442
+	const Systhr_wake                  : scno = 443
+	const Syskldunloadf                : scno = 444
+	const Sysaudit                     : scno = 445
+	const Sysauditon                   : scno = 446
+	const Sysgetauid                   : scno = 447
+	const Syssetauid                   : scno = 448
+	const Sysgetaudit                  : scno = 449
+	const Syssetaudit                  : scno = 450
+	const Sysgetaudit_addr             : scno = 451
+	const Syssetaudit_addr             : scno = 452
+	const Sysauditctl                  : scno = 453
+	const Sys_umtx_op                  : scno = 454
+	const Systhr_new                   : scno = 455
+	const Syssigqueue                  : scno = 456
+	const Syskmq_open                  : scno = 457
+	const Syskmq_setattr               : scno = 458
+	const Syskmq_timedreceive          : scno = 459
+	const Syskmq_timedsend             : scno = 460
+	const Syskmq_notify                : scno = 461
+	const Syskmq_unlink                : scno = 462
+	const Sysabort2                    : scno = 463
+	const Systhr_set_name              : scno = 464
+	const Sysaio_fsync                 : scno = 465
+	const Sysrtprio_thread             : scno = 466
+	const Syssctp_peeloff              : scno = 471
+	const Syssctp_generic_sendmsg      : scno = 472
+	const Syssctp_generic_sendmsg_iov  : scno = 473
+	const Syssctp_generic_recvmsg      : scno = 474
+	const Syspread                     : scno = 475
+	const Syspwrite                    : scno = 476
+	const Sysmmap                      : scno = 477
+	const Syslseek                     : scno = 478
+	const Systruncate                  : scno = 479
+	const Sysftruncate                 : scno = 480
+	const Systhr_kill2                 : scno = 481
+	const Sysshm_open                  : scno = 482
+	const Sysshm_unlink                : scno = 483
+	const Syscpuset                    : scno = 484
+	const Syscpuset_setid              : scno = 485
+	const Syscpuset_getid              : scno = 486
+	const Syscpuset_getaffinity        : scno = 487
+	const Syscpuset_setaffinity        : scno = 488
+	const Sysfaccessat                 : scno = 489
+	const Sysfchmodat                  : scno = 490
+	const Sysfchownat                  : scno = 491
+	const Sysfexecve                   : scno = 492
+	const Sysfstatat                   : scno = 493
+	const Sysfutimesat                 : scno = 494
+	const Syslinkat                    : scno = 495
+	const Sysmkdirat                   : scno = 496
+	const Sysmkfifoat                  : scno = 497
+	const Sysmknodat                   : scno = 498
+	const Sysopenat                    : scno = 499
+	const Sysreadlinkat                : scno = 500
+	const Sysrenameat                  : scno = 501
+	const Syssymlinkat                 : scno = 502
+	const Sysunlinkat                  : scno = 503
+	const Sysposix_openpt              : scno = 504
+	const Sysgssd_syscall              : scno = 505
+	const Sysjail_get                  : scno = 506
+	const Sysjail_set                  : scno = 507
+	const Sysjail_remove               : scno = 508
+	const Sysclosefrom                 : scno = 509
+	const Sys__semctl                  : scno = 510
+	const Sysmsgctl                    : scno = 511
+	const Sysshmctl                    : scno = 512
+	const Syslpathconf                 : scno = 513
+	const Sys__cap_rights_get          : scno = 515
+	const Syscap_enter                 : scno = 516
+	const Syscap_getmode               : scno = 517
+	const Syspdfork                    : scno = 518
+	const Syspdkill                    : scno = 519
+	const Syspdgetpid                  : scno = 520
+	const Syspselect                   : scno = 522
+	const Sysgetloginclass             : scno = 523
+	const Syssetloginclass             : scno = 524
+	const Sysrctl_get_racct            : scno = 525
+	const Sysrctl_get_rules            : scno = 526
+	const Sysrctl_get_limits           : scno = 527
+	const Sysrctl_add_rule             : scno = 528
+	const Sysrctl_remove_rule          : scno = 529
+	const Sysposix_fallocate           : scno = 530
+	const Sysposix_fadvise             : scno = 531
+	const Syswait6                     : scno = 532
+	const Syscap_rights_limit          : scno = 533
+	const Syscap_ioctls_limit          : scno = 534
+	const Syscap_ioctls_get            : scno = 535
+	const Syscap_fcntls_limit          : scno = 536
+	const Syscap_fcntls_get            : scno = 537
+	const Sysbindat                    : scno = 538
+	const Sysconnectat                 : scno = 539
+	const Syschflagsat                 : scno = 540
+	const Sysaccept4                   : scno = 541
+	const Syspipe2                     : scno = 542
+	const Sysaio_mlock                 : scno = 543
+	const Sysprocctl                   : scno = 544
+
+	extern const syscall : (sc:scno, args:... -> int64)
+
+	/* process control */
+	const exit	: (status:int -> void)
+	const getpid	: ( -> int64)
+	const kill	: (pid:int64, sig:int64 -> int64)
+	const fork	: (-> int64)
+	const wait4	: (pid:int64, loc:int32#, opt : int64, usage:rusage#	-> int64)
+	const waitpid	: (pid:int64, loc:int32#, opt : int64	-> int64)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
+
+	/* fd manipulation */
+	const open	: (path:byte[:], opts:fdopt -> fd)
+	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
+	const close	: (fd:fd -> int64)
+	const creat	: (path:byte[:], mode:int64 -> fd)
+	const read	: (fd:fd, buf:byte[:] -> size)
+	const write	: (fd:fd, buf:byte[:] -> size)
+	const lseek	: (fd:fd, off:uint64, whence:int64 -> int64)
+	const stat	: (path:byte[:], sb:statbuf# -> int64)
+	const lstat	: (path:byte[:], sb:statbuf# -> int64)
+	const fstat	: (fd:fd, sb:statbuf# -> int64)
+	const mkdir	: (path : byte[:], mode : int64	-> int64)
+	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
+	const getdirentries64	: (fd : fd, buf : byte[:], basep : uint64# -> int64)
+
+	/* networking */
+	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
+	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
+	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
+	const listen	: (sock : fd, backlog : int	-> int)
+	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
+
+	/* memory mapping */
+	const munmap	: (addr:byte#, len:size -> int64)
+	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
+
+	/* time - doublecheck if this is right */
+	const clock_getres	: (clk : clock, ts : timespec# -> int32)
+	const clock_gettime	: (clk : clock, ts : timespec# -> int32)
+	const clock_settime	: (clk : clock, ts : timespec# -> int32)
+	const sleep	: (time : uint64 -> int32)
+	const nanosleep	: (req : timespec#, rem : timespec# -> int32)
+
+	/* system information */
+	const uname 	: (buf : utsname# -> int)
+	const sysctl	: (mib : int[:], old : byte[:]#, new : byte[:] -> int)
+;;
+
+/* 
+wraps a syscall argument, converting it to 64 bits for the syscall function. This is
+the same as casting, but more concise than writing castto(int64)
+*/
+generic a = {x : @t
+	-> a(x)
+}
+
+extern const cstring	: (str : byte[:] -> byte#)
+extern const alloca	: (sz : size	-> byte#)
+extern const __cenvp : byte##
+
+/* process management */
+const exit	= {status;		syscall(Sysexit, a(status))}
+const getpid	= {;			-> syscall(Sysgetpid, 1)}
+const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
+const fork	= {;			-> syscall(Sysfork)}
+const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
+const waitpid	= {pid, loc, opt;
+	-> wait4(pid, loc, opt, 0 castto(rusage#)) 
+}
+
+const execv	= {cmd, args
+	var p, cargs, i
+
+	/* of course we fucking have to duplicate this code everywhere,
+	* since we want to stack allocate... */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
+}
+
+const execve	= {cmd, args, env
+	var cargs, cenv, i
+	var p
+
+	/* copy the args */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+
+	/*
+	 copy the env.
+	 of course we fucking have to duplicate this code everywhere,
+	 since we want to stack allocate... 
+	*/
+	p = alloca((env.len + 1)*sizeof(byte#))
+	cenv = (p castto(byte##))[:env.len]
+	for i = 0; i < env.len; i++
+		cenv[i] = cstring(env[i])
+	;;
+	cenv[env.len] = 0 castto(byte#)
+
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
+}
+
+/* fd manipulation */
+const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
+const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const close	= {fd;			-> syscall(Sysclose, a(fd))}
+const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
+const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
+const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
+const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
+const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
+const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
+generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)
+}
+const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries, a(fd), buf castto(byte#), a(buf.len), a(basep))}
+
+/* networking */
+const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
+const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
+const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
+const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
+const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
+
+/* memory management */
+const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
+const mmap	= {addr, len, prot, flags, fd, off;
+	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
+
+/* time */
+const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
+const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
+const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
+
+/* system information */
+const uname	= {buf;	-> syscall(Sysfreebsd4_uname, a(buf)) castto(int)}
+
+const sysctl = {mib, old, new
+	var mibp
+	var mibsz
+	var o
+	var oldp
+	var oldsz
+	var newp
+	var newsz
+	var ret
+
+	mibp = mib castto(byte#)
+	mibsz = a(mib.len)
+	o = old#
+	oldp = o castto(byte#)
+	oldsz = a(o.len)
+	newp = new castto(byte#)
+	newsz = a(new.len)
+
+	/* all args already passed through a() or ar  ptrs */
+	ret = syscall(Sys__sysctl, mibp, mibsz, oldp, oldsz, newp, newsz) castto(int)
+
+	old# = o[:oldsz]
+	-> ret
+}
+
+const clockid = {clk
+	match clk
+	| `Clockrealtime:		-> 0
+	| `Clockvirtual:		-> 1
+	| `Clockprof:			-> 2
+	| `Clockmonotonic:		-> 4
+	| `Clockuptime:			-> 5
+	| `Clockuptime_precise:		-> 7
+	| `Clockuptime_fast:		-> 8
+	| `Clockrealtime_precise:	-> 9
+	| `Clockrealtime_fast:		-> 10
+	| `Clockmonotonic_precise:	-> 11
+	| `Clockmonotonic_fast:		-> 12
+	| `Clocksecond:			-> 13
+	;;
+	-> a(-1)
+}
+
+const waitstatus = {st
+	match st & 0o177
+	| 0:    -> `Waitexit (st >> 8)
+	| 0x7f:-> `Waitstop (st >> 8)
+	| sig:  -> `Waitsig sig
+	;;
+}
+
--- /dev/null
+++ b/lib/std/sys+linux-x64.myr
@@ -1,0 +1,816 @@
+use "systypes.use"
+
+pkg sys =
+	type scno	= int64	/* syscall */
+
+	/* processes/threads */
+	type pid	= int	/* process id */
+	type tid	= int	/* thread id */
+	type cloneopt	= int64	/* options for clone(2) */
+
+	/* file descriptor manipulation */
+	type fdopt	= int64	/* fd options */
+	type fd		= int32	/* fd */
+	type whence	= uint64	/* seek from whence */
+	type filemode	= uint32	/* file open mode */
+
+	type mprot	= int64	/* memory protection */
+	type mopt	= int64	/* memory mapping options */
+	type socktype	= int64	/* socket type */
+	type sockproto	= int64	/* socket protocol */
+	type sockfam	= uint16	/* socket family */
+
+	type epollflags	= uint32
+	type epollop	= uint32
+	type epollevttype	= uint32
+
+	type pollevt	= uint16
+
+	type clock = union
+		`Clockrealtime
+		`Clockmonotonic
+		`Clockproccpu
+		`Clockthreadcpu
+		`Clockmonotonicraw
+		`Clockrealtimecoarse
+		`Clockmonotoniccoarse
+		`Clockboottime
+		`Clockrealtimealarm
+		`Clockboottimealarm
+	;;
+
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+		`Waitfail int32
+	;;
+
+	type timespec = struct
+		sec	: uint64
+		nsec	: uint64
+	;;
+
+	type timeval = struct
+		sec	: uint64
+		usec	: uint64
+	;;
+
+	type rusage = struct
+		utime	: timeval	/* user time */
+		stime	: timeval	/* system time */
+		_opaque	: uint64[14]	/* padding (darwin-specific data) */
+	;;
+
+	type statbuf = struct
+		 dev	: uint64
+		 ino	: uint64
+		 nlink	: uint64
+		 mode	: filemode
+		 uid	: uint32
+		 gid	: uint32
+		 __pad0	: uint32
+		 rdev	: uint64
+		 size	: uint64
+		 blksz	: uint32
+		 blocks	: uint64
+		 atime	: timespec
+		 mtime	: timespec
+		 ctime	: timespec
+		 __pad1	: uint64[3]
+	;;
+
+	type dirent64 = struct
+		ino	: uint64
+		off	: uint64
+		reclen	: uint16
+		etype	: byte
+		name	: byte[...]	/* special case; zero length => unchecked indexing */
+	;;
+
+	type utsname = struct
+		system	: byte[65]
+		node	: byte[65]
+		release	: byte[65]
+		version	: byte[65]
+		machine	: byte[65]
+		domain	: byte[65]
+	;;
+
+	type sockaddr = struct
+		fam	: sockfam
+		data	: byte[14]
+	;;
+
+	type sockaddr_in = struct
+		fam	: sockfam
+		port	: uint16
+		addr	: byte[4]
+		zero	: byte[8]
+	;;
+
+	type sockaddr_in6 = struct
+		fam	: sockfam
+		port	: uint16
+		addr	: byte[16]
+		scope	: uint32
+	;;
+
+	type sockaddr_storage = struct
+		fam	: sockfam
+		__align	: uint32
+		__pad	: byte[112]
+	;;
+
+	type epollevt = struct
+		events	: epollevttype
+		data	: byte[8]
+	;;
+
+	type pollfd = struct
+		fd	: fd
+		events	: pollevt
+		revents	: pollevt
+	;;
+
+	/* clone options */
+	const Clonesignal	: cloneopt = 0xff
+	const Clonevm		: cloneopt = 0x100
+	const Clonefs		: cloneopt = 0x200
+	const Clonefiles	: cloneopt = 0x400
+	const Clonesighand	: cloneopt = 0x800
+	const Cloneptrace	: cloneopt = 0x2000
+	const Clonevfork	: cloneopt = 0x4000
+	const Cloneparent	: cloneopt = 0x8000
+	const Clonethread	: cloneopt = 0x10000
+	const Clonenewns	: cloneopt = 0x20000
+	const Clonesysvsem	: cloneopt = 0x40000
+	const Clonesettls	: cloneopt = 0x80000
+	const Cloneparentsettid	: cloneopt = 0x100000
+	const Clonechildcleartid: cloneopt = 0x200000
+	const Clonedetached	: cloneopt = 0x400000
+	const Cloneuntraced	: cloneopt = 0x800000
+	const Clonechildsettid	: cloneopt = 0x1000000
+	const Clonenewuts	: cloneopt = 0x4000000
+	const Clonenewipc	: cloneopt = 0x8000000
+	const Clonenewuser	: cloneopt = 0x10000000
+	const Clonenewpid	: cloneopt = 0x20000000
+	const Clonenewnet	: cloneopt = 0x40000000
+	const Cloneio		: cloneopt = 0x80000000
+
+	type ptregs = struct
+	;;
+
+	/* open options */
+	const Ordonly  	: fdopt = 0x0
+	const Owronly  	: fdopt = 0x1
+	const Ordwr    	: fdopt = 0x2
+	const Ocreat   	: fdopt = 0x40
+	const Oexcl  	: fdopt = 0x80
+	const Otrunc   	: fdopt = 0x200
+	const Oappend  	: fdopt = 0x400
+	const Ondelay  	: fdopt = 0x800
+	const Odirect	: fdopt = 0x4000
+	const Odir	: fdopt = 0x10000
+	const Onofollow	: fdopt = 0x20000
+
+	/* stat modes */
+	const Sifmt	: filemode = 0xf000
+	const Sififo	: filemode = 0x1000
+	const Sifchr	: filemode = 0x2000
+	const Sifdir	: filemode = 0x4000
+	const Sifblk	: filemode = 0x6000
+	const Sifreg	: filemode = 0x8000
+	const Siflnk	: filemode = 0xa000
+	const Sifsock	: filemode = 0xc000
+
+	/* mmap protection */
+	const Mprotnone	: mprot = 0x0
+	const Mprotrd	: mprot = 0x1
+	const Mprotwr	: mprot = 0x2
+	const Mprotexec	: mprot = 0x4
+	const Mprotrw	: mprot = 0x3 /* convenience */
+	
+	/* mmap options */
+	const Mshared	: mopt = 0x1
+	const Mpriv	: mopt = 0x2
+	const Mfixed	: mopt = 0x10
+	const Mfile	: mopt = 0x0
+	const Manon	: mopt = 0x20
+	const M32bit	: mopt = 0x40
+
+	/* socket families. INCOMPLETE. */
+	const Afunspec	: sockfam = 0
+	const Afunix	: sockfam = 1
+	const Afinet	: sockfam = 2
+	const Afinet6	: sockfam = 10
+
+	/* socket types. */
+	const Sockstream	: socktype = 1	/* sequenced, reliable byte stream */
+	const Sockdgram		: socktype = 2	/* datagrams */
+	const Sockraw		: socktype = 3	/* raw proto */
+	const Sockrdm		: socktype = 4	/* reliably delivered messages */
+	const Sockseqpacket	: socktype = 5	/* sequenced, reliable packets */
+	const Sockdccp		: socktype = 6	/* data congestion control protocol */
+	const Sockpack		: socktype = 10	/* linux specific packet */
+
+	/* network protocols */
+	const Ipproto_ip	: sockproto = 0
+	const Ipproto_icmp	: sockproto = 1
+	const Ipproto_tcp	: sockproto = 6
+	const Ipproto_udp	: sockproto = 17
+	const Ipproto_raw	: sockproto = 255
+
+	/* epoll flags */
+	const Epollcloexec	: epollflags	= 0o2000000
+
+	/* epoll ops */
+	const Epollctladd	: epollop	= 0
+	const Epollctlmod	: epollop	= 1
+	const Epollctldel	: epollop	= 1
+
+	/* epoll events */
+	const Epollin	: epollevttype = 0x001
+	const Epollpri	: epollevttype = 0x002
+	const Epollout	: epollevttype = 0x004
+	const Epollerr	: epollevttype = 0x008
+	const Epollhup	: epollevttype = 0x010
+	const Epollrdnorm	: epollevttype = 0x040
+	const Epollrdband	: epollevttype = 0x080
+	const Epollwrnorm	: epollevttype = 0x100
+	const Epollwrband	: epollevttype = 0x200
+	const Epollmsg		: epollevttype = 0x400
+	const Epollrdhup	: epollevttype = 0x2000
+	const Epollwakeup	: epollevttype = 1 << 29
+	const Epolloneshot	: epollevttype = 1 << 30
+	const Epolledge	: epollevttype = 1 << 31
+
+	/* poll events : posix */
+	const Pollin	: pollevt = 0x001	/* There is data to read.  */
+	const Pollpri	: pollevt = 0x002	/* There is urgent data to read.  */
+	const Pollout	: pollevt = 0x004	/* Writing now will not block.  */
+
+	/* poll events: xopen */
+	const Pollrdnorm	: pollevt = 0x040	/* Normal data may be read.  */
+	const Pollrdband	: pollevt = 0x080	/* Priority data may be read.  */
+	const Pollwrnorm	: pollevt = 0x100	/* Writing now will not block.  */
+	const Pollwrband	: pollevt = 0x200	/* Priority data may be written.  */
+
+	/* poll events: linux */
+	const Pollmsg		: pollevt = 0x400
+	const Pollremove	: pollevt = 0x1000
+	const Pollrdhup		: pollevt = 0x2000
+
+	const Seekset	: whence = 0
+	const Seekcur	: whence = 1
+	const Seekend	: whence = 2
+
+	/* return value for a failed mapping */
+	const Mapbad	: byte# = -1 castto(byte#)
+
+	/* syscalls */
+	const Sysread			: scno = 0
+	const Syswrite			: scno = 1
+	const Sysopen			: scno = 2
+	const Sysclose			: scno = 3
+	const Sysstat			: scno = 4
+	const Sysfstat			: scno = 5
+	const Syslstat			: scno = 6
+	const Syspoll			: scno = 7
+	const Syslseek			: scno = 8
+	const Sysmmap			: scno = 9
+	const Sysmprotect		: scno = 10
+	const Sysmunmap			: scno = 11
+	const Sysbrk			: scno = 12
+	const Sysrt_sigaction		: scno = 13
+	const Sysrt_sigprocmask		: scno = 14
+	const Sysrt_sigreturn		: scno = 15
+	const Sysioctl			: scno = 16
+	const Syspread64		: scno = 17
+	const Syspwrite64		: scno = 18
+	const Sysreadv			: scno = 19
+	const Syswritev			: scno = 20
+	const Sysaccess			: scno = 21
+	const Syspipe			: scno = 22
+	const Sysselect			: scno = 23
+	const Syssched_yield		: scno = 24
+	const Sysmremap			: scno = 25
+	const Sysmsync			: scno = 26
+	const Sysmincore		: scno = 27
+	const Sysmadvise		: scno = 28
+	const Sysshmget			: scno = 29
+	const Sysshmat			: scno = 30
+	const Sysshmctl			: scno = 31
+	const Sysdup			: scno = 32
+	const Sysdup2			: scno = 33
+	const Syspause			: scno = 34
+	const Sysnanosleep		: scno = 35
+	const Sysgetitimer		: scno = 36
+	const Sysalarm			: scno = 37
+	const Syssetitimer		: scno = 38
+	const Sysgetpid			: scno = 39
+	const Syssendfile		: scno = 40
+	const Syssocket			: scno = 41
+	const Sysconnect		: scno = 42
+	const Sysaccept			: scno = 43
+	const Syssendto			: scno = 44
+	const Sysrecvfrom		: scno = 45
+	const Syssendmsg		: scno = 46
+	const Sysrecvmsg		: scno = 47
+	const Sysshutdown		: scno = 48
+	const Sysbind			: scno = 49
+	const Syslisten			: scno = 50
+	const Sysgetsockname		: scno = 51
+	const Sysgetpeername		: scno = 52
+	const Syssocketpair		: scno = 53
+	const Syssetsockopt		: scno = 54
+	const Sysgetsockopt		: scno = 55
+	const Sysclone			: scno = 56
+	const Sysfork			: scno = 57
+	const Sysvfork			: scno = 58
+	const Sysexecve			: scno = 59
+	const Sysexit			: scno = 60
+	const Syswait4			: scno = 61
+	const Syskill			: scno = 62
+	const Sysuname			: scno = 63
+	const Syssemget			: scno = 64
+	const Syssemop			: scno = 65
+	const Syssemctl			: scno = 66
+	const Sysshmdt			: scno = 67
+	const Sysmsgget			: scno = 68
+	const Sysmsgsnd			: scno = 69
+	const Sysmsgrcv			: scno = 70
+	const Sysmsgctl			: scno = 71
+	const Sysfcntl			: scno = 72
+	const Sysflock			: scno = 73
+	const Sysfsync			: scno = 74
+	const Sysfdatasync		: scno = 75
+	const Systruncate		: scno = 76
+	const Sysftruncate		: scno = 77
+	const Sysgetdents		: scno = 78
+	const Sysgetcwd			: scno = 79
+	const Syschdir			: scno = 80
+	const Sysfchdir			: scno = 81
+	const Sysrename			: scno = 82
+	const Sysmkdir			: scno = 83
+	const Sysrmdir			: scno = 84
+	const Syscreat			: scno = 85
+	const Syslink			: scno = 86
+	const Sysunlink			: scno = 87
+	const Syssymlink		: scno = 88
+	const Sysreadlink		: scno = 89
+	const Syschmod			: scno = 90
+	const Sysfchmod			: scno = 91
+	const Syschown			: scno = 92
+	const Sysfchown			: scno = 93
+	const Syslchown			: scno = 94
+	const Sysumask			: scno = 95
+	const Sysgettimeofday		: scno = 96
+	const Sysgetrlimit		: scno = 97
+	const Sysgetrusage		: scno = 98
+	const Syssysinfo		: scno = 99
+	const Systimes			: scno = 100
+	const Sysptrace			: scno = 101
+	const Sysgetuid			: scno = 102
+	const Syssyslog			: scno = 103
+	const Sysgetgid			: scno = 104
+	const Syssetuid			: scno = 105
+	const Syssetgid			: scno = 106
+	const Sysgeteuid		: scno = 107
+	const Sysgetegid		: scno = 108
+	const Syssetpgid		: scno = 109
+	const Sysgetppid		: scno = 110
+	const Sysgetpgrp		: scno = 111
+	const Syssetsid			: scno = 112
+	const Syssetreuid		: scno = 113
+	const Syssetregid		: scno = 114
+	const Sysgetgroups		: scno = 115
+	const Syssetgroups		: scno = 116
+	const Syssetresuid		: scno = 117
+	const Sysgetresuid		: scno = 118
+	const Syssetresgid		: scno = 119
+	const Sysgetresgid		: scno = 120
+	const Sysgetpgid		: scno = 121
+	const Syssetfsuid		: scno = 122
+	const Syssetfsgid		: scno = 123
+	const Sysgetsid			: scno = 124
+	const Syscapget			: scno = 125
+	const Syscapset			: scno = 126
+	const Sysrt_sigpending		: scno = 127
+	const Sysrt_sigtimedwait	: scno = 128
+	const Sysrt_sigqueueinfo	: scno = 129
+	const Sysrt_sigsuspend		: scno = 130
+	const Syssigaltstack		: scno = 131
+	const Sysutime			: scno = 132
+	const Sysmknod			: scno = 133
+	const Sysuselib			: scno = 134
+	const Syspersonality		: scno = 135
+	const Sysustat			: scno = 136
+	const Sysstatfs			: scno = 137
+	const Sysfstatfs		: scno = 138
+	const Syssysfs			: scno = 139
+	const Sysgetpriority		: scno = 140
+	const Syssetpriority		: scno = 141
+	const Syssched_setparam		: scno = 142
+	const Syssched_getparam		: scno = 143
+	const Syssched_setscheduler	: scno = 144
+	const Syssched_getscheduler	: scno = 145
+	const Syssched_get_priority_max	: scno = 146
+	const Syssched_get_priority_min	: scno = 147
+	const Syssched_rr_get_interval	: scno = 148
+	const Sysmlock			: scno = 149
+	const Sysmunlock		: scno = 150
+	const Sysmlockall		: scno = 151
+	const Sysmunlockall		: scno = 152
+	const Sysvhangup		: scno = 153
+	const Sysmodify_ldt		: scno = 154
+	const Syspivot_root		: scno = 155
+	const Sys_sysctl		: scno = 156
+	const Sysprctl			: scno = 157
+	const Sysarch_prctl		: scno = 158
+	const Sysadjtimex		: scno = 159
+	const Syssetrlimit		: scno = 160
+	const Syschroot			: scno = 161
+	const Syssync			: scno = 162
+	const Sysacct			: scno = 163
+	const Syssettimeofday		: scno = 164
+	const Sysmount			: scno = 165
+	const Sysumount2		: scno = 166
+	const Sysswapon			: scno = 167
+	const Sysswapoff		: scno = 168
+	const Sysreboot			: scno = 169
+	const Syssethostname		: scno = 170
+	const Syssetdomainname		: scno = 171
+	const Sysiopl			: scno = 172
+	const Sysioperm			: scno = 173
+	const Syscreate_module		: scno = 174
+	const Sysinit_module		: scno = 175
+	const Sysdelete_module		: scno = 176
+	const Sysget_kernel_syms	: scno = 177
+	const Sysquery_module		: scno = 178
+	const Sysquotactl		: scno = 179
+	const Sysnfsservctl		: scno = 180
+	const Sysgetpmsg		: scno = 181
+	const Sysputpmsg		: scno = 182
+	const Sysafs_syscall		: scno = 183
+	const Systuxcall		: scno = 184
+	const Syssecurity		: scno = 185
+	const Sysgettid			: scno = 186
+	const Sysreadahead		: scno = 187
+	const Syssetxattr		: scno = 188
+	const Syslsetxattr		: scno = 189
+	const Sysfsetxattr		: scno = 190
+	const Sysgetxattr		: scno = 191
+	const Syslgetxattr		: scno = 192
+	const Sysfgetxattr		: scno = 193
+	const Syslistxattr		: scno = 194
+	const Sysllistxattr		: scno = 195
+	const Sysflistxattr		: scno = 196
+	const Sysremovexattr		: scno = 197
+	const Syslremovexattr		: scno = 198
+	const Sysfremovexattr		: scno = 199
+	const Systkill			: scno = 200
+	const Systime			: scno = 201
+	const Sysfutex			: scno = 202
+	const Syssched_setaffinity	: scno = 203
+	const Syssched_getaffinity	: scno = 204
+	const Sysset_thread_area	: scno = 205
+	const Sysio_setup		: scno = 206
+	const Sysio_destroy		: scno = 207
+	const Sysio_getevents		: scno = 208
+	const Sysio_submit		: scno = 209
+	const Sysio_cancel		: scno = 210
+	const Sysget_thread_area	: scno = 211
+	const Syslookup_dcookie		: scno = 212
+	const Sysepoll_create		: scno = 213
+	const Sysepoll_ctl_old		: scno = 214
+	const Sysepoll_wait_old		: scno = 215
+	const Sysremap_file_pages	: scno = 216
+	const Sysgetdents64		: scno = 217
+	const Sysset_tid_address	: scno = 218
+	const Sysrestart_syscall	: scno = 219
+	const Syssemtimedop		: scno = 220
+	const Sysfadvise64		: scno = 221
+	const Systimer_create		: scno = 222
+	const Systimer_settime		: scno = 223
+	const Systimer_gettime		: scno = 224
+	const Systimer_getoverrun	: scno = 225
+	const Systimer_delete		: scno = 226
+	const Sysclock_settime		: scno = 227
+	const Sysclock_gettime		: scno = 228
+	const Sysclock_getres		: scno = 229
+	const Sysclock_nanosleep	: scno = 230
+	const Sysexit_group		: scno = 231
+	const Sysepoll_wait		: scno = 232
+	const Sysepoll_ctl		: scno = 233
+	const Systgkill			: scno = 234
+	const Sysutimes			: scno = 235
+	const Sysvserver		: scno = 236
+	const Sysmbind			: scno = 237
+	const Sysset_mempolicy		: scno = 238
+	const Sysget_mempolicy		: scno = 239
+	const Sysmq_open		: scno = 240
+	const Sysmq_unlink		: scno = 241
+	const Sysmq_timedsend		: scno = 242
+	const Sysmq_timedreceive	: scno = 243
+	const Sysmq_notify		: scno = 244
+	const Sysmq_getsetattr		: scno = 245
+	const Syskexec_load		: scno = 246
+	const Syswaitid			: scno = 247
+	const Sysadd_key		: scno = 248
+	const Sysrequest_key		: scno = 249
+	const Syskeyctl			: scno = 250
+	const Sysioprio_set		: scno = 251
+	const Sysioprio_get		: scno = 252
+	const Sysinotify_init		: scno = 253
+	const Sysinotify_add_watch	: scno = 254
+	const Sysinotify_rm_watch	: scno = 255
+	const Sysmigrate_pages		: scno = 256
+	const Sysopenat			: scno = 257
+	const Sysmkdirat		: scno = 258
+	const Sysmknodat		: scno = 259
+	const Sysfchownat		: scno = 260
+	const Sysfutimesat		: scno = 261
+	const Sysnewfstatat		: scno = 262
+	const Sysunlinkat		: scno = 263
+	const Sysrenameat		: scno = 264
+	const Syslinkat			: scno = 265
+	const Syssymlinkat		: scno = 266
+	const Sysreadlinkat		: scno = 267
+	const Sysfchmodat		: scno = 268
+	const Sysfaccessat		: scno = 269
+	const Syspselect6		: scno = 270
+	const Sysppoll			: scno = 271
+	const Sysunshare		: scno = 272
+	const Sysset_robust_list	: scno = 273
+	const Sysget_robust_list	: scno = 274
+	const Syssplice			: scno = 275
+	const Systee			: scno = 276
+	const Syssync_file_range	: scno = 277
+	const Sysvmsplice		: scno = 278
+	const Sysmove_pages		: scno = 279
+	const Sysutimensat		: scno = 280
+	const Sysepoll_pwait		: scno = 281
+	const Syssignalfd		: scno = 282
+	const Systimerfd_create		: scno = 283
+	const Syseventfd		: scno = 284
+	const Sysfallocate		: scno = 285
+	const Systimerfd_settime	: scno = 286
+	const Systimerfd_gettime	: scno = 287
+	const Sysaccept4		: scno = 288
+	const Syssignalfd4		: scno = 289
+	const Syseventfd2		: scno = 290
+	const Sysepoll_create1		: scno = 291
+	const Sysdup3			: scno = 292
+	const Syspipe2			: scno = 293
+	const Sysinotify_init1		: scno = 294
+	const Syspreadv			: scno = 295
+	const Syspwritev		: scno = 296
+	const Sysrt_tgsigqueueinfo	: scno = 297
+	const Sysperf_event_open	: scno = 298
+	const Sysrecvmmsg		: scno = 299
+	const Sysfanotify_init		: scno = 300
+	const Sysfanotify_mark		: scno = 301
+	const Sysprlimit64		: scno = 302
+	const Sysname_to_handle_at	: scno = 303
+	const Sysopen_by_handle_at	: scno = 304
+	const Sysclock_adjtime		: scno = 305
+	const Syssyncfs			: scno = 306
+	const Syssendmmsg		: scno = 307
+	const Syssetns			: scno = 308
+	const Sysgetcpu			: scno = 309
+	const Sysprocess_vm_readv	: scno = 310
+	const Sysprocess_vm_writev	: scno = 311
+
+	/* getting to the os */
+	extern const syscall	: (sc:scno, args:... -> int64)
+
+	/* process management */
+	const exit	: (status:int -> void)
+	const exit_group	: (status:int -> void)
+	const getpid	: ( -> pid)
+	const kill	: (pid:pid, sig:int64 -> int64)
+	const fork	: (-> pid)
+	/* FIXME: where the fuck is 'struct pt_reg' defined?? */
+	const clone	: (flags : cloneopt, stk : byte#, ptid : pid#, ctid : pid#, ptreg : byte# -> pid)
+	const wait4	: (pid:pid, loc:int32#, opt : int64, usage:rusage#	-> int64)
+	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
+
+	/* file manipulation */
+	const open	: (path:byte[:], opts:fdopt -> fd)
+	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
+	const close	: (fd:fd -> int64)
+	const creat	: (path:byte[:], mode:int64 -> fd)
+	const unlink	: (path:byte[:] -> int)
+	const read	: (fd:fd, buf:byte[:] -> size)
+	const write	: (fd:fd, buf:byte[:] -> size)
+	const lseek	: (fd:fd, off:off, whence:whence -> int64)
+	const stat	: (path:byte[:], sb:statbuf# -> int64)
+	const lstat	: (path:byte[:], sb:statbuf# -> int64)
+	const fstat	: (fd:fd, sb:statbuf# -> int64)
+	const mkdir	: (path : byte[:], mode : int64	-> int64)
+	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
+	const getdents64	: (fd:fd, buf : byte[:] -> int64)
+	const chdir	: (p : byte[:] -> int64)
+	const getcwd	: (buf : byte[:] -> int64)
+
+	/* fd stuff */
+	const pipe	: (fds : fd[2]# -> int64)
+	const dup	: (fd : fd -> fd)
+	const dup2	: (src : fd, dst : fd -> fd)
+
+	/* threading */
+	const futex	: (uaddr : int32#, op : int32, val : int32, \
+		ts : timespec#, uaddr2 : int#, val3 : int# -> int64)
+
+	/* polling */
+	const epollcreate	: (flg : epollflags	-> fd)	/* actually epoll_create1 */
+	const epollctl	: (epfd : fd, op : int, fd : fd, evt : epollevt# -> int)
+	const epollwait	: (epfd : fd, evts : epollevt[:], timeout : int -> int)
+	const poll	: (pfd	: pollfd[:], timeout : int	-> int)
+
+	/* networking */
+	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
+	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
+	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
+	const listen	: (sock : fd, backlog : int	-> int)
+	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
+
+	/* memory mapping */
+	const munmap	: (addr:byte#, len:size -> int64)
+	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
+
+	/* time */
+	const clock_getres	: (clk : clock, ts : timespec# -> int32)
+	const clock_gettime	: (clk : clock, ts : timespec# -> int32)
+	const clock_settime	: (clk : clock, ts : timespec# -> int32)
+	const sleep	: (time : uint64 -> int32)
+	const nanosleep	: (req : timespec#, rem : timespec# -> int32)
+
+	/* system information */
+	const uname 	: (buf : utsname# -> int)
+
+	/* exported values: initialized by start code */
+	extern const __environment : byte[:][:]
+	extern const __cenvp : byte##
+;;
+
+/* 
+wraps a syscall argument, converting it to 64 bits for the syscall function.
+This is the same as casting, but more concise than writing castto(int64).
+*/
+generic a = {x : @t; -> x castto(uint64)}
+
+/* asm stubs from util.s */
+extern const cstring	: (str : byte[:] -> byte#)
+extern const alloca	: (sz : size	-> byte#)
+
+/* process management */
+const exit	= {status;		syscall(Sysexit, a(status))}
+const exit_group	= {status;	syscall(Sysexit_group, a(status))}
+const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
+const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
+const fork	= {;			-> syscall(Sysfork) castto(pid)}
+const clone	= {flags, stk, ptid, ctid, ptreg;	-> syscall(Sysclone, a(flags), a(stk), a(ptid), a(ctid), a(ptreg)) castto(pid)}
+const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(usage))}
+const waitpid	= {pid, loc, opt;
+	var rusage
+	-> wait4(pid, loc, opt, &rusage)
+}
+
+const execv	= {cmd, args
+	var p, cargs, i
+
+	/* of course we fucking have to duplicate this code everywhere,
+	* since we want to stack allocate... */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len + 1]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
+}
+
+const execve	= {cmd, args, env
+	var cargs, cenv, i
+	var p
+
+	/* copy the args */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len + 1]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+
+	/*
+	 copy the env.
+	 of course we fucking have to duplicate this code everywhere,
+	 since we want to stack allocate... 
+	*/
+	p = alloca((env.len + 1)*sizeof(byte#))
+	cenv = (p castto(byte##))[:env.len]
+	for i = 0; i < env.len; i++
+		cenv[i] = cstring(env[i])
+	;;
+	cenv[env.len] = 0 castto(byte#)
+
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
+}
+
+/* file manipulation */
+const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
+const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const close	= {fd;			-> syscall(Sysclose, a(fd))}
+const creat	= {path, mode;		-> syscall(Syscreat, cstring(path), a(mode)) castto(fd)}
+const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
+const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
+const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
+const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
+const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
+const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
+generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
+const getdents64	= {fd, buf;	-> syscall(Sysgetdents64, a(fd), buf castto(byte#), a(buf.len))}
+const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
+const getcwd	= {buf;	-> syscall(Sysgetcwd, a(buf), a(buf.len))}
+
+/* file stuff */
+const pipe	= {fds;	-> syscall(Syspipe, a(fds))}
+const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
+const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+
+/* threading */
+const futex	= {uaddr, op, val, timeout, uaddr2, val3
+	-> syscall(Sysfutex, a(uaddr), a(op), a(val), a(timeout), a(uaddr2), a(val3))}
+
+/* poll */
+const poll	= {pfd, timeout;	-> syscall(Syspoll, pfd castto(pollfd#), a(pfd.len), a(timeout)) castto(int)}
+const epollctl	= {epfd, op, fd, evt;
+	-> syscall(Sysepoll_ctl, a(epfd), a(op), a(fd), a(evt)) castto(int)}
+const epollwait	= {epfd, evts, timeout;
+	-> syscall(Sysepoll_wait, a(epfd), evts castto(epollevt#), a(evts.len), a(timeout)) castto(int)}
+const epollcreate	= {flg;	-> syscall(Sysepoll_create1, a(flg)) castto(fd)}
+
+/* networking */
+const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd)}
+const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
+const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
+const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
+const accept	= {sock, addr, lenp;	-> syscall(Sysaccept, a(sock), a(addr), a(lenp)) castto(fd)}
+
+/* memory mapping */
+const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
+const mmap	= {addr, len, prot, flags, fd, off;
+	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)
+}
+
+/* time */
+const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
+const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
+const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
+
+const sleep = {time
+	var req, rem
+	req = [.sec = time, .nsec = 0]
+	-> nanosleep(&req, &rem)
+}
+
+const nanosleep	= {req, rem;	-> syscall(Sysnanosleep, a(req), a(rem)) castto(int32)}
+
+/* system information */
+const uname	= {buf;	-> syscall(Sysuname, buf) castto(int)}
+
+const clockid = {clk
+	match clk
+	| `Clockrealtime:	-> 0
+	| `Clockmonotonic:	-> 1
+	| `Clockproccpu:	-> 2
+	| `Clockthreadcpu:	-> 3
+	| `Clockmonotonicraw:	-> 4
+	| `Clockrealtimecoarse:	-> 5
+	| `Clockmonotoniccoarse:-> 6
+	| `Clockboottime:	-> 7
+	| `Clockrealtimealarm:	-> 8
+	| `Clockboottimealarm:	-> 9
+	;;
+	-> -1
+}
+
+
+const waitstatus = {st
+	if st & 0x7f == 0 /* if exited */
+		-> `Waitexit ((st & 0xff00) >> 8)
+	elif ((st & 0xffff)-1) < 0xff /* if signaled */
+		-> `Waitsig ((st) & 0x7f)
+	elif (((st & 0xffff)*0x10001)>>8) > 0x7f00
+		-> `Waitstop ((st & 0xff00) >> 8)
+	;;
+	-> `Waitfail st	/* wait failed to give a result */
+}
--- /dev/null
+++ b/lib/std/sys+osx-x64.myr
@@ -1,0 +1,947 @@
+use "systypes.use"
+
+pkg sys =
+	type scno 	= int64	/* syscall */
+	type fdopt	= int64	/* fd options */
+	type fd		= int32	/* fd */
+	type pid	= int64	/* pid */
+	type mprot	= int64	/* memory protection */
+	type mopt	= int64	/* memory mapping options */
+	type socktype	= int64	/* socket type */
+	type sockproto	= int64	/* socket protocol */
+	type sockfam	= uint8	/* socket family */
+	type filemode	= uint16	/* file permission bits */
+	type kflags	= uint16	/* kqueue flags */
+	type whence	= int64
+	type fcntlcmd	= int64
+
+	type timespec = struct
+		sec	: uint64
+		nsec	: uint32
+	;;
+
+	type timeval = struct
+		sec	: uint64
+		usec	: uint32
+	;;
+
+	type timezone = struct
+		minwest	: int32 /* of greenwich */
+		dsttime	: int32	/* nonzero if DST applies */
+	;;
+
+	type clock = union
+		`Clockrealtime
+		`Clockmonotonic
+	;;
+
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+		`Waitfail int32
+	;;
+
+	type statbuf = struct
+		dev	: int32
+		mode	: filemode
+		nlink	: uint16
+		ino	: uint64
+		uid	: uint32
+		gid	: uint32
+		rdev	: uint32
+		atime	: timespec
+		mtime	: timespec
+		ctime	: timespec
+		birthtimespec	: timespec
+		size	: off
+		blocks	: int64
+		blksize	: int32
+		flags	: uint32
+		gen	: uint32
+		_spare	: uint32
+		_qspare	: uint64[2]
+	;;
+
+	type rusage = struct
+		utime	: timeval	/* user time */
+		stime	: timeval	/* system time */
+		_opaque	: uint64[14]	/* padding (darwin-specific data) */
+	;;
+
+	type utsname = struct
+		system	: byte[256]
+		node	: byte[256]
+		release	: byte[256]
+		version	: byte[256]
+		machine	: byte[256]
+	;;
+
+	type sockaddr = struct
+		len	: byte
+		fam	: sockfam
+		data	: byte[14] /* what is the *actual* length? */
+	;;
+
+	type sockaddr_in = struct
+		len	: byte
+		fam	: sockfam
+		port	: uint16
+		addr	: byte[4]
+		zero	: byte[8]
+	;;
+
+	type sockaddr_in6 = struct
+		len	: byte
+		fam	: sockfam
+		port	: uint16
+		flowinf	: uint32
+		addr	: byte[16]
+		scope	: uint32
+	;;
+
+
+	type sockaddr_storage = struct
+		len	: byte
+		fam	: sockfam
+		__pad1	: byte[6]
+		__align	: uint64
+		__pad2	: byte[112]
+	;;
+
+	type dirent64 = struct
+		ino	: uint64
+		seekoff	: uint64	/* seek offset (optional, used by servers) */
+		reclen	: uint16	/* length of this record */
+		namlen	: uint16	/* length of string in d_name */
+		typeid  : uint8		/* file type, see below */
+		name	: byte[...]
+	;;
+
+	type kevent = struct
+		ident	: intptr	/* identifier for this event */
+		filter	: int16		/* filter for event */
+		flags	: uint16	/* general flags */
+		fflags	: uint32	/* filter-specific flags */
+		data	: intptr	/* filter-specific data */
+		udata	: byte#		/* opaque user data identifier */
+	;;
+
+	type kevent64 = struct
+		ident	: uint64	/* identifier for this event */
+		filter	: int16		/* filter for event */
+		flags	: kflags	/* general flags */
+		fflags	: uint32	/* filter-specific flags */
+		data	: int64		/* filter-specific data */
+		udata	: uint64	/* opaque user data identifier */
+		ext	: uint64[2]	/* filter-specific extensions */
+	;;
+
+	const Seekset	: whence = 0
+	const Seekcur	: whence = 1
+	const Seekend	: whence = 2
+
+	/* system specific constants */
+	const Maxpathlen	: size = 1024
+
+	/* fcntl constants */
+	const Fdupfd		: fcntlcmd = 0		       /* duplicate file descriptor */
+	const Fgetfd		: fcntlcmd = 1		       /* get file descriptor flags */
+	const Fsetfd		: fcntlcmd = 2		       /* set file descriptor flags */
+	const Fgetfl		: fcntlcmd = 3		       /* get file status flags */
+	const Fsetfl		: fcntlcmd = 4		       /* set file status flags */
+	const Fgetown		: fcntlcmd = 5		       /* get SIGIO/SIGURG proc/pgrp */
+	const Fsetown		: fcntlcmd = 6		       /* set SIGIO/SIGURG proc/pgrp */
+	const Fgetlk		: fcntlcmd = 7		       /* get record locking information */
+	const Fsetlk		: fcntlcmd = 8		       /* set record locking information */
+	const Fsetlkw		: fcntlcmd = 9		       /* F_SETLK; wait if blocked */
+	const Fsetlkwtimeout	: fcntlcmd = 10			/* F_SETLK; wait if blocked, return on timeout */
+	const Fflush_data	: fcntlcmd = 40
+	const Fchkclean		: fcntlcmd = 41			/* Used for regression test */
+	const Fpreallocate	: fcntlcmd = 42			/* Preallocate storage */
+	const Fsetsize		: fcntlcmd = 43			/* Truncate a file without zeroing space */
+	const Frdadvise		: fcntlcmd = 44			/* Issue an advisory read async with no copy to user */
+	const Frdahead		: fcntlcmd = 45			/* turn read ahead off/on for this fd */
+	/* 46,47 used to be F_READBOOTSTRAP and F_WRITEBOOTSTRAP */
+	const Fnocache		: fcntlcmd = 48			/* turn data caching off/on for this fd */
+	const Flog2phys		: fcntlcmd = 49			/* file offset to device offset */
+	const Fgetpath		: fcntlcmd = 50			/* return the full path of the fd */
+	const Ffullfsync	: fcntlcmd = 51			/* fsync + ask the drive to flush to the media */
+	const Fpathpkg_check 	: fcntlcmd = 52			/* find which component (if any) is a package */
+	const Ffreeze_fs	: fcntlcmd = 53			/* "freeze" all fs operations */
+	const Fthaw_fs		: fcntlcmd = 54			/* "thaw" all fs operations */
+	const Fglobal_nocache	: fcntlcmd = 55			/* turn data caching off/on (globally) for this file */
+	const Faddsigs		: fcntlcmd = 59			/* add detached signatures */
+	const Faddfilesigs	: fcntlcmd = 61			/* add signature from same file (used by dyld for shared libs) */
+	const Fgetprotclass	: fcntlcmd = 63			/* Get the protection class of a file from the EA, returns int */
+	const Fsetprotclass	: fcntlcmd = 64			/* Set the protection class of a file for the EA, requires int */
+	const Flog2phys_ext	: fcntlcmd = 65			/* file offset to device offset, extended */
+	const Fgetlkpid		: fcntlcmd = 66			/* get record locking information, per-process */
+	/* See F_DUPFD_CLOEXEC below for 67 */
+	const Fsetbacktore	: fcntlcmd = 70			/* Mark the file as being the backing store for another filesystem */
+	const Fgetpath_mtminfo	: fcntlcmd = 71			/* return the full path of the FD, but error in specific mtmd circumstances */
+	/* 72 is free.	It used to be F_GETENCRYPTEDDATA, which is now removed. */
+	const Fsetnosigpipe	: fcntlcmd = 73			/* No SIGPIPE generated on EPIPE */
+	const Fgetnosigpipe	: fcntlcmd = 74			/* Status of SIGPIPE for this fd */
+
+	/* kqueue events */
+	const Kevadd		: kflags = 0x0001	/* add event to kq (implies enable) */
+	const Kevdelete		: kflags = 0x0002	/* delete event from kq */
+	const Kevenable		: kflags = 0x0004	/* enable event */
+	const Kevdisable	: kflags = 0x0008	/* disable event (not reported) */
+	const Kevreceipt	: kflags = 0x0040	/* force EV_ERROR on success, data == 0 */
+
+	/* kqueue flags */
+	const Kevoneshot	: kflags = 0x0010	/* only report one occurrence */
+	const Kevclear		: kflags = 0x0020	/* clear event state after reporting */
+	const Kevdispatch	: kflags = 0x0080	/* disable event after reporting */
+
+	const Kevsysflags	: kflags = 0xf000	/* reserved by system */
+	const Kevflag0		: kflags = 0x1000	/* filter-specific flag */
+	const Kevflag1		: kflags = 0x2000	/* filter-specific flag */
+
+	/* kqueue returned values */
+	const Keveof		: kflags = 0x8000	/* eof detected */
+	const Keverror		: kflags = 0x4000	/* error, data contains errno */
+
+	/* open options */
+	const Ordonly  	: fdopt = 0x0
+	const Owronly  	: fdopt = 0x1
+	const Ordwr    	: fdopt = 0x2
+	const Ondelay  	: fdopt = 0x4
+	const Oappend  	: fdopt = 0x8
+	const Ocreat   	: fdopt = 0x200
+	const Onofollow	: fdopt = 0x100
+	const Otrunc   	: fdopt = 0x400
+	const Odir	: fdopt = 0x100000
+
+	/* stat modes */
+	const Sifmt	: filemode = 0xf000
+	const Sififo	: filemode = 0x1000
+	const Sifchr	: filemode = 0x2000
+	const Sifdir	: filemode = 0x4000
+	const Sifblk	: filemode = 0x6000
+	const Sifreg	: filemode = 0x8000
+	const Siflnk	: filemode = 0xa000
+	const Sifsock	: filemode = 0xc000
+
+	/* mmap protection */
+	const Mprotnone	: mprot = 0x0
+	const Mprotrd	: mprot = 0x1
+	const Mprotwr	: mprot = 0x2
+	const Mprotexec	: mprot = 0x4
+	const Mprotrw	: mprot = 0x3
+
+	/* mmap options */
+	const Mshared	: mopt = 0x1
+	const Mpriv	: mopt = 0x2
+	const Mfixed	: mopt = 0x10
+	const Mfile	: mopt = 0x0
+	const Manon	: mopt = 0x1000
+	/* Only on Linux
+	const M32bit	: mopt = 0x40
+	*/
+
+	/* socket families. INCOMPLETE. */
+	const Afunspec	: sockfam = 0
+	const Afunix	: sockfam = 1
+	const Afinet	: sockfam = 2
+	const Afinet6	: sockfam = 30
+
+	/* socket types. */
+	const Sockstream	: socktype = 1
+	const Sockdgram		: socktype = 2
+	const Sockraw		: socktype = 3
+	const Sockrdm		: socktype = 4
+	const Sockseqpacket	: socktype = 5
+
+	/* network protocols */
+	const Ipproto_ip	: sockproto = 0
+	const Ipproto_icmp	: sockproto = 1
+	const Ipproto_tcp	: sockproto = 6
+	const Ipproto_udp	: sockproto = 17
+	const Ipproto_raw	: sockproto = 255
+
+	/* return value for a failed mapping */
+	const Mapbad	: byte# = -1 castto(byte#)
+
+	/* syscalls.
+	note, creat() implemented as open(path, Creat|Trunc|Wronly) */
+	const Syssyscall	: scno = 0x2000000
+	const Sysexit		: scno = 0x2000001
+	const Sysfork		: scno = 0x2000002
+	const Sysread		: scno = 0x2000003
+	const Syswrite		: scno = 0x2000004
+	const Sysopen		: scno = 0x2000005
+	const Sysclose		: scno = 0x2000006
+	const Syswait4		: scno = 0x2000007
+	const Syslink		: scno = 0x2000009
+	const Sysunlink		: scno = 0x200000a
+	const Syschdir		: scno = 0x200000c
+	const Sysfchdir		: scno = 0x200000d
+	const Sysmknod		: scno = 0x200000e
+	const Syschmod		: scno = 0x200000f
+	const Syschown		: scno = 0x2000010
+	const Sysgetfsstat	: scno = 0x2000012
+	const Sysgetpid		: scno = 0x2000014
+	const Syssetuid		: scno = 0x2000017
+	const Sysgetuid		: scno = 0x2000018
+	const Sysgeteuid	: scno = 0x2000019
+	const Sysptrace		: scno = 0x200001a
+	const Sysrecvmsg	: scno = 0x200001b
+	const Syssendmsg	: scno = 0x200001c
+	const Sysrecvfrom	: scno = 0x200001d
+	const Sysaccept		: scno = 0x200001e
+	const Sysgetpeername	: scno = 0x200001f
+	const Sysgetsockname	: scno = 0x2000020
+	const Sysaccess		: scno = 0x2000021
+	const Syschflags	: scno = 0x2000022
+	const Sysfchflags	: scno = 0x2000023
+	const Syssync		: scno = 0x2000024
+	const Syskill		: scno = 0x2000025
+	const Sysgetppid	: scno = 0x2000027
+	const Sysdup		: scno = 0x2000029
+	const Syspipe		: scno = 0x200002a
+	const Sysgetegid	: scno = 0x200002b
+	const Sysprofil		: scno = 0x200002c
+	const Syssigaction	: scno = 0x200002e
+	const Sysgetgid		: scno = 0x200002f
+	const Syssigprocmask	: scno = 0x2000030
+	const Sysgetlogin	: scno = 0x2000031
+	const Syssetlogin	: scno = 0x2000032
+	const Sysacct		: scno = 0x2000033
+	const Syssigpending	: scno = 0x2000034
+	const Syssigaltstack	: scno = 0x2000035
+	const Sysioctl		: scno = 0x2000036
+	const Sysreboot		: scno = 0x2000037
+	const Sysrevoke		: scno = 0x2000038
+	const Syssymlink	: scno = 0x2000039
+	const Sysreadlink	: scno = 0x200003a
+	const Sysexecve		: scno = 0x200003b
+	const Sysumask		: scno = 0x200003c
+	const Syschroot		: scno = 0x200003d
+	const Sysmsync		: scno = 0x2000041
+	const Sysvfork		: scno = 0x2000042
+	const Sysmunmap		: scno = 0x2000049
+	const Sysmprotect	: scno = 0x200004a
+	const Sysmadvise	: scno = 0x200004b
+	const Sysmincore	: scno = 0x200004e
+	const Sysgetgroups	: scno = 0x200004f
+	const Syssetgroups	: scno = 0x2000050
+	const Sysgetpgrp	: scno = 0x2000051
+	const Syssetpgid	: scno = 0x2000052
+	const Syssetitimer	: scno = 0x2000053
+	const Sysswapon		: scno = 0x2000055
+	const Sysgetitimer	: scno = 0x2000056
+	const Sysgetdtablesize	: scno = 0x2000059
+	const Sysdup2		: scno = 0x200005a
+	const Sysfcntl		: scno = 0x200005c
+	const Sysselect		: scno = 0x200005d
+	const Sysfsync		: scno = 0x200005f
+	const Syssetpriority	: scno = 0x2000060
+	const Syssocket		: scno = 0x2000061
+	const Sysconnect	: scno = 0x2000062
+	const Sysgetpriority	: scno = 0x2000064
+	const Sysbind		: scno = 0x2000068
+	const Syssetsockopt	: scno = 0x2000069
+	const Syslisten		: scno = 0x200006a
+	const Syssigsuspend	: scno = 0x200006f
+	const Sysgettimeofday	: scno = 0x2000074
+	const Sysgetrusage	: scno = 0x2000075
+	const Sysgetsockopt	: scno = 0x2000076
+	const Sysreadv		: scno = 0x2000078
+	const Syswritev		: scno = 0x2000079
+	const Syssettimeofday	: scno = 0x200007a
+	const Sysfchown		: scno = 0x200007b
+	const Sysfchmod		: scno = 0x200007c
+	const Syssetreuid	: scno = 0x200007e
+	const Syssetregid	: scno = 0x200007f
+	const Sysrename		: scno = 0x2000080
+	const Sysflock		: scno = 0x2000083
+	const Sysmkfifo		: scno = 0x2000084
+	const Syssendto		: scno = 0x2000085
+	const Sysshutdown	: scno = 0x2000086
+	const Syssocketpair	: scno = 0x2000087
+	const Sysmkdir		: scno = 0x2000088
+	const Sysrmdir		: scno = 0x2000089
+	const Sysutimes		: scno = 0x200008a
+	const Sysfutimes	: scno = 0x200008b
+	const Sysadjtime	: scno = 0x200008c
+	const Sysgethostuuid	: scno = 0x200008e
+	const Syssetsid		: scno = 0x2000093
+	const Sysgetpgid	: scno = 0x2000097
+	const Syssetprivexec	: scno = 0x2000098
+	const Syspread		: scno = 0x2000099
+	const Syspwrite		: scno = 0x200009a
+	const Sysnfssvc		: scno = 0x200009b
+	const Sysstatfs		: scno = 0x200009d
+	const Sysfstatfs	: scno = 0x200009e
+	const Sysunmount	: scno = 0x200009f
+	const Sysgetfh		: scno = 0x20000a1
+	const Sysquotactl	: scno = 0x20000a5
+	const Sysmount		: scno = 0x20000a7
+	const Syscsops		: scno = 0x20000a9
+	const Syswaitid		: scno = 0x20000ad
+	const Sysadd_profil	: scno = 0x20000b0
+	const Syskdebug_trace	: scno = 0x20000b4
+	const Syssetgid		: scno = 0x20000b5
+	const Syssetegid	: scno = 0x20000b6
+	const Sysseteuid	: scno = 0x20000b7
+	const Syssigreturn	: scno = 0x20000b8
+	const Syschud		: scno = 0x20000b9
+	const Sysfdatasync	: scno = 0x20000bb
+	const Sysstat		: scno = 0x20000bc
+	const Sysfstat		: scno = 0x20000bd
+	const Syslstat		: scno = 0x20000be
+	const Syspathconf	: scno = 0x20000bf
+	const Sysfpathconf	: scno = 0x20000c0
+	const Sysgetrlimit	: scno = 0x20000c2
+	const Syssetrlimit	: scno = 0x20000c3
+	const Sysgetdirentries	: scno = 0x20000c4
+	const Sysmmap		: scno = 0x20000c5
+	const Syslseek		: scno = 0x20000c7
+	const Systruncate	: scno = 0x20000c8
+	const Sysftruncate	: scno = 0x20000c9
+	const Sys__sysctl	: scno = 0x20000ca
+	const Sysmlock		: scno = 0x20000cb
+	const Sysmunlock	: scno = 0x20000cc
+	const Sysundelete	: scno = 0x20000cd
+	const SysATsocket	: scno = 0x20000ce
+	const SysATgetmsg	: scno = 0x20000cf
+	const SysATputmsg	: scno = 0x20000d0
+	const SysATPsndreq	: scno = 0x20000d1
+	const SysATPsndrsp	: scno = 0x20000d2
+	const SysATPgetreq	: scno = 0x20000d3
+	const SysATPgetrsp	: scno = 0x20000d4
+	const Sysmkcomplex	: scno = 0x20000d8
+	const Sysstatv		: scno = 0x20000d9
+	const Syslstatv		: scno = 0x20000da
+	const Sysfstatv		: scno = 0x20000db
+	const Sysgetattrlist	: scno = 0x20000dc
+	const Syssetattrlist	: scno = 0x20000dd
+	const Sysgetdirentriesattr	: scno = 0x20000de
+	const Sysexchangedata	: scno = 0x20000df
+	const Syssearchfs	: scno = 0x20000e1
+	const Sysdelete		: scno = 0x20000e2
+	const Syscopyfile	: scno = 0x20000e3
+	const Sysfgetattrlist	: scno = 0x20000e4
+	const Sysfsetattrlist	: scno = 0x20000e5
+	const Syspoll		: scno = 0x20000e6
+	const Syswatchevent	: scno = 0x20000e7
+	const Syswaitevent	: scno = 0x20000e8
+	const Sysmodwatch	: scno = 0x20000e9
+	const Sysgetxattr	: scno = 0x20000ea
+	const Sysfgetxattr	: scno = 0x20000eb
+	const Syssetxattr	: scno = 0x20000ec
+	const Sysfsetxattr	: scno = 0x20000ed
+	const Sysremovexattr	: scno = 0x20000ee
+	const Sysfremovexattr	: scno = 0x20000ef
+	const Syslistxattr	: scno = 0x20000f0
+	const Sysflistxattr	: scno = 0x20000f1
+	const Sysfsctl		: scno = 0x20000f2
+	const Sysinitgroups	: scno = 0x20000f3
+	const Sysposix_spawn	: scno = 0x20000f4
+	const Sysffsctl		: scno = 0x20000f5
+	const Sysnfsclnt	: scno = 0x20000f7
+	const Sysfhopen		: scno = 0x20000f8
+	const Sysminherit	: scno = 0x20000fa
+	const Syssemsys		: scno = 0x20000fb
+	const Sysmsgsys		: scno = 0x20000fc
+	const Sysshmsys		: scno = 0x20000fd
+	const Syssemctl		: scno = 0x20000fe
+	const Syssemget		: scno = 0x20000ff
+	const Syssemop		: scno = 0x2000100
+	const Sysmsgctl		: scno = 0x2000102
+	const Sysmsgget		: scno = 0x2000103
+	const Sysmsgsnd		: scno = 0x2000104
+	const Sysmsgrcv		: scno = 0x2000105
+	const Sysshmat		: scno = 0x2000106
+	const Sysshmctl		: scno = 0x2000107
+	const Sysshmdt		: scno = 0x2000108
+	const Sysshmget		: scno = 0x2000109
+	const Sysshm_open	: scno = 0x200010a
+	const Sysshm_unlink	: scno = 0x200010b
+	const Syssem_open	: scno = 0x200010c
+	const Syssem_close	: scno = 0x200010d
+	const Syssem_unlink	: scno = 0x200010e
+	const Syssem_wait	: scno = 0x200010f
+	const Syssem_trywait	: scno = 0x2000110
+	const Syssem_post	: scno = 0x2000111
+	const Syssem_getvalue	: scno = 0x2000112
+	const Syssem_init	: scno = 0x2000113
+	const Syssem_destroy	: scno = 0x2000114
+	const Sysopen_extended	: scno = 0x2000115
+	const Sysumask_extended	: scno = 0x2000116
+	const Sysstat_extended	: scno = 0x2000117
+	const Syslstat_extended	: scno = 0x2000118
+	const Sysfstat_extended	: scno = 0x2000119
+	const Syschmod_extended	: scno = 0x200011a
+	const Sysfchmod_extended	: scno = 0x200011b
+	const Sysaccess_extended	: scno = 0x200011c
+	const Syssettid		: scno = 0x200011d
+	const Sysgettid		: scno = 0x200011e
+	const Syssetsgroups	: scno = 0x200011f
+	const Sysgetsgroups	: scno = 0x2000120
+	const Syssetwgroups	: scno = 0x2000121
+	const Sysgetwgroups	: scno = 0x2000122
+	const Sysmkfifo_extended	: scno = 0x2000123
+	const Sysmkdir_extended	: scno = 0x2000124
+	const Sysidentitysvc	: scno = 0x2000125
+	const Sysshared_region_check_np	: scno = 0x2000126
+	const Sysshared_region_map_np	: scno = 0x2000127
+	const Sysvm_pressure_monitor	: scno = 0x2000128
+	const Syspsynch_rw_longrdlock	: scno = 0x2000129
+	const Syspsynch_rw_yieldwrlock	: scno = 0x200012a
+	const Syspsynch_rw_downgrade	: scno = 0x200012b
+	const Syspsynch_rw_upgrade	: scno = 0x200012c
+	const Syspsynch_mutexwait	: scno = 0x200012d
+	const Syspsynch_mutexdrop	: scno = 0x200012e
+	const Syspsynch_cvbroad	: scno = 0x200012f
+	const Syspsynch_cvsignal	: scno = 0x2000130
+	const Syspsynch_cvwait	: scno = 0x2000131
+	const Syspsynch_rw_rdlock	: scno = 0x2000132
+	const Syspsynch_rw_wrlock	: scno = 0x2000133
+	const Syspsynch_rw_unlock	: scno = 0x2000134
+	const Syspsynch_rw_unlock2	: scno = 0x2000135
+	const Sysgetsid		: scno = 0x2000136
+	const Syssettid_with_pid	: scno = 0x2000137
+	const Sysaio_fsync	: scno = 0x2000139
+	const Sysaio_return	: scno = 0x200013a
+	const Sysaio_suspend	: scno = 0x200013b
+	const Sysaio_cancel	: scno = 0x200013c
+	const Sysaio_error	: scno = 0x200013d
+	const Sysaio_read	: scno = 0x200013e
+	const Sysaio_write	: scno = 0x200013f
+	const Syslio_listio	: scno = 0x2000140
+	const Sysiopolicysys	: scno = 0x2000142
+	const Sysmlockall	: scno = 0x2000144
+	const Sysmunlockall	: scno = 0x2000145
+	const Sysissetugid	: scno = 0x2000147
+	const Sys__pthread_kill	: scno = 0x2000148
+	const Sys__pthread_sigmask	: scno = 0x2000149
+	const Sys__sigwait	: scno = 0x200014a
+	const Sys__disable_threadsignal	: scno = 0x200014b
+	const Sys__pthread_markcancel	: scno = 0x200014c
+	const Sys__pthread_canceled	: scno = 0x200014d
+	const Sys__semwait_signal	: scno = 0x200014e
+	const Sysproc_info	: scno = 0x2000150
+	const Syssendfile	: scno = 0x2000151
+	const Sysstat64		: scno = 0x2000152
+	const Sysfstat64	: scno = 0x2000153
+	const Syslstat64	: scno = 0x2000154
+	const Sysstat64_extended	: scno = 0x2000155
+	const Syslstat64_extended	: scno = 0x2000156
+	const Sysfstat64_extended	: scno = 0x2000157
+	const Sysgetdirentries64	: scno = 0x2000158
+	const Sysstatfs64	: scno = 0x2000159
+	const Sysfstatfs64	: scno = 0x200015a
+	const Sysgetfsstat64	: scno = 0x200015b
+	const Sys__pthread_chdir	: scno = 0x200015c
+	const Sys__pthread_fchdir	: scno = 0x200015d
+	const Sysaudit		: scno = 0x200015e
+	const Sysauditon	: scno = 0x200015f
+	const Sysgetauid	: scno = 0x2000161
+	const Syssetauid	: scno = 0x2000162
+	const Sysgetaudit	: scno = 0x2000163
+	const Syssetaudit	: scno = 0x2000164
+	const Sysgetaudit_addr	: scno = 0x2000165
+	const Syssetaudit_addr	: scno = 0x2000166
+	const Sysauditctl	: scno = 0x2000167
+	const Sysbsdthread_create	: scno = 0x2000168
+	const Sysbsdthread_terminate	: scno = 0x2000169
+	const Syskqueue		: scno = 0x200016a
+	const Syskevent		: scno = 0x200016b
+	const Syslchown		: scno = 0x200016c
+	const Sysstack_snapshot	: scno = 0x200016d
+	const Sysbsdthread_register	: scno = 0x200016e
+	const Sysworkq_open	: scno = 0x200016f
+	const Sysworkq_kernreturn	: scno = 0x2000170
+	const Syskevent64	: scno = 0x2000171
+	const Sys__old_semwait_signal	: scno = 0x2000172
+	const Sys__old_semwait_signal_nocancel	: scno = 0x2000173
+	const Systhread_selfid	: scno = 0x2000174
+	const Sys__mac_execve	: scno = 0x200017c
+	const Sys__mac_syscall	: scno = 0x200017d
+	const Sys__mac_get_file	: scno = 0x200017e
+	const Sys__mac_set_file	: scno = 0x200017f
+	const Sys__mac_get_link	: scno = 0x2000180
+	const Sys__mac_set_link	: scno = 0x2000181
+	const Sys__mac_get_proc	: scno = 0x2000182
+	const Sys__mac_set_proc	: scno = 0x2000183
+	const Sys__mac_get_fd	: scno = 0x2000184
+	const Sys__mac_set_fd	: scno = 0x2000185
+	const Sys__mac_get_pid	: scno = 0x2000186
+	const Sys__mac_get_lcid	: scno = 0x2000187
+	const Sys__mac_get_lctx	: scno = 0x2000188
+	const Sys__mac_set_lctx	: scno = 0x2000189
+	const Syssetlcid	: scno = 0x200018a
+	const Sysgetlcid	: scno = 0x200018b
+	const Sysread_nocancel	: scno = 0x200018c
+	const Syswrite_nocancel	: scno = 0x200018d
+	const Sysopen_nocancel	: scno = 0x200018e
+	const Sysclose_nocancel	: scno = 0x200018f
+	const Syswait4_nocancel	: scno = 0x2000190
+	const Sysrecvmsg_nocancel	: scno = 0x2000191
+	const Syssendmsg_nocancel	: scno = 0x2000192
+	const Sysrecvfrom_nocancel	: scno = 0x2000193
+	const Sysaccept_nocancel	: scno = 0x2000194
+	const Sysmsync_nocancel		: scno = 0x2000195
+	const Sysfcntl_nocancel		: scno = 0x2000196
+	const Sysselect_nocancel	: scno = 0x2000197
+	const Sysfsync_nocancel		: scno = 0x2000198
+	const Sysconnect_nocancel	: scno = 0x2000199
+	const Syssigsuspend_nocancel	: scno = 0x200019a
+	const Sysreadv_nocancel		: scno = 0x200019b
+	const Syswritev_nocancel	: scno = 0x200019c
+	const Syssendto_nocancel	: scno = 0x200019d
+	const Syspread_nocancel		: scno = 0x200019e
+	const Syspwrite_nocancel	: scno = 0x200019f
+	const Syswaitid_nocancel	: scno = 0x20001a0
+	const Syspoll_nocancel		: scno = 0x20001a1
+	const Sysmsgsnd_nocancel	: scno = 0x20001a2
+	const Sysmsgrcv_nocancel	: scno = 0x20001a3
+	const Syssem_wait_nocancel	: scno = 0x20001a4
+	const Sysaio_suspend_nocancel	: scno = 0x20001a5
+	const Sys__sigwait_nocancel	: scno = 0x20001a6
+	const Sys__semwait_signal_nocancel	: scno = 0x20001a7
+	const Sys__mac_mount		: scno = 0x20001a8
+	const Sys__mac_get_mount	: scno = 0x20001a9
+	const Sys__mac_getfsstat	: scno = 0x20001aa
+	const Sysfsgetpath		: scno = 0x20001ab
+	const Sysaudit_session_self	: scno = 0x20001ac
+	const Sysaudit_session_join	: scno = 0x20001ad
+	const Syspid_suspend		: scno = 0x20001ae
+	const Syspid_resume		: scno = 0x20001af
+	const Sysfileport_makeport	: scno = 0x20001b0
+	const Sysfileport_makefd	: scno = 0x20001b1
+
+	extern const syscall : (sc:scno, args:... -> int64)
+
+	/* process control */
+	const exit	: (status:int -> void)
+	const getpid	: ( -> pid)
+	const kill	: (pid : pid, sig:int64 -> int64)
+	const fork	: (-> pid)
+	const wait4	: (pid : pid, loc:int32#, opt : int64, rusage:rusage#	-> int64)
+	const waitpid	: (pid : pid, loc:int32#, opt : int64	-> int64)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
+
+	/* file manipulation */
+	const open	: (path:byte[:], opts:fdopt -> fd)
+	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
+	const close	: (fd:fd -> int64)
+	const creat	: (path:byte[:], mode:int64 -> fd)
+	const unlink	: (path:byte[:] -> int)
+	const read	: (fd:fd, buf:byte[:] -> size)
+	const write	: (fd:fd, buf:byte[:] -> size)
+	const lseek	: (fd:fd, off:off, whence:whence -> off)
+	const stat	: (path:byte[:], sb:statbuf# -> int64)
+	const lstat	: (path:byte[:], sb:statbuf# -> int64)
+	const fstat	: (fd:fd, sb:statbuf# -> int64)
+	const mkdir	: (path : byte[:], mode : int64	-> int64)
+	generic ioctl	: (fd:fd, req : int64, args:@a# -> int64)
+	const getdirentries64	: (fd : fd, buf : byte[:], basep : int64# -> int64)
+	const chdir	: (p : byte[:] -> int64)
+
+	/* fd stuff */
+	const pipe	: (fd : fd[2]# -> int64)
+	const dup	: (fd : fd -> fd)
+	const dup2	: (src : fd, dst : fd -> fd)
+	/* NB: the C ABI uses '...' for the args. */
+	const fcntl	: (fd : fd, cmd : fcntlcmd, args : byte# -> int64)
+
+	/* kqueue */
+	const kqueue	: (-> fd)
+	const kevent	: (q : fd, cl : kevent[:], el : kevent[:], flg : kflags, timeout : timespec# -> int64)
+	const kevent64	: (q : fd, cl : kevent64[:], el : kevent64[:], flg : kflags, timeout : timespec# -> int64)
+
+
+
+	/* networking */
+	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
+	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
+	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
+	const listen	: (sock : fd, backlog : int	-> int)
+	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
+
+
+	/* memory mapping */
+	const munmap	: (addr:byte#, len:size -> int64)
+	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
+
+	/* time */
+	const gettimeofday	: (tv : timeval#, tz : timezone# -> int)
+	const settimeofday	: (tv : timeval#, tz : timezone# -> int)
+	/* faked with gettimeofday */
+	const clock_getres	: (clk : clock, ts : timespec# -> int)
+	const clock_gettime	: (clk : clock, ts : timespec# -> int)
+	const clock_settime	: (clk : clock, ts : timespec# -> int)
+	/* FIXME: HACK HACK HACK -- does nothing */
+	const sleep	: (time : uint64 -> int32)
+
+	/* system information */
+	const uname 	: (buf : utsname# -> int)
+	const sysctl	: (mib : int[:], old : byte[:]#, new : byte[:] -> int)
+
+	/* filled by start code */
+	extern const __cenvp : byte##
+	extern const __environment : byte[:][:]
+;;
+
+/*
+wraps a syscall argument, converting it to 64 bits for the syscall function. This is
+the same as casting, but more concise than writing castto(int64)
+*/
+generic a = {x : @t
+	-> x castto(uint64)
+}
+
+/* OSX has a number of funky syscalls */
+extern const __osx_fork	: (-> pid)
+extern const __osx_pipe : (fd : fd[2]# -> int64)
+extern const __osx_getpid	: (-> pid)
+extern const __osx_lseek	: (fd:fd, off:off, whence:whence -> off)
+extern const __osx_gettimeofday	: (tv : timeval#, tz : timezone# -> int)
+/*
+extern const __osx_ptrace
+extern const __osx_signalstack
+extern const __osx_sigreturn
+extern const __osx_thread_selfid
+extern const __osx_vfork
+*/
+
+extern const cstring : (str : byte[:] -> byte#)
+extern const alloca : (sz : size -> byte#)
+
+/* process control */
+const exit	= {status;		syscall(Sysexit, a(status))}
+const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
+const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
+const fork	= {;			-> __osx_fork()}
+const wait4	= {pid, loc, opt, rusage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(rusage))}
+const waitpid	= {pid, loc, opt;
+	-> wait4(pid, loc, opt, 0 castto(rusage#))
+}
+
+const sleep = {time;	-> 0}
+
+const execv	= {cmd, args
+	var p, cargs, i
+
+	/* doesn't just call execve() for efficiency's sake. */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len + 1]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
+}
+
+const execve	= {cmd, args, env
+	var cargs, cenv, i
+	var p
+
+	/* copy the args */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (p castto(byte##))[:args.len + 1]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+
+	/*
+	 copy the env.
+	 of course we fucking have to duplicate this code everywhere,
+	 since we want to stack allocate...
+	*/
+	p = alloca((env.len + 1)*sizeof(byte#))
+	cenv = (p castto(byte##))[:env.len]
+	for i = 0; i < env.len; i++
+		cenv[i] = cstring(env[i])
+	;;
+	cenv[env.len] = 0 castto(byte#)
+
+	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
+}
+
+
+/* fd manipulation */
+const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
+const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const close	= {fd;			-> syscall(Sysclose, a(fd))}
+const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
+const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
+const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const lseek	= {fd, off, whence;	-> __osx_lseek(fd, off, whence)}
+const stat	= {path, sb;		-> syscall(Sysstat64, cstring(path), a(sb))}
+const lstat	= {path, sb;		-> syscall(Syslstat64, cstring(path), a(sb))}
+const fstat	= {fd, sb;		-> syscall(Sysfstat64, a(fd), a(sb))}
+const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
+generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
+const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries64, a(fd), buf castto(byte#), a(buf.len), a(basep))}
+const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
+
+/* fd stuff */
+const pipe	= {fd;	-> __osx_pipe(fd)}
+const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
+const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}
+
+/* kqueueueueueueue */
+const kqueue	= {;	-> syscall(Syskqueue) castto(fd)}
+const kevent	= {q, cl, el, flg, timeout
+	-> syscall(Syskevent, a(q), \
+		cl castto(kevent#), a(cl.len), \
+		el castto(kevent#), a(el.len), \
+		a(flg), \
+		timeout)
+}
+
+const kevent64	= {q, cl, el, flg, timeout
+	-> syscall(Syskevent, a(q), \
+		cl castto(kevent#), a(cl.len), \
+		el castto(kevent#), a(el.len), \
+		a(flg), \
+		timeout)
+}
+
+/* networking */
+const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
+const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
+const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
+const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
+const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
+
+/* memory management */
+const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
+const mmap	= {addr, len, prot, flags, fd, off;
+	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
+
+/* time */
+const gettimeofday = {tv, tz;	-> __osx_gettimeofday(tv, tz) castto(int)}
+const settimeofday = {tv, tz;	-> syscall(Syssettimeofday, a(tv), a(tz)) castto(int)}
+
+/* faked  with gettimeofday */
+const clock_getres = {clk, ts
+	ts.sec = 0
+	ts.nsec = 1000*10 /* 10ms is reasonable resolution */
+	-> 0
+}
+
+const clock_gettime = {clk, ts
+	var tv
+	var ret
+
+	ret = gettimeofday(&tv, 0 castto(timezone#))
+	ts.sec = tv.sec
+	ts.nsec = tv.usec * 1000
+	-> ret
+}
+
+const clock_settime = {clk, ts
+	var tv
+
+	tv.sec = ts.sec
+	tv.usec = ts.nsec / 1000
+	-> settimeofday(&tv, 0 castto(timezone#))
+}
+
+/* system information */
+const uname	= {buf;
+	var mib : int[2]
+	var ret
+	var sys
+	var nod
+	var rel
+	var ver
+	var mach
+
+	ret = 0
+	mib[0] = 1 /* CTL_KERN */
+	mib[1] = 1 /* KERN_OSTYPE */
+	sys = buf.system[:]
+	ret = sysctl(mib[:], &sys, [][:])
+	if ret < 0
+		-> ret
+	;;
+
+	mib[0] = 1 /* CTL_KERN */
+	mib[1] = 10 /* KERN_HOSTNAME */
+	nod = buf.node[:]
+	ret = sysctl(mib[:], &nod, [][:])
+	if ret < 0
+		-> ret
+	;;
+
+	mib[0] = 1 /* CTL_KERN */
+	mib[1] = 2 /* KERN_OSRELEASE */
+	rel = buf.release[:]
+	ret = sysctl(mib[:], &rel, [][:])
+	if ret < 0
+		-> ret
+	;;
+
+	mib[0] = 1 /* CTL_KERN */
+	mib[1] = 4 /* KERN_VERSION */
+	ver = buf.version[:]
+	ret = sysctl(mib[:], &ver, [][:])
+	if ret < 0
+		-> ret
+	;;
+
+	mib[0] = 6 /* CTL_HW */
+	mib[1] = 1 /* HW_MACHINE */
+	mach = buf.machine[:]
+	ret = sysctl(mib[:], &mach, [][:])
+	if ret < 0
+		-> ret
+	;;
+
+	-> 0
+}
+
+const sysctl = {mib, old, new
+	var mibp
+	var mibsz
+	var o
+	var oldp
+	var oldsz
+	var newp
+	var newsz
+	var ret
+
+	mibp = mib castto(byte#)
+	mibsz = mib.len castto(uint64)
+	o = old#
+	oldp = o castto(byte#)
+	oldsz = (o.len castto(uint64))
+	if new.len > 0
+		newp = new castto(byte#)
+		newsz = new.len castto(uint64)
+	else
+		newp = 0 castto(byte#)
+		newsz = 0
+	;;
+
+	ret = syscall(Sys__sysctl, a(mibp), a(mibsz), a(oldp), a(&oldsz), a(newp), a(newsz)) castto(int)
+
+	old# = o[:oldsz]
+	-> ret
+}
+
+const waitstatus = {st
+	if st < 0
+		-> `Waitfail st
+	;;
+	match st & 0o177
+	| 0:    -> `Waitexit (st >> 8)
+	| 0o177:-> `Waitstop (st >> 8)
+	| sig:  -> `Waitsig sig
+	;;
+}
+
--- /dev/null
+++ b/lib/std/sys+plan9-x64.myr
@@ -1,0 +1,242 @@
+use "systypes.use"
+
+pkg sys =
+	type scno	= int64	/* syscall */
+	type pid	= int32 /* process id */
+	type fdopt	= int32	/* fd options */
+	type fd		= int32	/* fd */
+	type rflags	= int32	/* rfork flags */
+
+	type tos = struct
+		prof	: prof
+		cyclefreq	: uint64
+		kcycles	: int64
+		pcycles	: int64
+		pid	: pid
+		clock	: uint32
+	;;
+
+	type prof = struct
+		pp	: byte#	/* plink */
+		next	: byte#	/* plink */
+		last	: byte#	/* plink */
+		first	: byte#	/* plink */
+		pid	: pid	/* plink */
+		what	: uint32	/* plink */
+	;;
+
+
+	const Ordonly	: fdopt = 0
+	const Owronly	: fdopt = 1
+	const Ordwr	: fdopt = 2
+	const Oexec	: fdopt = 3
+
+	const Otrunc	: fdopt = 16
+	const Ocexec	: fdopt = 32
+	const Orclose	: fdopt = 64
+	const Oexcl	: fdopt = 0x1000
+
+	const Qtdir	: int  = 0x80
+	const Qtappend	: int  = 0x40
+	const Qtexcl	: int  = 0x20
+	const Qtmount	: int  = 0x10
+	const Qtauth	: int  = 0x08
+	const Qttmp	: int  = 0x04
+	const Qtfile	: int  = 0x00
+
+	const Dmdir	: int = 0x8000000
+	const Dmappend	: int = 0x4000000
+	const Dmexcl	: int = 0x2000000
+	const Dmmount	: int = 0x1000000
+	const Dmauth	: int = 0x0800000
+	const Dmtmp	: int = 0x0400000
+	const Dmread	: int = 0x4
+	const Dmwrite	: int = 0x2
+	const Dmexec	: int = 0x1
+
+	const Rfnameg	: rflags = 1 << 0
+	const Rfenvg	: rflags = 1 << 1
+	const Rffdg	: rflags = 1 << 2
+	const Rfnoteg	: rflags = 1 << 3
+	const Rfproc	: rflags = 1 << 4
+	const Rfmem	: rflags = 1 << 5
+	const Rfnowait	: rflags = 1 << 6
+	const Rfcnameg	: rflags = 1 << 10
+	const Rfcenvg	: rflags = 1 << 11
+	const Rfcfdg	: rflags = 1 << 12
+	const Rfrend	: rflags = 1 << 13
+	const Rfnomnt	: rflags = 1 << 14
+
+	const Syssysr1		: scno = 0
+	const Sys_errstr	: scno = 1
+	const Sysbind		: scno = 2
+	const Syschdir		: scno = 3
+	const Sysclose		: scno = 4
+	const Sysdup		: scno = 5
+	const Sysalarm		: scno = 6
+	const Sysexec		: scno = 7
+	const Sysexits		: scno = 8
+	const Sys_fsession	: scno = 9
+	const Sysfauth		: scno = 10
+	const Sys_fstat		: scno = 11
+	const Syssegbrk		: scno = 12
+	const Sys_mount		: scno = 13
+	const Sysopen		: scno = 14
+	const Sys_read		: scno = 15
+	const Sysoseek		: scno = 16
+	const Syssleep		: scno = 17
+	const Sys_stat		: scno = 18
+	const Sysrfork		: scno = 19
+	const Sys_write		: scno = 20
+	const Syspipe		: scno = 21
+	const Syscreate		: scno = 22
+	const Sysfd2path	: scno = 23
+	const Sysbrk_		: scno = 24
+	const Sysremove		: scno = 25
+	const Sys_wstat		: scno = 26
+	const Sys_fwstat	: scno = 27
+	const Sysnotify		: scno = 28
+	const Sysnoted		: scno = 29
+	const Syssegattach	: scno = 30
+	const Syssegdetach	: scno = 31
+	const Syssegfree	: scno = 32
+	const Syssegflush	: scno = 33
+	const Sysrendezvous	: scno = 34
+	const Sysunmount	: scno = 35
+	const Sys_wait		: scno = 36
+	const Syssemacquire	: scno = 37
+	const Syssemrelease	: scno = 38
+	const Sysseek		: scno = 39
+	const Sysfversion	: scno = 40
+	const Syserrstr		: scno = 41
+	const Sysstat		: scno = 42
+	const Sysfstat		: scno = 43
+	const Syswstat		: scno = 44
+	const Sysfwstat		: scno = 45
+	const Sysmount		: scno = 46
+	const Sysawait		: scno = 47
+	const Syspread		: scno = 50
+	const Syspwrite		: scno = 51
+	const Systsemacquire	: scno = 52
+	const Sys_nsec		: scno = 53
+
+
+	const sysr1	: (-> int64)
+	const bind	: (nm : byte[:], old : byte[:] -> int64)
+	const chdir	: (dir : byte[:] -> int64)
+	const close	: (fd : fd -> int64)
+	const dup	: (old : fd, new : fd -> fd)
+	const alarm	: (msec : uint32 -> int64)
+	const exits	: (msg : byte[:] -> int64)
+	const fauth	: (fd : fd, name : byte[:] -> int64)
+	const segbrk	: (saddr : void#, addr : void# -> int64)
+	const open	: (path : byte[:], opt : fdopt -> fd)
+	const sleep	: (msec : uint32 -> int64)
+	const rfork	: (rflags : rflags -> pid)
+	const pipe	: (fds : fd[2]# -> int64)
+	const create	: (path : byte[:], opt : fdopt, perm : int -> fd)
+	const fd2path	: (fd : fd, path : byte[:] -> int64)
+	const remove	: (path : byte[:] -> int64)
+	const notify	: (fn : (a : void#, c : char# -> int64) -> int64)
+	const noted	: (v : int32 -> int64)
+	const segattach	: (attr : int32, class : byte[:], va : void#, len : uint32 -> int64)
+	const segdetach	: (va : void# -> int64)
+	const segfree	: (va : byte#, len : size -> int64)
+	const segflush	: (va : void#, len : uint32 -> int64)
+	const unmount	: (name : byte[:], old : byte[:] -> int64)
+	const errstr	: (buf : byte[:] -> int64)
+	const stat	: (name : byte[:], edir : byte[:] -> int64)
+	const fstat	: (fd : fd, edir : byte[:] -> int64)
+	const wstat	: (name : byte[:], edir : byte[:] -> int64)
+	const fwstat	: (fd : byte[:],  edir : byte[:] -> int64)
+	const seek	: (fd : fd, len : off, ty : int64 -> off)
+	const mount	: (fd : fd, afd : fd, old : byte[:], flag : int32, aname : byte[:] -> int64)
+	const await	: (buf : byte[:] -> int64)
+	const pread	: (fd : fd, buf : byte[:], off : off -> size)
+	const pwrite	: (fd : fd, buf : byte[:], off : off -> size)
+	const exec	: (bin : byte[:], args : byte[:][:] -> int64)
+	const brk_	: (endp : byte# -> int64)
+	const nsec	: (-> uint64)
+
+	extern const alloca	: (sz : size	-> byte#)
+
+	extern var tosptr	: tos#
+	extern var curbrk	: byte#
+;;
+
+/* asm stub from syscall.s */
+extern const syscall : (scno : scno, args : ... -> int64)
+/* asm stubs from util+plan9.s */
+extern const cstring	: (str : byte[:] -> byte#)
+extern const alloca	: (sz : size	-> byte#)
+
+
+/*
+ABI mismatch: Plan 9 aligns all arguments individually to
+8 bytes, Myrddin uses natural alignment (min(sizeof(t), 16).
+Cast to a 64 bit type to paper over this.
+*/
+generic a	= {a : @t;	-> a castto(uint64)}
+generic s	= {a : @t;	-> a castto(int64)}
+generic p	= {a : @t;	-> a castto(byte#)}
+
+const sysr1	= {;		-> syscall(Syssysr1)}
+const bind	= {name, old;	-> syscall(Sysbind, cstring(name), cstring(old))}
+const chdir 	= {dir;		-> syscall(Syschdir, cstring(dir)) }
+const close 	= {fd;		-> syscall(Sysclose, a(fd))}
+const dup	= {ofd, nfd;	-> syscall(Sysdup, a(ofd), a(nfd)) castto(fd)}
+const alarm 	= {msec;	-> syscall(Sysalarm, a(msec))}
+const exits 	= {msg;		-> syscall(Sysexits, cstring(msg))}
+const fauth 	= {fd, aname;	-> syscall(Sysfauth, a(fd), cstring(aname))}
+const segbrk 	= {saddr, addr;	-> syscall(Syssegbrk, a(saddr), a(addr))}
+const open 	= {path, opt;	-> syscall(Sysopen, cstring(path), a(opt)) castto(fd)}
+const sleep 	= {msec;	-> syscall(Syssleep, a(msec))}
+const rfork 	= {rflags;	-> syscall(Sysrfork, a(rflags)) castto(pid)}
+const pipe 	= {fds;		-> syscall(Syspipe, a(fds))}
+const create 	= {path, mode, perm;	-> syscall(Syscreate, cstring(path), a(mode), a(perm)) castto(fd)}
+const fd2path	= {fd, buf;	-> syscall(Sysfd2path, a(fd), p(buf), a(buf.len))}
+const remove	= {path;	-> syscall(Sysremove, cstring(path))}
+const notify	= {fn;		-> syscall(Sysnotify, fn)}	/* FIXME: this is likely to break when we do closures... */
+const noted	= {v;		-> syscall(Sysnoted, a(v))}
+const segattach	= {attr, class, va, len;	-> syscall(Syssegattach, a(attr), cstring(class), a(va), a(len))}
+const segdetach	= {va;		-> syscall(Syssegdetach, a(va))}
+const segfree	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
+const segflush	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
+const unmount	= {name, old;	-> syscall(Sysunmount, cstring(name), cstring(old))}
+const errstr	= {buf;		-> syscall(Syserrstr, p(buf), a(buf.len))}
+const stat	= {name, edir;	-> syscall(Sysstat, cstring(name), p(edir), a(edir.len))}
+const fstat	= {fd, edir;	-> syscall(Sysstat, a(fd), p(edir), a(edir.len))}
+const wstat	= {name, edir;	-> syscall(Syswstat, cstring(name), p(edir), a(edir.len))}
+const fwstat	= {fd, edir;	-> syscall(Sysfwstat, a(fd), p(edir), a(edir.len))}
+const mount	= {fd, afd, old, flag, aname;	-> syscall(Sysmount, a(fd), a(afd), cstring(old), a(flag), cstring(aname))}
+const pread	= {fd, buf, off;	-> syscall(Syspread, a(fd), p(buf), a(buf.len), off) castto(size)}
+const pwrite	= {fd, buf, off;	-> syscall(Syspwrite, a(fd), p(buf), a(buf.len), s(off)) castto(size)}
+const await	= {buf;	-> syscall(Sysawait, p(buf), a(buf.len))}
+const brk_	= {endp;	-> syscall(Sysbrk_, p(endp))}
+const nsec	= {;	-> syscall(Sys_nsec) castto(uint64)}
+const seek	= {fd, n, ty
+	var ret : off
+	syscall(Sysseek, a(&ret), a(fd), a(n), a(ty))
+	-> ret
+}
+
+const exec	= {bin, args
+	var p, cargs, i
+
+	/* we need an array of C strings. */
+	p = alloca((args.len + 1)*sizeof(byte#))
+	cargs = (a(p) castto(byte##))[:args.len + 1]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+	-> syscall(Sysexec, cstring(bin), a(cargs))
+}
+
+/* ??? do I care for now?
+const fversion	= {fd, bufsz, vers, nvers;	-> syscall(Sysfversion, fd, bufsz, }
+const rendezvous	= {;}
+const semacquire	= {;}
+const semrelease	= {;}
+const tsemacquire	= {;}
+*/
--- /dev/null
+++ b/lib/std/syscall+freebsd-x64.s
@@ -1,0 +1,21 @@
+.globl sys$syscall
+sys$syscall:
+	/*
+	hack: We load 6 args regardless of
+	how many we actually have. This may
+	load junk values, but if the syscall
+	doesn't use them, it's going to be
+	harmless.
+	 */
+	movq %rdi,%rax
+	movq %rsi,%rdi
+	movq %rdx,%rsi
+	movq %rcx,%rdx
+	movq %r8,%r10
+	movq %r9,%r8
+	movq 8(%rsp),%r9
+
+	syscall
+
+	ret
+
--- /dev/null
+++ b/lib/std/syscall+linux-x64.s
@@ -1,0 +1,22 @@
+.globl sys$syscall
+sys$syscall:
+	/*
+	hack: We load 6 args regardless of
+	how many we actually have. This may
+	load junk values, but if the syscall
+	doesn't use them, it's going to be
+	harmless.
+	 */
+	movq %rdi,%rax
+        /* 8(%rsp): hidden type arg */
+	movq 16(%rsp),%rdi
+	movq 24(%rsp),%rsi
+	movq 32(%rsp),%rdx
+	movq 40(%rsp),%r10
+	movq 48(%rsp),%r8
+	movq 56(%rsp),%r9
+
+	syscall
+
+	ret
+
--- /dev/null
+++ b/lib/std/syscall+osx-x64.s
@@ -1,0 +1,96 @@
+.globl _sys$syscall
+_sys$syscall:
+
+	/*
+	hack: We load 6 args regardless of
+	how many we actually have. This may
+	load junk values, but if the syscall
+	doesn't use them, it's going to be
+	harmless.
+	 */
+	movq %rdi,%rax
+        /* 8(%rsp): hidden type arg */
+	movq 16(%rsp),%rdi
+	movq 24(%rsp),%rsi
+	movq 32(%rsp),%rdx
+	movq 40(%rsp),%r10
+	movq 48(%rsp),%r8
+	movq 56(%rsp),%r9
+
+	syscall
+	jae .success
+	negq %rax
+
+.success:
+	ret
+
+/*
+ * OSX is strange about fork, and needs an assembly wrapper.
+ * The fork() syscall, when called directly, returns the pid in both
+ * processes, which means that both parent and child think they're
+ * the parent.
+ *
+ * checking this involves peeking in %edx, so we need to do this in asm.
+ */
+.globl _sys$__osx_fork
+_sys$__osx_fork:
+	movq $0x2000002,%rax
+	syscall
+
+	jae .forksuccess
+	negq %rax
+
+.forksuccess:
+	testl %edx,%edx
+	jz .isparent
+	xorq %rax,%rax
+.isparent:
+	ret
+
+/*
+ * OSX is strange about pipe, and needs an assembly wrapper.
+ * The pipe() syscall returns the pipes created in eax:edx, and
+ * needs to copy them to the destination locations manually.
+ */
+.globl _sys$__osx_pipe
+_sys$__osx_pipe:
+	movq $0x200002a,%rax
+	syscall
+
+	jae .pipesuccess
+	negq %rax
+
+.pipesuccess:
+	movl %eax,(%rdi)
+	movl %edx,4(%rdi)
+	xorq %rax,%rax
+	ret
+
+.globl _sys$__osx_lseek
+_sys$__osx_lseek:
+	movq $0x20000C7,%rax
+	syscall
+
+	jae .lseeksuccess
+	negq %rax
+
+.lseeksuccess:
+        shlq $32,%rdx
+        orq  %rdx,%rax
+	ret
+
+
+.globl _sys$__osx_gettimeofday
+_sys$__osx_gettimeofday:
+	movq $0x2000074,%rax
+	syscall
+
+	jae .gettimeofdaysuccess
+	negq %rax
+
+.gettimeofdaysuccess:
+	movq %rax, (%rdi)
+	movl %edx,8(%rdi)
+	xorq %rax,%rax
+	ret
+
--- /dev/null
+++ b/lib/std/syscall+plan9-x64.s
@@ -1,0 +1,33 @@
+/*
+Ugly: Kernel is caller-save, Myrddin
+is callee-save. We need to preserve
+registers before entering the kernel.
+
+However, we also need SP to point to the
+start of the arguments.
+
+Luckily, the kernel doesn't touch our stack,
+and we have 256 bytes of gap if we get a note.
+*/
+TEXT sys$syscall+0(SB),1,$0
+	MOVQ	R11,-16(SP)
+	MOVQ	R12,-24(SP)
+	MOVQ	R13,-32(SP)
+	MOVQ	R14,-40(SP)
+	MOVQ	R15,-48(SP)
+	MOVQ	BP,-56(SP)
+	MOVQ	8(SP),RARG
+
+	ADDQ	$8,SP
+	MOVQ	DI, RARG
+	SYSCALL
+	SUBQ	$8,SP
+
+	MOVQ	-16(SP),R11
+	MOVQ	-24(SP),R12
+	MOVQ	-32(SP),R13
+	MOVQ	-40(SP),R14
+	MOVQ	-48(SP),R15
+	MOVQ	-56(SP),BP
+	RET
+
--- /dev/null
+++ b/lib/std/syserrno+linux.myr
@@ -1,0 +1,38 @@
+pkg sys =
+	type errno = int
+
+	const Eperm	: errno =	 -1	/* Operation not permitted */
+	const Enoent	: errno =	 -2	/* No such file or directory */
+	const Esrch	: errno =	 -3	/* No such process */
+	const Eintr	: errno =	 -4	/* Interrupted system call */
+	const Eio	: errno =	 -5	/* I/O error */
+	const Enxio	: errno =	 -6	/* No such device or address */
+	const E2big	: errno =	 -7	/* Argument list too long */
+	const Enoexec	: errno =	 -8	/* Exec format error */
+	const Ebadf	: errno =	 -9	/* Bad file number */
+	const Echild	: errno =	-10	/* No child processes */
+	const Eagain	: errno =	-11	/* Try again */
+	const Enomem	: errno =	-12	/* Out of memory */
+	const Eacces	: errno =	-13	/* Permission denied */
+	const Efault	: errno =	-14	/* Bad address */
+	const Enotblk	: errno =	-15	/* Block device required */
+	const Ebusy	: errno =	-16	/* Device or resource busy */
+	const Eexist	: errno =	-17	/* File exists */
+	const Exdev	: errno =	-18	/* Cross-device link */
+	const Enodev	: errno =	-19	/* No such device */
+	const Enotdir	: errno =	-20	/* Not a directory */
+	const Eisdir	: errno =	-21	/* Is a directory */
+	const Einval	: errno =	-22	/* Invalid argument */
+	const Enfile	: errno =	-23	/* File table overflow */
+	const Emfile	: errno =	-24	/* Too many open files */
+	const Enotty	: errno =	-25	/* Not a typewriter */
+	const Etxtbsy	: errno =	-26	/* Text file busy */
+	const Efbig	: errno =	-27	/* File too large */
+	const Enospc	: errno =	-28	/* No space left on device */
+	const Espipe	: errno =	-29	/* Illegal seek */
+	const Erofs	: errno =	-30	/* Read-only file system */
+	const Emlink	: errno =	-31	/* Too many links */
+	const Epipe	: errno =	-32	/* Broken pipe */
+	const Edom	: errno =	-33	/* Math argument out of domain of func */
+	const Erange	: errno =	-34	/* Math result not representable */
+;;
--- /dev/null
+++ b/lib/std/syserrno+osx.myr
@@ -1,0 +1,54 @@
+pkg sys =
+	type errno = int
+
+	const Eperm	: errno = -1		/* Operation not permitted */
+	const Enoent	: errno = -2		/* No such file or directory */
+	const Esrch	: errno = -3		/* No such process */
+	const Eintr	: errno = -4		/* Interrupted system call */
+	const Eio	: errno = -5		/* Input/output error */
+	const Enxio	: errno = -6		/* Device not configured */
+	const E2big	: errno = -7		/* Argument list too long */
+	const Enoexec	: errno = -8		/* Exec format error */
+	const Ebadf	: errno = -9		/* Bad file descriptor */
+	const Echild	: errno = -10		/* No child processes */
+	const Edeadlk	: errno = -11		/* Resource deadlock avoided */
+				/* 11 was EAGAIN */
+	const Enomem	: errno = -12		/* Cannot allocate memory */
+	const Eacces	: errno = -13		/* Permission denied */
+	const Efault	: errno = -14		/* Bad address */
+	const Enotblk	: errno = -15		/* Block device required */
+	const Ebusy	: errno = -16		/* Device / Resource busy */
+	const Eexist	: errno = -17		/* File exists */
+	const Exdev	: errno = -18		/* Cross-device link */
+	const Enodev	: errno = -19		/* Operation not supported by device */
+	const Enotdir	: errno = -20		/* Not a directory */
+	const Eisdir	: errno = -21		/* Is a directory */
+	const Einval	: errno = -22		/* Invalid argument */
+	const Enfile	: errno = -23		/* Too many open files in system */
+	const Emfile	: errno = -24		/* Too many open files */
+	const Enotty	: errno = -25		/* Inappropriate ioctl for device */
+	const Etxtbsy	: errno = -26		/* Text file busy */
+	const Efbig	: errno = -27		/* File too large */
+	const Enospc	: errno = -28		/* No space left on device */
+	const Espipe	: errno = -29		/* Illegal seek */
+	const Erofs	: errno = -30		/* Read-only file system */
+	const Emlink	: errno = -31		/* Too many links */
+	const Epipe	: errno = -32		/* Broken pipe */
+
+	/* math software */
+	const Edom	: errno = -33		/* Numerical argument out of domain */
+	const Erange	: errno = -34		/* Result too large */
+
+	/* non-blocking and interrupt i/o */
+	const Eagain	: errno = -35		/* Resource temporarily unavailable */
+	const Einprogress	: errno = -36		/* Operation now in progress */
+	const Ealready	: errno = -37		/* Operation already in progress */
+
+	/* ipc/network software -- argument errors */
+	const Enotsock	: errno = -38		/* Socket operation on non-socket */
+	const Edestaddrreq	: errno = -39		/* Destination address required */
+	const Emsgsize	: errno = -40		/* Message too long */
+	const Eprototype	: errno = -41		/* Protocol wrong type for socket */
+	const Enoprotoopt	: errno = -42		/* Protocol not available */
+	const Eprotonosupport	: errno = -43		/* Protocol not supported */
+;;
--- /dev/null
+++ b/lib/std/syserrno+plan9.myr
@@ -1,0 +1,38 @@
+pkg sys =
+	type errno = int
+
+	const Eperm	: errno =	 -1	/* Operation not permitted */
+	const Enoent	: errno =	 -2	/* No such file or directory */
+	const Esrch	: errno =	 -3	/* No such process */
+	const Eintr	: errno =	 -4	/* Interrupted system call */
+	const Eio	: errno =	 -5	/* I/O error */
+	const Enxio	: errno =	 -6	/* No such device or address */
+	const E2big	: errno =	 -7	/* Argument list too long */
+	const Enoexec	: errno =	 -8	/* Exec format error */
+	const Ebadf	: errno =	 -9	/* Bad file number */
+	const Echild	: errno =	-10	/* No child processes */
+	const Eagain	: errno =	-11	/* Try again */
+	const Enomem	: errno =	-12	/* Out of memory */
+	const Eacces	: errno =	-13	/* Permission denied */
+	const Efault	: errno =	-14	/* Bad address */
+	const Enotblk	: errno =	-15	/* Block device required */
+	const Ebusy	: errno =	-16	/* Device or resource busy */
+	const Eexist	: errno =	-17	/* File exists */
+	const Exdev	: errno =	-18	/* Cross-device link */
+	const Enodev	: errno =	-19	/* No such device */
+	const Enotdir	: errno =	-20	/* Not a directory */
+	const Eisdir	: errno =	-21	/* Is a directory */
+	const Einval	: errno =	-22	/* Invalid argument */
+	const Enfile	: errno =	-23	/* File table overflow */
+	const Emfile	: errno =	-24	/* Too many open files */
+	const Enotty	: errno =	-25	/* Not a typewriter */
+	const Etxtbsy	: errno =	-26	/* Text file busy */
+	const Efbig	: errno =	-27	/* File too large */
+	const Enospc	: errno =	-28	/* No space left on device */
+	const Espipe	: errno =	-29	/* Illegal seek */
+	const Erofs	: errno =	-30	/* Read-only file system */
+	const Emlink	: errno =	-31	/* Too many links */
+	const Epipe	: errno =	-32	/* Broken pipe */
+	const Edom	: errno =	-33	/* Math argument out of domain of func */
+	const Erange	: errno =	-34	/* Math result not representable */
+;;
--- /dev/null
+++ b/lib/std/systypes.myr
@@ -1,0 +1,7 @@
+pkg sys =
+	type size	= int64	/* spans entire address space */
+	type usize	= int64	/* signed size */
+	type off	= int64	/* file offsets */
+	type intptr	= uint64/* can hold any pointer losslessly */
+	type time	= int64	/* milliseconds since epoch */
+;;
--- /dev/null
+++ b/lib/std/syswrap+plan9-x6.myr
@@ -1,0 +1,104 @@
+use sys
+use "types.use"
+
+pkg std =
+	type fd		= sys.fd
+	type pid	= sys.pid
+	type fdopt	= sys.fdopt
+
+	const Failmem	: byte#	= -1 castto(byte#)
+
+	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
+	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
+	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
+	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
+	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
+	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
+	const Odir	: fdopt = 0x0	/* no-op on plan9 */
+
+	/* fd stuff */
+	const open	: (path : byte[:], opts : fdopt -> fd)
+	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
+	const close	: (fd : fd -> int64)
+	const creat	: (path : byte[:], mode : int64 -> fd)
+	const read	: (fd : fd, buf : byte[:] -> size)
+	const write	: (fd : fd, buf : byte[:] -> size)
+	const pipe	: (fds : fd[2]# -> int64)
+
+	/* path manipulation */
+	const mkdir	: (path : byte[:], mode : int64 -> int64)
+	const unlink	: (path : byte[:] -> int)
+
+	/* process stuff */
+	const getpid	: ( -> pid)
+	const suicide	: ( -> void)
+	const fork	: (-> pid)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	const exit	: (status:int -> void)
+	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
+	const getmem	: (sz : size -> byte#)
+	const freemem	: (p : byte#, sz : size -> void)
+;;
+
+/* fd stuff */
+const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
+const openmode	= {path, opts, mode;
+	var fd
+
+
+	if opts & Ocreat != 0
+		fd = sys.create(path, opts castto(sys.fdopt), mode castto(int))
+	else
+		fd = sys.open(path, opts castto(sys.fdopt))
+	;;
+	if opts & Oappend != 0
+		sys.seek(fd, 0, 2)
+	;;
+	-> fd castto(fd)
+}
+
+const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(int64)}
+const read	= {fd, buf;	-> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
+const write	= {fd, buf;	-> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
+const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
+
+/* path manipulation */
+const unlink	= {path;	-> sys.remove(path)}
+const mkdir	= {path, mode;
+	var fd
+
+	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
+	if fd < 0
+		-> -1
+	;;
+	sys.close(fd)
+	-> 0
+}
+
+/* process stuff */
+const getpid	= {;	-> sys.gettos().pid castto(pid)}
+const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
+const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
+const execv	= {cmd, args;	-> sys.exec(cmd, args) castto(int64)}
+const execve	= {cmd, args, env;	-> sys.exec(cmd, args) castto(int64)}
+const exit	= {status;
+	if status == 0
+		sys.exits("")
+	else
+		sys.exits("failure")
+	;;
+}
+
+/* FIXME: horribly broken. We wait for a pid to exit, and lie about which one. */
+const waitpid	= {pid, loc, opt;
+	var buf : byte[512]
+	var n
+
+	n = sys.await(buf[:])
+	-> pid
+}
+
+/* memory stuff */
+const getmem	= {sz;		-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)}
+const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
--- /dev/null
+++ b/lib/std/syswrap+plan9.myr
@@ -1,0 +1,220 @@
+use sys
+
+use "option.use"
+use "types.use"
+
+pkg std =
+	type fd		= sys.fd
+	type pid	= sys.pid
+	type fdopt	= sys.fdopt
+	type whence = int64
+
+	type sysinfo = struct
+		system	: byte[:]
+		version	: byte[:]
+		release	: byte[:]
+		arch	: byte[:]
+	;;
+
+	const Seekset	: whence = 0
+	const Seekcur	: whence = 1
+	const Seekend	: whence = 2
+
+	const Failmem	: byte#	= -1 castto(byte#)
+
+	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
+	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
+	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
+	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
+	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
+	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
+	const Odir	: fdopt = 0x0	/* no-op on plan9 */
+
+	/* fd stuff */
+	const open	: (path : byte[:], opts : fdopt -> fd)
+	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
+	const close	: (fd : fd -> int64)
+	const creat	: (path : byte[:], mode : int64 -> fd)
+	const read	: (fd : fd, buf : byte[:] -> size)
+	const write	: (fd : fd, buf : byte[:] -> size)
+	const seek	: (fd : fd, delta : off, whence : whence -> off)
+	const pipe	: (fds : fd[2]# -> int64)
+	const dup2	: (ofd : fd, nfd : fd -> fd)
+
+	/* useful/portable bits of stat */
+	const fmtime	: (f : byte[:]	-> option(time))
+	const fsize	: (f : byte[:]	-> option(off))
+	const fexists	: (f : byte[:]	-> bool)
+
+	/* the important bits that uname provides */
+	const getsysinfo	: (si : sysinfo# -> void)
+
+	/* path manipulation */
+	const mkdir	: (path : byte[:], mode : int64 -> int64)
+	const chdir	: (path : byte[:] -> bool)
+	const remove	: (path : byte[:] -> bool)
+
+	/* process stuff */
+	const getpid	: ( -> pid)
+	const suicide	: ( -> void)
+	const fork	: (-> pid)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> pid)
+
+	pkglocal const Canunmap	: bool = true
+	pkglocal const getmem	: (sz : size -> byte#)
+	pkglocal const freemem	: (p : byte#, sz : size -> void)
+	pkglocal const curtime	: (-> time)
+	pkglocal const p9errstr	: (buf : byte[:] -> byte[:])
+
+	/* statbuf offsets */
+	pkglocal const Sizeoff	: int64 = 0
+	pkglocal const Typeoff	: int64 = 2
+	pkglocal const Devoff	: int64 = 4
+	pkglocal const Qidtypeoff	: int64 =8
+	pkglocal const Qidversoff	: int64 = 9
+	pkglocal const Qidpathoff	: int64 = 13
+	pkglocal const Modeoff	: int64 = 21
+	pkglocal const Atimeoff	: int64 = 25
+	pkglocal const Mtimeoff	: int64 = 29
+	pkglocal const Lengthoff	: int64 = 31
+	pkglocal const Stringsoff	: int64 = 39
+;;
+
+/* UGLY: circular dependency breaking... */
+extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
+
+/* fd stuff */
+const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
+const openmode	= {path, opts, mode;
+	var fd
+
+
+	if opts & Ocreat != 0
+		fd = sys.create(path, (opts & ~Ocreat) castto(sys.fdopt), mode castto(int))
+	else
+		fd = sys.open(path, opts castto(sys.fdopt))
+	;;
+	if opts & Oappend != 0
+		sys.seek(fd, 0, 2)
+	;;
+	-> fd castto(fd)
+}
+
+
+/* useful/portable bits of stat */
+const fexists = {path
+	var buf : byte[4]	/* big enough for size, nothing else. */
+	-> sys.stat(path, buf[:]) >= 0
+}
+
+const fmtime = {path
+	var buf	: byte[Stringsoff + 512]	/* enough space for some strings */
+
+	if sys.stat(path, buf[:]) < Stringsoff
+		-> `None
+	;;
+	-> `Some (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
+}
+
+const fsize = {path
+	var buf	: byte[Stringsoff + 512]	/* enough space for some strings */
+
+	if sys.stat(path, buf[:]) < Stringsoff
+		-> `None
+	;;
+	-> `Some (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
+}
+
+const getsysinfo = {si
+	si.system = getenvv("osname", "Plan9")
+	si.release = "4"
+	si.version = "0"
+	si.arch = getenvv("objtype", "amd64")
+}
+
+const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(int64)}
+const read	= {fd, buf;	-> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
+const write	= {fd, buf;	-> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
+const seek	= {fd, off, whence; 	-> sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)) castto(off)}
+const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
+const dup2	= {ofd, nfd;	-> sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
+
+/* path manipulation */
+const remove	= {path;	-> sys.remove(path) == 0}
+const chdir	= {path;	-> sys.chdir(path) == 0}
+const mkdir	= {path, mode;
+	var fd
+
+	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
+	if fd < 0
+		-> -1
+	;;
+	sys.close(fd)
+	-> 0
+}
+
+/* process stuff */
+const getpid	= {;	-> sys.tosptr.pid castto(pid)}
+const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
+const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
+const execv	= {cmd, args;	-> sys.exec(cmd, args) castto(int64)}
+const execve	= {cmd, args, env;	-> sys.exec(cmd, args) castto(int64)}
+
+/* memory stuff */
+const getmem	= {sz
+	var endp, oldp
+
+	oldp = sys.curbrk
+	endp = (sys.curbrk castto(intptr)) + (sz castto(intptr))
+	endp = (endp + 4095) & ~4095
+	if sys.brk_(endp castto(byte#)) < 0
+		-> Failmem
+	;;
+	sys.curbrk = endp castto(byte#)
+	-> oldp
+}
+	
+const freemem = {p, sz
+	/* FIXME: we leak address space */
+	sys.segfree(p, sz castto(sys.size))
+}
+
+const curtime = {
+	-> sys.nsec()/1000 castto(time)
+}
+
+const p9errstr = {errbuf
+	var i
+
+	sys.errstr(errbuf)
+	for i = 0; errbuf[i] != 0 && i < errbuf.len; i++
+		continue
+	;;
+	-> errbuf[:i]
+}
+
+/* FIXME: will be needed when we resize stat bufs when statting.
+const statsz = {buf
+	-> (buf[0] castto(int64)) | ((buf[1] << 8) castto(int64))
+}
+*/
+
+const getle32 = {buf
+	-> (buf[0] castto(int32)) \
+		| ((buf[1] castto(int32)) << 8) \
+		| ((buf[2] castto(int32)) << 16) \
+		| ((buf[3] castto(int32)) << 24)
+}
+
+const getle64 = {buf
+	-> (buf[0] castto(int64)) \
+		| ((buf[1] castto(int64)) << 8) \
+		| ((buf[2] castto(int64)) << 16) \
+		| ((buf[3] castto(int64)) << 24) \
+		| ((buf[4] castto(int64)) << 64) \
+		| ((buf[5] castto(int64)) << 40) \
+		| ((buf[6] castto(int64)) << 48) \
+		| ((buf[7] castto(int64)) << 56)
+}
--- /dev/null
+++ b/lib/std/syswrap+posixy.myr
@@ -1,0 +1,148 @@
+use sys
+use "cstrconv.use"
+use "option.use"
+use "types.use"
+use "errno.use"
+
+pkg std =
+	type fd		= sys.fd
+	type pid	= sys.pid
+	type fdopt	= sys.fdopt
+	type whence	= sys.whence
+
+	type sysinfo = struct
+		system	: byte[:]
+		version	: byte[:]
+		release	: byte[:]
+		arch	: byte[:]
+		uname	: sys.utsname	/* storage */
+	;;
+
+	const Failmem	: byte#	= -1 castto(byte#)
+
+	const Seekset	: whence = sys.Seekset	castto(whence)
+	const Seekcur	: whence = sys.Seekcur	castto(whence)
+	const Seekend	: whence = sys.Seekend	castto(whence)
+
+	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
+	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
+	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
+	const Ocreat   	: fdopt = sys.Ocreat	castto(fdopt)
+	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
+	const Oappend  	: fdopt = sys.Oappend	castto(fdopt)
+	const Odir	: fdopt = sys.Odir	castto(fdopt)
+
+	/* fd stuff */
+	const open	: (path : byte[:], opts : fdopt -> fd)
+	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
+	const close	: (fd : fd -> int64)
+	const creat	: (path : byte[:], mode : int64 -> fd)
+	const read	: (fd : fd, buf : byte[:] -> size)
+	const write	: (fd : fd, buf : byte[:] -> size)
+	const pipe	: (fds : fd[2]# -> int64)
+	const seek	: (fd : fd, delta : off, whence : whence -> off)
+	const dup2	: (ofd : fd, nfd : fd -> fd)
+
+	/* useful/portable bits of stat */
+	const fmtime	: (f : byte[:]	-> option(time))
+	const fsize	: (f : byte[:]	-> option(off))
+	const fexists	: (f : byte[:]	-> bool)
+
+	/* useful/portable bits of uname */
+	const getsysinfo	: (si : sysinfo# -> void)
+
+	/* path manipulation */
+	const mkdir	: (path : byte[:], mode : int64 -> int64)
+	const remove	: (path : byte[:] -> bool)
+	const chdir	: (path : byte[:] -> bool)
+
+	/* process stuff */
+	const getpid	: ( -> pid)
+	const suicide	: ( -> void)
+	const fork	: (-> pid)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
+
+	pkglocal const Canunmap	: bool = true
+	pkglocal const getmem	: (sz : size -> byte#)
+	pkglocal const freemem	: (p : byte#, sz : size -> void)
+	pkglocal const curtime	: (-> time)
+;;
+
+/* fd stuff */
+const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
+const openmode	= {path, opts, mode;	-> sys.openmode(path, opts castto(sys.fdopt), mode) castto(fd)}
+const close	= {fd;		-> sys.close(fd castto(sys.fd))}
+const creat	= {path, mode;	-> sys.creat(path, mode) castto(fd)}
+const read	= {fd, buf;	-> sys.read(fd castto(sys.fd), buf) castto(size)}
+const write	= {fd, buf;	-> sys.write(fd castto(sys.fd), buf) castto(size)}
+const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#))}
+const seek	= {fd, delta, whence;	-> sys.lseek(fd castto(sys.fd), delta castto(sys.off), whence castto(sys.whence)) castto(off)}
+const dup2	= {ofd, nfd;	-> sys.dup2(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
+
+/* path manipulation */
+const mkdir	= {path, mode;	-> sys.mkdir(path, mode)}
+const chdir	= {path;	-> sys.chdir(path) == 0}
+const remove	= {path;	-> sys.unlink(path) == 0}
+
+/* useful/portable bits of uname */
+const getsysinfo = {si
+	sys.uname(&si.uname)
+	si.system = cstrconv(si.uname.system[:])
+	si.version = cstrconv(si.uname.version[:])
+	si.release = cstrconv(si.uname.release[:])
+	si.arch = cstrconv(si.uname.machine[:])
+}
+
+/* process stuff */
+const getpid	= {;		-> sys.getpid() castto(pid)}
+const suicide	= {;		sys.kill(sys.getpid(), 6)}	/* kill self with sigabort */
+const fork	= {;		-> sys.fork() castto(pid)}
+const execv	= {cmd, args;	-> sys.execv(cmd, args)}
+const execve	= {cmd, args, env;	-> sys.execve(cmd, args, env)}
+const sleep	= {time;	sys.sleep(time)}
+
+/* memory stuff */
+const getmem	= {sz;		-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)}
+const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
+const curtime = {
+	var tm, sec, nsec
+
+	if sys.clock_gettime(`sys.Clockrealtime, &tm) == 0
+		sec = tm.sec
+		nsec = tm.nsec castto(uint64)
+		-> (sec*1_000_000 + nsec/1000) castto(time)
+	else
+		-> -1
+	;;
+}
+
+const fexists = {path
+	var sb
+
+	-> sys.stat(path, &sb) == 0
+}
+
+const fmtime = {path
+	var sb
+	var sec, nsec
+
+	if sys.stat(path, &sb) == 0
+		sec = sb.mtime.sec castto(time)
+		nsec = sb.mtime.nsec castto(time)
+		-> `Some sec*1000 + nsec/1_000_000
+	else
+		-> `None
+	;;
+}
+
+const fsize = {path
+	var sb
+
+	if sys.stat(path, &sb) == 0
+		-> `Some (sb.size castto(off))
+	else
+		-> `None
+	;;
+}
--- /dev/null
+++ b/lib/std/syswrap-ss+linux.myr
@@ -1,0 +1,22 @@
+use sys
+use "errno.use"
+
+pkg std =
+	const exit	: (status:int -> void)
+	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
+;;
+
+const exit	= {status;	sys.exit_group(status)}
+const bgetcwd	= {buf;
+	var err
+	err = sys.getcwd(buf) castto(errno)
+	/*
+	if we got a length back, it includes
+	the nul byte. chop that off.
+	*/
+	if err > 0
+		-> err - 1
+	else
+		-> err
+	;;
+}
--- /dev/null
+++ b/lib/std/syswrap-ss+osx.myr
@@ -1,0 +1,35 @@
+use sys
+use "errno.use"
+use "cstrconv.use"
+use "slcp.use"
+use "die.use"
+
+pkg std =
+	const exit	: (status:int -> void)
+	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
+;;
+
+const exit	= {status;	sys.exit(status)}
+const bgetcwd	= {buf
+	var path : byte[sys.Maxpathlen]
+	var fd, len, err
+
+	fd = sys.open(".", sys.Ordonly)
+	if fd < 0
+		-> fd castto(errno)
+	;;
+	/* 
+	FIXME: if the path is longer than sys.Pathmax, we should fall back to
+	the ugly method of finding the path.
+	*/
+	err = sys.fcntl(fd, sys.Fgetpath, path[:] castto(byte#)) castto(errno)
+	if err < 0
+		-> err
+	;;
+	len = cstrlen(path[:])
+	if len >= buf.len
+		-> Erange
+	;;
+	slcp(buf[:len], path[:len])
+	-> len castto(errno)
+}
--- /dev/null
+++ b/lib/std/syswrap-ss+plan9.myr
@@ -1,0 +1,56 @@
+use sys
+
+use "errno.use"
+use "cstrconv.use"
+
+pkg std =
+	const exit	: (status : int -> void)
+	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
+;;
+
+const bgetcwd = {buf
+	var fd
+
+	fd = sys.open(".", sys.Ordonly)
+	if fd < 0
+		-> fd castto(errno)
+	;;
+
+	if sys.fd2path(fd, buf) == 0
+		/*
+		Because we don't return the size, the best we can do is
+		assume that if the buffer is completely full, we have
+		truncated it. Since we truncate at utf8 characters, we
+		can have at most 3 bytes truncated (4 bytes will fit
+		any utf8 char), and one byte for the nul terminator.
+		*/
+		if cstrlen(buf) + 5 == buf.len
+			-> Erange
+		else
+			-> cstrlen(buf) castto(errno)
+		;;
+	;;
+	-> Emisc
+}
+
+const digitchars = "0123456789"
+const exit	= {status
+	var buf : byte[32]	/* big enough for exit status numbers */
+	var n, i
+	
+	if status == 0
+		sys.exits("")
+	else
+		status &= 255
+		i = 100
+		n = 0
+		while i > 0
+			if status >= i
+				buf[n++] = digitchars[(status/i)%10]
+			;;
+			i /= 10
+		;;
+		sys.exits(buf[:n])
+	;;
+}
+
--- /dev/null
+++ b/lib/std/test/bigint.myr
@@ -1,0 +1,136 @@
+use std
+
+type cmd = union
+	`Add (cmd#, cmd#)
+	`Sub (cmd#, cmd#)
+	`Mul (cmd#, cmd#)
+	`Div (cmd#, cmd#)
+	`Mod (cmd#, cmd#)
+	`Shl (cmd#, cmd#)
+	`Shr (cmd#, cmd#)
+	`Modpow (cmd#, cmd#, cmd#)
+	`Val byte[:]
+;;
+
+const main = {
+	var a, b, c, d, e
+	var buf : byte[64], n
+
+	/* a few combined ops */
+	a = std.mkbigint(1234)
+	b = std.mkbigint(0x7fffffff)
+	c = std.mkbigint(7919)
+	d = std.mkbigint(113051)
+	e = std.mkbigint(11)
+
+	std.bigmul(a, b)
+	std.bigmul(a, b)
+	std.bigadd(a, c)
+	std.bigsub(a, d)
+	std.bigdiv(a, e)
+
+	std.bigfree(b)
+	std.bigfree(c)
+	std.bigfree(d)
+	std.bigfree(e)
+
+	n = std.bigbfmt(buf[:], a, 0)
+	std.assert(std.sleq(buf[:n], "517347321949036993306"), "simple smoke test failed")
+
+	/* make sure we format '0' correctly */
+	run(std.mk(`Val "0"), "0")
+	/* smoke test for division */
+	run(std.mk(`Div (\
+		std.mk(`Val "1234_5678_1234_6789_6666_7777_8888"), \
+		std.mk(`Val "1234_5678_1234_6789_6666_7777"))), \
+		"10000")
+	run(std.mk(`Div (\
+		std.mk(`Val "0xffff_1234_1234_1234_1234"), \
+		std.mk(`Val "0xf010_1234_2314"))), \
+		"4580035496")
+	run(std.mk(`Div (\
+		std.mk(`Val "5192296858534810493479828944327220"), \
+		std.mk(`Val "75557863709417659441940"))), \
+		"68719476751")
+	run(std.mk(`Div (\
+		std.mk(`Val "75557863709417659441940"), \
+		std.mk(`Val "5192296858534810493479828944327220"))), \
+		"0")
+
+	/* smoke test for mod */
+	run(std.mk(`Mod (\
+		std.mk(`Val "5192296858534810493479828944327220"), \
+		std.mk(`Val "75557863709417659441940"))),\
+		"257025710597479990280")
+
+	run(std.mk(`Modpow (\
+		std.mk(`Val "1"), \
+		std.mk(`Val "3"), \
+		std.mk(`Val "2"))), \
+		"1")
+
+	run(std.mk(`Modpow (\
+		std.mk(`Val "5192296858534810493479828944327220"), \
+		std.mk(`Val "75557863709417659441940"), \
+		std.mk(`Val "755578"))), \
+		"49054")
+	run(std.mk(`Modpow (\
+		std.mk(`Val "7220"), \
+		std.mk(`Val "755578"), \
+		std.mk(`Val "75557863709417659441940"))), \
+		"27076504425474791131220")
+
+}
+
+const run = {e : cmd#, res : byte[:]
+	var buf : byte[4096]
+	var v, n
+
+	v = eval(e)
+	n = std.bigbfmt(buf[:], v, 0)
+	if !std.sleq(buf[:n], res)
+		std.fatal("%s != %s\n", buf[:n], res)
+	;;
+}
+
+const eval = {e : cmd#
+	var buf : byte[2048]
+	var a, b, c	/* scratch vars */
+	var n		/* buf len */
+
+	match e#
+	| `Add (x, y):	-> binop("+", std.bigadd, x, y)
+	| `Sub (x, y):	-> binop("-", std.bigsub, x, y)
+	| `Mul (x, y):	-> binop("*", std.bigmul, x, y)
+	| `Div (x, y):	-> binop("/", std.bigdiv, x, y)
+	| `Mod (x, y):	-> binop("%", std.bigmod, x, y)
+	| `Shl (x, y):	-> binop("<<", std.bigshl, x, y)
+	| `Shr (x, y):	-> binop(">>", std.bigshr, x, y)
+	| `Val x:
+		a = try(std.bigparse(x))
+		n = std.bigbfmt(buf[:], a, 0)
+		-> a
+	| `Modpow (x, y, z):
+		a = eval(x)
+		b = eval(y)
+		c = eval(z)
+		-> std.bigmodpow(a, b, c)
+	;;
+}
+
+const binop = {name, op, x, y
+	var a, b
+
+	a = eval(x)
+	b = eval(y)
+	op(a, b)
+	std.bigfree(b)
+	-> a
+}
+
+generic try = {x : std.option(@a)
+	match x
+	| `std.Some v:	-> v
+	| `std.None:	std.die("failed to get val")
+	;;
+}
--- /dev/null
+++ b/lib/std/test/bytebuf.myr
@@ -1,0 +1,72 @@
+use "bytebuf.use"
+
+/* support */
+use "die.use"
+use "fmt.use"
+use "sleq.use"
+
+const main = {
+	var bb, v
+
+	bb = std.mkbytebuf()
+
+	std.bytebufputc(bb, 'a')
+	std.assert(bb.len == 1, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "a"), \
+		"byte buf contents not \"a\"\n")
+
+	std.bytebufputs(bb, "bc")
+	std.assert(bb.len == 3, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abc"), \
+		"byte buf contents not \"abc\"\n")
+
+	std.bytebufputb(bb, 'd' castto(byte))
+	std.assert(bb.len == 4, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcd"), \
+		"byte buf contents not \"abcd\"\n")
+
+	std.bytebufputle8(bb, 'e' castto(int64))
+	std.assert(bb.len == 5, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcde"), \
+		"byte buf contents not \"abcde\"\n")
+
+	std.bytebufputbe8(bb, 'e' castto(int64))
+	std.assert(bb.len == 6, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdee"), \
+		"byte buf contents not \"abcdee\"\n")
+
+	std.bytebufputle16(bb, ('f' | ('g' << 8)) castto(int64))
+	std.assert(bb.len == 8, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefg"), \
+		"byte buf contents not \"abcdeefg\"\n")
+
+	std.bytebufputbe16(bb, ('f' | ('g' << 8)) castto(int64))
+	std.assert(bb.len == 10, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggf"), \
+		"byte buf contents not \"abcdeefggf\"\n")
+
+	std.bytebufputle32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
+	std.assert(bb.len == 14, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijk"), \
+		"byte buf contents not \"abcdeefggfhijk\"\n")
+
+	std.bytebufputbe32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
+	std.assert(bb.len == 18, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjih"), \
+		"byte buf contents not \"abcdeefggfhijkkji\"\n")
+
+	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
+	v |= v << 32
+	std.bytebufputle64(bb, v)
+	std.assert(bb.len == 26, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjihlmnolmno"), \
+		"byte buf contents not \"abcdeefggfhijkkjihlmnolmno\"\n")
+
+	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
+	v |= v << 32
+	std.bytebufputbe64(bb, v)
+	std.assert(bb.len == 34, "byte buf size wrong\n")
+	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjihlmnolmnoonmlonml"), \
+		"byte buf contents not \"abcdeefggfhijkkjilmnolmnoonmlonml\"\n")
+}
+
--- /dev/null
+++ b/lib/std/test/chartype.myr
@@ -1,0 +1,23 @@
+use std
+
+const main = {
+	std.assert(std.isalpha('a'), "a should be alpha\n")
+	std.assert(std.isupper('A'), "A should be upper\n")
+	std.assert(std.islower('a'), "a should be lower\n")
+	std.assert(std.isdigit('0'), "0 should be isdigit\n")
+	std.assert(std.isnum('\u{0c66}'), "\u{0c66} should be isnum\n")
+	std.assert(std.isalnum('a'), "a should be isalnum\n")
+	std.assert(std.isalnum('0'), "0 should be isalnum\n")
+	std.assert(std.isspace(' '), "' ' should be isspace\n")
+	std.assert(std.isblank(' '), "' ' should be isblank\n")
+
+	std.assert(!std.isalpha('0'), "0 should not be alpha\n")
+	std.assert(!std.isupper('a'), "a should not be upper\n")
+	std.assert(!std.islower('A'), "A should not be lower\n")
+	std.assert(!std.isdigit('a'), "a should not be isdigit\n")
+	std.assert(!std.isnum('a'), " should not be isnum\n")
+	std.assert(!std.isalnum('}'), "a should not be isalnum\n")
+	std.assert(!std.isalnum('!'), "! should not be isalnum\n")
+	std.assert(!std.isspace('@'), "@ should not be isspace\n")
+	std.assert(!std.isblank('@'), "@ should not be isblank\n")
+}
--- /dev/null
+++ b/lib/std/test/fmt.myr
@@ -1,0 +1,34 @@
+use std
+
+const check = {expected, fmt, args : ...
+	var buf : byte[2048]
+	var sl, ap
+
+	ap = std.vastart(&args)
+	sl = std.bfmtv(buf[:], fmt, &ap)
+	if !std.sleq(expected, sl)
+		std.fatal("mismatched fmt: got \"{}\", expected \"{}\"\n", sl, expected)
+	;;
+}
+
+const main = {
+	check("      abcd", "{w=10}", "abcd")
+	check("00000bdcae", "{p=0,w=10}", "bdcae")
+	check("abcdefghijkl", "{p=0,w=10}", "abcdefghijkl")
+	check("a", "{w=0,p=1}", "a")
+	check("        10", "{w=10}", 10)
+	check("0000000010", "{p=0,w=10}", 10)
+	check("4294967295", "{p=0,w=10}", -1 castto(uint))
+	check("-000000001", "{p=0,w=10}", -1)
+	check("xxxxxxxx-1", "{p=x,w=10}", -1)
+	check("        -1", "{w=10}", -1)
+	check("100000"    , "{3}", 100000)
+	check("foobarbaz", "{}bar{}", "foo", "baz")
+	check("{}barbaz", "{{}}bar{}", "baz")
+	check("{barbaz}", "{{bar{}}}", "baz")
+	check("abcd", "{}", "abcd")
+	check("123", "{}", 123)
+	check("7b", "{x}", 123)
+	check("0x7b", "0x{x}", 123)
+}
+
--- /dev/null
+++ b/lib/std/test/htab.myr
@@ -1,0 +1,104 @@
+use std
+
+const insertion = {
+	/*
+	var ht
+	var i
+
+	ht = std.mkht(idhash, ideq)
+	/* only a few values; shouldn't trigger growth */
+	for i = 0; i < 5; i++
+		std.htput(ht, i, i)
+	;;
+	for i = 0; i < 5; i++
+		std.assert(std.htgetv(ht, i, -1) == i, "returned incorrect value from hash table")
+	;;
+
+	/* and grow */
+	for i = 0; i < 5000; i++
+		std.htput(ht, i, i)
+	;;
+	for i = 0; i < 5000; i++
+		std.assert(std.htgetv(ht, i, -1) == i, "returned incorrect value from hash table")
+	;;
+	*/
+}
+
+const deletion = {
+	var ht
+	var i
+
+	ht = std.mkht(idhash, ideq)
+	/* create a hash table with a few hundred values */
+	for i = 0; i < 4000; i++
+		std.htput(ht, i, i)
+	;;
+	for i = 0; i < 200; i++
+		std.htdel(ht, i*2)
+	;;
+	for i = 0; i < 200; i++
+		std.assert(!std.hthas(ht, i*2), "deleted item still present")
+	;;
+	for i = 0; i < 200; i++
+		std.assert(std.hthas(ht, i*2+1), "undeleted item missing")
+	;;
+	for i = 400; i < 4000; i++
+		std.assert(std.hthas(ht, i), "undeleted item missing")
+	;;
+
+}
+
+const collision = {
+	var ht
+	var i
+
+	ht = std.mkht(idhash, ideq)
+	/* insert an element a few hundred times */
+	for i = 0; i < 500; i++
+		std.htput(ht, 0, i)
+	;;
+	std.assert(std.hthas(ht, 0), "inserted element not present")
+	std.assert(std.htgetv(ht, 0, -1) == 499, "inserted element has wrong value")
+	std.htdel(ht, 0)
+	std.assert(!std.hthas(ht, 0), "element left in table")
+}
+
+const tombstonefill = {
+	var ht
+	var i
+
+	ht = std.mkht(idhash, ideq)
+	/* 
+	insert an element into each slot in the hash table, and
+	delete it. With direct hashing, this is guaranteed to have
+	put a tombstone into each slot.
+	*/
+	for i = 0; i <= ht.keys.len; i++
+		std.htput(ht, i, i)
+		std.htdel(ht, i)
+	;;
+	/* make sure we haven't actually got anything in the table */
+	std.assert(ht.nelt == 0, "elements left in hash table")
+	std.assert(!std.hthas(ht, 1), "found phantom element")
+}
+
+const main = {
+	/* only a few elements */
+	std.put("insertion\n")
+	insertion()
+	std.put("deletion\n")
+	deletion()
+	std.put("collision\n")
+	collision()
+
+	/* what happens if we try to fill everything up with tombstones? */
+	tombstonefill()
+}
+
+const idhash = {x
+	-> x
+}
+
+const ideq = {a, b
+	-> a == b
+}
--- /dev/null
+++ b/lib/std/test/ipparse.myr
@@ -1,0 +1,64 @@
+use std
+
+const main = {
+	/* valid ipv4 address */
+	eq("1.2.3.4", `std.Some `std.Ipv4 [1,2,3,4])
+
+	/* invalid ipv4 address */
+	eq("1.3.4", `std.None)	/* too short */
+	eq("1.2.3.4.5", `std.None)	/* too long */
+	eq("1.3.4.256", `std.None)	/* out of bounds 1 */
+	eq("260.2.3.4", `std.None)	/* out of bounds 2 */
+
+	/* valid ipv6 addresses */
+	eq("2a03:2880:2110:df07:face:b00c:0:1", \
+		`std.Some `std.Ipv6 [0x2a, 0x03, 0x28, 0x80, 0x21, 0x10,
+			0xdf, 0xfa, 0xce, 0xb0, 0x0c, 0x00, 0x00, 0x01, 0x01])
+	eq("abcd::dcba", \
+		`std.Some `std.Ipv6 [0xab, 0xcd, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
+	eq("::abcd:dcba", \
+		`std.Some `std.Ipv6 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd, 0xdc, 0xba])
+	eq("::", `std.Some `std.Ipv6 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
+
+	/* invalid ipv4 addresses */
+	eq("2a03:2880:2110:df07:face:b00c:0:1:abc", `std.None)	/* too long */
+	eq("2a03:2880:2110:df07:face:b00c:0", `std.None)	/* too short */
+	eq("2a03:2880:2110:df07:face:b00c:0:1:", `std.None)	/* trailing ':' */
+}
+
+const eq = {ip, expected
+	var parsed
+	var p, e
+
+	parsed = std.ipparse(ip)
+	p = ipbytes(parsed)
+	e = ipbytes(expected)
+	if !std.sleq(p, e)
+		std.fput(1, "misparsed ip {}\n", ip)
+		std.put("parsed: ")
+		for b in p
+			std.put("{x}, ", b)
+		;;
+		std.put("\nexpected: ")
+		for b in e
+			std.put("{x}, ", b)
+		;;
+		std.put("\n")
+		std.fatal("failed\n")
+	;;
+}
+
+const ipbytes = {ipopt
+	match ipopt
+	| `std.Some ip:
+		match ip
+		| `std.Ipv4 b:	-> b[:]
+		| `std.Ipv6 b:	-> b[:]
+		;;
+	| `std.None:	-> [][:]
+	;;
+}
+
--- /dev/null
+++ b/lib/std/test/option.myr
@@ -1,0 +1,43 @@
+use std
+
+const f = {x
+	if x == 123
+		-> `std.Some 42
+	else
+		-> `std.None
+	;;
+}
+
+type t = struct
+	next	: std.option(int)
+;;
+
+const main = {
+	var v, s : t
+	
+	match `std.Some 42
+	| `std.Some x:	std.assert(x == 42, "created wrong value\n")
+	| `std.None:	std.assert(false, "should not be reached\n")
+	;;
+
+	match `std.None
+	| `std.Some x:	std.assert(x, "should not be reached\n")
+	| `std.None:	/* everything ok */
+	;;
+
+	v = f(123)
+	match v
+	| `std.Some x:	std.assert(x == 42, "created wrong value\n")
+	| `std.None:	std.assert(false, "should not be reached\n")
+	;;
+
+	v = f(666)
+	match v
+	| `std.Some x:	std.assert(false, "should not be reached\n")
+	| `std.None:	/* everything ok */
+	;;
+
+	s = [.next = `std.None]
+	s = [.next = `std.Some 123]
+}
+
--- /dev/null
+++ b/lib/std/test/pathjoin.myr
@@ -1,0 +1,61 @@
+use std
+
+const main = {
+	/* untouched */
+	norm("foo", "foo")
+	norm("foo/bar", "foo/bar")
+	norm("/foo/bar", "/foo/bar")
+	norm(".", ".")
+
+	/* empty path becomes "." */
+	norm("", ".")
+
+	/* delete //, trailing / */
+	norm("foo/", "foo")
+	norm("foo//bar/baz", "foo/bar/baz")
+	norm("//foo//bar/", "/foo/bar")
+
+	/* delete '.' */
+	norm("foo/./bar", "foo/bar")
+	norm("/foo/bar/.", "/foo/bar")
+	norm("./foo/bar/.", "foo/bar")
+
+	/* elide '..' */
+	norm("/../foo/bar", "/foo/bar")
+	norm("../../foo/bar", "../../foo/bar")
+	norm("foo/bar/..", "foo")
+	norm("foo/bar/../..", ".")
+	norm("foo/../bar/../..", "..")
+	norm("/foo/../bar/../..", "/")
+
+	/* mix all of the above */
+	norm("/../foo//bar", "/foo/bar")
+	norm("..//../foo/bar", "../../foo/bar")
+	norm("foo//./bar/..", "foo")
+	norm("foo/bar/.././..", ".")
+	norm("//foo/../bar/../..", "/")
+	norm("foo/../bar/../..", "..")
+
+	/* vanilla pathjoin */
+	eq(std.pathcat("a", "b"), "a/b")
+	eq(std.pathjoin(["a", "b", "c"][:]), "a/b/c")
+	/* pathjoin with empty dirs */
+	eq(std.pathcat("", "foo"), "foo")
+	eq(std.pathjoin(["", "foo", "bar"][:]), "foo/bar")
+}
+
+const norm = {a, b
+	var p
+
+	p = std.pathnorm(a)
+	if !std.sleq(p, b)
+		std.fatal("mismatched paths: '{}' => '{}' != '{}'\n", a, p, b)
+	;;
+	std.slfree(p)
+}
+
+const eq = {a, b
+	if !std.sleq(a, b)
+		std.fatal("mismatched paths: '{}' != '{}'\n", a, b)
+	;;
+}
--- /dev/null
+++ b/lib/std/test/search.myr
@@ -1,0 +1,34 @@
+use std
+
+const sl = [1, 3, 5, 8, 9, 33]
+
+const main = {
+
+	expect(std.lsearch(sl[:], 1, std.numcmp), `std.Some 0)
+	expect(std.lsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
+	expect(std.lsearch(sl[:], 5, std.numcmp), `std.Some 2)
+	expect(std.lsearch(sl[:], 6, std.numcmp), `std.None)
+
+	expect(std.bsearch(sl[:], 1, std.numcmp), `std.Some 0)
+	expect(std.bsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
+	expect(std.bsearch(sl[:], 5, std.numcmp), `std.Some 2)
+	expect(std.bsearch(sl[:], 6, std.numcmp), `std.None)
+}
+
+const expect = {a, b
+	match a
+	| `std.None:
+		match b
+		| `std.Some x: std.fatal("Expected `std.None, `std.None, got `std.None, `std.Some %i\n", x)
+		| `std.None:	/* nothing */
+		;;
+	| `std.Some x:
+		match b
+		| `std.None: std.fatal("Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.None\n", x, x, x)
+		| `std.Some y: 
+			if x != y
+				std.fatal("Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.Some %i\n", x, x, x, y)
+			;;
+		;;
+	;;
+}
--- /dev/null
+++ b/lib/std/test/slcp.myr
@@ -1,0 +1,14 @@
+use std
+
+const main = {
+	var a = [1,2,3,4,5]
+	var b = [6,7,8,9,10]
+	var a_cped = [3, 4, 5, 4, 5]
+	var b_cped = [6, 7, 6, 7, 8]
+	
+
+	std.slcp(a[:a.len-2], a[2:])
+	std.slcp(b[2:], b[:b.len-2])
+	std.assert(std.sleq(a[:], a_cped[:]), "slcp of a failed")
+	std.assert(std.sleq(b[:], b_cped[:]), "slcp of a failed")
+}
--- /dev/null
+++ b/lib/std/test/sort.myr
@@ -1,0 +1,38 @@
+use std
+
+const main = {
+	var i
+
+	var a = [ 3, 5, 4, 9, 7, 2, 6, 0, 1, 8, ]
+	var a_sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+	var b = [3, 4, 5, 1, 2, 6, 7, 8, 9, 10]
+	var b_sorted = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+	var c = ["a", "aa", "b", "C", "Cc", "cC", "d", "f", "fuckit", "go",]
+	var c_sorted = ["C", "Cc", "a", "aa", "b", "cC", "d", "f", "fuckit", "go"]
+
+	/* with custom intcmp */
+	std.sort(a[:], intcmp)
+	std.assert(std.sleq(a[:], a_sorted[:]), "a was missorted")
+
+	/* with libstd generic numcmp */
+	std.sort(b[:], std.numcmp)
+	std.assert(std.sleq(b[:], b_sorted[:]), "b was missorted")
+
+	/* string sorting */
+	std.sort(c[:], std.strcmp)
+	for i = 0; i < c.len; i++
+		std.assert(std.sleq(c[i], c_sorted[i]), "c was missorted")
+	;;
+}
+
+const intcmp = {a, b
+	if a < b
+		-> `std.Before
+	elif a == b
+		-> `std.Equal
+	else
+		-> `std.After
+	;;
+}
+
+	
--- /dev/null
+++ b/lib/std/test/strbuf.myr
@@ -1,0 +1,40 @@
+use std
+
+const main = {
+	var sb
+	var buf : byte[16]
+
+	sb = std.mksb()
+	std.assert(std.sleq(std.sbpeek(sb), ""), "mismatched empty str\n")
+	std.sbputs(sb, "hello")
+	std.assert(std.sleq(std.sbpeek(sb), "hello"), "mismatched hello\n")
+	std.sbputs(sb, ", hello")
+	std.assert(std.sleq(std.sbpeek(sb), "hello, hello"), "mismatched double hello\n")
+	std.sbtrim(sb, 7)
+	std.assert(std.sleq(std.sbpeek(sb), "hello, "), "mismatched trim\n")
+	std.sbputs(sb, "world")
+	std.assert(std.sleq(std.sbpeek(sb), "hello, world"), "mismatched hello world\n")
+	std.sbtrim(sb, -5)
+	std.assert(std.sleq(std.sbpeek(sb), "hello, "), "mismatched rtrim\n")
+	std.sbputc(sb, '世')
+	std.sbputc(sb, '界')
+	std.assert(std.sleq(std.sbpeek(sb), "hello, 世界"), "mismatched unicode\n")
+	std.sbputb(sb, 10)
+	std.assert(std.sleq(std.sbpeek(sb), "hello, 世界\n"), "mismatched byte\n")
+
+	sb = std.mkbufsb(buf[:])
+	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 5 characters */
+	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 10 characters */
+	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 15 characters */
+	std.assert(!std.sbputs(sb, "hello"), "erronous success\n") /* 16 characters */
+	std.assert(std.sleq(std.sbpeek(sb), "hellohellohelloh"), "failed to copy as much as possible\n")
+	std.sbtrim(sb, -1)
+	std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "failed rtrim\n")
+	std.sbputc(sb, '世')
+	std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "modified overflowed putc\n")
+	std.sbtrim(sb, -2)
+	std.assert(std.sleq(std.sbpeek(sb), "hellohellohel"), "failed rtrim\n")
+	std.sbputc(sb, '世')
+	std.assert(std.sleq(std.sbpeek(sb), "hellohellohel世"), "failed to append with putc\n")
+}
+
--- /dev/null
+++ b/lib/std/test/try.myr
@@ -1,0 +1,8 @@
+use std
+
+const main = {
+	var x = `std.Some 123
+	var r : std.result(int, byte[:]) = `std.Ok 666
+	std.assert(std.get(x) == 123, "expected 123 from try")
+	std.assert(std.try(r) == 666, "expected 123 from try")
+}
--- /dev/null
+++ b/lib/std/try.myr
@@ -1,0 +1,38 @@
+use "result.use"
+use "option.use"
+use "fmt.use"
+
+pkg std =
+	generic try : (v : result(@a, @b) -> @a)
+	generic tryv : (v : result(@a, @b), d : @a -> @a)
+	generic get : (v : option(@a) -> @a)
+	generic getv : (v : option(@a), d : @a -> @a)
+;;
+
+generic try = {v
+	match v
+	| `Ok x:	-> x
+	| `Fail m:	fatal("error: {}\n", m)
+	;;
+}
+
+generic tryv = {v, d
+	match v
+	| `Ok x:	-> x
+	| `Fail m:	-> d
+	;;
+}
+
+generic get = {v
+	match v
+	| `Some x:	-> x
+	| `None:	fatal("error: option had `None\n")
+	;;
+}
+
+generic getv = {v, d
+	match v
+	| `Some x:	-> x
+	| `None:	-> d
+	;;
+}
--- /dev/null
+++ b/lib/std/types.myr
@@ -1,0 +1,9 @@
+use sys
+
+pkg std =
+	type size	= sys.size	/* spans entire address space */
+	type usize	= sys.usize	/* signed size */
+	type off	= sys.off	/* file offsets */
+	type intptr	= sys.intptr	/* can hold any pointer losslessly */
+	type time	= sys.time	/* milliseconds since epoch */
+;;
--- /dev/null
+++ b/lib/std/units.myr
@@ -1,0 +1,11 @@
+pkg std =
+	/* JEDEC 100B.1 memory sizes */
+	generic KiB	: @a::(integral,numeric)	= 1024 
+	generic MiB	: @a::(integral,numeric)	= KiB*1024
+	generic GiB	: @a::(integral,numeric)	= MiB*1024
+	generic TiB	: @a::(integral,numeric)	= GiB*1024
+	generic PiB	: @a::(integral,numeric)	= TiB*1024
+	generic EiB	: @a::(integral,numeric)	= PiB*1024
+	generic ZiB	: @a::(integral,numeric)	= EiB*1024
+	generic YiB	: @a::(integral,numeric)	= ZiB*1024
+;;
--- /dev/null
+++ b/lib/std/utf.myr
@@ -1,0 +1,103 @@
+use "die.use"
+use "types.use"
+
+pkg std =
+	const Badchar	: char = -1 castto(char)
+	const Maxcharlen : size = 4
+	const Maxcharval : char = 0x10FFFF
+
+	const charlen	: (chr : char -> size)
+	const encode	: (buf : byte[:], chr : char -> size)
+	const decode	: (buf : byte[:] -> char)
+	const striter	: (str : byte[:] -> (char, byte[:]))
+;;
+
+const charlen = {c
+	if c < 0x80
+		-> 1
+	elif c < 0x800
+		-> 2
+	elif c < 0x10000
+		-> 3
+	elif c < 0x200000
+		-> 4
+	else
+		-> -1
+	;;
+}
+
+const encode = {buf, c
+	var len
+	var mark
+	var i
+
+	len = charlen(c)
+	if len < 0 || buf.len < len
+		-> -1
+	;;
+
+	if (len == 1)
+		mark = 0
+	else
+		mark = (((1 << (8 - len)) - 1) ^ 0xff) castto(char)
+	;;
+
+	for i = len - 1; i > 0; i--
+		buf[i] = (c & 0x3f | 0x80) castto(byte)
+		c >>= 6
+	;;
+
+	buf[0] = (c | mark) castto(byte)
+	-> len
+}
+
+const decode = {buf
+	var c
+	var b
+
+	(c, b) = striter(buf)
+	-> c
+}
+
+const striter = {str
+	var len
+	var mask
+	var chr
+	var i
+	var c
+	var tmp
+
+	if str.len == 0
+		/* empty string: no resync needed */
+		-> (Badchar, str)
+	;;
+	c = str[0]
+	len = 0
+	if c & 0x80 == 0	/* 0b0xxx_xxxx */
+		len = 1
+	elif c & 0xe0 == 0xc0	/* 0b110x_xxxx */
+		len = 2
+	elif c & 0xf0 == 0xe0 	/* 0b1110_xxxx */
+		len = 3
+	elif c & 0xf8 == 0xf0 	/* 0b1111_0xxx */
+		len = 4
+	else
+		/* skip one char forward so we can try
+		   resyncing the character stream */
+		-> (Badchar, str[1:])
+	;;
+
+	if len == 0 || len > str.len
+		/* again, we want to try to resync */
+		-> (Badchar, str[1:])
+	;;
+
+	mask = (1 << (8 - len)) - 1
+	chr = (c castto(uint32)) & mask
+	for i = 1; i < len; i++
+		tmp = str[i] castto(uint32)
+		chr = (chr << 6) | (tmp & 0x3f)
+	;;
+
+	-> (chr castto(char), str[len:])
+}
--- /dev/null
+++ b/lib/std/util+plan9-x64.s
@@ -1,0 +1,64 @@
+/*
+ * Allocates a C string on the stack, for
+ * use within system calls, which is the only
+ * place the Myrddin stack should need nul-terminated
+ * strings.
+ *
+ * This is in assembly, because for efficiency we
+ * allocate the C strings on the stack, and don't adjust
+ * SP when returning.
+ */
+TEXT sys$cstring+0(SB),$0
+	/* save registers */
+	MOVQ	SP,AX
+	SUBQ	$40,SP
+	MOVQ	BP,-8(AX)
+	MOVQ	R15,-16(AX)
+	MOVQ	SI,-24(AX)
+	MOVQ	DI,-32(AX)
+	MOVQ	CX,-40(AX)
+	MOVQ	AX,BP
+
+	MOVQ 	(BP),R15	/* ret addr */
+	MOVQ	8(BP),SI	/* src */
+	MOVQ	16(BP),CX	/* len */
+
+	SUBQ	CX,SP		/* get stack */
+	SUBQ	$1,SP		/* +1 for nul */
+	MOVQ	SP,DI		/* dest */
+	MOVQ	SP,AX		/* ret val */
+	ANDQ	$(~15),SP	/* align */
+	SUBQ	$32,SP		/* "unpop" the args and make room for return addr */
+
+	CLD
+	REP
+	MOVSB
+	MOVB	$0,(DI)		/* terminate */
+
+	/* Restore registers */
+	MOVQ	R15,0(SP)	/* place ret addr */
+	MOVQ	-40(BP),CX
+	MOVQ	-32(BP),DI
+	MOVQ	-24(BP),SI
+	MOVQ	-16(BP),R15
+	MOVQ	-8(BP) ,BP
+	RET
+
+TEXT sys$alloca+0(SB),$0
+	/* save registers */
+	MOVQ	(SP),R10	/* ret addr */
+
+	/* get stack space */
+	SUBQ	DI,SP		/* get stack space */
+	MOVQ	SP,AX		/* top of stack (return value) */
+	ANDQ	$(~15),SP	/* align */
+	SUBQ	$32,SP		/* "unpop" the args, and make room for ret addr */
+
+	MOVQ	R10,(SP)	/* place ret addr */
+	RET
+
+GLOBL	sys$tosptr+0(SB),$8
+DATA	sys$tosptr+0(SB)/8,$_tos+0(SB)
+GLOBL	sys$curbrk+0(SB),$8
+DATA	sys$curbrk+0(SB)/8,$end+0(SB)
+
--- /dev/null
+++ b/lib/std/util+posixy-x64.s
@@ -1,0 +1,72 @@
+/*
+ * Allocates a C string on the stack, for
+ * use within system calls, which is the only
+ * place the Myrddin stack should need nul-terminated
+ * strings.
+ *
+ * This is in assembly, because for efficiency we
+ * allocate the C strings on the stack, and don't adjust
+ * %rsp when returning.
+ */
+.globl sys$cstring
+.globl _sys$cstring
+_sys$cstring:
+sys$cstring:
+	/* save registers */
+	pushq %rbp
+	movq %rsp,%rbp
+	pushq %r15
+	pushq %rsi
+	pushq %rdi
+	pushq %rcx
+
+	movq 8(%rbp),%r15	/* ret addr */
+	movq 16(%rbp),%rsi	/* src */
+	movq 24(%rbp),%rcx	/* len */
+
+	subq %rcx,%rsp		/* get stack */
+	subq $1,%rsp		/* +1 for nul */
+	movq %rsp,%rdi		/* dest */
+	movq %rsp,%rax		/* ret val */
+	subq $31,%rsp		/* "unpop" the args */
+	andq $(~15),%rsp	/* align */
+
+	cld
+	rep movsb
+	movb $0,(%rdi)		/* terminate */
+
+	pushq %r15		/* ret addr */
+
+	/* restore registers */
+	movq -32(%rbp),%rcx
+	movq -24(%rbp),%rdi
+	movq -16(%rbp),%rsi
+	movq -8(%rbp),%r15
+	movq (%rbp),%rbp
+	ret
+
+.globl sys$alloca
+.globl _sys$alloca
+_sys$alloca:
+sys$alloca:
+	/* save registers */
+	pushq %rbp
+	movq %rsp,%rbp
+	pushq %r15
+	pushq %rbx
+
+	movq 8(%rbp),%r15	/* ret addr */
+
+	/* get stack space */
+	subq %rdi,%rsp		/* get stack space */
+	movq %rsp,%rax		/* top of stack (return value) */
+	subq $31,%rsp		/* "unpop" the args for return */
+	andq $(~15),%rsp	/* align */
+
+	pushq %r15		/* ret addr */
+
+	/* restore registers */
+	movq -16(%rbp),%rbx
+	movq -8(%rbp),%r15
+	movq (%rbp),%rbp
+	ret
--- /dev/null
+++ b/lib/std/varargs.myr
@@ -1,0 +1,105 @@
+use "types.use"
+use "introspect.use"
+use "sleq.use"
+use "die.use"
+
+pkg std =
+	type valist
+
+	const vastart	: (args : ...# -> valist)
+	const vatype	: (ap : valist# -> byte[:])
+	const vabytes	: (ap : valist# -> byte[:])
+	generic vanext	: (ap : valist# -> @a)
+;;
+
+type valist = struct
+	args	: byte#
+	tc	: typecursor
+;;
+
+/* 
+ * a valist is really just a pointer to the varargs.
+ * we assume that these sit on the stack nicely,
+ * and don't need special handling to get to.
+ * 
+ * This will be a problem when we switch to a
+ * register based convention. We might want to
+ * force varargs onto the stack regardless.
+ */
+const vastart = {args
+	var tc, a, ip
+
+	/*
+	pull out the args. These are on the stacks like so:
+
+		[ required ]
+		[   args   ]
+	       ---variadic--- 
+		[ typeinfo ] --> type description
+	        ------------
+		[ variadic ]
+		[   args   ]
+		[   here   ]
+
+	&args points to the typeinfo, &args + sizeof(void#)
+	points to the rest argument.
+	*/
+		
+	tc = typeenc(args)
+	ip = (args castto(intptr)) + sizeof(byte#)
+	a = ip castto(byte#)
+	-> [.args = a, .tc = tc]
+}
+
+const vatype = {ap
+	-> tcpeek(&ap.tc)
+}
+
+const vabytes = {ap
+	var sl
+	var ti, align, sz
+	var p
+
+	ti = typeinfo(tcpeek(&ap.tc))
+
+	/* apply the alignment to the arg pointer */
+	align = ti.align castto(intptr)
+	p = ap.args castto(intptr)
+	p = (p + align - 1) & ~(align - 1)
+	ap.args = p castto(byte#)
+
+	sl = ap.args[:ti.size]
+	tcnext(&ap.tc)
+
+	sz = ti.size castto(intptr)
+	ap.args = ((p castto(intptr)) + sz) castto(byte#)
+
+	-> sl
+}
+
+const inspectarg = {x
+}
+
+generic vanext = {ap -> @a
+	var v : @a
+	var ti
+	var align
+	var p
+
+	ti = typeinfo(tcpeek(&ap.tc))
+
+	/* apply the alignment to the arg pointer */
+	align = ti.align castto(intptr)
+	inspectarg(align)
+	p = ap.args castto(intptr)
+	p = (p + align - 1) & ~(align - 1)
+	ap.args = p castto(byte#)
+
+	v = (ap.args castto(@a#))#
+	/* TODO: check for type mismatch */
+	tcnext(&ap.tc)
+
+	/* only move on after we read through the value */
+	ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)
+	-> v
+}
--- /dev/null
+++ b/lib/std/wait+plan9.myr
@@ -1,0 +1,94 @@
+use sys
+
+use "alloc.use"
+use "chartype.use"
+use "die.use"
+use "extremum.use"
+use "hashfuncs.use"
+use "hasprefix.use"
+use "htab.use"
+use "intparse.use"
+use "option.use"
+use "strsplit.use"
+use "syswrap.use"
+use "utf.use"
+
+pkg std =
+	type waitstatus = union
+		`Wsuccess
+		`Wfailure
+		`Wsignalled
+		`Waiterror
+	;;
+
+	const wait	: (pid : pid -> waitstatus)
+;;
+
+var statusinit	: bool = false
+var statusmap	: htab(pid, waitstatus)#
+
+const wait = {pid
+	var buf : byte[512]
+	var xpid, status
+	var n
+
+	if !statusinit
+		statusmap = mkht(pidhash, pideq)
+		statusinit = true
+	;;
+		
+	match htget(statusmap, pid)
+	| `Some st:
+		htdel(statusmap, pid)
+		-> st
+	| `None:	/* nothing */
+	;;
+
+	while true
+		n = sys.await(buf[:])
+		if n < 0
+			-> `Waiterror
+		;;
+
+		(status, xpid) = parsestatus(buf[:n])
+		if xpid == pid
+			-> status
+		else
+			htput(statusmap, pid, status)
+		;;
+	;;
+	/* impossible */
+	-> `Waiterror
+}
+
+const parsestatus = {status	-> (waitstatus, pid)
+	var st : waitstatus, xpid, sp
+
+	sp = strsplit(status, " ")
+	if sp.len == 0
+		slfree(sp)
+		-> (`Wfailure, -1)
+	;;
+
+	match intparse(sp[0])
+	| `Some pid:
+		xpid = pid
+		if sp.len == 4 || (sp.len == 5 && sp[4].len > 0)	/* we exited with nil */
+			st = `Wsuccess
+		elif sp.len == 5	/* we have a status */
+			st = `Wfailure
+		else	/* we have a malformed await message */
+			st = `Waiterror
+		;;
+	| `None:
+		xpid = -1
+		st = `Waiterror
+	;;
+
+	slfree(sp)
+	-> (st, xpid)
+
+}
+
+const pidhash	= {x;	-> inthash(x castto(int32))}
+const pideq	= {a, b;	-> a == b}
\ No newline at end of file
--- /dev/null
+++ b/lib/std/wait+posixy.myr
@@ -1,0 +1,41 @@
+use sys
+
+use "die.use"
+use "syswrap.use"
+
+pkg std =
+	type waitstatus = union
+		`Wsuccess
+		`Wfailure
+		`Wsignalled
+		`Waiterror
+	;;
+
+	const wait	: (pid : pid -> waitstatus)
+;;
+
+const wait = {pid
+	var st
+
+:again
+	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
+		match sys.waitstatus(st)
+		/* 
+		when a process stops, eg, if paused by a debugger,
+		wait() will return. This API is for waiting until
+		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
+			;;
+		;;
+	;;
+	-> `Waiterror
+}
+
--- a/libbio/bio.myr
+++ /dev/null
@@ -1,502 +1,0 @@
-use std
-
-pkg bio =
-	type mode = int
-	const Rd	: mode = 1
-	const Wr	: mode = 2
-	const Rw	: mode = 1 | 2
-
-	type file = struct
-		/* backing fd */
-		fd	: std.fd
-		mode	: mode
-
-		/* read buffer */
-		rbuf	: byte[:]
-		rstart	: std.size
-		rend	: std.size
-
-		/* write buffer */
-		wbuf	: byte[:]
-		wend	: std.size
-	;;
-
-	/* creation */
-	const mkfile	: (fd : std.fd, mode : mode	-> file#)
-	const open	: (path : byte[:], mode : mode	-> std.result(file#, byte[:]))
-	const dial	: (srv	: byte[:], mode : mode	-> std.result(file#, byte[:]))
-	const create	: (path : byte[:], mode : mode, perm : int	-> std.result(file#, byte[:]))
-	const close	: (f : file# -> bool)
-	const free	: (f : file# -> void)
-
-	/* basic i/o. Returns sub-buffer when applicable. */
-	const write	: (f : file#, src : byte[:]	-> std.size)
-	const read	: (f : file#, dst : byte[:]	-> std.option(byte[:]))
-	const flush	: (f : file# -> bool)
-
-	/* seeking */
-
-	/* single unit operations */
-	const putb	: (f : file#, b : byte	-> std.size)
-	const putc	: (f : file#, c : char	-> std.size)
-	const getb	: (f : file# -> std.option(byte))
-	const getc	: (f : file# -> std.option(char))
-
-	/* peeking */
-	const peekb	: (f : file# -> std.option(byte))
-	const peekc	: (f : file# -> std.option(char))
-
-	/* delimited read; returns freshly allocated buffer. */
-	const readln	: (f : file#	-> std.option(byte[:]))
-	const readto	: (f : file#, delim : byte[:]	-> std.option(byte[:]))
-	const skipto	: (f : file#, delim : byte[:]	-> bool)
-
-	/* formatted i/o */
-	const put	: (f : file#, fmt : byte[:], args : ... -> std.size)
-
-	/* pkg funcs */
-	pkglocal const ensureread	: (f : file#, n : std.size -> bool)
-	pkglocal const ensurewrite	: (f : file#, n : std.size -> bool)
-;;
-
-const Bufsz = 16*std.KiB
-const Small = 512
-
-/* Creates a file from an fd, opened in the given mode. */
-const mkfile = {fd, mode
-	var f
-
-	f = std.alloc()
-
-	f.fd = fd
-	f.mode = mode
-	if mode & Rd != 0
-		f.rbuf = std.slalloc(Bufsz)
-		f.rstart = 0
-		f.rend = 0
-	;;
-	if mode & Wr != 0
-		f.wbuf = std.slalloc(Bufsz)
-		f.wend = 0
-	;;
-	-> f
-}
-
-/* Opens a file with mode provided. */
-const open = {path, mode 
-	-> sysopen(path, mode, sysmode(mode), 0o777)
-}
-
-/*
-   Creates a file for the provided path, with opened in
-   the requested mode, with the requested permissions
-*/
-const create = {path, mode, perm
-	-> sysopen(path, mode, sysmode(mode) | std.Ocreat | std.Otrunc, perm)
-}
-
-/* dial the server, and open a file using the returned fd */
-const dial = {srv, mode
-	match std.dial(srv)
-	| `std.Ok sock:	-> `std.Ok mkfile(sock, mode)
-	| `std.Fail m:	-> `std.Fail m
-	;;
-}
-
-/* map from the bio modes to the unix open modes */
-const sysmode = {mode
-	match mode
-	| Rd:	-> std.Ordonly
-	| Wr:	-> std.Owronly
-	| Rw:	-> std.Ordwr
-	| _:	std.fatal("bio: bad file mode")
-	;;
-	-> 0
-}
-
-/* open the file, and return it */
-const sysopen = {path, mode, openmode, perm
-	var fd
-
-	fd = std.openmode(path, openmode, perm castto(int64))
-	if fd < 0
-		-> `std.Fail "could not open fd"
-	else
-		-> `std.Ok mkfile(fd, mode)
-	;;
-}
-
-/* closes a file, flushing it to the output fd */
-const close = {f
-	var fd
-
-	fd = f.fd
-	free(f)
-	-> std.close(fd) == 0
-}
-
-const free = {f
-	flush(f)
-	if f.mode & Rd != 0
-		std.slfree(f.rbuf)
-	;;
-
-	if f.mode & Wr != 0
-		std.slfree(f.wbuf)
-	;;
-	std.free(f)
-}
-
-/* 
-writes to as much from `src` as possible to a file,
-returning the number of bytes written.
-*/
-const write = {f, src
-	std.assert(f.mode & Wr != 0, "File is not in write mode")
-	/*
-	Tack small writes onto the buffer end. Big ones
-	flush the buffer and then go right to kernel.
-	*/
-	if src.len < (f.wbuf.len - f.wend)
-		std.slcp(f.wbuf[f.wend:f.wend+src.len], src)
-		f.wend += src.len
-		-> src.len
-	else
-		flush(f)
-		-> writebuf(f.fd, src)
-	;;
-}
-
-/*
-reads as much into 'dst' as possible, up to the size of 'dst',
-returning the number of bytes read.
-*/
-const read = {f, dst
-	var n
-	var d
-	var count
-
-	std.assert(f.mode & Rd != 0, "File is not in read mode")
-	/* 
-	 * small reads should try to fill, so we don't have to make a
-	 * syscall for every read
-	 */
-	if dst.len < Small
-		fill(f, f.rbuf.len - f.rend)
-	;;
-	/* Read as much as we can from the buffer */
-	count = std.min(dst.len, f.rend - f.rstart)
-	std.slcp(dst[:count], f.rbuf[f.rstart:f.rstart+count])
-	f.rstart += count
-
-	/* if we drained the buffer, reset it */
-	if f.rstart == f.rend
-		f.rstart = 0
-		f.rend = 0
-	;;
-
-	/* Read the rest directly from the fd */
-	d = dst[count:]
-	while dst.len > 0
-		n = std.read(f.fd, d)
-		if n <= 0
-			goto readdone
-		;;
-		count += n
-		d = d[n:]
-	;;
-:readdone
-	if count > 0
-		-> `std.Some dst[:count]
-	else
-		-> `std.None
-	;;
-}
-
-/* flushes f out to the backing fd */
-const flush = {f
-	var ret
-
-	ret = true
-	if f.mode & Wr != 0
-		ret = (writebuf(f.fd, f.wbuf[:f.wend]) == f.wend)
-		f.wend = 0
-	;;
-	-> ret
-}
-
-/* writes a single byte to the output stream */
-const putb = {f, b
-	ensurewrite(f, 1)
-	f.wbuf[f.wend++] = b
-	-> 1
-}
-
-/* writes a single character to the output stream, encoded in utf8 */
-const putc = {f, c
-	var sz
-	
-	sz = std.charlen(c)
-	ensurewrite(f, sz)
-	std.encode(f.wbuf[f.wend:], c)
-	f.wend += sz
-	-> sz
-}
-
-/* reads a single byte from the input stream */
-const getb = {f
-	if ensureread(f, 1)
-		-> `std.Some f.rbuf[f.rstart++]
-	;;
-	-> `std.None
-}
-
-/* reads a single character from the input stream, encoded in utf8 */
-const getc = {f
-	var c
-
-	if ensurecodepoint(f)
-		c = std.decode(f.rbuf[f.rstart:f.rend])
-		f.rstart += std.charlen(c)
-		-> `std.Some c
-	;;
-	-> `std.None
-}
-
-/* ensures we have enough to read a single codepoint in the buffer */
-const ensurecodepoint = {f
-	var b
-	var len
-
-	if !ensureread(f, 1)
-		-> false
-	;;
-	b = f.rbuf[f.rstart]
-	if b & 0x80 == 0	/* 0b0xxx_xxxx */
-		len = 1
-	elif b & 0xe0 == 0xc0	/* 0b110x_xxxx */
-		len = 2
-	elif b & 0xf0 == 0xe0 	/* 0b1110_xxxx */
-		len = 3
-	elif b & 0xf8 == 0xf0 	/* 0b1111_0xxx */
-		len = 4
-	else
-		len = 1		/* invalid unicode char */
-	;;
-	-> ensureread(f, len)
-}
-
-/*
-  writes a single integer-like value to the output stream, in
-  little endian format
-*/
-generic putle = {f, v : @a::(numeric,integral)
-	var i
-
-	for i = 0; i < sizeof(@a); i++
-		putb(f, (v & 0xff) castto(byte))
-		v >>= 8
-	;;
-	-> sizeof(@a)
-}
-
-/*
-  writes a single integer-like value to the output stream, in
-  big endian format
-*/
-generic putbe = {f, v : @a::(numeric,integral)
-	var i
-
-	for i = sizeof(@a); i != 0; i--
-		putb(f, ((v >> ((i-1)*8)) & 0xff) castto(byte))
-	;;
-	-> sizeof(@a)
-}
-
-
-/* peeks a single byte from an input stream */
-const peekb = {f
-	if !ensureread(f, 1)
-		-> `std.None
-	else
-		-> `std.Some f.rbuf[f.rstart]
-	;;
-}
-
-/* peeks a single character from a utf8 encoded input stream */
-const peekc = {f
-	if !ensurecodepoint(f)
-		-> `std.None
-	else
-		-> `std.Some std.decode(f.rbuf[f.rstart:f.rend])
-	;;
-}
-
-/*
-  reads up to a single character delimiter. drops the delimiter
-  from the input stream. EOF always counts as a delimiter.
-  
-  Eg, with the input "foo,bar\n"
-
-  	bio.readto(f, ',')	-> "foo"
-  	bio.readto(f, ',')	-> "bar\n"
-*/
-const readto = {f, delim
-	-> readdelim(f, delim, false)
-}
-
-/* same as readto, but drops the read data. */
-const skipto = {f, delim
-	match readdelim(f, delim, true)
-	| `std.Some ret:	-> true
-	| `std.None:	-> false
-	;;
-}
-
-/* Same as readto, but the delimiter is always a '\n' */
-const readln = {f
-	-> readto(f, "\n")
-}
-
-const readdelim = {f, delim, drop
-	var ret
-	var i, j
-
-	ret = [][:]
-	while true
-		if !ensureread(f, delim.len)
-			if !drop
-				ret = readinto(f, ret, f.rend - f.rstart)
-			;;
-			if ret.len > 0
-				-> `std.Some ret
-			else
-				-> `std.None
-			;;
-		;;
-		for i = f.rstart; i < f.rend; i++
-			if f.rbuf[i] == delim[0]
-				for j = 0; j < delim.len; j++
-					if f.rbuf[i + j] != delim[j]
-						goto nextiterread
-					;;
-				;;
-				if !drop
-					ret = readinto(f, ret, i - f.rstart)
-				;;
-				f.rstart += delim.len
-				-> `std.Some ret
-			;;
-:nextiterread
-		;;
-		if !drop
-			ret = readinto(f, ret, f.rend - f.rstart)
-		;;
-	;;
-	std.die("unreachable")
-}
-
-/*
-Same as std.put, but buffered. Returns the number of bytes written.
-
-FIXME: depends on std.fmt() having a flush buffer API. Until then,
-we're stuck with a small static buffer.
-*/
-const put = {f, fmt, args
-	var sl, ap, n
-
-	ap = std.vastart(&args)
-	sl = std.fmtv(fmt, &ap)
-	n = write(f, sl)
-	std.slfree(sl)
-	-> n
-}
-
-/* 
-reads n bytes from the read buffer onto the heap-allocated slice
-provided.
-*/
-const readinto = {f, buf, n
-	var ret
-
-	std.assert(f.rstart + n <= f.rend, "Reading too much from buffer")
-	ret = std.sljoin(buf, f.rbuf[f.rstart:f.rstart + n])
-	f.rstart += n
-	-> ret
-}
-
-/* makes sure we can bufferedly write at least n bytes */
-const ensurewrite = {f, n
-	std.assert(n < f.wbuf.len, "ensured write capacity > buffer size")
-	if n > f.wbuf.len - f.wend
-		-> flush(f)
-	;;
-	-> true
-}
-
-/*
-makes sure we have at least n bytes buffered. returns true if we succeed
-in buffering n bytes, false if we fail.
-*/
-const ensureread = {f, n
-	var held
-	var cap
-
-	std.assert(n < f.rbuf.len, "ensured read capacity > buffer size")
-	held = f.rend - f.rstart
-	if n > held
-		/* if we need to shift the slice down to the start, do it */
-		cap = f.rend - f.rstart
-		if n > (cap + held)
-			std.slcp(f.rbuf[:cap], f.rbuf[f.rstart:f.rend])
-			f.rstart = 0
-			f.rend = cap
-		;;
-		-> fill(f, n) > n
-	else
-		-> true
-	;;
-}
-
-/* blats a buffer to an fd */
-const writebuf = {fd, src
-	var n
-	var count
-
-	count = 0
-	while src.len != 0
-		n = std.write(fd, src)
-		if n <= 0
-			goto writedone
-		;;
-		count += n
-		src = src[n:]
-	;;
-:writedone
-	-> count
-}
-
-
-
-/*
-Reads as many bytes as possible from the file into
-the read buffer.
-*/
-const fill = {f, min
-	var n
-	var count
-
-	count = 0
-	while count < min
-		n = std.read(f.fd, f.rbuf[f.rend:])
-		if n <= 0
-			goto filldone
-		;;
-		count += n
-		f.rend += n
-	;;
-:filldone
-	-> count
-}
-
-
--- a/libbio/bld.sub
+++ /dev/null
@@ -1,7 +1,0 @@
-lib bio = 
-	bio.myr
-	geti.myr
-	puti.myr
-
-        lib ../libstd:std
-;;
--- a/libbio/configure
+++ /dev/null
@@ -1,52 +1,0 @@
-#!/bin/sh
-
-prefix="/usr/local"
-
-for i in `seq 300`; do
-    echo "Lots of output to emulate automake... ok"
-    echo "Testing for things you'll never use... fail"
-    echo "Satisfying the fortran77 lobby... ok"
-    echo "Burning CPU time checking for the bloody obvious... ok"
-done
-echo "Automake emulated successfully"
-
-INST_ROOT='/usr/local'
-
-for arg in $*; do
-    shift 1
-    case $arg in
-        "--prefix" | "-p")
-            prefix=shift $*
-            ;;
-        --prefix=*)
-            prefix=`echo $arg | sed 's/^--prefix=//g'`
-            ;;
-        "--help" | "-h")
-            echo "Usage:"
-            echo "      --prefix | -p: The prefix to install to"
-            break;
-            ;;
-        *) echo "Unrecognized argument $arg";;
-    esac
-done
-
-OS=`uname`
-
-echo export INST_ROOT=$prefix > config.mk
-case $OS in
-    *Linux*)
-        echo 'export SYS=linux' >> config.mk
-        ;;
-    *Darwin*)
-        echo 'export SYS=osx' >> config.mk
-        ;;
-    *)
-        echo 'Unknown architecture.'
-        ;;
-esac
-
-cat << EOF
-    Building with:
-        prefix=$prefix
-EOF
-
--- a/libbio/geti.myr
+++ /dev/null
@@ -1,63 +1,0 @@
-use std
-
-use "bio.use"
-
-pkg bio =
-	/* unsigned big endian */
-	generic getbe8	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getbe16	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getbe32	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getbe64	: (f : file# -> std.option(@a::(numeric,integral)))
-
-	/* signed big endian */
-	generic getle8	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getle16	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getle32	: (f : file# -> std.option(@a::(numeric,integral)))
-	generic getle64	: (f : file# -> std.option(@a::(numeric,integral)))
-;;
-
-/*
-  reads a single integer-like value to the output stream, in
-  little endian format
-*/
-generic getle = {f, n -> std.option(@a::(numeric,integral))
-	var v, i
-
-	v = 0
-	if !ensureread(f, n)
-		-> `std.None
-	;;
-	for i = 0; i < n; i++
-		v |= (f.rbuf[f.rstart++] castto(uint64)) << (8*(i castto(uint64)))
-	;;
-	-> `std.Some v castto(@a::(numeric,integral))
-}
-
-/*
-  reads a single integer-like value to the output stream, in
-  big endian format
-*/
-generic getbe = {f, n -> std.option(@a::(numeric,integral))
-	var v, i
-
-	v = 0
-	if !ensureread(f,n)
-		-> `std.None
-	;;
-	for i = 0; i < n; i++
-		v <<= 8
-		v |= (f.rbuf[f.rstart++] castto(uint64))
-	;;
-	-> `std.Some v castto(@a::(numeric,integral))
-}
-
-generic getbe8  = {f; -> getbe(f, 1)}
-generic getbe16 = {f; -> getbe(f, 2)}
-generic getbe32 = {f; -> getbe(f, 4)}
-generic getbe64 = {f; -> getbe(f, 8)}
-
-generic getle8  = {f; -> getle(f, 1)}
-generic getle16 = {f; -> getle(f, 2)}
-generic getle32 = {f; -> getle(f, 4)}
-generic getle64 = {f; -> getle(f, 8)}
-
--- a/libbio/puti.myr
+++ /dev/null
@@ -1,62 +1,0 @@
-use std
-
-use "bio.use"
-
-pkg bio =
-	/* unsigned big endian */
-	generic putbe8	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putbe16	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putbe32	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putbe64	: (f : file#, v : @a::(numeric,integral) -> std.size)
-
-	/* unsigned little endian */
-	generic putle8	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putle16	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putle32	: (f : file#, v : @a::(numeric,integral) -> std.size)
-	generic putle64	: (f : file#, v : @a::(numeric,integral) -> std.size)
-;;
-
-generic putbe8  = {f, v; -> putbe(f, v castto(uint64), 1)}
-generic putbe16 = {f, v; -> putbe(f, v castto(uint64), 2)}
-generic putbe32 = {f, v; -> putbe(f, v castto(uint64), 4)}
-generic putbe64 = {f, v; -> putbe(f, v castto(uint64), 8)}
-
-generic putle8  = {f, v; -> putle(f, v castto(uint64), 1)}
-generic putle16 = {f, v; -> putle(f, v castto(uint64), 2)}
-generic putle32 = {f, v; -> putle(f, v castto(uint64), 4)}
-generic putle64 = {f, v; -> putle(f, v castto(uint64), 8)}
-
-const putle = {f, v, n
-	var buf : byte[8]
-
-	if !ensurewrite(f, n)
-		-> 0
-	;;
-	buf[0] = (v >> 0) & 0xff castto(byte)
-	buf[1] = (v >> 8) & 0xff castto(byte)
-	buf[2] = (v >> 16) & 0xff castto(byte)
-	buf[3] = (v >> 24) & 0xff castto(byte)
-	buf[4] = (v >> 32) & 0xff castto(byte)
-	buf[5] = (v >> 40) & 0xff castto(byte)
-	buf[6] = (v >> 48) & 0xff castto(byte)
-	buf[7] = (v >> 56) & 0xff castto(byte)
-	-> write(f, buf[:n])
-}
-
-const putbe = {f, v, n
-	var buf : byte[8]
-
-	if !ensurewrite(f, n)
-		-> 0
-	;;
-	buf[0] = (v >> 56) & 0xff castto(byte)
-	buf[1] = (v >> 48) & 0xff castto(byte)
-	buf[2] = (v >> 40) & 0xff castto(byte)
-	buf[3] = (v >> 32) & 0xff castto(byte)
-	buf[4] = (v >> 24) & 0xff castto(byte)
-	buf[5] = (v >> 16) & 0xff castto(byte)
-	buf[6] = (v >> 8) & 0xff castto(byte)
-	buf[7] = (v >> 0) & 0xff castto(byte)
-	-> write(f, buf[8-n:])
-}
-
--- a/libbio/test/Makefile
+++ /dev/null
@@ -1,20 +1,0 @@
-# don't build anything for 'all'
-all: 
-	$(MAKE) -C ..
-
-check:
-	./runtest.sh
-
-.PHONY: %
-%:
-	./runtest.sh $@
-
-.PHONY: clean
-clean:
-	rm -f testmatch.use testmatch.o
-	@for i in `awk '/^[A-Z]/{print $$2}' tests`; do \
-	    echo rm -f $$i; \
-	    rm -f $$i; \
-	done
-
-install:
--- a/libbio/test/bio-create.myr
+++ /dev/null
@@ -1,13 +1,0 @@
-use std
-use bio
-
-const main = {
-	var f
-
-	std.mkdir("tmpout", 0o755);
-	match bio.create("tmpout/test-create", bio.Wr, 0o644)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Failed to open file\n")
-	;;
-	bio.close(f)
-}
--- a/libbio/test/bio-delim.myr
+++ /dev/null
@@ -1,70 +1,0 @@
-use std
-use bio
-
-const main = {
-	var f
-	var d
-
-	match bio.open("data/lines", bio.Rd)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file\n")
-	;;
-
-	/* read first line */
-	d = readln(f)
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* read second line, should not include \n */
-	d = readln(f)
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* read to ';' */
-	d = readto(f, ";")
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* read to ';'  again */
-	d = readto(f, ";")
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* '--'  this time */
-	d = readto(f, "--")
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* and without the terminator, we should get the remaining text */
-	d = readto(f, "not-there")
-	std.write(1, d)
-	std.write(1, "\n")
-	std.slfree(d)
-
-	/* and now, eof */
-	d = readln(f)
-	d = readto(f, "actually, eof")
-	
-	bio.close(f)
-}
-
-const readln = {f
-	match bio.readln(f)
-	| `std.Some d:	-> d
-	| `std.None:	std.put("eof\n")
-			-> [][:]
-	;;
-}
-
-const readto = {f, delim
-	match bio.readto(f, delim)
-	| `std.Some d:	-> d
-	| `std.None:	std.put("eof\n")
-			-> [][:]
-	;;
-}
--- a/libbio/test/bio-endianrd.myr
+++ /dev/null
@@ -1,57 +1,0 @@
-use std
-use bio
-
-generic try = {opt : std.option(@a::(integral,numeric))-> @a::(integral,numeric)
-	match opt
-	| `std.Some val:	-> val
-	| `std.None:	std.fatal(1, "read failed")
-	;;
-}
-const main = {
-	var b : byte
-	var w : uint16
-	var l : uint32
-	var q : uint64
-	var f
-
-	/* use the expected write data as read data */
-	match bio.open("data/bio-endianwr-expected", bio.Rd)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-	
-	/* byte */
-	/*
-	/* FIXME: compiler bug. multiplication on byte
-	   values is currently broken. */
-	b = 0xaa
-	std.assert(try(bio.getle8(f)) == b, "le byte broken\n")
-	std.assert(try(bio.getbe8(f)) == b, "be byte broken\n")
-	*/
-
-	/* word */
-	w = 0xaabb
-	std.assert(try(bio.getle16(f)) == w, "le word broken\n")
-	std.assert(try(bio.getbe16(f)) == w, "be word broken\n")
-
-	/* long */
-	l = 0xaabbccdd
-	std.assert(try(bio.getle32(f)) == l, "le long broken\n")
-	std.assert(try(bio.getbe32(f)) == l, "be long broken\n")
-
-	/* quad */
-	q = 0x11223344aabbccdd castto(uint64)
-	std.assert(try(bio.getle64(f)) == q, "le quad broken\n")
-	std.assert(try(bio.getbe64(f)) == q, "be quad broken\n")
-
-	/* end of file */
-	match bio.getle64(f)
-	| `std.None:
-	| `std.Some v:	std.die("read past end of file\n")
-	;;
-
-	bio.close(f);
-
-	std.put("success: all reads matched\n")
-}
-
--- a/libbio/test/bio-endianwr.myr
+++ /dev/null
@@ -1,42 +1,0 @@
-use std
-use bio
-
-const main = {
-	var b : byte
-	var w : uint16
-	var l : uint32
-	var q : uint64
-	var f
-
-	match bio.create("tmpout/test-endianwr", bio.Wr, 0o644)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-	
-	/* byte */
-	/*
-	/* FIXME: compiler bug. multiplication on byte
-	   values is currently broken. */
-	b = 0xaa
-	bio.putle(f, b)
-	bio.putbe(f, b)
-	*/
-
-	/* word */
-	w = 0xaabb
-	bio.putle16(f, w)
-	bio.putbe16(f, w)
-
-	/* long */
-	l = 0xaabbccdd
-	bio.putle32(f, l)
-	bio.putbe32(f, l)
-
-	/* quad */
-	q = 0x11223344aabbccdd castto(uint64)
-	bio.putle64(f, q)
-	bio.putbe64(f, q)
-
-	/* and test for flush on close */
-	bio.close(f);
-}
--- a/libbio/test/bio-peek.myr
+++ /dev/null
@@ -1,45 +1,0 @@
-use std
-use bio
-
-const main = {
-	var f
-	/* Must be bigger than a bio buffer (ie, > 64k) */
-	var buf : byte[64*1024]
-
-	match bio.open("data/datafile", bio.Rd)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-	
-	std.assert(peekb(f) == 0x30, "wrong byte value read from datafile")
-	std.assert(peekc(f) == '0', "wrong char value read from datafile")
-
-	bio.read(f, buf[:4])	/* skip ahead 4 bytes */
-	std.assert(peekb(f) == 0x34, "wrong byte value read from datafile")
-	std.assert(peekc(f) == '4', "wrong char value read from datafile")
-
-	bio.read(f, buf[:])	/* skip ahead 64k */
-	std.assert(peekb(f) == 0x30, "wrong byte value read from datafile")
-	std.assert(peekc(f) == '0', "wrong char value read from datafile")
-
-	bio.close(f);
-	std.put("Succeded peeeking values\n")
-}
-
-const peekc = {f
-	match bio.peekc(f)
-	| `std.Some c:	-> c
-	| `std.None:
-		std.put("eof")
-		-> -1
-	;;
-}
-
-const peekb = {f
-	match bio.peekb(f)
-	| `std.Some b:	-> b
-	| `std.None:
-		std.put("eof")
-		-> -1
-	;;
-}
--- a/libbio/test/bio-read.myr
+++ /dev/null
@@ -1,46 +1,0 @@
-use std
-use bio
-
-const main = {
-	var f
-	/* Must be bigger than a bio buffer (ie, > 64k) */
-	var buf : byte[64*1024]
-	var b
-
-	match bio.open("data/datafile", bio.Rd)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-	
-	/* read a 4 byte chunk j*/
-	b = r(f, buf[:4])
-	std.write(1, b)
-	std.write(1, "\n")
-
-	/* read the next 32 bytes */
-	b = r(f, buf[:32])
-	std.write(1, b)
-	std.write(1, "\n")
-
-	/* read a 64k chunk */
-	b = r(f, buf[:])
-	std.write(1, b)
-	std.write(1, "\n")
-
-	/* read to EOF */
-	b = r(f, buf[:])
-	std.write(1, b)
-	std.write(1, "\n")
-
-	/* and fail */
-	b = r(f, buf[:])
-
-	bio.close(f)
-}
-
-const r = {f, buf
-	match bio.read(f, buf)
-	| `std.Some b:	-> b
-	| `std.None:	std.put("eof\n")
-	;;
-}
--- a/libbio/test/bio-unitwr.myr
+++ /dev/null
@@ -1,14 +1,0 @@
-use std
-use bio
-
-const main = {
-	var f
-	match bio.create("tmpout/test-unitwr", bio.Wr, 0o644)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-	bio.putb(f, 42)
-	bio.putc(f, 'ה')
-	bio.putb(f, 0xa)
-	bio.close(f);
-}
--- a/libbio/test/bio-write.myr
+++ /dev/null
@@ -1,33 +1,0 @@
-use std
-use bio
-
-const main = {
-	var i
-	var f
-	/* Must be bigger than a bio buffer (ie, > 64k) */
-	var buf : byte[64*1024]
-
-	match bio.create("tmpout/test-write", bio.Wr, 0o644)
-	| `std.Some bio:	f = bio
-	| `std.None:	std.fatal(1, "Unable to open data file")
-	;;
-
-	/* write a 5 byte chunk */
-	bio.write(f, "test\n")
-
-	/* again */
-	bio.write(f, "test\n")
-
-	/* write a 64k chunk */
-	for i = 0; i < 64*1024; i++
-		buf[i] = 0x31
-	;;
-	bio.write(f, buf[:])
-
-	/* final message after a big burst */
-	bio.write(f, "goodbye\n")
-	bio.flush(f)
-
-	/* and test for flush on close */
-	bio.close(f);
-}
--- a/libbio/test/data/bio-delim-expected
+++ /dev/null
@@ -1,10 +1,0 @@
-first line
-second line
-data with
-semicolons
-
-and
-no-terminator
-
-eof
-eof
--- a/libbio/test/data/bio-endianrd-expected
+++ /dev/null
@@ -1,1 +1,0 @@
-success: all reads matched
--- a/libbio/test/data/bio-endianwr-expected
+++ /dev/null
@@ -1,1 +1,0 @@
-�����̻������̻�D3""3D���
\ No newline at end of file
--- a/libbio/test/data/bio-peek-expected
+++ /dev/null
@@ -1,1 +1,0 @@
-Succeded peeeking values
--- a/libbio/test/data/bio-read-expected
+++ /dev/null
@@ -1,6 +1,0 @@
-0123
-45678901234567890123456789012345
-678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
\ No newline at end of file
-234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
\ No newline at end of file
-
-eof
--- a/libbio/test/data/bio-unitwr-expected
+++ /dev/null
@@ -1,1 +1,0 @@
-*ה
--- a/libbio/test/data/bio-write-expected
+++ /dev/null
@@ -1,3 +1,0 @@
-test
-test
-111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
\ No newline at end of file
--- a/libbio/test/data/datafile
+++ /dev/null
@@ -1,1 +1,0 @@
-012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
\ No newline at end of file
--- a/libbio/test/data/lines
+++ /dev/null
@@ -1,4 +1,0 @@
-first line
-second line
-data with;semicolons;
-and--no-terminator
--- a/libbio/test/runtest.sh
+++ /dev/null
@@ -1,124 +1,0 @@
-#!/bin/bash
-NFAILURES=0
-NPASSES=0
-
-function build {
-    rm -f $1 $1.o $1.s $1.use
-    myrbuild $FLAGS -b $1 $1.myr $EXTRA_SRC
-}
-
-function pass {
-    PASSED="$PASSED $1"
-    NPASSED=$[$NPASSED + 1]
-}
-
-function fail {
-    echo "FAIL: $1"
-    FAILED="$FAILED $1"
-    NFAILED=$[$NFAILED + 1]
-}
-
-function expectstatus {
-    ./$1 $3
-    if [ $? -eq $2 ]; then
-        pass $1
-        return
-    else
-        fail $1
-    fi
-}
-
-function expectprint {
-    if [ "`./$1 $3`" != "$2" ]; then
-        fail $1
-    else
-        pass $1
-    fi
-}
-
-
-function expectcompare {
-    if [ x"" !=  x"$TMPDIR" ]; then 
-        t=$TMPDIR/myrtest-$1-$RANDOM
-    else
-        t=/tmp/myrtest-$1-$RANDOM
-    fi
-    ./$1 $3 > $t
-    if cmp $t data/$1-expected; then
-        pass $1
-    else
-        fail $1
-    fi
-    rm -f $t
-}
-
-function expectfcompare {
-    ./$1 $3
-    if cmp data/$1-expected $2; then
-        pass $1
-    else
-        fail $1
-    fi
-}
-
-function shouldskip {
-  if [ -z $ARGS ]; then
-      return 1
-  fi
-
-  for i in $ARGS; do
-      if [ $i = $1 ]; then
-          return 1
-      fi
-  done
-  return 0
-}
-
-
-# Should build and run
-function B {
-    if shouldskip $1; then
-        return
-    fi
-
-    test="$1"; shift
-    type="$1"; shift
-    res="$1"; shift
-    if [ $# > 0 ]; then
-        args="$1"; shift
-    fi
-    build $test
-    case $type in
-    "E")  expectstatus "$test" "$res" "$input";;
-    "P")  expectprint "$test" "$res" "$input";;
-    "C")  expectcompare "$test" "$res" "$input";;
-    "F")  expectfcompare "$test" "$res" "$args";;
-    esac
-}
-
-# Should fail
-function F {
-    if shouldskip $1; then
-        return
-    fi
-    (build $1) > /dev/null
-    if [ $? -eq '1' ]; then
-        pass $1
-    else
-        fail $1
-    fi
-}
-
-# Should generate a usefile
-function U {
-    return
-}
-
-source tests
-
-echo "PASSED ($NPASSED): $PASSED"
-if [ -z "$NFAILED" ]; then
-    echo "SUCCESS"
-else
-    echo "FAILURES ($NFAILED): $FAILED"
-fi
--- a/libbio/test/tests
+++ /dev/null
@@ -1,31 +1,0 @@
-FLAGS=-I../
-mkdir -p tmpout
-# Format:
-# [B|F] testname [E|P] result
-#    [B|F]: Compiler outcome.
-#	B: Expect that this test will build.
-#	F: Expect that this test will not build.
-#    testname: Test case
-#	The test that will run. We will try to
-#	compile 'testname.myr' to 'testname',
-#	and then execute it, verifying the result
-#    [E|P|C]: Result type
-#	E tells us that the result is an exit status
-#	P tells us that the result is on stdout,
-#         and should be compared to the value on the
-#         line
-#	C tells us that the result is on stdout,
-#         and should be compared to the contents of
-#         the file passed on the line.
-#    result: Result value
-#	What we compare with. This should be self-
-#	evident.
-B bio-create    F	tmpout/test-create
-B bio-read	C
-B bio-write	F	tmpout/test-write
-B bio-delim	C
-B bio-endianwr	F	tmpout/test-endianwr
-B bio-endianrd	C
-B bio-unitwr	F	tmpout/test-unitwr
-B bio-peek	C
-#B bio-fmt	C
--- a/libcryptohash/bld.sub
+++ /dev/null
@@ -1,7 +1,0 @@
-lib cryptohash =
-	md5.myr
-	sha1.myr
-	sha256.myr
-	sha512.myr
-;;
-
--- a/libcryptohash/md5.myr
+++ /dev/null
@@ -1,215 +1,0 @@
-use std
-
-pkg cryptohash =
-	type md5
-
-	const md5	: (data : byte[:] -> byte[16])
-	const md5init	: (st : md5# -> void)
-	const md5add	: (st : md5#, data : byte[:] -> void)
-	const md5fin	: (st : md5# -> byte[16])
-;;
-
-type md5 = struct
-	a : uint32
-	b : uint32
-	c : uint32
-	d : uint32
-	tail : byte[64]
-	msglen : uint64
-
-;;
-
-const md5 = {data
-	var st
-
-	md5init(&st)
-	md5add(&st, data)
-	-> md5fin(&st)
-}
-
-const md5init = {st
-	st.a = 0x67452301
-	st.b = 0xefcdab89
-	st.c = 0x98badcfe
-	st.d = 0x10325476
-        st.msglen = 0
-}
-
-const md5add = {st, data
-	var n, ntail
-
-        ntail = st.msglen % 64
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(64 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail + n], data[:n])
-		data = data[n:]
-		if n + ntail < 64
-			->
-		;;
-		step(st, st.tail[:])
-	;;
-	while data.len >= 64
-		step(st, data[:64])
-		data = data[64:]
-	;;
-	std.slcp(st.tail[:data.len], data)
-}
-
-const md5fin = {st
-	var r : byte[16]
-        var ntail
-
-        /* append first padding block */
-        ntail = st.msglen % 64
-        st.tail[ntail++] = 0x80
-	std.slfill(st.tail[ntail:], 0)
-	if 64 - ntail < 8
-		step(st, st.tail[:])
-        	std.slfill(st.tail[:], 0)
-	;;
-
-        /* append size block */
-	st.tail[56] = ((st.msglen * 8) >> 0)    castto(byte)
-	st.tail[57] = ((st.msglen * 8) >> 8)	castto(byte)
-	st.tail[58] = ((st.msglen * 8) >> 16)	castto(byte)
-	st.tail[59] = ((st.msglen * 8) >> 24)	castto(byte)
-	st.tail[60] = ((st.msglen * 8) >> 32)	castto(byte)
-	st.tail[61] = ((st.msglen * 8) >> 40)	castto(byte)
-	st.tail[62] = ((st.msglen * 8) >> 48)	castto(byte)
-	st.tail[63] = ((st.msglen * 8) >> 56)	castto(byte)
-        step(st, st.tail[:])
-
-	r[0] = (st.a >> 0)	castto(byte)
-	r[1] = (st.a >> 8)	castto(byte)
-	r[2] = (st.a >> 16)	castto(byte)
-	r[3] = (st.a >> 24)	castto(byte)
-	r[4] = (st.b >> 0)	castto(byte)
-	r[5] = (st.b >> 8)	castto(byte)
-	r[6] = (st.b >> 16)	castto(byte)
-	r[7] = (st.b >> 24)	castto(byte)
-	r[8] = (st.c >> 0)	castto(byte)
-	r[9] = (st.c >> 8)	castto(byte)
-	r[10] = (st.c >> 16)	castto(byte)
-	r[11] = (st.c >> 24)	castto(byte)
-	r[12] = (st.d >> 0)	castto(byte)
-	r[13] = (st.d >> 8)	castto(byte)
-	r[14] = (st.d >> 16)	castto(byte)
-	r[15] = (st.d >> 24)	castto(byte)
-	-> r
-}
-
-const step = {st, blk
-	var a, b, c, d
-	var s00, s01, s02, s03, s04, s05, s06, s07
-	var s08, s09, s10, s11, s12, s13, s14, s15
-
-	a = st.a
-	b = st.b
-	c = st.c
-	d = st.d
-
-	s00 = unpack(blk[0:4])
-	s01 = unpack(blk[4:8])
-	s02 = unpack(blk[8:12])
-	s03 = unpack(blk[12:16])
-	s04 = unpack(blk[16:20])
-	s05 = unpack(blk[20:24])
-	s06 = unpack(blk[24:28])
-	s07 = unpack(blk[28:32])
-	s08 = unpack(blk[32:36])
-	s09 = unpack(blk[36:40])
-	s10 = unpack(blk[40:44])
-	s11 = unpack(blk[44:48])
-	s12 = unpack(blk[48:52])
-	s13 = unpack(blk[52:56])
-	s14 = unpack(blk[56:60])
-	s15 = unpack(blk[60:64])
-
-	/* round 1 */
-	a += (d ^ (b & (c ^ d))) + 0xd76aa478 + s00;  a = b + (a <<  7 | a >> 25)
-	d += (c ^ (a & (b ^ c))) + 0xe8c7b756 + s01;  d = a + (d << 12 | d >> 20)
-	c += (b ^ (d & (a ^ b))) + 0x242070db + s02;  c = d + (c << 17 | c >> 15)
-	b += (a ^ (c & (d ^ a))) + 0xc1bdceee + s03;  b = c + (b << 22 | b >> 10)
-	a += (d ^ (b & (c ^ d))) + 0xf57c0faf + s04;  a = b + (a <<  7 | a >> 25)
-	d += (c ^ (a & (b ^ c))) + 0x4787c62a + s05;  d = a + (d << 12 | d >> 20)
-	c += (b ^ (d & (a ^ b))) + 0xa8304613 + s06;  c = d + (c << 17 | c >> 15)
-	b += (a ^ (c & (d ^ a))) + 0xfd469501 + s07;  b = c + (b << 22 | b >> 10)
-	a += (d ^ (b & (c ^ d))) + 0x698098d8 + s08;  a = b + (a <<  7 | a >> 25)
-	d += (c ^ (a & (b ^ c))) + 0x8b44f7af + s09;  d = a + (d << 12 | d >> 20)
-	c += (b ^ (d & (a ^ b))) + 0xffff5bb1 + s10;  c = d + (c << 17 | c >> 15)
-	b += (a ^ (c & (d ^ a))) + 0x895cd7be + s11;  b = c + (b << 22 | b >> 10)
-	a += (d ^ (b & (c ^ d))) + 0x6b901122 + s12;  a = b + (a <<  7 | a >> 25)
-	d += (c ^ (a & (b ^ c))) + 0xfd987193 + s13;  d = a + (d << 12 | d >> 20)
-	c += (b ^ (d & (a ^ b))) + 0xa679438e + s14;  c = d + (c << 17 | c >> 15)
-	b += (a ^ (c & (d ^ a))) + 0x49b40821 + s15;  b = c + (b << 22 | b >> 10)
-
-	/* round 2 */
-	a += (c ^ (d & (b ^ c))) + 0xf61e2562 + s01;  a = b + (a <<  5 | a >> 27)
-	d += (b ^ (c & (a ^ b))) + 0xc040b340 + s06;  d = a + (d <<  9 | d >> 23)
-	c += (a ^ (b & (d ^ a))) + 0x265e5a51 + s11;  c = d + (c << 14 | c >> 18)
-	b += (d ^ (a & (c ^ d))) + 0xe9b6c7aa + s00;  b = c + (b << 20 | b >> 12)
-	a += (c ^ (d & (b ^ c))) + 0xd62f105d + s05;  a = b + (a <<  5 | a >> 27)
-	d += (b ^ (c & (a ^ b))) + 0x02441453 + s10;  d = a + (d <<  9 | d >> 23)
-	c += (a ^ (b & (d ^ a))) + 0xd8a1e681 + s15;  c = d + (c << 14 | c >> 18)
-	b += (d ^ (a & (c ^ d))) + 0xe7d3fbc8 + s04;  b = c + (b << 20 | b >> 12)
-	a += (c ^ (d & (b ^ c))) + 0x21e1cde6 + s09;  a = b + (a <<  5 | a >> 27)
-	d += (b ^ (c & (a ^ b))) + 0xc33707d6 + s14;  d = a + (d <<  9 | d >> 23)
-	c += (a ^ (b & (d ^ a))) + 0xf4d50d87 + s03;  c = d + (c << 14 | c >> 18)
-	b += (d ^ (a & (c ^ d))) + 0x455a14ed + s08;  b = c + (b << 20 | b >> 12)
-	a += (c ^ (d & (b ^ c))) + 0xa9e3e905 + s13;  a = b + (a <<  5 | a >> 27)
-	d += (b ^ (c & (a ^ b))) + 0xfcefa3f8 + s02;  d = a + (d <<  9 | d >> 23)
-	c += (a ^ (b & (d ^ a))) + 0x676f02d9 + s07;  c = d + (c << 14 | c >> 18)
-	b += (d ^ (a & (c ^ d))) + 0x8d2a4c8a + s12;  b = c + (b << 20 | b >> 12)
-
-	/* round 3 */
-	a += (b ^ c ^ d) + 0xfffa3942 + s05;  a = b + (a <<  4 | a >> 28)
-	d += (a ^ b ^ c) + 0x8771f681 + s08;  d = a + (d << 11 | d >> 21)
-	c += (d ^ a ^ b) + 0x6d9d6122 + s11;  c = d + (c << 16 | c >> 16)
-	b += (c ^ d ^ a) + 0xfde5380c + s14;  b = c + (b << 23 | b >>  9)
-	a += (b ^ c ^ d) + 0xa4beea44 + s01;  a = b + (a <<  4 | a >> 28)
-	d += (a ^ b ^ c) + 0x4bdecfa9 + s04;  d = a + (d << 11 | d >> 21)
-	c += (d ^ a ^ b) + 0xf6bb4b60 + s07;  c = d + (c << 16 | c >> 16)
-	b += (c ^ d ^ a) + 0xbebfbc70 + s10;  b = c + (b << 23 | b >>  9)
-	a += (b ^ c ^ d) + 0x289b7ec6 + s13;  a = b + (a <<  4 | a >> 28)
-	d += (a ^ b ^ c) + 0xeaa127fa + s00;  d = a + (d << 11 | d >> 21)
-	c += (d ^ a ^ b) + 0xd4ef3085 + s03;  c = d + (c << 16 | c >> 16)
-	b += (c ^ d ^ a) + 0x04881d05 + s06;  b = c + (b << 23 | b >>  9)
-	a += (b ^ c ^ d) + 0xd9d4d039 + s09;  a = b + (a <<  4 | a >> 28)
-	d += (a ^ b ^ c) + 0xe6db99e5 + s12;  d = a + (d << 11 | d >> 21)
-	c += (d ^ a ^ b) + 0x1fa27cf8 + s15;  c = d + (c << 16 | c >> 16)
-	b += (c ^ d ^ a) + 0xc4ac5665 + s02;  b = c + (b << 23 | b >>  9)
-
-	/* round 4 */
-	a += (c ^ (b | ~d)) + 0xf4292244 + s00;  a = b + (a <<  6 | a >> 26)
-	d += (b ^ (a | ~c)) + 0x432aff97 + s07;  d = a + (d << 10 | d >> 22)
-	c += (a ^ (d | ~b)) + 0xab9423a7 + s14;  c = d + (c << 15 | c >> 17)
-	b += (d ^ (c | ~a)) + 0xfc93a039 + s05;  b = c + (b << 21 | b >> 11)
-	a += (c ^ (b | ~d)) + 0x655b59c3 + s12;  a = b + (a <<  6 | a >> 26)
-	d += (b ^ (a | ~c)) + 0x8f0ccc92 + s03;  d = a + (d << 10 | d >> 22)
-	c += (a ^ (d | ~b)) + 0xffeff47d + s10;  c = d + (c << 15 | c >> 17)
-	b += (d ^ (c | ~a)) + 0x85845dd1 + s01;  b = c + (b << 21 | b >> 11)
-	a += (c ^ (b | ~d)) + 0x6fa87e4f + s08;  a = b + (a <<  6 | a >> 26)
-	d += (b ^ (a | ~c)) + 0xfe2ce6e0 + s15;  d = a + (d << 10 | d >> 22)
-	c += (a ^ (d | ~b)) + 0xa3014314 + s06;  c = d + (c << 15 | c >> 17)
-	b += (d ^ (c | ~a)) + 0x4e0811a1 + s13;  b = c + (b << 21 | b >> 11)
-	a += (c ^ (b | ~d)) + 0xf7537e82 + s04;  a = b + (a <<  6 | a >> 26)
-	d += (b ^ (a | ~c)) + 0xbd3af235 + s11;  d = a + (d << 10 | d >> 22)
-	c += (a ^ (d | ~b)) + 0x2ad7d2bb + s02;  c = d + (c << 15 | c >> 17)
-	b += (d ^ (c | ~a)) + 0xeb86d391 + s09;  b = c + (b << 21 | b >> 11)
-
-	st.a += a
-	st.b += b
-	st.c += c
-	st.d += d
-}
-
-const unpack = {b
-	var v : uint32
-
-	v = ((b[0] castto(uint32)) << 0)
-	v |= ((b[1] castto(uint32)) << 8)
-	v |= ((b[2] castto(uint32)) << 16)
-	v |= ((b[3] castto(uint32)) << 24)
-	-> v
-}
--- a/libcryptohash/sha1.myr
+++ /dev/null
@@ -1,243 +1,0 @@
-use std
-
-pkg cryptohash =
-	type sha1
-
-	const sha1	: (data : byte[:] -> byte[20])
-	const sha1init	: (st : sha1# -> void)
-	const sha1add	: (st : sha1#, data : byte[:] -> void)
-	const sha1fin	: (st : sha1# -> byte[20])
-;;
-
-type sha1 = struct
-	a : uint32
-	b : uint32
-	c : uint32
-	d : uint32
-	e : uint32
-	tail : byte[64]
-	msglen : uint64
-;;
-
-const sha1 = {data
-	var st
-
-	sha1init(&st)
-	sha1add(&st, data)
-	-> sha1fin(&st)
-}
-
-const sha1init = {st
-        st.a = 0x67452301
-        st.b = 0xefcdab89
-        st.c = 0x98badcfe
-        st.d = 0x10325476
-        st.e = 0xc3d2e1f0
-        st.msglen = 0
-}
-
-const sha1add = {st, data
-	var n, ntail
-
-        ntail = st.msglen % 64
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(64 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail + n], data[:n])
-		data = data[n:]
-		if n + ntail < 64
-			->
-		;;
-		step(st, st.tail[:])
-        ;;
-
-	while data.len >= 64
-		step(st, data[:64])
-		data = data[64:]
-        ;;
-
-	std.slcp(st.tail[:data.len], data)
-}
-
-const sha1fin = {st
-	var r : byte[20]
-        var ntail
-
-        /* append first padding block */
-        ntail = st.msglen % 64
-        st.tail[ntail++] = 0x80
-	std.slfill(st.tail[ntail:], 0)
-	if 64 - ntail < 8
-		step(st, st.tail[:])
-        	std.slfill(st.tail[:], 0)
-        ;;
-
-
-        /* append size block */
-	st.tail[56] = ((st.msglen * 8) >> 56)   castto(byte)
-	st.tail[57] = ((st.msglen * 8) >> 48)	castto(byte)
-	st.tail[58] = ((st.msglen * 8) >> 40)	castto(byte)
-	st.tail[59] = ((st.msglen * 8) >> 32)	castto(byte)
-	st.tail[60] = ((st.msglen * 8) >> 24)	castto(byte)
-	st.tail[61] = ((st.msglen * 8) >> 16)	castto(byte)
-	st.tail[62] = ((st.msglen * 8) >> 8)	castto(byte)
-	st.tail[63] = ((st.msglen * 8) >> 0)	castto(byte)
-        step(st, st.tail[:])
-
-	r[0]  = (st.a >> 24)	castto(byte)
-	r[1]  = (st.a >> 16)	castto(byte)
-	r[2]  = (st.a >> 8)	castto(byte)
-	r[3]  = (st.a >> 0)	castto(byte)
-	r[4]  = (st.b >> 24)	castto(byte)
-	r[5]  = (st.b >> 16)	castto(byte)
-	r[6]  = (st.b >> 8)	castto(byte)
-	r[7]  = (st.b >> 0)	castto(byte)
-	r[8]  = (st.c >> 24)	castto(byte)
-	r[9]  = (st.c >> 16)	castto(byte)
-	r[10] = (st.c >> 8)	castto(byte)
-	r[11] = (st.c >> 0)	castto(byte)
-	r[12] = (st.d >> 16)	castto(byte)
-	r[13] = (st.d >> 24)	castto(byte)
-	r[14] = (st.d >> 8)	castto(byte)
-	r[15] = (st.d >> 0)	castto(byte)
-	r[16] = (st.e >> 16)	castto(byte)
-	r[17] = (st.e >> 24)	castto(byte)
-	r[18] = (st.e >> 8)	castto(byte)
-	r[19] = (st.e >> 0)	castto(byte)
-	-> r
-}
-
-const K0 = 0x5a827999
-const K1 = 0x6ed9eba1
-const K2 = 0x8f1bbcdc
-const K3 = 0xCA62C1D6
-const step = {st, msg
-        var a, b, c, d, e
-	var s00, s01, s02, s03, s04, s05, s06, s07
-	var s08, s09, s10, s11, s12, s13, s14, s15
-        var t
-
-        a = st.a
-        b = st.b
-        c = st.c
-        d = st.d
-        e = st.e
-
-        s00 = unpack(msg[ 0: 4])
-        s01 = unpack(msg[ 4: 8])
-        s02 = unpack(msg[ 8:12])
-        s03 = unpack(msg[12:16])
-        s04 = unpack(msg[16:20])
-        s05 = unpack(msg[20:24])
-        s06 = unpack(msg[24:28])
-        s07 = unpack(msg[28:32])
-        s08 = unpack(msg[32:36])
-        s09 = unpack(msg[36:40])
-        s10 = unpack(msg[40:44])
-        s11 = unpack(msg[44:48])
-        s12 = unpack(msg[48:52])
-        s13 = unpack(msg[52:56])
-        s14 = unpack(msg[56:60])
-        s15 = unpack(msg[60:64])
-
-        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s00 + K0;  b = b << 30 | b >> 2
-        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s01 + K0;  a = a << 30 | a >> 2
-        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s02 + K0;  e = e << 30 | e >> 2
-        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s03 + K0;  d = d << 30 | d >> 2
-        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s04 + K0;  c = c << 30 | c >> 2
-        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s05 + K0;  b = b << 30 | b >> 2
-        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s06 + K0;  a = a << 30 | a >> 2
-        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s07 + K0;  e = e << 30 | e >> 2
-        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s08 + K0;  d = d << 30 | d >> 2
-        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s09 + K0;  c = c << 30 | c >> 2
-        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s10 + K0;  b = b << 30 | b >> 2
-        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s11 + K0;  a = a << 30 | a >> 2
-        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s12 + K0;  e = e << 30 | e >> 2
-        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s13 + K0;  d = d << 30 | d >> 2
-        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s14 + K0;  c = c << 30 | c >> 2
-        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s15 + K0;  b = b << 30 | b >> 2
-
-
-        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s00 + K0;  a = a << 30 | a >> 2
-        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s01 + K0;  e = e << 30 | e >> 2
-        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s02 + K0;  d = d << 30 | d >> 2
-        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s03 + K0;  c = c << 30 | c >> 2
-        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s04 + K1;  b = b << 30 | b >> 2
-        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s05 + K1;  a = a << 30 | a >> 2
-        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s06 + K1;  e = e << 30 | e >> 2
-        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s07 + K1;  d = d << 30 | d >> 2
-        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s08 + K1;  c = c << 30 | c >> 2
-        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s09 + K1;  b = b << 30 | b >> 2
-        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s10 + K1;  a = a << 30 | a >> 2
-        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s11 + K1;  e = e << 30 | e >> 2
-        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s12 + K1;  d = d << 30 | d >> 2
-        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s13 + K1;  c = c << 30 | c >> 2
-        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s14 + K1;  b = b << 30 | b >> 2
-        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s15 + K1;  a = a << 30 | a >> 2
-        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s00 + K1;  e = e << 30 | e >> 2
-        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s01 + K1;  d = d << 30 | d >> 2
-        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s02 + K1;  c = c << 30 | c >> 2
-        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s03 + K1;  b = b << 30 | b >> 2
-        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s04 + K1;  a = a << 30 | a >> 2
-        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s05 + K1;  e = e << 30 | e >> 2
-        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s06 + K1;  d = d << 30 | d >> 2
-        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s07 + K1;  c = c << 30 | c >> 2
-
-        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s08 + K2;  b = b << 30 | b >> 2
-        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s09 + K2;  a = a << 30 | a >> 2
-        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s10 + K2;  e = e << 30 | e >> 2
-        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s11 + K2;  d = d << 30 | d >> 2
-        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s12 + K2;  c = c << 30 | c >> 2
-        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s13 + K2;  b = b << 30 | b >> 2
-        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s14 + K2;  a = a << 30 | a >> 2
-        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s15 + K2;  e = e << 30 | e >> 2
-        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s00 + K2;  d = d << 30 | d >> 2
-        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s01 + K2;  c = c << 30 | c >> 2
-        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s02 + K2;  b = b << 30 | b >> 2
-        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s03 + K2;  a = a << 30 | a >> 2
-        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s04 + K2;  e = e << 30 | e >> 2
-        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s05 + K2;  d = d << 30 | d >> 2
-        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s06 + K2;  c = c << 30 | c >> 2
-        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s07 + K2;  b = b << 30 | b >> 2
-        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s08 + K2;  a = a << 30 | a >> 2
-        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s09 + K2;  e = e << 30 | e >> 2
-        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s10 + K2;  d = d << 30 | d >> 2
-        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s11 + K2;  c = c << 30 | c >> 2
-
-        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s12 + K3;  b = b << 30 | b >> 2
-        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s13 + K3;  a = a << 30 | a >> 2
-        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s14 + K3;  e = e << 30 | e >> 2
-        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s15 + K3;  d = d << 30 | d >> 2
-        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s00 + K3;  c = c << 30 | c >> 2
-        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s01 + K3;  b = b << 30 | b >> 2
-        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s02 + K3;  a = a << 30 | a >> 2
-        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s03 + K3;  e = e << 30 | e >> 2
-        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s04 + K3;  d = d << 30 | d >> 2
-        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s05 + K3;  c = c << 30 | c >> 2
-        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s06 + K3;  b = b << 30 | b >> 2
-        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s07 + K3;  a = a << 30 | a >> 2
-        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s08 + K3;  e = e << 30 | e >> 2
-        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s09 + K3;  d = d << 30 | d >> 2
-        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s10 + K3;  c = c << 30 | c >> 2
-        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s11 + K3;  b = b << 30 | b >> 2
-        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s12 + K3;  a = a << 30 | a >> 2
-        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s13 + K3;  e = e << 30 | e >> 2
-        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s14 + K3;  d = d << 30 | d >> 2
-        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s15 + K3;  c = c << 30 | c >> 2
-
-        st.a += a
-        st.b += b
-        st.c += c
-        st.d += d
-        st.e += e
-}
-
-const unpack = {b
-	var v : uint32
-
-	v = ((b[0] castto(uint32)) << 24)
-	v |= ((b[1] castto(uint32)) << 16)
-	v |= ((b[2] castto(uint32)) << 8)
-	v |= ((b[3] castto(uint32)) << 0)
-	-> v
-}
--- a/libcryptohash/sha256.myr
+++ /dev/null
@@ -1,415 +1,0 @@
-use std
-
-pkg cryptohash =
-	type sha256
-	type sha224
-
-	const sha256	: (data : byte[:] -> byte[32])
-	const sha256init	: (st : sha256# -> void)
-	const sha256add	: (st : sha256#, data : byte[:] -> void)
-	const sha256fin	: (st : sha256# -> byte[32])
-
-	const sha224	: (data : byte[:] -> byte[28])
-	const sha224init	: (st : sha224# -> void)
-	const sha224add	: (st : sha224#, data : byte[:] -> void)
-	const sha224fin	: (st : sha224# -> byte[28])
-;;
-
-type sha256 = struct
-	x	: uint32[8]
-	tail	: byte[64]
-	msglen	: uint64
-;;
-
-const sha256 = {data
-	var st
-
-	sha256init(&st)
-	sha256add(&st, data)
-	-> sha256fin(&st)
-}
-
-const sha256init = {st
-	st.x[0] = 0x6A09E667
-	st.x[1] = 0xBB67AE85
-	st.x[2] = 0x3C6EF372
-	st.x[3] = 0xA54FF53A
-	st.x[4] = 0x510e527f
-	st.x[5] = 0x9b05688c
-	st.x[6] = 0x1f83d9ab
-	st.x[7] = 0x5be0cd19
-	st.msglen = 0
-}
-
-const sha256add = {st, data
-	var n, ntail
-
-	ntail = st.msglen % 64
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(64 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail + n], data[:n])
-		data = data[n:]
-		if n + ntail < 64
-			->
-		;;
-		step(st.x[:], st.tail[:])
-	;;
-
-	while data.len >= 64
-		step(st.x[:], data[:64])
-		data = data[64:]
-	;;
-
-	ntail = st.msglen % 64
-	std.slcp(st.tail[:ntail], data)
-}
-
-const sha256fin = {st
-	var r : byte[32]
-
-	tail(st.x[:], st.msglen, st.tail[:])
-
-	pack(r[0:4], st.x[0])
-	pack(r[4:8], st.x[1])
-	pack(r[8:12], st.x[2])
-	pack(r[12:16], st.x[3])
-	pack(r[16:20], st.x[4])
-	pack(r[20:24], st.x[5])
-	pack(r[24:28], st.x[6])
-	pack(r[28:32], st.x[7])
-	-> r
-}
-
-type sha224 = struct
-	x : uint32[8]
-	tail : byte[64]
-	msglen : uint64
-;;
-
-const sha224 = {data
-	var st
-
-	sha224init(&st)
-	sha224add(&st, data)
-	-> sha224fin(&st)
-}
-
-const sha224init = {st
-	st.x[0] = 0xc1059ed8
-	st.x[1] = 0x367cd507
-	st.x[2] = 0x3070dd17
-	st.x[3] = 0xf70e5939
-	st.x[4] = 0xffc00b31
-	st.x[5] = 0x68581511
-	st.x[6] = 0x64f98fa7
-	st.x[7] = 0xbefa4fa4
-	st.msglen = 0
-}
-
-const sha224add = {st, data
-	var n, ntail
-
-	ntail = st.msglen % 64
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(64 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail + n], data[:n])
-		data = data[n:]
-		if n + ntail < 64
-			->
-		;;
-		step(st.x[:], st.tail[:])
-	;;
-
-	while data.len >= 64
-		step(st.x[:], data[:64])
-		data = data[64:]
-	;;
-
-	ntail = st.msglen % 64
-	std.slcp(st.tail[:ntail], data)
-}
-
-const sha224fin = {st
-	var r : byte[28]
-
-	tail(st.x[:], st.msglen, st.tail[:])
-
-	pack(r[0:4], st.x[0])
-	pack(r[4:8], st.x[1])
-	pack(r[8:12], st.x[2])
-	pack(r[12:16], st.x[3])
-	pack(r[16:20], st.x[4])
-	pack(r[20:24], st.x[5])
-	pack(r[24:28], st.x[6])
-	-> r
-}
-
-
-const tail = {x, msglen, tail
-	var ntail
-
-	/* append first padding block */
-	ntail = msglen % 64
-	tail[ntail++] = 0x80
-	std.slfill(tail[ntail:], 0)
-	if 64 - ntail < 8
-		step(x, tail)
-		std.slfill(tail, 0)
-	;;
-
-	/* append size block */
-	tail[56] = ((msglen * 8) >> 56)   castto(byte)
-	tail[57] = ((msglen * 8) >> 48)	castto(byte)
-	tail[58] = ((msglen * 8) >> 40)	castto(byte)
-	tail[59] = ((msglen * 8) >> 32)	castto(byte)
-	tail[60] = ((msglen * 8) >> 24)	castto(byte)
-	tail[61] = ((msglen * 8) >> 16)	castto(byte)
-	tail[62] = ((msglen * 8) >> 8)	castto(byte)
-	tail[63] = ((msglen * 8) >> 0)	castto(byte)
-	step(x, tail)
-}
-
-const step = {x, msg
-	var a, b, c, d, e, f, g, h
-	var s00, s01, s02, s03, s04, s05, s06, s07
-	var s08, s09, s10, s11, s12, s13, s14, s15
-	var s16, s17, s18, s19, s20, s21, s22, s23
-	var s24, s25, s26, s27, s28, s29, s30, s31
-	var s32, s33, s34, s35, s36, s37, s38, s39
-	var s40, s41, s42, s43, s44, s45, s46, s47
-	var s48, s49, s50, s51, s52, s53, s54, s55
-	var s56, s57, s58, s59, s60, s61, s62, s63
-
-	a = x[0]
-	b = x[1]
-	c = x[2]
-	d = x[3]
-	e = x[4]
-	f = x[5]
-	g = x[6]
-	h = x[7]
-
-	s00 = unpack(msg[ 0: 4])
-	s01 = unpack(msg[ 4: 8])
-	s02 = unpack(msg[ 8:12])
-	s03 = unpack(msg[12:16])
-	s04 = unpack(msg[16:20])
-	s05 = unpack(msg[20:24])
-	s06 = unpack(msg[24:28])
-	s07 = unpack(msg[28:32])
-	s08 = unpack(msg[32:36])
-	s09 = unpack(msg[36:40])
-	s10 = unpack(msg[40:44])
-	s11 = unpack(msg[44:48])
-	s12 = unpack(msg[48:52])
-	s13 = unpack(msg[52:56])
-	s14 = unpack(msg[56:60])
-	s15 = unpack(msg[60:64])
-
-	s16 = s00 + s09 + (((s01 << 25) | (s01 >> 7)) ^ ((s01 << 14) | (s01 >> 18)) ^ (s01 >> 3)) + (((s14 << 15) | (s14 >> 17)) ^ ((s14 << (32- 19)) | (s14 >> 19)) ^ (s14 >> 10));
-	s17 = s01 + s10 + (((s02 << 25) | (s02 >> 7)) ^ ((s02 << 14) | (s02 >> 18)) ^ (s02 >> 3)) + (((s15 << 15) | (s15 >> 17)) ^ ((s15 << (32- 19)) | (s15 >> 19)) ^ (s15 >> 10));
-	s18 = s02 + s11 + (((s03 << 25) | (s03 >> 7)) ^ ((s03 << 14) | (s03 >> 18)) ^ (s03 >> 3)) + (((s16 << 15) | (s16 >> 17)) ^ ((s16 << (32- 19)) | (s16 >> 19)) ^ (s16 >> 10));
-	s19 = s03 + s12 + (((s04 << 25) | (s04 >> 7)) ^ ((s04 << 14) | (s04 >> 18)) ^ (s04 >> 3)) + (((s17 << 15) | (s17 >> 17)) ^ ((s17 << (32- 19)) | (s17 >> 19)) ^ (s17 >> 10));
-	s20 = s04 + s13 + (((s05 << 25) | (s05 >> 7)) ^ ((s05 << 14) | (s05 >> 18)) ^ (s05 >> 3)) + (((s18 << 15) | (s18 >> 17)) ^ ((s18 << (32- 19)) | (s18 >> 19)) ^ (s18 >> 10));
-	s21 = s05 + s14 + (((s06 << 25) | (s06 >> 7)) ^ ((s06 << 14) | (s06 >> 18)) ^ (s06 >> 3)) + (((s19 << 15) | (s19 >> 17)) ^ ((s19 << (32- 19)) | (s19 >> 19)) ^ (s19 >> 10));
-	s22 = s06 + s15 + (((s07 << 25) | (s07 >> 7)) ^ ((s07 << 14) | (s07 >> 18)) ^ (s07 >> 3)) + (((s20 << 15) | (s20 >> 17)) ^ ((s20 << (32- 19)) | (s20 >> 19)) ^ (s20 >> 10));
-	s23 = s07 + s16 + (((s08 << 25) | (s08 >> 7)) ^ ((s08 << 14) | (s08 >> 18)) ^ (s08 >> 3)) + (((s21 << 15) | (s21 >> 17)) ^ ((s21 << (32- 19)) | (s21 >> 19)) ^ (s21 >> 10));
-	s24 = s08 + s17 + (((s09 << 25) | (s09 >> 7)) ^ ((s09 << 14) | (s09 >> 18)) ^ (s09 >> 3)) + (((s22 << 15) | (s22 >> 17)) ^ ((s22 << (32- 19)) | (s22 >> 19)) ^ (s22 >> 10));
-	s25 = s09 + s18 + (((s10 << 25) | (s10 >> 7)) ^ ((s10 << 14) | (s10 >> 18)) ^ (s10 >> 3)) + (((s23 << 15) | (s23 >> 17)) ^ ((s23 << (32- 19)) | (s23 >> 19)) ^ (s23 >> 10));
-	s26 = s10 + s19 + (((s11 << 25) | (s11 >> 7)) ^ ((s11 << 14) | (s11 >> 18)) ^ (s11 >> 3)) + (((s24 << 15) | (s24 >> 17)) ^ ((s24 << (32- 19)) | (s24 >> 19)) ^ (s24 >> 10));
-	s27 = s11 + s20 + (((s12 << 25) | (s12 >> 7)) ^ ((s12 << 14) | (s12 >> 18)) ^ (s12 >> 3)) + (((s25 << 15) | (s25 >> 17)) ^ ((s25 << (32- 19)) | (s25 >> 19)) ^ (s25 >> 10));
-	s28 = s12 + s21 + (((s13 << 25) | (s13 >> 7)) ^ ((s13 << 14) | (s13 >> 18)) ^ (s13 >> 3)) + (((s26 << 15) | (s26 >> 17)) ^ ((s26 << (32- 19)) | (s26 >> 19)) ^ (s26 >> 10));
-	s29 = s13 + s22 + (((s14 << 25) | (s14 >> 7)) ^ ((s14 << 14) | (s14 >> 18)) ^ (s14 >> 3)) + (((s27 << 15) | (s27 >> 17)) ^ ((s27 << (32- 19)) | (s27 >> 19)) ^ (s27 >> 10));
-	s30 = s14 + s23 + (((s15 << 25) | (s15 >> 7)) ^ ((s15 << 14) | (s15 >> 18)) ^ (s15 >> 3)) + (((s28 << 15) | (s28 >> 17)) ^ ((s28 << (32- 19)) | (s28 >> 19)) ^ (s28 >> 10));
-	s31 = s15 + s24 + (((s16 << 25) | (s16 >> 7)) ^ ((s16 << 14) | (s16 >> 18)) ^ (s16 >> 3)) + (((s29 << 15) | (s29 >> 17)) ^ ((s29 << (32- 19)) | (s29 >> 19)) ^ (s29 >> 10));
-	s32 = s16 + s25 + (((s17 << 25) | (s17 >> 7)) ^ ((s17 << 14) | (s17 >> 18)) ^ (s17 >> 3)) + (((s30 << 15) | (s30 >> 17)) ^ ((s30 << (32- 19)) | (s30 >> 19)) ^ (s30 >> 10));
-	s33 = s17 + s26 + (((s18 << 25) | (s18 >> 7)) ^ ((s18 << 14) | (s18 >> 18)) ^ (s18 >> 3)) + (((s31 << 15) | (s31 >> 17)) ^ ((s31 << (32- 19)) | (s31 >> 19)) ^ (s31 >> 10));
-	s34 = s18 + s27 + (((s19 << 25) | (s19 >> 7)) ^ ((s19 << 14) | (s19 >> 18)) ^ (s19 >> 3)) + (((s32 << 15) | (s32 >> 17)) ^ ((s32 << (32- 19)) | (s32 >> 19)) ^ (s32 >> 10));
-	s35 = s19 + s28 + (((s20 << 25) | (s20 >> 7)) ^ ((s20 << 14) | (s20 >> 18)) ^ (s20 >> 3)) + (((s33 << 15) | (s33 >> 17)) ^ ((s33 << (32- 19)) | (s33 >> 19)) ^ (s33 >> 10));
-	s36 = s20 + s29 + (((s21 << 25) | (s21 >> 7)) ^ ((s21 << 14) | (s21 >> 18)) ^ (s21 >> 3)) + (((s34 << 15) | (s34 >> 17)) ^ ((s34 << (32- 19)) | (s34 >> 19)) ^ (s34 >> 10));
-	s37 = s21 + s30 + (((s22 << 25) | (s22 >> 7)) ^ ((s22 << 14) | (s22 >> 18)) ^ (s22 >> 3)) + (((s35 << 15) | (s35 >> 17)) ^ ((s35 << (32- 19)) | (s35 >> 19)) ^ (s35 >> 10));
-	s38 = s22 + s31 + (((s23 << 25) | (s23 >> 7)) ^ ((s23 << 14) | (s23 >> 18)) ^ (s23 >> 3)) + (((s36 << 15) | (s36 >> 17)) ^ ((s36 << (32- 19)) | (s36 >> 19)) ^ (s36 >> 10));
-	s39 = s23 + s32 + (((s24 << 25) | (s24 >> 7)) ^ ((s24 << 14) | (s24 >> 18)) ^ (s24 >> 3)) + (((s37 << 15) | (s37 >> 17)) ^ ((s37 << (32- 19)) | (s37 >> 19)) ^ (s37 >> 10));
-	s40 = s24 + s33 + (((s25 << 25) | (s25 >> 7)) ^ ((s25 << 14) | (s25 >> 18)) ^ (s25 >> 3)) + (((s38 << 15) | (s38 >> 17)) ^ ((s38 << (32- 19)) | (s38 >> 19)) ^ (s38 >> 10));
-	s41 = s25 + s34 + (((s26 << 25) | (s26 >> 7)) ^ ((s26 << 14) | (s26 >> 18)) ^ (s26 >> 3)) + (((s39 << 15) | (s39 >> 17)) ^ ((s39 << (32- 19)) | (s39 >> 19)) ^ (s39 >> 10));
-	s42 = s26 + s35 + (((s27 << 25) | (s27 >> 7)) ^ ((s27 << 14) | (s27 >> 18)) ^ (s27 >> 3)) + (((s40 << 15) | (s40 >> 17)) ^ ((s40 << (32- 19)) | (s40 >> 19)) ^ (s40 >> 10));
-	s43 = s27 + s36 + (((s28 << 25) | (s28 >> 7)) ^ ((s28 << 14) | (s28 >> 18)) ^ (s28 >> 3)) + (((s41 << 15) | (s41 >> 17)) ^ ((s41 << (32- 19)) | (s41 >> 19)) ^ (s41 >> 10));
-	s44 = s28 + s37 + (((s29 << 25) | (s29 >> 7)) ^ ((s29 << 14) | (s29 >> 18)) ^ (s29 >> 3)) + (((s42 << 15) | (s42 >> 17)) ^ ((s42 << (32- 19)) | (s42 >> 19)) ^ (s42 >> 10));
-	s45 = s29 + s38 + (((s30 << 25) | (s30 >> 7)) ^ ((s30 << 14) | (s30 >> 18)) ^ (s30 >> 3)) + (((s43 << 15) | (s43 >> 17)) ^ ((s43 << (32- 19)) | (s43 >> 19)) ^ (s43 >> 10));
-	s46 = s30 + s39 + (((s31 << 25) | (s31 >> 7)) ^ ((s31 << 14) | (s31 >> 18)) ^ (s31 >> 3)) + (((s44 << 15) | (s44 >> 17)) ^ ((s44 << (32- 19)) | (s44 >> 19)) ^ (s44 >> 10));
-	s47 = s31 + s40 + (((s32 << 25) | (s32 >> 7)) ^ ((s32 << 14) | (s32 >> 18)) ^ (s32 >> 3)) + (((s45 << 15) | (s45 >> 17)) ^ ((s45 << (32- 19)) | (s45 >> 19)) ^ (s45 >> 10));
-	s48 = s32 + s41 + (((s33 << 25) | (s33 >> 7)) ^ ((s33 << 14) | (s33 >> 18)) ^ (s33 >> 3)) + (((s46 << 15) | (s46 >> 17)) ^ ((s46 << (32- 19)) | (s46 >> 19)) ^ (s46 >> 10));
-	s49 = s33 + s42 + (((s34 << 25) | (s34 >> 7)) ^ ((s34 << 14) | (s34 >> 18)) ^ (s34 >> 3)) + (((s47 << 15) | (s47 >> 17)) ^ ((s47 << (32- 19)) | (s47 >> 19)) ^ (s47 >> 10));
-	s50 = s34 + s43 + (((s35 << 25) | (s35 >> 7)) ^ ((s35 << 14) | (s35 >> 18)) ^ (s35 >> 3)) + (((s48 << 15) | (s48 >> 17)) ^ ((s48 << (32- 19)) | (s48 >> 19)) ^ (s48 >> 10));
-	s51 = s35 + s44 + (((s36 << 25) | (s36 >> 7)) ^ ((s36 << 14) | (s36 >> 18)) ^ (s36 >> 3)) + (((s49 << 15) | (s49 >> 17)) ^ ((s49 << (32- 19)) | (s49 >> 19)) ^ (s49 >> 10));
-	s52 = s36 + s45 + (((s37 << 25) | (s37 >> 7)) ^ ((s37 << 14) | (s37 >> 18)) ^ (s37 >> 3)) + (((s50 << 15) | (s50 >> 17)) ^ ((s50 << (32- 19)) | (s50 >> 19)) ^ (s50 >> 10));
-	s53 = s37 + s46 + (((s38 << 25) | (s38 >> 7)) ^ ((s38 << 14) | (s38 >> 18)) ^ (s38 >> 3)) + (((s51 << 15) | (s51 >> 17)) ^ ((s51 << (32- 19)) | (s51 >> 19)) ^ (s51 >> 10));
-	s54 = s38 + s47 + (((s39 << 25) | (s39 >> 7)) ^ ((s39 << 14) | (s39 >> 18)) ^ (s39 >> 3)) + (((s52 << 15) | (s52 >> 17)) ^ ((s52 << (32- 19)) | (s52 >> 19)) ^ (s52 >> 10));
-	s55 = s39 + s48 + (((s40 << 25) | (s40 >> 7)) ^ ((s40 << 14) | (s40 >> 18)) ^ (s40 >> 3)) + (((s53 << 15) | (s53 >> 17)) ^ ((s53 << (32- 19)) | (s53 >> 19)) ^ (s53 >> 10));
-	s56 = s40 + s49 + (((s41 << 25) | (s41 >> 7)) ^ ((s41 << 14) | (s41 >> 18)) ^ (s41 >> 3)) + (((s54 << 15) | (s54 >> 17)) ^ ((s54 << (32- 19)) | (s54 >> 19)) ^ (s54 >> 10));
-	s57 = s41 + s50 + (((s42 << 25) | (s42 >> 7)) ^ ((s42 << 14) | (s42 >> 18)) ^ (s42 >> 3)) + (((s55 << 15) | (s55 >> 17)) ^ ((s55 << (32- 19)) | (s55 >> 19)) ^ (s55 >> 10));
-	s58 = s42 + s51 + (((s43 << 25) | (s43 >> 7)) ^ ((s43 << 14) | (s43 >> 18)) ^ (s43 >> 3)) + (((s56 << 15) | (s56 >> 17)) ^ ((s56 << (32- 19)) | (s56 >> 19)) ^ (s56 >> 10));
-	s59 = s43 + s52 + (((s44 << 25) | (s44 >> 7)) ^ ((s44 << 14) | (s44 >> 18)) ^ (s44 >> 3)) + (((s57 << 15) | (s57 >> 17)) ^ ((s57 << (32- 19)) | (s57 >> 19)) ^ (s57 >> 10));
-	s60 = s44 + s53 + (((s45 << 25) | (s45 >> 7)) ^ ((s45 << 14) | (s45 >> 18)) ^ (s45 >> 3)) + (((s58 << 15) | (s58 >> 17)) ^ ((s58 << (32- 19)) | (s58 >> 19)) ^ (s58 >> 10));
-	s61 = s45 + s54 + (((s46 << 25) | (s46 >> 7)) ^ ((s46 << 14) | (s46 >> 18)) ^ (s46 >> 3)) + (((s59 << 15) | (s59 >> 17)) ^ ((s59 << (32- 19)) | (s59 >> 19)) ^ (s59 >> 10));
-	s62 = s46 + s55 + (((s47 << 25) | (s47 >> 7)) ^ ((s47 << 14) | (s47 >> 18)) ^ (s47 >> 3)) + (((s60 << 15) | (s60 >> 17)) ^ ((s60 << (32- 19)) | (s60 >> 19)) ^ (s60 >> 10));
-	s63 = s47 + s56 + (((s48 << 25) | (s48 >> 7)) ^ ((s48 << 14) | (s48 >> 18)) ^ (s48 >> 3)) + (((s61 << 15) | (s61 >> 17)) ^ ((s61 << (32- 19)) | (s61 >> 19)) ^ (s61 >> 10));
-
-		
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x428a2f98 + s00;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x71374491 + s01;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xb5c0fbcf + s02;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xe9b5dba5 + s03;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x3956c25b + s04;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x59f111f1 + s05;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x923f82a4 + s06;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xab1c5ed5 + s07;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xd807aa98 + s08;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x12835b01 + s09;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x243185be + s10;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x550c7dc3 + s11;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x72be5d74 + s12;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x80deb1fe + s13;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x9bdc06a7 + s14;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xc19bf174 + s15;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xe49b69c1 + s16;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xefbe4786 + s17;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x0fc19dc6 + s18;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x240ca1cc + s19;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x2de92c6f + s20;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x4a7484aa + s21;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x5cb0a9dc + s22;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x76f988da + s23;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x983e5152 + s24;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xa831c66d + s25;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xb00327c8 + s26;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xbf597fc7 + s27;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0xc6e00bf3 + s28;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xd5a79147 + s29;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x06ca6351 + s30;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x14292967 + s31;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x27b70a85 + s32;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x2e1b2138 + s33;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x4d2c6dfc + s34;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x53380d13 + s35;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x650a7354 + s36;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x766a0abb + s37;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x81c2c92e + s38;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x92722c85 + s39;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0xa2bfe8a1 + s40;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0xa81a664b + s41;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0xc24b8b70 + s42;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0xc76c51a3 + s43;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0xd192e819 + s44;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xd6990624 + s45;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0xf40e3585 + s46;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x106aa070 + s47;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x19a4c116 + s48;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x1e376c08 + s49;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x2748774c + s50;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x34b0bcb5 + s51;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x391c0cb3 + s52;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0x4ed8aa4a + s53;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0x5b9cca4f + s54;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0x682e6ff3 + s55;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-	h += (((e << 26) | (e >> 6)) ^ ((e << 21) | (e >> 11)) ^ ((e << 7) | (e >> 25))) + (g ^ (e & (f ^ g))) + 0x748f82ee + s56;
-	d += h;  h += (((a << 30) | (a >> 2)) ^ ((a << 19) | (a >> 13)) ^ ((a << 10) | (a >> 22))) + ((a & (b | c)) | (b & c));
-	g += (((d << 26) | (d >> 6)) ^ ((d << 21) | (d >> 11)) ^ ((d << 7) | (d >> 25))) + (f ^ (d & (e ^ f))) + 0x78a5636f + s57;
-	c += g;  g += (((h << 30) | (h >> 2)) ^ ((h << 19) | (h >> 13)) ^ ((h << 10) | (h >> 22))) + ((h & (a | b)) | (a & b));
-	f += (((c << 26) | (c >> 6)) ^ ((c << 21) | (c >> 11)) ^ ((c << 7) | (c >> 25))) + (e ^ (c & (d ^ e))) + 0x84c87814 + s58;
-	b += f;  f += (((g << 30) | (g >> 2)) ^ ((g << 19) | (g >> 13)) ^ ((g << 10) | (g >> 22))) + ((g & (h | a)) | (h & a));
-	e += (((b << 26) | (b >> 6)) ^ ((b << 21) | (b >> 11)) ^ ((b << 7) | (b >> 25))) + (d ^ (b & (c ^ d))) + 0x8cc70208 + s59;
-	a += e;  e += (((f << 30) | (f >> 2)) ^ ((f << 19) | (f >> 13)) ^ ((f << 10) | (f >> 22))) + ((f & (g | h)) | (g & h));
-	d += (((a << 26) | (a >> 6)) ^ ((a << 21) | (a >> 11)) ^ ((a << 7) | (a >> 25))) + (c ^ (a & (b ^ c))) + 0x90befffa + s60;
-	h += d;  d += (((e << 30) | (e >> 2)) ^ ((e << 19) | (e >> 13)) ^ ((e << 10) | (e >> 22))) + ((e & (f | g)) | (f & g));
-	c += (((h << 26) | (h >> 6)) ^ ((h << 21) | (h >> 11)) ^ ((h << 7) | (h >> 25))) + (b ^ (h & (a ^ b))) + 0xa4506ceb + s61;
-	g += c;  c += (((d << 30) | (d >> 2)) ^ ((d << 19) | (d >> 13)) ^ ((d << 10) | (d >> 22))) + ((d & (e | f)) | (e & f));
-	b += (((g << 26) | (g >> 6)) ^ ((g << 21) | (g >> 11)) ^ ((g << 7) | (g >> 25))) + (a ^ (g & (h ^ a))) + 0xbef9a3f7 + s62;
-	f += b;  b += (((c << 30) | (c >> 2)) ^ ((c << 19) | (c >> 13)) ^ ((c << 10) | (c >> 22))) + ((c & (d | e)) | (d & e));
-	a += (((f << 26) | (f >> 6)) ^ ((f << 21) | (f >> 11)) ^ ((f << 7) | (f >> 25))) + (h ^ (f & (g ^ h))) + 0xc67178f2 + s63;
-	e += a;  a += (((b << 30) | (b >> 2)) ^ ((b << 19) | (b >> 13)) ^ ((b << 10) | (b >> 22))) + ((b & (c | d)) | (c & d));
-
-	x[0] += a
-	x[1] += b
-	x[2] += c
-	x[3] += d
-	x[4] += e
-	x[5] += f
-	x[6] += g
-	x[7] += h
-}
-
-const unpack = {b
-	var v : uint32
-
-	v = ((b[0] castto(uint32)) << 24)
-	v |= ((b[1] castto(uint32)) << 16)
-	v |= ((b[2] castto(uint32)) << 8)
-	v |= ((b[3] castto(uint32)) << 0)
-	-> v
-}
-
-const pack = {out, v
-	out[0]  = (v >> 24)	castto(byte)
-	out[1]  = (v >> 16)	castto(byte)
-	out[2]  = (v >> 8)	castto(byte)
-	out[3]  = (v >> 0)	castto(byte)
-}
--- a/libcryptohash/sha512.myr
+++ /dev/null
@@ -1,474 +1,0 @@
-use std
-
-pkg cryptohash =
-	type sha512
-	type sha384
-
-	const sha512	: (data : byte[:] -> byte[64])
-	const sha512init	: (st : sha512# -> void)
-	const sha512add	: (st : sha512#, data : byte[:] -> void)
-	const sha512fin	: (st : sha512# -> byte[64])
-
-	const sha384	: (data : byte[:] -> byte[48])
-	const sha384init	: (st : sha384# -> void)
-	const sha384add	: (st : sha384#, data : byte[:] -> void)
-	const sha384fin	: (st : sha384# -> byte[48])
-;;
-
-
-type sha512 = struct
-	x	: uint64[8]
-	tail	: byte[128]
-	msglen	: uint64
-;;
-
-type sha384 = struct
-	x	: uint64[8]
-	tail	: byte[128]
-	msglen	: uint64
-;;
-
-const sha512 = {data
-	var st
-
-	sha512init(&st)
-	sha512add(&st, data)
-	-> sha512fin(&st)
-}
-
-const sha512init = {st
-	st.x[0] = 0x6a09e667f3bcc908ul
-	st.x[1] = 0xbb67ae8584caa73bul
-	st.x[2] = 0x3c6ef372fe94f82bul
-	st.x[3] = 0xa54ff53a5f1d36f1ul
-	st.x[4] = 0x510e527fade682d1ul
-	st.x[5] = 0x9b05688c2b3e6c1ful
-	st.x[6] = 0x1f83d9abfb41bd6bul
-	st.x[7] = 0x5be0cd19137e2179ul
-	st.msglen = 0
-}
-
-const sha512add = {st, data
-	var n, ntail
-
-	ntail = st.msglen % 128
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(128 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail+n], data[:n])
-		data = data[n:]
-		if n + ntail < 128
-			->
-		;;
-		step(st.x[:], st.tail[:])
-	;;
-
-	while data.len >= 128
-		step(st.x[:], data[:128])
-		data = data[128:]
-	;;
-
-	ntail = st.msglen % 128
-	std.slcp(st.tail[:ntail], data)
-}
-
-const sha512fin = {st
-	var r : byte[64]
-
-	tail(st.x[:], st.msglen, st.tail[:])
-
-	pack(r[ 0: 8],	st.x[0])
-	pack(r[ 8:16],	st.x[1])
-	pack(r[16:24],	st.x[2])
-	pack(r[24:32],	st.x[3])
-	pack(r[32:40],	st.x[4])
-	pack(r[40:48],	st.x[5])
-	pack(r[48:56],	st.x[6])
-	pack(r[56:64],	st.x[7])
-	-> r
-}
-
-const sha384 = {data
-	var st
-
-	sha384init(&st)
-	sha384add(&st, data)
-	-> sha384fin(&st)
-}
-
-const sha384init = {st
-	st.x[0] = 0xCBBB9D5DC1059ED8ul
-	st.x[1] = 0x629A292A367CD507ul
-	st.x[2] = 0x9159015A3070DD17ul
-	st.x[3] = 0x152FECD8F70E5939ul
-	st.x[4] = 0x67332667FFC00B31ul
-	st.x[5] = 0x8EB44A8768581511ul
-	st.x[6] = 0xDB0C2E0D64F98FA7ul
-	st.x[7] = 0x47B5481DBEFA4FA4ul
-	st.msglen = 0
-}
-
-const sha384add = {st, data
-	var n, ntail
-
-	ntail = st.msglen % 128
-	st.msglen += data.len
-	if ntail > 0
-		n = std.min(128 - ntail, data.len)
-		std.slcp(st.tail[ntail:ntail+n], data[:n])
-		data = data[n:]
-		if n + ntail < 128
-			->
-		;;
-		step(st.x[:], st.tail[:])
-	;;
-
-	while data.len >= 128
-		step(st.x[:], data[:128])
-		data = data[128:]
-	;;
-
-	ntail = st.msglen % 128
-	std.slcp(st.tail[:ntail], data)
-}
-
-const sha384fin = {st
-	var r : byte[48]
-
-	tail(st.x[:], st.msglen, st.tail[:])
-
-	pack(r[ 0: 8],	st.x[0])
-	pack(r[ 8:16],	st.x[1])
-	pack(r[16:24],	st.x[2])
-	pack(r[24:32],	st.x[3])
-	pack(r[32:40],	st.x[4])
-	pack(r[40:48],	st.x[5])
-	-> r
-}
-
-
-const tail = {x, msglen, tail
-	var ntail
-
-	/* append first padding block */
-	ntail = msglen % 128
-	tail[ntail++] = 0x80
-	std.slfill(tail[ntail:], 0)
-	if 128 - ntail < 16
-		step(x, tail)
-		std.slfill(tail, 0)
-	;;
-
-	/* append size block */
-	tail[120] = ((msglen * 8) >> 56)	castto(byte)
-	tail[121] = ((msglen * 8) >> 48)	castto(byte)
-	tail[122] = ((msglen * 8) >> 40)	castto(byte)
-	tail[123] = ((msglen * 8) >> 32)	castto(byte)
-	tail[124] = ((msglen * 8) >> 24)	castto(byte)
-	tail[125] = ((msglen * 8) >> 16)	castto(byte)
-	tail[126] = ((msglen * 8) >> 8)	castto(byte)
-	tail[127] = ((msglen * 8) >> 0)	castto(byte)
-	step(x, tail)
-}
-
-const step = {x : uint64[:], msg
-	var a, b, c, d, e, f, g, h
-	var s00, s01, s02, s03, s04, s05, s06, s07
-	var s08, s09, s10, s11, s12, s13, s14, s15
-	var s16, s17, s18, s19, s20, s21, s22, s23
-	var s24, s25, s26, s27, s28, s29, s30, s31
-	var s32, s33, s34, s35, s36, s37, s38, s39
-	var s40, s41, s42, s43, s44, s45, s46, s47
-	var s48, s49, s50, s51, s52, s53, s54, s55
-	var s56, s57, s58, s59, s60, s61, s62, s63
-	var s64, s65, s66, s67, s68, s69, s70, s71
-	var s72, s73, s74, s75, s76, s77, s78, s79
-
-	a = x[0]
-	b = x[1]
-	c = x[2]
-	d = x[3]
-	e = x[4]
-	f = x[5]
-	g = x[6]
-	h = x[7]
-
-	s00 = unpack(msg[  0:  8])
-	s01 = unpack(msg[  8: 16])
-	s02 = unpack(msg[ 16: 24])
-	s03 = unpack(msg[ 24: 32])
-	s04 = unpack(msg[ 32: 40])
-	s05 = unpack(msg[ 40: 48])
-	s06 = unpack(msg[ 48: 56])
-	s07 = unpack(msg[ 56: 64])
-	s08 = unpack(msg[ 64: 72])
-	s09 = unpack(msg[ 72: 80])
-	s10 = unpack(msg[ 80: 88])
-	s11 = unpack(msg[ 88: 96])
-	s12 = unpack(msg[ 96:104])
-	s13 = unpack(msg[104:112])
-	s14 = unpack(msg[112:120])
-	s15 = unpack(msg[120:128])
-
-	s16 = s00 + s09 + (((s01 << 63) | (s01 >> 1))^((s01 << 56) | (s01 >> 8))^(s01 >> 7)) + (((s14 << 45) | (s14 >> 19))^((s14 << 3) | (s14 >> 61))^(s14 >> 6))
-	s17 = s01 + s10 + (((s02 << 63) | (s02 >> 1))^((s02 << 56) | (s02 >> 8))^(s02 >> 7)) + (((s15 << 45) | (s15 >> 19))^((s15 << 3) | (s15 >> 61))^(s15 >> 6))
-	s18 = s02 + s11 + (((s03 << 63) | (s03 >> 1))^((s03 << 56) | (s03 >> 8))^(s03 >> 7)) + (((s16 << 45) | (s16 >> 19))^((s16 << 3) | (s16 >> 61))^(s16 >> 6))
-	s19 = s03 + s12 + (((s04 << 63) | (s04 >> 1))^((s04 << 56) | (s04 >> 8))^(s04 >> 7)) + (((s17 << 45) | (s17 >> 19))^((s17 << 3) | (s17 >> 61))^(s17 >> 6))
-	s20 = s04 + s13 + (((s05 << 63) | (s05 >> 1))^((s05 << 56) | (s05 >> 8))^(s05 >> 7)) + (((s18 << 45) | (s18 >> 19))^((s18 << 3) | (s18 >> 61))^(s18 >> 6))
-	s21 = s05 + s14 + (((s06 << 63) | (s06 >> 1))^((s06 << 56) | (s06 >> 8))^(s06 >> 7)) + (((s19 << 45) | (s19 >> 19))^((s19 << 3) | (s19 >> 61))^(s19 >> 6))
-	s22 = s06 + s15 + (((s07 << 63) | (s07 >> 1))^((s07 << 56) | (s07 >> 8))^(s07 >> 7)) + (((s20 << 45) | (s20 >> 19))^((s20 << 3) | (s20 >> 61))^(s20 >> 6))
-	s23 = s07 + s16 + (((s08 << 63) | (s08 >> 1))^((s08 << 56) | (s08 >> 8))^(s08 >> 7)) + (((s21 << 45) | (s21 >> 19))^((s21 << 3) | (s21 >> 61))^(s21 >> 6))
-	s24 = s08 + s17 + (((s09 << 63) | (s09 >> 1))^((s09 << 56) | (s09 >> 8))^(s09 >> 7)) + (((s22 << 45) | (s22 >> 19))^((s22 << 3) | (s22 >> 61))^(s22 >> 6))
-	s25 = s09 + s18 + (((s10 << 63) | (s10 >> 1))^((s10 << 56) | (s10 >> 8))^(s10 >> 7)) + (((s23 << 45) | (s23 >> 19))^((s23 << 3) | (s23 >> 61))^(s23 >> 6))
-	s26 = s10 + s19 + (((s11 << 63) | (s11 >> 1))^((s11 << 56) | (s11 >> 8))^(s11 >> 7)) + (((s24 << 45) | (s24 >> 19))^((s24 << 3) | (s24 >> 61))^(s24 >> 6))
-	s27 = s11 + s20 + (((s12 << 63) | (s12 >> 1))^((s12 << 56) | (s12 >> 8))^(s12 >> 7)) + (((s25 << 45) | (s25 >> 19))^((s25 << 3) | (s25 >> 61))^(s25 >> 6))
-	s28 = s12 + s21 + (((s13 << 63) | (s13 >> 1))^((s13 << 56) | (s13 >> 8))^(s13 >> 7)) + (((s26 << 45) | (s26 >> 19))^((s26 << 3) | (s26 >> 61))^(s26 >> 6))
-	s29 = s13 + s22 + (((s14 << 63) | (s14 >> 1))^((s14 << 56) | (s14 >> 8))^(s14 >> 7)) + (((s27 << 45) | (s27 >> 19))^((s27 << 3) | (s27 >> 61))^(s27 >> 6))
-	s30 = s14 + s23 + (((s15 << 63) | (s15 >> 1))^((s15 << 56) | (s15 >> 8))^(s15 >> 7)) + (((s28 << 45) | (s28 >> 19))^((s28 << 3) | (s28 >> 61))^(s28 >> 6))
-	s31 = s15 + s24 + (((s16 << 63) | (s16 >> 1))^((s16 << 56) | (s16 >> 8))^(s16 >> 7)) + (((s29 << 45) | (s29 >> 19))^((s29 << 3) | (s29 >> 61))^(s29 >> 6))
-	s32 = s16 + s25 + (((s17 << 63) | (s17 >> 1))^((s17 << 56) | (s17 >> 8))^(s17 >> 7)) + (((s30 << 45) | (s30 >> 19))^((s30 << 3) | (s30 >> 61))^(s30 >> 6))
-	s33 = s17 + s26 + (((s18 << 63) | (s18 >> 1))^((s18 << 56) | (s18 >> 8))^(s18 >> 7)) + (((s31 << 45) | (s31 >> 19))^((s31 << 3) | (s31 >> 61))^(s31 >> 6))
-	s34 = s18 + s27 + (((s19 << 63) | (s19 >> 1))^((s19 << 56) | (s19 >> 8))^(s19 >> 7)) + (((s32 << 45) | (s32 >> 19))^((s32 << 3) | (s32 >> 61))^(s32 >> 6))
-	s35 = s19 + s28 + (((s20 << 63) | (s20 >> 1))^((s20 << 56) | (s20 >> 8))^(s20 >> 7)) + (((s33 << 45) | (s33 >> 19))^((s33 << 3) | (s33 >> 61))^(s33 >> 6))
-	s36 = s20 + s29 + (((s21 << 63) | (s21 >> 1))^((s21 << 56) | (s21 >> 8))^(s21 >> 7)) + (((s34 << 45) | (s34 >> 19))^((s34 << 3) | (s34 >> 61))^(s34 >> 6))
-	s37 = s21 + s30 + (((s22 << 63) | (s22 >> 1))^((s22 << 56) | (s22 >> 8))^(s22 >> 7)) + (((s35 << 45) | (s35 >> 19))^((s35 << 3) | (s35 >> 61))^(s35 >> 6))
-	s38 = s22 + s31 + (((s23 << 63) | (s23 >> 1))^((s23 << 56) | (s23 >> 8))^(s23 >> 7)) + (((s36 << 45) | (s36 >> 19))^((s36 << 3) | (s36 >> 61))^(s36 >> 6))
-	s39 = s23 + s32 + (((s24 << 63) | (s24 >> 1))^((s24 << 56) | (s24 >> 8))^(s24 >> 7)) + (((s37 << 45) | (s37 >> 19))^((s37 << 3) | (s37 >> 61))^(s37 >> 6))
-	s40 = s24 + s33 + (((s25 << 63) | (s25 >> 1))^((s25 << 56) | (s25 >> 8))^(s25 >> 7)) + (((s38 << 45) | (s38 >> 19))^((s38 << 3) | (s38 >> 61))^(s38 >> 6))
-	s41 = s25 + s34 + (((s26 << 63) | (s26 >> 1))^((s26 << 56) | (s26 >> 8))^(s26 >> 7)) + (((s39 << 45) | (s39 >> 19))^((s39 << 3) | (s39 >> 61))^(s39 >> 6))
-	s42 = s26 + s35 + (((s27 << 63) | (s27 >> 1))^((s27 << 56) | (s27 >> 8))^(s27 >> 7)) + (((s40 << 45) | (s40 >> 19))^((s40 << 3) | (s40 >> 61))^(s40 >> 6))
-	s43 = s27 + s36 + (((s28 << 63) | (s28 >> 1))^((s28 << 56) | (s28 >> 8))^(s28 >> 7)) + (((s41 << 45) | (s41 >> 19))^((s41 << 3) | (s41 >> 61))^(s41 >> 6))
-	s44 = s28 + s37 + (((s29 << 63) | (s29 >> 1))^((s29 << 56) | (s29 >> 8))^(s29 >> 7)) + (((s42 << 45) | (s42 >> 19))^((s42 << 3) | (s42 >> 61))^(s42 >> 6))
-	s45 = s29 + s38 + (((s30 << 63) | (s30 >> 1))^((s30 << 56) | (s30 >> 8))^(s30 >> 7)) + (((s43 << 45) | (s43 >> 19))^((s43 << 3) | (s43 >> 61))^(s43 >> 6))
-	s46 = s30 + s39 + (((s31 << 63) | (s31 >> 1))^((s31 << 56) | (s31 >> 8))^(s31 >> 7)) + (((s44 << 45) | (s44 >> 19))^((s44 << 3) | (s44 >> 61))^(s44 >> 6))
-	s47 = s31 + s40 + (((s32 << 63) | (s32 >> 1))^((s32 << 56) | (s32 >> 8))^(s32 >> 7)) + (((s45 << 45) | (s45 >> 19))^((s45 << 3) | (s45 >> 61))^(s45 >> 6))
-	s48 = s32 + s41 + (((s33 << 63) | (s33 >> 1))^((s33 << 56) | (s33 >> 8))^(s33 >> 7)) + (((s46 << 45) | (s46 >> 19))^((s46 << 3) | (s46 >> 61))^(s46 >> 6))
-	s49 = s33 + s42 + (((s34 << 63) | (s34 >> 1))^((s34 << 56) | (s34 >> 8))^(s34 >> 7)) + (((s47 << 45) | (s47 >> 19))^((s47 << 3) | (s47 >> 61))^(s47 >> 6))
-	s50 = s34 + s43 + (((s35 << 63) | (s35 >> 1))^((s35 << 56) | (s35 >> 8))^(s35 >> 7)) + (((s48 << 45) | (s48 >> 19))^((s48 << 3) | (s48 >> 61))^(s48 >> 6))
-	s51 = s35 + s44 + (((s36 << 63) | (s36 >> 1))^((s36 << 56) | (s36 >> 8))^(s36 >> 7)) + (((s49 << 45) | (s49 >> 19))^((s49 << 3) | (s49 >> 61))^(s49 >> 6))
-	s52 = s36 + s45 + (((s37 << 63) | (s37 >> 1))^((s37 << 56) | (s37 >> 8))^(s37 >> 7)) + (((s50 << 45) | (s50 >> 19))^((s50 << 3) | (s50 >> 61))^(s50 >> 6))
-	s53 = s37 + s46 + (((s38 << 63) | (s38 >> 1))^((s38 << 56) | (s38 >> 8))^(s38 >> 7)) + (((s51 << 45) | (s51 >> 19))^((s51 << 3) | (s51 >> 61))^(s51 >> 6))
-	s54 = s38 + s47 + (((s39 << 63) | (s39 >> 1))^((s39 << 56) | (s39 >> 8))^(s39 >> 7)) + (((s52 << 45) | (s52 >> 19))^((s52 << 3) | (s52 >> 61))^(s52 >> 6))
-	s55 = s39 + s48 + (((s40 << 63) | (s40 >> 1))^((s40 << 56) | (s40 >> 8))^(s40 >> 7)) + (((s53 << 45) | (s53 >> 19))^((s53 << 3) | (s53 >> 61))^(s53 >> 6))
-	s56 = s40 + s49 + (((s41 << 63) | (s41 >> 1))^((s41 << 56) | (s41 >> 8))^(s41 >> 7)) + (((s54 << 45) | (s54 >> 19))^((s54 << 3) | (s54 >> 61))^(s54 >> 6))
-	s57 = s41 + s50 + (((s42 << 63) | (s42 >> 1))^((s42 << 56) | (s42 >> 8))^(s42 >> 7)) + (((s55 << 45) | (s55 >> 19))^((s55 << 3) | (s55 >> 61))^(s55 >> 6))
-	s58 = s42 + s51 + (((s43 << 63) | (s43 >> 1))^((s43 << 56) | (s43 >> 8))^(s43 >> 7)) + (((s56 << 45) | (s56 >> 19))^((s56 << 3) | (s56 >> 61))^(s56 >> 6))
-	s59 = s43 + s52 + (((s44 << 63) | (s44 >> 1))^((s44 << 56) | (s44 >> 8))^(s44 >> 7)) + (((s57 << 45) | (s57 >> 19))^((s57 << 3) | (s57 >> 61))^(s57 >> 6))
-	s60 = s44 + s53 + (((s45 << 63) | (s45 >> 1))^((s45 << 56) | (s45 >> 8))^(s45 >> 7)) + (((s58 << 45) | (s58 >> 19))^((s58 << 3) | (s58 >> 61))^(s58 >> 6))
-	s61 = s45 + s54 + (((s46 << 63) | (s46 >> 1))^((s46 << 56) | (s46 >> 8))^(s46 >> 7)) + (((s59 << 45) | (s59 >> 19))^((s59 << 3) | (s59 >> 61))^(s59 >> 6))
-	s62 = s46 + s55 + (((s47 << 63) | (s47 >> 1))^((s47 << 56) | (s47 >> 8))^(s47 >> 7)) + (((s60 << 45) | (s60 >> 19))^((s60 << 3) | (s60 >> 61))^(s60 >> 6))
-	s63 = s47 + s56 + (((s48 << 63) | (s48 >> 1))^((s48 << 56) | (s48 >> 8))^(s48 >> 7)) + (((s61 << 45) | (s61 >> 19))^((s61 << 3) | (s61 >> 61))^(s61 >> 6))
-	s64 = s48 + s57 + (((s49 << 63) | (s49 >> 1))^((s49 << 56) | (s49 >> 8))^(s49 >> 7)) + (((s62 << 45) | (s62 >> 19))^((s62 << 3) | (s62 >> 61))^(s62 >> 6))
-	s65 = s49 + s58 + (((s50 << 63) | (s50 >> 1))^((s50 << 56) | (s50 >> 8))^(s50 >> 7)) + (((s63 << 45) | (s63 >> 19))^((s63 << 3) | (s63 >> 61))^(s63 >> 6))
-	s66 = s50 + s59 + (((s51 << 63) | (s51 >> 1))^((s51 << 56) | (s51 >> 8))^(s51 >> 7)) + (((s64 << 45) | (s64 >> 19))^((s64 << 3) | (s64 >> 61))^(s64 >> 6))
-	s67 = s51 + s60 + (((s52 << 63) | (s52 >> 1))^((s52 << 56) | (s52 >> 8))^(s52 >> 7)) + (((s65 << 45) | (s65 >> 19))^((s65 << 3) | (s65 >> 61))^(s65 >> 6))
-	s68 = s52 + s61 + (((s53 << 63) | (s53 >> 1))^((s53 << 56) | (s53 >> 8))^(s53 >> 7)) + (((s66 << 45) | (s66 >> 19))^((s66 << 3) | (s66 >> 61))^(s66 >> 6))
-	s69 = s53 + s62 + (((s54 << 63) | (s54 >> 1))^((s54 << 56) | (s54 >> 8))^(s54 >> 7)) + (((s67 << 45) | (s67 >> 19))^((s67 << 3) | (s67 >> 61))^(s67 >> 6))
-	s70 = s54 + s63 + (((s55 << 63) | (s55 >> 1))^((s55 << 56) | (s55 >> 8))^(s55 >> 7)) + (((s68 << 45) | (s68 >> 19))^((s68 << 3) | (s68 >> 61))^(s68 >> 6))
-	s71 = s55 + s64 + (((s56 << 63) | (s56 >> 1))^((s56 << 56) | (s56 >> 8))^(s56 >> 7)) + (((s69 << 45) | (s69 >> 19))^((s69 << 3) | (s69 >> 61))^(s69 >> 6))
-	s72 = s56 + s65 + (((s57 << 63) | (s57 >> 1))^((s57 << 56) | (s57 >> 8))^(s57 >> 7)) + (((s70 << 45) | (s70 >> 19))^((s70 << 3) | (s70 >> 61))^(s70 >> 6))
-	s73 = s57 + s66 + (((s58 << 63) | (s58 >> 1))^((s58 << 56) | (s58 >> 8))^(s58 >> 7)) + (((s71 << 45) | (s71 >> 19))^((s71 << 3) | (s71 >> 61))^(s71 >> 6))
-	s74 = s58 + s67 + (((s59 << 63) | (s59 >> 1))^((s59 << 56) | (s59 >> 8))^(s59 >> 7)) + (((s72 << 45) | (s72 >> 19))^((s72 << 3) | (s72 >> 61))^(s72 >> 6))
-	s75 = s59 + s68 + (((s60 << 63) | (s60 >> 1))^((s60 << 56) | (s60 >> 8))^(s60 >> 7)) + (((s73 << 45) | (s73 >> 19))^((s73 << 3) | (s73 >> 61))^(s73 >> 6))
-	s76 = s60 + s69 + (((s61 << 63) | (s61 >> 1))^((s61 << 56) | (s61 >> 8))^(s61 >> 7)) + (((s74 << 45) | (s74 >> 19))^((s74 << 3) | (s74 >> 61))^(s74 >> 6))
-	s77 = s61 + s70 + (((s62 << 63) | (s62 >> 1))^((s62 << 56) | (s62 >> 8))^(s62 >> 7)) + (((s75 << 45) | (s75 >> 19))^((s75 << 3) | (s75 >> 61))^(s75 >> 6))
-	s78 = s62 + s71 + (((s63 << 63) | (s63 >> 1))^((s63 << 56) | (s63 >> 8))^(s63 >> 7)) + (((s76 << 45) | (s76 >> 19))^((s76 << 3) | (s76 >> 61))^(s76 >> 6))
-	s79 = s63 + s72 + (((s64 << 63) | (s64 >> 1))^((s64 << 56) | (s64 >> 8))^(s64 >> 7)) + (((s77 << 45) | (s77 >> 19))^((s77 << 3) | (s77 >> 61))^(s77 >> 6))
-
-
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x428a2f98d728ae22ul + s00
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x7137449123ef65cdul + s01
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb5c0fbcfec4d3b2ful + s02
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xe9b5dba58189dbbcul + s03
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x3956c25bf348b538ul + s04
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x59f111f1b605d019ul + s05
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x923f82a4af194f9bul + s06
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xab1c5ed5da6d8118ul + s07
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xd807aa98a3030242ul + s08
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x12835b0145706fbeul + s09
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x243185be4ee4b28cul + s10
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x550c7dc3d5ffb4e2ul + s11
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x72be5d74f27b896ful + s12
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x80deb1fe3b1696b1ul + s13
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x9bdc06a725c71235ul + s14
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc19bf174cf692694ul + s15
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xe49b69c19ef14ad2ul + s16
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xefbe4786384f25e3ul + s17
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x0fc19dc68b8cd5b5ul + s18
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x240ca1cc77ac9c65ul + s19
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x2de92c6f592b0275ul + s20
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4a7484aa6ea6e483ul + s21
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5cb0a9dcbd41fbd4ul + s22
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x76f988da831153b5ul + s23
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x983e5152ee66dfabul + s24
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa831c66d2db43210ul + s25
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb00327c898fb213ful + s26
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xbf597fc7beef0ee4ul + s27
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xc6e00bf33da88fc2ul + s28
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd5a79147930aa725ul + s29
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x06ca6351e003826ful + s30
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x142929670a0e6e70ul + s31
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x27b70a8546d22ffcul + s32
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x2e1b21385c26c926ul + s33
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x4d2c6dfc5ac42aedul + s34
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x53380d139d95b3dful + s35
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x650a73548baf63deul + s36
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x766a0abb3c77b2a8ul + s37
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x81c2c92e47edaee6ul + s38
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x92722c851482353bul + s39
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xa2bfe8a14cf10364ul + s40
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa81a664bbc423001ul + s41
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xc24b8b70d0f89791ul + s42
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xc76c51a30654be30ul + s43
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xd192e819d6ef5218ul + s44
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd69906245565a910ul + s45
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xf40e35855771202aul + s46
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x106aa07032bbd1b8ul + s47
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x19a4c116b8d2d0c8ul + s48
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x1e376c085141ab53ul + s49
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x2748774cdf8eeb99ul + s50
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x34b0bcb5e19b48a8ul + s51
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x391c0cb3c5c95a63ul + s52
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4ed8aa4ae3418acbul + s53
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5b9cca4f7763e373ul + s54
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x682e6ff3d6b2b8a3ul + s55
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x748f82ee5defb2fcul + s56
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x78a5636f43172f60ul + s57
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x84c87814a1f0ab72ul + s58
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x8cc702081a6439ecul + s59
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x90befffa23631e28ul + s60
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xa4506cebde82bde9ul + s61
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xbef9a3f7b2c67915ul + s62
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc67178f2e372532bul + s63
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xca273eceea26619cul + s64
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xd186b8c721c0c207ul + s65
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xeada7dd6cde0eb1eul + s66
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xf57d4f7fee6ed178ul + s67
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x06f067aa72176fbaul + s68
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x0a637dc5a2c898a6ul + s69
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x113f9804bef90daeul + s70
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x1b710b35131c471bul + s71
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-	h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x28db77f523047d84ul + s72
-	d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
-	g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x32caab7b40c72493ul + s73
-	c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
-	f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x3c9ebe0a15c9bebcul + s74
-	b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
-	e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x431d67c49c100d4cul + s75
-	a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
-	d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x4cc5d4becb3e42b6ul + s76
-	h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
-	c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x597f299cfc657e2aul + s77
-	g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
-	b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5fcb6fab3ad6faecul + s78
-	f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
-	a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x6c44198c4a475817ul + s79
-	e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
-
-	x[0] += a
-	x[1] += b
-	x[2] += c
-	x[3] += d
-	x[4] += e
-	x[5] += f
-	x[6] += g
-	x[7] += h
-}
-
-const unpack = {b
-	var v : uint64
-
-	v = ((b[0] castto(uint64)) << 56)
-	v |= ((b[1] castto(uint64)) << 48)
-	v |= ((b[2] castto(uint64)) << 40)
-	v |= ((b[3] castto(uint64)) << 32)
-	v |= ((b[4] castto(uint64)) << 24)
-	v |= ((b[5] castto(uint64)) << 16)
-	v |= ((b[6] castto(uint64)) << 8)
-	v |= ((b[7] castto(uint64)) << 0)
-	-> v
-}
-
-const pack = {out, v
-	out[0]  = (v >> 56)	castto(byte)
-	out[1]  = (v >> 48)	castto(byte)
-	out[2]  = (v >> 40)	castto(byte)
-	out[3]  = (v >> 32)	castto(byte)
-	out[4]  = (v >> 24)	castto(byte)
-	out[5]  = (v >> 16)	castto(byte)
-	out[6]  = (v >> 8)	castto(byte)
-	out[7]  = (v >> 0)	castto(byte)
-}
-
--- a/libcryptohash/test/md5.myr
+++ /dev/null
@@ -1,18 +1,0 @@
-use std
-use cryptohash
-
-use "test/util.use"
-
-const main = {
-	hasheq(cryptohash.md5("")[:], \
-		"d41d8cd98f00b204e9800998ecf8427e")
-	hasheq(cryptohash.md5("h")[:], \
-		"2510c39011c5be704182423e3a695e91")
-	/* 64 byte block */
-	hasheq(cryptohash.md5("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"014842d480b571495a4a0363793f7367")
-	/* tail spanning */
-	hasheq(cryptohash.md5("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"3b0bb4c5ece4a6568caa7266e740a140")
-}
-
--- a/libcryptohash/test/sha1.myr
+++ /dev/null
@@ -1,18 +1,0 @@
-use std
-use cryptohash
-
-use "test/util.use"
-
-const main = {
-	hasheq(cryptohash.sha1("")[:], \
-		"da39a3ee5e6b4b0d3255bfef60951890d8af0709")
-	hasheq(cryptohash.sha1("h")[:], \
-		"27d5482eebd075de44389774e2fc8c695cf48a75")
-	/* 64 byte block */
-	hasheq(cryptohash.sha1("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"0098ba824b5c16427bd7a1125a2a442aec25644d")
-	/* tail spanning */
-	hasheq(cryptohash.sha1("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"4eb17e52bb55910b037869438f69d9c87643d75a")
-}
-
--- a/libcryptohash/test/sha256.myr
+++ /dev/null
@@ -1,29 +1,0 @@
-use std
-use cryptohash
-
-use "test/util.use"
-
-const main = {
-	hasheq(cryptohash.sha224("")[:], \
-		"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
-	hasheq(cryptohash.sha224("h")[:], \
-		"e0ccaeadfef916630c35576679e4cd4b438e7fc95a60b7361705f708")
-	/* 64 byte block */
-	hasheq(cryptohash.sha224("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"a88cd5cde6d6fe9136a4e58b49167461ea95d388ca2bdb7afdc3cbf4")
-	/* tail spanning */
-	hasheq(cryptohash.sha224("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"4a5859b7efa22c3b25710520fc97b0a901f5cdba3e4f0becfeea725e")
-
-	hasheq(cryptohash.sha256("")[:], \
-		"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
-	hasheq(cryptohash.sha256("h")[:], \
-		"aaa9402664f1a41f40ebbc52c9993eb66aeb366602958fdfaa283b71e64db123")
-	/* 64 byte block */
-	hasheq(cryptohash.sha256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb")
-	/* tail spanning */
-	hasheq(cryptohash.sha256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"bac8bf0f9794a520a5bf0ec64d3206edd1b9f2ef5ea118c9cad5365d84578de4")
-}
-
--- a/libcryptohash/test/sha512.myr
+++ /dev/null
@@ -1,29 +1,0 @@
-use std
-use cryptohash
-
-use "test/util.use"
-
-const main = {
-	hasheq(cryptohash.sha384("")[:], \
-		"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
-	hasheq(cryptohash.sha384("h")[:], \
-		"a4eb0778c79fce94c02126543cba398d645b2fd4c6ff6a02eecc026bbe0cc0dd666279722b7615bc15b4c9126b941c04")
-	/* 64 byte block */
-	hasheq(cryptohash.sha384("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"2e404b9339da795776e510d96930b3be2904c500395b8cb7413334b82d4dec413b4b8113045a05bbbcff846f027423f6")
-	/* tail spanning */
-	hasheq(cryptohash.sha384("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"f8f4b55a0fb1ac8506d2e5195c714a1ad16c3bf61ad8b2d544344b105a49a77ff3b8eb61e8f970a71864e9dad87042b1")
-
-	hasheq(cryptohash.sha512("")[:], \
-		"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
-	hasheq(cryptohash.sha512("h")[:], \
-		"2241bc8fc70705b42efead371fd4982c5ba69917e5b4b895810002644f0386da9c3131793458c2bf47608480d64a07278133c99912e0ba2daf23098f3520eb97")
-	/* 64 byte block */
-	hasheq(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")[:], \
-		"01d35c10c6c38c2dcf48f7eebb3235fb5ad74a65ec4cd016e2354c637a8fb49b695ef3c1d6f7ae4cd74d78cc9c9bcac9d4f23a73019998a7f73038a5c9b2dbde")
-	/* tail spanning */
-	hasheq(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb")[:], \
-		"d5c989d2e41299b6bfd57562b4b09cd2efa56f13c8fa109e0ce5ddbd6bfb5b34f8563608d6162104bef750023732581f22704d5df43feecbb05742be1d7c34fa")
-}
-
--- a/libcryptohash/test/util.myr
+++ /dev/null
@@ -1,19 +1,0 @@
-use std
-
-pkg =
-	const hasheq	: (got : byte[:], expected : byte[:] -> void)
-;;
-
-const hasheq = {got, expected
-	var sb, str
-
-	sb = std.mksb()
-	for x in got
-		std.sbfmt(sb, "{p=0,w=2,x}", x)
-	;;
-	str = std.sbfin(sb)
-	if (!std.sleq(str, expected))
-		std.fatal("mismatched hashes:\n\tgot:\t{}\n\texpected:\t{}\n", str, expected)
-	;;
-	std.slfree(str)
-}
--- a/libregex/bld.sub
+++ /dev/null
@@ -1,21 +1,0 @@
-lib regex =
-	compile.myr
-	interp.myr
-	ranges.myr
-	types.myr
-
-        lib ../libstd:std
-;;
-
-bin redump {noinst} =
-	redump.myr
-        lib ../libstd:std
-        lib ../libbio:bio
-        lib regex
-;;
-
-gen ranges.myr {durable} =
-	mkchartab -a -p_ranges UnicodeData.txt -o ranges.myr
-;;
-
-sub = test ;;
--- a/libregex/compile.myr
+++ /dev/null
@@ -1,848 +1,0 @@
-use std
-
-use "types.use"
-use "ranges.use"
-
-pkg regex =
-	const parse	: (re : byte[:]	-> std.result(ast#, status))
-	const compile	: (re : byte[:] -> std.result(regex#, status))
-	const dbgcompile	: (re : byte[:] -> std.result(regex#, status))
-	const free	: (re : regex# -> void)
-	const failmsg	: (st : status -> byte[:])
-;;
-
-type parseresult = union
-	`Some ast#
-	`None
-	`Fail status
-;;
-
-/* Compiles a pattern into a regex */
-const compile = {pat
-	-> regexcompile(std.mk([.pat = pat, .nmatch = 1]), 0)
-}
-
-const parse = {pat
-	var re
-
-	re = std.mk([.pat = pat, .nmatch = 1])
-	match regexparse(re)
-	| `None:	-> `std.Fail `Incomplete
-	| `Fail f:	-> `std.Fail f
-	| `Some t:
-		if re.pat.len > 0
-			-> `std.Fail `Incomplete
-		else
-			-> `std.Ok t
-		;;
-	;;
-}
-
-/* Compiles a pattern into a debug regex. This can be verbose. */
-const dbgcompile = {pat
-	var re
-
-	re = std.mk([.pat = pat, .nmatch = 1, .debug = true])
-	-> regexcompile(re, 0)
-}
-
-/* compiles a pattern into an allocated regex */
-const regexcompile = {re, id
-	match regexparse(re)
-	| `None:	-> `std.Fail (`Incomplete)
-	| `Fail f:	-> `std.Fail f
-	| `Some t:
-		/*
-		we can stop early if we get 
-		an incorrectly encoded char
-		*/
-		if re.pat.len > 0
-			astfree(t)
-			-> `std.Fail (`Incomplete)
-		;;
-		dump(re, t, 0)
-		append(re, `Ilbra 0)
-		gen(re, t)
-		append(re, `Irbra 0)
-		append(re, `Imatch id)
-		idump(re)
-		astfree(t)
-		-> `std.Ok re
-	;;
-	-> `std.Fail (`Noimpl)
-}
-
-const free = {re
-	/* all the threads should be dead,
-	 so we shouldn't have to free any*/
-	std.slfree(re.prog)
-	std.free(re)
-}
-
-
-/* generates bytecode from an AST */
-const gen = {re, t
-	match t#
-	|`Alt	(a, b): genalt(re, a, b)
-	|`Cat	(a, b): gen(re, a); gen(re, b)
-	/* repetition */
-	|`Star	a:	genstar(re, a, false)
-	|`Rstar a:	genstar(re, a, true)
-	|`Plus	a:	gen(re, a); genstar(re, a, false)
-	|`Rplus	a:	gen(re, a); genstar(re, a, true)
-	|`Quest	a:	genquest(re, a)
-
-	/* end matches */
-	|`Chr	c:	genchar(re, c)
-	|`Ranges  sl:	genranges(re, sl)
-
-	/* meta */
-	|`Bol:	append(re, `Ibol)
-	|`Eol:	append(re, `Ibol)
-	|`Bow:	append(re, `Ibow)
-	|`Eow:	append(re, `Ieow)
-	|`Cap	(m, a):
-		append(re, `Ilbra m)
-		gen(re, a)
-		append(re, `Irbra m)
-	;;
-	-> re.proglen
-}
-
-const genranges = {re, sl
-	var lbuf : byte[4], hbuf : byte[4], boundbuf : byte[4]
-	var lsz, hsz, bsz, i
-	var rt : rangetrie#
-
-	/* generate a trie of ranges */
-	rt = std.zalloc()
-	for r in sl
-		/* 
-		encode:
-			lo => bounds[loidx] - 1
-			bounds[loidx] => bounds[loidx + 1] - 1
-			...
-			bounds[hiidx - 1] => hi
-		*/
-		lsz = std.encode(lbuf[:], r[0])
-		hsz = std.encode(hbuf[:], r[1])
-		for i = lsz; i < hsz; i++
-			bsz = bound(boundbuf[:], i, 0xff)
-			rtinsert(rt, lbuf[:lsz], boundbuf[:bsz])
-			lsz = bound(lbuf[:], i + 1, 0x00)
-		;;
-		rtinsert(rt, lbuf[:lsz], hbuf[:hsz])
-	;;
-	if re.debug
-		rtdump(rt, 0)
-	;;
-	rangegen(re, rt, rt.ranges, rt.link, rangeprogsize(rt) + re.proglen)
-	rtfree(rt)
-	-> re.proglen
-}
-
-const bound = {buf, len, fill
-	var i, s
-
-	if len == 1
-		buf[0] = 0x7f
-	else
-		s = len castto(byte)
-		buf[0] = (0xff << (8 - s)) | (fill >> (s + 1))
-		for i = 1; i < len; i++
-			buf[i] = 0x80 | (fill >> 2)
-		;;
-	;;
-	-> len
-}
-
-type rangetrie = struct
-	ranges	: (byte, byte)[:]
-	link	: rangetrie#[:]
-	end	: bool
-;;
-
-const rtdump = {rt, ind
-	var i
-	var l, h
-
-	indent(ind)
-	std.put("Range (end = {}) {{\n", rt.end)
-	for i = 0; i < rt.ranges.len; i++
-		indent(ind + 1)
-		(l, h) = rt.ranges[i]
-		std.put("0x{x}-0x{x}: \n", l, h)
-		rtdump(rt.link[i], ind + 1)
-	;;
-	indent(ind)
-	std.put("}\n")
-}
-
-const indent = {ind
-	var i
-	for i = 0; i < ind; i++
-		std.put("\t")
-	;;
-}
-
-const rtinsert = {rt, lo, hi
-	var a, b
-	var n
-
-	std.assert(lo.len == hi.len, "range sizes differ")
-	if lo.len == 0
-		rt.end = true
-		->
-	;;
-
-	n = rt.ranges.len
-	if n == 0
-		rt.ranges = std.slpush(rt.ranges, (lo[0], hi[0]))
-		rt.link = std.slpush(rt.link, std.zalloc())
-	else
-		/*
-		this is a safe way to compare because we know that ranges
-		should always be coming in ordered. This means that equal
-		values will be added one after the other.
-		*/
-		(a, b) = rt.ranges[n - 1]
-		if a != lo[0] || b != hi[0]
-			rt.ranges = std.slpush(rt.ranges, (lo[0], hi[0]))
-			rt.link = std.slpush(rt.link, std.zalloc())
-		;;
-	;;
-
-	rtinsert(rt.link[rt.link.len - 1], lo[1:], hi[1:])
-}
-
-const rtfree = {rt
-	for l in rt.link
-		rtfree(l)
-	;;
-	std.slfree(rt.link)
-	std.slfree(rt.ranges)
-	std.free(rt)
-}
-
-const rangegen = {re, rt, ranges, links, end
-	var alt, l0, l1, l2
-	var a, b
-	var n
-
-	n = ranges.len
-	if n == 0
-		-> re.proglen
-	elif n == 1
-		(a, b) = ranges[0]
-		append(re, `Irange (a, b))
-		if links[0].end
-			if links[0].ranges.len > 0
-				append(re, `Ifork (re.prog.len + 1, end))
-			else
-				append(re, `Ijmp end)
-			;;
-		;;
-		rangegen(re, links[0], links[0].ranges, links[0].link, end)
-	else
-		alt = re.proglen
-		l0 = append(re, `Ifork (-1, -1))
-		l1 = rangegen(re, rt, ranges[0:n/2], links[0:n/2], end)
-		l2 = rangegen(re, rt, ranges[n/2:n], links[n/2:n], end)
-		re.prog[alt] = `Ifork (l0, l1)
-	;;
-	-> re.proglen
-}
-
-const rangeprogsize = {rt
-	var sz
-
-	if rt.ranges.len == 0
-		sz = 0
-	else
-		sz = 2*rt.ranges.len - 1
-		for l in rt.link
-			sz += rangeprogsize(l)
-		;;
-	;;
-	if rt.end
-		sz += 1
-	;;
-	-> sz
-}
-
-/* calculates the forward jump distance for a utf8 character range */
-const jmpdist = {n
-	var d
-	var i
-
-	d = n - 1
-	for i = n - 1; i > 0; i--
-		d += i
-	;;
-	-> d
-}
-
-/* generates an alternation */
-const genalt = {re, l, r
-	var alt
-	var jmp
-	var l0
-	var l1
-	var l2
-
-	alt 	= re.proglen
-	l0	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
-		  gen(re, l)
-	jmp	= re.proglen
-	l1 	= append(re, `Ijmp -1) /* needs to be replaced */
-	l2	= gen(re, r)
-
-	re.prog[alt] = `Ifork(l0, l1)
-	re.prog[jmp] = `Ijmp l2
-	-> re.proglen
-}
-
-/* generates a repetition operator */
-const genstar = {re, rep, reluct
-	var alt
-	var jmp
-	var l0
-	var l1
-	var l2
-
-	l0 	= re.proglen
-	alt	= re.proglen
-	l1 	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
-	jmp	= gen(re, rep)
-	l2	= append(re, `Ijmp -1)
-
-
-	/* reluctant matches should prefer jumping to the end. */
-	if reluct
-		re.prog[alt] = `Ifork (l2, l1)
-	else
-		re.prog[alt] = `Ifork (l1, l2)
-	;;
-	re.prog[jmp] = `Ijmp l0
-	-> re.proglen
-}
-
-/* generates a question mark operator */
-const genquest = {re, q
-	var alt
-	var l0
-	var l1
-
-	alt	= re.proglen
-	l0	= append(re, `Ifork (-1, -1)) /* needs to be replaced */
-	l1	= gen(re, q)
-	re.prog[alt] = `Ifork (l0, l1)
-	-> re.proglen
-}
-
-/* generates a single char match */
-const genchar = {re, c
-	var b : byte[4]
-	var n
-	var i
-
-	n = std.encode(b[:], c)
-	std.assert(n > 0 && n < 4, "non-utf character in regex\n")
-	for i = 0; i < n; i++
-		append(re, `Ibyte b[i])
-	;;
-	-> re.proglen
-}
-
-/* appends an instructon to an re program */
-const append = {re, insn
-	if re.proglen == re.prog.len
-		re.prog = std.slgrow(re.prog, std.max(1, 2*re.proglen))
-	;;
-	re.prog[re.proglen] = insn
-	re.proglen++
-	-> re.proglen
-}
-
-/* instruction dump */
-const idump = {re
-	var i
-
-	if !re.debug
-		->
-	;;
-	for i = 0; i < re.proglen; i++
-		std.put("{}:\t", i)
-		match re.prog[i]
-		/* Char matching. Consume exactly one byte from the string. */
-		| `Ibyte b:		std.put("`Ibyte {} ({})\n", b, b castto(char)) 
-		| `Irange (start, end):	
-			std.put("`Irange ({},{})", start, end) 
-			if std.isalnum(start castto(char)) && std.isalnum(end castto(char))
-				std.put("\t/* {}-{} */", start castto(char), end castto(char))
-			;;
-			std.put("\n")
-		/* capture groups */
-		| `Ilbra m:		std.put("`Ilbra {}\n", m) 
-		| `Irbra m:		std.put("`Irbra {}\n", m) 
-		/* anchors */
-		| `Ibol:			std.put("`Ibol\n")
-		| `Ieol:			std.put("`Ieol\n")
-		| `Ibow:			std.put("`Ibow\n")
-		| `Ieow:			std.put("`Ieow\n")
-		/* control flow */
-		| `Ifork	(lip, rip):	std.put("`Ifork ({},{})\n", lip, rip) 
-		| `Ijmp ip:		std.put("`Ijmp {}\n", ip) 
-		| `Imatch id:		std.put("`Imatch {}\n", id) 
-		;;
-	;;
-}
-
-/* AST dump */
-const dump = {re, t, indent
-	var i
-
-	if !re.debug
-		->
-	;;
-	for i = 0; i < indent; i++
-		std.put("  ")
-	;;
-	match t#
-	| `Alt	(a, b):
-		std.put("Alt\n")
-		dump(re, a, indent + 1)
-		dump(re, b, indent + 1)
-	| `Cat	(a, b):
-		std.put("Cat\n")
-		dump(re, a, indent + 1)
-		dump(re, b, indent + 1)
-	/* repetition */
-	| `Star	a:
-		std.put("Star\n")
-		dump(re, a, indent + 1)
-	| `Rstar a:
-		std.put("Rstar\n")
-		dump(re, a, indent + 1)
-	| `Plus	a:
-		std.put("Plus\n")
-		dump(re, a, indent + 1)
-	| `Rplus a:
-		std.put("Rplus\n")
-		dump(re, a, indent + 1)
-	| `Quest	a:
-		std.put("Quest\n")
-		dump(re, a, indent + 1)
-	| `Bol:
-		std.put("Bol\n")
-	| `Eol:
-		std.put("Eol\n")
-	| `Bow:
-		std.put("Bow\n")
-	| `Eow:
-		std.put("Eow\n")
-	/* end matches */
-	| `Chr	c:
-		std.put("Char {}\n", c)
-	| `Ranges rl:
-                std.put("Ranges")
-		for r in rl
-			for i = 0; i < indent + 1; i++
-				std.put("  ")
-			;;
-			std.put("\t({}-{})\n", r[0], r[1])
-		;;
-
-	/* meta */
-	| `Cap	(m, a):
-		std.put("Cap {}\n", m)
-		dump(re, a, indent + 1)
-	;;
-}
-
-/* parses an expression */
-const regexparse = {re
-	match altexpr(re)
-	| `Some t:
-		if re.pat.len == 0
-			-> `Some t
-		else
-			astfree(t)
-			-> `Fail `Incomplete
-		;;
-	| `None:
-		-> `None
-	| `Fail st:
-		-> `Fail st
-	;;
-}
-
-const altexpr = {re
-	var ret
-
-	match catexpr(re)
-	| `Some t:
-		ret = t
-		if matchc(re, '|')
-			match altexpr(re)
-			| `Some rhs:
-				ret = mk(`Alt (ret, rhs))
-			| `None:
-				astfree(ret)
-				-> `Fail (`Incomplete)
-			| `Fail f:
-				-> `Fail f
-			;;
-		;;
-	| other:
-		-> other
-	;;
-	-> `Some ret
-}
-
-const catexpr = {re
-	var ret
-
-	match repexpr(re)
-	| `Some t: 
-		ret = t
-		match catexpr(re)
-		| `Some rhs:
-			ret = mk(`Cat (t, rhs))
-		| `Fail f:	-> `Fail f
-		| `None:	/* nothing */
-		;;
-	| other:
-		-> other
-	;;
-	-> `Some ret
-}
-
-const repexpr = {re
-	var ret
-
-	match baseexpr(re)
-	| `Some t:
-		if matchc(re, '*')
-                        if matchc(re, '?')
-                                ret = mk(`Rstar t)
-                        else
-				ret = mk(`Star t)
-			;;
-		elif matchc(re, '+')
-                        if matchc(re, '?')
-				ret = mk(`Rplus t)
-			else
-				ret = mk(`Plus t)
-			;;
-		elif matchc(re, '?')
-			ret = mk(`Quest t)
-		else
-			ret = t
-		;;
-	| other:
-		-> other
-	;;
-	-> `Some ret
-}
-
-const baseexpr = {re
-	var ret, m
-
-	if re.pat.len == 0
-		-> `None
-	;;
-	match peekc(re)
-	/* lower prec operators */
-	| '|':	-> `None
-	| ')':	-> `None
-	| '*':	-> `Fail `Badrep
-	| '+':	-> `Fail `Badrep
-	| '?':	-> `Fail `Badrep
-	| '[':	-> chrclass(re)
-	| '.':	getc(re); ret = mk(`Ranges std.slpush([][:], [0, std.Maxcharval]))
-	| '^':	getc(re); ret = mk(`Bol)
-	| '$':	getc(re); ret = mk(`Eol)
-	| '(':	
-		m = re.nmatch++
-		getc(re)
-		match altexpr(re)
-		| `Some s:
-			if matchc(re, ')')
-				-> `Some mk(`Cap (m, s))
-			else
-				-> `Fail `Unbalanced
-			;;
-		| `None:	-> `Fail `Emptyparen
-		| `Fail st:	-> `Fail st
-		;;
-	| '\\':
-		getc(re) /* consume the slash */
-		if re.pat.len == 0
-			-> `Fail `Incomplete
-		;;
-		-> escaped(re)
-	| c:
-		getc(re)
-		ret = mk(`Chr c)
-	;;
-	-> `Some ret
-}
-
-const escaped = {re
-	var ret
-
-	match getc(re)
-	/* character classes */
-	| 'd': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciidigit[:]))
-	| 'x': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciixdigit[:]))
-	| 's': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciispace[:]))
-	| 'w': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciiword[:]))
-	| 'h': ret = `Some mk(`Ranges std.sldup(_ranges.tabasciiblank[:]))
-
-	/* negated character classes */
-	| 'W': ret = `Some mk(`Ranges negate(_ranges.tabasciiword[:]))
-	| 'S': ret = `Some mk(`Ranges negate(_ranges.tabasciispace[:]))
-	| 'D': ret = `Some mk(`Ranges negate(_ranges.tabasciidigit[:]))
-	| 'X': ret = `Some mk(`Ranges negate(_ranges.tabasciixdigit[:]))
-	| 'H': ret = `Some mk(`Ranges negate(_ranges.tabasciiblank[:]))
-
-	/* unicode character classes */
-	| 'p':	ret = unicodeclass(re, false)
-	| 'P':  ret = unicodeclass(re, true)
-
-	/* operators that need an escape */
-	| '<': ret = `Some mk(`Bow)
-	| '>': ret = `Some mk(`Eow)
-
-	/* escaped metachars */
-	| '^': ret = `Some mk(`Chr '^')
-	| '$': ret = `Some mk(`Chr '$')
-	| '.': ret = `Some mk(`Chr '.')
-	| '+': ret = `Some mk(`Chr '+')
-	| '?': ret = `Some mk(`Chr '?')
-	| chr: ret = `Fail `Badescape
-	;;
-	-> ret
-}
-
-const unicodeclass = {re, neg
-	var c, s
-	var tab
-	var t
-	var n
-
-	if re.pat.len == 0
-		-> `Fail (`Incomplete)
-	;;
-	n = 0
-	s = re.pat
-	/* either a single char pattern, or {pat} */
-	match getc(re)
-	| '{':
-		s = s[1:]
-		while re.pat.len > 0
-			c = getc(re)
-			if c == '}'
-				break
-			;;
-			n += std.charlen(c)
-		;;
-	| r:
-		n += std.charlen(r)
-	;;
-	s = s[:n]
-	/* letters */
-	if std.sleq(s, "L") || std.sleq(s, "Letter")
-		tab = _ranges.tabalpha[:]
-	elif std.sleq(s, "Lu") || std.sleq(s, "Uppercase_Letter")
-		tab = _ranges.tabupper[:]
-	elif std.sleq(s, "Ll") || std.sleq(s, "Lowercase_Letter")
-		tab = _ranges.tablower[:]
-	elif std.sleq(s, "Lt") || std.sleq(s, "Titlecase_Letter")
-		tab = _ranges.tablower[:]
-	/* numbers (incomplete) */
-	elif std.sleq(s, "N") || std.sleq(s, "Number")
-		tab = _ranges.tabdigit[:]
-	elif std.sleq(s, "Z") || std.sleq(s, "Separator")
-		tab = _ranges.tabspace[:]
-	elif std.sleq(s, "Zs") || std.sleq(s, "Space_Separator")
-		tab = _ranges.tabblank[:]
-	else
-		-> `Fail (`Badrange)
-	;;
-	if !neg
-		t = mk(`Ranges std.sldup(tab))
-	else
-		t = mk(`Ranges negate(tab))
-	;;
-	-> `Some t
-}
-
-const chrclass = {re
-	var rl, m, n
-	var neg
-	var t
-
-	/* we know we saw '[' on entry */
-	matchc(re, '[')
-	neg = false
-	if matchc(re, '^')
-		neg = true
-	;;
-	rl = rangematch(re, [][:])
-	while peekc(re) != ']' && re.pat.len > 0
-		rl = rangematch(re, rl)
-	;;
-	if !matchc(re, ']')
-		std.slfree(rl)
-		-> `Fail `Unbalanced
-	;;
-
-	std.sort(rl, {a, b;
-		if a[0] < b[0]
-			-> `std.Before
-		elif a[0] == b[0]
-			-> `std.Equal
-		else
-			-> `std.After
-		;;})
-	m = merge(rl)
-	std.slfree(rl)
-	if neg
-		n = negate(m)
-		std.slfree(m)
-		t = mk(`Ranges n)
-	else
-		t = mk(`Ranges m)
-	;;
-	-> `Some t
-}
-
-const rangematch = {re, sl
-	var lo
-	var hi
-
-	lo = getc(re)
-	if matchc(re, '-')
-		hi = getc(re)
-		if lo <= hi
-			-> std.slpush(sl, [lo, hi])
-		else
-			-> std.slpush(sl, [hi, lo])
-		;;
-	else
-		-> std.slpush(sl, [lo, lo])
-	;;
-}
-
-const negate = {rng
-	var start, end, next
-	var neg
-
-	neg = [][:]
-	start = 0
-	next = 0 /* if we have no ranges */
-	for r in rng
-		(end, next) = (r[0], r[1])
-		neg = std.slpush(neg, [start, end - 1])
-		start = next + 1
-	;;
-	neg = std.slpush(neg, [next + 1, std.Maxcharval])
-	-> neg
-}
-
-/* rl is a sorted list of ranges */
-const merge = {rl
-	var lo, hi
-	var ret
-
-	if rl.len == 0
-		-> [][:]
-	;;
-	ret = [][:]
-	lo = rl[0][0]
-	hi = rl[0][1]
-	for r in rl[1:]
-		/* if it overlaps or abuts, merge */
-		if r[0] <= hi + 1
-			hi = r[1]
-		else
-			ret = std.slpush(ret, [lo, hi])
-			lo = r[0]
-			hi = r[1]
-		;;
-	;;
-	-> std.slpush(ret, [lo, hi])
-}
-
-
-const matchc = {re, c
-	var str
-	var chr
-
-	(chr, str) = std.striter(re.pat)
-	if chr != c
-		-> false
-	;;
-	re.pat = str
-	-> true
-}
-
-const getc = {re
-	var c
-
-	(c, re.pat) = std.striter(re.pat)
-	-> c
-}
-
-const peekc = {re
-	var c
-
-	(c, _) = std.striter(re.pat)
-	-> c
-}
-
-const mk = {v
-	var t
-
-	t = std.alloc()
-	t# = v
-	-> t
-}
-
-const astfree = {t
-	match t#
-	| `Alt	(a, b): astfree(a); astfree(b)
-	| `Cat	(a, b): astfree(a); astfree(b)
-	/* repetition */
-	| `Star	a:	astfree(a)
-	| `Rstar a:	astfree(a)
-	| `Plus	a:	astfree(a)
-	| `Rplus a:	astfree(a)
-	| `Quest a:	astfree(a)
-
-	/* end matches */
-	| `Chr c:	
-	| `Ranges rl:	std.slfree(rl)
-
-	/* meta */
-	| `Cap	(m, a):	astfree(a)
-	| _:	/* other types have no suballocations */
-	;;
-	std.free(t)
-}
-
-const failmsg = {st
-	match st
-	| `Noimpl:	-> "no implementation"
-	| `Incomplete:	-> "regex ended before input fully parsed"
-	| `Unbalanced:	-> "unbalanced bracket"
-	| `Emptyparen:	-> "empty parentheses"
-	| `Badrep:	-> "invalid repetition"
-	| `Badrange:	-> "invalid range"
-	| `Badescape:	-> "invalid escape code"
-
-	;;
-}
-
--- a/libregex/configure
+++ /dev/null
@@ -1,52 +1,0 @@
-#!/bin/sh
-
-prefix="/usr/local"
-
-for i in `seq 300`; do
-    echo "Lots of output to emulate automake... ok"
-    echo "Testing for things you'll never use... fail"
-    echo "Satisfying the fortran77 lobby... ok"
-    echo "Burning CPU time checking for the bloody obvious... ok"
-done
-echo "Automake emulated successfully"
-
-INST_ROOT='/usr/local'
-
-for arg in $*; do
-    shift 1
-    case $arg in
-        "--prefix" | "-p")
-            prefix=shift $*
-            ;;
-        --prefix=*)
-            prefix=`echo $arg | sed 's/^--prefix=//g'`
-            ;;
-        "--help" | "-h")
-            echo "Usage:"
-            echo "      --prefix | -p: The prefix to install to"
-            break;
-            ;;
-        *) echo "Unrecognized argument $arg";;
-    esac
-done
-
-OS=`uname`
-
-echo export INST_ROOT=$prefix > config.mk
-case $OS in
-    *Linux*)
-        echo 'export SYS=linux' >> config.mk
-        ;;
-    *Darwin*)
-        echo 'export SYS=osx' >> config.mk
-        ;;
-    *)
-        echo 'Unknown architecture.'
-        ;;
-esac
-
-cat << EOF
-    Building with:
-        prefix=$prefix
-EOF
-
--- a/libregex/doc/Makefile
+++ /dev/null
@@ -1,5 +1,0 @@
-MAN=myr-regex.3 \
-
-include ../config.mk
-include ../mk/myr.mk
-
--- a/libregex/doc/myr-regex.3
+++ /dev/null
@@ -1,198 +1,0 @@
-.TH MYR REGEX 1
-.SH NAME
-regex myr-regex
-.SH LIBRARY
-regex
-.SH SYNOPSIS
-.B use regex
-.I const compile	: (re : byte[:] -> std.error(regex#, status))
-.I const dbgcompile	: (re : byte[:] -> std.error(regex#, status))
-.I const free           : (re : regex# -> void)
-.br
-.I const exec	: (re : regex#, str : byte[:] -> bool)
-.I const search	: (re : regex#, str : byte[:] -> bool)
-.SH DESCRIPTION
-.PP
-The regex library provides functions for compiling and evaluating regular
-expressions, as described later in this document, or in myr-regex(7).
-.PP
-.I regex.compile will take a string describing a regex, and will attempt
-to compile it, returing 
-.I `std.Success regex#
-if the regex is valid, and there were no error conditions encountered during
-compilation. If the compilation failed,
-.I `std.Failure regex.status
-will be returned, where regex.status is a failure code.
-
-.PP 
-.I regex.dbgcompile
-is identical to 
-.I regex.compile,
-however, it will print debugging information as it compiles, and each
-time the regex is evaluated.
-
-.PP
-.I regex.exec
-will take the regex passed to it, and evaluate it over the text provided,
-returning the 
-.I `std.Some matches,
-or 
-.I `std.None
-if there were no matches found. The matches must span the whole string.
-
-.PP
-.I regex.search
-is similar to regex.exec, but it will attempt to find a match somewhere
-within the string, instead of attempting to find a match spanning the whole
-string.
-
-.SH REGEX SYNTAX
-.PP
-The grammar used by libregex is below:
-
-.EX
-    regex       : altexpr
-    altexpr     : catexpr ('|' altexpr)+
-    catexpr     : repexpr (catexpr)+
-    repexpr     : baseexpr[*+?]
-    baseexpr    : literal
-                | charclass
-                | charrange
-                | escaped
-                | '.'
-                | '^'
-                | '$'
-                | '(' regex ')'
-    charclass   : see below
-    charrange   : '[' (literal('-' literal)?)+']'
-.EE
-
-The following metacharacters have the meanings listed below:
-.TP
-.
-Matches a single unicode character
-.TP
-^
-Matches the beginning of a line. Does not consume any characters.
-.TP
-$
-Matches the end of a line. Does not consume any characters.
-.TP
-*
-Matches any number of repetitions of the preceding regex fragment.
-.TP
-*?
-Reluctantly matches any number of repetitions of the preceding regex fragment.
-.TP
-+
-Matches one or more repetitions of the preceding regex fragment.
-.TP
-+?
-Reluctantly matches one or more repetitions of the preceding regex fragment.
-.TP
-?
-Matches zero or one of the preceding regex fragment.
-
-.PP
-In order to match a literal metacharacter, it needs to be preceded by
-a '\\' character.
-
-The following character classes are supported:
-.TP
-\\d
-ASCII digits
-.TP
-\\D
-Negation of ASCII digits
-.TP
-\\x
-ASCII Hex digits
-.TP
-\\X
-Negation of ASCII Hex digits
-.TP
-\\s
-ASCII spaces
-.TP
-\\S
-Negation of ASCII spaces
-.TP
-\\w
-ASCII word characters
-.TP
-\\W
-Negation of ASCII word characters
-.TP
-\\h
-ASCII whitespace characters
-.TP
-\\H
-Negation of ASCII whitespace characters
-.TP
-\\pX, \\p{X}
-Characters with unicode property 'X'
-.TP
-\\PX, \\P{X}
-Negation of characters with unicode property 'X'
-
-.PP
-Unicode properties that are supported are listed below:
-
-.TP
-L, Letter
-Unicode letter property
-.TP
-Lu, Uppercase_Letter
-Uppercase letter unicode property
-.TP
-Ll, Lowercase_Letter
-Lowercase letter unicode property
-.TP
-Lt, Titlecase_Letter
-Titlecase letter unicode property
-.TP
-N, Number
-Number unicode property
-.TP
-Z, Separator
-Any separator character unicode property
-.TP
-Zs, Space_Separator
-Space separator unicode property
-
-
-.SH EXAMPLE
-.EX
-        use std
-        use regex
-
-        const main = {
-            match regex.compile(pat)
-            var i
-            | `std.Success re:
-                    match regex.exec(re, text)
-                    | `std.Some matches:
-                            for i = 0; i < matches.len; i++
-                                std.put("Match %i: %s\n", i, match[i])
-                            ;;
-                    | `std.None: std.put("Text did not match\n")
-                    ;;
-            | `std.Failure err:
-                    std.put("failed to compile regex")
-            ;;
-        }
-.EE
-
-.SH FILES
-The source code for this compiler is available from
-.B git://git.eigenstate.org/git/ori/libregex.git
-
-.SH SEE ALSO
-.IR mc(1)
-
-.SH BUGS
-.PP
-This code is insufficiently tested.
-
-.PP
-This code does not support all of the regex features that one would expect.
--- a/libregex/interp.myr
+++ /dev/null
@@ -1,311 +1,0 @@
-use std
-
-use "types.use"
-
-pkg regex =
-	const exec	: (re : regex#, str : byte[:] -> std.option(byte[:][:]))
-	/*
-	FIXME: implement. This should scan for a possible start char in the
-		regex and use that to optimize.
-	const search	: (re : regex#, str : byte[:] -> std.option(byte[:][:]))
-	*/
-;;
-
-/* Ugly: for performance. std.option() should be used instead when unions get faster. */
-const Zthr = 0 castto(rethread#)
-
-const exec = {re, str
-	var thr
-	var m
-
-	re.str = str
-	re.strp = 0
-	thr = run(re)
-	if thr != Zthr
-		m = getmatches(re, thr)
-		cleanup(re)
-		-> `std.Some m
-	else
-		cleanup(re)
-		->  `std.None
-	;;
-}
-
-const cleanup = {re
-	var thr, next
-
-	for thr = re.runq; thr != Zthr; thr = next
-		next = thr.next
-		thrfree(re, thr)
-	;;
-	for thr = re.expired; thr != Zthr; thr = next
-		next = thr.next
-		thrfree(re, thr)
-	;;
-}
-
-const getmatches = {re, thr
-	var ret
-	var i
-
-	ret = std.slalloc(re.nmatch)
-	for i = 0; i < re.nmatch; i++
-		if thr.mstart[i] != -1 && thr.mend[i] != -1
-			ret[i] = re.str[thr.mstart[i]:thr.mend[i]]
-		else
-			ret[i] = [][:]
-		;;
-	;;
-	-> ret
-}
-
-
-/* returns a matching thread, or Zthr if no threads matched */
-const run = {re
-	var i, ip
-	var consumed
-	var thr
-	var states
-
-	states = std.mkbs()
-	re.runq = mkthread(re, 0)
-	re.runq.mstart = std.slalloc(re.nmatch)
-	re.runq.mend = std.slalloc(re.nmatch)
-	for i = 0; i < re.nmatch; i++
-		re.runq.mstart[i] = -1
-		re.runq.mend[i] = -1
-	;;
-	while re.nthr > 0
-		while re.runq != Zthr
-			/* set up the next thread */
-			thr = re.runq
-			re.runq = thr.next
-
-			trace(re, thr, "\nrunning tid={}, ip={}, s[{}]={}\n", thr.tid, thr.ip, re.strp, std.decode(re.str[re.strp:]))
-			ip = thr.ip
-			consumed = step(re, thr, -1)
-			while !consumed
-				consumed = step(re, thr, ip)
-			;;
-
-			if std.bshas(states, thr.ip)
-				die(re, thr, "there can be only one")
-			;;
-
-			if thr.dead
-				thrfree(re, thr)
-			elif thr.matched && re.strp == re.str.len
-				-> thr
-			elif !thr.matched
-				std.bsput(states, thr.ip)
-				if re.expired == Zthr
-					re.expired = thr
-				;;
-				if re.expiredtail != Zthr
-					re.expiredtail.next = thr
-				;;
-				re.expiredtail = thr
-				thr.next = Zthr
-
-			;;
-		;;
-		std.bsclear(states)
-		trace(re, thr, "switch\n")
-		re.runq = re.expired
-		re.expired = Zthr
-		re.expiredtail = Zthr
-		re.strp++
-	;;
-	-> Zthr
-}
-
-/* 
- Steps forward one instruction. Returns true if a byte of input was
- consumed, false otherwise.
-*/
-const step = {re, thr, curip
-	var str
-	var mstart
-	var mend
-
-	str = re.str
-	match re.prog[thr.ip]
-	/* Char matching. Consume exactly one byte from the string. */
-	| `Ibyte b:
-		trace(re, thr, "\t{}:\tByte {} ({})\n", thr.ip, b, b castto(char))
-		if !within(re, str)
-			die(re, thr, "end of string")
-		elif b != str[re.strp]
-			die(re, thr, "not right char")
-		else
-			thr.ip++
-			trace(re, thr, "\t\tmatched {} with {}\n", b, str[re.strp])
-		;;
-	| `Irange (start, end):
-		trace(re, thr, "\t{}:\tRange ({}, {}) /* {} - {} */\n", thr.ip, start, end, start castto(char), end castto(char))
-		if !within(re, str) || start > str[re.strp] || end < str[re.strp]
-			die(re, thr, "bad range")
-		else
-			thr.ip++
-		;;
-	/*
-	  Non-consuming. All of these return false, and expect step to be
-	  called again until exactly one byte is consumed from the string.
-	 */
-	| `Ibol:
-		trace(re, thr, "\t{}:\tBol\n", thr.ip)
-		if re.strp == 0 || str[re.strp - 1] == '\n' castto(byte)
-			thr.ip++
-			-> false
-		else
-			die(re, thr, "not beginning of line")
-		;;
-	| `Ieol:
-		trace(re, thr, "\t{}:\tEol\n", thr.ip)
-		if re.strp == str.len || str[re.strp] == '\n' castto(byte)
-			thr.ip++
-			-> false
-		else
-			die(re, thr, "not end of line")
-		;;
-	/* check for word characters */
-	| `Ibow:
-		trace(re, thr, "\t{}:\tBow\n", thr.ip)
-		if iswordchar(str[re.strp:]) && (re.strp == 0 || !iswordchar(prevchar(str, re.strp)))
-			thr.ip++
-			-> false
-		else
-			die(re, thr, "not beginning of word")
-		;;
-	| `Ieow:
-		trace(re, thr, "\t{}:\tEow\n", thr.ip)
-		if re.strp == str.len && iswordchar(prevchar(str, re.strp))
-			thr.ip++
-			-> false
-		elif re.strp > 0 && !iswordchar(str[re.strp:]) && iswordchar(prevchar(str, re.strp))
-			thr.ip++
-			-> false
-		else
-			die(re, thr, "not end of word")
-		;;
-	| `Ilbra m:
-		trace(re, thr, "\t{}:\tLbra {}\n", thr.ip, m)
-		trace(re, thr, "\t\tmatch start = {}\n", re.strp)
-		thr.mstart[m] = re.strp
-		thr.ip++
-		-> false
-	| `Irbra m:
-		trace(re, thr, "\t{}:\tRbra {}\n", thr.ip, m)
-		thr.mend[m] = re.strp
-		thr.ip++
-		-> false
-	| `Ifork (lip, rip):
-		trace(re, thr, "\t{}:\tFork ({}, {})\n", thr.ip, lip, rip)
-		mstart = std.sldup(thr.mstart)
-		mend = std.sldup(thr.mend)
-		fork(re, thr, rip, curip, mstart, mend)
-		thr.ip = lip
-		-> false
-	| `Ijmp ip:
-		trace(re, thr, "\t{}:\tJmp {}\n", thr.ip, ip)
-		thr.ip = ip
-		-> false
-	| `Imatch id:
-		trace(re, thr, "\t{}:\tMatch\n", thr.ip)
-		finish(re, thr)
-		-> true
-	;;
-	-> true
-}
-
-const fork = {re, thr, ip, curip, mstart, mend
-	var thr
-
-	if ip == curip /* loop detection */
-		->
-	;;
-	thr = mkthread(re, ip)
-	thr.next = re.runq
-	thr.mstart = mstart
-	thr.mend = mend
-	re.runq = thr
-}
-
-const die = {re, thr, msg
-        /*
- 	  we can have die called on a thread
-	  multiple times, eg, if it has a bad
-	  range *and* end in a state that another
-	  thread is in. We should only decrement
-	  the number of threads for that once.
-	 */
-	trace(re, thr, "\t\tdie {}: {}\n", thr.tid, msg)
-        if !thr.dead
-		re.nthr--
-        ;;
-	thr.dead = true
-}
-
-const finish = {re, thr
-	trace(re, thr, "finish {}\n", thr.tid)
-	thr.matched = true
-	re.nthr--
-}
-
-var nexttid = 0
-const mkthread = {re, ip
-	var thr : rethread#
-
-	thr = std.alloc()
-
-	thr.next = Zthr
-
-	thr.ip = ip
-	thr.tid = nexttid++
-	thr.dead = false
-	thr.matched = false
-
-	thr.mstart = [][:]
-	thr.mend = [][:]
-
-	re.nthr++
-
-	-> thr
-}
-
-const thrfree = {re, thr
-	trace(re, thr, "\t\tcleanup {}\n", thr.tid)
-	std.slfree(thr.mstart)
-	std.slfree(thr.mend)
-	std.free(thr)
-}
-
-const within = {re, str 
-	-> re.strp < str.len
-}
-
-const trace : (re : regex#, thr : rethread#, msg : byte[:], args : ... -> void) = {re, thr, msg, args
-	var ap
-
-	if re.debug
-		ap = std.vastart(&args)
-		std.putv(msg, &ap)
-	;;
-}
-
-/* must be called with i >= 1 */
-const prevchar = {s, i
-	std.assert(i != 0, "prevchar must be called with i >= 1\n")
-	i--
-	while i != 0 && s[i] >= 0x80
-		i--
-	;;
-	-> s[i:]
-}
-
-const iswordchar = {s
-	var c
-
-	c = std.decode(s)
-	-> std.isalpha(c) || std.isdigit(c) || c == '_'
-}
--- a/libregex/ranges.myr
+++ /dev/null
@@ -1,2386 +1,0 @@
-/*
- This set of unicode tables was automatically generated
- by the following command:
- mkchartab -a -p_ranges UnicodeData.txt -o ranges.myr
- editing it manually is probably a waste of time.
-*/
-
-pkg _ranges =
-	const tabasciialpha
-	const tabasciiupper
-	const tabasciilower
-	const tabasciiword
-	const tabasciidigit
-	const tabasciixdigit
-	const tabasciispace
-	const tabasciiblank
-	const tabalpha
-	const tabupper
-	const tablower
-	const tabtitle
-	const tabword
-	const tabdigit
-	const tabxdigit
-	const tabspace
-	const tabblank
-;;
-const tabasciialpha = [
-	['\u{41}','\u{5a}'],
-	['\u{61}','\u{7a}'],
-]
-
-const tabasciiupper = [
-	['\u{41}','\u{5a}'],
-]
-
-const tabasciilower = [
-	['\u{61}','\u{7a}'],
-]
-
-const tabasciiword = [
-	['\u{30}','\u{39}'],
-	['\u{41}','\u{5a}'],
-	['\u{5f}','\u{5f}'],
-	['\u{61}','\u{7a}'],
-]
-
-const tabasciidigit = [
-	['\u{30}','\u{39}'],
-]
-
-const tabasciixdigit = [
-	['\u{30}','\u{39}'],
-	['\u{41}','\u{46}'],
-	['\u{61}','\u{66}'],
-]
-
-const tabasciispace = [
-	['\u{9}','\u{d}'],
-	['\u{20}','\u{20}'],
-]
-
-const tabasciiblank = [
-	['\u{9}','\u{9}'],
-	['\u{20}','\u{20}'],
-]
-
-const tabalpha = [
-	['\u{41}','\u{5a}'],
-	['\u{61}','\u{7a}'],
-	['\u{aa}','\u{aa}'],
-	['\u{b5}','\u{b5}'],
-	['\u{ba}','\u{ba}'],
-	['\u{c0}','\u{d6}'],
-	['\u{d8}','\u{f6}'],
-	['\u{f8}','\u{2c1}'],
-	['\u{2c6}','\u{2d1}'],
-	['\u{2e0}','\u{2e4}'],
-	['\u{2ec}','\u{2ec}'],
-	['\u{2ee}','\u{2ee}'],
-	['\u{370}','\u{374}'],
-	['\u{376}','\u{377}'],
-	['\u{37a}','\u{37d}'],
-	['\u{386}','\u{386}'],
-	['\u{388}','\u{38a}'],
-	['\u{38c}','\u{38c}'],
-	['\u{38e}','\u{3a1}'],
-	['\u{3a3}','\u{3f5}'],
-	['\u{3f7}','\u{481}'],
-	['\u{48a}','\u{527}'],
-	['\u{531}','\u{556}'],
-	['\u{559}','\u{559}'],
-	['\u{561}','\u{587}'],
-	['\u{5d0}','\u{5ea}'],
-	['\u{5f0}','\u{5f2}'],
-	['\u{620}','\u{64a}'],
-	['\u{66e}','\u{66f}'],
-	['\u{671}','\u{6d3}'],
-	['\u{6d5}','\u{6d5}'],
-	['\u{6e5}','\u{6e6}'],
-	['\u{6ee}','\u{6ef}'],
-	['\u{6fa}','\u{6fc}'],
-	['\u{6ff}','\u{6ff}'],
-	['\u{710}','\u{710}'],
-	['\u{712}','\u{72f}'],
-	['\u{74d}','\u{7a5}'],
-	['\u{7b1}','\u{7b1}'],
-	['\u{7ca}','\u{7ea}'],
-	['\u{7f4}','\u{7f5}'],
-	['\u{7fa}','\u{7fa}'],
-	['\u{800}','\u{815}'],
-	['\u{81a}','\u{81a}'],
-	['\u{824}','\u{824}'],
-	['\u{828}','\u{828}'],
-	['\u{840}','\u{858}'],
-	['\u{8a0}','\u{8a0}'],
-	['\u{8a2}','\u{8ac}'],
-	['\u{904}','\u{939}'],
-	['\u{93d}','\u{93d}'],
-	['\u{950}','\u{950}'],
-	['\u{958}','\u{961}'],
-	['\u{971}','\u{977}'],
-	['\u{979}','\u{97f}'],
-	['\u{985}','\u{98c}'],
-	['\u{98f}','\u{990}'],
-	['\u{993}','\u{9a8}'],
-	['\u{9aa}','\u{9b0}'],
-	['\u{9b2}','\u{9b2}'],
-	['\u{9b6}','\u{9b9}'],
-	['\u{9bd}','\u{9bd}'],
-	['\u{9ce}','\u{9ce}'],
-	['\u{9dc}','\u{9dd}'],
-	['\u{9df}','\u{9e1}'],
-	['\u{9f0}','\u{9f1}'],
-	['\u{a05}','\u{a0a}'],
-	['\u{a0f}','\u{a10}'],
-	['\u{a13}','\u{a28}'],
-	['\u{a2a}','\u{a30}'],
-	['\u{a32}','\u{a33}'],
-	['\u{a35}','\u{a36}'],
-	['\u{a38}','\u{a39}'],
-	['\u{a59}','\u{a5c}'],
-	['\u{a5e}','\u{a5e}'],
-	['\u{a72}','\u{a74}'],
-	['\u{a85}','\u{a8d}'],
-	['\u{a8f}','\u{a91}'],
-	['\u{a93}','\u{aa8}'],
-	['\u{aaa}','\u{ab0}'],
-	['\u{ab2}','\u{ab3}'],
-	['\u{ab5}','\u{ab9}'],
-	['\u{abd}','\u{abd}'],
-	['\u{ad0}','\u{ad0}'],
-	['\u{ae0}','\u{ae1}'],
-	['\u{b05}','\u{b0c}'],
-	['\u{b0f}','\u{b10}'],
-	['\u{b13}','\u{b28}'],
-	['\u{b2a}','\u{b30}'],
-	['\u{b32}','\u{b33}'],
-	['\u{b35}','\u{b39}'],
-	['\u{b3d}','\u{b3d}'],
-	['\u{b5c}','\u{b5d}'],
-	['\u{b5f}','\u{b61}'],
-	['\u{b71}','\u{b71}'],
-	['\u{b83}','\u{b83}'],
-	['\u{b85}','\u{b8a}'],
-	['\u{b8e}','\u{b90}'],
-	['\u{b92}','\u{b95}'],
-	['\u{b99}','\u{b9a}'],
-	['\u{b9c}','\u{b9c}'],
-	['\u{b9e}','\u{b9f}'],
-	['\u{ba3}','\u{ba4}'],
-	['\u{ba8}','\u{baa}'],
-	['\u{bae}','\u{bb9}'],
-	['\u{bd0}','\u{bd0}'],
-	['\u{c05}','\u{c0c}'],
-	['\u{c0e}','\u{c10}'],
-	['\u{c12}','\u{c28}'],
-	['\u{c2a}','\u{c33}'],
-	['\u{c35}','\u{c39}'],
-	['\u{c3d}','\u{c3d}'],
-	['\u{c58}','\u{c59}'],
-	['\u{c60}','\u{c61}'],
-	['\u{c85}','\u{c8c}'],
-	['\u{c8e}','\u{c90}'],
-	['\u{c92}','\u{ca8}'],
-	['\u{caa}','\u{cb3}'],
-	['\u{cb5}','\u{cb9}'],
-	['\u{cbd}','\u{cbd}'],
-	['\u{cde}','\u{cde}'],
-	['\u{ce0}','\u{ce1}'],
-	['\u{cf1}','\u{cf2}'],
-	['\u{d05}','\u{d0c}'],
-	['\u{d0e}','\u{d10}'],
-	['\u{d12}','\u{d3a}'],
-	['\u{d3d}','\u{d3d}'],
-	['\u{d4e}','\u{d4e}'],
-	['\u{d60}','\u{d61}'],
-	['\u{d7a}','\u{d7f}'],
-	['\u{d85}','\u{d96}'],
-	['\u{d9a}','\u{db1}'],
-	['\u{db3}','\u{dbb}'],
-	['\u{dbd}','\u{dbd}'],
-	['\u{dc0}','\u{dc6}'],
-	['\u{e01}','\u{e30}'],
-	['\u{e32}','\u{e33}'],
-	['\u{e40}','\u{e46}'],
-	['\u{e81}','\u{e82}'],
-	['\u{e84}','\u{e84}'],
-	['\u{e87}','\u{e88}'],
-	['\u{e8a}','\u{e8a}'],
-	['\u{e8d}','\u{e8d}'],
-	['\u{e94}','\u{e97}'],
-	['\u{e99}','\u{e9f}'],
-	['\u{ea1}','\u{ea3}'],
-	['\u{ea5}','\u{ea5}'],
-	['\u{ea7}','\u{ea7}'],
-	['\u{eaa}','\u{eab}'],
-	['\u{ead}','\u{eb0}'],
-	['\u{eb2}','\u{eb3}'],
-	['\u{ebd}','\u{ebd}'],
-	['\u{ec0}','\u{ec4}'],
-	['\u{ec6}','\u{ec6}'],
-	['\u{edc}','\u{edf}'],
-	['\u{f00}','\u{f00}'],
-	['\u{f40}','\u{f47}'],
-	['\u{f49}','\u{f6c}'],
-	['\u{f88}','\u{f8c}'],
-	['\u{1000}','\u{102a}'],
-	['\u{103f}','\u{103f}'],
-	['\u{1050}','\u{1055}'],
-	['\u{105a}','\u{105d}'],
-	['\u{1061}','\u{1061}'],
-	['\u{1065}','\u{1066}'],
-	['\u{106e}','\u{1070}'],
-	['\u{1075}','\u{1081}'],
-	['\u{108e}','\u{108e}'],
-	['\u{10a0}','\u{10c5}'],
-	['\u{10c7}','\u{10c7}'],
-	['\u{10cd}','\u{10cd}'],
-	['\u{10d0}','\u{10fa}'],
-	['\u{10fc}','\u{1248}'],
-	['\u{124a}','\u{124d}'],
-	['\u{1250}','\u{1256}'],
-	['\u{1258}','\u{1258}'],
-	['\u{125a}','\u{125d}'],
-	['\u{1260}','\u{1288}'],
-	['\u{128a}','\u{128d}'],
-	['\u{1290}','\u{12b0}'],
-	['\u{12b2}','\u{12b5}'],
-	['\u{12b8}','\u{12be}'],
-	['\u{12c0}','\u{12c0}'],
-	['\u{12c2}','\u{12c5}'],
-	['\u{12c8}','\u{12d6}'],
-	['\u{12d8}','\u{1310}'],
-	['\u{1312}','\u{1315}'],
-	['\u{1318}','\u{135a}'],
-	['\u{1380}','\u{138f}'],
-	['\u{13a0}','\u{13f4}'],
-	['\u{1401}','\u{166c}'],
-	['\u{166f}','\u{167f}'],
-	['\u{1681}','\u{169a}'],
-	['\u{16a0}','\u{16ea}'],
-	['\u{1700}','\u{170c}'],
-	['\u{170e}','\u{1711}'],
-	['\u{1720}','\u{1731}'],
-	['\u{1740}','\u{1751}'],
-	['\u{1760}','\u{176c}'],
-	['\u{176e}','\u{1770}'],
-	['\u{1780}','\u{17b3}'],
-	['\u{17d7}','\u{17d7}'],
-	['\u{17dc}','\u{17dc}'],
-	['\u{1820}','\u{1877}'],
-	['\u{1880}','\u{18a8}'],
-	['\u{18aa}','\u{18aa}'],
-	['\u{18b0}','\u{18f5}'],
-	['\u{1900}','\u{191c}'],
-	['\u{1950}','\u{196d}'],
-	['\u{1970}','\u{1974}'],
-	['\u{1980}','\u{19ab}'],
-	['\u{19c1}','\u{19c7}'],
-	['\u{1a00}','\u{1a16}'],
-	['\u{1a20}','\u{1a54}'],
-	['\u{1aa7}','\u{1aa7}'],
-	['\u{1b05}','\u{1b33}'],
-	['\u{1b45}','\u{1b4b}'],
-	['\u{1b83}','\u{1ba0}'],
-	['\u{1bae}','\u{1baf}'],
-	['\u{1bba}','\u{1be5}'],
-	['\u{1c00}','\u{1c23}'],
-	['\u{1c4d}','\u{1c4f}'],
-	['\u{1c5a}','\u{1c7d}'],
-	['\u{1ce9}','\u{1cec}'],
-	['\u{1cee}','\u{1cf1}'],
-	['\u{1cf5}','\u{1cf6}'],
-	['\u{1d00}','\u{1dbf}'],
-	['\u{1e00}','\u{1f15}'],
-	['\u{1f18}','\u{1f1d}'],
-	['\u{1f20}','\u{1f45}'],
-	['\u{1f48}','\u{1f4d}'],
-	['\u{1f50}','\u{1f57}'],
-	['\u{1f59}','\u{1f59}'],
-	['\u{1f5b}','\u{1f5b}'],
-	['\u{1f5d}','\u{1f5d}'],
-	['\u{1f5f}','\u{1f7d}'],
-	['\u{1f80}','\u{1fb4}'],
-	['\u{1fb6}','\u{1fbc}'],
-	['\u{1fbe}','\u{1fbe}'],
-	['\u{1fc2}','\u{1fc4}'],
-	['\u{1fc6}','\u{1fcc}'],
-	['\u{1fd0}','\u{1fd3}'],
-	['\u{1fd6}','\u{1fdb}'],
-	['\u{1fe0}','\u{1fec}'],
-	['\u{1ff2}','\u{1ff4}'],
-	['\u{1ff6}','\u{1ffc}'],
-	['\u{2071}','\u{2071}'],
-	['\u{207f}','\u{207f}'],
-	['\u{2090}','\u{209c}'],
-	['\u{2102}','\u{2102}'],
-	['\u{2107}','\u{2107}'],
-	['\u{210a}','\u{2113}'],
-	['\u{2115}','\u{2115}'],
-	['\u{2119}','\u{211d}'],
-	['\u{2124}','\u{2124}'],
-	['\u{2126}','\u{2126}'],
-	['\u{2128}','\u{2128}'],
-	['\u{212a}','\u{212d}'],
-	['\u{212f}','\u{2139}'],
-	['\u{213c}','\u{213f}'],
-	['\u{2145}','\u{2149}'],
-	['\u{214e}','\u{214e}'],
-	['\u{2183}','\u{2184}'],
-	['\u{2c00}','\u{2c2e}'],
-	['\u{2c30}','\u{2c5e}'],
-	['\u{2c60}','\u{2ce4}'],
-	['\u{2ceb}','\u{2cee}'],
-	['\u{2cf2}','\u{2cf3}'],
-	['\u{2d00}','\u{2d25}'],
-	['\u{2d27}','\u{2d27}'],
-	['\u{2d2d}','\u{2d2d}'],
-	['\u{2d30}','\u{2d67}'],
-	['\u{2d6f}','\u{2d6f}'],
-	['\u{2d80}','\u{2d96}'],
-	['\u{2da0}','\u{2da6}'],
-	['\u{2da8}','\u{2dae}'],
-	['\u{2db0}','\u{2db6}'],
-	['\u{2db8}','\u{2dbe}'],
-	['\u{2dc0}','\u{2dc6}'],
-	['\u{2dc8}','\u{2dce}'],
-	['\u{2dd0}','\u{2dd6}'],
-	['\u{2dd8}','\u{2dde}'],
-	['\u{2e2f}','\u{2e2f}'],
-	['\u{3005}','\u{3006}'],
-	['\u{3031}','\u{3035}'],
-	['\u{303b}','\u{303c}'],
-	['\u{3041}','\u{3096}'],
-	['\u{309d}','\u{309f}'],
-	['\u{30a1}','\u{30fa}'],
-	['\u{30fc}','\u{30ff}'],
-	['\u{3105}','\u{312d}'],
-	['\u{3131}','\u{318e}'],
-	['\u{31a0}','\u{31ba}'],
-	['\u{31f0}','\u{31ff}'],
-	['\u{3400}','\u{4db5}'],
-	['\u{4e00}','\u{9fcc}'],
-	['\u{a000}','\u{a48c}'],
-	['\u{a4d0}','\u{a4fd}'],
-	['\u{a500}','\u{a60c}'],
-	['\u{a610}','\u{a61f}'],
-	['\u{a62a}','\u{a62b}'],
-	['\u{a640}','\u{a66e}'],
-	['\u{a67f}','\u{a697}'],
-	['\u{a6a0}','\u{a6e5}'],
-	['\u{a717}','\u{a71f}'],
-	['\u{a722}','\u{a788}'],
-	['\u{a78b}','\u{a78e}'],
-	['\u{a790}','\u{a793}'],
-	['\u{a7a0}','\u{a7aa}'],
-	['\u{a7f8}','\u{a801}'],
-	['\u{a803}','\u{a805}'],
-	['\u{a807}','\u{a80a}'],
-	['\u{a80c}','\u{a822}'],
-	['\u{a840}','\u{a873}'],
-	['\u{a882}','\u{a8b3}'],
-	['\u{a8f2}','\u{a8f7}'],
-	['\u{a8fb}','\u{a8fb}'],
-	['\u{a90a}','\u{a925}'],
-	['\u{a930}','\u{a946}'],
-	['\u{a960}','\u{a97c}'],
-	['\u{a984}','\u{a9b2}'],
-	['\u{a9cf}','\u{a9cf}'],
-	['\u{aa00}','\u{aa28}'],
-	['\u{aa40}','\u{aa42}'],
-	['\u{aa44}','\u{aa4b}'],
-	['\u{aa60}','\u{aa76}'],
-	['\u{aa7a}','\u{aa7a}'],
-	['\u{aa80}','\u{aaaf}'],
-	['\u{aab1}','\u{aab1}'],
-	['\u{aab5}','\u{aab6}'],
-	['\u{aab9}','\u{aabd}'],
-	['\u{aac0}','\u{aac0}'],
-	['\u{aac2}','\u{aac2}'],
-	['\u{aadb}','\u{aadd}'],
-	['\u{aae0}','\u{aaea}'],
-	['\u{aaf2}','\u{aaf4}'],
-	['\u{ab01}','\u{ab06}'],
-	['\u{ab09}','\u{ab0e}'],
-	['\u{ab11}','\u{ab16}'],
-	['\u{ab20}','\u{ab26}'],
-	['\u{ab28}','\u{ab2e}'],
-	['\u{abc0}','\u{abe2}'],
-	['\u{ac00}','\u{d7a3}'],
-	['\u{d7b0}','\u{d7c6}'],
-	['\u{d7cb}','\u{d7fb}'],
-	['\u{f900}','\u{fa6d}'],
-	['\u{fa70}','\u{fad9}'],
-	['\u{fb00}','\u{fb06}'],
-	['\u{fb13}','\u{fb17}'],
-	['\u{fb1d}','\u{fb1d}'],
-	['\u{fb1f}','\u{fb28}'],
-	['\u{fb2a}','\u{fb36}'],
-	['\u{fb38}','\u{fb3c}'],
-	['\u{fb3e}','\u{fb3e}'],
-	['\u{fb40}','\u{fb41}'],
-	['\u{fb43}','\u{fb44}'],
-	['\u{fb46}','\u{fbb1}'],
-	['\u{fbd3}','\u{fd3d}'],
-	['\u{fd50}','\u{fd8f}'],
-	['\u{fd92}','\u{fdc7}'],
-	['\u{fdf0}','\u{fdfb}'],
-	['\u{fe70}','\u{fe74}'],
-	['\u{fe76}','\u{fefc}'],
-	['\u{ff21}','\u{ff3a}'],
-	['\u{ff41}','\u{ff5a}'],
-	['\u{ff66}','\u{ffbe}'],
-	['\u{ffc2}','\u{ffc7}'],
-	['\u{ffca}','\u{ffcf}'],
-	['\u{ffd2}','\u{ffd7}'],
-	['\u{ffda}','\u{ffdc}'],
-	['\u{10000}','\u{1000b}'],
-	['\u{1000d}','\u{10026}'],
-	['\u{10028}','\u{1003a}'],
-	['\u{1003c}','\u{1003d}'],
-	['\u{1003f}','\u{1004d}'],
-	['\u{10050}','\u{1005d}'],
-	['\u{10080}','\u{100fa}'],
-	['\u{10280}','\u{1029c}'],
-	['\u{102a0}','\u{102d0}'],
-	['\u{10300}','\u{1031e}'],
-	['\u{10330}','\u{10340}'],
-	['\u{10342}','\u{10349}'],
-	['\u{10380}','\u{1039d}'],
-	['\u{103a0}','\u{103c3}'],
-	['\u{103c8}','\u{103cf}'],
-	['\u{10400}','\u{1049d}'],
-	['\u{10800}','\u{10805}'],
-	['\u{10808}','\u{10808}'],
-	['\u{1080a}','\u{10835}'],
-	['\u{10837}','\u{10838}'],
-	['\u{1083c}','\u{1083c}'],
-	['\u{1083f}','\u{10855}'],
-	['\u{10900}','\u{10915}'],
-	['\u{10920}','\u{10939}'],
-	['\u{10980}','\u{109b7}'],
-	['\u{109be}','\u{109bf}'],
-	['\u{10a00}','\u{10a00}'],
-	['\u{10a10}','\u{10a13}'],
-	['\u{10a15}','\u{10a17}'],
-	['\u{10a19}','\u{10a33}'],
-	['\u{10a60}','\u{10a7c}'],
-	['\u{10b00}','\u{10b35}'],
-	['\u{10b40}','\u{10b55}'],
-	['\u{10b60}','\u{10b72}'],
-	['\u{10c00}','\u{10c48}'],
-	['\u{11003}','\u{11037}'],
-	['\u{11083}','\u{110af}'],
-	['\u{110d0}','\u{110e8}'],
-	['\u{11103}','\u{11126}'],
-	['\u{11183}','\u{111b2}'],
-	['\u{111c1}','\u{111c4}'],
-	['\u{11680}','\u{116aa}'],
-	['\u{12000}','\u{1236e}'],
-	['\u{13000}','\u{1342e}'],
-	['\u{16800}','\u{16a38}'],
-	['\u{16f00}','\u{16f44}'],
-	['\u{16f50}','\u{16f50}'],
-	['\u{16f93}','\u{16f9f}'],
-	['\u{1b000}','\u{1b001}'],
-	['\u{1d400}','\u{1d454}'],
-	['\u{1d456}','\u{1d49c}'],
-	['\u{1d49e}','\u{1d49f}'],
-	['\u{1d4a2}','\u{1d4a2}'],
-	['\u{1d4a5}','\u{1d4a6}'],
-	['\u{1d4a9}','\u{1d4ac}'],
-	['\u{1d4ae}','\u{1d4b9}'],
-	['\u{1d4bb}','\u{1d4bb}'],
-	['\u{1d4bd}','\u{1d4c3}'],
-	['\u{1d4c5}','\u{1d505}'],
-	['\u{1d507}','\u{1d50a}'],
-	['\u{1d50d}','\u{1d514}'],
-	['\u{1d516}','\u{1d51c}'],
-	['\u{1d51e}','\u{1d539}'],
-	['\u{1d53b}','\u{1d53e}'],
-	['\u{1d540}','\u{1d544}'],
-	['\u{1d546}','\u{1d546}'],
-	['\u{1d54a}','\u{1d550}'],
-	['\u{1d552}','\u{1d6a5}'],
-	['\u{1d6a8}','\u{1d6c0}'],
-	['\u{1d6c2}','\u{1d6da}'],
-	['\u{1d6dc}','\u{1d6fa}'],
-	['\u{1d6fc}','\u{1d714}'],
-	['\u{1d716}','\u{1d734}'],
-	['\u{1d736}','\u{1d74e}'],
-	['\u{1d750}','\u{1d76e}'],
-	['\u{1d770}','\u{1d788}'],
-	['\u{1d78a}','\u{1d7a8}'],
-	['\u{1d7aa}','\u{1d7c2}'],
-	['\u{1d7c4}','\u{1d7cb}'],
-	['\u{1ee00}','\u{1ee03}'],
-	['\u{1ee05}','\u{1ee1f}'],
-	['\u{1ee21}','\u{1ee22}'],
-	['\u{1ee24}','\u{1ee24}'],
-	['\u{1ee27}','\u{1ee27}'],
-	['\u{1ee29}','\u{1ee32}'],
-	['\u{1ee34}','\u{1ee37}'],
-	['\u{1ee39}','\u{1ee39}'],
-	['\u{1ee3b}','\u{1ee3b}'],
-	['\u{1ee42}','\u{1ee42}'],
-	['\u{1ee47}','\u{1ee47}'],
-	['\u{1ee49}','\u{1ee49}'],
-	['\u{1ee4b}','\u{1ee4b}'],
-	['\u{1ee4d}','\u{1ee4f}'],
-	['\u{1ee51}','\u{1ee52}'],
-	['\u{1ee54}','\u{1ee54}'],
-	['\u{1ee57}','\u{1ee57}'],
-	['\u{1ee59}','\u{1ee59}'],
-	['\u{1ee5b}','\u{1ee5b}'],
-	['\u{1ee5d}','\u{1ee5d}'],
-	['\u{1ee5f}','\u{1ee5f}'],
-	['\u{1ee61}','\u{1ee62}'],
-	['\u{1ee64}','\u{1ee64}'],
-	['\u{1ee67}','\u{1ee6a}'],
-	['\u{1ee6c}','\u{1ee72}'],
-	['\u{1ee74}','\u{1ee77}'],
-	['\u{1ee79}','\u{1ee7c}'],
-	['\u{1ee7e}','\u{1ee7e}'],
-	['\u{1ee80}','\u{1ee89}'],
-	['\u{1ee8b}','\u{1ee9b}'],
-	['\u{1eea1}','\u{1eea3}'],
-	['\u{1eea5}','\u{1eea9}'],
-	['\u{1eeab}','\u{1eebb}'],
-	['\u{20000}','\u{2a6d6}'],
-	['\u{2a700}','\u{2b734}'],
-	['\u{2b740}','\u{2b81d}'],
-	['\u{2f800}','\u{2fa1d}'],
-]
-
-const tabupper = [
-	['\u{41}','\u{5a}'],
-	['\u{c0}','\u{d6}'],
-	['\u{d8}','\u{de}'],
-	['\u{100}','\u{100}'],
-	['\u{102}','\u{102}'],
-	['\u{104}','\u{104}'],
-	['\u{106}','\u{106}'],
-	['\u{108}','\u{108}'],
-	['\u{10a}','\u{10a}'],
-	['\u{10c}','\u{10c}'],
-	['\u{10e}','\u{10e}'],
-	['\u{110}','\u{110}'],
-	['\u{112}','\u{112}'],
-	['\u{114}','\u{114}'],
-	['\u{116}','\u{116}'],
-	['\u{118}','\u{118}'],
-	['\u{11a}','\u{11a}'],
-	['\u{11c}','\u{11c}'],
-	['\u{11e}','\u{11e}'],
-	['\u{120}','\u{120}'],
-	['\u{122}','\u{122}'],
-	['\u{124}','\u{124}'],
-	['\u{126}','\u{126}'],
-	['\u{128}','\u{128}'],
-	['\u{12a}','\u{12a}'],
-	['\u{12c}','\u{12c}'],
-	['\u{12e}','\u{12e}'],
-	['\u{130}','\u{130}'],
-	['\u{132}','\u{132}'],
-	['\u{134}','\u{134}'],
-	['\u{136}','\u{136}'],
-	['\u{139}','\u{139}'],
-	['\u{13b}','\u{13b}'],
-	['\u{13d}','\u{13d}'],
-	['\u{13f}','\u{13f}'],
-	['\u{141}','\u{141}'],
-	['\u{143}','\u{143}'],
-	['\u{145}','\u{145}'],
-	['\u{147}','\u{147}'],
-	['\u{14a}','\u{14a}'],
-	['\u{14c}','\u{14c}'],
-	['\u{14e}','\u{14e}'],
-	['\u{150}','\u{150}'],
-	['\u{152}','\u{152}'],
-	['\u{154}','\u{154}'],
-	['\u{156}','\u{156}'],
-	['\u{158}','\u{158}'],
-	['\u{15a}','\u{15a}'],
-	['\u{15c}','\u{15c}'],
-	['\u{15e}','\u{15e}'],
-	['\u{160}','\u{160}'],
-	['\u{162}','\u{162}'],
-	['\u{164}','\u{164}'],
-	['\u{166}','\u{166}'],
-	['\u{168}','\u{168}'],
-	['\u{16a}','\u{16a}'],
-	['\u{16c}','\u{16c}'],
-	['\u{16e}','\u{16e}'],
-	['\u{170}','\u{170}'],
-	['\u{172}','\u{172}'],
-	['\u{174}','\u{174}'],
-	['\u{176}','\u{176}'],
-	['\u{178}','\u{179}'],
-	['\u{17b}','\u{17b}'],
-	['\u{17d}','\u{17d}'],
-	['\u{181}','\u{182}'],
-	['\u{184}','\u{184}'],
-	['\u{186}','\u{187}'],
-	['\u{189}','\u{18b}'],
-	['\u{18e}','\u{191}'],
-	['\u{193}','\u{194}'],
-	['\u{196}','\u{198}'],
-	['\u{19c}','\u{19d}'],
-	['\u{19f}','\u{1a0}'],
-	['\u{1a2}','\u{1a2}'],
-	['\u{1a4}','\u{1a4}'],
-	['\u{1a6}','\u{1a7}'],
-	['\u{1a9}','\u{1a9}'],
-	['\u{1ac}','\u{1ac}'],
-	['\u{1ae}','\u{1af}'],
-	['\u{1b1}','\u{1b3}'],
-	['\u{1b5}','\u{1b5}'],
-	['\u{1b7}','\u{1b8}'],
-	['\u{1bc}','\u{1bc}'],
-	['\u{1c4}','\u{1c4}'],
-	['\u{1c7}','\u{1c7}'],
-	['\u{1ca}','\u{1ca}'],
-	['\u{1cd}','\u{1cd}'],
-	['\u{1cf}','\u{1cf}'],
-	['\u{1d1}','\u{1d1}'],
-	['\u{1d3}','\u{1d3}'],
-	['\u{1d5}','\u{1d5}'],
-	['\u{1d7}','\u{1d7}'],
-	['\u{1d9}','\u{1d9}'],
-	['\u{1db}','\u{1db}'],
-	['\u{1de}','\u{1de}'],
-	['\u{1e0}','\u{1e0}'],
-	['\u{1e2}','\u{1e2}'],
-	['\u{1e4}','\u{1e4}'],
-	['\u{1e6}','\u{1e6}'],
-	['\u{1e8}','\u{1e8}'],
-	['\u{1ea}','\u{1ea}'],
-	['\u{1ec}','\u{1ec}'],
-	['\u{1ee}','\u{1ee}'],
-	['\u{1f1}','\u{1f1}'],
-	['\u{1f4}','\u{1f4}'],
-	['\u{1f6}','\u{1f8}'],
-	['\u{1fa}','\u{1fa}'],
-	['\u{1fc}','\u{1fc}'],
-	['\u{1fe}','\u{1fe}'],
-	['\u{200}','\u{200}'],
-	['\u{202}','\u{202}'],
-	['\u{204}','\u{204}'],
-	['\u{206}','\u{206}'],
-	['\u{208}','\u{208}'],
-	['\u{20a}','\u{20a}'],
-	['\u{20c}','\u{20c}'],
-	['\u{20e}','\u{20e}'],
-	['\u{210}','\u{210}'],
-	['\u{212}','\u{212}'],
-	['\u{214}','\u{214}'],
-	['\u{216}','\u{216}'],
-	['\u{218}','\u{218}'],
-	['\u{21a}','\u{21a}'],
-	['\u{21c}','\u{21c}'],
-	['\u{21e}','\u{21e}'],
-	['\u{220}','\u{220}'],
-	['\u{222}','\u{222}'],
-	['\u{224}','\u{224}'],
-	['\u{226}','\u{226}'],
-	['\u{228}','\u{228}'],
-	['\u{22a}','\u{22a}'],
-	['\u{22c}','\u{22c}'],
-	['\u{22e}','\u{22e}'],
-	['\u{230}','\u{230}'],
-	['\u{232}','\u{232}'],
-	['\u{23a}','\u{23b}'],
-	['\u{23d}','\u{23e}'],
-	['\u{241}','\u{241}'],
-	['\u{243}','\u{246}'],
-	['\u{248}','\u{248}'],
-	['\u{24a}','\u{24a}'],
-	['\u{24c}','\u{24c}'],
-	['\u{24e}','\u{24e}'],
-	['\u{370}','\u{370}'],
-	['\u{372}','\u{372}'],
-	['\u{376}','\u{376}'],
-	['\u{386}','\u{386}'],
-	['\u{388}','\u{38a}'],
-	['\u{38c}','\u{38c}'],
-	['\u{38e}','\u{38f}'],
-	['\u{391}','\u{3a1}'],
-	['\u{3a3}','\u{3ab}'],
-	['\u{3cf}','\u{3cf}'],
-	['\u{3d2}','\u{3d4}'],
-	['\u{3d8}','\u{3d8}'],
-	['\u{3da}','\u{3da}'],
-	['\u{3dc}','\u{3dc}'],
-	['\u{3de}','\u{3de}'],
-	['\u{3e0}','\u{3e0}'],
-	['\u{3e2}','\u{3e2}'],
-	['\u{3e4}','\u{3e4}'],
-	['\u{3e6}','\u{3e6}'],
-	['\u{3e8}','\u{3e8}'],
-	['\u{3ea}','\u{3ea}'],
-	['\u{3ec}','\u{3ec}'],
-	['\u{3ee}','\u{3ee}'],
-	['\u{3f4}','\u{3f4}'],
-	['\u{3f7}','\u{3f7}'],
-	['\u{3f9}','\u{3fa}'],
-	['\u{3fd}','\u{42f}'],
-	['\u{460}','\u{460}'],
-	['\u{462}','\u{462}'],
-	['\u{464}','\u{464}'],
-	['\u{466}','\u{466}'],
-	['\u{468}','\u{468}'],
-	['\u{46a}','\u{46a}'],
-	['\u{46c}','\u{46c}'],
-	['\u{46e}','\u{46e}'],
-	['\u{470}','\u{470}'],
-	['\u{472}','\u{472}'],
-	['\u{474}','\u{474}'],
-	['\u{476}','\u{476}'],
-	['\u{478}','\u{478}'],
-	['\u{47a}','\u{47a}'],
-	['\u{47c}','\u{47c}'],
-	['\u{47e}','\u{47e}'],
-	['\u{480}','\u{480}'],
-	['\u{48a}','\u{48a}'],
-	['\u{48c}','\u{48c}'],
-	['\u{48e}','\u{48e}'],
-	['\u{490}','\u{490}'],
-	['\u{492}','\u{492}'],
-	['\u{494}','\u{494}'],
-	['\u{496}','\u{496}'],
-	['\u{498}','\u{498}'],
-	['\u{49a}','\u{49a}'],
-	['\u{49c}','\u{49c}'],
-	['\u{49e}','\u{49e}'],
-	['\u{4a0}','\u{4a0}'],
-	['\u{4a2}','\u{4a2}'],
-	['\u{4a4}','\u{4a4}'],
-	['\u{4a6}','\u{4a6}'],
-	['\u{4a8}','\u{4a8}'],
-	['\u{4aa}','\u{4aa}'],
-	['\u{4ac}','\u{4ac}'],
-	['\u{4ae}','\u{4ae}'],
-	['\u{4b0}','\u{4b0}'],
-	['\u{4b2}','\u{4b2}'],
-	['\u{4b4}','\u{4b4}'],
-	['\u{4b6}','\u{4b6}'],
-	['\u{4b8}','\u{4b8}'],
-	['\u{4ba}','\u{4ba}'],
-	['\u{4bc}','\u{4bc}'],
-	['\u{4be}','\u{4be}'],
-	['\u{4c0}','\u{4c1}'],
-	['\u{4c3}','\u{4c3}'],
-	['\u{4c5}','\u{4c5}'],
-	['\u{4c7}','\u{4c7}'],
-	['\u{4c9}','\u{4c9}'],
-	['\u{4cb}','\u{4cb}'],
-	['\u{4cd}','\u{4cd}'],
-	['\u{4d0}','\u{4d0}'],
-	['\u{4d2}','\u{4d2}'],
-	['\u{4d4}','\u{4d4}'],
-	['\u{4d6}','\u{4d6}'],
-	['\u{4d8}','\u{4d8}'],
-	['\u{4da}','\u{4da}'],
-	['\u{4dc}','\u{4dc}'],
-	['\u{4de}','\u{4de}'],
-	['\u{4e0}','\u{4e0}'],
-	['\u{4e2}','\u{4e2}'],
-	['\u{4e4}','\u{4e4}'],
-	['\u{4e6}','\u{4e6}'],
-	['\u{4e8}','\u{4e8}'],
-	['\u{4ea}','\u{4ea}'],
-	['\u{4ec}','\u{4ec}'],
-	['\u{4ee}','\u{4ee}'],
-	['\u{4f0}','\u{4f0}'],
-	['\u{4f2}','\u{4f2}'],
-	['\u{4f4}','\u{4f4}'],
-	['\u{4f6}','\u{4f6}'],
-	['\u{4f8}','\u{4f8}'],
-	['\u{4fa}','\u{4fa}'],
-	['\u{4fc}','\u{4fc}'],
-	['\u{4fe}','\u{4fe}'],
-	['\u{500}','\u{500}'],
-	['\u{502}','\u{502}'],
-	['\u{504}','\u{504}'],
-	['\u{506}','\u{506}'],
-	['\u{508}','\u{508}'],
-	['\u{50a}','\u{50a}'],
-	['\u{50c}','\u{50c}'],
-	['\u{50e}','\u{50e}'],
-	['\u{510}','\u{510}'],
-	['\u{512}','\u{512}'],
-	['\u{514}','\u{514}'],
-	['\u{516}','\u{516}'],
-	['\u{518}','\u{518}'],
-	['\u{51a}','\u{51a}'],
-	['\u{51c}','\u{51c}'],
-	['\u{51e}','\u{51e}'],
-	['\u{520}','\u{520}'],
-	['\u{522}','\u{522}'],
-	['\u{524}','\u{524}'],
-	['\u{526}','\u{526}'],
-	['\u{531}','\u{556}'],
-	['\u{10a0}','\u{10c5}'],
-	['\u{10c7}','\u{10c7}'],
-	['\u{10cd}','\u{10cd}'],
-	['\u{1e00}','\u{1e00}'],
-	['\u{1e02}','\u{1e02}'],
-	['\u{1e04}','\u{1e04}'],
-	['\u{1e06}','\u{1e06}'],
-	['\u{1e08}','\u{1e08}'],
-	['\u{1e0a}','\u{1e0a}'],
-	['\u{1e0c}','\u{1e0c}'],
-	['\u{1e0e}','\u{1e0e}'],
-	['\u{1e10}','\u{1e10}'],
-	['\u{1e12}','\u{1e12}'],
-	['\u{1e14}','\u{1e14}'],
-	['\u{1e16}','\u{1e16}'],
-	['\u{1e18}','\u{1e18}'],
-	['\u{1e1a}','\u{1e1a}'],
-	['\u{1e1c}','\u{1e1c}'],
-	['\u{1e1e}','\u{1e1e}'],
-	['\u{1e20}','\u{1e20}'],
-	['\u{1e22}','\u{1e22}'],
-	['\u{1e24}','\u{1e24}'],
-	['\u{1e26}','\u{1e26}'],
-	['\u{1e28}','\u{1e28}'],
-	['\u{1e2a}','\u{1e2a}'],
-	['\u{1e2c}','\u{1e2c}'],
-	['\u{1e2e}','\u{1e2e}'],
-	['\u{1e30}','\u{1e30}'],
-	['\u{1e32}','\u{1e32}'],
-	['\u{1e34}','\u{1e34}'],
-	['\u{1e36}','\u{1e36}'],
-	['\u{1e38}','\u{1e38}'],
-	['\u{1e3a}','\u{1e3a}'],
-	['\u{1e3c}','\u{1e3c}'],
-	['\u{1e3e}','\u{1e3e}'],
-	['\u{1e40}','\u{1e40}'],
-	['\u{1e42}','\u{1e42}'],
-	['\u{1e44}','\u{1e44}'],
-	['\u{1e46}','\u{1e46}'],
-	['\u{1e48}','\u{1e48}'],
-	['\u{1e4a}','\u{1e4a}'],
-	['\u{1e4c}','\u{1e4c}'],
-	['\u{1e4e}','\u{1e4e}'],
-	['\u{1e50}','\u{1e50}'],
-	['\u{1e52}','\u{1e52}'],
-	['\u{1e54}','\u{1e54}'],
-	['\u{1e56}','\u{1e56}'],
-	['\u{1e58}','\u{1e58}'],
-	['\u{1e5a}','\u{1e5a}'],
-	['\u{1e5c}','\u{1e5c}'],
-	['\u{1e5e}','\u{1e5e}'],
-	['\u{1e60}','\u{1e60}'],
-	['\u{1e62}','\u{1e62}'],
-	['\u{1e64}','\u{1e64}'],
-	['\u{1e66}','\u{1e66}'],
-	['\u{1e68}','\u{1e68}'],
-	['\u{1e6a}','\u{1e6a}'],
-	['\u{1e6c}','\u{1e6c}'],
-	['\u{1e6e}','\u{1e6e}'],
-	['\u{1e70}','\u{1e70}'],
-	['\u{1e72}','\u{1e72}'],
-	['\u{1e74}','\u{1e74}'],
-	['\u{1e76}','\u{1e76}'],
-	['\u{1e78}','\u{1e78}'],
-	['\u{1e7a}','\u{1e7a}'],
-	['\u{1e7c}','\u{1e7c}'],
-	['\u{1e7e}','\u{1e7e}'],
-	['\u{1e80}','\u{1e80}'],
-	['\u{1e82}','\u{1e82}'],
-	['\u{1e84}','\u{1e84}'],
-	['\u{1e86}','\u{1e86}'],
-	['\u{1e88}','\u{1e88}'],
-	['\u{1e8a}','\u{1e8a}'],
-	['\u{1e8c}','\u{1e8c}'],
-	['\u{1e8e}','\u{1e8e}'],
-	['\u{1e90}','\u{1e90}'],
-	['\u{1e92}','\u{1e92}'],
-	['\u{1e94}','\u{1e94}'],
-	['\u{1e9e}','\u{1e9e}'],
-	['\u{1ea0}','\u{1ea0}'],
-	['\u{1ea2}','\u{1ea2}'],
-	['\u{1ea4}','\u{1ea4}'],
-	['\u{1ea6}','\u{1ea6}'],
-	['\u{1ea8}','\u{1ea8}'],
-	['\u{1eaa}','\u{1eaa}'],
-	['\u{1eac}','\u{1eac}'],
-	['\u{1eae}','\u{1eae}'],
-	['\u{1eb0}','\u{1eb0}'],
-	['\u{1eb2}','\u{1eb2}'],
-	['\u{1eb4}','\u{1eb4}'],
-	['\u{1eb6}','\u{1eb6}'],
-	['\u{1eb8}','\u{1eb8}'],
-	['\u{1eba}','\u{1eba}'],
-	['\u{1ebc}','\u{1ebc}'],
-	['\u{1ebe}','\u{1ebe}'],
-	['\u{1ec0}','\u{1ec0}'],
-	['\u{1ec2}','\u{1ec2}'],
-	['\u{1ec4}','\u{1ec4}'],
-	['\u{1ec6}','\u{1ec6}'],
-	['\u{1ec8}','\u{1ec8}'],
-	['\u{1eca}','\u{1eca}'],
-	['\u{1ecc}','\u{1ecc}'],
-	['\u{1ece}','\u{1ece}'],
-	['\u{1ed0}','\u{1ed0}'],
-	['\u{1ed2}','\u{1ed2}'],
-	['\u{1ed4}','\u{1ed4}'],
-	['\u{1ed6}','\u{1ed6}'],
-	['\u{1ed8}','\u{1ed8}'],
-	['\u{1eda}','\u{1eda}'],
-	['\u{1edc}','\u{1edc}'],
-	['\u{1ede}','\u{1ede}'],
-	['\u{1ee0}','\u{1ee0}'],
-	['\u{1ee2}','\u{1ee2}'],
-	['\u{1ee4}','\u{1ee4}'],
-	['\u{1ee6}','\u{1ee6}'],
-	['\u{1ee8}','\u{1ee8}'],
-	['\u{1eea}','\u{1eea}'],
-	['\u{1eec}','\u{1eec}'],
-	['\u{1eee}','\u{1eee}'],
-	['\u{1ef0}','\u{1ef0}'],
-	['\u{1ef2}','\u{1ef2}'],
-	['\u{1ef4}','\u{1ef4}'],
-	['\u{1ef6}','\u{1ef6}'],
-	['\u{1ef8}','\u{1ef8}'],
-	['\u{1efa}','\u{1efa}'],
-	['\u{1efc}','\u{1efc}'],
-	['\u{1efe}','\u{1efe}'],
-	['\u{1f08}','\u{1f0f}'],
-	['\u{1f18}','\u{1f1d}'],
-	['\u{1f28}','\u{1f2f}'],
-	['\u{1f38}','\u{1f3f}'],
-	['\u{1f48}','\u{1f4d}'],
-	['\u{1f59}','\u{1f59}'],
-	['\u{1f5b}','\u{1f5b}'],
-	['\u{1f5d}','\u{1f5d}'],
-	['\u{1f5f}','\u{1f5f}'],
-	['\u{1f68}','\u{1f6f}'],
-	['\u{1fb8}','\u{1fbb}'],
-	['\u{1fc8}','\u{1fcb}'],
-	['\u{1fd8}','\u{1fdb}'],
-	['\u{1fe8}','\u{1fec}'],
-	['\u{1ff8}','\u{1ffb}'],
-	['\u{2102}','\u{2102}'],
-	['\u{2107}','\u{2107}'],
-	['\u{210b}','\u{210d}'],
-	['\u{2110}','\u{2112}'],
-	['\u{2115}','\u{2115}'],
-	['\u{2119}','\u{211d}'],
-	['\u{2124}','\u{2124}'],
-	['\u{2126}','\u{2126}'],
-	['\u{2128}','\u{2128}'],
-	['\u{212a}','\u{212d}'],
-	['\u{2130}','\u{2133}'],
-	['\u{213e}','\u{213f}'],
-	['\u{2145}','\u{2145}'],
-	['\u{2183}','\u{2183}'],
-	['\u{2c00}','\u{2c2e}'],
-	['\u{2c60}','\u{2c60}'],
-	['\u{2c62}','\u{2c64}'],
-	['\u{2c67}','\u{2c67}'],
-	['\u{2c69}','\u{2c69}'],
-	['\u{2c6b}','\u{2c6b}'],
-	['\u{2c6d}','\u{2c70}'],
-	['\u{2c72}','\u{2c72}'],
-	['\u{2c75}','\u{2c75}'],
-	['\u{2c7e}','\u{2c80}'],
-	['\u{2c82}','\u{2c82}'],
-	['\u{2c84}','\u{2c84}'],
-	['\u{2c86}','\u{2c86}'],
-	['\u{2c88}','\u{2c88}'],
-	['\u{2c8a}','\u{2c8a}'],
-	['\u{2c8c}','\u{2c8c}'],
-	['\u{2c8e}','\u{2c8e}'],
-	['\u{2c90}','\u{2c90}'],
-	['\u{2c92}','\u{2c92}'],
-	['\u{2c94}','\u{2c94}'],
-	['\u{2c96}','\u{2c96}'],
-	['\u{2c98}','\u{2c98}'],
-	['\u{2c9a}','\u{2c9a}'],
-	['\u{2c9c}','\u{2c9c}'],
-	['\u{2c9e}','\u{2c9e}'],
-	['\u{2ca0}','\u{2ca0}'],
-	['\u{2ca2}','\u{2ca2}'],
-	['\u{2ca4}','\u{2ca4}'],
-	['\u{2ca6}','\u{2ca6}'],
-	['\u{2ca8}','\u{2ca8}'],
-	['\u{2caa}','\u{2caa}'],
-	['\u{2cac}','\u{2cac}'],
-	['\u{2cae}','\u{2cae}'],
-	['\u{2cb0}','\u{2cb0}'],
-	['\u{2cb2}','\u{2cb2}'],
-	['\u{2cb4}','\u{2cb4}'],
-	['\u{2cb6}','\u{2cb6}'],
-	['\u{2cb8}','\u{2cb8}'],
-	['\u{2cba}','\u{2cba}'],
-	['\u{2cbc}','\u{2cbc}'],
-	['\u{2cbe}','\u{2cbe}'],
-	['\u{2cc0}','\u{2cc0}'],
-	['\u{2cc2}','\u{2cc2}'],
-	['\u{2cc4}','\u{2cc4}'],
-	['\u{2cc6}','\u{2cc6}'],
-	['\u{2cc8}','\u{2cc8}'],
-	['\u{2cca}','\u{2cca}'],
-	['\u{2ccc}','\u{2ccc}'],
-	['\u{2cce}','\u{2cce}'],
-	['\u{2cd0}','\u{2cd0}'],
-	['\u{2cd2}','\u{2cd2}'],
-	['\u{2cd4}','\u{2cd4}'],
-	['\u{2cd6}','\u{2cd6}'],
-	['\u{2cd8}','\u{2cd8}'],
-	['\u{2cda}','\u{2cda}'],
-	['\u{2cdc}','\u{2cdc}'],
-	['\u{2cde}','\u{2cde}'],
-	['\u{2ce0}','\u{2ce0}'],
-	['\u{2ce2}','\u{2ce2}'],
-	['\u{2ceb}','\u{2ceb}'],
-	['\u{2ced}','\u{2ced}'],
-	['\u{2cf2}','\u{2cf2}'],
-	['\u{a640}','\u{a640}'],
-	['\u{a642}','\u{a642}'],
-	['\u{a644}','\u{a644}'],
-	['\u{a646}','\u{a646}'],
-	['\u{a648}','\u{a648}'],
-	['\u{a64a}','\u{a64a}'],
-	['\u{a64c}','\u{a64c}'],
-	['\u{a64e}','\u{a64e}'],
-	['\u{a650}','\u{a650}'],
-	['\u{a652}','\u{a652}'],
-	['\u{a654}','\u{a654}'],
-	['\u{a656}','\u{a656}'],
-	['\u{a658}','\u{a658}'],
-	['\u{a65a}','\u{a65a}'],
-	['\u{a65c}','\u{a65c}'],
-	['\u{a65e}','\u{a65e}'],
-	['\u{a660}','\u{a660}'],
-	['\u{a662}','\u{a662}'],
-	['\u{a664}','\u{a664}'],
-	['\u{a666}','\u{a666}'],
-	['\u{a668}','\u{a668}'],
-	['\u{a66a}','\u{a66a}'],
-	['\u{a66c}','\u{a66c}'],
-	['\u{a680}','\u{a680}'],
-	['\u{a682}','\u{a682}'],
-	['\u{a684}','\u{a684}'],
-	['\u{a686}','\u{a686}'],
-	['\u{a688}','\u{a688}'],
-	['\u{a68a}','\u{a68a}'],
-	['\u{a68c}','\u{a68c}'],
-	['\u{a68e}','\u{a68e}'],
-	['\u{a690}','\u{a690}'],
-	['\u{a692}','\u{a692}'],
-	['\u{a694}','\u{a694}'],
-	['\u{a696}','\u{a696}'],
-	['\u{a722}','\u{a722}'],
-	['\u{a724}','\u{a724}'],
-	['\u{a726}','\u{a726}'],
-	['\u{a728}','\u{a728}'],
-	['\u{a72a}','\u{a72a}'],
-	['\u{a72c}','\u{a72c}'],
-	['\u{a72e}','\u{a72e}'],
-	['\u{a732}','\u{a732}'],
-	['\u{a734}','\u{a734}'],
-	['\u{a736}','\u{a736}'],
-	['\u{a738}','\u{a738}'],
-	['\u{a73a}','\u{a73a}'],
-	['\u{a73c}','\u{a73c}'],
-	['\u{a73e}','\u{a73e}'],
-	['\u{a740}','\u{a740}'],
-	['\u{a742}','\u{a742}'],
-	['\u{a744}','\u{a744}'],
-	['\u{a746}','\u{a746}'],
-	['\u{a748}','\u{a748}'],
-	['\u{a74a}','\u{a74a}'],
-	['\u{a74c}','\u{a74c}'],
-	['\u{a74e}','\u{a74e}'],
-	['\u{a750}','\u{a750}'],
-	['\u{a752}','\u{a752}'],
-	['\u{a754}','\u{a754}'],
-	['\u{a756}','\u{a756}'],
-	['\u{a758}','\u{a758}'],
-	['\u{a75a}','\u{a75a}'],
-	['\u{a75c}','\u{a75c}'],
-	['\u{a75e}','\u{a75e}'],
-	['\u{a760}','\u{a760}'],
-	['\u{a762}','\u{a762}'],
-	['\u{a764}','\u{a764}'],
-	['\u{a766}','\u{a766}'],
-	['\u{a768}','\u{a768}'],
-	['\u{a76a}','\u{a76a}'],
-	['\u{a76c}','\u{a76c}'],
-	['\u{a76e}','\u{a76e}'],
-	['\u{a779}','\u{a779}'],
-	['\u{a77b}','\u{a77b}'],
-	['\u{a77d}','\u{a77e}'],
-	['\u{a780}','\u{a780}'],
-	['\u{a782}','\u{a782}'],
-	['\u{a784}','\u{a784}'],
-	['\u{a786}','\u{a786}'],
-	['\u{a78b}','\u{a78b}'],
-	['\u{a78d}','\u{a78d}'],
-	['\u{a790}','\u{a790}'],
-	['\u{a792}','\u{a792}'],
-	['\u{a7a0}','\u{a7a0}'],
-	['\u{a7a2}','\u{a7a2}'],
-	['\u{a7a4}','\u{a7a4}'],
-	['\u{a7a6}','\u{a7a6}'],
-	['\u{a7a8}','\u{a7a8}'],
-	['\u{a7aa}','\u{a7aa}'],
-	['\u{ff21}','\u{ff3a}'],
-	['\u{10400}','\u{10427}'],
-	['\u{1d400}','\u{1d419}'],
-	['\u{1d434}','\u{1d44d}'],
-	['\u{1d468}','\u{1d481}'],
-	['\u{1d49c}','\u{1d49c}'],
-	['\u{1d49e}','\u{1d49f}'],
-	['\u{1d4a2}','\u{1d4a2}'],
-	['\u{1d4a5}','\u{1d4a6}'],
-	['\u{1d4a9}','\u{1d4ac}'],
-	['\u{1d4ae}','\u{1d4b5}'],
-	['\u{1d4d0}','\u{1d4e9}'],
-	['\u{1d504}','\u{1d505}'],
-	['\u{1d507}','\u{1d50a}'],
-	['\u{1d50d}','\u{1d514}'],
-	['\u{1d516}','\u{1d51c}'],
-	['\u{1d538}','\u{1d539}'],
-	['\u{1d53b}','\u{1d53e}'],
-	['\u{1d540}','\u{1d544}'],
-	['\u{1d546}','\u{1d546}'],
-	['\u{1d54a}','\u{1d550}'],
-	['\u{1d56c}','\u{1d585}'],
-	['\u{1d5a0}','\u{1d5b9}'],
-	['\u{1d5d4}','\u{1d5ed}'],
-	['\u{1d608}','\u{1d621}'],
-	['\u{1d63c}','\u{1d655}'],
-	['\u{1d670}','\u{1d689}'],
-	['\u{1d6a8}','\u{1d6c0}'],
-	['\u{1d6e2}','\u{1d6fa}'],
-	['\u{1d71c}','\u{1d734}'],
-	['\u{1d756}','\u{1d76e}'],
-	['\u{1d790}','\u{1d7a8}'],
-	['\u{1d7ca}','\u{1d7ca}'],
-]
-
-const tablower = [
-	['\u{61}','\u{7a}'],
-	['\u{b5}','\u{b5}'],
-	['\u{df}','\u{f6}'],
-	['\u{f8}','\u{ff}'],
-	['\u{101}','\u{101}'],
-	['\u{103}','\u{103}'],
-	['\u{105}','\u{105}'],
-	['\u{107}','\u{107}'],
-	['\u{109}','\u{109}'],
-	['\u{10b}','\u{10b}'],
-	['\u{10d}','\u{10d}'],
-	['\u{10f}','\u{10f}'],
-	['\u{111}','\u{111}'],
-	['\u{113}','\u{113}'],
-	['\u{115}','\u{115}'],
-	['\u{117}','\u{117}'],
-	['\u{119}','\u{119}'],
-	['\u{11b}','\u{11b}'],
-	['\u{11d}','\u{11d}'],
-	['\u{11f}','\u{11f}'],
-	['\u{121}','\u{121}'],
-	['\u{123}','\u{123}'],
-	['\u{125}','\u{125}'],
-	['\u{127}','\u{127}'],
-	['\u{129}','\u{129}'],
-	['\u{12b}','\u{12b}'],
-	['\u{12d}','\u{12d}'],
-	['\u{12f}','\u{12f}'],
-	['\u{131}','\u{131}'],
-	['\u{133}','\u{133}'],
-	['\u{135}','\u{135}'],
-	['\u{137}','\u{138}'],
-	['\u{13a}','\u{13a}'],
-	['\u{13c}','\u{13c}'],
-	['\u{13e}','\u{13e}'],
-	['\u{140}','\u{140}'],
-	['\u{142}','\u{142}'],
-	['\u{144}','\u{144}'],
-	['\u{146}','\u{146}'],
-	['\u{148}','\u{149}'],
-	['\u{14b}','\u{14b}'],
-	['\u{14d}','\u{14d}'],
-	['\u{14f}','\u{14f}'],
-	['\u{151}','\u{151}'],
-	['\u{153}','\u{153}'],
-	['\u{155}','\u{155}'],
-	['\u{157}','\u{157}'],
-	['\u{159}','\u{159}'],
-	['\u{15b}','\u{15b}'],
-	['\u{15d}','\u{15d}'],
-	['\u{15f}','\u{15f}'],
-	['\u{161}','\u{161}'],
-	['\u{163}','\u{163}'],
-	['\u{165}','\u{165}'],
-	['\u{167}','\u{167}'],
-	['\u{169}','\u{169}'],
-	['\u{16b}','\u{16b}'],
-	['\u{16d}','\u{16d}'],
-	['\u{16f}','\u{16f}'],
-	['\u{171}','\u{171}'],
-	['\u{173}','\u{173}'],
-	['\u{175}','\u{175}'],
-	['\u{177}','\u{177}'],
-	['\u{17a}','\u{17a}'],
-	['\u{17c}','\u{17c}'],
-	['\u{17e}','\u{180}'],
-	['\u{183}','\u{183}'],
-	['\u{185}','\u{185}'],
-	['\u{188}','\u{188}'],
-	['\u{18c}','\u{18d}'],
-	['\u{192}','\u{192}'],
-	['\u{195}','\u{195}'],
-	['\u{199}','\u{19b}'],
-	['\u{19e}','\u{19e}'],
-	['\u{1a1}','\u{1a1}'],
-	['\u{1a3}','\u{1a3}'],
-	['\u{1a5}','\u{1a5}'],
-	['\u{1a8}','\u{1a8}'],
-	['\u{1aa}','\u{1ab}'],
-	['\u{1ad}','\u{1ad}'],
-	['\u{1b0}','\u{1b0}'],
-	['\u{1b4}','\u{1b4}'],
-	['\u{1b6}','\u{1b6}'],
-	['\u{1b9}','\u{1ba}'],
-	['\u{1bd}','\u{1bf}'],
-	['\u{1c6}','\u{1c6}'],
-	['\u{1c9}','\u{1c9}'],
-	['\u{1cc}','\u{1cc}'],
-	['\u{1ce}','\u{1ce}'],
-	['\u{1d0}','\u{1d0}'],
-	['\u{1d2}','\u{1d2}'],
-	['\u{1d4}','\u{1d4}'],
-	['\u{1d6}','\u{1d6}'],
-	['\u{1d8}','\u{1d8}'],
-	['\u{1da}','\u{1da}'],
-	['\u{1dc}','\u{1dd}'],
-	['\u{1df}','\u{1df}'],
-	['\u{1e1}','\u{1e1}'],
-	['\u{1e3}','\u{1e3}'],
-	['\u{1e5}','\u{1e5}'],
-	['\u{1e7}','\u{1e7}'],
-	['\u{1e9}','\u{1e9}'],
-	['\u{1eb}','\u{1eb}'],
-	['\u{1ed}','\u{1ed}'],
-	['\u{1ef}','\u{1f0}'],
-	['\u{1f3}','\u{1f3}'],
-	['\u{1f5}','\u{1f5}'],
-	['\u{1f9}','\u{1f9}'],
-	['\u{1fb}','\u{1fb}'],
-	['\u{1fd}','\u{1fd}'],
-	['\u{1ff}','\u{1ff}'],
-	['\u{201}','\u{201}'],
-	['\u{203}','\u{203}'],
-	['\u{205}','\u{205}'],
-	['\u{207}','\u{207}'],
-	['\u{209}','\u{209}'],
-	['\u{20b}','\u{20b}'],
-	['\u{20d}','\u{20d}'],
-	['\u{20f}','\u{20f}'],
-	['\u{211}','\u{211}'],
-	['\u{213}','\u{213}'],
-	['\u{215}','\u{215}'],
-	['\u{217}','\u{217}'],
-	['\u{219}','\u{219}'],
-	['\u{21b}','\u{21b}'],
-	['\u{21d}','\u{21d}'],
-	['\u{21f}','\u{21f}'],
-	['\u{221}','\u{221}'],
-	['\u{223}','\u{223}'],
-	['\u{225}','\u{225}'],
-	['\u{227}','\u{227}'],
-	['\u{229}','\u{229}'],
-	['\u{22b}','\u{22b}'],
-	['\u{22d}','\u{22d}'],
-	['\u{22f}','\u{22f}'],
-	['\u{231}','\u{231}'],
-	['\u{233}','\u{239}'],
-	['\u{23c}','\u{23c}'],
-	['\u{23f}','\u{240}'],
-	['\u{242}','\u{242}'],
-	['\u{247}','\u{247}'],
-	['\u{249}','\u{249}'],
-	['\u{24b}','\u{24b}'],
-	['\u{24d}','\u{24d}'],
-	['\u{24f}','\u{293}'],
-	['\u{295}','\u{2af}'],
-	['\u{371}','\u{371}'],
-	['\u{373}','\u{373}'],
-	['\u{377}','\u{377}'],
-	['\u{37b}','\u{37d}'],
-	['\u{390}','\u{390}'],
-	['\u{3ac}','\u{3ce}'],
-	['\u{3d0}','\u{3d1}'],
-	['\u{3d5}','\u{3d7}'],
-	['\u{3d9}','\u{3d9}'],
-	['\u{3db}','\u{3db}'],
-	['\u{3dd}','\u{3dd}'],
-	['\u{3df}','\u{3df}'],
-	['\u{3e1}','\u{3e1}'],
-	['\u{3e3}','\u{3e3}'],
-	['\u{3e5}','\u{3e5}'],
-	['\u{3e7}','\u{3e7}'],
-	['\u{3e9}','\u{3e9}'],
-	['\u{3eb}','\u{3eb}'],
-	['\u{3ed}','\u{3ed}'],
-	['\u{3ef}','\u{3f3}'],
-	['\u{3f5}','\u{3f5}'],
-	['\u{3f8}','\u{3f8}'],
-	['\u{3fb}','\u{3fc}'],
-	['\u{430}','\u{45f}'],
-	['\u{461}','\u{461}'],
-	['\u{463}','\u{463}'],
-	['\u{465}','\u{465}'],
-	['\u{467}','\u{467}'],
-	['\u{469}','\u{469}'],
-	['\u{46b}','\u{46b}'],
-	['\u{46d}','\u{46d}'],
-	['\u{46f}','\u{46f}'],
-	['\u{471}','\u{471}'],
-	['\u{473}','\u{473}'],
-	['\u{475}','\u{475}'],
-	['\u{477}','\u{477}'],
-	['\u{479}','\u{479}'],
-	['\u{47b}','\u{47b}'],
-	['\u{47d}','\u{47d}'],
-	['\u{47f}','\u{47f}'],
-	['\u{481}','\u{481}'],
-	['\u{48b}','\u{48b}'],
-	['\u{48d}','\u{48d}'],
-	['\u{48f}','\u{48f}'],
-	['\u{491}','\u{491}'],
-	['\u{493}','\u{493}'],
-	['\u{495}','\u{495}'],
-	['\u{497}','\u{497}'],
-	['\u{499}','\u{499}'],
-	['\u{49b}','\u{49b}'],
-	['\u{49d}','\u{49d}'],
-	['\u{49f}','\u{49f}'],
-	['\u{4a1}','\u{4a1}'],
-	['\u{4a3}','\u{4a3}'],
-	['\u{4a5}','\u{4a5}'],
-	['\u{4a7}','\u{4a7}'],
-	['\u{4a9}','\u{4a9}'],
-	['\u{4ab}','\u{4ab}'],
-	['\u{4ad}','\u{4ad}'],
-	['\u{4af}','\u{4af}'],
-	['\u{4b1}','\u{4b1}'],
-	['\u{4b3}','\u{4b3}'],
-	['\u{4b5}','\u{4b5}'],
-	['\u{4b7}','\u{4b7}'],
-	['\u{4b9}','\u{4b9}'],
-	['\u{4bb}','\u{4bb}'],
-	['\u{4bd}','\u{4bd}'],
-	['\u{4bf}','\u{4bf}'],
-	['\u{4c2}','\u{4c2}'],
-	['\u{4c4}','\u{4c4}'],
-	['\u{4c6}','\u{4c6}'],
-	['\u{4c8}','\u{4c8}'],
-	['\u{4ca}','\u{4ca}'],
-	['\u{4cc}','\u{4cc}'],
-	['\u{4ce}','\u{4cf}'],
-	['\u{4d1}','\u{4d1}'],
-	['\u{4d3}','\u{4d3}'],
-	['\u{4d5}','\u{4d5}'],
-	['\u{4d7}','\u{4d7}'],
-	['\u{4d9}','\u{4d9}'],
-	['\u{4db}','\u{4db}'],
-	['\u{4dd}','\u{4dd}'],
-	['\u{4df}','\u{4df}'],
-	['\u{4e1}','\u{4e1}'],
-	['\u{4e3}','\u{4e3}'],
-	['\u{4e5}','\u{4e5}'],
-	['\u{4e7}','\u{4e7}'],
-	['\u{4e9}','\u{4e9}'],
-	['\u{4eb}','\u{4eb}'],
-	['\u{4ed}','\u{4ed}'],
-	['\u{4ef}','\u{4ef}'],
-	['\u{4f1}','\u{4f1}'],
-	['\u{4f3}','\u{4f3}'],
-	['\u{4f5}','\u{4f5}'],
-	['\u{4f7}','\u{4f7}'],
-	['\u{4f9}','\u{4f9}'],
-	['\u{4fb}','\u{4fb}'],
-	['\u{4fd}','\u{4fd}'],
-	['\u{4ff}','\u{4ff}'],
-	['\u{501}','\u{501}'],
-	['\u{503}','\u{503}'],
-	['\u{505}','\u{505}'],
-	['\u{507}','\u{507}'],
-	['\u{509}','\u{509}'],
-	['\u{50b}','\u{50b}'],
-	['\u{50d}','\u{50d}'],
-	['\u{50f}','\u{50f}'],
-	['\u{511}','\u{511}'],
-	['\u{513}','\u{513}'],
-	['\u{515}','\u{515}'],
-	['\u{517}','\u{517}'],
-	['\u{519}','\u{519}'],
-	['\u{51b}','\u{51b}'],
-	['\u{51d}','\u{51d}'],
-	['\u{51f}','\u{51f}'],
-	['\u{521}','\u{521}'],
-	['\u{523}','\u{523}'],
-	['\u{525}','\u{525}'],
-	['\u{527}','\u{527}'],
-	['\u{561}','\u{587}'],
-	['\u{1d00}','\u{1d2b}'],
-	['\u{1d6b}','\u{1d77}'],
-	['\u{1d79}','\u{1d9a}'],
-	['\u{1e01}','\u{1e01}'],
-	['\u{1e03}','\u{1e03}'],
-	['\u{1e05}','\u{1e05}'],
-	['\u{1e07}','\u{1e07}'],
-	['\u{1e09}','\u{1e09}'],
-	['\u{1e0b}','\u{1e0b}'],
-	['\u{1e0d}','\u{1e0d}'],
-	['\u{1e0f}','\u{1e0f}'],
-	['\u{1e11}','\u{1e11}'],
-	['\u{1e13}','\u{1e13}'],
-	['\u{1e15}','\u{1e15}'],
-	['\u{1e17}','\u{1e17}'],
-	['\u{1e19}','\u{1e19}'],
-	['\u{1e1b}','\u{1e1b}'],
-	['\u{1e1d}','\u{1e1d}'],
-	['\u{1e1f}','\u{1e1f}'],
-	['\u{1e21}','\u{1e21}'],
-	['\u{1e23}','\u{1e23}'],
-	['\u{1e25}','\u{1e25}'],
-	['\u{1e27}','\u{1e27}'],
-	['\u{1e29}','\u{1e29}'],
-	['\u{1e2b}','\u{1e2b}'],
-	['\u{1e2d}','\u{1e2d}'],
-	['\u{1e2f}','\u{1e2f}'],
-	['\u{1e31}','\u{1e31}'],
-	['\u{1e33}','\u{1e33}'],
-	['\u{1e35}','\u{1e35}'],
-	['\u{1e37}','\u{1e37}'],
-	['\u{1e39}','\u{1e39}'],
-	['\u{1e3b}','\u{1e3b}'],
-	['\u{1e3d}','\u{1e3d}'],
-	['\u{1e3f}','\u{1e3f}'],
-	['\u{1e41}','\u{1e41}'],
-	['\u{1e43}','\u{1e43}'],
-	['\u{1e45}','\u{1e45}'],
-	['\u{1e47}','\u{1e47}'],
-	['\u{1e49}','\u{1e49}'],
-	['\u{1e4b}','\u{1e4b}'],
-	['\u{1e4d}','\u{1e4d}'],
-	['\u{1e4f}','\u{1e4f}'],
-	['\u{1e51}','\u{1e51}'],
-	['\u{1e53}','\u{1e53}'],
-	['\u{1e55}','\u{1e55}'],
-	['\u{1e57}','\u{1e57}'],
-	['\u{1e59}','\u{1e59}'],
-	['\u{1e5b}','\u{1e5b}'],
-	['\u{1e5d}','\u{1e5d}'],
-	['\u{1e5f}','\u{1e5f}'],
-	['\u{1e61}','\u{1e61}'],
-	['\u{1e63}','\u{1e63}'],
-	['\u{1e65}','\u{1e65}'],
-	['\u{1e67}','\u{1e67}'],
-	['\u{1e69}','\u{1e69}'],
-	['\u{1e6b}','\u{1e6b}'],
-	['\u{1e6d}','\u{1e6d}'],
-	['\u{1e6f}','\u{1e6f}'],
-	['\u{1e71}','\u{1e71}'],
-	['\u{1e73}','\u{1e73}'],
-	['\u{1e75}','\u{1e75}'],
-	['\u{1e77}','\u{1e77}'],
-	['\u{1e79}','\u{1e79}'],
-	['\u{1e7b}','\u{1e7b}'],
-	['\u{1e7d}','\u{1e7d}'],
-	['\u{1e7f}','\u{1e7f}'],
-	['\u{1e81}','\u{1e81}'],
-	['\u{1e83}','\u{1e83}'],
-	['\u{1e85}','\u{1e85}'],
-	['\u{1e87}','\u{1e87}'],
-	['\u{1e89}','\u{1e89}'],
-	['\u{1e8b}','\u{1e8b}'],
-	['\u{1e8d}','\u{1e8d}'],
-	['\u{1e8f}','\u{1e8f}'],
-	['\u{1e91}','\u{1e91}'],
-	['\u{1e93}','\u{1e93}'],
-	['\u{1e95}','\u{1e9d}'],
-	['\u{1e9f}','\u{1e9f}'],
-	['\u{1ea1}','\u{1ea1}'],
-	['\u{1ea3}','\u{1ea3}'],
-	['\u{1ea5}','\u{1ea5}'],
-	['\u{1ea7}','\u{1ea7}'],
-	['\u{1ea9}','\u{1ea9}'],
-	['\u{1eab}','\u{1eab}'],
-	['\u{1ead}','\u{1ead}'],
-	['\u{1eaf}','\u{1eaf}'],
-	['\u{1eb1}','\u{1eb1}'],
-	['\u{1eb3}','\u{1eb3}'],
-	['\u{1eb5}','\u{1eb5}'],
-	['\u{1eb7}','\u{1eb7}'],
-	['\u{1eb9}','\u{1eb9}'],
-	['\u{1ebb}','\u{1ebb}'],
-	['\u{1ebd}','\u{1ebd}'],
-	['\u{1ebf}','\u{1ebf}'],
-	['\u{1ec1}','\u{1ec1}'],
-	['\u{1ec3}','\u{1ec3}'],
-	['\u{1ec5}','\u{1ec5}'],
-	['\u{1ec7}','\u{1ec7}'],
-	['\u{1ec9}','\u{1ec9}'],
-	['\u{1ecb}','\u{1ecb}'],
-	['\u{1ecd}','\u{1ecd}'],
-	['\u{1ecf}','\u{1ecf}'],
-	['\u{1ed1}','\u{1ed1}'],
-	['\u{1ed3}','\u{1ed3}'],
-	['\u{1ed5}','\u{1ed5}'],
-	['\u{1ed7}','\u{1ed7}'],
-	['\u{1ed9}','\u{1ed9}'],
-	['\u{1edb}','\u{1edb}'],
-	['\u{1edd}','\u{1edd}'],
-	['\u{1edf}','\u{1edf}'],
-	['\u{1ee1}','\u{1ee1}'],
-	['\u{1ee3}','\u{1ee3}'],
-	['\u{1ee5}','\u{1ee5}'],
-	['\u{1ee7}','\u{1ee7}'],
-	['\u{1ee9}','\u{1ee9}'],
-	['\u{1eeb}','\u{1eeb}'],
-	['\u{1eed}','\u{1eed}'],
-	['\u{1eef}','\u{1eef}'],
-	['\u{1ef1}','\u{1ef1}'],
-	['\u{1ef3}','\u{1ef3}'],
-	['\u{1ef5}','\u{1ef5}'],
-	['\u{1ef7}','\u{1ef7}'],
-	['\u{1ef9}','\u{1ef9}'],
-	['\u{1efb}','\u{1efb}'],
-	['\u{1efd}','\u{1efd}'],
-	['\u{1eff}','\u{1f07}'],
-	['\u{1f10}','\u{1f15}'],
-	['\u{1f20}','\u{1f27}'],
-	['\u{1f30}','\u{1f37}'],
-	['\u{1f40}','\u{1f45}'],
-	['\u{1f50}','\u{1f57}'],
-	['\u{1f60}','\u{1f67}'],
-	['\u{1f70}','\u{1f7d}'],
-	['\u{1f80}','\u{1f87}'],
-	['\u{1f90}','\u{1f97}'],
-	['\u{1fa0}','\u{1fa7}'],
-	['\u{1fb0}','\u{1fb4}'],
-	['\u{1fb6}','\u{1fb7}'],
-	['\u{1fbe}','\u{1fbe}'],
-	['\u{1fc2}','\u{1fc4}'],
-	['\u{1fc6}','\u{1fc7}'],
-	['\u{1fd0}','\u{1fd3}'],
-	['\u{1fd6}','\u{1fd7}'],
-	['\u{1fe0}','\u{1fe7}'],
-	['\u{1ff2}','\u{1ff4}'],
-	['\u{1ff6}','\u{1ff7}'],
-	['\u{210a}','\u{210a}'],
-	['\u{210e}','\u{210f}'],
-	['\u{2113}','\u{2113}'],
-	['\u{212f}','\u{212f}'],
-	['\u{2134}','\u{2134}'],
-	['\u{2139}','\u{2139}'],
-	['\u{213c}','\u{213d}'],
-	['\u{2146}','\u{2149}'],
-	['\u{214e}','\u{214e}'],
-	['\u{2184}','\u{2184}'],
-	['\u{2c30}','\u{2c5e}'],
-	['\u{2c61}','\u{2c61}'],
-	['\u{2c65}','\u{2c66}'],
-	['\u{2c68}','\u{2c68}'],
-	['\u{2c6a}','\u{2c6a}'],
-	['\u{2c6c}','\u{2c6c}'],
-	['\u{2c71}','\u{2c71}'],
-	['\u{2c73}','\u{2c74}'],
-	['\u{2c76}','\u{2c7b}'],
-	['\u{2c81}','\u{2c81}'],
-	['\u{2c83}','\u{2c83}'],
-	['\u{2c85}','\u{2c85}'],
-	['\u{2c87}','\u{2c87}'],
-	['\u{2c89}','\u{2c89}'],
-	['\u{2c8b}','\u{2c8b}'],
-	['\u{2c8d}','\u{2c8d}'],
-	['\u{2c8f}','\u{2c8f}'],
-	['\u{2c91}','\u{2c91}'],
-	['\u{2c93}','\u{2c93}'],
-	['\u{2c95}','\u{2c95}'],
-	['\u{2c97}','\u{2c97}'],
-	['\u{2c99}','\u{2c99}'],
-	['\u{2c9b}','\u{2c9b}'],
-	['\u{2c9d}','\u{2c9d}'],
-	['\u{2c9f}','\u{2c9f}'],
-	['\u{2ca1}','\u{2ca1}'],
-	['\u{2ca3}','\u{2ca3}'],
-	['\u{2ca5}','\u{2ca5}'],
-	['\u{2ca7}','\u{2ca7}'],
-	['\u{2ca9}','\u{2ca9}'],
-	['\u{2cab}','\u{2cab}'],
-	['\u{2cad}','\u{2cad}'],
-	['\u{2caf}','\u{2caf}'],
-	['\u{2cb1}','\u{2cb1}'],
-	['\u{2cb3}','\u{2cb3}'],
-	['\u{2cb5}','\u{2cb5}'],
-	['\u{2cb7}','\u{2cb7}'],
-	['\u{2cb9}','\u{2cb9}'],
-	['\u{2cbb}','\u{2cbb}'],
-	['\u{2cbd}','\u{2cbd}'],
-	['\u{2cbf}','\u{2cbf}'],
-	['\u{2cc1}','\u{2cc1}'],
-	['\u{2cc3}','\u{2cc3}'],
-	['\u{2cc5}','\u{2cc5}'],
-	['\u{2cc7}','\u{2cc7}'],
-	['\u{2cc9}','\u{2cc9}'],
-	['\u{2ccb}','\u{2ccb}'],
-	['\u{2ccd}','\u{2ccd}'],
-	['\u{2ccf}','\u{2ccf}'],
-	['\u{2cd1}','\u{2cd1}'],
-	['\u{2cd3}','\u{2cd3}'],
-	['\u{2cd5}','\u{2cd5}'],
-	['\u{2cd7}','\u{2cd7}'],
-	['\u{2cd9}','\u{2cd9}'],
-	['\u{2cdb}','\u{2cdb}'],
-	['\u{2cdd}','\u{2cdd}'],
-	['\u{2cdf}','\u{2cdf}'],
-	['\u{2ce1}','\u{2ce1}'],
-	['\u{2ce3}','\u{2ce4}'],
-	['\u{2cec}','\u{2cec}'],
-	['\u{2cee}','\u{2cee}'],
-	['\u{2cf3}','\u{2cf3}'],
-	['\u{2d00}','\u{2d25}'],
-	['\u{2d27}','\u{2d27}'],
-	['\u{2d2d}','\u{2d2d}'],
-	['\u{a641}','\u{a641}'],
-	['\u{a643}','\u{a643}'],
-	['\u{a645}','\u{a645}'],
-	['\u{a647}','\u{a647}'],
-	['\u{a649}','\u{a649}'],
-	['\u{a64b}','\u{a64b}'],
-	['\u{a64d}','\u{a64d}'],
-	['\u{a64f}','\u{a64f}'],
-	['\u{a651}','\u{a651}'],
-	['\u{a653}','\u{a653}'],
-	['\u{a655}','\u{a655}'],
-	['\u{a657}','\u{a657}'],
-	['\u{a659}','\u{a659}'],
-	['\u{a65b}','\u{a65b}'],
-	['\u{a65d}','\u{a65d}'],
-	['\u{a65f}','\u{a65f}'],
-	['\u{a661}','\u{a661}'],
-	['\u{a663}','\u{a663}'],
-	['\u{a665}','\u{a665}'],
-	['\u{a667}','\u{a667}'],
-	['\u{a669}','\u{a669}'],
-	['\u{a66b}','\u{a66b}'],
-	['\u{a66d}','\u{a66d}'],
-	['\u{a681}','\u{a681}'],
-	['\u{a683}','\u{a683}'],
-	['\u{a685}','\u{a685}'],
-	['\u{a687}','\u{a687}'],
-	['\u{a689}','\u{a689}'],
-	['\u{a68b}','\u{a68b}'],
-	['\u{a68d}','\u{a68d}'],
-	['\u{a68f}','\u{a68f}'],
-	['\u{a691}','\u{a691}'],
-	['\u{a693}','\u{a693}'],
-	['\u{a695}','\u{a695}'],
-	['\u{a697}','\u{a697}'],
-	['\u{a723}','\u{a723}'],
-	['\u{a725}','\u{a725}'],
-	['\u{a727}','\u{a727}'],
-	['\u{a729}','\u{a729}'],
-	['\u{a72b}','\u{a72b}'],
-	['\u{a72d}','\u{a72d}'],
-	['\u{a72f}','\u{a731}'],
-	['\u{a733}','\u{a733}'],
-	['\u{a735}','\u{a735}'],
-	['\u{a737}','\u{a737}'],
-	['\u{a739}','\u{a739}'],
-	['\u{a73b}','\u{a73b}'],
-	['\u{a73d}','\u{a73d}'],
-	['\u{a73f}','\u{a73f}'],
-	['\u{a741}','\u{a741}'],
-	['\u{a743}','\u{a743}'],
-	['\u{a745}','\u{a745}'],
-	['\u{a747}','\u{a747}'],
-	['\u{a749}','\u{a749}'],
-	['\u{a74b}','\u{a74b}'],
-	['\u{a74d}','\u{a74d}'],
-	['\u{a74f}','\u{a74f}'],
-	['\u{a751}','\u{a751}'],
-	['\u{a753}','\u{a753}'],
-	['\u{a755}','\u{a755}'],
-	['\u{a757}','\u{a757}'],
-	['\u{a759}','\u{a759}'],
-	['\u{a75b}','\u{a75b}'],
-	['\u{a75d}','\u{a75d}'],
-	['\u{a75f}','\u{a75f}'],
-	['\u{a761}','\u{a761}'],
-	['\u{a763}','\u{a763}'],
-	['\u{a765}','\u{a765}'],
-	['\u{a767}','\u{a767}'],
-	['\u{a769}','\u{a769}'],
-	['\u{a76b}','\u{a76b}'],
-	['\u{a76d}','\u{a76d}'],
-	['\u{a76f}','\u{a76f}'],
-	['\u{a771}','\u{a778}'],
-	['\u{a77a}','\u{a77a}'],
-	['\u{a77c}','\u{a77c}'],
-	['\u{a77f}','\u{a77f}'],
-	['\u{a781}','\u{a781}'],
-	['\u{a783}','\u{a783}'],
-	['\u{a785}','\u{a785}'],
-	['\u{a787}','\u{a787}'],
-	['\u{a78c}','\u{a78c}'],
-	['\u{a78e}','\u{a78e}'],
-	['\u{a791}','\u{a791}'],
-	['\u{a793}','\u{a793}'],
-	['\u{a7a1}','\u{a7a1}'],
-	['\u{a7a3}','\u{a7a3}'],
-	['\u{a7a5}','\u{a7a5}'],
-	['\u{a7a7}','\u{a7a7}'],
-	['\u{a7a9}','\u{a7a9}'],
-	['\u{a7fa}','\u{a7fa}'],
-	['\u{fb00}','\u{fb06}'],
-	['\u{fb13}','\u{fb17}'],
-	['\u{ff41}','\u{ff5a}'],
-	['\u{10428}','\u{1044f}'],
-	['\u{1d41a}','\u{1d433}'],
-	['\u{1d44e}','\u{1d454}'],
-	['\u{1d456}','\u{1d467}'],
-	['\u{1d482}','\u{1d49b}'],
-	['\u{1d4b6}','\u{1d4b9}'],
-	['\u{1d4bb}','\u{1d4bb}'],
-	['\u{1d4bd}','\u{1d4c3}'],
-	['\u{1d4c5}','\u{1d4cf}'],
-	['\u{1d4ea}','\u{1d503}'],
-	['\u{1d51e}','\u{1d537}'],
-	['\u{1d552}','\u{1d56b}'],
-	['\u{1d586}','\u{1d59f}'],
-	['\u{1d5ba}','\u{1d5d3}'],
-	['\u{1d5ee}','\u{1d607}'],
-	['\u{1d622}','\u{1d63b}'],
-	['\u{1d656}','\u{1d66f}'],
-	['\u{1d68a}','\u{1d6a5}'],
-	['\u{1d6c2}','\u{1d6da}'],
-	['\u{1d6dc}','\u{1d6e1}'],
-	['\u{1d6fc}','\u{1d714}'],
-	['\u{1d716}','\u{1d71b}'],
-	['\u{1d736}','\u{1d74e}'],
-	['\u{1d750}','\u{1d755}'],
-	['\u{1d770}','\u{1d788}'],
-	['\u{1d78a}','\u{1d78f}'],
-	['\u{1d7aa}','\u{1d7c2}'],
-	['\u{1d7c4}','\u{1d7c9}'],
-	['\u{1d7cb}','\u{1d7cb}'],
-]
-
-const tabtitle = [
-	['\u{1c5}','\u{1c5}'],
-	['\u{1c8}','\u{1c8}'],
-	['\u{1cb}','\u{1cb}'],
-	['\u{1f2}','\u{1f2}'],
-	['\u{1f88}','\u{1f8f}'],
-	['\u{1f98}','\u{1f9f}'],
-	['\u{1fa8}','\u{1faf}'],
-	['\u{1fbc}','\u{1fbc}'],
-	['\u{1fcc}','\u{1fcc}'],
-	['\u{1ffc}','\u{1ffc}'],
-]
-
-const tabword = [
-	['\u{30}','\u{39}'],
-	['\u{41}','\u{5a}'],
-	['\u{5f}','\u{5f}'],
-	['\u{61}','\u{7a}'],
-	['\u{aa}','\u{aa}'],
-	['\u{b5}','\u{b5}'],
-	['\u{ba}','\u{ba}'],
-	['\u{c0}','\u{d6}'],
-	['\u{d8}','\u{f6}'],
-	['\u{f8}','\u{2c1}'],
-	['\u{2c6}','\u{2d1}'],
-	['\u{2e0}','\u{2e4}'],
-	['\u{2ec}','\u{2ec}'],
-	['\u{2ee}','\u{2ee}'],
-	['\u{370}','\u{374}'],
-	['\u{376}','\u{377}'],
-	['\u{37a}','\u{37d}'],
-	['\u{386}','\u{386}'],
-	['\u{388}','\u{38a}'],
-	['\u{38c}','\u{38c}'],
-	['\u{38e}','\u{3a1}'],
-	['\u{3a3}','\u{3f5}'],
-	['\u{3f7}','\u{481}'],
-	['\u{48a}','\u{527}'],
-	['\u{531}','\u{556}'],
-	['\u{559}','\u{559}'],
-	['\u{561}','\u{587}'],
-	['\u{5d0}','\u{5ea}'],
-	['\u{5f0}','\u{5f2}'],
-	['\u{620}','\u{64a}'],
-	['\u{660}','\u{669}'],
-	['\u{66e}','\u{66f}'],
-	['\u{671}','\u{6d3}'],
-	['\u{6d5}','\u{6d5}'],
-	['\u{6e5}','\u{6e6}'],
-	['\u{6ee}','\u{6fc}'],
-	['\u{6ff}','\u{6ff}'],
-	['\u{710}','\u{710}'],
-	['\u{712}','\u{72f}'],
-	['\u{74d}','\u{7a5}'],
-	['\u{7b1}','\u{7b1}'],
-	['\u{7c0}','\u{7ea}'],
-	['\u{7f4}','\u{7f5}'],
-	['\u{7fa}','\u{7fa}'],
-	['\u{800}','\u{815}'],
-	['\u{81a}','\u{81a}'],
-	['\u{824}','\u{824}'],
-	['\u{828}','\u{828}'],
-	['\u{840}','\u{858}'],
-	['\u{8a0}','\u{8a0}'],
-	['\u{8a2}','\u{8ac}'],
-	['\u{904}','\u{939}'],
-	['\u{93d}','\u{93d}'],
-	['\u{950}','\u{950}'],
-	['\u{958}','\u{961}'],
-	['\u{966}','\u{96f}'],
-	['\u{971}','\u{977}'],
-	['\u{979}','\u{97f}'],
-	['\u{985}','\u{98c}'],
-	['\u{98f}','\u{990}'],
-	['\u{993}','\u{9a8}'],
-	['\u{9aa}','\u{9b0}'],
-	['\u{9b2}','\u{9b2}'],
-	['\u{9b6}','\u{9b9}'],
-	['\u{9bd}','\u{9bd}'],
-	['\u{9ce}','\u{9ce}'],
-	['\u{9dc}','\u{9dd}'],
-	['\u{9df}','\u{9e1}'],
-	['\u{9e6}','\u{9f1}'],
-	['\u{a05}','\u{a0a}'],
-	['\u{a0f}','\u{a10}'],
-	['\u{a13}','\u{a28}'],
-	['\u{a2a}','\u{a30}'],
-	['\u{a32}','\u{a33}'],
-	['\u{a35}','\u{a36}'],
-	['\u{a38}','\u{a39}'],
-	['\u{a59}','\u{a5c}'],
-	['\u{a5e}','\u{a5e}'],
-	['\u{a66}','\u{a6f}'],
-	['\u{a72}','\u{a74}'],
-	['\u{a85}','\u{a8d}'],
-	['\u{a8f}','\u{a91}'],
-	['\u{a93}','\u{aa8}'],
-	['\u{aaa}','\u{ab0}'],
-	['\u{ab2}','\u{ab3}'],
-	['\u{ab5}','\u{ab9}'],
-	['\u{abd}','\u{abd}'],
-	['\u{ad0}','\u{ad0}'],
-	['\u{ae0}','\u{ae1}'],
-	['\u{ae6}','\u{aef}'],
-	['\u{b05}','\u{b0c}'],
-	['\u{b0f}','\u{b10}'],
-	['\u{b13}','\u{b28}'],
-	['\u{b2a}','\u{b30}'],
-	['\u{b32}','\u{b33}'],
-	['\u{b35}','\u{b39}'],
-	['\u{b3d}','\u{b3d}'],
-	['\u{b5c}','\u{b5d}'],
-	['\u{b5f}','\u{b61}'],
-	['\u{b66}','\u{b6f}'],
-	['\u{b71}','\u{b71}'],
-	['\u{b83}','\u{b83}'],
-	['\u{b85}','\u{b8a}'],
-	['\u{b8e}','\u{b90}'],
-	['\u{b92}','\u{b95}'],
-	['\u{b99}','\u{b9a}'],
-	['\u{b9c}','\u{b9c}'],
-	['\u{b9e}','\u{b9f}'],
-	['\u{ba3}','\u{ba4}'],
-	['\u{ba8}','\u{baa}'],
-	['\u{bae}','\u{bb9}'],
-	['\u{bd0}','\u{bd0}'],
-	['\u{be6}','\u{bef}'],
-	['\u{c05}','\u{c0c}'],
-	['\u{c0e}','\u{c10}'],
-	['\u{c12}','\u{c28}'],
-	['\u{c2a}','\u{c33}'],
-	['\u{c35}','\u{c39}'],
-	['\u{c3d}','\u{c3d}'],
-	['\u{c58}','\u{c59}'],
-	['\u{c60}','\u{c61}'],
-	['\u{c66}','\u{c6f}'],
-	['\u{c85}','\u{c8c}'],
-	['\u{c8e}','\u{c90}'],
-	['\u{c92}','\u{ca8}'],
-	['\u{caa}','\u{cb3}'],
-	['\u{cb5}','\u{cb9}'],
-	['\u{cbd}','\u{cbd}'],
-	['\u{cde}','\u{cde}'],
-	['\u{ce0}','\u{ce1}'],
-	['\u{ce6}','\u{cef}'],
-	['\u{cf1}','\u{cf2}'],
-	['\u{d05}','\u{d0c}'],
-	['\u{d0e}','\u{d10}'],
-	['\u{d12}','\u{d3a}'],
-	['\u{d3d}','\u{d3d}'],
-	['\u{d4e}','\u{d4e}'],
-	['\u{d60}','\u{d61}'],
-	['\u{d66}','\u{d6f}'],
-	['\u{d7a}','\u{d7f}'],
-	['\u{d85}','\u{d96}'],
-	['\u{d9a}','\u{db1}'],
-	['\u{db3}','\u{dbb}'],
-	['\u{dbd}','\u{dbd}'],
-	['\u{dc0}','\u{dc6}'],
-	['\u{e01}','\u{e30}'],
-	['\u{e32}','\u{e33}'],
-	['\u{e40}','\u{e46}'],
-	['\u{e50}','\u{e59}'],
-	['\u{e81}','\u{e82}'],
-	['\u{e84}','\u{e84}'],
-	['\u{e87}','\u{e88}'],
-	['\u{e8a}','\u{e8a}'],
-	['\u{e8d}','\u{e8d}'],
-	['\u{e94}','\u{e97}'],
-	['\u{e99}','\u{e9f}'],
-	['\u{ea1}','\u{ea3}'],
-	['\u{ea5}','\u{ea5}'],
-	['\u{ea7}','\u{ea7}'],
-	['\u{eaa}','\u{eab}'],
-	['\u{ead}','\u{eb0}'],
-	['\u{eb2}','\u{eb3}'],
-	['\u{ebd}','\u{ebd}'],
-	['\u{ec0}','\u{ec4}'],
-	['\u{ec6}','\u{ec6}'],
-	['\u{ed0}','\u{ed9}'],
-	['\u{edc}','\u{edf}'],
-	['\u{f00}','\u{f00}'],
-	['\u{f20}','\u{f29}'],
-	['\u{f40}','\u{f47}'],
-	['\u{f49}','\u{f6c}'],
-	['\u{f88}','\u{f8c}'],
-	['\u{1000}','\u{102a}'],
-	['\u{103f}','\u{1049}'],
-	['\u{1050}','\u{1055}'],
-	['\u{105a}','\u{105d}'],
-	['\u{1061}','\u{1061}'],
-	['\u{1065}','\u{1066}'],
-	['\u{106e}','\u{1070}'],
-	['\u{1075}','\u{1081}'],
-	['\u{108e}','\u{108e}'],
-	['\u{1090}','\u{1099}'],
-	['\u{10a0}','\u{10c5}'],
-	['\u{10c7}','\u{10c7}'],
-	['\u{10cd}','\u{10cd}'],
-	['\u{10d0}','\u{10fa}'],
-	['\u{10fc}','\u{1248}'],
-	['\u{124a}','\u{124d}'],
-	['\u{1250}','\u{1256}'],
-	['\u{1258}','\u{1258}'],
-	['\u{125a}','\u{125d}'],
-	['\u{1260}','\u{1288}'],
-	['\u{128a}','\u{128d}'],
-	['\u{1290}','\u{12b0}'],
-	['\u{12b2}','\u{12b5}'],
-	['\u{12b8}','\u{12be}'],
-	['\u{12c0}','\u{12c0}'],
-	['\u{12c2}','\u{12c5}'],
-	['\u{12c8}','\u{12d6}'],
-	['\u{12d8}','\u{1310}'],
-	['\u{1312}','\u{1315}'],
-	['\u{1318}','\u{135a}'],
-	['\u{1380}','\u{138f}'],
-	['\u{13a0}','\u{13f4}'],
-	['\u{1401}','\u{166c}'],
-	['\u{166f}','\u{167f}'],
-	['\u{1681}','\u{169a}'],
-	['\u{16a0}','\u{16ea}'],
-	['\u{1700}','\u{170c}'],
-	['\u{170e}','\u{1711}'],
-	['\u{1720}','\u{1731}'],
-	['\u{1740}','\u{1751}'],
-	['\u{1760}','\u{176c}'],
-	['\u{176e}','\u{1770}'],
-	['\u{1780}','\u{17b3}'],
-	['\u{17d7}','\u{17d7}'],
-	['\u{17dc}','\u{17dc}'],
-	['\u{17e0}','\u{17e9}'],
-	['\u{1810}','\u{1819}'],
-	['\u{1820}','\u{1877}'],
-	['\u{1880}','\u{18a8}'],
-	['\u{18aa}','\u{18aa}'],
-	['\u{18b0}','\u{18f5}'],
-	['\u{1900}','\u{191c}'],
-	['\u{1946}','\u{196d}'],
-	['\u{1970}','\u{1974}'],
-	['\u{1980}','\u{19ab}'],
-	['\u{19c1}','\u{19c7}'],
-	['\u{19d0}','\u{19d9}'],
-	['\u{1a00}','\u{1a16}'],
-	['\u{1a20}','\u{1a54}'],
-	['\u{1a80}','\u{1a89}'],
-	['\u{1a90}','\u{1a99}'],
-	['\u{1aa7}','\u{1aa7}'],
-	['\u{1b05}','\u{1b33}'],
-	['\u{1b45}','\u{1b4b}'],
-	['\u{1b50}','\u{1b59}'],
-	['\u{1b83}','\u{1ba0}'],
-	['\u{1bae}','\u{1be5}'],
-	['\u{1c00}','\u{1c23}'],
-	['\u{1c40}','\u{1c49}'],
-	['\u{1c4d}','\u{1c7d}'],
-	['\u{1ce9}','\u{1cec}'],
-	['\u{1cee}','\u{1cf1}'],
-	['\u{1cf5}','\u{1cf6}'],
-	['\u{1d00}','\u{1dbf}'],
-	['\u{1e00}','\u{1f15}'],
-	['\u{1f18}','\u{1f1d}'],
-	['\u{1f20}','\u{1f45}'],
-	['\u{1f48}','\u{1f4d}'],
-	['\u{1f50}','\u{1f57}'],
-	['\u{1f59}','\u{1f59}'],
-	['\u{1f5b}','\u{1f5b}'],
-	['\u{1f5d}','\u{1f5d}'],
-	['\u{1f5f}','\u{1f7d}'],
-	['\u{1f80}','\u{1fb4}'],
-	['\u{1fb6}','\u{1fbc}'],
-	['\u{1fbe}','\u{1fbe}'],
-	['\u{1fc2}','\u{1fc4}'],
-	['\u{1fc6}','\u{1fcc}'],
-	['\u{1fd0}','\u{1fd3}'],
-	['\u{1fd6}','\u{1fdb}'],
-	['\u{1fe0}','\u{1fec}'],
-	['\u{1ff2}','\u{1ff4}'],
-	['\u{1ff6}','\u{1ffc}'],
-	['\u{2071}','\u{2071}'],
-	['\u{207f}','\u{207f}'],
-	['\u{2090}','\u{209c}'],
-	['\u{2102}','\u{2102}'],
-	['\u{2107}','\u{2107}'],
-	['\u{210a}','\u{2113}'],
-	['\u{2115}','\u{2115}'],
-	['\u{2119}','\u{211d}'],
-	['\u{2124}','\u{2124}'],
-	['\u{2126}','\u{2126}'],
-	['\u{2128}','\u{2128}'],
-	['\u{212a}','\u{212d}'],
-	['\u{212f}','\u{2139}'],
-	['\u{213c}','\u{213f}'],
-	['\u{2145}','\u{2149}'],
-	['\u{214e}','\u{214e}'],
-	['\u{2183}','\u{2184}'],
-	['\u{2c00}','\u{2c2e}'],
-	['\u{2c30}','\u{2c5e}'],
-	['\u{2c60}','\u{2ce4}'],
-	['\u{2ceb}','\u{2cee}'],
-	['\u{2cf2}','\u{2cf3}'],
-	['\u{2d00}','\u{2d25}'],
-	['\u{2d27}','\u{2d27}'],
-	['\u{2d2d}','\u{2d2d}'],
-	['\u{2d30}','\u{2d67}'],
-	['\u{2d6f}','\u{2d6f}'],
-	['\u{2d80}','\u{2d96}'],
-	['\u{2da0}','\u{2da6}'],
-	['\u{2da8}','\u{2dae}'],
-	['\u{2db0}','\u{2db6}'],
-	['\u{2db8}','\u{2dbe}'],
-	['\u{2dc0}','\u{2dc6}'],
-	['\u{2dc8}','\u{2dce}'],
-	['\u{2dd0}','\u{2dd6}'],
-	['\u{2dd8}','\u{2dde}'],
-	['\u{2e2f}','\u{2e2f}'],
-	['\u{3005}','\u{3006}'],
-	['\u{3031}','\u{3035}'],
-	['\u{303b}','\u{303c}'],
-	['\u{3041}','\u{3096}'],
-	['\u{309d}','\u{309f}'],
-	['\u{30a1}','\u{30fa}'],
-	['\u{30fc}','\u{30ff}'],
-	['\u{3105}','\u{312d}'],
-	['\u{3131}','\u{318e}'],
-	['\u{31a0}','\u{31ba}'],
-	['\u{31f0}','\u{31ff}'],
-	['\u{3400}','\u{4db5}'],
-	['\u{4e00}','\u{9fcc}'],
-	['\u{a000}','\u{a48c}'],
-	['\u{a4d0}','\u{a4fd}'],
-	['\u{a500}','\u{a60c}'],
-	['\u{a610}','\u{a62b}'],
-	['\u{a640}','\u{a66e}'],
-	['\u{a67f}','\u{a697}'],
-	['\u{a6a0}','\u{a6e5}'],
-	['\u{a717}','\u{a71f}'],
-	['\u{a722}','\u{a788}'],
-	['\u{a78b}','\u{a78e}'],
-	['\u{a790}','\u{a793}'],
-	['\u{a7a0}','\u{a7aa}'],
-	['\u{a7f8}','\u{a801}'],
-	['\u{a803}','\u{a805}'],
-	['\u{a807}','\u{a80a}'],
-	['\u{a80c}','\u{a822}'],
-	['\u{a840}','\u{a873}'],
-	['\u{a882}','\u{a8b3}'],
-	['\u{a8d0}','\u{a8d9}'],
-	['\u{a8f2}','\u{a8f7}'],
-	['\u{a8fb}','\u{a8fb}'],
-	['\u{a900}','\u{a925}'],
-	['\u{a930}','\u{a946}'],
-	['\u{a960}','\u{a97c}'],
-	['\u{a984}','\u{a9b2}'],
-	['\u{a9cf}','\u{a9d9}'],
-	['\u{aa00}','\u{aa28}'],
-	['\u{aa40}','\u{aa42}'],
-	['\u{aa44}','\u{aa4b}'],
-	['\u{aa50}','\u{aa59}'],
-	['\u{aa60}','\u{aa76}'],
-	['\u{aa7a}','\u{aa7a}'],
-	['\u{aa80}','\u{aaaf}'],
-	['\u{aab1}','\u{aab1}'],
-	['\u{aab5}','\u{aab6}'],
-	['\u{aab9}','\u{aabd}'],
-	['\u{aac0}','\u{aac0}'],
-	['\u{aac2}','\u{aac2}'],
-	['\u{aadb}','\u{aadd}'],
-	['\u{aae0}','\u{aaea}'],
-	['\u{aaf2}','\u{aaf4}'],
-	['\u{ab01}','\u{ab06}'],
-	['\u{ab09}','\u{ab0e}'],
-	['\u{ab11}','\u{ab16}'],
-	['\u{ab20}','\u{ab26}'],
-	['\u{ab28}','\u{ab2e}'],
-	['\u{abc0}','\u{abe2}'],
-	['\u{abf0}','\u{abf9}'],
-	['\u{ac00}','\u{d7a3}'],
-	['\u{d7b0}','\u{d7c6}'],
-	['\u{d7cb}','\u{d7fb}'],
-	['\u{f900}','\u{fa6d}'],
-	['\u{fa70}','\u{fad9}'],
-	['\u{fb00}','\u{fb06}'],
-	['\u{fb13}','\u{fb17}'],
-	['\u{fb1d}','\u{fb1d}'],
-	['\u{fb1f}','\u{fb28}'],
-	['\u{fb2a}','\u{fb36}'],
-	['\u{fb38}','\u{fb3c}'],
-	['\u{fb3e}','\u{fb3e}'],
-	['\u{fb40}','\u{fb41}'],
-	['\u{fb43}','\u{fb44}'],
-	['\u{fb46}','\u{fbb1}'],
-	['\u{fbd3}','\u{fd3d}'],
-	['\u{fd50}','\u{fd8f}'],
-	['\u{fd92}','\u{fdc7}'],
-	['\u{fdf0}','\u{fdfb}'],
-	['\u{fe70}','\u{fe74}'],
-	['\u{fe76}','\u{fefc}'],
-	['\u{ff10}','\u{ff19}'],
-	['\u{ff21}','\u{ff3a}'],
-	['\u{ff41}','\u{ff5a}'],
-	['\u{ff66}','\u{ffbe}'],
-	['\u{ffc2}','\u{ffc7}'],
-	['\u{ffca}','\u{ffcf}'],
-	['\u{ffd2}','\u{ffd7}'],
-	['\u{ffda}','\u{ffdc}'],
-	['\u{10000}','\u{1000b}'],
-	['\u{1000d}','\u{10026}'],
-	['\u{10028}','\u{1003a}'],
-	['\u{1003c}','\u{1003d}'],
-	['\u{1003f}','\u{1004d}'],
-	['\u{10050}','\u{1005d}'],
-	['\u{10080}','\u{100fa}'],
-	['\u{10280}','\u{1029c}'],
-	['\u{102a0}','\u{102d0}'],
-	['\u{10300}','\u{1031e}'],
-	['\u{10330}','\u{10340}'],
-	['\u{10342}','\u{10349}'],
-	['\u{10380}','\u{1039d}'],
-	['\u{103a0}','\u{103c3}'],
-	['\u{103c8}','\u{103cf}'],
-	['\u{10400}','\u{1049d}'],
-	['\u{104a0}','\u{104a9}'],
-	['\u{10800}','\u{10805}'],
-	['\u{10808}','\u{10808}'],
-	['\u{1080a}','\u{10835}'],
-	['\u{10837}','\u{10838}'],
-	['\u{1083c}','\u{1083c}'],
-	['\u{1083f}','\u{10855}'],
-	['\u{10900}','\u{10915}'],
-	['\u{10920}','\u{10939}'],
-	['\u{10980}','\u{109b7}'],
-	['\u{109be}','\u{109bf}'],
-	['\u{10a00}','\u{10a00}'],
-	['\u{10a10}','\u{10a13}'],
-	['\u{10a15}','\u{10a17}'],
-	['\u{10a19}','\u{10a33}'],
-	['\u{10a60}','\u{10a7c}'],
-	['\u{10b00}','\u{10b35}'],
-	['\u{10b40}','\u{10b55}'],
-	['\u{10b60}','\u{10b72}'],
-	['\u{10c00}','\u{10c48}'],
-	['\u{11003}','\u{11037}'],
-	['\u{11066}','\u{1106f}'],
-	['\u{11083}','\u{110af}'],
-	['\u{110d0}','\u{110e8}'],
-	['\u{110f0}','\u{110f9}'],
-	['\u{11103}','\u{11126}'],
-	['\u{11136}','\u{1113f}'],
-	['\u{11183}','\u{111b2}'],
-	['\u{111c1}','\u{111c4}'],
-	['\u{111d0}','\u{111d9}'],
-	['\u{11680}','\u{116aa}'],
-	['\u{116c0}','\u{116c9}'],
-	['\u{12000}','\u{1236e}'],
-	['\u{13000}','\u{1342e}'],
-	['\u{16800}','\u{16a38}'],
-	['\u{16f00}','\u{16f44}'],
-	['\u{16f50}','\u{16f50}'],
-	['\u{16f93}','\u{16f9f}'],
-	['\u{1b000}','\u{1b001}'],
-	['\u{1d400}','\u{1d454}'],
-	['\u{1d456}','\u{1d49c}'],
-	['\u{1d49e}','\u{1d49f}'],
-	['\u{1d4a2}','\u{1d4a2}'],
-	['\u{1d4a5}','\u{1d4a6}'],
-	['\u{1d4a9}','\u{1d4ac}'],
-	['\u{1d4ae}','\u{1d4b9}'],
-	['\u{1d4bb}','\u{1d4bb}'],
-	['\u{1d4bd}','\u{1d4c3}'],
-	['\u{1d4c5}','\u{1d505}'],
-	['\u{1d507}','\u{1d50a}'],
-	['\u{1d50d}','\u{1d514}'],
-	['\u{1d516}','\u{1d51c}'],
-	['\u{1d51e}','\u{1d539}'],
-	['\u{1d53b}','\u{1d53e}'],
-	['\u{1d540}','\u{1d544}'],
-	['\u{1d546}','\u{1d546}'],
-	['\u{1d54a}','\u{1d550}'],
-	['\u{1d552}','\u{1d6a5}'],
-	['\u{1d6a8}','\u{1d6c0}'],
-	['\u{1d6c2}','\u{1d6da}'],
-	['\u{1d6dc}','\u{1d6fa}'],
-	['\u{1d6fc}','\u{1d714}'],
-	['\u{1d716}','\u{1d734}'],
-	['\u{1d736}','\u{1d74e}'],
-	['\u{1d750}','\u{1d76e}'],
-	['\u{1d770}','\u{1d788}'],
-	['\u{1d78a}','\u{1d7a8}'],
-	['\u{1d7aa}','\u{1d7c2}'],
-	['\u{1d7c4}','\u{1d7cb}'],
-	['\u{1d7ce}','\u{1d7ff}'],
-	['\u{1ee00}','\u{1ee03}'],
-	['\u{1ee05}','\u{1ee1f}'],
-	['\u{1ee21}','\u{1ee22}'],
-	['\u{1ee24}','\u{1ee24}'],
-	['\u{1ee27}','\u{1ee27}'],
-	['\u{1ee29}','\u{1ee32}'],
-	['\u{1ee34}','\u{1ee37}'],
-	['\u{1ee39}','\u{1ee39}'],
-	['\u{1ee3b}','\u{1ee3b}'],
-	['\u{1ee42}','\u{1ee42}'],
-	['\u{1ee47}','\u{1ee47}'],
-	['\u{1ee49}','\u{1ee49}'],
-	['\u{1ee4b}','\u{1ee4b}'],
-	['\u{1ee4d}','\u{1ee4f}'],
-	['\u{1ee51}','\u{1ee52}'],
-	['\u{1ee54}','\u{1ee54}'],
-	['\u{1ee57}','\u{1ee57}'],
-	['\u{1ee59}','\u{1ee59}'],
-	['\u{1ee5b}','\u{1ee5b}'],
-	['\u{1ee5d}','\u{1ee5d}'],
-	['\u{1ee5f}','\u{1ee5f}'],
-	['\u{1ee61}','\u{1ee62}'],
-	['\u{1ee64}','\u{1ee64}'],
-	['\u{1ee67}','\u{1ee6a}'],
-	['\u{1ee6c}','\u{1ee72}'],
-	['\u{1ee74}','\u{1ee77}'],
-	['\u{1ee79}','\u{1ee7c}'],
-	['\u{1ee7e}','\u{1ee7e}'],
-	['\u{1ee80}','\u{1ee89}'],
-	['\u{1ee8b}','\u{1ee9b}'],
-	['\u{1eea1}','\u{1eea3}'],
-	['\u{1eea5}','\u{1eea9}'],
-	['\u{1eeab}','\u{1eebb}'],
-	['\u{20000}','\u{2a6d6}'],
-	['\u{2a700}','\u{2b734}'],
-	['\u{2b740}','\u{2b81d}'],
-	['\u{2f800}','\u{2fa1d}'],
-]
-
-const tabdigit = [
-	['\u{30}','\u{39}'],
-	['\u{660}','\u{669}'],
-	['\u{6f0}','\u{6f9}'],
-	['\u{7c0}','\u{7c9}'],
-	['\u{966}','\u{96f}'],
-	['\u{9e6}','\u{9ef}'],
-	['\u{a66}','\u{a6f}'],
-	['\u{ae6}','\u{aef}'],
-	['\u{b66}','\u{b6f}'],
-	['\u{be6}','\u{bef}'],
-	['\u{c66}','\u{c6f}'],
-	['\u{ce6}','\u{cef}'],
-	['\u{d66}','\u{d6f}'],
-	['\u{e50}','\u{e59}'],
-	['\u{ed0}','\u{ed9}'],
-	['\u{f20}','\u{f29}'],
-	['\u{1040}','\u{1049}'],
-	['\u{1090}','\u{1099}'],
-	['\u{17e0}','\u{17e9}'],
-	['\u{1810}','\u{1819}'],
-	['\u{1946}','\u{194f}'],
-	['\u{19d0}','\u{19d9}'],
-	['\u{1a80}','\u{1a89}'],
-	['\u{1a90}','\u{1a99}'],
-	['\u{1b50}','\u{1b59}'],
-	['\u{1bb0}','\u{1bb9}'],
-	['\u{1c40}','\u{1c49}'],
-	['\u{1c50}','\u{1c59}'],
-	['\u{a620}','\u{a629}'],
-	['\u{a8d0}','\u{a8d9}'],
-	['\u{a900}','\u{a909}'],
-	['\u{a9d0}','\u{a9d9}'],
-	['\u{aa50}','\u{aa59}'],
-	['\u{abf0}','\u{abf9}'],
-	['\u{ff10}','\u{ff19}'],
-	['\u{104a0}','\u{104a9}'],
-	['\u{11066}','\u{1106f}'],
-	['\u{110f0}','\u{110f9}'],
-	['\u{11136}','\u{1113f}'],
-	['\u{111d0}','\u{111d9}'],
-	['\u{116c0}','\u{116c9}'],
-	['\u{1d7ce}','\u{1d7ff}'],
-]
-
-const tabxdigit = [
-	['\u{30}','\u{39}'],
-	['\u{41}','\u{46}'],
-	['\u{61}','\u{66}'],
-]
-
-const tabspace = [
-	['\u{9}','\u{d}'],
-	['\u{20}','\u{20}'],
-	['\u{85}','\u{85}'],
-	['\u{a0}','\u{a0}'],
-	['\u{1680}','\u{1680}'],
-	['\u{2000}','\u{200a}'],
-	['\u{2028}','\u{2029}'],
-	['\u{202f}','\u{202f}'],
-	['\u{205f}','\u{205f}'],
-	['\u{3000}','\u{3000}'],
-]
-
-const tabblank = [
-	['\u{9}','\u{9}'],
-	['\u{20}','\u{20}'],
-	['\u{a0}','\u{a0}'],
-	['\u{1680}','\u{1680}'],
-	['\u{2000}','\u{200a}'],
-	['\u{202f}','\u{202f}'],
-	['\u{205f}','\u{205f}'],
-	['\u{3000}','\u{3000}'],
-]
-
--- a/libregex/redump.myr
+++ /dev/null
@@ -1,87 +1,0 @@
-use std
-use bio
-use regex
-
-const main = {args
-	var cmd, comp
-	var verbose
-	var fd
-
-	verbose = false
-	cmd = std.optparse(args, &[
-		.argdesc = "regex [inputs...]",
-		.minargs = 1,
-		.maxargs = 1,
-		.opts = [
-			[.opt='v', .desc="dump verbose regex output"]
-		][:],
-	])
-	for opt in cmd.opts
-		match opt
-		| ('v', _):	verbose = true
-		| _:	std.fatal("Unknown argument")
-		;;
-	;;
-	if verbose
-		comp = regex.dbgcompile(cmd.args[0])
-	else
-		comp = regex.compile(cmd.args[0])
-	;;
-	match comp
-	| `std.Fail m:	
-		std.fatal("unable to compile regex: {}\n", regex.failmsg(m))
-	| `std.Ok re:
-		if cmd.args.len > 1
-			runall(re, cmd.args)
-		else
-			fd = bio.mkfile(0, bio.Rd)
-			dump(re, fd)
-			bio.close(fd)
-		;;
-	;;
-}
-
-const runall = {re, files
-
-	for f in files
-		match bio.open(f, bio.Rd)
-		| `std.Ok fd:
-			dump(re, fd)
-			bio.close(fd)
-		| `std.Fail m:
-			std.fatal("failed to open {}: {}\n", f, m)
-		;;
-	;;
-}
-
-const dump = {re, fd 
-	while true
-		match bio.readln(fd)
-		| `std.Some ln:
-			show(re, ln, regex.exec(re, ln))
-			std.slfree(ln)
-		| `std.None:
-			break
-		;;
-	;;
-}
-
-const show = {re, ln, mg
-	var i
-
-	match mg
-	| `std.Some rl:
-		std.put("Matched: {}\n", rl[0])
-		for i = 1; i < rl.len; i++
-			std.put("\tgroup {}: {}\n", i, rl[i])
-		;;
-	| `std.None:
-		std.put("Match failed:\n")
-		std.put("\t{}\n", ln)
-		std.put("\t")
-		for i = 0; i < re.strp - 1; i++
-			std.put("~")
-		;;
-		std.put("^\n")
-	;;
-}
--- a/libregex/test/basic.myr
+++ /dev/null
@@ -1,39 +1,0 @@
-use std
-
-use "testmatch.use"
-
-const main = {
-	var s : byte[:]
-		
-	s = std.strjoin([
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-	][:], "")
-	testmatch(".*bc", "Abc", `std.Some [][:])
-	testmatch("(a*)*", "a", `std.Some ["a"][:])
-	testmatch("(aa|aab?)*", s, `std.Some ["aa"][:])
-        /* greedy matches */
-	testmatch("(<.*>).*", "<a foo> blah <bar>", `std.Some [
-			"<a foo> blah <bar>",
-		][:])
-	testmatch("(<.+>).*", "<a foo> blah <bar>", `std.Some [
-			"<a foo> blah <bar>",
-		][:])
-        /* reluctant matches */
-	testmatch("(<.*?>).*", "<a foo> blah <bar>", `std.Some [
-			"<a foo>",
-		][:])
-	testmatch("(<.+?>).*", "<a foo> blah <bar>", `std.Some [
-			"<a foo>",
-		][:])
-}
--- a/libregex/test/bld.sub
+++ /dev/null
@@ -1,7 +1,0 @@
-test basic {inc=../libstd,inc=..} = basic.myr testmatch.myr;;
-test boundaries {inc=../libstd,inc=..} = boundaries.myr testmatch.myr;;
-test capture {inc=../libstd,inc=..} = capture.myr testmatch.myr;;
-test class {inc=../libstd,inc=..} = class.myr testmatch.myr;;
-test failmatch {inc=../libstd,inc=..} = failmatch.myr testmatch.myr;;
-test negclass {inc=../libstd,inc=..} = negclass.myr testmatch.myr;;
-test unicode {inc=../libstd,inc=..} = unicode.myr testmatch.myr;;
--- a/libregex/test/boundaries.myr
+++ /dev/null
@@ -1,36 +1,0 @@
-use std
-use "testmatch.use"
-
-const main = {
-	/* expected matches */
-	testmatch("\\<([a-z]*)\\>", "abcdef", `std.Some [
-		"abcdef",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "!m!", `std.Some [	/* single char word in midstring */
-		"m",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "!m", `std.Some [	/* single char word at end of string */
-		"m",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "m!", `std.Some [	/* single char word at start of string */
-		"m",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!", `std.Some [	/* word in midstring */
-		"matches",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "matches!!%!", `std.Some [	/* word at start of string */
-		"matches",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches", `std.Some [	/* word at end of string */
-		"matches",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!foo", `std.Some [	/* matches last word in string */
-		"foo",
-	][:])
-	testmatch(".*(\\<.*\\>).*", "123", `std.Some [	/* numbers are also word bounds */
-		"123",
-	][:])
-	
-	/* nonmatches */
-	testmatch("\\<([a-z]*)\\>foo", "abcdefoo", `std.None)	/* word boundary needed in midstring */
-}
--- a/libregex/test/capture.myr
+++ /dev/null
@@ -1,17 +1,0 @@
-use std
-use "testmatch.use"
-
-const main = {
-	testmatch("A(.*)", "Abc", `std.Some ["bc"][:])
-	testmatch("A(.*)e", "Abcde", `std.Some ["bcd"][:])
-	testmatch("(a|b)+", "abab", `std.Some ["b"][:])
-	testmatch("A(b(.*)d)e", "Abcde", `std.Some [
-		"bcd",
-		"c"
-	][:])
-	testmatch("(a?)(a*)(a?)", "aaaa", `std.Some [
-		"a",
-		"aaa",
-		""
-	][:])
-}
--- a/libregex/test/class.myr
+++ /dev/null
@@ -1,67 +1,0 @@
-use std
-
-use "testmatch.use"
-
-const main = {
-	asciiclass()
-	set()
-	/*
-	unicodeclass()
-	negasciiclass()
-	negasciirange()
-	negset()
-	*/
-}
-
-const asciiclass = {
-	/* \d success */
-	testmatch("\\d", "1", `std.Some [][:])
-	testmatch("\\d\\d", "13", `std.Some [][:])
-	testmatch("\\d+", "13688", `std.Some [][:])
-	/* \d fail */
-	testmatch("\\d", "x", `std.None)
-	testmatch("\\d\\d", "x3", `std.None)
-	testmatch("\\d+", "1368f", `std.None)
-
-	/* \x success */
-	testmatch("\\x", "a", `std.Some [][:])
-	testmatch("\\x\\x", "1F", `std.Some [][:])
-	testmatch("\\x+", "13b8cDEf", `std.Some [][:])
-	/* \x fail */
-	testmatch("\\x", "Z", `std.None)
-	testmatch("\\x\\x", "fg", `std.None)
-	testmatch("\\x+", "13b8cg", `std.None)
-
-	/* \s success */
-	testmatch("\\s", " ", `std.Some [][:])
-	testmatch("\\s\\s", "\t\n", `std.Some [][:])
-	testmatch("\\s+", "\t\n\r \t", `std.Some [][:])
-	/* \s fail */
-	testmatch("\\s", "a", `std.None)
-	testmatch("\\s\\s", "i\n", `std.None)
-	testmatch("\\s+", "\t\n\r.\t", `std.None)
-
-	/* word success */
-	testmatch("\\w+", "abcABC0123_", `std.Some [][:])
-	/* word fail */
-	testmatch("\\w+", "abcABC0123_.", `std.None)
-
-	/* \h success */
-	testmatch("\\h", " ", `std.Some [][:])
-	testmatch("\\h\\h", "\t ", `std.Some [][:])
-	testmatch("\\h+", "\t \t ", `std.Some [][:])
-	/* \h fail */
-	testmatch("\\h", "\n", `std.None)
-	testmatch("\\h\\h", "\t\r", `std.None)
-	testmatch("\\h+", "\t \t.", `std.None)
-}
-
-const set = {
-	/* ranges */
-	testmatch("[a-z]*", "abcd", `std.Some [][:])
-	testmatch("[a-zA-Z]*", "abCD", `std.Some [][:])
-	testmatch("[a-zA-Z0-9_]*", "_abCD018", `std.Some [][:])
-
-	testmatch("[abc]*", "abba", `std.Some [][:])
-	testmatch("[a-zABC]*", "abBa", `std.Some [][:])
-}
--- a/libregex/test/failmatch.myr
+++ /dev/null
@@ -1,7 +1,0 @@
-use std
-
-use "testmatch.use"
-
-const main = {
-	testmatch(".*bcd", "Abc", `std.None)
-}
--- a/libregex/test/negclass.myr
+++ /dev/null
@@ -1,72 +1,0 @@
-use std
-
-use "testmatch.use"
-
-const main = {
-	asciiclass()
-	set()
-	/*
-	unicodeclass()
-	negasciiclass()
-	negasciirange()
-	negset()
-	*/
-}
-
-const asciiclass = {
-	/* \D success */
-	testmatch("\\D", "x", `std.Some [][:])
-	testmatch("\\D+", "xa!#^cs", `std.Some [][:])
-
-	/* \D fail: end of ranges chars */
-	testmatch("\\D", "0", `std.None)
-	testmatch("\\D", "9", `std.None)
-	testmatch("\\D+", "a35x", `std.None)
-	testmatch("\\D+", "13688", `std.None)
-
-	/* \X success */
-	testmatch("\\X", "Z", `std.Some [][:])
-	testmatch("\\X\\X", "gg", `std.Some [][:])
-	/* \X fail */
-	testmatch("\\X", "a", `std.None)
-	testmatch("\\X+", "zz13b8cDEf", `std.None)
-
-	/* \S success */
-	testmatch("\\S", "a", `std.Some [][:])
-	testmatch("\\S\\S", "i%", `std.Some [][:])
-	testmatch("\\S+", "alskd690!#!!", `std.Some [][:])
-
-	/* \S fail */
-	testmatch("\\S", " ", `std.None)
-	testmatch("\\S\\S", "\t\n", `std.None)
-	testmatch("\\S+", "\t \nkait", `std.None)
-
-	/* word success */
-	testmatch("\\W+", "!%!^^@@!^", `std.Some [][:])
-	/* word fail */
-	testmatch("\\W+", "a^#$bcABC0123_", `std.None)
-
-	/* \H success */
-	testmatch("\\H", "\n", `std.Some [][:])
-	testmatch("\\H\\H", "\n\r", `std.Some [][:])
-	/* \H fail */
-	testmatch("\\H+", "\t \t.", `std.None)
-	testmatch("\\H\\H", "\t ", `std.None)
-	testmatch("\\H+", "\ta35 \t ", `std.None)
-}
-
-const set = {
-	/* ranges: should succeed */
-	testmatch("[^a-z]*", "ABCD", `std.Some [][:])
-	testmatch("[^a-zA-Z]*", "1234", `std.Some [][:])
-	testmatch("[^a-zA-Z0-9_]*", "-^^-", `std.Some [][:])
-	testmatch("[^abc]*", "d6d", `std.Some [][:])
-	testmatch("[^a-zABC]*", "!^!!))#", `std.Some [][:])
-
-	/* ranges: should fail */
-	testmatch("[^a-z]*", "abcd", `std.None)
-	testmatch("[^a-zA-Z]*", "abCD", `std.None)
-	testmatch("[^a-zA-Z0-9_]*", "_abCD018", `std.None)
-	testmatch("[^abc]*", "abba", `std.None)
-	testmatch("[^a-zABC]*", "abBa", `std.None)
-}
--- a/libregex/test/runtest.sh
+++ /dev/null
@@ -1,124 +1,0 @@
-#!/bin/bash
-NFAILURES=0
-NPASSES=0
-
-function build {
-    rm -f $1 $1.o $1.s $1.use
-    myrbuild $FLAGS -b $1 $1.myr $EXTRA_SRC
-}
-
-function pass {
-    PASSED="$PASSED $1"
-    NPASSED=$[$NPASSED + 1]
-}
-
-function fail {
-    echo "FAIL: $1"
-    FAILED="$FAILED $1"
-    NFAILED=$[$NFAILED + 1]
-}
-
-function expectstatus {
-    ./$1 $3
-    if [ $? -eq $2 ]; then
-        pass $1
-        return
-    else
-        fail $1
-    fi
-}
-
-function expectprint {
-    if [ "`./$1 $3`" != "$2" ]; then
-        fail $1
-    else
-        pass $1
-    fi
-}
-
-
-function expectcompare {
-    if [ x"" !=  x"$TMPDIR" ]; then 
-        t=$TMPDIR/myrtest-$1-$RANDOM
-    else
-        t=/tmp/myrtest-$1-$RANDOM
-    fi
-    ./$1 $3 > $t
-    if cmp $t data/$1-expected; then
-        pass $1
-    else
-        fail $1
-    fi
-    rm -f $t
-}
-
-function expectfcompare {
-    ./$1 $3
-    if cmp data/$1-expected $2; then
-        pass $1
-    else
-        fail $1
-    fi
-}
-
-function shouldskip {
-  if [ -z $ARGS ]; then
-      return 1
-  fi
-
-  for i in $ARGS; do
-      if [ $i = $1 ]; then
-          return 1
-      fi
-  done
-  return 0
-}
-
-
-# Should build and run
-function B {
-    if shouldskip $1; then
-        return
-    fi
-
-    test="$1"; shift
-    type="$1"; shift
-    res="$1"; shift
-    if [ $# > 0 ]; then
-        args="$1"; shift
-    fi
-    build $test
-    case $type in
-    "E")  expectstatus "$test" "$res" "$input";;
-    "P")  expectprint "$test" "$res" "$input";;
-    "C")  expectcompare "$test" "$res" "$input";;
-    "F")  expectfcompare "$test" "$res" "$args";;
-    esac
-}
-
-# Should fail
-function F {
-    if shouldskip $1; then
-        return
-    fi
-    (build $1) > /dev/null
-    if [ $? -eq '1' ]; then
-        pass $1
-    else
-        fail $1
-    fi
-}
-
-# Should generate a usefile
-function U {
-    return
-}
-
-source tests
-
-echo "PASSED ($NPASSED): $PASSED"
-if [ -z "$NFAILED" ]; then
-    echo "SUCCESS"
-else
-    echo "FAILURES ($NFAILED): $FAILED"
-fi
--- a/libregex/test/testmatch.myr
+++ /dev/null
@@ -1,58 +1,0 @@
-use std
-use regex
-
-pkg =
-	const testmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
-	const dbgmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
-;;
-
-const testmatch = {pat, text, expected
-	run(regex.compile(pat), pat, text, expected)
-}
-
-const dbgmatch = {pat, text, expected
-	run(regex.dbgcompile(pat), pat, text, expected)
-}
-
-const run = {regex, pat, text, expected
-	var i, re
-
-	re = std.try(regex)
-	match regex.exec(re, text)
-	| `std.Some res:
-		match expected
-		| `std.None:
-			std.fatal("expected no match, got:")
-			for i = 0; i < res.len; i++
-				std.put("\t{}: {}\n", i, res[i])
-			;;
-		| `std.Some exp:
-			if !std.sleq(res[0], text)
-				std.put("whole match does not match text!\n")
-				std.fatal("failed matching {} over {}\n", pat, text)
-			;;
-			res = res[1:]
-			if res.len != exp.len
-				std.put("mismatch: expected {} matches, got {}\n",  exp.len, res.len)
-				std.fatal("failed matching {} over {}\n", pat, text)
-			;;
-			for i = 0; i < exp.len; i++
-				if !std.sleq(res[i], exp[i])
-					std.put("mismatch on {}: expected {}, got {}\n", i, exp[i], res[i])
-					std.fatal("failed matching {} over {}\n", pat, text)
-				;;
-			;;
-		;;
-	| `std.None:
-		match expected
-		| `std.None:	/* : expected failure */
-		| `std.Some matches:
-			std.put("expected matches:\n")
-			for i = 0; i < matches.len; i++
-				std.put("\t{}: {}\n", i, matches[i])
-			;;
-			std.fatal("no match found\n")
-		;;
-	;;
-	regex.free(re)
-}
--- a/libregex/test/tests
+++ /dev/null
@@ -1,29 +1,0 @@
-FLAGS=-I../
-EXTRA_SRC=testmatch.myr
-# Format:
-# [B|F] testname [E|P] result
-#    [B|F]: Compiler outcome.
-#	B: Expect that this test will build.
-#	F: Expect that this test will not build.
-#    testname: Test case
-#	The test that will run. We will try to
-#	compile 'testname.myr' to 'testname',
-#	and then execute it, verifying the result
-#    [E|P|C]: Result type
-#	E tells us that the result is an exit status
-#	P tells us that the result is on stdout,
-#         and should be compared to the value on the
-#         line
-#	C tells us that the result is on stdout,
-#         and should be compared to the contents of
-#         the file passed on the line.
-#    result: Result value
-#	What we compare with. This should be self-
-#	evident.
-B basic		C
-B boundaries	C
-B capture	C
-B class		C
-B failmatch	C
-B negclass	C
-B unicode		C
--- a/libregex/test/unicode.myr
+++ /dev/null
@@ -1,19 +1,0 @@
-use std
-use regex
-
-use "testmatch.use"
-
-const main = {
-	testmatch(".*bæc", "Abæc", `std.Some [][:])
-	testmatch("(\\p{L}*)bæc\\P{L}*", \
-		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
-		`std.Some ["Aa"][:])
-        /* test various syntaxen */
-	testmatch("(\\pL*)bæc\\PL*", \
-		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
-		`std.Some ["Aa"][:])
-	testmatch("(\\p{Letter}*)bæc\\P{Uppercase_Letter}*", \
-		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
-		`std.Some ["Aa"][:])
-	testmatch(".", "æ", `std.Some [][:])
-}
--- a/libregex/types.myr
+++ /dev/null
@@ -1,88 +1,0 @@
-use std
-
-pkg regex =
-	type status = union
-		`Noimpl
-		`Incomplete
-		`Unbalanced
-		`Emptyparen
-		`Badrep
-		`Badrange
-		`Badescape
-	;;
-
-	type ast = union
-		/* basic string building */
-		`Alt	(ast#, ast#)
-		`Cat	(ast#, ast#)
-
-		/* repetition */
-		`Star	ast#
-		`Rstar  ast#
-		`Plus	ast#
-		`Rplus	ast#
-		`Quest	ast#	
-
-		/* end matches */
-		`Chr	char
-		`Ranges	char[2][:]
-
-		/* meta */
-		`Cap	(std.size, ast#) /* id, ast */
-		`Bol	/* beginning of line */
-		`Eol	/* end of line */
-		`Bow	/* beginning of word */
-		`Eow	/* end of word */
-	;;
-
-
-	type regex = struct
-		/* compile state */
-		debug	: bool
-		pat	: byte[:]
-		nmatch	: std.size
-
-		/* VM state */
-		runq	: rethread#
-		expired	: rethread#
-		expiredtail	: rethread#
-		proglen	: std.size
-		prog	: reinst[:]
-		nthr	: std.size
-		str	: byte[:]
-		strp	: std.size
-	;;
-
-	type rethread = struct
-		next	: rethread#	/* run queue link */
-
-		tid	: std.size	/* just for debugging */
-		ip	: std.size	/* the instruction pointer */
-		dead	: bool		/* thread died */
-		matched	: bool		/* thread matched */
-
-		mstart	: std.size[:]	/* match starts */
-		mend	: std.size[:]	/* match ends */
-	;;
-
-	pkglocal type reinst = union
-		/* direct consumers */
-		`Ibyte	byte
-		`Irange	(byte, byte)
-
-		/* groups */
-		`Ilbra	std.size
-		`Irbra	std.size
-
-		/* anchors */
-		`Ibol
-		`Ieol
-		`Ibow
-		`Ieow
-
-		/* control flow */
-		`Ifork	(std.size, std.size)
-		`Ijmp	std.size
-		`Imatch	std.size
-	;;
-;;
--- a/libstd/alloc.myr
+++ /dev/null
@@ -1,423 +1,0 @@
-use "die.use"
-use "extremum.use"
-use "types.use"
-use "units.use"
-use "syswrap.use"
-
-/*
-The allocator implementation here is based on Bonwick's slab allocator.
-
-For small allocations (up to Bktmax), it works by requesting large,
-power of two aligned chunks from the operating system, and breaking
-them into a linked list of equal sized chunks. Allocations are then
-satisfied by taking the head of the list of chunks. Empty slabs
-are removed from the freelist.
-
-The data structure looks something like this:
-   Bkts:
-	[16  byte] -> [slab hdr | chunk -> chunk -> chunk] -> [slab hdr | chunk -> chunk -> chunk]
-	[32  byte] -> Zslab
-	[64  byte] -> [slab hdr | chunk -> chunk]
-	...
-	[32k byte] -> ...
-
-Large allocations are simply satisfied by mmap().
-
-*/
-
-pkg std =
-	generic alloc	: (		-> @a#)
-	generic zalloc	: (		-> @a#)
-	generic free	: (v:@a#	-> void)
-
-	generic slalloc	: (len : size	-> @a[:])
-	generic slzalloc	: (len : size	-> @a[:])
-	generic slgrow	: (sl : @a[:], len : size	-> @a[:])
-	generic slzgrow	: (sl : @a[:], len : size	-> @a[:])
-	generic slfree	: (sl : @a[:]	-> void)
-
-	const bytealloc	: (sz:size	-> byte#)
-	const zbytealloc	: (sz:size	-> byte#)
-	const bytefree	: (m:byte#, sz:size	-> void)
-
-
-;;
-
-/* null pointers. only used internally. */
-const Zslab	= 0 castto(slab#)
-const Zchunk	= 0 castto(chunk#)
-
-const Slabsz 	= 1*MiB	/* 1 meg slabs */
-const Cachemax	= 16	/* maximum number of slabs in the cache */
-const Bktmax	= 32*KiB	/* Slabsz / 8; a balance. */
-const Pagesz	= 4*KiB
-const Align	= 16	/* minimum allocation alignment */
-
-var buckets	: bucket[32] /* excessive */
-
-type slheader = struct
-	cap	: size	/* capacity in bytes */
-	magic	: size	/* magic check value */
-;;
-
-type bucket = struct
-	sz	: size	/* aligned size */
-	nper	: size	/* max number of elements per slab */
-	slabs	: slab#	/* partially filled or free slabs */
-	cache	: slab# /* cache of empty slabs, to prevent thrashing */
-	ncache	: size  /* size of cache */
-;;
-
-type slab = struct
-	head	: byte#	/* head of virtual addresses, so we don't leak address space */
-	next	: slab#	/* the next slab on the chain */
-	freehd	: chunk#	/* the nodes we're allocating */
-	nfree	: size	/* the number of free nodes */
-;;
-
-type chunk = struct	/* NB: must be smaller than sizeof(slab) */
-	next	: chunk#	/* the next chunk in the free list */
-;;
-
-const __init__ = {
-	var i
-
-	for i = 0; i < buckets.len && (Align << i) <= Bktmax; i++
-		bktinit(&buckets[i], Align << i)
-	;;
-}
-
-/* Allocates an object of type @a, returning a pointer to it. */
-generic alloc = {-> @a#
-	-> bytealloc(sizeof(@a)) castto(@a#)
-}
-
-generic zalloc = {-> @a#
-	-> zbytealloc(sizeof(@a)) castto(@a#)
-}
-
-/* Frees a value of type @a */
-generic free = {v:@a# -> void
-	bytefree(v castto(byte#), sizeof(@a))
-}
-
-/* allocates a slice of 'len' elements. */
-generic slalloc = {len
-	var p, sz
-
-	if len == 0
-		-> [][:]
-	;;
-	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
-	p = bytealloc(sz)
-	p = inithdr(p, sz)
-	-> (p castto(@a#))[0:len]
-}
-
-generic slzalloc = {len
-	var p, sz
-
-	if len == 0
-		-> [][:]
-	;;
-	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
-	p = zbytealloc(sz)
-	p = inithdr(p, sz)
-	-> (p castto(@a#))[0:len]
-}
-
-const inithdr = {p, sz
-	var phdr, prest
-
-	phdr = p castto(slheader#)
-	phdr.cap = allocsz(sz) - align(sizeof(slheader), Align)
-	phdr.magic = (0xdeadbeefbadf00d castto(size))
-
-	prest = (p castto(size)) + align(sizeof(slheader), Align)
-	-> prest castto(byte#)
-}
-
-const checkhdr = {p
-	var phdr, addr
-
-	addr = p castto(size)
-	addr -= align(sizeof(slheader), Align)
-	phdr = addr castto(slheader#)
-	assert(phdr.magic == (0xdeadbeefbadf00d castto(size)), "corrupt memory\n")
-}
-
-/* Frees a slice */
-generic slfree	 = {sl
-	var head
-
-	if sl.len == 0
-		->
-	;;
-
-	checkhdr(sl castto(byte#))
-	head = (sl castto(byte#)) castto(size)
-	head -= align(sizeof(slheader), Align)
-	bytefree(head castto(byte#), slcap(sl castto(byte#)))
-}
-
-/* Grows a slice */
-generic slgrow = {sl : @a[:], len
-	var i, n
-	var new
-
-	/* if the slice doesn't need a bigger bucket, we don't need to realloc. */
-	if sl.len > 0 && slcap(sl castto(byte#)) >= allocsz(len*sizeof(@a))
-		-> (sl castto(@a#))[:len]
-	;;
-
-	new = slalloc(len)
-	n = min(len, sl.len)
-	for i = 0; i < n; i++
-		new[i] = sl[i]
-	;;
-	if sl.len > 0
-		slfree(sl)
-	;;
-	-> new
-}
-
-/* Grows a slice, filling new entries with zero bytes */
-generic slzgrow = {sl : @a[:], len
-	var oldsz
-
-	oldsz = sl.len*sizeof(@a)
-	sl = slgrow(sl, len)
-	zfill((sl castto(byte#))[oldsz:len*sizeof(@a)])
-	-> sl
-}
-
-const slcap = {p
-	var phdr
-
-	phdr = (p castto(size)) - align(sizeof(slheader), Align) castto(slheader#)
-	-> phdr.cap
-}
-
-const zbytealloc = {sz
-	var p
-
-	p = bytealloc(sz)
-	zfill(p[0:sz])
-	-> p
-}
-
-const zfill = {sl
-	var i
-
-	for i = 0; i < sl.len; i++
-		sl[i] = 0
-	;;
-}
-
-/* Allocates a blob that is 'sz' bytes long. Dies if the allocation fails */
-const bytealloc = {sz
-	var bkt, p
-
-	if (sz <= Bktmax)
-		bkt = &buckets[bktnum(sz)]
-		p = bktalloc(bkt)
-	else
-		p = getmem(sz)
-		if p == Failmem
-			die("could not get memory\n")
-		;;
-	;;
-	-> p
-}
-
-/* frees a blob that is 'sz' bytes long. */
-const bytefree = {p, sz
-	var bkt
-	var b, i
-
-	b = p[:sz]
-	for i = 0; i < sz; i++
-		b[i] = 0xa8
-	;;
-	if (sz < Bktmax)
-		bkt = &buckets[bktnum(sz)]
-		bktfree(bkt, p)
-	else
-		freemem(p, sz)
-	;;
-}
-
-/* Sets up a single empty bucket */
-const bktinit = {b, sz
-	b.sz = align(sz, Align)
-	b.nper = (Slabsz - sizeof(slab))/b.sz
-	b.slabs = Zslab
-	b.cache = Zslab
-	b.ncache = 0
-}
-
-/* Creates a slab for bucket 'bkt', and fills the chunk list */
-const mkslab = {bkt
-	var i, p, s
-	var b, bnext
-	var off /* offset of chunk head */
-
-	if bkt.ncache > 0
-		s = bkt.cache
-		bkt.cache = s.next
-		bkt.ncache--
-	;;
-	/*
-	tricky: we need power of two alignment, so we allocate double the
-	needed size, chop off the unaligned ends, and waste the address
-	space. Since the OS is "smart enough", this shouldn't actually
-	cost us memory, and 64 bits of address space means that we're not
-	going to have issues with running out of address space for a
-	while. On a 32 bit system this would be a bad idea.
-	*/
-	p = getmem(Slabsz*2)
-	if p == Failmem
-		die("Unable to mmap")
-	;;
-
-	s = align(p castto(size), Slabsz) castto(slab#)
-	s.head = p
-	s.nfree = bkt.nper
-	/* skip past the slab header */
-	off = align(sizeof(slab), Align)
-	bnext = nextchunk(s castto(chunk#), off)
-	s.freehd = bnext
-	for i = 0; i < bkt.nper; i++
-		b = bnext
-		bnext = nextchunk(b, bkt.sz)
-		b.next = bnext
-	;;
-	b.next = Zchunk
-	-> s
-}
-
-/* 
-Allocates a node from bucket 'bkt', crashing if the
-allocation cannot be satisfied. Will create a new slab
-if there are no slabs on the freelist.
-*/
-const bktalloc = {bkt
-	var s
-	var b
-
-	/* find a slab */
-	s = bkt.slabs
-	if s == Zslab
-		s = mkslab(bkt)
-		if s == Zslab
-			die("No memory left")
-		;;
-		bkt.slabs = s
-	;;
-
-	/* grab the first chunk on the slab */
-	b = s.freehd
-	s.freehd = b.next
-	s.nfree--
-	if s.nfree == 0
-		bkt.slabs = s.next
-		s.next = Zslab
-	;;
-
-	-> b castto(byte#)
-}
-
-/*
-Frees a chunk of memory 'm' into bucket 'bkt'.
-Assumes that the memory already came from a slab
-that was created for bucket 'bkt'. Will crash
-if this is not the case.
-*/
-const bktfree = {bkt, m
-	var s, b
-
-	s = mtrunc(m, Slabsz) castto(slab#)
-	b = m castto(chunk#)
-	if s.nfree == 0
-		s.next = bkt.slabs
-		bkt.slabs = s
-	elif s.nfree == bkt.nper
-		/*
-		HACK HACK HACK: if we can't unmap, keep an infinite cache per slab size.
-		We should solve this better somehow.
-		*/
-		if bkt.ncache < Cachemax || !Canunmap
-			s.next = bkt.cache
-			bkt.cache = s
-		else
-			/* we mapped 2*Slabsz so we could align it,
-			 so we need to unmap the same */
-			freemem(s.head, Slabsz*2)
-		;;
-	;;
-	s.nfree++
-	b.next = s.freehd
-	s.freehd = b
-}
-
-/*
-Finds the correct bucket index to allocate from
-for allocations of size 'sz'
-*/
-const bktnum = {sz
-	var i, bktsz
-
-	bktsz = Align
-	for i = 0; bktsz <= Bktmax; i++
-		if bktsz >= sz
-			-> i
-		;;
-		bktsz *= 2
-	;;
-	die("Size does not match any buckets")
-}
-
-/*
-returns the actual size we allocated for a given
-size request
-*/
-const allocsz = {sz
-	var i, bktsz
-
-	if sz <= Bktmax
-		bktsz = Align
-		for i = 0; bktsz <= Bktmax; i++
-			if bktsz >= sz
-				-> bktsz
-			;;
-			bktsz *= 2
-		;;
-	else
-		-> align(sz, Pagesz)
-	;;
-	die("Size does not match any buckets")
-}
-
-/*
-aligns a size to a requested alignment.
-'align' must be a power of two
-*/
-const align = {v, align
-	-> (v + align - 1) & ~(align - 1)
-}
-
-/*
-chunks are variable sizes, so we can't just
-index to get to the next one
-*/
-const nextchunk = {b, sz : size
-	-> ((b castto(intptr)) + (sz castto(intptr))) castto(chunk#)
-}
-
-/*
-truncates a pointer to 'align'. 'align' must
-be a power of two.
-*/
-const mtrunc = {m, align
-	-> ((m castto(intptr)) & ~((align castto(intptr)) - 1)) castto(byte#)
-}
--- a/libstd/bigint.myr
+++ /dev/null
@@ -1,742 +1,0 @@
-use "alloc.use"
-use "chartype.use"
-use "cmp.use"
-use "die.use"
-use "extremum.use"
-use "hasprefix.use"
-use "option.use"
-use "slcp.use"
-use "sldup.use"
-use "slfill.use"
-use "slpush.use"
-use "types.use"
-use "utf.use"
-use "errno.use"
-
-pkg std =
-	type bigint = struct
-		dig	: uint32[:] 	/* little endian, no leading zeros. */
-		sign	: int		/* -1 for -ve, 0 for zero, 1 for +ve. */
-	;;
-
-	/* administrivia */
-	generic mkbigint	: (v : @a::(numeric,integral) -> bigint#)
-	const bigfree	: (a : bigint# -> void)
-	const bigdup	: (a : bigint# -> bigint#)
-	const bigassign	: (d : bigint#, s : bigint# -> bigint#)
-	const bigmove	: (d : bigint#, s : bigint# -> bigint#)
-	const bigparse	: (s : byte[:] -> option(bigint#))
-	const bigclear	: (a : bigint# -> bigint#)
-	const bigbfmt	: (b : byte[:], a : bigint#, base : int -> size)
-	/*
-	const bigtoint	: (a : bigint#	-> @a::(numeric,integral))
-	*/
-
-	/* some useful predicates */
-	const bigiszero	: (a : bigint# -> bool)
-	const bigeq	: (a : bigint#, b : bigint# -> bool)
-	generic bigeqi	: (a : bigint#, b : @a::(numeric,integral) -> bool)
-	const bigcmp	: (a : bigint#, b : bigint# -> order)
-
-	/* bigint*bigint -> bigint ops */
-	const bigadd	: (a : bigint#, b : bigint# -> bigint#)
-	const bigsub	: (a : bigint#, b : bigint# -> bigint#)
-	const bigmul	: (a : bigint#, b : bigint# -> bigint#)
-	const bigdiv	: (a : bigint#, b : bigint# -> bigint#)
-	const bigmod	: (a : bigint#, b : bigint# -> bigint#)
-	const bigdivmod	: (a : bigint#, b : bigint# -> (bigint#, bigint#))
-	const bigshl	: (a : bigint#, b : bigint# -> bigint#)
-	const bigshr	: (a : bigint#, b : bigint# -> bigint#)
-	const bigmodpow	: (b : bigint#, e : bigint#, m : bigint# -> bigint#)
-	/*
-	const bigpow	: (a : bigint#, b : bigint# -> bigint#)
-	*/
-
-	/* bigint*int -> bigint ops */
-	generic bigaddi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	generic bigsubi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	generic bigmuli	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	generic bigdivi	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	generic bigshli	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	generic bigshri	: (a : bigint#, b : @a::(integral,numeric) -> bigint#)
-	/*
-	const bigpowi	: (a : bigint#, b : uint64 -> bigint#)
-	*/
-;;
-
-const Base = 0x100000000ul
-generic mkbigint = {v : @a::(integral,numeric)
-	var a
-	var val
-
-	a = zalloc()
-
-	if v < 0
-		a.sign = -1
-		v = -v
-	elif v > 0
-		a.sign = 1
-	;;
-	val = v castto(uint64)
-	a.dig = slpush([][:], val castto(uint32))
-	if val > Base
-		a.dig = slpush(a.dig, (val/Base) castto(uint32))
-	;;
-	-> trim(a)
-}
-
-const bigfree = {a
-	slfree(a.dig)
-	free(a)
-}
-
-const bigdup = {a
-	-> bigassign(zalloc(), a)
-}
-
-const bigassign = {d, s
-	slfree(d.dig)
-	d# = s#
-	d.dig = sldup(s.dig)
-	-> d
-}
-
-const bigmove = {d, s
-	slfree(d.dig)
-	d# = s#
-	s.dig = [][:]
-	s.sign = 0
-	-> d
-}
-
-const bigclear = {v
-	std.slfree(v.dig)
-	v.sign = 0
-	v.dig = [][:]
-	-> v
-}
-
-/* for now, just dump out something for debugging... */
-const bigbfmt = {buf, x, base
-	const digitchars = [
-	'0','1','2','3','4','5','6','7','8','9',
-	'a','b','c','d','e','f', 'g', 'h', 'i', 'j',
-	'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
-	't', 'u', 'v', 'w', 'x', 'y', 'z']
-	var v, val
-	var n, i
-	var tmp, rem, b
-
-	if base < 0 || base > 36
-		die("invalid base in bigbfmt\n")
-	;;
-
-	if bigiszero(x)
-		n
-	;;
-
-	if base == 0
-		b = mkbigint(10)
-	else
-		b = mkbigint(base)
-	;;
-	n = 0
-	val = bigdup(x)
-	/* generate the digits in reverse order */
-	while !bigiszero(val)
-		(v, rem) = bigdivmod(val, b)
-		if rem.dig.len > 0
-			n += encode(buf[n:], digitchars[rem.dig[0]])
-		else
-			n += encode(buf[n:], '0')
-		;;
-		bigfree(val)
-		bigfree(rem)
-		val = v
-	;;
-	bigfree(val)
-	bigfree(b)
-
-	/* this is done last, so we get things right when we reverse the string */
-	if x.sign == 0
-		n += encode(buf[n:], '0')
-	elif x.sign == -1
-		n += encode(buf[n:], '-')
-	;;
-
-	/* we only generated ascii digits, so this works for reversing. */
-	for i = 0; i < n/2; i++
-		tmp = buf[i]
-		buf[i] = buf[n - i - 1]
-		buf[n - i - 1] = tmp
-	;;
-	-> n
-}
-
-const bigparse = {str
-	var c, val : int, base
-	var v, b
-	var a
-
-	if hasprefix(str, "0x") || hasprefix(str, "0X")
-		base = 16
-	elif hasprefix(str, "0o") || hasprefix(str, "0O")
-		base = 8
-	elif hasprefix(str, "0b") || hasprefix(str, "0B")
-		base = 2
-	else
-		base = 10
-	;;
-	if base != 10
-		str = str[2:]
-	;;
-
-	a = mkbigint(0)
-	b = mkbigint(base)
-	/*
-	 efficiency hack: to save allocations,
-	 just mutate v[0]. The value will always
-	 fit in one digit.
-	 */
-	v = mkbigint(1)
-	while str.len != 0
-		(c, str) = striter(str)
-		if c == '_'
-			continue
-		;;
-		val = charval(c, base)
-		if val < 0 || val > base
-			bigfree(a)
-			bigfree(b)
-			bigfree(v)
-			-> `None
-		;;
-		v.dig[0] = val castto(uint32)
-		if val == 0
-			v.sign = 0
-		else
-			v.sign = 1
-		;;
-		bigmul(a, b)
-		bigadd(a, v)
-
-	;;
-	-> `Some a
-}
-
-const bigiszero = {v
-	-> v.dig.len == 0
-}
-
-const bigeq = {a, b
-	var i
-
-	if a.sign != b.sign || a.dig.len != b.dig.len
-		-> false
-	;;
-	for i = 0; i < a.dig.len; i++
-		if a.dig[i] != b.dig[i]
-			-> false
-		;;
-	;;
-	-> true
-}
-
-generic bigeqi = {a, b
-	var v
-	var dig : uint32[2]
-
-	bigdigit(&v, b < 0, b castto(uint64), dig[:])
-	-> bigeq(a, &v)
-}
-
-const bigcmp = {a, b
-	var i
-	var da, db, sa, sb
-
-	sa = a.sign castto(int64)
-	sb = b.sign castto(int64)
-	if sa < sb
-		-> `Before
-	elif sa > sb
-		-> `After
-	elif a.dig.len < b.dig.len
-		-> signedorder(-sa)
-	elif a.dig.len > b.dig.len
-		-> signedorder(sa)
-	else
-		/* otherwise, the one with the first larger digit is bigger */
-		for i = a.dig.len; i > 0; i--
-			da = a.dig[i - 1] castto(int64)
-			db = b.dig[i - 1] castto(int64)
-			-> signedorder(sa * (da - db))
-		;;
-	;;
-	-> `Equal
-}
-
-const signedorder = {sign
-	if sign < 0
-		-> `Before 
-	elif sign == 0
-		-> `Equal
-	else
-		-> `After
-	;;
-}
-
-/* a += b */
-const bigadd = {a, b
-	if a.sign == b.sign || a.sign == 0 
-		a.sign = b.sign
-		-> uadd(a, b)
-	elif b.sign == 0
-		-> a
-	else
-		match bigcmp(a, b)
-		| `Before: /* a is negative */
-		    a.sign = b.sign
-		    -> usub(b, a)
-		| `After: /* b is negative */
-		    -> usub(a, b)
-		| `Equal:
-			die("Impossible. Equal vals with different sign.")
-		;;
-	;;
-}
-
-/* adds two unsigned values together. */
-const uadd = {a, b
-	var v, i
-	var carry
-	var n
-
-	carry = 0
-	n = max(a.dig.len, b.dig.len)
-	/* guaranteed to carry no more than one value */
-	a.dig = slzgrow(a.dig, n + 1)
-	for i = 0; i < n; i++
-		v = (a.dig[i] castto(uint64)) + carry;
-		if i < b.dig.len
-			v += (b.dig[i] castto(uint64))
-		;;
-
-		if v >= Base
-			carry = 1
-		else
-			carry = 0
-		;;
-		a.dig[i] = v castto(uint32)
-	;;
-	a.dig[i] += carry castto(uint32)
-	-> trim(a)
-}
-
-/* a -= b */
-const bigsub = {a, b
-	/* 0 - x = -x */
-	if a.sign == 0
-		bigassign(a, b)
-		a.sign = -b.sign
-		-> a
-	/* x - 0 = x */
-	elif b.sign == 0
-		-> a
-	elif a.sign != b.sign
-		-> uadd(a, b)
-	else
-		match bigcmp(a, b)
-		| `Before: /* a is negative */
-		    a.sign = b.sign
-		    -> usub(b, a)
-		| `After: /* b is negative */
-		    -> usub(a, b)
-		| `Equal:
-		    -> bigclear(a)
-		;;
-	;;
-	-> a
-}
-
-/* subtracts two unsigned values, where 'a' is strictly greater than 'b' */
-const usub = {a, b
-	var carry
-	var v, i
-
-	carry = 0
-	for i = 0; i < a.dig.len; i++
-		v = (a.dig[i] castto(int64)) - carry
-		if i < b.dig.len
-			v -= (b.dig[i] castto(int64)) 
-		;;
-		if v < 0
-			carry = 1
-		else
-			carry = 0
-		;;
-		a.dig[i] = v castto(uint32)
-	;;
-	-> trim(a)
-}
-
-/* a *= b */
-const bigmul = {a, b
-	var i, j
-	var ai, bj, wij
-	var carry, t
-	var w
-
-	if a.sign == 0 || b.sign == 0
-		a.sign = 0
-		slfree(a.dig)
-		a.dig = [][:]
-		-> a
-	elif a.sign != b.sign
-		a.sign = -1
-	else
-		a.sign = 1
-	;;
-	w  = slzalloc(a.dig.len + b.dig.len)
-	for j = 0; j < b.dig.len; j++
-		carry = 0
-		for i = 0; i < a.dig.len; i++
-			ai = a.dig[i] castto(uint64)
-			bj = b.dig[j] castto(uint64)
-			wij = w[i+j] castto(uint64)
-			t = ai * bj + wij + carry
-			w[i + j] = (t castto(uint32))
-			carry = t >> 32
-		;;
-		w[i+j] = carry castto(uint32)
-	;;
-	slfree(a.dig)
-	a.dig = w
-	-> trim(a)
-}
-
-const bigdiv = {a : bigint#, b : bigint# -> bigint#
-	var q, r
-
-	(q, r) = bigdivmod(a, b)
-	bigfree(r)
-	-> bigmove(a, q)
-}
-const bigmod = {a : bigint#, b : bigint# -> bigint#
-	var q, r
-
-	(q, r) = bigdivmod(a, b)
-	bigfree(q)
-	-> bigmove(a, r)
-}
-
-/* a /= b */
-const bigdivmod = {a : bigint#, b : bigint# -> (bigint#, bigint#)
-	/*
-	Implements bigint division using Algorithm D from
-	Knuth: Seminumerical algorithms, Section 4.3.1.
-	*/
-	var m : int64, n : int64
-	var qhat, rhat, carry, shift
-	var x, y, z, w, p, t /* temporaries */
-	var b0, aj
-	var u, v
-	var i, j : int64
-	var q
-
-	if bigiszero(b)
-		die("divide by zero\n")
-	;;
-	/* if b > a, we trucate to 0, with remainder 'a' */
-	if a.dig.len < b.dig.len
-		-> (mkbigint(0), bigdup(a))
-	;;
-
-	q = zalloc()
-	q.dig = slzalloc(max(a.dig.len, b.dig.len) + 1)
-	if a.sign != b.sign
-		q.sign = -1
-	else
-		q.sign = 1
-	;;
-
-	/* handle single digit divisor separately: the knuth algorithm needs at least 2 digits. */
-	if b.dig.len == 1
-		carry = 0
-		b0 = (b.dig[0] castto(uint64))
-		for j = a.dig.len; j > 0; j--
-			aj = (a.dig[j - 1] castto(uint64))
-			q.dig[j - 1] = (((carry << 32) + aj)/b0) castto(uint32)
-			carry = (carry << 32) + aj - (q.dig[j-1] castto(uint64))*b0
-		;;
-		q = trim(q)
-		-> (q, trim(mkbigint(carry castto(int32))))
-	;;
-
-	u = bigdup(a)
-	v = bigdup(b)
-	m = u.dig.len
-	n = v.dig.len
-
-	shift = nlz(v.dig[n - 1])
-	bigshli(u, shift)
-	bigshli(v, shift)
-	u.dig = slzgrow(u.dig, u.dig.len + 1)
-
-	for j = m - n; j >= 0; j--
-		/* load a few temps */
-		x = u.dig[j + n] castto(uint64)
-		y = u.dig[j + n - 1] castto(uint64)
-		z = v.dig[n - 1] castto(uint64)
-		w = v.dig[n - 2] castto(uint64)
-		t = u.dig[j + n - 2] castto(uint64)
-
-		/* estimate qhat */
-		qhat = (x*Base + y)/z
-		rhat = (x*Base + y) - qhat*z
-:divagain
-		if qhat >= Base || (qhat * w) > (rhat*Base + t)
-			qhat--
-			rhat += z
-			if rhat < Base
-				goto divagain
-			;;
-		;;
-
-		/* multiply and subtract */
-		carry = 0
-		for i = 0; i < n; i++
-			p = qhat * (v.dig[i] castto(uint64))
-
-			t = (u.dig[i+j] castto(uint64)) - carry - (p % Base)
-			u.dig[i+j] = t castto(uint32)
-
-			carry = (((p castto(int64)) >> 32) - ((t castto(int64)) >> 32)) castto(uint64);
-		;;
-		t = (u.dig[j + n] castto(uint64)) - carry
-		u.dig[j + n] = t castto(uint32)
-		q.dig[j] = qhat castto(uint32)
-		/* adjust */
-		if t castto(int64) < 0
-			q.dig[j]--
-			carry = 0
-			for i = 0; i < n; i++
-				t = (u.dig[i+j] castto(uint64)) + (v.dig[i] castto(uint64)) + carry
-				u.dig[i+j] = t castto(uint32)
-				carry = t >> 32
-			;;
-			u.dig[j+n] = u.dig[j+n] + (carry castto(uint32));
-		;;
-
-	;;
-	/* undo the biasing for remainder */
-	u = bigshri(u, shift)
-	-> (trim(q), trim(u))
-}
-
-/* computes b^e % m */
-const bigmodpow = {base, exp, mod
-	var r, n
-
-	r = mkbigint(1)
-	n = 0
-    	while !bigiszero(exp)
-		if (exp.dig[0] & 1) != 0
-			bigmul(r, base)
-			bigmod(r, mod)
-		;;
-		bigshri(exp, 1)
-		bigmul(base, base)
-		bigmod(base, mod)
-	;;
-	-> bigmove(base, r)
-}
-
-/* returns the number of leading zeros */
-const nlz = {a : uint32
-	var n
-
-	if a == 0
-		-> 32
-	;;
-	n = 0
-	if a <= 0x0000ffff
-		n += 16
-		a <<= 16
-	;;
-	if a <= 0x00ffffff
-		n += 8
-		a <<= 8
-	;;
-	if a <= 0x0fffffff
-		n += 4
-		a <<= 4
-	;;
-	if a <= 0x3fffffff
-		n += 2
-		a <<= 2
-	;;
-	if a <= 0x7fffffff
-		n += 1
-		a <<= 1
-	;;
-	-> n
-}
-
-
-/* a <<= b */
-const bigshl = {a, b
-	match b.dig.len
-	| 0:	-> a
-	| 1:	-> bigshli(a, b.dig[0] castto(uint64))
-	| n:	die("shift by way too much\n")
-	;;
-}
-
-/* a >>= b, unsigned */
-const bigshr = {a, b
-	match b.dig.len
-	| 0:	-> a
-	| 1:	-> bigshri(a, b.dig[0] castto(uint64))
-	| n:	die("shift by way too much\n")
-	;;
-}
-
-/* a + b, b is integer.
-FIXME: acually make this a performace improvement
-*/
-generic bigaddi = {a, b
-	var bigb : bigint
-	var dig : uint32[2]
-
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
-	bigadd(a, &bigb)
-	-> a
-}
-
-generic bigsubi = {a, b : @a::(numeric,integral)
-	var bigb : bigint
-	var dig : uint32[2]
-
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
-	bigsub(a, &bigb)
-	-> a
-}
-
-generic bigmuli = {a, b
-	var bigb : bigint
-	var dig : uint32[2]
-
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
-	bigmul(a, &bigb)
-	-> a
-}
-
-generic bigdivi = {a, b
-	var bigb : bigint
-	var dig : uint32[2]
-
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
-	bigdiv(a, &bigb)
-	-> a
-}
-
-/* 
-  a << s, with integer arg.
-  logical left shift. any other type would be illogical.
- */
-generic bigshli = {a, s : @a::(numeric,integral)
-	var off, shift
-	var t, carry
-	var i
-
-	assert(s >= 0, "shift amount must be positive")
-	off = (s castto(uint64)) / 32
-	shift = (s castto(uint64)) % 32
-
-	/* zero shifted by anything is zero */
-	if a.sign == 0
-		-> a
-	;;
-	a.dig = slzgrow(a.dig, 1 + a.dig.len + off castto(size))
-	/* blit over the base values */
-	for i = a.dig.len; i > off; i--
-		a.dig[i - 1] = a.dig[i - 1 - off]
-	;;
-	for i = 0; i < off; i++
-		a.dig[i] = 0
-	;;
-	/* and shift over by the remainder */
-	carry = 0
-	for i = 0; i < a.dig.len; i++
-		t = (a.dig[i] castto(uint64)) << shift
-		a.dig[i] = (t | carry) castto(uint32) 
-		carry = t >> 32
-	;;
-	-> trim(a)
-}
-
-/* logical shift right, zero fills. sign remains untouched. */
-generic bigshri = {a, s
-	var off, shift
-	var t, carry
-	var i
-
-	assert(s >= 0, "shift amount must be positive")
-	off = (s castto(uint64)) / 32
-	shift = (s castto(uint64)) % 32
-
-	/* blit over the base values */
-	for i = 0; i < a.dig.len - off; i++
-		a.dig[i] = a.dig[i + off]
-	;;
-	for i = a.dig.len - off; i < a.dig.len; i++
-		a.dig[i] = 0
-	;;
-	/* and shift over by the remainder */
-	carry = 0
-	for i = a.dig.len; i > 0; i--
-		t = (a.dig[i - 1] castto(uint64))
-		a.dig[i - 1] = (carry | (t >> shift)) castto(uint32) 
-		carry = t << (32 - shift)
-	;;
-	-> trim(a)
-}
-
-/* creates a bigint on the stack; should not be modified. */
-const bigdigit = {v, isneg : bool, val : uint64, dig
-	v.sign = 1
-	if isneg
-		val = -val
-		v.sign = -1
-	;;
-	if val == 0
-		v.sign = 0
-		v.dig = [][:]
-	elif val < Base
-		v.dig = dig[:1]
-		v.dig[0] = val castto(uint32)
-	else
-		v.dig = dig
-		v.dig[0] = val castto(uint32)
-		v.dig[1] = (val >> 32) castto(uint32)
-	;;
-}
-
-/* trims leading zeros */
-const trim = {a
-	var i
-
-	for i = a.dig.len; i > 0; i--
-		if a.dig[i - 1] != 0
-			break
-		;;
-	;;
-	a.dig = slgrow(a.dig, i)
-	if i == 0
-		a.sign = 0
-	elif a.sign == 0
-		a.sign = 1
-	;;
-	-> a
-}
-
--- a/libstd/bitset.myr
+++ /dev/null
@@ -1,155 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "mk.use"
-use "slcp.use"
-use "sldup.use"
-use "slfill.use"
-use "types.use"
-
-pkg std =
-	type bitset = struct
-		bits : size[:]
-	;;
-
-	const mkbs	: (-> bitset#)
-	const bsdup	: (bs : bitset# -> bitset#)
-	const bsfree	: (bs : bitset# -> void)
-
-	const bsmax	: (a : bitset# -> size)
-
-	generic bsput	: (bs : bitset#, v : @a::(integral,numeric) -> void)
-	generic bsdel	: (bs : bitset#, v : @a::(integral,numeric) -> void)
-	generic bshas	: (bs : bitset#, v : @a::(integral,numeric) -> bool)
-
-	const bsdiff	: (a : bitset#, b : bitset# -> void)
-	const bsintersect	: (a : bitset#, b : bitset# -> void)
-	const bsunion	: (a : bitset#, b : bitset# -> void)
-	const bseq	: (a : bitset#, b : bitset# -> bool)
-	const bsissubset	: (a : bitset#, b : bitset# -> bool)
-
-
-	const bsclear	: (bs : bitset# -> bitset#)
-;;
-
-const mkbs = {
-	-> zalloc()
-}
-
-const bsdup = {bs
-	-> mk([.bits=sldup(bs.bits)])
-}
-
-const bsfree = {bs
-	slfree(bs.bits)
-	free(bs)
-}
-
-const bsclear = {bs
-	slfill(bs.bits, 0)
-	-> bs
-}
-
-const bsmax = {bs
-	-> bs.bits.len * sizeof(size) * 8
-}
-
-generic bsput = {bs, v
-	var idx
-	var off
-
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
-	ensurelen(bs, idx)
-	bs.bits[idx] |= (1 << off)
-}
-
-generic bsdel = {bs, v
-	var idx
-	var off
-
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
-	if idx >= bs.bits.len
-		->
-	;;
-	bs.bits[idx] &= ~(1 << off)
-}
-
-generic bshas = {bs, v
-	var idx
-	var off
-
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
-	if idx >= bs.bits.len
-		-> false
-	;;
-	-> (bs.bits[idx] & (1 << off)) != 0
-}
-
-const bsunion = {a, b
-	var i
-
-	eqsz(a, b)
-	for i = 0; i < b.bits.len; i++
-		a.bits[i] |= b.bits[i]
-	;;
-}
-
-const bsintersect = {a, b
-	var i, n
-
-	n = min(a.bits.len, b.bits.len)
-	for i = 0; i < n; i++
-		a.bits[i] &= b.bits[i]
-	;;
-}
-
-const bsdiff = {a, b
-	var i, n
-
-	n = min(b.bits.len, a.bits.len)
-	for i = 0; i < n; i++
-		a.bits[i] &= ~b.bits[i]
-	;;
-}
-
-const bsissubset = {a, b
-	var i
-
-	eqsz(a, b);
-	for i = 0; i < a.bits.len; i++
-		if (b.bits[i] & a.bits[i]) != b.bits[i]
-			-> false
-		;;
-	;;
-	-> true
-}
-
-const bseq = {a, b
-	var i
-
-	eqsz(a, b)
-	for i = 0; i < a.bits.len; i++
-		if a.bits[i] != b.bits[i]
-			-> false
-		;;
-	;;
-	-> true
-}
-
-const ensurelen = {bs, len
-	if bs.bits.len <= len
-		bs.bits = slzgrow(bs.bits, len + 1)
-	;;
-}
-
-const eqsz = {a, b
-	var sz
-
-	sz = max(a.bits.len, b.bits.len)
-	ensurelen(a, sz)
-	ensurelen(b, sz)
-}
-
--- a/libstd/blat.myr
+++ /dev/null
@@ -1,32 +1,0 @@
-use "syswrap.use"
-
-pkg std =
-	const blat : (path : byte[:], buf : byte[:], perm : int64 -> bool)
-	const fblat : (f : fd, buf : byte[:] -> bool)
-;;
-
-const blat = {path, buf, perm
-	var fd
-
-	fd = openmode(path, Ocreat|Owronly, perm)
-	if fd < 0
-		-> false
-	;;
-	-> fblat(fd, buf)
-}
-
-
-const fblat = {fd, buf
-	var written, n
-
-	n = 0
-	while true
-		written = write(fd, buf[n:])
-		if written <= 0
-			goto done
-		;;
-		n += written
-	;;
-:done
-	-> written == 0 && n == buf.len
-}
--- a/libstd/bld.sub
+++ /dev/null
@@ -1,103 +1,0 @@
-lib sys =
-	sys+freebsd-x64.myr
-	sys+linux-x64.myr
-	sys+osx-x64.myr
-	sys+plan9-x64.myr
-	syscall+freebsd-x64.s
-	syscall+linux-x64.s
-	syscall+osx-x64.s
-	syscall+plan9-x64.s
-	syserrno+linux.myr
-	syserrno+osx.myr
-	systypes.myr
-	ifreq+freebsd.myr
-	ifreq+linux.myr
-	ifreq+osx.myr
-	ifreq+plan9.myr
-	ifreq.myr	# dummy file: plan9 doesn't have ifreq
-	util+plan9-x64.s
-	util+posixy-x64.s
-;;
-
-lib std {inc=.} =
-	lib sys
-
-	# portable files
-	alloc.myr
-	bigint.myr
-	bitset.myr
-	blat.myr
-	chartype.myr
-	clear.myr
-	cmp.myr
-	cstrconv.myr
-	die.myr
-	dirname.myr
-	endian.myr
-	errno.myr
-	execvp.myr
-	extremum.myr
-	fltbits.myr
-	fltfmt.myr
-        fmt.myr
-	fmtfuncs.myr
-	getcwd.myr
-	getint.myr
-	hashfuncs.myr
-	hasprefix.myr
-	hassuffix.myr
-	htab.myr
-	intparse.myr
-        introspect.myr
-	ipparse.myr
-	mk.myr
-	mkpath.myr
-	now.myr
-	option.myr
-	optparse.myr
-	pathjoin.myr
-	putint.myr
-	rand.myr
-	result.myr
-	search.myr
-	slcp.myr
-	sldup.myr
-	sleq.myr
-	slfill.myr
-	sljoin.myr
-	slpush.myr
-	slput.myr
-	slurp.myr
-	sort.myr
-	spork.myr
-	strbuf.myr
-	strfind.myr
-	strjoin.myr
-	strsplit.myr
-	strstrip.myr
-	swap.myr
-	try.myr
-	types.myr
-	units.myr
-	utf.myr
-	varargs.myr
-
-	# platform specific files
-	env+plan9.myr
-	env+posixy.myr
-	errno+plan9.myr
-	dir+freebsd.myr
-	dir+linux.myr
-	dir+osx.myr
-	wait+posixy.myr
-	wait+plan9.myr
-	dial+posixy.myr
-	dial+plan9.myr
-	resolve+posixy.myr
-	resolve+plan9.myr
-	syswrap-ss+linux.myr
-	syswrap-ss+osx.myr
-	syswrap-ss+plan9.myr
-	syswrap+plan9.myr
-	syswrap+posixy.myr
-;;
--- a/libstd/build.sh
+++ /dev/null
@@ -1,8 +1,0 @@
-#!/bin/bash
-
-if [ -z "`which mbld`" ]; then
-    ../myrbuild/myrbuild -I. -C$MYR_MC -M$MYR_MUSE $@
-else
-    mbld
-fi
-
--- a/libstd/chartype.myr
+++ /dev/null
@@ -1,1242 +1,0 @@
-use "die.use"
-use "types.use"
-
-/* 
-   Tables adapted from plan 9's runetype.c,
-   which lives in sys/src/libc/port/runetype.c
-*/
-
-pkg std =
-	/* predicates */
-	const isalpha	: (c : char -> bool)
-	const isdigit	: (c : char -> bool)
-	const isxdigit	: (c : char -> bool)
-	const isnum	: (c : char -> bool)
-	const isalnum	: (c : char -> bool)
-	const isspace	: (c : char -> bool)
-	const isblank	: (c : char -> bool)
-	const islower	: (c : char -> bool)
-	const isupper	: (c : char -> bool)
-	const istitle	: (c : char -> bool)
-
-	/* transforms */
-	const tolower	: (c : char -> char)
-	const toupper	: (c : char -> char)
-	const totitle	: (c : char -> char)
-
-	generic charval : (c : char, base : int -> @a::(integral,numeric))
-;;
-
-extern const put	: (fmt : byte[:], args : ... -> size)
-
-/*
- * alpha ranges -
- *	only covers ranges not in lower||upper
- */
-const ralpha2 = [
-	0x00d8,	0x00f6,	/* Ø - ö */
-	0x00f8,	0x01f5,	/* ø - ǵ */
-	0x0250,	0x02a8,	/* ɐ - ʨ */
-	0x038e,	0x03a1,	/* Ύ - Ρ */
-	0x03a3,	0x03ce,	/* Σ - ώ */
-	0x03d0,	0x03d6,	/* ϐ - ϖ */
-	0x03e2,	0x03f3,	/* Ϣ - ϳ */
-	0x0490,	0x04c4,	/* Ґ - ӄ */
-	0x0561,	0x0587,	/* ա - և */
-	0x05d0,	0x05ea,	/* א - ת */
-	0x05f0,	0x05f2,	/* װ - ײ */
-	0x0621,	0x063a,	/* ء - غ */
-	0x0640,	0x064a,	/* ـ - ي */
-	0x0671,	0x06b7,	/* ٱ - ڷ */
-	0x06ba,	0x06be,	/* ں - ھ */
-	0x06c0,	0x06ce,	/* ۀ - ێ */
-	0x06d0,	0x06d3,	/* ې - ۓ */
-	0x0905,	0x0939,	/* अ - ह */
-	0x0958,	0x0961,	/* क़ - ॡ */
-	0x0985,	0x098c,	/* অ - ঌ */
-	0x098f,	0x0990,	/* এ - ঐ */
-	0x0993,	0x09a8,	/* ও - ন */
-	0x09aa,	0x09b0,	/* প - র */
-	0x09b6,	0x09b9,	/* শ - হ */
-	0x09dc,	0x09dd,	/* ড় - ঢ় */
-	0x09df,	0x09e1,	/* য় - ৡ */
-	0x09f0,	0x09f1,	/* ৰ - ৱ */
-	0x0a05,	0x0a0a,	/* ਅ - ਊ */
-	0x0a0f,	0x0a10,	/* ਏ - ਐ */
-	0x0a13,	0x0a28,	/* ਓ - ਨ */
-	0x0a2a,	0x0a30,	/* ਪ - ਰ */
-	0x0a32,	0x0a33,	/* ਲ - ਲ਼ */
-	0x0a35,	0x0a36,	/* ਵ - ਸ਼ */
-	0x0a38,	0x0a39,	/* ਸ - ਹ */
-	0x0a59,	0x0a5c,	/* ਖ਼ - ੜ */
-	0x0a85,	0x0a8b,	/* અ - ઋ */
-	0x0a8f,	0x0a91,	/* એ - ઑ */
-	0x0a93,	0x0aa8,	/* ઓ - ન */
-	0x0aaa,	0x0ab0,	/* પ - ર */
-	0x0ab2,	0x0ab3,	/* લ - ળ */
-	0x0ab5,	0x0ab9,	/* વ - હ */
-	0x0b05,	0x0b0c,	/* ଅ - ଌ */
-	0x0b0f,	0x0b10,	/* ଏ - ଐ */
-	0x0b13,	0x0b28,	/* ଓ - ନ */
-	0x0b2a,	0x0b30,	/* ପ - ର */
-	0x0b32,	0x0b33,	/* ଲ - ଳ */
-	0x0b36,	0x0b39,	/* ଶ - ହ */
-	0x0b5c,	0x0b5d,	/* ଡ଼ - ଢ଼ */
-	0x0b5f,	0x0b61,	/* ୟ - ୡ */
-	0x0b85,	0x0b8a,	/* அ - ஊ */
-	0x0b8e,	0x0b90,	/* எ - ஐ */
-	0x0b92,	0x0b95,	/* ஒ - க */
-	0x0b99,	0x0b9a,	/* ங - ச */
-	0x0b9e,	0x0b9f,	/* ஞ - ட */
-	0x0ba3,	0x0ba4,	/* ண - த */
-	0x0ba8,	0x0baa,	/* ந - ப */
-	0x0bae,	0x0bb5,	/* ம - வ */
-	0x0bb7,	0x0bb9,	/* ஷ - ஹ */
-	0x0c05,	0x0c0c,	/* అ - ఌ */
-	0x0c0e,	0x0c10,	/* ఎ - ఐ */
-	0x0c12,	0x0c28,	/* ఒ - న */
-	0x0c2a,	0x0c33,	/* ప - ళ */
-	0x0c35,	0x0c39,	/* వ - హ */
-	0x0c60,	0x0c61,	/* ౠ - ౡ */
-	0x0c85,	0x0c8c,	/* ಅ - ಌ */
-	0x0c8e,	0x0c90,	/* ಎ - ಐ */
-	0x0c92,	0x0ca8,	/* ಒ - ನ */
-	0x0caa,	0x0cb3,	/* ಪ - ಳ */
-	0x0cb5,	0x0cb9,	/* ವ - ಹ */
-	0x0ce0,	0x0ce1,	/* ೠ - ೡ */
-	0x0d05,	0x0d0c,	/* അ - ഌ */
-	0x0d0e,	0x0d10,	/* എ - ഐ */
-	0x0d12,	0x0d28,	/* ഒ - ന */
-	0x0d2a,	0x0d39,	/* പ - ഹ */
-	0x0d60,	0x0d61,	/* ൠ - ൡ */
-	0x0e01,	0x0e30,	/* ก - ะ */
-	0x0e32,	0x0e33,	/* า - ำ */
-	0x0e40,	0x0e46,	/* เ - ๆ */
-	0x0e5a,	0x0e5b,	/* ๚ - ๛ */
-	0x0e81,	0x0e82,	/* ກ - ຂ */
-	0x0e87,	0x0e88,	/* ງ - ຈ */
-	0x0e94,	0x0e97,	/* ດ - ທ */
-	0x0e99,	0x0e9f,	/* ນ - ຟ */
-	0x0ea1,	0x0ea3,	/* ມ - ຣ */
-	0x0eaa,	0x0eab,	/* ສ - ຫ */
-	0x0ead,	0x0eae,	/* ອ - ຮ */
-	0x0eb2,	0x0eb3,	/* າ - ຳ */
-	0x0ec0,	0x0ec4,	/* ເ - ໄ */
-	0x0edc,	0x0edd,	/* ໜ - ໝ */
-	0x0f18,	0x0f19,	/* ༘ - ༙ */
-	0x0f40,	0x0f47,	/* ཀ - ཇ */
-	0x0f49,	0x0f69,	/* ཉ - ཀྵ */
-	0x10d0,	0x10f6,	/* ა - ჶ */
-	0x1100,	0x1159,	/* ᄀ - ᅙ */
-	0x115f,	0x11a2,	/* ᅟ - ᆢ */
-	0x11a8,	0x11f9,	/* ᆨ - ᇹ */
-	0x1e00,	0x1e9b,	/* Ḁ - ẛ */
-	0x1f50,	0x1f57,	/* ὐ - ὗ */
-	0x1f80,	0x1fb4,	/* ᾀ - ᾴ */
-	0x1fb6,	0x1fbc,	/* ᾶ - ᾼ */
-	0x1fc2,	0x1fc4,	/* ῂ - ῄ */
-	0x1fc6,	0x1fcc,	/* ῆ - ῌ */
-	0x1fd0,	0x1fd3,	/* ῐ - ΐ */
-	0x1fd6,	0x1fdb,	/* ῖ - Ί */
-	0x1fe0,	0x1fec,	/* ῠ - Ῥ */
-	0x1ff2,	0x1ff4,	/* ῲ - ῴ */
-	0x1ff6,	0x1ffc,	/* ῶ - ῼ */
-	0x210a,	0x2113,	/* ℊ - ℓ */
-	0x2115,	0x211d,	/* ℕ - ℝ */
-	0x2120,	0x2122,	/* ℠ - ™ */
-	0x212a,	0x2131,	/* K - ℱ */
-	0x2133,	0x2138,	/* ℳ - ℸ */
-	0x3041,	0x3094,	/* ぁ - ゔ */
-	0x30a1,	0x30fa,	/* ァ - ヺ */
-	0x3105,	0x312c,	/* ㄅ - ㄬ */
-	0x3131,	0x318e,	/* ㄱ - ㆎ */
-	0x3192,	0x319f,	/* ㆒ - ㆟ */
-	0x3260,	0x327b,	/* ㉠ - ㉻ */
-	0x328a,	0x32b0,	/* ㊊ - ㊰ */
-	0x32d0,	0x32fe,	/* ㋐ - ㋾ */
-	0x3300,	0x3357,	/* ㌀ - ㍗ */
-	0x3371,	0x3376,	/* ㍱ - ㍶ */
-	0x337b,	0x3394,	/* ㍻ - ㎔ */
-	0x3399,	0x339e,	/* ㎙ - ㎞ */
-	0x33a9,	0x33ad,	/* ㎩ - ㎭ */
-	0x33b0,	0x33c1,	/* ㎰ - ㏁ */
-	0x33c3,	0x33c5,	/* ㏃ - ㏅ */
-	0x33c7,	0x33d7,	/* ㏇ - ㏗ */
-	0x33d9,	0x33dd,	/* ㏙ - ㏝ */
-	0x4e00,	0x9fff,	/* 一 - 鿿 */
-	0xac00,	0xd7a3,	/* 가 - 힣 */
-	0xf900,	0xfb06,	/* 豈 - st */
-	0xfb13,	0xfb17,	/* ﬓ - ﬗ */
-	0xfb1f,	0xfb28,	/* ײַ - ﬨ */
-	0xfb2a,	0xfb36,	/* שׁ - זּ */
-	0xfb38,	0xfb3c,	/* טּ - לּ */
-	0xfb40,	0xfb41,	/* נּ - סּ */
-	0xfb43,	0xfb44,	/* ףּ - פּ */
-	0xfb46,	0xfbb1,	/* צּ - ﮱ */
-	0xfbd3,	0xfd3d,	/* ﯓ - ﴽ */
-	0xfd50,	0xfd8f,	/* ﵐ - ﶏ */
-	0xfd92,	0xfdc7,	/* ﶒ - ﷇ */
-	0xfdf0,	0xfdf9,	/* ﷰ - ﷹ */
-	0xfe70,	0xfe72,	/* ﹰ - ﹲ */
-	0xfe76,	0xfefc,	/* ﹶ - ﻼ */
-	0xff66,	0xff6f,	/* ヲ - ッ */
-	0xff71,	0xff9d,	/* ア - ン */
-	0xffa0,	0xffbe,	/* ᅠ - ᄒ */
-	0xffc2,	0xffc7,	/* ᅡ - ᅦ */
-	0xffca,	0xffcf,	/* ᅧ - ᅬ */
-	0xffd2,	0xffd7,	/* ᅭ - ᅲ */
-	0xffda,	0xffdc	/* ᅳ - ᅵ */
-]
-
-/*
- * alpha singlets -
- *	only covers ranges not in lower||upper
- */
-const ralpha1 = [
-	0x00aa,	/* ª */
-	0x00b5,	/* µ */
-	0x00ba,	/* º */
-	0x03da,	/* Ϛ */
-	0x03dc,	/* Ϝ */
-	0x03de,	/* Ϟ */
-	0x03e0,	/* Ϡ */
-	0x06d5,	/* ە */
-	0x09b2,	/* ল */
-	0x0a5e,	/* ਫ਼ */
-	0x0a8d,	/* ઍ */
-	0x0ae0,	/* ૠ */
-	0x0b9c,	/* ஜ */
-	0x0cde,	/* ೞ */
-	0x0e4f,	/* ๏ */
-	0x0e84,	/* ຄ */
-	0x0e8a,	/* ຊ */
-	0x0e8d,	/* ຍ */
-	0x0ea5,	/* ລ */
-	0x0ea7,	/* ວ */
-	0x0eb0,	/* ະ */
-	0x0ebd,	/* ຽ */
-	0x1fbe,	/* ι */
-	0x207f,	/* ⁿ */
-	0x20a8,	/* ₨ */
-	0x2102,	/* ℂ */
-	0x2107,	/* ℇ */
-	0x2124,	/* ℤ */
-	0x2126,	/* Ω */
-	0x2128,	/* ℨ */
-	0xfb3e,	/* מּ */
-	0xfe74	/* ﹴ */
-]
-
-/*
- * space ranges
- */
-const rspace2 = [
-	0x0009,	0x0009,	/* tab */
-	0x0020,	0x0020,	/* space */
-	0x0085, 0x0085,
-	0x00a0,	0x00a0,	/*   */
-	0x1680, 0x1680,
-	0x180e, 0x180e,
-	0x2000,	0x200b,	/*   - ​ */
-	0x2028,	0x2029,	/* 
 - 
 */
-	0x202f, 0x202f,
-	0x205f, 0x205f,
-	0x3000,	0x3000,	/*   */
-	0xfeff,	0xfeff	/*  */
-]
-
-/*
- * lower case ranges
- *	3rd col is conversion excess 500
- */
-const rtoupper2 = [
-	0x0061,	0x007a, 468,	/* a-z A-Z */
-	0x00e0,	0x00f6, 468,	/* à-ö À-Ö */
-	0x00f8,	0x00fe, 468,	/* ø-þ Ø-Þ */
-	0x0256,	0x0257, 295,	/* ɖ-ɗ Ɖ-Ɗ */
-	0x0258,	0x0259, 298,	/* ɘ-ə Ǝ-Ə */
-	0x028a,	0x028b, 283,	/* ʊ-ʋ Ʊ-Ʋ */
-	0x03ad,	0x03af, 463,	/* έ-ί Έ-Ί */
-	0x03b1,	0x03c1, 468,	/* α-ρ Α-Ρ */
-	0x03c3,	0x03cb, 468,	/* σ-ϋ Σ-Ϋ */
-	0x03cd,	0x03ce, 437,	/* ύ-ώ Ύ-Ώ */
-	0x0430,	0x044f, 468,	/* а-я А-Я */
-	0x0451,	0x045c, 420,	/* ё-ќ Ё-Ќ */
-	0x045e,	0x045f, 420,	/* ў-џ Ў-Џ */
-	0x0561,	0x0586, 452,	/* ա-ֆ Ա-Ֆ */
-	0x1f00,	0x1f07, 508,	/* ἀ-ἇ Ἀ-Ἇ */
-	0x1f10,	0x1f15, 508,	/* ἐ-ἕ Ἐ-Ἕ */
-	0x1f20,	0x1f27, 508,	/* ἠ-ἧ Ἠ-Ἧ */
-	0x1f30,	0x1f37, 508,	/* ἰ-ἷ Ἰ-Ἷ */
-	0x1f40,	0x1f45, 508,	/* ὀ-ὅ Ὀ-Ὅ */
-	0x1f60,	0x1f67, 508,	/* ὠ-ὧ Ὠ-Ὧ */
-	0x1f70,	0x1f71, 574,	/* ὰ-ά Ὰ-Ά */
-	0x1f72,	0x1f75, 586,	/* ὲ-ή Ὲ-Ή */
-	0x1f76,	0x1f77, 600,	/* ὶ-ί Ὶ-Ί */
-	0x1f78,	0x1f79, 628,	/* ὸ-ό Ὸ-Ό */
-	0x1f7a,	0x1f7b, 612,	/* ὺ-ύ Ὺ-Ύ */
-	0x1f7c,	0x1f7d, 626,	/* ὼ-ώ Ὼ-Ώ */
-	0x1f80,	0x1f87, 508,	/* ᾀ-ᾇ ᾈ-ᾏ */
-	0x1f90,	0x1f97, 508,	/* ᾐ-ᾗ ᾘ-ᾟ */
-	0x1fa0,	0x1fa7, 508,	/* ᾠ-ᾧ ᾨ-ᾯ */
-	0x1fb0,	0x1fb1, 508,	/* ᾰ-ᾱ Ᾰ-Ᾱ */
-	0x1fd0,	0x1fd1, 508,	/* ῐ-ῑ Ῐ-Ῑ */
-	0x1fe0,	0x1fe1, 508,	/* ῠ-ῡ Ῠ-Ῡ */
-	0x2170,	0x217f, 484,	/* ⅰ-ⅿ Ⅰ-Ⅿ */
-	0x24d0,	0x24e9, 474,	/* ⓐ-ⓩ Ⓐ-Ⓩ */
-	0xff41,	0xff5a, 468	/* a-z A-Z */
-]
-
-/*
- * lower case singlets
- *	2nd col is conversion excess 500
- */
-const rtoupper1 = [
-	0x00ff, 621,	/* ÿ Ÿ */
-	0x0101, 499,	/* ā Ā */
-	0x0103, 499,	/* ă Ă */
-	0x0105, 499,	/* ą Ą */
-	0x0107, 499,	/* ć Ć */
-	0x0109, 499,	/* ĉ Ĉ */
-	0x010b, 499,	/* ċ Ċ */
-	0x010d, 499,	/* č Č */
-	0x010f, 499,	/* ď Ď */
-	0x0111, 499,	/* đ Đ */
-	0x0113, 499,	/* ē Ē */
-	0x0115, 499,	/* ĕ Ĕ */
-	0x0117, 499,	/* ė Ė */
-	0x0119, 499,	/* ę Ę */
-	0x011b, 499,	/* ě Ě */
-	0x011d, 499,	/* ĝ Ĝ */
-	0x011f, 499,	/* ğ Ğ */
-	0x0121, 499,	/* ġ Ġ */
-	0x0123, 499,	/* ģ Ģ */
-	0x0125, 499,	/* ĥ Ĥ */
-	0x0127, 499,	/* ħ Ħ */
-	0x0129, 499,	/* ĩ Ĩ */
-	0x012b, 499,	/* ī Ī */
-	0x012d, 499,	/* ĭ Ĭ */
-	0x012f, 499,	/* į Į */
-	0x0131, 268,	/* ı I */
-	0x0133, 499,	/* ij IJ */
-	0x0135, 499,	/* ĵ Ĵ */
-	0x0137, 499,	/* ķ Ķ */
-	0x013a, 499,	/* ĺ Ĺ */
-	0x013c, 499,	/* ļ Ļ */
-	0x013e, 499,	/* ľ Ľ */
-	0x0140, 499,	/* ŀ Ŀ */
-	0x0142, 499,	/* ł Ł */
-	0x0144, 499,	/* ń Ń */
-	0x0146, 499,	/* ņ Ņ */
-	0x0148, 499,	/* ň Ň */
-	0x014b, 499,	/* ŋ Ŋ */
-	0x014d, 499,	/* ō Ō */
-	0x014f, 499,	/* ŏ Ŏ */
-	0x0151, 499,	/* ő Ő */
-	0x0153, 499,	/* œ Œ */
-	0x0155, 499,	/* ŕ Ŕ */
-	0x0157, 499,	/* ŗ Ŗ */
-	0x0159, 499,	/* ř Ř */
-	0x015b, 499,	/* ś Ś */
-	0x015d, 499,	/* ŝ Ŝ */
-	0x015f, 499,	/* ş Ş */
-	0x0161, 499,	/* š Š */
-	0x0163, 499,	/* ţ Ţ */
-	0x0165, 499,	/* ť Ť */
-	0x0167, 499,	/* ŧ Ŧ */
-	0x0169, 499,	/* ũ Ũ */
-	0x016b, 499,	/* ū Ū */
-	0x016d, 499,	/* ŭ Ŭ */
-	0x016f, 499,	/* ů Ů */
-	0x0171, 499,	/* ű Ű */
-	0x0173, 499,	/* ų Ų */
-	0x0175, 499,	/* ŵ Ŵ */
-	0x0177, 499,	/* ŷ Ŷ */
-	0x017a, 499,	/* ź Ź */
-	0x017c, 499,	/* ż Ż */
-	0x017e, 499,	/* ž Ž */
-	0x017f, 200,	/* ſ S */
-	0x0183, 499,	/* ƃ Ƃ */
-	0x0185, 499,	/* ƅ Ƅ */
-	0x0188, 499,	/* ƈ Ƈ */
-	0x018c, 499,	/* ƌ Ƌ */
-	0x0192, 499,	/* ƒ Ƒ */
-	0x0199, 499,	/* ƙ Ƙ */
-	0x01a1, 499,	/* ơ Ơ */
-	0x01a3, 499,	/* ƣ Ƣ */
-	0x01a5, 499,	/* ƥ Ƥ */
-	0x01a8, 499,	/* ƨ Ƨ */
-	0x01ad, 499,	/* ƭ Ƭ */
-	0x01b0, 499,	/* ư Ư */
-	0x01b4, 499,	/* ƴ Ƴ */
-	0x01b6, 499,	/* ƶ Ƶ */
-	0x01b9, 499,	/* ƹ Ƹ */
-	0x01bd, 499,	/* ƽ Ƽ */
-	0x01c5, 499,	/* Dž DŽ */
-	0x01c6, 498,	/* dž DŽ */
-	0x01c8, 499,	/* Lj LJ */
-	0x01c9, 498,	/* lj LJ */
-	0x01cb, 499,	/* Nj NJ */
-	0x01cc, 498,	/* nj NJ */
-	0x01ce, 499,	/* ǎ Ǎ */
-	0x01d0, 499,	/* ǐ Ǐ */
-	0x01d2, 499,	/* ǒ Ǒ */
-	0x01d4, 499,	/* ǔ Ǔ */
-	0x01d6, 499,	/* ǖ Ǖ */
-	0x01d8, 499,	/* ǘ Ǘ */
-	0x01da, 499,	/* ǚ Ǚ */
-	0x01dc, 499,	/* ǜ Ǜ */
-	0x01df, 499,	/* ǟ Ǟ */
-	0x01e1, 499,	/* ǡ Ǡ */
-	0x01e3, 499,	/* ǣ Ǣ */
-	0x01e5, 499,	/* ǥ Ǥ */
-	0x01e7, 499,	/* ǧ Ǧ */
-	0x01e9, 499,	/* ǩ Ǩ */
-	0x01eb, 499,	/* ǫ Ǫ */
-	0x01ed, 499,	/* ǭ Ǭ */
-	0x01ef, 499,	/* ǯ Ǯ */
-	0x01f2, 499,	/* Dz DZ */
-	0x01f3, 498,	/* dz DZ */
-	0x01f5, 499,	/* ǵ Ǵ */
-	0x01fb, 499,	/* ǻ Ǻ */
-	0x01fd, 499,	/* ǽ Ǽ */
-	0x01ff, 499,	/* ǿ Ǿ */
-	0x0201, 499,	/* ȁ Ȁ */
-	0x0203, 499,	/* ȃ Ȃ */
-	0x0205, 499,	/* ȅ Ȅ */
-	0x0207, 499,	/* ȇ Ȇ */
-	0x0209, 499,	/* ȉ Ȉ */
-	0x020b, 499,	/* ȋ Ȋ */
-	0x020d, 499,	/* ȍ Ȍ */
-	0x020f, 499,	/* ȏ Ȏ */
-	0x0211, 499,	/* ȑ Ȑ */
-	0x0213, 499,	/* ȓ Ȓ */
-	0x0215, 499,	/* ȕ Ȕ */
-	0x0217, 499,	/* ȗ Ȗ */
-	0x0253, 290,	/* ɓ Ɓ */
-	0x0254, 294,	/* ɔ Ɔ */
-	0x025b, 297,	/* ɛ Ɛ */
-	0x0260, 295,	/* ɠ Ɠ */
-	0x0263, 293,	/* ɣ Ɣ */
-	0x0268, 291,	/* ɨ Ɨ */
-	0x0269, 289,	/* ɩ Ɩ */
-	0x026f, 289,	/* ɯ Ɯ */
-	0x0272, 287,	/* ɲ Ɲ */
-	0x0283, 282,	/* ʃ Ʃ */
-	0x0288, 282,	/* ʈ Ʈ */
-	0x0292, 281,	/* ʒ Ʒ */
-	0x03ac, 462,	/* ά Ά */
-	0x03cc, 436,	/* ό Ό */
-	0x03d0, 438,	/* ϐ Β */
-	0x03d1, 443,	/* ϑ Θ */
-	0x03d5, 453,	/* ϕ Φ */
-	0x03d6, 446,	/* ϖ Π */
-	0x03e3, 499,	/* ϣ Ϣ */
-	0x03e5, 499,	/* ϥ Ϥ */
-	0x03e7, 499,	/* ϧ Ϧ */
-	0x03e9, 499,	/* ϩ Ϩ */
-	0x03eb, 499,	/* ϫ Ϫ */
-	0x03ed, 499,	/* ϭ Ϭ */
-	0x03ef, 499,	/* ϯ Ϯ */
-	0x03f0, 414,	/* ϰ Κ */
-	0x03f1, 420,	/* ϱ Ρ */
-	0x0461, 499,	/* ѡ Ѡ */
-	0x0463, 499,	/* ѣ Ѣ */
-	0x0465, 499,	/* ѥ Ѥ */
-	0x0467, 499,	/* ѧ Ѧ */
-	0x0469, 499,	/* ѩ Ѩ */
-	0x046b, 499,	/* ѫ Ѫ */
-	0x046d, 499,	/* ѭ Ѭ */
-	0x046f, 499,	/* ѯ Ѯ */
-	0x0471, 499,	/* ѱ Ѱ */
-	0x0473, 499,	/* ѳ Ѳ */
-	0x0475, 499,	/* ѵ Ѵ */
-	0x0477, 499,	/* ѷ Ѷ */
-	0x0479, 499,	/* ѹ Ѹ */
-	0x047b, 499,	/* ѻ Ѻ */
-	0x047d, 499,	/* ѽ Ѽ */
-	0x047f, 499,	/* ѿ Ѿ */
-	0x0481, 499,	/* ҁ Ҁ */
-	0x0491, 499,	/* ґ Ґ */
-	0x0493, 499,	/* ғ Ғ */
-	0x0495, 499,	/* ҕ Ҕ */
-	0x0497, 499,	/* җ Җ */
-	0x0499, 499,	/* ҙ Ҙ */
-	0x049b, 499,	/* қ Қ */
-	0x049d, 499,	/* ҝ Ҝ */
-	0x049f, 499,	/* ҟ Ҟ */
-	0x04a1, 499,	/* ҡ Ҡ */
-	0x04a3, 499,	/* ң Ң */
-	0x04a5, 499,	/* ҥ Ҥ */
-	0x04a7, 499,	/* ҧ Ҧ */
-	0x04a9, 499,	/* ҩ Ҩ */
-	0x04ab, 499,	/* ҫ Ҫ */
-	0x04ad, 499,	/* ҭ Ҭ */
-	0x04af, 499,	/* ү Ү */
-	0x04b1, 499,	/* ұ Ұ */
-	0x04b3, 499,	/* ҳ Ҳ */
-	0x04b5, 499,	/* ҵ Ҵ */
-	0x04b7, 499,	/* ҷ Ҷ */
-	0x04b9, 499,	/* ҹ Ҹ */
-	0x04bb, 499,	/* һ Һ */
-	0x04bd, 499,	/* ҽ Ҽ */
-	0x04bf, 499,	/* ҿ Ҿ */
-	0x04c2, 499,	/* ӂ Ӂ */
-	0x04c4, 499,	/* ӄ Ӄ */
-	0x04c8, 499,	/* ӈ Ӈ */
-	0x04cc, 499,	/* ӌ Ӌ */
-	0x04d1, 499,	/* ӑ Ӑ */
-	0x04d3, 499,	/* ӓ Ӓ */
-	0x04d5, 499,	/* ӕ Ӕ */
-	0x04d7, 499,	/* ӗ Ӗ */
-	0x04d9, 499,	/* ә Ә */
-	0x04db, 499,	/* ӛ Ӛ */
-	0x04dd, 499,	/* ӝ Ӝ */
-	0x04df, 499,	/* ӟ Ӟ */
-	0x04e1, 499,	/* ӡ Ӡ */
-	0x04e3, 499,	/* ӣ Ӣ */
-	0x04e5, 499,	/* ӥ Ӥ */
-	0x04e7, 499,	/* ӧ Ӧ */
-	0x04e9, 499,	/* ө Ө */
-	0x04eb, 499,	/* ӫ Ӫ */
-	0x04ef, 499,	/* ӯ Ӯ */
-	0x04f1, 499,	/* ӱ Ӱ */
-	0x04f3, 499,	/* ӳ Ӳ */
-	0x04f5, 499,	/* ӵ Ӵ */
-	0x04f9, 499,	/* ӹ Ӹ */
-	0x1e01, 499,	/* ḁ Ḁ */
-	0x1e03, 499,	/* ḃ Ḃ */
-	0x1e05, 499,	/* ḅ Ḅ */
-	0x1e07, 499,	/* ḇ Ḇ */
-	0x1e09, 499,	/* ḉ Ḉ */
-	0x1e0b, 499,	/* ḋ Ḋ */
-	0x1e0d, 499,	/* ḍ Ḍ */
-	0x1e0f, 499,	/* ḏ Ḏ */
-	0x1e11, 499,	/* ḑ Ḑ */
-	0x1e13, 499,	/* ḓ Ḓ */
-	0x1e15, 499,	/* ḕ Ḕ */
-	0x1e17, 499,	/* ḗ Ḗ */
-	0x1e19, 499,	/* ḙ Ḙ */
-	0x1e1b, 499,	/* ḛ Ḛ */
-	0x1e1d, 499,	/* ḝ Ḝ */
-	0x1e1f, 499,	/* ḟ Ḟ */
-	0x1e21, 499,	/* ḡ Ḡ */
-	0x1e23, 499,	/* ḣ Ḣ */
-	0x1e25, 499,	/* ḥ Ḥ */
-	0x1e27, 499,	/* ḧ Ḧ */
-	0x1e29, 499,	/* ḩ Ḩ */
-	0x1e2b, 499,	/* ḫ Ḫ */
-	0x1e2d, 499,	/* ḭ Ḭ */
-	0x1e2f, 499,	/* ḯ Ḯ */
-	0x1e31, 499,	/* ḱ Ḱ */
-	0x1e33, 499,	/* ḳ Ḳ */
-	0x1e35, 499,	/* ḵ Ḵ */
-	0x1e37, 499,	/* ḷ Ḷ */
-	0x1e39, 499,	/* ḹ Ḹ */
-	0x1e3b, 499,	/* ḻ Ḻ */
-	0x1e3d, 499,	/* ḽ Ḽ */
-	0x1e3f, 499,	/* ḿ Ḿ */
-	0x1e41, 499,	/* ṁ Ṁ */
-	0x1e43, 499,	/* ṃ Ṃ */
-	0x1e45, 499,	/* ṅ Ṅ */
-	0x1e47, 499,	/* ṇ Ṇ */
-	0x1e49, 499,	/* ṉ Ṉ */
-	0x1e4b, 499,	/* ṋ Ṋ */
-	0x1e4d, 499,	/* ṍ Ṍ */
-	0x1e4f, 499,	/* ṏ Ṏ */
-	0x1e51, 499,	/* ṑ Ṑ */
-	0x1e53, 499,	/* ṓ Ṓ */
-	0x1e55, 499,	/* ṕ Ṕ */
-	0x1e57, 499,	/* ṗ Ṗ */
-	0x1e59, 499,	/* ṙ Ṙ */
-	0x1e5b, 499,	/* ṛ Ṛ */
-	0x1e5d, 499,	/* ṝ Ṝ */
-	0x1e5f, 499,	/* ṟ Ṟ */
-	0x1e61, 499,	/* ṡ Ṡ */
-	0x1e63, 499,	/* ṣ Ṣ */
-	0x1e65, 499,	/* ṥ Ṥ */
-	0x1e67, 499,	/* ṧ Ṧ */
-	0x1e69, 499,	/* ṩ Ṩ */
-	0x1e6b, 499,	/* ṫ Ṫ */
-	0x1e6d, 499,	/* ṭ Ṭ */
-	0x1e6f, 499,	/* ṯ Ṯ */
-	0x1e71, 499,	/* ṱ Ṱ */
-	0x1e73, 499,	/* ṳ Ṳ */
-	0x1e75, 499,	/* ṵ Ṵ */
-	0x1e77, 499,	/* ṷ Ṷ */
-	0x1e79, 499,	/* ṹ Ṹ */
-	0x1e7b, 499,	/* ṻ Ṻ */
-	0x1e7d, 499,	/* ṽ Ṽ */
-	0x1e7f, 499,	/* ṿ Ṿ */
-	0x1e81, 499,	/* ẁ Ẁ */
-	0x1e83, 499,	/* ẃ Ẃ */
-	0x1e85, 499,	/* ẅ Ẅ */
-	0x1e87, 499,	/* ẇ Ẇ */
-	0x1e89, 499,	/* ẉ Ẉ */
-	0x1e8b, 499,	/* ẋ Ẋ */
-	0x1e8d, 499,	/* ẍ Ẍ */
-	0x1e8f, 499,	/* ẏ Ẏ */
-	0x1e91, 499,	/* ẑ Ẑ */
-	0x1e93, 499,	/* ẓ Ẓ */
-	0x1e95, 499,	/* ẕ Ẕ */
-	0x1ea1, 499,	/* ạ Ạ */
-	0x1ea3, 499,	/* ả Ả */
-	0x1ea5, 499,	/* ấ Ấ */
-	0x1ea7, 499,	/* ầ Ầ */
-	0x1ea9, 499,	/* ẩ Ẩ */
-	0x1eab, 499,	/* ẫ Ẫ */
-	0x1ead, 499,	/* ậ Ậ */
-	0x1eaf, 499,	/* ắ Ắ */
-	0x1eb1, 499,	/* ằ Ằ */
-	0x1eb3, 499,	/* ẳ Ẳ */
-	0x1eb5, 499,	/* ẵ Ẵ */
-	0x1eb7, 499,	/* ặ Ặ */
-	0x1eb9, 499,	/* ẹ Ẹ */
-	0x1ebb, 499,	/* ẻ Ẻ */
-	0x1ebd, 499,	/* ẽ Ẽ */
-	0x1ebf, 499,	/* ế Ế */
-	0x1ec1, 499,	/* ề Ề */
-	0x1ec3, 499,	/* ể Ể */
-	0x1ec5, 499,	/* ễ Ễ */
-	0x1ec7, 499,	/* ệ Ệ */
-	0x1ec9, 499,	/* ỉ Ỉ */
-	0x1ecb, 499,	/* ị Ị */
-	0x1ecd, 499,	/* ọ Ọ */
-	0x1ecf, 499,	/* ỏ Ỏ */
-	0x1ed1, 499,	/* ố Ố */
-	0x1ed3, 499,	/* ồ Ồ */
-	0x1ed5, 499,	/* ổ Ổ */
-	0x1ed7, 499,	/* ỗ Ỗ */
-	0x1ed9, 499,	/* ộ Ộ */
-	0x1edb, 499,	/* ớ Ớ */
-	0x1edd, 499,	/* ờ Ờ */
-	0x1edf, 499,	/* ở Ở */
-	0x1ee1, 499,	/* ỡ Ỡ */
-	0x1ee3, 499,	/* ợ Ợ */
-	0x1ee5, 499,	/* ụ Ụ */
-	0x1ee7, 499,	/* ủ Ủ */
-	0x1ee9, 499,	/* ứ Ứ */
-	0x1eeb, 499,	/* ừ Ừ */
-	0x1eed, 499,	/* ử Ử */
-	0x1eef, 499,	/* ữ Ữ */
-	0x1ef1, 499,	/* ự Ự */
-	0x1ef3, 499,	/* ỳ Ỳ */
-	0x1ef5, 499,	/* ỵ Ỵ */
-	0x1ef7, 499,	/* ỷ Ỷ */
-	0x1ef9, 499,	/* ỹ Ỹ */
-	0x1f51, 508,	/* ὑ Ὑ */
-	0x1f53, 508,	/* ὓ Ὓ */
-	0x1f55, 508,	/* ὕ Ὕ */
-	0x1f57, 508,	/* ὗ Ὗ */
-	0x1fb3, 509,	/* ᾳ ᾼ */
-	0x1fc3, 509,	/* ῃ ῌ */
-	0x1fe5, 507,	/* ῥ Ῥ */
-	0x1ff3, 509	/* ῳ ῼ */
-]
-
-const rnums = [
-	0x0030, 0x0039,
-	0x0660, 0x0669,
-	0x06f0, 0x06f9,
-	0x07c0, 0x07c9,
-	0x0966, 0x096f,
-	0x09e6, 0x09ef,
-	0x0a66, 0x0a6f,
-	0x0ae6, 0x0aef,
-	0x0b66, 0x0b6f,
-	0x0be6, 0x0bef,
-	0x0c66, 0x0c6f,
-	0x0ce6, 0x0cef,
-	0x0d66, 0x0d6f,
-	0x0e50, 0x0e59,
-	0x0ed0, 0x0ed9,
-	0x0f20, 0x0f29,
-	0x1040, 0x1049,
-	0x17e0, 0x17e9,
-	0x1810, 0x1819,
-	0x1946, 0x194f,
-	0x19d0, 0x19d9,
-	0x1b50, 0x1b59,
-	0xff10, 0xff19,
-	0x104a0, 0x104a9,
-	0x1d7ce, 0x1d7ff
-]
-
-/*
- * upper case ranges
- *	3rd col is conversion excess 500
- */
-const rtolower2 = [
-	0x0041,	0x005a, 532,	/* A-Z a-z */
-	0x00c0,	0x00d6, 532,	/* À-Ö à-ö */
-	0x00d8,	0x00de, 532,	/* Ø-Þ ø-þ */
-	0x0189,	0x018a, 705,	/* Ɖ-Ɗ ɖ-ɗ */
-	0x018e,	0x018f, 702,	/* Ǝ-Ə ɘ-ə */
-	0x01b1,	0x01b2, 717,	/* Ʊ-Ʋ ʊ-ʋ */
-	0x0388,	0x038a, 537,	/* Έ-Ί έ-ί */
-	0x038e,	0x038f, 563,	/* Ύ-Ώ ύ-ώ */
-	0x0391,	0x03a1, 532,	/* Α-Ρ α-ρ */
-	0x03a3,	0x03ab, 532,	/* Σ-Ϋ σ-ϋ */
-	0x0401,	0x040c, 580,	/* Ё-Ќ ё-ќ */
-	0x040e,	0x040f, 580,	/* Ў-Џ ў-џ */
-	0x0410,	0x042f, 532,	/* А-Я а-я */
-	0x0531,	0x0556, 548,	/* Ա-Ֆ ա-ֆ */
-	0x10a0,	0x10c5, 548,	/* Ⴀ-Ⴥ ა-ჵ */
-	0x1f08,	0x1f0f, 492,	/* Ἀ-Ἇ ἀ-ἇ */
-	0x1f18,	0x1f1d, 492,	/* Ἐ-Ἕ ἐ-ἕ */
-	0x1f28,	0x1f2f, 492,	/* Ἠ-Ἧ ἠ-ἧ */
-	0x1f38,	0x1f3f, 492,	/* Ἰ-Ἷ ἰ-ἷ */
-	0x1f48,	0x1f4d, 492,	/* Ὀ-Ὅ ὀ-ὅ */
-	0x1f68,	0x1f6f, 492,	/* Ὠ-Ὧ ὠ-ὧ */
-	0x1f88,	0x1f8f, 492,	/* ᾈ-ᾏ ᾀ-ᾇ */
-	0x1f98,	0x1f9f, 492,	/* ᾘ-ᾟ ᾐ-ᾗ */
-	0x1fa8,	0x1faf, 492,	/* ᾨ-ᾯ ᾠ-ᾧ */
-	0x1fb8,	0x1fb9, 492,	/* Ᾰ-Ᾱ ᾰ-ᾱ */
-	0x1fba,	0x1fbb, 426,	/* Ὰ-Ά ὰ-ά */
-	0x1fc8,	0x1fcb, 414,	/* Ὲ-Ή ὲ-ή */
-	0x1fd8,	0x1fd9, 492,	/* Ῐ-Ῑ ῐ-ῑ */
-	0x1fda,	0x1fdb, 400,	/* Ὶ-Ί ὶ-ί */
-	0x1fe8,	0x1fe9, 492,	/* Ῠ-Ῡ ῠ-ῡ */
-	0x1fea,	0x1feb, 388,	/* Ὺ-Ύ ὺ-ύ */
-	0x1ff8,	0x1ff9, 372,	/* Ὸ-Ό ὸ-ό */
-	0x1ffa,	0x1ffb, 374,	/* Ὼ-Ώ ὼ-ώ */
-	0x2160,	0x216f, 516,	/* Ⅰ-Ⅿ ⅰ-ⅿ */
-	0x24b6,	0x24cf, 526,	/* Ⓐ-Ⓩ ⓐ-ⓩ */
-	0xff21,	0xff3a, 532	/* A-Z a-z */
-]
-
-/*
- * upper case singlets
- *	2nd col is conversion excess 500
- */
-const rtolower1 = [
-	0x0100, 501,	/* Ā ā */
-	0x0102, 501,	/* Ă ă */
-	0x0104, 501,	/* Ą ą */
-	0x0106, 501,	/* Ć ć */
-	0x0108, 501,	/* Ĉ ĉ */
-	0x010a, 501,	/* Ċ ċ */
-	0x010c, 501,	/* Č č */
-	0x010e, 501,	/* Ď ď */
-	0x0110, 501,	/* Đ đ */
-	0x0112, 501,	/* Ē ē */
-	0x0114, 501,	/* Ĕ ĕ */
-	0x0116, 501,	/* Ė ė */
-	0x0118, 501,	/* Ę ę */
-	0x011a, 501,	/* Ě ě */
-	0x011c, 501,	/* Ĝ ĝ */
-	0x011e, 501,	/* Ğ ğ */
-	0x0120, 501,	/* Ġ ġ */
-	0x0122, 501,	/* Ģ ģ */
-	0x0124, 501,	/* Ĥ ĥ */
-	0x0126, 501,	/* Ħ ħ */
-	0x0128, 501,	/* Ĩ ĩ */
-	0x012a, 501,	/* Ī ī */
-	0x012c, 501,	/* Ĭ ĭ */
-	0x012e, 501,	/* Į į */
-	0x0130, 301,	/* İ i */
-	0x0132, 501,	/* IJ ij */
-	0x0134, 501,	/* Ĵ ĵ */
-	0x0136, 501,	/* Ķ ķ */
-	0x0139, 501,	/* Ĺ ĺ */
-	0x013b, 501,	/* Ļ ļ */
-	0x013d, 501,	/* Ľ ľ */
-	0x013f, 501,	/* Ŀ ŀ */
-	0x0141, 501,	/* Ł ł */
-	0x0143, 501,	/* Ń ń */
-	0x0145, 501,	/* Ņ ņ */
-	0x0147, 501,	/* Ň ň */
-	0x014a, 501,	/* Ŋ ŋ */
-	0x014c, 501,	/* Ō ō */
-	0x014e, 501,	/* Ŏ ŏ */
-	0x0150, 501,	/* Ő ő */
-	0x0152, 501,	/* Œ œ */
-	0x0154, 501,	/* Ŕ ŕ */
-	0x0156, 501,	/* Ŗ ŗ */
-	0x0158, 501,	/* Ř ř */
-	0x015a, 501,	/* Ś ś */
-	0x015c, 501,	/* Ŝ ŝ */
-	0x015e, 501,	/* Ş ş */
-	0x0160, 501,	/* Š š */
-	0x0162, 501,	/* Ţ ţ */
-	0x0164, 501,	/* Ť ť */
-	0x0166, 501,	/* Ŧ ŧ */
-	0x0168, 501,	/* Ũ ũ */
-	0x016a, 501,	/* Ū ū */
-	0x016c, 501,	/* Ŭ ŭ */
-	0x016e, 501,	/* Ů ů */
-	0x0170, 501,	/* Ű ű */
-	0x0172, 501,	/* Ų ų */
-	0x0174, 501,	/* Ŵ ŵ */
-	0x0176, 501,	/* Ŷ ŷ */
-	0x0178, 379,	/* Ÿ ÿ */
-	0x0179, 501,	/* Ź ź */
-	0x017b, 501,	/* Ż ż */
-	0x017d, 501,	/* Ž ž */
-	0x0181, 710,	/* Ɓ ɓ */
-	0x0182, 501,	/* Ƃ ƃ */
-	0x0184, 501,	/* Ƅ ƅ */
-	0x0186, 706,	/* Ɔ ɔ */
-	0x0187, 501,	/* Ƈ ƈ */
-	0x018b, 501,	/* Ƌ ƌ */
-	0x0190, 703,	/* Ɛ ɛ */
-	0x0191, 501,	/* Ƒ ƒ */
-	0x0193, 705,	/* Ɠ ɠ */
-	0x0194, 707,	/* Ɣ ɣ */
-	0x0196, 711,	/* Ɩ ɩ */
-	0x0197, 709,	/* Ɨ ɨ */
-	0x0198, 501,	/* Ƙ ƙ */
-	0x019c, 711,	/* Ɯ ɯ */
-	0x019d, 713,	/* Ɲ ɲ */
-	0x01a0, 501,	/* Ơ ơ */
-	0x01a2, 501,	/* Ƣ ƣ */
-	0x01a4, 501,	/* Ƥ ƥ */
-	0x01a7, 501,	/* Ƨ ƨ */
-	0x01a9, 718,	/* Ʃ ʃ */
-	0x01ac, 501,	/* Ƭ ƭ */
-	0x01ae, 718,	/* Ʈ ʈ */
-	0x01af, 501,	/* Ư ư */
-	0x01b3, 501,	/* Ƴ ƴ */
-	0x01b5, 501,	/* Ƶ ƶ */
-	0x01b7, 719,	/* Ʒ ʒ */
-	0x01b8, 501,	/* Ƹ ƹ */
-	0x01bc, 501,	/* Ƽ ƽ */
-	0x01c4, 502,	/* DŽ dž */
-	0x01c5, 501,	/* Dž dž */
-	0x01c7, 502,	/* LJ lj */
-	0x01c8, 501,	/* Lj lj */
-	0x01ca, 502,	/* NJ nj */
-	0x01cb, 501,	/* Nj nj */
-	0x01cd, 501,	/* Ǎ ǎ */
-	0x01cf, 501,	/* Ǐ ǐ */
-	0x01d1, 501,	/* Ǒ ǒ */
-	0x01d3, 501,	/* Ǔ ǔ */
-	0x01d5, 501,	/* Ǖ ǖ */
-	0x01d7, 501,	/* Ǘ ǘ */
-	0x01d9, 501,	/* Ǚ ǚ */
-	0x01db, 501,	/* Ǜ ǜ */
-	0x01de, 501,	/* Ǟ ǟ */
-	0x01e0, 501,	/* Ǡ ǡ */
-	0x01e2, 501,	/* Ǣ ǣ */
-	0x01e4, 501,	/* Ǥ ǥ */
-	0x01e6, 501,	/* Ǧ ǧ */
-	0x01e8, 501,	/* Ǩ ǩ */
-	0x01ea, 501,	/* Ǫ ǫ */
-	0x01ec, 501,	/* Ǭ ǭ */
-	0x01ee, 501,	/* Ǯ ǯ */
-	0x01f1, 502,	/* DZ dz */
-	0x01f2, 501,	/* Dz dz */
-	0x01f4, 501,	/* Ǵ ǵ */
-	0x01fa, 501,	/* Ǻ ǻ */
-	0x01fc, 501,	/* Ǽ ǽ */
-	0x01fe, 501,	/* Ǿ ǿ */
-	0x0200, 501,	/* Ȁ ȁ */
-	0x0202, 501,	/* Ȃ ȃ */
-	0x0204, 501,	/* Ȅ ȅ */
-	0x0206, 501,	/* Ȇ ȇ */
-	0x0208, 501,	/* Ȉ ȉ */
-	0x020a, 501,	/* Ȋ ȋ */
-	0x020c, 501,	/* Ȍ ȍ */
-	0x020e, 501,	/* Ȏ ȏ */
-	0x0210, 501,	/* Ȑ ȑ */
-	0x0212, 501,	/* Ȓ ȓ */
-	0x0214, 501,	/* Ȕ ȕ */
-	0x0216, 501,	/* Ȗ ȗ */
-	0x0386, 538,	/* Ά ά */
-	0x038c, 564,	/* Ό ό */
-	0x03e2, 501,	/* Ϣ ϣ */
-	0x03e4, 501,	/* Ϥ ϥ */
-	0x03e6, 501,	/* Ϧ ϧ */
-	0x03e8, 501,	/* Ϩ ϩ */
-	0x03ea, 501,	/* Ϫ ϫ */
-	0x03ec, 501,	/* Ϭ ϭ */
-	0x03ee, 501,	/* Ϯ ϯ */
-	0x0460, 501,	/* Ѡ ѡ */
-	0x0462, 501,	/* Ѣ ѣ */
-	0x0464, 501,	/* Ѥ ѥ */
-	0x0466, 501,	/* Ѧ ѧ */
-	0x0468, 501,	/* Ѩ ѩ */
-	0x046a, 501,	/* Ѫ ѫ */
-	0x046c, 501,	/* Ѭ ѭ */
-	0x046e, 501,	/* Ѯ ѯ */
-	0x0470, 501,	/* Ѱ ѱ */
-	0x0472, 501,	/* Ѳ ѳ */
-	0x0474, 501,	/* Ѵ ѵ */
-	0x0476, 501,	/* Ѷ ѷ */
-	0x0478, 501,	/* Ѹ ѹ */
-	0x047a, 501,	/* Ѻ ѻ */
-	0x047c, 501,	/* Ѽ ѽ */
-	0x047e, 501,	/* Ѿ ѿ */
-	0x0480, 501,	/* Ҁ ҁ */
-	0x0490, 501,	/* Ґ ґ */
-	0x0492, 501,	/* Ғ ғ */
-	0x0494, 501,	/* Ҕ ҕ */
-	0x0496, 501,	/* Җ җ */
-	0x0498, 501,	/* Ҙ ҙ */
-	0x049a, 501,	/* Қ қ */
-	0x049c, 501,	/* Ҝ ҝ */
-	0x049e, 501,	/* Ҟ ҟ */
-	0x04a0, 501,	/* Ҡ ҡ */
-	0x04a2, 501,	/* Ң ң */
-	0x04a4, 501,	/* Ҥ ҥ */
-	0x04a6, 501,	/* Ҧ ҧ */
-	0x04a8, 501,	/* Ҩ ҩ */
-	0x04aa, 501,	/* Ҫ ҫ */
-	0x04ac, 501,	/* Ҭ ҭ */
-	0x04ae, 501,	/* Ү ү */
-	0x04b0, 501,	/* Ұ ұ */
-	0x04b2, 501,	/* Ҳ ҳ */
-	0x04b4, 501,	/* Ҵ ҵ */
-	0x04b6, 501,	/* Ҷ ҷ */
-	0x04b8, 501,	/* Ҹ ҹ */
-	0x04ba, 501,	/* Һ һ */
-	0x04bc, 501,	/* Ҽ ҽ */
-	0x04be, 501,	/* Ҿ ҿ */
-	0x04c1, 501,	/* Ӂ ӂ */
-	0x04c3, 501,	/* Ӄ ӄ */
-	0x04c7, 501,	/* Ӈ ӈ */
-	0x04cb, 501,	/* Ӌ ӌ */
-	0x04d0, 501,	/* Ӑ ӑ */
-	0x04d2, 501,	/* Ӓ ӓ */
-	0x04d4, 501,	/* Ӕ ӕ */
-	0x04d6, 501,	/* Ӗ ӗ */
-	0x04d8, 501,	/* Ә ә */
-	0x04da, 501,	/* Ӛ ӛ */
-	0x04dc, 501,	/* Ӝ ӝ */
-	0x04de, 501,	/* Ӟ ӟ */
-	0x04e0, 501,	/* Ӡ ӡ */
-	0x04e2, 501,	/* Ӣ ӣ */
-	0x04e4, 501,	/* Ӥ ӥ */
-	0x04e6, 501,	/* Ӧ ӧ */
-	0x04e8, 501,	/* Ө ө */
-	0x04ea, 501,	/* Ӫ ӫ */
-	0x04ee, 501,	/* Ӯ ӯ */
-	0x04f0, 501,	/* Ӱ ӱ */
-	0x04f2, 501,	/* Ӳ ӳ */
-	0x04f4, 501,	/* Ӵ ӵ */
-	0x04f8, 501,	/* Ӹ ӹ */
-	0x1e00, 501,	/* Ḁ ḁ */
-	0x1e02, 501,	/* Ḃ ḃ */
-	0x1e04, 501,	/* Ḅ ḅ */
-	0x1e06, 501,	/* Ḇ ḇ */
-	0x1e08, 501,	/* Ḉ ḉ */
-	0x1e0a, 501,	/* Ḋ ḋ */
-	0x1e0c, 501,	/* Ḍ ḍ */
-	0x1e0e, 501,	/* Ḏ ḏ */
-	0x1e10, 501,	/* Ḑ ḑ */
-	0x1e12, 501,	/* Ḓ ḓ */
-	0x1e14, 501,	/* Ḕ ḕ */
-	0x1e16, 501,	/* Ḗ ḗ */
-	0x1e18, 501,	/* Ḙ ḙ */
-	0x1e1a, 501,	/* Ḛ ḛ */
-	0x1e1c, 501,	/* Ḝ ḝ */
-	0x1e1e, 501,	/* Ḟ ḟ */
-	0x1e20, 501,	/* Ḡ ḡ */
-	0x1e22, 501,	/* Ḣ ḣ */
-	0x1e24, 501,	/* Ḥ ḥ */
-	0x1e26, 501,	/* Ḧ ḧ */
-	0x1e28, 501,	/* Ḩ ḩ */
-	0x1e2a, 501,	/* Ḫ ḫ */
-	0x1e2c, 501,	/* Ḭ ḭ */
-	0x1e2e, 501,	/* Ḯ ḯ */
-	0x1e30, 501,	/* Ḱ ḱ */
-	0x1e32, 501,	/* Ḳ ḳ */
-	0x1e34, 501,	/* Ḵ ḵ */
-	0x1e36, 501,	/* Ḷ ḷ */
-	0x1e38, 501,	/* Ḹ ḹ */
-	0x1e3a, 501,	/* Ḻ ḻ */
-	0x1e3c, 501,	/* Ḽ ḽ */
-	0x1e3e, 501,	/* Ḿ ḿ */
-	0x1e40, 501,	/* Ṁ ṁ */
-	0x1e42, 501,	/* Ṃ ṃ */
-	0x1e44, 501,	/* Ṅ ṅ */
-	0x1e46, 501,	/* Ṇ ṇ */
-	0x1e48, 501,	/* Ṉ ṉ */
-	0x1e4a, 501,	/* Ṋ ṋ */
-	0x1e4c, 501,	/* Ṍ ṍ */
-	0x1e4e, 501,	/* Ṏ ṏ */
-	0x1e50, 501,	/* Ṑ ṑ */
-	0x1e52, 501,	/* Ṓ ṓ */
-	0x1e54, 501,	/* Ṕ ṕ */
-	0x1e56, 501,	/* Ṗ ṗ */
-	0x1e58, 501,	/* Ṙ ṙ */
-	0x1e5a, 501,	/* Ṛ ṛ */
-	0x1e5c, 501,	/* Ṝ ṝ */
-	0x1e5e, 501,	/* Ṟ ṟ */
-	0x1e60, 501,	/* Ṡ ṡ */
-	0x1e62, 501,	/* Ṣ ṣ */
-	0x1e64, 501,	/* Ṥ ṥ */
-	0x1e66, 501,	/* Ṧ ṧ */
-	0x1e68, 501,	/* Ṩ ṩ */
-	0x1e6a, 501,	/* Ṫ ṫ */
-	0x1e6c, 501,	/* Ṭ ṭ */
-	0x1e6e, 501,	/* Ṯ ṯ */
-	0x1e70, 501,	/* Ṱ ṱ */
-	0x1e72, 501,	/* Ṳ ṳ */
-	0x1e74, 501,	/* Ṵ ṵ */
-	0x1e76, 501,	/* Ṷ ṷ */
-	0x1e78, 501,	/* Ṹ ṹ */
-	0x1e7a, 501,	/* Ṻ ṻ */
-	0x1e7c, 501,	/* Ṽ ṽ */
-	0x1e7e, 501,	/* Ṿ ṿ */
-	0x1e80, 501,	/* Ẁ ẁ */
-	0x1e82, 501,	/* Ẃ ẃ */
-	0x1e84, 501,	/* Ẅ ẅ */
-	0x1e86, 501,	/* Ẇ ẇ */
-	0x1e88, 501,	/* Ẉ ẉ */
-	0x1e8a, 501,	/* Ẋ ẋ */
-	0x1e8c, 501,	/* Ẍ ẍ */
-	0x1e8e, 501,	/* Ẏ ẏ */
-	0x1e90, 501,	/* Ẑ ẑ */
-	0x1e92, 501,	/* Ẓ ẓ */
-	0x1e94, 501,	/* Ẕ ẕ */
-	0x1ea0, 501,	/* Ạ ạ */
-	0x1ea2, 501,	/* Ả ả */
-	0x1ea4, 501,	/* Ấ ấ */
-	0x1ea6, 501,	/* Ầ ầ */
-	0x1ea8, 501,	/* Ẩ ẩ */
-	0x1eaa, 501,	/* Ẫ ẫ */
-	0x1eac, 501,	/* Ậ ậ */
-	0x1eae, 501,	/* Ắ ắ */
-	0x1eb0, 501,	/* Ằ ằ */
-	0x1eb2, 501,	/* Ẳ ẳ */
-	0x1eb4, 501,	/* Ẵ ẵ */
-	0x1eb6, 501,	/* Ặ ặ */
-	0x1eb8, 501,	/* Ẹ ẹ */
-	0x1eba, 501,	/* Ẻ ẻ */
-	0x1ebc, 501,	/* Ẽ ẽ */
-	0x1ebe, 501,	/* Ế ế */
-	0x1ec0, 501,	/* Ề ề */
-	0x1ec2, 501,	/* Ể ể */
-	0x1ec4, 501,	/* Ễ ễ */
-	0x1ec6, 501,	/* Ệ ệ */
-	0x1ec8, 501,	/* Ỉ ỉ */
-	0x1eca, 501,	/* Ị ị */
-	0x1ecc, 501,	/* Ọ ọ */
-	0x1ece, 501,	/* Ỏ ỏ */
-	0x1ed0, 501,	/* Ố ố */
-	0x1ed2, 501,	/* Ồ ồ */
-	0x1ed4, 501,	/* Ổ ổ */
-	0x1ed6, 501,	/* Ỗ ỗ */
-	0x1ed8, 501,	/* Ộ ộ */
-	0x1eda, 501,	/* Ớ ớ */
-	0x1edc, 501,	/* Ờ ờ */
-	0x1ede, 501,	/* Ở ở */
-	0x1ee0, 501,	/* Ỡ ỡ */
-	0x1ee2, 501,	/* Ợ ợ */
-	0x1ee4, 501,	/* Ụ ụ */
-	0x1ee6, 501,	/* Ủ ủ */
-	0x1ee8, 501,	/* Ứ ứ */
-	0x1eea, 501,	/* Ừ ừ */
-	0x1eec, 501,	/* Ử ử */
-	0x1eee, 501,	/* Ữ ữ */
-	0x1ef0, 501,	/* Ự ự */
-	0x1ef2, 501,	/* Ỳ ỳ */
-	0x1ef4, 501,	/* Ỵ ỵ */
-	0x1ef6, 501,	/* Ỷ ỷ */
-	0x1ef8, 501,	/* Ỹ ỹ */
-	0x1f59, 492,	/* Ὑ ὑ */
-	0x1f5b, 492,	/* Ὓ ὓ */
-	0x1f5d, 492,	/* Ὕ ὕ */
-	0x1f5f, 492,	/* Ὗ ὗ */
-	0x1fbc, 491,	/* ᾼ ᾳ */
-	0x1fcc, 491,	/* ῌ ῃ */
-	0x1fec, 493,	/* Ῥ ῥ */
-	0x1ffc, 491	/* ῼ ῳ */
-]
-
-/*
- * title characters are those between
- * upper and lower case. ie DZ Dz dz
- */
-const rtotitle1 = [
-	0x01c4, 501,	/* DŽ Dž */
-	0x01c6, 499,	/* dž Dž */
-	0x01c7, 501,	/* LJ Lj */
-	0x01c9, 499,	/* lj Lj */
-	0x01ca, 501,	/* NJ Nj */
-	0x01cc, 499,	/* nj Nj */
-	0x01f1, 501,	/* DZ Dz */
-	0x01f3, 499	/* dz Dz */
-]
-
-const findc = {c, t, n, nelt, ret
-	var p, m
-
-	/*
-	we're processing in chunks of size 
-	nelt, so 1 chunk is of length 'nelt'
-	*/
-	while n > 1
-		m = n/2
-		p = t[m*nelt:]
-		if c >= p[0]
-			t = p
-			n = n - m
-		else
-			n = m
-		;;
-	;;
-
-	if t.len != 0 && c >= t[0]
-		ret# = t
-		-> true
-	else
-		-> false
-	;;
-}
-
-
-const isalpha = {c
-	var l
-
-	if isupper(c) || islower(c)
-		-> true
-	elif findc(c, ralpha2[:], ralpha2.len/2, 2, &l)
-		if (c >= l[0] && c <= l[1])
-			-> true
-		;;
-	elif findc(c, ralpha1[:], ralpha1.len, 1, &l)
-		if (c == l[0])
-			-> true
-		;;
-	;;
-	-> false
-}
-
-const isdigit = {c
-	-> c >= '0' && c <= '9'
-}
-
-const isxdigit = {c
-	-> c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'
-}
-
-const isnum = {c
-	var l
-
-	if findc(c, rnums[:], rnums.len/2, 2, &l)
-		if(c >= l[0] && c <= l[1])
-			-> true
-		;;
-	;;
-	-> false
-}
-
-const isalnum = {c
-	-> isalpha(c) || isnum(c)
-}
-
-const isblank = {c
-	var l
-	var sl
-	var len
-
-	l = rspace2[:]
-	sl = rspace2[:]
-	len = rspace2.len/2
-	if findc(c, sl, len, 2, &l)
-		if(c >= l[0] && c <= l[1])
-			-> true
-		;;
-	;;
-	-> false
-}
-
-const isspace = {c
-	-> c == '\n' || isblank(c)
-}
-
-const islower = {c
-	var l
-
-	/* the first character in the toupper table is the lowercase char */
-	if findc(c, rtoupper2[:], rtoupper2.len/3, 3, &l)
-		if (c >= l[0] && c <= l[1])
-			-> true
-		;;
-	elif findc(c, rtoupper1[:], rtoupper1.len/2, 2, &l)
-		if (c == l[0])
-			-> true
-		;;
-	;;
-	-> false
-}
-
-const isupper = {c
-	var l
-
-	/* the first character in the tolower table is the uppercase char */
-	if findc(c, rtolower2[:], rtolower2.len/3, 3, &l)
-		if (c >= l[0] && c <= l[1])
-			-> true
-		;;
-	elif findc(c, rtolower1[:], rtolower1.len/2, 2, &l)
-		if (c == l[0])
-			-> true
-		;;
-	;;
-	-> false
-}
-
-const istitle = {c
-	-> isupper(c) && islower(c)
-}
-
-const tolower = {c
-	var l
-
-	if findc(c, rtolower2[:], rtolower2.len/3, 3, &l)
-		if c >= l[0] && c <= l[1]
-			-> c + l[2] - 500;
-		;;
-	elif findc(c, rtolower1[:], rtolower1.len/2, 2, &l) 
-		if c == l[0]
-			-> c + l[1] - 500;
-		;;
-	;;
-	-> c
-}
-
-const toupper = {c
-	var l
-
-	if findc(c, rtoupper2[:], rtoupper2.len/3, 3, &l);
-		if c >= l[0] && c <= l[1]
-			-> c + l[2] - 500;
-		;;
-	elif findc(c, rtoupper1[:], rtoupper1.len/2, 2, &l);
-		if c == l[0]
-			-> c + l[1] - 500;
-		;;
-	;;
-	-> c
-}
-
-const totitle = {c
-	var l
-
-	if findc(c, rtotitle1[:], rtotitle1.len/2, 2, &l);
-		if c == l[0]
-			-> c + l[1] - 500;
-		;;
-	;;
-	-> c
-}
-
-generic charval = {c, base -> @a::(numeric,integral)
-	var v = -1
-
-	if c >= '0' && c <= '9'
-		v =  (c - '0') castto(@a::(integral,numeric))
-	elif c >= 'a' && c <= 'z'
-		v =  (c - 'a' + 10) castto(@a::(integral,numeric))
-	elif c >= 'A' && c <= 'Z'
-		v =  (c - 'A' + 10) castto(@a::(integral,numeric))
-	;;
-
-	if v < 0 || v > (base castto(@a::(integral,numeric)))
-		-> -1
-	;;
-	-> v
-}
--- a/libstd/clear.myr
+++ /dev/null
@@ -1,12 +1,0 @@
-use "slfill.use"
-pkg std =
-	generic clear	: (p : @a#	-> void)
-;;
-
-generic clear = {p : @a#
-	var bp
-
-	bp = p castto(byte#)
-	slfill(bp[:sizeof(@a)], 0)
-}
-
--- a/libstd/cmp.myr
+++ /dev/null
@@ -1,54 +1,0 @@
-use "extremum.use"
-use "types.use"
-
-pkg std =
-	type order = union
-		`Before
-		`Equal
-		`After
-	;;
-
-	generic numcmp	: (a : @a, b : @a -> order)
-	const strcmp	: (a : byte[:], b : byte[:] -> order)
-	const strncmp	: (a : byte[:], b : byte[:], n : size -> order)
-;;
-
-generic numcmp = {a, b
-	if a < b
-		-> `Before
-	elif a == b
-		-> `Equal
-	else
-		-> `After
-	;;
-}
-
-const strcmp = {a, b
-	var l
-	var i
-
-	l = min(a.len, b.len)
-	for i = 0; i < l; i++
-		if a[i] < b[i]
-			-> `Before
-		elif a[i] > b[i]
-			-> `After
-		;;
-	;;
-
-	if a.len < b.len
-		-> `Before
-	elif a.len > b.len
-		-> `After
-	else
-		-> `Equal
-	;;
-		
-}
-
-const strncmp = {a, b, n
-	a = a[:min(a.len, n)]
-	b = b[:min(b.len, n)]
-	-> strcmp(a, b)
-}
-
--- a/libstd/cstrconv.myr
+++ /dev/null
@@ -1,40 +1,0 @@
-use "types.use"
-
-pkg std =
-	const cstrlen	: (buf : byte[:] -> size)
-	const cstrconv	: (buf : byte[:] -> byte[:])
-	const cstrconvp	: (p : byte# -> byte[:])
-;;
-
-const cstrconv = {buf
-	var i
-
-	for i = 0; i < buf.len; i++
-		if buf[i] == 0
-			-> buf[:i]
-		;;
-	;;
-	-> buf
-}
-
-const cstrconvp = {p
-	var i, base
-
-	i = 0
-	base = p castto(intptr)
-	while ((base + i) castto(byte#))# != 0
-		i++
-	;;
-	-> p[:i]
-}
-
-const cstrlen = {buf
-	var i
-
-	for i = 0; i < buf.len; i++
-		if buf[i] == 0
-			break
-		;;
-	;;
-	-> i
-}
--- a/libstd/dial+plan9.myr
+++ /dev/null
@@ -1,165 +1,0 @@
-use sys
-
-use "alloc.use"
-use "die.use"
-use "fmt.use"
-use "option.use"
-use "pathjoin.use"
-use "result.use"
-use "sleq.use"
-use "strfind.use"
-use "strstrip.use"
-use "syswrap.use"
-use "utf.use"
-
-
-pkg std =
-	const dial	: (dialstr : byte[:] -> result(fd, byte[:]))
-;;
-
-const Maxpath = 512
-
-const dial = {str
-	var netdir, proto, rem
-
-	(netdir, proto, rem) = parsedial(str)
-	if netdir.len != 0
-		-> csdial(netdir, proto, rem)
-	;;
-
-	match csdial("/net", proto, rem)
-	| `Ok fd:	-> `Ok fd
-	| `Fail m:
-		-> csdial("/net.alt", proto, rem)
-	;;
-}
-
-const csdial = {netdir, proto, rem
-	var dir, clone, addr, csaddr
-	var ret, csfd, n
-	var buf	: byte[Maxpath]
-
-	/* Try using the connection server */
-	dir = fmt("{}/cs", netdir)
-	csfd = open(dir, Ordwr)
-	if csfd < 0
-		clone = fmt("{}/{}/clone", netdir, proto)
-		ret = call(clone, rem, netdir)
-		slfree(clone)
-		if ret == -1
-			-> `Fail "unable to dial without cs"
-		else
-			-> `Ok ret
-		;;
-	;;
-	slfree(dir)
-
-	csaddr = fmt("{}!{}", proto, rem)
-	if write(csfd, csaddr) < 0
-		close(csfd)
-		-> `Fail "couldn't blah cs"
-	;;
-	slfree(csaddr)
-
-	seek(csfd, 0, 0)
-	while true
-		n = read(csfd, buf[:])
-		if n <= 0
-			break
-		;;
-
-		match strfind(buf[:n], " ")
-		| `None:	continue
-		| `Some i:
-			clone = buf[:i]
-			addr = buf[i+1:n]
-		;;
-
-		ret = call(clone, addr, netdir)
-		if ret >= 0
-			break
-		;;
-	;;
-
-	close(csfd)
-	if ret < 0
-		-> `Fail "unable to dial"
-	;;
-	-> `Ok ret
-}
-
-const call = {clone, addr, netdir
-	var namebuf : byte[Maxpath]
-	var databuf : byte[Maxpath]
-	var name, base, dpath
-	var cfd, datafd
-	var c, n
-
-	datafd = -1
-	c = nsclonestr(clone, netdir)
-	cfd = open(c, Ordwr)
-	if cfd < 0
-		goto cleanup
-	;;
-
-	n = read(cfd, namebuf[:])
-	if n < 0
-		goto cleanup
-	;;
-	fput(cfd, "connect {}", addr)
-	name = strstrip(namebuf[:n])
-	match strrfind(c, "/")
-	| `None:	die("there should be a '/' here\n")
-	| `Some i:	base = c[:i]
-	;;
-	dpath = bfmt(databuf[:], "{}/{}/data", base, name)
-	datafd = open(dpath, Ordwr)
-:cleanup
-	close(cfd)
-	slfree(c)
-	-> datafd
-}
-
-const nsclonestr = {clone, netdir
-	if decode(clone) == '#' || decode(clone) == '/'
-		match std.strfind(clone[1:], "/")
-		| `Some i:	clone = clone[i+1:]
-		| `None:	/* nothing */
-		;;
-	;;
-	-> pathcat(netdir, clone)
-}
-
-const parsedial = {str
-	var netdir, proto, rem, hd, tl
-
-	netdir=""
-	proto = ""
-	rem = ""
-	match strfind(str, "!")
-	| `None:
-		proto = "net"
-		rem = str
-	| `Some sep:
-		hd = str[:sep]
-		tl = str[sep+1:]
-		if decode(hd) == '#' || decode(hd) == '/'
-			match strrfind(hd, "/")
-			| `Some idx:
-				netdir = hd[:idx]
-				proto = hd[idx+1:]
-			| `None:
-				netdir = ""
-				proto = hd
-			;;
-		else
-			netdir = ""
-			proto = hd
-
-		;;
-		rem = tl
-	;;
-
-	-> (netdir, proto, rem)
-}
-
--- a/libstd/dial+posixy.myr
+++ /dev/null
@@ -1,147 +1,0 @@
-use sys
-
-use "alloc.use"
-use "chartype.use"
-use "die.use"
-use "endian.use"
-use "hasprefix.use"
-use "intparse.use"
-use "ipparse.use"
-use "option.use"
-use "resolve.use"
-use "result.use"
-use "sleq.use"
-use "strfind.use"
-use "syswrap.use"
-use "utf.use"
-
-pkg std =
-	const dial	: (dialstr : byte[:] -> result(fd, byte[:]))
-;;
-
-/*
- 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
-*/
-
-/* takes a plan 9 style dial string */
-const dial = {str
-	var proto, host, port
-	var sa4 : sys.sockaddr_in
-	var sa6 : sys.sockaddr_in6
-	var sa	: sys.sockaddr#
-	var sock
-
-	match parsedial(str)
-	| `Ok val:	(proto, host, port) = val
-	| `Fail m:	-> `Fail m
-	;;
-
-	match getaddr(host)
-	| `Ipv4 bits:
-		sa4.fam = sys.Afinet
-		sa4.addr = bits
-		sa4.port = hosttonet(port)
-		sa = &sa4 castto(sys.sockaddr#)
-	| `Ipv6 bits:
-		sa6.fam = sys.Afinet6
-		sa6.addr = bits
-		sa6.port = hosttonet(port)
-		sa = &sa6 castto(sys.sockaddr#)
-	;;
-	sock = sys.socket(sa.fam, proto, 0)
-
-	if sock < 0
-		-> `Fail "failed to connect to socket"
-	;;
-	var err
-	err = sys.connect(sock, sa, sizeof(sys.sockaddr_in))
-	if err < 0
-		sys.close(sock)
-		-> `Fail "Failed to bind socket"
-	;;
-
-	-> `Ok (sock castto(fd))
-}
-
-const parsedial = {str
-	var proto, host, port
-	var socktype, portnum
-
-	(proto, str) = nameseg(str)
-	(host, str) = nameseg(str)
-	(port, str) = nameseg(str)
-
-	if proto.len == 0
-		-> `Fail "missing proto"
-	elif host.len == 0
-		-> `Fail "missing host"
-	elif port.len == 0
-		-> `Fail "missing port"
-	;;
-
-	if sleq(proto, "net")
-		-> `Fail "net wildcard proto not yet supported\n"
-	elif sleq(proto, "unix")
-		-> `Fail "net unix proto not yet supported\n"
-	elif sleq(proto, "tcp")
-		socktype = sys.Sockstream
-	elif sleq(proto, "udp")
-		socktype = sys.Sockdgram
-	;;
-
-	match parseport(port)
-	| `Some n:	portnum = n
-	| `None:	-> `Fail "bad port"
-	;;
-
-	-> `Ok (socktype, host, portnum)
-}
-
-const parseport = {port
-	match intparse(port)
-	| `Some n:	-> `Some n
-	| `None:
-		/* a small number of hardcoded ports */
-		if sleq(port, "http")
-			-> `Some 80
-		elif sleq(port, "https")
-			-> `Some 443
-		elif sleq(port, "ircd")
-			-> `Some 6667
-		elif sleq(port, "dns")
-			-> `Some 53
-		;;
-	;;
-	-> `None
-}
-
-const getaddr = {addr
-	var ip
-
-	match ipparse(addr)
-	| `Some a:	ip = a
-	| `None:
-		match resolve(addr)
-		| `Ok hi:
-			ip = hi[0].addr
-			slfree(hi)
-		| `Fail m:
-		;;
-	;;
-	-> ip
-}
-
-const nameseg = {str
-	match strfind(str, "!")
-	| `Some idx:
-		-> (str[:idx], str[idx+1:])
-	| `None:
-		-> (str, "")
-	;;
-}
-
--- a/libstd/die.myr
+++ /dev/null
@@ -1,19 +1,0 @@
-use "syswrap.use"
-use "types.use"
-
-pkg std = 
-	$noret const die	: (msg : byte[:] -> void)
-	const assert	: (cond : bool, msg : byte[:] -> void)
-;;
-
-const die = {msg
-	write(2, msg)
-	suicide()
-}
-
-const assert = {cond, msg
-	if !cond
-		die(msg)
-	;;
-}
-
--- a/libstd/dir+linux.myr
+++ /dev/null
@@ -1,66 +1,0 @@
-use sys
-
-use "alloc.use"
-use "die.use"
-use "option.use"
-use "result.use"
-use "slcp.use"
-use "sldup.use"
-use "types.use"
-
-pkg std =
-	type dir = struct
-		fd	: sys.fd
-		buf	: byte[16384]
-		len	: int64
-		off	: int64
-	;;
-
-	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
-	const dirread	: (d : dir# -> std.option(byte[:]))
-	const dirclose	: (d : dir# -> void)
-;;
-
-const Direntoverhead = 20
-
-const diropen = {p
-	var fd
-	var dir
-
-	fd = sys.open(p, sys.Ordonly | sys.Odir)
-	if fd < 0
-		-> `Fail "couldn't open directory"
-	;;
-	dir = zalloc()
-	dir.fd = fd
-	-> `Ok dir
-}
-
-const dirread = {d
-	var len
-	var dent
-	var namelen
-
-	if d.off >= d.len
-		len = sys.getdents64(d.fd, d.buf[:])
-		if len <= 0
-			-> `None
-		;;
-		d.len = len
-		d.off = 0
-	;;
-
-	dent = &d.buf[d.off] castto(sys.dirent64#)
-	namelen = 0
-	d.off += dent.reclen castto(int64)
-	while dent.name[namelen] != 0
-		namelen++
-	;;
-	-> `Some sldup(dent.name[:namelen])
-}
-
-const dirclose = {d
-	sys.close(d.fd)
-	free(d)
-}
-
--- a/libstd/dir+osx.myr
+++ /dev/null
@@ -1,60 +1,0 @@
-use sys
-
-use "alloc.use"
-use "die.use"
-use "option.use"
-use "result.use"
-use "slcp.use"
-use "sldup.use"
-use "types.use"
-
-pkg std =
-	type dir = struct
-		fd	: sys.fd
-		buf	: byte[16384]
-		len	: int64
-		off	: int64
-		base	: int64
-	;;
-
-	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
-	const dirread	: (d : dir# -> std.option(byte[:]))
-	const dirclose	: (d : dir# -> void)
-;;
-
-const diropen = {p
-	var fd
-	var dir
-
-	fd = sys.open(p, sys.Ordonly | sys.Odir)
-	if fd < 0
-		-> `Fail "couldn't open directory"
-	;;
-	dir = zalloc()
-	dir.fd = fd
-	-> `Ok dir
-}
-
-const dirread = {d
-	var len
-	var dent
-
-	if d.off >= d.len
-		len = sys.getdirentries64(d.fd, d.buf[:], &d.base)
-		if len <= 0
-			-> `None
-		;;
-		d.len = len
-		d.off = 0
-	;;
-
-	dent = &d.buf[d.off] castto(sys.dirent64#)
-	d.off += dent.reclen castto(int64)
-	-> `Some sldup(dent.name[:dent.namlen])
-}
-
-const dirclose = {d
-	sys.close(d.fd)
-	free(d)
-}
-
--- a/libstd/dir+plan9.myr
+++ /dev/null
@@ -1,66 +1,0 @@
-use sys
-
-use "alloc.use"
-use "die.use"
-use "option.use"
-use "result.use"
-use "slcp.use"
-use "sldup.use"
-use "syswrap.use"
-use "types.use"
-
-pkg std =
-	type dir = struct
-		fd	: fd
-		buf	: byte[65536]	/* a big big, but at least it will always hold a directory entry... */
-		len	: int64
-		off	: int64
-	;;
-
-	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
-	const dirread	: (d : dir# -> std.option(byte[:]))
-	const dirclose	: (d : dir# -> void)
-;;
-
-const diropen = {p
-	var fd
-	var dir
-
-	fd = open(p, Ordonly)
-	if fd < 0
-		-> `Fail "couldn't open directory"
-	;;
-
-	dir = zalloc()
-	dir.fd = fd
-	-> `Ok dir
-}
-	
-
-const dirread = {d
-	var len : int64, name, base, namelen, dirlen
-
-	/* NB: On Plan 9, read(2) will always return whole directory entries */
-	if d.off >= d.len
-		len = read(d.fd, d.buf[:]) castto(int64)
-		if len <= 0
-			-> `None
-		;;
-		d.len = len
-		d.off = 0
-	;;
-
-	namelen = (d.buf[d.off + Stringsoff] castto(int64)) | \
-		((d.buf[d.off + Stringsoff + 1] castto(int64)) << 8)
-	base = d.off + Stringsoff + 2
-	dirlen = (d.buf[d.off] castto(int64)) | \
-		((d.buf[d.off + 1] castto(int64)) << 8)
-	name = d.buf[base:base + namelen]
-	d.off += dirlen + 2
-	-> `Some std.sldup(name)
-}
-
-const dirclose = {d
-	close(d.fd)
-	free(d)
-}
--- a/libstd/dirname.myr
+++ /dev/null
@@ -1,37 +1,0 @@
-use "alloc.use"
-use "slcp.use"
-use "die.use"
-use "sldup.use"
-use "strfind.use"
-use "option.use"
-
-pkg std =
-	const dirname	: (p : byte[:] -> byte[:])
-	const basename	: (p : byte[:] -> byte[:])
-;;
-
-const dirname = {p
-	match std.strrfind(p, "/")
-	| `std.Some idx:
-		-> std.sldup(p[:idx])
-	| `std.None:
-		-> std.sldup(".")
-	;;
-}
-
-const basename = {p
-:again
-	if p.len == 0
-		-> std.sldup(".")
-	;;
-
-	match std.strrfind(p, "/")
-	| `std.Some idx:
-		if idx == p.len - 1
-			goto again
-		;;
-		-> std.sldup(p[idx+1:])
-	| `std.None:
-		-> std.sldup(p)
-	;;
-}
--- a/libstd/endian.myr
+++ /dev/null
@@ -1,32 +1,0 @@
-pkg std =
-	generic hosttonet	: (v : @a -> @a)
-	generic nettohost	: (v : @a -> @a)
-;;
-
-/* FIXME: we only support little endian platforms right now,
-   so we assume a little endian machine. FIX THIS. */
-generic hosttonet = {v : @a::(integral,numeric)
-	var i
-	var ret
-
-	ret = 0
-	for i = 0; i < sizeof(@a); i++
-		ret <<= 8
-		ret |= v & 0xff 
-		v >>= 8
-	;;
-	-> ret
-}
-
-generic nettohost = {v : @a::(integral,numeric)
-	var i
-	var ret
-
-	ret = 0
-	for i = 0; i < sizeof(@a); i++
-		ret <<= 8
-		ret |= v & 0xff 
-		v >>= 8
-	;;
-	-> ret
-}
--- a/libstd/env+plan9.myr
+++ /dev/null
@@ -1,56 +1,0 @@
-use sys
-
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "fmt.use"
-use "option.use"
-use "result.use"
-use "slcp.use"
-use "sldup.use"
-use "sleq.use"
-use "slpush.use"
-use "slurp.use"
-
-pkg std =
-	const getenv :	(name : byte[:] -> option(byte[:]))
-	const getenvv :	(name : byte[:], default : byte[:] -> byte[:])
-;;
-
-var envkey 	: byte[:][:]
-var envval	: byte[:][:]
-
-const envfind = {key
-	var i
-	for i = 0; i < envkey.len; i++
-		if std.sleq(envkey[i], key)
-			-> `Some envval[i]
-		;;
-	;;
-	-> `None
-}
-
-const getenv = {name
-	var buf : byte[128]
-	var s
-
-	match envfind(name)
-	| `Some val:	-> `Some val
-	| `None:
-		s = bfmt(buf[:], "/env/{}", name)
-		match std.slurp(s)
-		| `Fail m: -> `None
-		| `Ok data:
-			envkey = slpush(envkey, sldup(name))
-			envval = slpush(envval, data)
-			-> `Some data
-		;;
-	;;
-}
-
-const getenvv = {name, default
-	match getenv(name)
-	| `Some val:	-> val
-	| `None:	-> default
-	;;
-}
--- a/libstd/env+posixy.myr
+++ /dev/null
@@ -1,28 +1,0 @@
-use sys
-
-use "extremum.use"
-use "option.use"
-use "sleq.use"
-
-pkg std =
-	const getenv :	(name : byte[:] -> option(byte[:]))
-	const getenvv :	(name : byte[:], default : byte[:] -> byte[:])
-;;
-
-const getenv = {name
-	var n
-	for env in sys.__environment
-		n = min(name.len, env.len)
-		if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
-			-> `Some env[n+1:]
-		;;
-	;;
-	-> `None
-}
-
-const getenvv = {name, default
-	match getenv(name)
-	| `Some v:	-> v
-	| `None:	-> default
-	;;
-}
--- a/libstd/errno+plan9.myr
+++ /dev/null
@@ -1,6 +1,0 @@
-pkg std =
-	type errno = int
-	const Erange	: errno = 1
-	const Emisc	: errno = 2
-	const Eexist	: errno = 3
-;;
--- a/libstd/errno.myr
+++ /dev/null
@@ -1,40 +1,0 @@
-use sys
-
-pkg std =
-	type errno = int
-
-	const Eperm	: errno = sys.Eperm	castto(errno)
-	const Enoent	: errno = sys.Enoent	castto(errno)
-	const Esrch	: errno = sys.Esrch	castto(errno)
-	const Eintr	: errno = sys.Eintr	castto(errno)
-	const Eio	: errno = sys.Eio	castto(errno)
-	const Enxio	: errno = sys.Enxio	castto(errno)
-	const E2big	: errno = sys.E2big	castto(errno)
-	const Enoexec	: errno = sys.Enoexec	castto(errno)
-	const Ebadf	: errno = sys.Ebadf	castto(errno)
-	const Echild	: errno = sys.Echild	castto(errno)
-	const Eagain	: errno = sys.Eagain	castto(errno)
-	const Enomem	: errno = sys.Enomem	castto(errno)
-	const Eacces	: errno = sys.Eacces	castto(errno)
-	const Efault	: errno = sys.Efault	castto(errno)
-	const Enotblk	: errno = sys.Enotblk	castto(errno)
-	const Ebusy	: errno = sys.Ebusy	castto(errno)
-	const Eexist	: errno = sys.Eexist	castto(errno)
-	const Exdev	: errno = sys.Exdev	castto(errno)
-	const Enodev	: errno = sys.Enodev	castto(errno)
-	const Enotdir	: errno = sys.Enotdir	castto(errno)
-	const Eisdir	: errno = sys.Eisdir	castto(errno)
-	const Einval	: errno = sys.Einval	castto(errno)
-	const Enfile	: errno = sys.Enfile	castto(errno)
-	const Emfile	: errno = sys.Emfile	castto(errno)
-	const Enotty	: errno = sys.Enotty	castto(errno)
-	const Etxtbsy	: errno = sys.Etxtbsy	castto(errno)
-	const Efbig	: errno = sys.Efbig	castto(errno)
-	const Enospc	: errno = sys.Enospc	castto(errno)
-	const Espipe	: errno = sys.Espipe	castto(errno)
-	const Erofs	: errno = sys.Erofs	castto(errno)
-	const Emlink	: errno = sys.Emlink	castto(errno)
-	const Epipe	: errno = sys.Epipe	castto(errno)
-	const Edom	: errno = sys.Edom	castto(errno)
-	const Erange	: errno = sys.Erange	castto(errno)
-;;
--- a/libstd/execvp.myr
+++ /dev/null
@@ -1,57 +1,0 @@
-use "alloc.use"
-use "env.use"
-use "fmt.use"
-use "option.use"
-use "strfind.use"
-use "strsplit.use"
-use "syswrap.use"
-
-pkg std = 
-	const execvp	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execvpe	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-;;
-
-const execvp = {cmd, args
-	var paths, binpath
-	var buf : byte[512]
-
-	match strfind(cmd, "/")
-	| `Some _:
-		-> execv(cmd, args)
-	| `None:
-		paths = getpaths()
-		for p in paths
-			binpath = bfmt(buf[:], "{}/{}", p, cmd)
-			execv(binpath, args)
-		;;
-		slfree(paths)
-	;;
-	-> -1
-}
-
-const execvpe = {cmd, args, env
-	var paths, binpath
-	var buf : byte[512]
-
-	match strfind(cmd, "/")
-	| `Some _:
-		-> execve(cmd, args, env)
-	| `None:
-		paths = getpaths()
-		for p in paths
-			binpath = bfmt(buf[:], "{}/{}", p, cmd)
-			execve(binpath, args, env)
-		;;
-		slfree(paths)
-	;;
-	-> -1
-}
-
-const getpaths = {
-	var path
-	match getenv("PATH")
-	| `Some p:	path = p
-	| `None:	path = "/usr/local/bin:/bin:/usr/bin"
-	;;
-	-> strsplit(path, ":")
-}
--- a/libstd/extremum.myr
+++ /dev/null
@@ -1,40 +1,0 @@
-pkg std =
-	generic min	: (a : @a::numeric, b : @a::numeric  -> @a::numeric)
-	generic max	: (a : @a::numeric, b : @a::numeric  -> @a::numeric)
-	generic clamp	: (a : @a::numeric, min : @a::numeric, max : @a::numeric -> @a::numeric)
-	generic abs	: (a : @a::numeric -> @a::numeric)
-;;
-
-generic min = {a, b
-	if a < b
-		-> a
-	else
-		-> b
-	;;
-}
-
-generic max = {a, b
-	if a > b
-		-> a
-	else
-		-> b
-	;;
-}
-
-generic clamp = {a, min, max
-	if a < min
-		-> min
-	elif a > max
-		-> max
-	else
-		-> a
-	;;
-}
-
-generic abs = {a : @a::numeric
-	if a < (0 castto(@a::numeric))
-		-> -a
-	else
-		-> a
-	;;
-}
--- a/libstd/fltbits.myr
+++ /dev/null
@@ -1,60 +1,0 @@
-pkg std =
-	const flt64bits	: (flt : flt64 -> int64)
-	const flt32bits	: (flt : flt32 -> int32)
-	const flt64frombits	: (bits : uint64 -> flt64)
-	const flt32frombits	: (bits : uint32 -> flt32)
-	const flt64explode	: (flt : flt64 -> (bool, int64, int64))
-	const flt32explode	: (flt : flt32 -> (bool, int32, int32))
-;;
-
-const flt64bits	= {flt;	-> (&flt castto(int64#))#}
-const flt32bits	= {flt;	-> (&flt castto(int32#))#}
-const flt64frombits	= {bits;	-> (&bits castto(flt64#))#}
-const flt32frombits	= {bits;	-> (&bits castto(flt32#))#}
-
-const flt64explode = {flt
-	var bits, isneg, mant, exp
-
-	bits = flt64bits(flt)
-	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] */
-
-	/* add back the implicit bit if this is not a denormal */
-	if exp != 0
-		mant |= 1l << 52
-	else
-		exp = 1
-	;;
-	/*
-	   adjust for exponent bias. nb: because we are
-	   treating the mantissa as m.0 instead of 0.m,
-	   our exponent bias needs to be offset by the
-	   size of m
-	*/
-	-> (isneg, mant, exp)
-}
-
-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] */
-
-	/* add back the implicit bit if this is not a denormal */
-	if exp != 0
-		mant |= 1 << 22
-	else
-		exp = 1
-	;;
-	/*
-	   adjust for exponent bias. nb: because we are
-	   treating the mantissa as m.0 instead of 0.m,
-	   our exponent bias needs to be offset by the
-	   size of m
-	*/
-	-> (isneg, mant, exp)
-}
-
--- a/libstd/fltfmt.myr
+++ /dev/null
@@ -1,239 +1,0 @@
-use "alloc.use"
-use "bigint.use"
-use "die.use"
-use "extremum.use"
-use "fltbits.use"
-use "slpush.use"
-use "strbuf.use"
-use "types.use"
-use "utf.use"
-
-pkg std =
-	pkglocal const MNormal = 0
-	pkglocal const MAbsolute = 1
-	pkglocal const MRelative = 2
-
-	pkglocal const flt64bfmt	: (sb : strbuf#, val : flt64, mode : int, precision : int -> void)
-	pkglocal const flt32bfmt	: (sb : strbuf#, val : flt32, mode : int, precision : int -> void)
-;;
-
-const Dblbias = 1023
-const Fltbias = 127
-
-const flt64bfmt = {sb, val, mode, precision
-	var isneg, exp, mant
-
-	(isneg, mant, exp) = flt64explode(val)
-	dragon4(sb, isneg, mant, (exp - 52) castto(int64), Dblbias, mode, precision)
-}
-
-const flt32bfmt = {sb, val, mode, precision
-	var isneg, exp, mant
-
-	(isneg, mant, exp) = flt32explode(val)
-	dragon4(sb, isneg, mant castto(int64), (exp - 52) castto(int64), Fltbias, mode, precision)
-}
-
-/*
-sb: output buffer
-e: exponent
-p: precision
-f: mantissa
-
-flting value: x = f^(e - p)
-*/
-const dragon4 = {sb, isneg, f, e, p, mode, cutoff
-	var r, s, t, u, v, y
-	var udig
-	var mm, mp	/* margins above and below */
-	var roundup
-	var low, high
-	var k, n
-	var a, i
-
-	/* if we have zero for the mantissa, we can return early */
-	n = 0
-	if isneg
-		sbputs(sb, "-")
-	;;
-	if f == 0
-		sbputs(sb, "0.0")
-	;;
-
-	/* initialize */
-	roundup = false
-	r = mkbigint(f)
-	r = bigshli(r, max(e - p, 0))
-	s = bigshli(mkbigint(1), max(0, -(e - p)))
-	mm = bigshli(mkbigint(1), max((e - p), 0))
-	mp = bigdup(mm)
-
-	/* fixup: unequal gaps */
-	t = mkbigint(1)
-	bigshli(t, p - 1)
-	if bigeqi(t, f)
-		bigshli(mp, 1)
-		bigshli(r, 1)
-		bigshli(s, 1)
-	;;
-	bigfree(t)
-
-	k = 0
-	while true
-		/* r < ceil(s/b) */
-		t = bigdup(s)
-		bigaddi(t, 9)
-		bigdivi(t, 10)
-		match bigcmp(r, t)
-		| `Before:
-			k--
-			bigmuli(r, 10)
-			bigmuli(mm, 10)
-			bigmuli(mp, 10)
-		| _:
-			bigfree(t)
-			break
-		;;
-		bigfree(t)
-	;;
-
-	while true
-		t = bigdup(r)
-		bigshli(t, 1)
-		bigadd(t, mp)
-		while true
-			u = bigdup(s)
-			bigshli(u, 1)
-			match bigcmp(t, u)
-			| `Before:
-				bigfree(u)
-				break
-			| _:
-				k++
-				bigmuli(s, 10)
-				bigfree(u)
-			;;
-		;;
-		if mode == MNormal
-			cutoff = k
-		else
-			if mode == MRelative
-				cutoff += k - 1
-			;;
-			/* common between relative and absolute */
-			a = cutoff - k - 1
-			y = bigdup(s)
-			if a < 0
-				for i = 0; i < a; i++
-					bigmuli(y, 10)
-				;;
-			else
-				for i = 0; i < -a; i++
-					bigaddi(y, 9)
-					bigdivi(y, 10)
-				;;
-			;;
-			match bigcmp(y, mm)
-			| `Before:	/* nothing */
-			| _:
-				bigfree(mm)
-				mm = y
-			;;
-			match bigcmp(y, mp)
-			| `Before:	/* nothing */
-			| _:
-				bigfree(mp)
-				mp = y
-				roundup = true
-			;;
-		;;
-		u = bigdup(s)
-		bigshli(u, 1)
-		match bigcmp(t, u)
-		| `Before:
-			bigfree(t)
-			bigfree(u)
-			break
-		| _:
-		;;
-	;;
-
-	if k <= 0
-		sbputs(sb, "0.")
-	;;
-	while true
-		k--
-		bigmuli(r, 10)
-		u = bigdup(r);
-		bigdiv(u, s)
-
-		bigmod(r, s)
-		bigmuli(mm, 10)
-		bigmuli(mp, 10)
-
-		low = false
-		t = bigdup(r)
-		bigshli(t, 1)
-		match bigcmp(t, mm)
-		| `Before:	low = true
-		| _:
-		;;
-		bigfree(t)
-		
-		v = bigdup(r)
-		bigshli(v, 1)
-		t = bigdup(s)
-		bigshli(t, 1)
-		bigsub(t, mp)
-		match bigcmp(v, t)
-		| `After: high = true
-		| `Equal: high = roundup
-		| `Before: high = false
-		;;
-		bigfree(v)
-		bigfree(t)
-		if low || high || k == cutoff
-			break
-		;;
-		format(sb, lowdig(u), k)
-		bigfree(u)
-	;;
-
-	/* format the last digit */
-	udig = lowdig(u)
-	if low && !high
-		format(sb, udig, k)
-	elif high && !low
-		format(sb, udig + 1, k)
-	else
-		bigmuli(r, 2)
-		match bigcmp(r, s)
-		| `Before:	format(sb, udig, k)
-		| `Equal:	format(sb, udig, k)
-		| `After:	format(sb, udig + 1, k)
-		;;
-	;;
-	-> n
-}
-
-const lowdig = {u
-	if u.dig.len > 0
-		-> u.dig[0]
-	;;
-	-> 0
-}
-
-const format = {sb, d, k
-	const dig = "0123456789"
-	var i
-
-	if k < 0
-		for i = 0; i < -k - 1; i++
-			sbputs(sb, "0")
-		;;
-	;;
-	sbputb(sb, dig[d])
-	if k == 0
-		sbputs(sb, ".")
-	;;
-}
--- a/libstd/fmt.myr
+++ /dev/null
@@ -1,499 +1,0 @@
-use "alloc.use"
-use "chartype.use"
-use "die.use"
-use "extremum.use"
-use "fltfmt.use"
-use "hashfuncs.use"
-use "hasprefix.use"
-use "htab.use"
-use "introspect.use"
-use "intparse.use"
-use "option.use"
-use "sleq.use"
-use "slpush.use"
-use "strbuf.use"
-use "strfind.use"
-use "strsplit.use"
-use "syswrap-ss.use"
-use "syswrap.use"
-use "types.use"
-use "utf.use"
-use "varargs.use"
-
-pkg std =
-	/* write to fd */
-	const put	: (fmt : byte[:], args : ... -> size)
-	const fput	: (fd : fd, fmt : byte[:], args : ... -> size)
-	const putv	: (fmt : byte[:], ap : valist# -> size)
-	const fputv	: (fd : fd, fmt : byte[:], ap : valist# -> size)
-
-	/* write to buffer */
-	const fmt	: (fmt : byte[:], args : ... -> byte[:])
-	const fmtv	: (fmt : byte[:], ap : valist# -> byte[:])
-	const bfmt	: (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
-	const bfmtv	: (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
-
-	/* write to strbuf */
-	const sbfmt	: (buf : strbuf#, fmt : byte[:], args : ... -> size)
-	const sbfmtv	: (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
-
-	/* add a formatter function */
-	const fmtinstall	: (ty : byte[:], \
-		fn : (sb : strbuf#, ap : valist#, opts : (byte[:],byte[:])[:] -> void), \
-		optdesc : (byte[:], bool)[:] \
-		-> void)
-
-	$noret const fatal	: (fmt : byte[:], args : ... -> void)
-	$noret const fatalv	: (fmt : byte[:], ap : valist# -> void)
-;;
-
-const __init__ = {
-	fmtmap = mkht(strhash, streq)
-}
-
-type fmtdesc = struct
-	fn	: (sb : strbuf#, ap : valist#, opts : (byte[:],byte[:])[:] -> void)
-	optdesc	: (byte[:], bool)[:]
-;;
-
-/* same as 'put', but exits the program after printing */
-const fatal = {fmt, args
-	var ap
-
-	ap = vastart(&args)
-	putv(fmt, &ap)
-	exit(1)
-}
-
-/* same as 'putv', but exits the program after printing */
-const fatalv = {fmt, ap
-	putv(fmt, ap)
-	exit(1)
-}
-
-var fmtmap : htab(byte[:], fmtdesc)#
-
-const fmtinstall = {ty, fn, optdesc
-	htput(fmtmap, ty, [.fn=fn, .optdesc=optdesc])
-}
-
-const put = {fmt, args
-	var ap
-
-	ap = vastart(&args)
-	-> fputv(1, fmt, &ap)
-}
-
-const putv = {fmt, ap
-	-> fputv(1, fmt, ap)
-}
-
-const fput = {fd, fmt, args
-	var ap
-
-	ap = vastart(&args)
-	-> fputv(fd, fmt, &ap)
-}
-
-const fputv = {fd, fmt, ap
-	var sb, s
-
-	sb = mksb()
-	sbfmtv(sb, fmt, ap)
-	s = sbfin(sb)
-	-> writeall(fd, s)
-}
-
-const fmt = {fmt, args
-	var ap
-
-	ap = vastart(&args)
-	-> fmtv(fmt, &ap)
-}
-
-const fmtv = {fmt, ap
-	var sb
-
-	sb = mksb()
-	sbfmtv(sb, fmt, ap)
-	-> sbfin(sb)
-}
-
-const bfmt = {buf, fmt, args
-	var ap
-
-	ap = vastart(&args)
-	-> bfmtv(buf, fmt, &ap)
-}
-
-const bfmtv = {buf, fmt, ap
-	var sb
-
-	sb = mkbufsb(buf)
-	sbfmtv(sb, fmt, ap)
-	-> sbfin(sb)
-}
-
-const sbfmt = {sb, fmt, args
-	var ap
-
-	ap = vastart(&args)
-	-> sbfmtv(sb, fmt, &ap)
-}
-
-const sbfmtv = {sb, fmt, ap -> size
-	var nfmt, nparams, pl, orig
-	var c, params, ty
-
-	orig = fmt
-	nparams = ap.tc.nelt
-	nfmt = 0
-	while fmt.len != 0
-		(c, fmt) = striter(fmt)
-		match c
-		| '{':
-			if decode(fmt) == '{'
-				(c, fmt) = striter(fmt)
-				sbputc(sb, '{')
-			else
-				(params, fmt) = getparams(fmt)
-				nfmt++
-				if nfmt > nparams
-					die("too few params for fmt\n")
-				;;
-
-				ty = vatype(ap)
-				match htget(fmtmap, ty)
-				| `Some f:
-					pl = parseparams(params, f.optdesc)
-					f.fn(sb, ap, pl)
-					std.slfree(pl)
-				| `None:
-					fallbackfmt(sb, params, ty, ap)
-				;;
-			;;
-		| '}':
-			if decode(fmt) == '}'
-				sbputc(sb, '}')
-			;;
-		| chr:
-			sbputc(sb, chr)
-		;;
-:fmtdone
-	;;
-	if nfmt != nparams
-		write(1, orig)
-		die("too many params for fmt\n")
-	;;
-	-> sb.len
-}
-
-const parseparams = {paramstr, optdesc
-	var params, opts
-	var o, a, ha : bool, gotarg : bool
-
-	opts = [][:]
-	params = strsplit(paramstr, ",")
-	for p in params
-		/* parse out the key/value pair */
-		match std.strfind(p, "=")
-		| `std.Some idx:
-			o = p[:idx]
-			a = p[idx+1:]
-			gotarg = true
-		| `std.None:
-			o = p
-			a = ""
-			gotarg = false
-		;;
-
-		/* verify and add the arg */
-		for (opt, hasarg) in optdesc
-			if !std.sleq(opt, o)
-				continue
-			;;
-			ha = hasarg
-			if ha == gotarg
-				opts = std.slpush(opts, (o, a))
-			else
-				std.fatal("invalid option {}", o)
-			;;
-		;;
-	;;
-	slfree(params)
-	-> opts
-}
-
-
-const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
-	/* value types */
-	var t_val : bool
-	var b_val : int8, ub_val : uint8
-	var w_val : int16, uw_val : uint16
-	var i_val : int32, ui_val : uint32
-	var l_val : int64, ul_val : uint64
-	var z_val : size
-	var p_val : byte#
-        var c_val : char
-	var s_val : byte[:]
-	var f32_val : flt32, f64_val : flt64
-	var i8 : int8, i16: int16, i32 : int32
-	var by : byte
-	var i : int, i64 : int64, l : long
-	var ui8 : int8, ui16: int16, ui32 : int32
-	var ui : int, ui64 : int64, ul : long
-
-	match typedesc(tyenc)
-	| `Tynone:	/* nothing */
-	/* atomic types */
-	| `Tyvoid:
-		sbputs(sb, "void")
-	| `Tybool:
-		t_val = vanext(ap)
-		if t_val
-			sbputs(sb ,"true")
-		else
-			sbputs(sb, "false")
-		;;
-	| `Tychar:
-		c_val = vanext(ap)
-		sbputc(sb, c_val)
-	| `Tyint8:
-		b_val = vanext(ap)
-		intfmt(sb, intparams(params), true, b_val)
-	| `Tyint16:
-		w_val = vanext(ap)
-		intfmt(sb, intparams(params), true, w_val)
-	| `Tyint:
-		i_val = vanext(ap)
-		intfmt(sb, intparams(params), true, i_val)
-	| `Tyint32:
-		i_val = vanext(ap)
-		intfmt(sb, intparams(params), true, i_val)
-	| `Tyint64:
-		l_val = vanext(ap)
-		intfmt(sb, intparams(params), true, l_val)
-	| `Tylong:
-		l_val = vanext(ap)
-		intfmt(sb, intparams(params), true, l_val)
-
-	| `Tybyte:
-		ub_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ub_val)
-	| `Tyuint8:
-		ub_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ub_val)
-	| `Tyuint16:
-		uw_val = vanext(ap)
-		intfmt(sb, intparams(params), false, uw_val)
-	| `Tyuint:
-		ui_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ui_val)
-	| `Tyuint32:
-		ui_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ui_val)
-	| `Tyuint64:
-		ul_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ul_val)
-	| `Tyulong:
-		ul_val = vanext(ap)
-		intfmt(sb, intparams(params), false, ul_val)
-	| `Tyflt32:
-		f32_val = vanext(ap)
-		flt32bfmt(sb, f32_val, MNormal, 0)
-	| `Tyflt64:
-		f64_val = vanext(ap)
-		flt64bfmt(sb, f64_val, MNormal, 0)
-	| `Tyvalist:
-		sbputs(sb, "...")
-
-	/* compound types */
-	| `Typtr desc:
-		p_val = vanext(ap)
-		sbputs(sb, "0x")
-		intfmt(sb, \
-			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
-			false, p_val castto(intptr))
-	| `Tyslice desc:
-		match typedesc(desc)
-		| `Tybyte:
-			s_val = vanext(ap)
-			strfmt(sb, s_val, params)
-		| _:
-			sbputs(sb, "slice[:]")
-		;;
-	| `Tyfunc tc:
-		p_val = vanext(ap)
-		sbputs(sb, "func{")
-		intfmt(sb, \
-			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
-			false, p_val castto(intptr))
-		sbputs(sb, "}")
-	| `Tyarray (sz, data):
-		sbputs(sb, "array")
-	/* aggregate types */
-	| `Tytuple typecursor:
-		vabytes(ap)
-		sbputs(sb, "tuple")
-	| `Tystruct namecursor:
-		vabytes(ap)
-		sbputs(sb, "struct")
-	| `Tyunion namecursor:
-		vabytes(ap)
-		sbputs(sb, "union")
-	| `Tyname (name, desc):
-		fallbackfmt(sb, params, desc, ap)
-	;;
-}
-
-const getparams = {fmt
-	var i
-
-	for i = 0; i < fmt.len; i++
-		if fmt[i] == '}' castto(byte)
-			goto foundparams
-		;;
-	;;
-	die("invalid format string")
-:foundparams
-	-> (fmt[:i], fmt[i+1:])
-}
-
-type intparams = struct
-	base	: size
-	padto	: size
-	padfill	: char
-;;
-
-const intparams = {params
-	var ip : intparams
-	var opts
-
-	ip = [
-		.base = 10,
-		.padfill = ' ',
-		.padto = 0
-	]
-
-	opts = parseparams(params, [
-		("x", false),
-		("w", true),
-		("p", true)][:])
-	for o in opts
-		match o
-		| ("x", ""):	ip.base = 16
-		| ("w", wid):	ip.padto = getint(wid, "fmt: width must be integer")
-		| ("p", pad):	ip.padfill = decode(pad)
-		| _:	std.die("unreachable")
-		;;
-	;;
-	std.assert(ip.padto >= 0, "pad must be >= 0")
-	std.slfree(opts)
-	-> ip
-}
-
-const strfmt = {sb, str, params
-	var opts
-	var w, p, i
-
-	p = ' '
-	w = 0
-	opts = parseparams(params, [
-		("w", true),
-		("p", true)][:])
-	for o in opts
-		match o
-		| ("w", wid):	w = getint(wid, "fmt: width must be integer")
-		| ("p", pad):	p = decode(pad)
-		| _:	std.die("unreachable")
-		;;
-	;;
-	std.assert(p >= 0, "pad must be >= 0")
-	std.slfree(opts)
-	for i = 0; i < w - graphemewidth(str); i++
-		sbputc(sb, p)
-	;;
-	sbputs(sb, str)
-}
-
-/*
-Hah. like we're going to put in the work to actually
-count graphemes.
-*/
-const graphemewidth = {str
-	-> str.len
-}
-
-const digitchars = [
-	'0','1','2','3','4',
-	'5','6','7','8','9',
-	'a','b','c','d','e','f'
-]
-generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric)
-	var isneg
-	var val
-	var b : char[32]
-	var i, j, npad
-	var base
-
-	base = opts.base castto(uint64)
-	if signed && bits < 0
-		val = -bits castto(uint64)
-		isneg = true
-	else
-		val = bits castto(uint64)
-		val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a)))
-		isneg = false
-	;;
-
-	i = 0
-	if val == 0
-		b[0] = '0'
-		i++
-	;;
-	while val != 0
-		b[i] = digitchars[val % base]
-		val /= base
-		i++
-	;;
-
-	npad = clamp(opts.padto - i, 0, opts.padto)
-	if isneg
-		npad--
-	;;
-	if opts.padfill == '0' && isneg
-		sbputc(sb, '-')
-	;;
-	for j = 0; j < npad; j++
-		sbputc(sb, opts.padfill)
-	;;
-	if opts.padfill != '0' && isneg
-		sbputc(sb, '-')
-	;;
-	for j = i; j != 0; j--
-		sbputc(sb, b[j - 1])
-	;;
-}
-
-const writeall = {fd, buf
-	var n, len
-
-	len = 0
-	while true
-		n = write(fd, buf)
-		if n <= 0 || n >= len
-			break
-		;;
-		len += n
-	;;
-	-> len
-}
-
-
-/* would use std.get(), but that's a dependency loop */
-const getint = {s, msg
-	match std.intparse(s)
-	| `Some w:	-> w;
-	| `None:	die(msg)
-	;;
-}
--- a/libstd/fmtfuncs.myr
+++ /dev/null
@@ -1,54 +1,0 @@
-use "alloc.use"
-use "bigint.use"
-use "bitset.use"
-use "fmt.use"
-use "introspect.use"
-use "strbuf.use"
-use "varargs.use"
-
-pkg std =
-;;
-
-const __init__ = {
-	var bigint : bigint#
-	var bitset : bitset#
-
-	fmtinstall(typeof(bigint), bigfmt, [][:])
-	fmtinstall(typeof(bitset), bsfmt, [][:])
-}
-
-const bigfmt = {sb, ap, opts
-	var a, n, buf
-
-	a = vanext(ap)
- 	/*
-	allocate a buffer guaranteed to be big enough.
-	that's 
-		2 + floor(nbits/(log_2(10)))
-	or
-		2 + a.dig.len * 32/3.32...
-	or
-		2 + a.dig.len * 10
-	plus one for the - sign.
-	*/
-	buf = slalloc(3 + a.dig.len * 10)
-	n = bigbfmt(buf, a, 10)
-	sbputs(sb, buf[:n])
-	slfree(buf)
-}
-
-const bsfmt = {sb, ap, opts
-	var i, bs, sep
-
-	bs = vanext(ap)
-	sep = ""
-	sbputs(sb, "bitset{")
-	for i = 0; i < bsmax(bs); i++
-		if bshas(bs, i)
-			sbfmt(sb, sep)
-			sbfmt(sb, "{}", i)
-			sep = ", "
-		;;
-	;;
-	sbputs(sb, "}")
-}
--- a/libstd/getcwd.myr
+++ /dev/null
@@ -1,31 +1,0 @@
-
-use "alloc.use"
-use "errno.use"
-use "extremum.use"
-use "syswrap.use"
-use "syswrap-ss.use"
-pkg std =
-	const getcwd : (-> byte[:])
-;;
-
-const getcwd = {
-	var len, n, buf
-
-	len = 128
-	while true
-		buf = std.slalloc(len)
-		n = bgetcwd(buf)
-		if n >= 0
-			/* n is the length of the nul terminated c string */
-			-> buf[:n]
-		elif n != Erange
-			std.slfree(buf)
-			-> ""
-		else
-			len *= 2
-		;;
-	;;
-	/* unreachable; shut up return without value analysis */
-	-> ""
-}
-	
--- a/libstd/getint.myr
+++ /dev/null
@@ -1,64 +1,0 @@
-pkg std =
-	generic getle64	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getbe64	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getle32	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getbe32	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getle16	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getbe16	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getle8	: (buf : byte[:]	-> @a::(numeric,integral))
-	generic getbe8	: (buf : byte[:]	-> @a::(numeric,integral))
-;;
-
-generic getbe64 = {buf -> @a::(numeric,integral)
-	-> ((buf[0] castto(@a::(numeric,integral))) << 56) | \
-		((buf[1] castto(@a::(numeric,integral))) << 48) | \
-		((buf[2] castto(@a::(numeric,integral))) << 40) | \
-		((buf[3] castto(@a::(numeric,integral))) << 32) | \
-		((buf[4] castto(@a::(numeric,integral))) << 24) | \
-		((buf[5] castto(@a::(numeric,integral))) << 16) | \
-		((buf[6] castto(@a::(numeric,integral))) << 8) | \
-		((buf[7] castto(@a::(numeric,integral))) << 0)
-}
-
-generic getle64 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral)))  << 0) | \
-		((buf[1] castto(@a::(numeric,integral)))  << 8) | \
-		((buf[2] castto(@a::(numeric,integral)))  << 16) | \
-		((buf[3] castto(@a::(numeric,integral)))  << 24) | \
-		((buf[4] castto(@a::(numeric,integral)))  << 32) | \
-		((buf[5] castto(@a::(numeric,integral)))  << 40) | \
-		((buf[6] castto(@a::(numeric,integral)))  << 48) | \
-		((buf[7] castto(@a::(numeric,integral)))  << 56)
-}
-
-generic getbe32 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 24) | \
-		((buf[1] castto(@a::(numeric,integral))) << 16) | \
-		((buf[2] castto(@a::(numeric,integral))) << 8) | \
-		((buf[3] castto(@a::(numeric,integral))) << 0)
-}
-
-generic getle32 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
-		((buf[1] castto(@a::(numeric,integral))) << 8) | \
-		((buf[2] castto(@a::(numeric,integral))) << 16) | \
-		((buf[3] castto(@a::(numeric,integral))) << 24)
-}
-
-generic getbe16 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 8) | \
-		((buf[1] castto(@a::(numeric,integral))) << 0)
-}
-
-generic getle16 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
-		((buf[1] castto(@a::(numeric,integral))) << 8)
-}
-
-generic getbe8 = {buf
-	-> (buf[0] castto(@a::(numeric,integral))) << 0
-}
-
-generic getle8 = {buf
-	-> (buf[0] castto(@a::(numeric,integral))) << 0
-}
--- a/libstd/hashfuncs.myr
+++ /dev/null
@@ -1,106 +1,0 @@
-use "die.use"
-use "sleq.use"
-use "types.use"
-
-pkg std =
-	const strhash	: (s : byte[:]	-> uint32)
-	const streq	: (a : byte[:], b : byte[:]	-> bool)
-
-	generic ptrhash	: (p : @a#	-> uint32)
-	generic ptreq	: (a : @a#, b : @a#	-> bool)
-
-	generic inthash	: (v : @a::(integral,numeric)	-> uint32)
-	generic inteq	: (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
-
-	const murmurhash2	: (data : byte[:], seed : uint32 -> uint32)
-
-	generic slhash	: (sl : @a[:] -> uint32)
-	generic tobytes	: (sl : @a[:] -> byte[:])
-;;
-
-const Seed = 1234
-
-generic slhash = {data : @a[:]
-	-> strhash(slbytes(data))
-}
-
-generic slbytes = {data : @a[:]
-	var n
-
-	n = data.len * sizeof(@a)
-	-> (data castto(byte#))[:n]
-}
-
-/* Supremely simple djb hash. */
-const strhash = {s
-	-> murmurhash2(s, Seed)
-}
-
-const streq = {a, b
-	-> sleq(a, b)
-}
-
-generic ptrhash = {p : @a#
-	var x
-
-	x = &p castto(byte#)
-	-> murmurhash2(x[0:sizeof(@a)], Seed)
-}
-
-generic ptreq = {a, b
-	-> a == b
-}
-
-generic inthash = {v : @a::(integral,numeric)
-	var p
-
-	p = &v castto(byte#)
-	-> murmurhash2(p[0:sizeof(@a)], Seed)
-}
-
-generic inteq = {a, b
-	-> a == b
-}
-
-const murmurhash2 = {data, seed
-	const m = 0x5bd1e995;
-	const r = 24
-	var h, k
-	
-	h = seed ^ data.len
-	while data.len >= 4
-		k = (data[0] castto(uint32))
-		k |= (data[1] castto(uint32)) << 8
-		k |= (data[2] castto(uint32)) << 16
-		k |= (data[3] castto(uint32)) << 24
-
-		k *= m
-		k ^= k >> r
-		k *= m
-
-		h *= m
-		h ^= k
-		data = data[4:]
-	;;
-
-	match data.len
-	| 3:
-		h ^= (data[2] castto(uint32)) << 16
-		h ^= (data[1] castto(uint32)) <<8
-		h ^= (data[0] castto(uint32))
-	| 2:
-		h ^= (data[1] castto(uint32)) <<8
-		h ^= (data[0] castto(uint32))
-	| 1:
-		h ^= (data[0] castto(uint32))
-	| 0:	/* nothing */
-	| _:	die("0 < len < 4 must be true")
-	;;
-	h *= m
-
-	h ^= h >> 13
-	h *= m
-	h ^= h >> 15
-
-	-> h
-}
--- a/libstd/hasprefix.myr
+++ /dev/null
@@ -1,12 +1,0 @@
-use "cmp.use"
-pkg std =
-	const hasprefix	: (s : byte[:], pre : byte[:] -> bool)
-;;
-
-const hasprefix = {s, pre
-       match strncmp(s, pre, pre.len)
-       | `Equal:       -> true
-       | _:            -> false
-       ;;
-}
-
--- a/libstd/hassuffix.myr
+++ /dev/null
@@ -1,15 +1,0 @@
-use "sleq.use"
-pkg std =
-	const hassuffix	: (s : byte[:], suff : byte[:] -> bool)
-;;
-
-const hassuffix = {s, suff
-	var tail
-
-	if suff.len <= s.len
-		tail = s[s.len - suff.len:]
-		-> sleq(tail, suff)
-	;;
-	-> false
-}
-
--- a/libstd/htab.myr
+++ /dev/null
@@ -1,209 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "option.use"
-use "types.use"
-
-pkg std =
-	type htab(@k, @v) = struct
-		hash	: (k : @k	-> uint32)
-		eq	: (a : @k, b : @k -> bool)
-
-		nelt	: size
-		ndead	: size
-		keys	: @k[:]
-		vals	: @v[:]
-		hashes	: uint32[:]
-		dead	: bool[:]
-	;;
-
-	generic mkht	: (h : (k : @k -> uint32), eq : (a : @k, b : @k -> bool) -> htab(@k, @v)#)
-	generic htfree	: (ht : htab(@k, @v)# -> void)
-	generic htput	: (ht : htab(@k, @v)#, k : @k, v : @v -> void)
-	generic htdel	: (ht : htab(@k, @v)#, k : @k -> void)
-	generic htget	: (ht : htab(@k, @v)#, k : @k -> option(@v))
-	generic htgetv	: (ht : htab(@k, @v)#, k : @k, fallback : @v-> @v)
-	generic hthas	: (ht : htab(@k, @v)#, k : @k -> bool)
-	generic htkeys	: (ht : htab(@k, @v)# -> @k[:])
-;;
-
-const Initsz = 32
-
-extern const put : (fmt : byte[:], args : ... -> size)
-
-generic hash = {ht, k
-	var h
-
-	h = ht.hash(k)
-	if h == 0
-		-> 1
-	else
-		-> h
-	;;
-}
-
-generic resize = {ht, sz
-	var oldk
-	var oldv
-	var oldh
-	var oldd
-	var i
-
-	oldk = ht.keys
-	oldv = ht.vals
-	oldh = ht.hashes
-	oldd = ht.dead
-	ht.keys = slalloc(sz)
-	ht.vals = slalloc(sz)
-	ht.hashes = slzalloc(sz)
-	ht.dead = slzalloc(sz)
-
-	ht.nelt = 0
-	ht.ndead = 0
-	for i = 0; i < oldk.len; i++
-		if oldh[i] != 0 && !oldd[i]
-			htput(ht, oldk[i], oldv[i])
-		;;
-	;;
-	slfree(oldk)
-	slfree(oldv)
-	slfree(oldh)
-	slfree(oldd)
-}
-
-generic idx = {ht, k
-	var i, di
-	var h
-
-	di = 0
-	h = hash(ht, k)
-	i = h & (ht.keys.len - 1)
-	while true
-		while ht.hashes[i] != 0 && !ht.dead[i] && ht.hashes[i] != h
-			di++
-			i = (h + di) & (ht.keys.len - 1)
-		;;
-
-		if ht.hashes[i] == 0
-			-> `None
-		;;
-		if ht.hashes[i] == h && !ht.dead[i] && ht.eq(ht.keys[i], k)
-			break
-		;;
-		di++
-		i = (h + di) & (ht.keys.len - 1)
-	;;
-	-> `Some i
-}
-
-generic mkht = {h, eq
-	var ht
-
-	ht = alloc()
-
-	ht.hash = h
-	ht.eq = eq
-
-	ht.nelt = 0
-	ht.ndead = 0
-	ht.keys = slalloc(Initsz)
-	ht.vals = slalloc(Initsz)
-	ht.hashes = slzalloc(Initsz)
-	ht.dead = slzalloc(Initsz)
-	-> ht
-}
-
-generic htfree = {ht
-	slfree(ht.keys)
-	slfree(ht.vals)
-	slfree(ht.hashes)
-	slfree(ht.dead)
-	free(ht)
-}
-
-generic htput = {ht, k, v
-	var i, di
-	var h
-	var neltincr
-
-	di = 0
-	h = hash(ht, k)
-	i = h & (ht.keys.len - 1)
-	neltincr = 1
-	while ht.hashes[i] != 0 && !ht.dead[i]
-		/* second insertion overwrites */
-		if ht.hashes[i] == h && !ht.dead[i]
-			/* dead key, we can just insert here */
-			if ht.dead[i]
-				break
-			/* replacing a key */
-			elif ht.eq(ht.keys[i], k)
-				neltincr = 0
-				break
-			;;
-		;;
-		di++
-		i = (h + di) & (ht.keys.len - 1)
-	;;
-	ht.nelt += neltincr
-	ht.hashes[i] = h
-	ht.keys[i] = k
-	ht.vals[i] = v
-	ht.dead[i] = false
-	if ht.keys.len < ht.nelt * 2
-		resize(ht, 2*ht.keys.len)
-	;;
-}
-
-generic htdel = {ht, k
-	match idx(ht, k)
-	| `Some i:
-		ht.dead[i] = true
-		ht.nelt--
-		ht.ndead++
-		std.put("ndead = {}\n", ht.ndead)
-		/* remove tombstones if we shrink enough */
-		if ht.keys.len < ht.ndead * 4
-			resize(ht, ht.keys.len)
-		;;
-	| _:	
-		/* do nothing */
-	;;
-}
-
-generic htget = {ht, k
-	match idx(ht, k)
-	| `Some i:	-> `Some ht.vals[i]
-	| `None:	-> `None
-	;;
-}
-
-generic htgetv = {ht, k, v
-	match idx(ht, k)
-	| `Some i:	-> ht.vals[i]
-	| `None:	-> v
-	;;
-}
-
-generic hthas = {ht, k
-	match idx(ht, k)
-	| `Some i:	-> true
-	| `None:	-> false
-	;;
-}
-
-generic htkeys = {ht
-	var keys
-	var i
-	var j
-
-	keys = slalloc(ht.nelt)
-	j = 0
-	for i = 0; i < ht.keys.len; i++
-		if ht.hashes[i] != 0 && !ht.dead[i]
-			keys[j++] = ht.keys[i]
-		;;
-	;;
-	-> keys
-}
-
--- a/libstd/ifreq+linux.myr
+++ /dev/null
@@ -1,67 +1,0 @@
-use "sys.use"
-
-pkg sys =
-	const Ifnamesz = 16
-
-	type ifreq_addr = struct
-		name	: byte[Ifnamesz]
-		addr	: sockaddr
-	;;
-
-	type ifreq_dstaddr = struct
-		name	: byte[Ifnamesz]
-		dstaddr	: sockaddr
-	;;
-
-	type ifreq_broadaddr = struct
-		name	: byte[Ifnamesz]
-		broadaddr	: sockaddr
-	;;
-
-	type ifreq_netmask = struct
-		name	: byte[Ifnamesz]
-		netmask	: sockaddr
-	;;
-
-
-	type ifreq_hwaddr = struct
-		name	: byte[Ifnamesz]
-		hwaddr	: sockaddr
-	;;
-
-	type ifreq_flags = struct
-		name	: byte[Ifnamesz]
-		flags	: int16
-	;;
-
-	type ifreq_ifindex = struct
-		name	: byte[Ifnamesz]
-		index	: int32
-	;;
-
-	type ifreq_metric = struct
-		name	: byte[Ifnamesz]
-		metric	: int32
-	;;
-
-
-	type ifreq_mtu = struct
-		name	: byte[Ifnamesz]
-		mtu	: int32
-	;;
-
-	type ifreq_slave = struct
-		name	: byte[Ifnamesz]
-		slave	: byte[Ifnamesz]
-	;;
-
-	type ifreq_newname = struct
-		name	: byte[Ifnamesz]
-		newname	: byte[Ifnamesz]
-	;;
-
-	type ifreq_data = struct
-		name	: byte[Ifnamesz]
-		data	: void#
-	;;
-;;
--- a/libstd/ifreq+osx.myr
+++ /dev/null
@@ -1,77 +1,0 @@
-use "sys.use"
-
-pkg sys =
-	const Ifnamesz = 16
-
-	type ifreq_addr = struct
-		name	: byte[Ifnamesz]
-		addr	: sockaddr
-	;;
-
-	type ifreq_dstaddr = struct
-		name	: byte[Ifnamesz]
-		dstaddr	: sockaddr
-	;;
-
-	type ifreq_broadaddr = struct
-		name	: byte[Ifnamesz]
-		broadaddr	: sockaddr
-	;;
-
-	type ifreq_flags = struct
-		name	: byte[Ifnamesz]
-		flags	: int16
-	;;
-
-	type ifreq_metric = struct
-		name	: byte[Ifnamesz]
-		metric	: int32
-	;;
-
-
-	type ifreq_phys = struct
-		name	: byte[Ifnamesz]
-		phys	: int32
-	;;
-
-	type ifreq_media = struct
-		name	: byte[Ifnamesz]
-		media	: int32
-	;;
-
-	type ifreq_data = struct
-		name	: byte[Ifnamesz]
-		data	: void#
-	;;
-
-	type ifreq_devmtu = struct
-		name	: byte[Ifnamesz]
-                cur	: uint32
-                min	: uint32
-                max	: uint32
-	;;
-
-	type ifreq_kpi = struct
-		name	: byte[Ifnamesz]
-                modid	: uint32
-                typeid	: uint32
-		ptr	: void#
-	;;
-
-	type ifreq_wakeflg = struct
-		name	: byte[Ifnamesz]
-		wakeflg	: uint32
-	;;
-		
-	type ifreq_routerefs = struct
-		name	: byte[Ifnamesz]
-		refs	: uint32
-	;;
-
-	type ifreq_icaps = struct
-		name	: byte[Ifnamesz]
-		req	: uint32
-		cur	: uint32
-	;;
-
-;;
--- a/libstd/ifreq+plan9.myr
+++ /dev/null
@@ -1,2 +1,0 @@
-pkg std =
-;;
--- a/libstd/intparse.myr
+++ /dev/null
@@ -1,70 +1,0 @@
-use "chartype.use"
-use "die.use"
-use "hasprefix.use"
-use "option.use"
-use "types.use"
-use "utf.use"
-
-pkg std =
-	generic intparsebase	: (s : byte[:], base : int -> option(@a::(integral,numeric)))
-	generic intparse	: (s : byte[:]	-> option(@a::(integral,numeric)))
-;;
-
-generic intparse = {s
-	var isneg 
-
-	isneg = false
-	if hasprefix(s, "-")
-		s = s[1:]
-		isneg = true
-	;;
-
-	if hasprefix(s, "0x")
-		-> doparse(s[2:], isneg, 16)
-	elif hasprefix(s, "0o")
-		-> doparse(s[2:], isneg, 8)
-	elif hasprefix(s, "0b")
-		-> doparse(s[2:], isneg, 2)
-	else
-		-> doparse(s, isneg, 10)
-	;;
-}
-
-generic intparsebase = {s, base
-	var isneg 
-
-	isneg = false
-	if hasprefix(s, "-")
-		s = s[1:]
-		isneg = true
-	;;
-
-	-> doparse(s, isneg, base)
-}
-
-generic doparse = {s, isneg, base
-	var c
-	var v
-	var cv : int32
-	
-	v = 0
-	while s.len != 0
-		(c, s) = striter(s)
-		if c == '_'
-			continue
-		;;
-		cv = charval(c, base)
-		if cv >= 0
-			v *= (base castto(@a::(integral,numeric)))
-			v += cv castto(@a::(integral,numeric))
-		else
-			-> `None
-		;;
-	;;
-
-	if isneg
-		-> `Some -v
-	else
-		-> `Some v
-	;;
-}
--- a/libstd/introspect.myr
+++ /dev/null
@@ -1,365 +1,0 @@
-use "types.use"
-use "die.use"
-
-pkg std =
-	type typedesc = union
-		`Tynone
-
-		/* atomic types */
-		`Tyvoid
-		`Tybool
-		`Tychar
-
-		`Tyint8
-		`Tyint16
-		`Tyint
-		`Tyint32
-		`Tyint64
-		`Tylong
-
-		`Tybyte
-		`Tyuint8
-		`Tyuint16
-		`Tyuint
-		`Tyuint32
-		`Tyuint64
-		`Tyulong
-		`Tyflt32
-		`Tyflt64
-		`Tyvalist
-
-		/* compound types */
-		`Typtr byte[:]
-		`Tyfunc	typecursor
-		`Tyslice byte[:]
-		`Tyarray (size, byte[:])
-
-		/* aggregate types */
-		`Tytuple	typecursor
-		`Tystruct	namecursor
-		`Tyunion	namecursor
-		/* name info */
-		`Tyname (byte[:], byte[:])
-	;;
-
-	type typecursor = struct
-		nelt	: size
-		rem	: byte[:]
-	;;
-
-	type namecursor = struct
-		nelt	: size
-		rem	: byte[:]
-	;;
-
-	type typeinfo = struct
-		size	: size
-		align	: size
-	;;
-
-	generic typeof	: (v : @a -> byte[:])
-	const typeenc	: (p : ...# -> typecursor)
-	const typedecode	: (e : byte[:] -> typedesc)
-	const typedesc	: (e : byte[:] -> typedesc)
-	const typeinfo	: (e : byte[:] -> typeinfo)
-
-	const tcnext	: (t : typecursor# -> byte[:])
-	const tcpeek	: (t : typecursor# -> byte[:])
-	const ncnext	: (t : namecursor# -> (byte[:], byte[:]))
-;;
-
-extern const put	: (fmt : byte[:], args : ... -> size)
-
-const Encnone	: byte = 0
-const Encvoid	: byte = 1
-const Encbool	: byte = 2
-const Encchar	: byte = 3
-
-const Encint8	: byte = 4
-const Encint16	: byte = 5
-const Encint	: byte = 6
-const Encint32	: byte = 7
-const Encint64	: byte = 8
-const Enclong	: byte = 9
-
-const Encbyte	: byte = 10
-const Encuint8	: byte = 11
-const Encuint16	: byte = 12
-const Encuint	: byte = 13
-const Encuint32	: byte = 14
-const Encuint64	: byte = 15
-const Enculong	: byte = 16
-const Encflt32	: byte = 17
-const Encflt64	: byte = 18
-const Encvalist	: byte = 19
-
-/* compound types */
-const Encptr	: byte = 20
-const Encfunc	: byte = 21
-const Encslice	: byte = 22
-const Encarray	: byte = 23
-
-/* aggregate types */
-const Enctuple	: byte = 24
-const Encstruct	: byte = 25
-const Encunion	: byte = 26
-const Encname	: byte = 30
-const Encindname	:byte = 30 | 0x80
-
-generic typeof = {v : @a -> byte[:]
-	var tc
-
-	tc = typesof(v)
-	-> tcnext(&tc)
-}
-
-const typeenc = {ap : ...#
-	var e
-
-	e = getenc(ap castto(byte##))
-	e = skiptypeinfo(e[1:])
-	-> lentypecursor(e)
-}
-	
-const typesof : (a : ... -> typecursor) = {a : ...
-	-> typeenc(&a)
-}
-
-const tcnext = {tc
-	var n, sz, cur
-
-	if tc.rem.len == 0
-		-> ""
-	;;
-	(n, sz) = getipacked(tc.rem)
-	cur = tc.rem[sz:sz+n]
-	tc.rem = tc.rem[sz+n:]
-	-> cur
-}
-
-const tcpeek = {tc
-	var n, sz
-
-	if tc.rem.len == 0
-		-> ""
-	;;
-	(n, sz) = getipacked(tc.rem)
-	-> tc.rem[sz:sz+n]
-}
-
-const ncnext = {nc
-	var n, sz, name, enc
-
-	if nc.rem.len == 0
-		-> ("", "")
-	;;
-
-	/* get the name */
-	(n, sz) = getipacked(nc.rem)
-	name = nc.rem[sz:sz+n]
-	nc.rem = nc.rem[sz+n:]
-
-	/* and the type */
-	(n, sz) = getipacked(nc.rem)
-	enc = nc.rem[sz:sz+n]
-	nc.rem = nc.rem[sz+n:]
-	-> (name, enc)
-}
-
-
-const getenc = {p : byte##
-	var val, sz, x
-
-	(val, sz) = getipacked(p#[:8])
-	x = &sz castto(byte#)
-	-> p#[sz:sz+val]
-}
-
-const typedesc = {ti
-	var len,sz, p
-
-	match ti[0]
-	| Encnone:	-> `Tynone
-	| Encvoid:	-> `Tyvoid
-	| Encbool:	-> `Tybool
-	| Encchar:	-> `Tychar
-
-	| Encint8:	-> `Tyint8
-	| Encint16:	-> `Tyint16
-	| Encint:	-> `Tyint
-	| Encint32:	-> `Tyint32
-	| Encint64:	-> `Tyint64
-	| Enclong:	-> `Tylong
-
-	| Encbyte:	-> `Tybyte
-	| Encuint8:	-> `Tyuint8
-	| Encuint16:	-> `Tyuint16
-	| Encuint:	-> `Tyuint
-	| Encuint32:	-> `Tyuint32
-	| Encuint64:	-> `Tyuint64
-	| Enculong:	-> `Tyulong
-	| Encflt32:	-> `Tyflt32
-	| Encflt64:	-> `Tyflt64
-	| Encvalist:	-> `Tyvalist
-
-	/* compound types */
-	| Encptr:	-> `Typtr getsub(ti[1:])
-	| Encfunc:	-> `Tyfunc lentypecursor(ti[1:])
-	| Encslice:	-> `Tyslice getsub(ti[1:])
-	| Encarray:
-		ti = skiptypeinfo(ti[1:])
-		(len, sz) = getipacked(ti)
-		-> `Tyarray (len, getsub(ti[sz:]))
-
-
-	/* aggregate types */
-	| Enctuple:
-		ti = skiptypeinfo(ti[1:])
-		-> `Tytuple lentypecursor(ti)
-	| Encstruct:
-		ti = skiptypeinfo(ti[1:])
-		-> `Tystruct lennamecursor(ti)
-	| Encunion:
-		ti = skiptypeinfo(ti[1:])
-		-> `Tyunion lennamecursor(ti)
-	| Encname:
-		-> `Tyname namedesc(ti[1:])
-	| Encindname:
-		/* 
-		ugly hack: the slice contains a pointer to the
-		value, so if we cast it to a byte##, we can
-		pull the indirect value out of the pointer.
-		*/
-		p = ti[1:] castto(byte##)
-		-> typedesc(getenc(p))
-	| _:
-		std.die("unknown type encoding")
-	;;
-}
-
-const typeinfo = {ti
-	var p
-
-	match ti[0]
-	| Encnone:	-> [.size=0, .align=1]
-	| Encvoid:	-> [.size=0, .align=1]
-	| Encbool:	-> [.size=0, .align=1]
-	| Encchar:	-> [.size=4, .align=4]
-
-	| Encint8:	-> [.size=1, .align=1]
-	| Encint16:	-> [.size=2, .align=2]
-	| Encint:	-> [.size=4, .align=4]
-	| Encint32:	-> [.size=4, .align=4]
-	| Encint64:	-> [.size=8, .align=8]
-	| Enclong:	-> [.size=8, .align=8]
-
-	| Encbyte:	-> [.size=1, .align=1]
-	| Encuint8:	-> [.size=1, .align=1]
-	| Encuint16:	-> [.size=2, .align=2]
-	| Encuint:	-> [.size=4, .align=4]
-	| Encuint32:	-> [.size=4, .align=4]
-	| Encuint64:	-> [.size=8, .align=8]
-	| Enculong:	-> [.size=8, .align=8]
-	| Encflt32:	-> [.size=4, .align=4]
-	| Encflt64:	-> [.size=8, .align=8]
-	| Encvalist:	-> [.size=8, .align=8]
-
-	/* compound types */
-	| Encptr:	-> [.size=8, .align=8]
-	| Encfunc:	-> [.size=8, .align=8]
-	| Encslice:	-> [.size=16, .align=8]
-
-	| Encarray: 	-> gettypeinfo(ti[1:])
-	| Enctuple:	-> gettypeinfo(ti[1:])
-	| Encstruct:	-> gettypeinfo(ti[1:])
-	| Encunion:	-> gettypeinfo(ti[1:])
-	| Encname:	-> getnameinfo(ti[1:])
-	| Encindname:
-		p = ti[1:] castto(byte##)
-		-> typeinfo(getenc(p))
-	| _:
-		std.die("unknown type encoding")
-	;;
-}
-
-const gettypeinfo = {e
-	var size, align, sz
-
-	(size, sz) = getipacked(e)	/* size */
-	e = e[sz:]
-	(align, sz) = getipacked(e)	/* align */
-	-> [.size = size, .align = align]
-}
-
-const skiptypeinfo = {e
-	var ignore, sz
-
-	(ignore, sz) = getipacked(e)	/* size */
-	e = e[sz:]
-	(ignore, sz) = getipacked(e)	/* align */
-	-> e[sz:]
-}
-
-const getnameinfo = {e
-	var n, name, sz, enc
-
-	(n, sz) = getipacked(e)
-	name = e[sz:n+sz]
-	e = e[n+sz:]
-	(n, sz) = getipacked(e)
-	enc = e[sz:n+sz]
-
-	-> typeinfo(enc)
-}
-
-const namedesc = {e
-	var n, sz, name, enc
-
-	(n, sz) = getipacked(e)
-	name = e[sz:n+sz]
-	e = e[n+sz:]
-	(n, sz) = getipacked(e)
-	enc = e[sz:n+sz]
-
-	-> (name, enc)
-}
-
-const lentypecursor = {e
-	var n, sz
-
-	(n, sz) = getipacked(e)
-	-> [.nelt=n, .rem=e[sz:]]
-}
-
-const lennamecursor = {e 
-	var n, sz
-
-	(n, sz) = getipacked(e)
-	-> [.nelt=n, .rem=e[sz:]]
-}
-
-const getsub = {e
-	var n, sz
-
-	(n, sz) = getipacked(e)
-	-> e[sz:sz+n]
-}
-
-const getipacked : (p : byte[:] -> (size, size)) = {p : byte[:]
-	var mask, val, len, i
-
-	mask = 0x80
-	val = 0
-	len = 1
-	while p[0] & mask != mask << 1
-		len++
-		mask >>= 1
-		mask |= 0x80
-	;;
-
-	val = (p[0] castto(size))  & ~(1 << (8 - len))
-	for i = 1; i < len; i++
-		val |= (p[i] castto(size)) << (i*8 - len)
-	;;
-	-> (val, len)
-}
--- a/libstd/ipparse.myr
+++ /dev/null
@@ -1,147 +1,0 @@
-use "die.use"
-use "intparse.use"
-use "option.use"
-use "strfind.use"
-use "types.use"
-use "chartype.use"
-use "fmt.use"
-use "slcp.use"
-use "slfill.use"
-use "sleq.use"
-
- /* FIXME: needed for decls which should be pulled in as hidden */
-use "hasprefix.use"
-use "utf.use"
-
-pkg std =
-
-	type netaddr = union
-		`Ipv4	byte[4]
-		`Ipv6	byte[16]
-	;;
-
-	const ipparse	: (ip : byte[:]	-> option(netaddr))
-	const ip4parse	: (ip : byte[:] -> option(netaddr))
-	const ip6parse	: (ip : byte[:] -> option(netaddr))
-;;
-
-const ipparse = {ip
-	match strfind(ip, ":")
-	| `Some _:	-> ip6parse(ip)
-	| `None:	-> ip4parse(ip)
-	;;
-}
-
-const ip4parse = {ip
-	var a, b, c, d
-	var ok
-	/*
-	var addr
-	var last : size
-	var x : option(int32)
-	var val : int32 /* need int32 to check for overflow */
-	var i
-	var j : size
-	*/
-
-	(a, ip, ok) = num(ip, 0, 255, 10, '.', true)
-	(ip, ok) = delim(ip, '.', ok)
-	(b, ip, ok) = num(ip, 0, 255, 10, '.', ok)
-	(ip, ok) = delim(ip, '.', ok)
-	(c, ip, ok) = num(ip, 0, 255, 10, '.', ok)
-	(ip, ok) = delim(ip, '.', ok)
-	(d, ip, ok) = num(ip, 0, 255, 10, '.', ok)
-
-	if ok && ip.len == 0
-		-> `Some (`Ipv4 [a, b, c, d])
-	else
-		-> `None
-	;;
-}
-
-const ip6parse = {ip
-	var val : byte[16]
-	var expand, split
-	var v, ok
-	var i, nseg
-
-	ok = true
-	expand = false
-	split = 0
-	if ip.len > 2 && std.sleq(ip[:2], "::")
-		expand = true
-		split = 0
-	;;
-	nseg = 0
-	for i = 0; ip.len > 0 && ok; i++
-		/* parse 'num' segment */
-		(v, ip, ok) = num(ip, 0, 65536, 16, ':', ok)
-		nseg++
-		if ip.len == 0 || nseg == 8
-			break
-		;;
-		(ip, ok) = delim(ip, ':', ok)
-		/* only one '::' allowed once */
-		if ip.len > 0 && ip[0] == ':'castto(byte) && !expand
-			expand = true
-			split = i
-			(ip, ok) = delim(ip, ':', ok)
-		;;
-
-		/* pack it into the bytes */
-		val[i*2] = ((v & 0xff00) >> 8) castto(byte)
-		val[i*2 + 1] = (v & 0xff) castto(byte)
-	;;
-
-	if ok && ip.len == 0
-		if expand
-			expandsplit(val[:], split, i)
-		elif nseg != 8
-			-> `None
-		;;
-		-> `Some `Ipv6 val
-	else
-		-> `None
-	;;
-}
-
-/* take "a:b::c:d" and expand it to "a:b:0:0:...:0:c:d" */
-const expandsplit = {ip, split, len
-	var width
-
-	width = 16 - len
-	std.slcp(ip[split:len], ip[split+width:len+width])
-	std.slfill(ip[len:len+width], 0)
-}
-
-const delim = {ip, sep, ok
-	if ip.len > 0 && ip[0] == sep castto(byte)
-		-> (ip[1:], ok)
-	else
-		-> ("", false)
-	;;
-}
-
-generic num = {ip, lo, hi, base, sep, ok -> (@a::(numeric,integral), byte[:], bool)
-	var len
-
-	if !ok
-		-> (0, "", false)
-	;;
-
-	for len = 0; len < ip.len; len++
-		if ip[len] == sep castto(byte)
-			break
-		;;
-	;;
-	match intparsebase(ip[:len], base)
-	| `std.Some v:
-		if v < lo || v > hi
-			-> (0, "", false)
-		;;
-		-> (v castto(@a::(numeric,integral)), ip[len:], true)
-	| `std.None:
-		-> (0, "", false)
-	;;
-}
-
--- a/libstd/mk.myr
+++ /dev/null
@@ -1,22 +1,0 @@
-use "alloc.use"
-
-pkg std =
-	generic mk	: (val : @a -> @a#)
-;;
-
-/* Takes a value, and heapifies it.
-
-FIXME: This depends on inlining and copy propagation
-in order to be efficient. Neither of those are
-currently implemented. That means that this function
-is not efficient.
-
-It's still damn convenient, though, so it's in.
-*/
-generic mk = {val
-	var p
-
-	p = alloc()
-	p# = val
-	-> p
-}
--- a/libstd/mkfile
+++ /dev/null
@@ -1,107 +1,0 @@
-</$objtype/mkfile
-
-SYSLIB=sys
-SYSSRC= \
-	sys.myr \
-	systypes.myr \
-	ifreq.myr \
-
-SYSASMSRC= \
-	syscall.s \
-	util.s
-
-
-STDLIB=std
-STDSRC= \
-	alloc.myr \
-	bigint.myr \
-	bitset.myr \
-	blat.myr \
-	chartype.myr \
-	cmp.myr \
-	dial.myr \
-	die.myr \
-	dir.myr \
-	endian.myr \
-	env.myr \
-	execvp.myr \
-	extremum.myr \
-	fltbits.myr \
-	fmt.myr \
-	fltfmt.myr \
-	hashfuncs.myr \
-	hasprefix.myr \
-	hassuffix.myr \
-	htab.myr \
-	intparse.myr \
-	ipparse.myr \
-	mk.myr \
-	now.myr \
-	option.myr \
-	optparse.myr \
-	pathjoin.myr \
-	rand.myr \
-	resolve.myr \
-	result.myr \
-	search.myr \
-	slcp.myr \
-	sldup.myr \
-	sleq.myr \
-	slfill.myr \
-	sljoin.myr \
-	slpush.myr \
-	slput.myr \
-	slurp.myr \
-	sort.myr \
-	spork.myr \
-	strfind.myr \
-	strjoin.myr \
-	strsplit.myr \
-	strstrip.myr \
-	syswrap.myr \
-	swap.myr \
-	try.myr \
-	types.myr \
-	units.myr \
-	utf.myr \
-	varargs.myr \
-	wait.myr \
-
-all:V: lib$STDLIB.a lib$SYSLIB.a
-
-install:V: all
-	mkdir -p /$objtype/lib/myr/
-	cp lib$STDLIB.a lib$SYSLIB.a /$objtype/lib/myr/
-	cp $STDLIB $SYSLIB /$objtype/lib/myr/
-
-lib$STDLIB.a: $STDSRC $ASMSRC lib$SYSLIB.a
-	../myrbuild/$O.out -I. -C../6/$O.out -M../muse/$O.out -l $STDLIB $STDSRC $STDASMSRC
-
-lib$SYSLIB.a: $SYSSRC $SYSASMSRC
-	../myrbuild/$O.out -C../6/$O.out -M../muse/$O.out -l $SYSLIB $SYSSRC $SYSASMSRC
-
-%.myr: %+plan9-x64.myr
-	cp $stem+plan9-x64.myr $stem.myr
-
-%.myr: %+plan9.myr
-	cp $stem+plan9.myr $stem.myr
-
-%.myr: %+x64.myr
-	cp $stem+x64.myr $stem.myr
-
-%.s: %+plan9-x64.s
-	cp $stem+plan9-x64.s $stem.s
-
-%.s: %+x64.s
-	cp $stem+x64.s $stem.s
-
-OBJ=${STDSRC:%.myr=%.$O} ${SYSSRC:%.myr=%.$O} ${STDASMSRC:%.s=%.$O} ${SYSASMSRC:%.s=%.$O}
-USE=${STDSRC:%.myr=%.use} ${SYSSRC:%.myr=%.use} ${STDLIB}
-LIBS=lib$STDLIB.a lib$SYSLIB.a
-.PHONY: clean
-clean:V:
-	rm -f $OBJ
-	rm -f $USE
-	rm -f $LIBS $STDLIB $SYSLIB
-
-nuke:V: clean
--- a/libstd/mkpath.myr
+++ /dev/null
@@ -1,22 +1,0 @@
-use "syswrap.use"
-use "errno.use"
-
-pkg std =
-	const mkpath	: (p : byte[:] -> bool)
-;;
-
-const mkpath = {p
-	var st
-	var i
-
-	for i = 0; i < p.len; i++
-		if p[i] == '/' castto(byte) && i != 0
-			st = mkdir(p[:i], 0o777)
-			if st != 0 && (st castto(errno)) != Eexist
-				-> false
-			;;
-		;;
-	;;
-
-	-> true
-}
--- a/libstd/now.myr
+++ /dev/null
@@ -1,11 +1,0 @@
-use "types.use"
-use "syswrap.use"
-
-pkg std =
-	const now	: (-> time)
-;;
-
-/* microseconds since epoch */
-const now = {
-	-> curtime()
-}
--- a/libstd/option.myr
+++ /dev/null
@@ -1,7 +1,0 @@
-pkg std =
-	type option(@a) = union
-		`Some @a
-		`None
-	;;
-;;
-
--- a/libstd/optparse.myr
+++ /dev/null
@@ -1,210 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "fmt.use"
-use "strbuf.use"
-use "option.use"
-use "sleq.use"
-use "slpush.use"
-use "syswrap-ss.use"
-use "syswrap.use"
-use "types.use"
-use "utf.use"
-
-pkg std =
-	type optdef = struct
-		argdesc	: byte[:]	/* the description for the usage */
-		minargs	: std.size	/* the minimum number of positional args */
-		maxargs	: std.size	/* the maximum number of positional args (0 = unlimited) */
-		noargs	: std.bool	/* whether we accept args at all */
-		opts	: optdesc[:]	/* the description of the options */
-	;;
-
-	type optdesc = struct
-		opt	: char
-		arg	: byte[:]
-		desc	: byte[:]
-		optional	: bool
-	;;
-
-	type optparsed = struct
-		opts	: (char, byte[:])[:]
-		args	: byte[:][:]
-	;;
-
-	const optparse	: (optargs : byte[:][:], def : optdef# -> optparsed)
-	const optusage	: (prog : byte[:], def : optdef# -> void)
-;;
-
-type optctx = struct
-	/* public variables */
-	args	: byte[:][:]
-
-	/* data passed in */
-	optdef	: optdef#
-	optargs	: byte[:][:]
-
-	/* state */
-	argidx	: size
-	curarg	: byte[:]
-	optdone	: bool	/* if we've seen '--', everything's an arg */
-	finished	: bool	/* if we've processed all the optargs */
-;;
-
-
-const optparse = {args, def
-	var ctx : optctx
-	var parsed
-
-	parsed = [
-		.opts=[][:],
-		.args=[][:]
-	]
-	optinit(&ctx, args, def)
-	while !optdone(&ctx)
-		parsed.opts = slpush(parsed.opts, optnext(&ctx))
-	;;
-	if ctx.args.len < def.minargs
-		put("error: expected at least {} args, got {}\n", def.minargs, ctx.args.len)
-		optusage(ctx.optargs[0], ctx.optdef)
-		exit(1)
-	;;
-	if def.maxargs > 0 && ctx.args.len < def.minargs
-		put("error: expected at most {} args, got {}\n", def.minargs, ctx.args.len)
-		optusage(ctx.optargs[0], ctx.optdef)
-		exit(1)
-	;;
-	if def.noargs && ctx.args.len != 0
-		put("error: expected no args, got {}\n", ctx.args.len)
-		optusage(ctx.optargs[0], ctx.optdef)
-		exit(1)
-	;;
-	parsed.args = ctx.args
-	-> parsed
-}
-
-const optinit = {ctx, args, def
-	ctx# = [
-		.optargs = args,
-		.optdef = def,
-		.optdone = false,
-		.finished = false,
-		.argidx = 0,
-		.curarg = [][:],
-		.args = [][:],
-	]
-
-	next(ctx)
-	-> ctx
-}
-
-const optnext = {ctx
-	var c
-	var arg
-
-	(c, ctx.curarg) = striter(ctx.curarg)
-
-	match optinfo(ctx, c)
-	| `None:
-		if c == 'h' || c == '?'
-			optusage(ctx.optargs[0], ctx.optdef)
-			exit(0)
-		else
-			fatal("unexpected argument '{}'\n", c)
-		;;
-	| `Some (true, needed):
-		/* -arg => '-a' 'rg' */
-		if ctx.curarg.len > 0
-			arg = ctx.curarg
-			ctx.curarg = ctx.curarg[ctx.curarg.len:]
-			next(ctx)
-		/* '-a rg' => '-a' 'rg' */
-		elif ctx.argidx < (ctx.optargs.len - 1)
-			arg = ctx.optargs[ctx.argidx + 1]
-			ctx.argidx++
-			next(ctx)
-		elif needed
-			put("Expected argument for {}\n", c)
-			exit(1)
-		;;
-	| `Some (false, _):
-		arg = ""
-		if ctx.curarg.len == 0
-			next(ctx)
-		;;
-	;;
-
-
-	-> (c, arg)
-}
-
-const optdone = {ctx
-	-> ctx.curarg.len == 0 && ctx.finished
-}
-
-const optinfo = {ctx, opt
-	for o in ctx.optdef.opts
-		if o.opt == opt
-			-> `Some (o.arg.len != 0, !o.optional)
-		;;
-	;;
-	-> `None
-}
-
-const next = {ctx
-	var i
-
-	for i = ctx.argidx + 1; i < ctx.optargs.len; i++
-		if !ctx.optdone && decode(ctx.optargs[i]) == '-'
-			if sleq(ctx.optargs[i], "--")
-				ctx.optdone = true
-			else
-				goto foundopt
-			;;
-		else
-			ctx.args = slpush(ctx.args, ctx.optargs[i])
-		;;
-	;;
-:finishedopt
-	ctx.finished = true
-	-> false
-:foundopt
-	ctx.argidx = i
-	ctx.curarg = ctx.optargs[i][1:]
-	-> true
-}
-
-const optusage = {prog, def
-	var sb, s
-
-	sb = mksb()
-	std.sbfmt(sb, "usage: {} [-h?", prog)
-	for o in def.opts
-		if o.arg.len == 0
-			std.sbfmt(sb, "{}", o.opt)
-		;;
-	;;
-	std.sbfmt(sb, "] ")
-	for o in def.opts
-		if o.arg.len != 0
-			std.sbfmt(sb, "[-{} {}] ", o.opt, o.arg)
-		;;
-	;;
-	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
-		std.sbfmt(sb, "\t-{}{}{}\t{}\n", o.opt, sep(o.arg), o.arg, o.desc)
-	;;
-	s = sbfin(sb)
-	write(1, s)
-	slfree(s)
-}
-
-const sep = {s
-	if s.len > 0
-		-> " "
-	else
-		-> ""
-	;;
-}
--- a/libstd/pathjoin.myr
+++ /dev/null
@@ -1,105 +1,0 @@
-use "alloc.use"
-use "extremum.use"
-use "strjoin.use"
-use "strsplit.use"
-use "sleq.use"
-use "sljoin.use"
-use "sldup.use"
-use "slcp.use"
-use "die.use"
-use "fmt.use"
-
-pkg std =
-	const pathcat	: (a : byte[:], b : byte[:] -> byte[:])
-	const pathjoin	: (p : byte[:][:] -> byte[:])
-	const pathnorm	: (p : byte[:] -> byte[:])
-;;
-
-const pathcat = {a, b
-	-> pathjoin([a, b][:])
-}
-
-const pathjoin = {l
-	var p, i, q
-
-	for i = 0; i < l.len; i++
-		if l[i].len != 0
-			break
-		;;
-	;;
-	p = strjoin(l[i:], "/")
-	q = pathnorm(p)
-	slfree(p)
-	-> q
-}
-
-const pathnorm = {p
-	var comps
-	var i, del, dst
-	var s, ret
-
-	comps = strsplit(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.
-	*/
-	for i = 0; i < comps.len; i++
-		if sleq(comps[i], ".")
-			comps[i] = ""
-		;;
-	;;
-
-	/*
-	then, resolve '..' by cancelling out previous components. Scan
-	backwards in the component list for the first real component,
-	and delete both it and the '..' that lead to it.
-	
-	Leave in extra '..' components, so that, eg, ../foo doesn't
-	get mangled.
-	*/
-	for i = 0; i < comps.len; i++
-		if !sleq(comps[i], "..")
-			continue
-		;;
-		for del = 1; del <= i; del++
-			if comps[i - del].len > 0 && !sleq(comps[i-del], "..")
-				comps[i - del] = ""
-				comps[i] = ""
-				break
-			;;
-		;;
-	;;
-
-	/* clear out the path nodes we decided to drop */
-	dst = 0
-	for i = 0; i < comps.len; i++
-		if comps[i].len > 0
-			comps[dst++] = comps[i]
-		;;
-	;;
-	comps = comps[:dst]
-
-	/*
-	and reassemble. If we have an absolute path,
-	make it absolute. If we have an empty path, return
-	".". Otherwise, just return the path.
-	*/
-	if p.len > 0 && sleq(p[:1], "/")
-		for i = 0; i < comps.len; i++
-			if !sleq(comps[i], "..")
-				break
-			;;
-		;;
-		s = strjoin(comps[i:], "/")
-		ret = fmt("/{}", s)
-		slfree(s)
-	elif comps.len == 0
-		ret = sldup(".")
-	else
-		ret = strjoin(comps, "/")
-	;;
-	slfree(comps)
-	-> ret
-}
-
--- a/libstd/putint.myr
+++ /dev/null
@@ -1,44 +1,0 @@
-use "types.use"
-use "die.use"
-
-pkg std =
-	generic putle64	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putbe64	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putle32	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putbe32	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putle16	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putbe16	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putle8	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-	generic putbe8	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
-;;
-
-generic putle64	= {buf, v;	-> putle(buf, v castto(uint64), 8)}
-generic putbe64	= {buf, v;	-> putbe(buf, v castto(uint64), 8)}
-generic putle32	= {buf, v;	-> putle(buf, v castto(uint64), 4)}
-generic putbe32	= {buf, v;	-> putbe(buf, v castto(uint64), 4)}
-generic putle16	= {buf, v;	-> putle(buf, v castto(uint64), 2)}
-generic putbe16	= {buf, v;	-> putbe(buf, v castto(uint64), 2)}
-generic putle8	= {buf, v;	-> putle(buf, v castto(uint64), 1)}
-generic putbe8	= {buf, v;	-> putbe(buf, v castto(uint64), 1)}
-
-const putbe = {buf, val, n
-	var i, k
-	
-	assert(buf.len >= n, "buffer too small")
-	for i = 0; i < n; i++
-		k = val >> (8*(n-i-1))
-		buf[i] = (k & 0xff) castto(byte)
-	;;
-	-> n castto(size)
-}
-
-const putle = {buf, val, n
-	var i
-
-	assert(buf.len >= n, "buffer too small")
-	for i = 0; i < n; i++
-		buf[i] = (val & 0xff) castto(byte)
-		val >>= 8
-	;;
-	-> n castto(size)
-}
--- a/libstd/rand.myr
+++ /dev/null
@@ -1,185 +1,0 @@
-use "die.use"
-use "types.use"
-use "alloc.use"
-/*
-   Translated from C by Ori Bernstein
- */
-
-/* 
-  A C-program for MT19937, with initialization improved 2002/1/26.
-  Coded by Takuji Nishimura and Makoto Matsumoto.
-  
-  Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
-  All rights reserved.                          
-  
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-  
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
- 
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
- 
-    3. The names of its contributors may not be used to endorse or promote 
-       products derived from this software without specific prior written 
-       permission.
- 
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- 
-  Any feedback is very welcome.
-  http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
-  email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
- */
-
-pkg std =
-	type rng
-
-	const mksrng	: (seed : uint32 -> rng#)
-	const delrng	: (rng : rng# -> void)
-	generic rand	: (rng : rng#, lo : @a::(numeric,integral), hi : @a::(numeric,integral) -> @a::(numeric,integral))
-	generic randN	: (rng : rng# -> @a::(numeric,integral))
-	const randbytes	: (rng : rng#, buf : byte[:]	-> size)
-	const rand32	: (rng : rng# -> uint32)
-;;
-
-type rng = struct
-	state	: uint32[624]
-	i	: uint32
-;;
-
-/* allocates and initializes a random number generator */
-const mksrng = {seed
-	var rng
-
-	rng = alloc()
-	init(rng, seed)
-	-> rng
-}
-
-const delrng = {rng
-	free(rng)
-}
-
-/* initializes a random number generator from the seed `seed`. */
-const init = {rng, seed
-	var i
-
-	for i = 0; i < 624; i++
-		rng.state[i] = seed
-		seed = 1812433253 * (seed ^ (seed >> 30)) + i + 1
-	;;
-	rng.i = i
-}
-
-/*
-   Generates a random integer from `rng` in the range [lo, hi),
-   returning the value. The range [lo, hi) must be positive,
-   nonempty, and the difference between hi and lo must be
-   less then 2^(type_bits - 1)
-*/
-generic rand = {rng, lo, hi -> @a::(integral,numeric)
-	var span, lim
-	var maxrand
-	var val
-
-	assert(hi - lo > 0, "rand.myr: range for random values must be >= 1")
-
-	span = hi - lo
-	maxrand = (1 << (8*sizeof(@a))) - 1 /* max for signed value */
-	if maxrand < 0 /* signed */
-		maxrand = (1 << (8*sizeof(@a)-1)) - 1 /* max for signed value */
-	;;
-
-	lim = (maxrand/span)*span
-	val = (randN(rng) & maxrand)
-	while val > lim 
-		val = (randN(rng) & maxrand)
-	;;
-	-> val % span + lo
-}
-
-/*
-   Generates a random integer of any size from the
-   random number generator `rng`. The returned value
-   may be negative, if the type is signed.
-*/
-generic randN = {rng -> @a::(integral,numeric)
-	var i, val
-
-	val = 0
-	for i = 0; i < sizeof(@a)/4; i++
-		val <<= 8*sizeof(@a)
-		val |= rand32(rng) castto(@a::(integral,numeric))
-	;;
-	-> val
-}
-
-/*
-   generates a 32 bit unsigned random number
-   from the random number generator `rng`.
-*/
-const rand32 = {rng
-	var x
-
-	if rng.i == 624
-		next(rng)
-	;;
-	x = rng.state[rng.i]
-	rng.i++
-
-	x ^= x >> 11
-	x ^= (x << 7) & 0x9D2C5680
-	x ^= (x << 15) & 0xEFC60000
-	-> x ^ (x >> 18)
-}
-
-const randbytes = {rng, buf
-	var i, n, r
-
-	n = 0
-	for i = 0; i < buf.len/4; i++
-		r = rand32(rng)
-		buf[n++] = (r >>  0 & 0xff) castto(byte)
-		buf[n++] = (r >>  8 & 0xff) castto(byte)
-		buf[n++] = (r >> 16 & 0xff) castto(byte)
-		buf[n++] = (r >> 32 & 0xff) castto(byte)
-	;;
-	r = rand32(rng)
-	for ; n != buf.len; n++
-		buf[n++] = (r & 0xff) castto(byte)
-		r >>= 8
-	;;
-	-> n
-
-}
-
-/* updates random number generator state when we tick over. */
-const next = {rng
-	var k
-	var y
-
-	for k = 0; k < 227; k++
-		y = (rng.state[k] & 0x80000000) | (rng.state[k + 1] & 0x7FFFFFFF)
-		rng.state[k] = rng.state[k + 397] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF)
-	;;
-	for ; k < 623; k++
-		y = (rng.state[k] & 0x80000000) | (rng.state[k + 1] & 0x7FFFFFFF)
-		rng.state[k] = rng.state[k - 227] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF);
-	;;
-	y = (rng.state[623] & 0x80000000) | (rng.state[0] & 0x7FFFFFFF)
-	rng.state[623] = rng.state[396] ^ (y >> 1) ^ ((y & 1) * 0x9908B0DF);
-	rng.i = 0
-}
--- a/libstd/resolve+plan9.myr
+++ /dev/null
@@ -1,2 +1,0 @@
-pkg std =
-;;
--- a/libstd/resolve+posixy.myr
+++ /dev/null
@@ -1,443 +1,0 @@
-use sys
-use "alloc.use"
-use "chartype.use"
-use "die.use"
-use "endian.use"
-use "result.use"
-use "extremum.use"
-use "hashfuncs.use"
-use "htab.use"
-use "ipparse.use"
-use "option.use"
-use "slcp.use"
-use "sleq.use"
-use "slpush.use"
-use "slurp.use"
-use "strfind.use"
-use "strsplit.use"
-use "strstrip.use"
-use "types.use"
-use "utf.use"
-
-pkg std =
-	type rectype = uint16
-
-	const DnsA	: rectype = 1  /* host address */
-	const DnsNS	: rectype = 2  /* authoritative name server */
-	const DnsMD	: rectype = 3  /* mail destination (Obsolete - use MX) */
-	const DnsMF	: rectype = 4  /* mail forwarder (Obsolete - use MX) */
-	const DnsCNAME	: rectype = 5  /* canonical name for an alias */
-	const DnsSOA	: rectype = 6  /* marks the start of a zone of authority */
-	const DnsMB	: rectype = 7  /* mailbox domain name (EXPERIMENTAL) */
-	const DnsMG	: rectype = 8  /* mail group member (EXPERIMENTAL) */
-	const DnsMR	: rectype = 9  /* mail rename domain name (EXPERIMENTAL) */
-	const DnsNULL	: rectype = 10 /* null RR (EXPERIMENTAL) */
-	const DnsWKS	: rectype = 11 /* well known service description */
-	const DnsPTR	: rectype = 12 /* domain name pointer */
-	const DnsHINFO	: rectype = 13 /* host information */
-	const DnsMINFO	: rectype = 14 /* mailbox or mail list information */
-	const DnsMX	: rectype = 15 /* mail exchange */
-	const DnsTXT	: rectype = 16 /* text strings */
-	const DnsAAAA	: rectype = 28 /* ipv6 host address */
-
-
-	type resolveerr = union
-		`Badhost
-		`Badsrv
-		`Badquery
-		`Badresp
-	;;
-
-	type hostinfo = struct
-		fam	: sys.sockfam
-		stype	: sys.socktype
-		ttl	: uint32
-		addr	: netaddr
-	/*
-		flags	: uint32
-		addr	: sockaddr[:]
-		canon	: byte[:]
-	*/
-	;;
-
-	const resolve	: (host : byte[:]	-> result(hostinfo[:], resolveerr))
-	const resolvemx	: (host : byte[:]	-> result(hostinfo[:], resolveerr))
-	const resolverec	: (host : byte[:], t : rectype	-> result(hostinfo[:], resolveerr))
-;;
-
-const Hostfile = "/etc/hosts"
-const Resolvfile = "/etc/resolv.conf"
-
-var hostmap	: htab(byte[:], hostinfo)#
-var search	: byte[:][:]
-var nameservers	: netaddr[:]
-
-const __init__ = {
-	hostmap = mkht(strhash, streq)
-	loadhosts()
-	loadresolv()
-}
-
-const resolve = {host
-	-> resolverec(host, DnsA)
-}
-
-const resolvemx = {host
-	-> resolverec(host, DnsMX)
-}
-
-const resolverec = {host, t
-	match hostfind(host)
-	| `Some hinf:
-		-> `Ok slpush([][:], hinf)
-	| `None:
-		-> dnsresolve(host, DnsA)
-	;;
-}
-
-const hostfind = {host
-	-> htget(hostmap, host)
-}
-
-const loadhosts = {
-	var h
-	var lines
-
-	match slurp(Hostfile)
-	| `Ok d:	h = d
-	| `Fail m:	->
-	;;
-
-	lines = strsplit(h, "\n")
-	for l in lines
-		/* trim comment */
-		match strfind(l, "#")
-		| `Some idx:	l = l[:idx]
-		| `None:	/* whole line */
-		;;
-
-		match word(l)
-		| `Some (ip, rest):
-			match ipparse(ip)
-			| `Some addr:
-				addhosts(addr, ip, rest)
-			| `None:
-				/*
-				invalid addresses are ignored: we don't want to break stuff
-				with invalid or unsupported addresses
-				*/
-				
-			;;
-		| `None:
-		;;
-	;;
-	slfree(lines)
-}
-
-const addhosts = {addr, as, str
-	var hinf
-	var fam
-
-	match addr
-	| `Ipv4 _:	fam = sys.Afinet
-	| `Ipv6 _:	fam = sys.Afinet6
-	;;
-	while true
-		match word(str)
-		| `Some (name, rest):
-			str = rest
-			if hthas(hostmap, name)
-				continue
-			;;
-			hinf = [
-				.fam=fam,
-				.stype = 0,
-				.ttl = 0,
-				.addr = addr
-			]
-			htput(hostmap, name, hinf)
-		| `None:
-			->
-		;;
-	;;
-}
-
-const loadresolv = {
-	var h
-	var lines
-
-	match slurp(Resolvfile)
-	| `Ok d:	h = d
-	| `Fail m:	->
-	;;
-
-	lines = strsplit(h, "\n")
-	for l in lines
-		match strfind(l, "#")
-		| `Some _idx: l = l[:_idx]
-		| `None:
-		;;
-
-		match word(l)
-		| `Some ("nameserver", srv):
-			addns(srv)
-		| `Some (_, rest):
-			/* invalid or unrecognized commands */
-		| `None:
-			/* unrecognized lines */
-		;;
-	;;
-	slfree(lines)
-}
-
-const addns = {rest
-	match word(rest)
-	| `Some (name, _):
-		match ipparse(name)
-		| `Some addr: 
-			nameservers = slpush(nameservers, addr)
-		| `None:
-			/* nothing */
-		;;
-	| `None:
-		/* nothing */
-	;;
-}
-
-const word = {s
-	var c, len
-
-	len = 0
-	s = strfstrip(s)
-	for c = decode(s[len:]); c != Badchar && !isblank(c); c = decode(s[len:])
-		len += charlen(c)
-	;;
-	if len == 0
-		-> `None
-	else
-		-> `Some (s[:len], s[len:])
-	;;
-}
-
-
-const dnsresolve = {host, t
-	var nsrv
-
-	if !valid(host)
-		-> `Fail (`Badhost)
-	;;
-	for ns in nameservers
-		nsrv = dnsconnect(ns)
-		if nsrv >= 0
-			-> dnsquery(nsrv, host, t)
-		;;
-	;;
-	-> `Fail (`Badsrv)
-}
-
-const dnsconnect = {ns
-	match ns
-	| `Ipv4 addr:	-> dnsconnectv4(addr)
-	| `Ipv6 addr:	die("don't support ipv6 yet\n")
-	;;
-}
-
-const dnsconnectv4 = {addr
-	var sa : sys.sockaddr_in
-	var s
-	var status
-
-	s = sys.socket(sys.Afinet, sys.Sockdgram, 0)
-	if s < 0
-		-> -1
-	;;
-	sa.fam = sys.Afinet
-	sa.port = hosttonet(53)
-	sa.addr = addr
-	status = sys.connect(s, (&sa) castto(sys.sockaddr#), sizeof(sys.sockaddr_in))
-	if status < 0
-		-> -1
-	;;
-	-> s
-}
-
-const dnsquery = {srv, host, t
-	var id
-	var r
-
-	id = tquery(srv, host, t)
-	r = rquery(srv, id)
-	-> r
-}
-
-const Qr : uint16 = 1 << 0
-const Aa : uint16 = 1 << 5
-const Tc : uint16 = 1 << 6
-const Rd : uint16 = 1 << 7
-const Ra : uint16 = 1 << 8
-
-var nextid : uint16 = 42
-const tquery = {srv, host, t
-	var pkt : byte[512] /* big enough */
-	var off : size
-
-	/* header */
-	off = 0
-	off += pack16(pkt[:], off, nextid)	/* id */
-	off += pack16(pkt[:], off, Ra)	/* flags */
-	off += pack16(pkt[:], off, 1)	/* qdcount */
-	off += pack16(pkt[:], off, 0)	/* ancount */
-	off += pack16(pkt[:], off, 0)	/* nscount */
-	off += pack16(pkt[:], off, 0)	/* arcount */
-
-	/* query */
-	off += packname(pkt[:], off, host)	/* host */
-	off += pack16(pkt[:], off, t castto(uint16)) /* qtype: a record */
-	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
-
-	sys.write(srv, pkt[:off])
-	-> nextid++
-}
-
-const rquery = {srv, id
-	var pktbuf : byte[1024]
-	var pkt
-	var n
-
-	n = sys.read(srv, pktbuf[:])
-	if n < 0
-	;;
-	pkt = pktbuf[:n]
-	-> hosts(pkt, id)
-}
-
-const hosts = {pkt, id : uint16
-	var off
-	var v, q, a
-	var i
-	var hinf : hostinfo[:]
-
-	off = 0
-	/* parse header */
-	(v, off) = unpack16(pkt, off)	/* id */
-	if v != id
-		-> `Fail (`Badresp)
-	;;
-	(v, off) = unpack16(pkt, off)	/* flags */
-	(q, off) = unpack16(pkt, off)	/* qdcount */
-	(a, off) = unpack16(pkt, off)	/* ancount */
-	(v, off) = unpack16(pkt, off)	/* nscount */
-	(v, off) = unpack16(pkt, off)	/* arcount */
-
-	/* skip past query records */
-	for i = 0; i < q; i++
-		off = skipname(pkt, off)	/* name */
-		(v, off) = unpack16(pkt, off)	/* type */
-		(v, off) = unpack16(pkt, off)	/* class */
-	;;
-
-	/* parse answer records */
-	hinf = slalloc(a castto(size))
-	for i = 0; i < a; i++
-		off = skipname(pkt, off)	/* name */
-		(v, off) = unpack16(pkt, off)	/* type */
-		(v, off) = unpack16(pkt, off)	/* class */
-		(hinf[i].ttl, off) = unpack32(pkt, off)	/* ttl */
-		(v, off) = unpack16(pkt, off)	/* rdatalen */
-		/* the thing we're interested in: our IP address */
-		hinf[i].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
-		off += 4;
-	;;
-	-> `Ok hinf
-}
-
-
-const skipname = {pkt, off
-	var sz
-
-	for sz = pkt[off] castto(size); sz != 0; sz = pkt[off] castto(size)
-		/* ptr is 2 bytes */
-		if sz & 0xC0 == 0xC0
-			-> off + 2
-		else
-			off += sz + 1
-		;;
-	;;
-	-> off + 1
-}
-
-
-const pack16 = {buf, off, v
-	buf[off]	= (v & 0xff00) >> 8 castto(byte)
-	buf[off+1]	= (v & 0x00ff) castto(byte)
-	-> sizeof(uint16) /* we always write one uint16 */
-}
-
-const unpack16 = {buf, off
-	var v
-
-	v = (buf[off] castto(uint16)) << 8
-	v |= (buf[off + 1] castto(uint16))
-	-> (v, off+sizeof(uint16))
-}
-
-const unpack32 = {buf, off
-	var v
-
-	v = (buf[off] castto(uint32)) << 24
-	v |= (buf[off+1] castto(uint32)) << 32
-	v |= (buf[off+2] castto(uint32)) << 8
-	v |= (buf[off+3] castto(uint32))
-	-> (v, off+sizeof(uint32))
-}
-
-const packname = {buf, off : size, host
-	var i
-	var start
-	var last
-
-	start = off
-	last = 0
-	for i = 0; i < host.len; i++
-		if host[i] == ('.' castto(byte))
-			off += addseg(buf, off, host[last:i])
-			last = i + 1
-		;;
-	;;
-	if host[host.len - 1] != ('.' castto(byte))
-		off += addseg(buf, off, host[last:])
-	;;
-	off += addseg(buf, off, "") /* null terminating segment */
-	-> off - start
-}
-
-const addseg = {buf, off, str
-	buf[off] = str.len castto(byte)
-	slcp(buf[off + 1 : off + str.len + 1], str)
-	-> str.len + 1
-}
-
-const valid = {host : byte[:]
-	var i
-	var seglen
-
-	/* maximum length: 255 chars */
-	if host.len > 255
-		-> false
-	;;
-
-	seglen = 0
-	for i = 0; i < host.len; i++
-		if host[i] == ('.' castto(byte))
-			seglen = 0
-		;;
-		if seglen > 63
-			-> false
-		;;
-		if host[i] & 0x80 != 0
-			-> false
-		;;
-	;;
-
-	-> true
-}
--- a/libstd/result.myr
+++ /dev/null
@@ -1,9 +1,0 @@
-use "die.use"
-
-pkg std =
-	type result(@a, @b) = union
-		`Ok	@a
-		`Fail	@b
-	;;
-;;
-
--- a/libstd/search.myr
+++ /dev/null
@@ -1,43 +1,0 @@
-use "cmp.use"
-use "option.use"
-
-pkg std =
-	generic lsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
-	generic bsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
-;;
-
-/* linear search over a list of values */
-generic lsearch = {sl, val, cmp
-	var i
-
-	for i = 0; i < sl.len; i++
-		match cmp(sl[i], val)
-		| `Equal:
-			-> `Some i
-		| _:
-			/* nothing */
-		;;
-	;;
-	-> `None
-}
-
-/* binary search over a sorted list of values. */
-generic bsearch  = {sl, val, cmp
-	var hi, lo, mid
-
-	lo = 0
-	hi = sl.len - 1
-
-	while lo <= hi
-		mid = (hi + lo) / 2
-		match cmp(val, sl[mid])
-		| `Before:	hi = mid - 1
-		| `After:	lo = mid + 1
-		| `Equal:	
-			-> `Some mid
-		;;
-	;;
-	-> `None
-}
-		
-
--- a/libstd/slcp.myr
+++ /dev/null
@@ -1,26 +1,0 @@
-use "die.use"
-use "types.use"
-
-pkg std =
-	generic slcp : (a : @a[:], b : @a[:] -> void)
-;;
-
-generic slcp = {a : @a[:], b : @a[:]
-	var i
-	var addr_a, addr_b
-
-	assert(a.len == b.len, "arguments to slcp() must be of equal length")
-
-	addr_a = a castto(@a#) castto(intptr)
-	addr_b = b castto(@a#) castto(intptr)
-	if addr_a <= addr_b
-		for i = 0; i < a.len; i++
-			a[i] = b[i]
-		;;
-	else
-		for i = a.len; i > 0; i--
-			a[i - 1] = b[i - 1]
-		;;
-	;;
-		
-}
--- a/libstd/sldup.myr
+++ /dev/null
@@ -1,15 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "slcp.use"
-
-pkg std =
-	generic sldup : (sl : @a[:] -> @a[:])
-;;
-
-generic sldup = {sl
-	var ret
-
-	ret = slalloc(sl.len)
-	slcp(ret, sl)
-	-> ret
-}
--- a/libstd/sleq.myr
+++ /dev/null
@@ -1,18 +1,0 @@
-pkg std =
-	generic sleq	: (a : @a[:], b : @a[:] -> bool)
-;;
-
-generic sleq = {a, b
-	var i
-
-	if a.len != b.len
-		-> false
-	;;
-
-	for i = 0; i < a.len; i++
-		if a[i] != b[i]
-			-> false
-		;;
-	;;
-	-> true
-}
--- a/libstd/slfill.myr
+++ /dev/null
@@ -1,12 +1,0 @@
-pkg std =
-	generic slfill	: (sl : @a[:], v : @a	-> @a[:])
-;;
-
-generic slfill = {sl, v
-	var i
-
-	for i = 0; i < sl.len; i++
-		sl[i] = v
-	;;
-	-> sl
-}
--- a/libstd/sljoin.myr
+++ /dev/null
@@ -1,15 +1,0 @@
-use "alloc.use"
-use "slcp.use"
-
-pkg std =
-	generic sljoin	: (dst : @a[:], src : @a[:]	-> @a[:])
-;;
-
-generic sljoin = {dst, src
-	var len
-
-	len = dst.len
-	dst = slgrow(dst, len + src.len)
-	slcp(dst[len:], src)
-	-> dst 
-}
--- a/libstd/slpush.myr
+++ /dev/null
@@ -1,20 +1,0 @@
-use "types.use"
-use "alloc.use"
-
-pkg std =
-	generic slpush	: (sl : @a[:], elt : @a	-> @a[:])
-;;
-
-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.
-	*/
-	sl = slgrow(sl, sl.len + 1)
-	sl[sl.len - 1] = elt
-	-> sl
-}
--- a/libstd/slput.myr
+++ /dev/null
@@ -1,20 +1,0 @@
-use "types.use"
-use "alloc.use"
-use "die.use"
-
-pkg std =
-	generic slput	: (sl : @a[:], idx : size, elt : @a	-> @a[:])
-;;
-
-generic slput = {sl, idx, elt
-	var i
-	var len
-
-	len = sl.len
-	sl = slgrow(sl, sl.len + 1)
-	for i = len - 1; i >= idx; i--
-		sl[i + 1] = sl[i]
-	;;
-	sl[idx] = elt
-	-> sl
-}
--- a/libstd/slurp.myr
+++ /dev/null
@@ -1,43 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "result.use"
-use "extremum.use"
-use "syswrap.use"
-use "types.use"
-
-pkg std =
-	const slurp : (path : byte[:] -> result(byte[:], byte[:]))
-	const fslurp : (path : fd -> result(byte[:], byte[:]))
-;;
-
-const Bufstart = 4096
-
-const slurp = {path
-	var fd
-	fd = open(path, Ordonly)
-	if fd < 0
-		-> `Fail "Could not open file"
-	;;
-	-> fslurp(fd)
-}
-
-const fslurp = {fd
-	var len, bufsz
-	var buf
-	var n
-
-	len = 0
-	bufsz = Bufstart
-	buf = slalloc(bufsz)
-	while true
-		n = read(fd, buf[len:])
-		if n <= 0
-			goto done
-		;;
-		len += n
-		bufsz *= 2
-		buf = slgrow(buf, bufsz)
-	;;
-:done
-	-> `Ok buf[:len]
-}
--- a/libstd/sort.myr
+++ /dev/null
@@ -1,61 +1,0 @@
-use "cmp.use"
-
-pkg std =
-	generic sort	: (sl:@a[:], cmp:(a:@a, b:@a -> order) -> @a[:])
-;;
-
-generic sort = {sl, cmp
-	var end
-	var tmp
-
-	heapify(sl, cmp)
-	end = sl.len - 1
-	while end > 0
-		tmp = sl[end]
-		sl[end] = sl[0]
-		sl[0] = tmp
-		end--
-		siftdown(sl[:end + 1], 0, cmp)
-	;;
-	-> sl
-}
-
-generic heapify = {sl, cmp
-	var start
-
-	start = sl.len/2 - 1
-	while start >= 0
-		siftdown(sl, start, cmp)
-		start--
-	;;
-}
-
-generic siftdown = {sl, start, cmp
-	var r, c, s
-	var tmp
-
-	r = start
-	while 2*r + 1 < sl.len
-		c = 2*r + 1
-		s = r
-		match cmp(sl[s], sl[c])
-		| `Before:	s = c
-		| _:		/* nothing */
-		;;
-		if c + 1 < sl.len
-			match cmp(sl[s], sl[c + 1])
-			| `Before:	s = c + 1
-			| _:	/* nothing */
-			;;
-		;;
-		if s != r
-			tmp = sl[r]
-			sl[r] = sl[s]
-			sl[s] = tmp
-			r = s
-		else
-			->
-		;;
-	;;
-}
-
--- a/libstd/spork.myr
+++ /dev/null
@@ -1,62 +1,0 @@
-use "die.use"
-use "execvp.use"
-use "fmt.use"
-use "result.use"
-use "syswrap.use"
-
-pkg std =
-	const spork	: (cmd : byte[:][:]	-> result((pid, fd, fd), int))
-	const sporkfd	: (cmd : byte[:][:], infd : fd, outfd : fd	-> result(pid, int))
-;;
-
-const spork = {cmd
-	var infds  :fd[2], outfds : fd[2]
-	var err
-
-	/* open up pipes */
-	err = pipe(&infds)
-	if err != 0
-		-> `Fail (-err castto(int))
-	;;
-	err = pipe(&outfds)
-	if err != 0
-		-> `Fail (-err castto(int))
-	;;
-
-	match sporkfd(cmd, infds[0] castto(fd), outfds[1] castto(fd))
-	| `Ok pid:
-		/* close unused fd ends */
-		close(infds[0]);
-		close(outfds[1]);
-		-> `Ok (pid, infds[1], outfds[0])
-	| `Fail m:
-		-> `Fail m
-	;;
-}
-
-const sporkfd = {cmd, infd, outfd
-	var pid
-
-	pid = fork()
-	/* error  */
-	if pid == -1
-		-> `Fail -1
-	/* child */
-	elif pid == 0
-		/* stdin/stdout for our communication. */
-		if dup2(infd castto(fd), 0) != 0
-			fatal("unable to set stdin\n")
-		;;
-		if dup2(outfd castto(fd), 1) != 1
-			fatal("unable to set stdout\n")
-		;;
-		close(infd)
-		close(outfd)
-		execvp(cmd[0], cmd) < 0
-		fatal("failed to exec {}\n", cmd[0])
-	/* parent */
-	else
-		-> `Ok pid
-	;;
-}
-
--- a/libstd/strbuf.myr
+++ /dev/null
@@ -1,107 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "slcp.use"
-use "types.use"
-use "utf.use"
-
-pkg std =
-	type strbuf = struct
-		buf	: byte[:]
-		len	: size
-		fixed	: bool
-	;;
-
-	const mksb	: (-> strbuf#)
-	const mkbufsb	: (buf : byte[:] -> strbuf#)
-	const sbfin	: (sb : strbuf# -> byte[:])
-	const sbfree	: (sb : strbuf# -> void)
-	const sbpeek	: (sb : strbuf# -> byte[:])
-
-	const sbputc	: (sb : strbuf#, v : char -> bool)
-	const sbputs	: (sb : strbuf#, v : byte[:] -> bool)
-	const sbputb	: (sb : strbuf#, v : byte -> bool)
-	const sbtrim	: (sb : strbuf#, len : size -> void)
-;;
-
-const mksb = {
-	var sb
-	sb = zalloc()
-	sb.buf = slalloc(1)
-	-> sb
-}
-
-const mkbufsb = {buf
-	var sb
-
-	sb = zalloc()
-	sb.buf = buf
-	sb.fixed = true
-	-> sb
-}
-
-const sbfin = {sb
-	var sl
-
-	sl = sb.buf[:sb.len]
-	free(sb)
-	-> sl
-}
-
-const sbfree = {sb
-	if !sb.fixed
-		slfree(sb.buf)
-	;;
-	free(sb)
-}
-
-
-const sbpeek = {sb : strbuf#
-	-> sb.buf[:sb.len]
-}
-
-const sbputc = {sb, v
-	if !ensure(sb, charlen(v))
-		-> false
-	;;
-	sb.len += encode(sb.buf[sb.len:], v)
-	-> true
-}
-const sbputs = {sb, v
-	var ok
-	var len
-
-	ok = ensure(sb, v.len)
-	/* copy what we can */
-	len = min(sb.buf.len - sb.len, v.len)
-	slcp(sb.buf[sb.len:sb.len + len], v[:len])
-	sb.len += len
-	-> ok
-}
-const sbputb = {sb, v
-	if !ensure(sb, 1)
-		-> false
-	;;
-	sb.buf[sb.len++] = v
-	-> true
-}
-
-const sbtrim = {sb, len
-	assert(abs(len) <= sb.len, "trim out of range\n")
-	if len < 0
-		sb.len -= abs(len)
-	else
-		sb.len = len
-	;;
-}
-
-const ensure = {sb, len
-	if sb.fixed && sb.len + len > sb.buf.len
-		-> false
-	;;
-	while sb.buf.len < sb.len + len
-		sb.buf = slgrow(sb.buf, 2*sb.buf.len)
-	;;
-	-> true
-}
-
--- a/libstd/strfind.myr
+++ /dev/null
@@ -1,51 +1,0 @@
-use "types.use"
-use "option.use"
-
-pkg std =
-	const strfind	: (haystack : byte[:], needle : byte[:] -> option(size))
-	const strrfind	: (haystack : byte[:], needle : byte[:] -> option(size))
-	const strhas	: (haystack : byte[:], needle : byte[:]	-> bool)
-;;
-
-const strfind = {haystack, needle
-	-> strfindin(haystack, needle, 0, haystack.len)
-}
-
-const strrfind = {haystack, needle
-	-> strfindin(haystack, needle, haystack.len - 1, -1)
-}
-
-const strfindin = {haystack, needle, start, end
-	var i, j, inc : size
-
-	inc = 1
-	if start > end
-		inc = -1
-	;;
-	for i = start; i != end; i += inc
-		/* 
-		if we knew the direction we could terminate early,
-		but we allow the start and end to be passed in.
-		*/
-		if i + needle.len > haystack.len
-			continue
-		;;
-		if haystack[i] == needle[0]
-			for j = 0; j < needle.len; j++
-				if haystack[i + j] != needle[j]
-					goto nextiter
-				;;
-			;;
-			-> `Some i
-		;;
-:nextiter
-	;;
-	-> `None
-}
-
-const strhas = {haystack, needle
-	match strfind(haystack, needle)
-	| `Some _:	-> true
-	| `None:	-> false
-	;;
-}
\ No newline at end of file
--- a/libstd/strjoin.myr
+++ /dev/null
@@ -1,41 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "slcp.use"
-
-pkg std =
-	const strcat	: (a : byte[:], b : byte[:] -> byte[:])
-	const strjoin	: (strings : byte[:][:], delim : byte[:] -> byte[:])
-;;
-
-const strcat = {a, b
-	-> strjoin([a, b][:], "")
-}
-
-const strjoin = {strings, delim
-	var len, off
-	var i
-	var s
-
-	len = 0
-	for i = 0; i < strings.len; i++
-		len += strings[i].len
-	;;
-	if strings.len > 0
-		len += (strings.len - 1)*delim.len
-	;;
-
-	s = slalloc(len)
-	off = 0
-	for i = 0; i < strings.len; i++
-		slcp(s[off:off + strings[i].len], strings[i])
-		off += strings[i].len
-		/* we don't want to terminate the last string with delim */
-		if i != strings.len - 1
-			slcp(s[off:off + delim.len], delim)
-			off += delim.len
-		;;
-	;;
-	-> s
-}
-
-
--- a/libstd/strsplit.myr
+++ /dev/null
@@ -1,35 +1,0 @@
-use "alloc.use"
-use "die.use"
-use "extremum.use"
-use "option.use"
-use "slpush.use"
-use "strfind.use"
-use "types.use"
-
-pkg std =
-	const strsplit	: (s : byte[:], delim : byte[:] -> byte[:][:])
-;;
-
-const strsplit = {s, delim
-	var last
-	var sp
-
-	sp = [][:]
-	if s.len == 0
-		-> sp
-	;;
-	last = 0
-	while true
-		match strfind(s, delim)
-		| `Some i:
-			sp = slpush(sp, s[:i])
-			s = s[i + delim.len:]
-		| `None:
-			goto donesplit
-		;;
-	;;
-:donesplit
-	sp = slpush(sp, s[:])
-	-> sp
-}
-
--- a/libstd/strstrip.myr
+++ /dev/null
@@ -1,43 +1,0 @@
-use "types.use"
-use "utf.use"
-use "chartype.use"
-
-pkg std =
-	const strstrip	: (str : byte[:] -> byte[:])
-	const strfstrip	: (str : byte[:] -> byte[:])
-	const strrstrip	: (str : byte[:] -> byte[:])
-;;
-
-/* strip blanks from both head and tail of str */
-const strstrip = {str
-	-> strrstrip(strfstrip(str))
-}
-
-/* strip forward on str */
-const strfstrip = {str
-	var c
-	
-	for c = decode(str); isblank(c); c = decode(str)
-		str = str[charlen(c):]
-	;;
-	-> str
-
-}
-
-/* strip reverse on str */
-const strrstrip = {str
-	var i
-	var end
-
-	/* scan backwards for start of utf8 char */
-	end = str.len
-	for i = str.len; i != 0; i--
-		if str[i - 1] & 0x80 == 0 || str[i-1] & 0xc0 != 0x80
-			if !isspace(decode(str[i-1:]))
-				break
-			;;
-			end = i - 1
-		;;
-	;;
-	-> str[:end]
-}
--- a/libstd/swap.myr
+++ /dev/null
@@ -1,11 +1,0 @@
-pkg std =
-	generic swap	: (a : @a#, b : @a# -> void)
-;;
-
-generic swap = {a : @a#, b : @a#
-	var t
-
-	t = a#
-	a# = b#
-	b# = t
-}
--- a/libstd/sys+freebsd-x64.myr
+++ /dev/null
@@ -1,805 +1,0 @@
-use "systypes.use"
-
-pkg sys =
-	type scno	= int64 /*syscall*/
-	type fdopt	= int64	/* fd options */
-	type fd		= int64	/* fd */
-	type mprot	= int64	/* memory protection */
-	type mopt	= int64	/* memory mapping options */
-	type socktype	= int64	/* socket type */
-	type sockproto	= int64	/* socket protocol */
-	type sockfam	= uint8	/* socket family */
-	type filemode	= uint16
-	type filetype	= uint8
-
-	type clock = union
-		`Clockrealtime
-		`Clockrealtime_precise
-		`Clockrealtime_fast
-		`Clockmonotonic
-		`Clockmonotonic_precise     
-		`Clockmonotonic_fast
-		`Clockuptime
-		`Clockuptime_precise
-		`Clockuptime_fast
-		`Clockvirtual
-		`Clockprof
-		`Clocksecond
-	;;
-
-	type waitstatus = union
-		`Waitexit int32
-		`Waitsig  int32
-		`Waitstop int32
-	;;
-
-	type timespec = struct
-		sec	: uint64
-		nsec	: uint64 
-	;;
-
-	type timeval = struct
-		sec	: uint64
-		usec	: uint64
-	;;
-
-	type rusage = struct
-		utime	: timeval /* user time */
-		stime	: timeval /* system time */
-		maxrss	: uint64 /* max resident set size*/
-		ixrss	: uint64 /* shared text size */
-		idrss	: uint64 /* unshared data size */
-		isrss	: uint64 /* unshared stack size */
-		minflt	: uint64 /* page reclaims */
-		majflt	: uint64 /* page faults */
-		nswap	: uint64 /* swaps */
-		inblock	: uint64 /* block input ops */
-		oublock	: uint64 /* block output ops */
-		msgsnd	: uint64 /* messages sent */	
-		msgrcv	: uint64 /* messages received */
-		nsignals : uint64 /* signals received */
-		nvcsw	: uint64 /* voluntary context switches */
-		nivcsw	: uint64 /* involuntary context switches */
-	;;
-
-	type statbuf = struct
-		dev	: uint32 
-		ino	: uint32 
-		mode	: filemode
-		nlink	: uint16
-		uid	: uint32
-		gid	: uint32
-		rdev	: uint32
-		atim	: timespec
-		mtim	: timespec
-		ctim	: timespec
-		size	: int64
-		blocks	: int64
-		blksize	: uint32
-		flags	: uint32
-		gen	: uint32
-		lspare	: int32
-		birthtim	: timespec 
-	;;
-
-	type utsname = struct
-		system	: byte[256]
-		node : byte[256] 
-		release : byte[256]
-		version : byte[256]
-		machine : byte[256]
-	;;
-
-	type sockaddr = struct
-		len	: byte
-		fam	: sockfam
-		data	: byte[14] /* what is the *actual* length? */
-	;;
-
-	type sockaddr_in = struct
-		len	: byte
-		fam	: sockfam
-		port	: uint16
-		addr	: byte[4]
-		zero	: byte[8]
-	;;
-
-	type sockaddr_storage = struct
-		len	: byte
-		fam	: sockfam
-		__pad1  : byte[6]
-		__align : int64
-		__pad2  : byte[112]
-	;;	
-	
-	type dirent = struct
-		fileno	: uint32
-		reclen	: uint16
-		ftype	: filetype
-		namelen	: uint8
-		name	: byte[256]	
-	;;	
-
-	/* open options */
-	const Ordonly  	: fdopt = 0x0
-	const Owronly  	: fdopt = 0x1
-	const Ordwr    	: fdopt = 0x2
-	const Oappend  	: fdopt = 0x8
-	const Ocreat   	: fdopt = 0x200
-	const Onofollow	: fdopt = 0x100
-	const Ondelay  	: fdopt = 0x4
-	const Otrunc   	: fdopt = 0x400
-	const Odir	: fdopt = 0x20000
-
-        /* stat modes */	
-	const Sifmt	: filemode = 0xf000
-	const Sififo	: filemode = 0x1000
-	const Sifchr	: filemode = 0x2000
-	const Sifdir	: filemode = 0x4000
-	const Sifblk	: filemode = 0x6000
-	const Sifreg	: filemode = 0x8000
-	const Siflnk	: filemode = 0xa000
-	const Sifsock 	: filemode = 0xc000
-
-	/* mmap protection */
-	const Mprotnone	: mprot = 0x0
-	const Mprotrd	: mprot = 0x1
-	const Mprotwr	: mprot = 0x2
-	const Mprotexec	: mprot = 0x4
-	const Mprotrw	: mprot = 0x3
-
-	/* mmap options */
-	const Mshared	: mopt = 0x1
-	const Mpriv	: mopt = 0x2
-	const Mfixed	: mopt = 0x10
-	const Mfile	: mopt = 0x0
-	const Manon	: mopt = 0x1000
-	const M32bit	: mopt = 0x80000
-
-	/* file types */
-	const Dtunknown	: filetype = 0
-	const Dtfifo	: filetype = 1
-	const Dtchr	: filetype = 2
-	const Dtdir	: filetype = 4
-	const Dtblk	: filetype = 6
-	const Dtreg	: filetype = 8
-	const Dtlnk	: filetype = 10
-	const Dtsock	: filetype = 12
-	const Dtwht	: filetype = 14
-
-	/* socket families. INCOMPLETE. */
-	const Afunspec	: sockfam = 0
-	const Afunix	: sockfam = 1
-	const Afinet	: sockfam = 2
-	const Afinet6	: sockfam = 28
-
-	/* socket types. */
-	const Sockstream	: socktype = 1
-	const Sockdgram		: socktype = 2
-	const Sockraw		: socktype = 3
-	const Sockrdm		: socktype = 4
-	const Sockseqpacket	: socktype = 5
-
-	/* network protocols */
-	const Ipproto_ip	: sockproto = 0
-	const Ipproto_icmp	: sockproto = 1
-	const Ipproto_tcp	: sockproto = 6
-	const Ipproto_udp	: sockproto = 17
-	const Ipproto_raw	: sockproto = 255
-
-	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
-
-	/* syscalls */
-	const Syssyscall                   : scno = 0
-	const Sysexit                      : scno = 1
-	const Sysfork                      : scno = 2
-	const Sysread                      : scno = 3
-	const Syswrite                     : scno = 4
-	const Sysopen                      : scno = 5
-	const Sysclose                     : scno = 6
-	const Syswait4                     : scno = 7
-	const Syslink                      : scno = 9
-	const Sysunlink                    : scno = 10
-	const Syschdir                     : scno = 12
-	const Sysfchdir                    : scno = 13
-	const Sysmknod                     : scno = 14
-	const Syschmod                     : scno = 15
-	const Syschown                     : scno = 16
-	const Sysbreak                     : scno = 17
-	const Sysfreebsd4_getfsstat        : scno = 18
-	const Sysgetpid                    : scno = 20
-	const Sysmount                     : scno = 21
-	const Sysunmount                   : scno = 22
-	const Syssetuid                    : scno = 23
-	const Sysgetuid                    : scno = 24
-	const Sysgeteuid                   : scno = 25
-	const Sysptrace                    : scno = 26
-	const Sysrecvmsg                   : scno = 27
-	const Syssendmsg                   : scno = 28
-	const Sysrecvfrom                  : scno = 29
-	const Sysaccept                    : scno = 30
-	const Sysgetpeername               : scno = 31
-	const Sysgetsockname               : scno = 32
-	const Sysaccess                    : scno = 33
-	const Syschflags                   : scno = 34
-	const Sysfchflags                  : scno = 35
-	const Syssync                      : scno = 36
-	const Syskill                      : scno = 37
-	const Sysgetppid                   : scno = 39
-	const Sysdup                       : scno = 41
-	const Syspipe                      : scno = 42
-	const Sysgetegid                   : scno = 43
-	const Sysprofil                    : scno = 44
-	const Sysktrace                    : scno = 45
-	const Sysgetgid                    : scno = 47
-	const Sysgetlogin                  : scno = 49
-	const Syssetlogin                  : scno = 50
-	const Sysacct                      : scno = 51
-	const Syssigaltstack               : scno = 53
-	const Sysioctl                     : scno = 54
-	const Sysreboot                    : scno = 55
-	const Sysrevoke                    : scno = 56
-	const Syssymlink                   : scno = 57
-	const Sysreadlink                  : scno = 58
-	const Sysexecve                    : scno = 59
-	const Sysumask                     : scno = 60
-	const Syschroot                    : scno = 61
-	const Sysmsync                     : scno = 65
-	const Sysvfork                     : scno = 66
-	const Syssbrk                      : scno = 69
-	const Syssstk                      : scno = 70
-	const Sysvadvise                   : scno = 72
-	const Sysmunmap                    : scno = 73
-	const Sysmprotect                  : scno = 74
-	const Sysmadvise                   : scno = 75
-	const Sysmincore                   : scno = 78
-	const Sysgetgroups                 : scno = 79
-	const Syssetgroups                 : scno = 80
-	const Sysgetpgrp                   : scno = 81
-	const Syssetpgid                   : scno = 82
-	const Syssetitimer                 : scno = 83
-	const Sysswapon                    : scno = 85
-	const Sysgetitimer                 : scno = 86
-	const Sysgetdtablesize             : scno = 89
-	const Sysdup2                      : scno = 90
-	const Sysfcntl                     : scno = 92
-	const Sysselect                    : scno = 93
-	const Sysfsync                     : scno = 95
-	const Syssetpriority               : scno = 96
-	const Syssocket                    : scno = 97
-	const Sysconnect                   : scno = 98
-	const Sysgetpriority               : scno = 100
-	const Sysbind                      : scno = 104
-	const Syssetsockopt                : scno = 105
-	const Syslisten                    : scno = 106
-	const Sysgettimeofday              : scno = 116
-	const Sysgetrusage                 : scno = 117
-	const Sysgetsockopt                : scno = 118
-	const Sysreadv                     : scno = 120
-	const Syswritev                    : scno = 121
-	const Syssettimeofday              : scno = 122
-	const Sysfchown                    : scno = 123
-	const Sysfchmod                    : scno = 124
-	const Syssetreuid                  : scno = 126
-	const Syssetregid                  : scno = 127
-	const Sysrename                    : scno = 128
-	const Sysflock                     : scno = 131
-	const Sysmkfifo                    : scno = 132
-	const Syssendto                    : scno = 133
-	const Sysshutdown                  : scno = 134
-	const Syssocketpair                : scno = 135
-	const Sysmkdir                     : scno = 136
-	const Sysrmdir                     : scno = 137
-	const Sysutimes                    : scno = 138
-	const Sysadjtime                   : scno = 140
-	const Syssetsid                    : scno = 147
-	const Sysquotactl                  : scno = 148
-	const Sysnlm_syscall               : scno = 154
-	const Sysnfssvc                    : scno = 155
-	const Sysfreebsd4_statfs           : scno = 157
-	const Sysfreebsd4_fstatfs          : scno = 158
-	const Syslgetfh                    : scno = 160
-	const Sysgetfh                     : scno = 161
-	const Sysfreebsd4_getdomainname    : scno = 162
-	const Sysfreebsd4_setdomainname    : scno = 163
-	const Sysfreebsd4_uname            : scno = 164
-	const Syssysarch                   : scno = 165
-	const Sysrtprio                    : scno = 166
-	const Syssemsys                    : scno = 169
-	const Sysmsgsys                    : scno = 170
-	const Sysshmsys                    : scno = 171
-	const Sysfreebsd6_pread            : scno = 173
-	const Sysfreebsd6_pwrite           : scno = 174
-	const Syssetfib                    : scno = 175
-	const Sysntp_adjtime               : scno = 176
-	const Syssetgid                    : scno = 181
-	const Syssetegid                   : scno = 182
-	const Sysseteuid                   : scno = 183
-	const Sysstat                      : scno = 188
-	const Sysfstat                     : scno = 189
-	const Syslstat                     : scno = 190
-	const Syspathconf                  : scno = 191
-	const Sysfpathconf                 : scno = 192
-	const Sysgetrlimit                 : scno = 194
-	const Syssetrlimit                 : scno = 195
-	const Sysgetdirentries             : scno = 196
-	const Sysfreebsd6_mmap             : scno = 197
-	const Sys__syscall                 : scno = 198
-	const Sysfreebsd6_lseek            : scno = 199
-	const Sysfreebsd6_truncate         : scno = 200
-	const Sysfreebsd6_ftruncate        : scno = 201
-	const Sys__sysctl                  : scno = 202
-	const Sysmlock                     : scno = 203
-	const Sysmunlock                   : scno = 204
-	const Sysundelete                  : scno = 205
-	const Sysfutimes                   : scno = 206
-	const Sysgetpgid                   : scno = 207
-	const Syspoll                      : scno = 209
-	const Sysfreebsd7___semctl         : scno = 220
-	const Syssemget                    : scno = 221
-	const Syssemop                     : scno = 222
-	const Sysfreebsd7_msgctl           : scno = 224
-	const Sysmsgget                    : scno = 225
-	const Sysmsgsnd                    : scno = 226
-	const Sysmsgrcv                    : scno = 227
-	const Sysshmat                     : scno = 228
-	const Sysfreebsd7_shmctl           : scno = 229
-	const Sysshmdt                     : scno = 230
-	const Sysshmget                    : scno = 231
-	const Sysclock_gettime             : scno = 232
-	const Sysclock_settime             : scno = 233
-	const Sysclock_getres              : scno = 234
-	const Sysktimer_create             : scno = 235
-	const Sysktimer_delete             : scno = 236
-	const Sysktimer_settime            : scno = 237
-	const Sysktimer_gettime            : scno = 238
-	const Sysktimer_getoverrun         : scno = 239
-	const Sysnanosleep                 : scno = 240
-	const Sysffclock_getcounter        : scno = 241
-	const Sysffclock_setestimate       : scno = 242
-	const Sysffclock_getestimate       : scno = 243
-	const Sysclock_getcpuclockid2      : scno = 247
-	const Sysntp_gettime               : scno = 248
-	const Sysminherit                  : scno = 250
-	const Sysrfork                     : scno = 251
-	const Sysopenbsd_poll              : scno = 252
-	const Sysissetugid                 : scno = 253
-	const Syslchown                    : scno = 254
-	const Sysaio_read                  : scno = 255
-	const Sysaio_write                 : scno = 256
-	const Syslio_listio                : scno = 257
-	const Sysgetdents                  : scno = 272
-	const Syslchmod                    : scno = 274
-	const Sysnetbsd_lchown             : scno = 275
-	const Syslutimes                   : scno = 276
-	const Sysnetbsd_msync              : scno = 277
-	const Sysnstat                     : scno = 278
-	const Sysnfstat                    : scno = 279
-	const Sysnlstat                    : scno = 280
-	const Syspreadv                    : scno = 289
-	const Syspwritev                   : scno = 290
-	const Sysfreebsd4_fhstatfs         : scno = 297
-	const Sysfhopen                    : scno = 298
-	const Sysfhstat                    : scno = 299
-	const Sysmodnext                   : scno = 300
-	const Sysmodstat                   : scno = 301
-	const Sysmodfnext                  : scno = 302
-	const Sysmodfind                   : scno = 303
-	const Syskldload                   : scno = 304
-	const Syskldunload                 : scno = 305
-	const Syskldfind                   : scno = 306
-	const Syskldnext                   : scno = 307
-	const Syskldstat                   : scno = 308
-	const Syskldfirstmod               : scno = 309
-	const Sysgetsid                    : scno = 310
-	const Syssetresuid                 : scno = 311
-	const Syssetresgid                 : scno = 312
-	const Sysaio_return                : scno = 314
-	const Sysaio_suspend               : scno = 315
-	const Sysaio_cancel                : scno = 316
-	const Sysaio_error                 : scno = 317
-	const Sysoaio_read                 : scno = 318
-	const Sysoaio_write                : scno = 319
-	const Sysolio_listio               : scno = 320
-	const Sysyield                     : scno = 321
-	const Sysmlockall                  : scno = 324
-	const Sysmunlockall                : scno = 325
-	const Sys__getcwd                  : scno = 326
-	const Syssched_setparam            : scno = 327
-	const Syssched_getparam            : scno = 328
-	const Syssched_setscheduler        : scno = 329
-	const Syssched_getscheduler        : scno = 330
-	const Syssched_yield               : scno = 331
-	const Syssched_get_priority_max    : scno = 332
-	const Syssched_get_priority_min    : scno = 333
-	const Syssched_rr_get_interval     : scno = 334
-	const Sysutrace                    : scno = 335
-	const Sysfreebsd4_sendfile         : scno = 336
-	const Syskldsym                    : scno = 337
-	const Sysjail                      : scno = 338
-	const Sysnnpfs_syscall             : scno = 339
-	const Syssigprocmask               : scno = 340
-	const Syssigsuspend                : scno = 341
-	const Sysfreebsd4_sigaction        : scno = 342
-	const Syssigpending                : scno = 343
-	const Sysfreebsd4_sigreturn        : scno = 344
-	const Syssigtimedwait              : scno = 345
-	const Syssigwaitinfo               : scno = 346
-	const Sys__acl_get_file            : scno = 347
-	const Sys__acl_set_file            : scno = 348
-	const Sys__acl_get_fd              : scno = 349
-	const Sys__acl_set_fd              : scno = 350
-	const Sys__acl_delete_file         : scno = 351
-	const Sys__acl_delete_fd           : scno = 352
-	const Sys__acl_aclcheck_file       : scno = 353
-	const Sys__acl_aclcheck_fd         : scno = 354
-	const Sysextattrctl                : scno = 355
-	const Sysextattr_set_file          : scno = 356
-	const Sysextattr_get_file          : scno = 357
-	const Sysextattr_delete_file       : scno = 358
-	const Sysaio_waitcomplete          : scno = 359
-	const Sysgetresuid                 : scno = 360
-	const Sysgetresgid                 : scno = 361
-	const Syskqueue                    : scno = 362
-	const Syskevent                    : scno = 363
-	const Sysextattr_set_fd            : scno = 371
-	const Sysextattr_get_fd            : scno = 372
-	const Sysextattr_delete_fd         : scno = 373
-	const Sys__setugid                 : scno = 374
-	const Syseaccess                   : scno = 376
-	const Sysafs3_syscall              : scno = 377
-	const Sysnmount                    : scno = 378
-	const Sys__mac_get_proc            : scno = 384
-	const Sys__mac_set_proc            : scno = 385
-	const Sys__mac_get_fd              : scno = 386
-	const Sys__mac_get_file            : scno = 387
-	const Sys__mac_set_fd              : scno = 388
-	const Sys__mac_set_file            : scno = 389
-	const Syskenv                      : scno = 390
-	const Syslchflags                  : scno = 391
-	const Sysuuidgen                   : scno = 392
-	const Syssendfile                  : scno = 393
-	const Sysmac_syscall               : scno = 394
-	const Sysgetfsstat                 : scno = 395
-	const Sysstatfs                    : scno = 396
-	const Sysfstatfs                   : scno = 397
-	const Sysfhstatfs                  : scno = 398
-	const Sysksem_close                : scno = 400
-	const Sysksem_post                 : scno = 401
-	const Sysksem_wait                 : scno = 402
-	const Sysksem_trywait              : scno = 403
-	const Sysksem_init                 : scno = 404
-	const Sysksem_open                 : scno = 405
-	const Sysksem_unlink               : scno = 406
-	const Sysksem_getvalue             : scno = 407
-	const Sysksem_destroy              : scno = 408
-	const Sys__mac_get_pid             : scno = 409
-	const Sys__mac_get_link            : scno = 410
-	const Sys__mac_set_link            : scno = 411
-	const Sysextattr_set_link          : scno = 412
-	const Sysextattr_get_link          : scno = 413
-	const Sysextattr_delete_link       : scno = 414
-	const Sys__mac_execve              : scno = 415
-	const Syssigaction                 : scno = 416
-	const Syssigreturn                 : scno = 417
-	const Sysgetcontext                : scno = 421
-	const Syssetcontext                : scno = 422
-	const Sysswapcontext               : scno = 423
-	const Sysswapoff                   : scno = 424
-	const Sys__acl_get_link            : scno = 425
-	const Sys__acl_set_link            : scno = 426
-	const Sys__acl_delete_link         : scno = 427
-	const Sys__acl_aclcheck_link       : scno = 428
-	const Syssigwait                   : scno = 429
-	const Systhr_create                : scno = 430
-	const Systhr_exit                  : scno = 431
-	const Systhr_self                  : scno = 432
-	const Systhr_kill                  : scno = 433
-	const Sys_umtx_lock                : scno = 434
-	const Sys_umtx_unlock              : scno = 435
-	const Sysjail_attach               : scno = 436
-	const Sysextattr_list_fd           : scno = 437
-	const Sysextattr_list_file         : scno = 438
-	const Sysextattr_list_link         : scno = 439
-	const Sysksem_timedwait            : scno = 441
-	const Systhr_suspend               : scno = 442
-	const Systhr_wake                  : scno = 443
-	const Syskldunloadf                : scno = 444
-	const Sysaudit                     : scno = 445
-	const Sysauditon                   : scno = 446
-	const Sysgetauid                   : scno = 447
-	const Syssetauid                   : scno = 448
-	const Sysgetaudit                  : scno = 449
-	const Syssetaudit                  : scno = 450
-	const Sysgetaudit_addr             : scno = 451
-	const Syssetaudit_addr             : scno = 452
-	const Sysauditctl                  : scno = 453
-	const Sys_umtx_op                  : scno = 454
-	const Systhr_new                   : scno = 455
-	const Syssigqueue                  : scno = 456
-	const Syskmq_open                  : scno = 457
-	const Syskmq_setattr               : scno = 458
-	const Syskmq_timedreceive          : scno = 459
-	const Syskmq_timedsend             : scno = 460
-	const Syskmq_notify                : scno = 461
-	const Syskmq_unlink                : scno = 462
-	const Sysabort2                    : scno = 463
-	const Systhr_set_name              : scno = 464
-	const Sysaio_fsync                 : scno = 465
-	const Sysrtprio_thread             : scno = 466
-	const Syssctp_peeloff              : scno = 471
-	const Syssctp_generic_sendmsg      : scno = 472
-	const Syssctp_generic_sendmsg_iov  : scno = 473
-	const Syssctp_generic_recvmsg      : scno = 474
-	const Syspread                     : scno = 475
-	const Syspwrite                    : scno = 476
-	const Sysmmap                      : scno = 477
-	const Syslseek                     : scno = 478
-	const Systruncate                  : scno = 479
-	const Sysftruncate                 : scno = 480
-	const Systhr_kill2                 : scno = 481
-	const Sysshm_open                  : scno = 482
-	const Sysshm_unlink                : scno = 483
-	const Syscpuset                    : scno = 484
-	const Syscpuset_setid              : scno = 485
-	const Syscpuset_getid              : scno = 486
-	const Syscpuset_getaffinity        : scno = 487
-	const Syscpuset_setaffinity        : scno = 488
-	const Sysfaccessat                 : scno = 489
-	const Sysfchmodat                  : scno = 490
-	const Sysfchownat                  : scno = 491
-	const Sysfexecve                   : scno = 492
-	const Sysfstatat                   : scno = 493
-	const Sysfutimesat                 : scno = 494
-	const Syslinkat                    : scno = 495
-	const Sysmkdirat                   : scno = 496
-	const Sysmkfifoat                  : scno = 497
-	const Sysmknodat                   : scno = 498
-	const Sysopenat                    : scno = 499
-	const Sysreadlinkat                : scno = 500
-	const Sysrenameat                  : scno = 501
-	const Syssymlinkat                 : scno = 502
-	const Sysunlinkat                  : scno = 503
-	const Sysposix_openpt              : scno = 504
-	const Sysgssd_syscall              : scno = 505
-	const Sysjail_get                  : scno = 506
-	const Sysjail_set                  : scno = 507
-	const Sysjail_remove               : scno = 508
-	const Sysclosefrom                 : scno = 509
-	const Sys__semctl                  : scno = 510
-	const Sysmsgctl                    : scno = 511
-	const Sysshmctl                    : scno = 512
-	const Syslpathconf                 : scno = 513
-	const Sys__cap_rights_get          : scno = 515
-	const Syscap_enter                 : scno = 516
-	const Syscap_getmode               : scno = 517
-	const Syspdfork                    : scno = 518
-	const Syspdkill                    : scno = 519
-	const Syspdgetpid                  : scno = 520
-	const Syspselect                   : scno = 522
-	const Sysgetloginclass             : scno = 523
-	const Syssetloginclass             : scno = 524
-	const Sysrctl_get_racct            : scno = 525
-	const Sysrctl_get_rules            : scno = 526
-	const Sysrctl_get_limits           : scno = 527
-	const Sysrctl_add_rule             : scno = 528
-	const Sysrctl_remove_rule          : scno = 529
-	const Sysposix_fallocate           : scno = 530
-	const Sysposix_fadvise             : scno = 531
-	const Syswait6                     : scno = 532
-	const Syscap_rights_limit          : scno = 533
-	const Syscap_ioctls_limit          : scno = 534
-	const Syscap_ioctls_get            : scno = 535
-	const Syscap_fcntls_limit          : scno = 536
-	const Syscap_fcntls_get            : scno = 537
-	const Sysbindat                    : scno = 538
-	const Sysconnectat                 : scno = 539
-	const Syschflagsat                 : scno = 540
-	const Sysaccept4                   : scno = 541
-	const Syspipe2                     : scno = 542
-	const Sysaio_mlock                 : scno = 543
-	const Sysprocctl                   : scno = 544
-
-	extern const syscall : (sc:scno, args:... -> int64)
-
-	/* process control */
-	const exit	: (status:int -> void)
-	const getpid	: ( -> int64)
-	const kill	: (pid:int64, sig:int64 -> int64)
-	const fork	: (-> int64)
-	const wait4	: (pid:int64, loc:int32#, opt : int64, usage:rusage#	-> int64)
-	const waitpid	: (pid:int64, loc:int32#, opt : int64	-> int64)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	/* wrappers to extract wait status */
-	const waitstatus	: (st : int32 -> waitstatus)
-
-	/* fd manipulation */
-	const open	: (path:byte[:], opts:fdopt -> fd)
-	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
-	const close	: (fd:fd -> int64)
-	const creat	: (path:byte[:], mode:int64 -> fd)
-	const read	: (fd:fd, buf:byte[:] -> size)
-	const write	: (fd:fd, buf:byte[:] -> size)
-	const lseek	: (fd:fd, off:uint64, whence:int64 -> int64)
-	const stat	: (path:byte[:], sb:statbuf# -> int64)
-	const lstat	: (path:byte[:], sb:statbuf# -> int64)
-	const fstat	: (fd:fd, sb:statbuf# -> int64)
-	const mkdir	: (path : byte[:], mode : int64	-> int64)
-	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
-	const getdirentries64	: (fd : fd, buf : byte[:], basep : uint64# -> int64)
-
-	/* networking */
-	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
-	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
-	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
-	const listen	: (sock : fd, backlog : int	-> int)
-	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
-
-	/* memory mapping */
-	const munmap	: (addr:byte#, len:size -> int64)
-	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
-
-	/* time - doublecheck if this is right */
-	const clock_getres	: (clk : clock, ts : timespec# -> int32)
-	const clock_gettime	: (clk : clock, ts : timespec# -> int32)
-	const clock_settime	: (clk : clock, ts : timespec# -> int32)
-	const sleep	: (time : uint64 -> int32)
-	const nanosleep	: (req : timespec#, rem : timespec# -> int32)
-
-	/* system information */
-	const uname 	: (buf : utsname# -> int)
-	const sysctl	: (mib : int[:], old : byte[:]#, new : byte[:] -> int)
-;;
-
-/* 
-wraps a syscall argument, converting it to 64 bits for the syscall function. This is
-the same as casting, but more concise than writing castto(int64)
-*/
-generic a = {x : @t
-	-> a(x)
-}
-
-extern const cstring	: (str : byte[:] -> byte#)
-extern const alloca	: (sz : size	-> byte#)
-extern const __cenvp : byte##
-
-/* process management */
-const exit	= {status;		syscall(Sysexit, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid, 1)}
-const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
-const fork	= {;			-> syscall(Sysfork)}
-const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
-const waitpid	= {pid, loc, opt;
-	-> wait4(pid, loc, opt, 0 castto(rusage#)) 
-}
-
-const execv	= {cmd, args
-	var p, cargs, i
-
-	/* of course we fucking have to duplicate this code everywhere,
-	* since we want to stack allocate... */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
-}
-
-const execve	= {cmd, args, env
-	var cargs, cenv, i
-	var p
-
-	/* copy the args */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-
-	/*
-	 copy the env.
-	 of course we fucking have to duplicate this code everywhere,
-	 since we want to stack allocate... 
-	*/
-	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
-	for i = 0; i < env.len; i++
-		cenv[i] = cstring(env[i])
-	;;
-	cenv[env.len] = 0 castto(byte#)
-
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
-}
-
-/* fd manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
-const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
-const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
-const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
-const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)
-}
-const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries, a(fd), buf castto(byte#), a(buf.len), a(basep))}
-
-/* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-
-/* memory management */
-const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
-const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
-
-/* time */
-const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
-const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
-const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
-
-/* system information */
-const uname	= {buf;	-> syscall(Sysfreebsd4_uname, a(buf)) castto(int)}
-
-const sysctl = {mib, old, new
-	var mibp
-	var mibsz
-	var o
-	var oldp
-	var oldsz
-	var newp
-	var newsz
-	var ret
-
-	mibp = mib castto(byte#)
-	mibsz = a(mib.len)
-	o = old#
-	oldp = o castto(byte#)
-	oldsz = a(o.len)
-	newp = new castto(byte#)
-	newsz = a(new.len)
-
-	/* all args already passed through a() or ar  ptrs */
-	ret = syscall(Sys__sysctl, mibp, mibsz, oldp, oldsz, newp, newsz) castto(int)
-
-	old# = o[:oldsz]
-	-> ret
-}
-
-const clockid = {clk
-	match clk
-	| `Clockrealtime:		-> 0
-	| `Clockvirtual:		-> 1
-	| `Clockprof:			-> 2
-	| `Clockmonotonic:		-> 4
-	| `Clockuptime:			-> 5
-	| `Clockuptime_precise:		-> 7
-	| `Clockuptime_fast:		-> 8
-	| `Clockrealtime_precise:	-> 9
-	| `Clockrealtime_fast:		-> 10
-	| `Clockmonotonic_precise:	-> 11
-	| `Clockmonotonic_fast:		-> 12
-	| `Clocksecond:			-> 13
-	;;
-	-> a(-1)
-}
-
-const waitstatus = {st
-	match st & 0o177
-	| 0:    -> `Waitexit (st >> 8)
-	| 0x7f:-> `Waitstop (st >> 8)
-	| sig:  -> `Waitsig sig
-	;;
-}
-
--- a/libstd/sys+linux-x64.myr
+++ /dev/null
@@ -1,816 +1,0 @@
-use "systypes.use"
-
-pkg sys =
-	type scno	= int64	/* syscall */
-
-	/* processes/threads */
-	type pid	= int	/* process id */
-	type tid	= int	/* thread id */
-	type cloneopt	= int64	/* options for clone(2) */
-
-	/* file descriptor manipulation */
-	type fdopt	= int64	/* fd options */
-	type fd		= int32	/* fd */
-	type whence	= uint64	/* seek from whence */
-	type filemode	= uint32	/* file open mode */
-
-	type mprot	= int64	/* memory protection */
-	type mopt	= int64	/* memory mapping options */
-	type socktype	= int64	/* socket type */
-	type sockproto	= int64	/* socket protocol */
-	type sockfam	= uint16	/* socket family */
-
-	type epollflags	= uint32
-	type epollop	= uint32
-	type epollevttype	= uint32
-
-	type pollevt	= uint16
-
-	type clock = union
-		`Clockrealtime
-		`Clockmonotonic
-		`Clockproccpu
-		`Clockthreadcpu
-		`Clockmonotonicraw
-		`Clockrealtimecoarse
-		`Clockmonotoniccoarse
-		`Clockboottime
-		`Clockrealtimealarm
-		`Clockboottimealarm
-	;;
-
-	type waitstatus = union
-		`Waitexit int32
-		`Waitsig  int32
-		`Waitstop int32
-		`Waitfail int32
-	;;
-
-	type timespec = struct
-		sec	: uint64
-		nsec	: uint64
-	;;
-
-	type timeval = struct
-		sec	: uint64
-		usec	: uint64
-	;;
-
-	type rusage = struct
-		utime	: timeval	/* user time */
-		stime	: timeval	/* system time */
-		_opaque	: uint64[14]	/* padding (darwin-specific data) */
-	;;
-
-	type statbuf = struct
-		 dev	: uint64
-		 ino	: uint64
-		 nlink	: uint64
-		 mode	: filemode
-		 uid	: uint32
-		 gid	: uint32
-		 __pad0	: uint32
-		 rdev	: uint64
-		 size	: uint64
-		 blksz	: uint32
-		 blocks	: uint64
-		 atime	: timespec
-		 mtime	: timespec
-		 ctime	: timespec
-		 __pad1	: uint64[3]
-	;;
-
-	type dirent64 = struct
-		ino	: uint64
-		off	: uint64
-		reclen	: uint16
-		etype	: byte
-		name	: byte[...]	/* special case; zero length => unchecked indexing */
-	;;
-
-	type utsname = struct
-		system	: byte[65]
-		node	: byte[65]
-		release	: byte[65]
-		version	: byte[65]
-		machine	: byte[65]
-		domain	: byte[65]
-	;;
-
-	type sockaddr = struct
-		fam	: sockfam
-		data	: byte[14]
-	;;
-
-	type sockaddr_in = struct
-		fam	: sockfam
-		port	: uint16
-		addr	: byte[4]
-		zero	: byte[8]
-	;;
-
-	type sockaddr_in6 = struct
-		fam	: sockfam
-		port	: uint16
-		addr	: byte[16]
-		scope	: uint32
-	;;
-
-	type sockaddr_storage = struct
-		fam	: sockfam
-		__align	: uint32
-		__pad	: byte[112]
-	;;
-
-	type epollevt = struct
-		events	: epollevttype
-		data	: byte[8]
-	;;
-
-	type pollfd = struct
-		fd	: fd
-		events	: pollevt
-		revents	: pollevt
-	;;
-
-	/* clone options */
-	const Clonesignal	: cloneopt = 0xff
-	const Clonevm		: cloneopt = 0x100
-	const Clonefs		: cloneopt = 0x200
-	const Clonefiles	: cloneopt = 0x400
-	const Clonesighand	: cloneopt = 0x800
-	const Cloneptrace	: cloneopt = 0x2000
-	const Clonevfork	: cloneopt = 0x4000
-	const Cloneparent	: cloneopt = 0x8000
-	const Clonethread	: cloneopt = 0x10000
-	const Clonenewns	: cloneopt = 0x20000
-	const Clonesysvsem	: cloneopt = 0x40000
-	const Clonesettls	: cloneopt = 0x80000
-	const Cloneparentsettid	: cloneopt = 0x100000
-	const Clonechildcleartid: cloneopt = 0x200000
-	const Clonedetached	: cloneopt = 0x400000
-	const Cloneuntraced	: cloneopt = 0x800000
-	const Clonechildsettid	: cloneopt = 0x1000000
-	const Clonenewuts	: cloneopt = 0x4000000
-	const Clonenewipc	: cloneopt = 0x8000000
-	const Clonenewuser	: cloneopt = 0x10000000
-	const Clonenewpid	: cloneopt = 0x20000000
-	const Clonenewnet	: cloneopt = 0x40000000
-	const Cloneio		: cloneopt = 0x80000000
-
-	type ptregs = struct
-	;;
-
-	/* open options */
-	const Ordonly  	: fdopt = 0x0
-	const Owronly  	: fdopt = 0x1
-	const Ordwr    	: fdopt = 0x2
-	const Ocreat   	: fdopt = 0x40
-	const Oexcl  	: fdopt = 0x80
-	const Otrunc   	: fdopt = 0x200
-	const Oappend  	: fdopt = 0x400
-	const Ondelay  	: fdopt = 0x800
-	const Odirect	: fdopt = 0x4000
-	const Odir	: fdopt = 0x10000
-	const Onofollow	: fdopt = 0x20000
-
-	/* stat modes */
-	const Sifmt	: filemode = 0xf000
-	const Sififo	: filemode = 0x1000
-	const Sifchr	: filemode = 0x2000
-	const Sifdir	: filemode = 0x4000
-	const Sifblk	: filemode = 0x6000
-	const Sifreg	: filemode = 0x8000
-	const Siflnk	: filemode = 0xa000
-	const Sifsock	: filemode = 0xc000
-
-	/* mmap protection */
-	const Mprotnone	: mprot = 0x0
-	const Mprotrd	: mprot = 0x1
-	const Mprotwr	: mprot = 0x2
-	const Mprotexec	: mprot = 0x4
-	const Mprotrw	: mprot = 0x3 /* convenience */
-	
-	/* mmap options */
-	const Mshared	: mopt = 0x1
-	const Mpriv	: mopt = 0x2
-	const Mfixed	: mopt = 0x10
-	const Mfile	: mopt = 0x0
-	const Manon	: mopt = 0x20
-	const M32bit	: mopt = 0x40
-
-	/* socket families. INCOMPLETE. */
-	const Afunspec	: sockfam = 0
-	const Afunix	: sockfam = 1
-	const Afinet	: sockfam = 2
-	const Afinet6	: sockfam = 10
-
-	/* socket types. */
-	const Sockstream	: socktype = 1	/* sequenced, reliable byte stream */
-	const Sockdgram		: socktype = 2	/* datagrams */
-	const Sockraw		: socktype = 3	/* raw proto */
-	const Sockrdm		: socktype = 4	/* reliably delivered messages */
-	const Sockseqpacket	: socktype = 5	/* sequenced, reliable packets */
-	const Sockdccp		: socktype = 6	/* data congestion control protocol */
-	const Sockpack		: socktype = 10	/* linux specific packet */
-
-	/* network protocols */
-	const Ipproto_ip	: sockproto = 0
-	const Ipproto_icmp	: sockproto = 1
-	const Ipproto_tcp	: sockproto = 6
-	const Ipproto_udp	: sockproto = 17
-	const Ipproto_raw	: sockproto = 255
-
-	/* epoll flags */
-	const Epollcloexec	: epollflags	= 0o2000000
-
-	/* epoll ops */
-	const Epollctladd	: epollop	= 0
-	const Epollctlmod	: epollop	= 1
-	const Epollctldel	: epollop	= 1
-
-	/* epoll events */
-	const Epollin	: epollevttype = 0x001
-	const Epollpri	: epollevttype = 0x002
-	const Epollout	: epollevttype = 0x004
-	const Epollerr	: epollevttype = 0x008
-	const Epollhup	: epollevttype = 0x010
-	const Epollrdnorm	: epollevttype = 0x040
-	const Epollrdband	: epollevttype = 0x080
-	const Epollwrnorm	: epollevttype = 0x100
-	const Epollwrband	: epollevttype = 0x200
-	const Epollmsg		: epollevttype = 0x400
-	const Epollrdhup	: epollevttype = 0x2000
-	const Epollwakeup	: epollevttype = 1 << 29
-	const Epolloneshot	: epollevttype = 1 << 30
-	const Epolledge	: epollevttype = 1 << 31
-
-	/* poll events : posix */
-	const Pollin	: pollevt = 0x001	/* There is data to read.  */
-	const Pollpri	: pollevt = 0x002	/* There is urgent data to read.  */
-	const Pollout	: pollevt = 0x004	/* Writing now will not block.  */
-
-	/* poll events: xopen */
-	const Pollrdnorm	: pollevt = 0x040	/* Normal data may be read.  */
-	const Pollrdband	: pollevt = 0x080	/* Priority data may be read.  */
-	const Pollwrnorm	: pollevt = 0x100	/* Writing now will not block.  */
-	const Pollwrband	: pollevt = 0x200	/* Priority data may be written.  */
-
-	/* poll events: linux */
-	const Pollmsg		: pollevt = 0x400
-	const Pollremove	: pollevt = 0x1000
-	const Pollrdhup		: pollevt = 0x2000
-
-	const Seekset	: whence = 0
-	const Seekcur	: whence = 1
-	const Seekend	: whence = 2
-
-	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
-
-	/* syscalls */
-	const Sysread			: scno = 0
-	const Syswrite			: scno = 1
-	const Sysopen			: scno = 2
-	const Sysclose			: scno = 3
-	const Sysstat			: scno = 4
-	const Sysfstat			: scno = 5
-	const Syslstat			: scno = 6
-	const Syspoll			: scno = 7
-	const Syslseek			: scno = 8
-	const Sysmmap			: scno = 9
-	const Sysmprotect		: scno = 10
-	const Sysmunmap			: scno = 11
-	const Sysbrk			: scno = 12
-	const Sysrt_sigaction		: scno = 13
-	const Sysrt_sigprocmask		: scno = 14
-	const Sysrt_sigreturn		: scno = 15
-	const Sysioctl			: scno = 16
-	const Syspread64		: scno = 17
-	const Syspwrite64		: scno = 18
-	const Sysreadv			: scno = 19
-	const Syswritev			: scno = 20
-	const Sysaccess			: scno = 21
-	const Syspipe			: scno = 22
-	const Sysselect			: scno = 23
-	const Syssched_yield		: scno = 24
-	const Sysmremap			: scno = 25
-	const Sysmsync			: scno = 26
-	const Sysmincore		: scno = 27
-	const Sysmadvise		: scno = 28
-	const Sysshmget			: scno = 29
-	const Sysshmat			: scno = 30
-	const Sysshmctl			: scno = 31
-	const Sysdup			: scno = 32
-	const Sysdup2			: scno = 33
-	const Syspause			: scno = 34
-	const Sysnanosleep		: scno = 35
-	const Sysgetitimer		: scno = 36
-	const Sysalarm			: scno = 37
-	const Syssetitimer		: scno = 38
-	const Sysgetpid			: scno = 39
-	const Syssendfile		: scno = 40
-	const Syssocket			: scno = 41
-	const Sysconnect		: scno = 42
-	const Sysaccept			: scno = 43
-	const Syssendto			: scno = 44
-	const Sysrecvfrom		: scno = 45
-	const Syssendmsg		: scno = 46
-	const Sysrecvmsg		: scno = 47
-	const Sysshutdown		: scno = 48
-	const Sysbind			: scno = 49
-	const Syslisten			: scno = 50
-	const Sysgetsockname		: scno = 51
-	const Sysgetpeername		: scno = 52
-	const Syssocketpair		: scno = 53
-	const Syssetsockopt		: scno = 54
-	const Sysgetsockopt		: scno = 55
-	const Sysclone			: scno = 56
-	const Sysfork			: scno = 57
-	const Sysvfork			: scno = 58
-	const Sysexecve			: scno = 59
-	const Sysexit			: scno = 60
-	const Syswait4			: scno = 61
-	const Syskill			: scno = 62
-	const Sysuname			: scno = 63
-	const Syssemget			: scno = 64
-	const Syssemop			: scno = 65
-	const Syssemctl			: scno = 66
-	const Sysshmdt			: scno = 67
-	const Sysmsgget			: scno = 68
-	const Sysmsgsnd			: scno = 69
-	const Sysmsgrcv			: scno = 70
-	const Sysmsgctl			: scno = 71
-	const Sysfcntl			: scno = 72
-	const Sysflock			: scno = 73
-	const Sysfsync			: scno = 74
-	const Sysfdatasync		: scno = 75
-	const Systruncate		: scno = 76
-	const Sysftruncate		: scno = 77
-	const Sysgetdents		: scno = 78
-	const Sysgetcwd			: scno = 79
-	const Syschdir			: scno = 80
-	const Sysfchdir			: scno = 81
-	const Sysrename			: scno = 82
-	const Sysmkdir			: scno = 83
-	const Sysrmdir			: scno = 84
-	const Syscreat			: scno = 85
-	const Syslink			: scno = 86
-	const Sysunlink			: scno = 87
-	const Syssymlink		: scno = 88
-	const Sysreadlink		: scno = 89
-	const Syschmod			: scno = 90
-	const Sysfchmod			: scno = 91
-	const Syschown			: scno = 92
-	const Sysfchown			: scno = 93
-	const Syslchown			: scno = 94
-	const Sysumask			: scno = 95
-	const Sysgettimeofday		: scno = 96
-	const Sysgetrlimit		: scno = 97
-	const Sysgetrusage		: scno = 98
-	const Syssysinfo		: scno = 99
-	const Systimes			: scno = 100
-	const Sysptrace			: scno = 101
-	const Sysgetuid			: scno = 102
-	const Syssyslog			: scno = 103
-	const Sysgetgid			: scno = 104
-	const Syssetuid			: scno = 105
-	const Syssetgid			: scno = 106
-	const Sysgeteuid		: scno = 107
-	const Sysgetegid		: scno = 108
-	const Syssetpgid		: scno = 109
-	const Sysgetppid		: scno = 110
-	const Sysgetpgrp		: scno = 111
-	const Syssetsid			: scno = 112
-	const Syssetreuid		: scno = 113
-	const Syssetregid		: scno = 114
-	const Sysgetgroups		: scno = 115
-	const Syssetgroups		: scno = 116
-	const Syssetresuid		: scno = 117
-	const Sysgetresuid		: scno = 118
-	const Syssetresgid		: scno = 119
-	const Sysgetresgid		: scno = 120
-	const Sysgetpgid		: scno = 121
-	const Syssetfsuid		: scno = 122
-	const Syssetfsgid		: scno = 123
-	const Sysgetsid			: scno = 124
-	const Syscapget			: scno = 125
-	const Syscapset			: scno = 126
-	const Sysrt_sigpending		: scno = 127
-	const Sysrt_sigtimedwait	: scno = 128
-	const Sysrt_sigqueueinfo	: scno = 129
-	const Sysrt_sigsuspend		: scno = 130
-	const Syssigaltstack		: scno = 131
-	const Sysutime			: scno = 132
-	const Sysmknod			: scno = 133
-	const Sysuselib			: scno = 134
-	const Syspersonality		: scno = 135
-	const Sysustat			: scno = 136
-	const Sysstatfs			: scno = 137
-	const Sysfstatfs		: scno = 138
-	const Syssysfs			: scno = 139
-	const Sysgetpriority		: scno = 140
-	const Syssetpriority		: scno = 141
-	const Syssched_setparam		: scno = 142
-	const Syssched_getparam		: scno = 143
-	const Syssched_setscheduler	: scno = 144
-	const Syssched_getscheduler	: scno = 145
-	const Syssched_get_priority_max	: scno = 146
-	const Syssched_get_priority_min	: scno = 147
-	const Syssched_rr_get_interval	: scno = 148
-	const Sysmlock			: scno = 149
-	const Sysmunlock		: scno = 150
-	const Sysmlockall		: scno = 151
-	const Sysmunlockall		: scno = 152
-	const Sysvhangup		: scno = 153
-	const Sysmodify_ldt		: scno = 154
-	const Syspivot_root		: scno = 155
-	const Sys_sysctl		: scno = 156
-	const Sysprctl			: scno = 157
-	const Sysarch_prctl		: scno = 158
-	const Sysadjtimex		: scno = 159
-	const Syssetrlimit		: scno = 160
-	const Syschroot			: scno = 161
-	const Syssync			: scno = 162
-	const Sysacct			: scno = 163
-	const Syssettimeofday		: scno = 164
-	const Sysmount			: scno = 165
-	const Sysumount2		: scno = 166
-	const Sysswapon			: scno = 167
-	const Sysswapoff		: scno = 168
-	const Sysreboot			: scno = 169
-	const Syssethostname		: scno = 170
-	const Syssetdomainname		: scno = 171
-	const Sysiopl			: scno = 172
-	const Sysioperm			: scno = 173
-	const Syscreate_module		: scno = 174
-	const Sysinit_module		: scno = 175
-	const Sysdelete_module		: scno = 176
-	const Sysget_kernel_syms	: scno = 177
-	const Sysquery_module		: scno = 178
-	const Sysquotactl		: scno = 179
-	const Sysnfsservctl		: scno = 180
-	const Sysgetpmsg		: scno = 181
-	const Sysputpmsg		: scno = 182
-	const Sysafs_syscall		: scno = 183
-	const Systuxcall		: scno = 184
-	const Syssecurity		: scno = 185
-	const Sysgettid			: scno = 186
-	const Sysreadahead		: scno = 187
-	const Syssetxattr		: scno = 188
-	const Syslsetxattr		: scno = 189
-	const Sysfsetxattr		: scno = 190
-	const Sysgetxattr		: scno = 191
-	const Syslgetxattr		: scno = 192
-	const Sysfgetxattr		: scno = 193
-	const Syslistxattr		: scno = 194
-	const Sysllistxattr		: scno = 195
-	const Sysflistxattr		: scno = 196
-	const Sysremovexattr		: scno = 197
-	const Syslremovexattr		: scno = 198
-	const Sysfremovexattr		: scno = 199
-	const Systkill			: scno = 200
-	const Systime			: scno = 201
-	const Sysfutex			: scno = 202
-	const Syssched_setaffinity	: scno = 203
-	const Syssched_getaffinity	: scno = 204
-	const Sysset_thread_area	: scno = 205
-	const Sysio_setup		: scno = 206
-	const Sysio_destroy		: scno = 207
-	const Sysio_getevents		: scno = 208
-	const Sysio_submit		: scno = 209
-	const Sysio_cancel		: scno = 210
-	const Sysget_thread_area	: scno = 211
-	const Syslookup_dcookie		: scno = 212
-	const Sysepoll_create		: scno = 213
-	const Sysepoll_ctl_old		: scno = 214
-	const Sysepoll_wait_old		: scno = 215
-	const Sysremap_file_pages	: scno = 216
-	const Sysgetdents64		: scno = 217
-	const Sysset_tid_address	: scno = 218
-	const Sysrestart_syscall	: scno = 219
-	const Syssemtimedop		: scno = 220
-	const Sysfadvise64		: scno = 221
-	const Systimer_create		: scno = 222
-	const Systimer_settime		: scno = 223
-	const Systimer_gettime		: scno = 224
-	const Systimer_getoverrun	: scno = 225
-	const Systimer_delete		: scno = 226
-	const Sysclock_settime		: scno = 227
-	const Sysclock_gettime		: scno = 228
-	const Sysclock_getres		: scno = 229
-	const Sysclock_nanosleep	: scno = 230
-	const Sysexit_group		: scno = 231
-	const Sysepoll_wait		: scno = 232
-	const Sysepoll_ctl		: scno = 233
-	const Systgkill			: scno = 234
-	const Sysutimes			: scno = 235
-	const Sysvserver		: scno = 236
-	const Sysmbind			: scno = 237
-	const Sysset_mempolicy		: scno = 238
-	const Sysget_mempolicy		: scno = 239
-	const Sysmq_open		: scno = 240
-	const Sysmq_unlink		: scno = 241
-	const Sysmq_timedsend		: scno = 242
-	const Sysmq_timedreceive	: scno = 243
-	const Sysmq_notify		: scno = 244
-	const Sysmq_getsetattr		: scno = 245
-	const Syskexec_load		: scno = 246
-	const Syswaitid			: scno = 247
-	const Sysadd_key		: scno = 248
-	const Sysrequest_key		: scno = 249
-	const Syskeyctl			: scno = 250
-	const Sysioprio_set		: scno = 251
-	const Sysioprio_get		: scno = 252
-	const Sysinotify_init		: scno = 253
-	const Sysinotify_add_watch	: scno = 254
-	const Sysinotify_rm_watch	: scno = 255
-	const Sysmigrate_pages		: scno = 256
-	const Sysopenat			: scno = 257
-	const Sysmkdirat		: scno = 258
-	const Sysmknodat		: scno = 259
-	const Sysfchownat		: scno = 260
-	const Sysfutimesat		: scno = 261
-	const Sysnewfstatat		: scno = 262
-	const Sysunlinkat		: scno = 263
-	const Sysrenameat		: scno = 264
-	const Syslinkat			: scno = 265
-	const Syssymlinkat		: scno = 266
-	const Sysreadlinkat		: scno = 267
-	const Sysfchmodat		: scno = 268
-	const Sysfaccessat		: scno = 269
-	const Syspselect6		: scno = 270
-	const Sysppoll			: scno = 271
-	const Sysunshare		: scno = 272
-	const Sysset_robust_list	: scno = 273
-	const Sysget_robust_list	: scno = 274
-	const Syssplice			: scno = 275
-	const Systee			: scno = 276
-	const Syssync_file_range	: scno = 277
-	const Sysvmsplice		: scno = 278
-	const Sysmove_pages		: scno = 279
-	const Sysutimensat		: scno = 280
-	const Sysepoll_pwait		: scno = 281
-	const Syssignalfd		: scno = 282
-	const Systimerfd_create		: scno = 283
-	const Syseventfd		: scno = 284
-	const Sysfallocate		: scno = 285
-	const Systimerfd_settime	: scno = 286
-	const Systimerfd_gettime	: scno = 287
-	const Sysaccept4		: scno = 288
-	const Syssignalfd4		: scno = 289
-	const Syseventfd2		: scno = 290
-	const Sysepoll_create1		: scno = 291
-	const Sysdup3			: scno = 292
-	const Syspipe2			: scno = 293
-	const Sysinotify_init1		: scno = 294
-	const Syspreadv			: scno = 295
-	const Syspwritev		: scno = 296
-	const Sysrt_tgsigqueueinfo	: scno = 297
-	const Sysperf_event_open	: scno = 298
-	const Sysrecvmmsg		: scno = 299
-	const Sysfanotify_init		: scno = 300
-	const Sysfanotify_mark		: scno = 301
-	const Sysprlimit64		: scno = 302
-	const Sysname_to_handle_at	: scno = 303
-	const Sysopen_by_handle_at	: scno = 304
-	const Sysclock_adjtime		: scno = 305
-	const Syssyncfs			: scno = 306
-	const Syssendmmsg		: scno = 307
-	const Syssetns			: scno = 308
-	const Sysgetcpu			: scno = 309
-	const Sysprocess_vm_readv	: scno = 310
-	const Sysprocess_vm_writev	: scno = 311
-
-	/* getting to the os */
-	extern const syscall	: (sc:scno, args:... -> int64)
-
-	/* process management */
-	const exit	: (status:int -> void)
-	const exit_group	: (status:int -> void)
-	const getpid	: ( -> pid)
-	const kill	: (pid:pid, sig:int64 -> int64)
-	const fork	: (-> pid)
-	/* FIXME: where the fuck is 'struct pt_reg' defined?? */
-	const clone	: (flags : cloneopt, stk : byte#, ptid : pid#, ctid : pid#, ptreg : byte# -> pid)
-	const wait4	: (pid:pid, loc:int32#, opt : int64, usage:rusage#	-> int64)
-	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	/* wrappers to extract wait status */
-	const waitstatus	: (st : int32 -> waitstatus)
-
-	/* file manipulation */
-	const open	: (path:byte[:], opts:fdopt -> fd)
-	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
-	const close	: (fd:fd -> int64)
-	const creat	: (path:byte[:], mode:int64 -> fd)
-	const unlink	: (path:byte[:] -> int)
-	const read	: (fd:fd, buf:byte[:] -> size)
-	const write	: (fd:fd, buf:byte[:] -> size)
-	const lseek	: (fd:fd, off:off, whence:whence -> int64)
-	const stat	: (path:byte[:], sb:statbuf# -> int64)
-	const lstat	: (path:byte[:], sb:statbuf# -> int64)
-	const fstat	: (fd:fd, sb:statbuf# -> int64)
-	const mkdir	: (path : byte[:], mode : int64	-> int64)
-	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
-	const getdents64	: (fd:fd, buf : byte[:] -> int64)
-	const chdir	: (p : byte[:] -> int64)
-	const getcwd	: (buf : byte[:] -> int64)
-
-	/* fd stuff */
-	const pipe	: (fds : fd[2]# -> int64)
-	const dup	: (fd : fd -> fd)
-	const dup2	: (src : fd, dst : fd -> fd)
-
-	/* threading */
-	const futex	: (uaddr : int32#, op : int32, val : int32, \
-		ts : timespec#, uaddr2 : int#, val3 : int# -> int64)
-
-	/* polling */
-	const epollcreate	: (flg : epollflags	-> fd)	/* actually epoll_create1 */
-	const epollctl	: (epfd : fd, op : int, fd : fd, evt : epollevt# -> int)
-	const epollwait	: (epfd : fd, evts : epollevt[:], timeout : int -> int)
-	const poll	: (pfd	: pollfd[:], timeout : int	-> int)
-
-	/* networking */
-	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
-	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
-	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
-	const listen	: (sock : fd, backlog : int	-> int)
-	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
-
-	/* memory mapping */
-	const munmap	: (addr:byte#, len:size -> int64)
-	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
-
-	/* time */
-	const clock_getres	: (clk : clock, ts : timespec# -> int32)
-	const clock_gettime	: (clk : clock, ts : timespec# -> int32)
-	const clock_settime	: (clk : clock, ts : timespec# -> int32)
-	const sleep	: (time : uint64 -> int32)
-	const nanosleep	: (req : timespec#, rem : timespec# -> int32)
-
-	/* system information */
-	const uname 	: (buf : utsname# -> int)
-
-	/* exported values: initialized by start code */
-	extern const __environment : byte[:][:]
-	extern const __cenvp : byte##
-;;
-
-/* 
-wraps a syscall argument, converting it to 64 bits for the syscall function.
-This is the same as casting, but more concise than writing castto(int64).
-*/
-generic a = {x : @t; -> x castto(uint64)}
-
-/* asm stubs from util.s */
-extern const cstring	: (str : byte[:] -> byte#)
-extern const alloca	: (sz : size	-> byte#)
-
-/* process management */
-const exit	= {status;		syscall(Sysexit, a(status))}
-const exit_group	= {status;	syscall(Sysexit_group, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
-const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
-const fork	= {;			-> syscall(Sysfork) castto(pid)}
-const clone	= {flags, stk, ptid, ctid, ptreg;	-> syscall(Sysclone, a(flags), a(stk), a(ptid), a(ctid), a(ptreg)) castto(pid)}
-const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(usage))}
-const waitpid	= {pid, loc, opt;
-	var rusage
-	-> wait4(pid, loc, opt, &rusage)
-}
-
-const execv	= {cmd, args
-	var p, cargs, i
-
-	/* of course we fucking have to duplicate this code everywhere,
-	* since we want to stack allocate... */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
-}
-
-const execve	= {cmd, args, env
-	var cargs, cenv, i
-	var p
-
-	/* copy the args */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-
-	/*
-	 copy the env.
-	 of course we fucking have to duplicate this code everywhere,
-	 since we want to stack allocate... 
-	*/
-	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
-	for i = 0; i < env.len; i++
-		cenv[i] = cstring(env[i])
-	;;
-	cenv[env.len] = 0 castto(byte#)
-
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
-}
-
-/* file manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
-const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> syscall(Syscreat, cstring(path), a(mode)) castto(fd)}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
-const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
-const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
-const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
-const getdents64	= {fd, buf;	-> syscall(Sysgetdents64, a(fd), buf castto(byte#), a(buf.len))}
-const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
-const getcwd	= {buf;	-> syscall(Sysgetcwd, a(buf), a(buf.len))}
-
-/* file stuff */
-const pipe	= {fds;	-> syscall(Syspipe, a(fds))}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
-
-/* threading */
-const futex	= {uaddr, op, val, timeout, uaddr2, val3
-	-> syscall(Sysfutex, a(uaddr), a(op), a(val), a(timeout), a(uaddr2), a(val3))}
-
-/* poll */
-const poll	= {pfd, timeout;	-> syscall(Syspoll, pfd castto(pollfd#), a(pfd.len), a(timeout)) castto(int)}
-const epollctl	= {epfd, op, fd, evt;
-	-> syscall(Sysepoll_ctl, a(epfd), a(op), a(fd), a(evt)) castto(int)}
-const epollwait	= {epfd, evts, timeout;
-	-> syscall(Sysepoll_wait, a(epfd), evts castto(epollevt#), a(evts.len), a(timeout)) castto(int)}
-const epollcreate	= {flg;	-> syscall(Sysepoll_create1, a(flg)) castto(fd)}
-
-/* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd)}
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const accept	= {sock, addr, lenp;	-> syscall(Sysaccept, a(sock), a(addr), a(lenp)) castto(fd)}
-
-/* memory mapping */
-const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
-const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)
-}
-
-/* time */
-const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
-const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
-const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
-
-const sleep = {time
-	var req, rem
-	req = [.sec = time, .nsec = 0]
-	-> nanosleep(&req, &rem)
-}
-
-const nanosleep	= {req, rem;	-> syscall(Sysnanosleep, a(req), a(rem)) castto(int32)}
-
-/* system information */
-const uname	= {buf;	-> syscall(Sysuname, buf) castto(int)}
-
-const clockid = {clk
-	match clk
-	| `Clockrealtime:	-> 0
-	| `Clockmonotonic:	-> 1
-	| `Clockproccpu:	-> 2
-	| `Clockthreadcpu:	-> 3
-	| `Clockmonotonicraw:	-> 4
-	| `Clockrealtimecoarse:	-> 5
-	| `Clockmonotoniccoarse:-> 6
-	| `Clockboottime:	-> 7
-	| `Clockrealtimealarm:	-> 8
-	| `Clockboottimealarm:	-> 9
-	;;
-	-> -1
-}
-
-
-const waitstatus = {st
-	if st & 0x7f == 0 /* if exited */
-		-> `Waitexit ((st & 0xff00) >> 8)
-	elif ((st & 0xffff)-1) < 0xff /* if signaled */
-		-> `Waitsig ((st) & 0x7f)
-	elif (((st & 0xffff)*0x10001)>>8) > 0x7f00
-		-> `Waitstop ((st & 0xff00) >> 8)
-	;;
-	-> `Waitfail st	/* wait failed to give a result */
-}
--- a/libstd/sys+osx-x64.myr
+++ /dev/null
@@ -1,947 +1,0 @@
-use "systypes.use"
-
-pkg sys =
-	type scno 	= int64	/* syscall */
-	type fdopt	= int64	/* fd options */
-	type fd		= int32	/* fd */
-	type pid	= int64	/* pid */
-	type mprot	= int64	/* memory protection */
-	type mopt	= int64	/* memory mapping options */
-	type socktype	= int64	/* socket type */
-	type sockproto	= int64	/* socket protocol */
-	type sockfam	= uint8	/* socket family */
-	type filemode	= uint16	/* file permission bits */
-	type kflags	= uint16	/* kqueue flags */
-	type whence	= int64
-	type fcntlcmd	= int64
-
-	type timespec = struct
-		sec	: uint64
-		nsec	: uint32
-	;;
-
-	type timeval = struct
-		sec	: uint64
-		usec	: uint32
-	;;
-
-	type timezone = struct
-		minwest	: int32 /* of greenwich */
-		dsttime	: int32	/* nonzero if DST applies */
-	;;
-
-	type clock = union
-		`Clockrealtime
-		`Clockmonotonic
-	;;
-
-	type waitstatus = union
-		`Waitexit int32
-		`Waitsig  int32
-		`Waitstop int32
-		`Waitfail int32
-	;;
-
-	type statbuf = struct
-		dev	: int32
-		mode	: filemode
-		nlink	: uint16
-		ino	: uint64
-		uid	: uint32
-		gid	: uint32
-		rdev	: uint32
-		atime	: timespec
-		mtime	: timespec
-		ctime	: timespec
-		birthtimespec	: timespec
-		size	: off
-		blocks	: int64
-		blksize	: int32
-		flags	: uint32
-		gen	: uint32
-		_spare	: uint32
-		_qspare	: uint64[2]
-	;;
-
-	type rusage = struct
-		utime	: timeval	/* user time */
-		stime	: timeval	/* system time */
-		_opaque	: uint64[14]	/* padding (darwin-specific data) */
-	;;
-
-	type utsname = struct
-		system	: byte[256]
-		node	: byte[256]
-		release	: byte[256]
-		version	: byte[256]
-		machine	: byte[256]
-	;;
-
-	type sockaddr = struct
-		len	: byte
-		fam	: sockfam
-		data	: byte[14] /* what is the *actual* length? */
-	;;
-
-	type sockaddr_in = struct
-		len	: byte
-		fam	: sockfam
-		port	: uint16
-		addr	: byte[4]
-		zero	: byte[8]
-	;;
-
-	type sockaddr_in6 = struct
-		len	: byte
-		fam	: sockfam
-		port	: uint16
-		flowinf	: uint32
-		addr	: byte[16]
-		scope	: uint32
-	;;
-
-
-	type sockaddr_storage = struct
-		len	: byte
-		fam	: sockfam
-		__pad1	: byte[6]
-		__align	: uint64
-		__pad2	: byte[112]
-	;;
-
-	type dirent64 = struct
-		ino	: uint64
-		seekoff	: uint64	/* seek offset (optional, used by servers) */
-		reclen	: uint16	/* length of this record */
-		namlen	: uint16	/* length of string in d_name */
-		typeid  : uint8		/* file type, see below */
-		name	: byte[...]
-	;;
-
-	type kevent = struct
-		ident	: intptr	/* identifier for this event */
-		filter	: int16		/* filter for event */
-		flags	: uint16	/* general flags */
-		fflags	: uint32	/* filter-specific flags */
-		data	: intptr	/* filter-specific data */
-		udata	: byte#		/* opaque user data identifier */
-	;;
-
-	type kevent64 = struct
-		ident	: uint64	/* identifier for this event */
-		filter	: int16		/* filter for event */
-		flags	: kflags	/* general flags */
-		fflags	: uint32	/* filter-specific flags */
-		data	: int64		/* filter-specific data */
-		udata	: uint64	/* opaque user data identifier */
-		ext	: uint64[2]	/* filter-specific extensions */
-	;;
-
-	const Seekset	: whence = 0
-	const Seekcur	: whence = 1
-	const Seekend	: whence = 2
-
-	/* system specific constants */
-	const Maxpathlen	: size = 1024
-
-	/* fcntl constants */
-	const Fdupfd		: fcntlcmd = 0		       /* duplicate file descriptor */
-	const Fgetfd		: fcntlcmd = 1		       /* get file descriptor flags */
-	const Fsetfd		: fcntlcmd = 2		       /* set file descriptor flags */
-	const Fgetfl		: fcntlcmd = 3		       /* get file status flags */
-	const Fsetfl		: fcntlcmd = 4		       /* set file status flags */
-	const Fgetown		: fcntlcmd = 5		       /* get SIGIO/SIGURG proc/pgrp */
-	const Fsetown		: fcntlcmd = 6		       /* set SIGIO/SIGURG proc/pgrp */
-	const Fgetlk		: fcntlcmd = 7		       /* get record locking information */
-	const Fsetlk		: fcntlcmd = 8		       /* set record locking information */
-	const Fsetlkw		: fcntlcmd = 9		       /* F_SETLK; wait if blocked */
-	const Fsetlkwtimeout	: fcntlcmd = 10			/* F_SETLK; wait if blocked, return on timeout */
-	const Fflush_data	: fcntlcmd = 40
-	const Fchkclean		: fcntlcmd = 41			/* Used for regression test */
-	const Fpreallocate	: fcntlcmd = 42			/* Preallocate storage */
-	const Fsetsize		: fcntlcmd = 43			/* Truncate a file without zeroing space */
-	const Frdadvise		: fcntlcmd = 44			/* Issue an advisory read async with no copy to user */
-	const Frdahead		: fcntlcmd = 45			/* turn read ahead off/on for this fd */
-	/* 46,47 used to be F_READBOOTSTRAP and F_WRITEBOOTSTRAP */
-	const Fnocache		: fcntlcmd = 48			/* turn data caching off/on for this fd */
-	const Flog2phys		: fcntlcmd = 49			/* file offset to device offset */
-	const Fgetpath		: fcntlcmd = 50			/* return the full path of the fd */
-	const Ffullfsync	: fcntlcmd = 51			/* fsync + ask the drive to flush to the media */
-	const Fpathpkg_check 	: fcntlcmd = 52			/* find which component (if any) is a package */
-	const Ffreeze_fs	: fcntlcmd = 53			/* "freeze" all fs operations */
-	const Fthaw_fs		: fcntlcmd = 54			/* "thaw" all fs operations */
-	const Fglobal_nocache	: fcntlcmd = 55			/* turn data caching off/on (globally) for this file */
-	const Faddsigs		: fcntlcmd = 59			/* add detached signatures */
-	const Faddfilesigs	: fcntlcmd = 61			/* add signature from same file (used by dyld for shared libs) */
-	const Fgetprotclass	: fcntlcmd = 63			/* Get the protection class of a file from the EA, returns int */
-	const Fsetprotclass	: fcntlcmd = 64			/* Set the protection class of a file for the EA, requires int */
-	const Flog2phys_ext	: fcntlcmd = 65			/* file offset to device offset, extended */
-	const Fgetlkpid		: fcntlcmd = 66			/* get record locking information, per-process */
-	/* See F_DUPFD_CLOEXEC below for 67 */
-	const Fsetbacktore	: fcntlcmd = 70			/* Mark the file as being the backing store for another filesystem */
-	const Fgetpath_mtminfo	: fcntlcmd = 71			/* return the full path of the FD, but error in specific mtmd circumstances */
-	/* 72 is free.	It used to be F_GETENCRYPTEDDATA, which is now removed. */
-	const Fsetnosigpipe	: fcntlcmd = 73			/* No SIGPIPE generated on EPIPE */
-	const Fgetnosigpipe	: fcntlcmd = 74			/* Status of SIGPIPE for this fd */
-
-	/* kqueue events */
-	const Kevadd		: kflags = 0x0001	/* add event to kq (implies enable) */
-	const Kevdelete		: kflags = 0x0002	/* delete event from kq */
-	const Kevenable		: kflags = 0x0004	/* enable event */
-	const Kevdisable	: kflags = 0x0008	/* disable event (not reported) */
-	const Kevreceipt	: kflags = 0x0040	/* force EV_ERROR on success, data == 0 */
-
-	/* kqueue flags */
-	const Kevoneshot	: kflags = 0x0010	/* only report one occurrence */
-	const Kevclear		: kflags = 0x0020	/* clear event state after reporting */
-	const Kevdispatch	: kflags = 0x0080	/* disable event after reporting */
-
-	const Kevsysflags	: kflags = 0xf000	/* reserved by system */
-	const Kevflag0		: kflags = 0x1000	/* filter-specific flag */
-	const Kevflag1		: kflags = 0x2000	/* filter-specific flag */
-
-	/* kqueue returned values */
-	const Keveof		: kflags = 0x8000	/* eof detected */
-	const Keverror		: kflags = 0x4000	/* error, data contains errno */
-
-	/* open options */
-	const Ordonly  	: fdopt = 0x0
-	const Owronly  	: fdopt = 0x1
-	const Ordwr    	: fdopt = 0x2
-	const Ondelay  	: fdopt = 0x4
-	const Oappend  	: fdopt = 0x8
-	const Ocreat   	: fdopt = 0x200
-	const Onofollow	: fdopt = 0x100
-	const Otrunc   	: fdopt = 0x400
-	const Odir	: fdopt = 0x100000
-
-	/* stat modes */
-	const Sifmt	: filemode = 0xf000
-	const Sififo	: filemode = 0x1000
-	const Sifchr	: filemode = 0x2000
-	const Sifdir	: filemode = 0x4000
-	const Sifblk	: filemode = 0x6000
-	const Sifreg	: filemode = 0x8000
-	const Siflnk	: filemode = 0xa000
-	const Sifsock	: filemode = 0xc000
-
-	/* mmap protection */
-	const Mprotnone	: mprot = 0x0
-	const Mprotrd	: mprot = 0x1
-	const Mprotwr	: mprot = 0x2
-	const Mprotexec	: mprot = 0x4
-	const Mprotrw	: mprot = 0x3
-
-	/* mmap options */
-	const Mshared	: mopt = 0x1
-	const Mpriv	: mopt = 0x2
-	const Mfixed	: mopt = 0x10
-	const Mfile	: mopt = 0x0
-	const Manon	: mopt = 0x1000
-	/* Only on Linux
-	const M32bit	: mopt = 0x40
-	*/
-
-	/* socket families. INCOMPLETE. */
-	const Afunspec	: sockfam = 0
-	const Afunix	: sockfam = 1
-	const Afinet	: sockfam = 2
-	const Afinet6	: sockfam = 30
-
-	/* socket types. */
-	const Sockstream	: socktype = 1
-	const Sockdgram		: socktype = 2
-	const Sockraw		: socktype = 3
-	const Sockrdm		: socktype = 4
-	const Sockseqpacket	: socktype = 5
-
-	/* network protocols */
-	const Ipproto_ip	: sockproto = 0
-	const Ipproto_icmp	: sockproto = 1
-	const Ipproto_tcp	: sockproto = 6
-	const Ipproto_udp	: sockproto = 17
-	const Ipproto_raw	: sockproto = 255
-
-	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
-
-	/* syscalls.
-	note, creat() implemented as open(path, Creat|Trunc|Wronly) */
-	const Syssyscall	: scno = 0x2000000
-	const Sysexit		: scno = 0x2000001
-	const Sysfork		: scno = 0x2000002
-	const Sysread		: scno = 0x2000003
-	const Syswrite		: scno = 0x2000004
-	const Sysopen		: scno = 0x2000005
-	const Sysclose		: scno = 0x2000006
-	const Syswait4		: scno = 0x2000007
-	const Syslink		: scno = 0x2000009
-	const Sysunlink		: scno = 0x200000a
-	const Syschdir		: scno = 0x200000c
-	const Sysfchdir		: scno = 0x200000d
-	const Sysmknod		: scno = 0x200000e
-	const Syschmod		: scno = 0x200000f
-	const Syschown		: scno = 0x2000010
-	const Sysgetfsstat	: scno = 0x2000012
-	const Sysgetpid		: scno = 0x2000014
-	const Syssetuid		: scno = 0x2000017
-	const Sysgetuid		: scno = 0x2000018
-	const Sysgeteuid	: scno = 0x2000019
-	const Sysptrace		: scno = 0x200001a
-	const Sysrecvmsg	: scno = 0x200001b
-	const Syssendmsg	: scno = 0x200001c
-	const Sysrecvfrom	: scno = 0x200001d
-	const Sysaccept		: scno = 0x200001e
-	const Sysgetpeername	: scno = 0x200001f
-	const Sysgetsockname	: scno = 0x2000020
-	const Sysaccess		: scno = 0x2000021
-	const Syschflags	: scno = 0x2000022
-	const Sysfchflags	: scno = 0x2000023
-	const Syssync		: scno = 0x2000024
-	const Syskill		: scno = 0x2000025
-	const Sysgetppid	: scno = 0x2000027
-	const Sysdup		: scno = 0x2000029
-	const Syspipe		: scno = 0x200002a
-	const Sysgetegid	: scno = 0x200002b
-	const Sysprofil		: scno = 0x200002c
-	const Syssigaction	: scno = 0x200002e
-	const Sysgetgid		: scno = 0x200002f
-	const Syssigprocmask	: scno = 0x2000030
-	const Sysgetlogin	: scno = 0x2000031
-	const Syssetlogin	: scno = 0x2000032
-	const Sysacct		: scno = 0x2000033
-	const Syssigpending	: scno = 0x2000034
-	const Syssigaltstack	: scno = 0x2000035
-	const Sysioctl		: scno = 0x2000036
-	const Sysreboot		: scno = 0x2000037
-	const Sysrevoke		: scno = 0x2000038
-	const Syssymlink	: scno = 0x2000039
-	const Sysreadlink	: scno = 0x200003a
-	const Sysexecve		: scno = 0x200003b
-	const Sysumask		: scno = 0x200003c
-	const Syschroot		: scno = 0x200003d
-	const Sysmsync		: scno = 0x2000041
-	const Sysvfork		: scno = 0x2000042
-	const Sysmunmap		: scno = 0x2000049
-	const Sysmprotect	: scno = 0x200004a
-	const Sysmadvise	: scno = 0x200004b
-	const Sysmincore	: scno = 0x200004e
-	const Sysgetgroups	: scno = 0x200004f
-	const Syssetgroups	: scno = 0x2000050
-	const Sysgetpgrp	: scno = 0x2000051
-	const Syssetpgid	: scno = 0x2000052
-	const Syssetitimer	: scno = 0x2000053
-	const Sysswapon		: scno = 0x2000055
-	const Sysgetitimer	: scno = 0x2000056
-	const Sysgetdtablesize	: scno = 0x2000059
-	const Sysdup2		: scno = 0x200005a
-	const Sysfcntl		: scno = 0x200005c
-	const Sysselect		: scno = 0x200005d
-	const Sysfsync		: scno = 0x200005f
-	const Syssetpriority	: scno = 0x2000060
-	const Syssocket		: scno = 0x2000061
-	const Sysconnect	: scno = 0x2000062
-	const Sysgetpriority	: scno = 0x2000064
-	const Sysbind		: scno = 0x2000068
-	const Syssetsockopt	: scno = 0x2000069
-	const Syslisten		: scno = 0x200006a
-	const Syssigsuspend	: scno = 0x200006f
-	const Sysgettimeofday	: scno = 0x2000074
-	const Sysgetrusage	: scno = 0x2000075
-	const Sysgetsockopt	: scno = 0x2000076
-	const Sysreadv		: scno = 0x2000078
-	const Syswritev		: scno = 0x2000079
-	const Syssettimeofday	: scno = 0x200007a
-	const Sysfchown		: scno = 0x200007b
-	const Sysfchmod		: scno = 0x200007c
-	const Syssetreuid	: scno = 0x200007e
-	const Syssetregid	: scno = 0x200007f
-	const Sysrename		: scno = 0x2000080
-	const Sysflock		: scno = 0x2000083
-	const Sysmkfifo		: scno = 0x2000084
-	const Syssendto		: scno = 0x2000085
-	const Sysshutdown	: scno = 0x2000086
-	const Syssocketpair	: scno = 0x2000087
-	const Sysmkdir		: scno = 0x2000088
-	const Sysrmdir		: scno = 0x2000089
-	const Sysutimes		: scno = 0x200008a
-	const Sysfutimes	: scno = 0x200008b
-	const Sysadjtime	: scno = 0x200008c
-	const Sysgethostuuid	: scno = 0x200008e
-	const Syssetsid		: scno = 0x2000093
-	const Sysgetpgid	: scno = 0x2000097
-	const Syssetprivexec	: scno = 0x2000098
-	const Syspread		: scno = 0x2000099
-	const Syspwrite		: scno = 0x200009a
-	const Sysnfssvc		: scno = 0x200009b
-	const Sysstatfs		: scno = 0x200009d
-	const Sysfstatfs	: scno = 0x200009e
-	const Sysunmount	: scno = 0x200009f
-	const Sysgetfh		: scno = 0x20000a1
-	const Sysquotactl	: scno = 0x20000a5
-	const Sysmount		: scno = 0x20000a7
-	const Syscsops		: scno = 0x20000a9
-	const Syswaitid		: scno = 0x20000ad
-	const Sysadd_profil	: scno = 0x20000b0
-	const Syskdebug_trace	: scno = 0x20000b4
-	const Syssetgid		: scno = 0x20000b5
-	const Syssetegid	: scno = 0x20000b6
-	const Sysseteuid	: scno = 0x20000b7
-	const Syssigreturn	: scno = 0x20000b8
-	const Syschud		: scno = 0x20000b9
-	const Sysfdatasync	: scno = 0x20000bb
-	const Sysstat		: scno = 0x20000bc
-	const Sysfstat		: scno = 0x20000bd
-	const Syslstat		: scno = 0x20000be
-	const Syspathconf	: scno = 0x20000bf
-	const Sysfpathconf	: scno = 0x20000c0
-	const Sysgetrlimit	: scno = 0x20000c2
-	const Syssetrlimit	: scno = 0x20000c3
-	const Sysgetdirentries	: scno = 0x20000c4
-	const Sysmmap		: scno = 0x20000c5
-	const Syslseek		: scno = 0x20000c7
-	const Systruncate	: scno = 0x20000c8
-	const Sysftruncate	: scno = 0x20000c9
-	const Sys__sysctl	: scno = 0x20000ca
-	const Sysmlock		: scno = 0x20000cb
-	const Sysmunlock	: scno = 0x20000cc
-	const Sysundelete	: scno = 0x20000cd
-	const SysATsocket	: scno = 0x20000ce
-	const SysATgetmsg	: scno = 0x20000cf
-	const SysATputmsg	: scno = 0x20000d0
-	const SysATPsndreq	: scno = 0x20000d1
-	const SysATPsndrsp	: scno = 0x20000d2
-	const SysATPgetreq	: scno = 0x20000d3
-	const SysATPgetrsp	: scno = 0x20000d4
-	const Sysmkcomplex	: scno = 0x20000d8
-	const Sysstatv		: scno = 0x20000d9
-	const Syslstatv		: scno = 0x20000da
-	const Sysfstatv		: scno = 0x20000db
-	const Sysgetattrlist	: scno = 0x20000dc
-	const Syssetattrlist	: scno = 0x20000dd
-	const Sysgetdirentriesattr	: scno = 0x20000de
-	const Sysexchangedata	: scno = 0x20000df
-	const Syssearchfs	: scno = 0x20000e1
-	const Sysdelete		: scno = 0x20000e2
-	const Syscopyfile	: scno = 0x20000e3
-	const Sysfgetattrlist	: scno = 0x20000e4
-	const Sysfsetattrlist	: scno = 0x20000e5
-	const Syspoll		: scno = 0x20000e6
-	const Syswatchevent	: scno = 0x20000e7
-	const Syswaitevent	: scno = 0x20000e8
-	const Sysmodwatch	: scno = 0x20000e9
-	const Sysgetxattr	: scno = 0x20000ea
-	const Sysfgetxattr	: scno = 0x20000eb
-	const Syssetxattr	: scno = 0x20000ec
-	const Sysfsetxattr	: scno = 0x20000ed
-	const Sysremovexattr	: scno = 0x20000ee
-	const Sysfremovexattr	: scno = 0x20000ef
-	const Syslistxattr	: scno = 0x20000f0
-	const Sysflistxattr	: scno = 0x20000f1
-	const Sysfsctl		: scno = 0x20000f2
-	const Sysinitgroups	: scno = 0x20000f3
-	const Sysposix_spawn	: scno = 0x20000f4
-	const Sysffsctl		: scno = 0x20000f5
-	const Sysnfsclnt	: scno = 0x20000f7
-	const Sysfhopen		: scno = 0x20000f8
-	const Sysminherit	: scno = 0x20000fa
-	const Syssemsys		: scno = 0x20000fb
-	const Sysmsgsys		: scno = 0x20000fc
-	const Sysshmsys		: scno = 0x20000fd
-	const Syssemctl		: scno = 0x20000fe
-	const Syssemget		: scno = 0x20000ff
-	const Syssemop		: scno = 0x2000100
-	const Sysmsgctl		: scno = 0x2000102
-	const Sysmsgget		: scno = 0x2000103
-	const Sysmsgsnd		: scno = 0x2000104
-	const Sysmsgrcv		: scno = 0x2000105
-	const Sysshmat		: scno = 0x2000106
-	const Sysshmctl		: scno = 0x2000107
-	const Sysshmdt		: scno = 0x2000108
-	const Sysshmget		: scno = 0x2000109
-	const Sysshm_open	: scno = 0x200010a
-	const Sysshm_unlink	: scno = 0x200010b
-	const Syssem_open	: scno = 0x200010c
-	const Syssem_close	: scno = 0x200010d
-	const Syssem_unlink	: scno = 0x200010e
-	const Syssem_wait	: scno = 0x200010f
-	const Syssem_trywait	: scno = 0x2000110
-	const Syssem_post	: scno = 0x2000111
-	const Syssem_getvalue	: scno = 0x2000112
-	const Syssem_init	: scno = 0x2000113
-	const Syssem_destroy	: scno = 0x2000114
-	const Sysopen_extended	: scno = 0x2000115
-	const Sysumask_extended	: scno = 0x2000116
-	const Sysstat_extended	: scno = 0x2000117
-	const Syslstat_extended	: scno = 0x2000118
-	const Sysfstat_extended	: scno = 0x2000119
-	const Syschmod_extended	: scno = 0x200011a
-	const Sysfchmod_extended	: scno = 0x200011b
-	const Sysaccess_extended	: scno = 0x200011c
-	const Syssettid		: scno = 0x200011d
-	const Sysgettid		: scno = 0x200011e
-	const Syssetsgroups	: scno = 0x200011f
-	const Sysgetsgroups	: scno = 0x2000120
-	const Syssetwgroups	: scno = 0x2000121
-	const Sysgetwgroups	: scno = 0x2000122
-	const Sysmkfifo_extended	: scno = 0x2000123
-	const Sysmkdir_extended	: scno = 0x2000124
-	const Sysidentitysvc	: scno = 0x2000125
-	const Sysshared_region_check_np	: scno = 0x2000126
-	const Sysshared_region_map_np	: scno = 0x2000127
-	const Sysvm_pressure_monitor	: scno = 0x2000128
-	const Syspsynch_rw_longrdlock	: scno = 0x2000129
-	const Syspsynch_rw_yieldwrlock	: scno = 0x200012a
-	const Syspsynch_rw_downgrade	: scno = 0x200012b
-	const Syspsynch_rw_upgrade	: scno = 0x200012c
-	const Syspsynch_mutexwait	: scno = 0x200012d
-	const Syspsynch_mutexdrop	: scno = 0x200012e
-	const Syspsynch_cvbroad	: scno = 0x200012f
-	const Syspsynch_cvsignal	: scno = 0x2000130
-	const Syspsynch_cvwait	: scno = 0x2000131
-	const Syspsynch_rw_rdlock	: scno = 0x2000132
-	const Syspsynch_rw_wrlock	: scno = 0x2000133
-	const Syspsynch_rw_unlock	: scno = 0x2000134
-	const Syspsynch_rw_unlock2	: scno = 0x2000135
-	const Sysgetsid		: scno = 0x2000136
-	const Syssettid_with_pid	: scno = 0x2000137
-	const Sysaio_fsync	: scno = 0x2000139
-	const Sysaio_return	: scno = 0x200013a
-	const Sysaio_suspend	: scno = 0x200013b
-	const Sysaio_cancel	: scno = 0x200013c
-	const Sysaio_error	: scno = 0x200013d
-	const Sysaio_read	: scno = 0x200013e
-	const Sysaio_write	: scno = 0x200013f
-	const Syslio_listio	: scno = 0x2000140
-	const Sysiopolicysys	: scno = 0x2000142
-	const Sysmlockall	: scno = 0x2000144
-	const Sysmunlockall	: scno = 0x2000145
-	const Sysissetugid	: scno = 0x2000147
-	const Sys__pthread_kill	: scno = 0x2000148
-	const Sys__pthread_sigmask	: scno = 0x2000149
-	const Sys__sigwait	: scno = 0x200014a
-	const Sys__disable_threadsignal	: scno = 0x200014b
-	const Sys__pthread_markcancel	: scno = 0x200014c
-	const Sys__pthread_canceled	: scno = 0x200014d
-	const Sys__semwait_signal	: scno = 0x200014e
-	const Sysproc_info	: scno = 0x2000150
-	const Syssendfile	: scno = 0x2000151
-	const Sysstat64		: scno = 0x2000152
-	const Sysfstat64	: scno = 0x2000153
-	const Syslstat64	: scno = 0x2000154
-	const Sysstat64_extended	: scno = 0x2000155
-	const Syslstat64_extended	: scno = 0x2000156
-	const Sysfstat64_extended	: scno = 0x2000157
-	const Sysgetdirentries64	: scno = 0x2000158
-	const Sysstatfs64	: scno = 0x2000159
-	const Sysfstatfs64	: scno = 0x200015a
-	const Sysgetfsstat64	: scno = 0x200015b
-	const Sys__pthread_chdir	: scno = 0x200015c
-	const Sys__pthread_fchdir	: scno = 0x200015d
-	const Sysaudit		: scno = 0x200015e
-	const Sysauditon	: scno = 0x200015f
-	const Sysgetauid	: scno = 0x2000161
-	const Syssetauid	: scno = 0x2000162
-	const Sysgetaudit	: scno = 0x2000163
-	const Syssetaudit	: scno = 0x2000164
-	const Sysgetaudit_addr	: scno = 0x2000165
-	const Syssetaudit_addr	: scno = 0x2000166
-	const Sysauditctl	: scno = 0x2000167
-	const Sysbsdthread_create	: scno = 0x2000168
-	const Sysbsdthread_terminate	: scno = 0x2000169
-	const Syskqueue		: scno = 0x200016a
-	const Syskevent		: scno = 0x200016b
-	const Syslchown		: scno = 0x200016c
-	const Sysstack_snapshot	: scno = 0x200016d
-	const Sysbsdthread_register	: scno = 0x200016e
-	const Sysworkq_open	: scno = 0x200016f
-	const Sysworkq_kernreturn	: scno = 0x2000170
-	const Syskevent64	: scno = 0x2000171
-	const Sys__old_semwait_signal	: scno = 0x2000172
-	const Sys__old_semwait_signal_nocancel	: scno = 0x2000173
-	const Systhread_selfid	: scno = 0x2000174
-	const Sys__mac_execve	: scno = 0x200017c
-	const Sys__mac_syscall	: scno = 0x200017d
-	const Sys__mac_get_file	: scno = 0x200017e
-	const Sys__mac_set_file	: scno = 0x200017f
-	const Sys__mac_get_link	: scno = 0x2000180
-	const Sys__mac_set_link	: scno = 0x2000181
-	const Sys__mac_get_proc	: scno = 0x2000182
-	const Sys__mac_set_proc	: scno = 0x2000183
-	const Sys__mac_get_fd	: scno = 0x2000184
-	const Sys__mac_set_fd	: scno = 0x2000185
-	const Sys__mac_get_pid	: scno = 0x2000186
-	const Sys__mac_get_lcid	: scno = 0x2000187
-	const Sys__mac_get_lctx	: scno = 0x2000188
-	const Sys__mac_set_lctx	: scno = 0x2000189
-	const Syssetlcid	: scno = 0x200018a
-	const Sysgetlcid	: scno = 0x200018b
-	const Sysread_nocancel	: scno = 0x200018c
-	const Syswrite_nocancel	: scno = 0x200018d
-	const Sysopen_nocancel	: scno = 0x200018e
-	const Sysclose_nocancel	: scno = 0x200018f
-	const Syswait4_nocancel	: scno = 0x2000190
-	const Sysrecvmsg_nocancel	: scno = 0x2000191
-	const Syssendmsg_nocancel	: scno = 0x2000192
-	const Sysrecvfrom_nocancel	: scno = 0x2000193
-	const Sysaccept_nocancel	: scno = 0x2000194
-	const Sysmsync_nocancel		: scno = 0x2000195
-	const Sysfcntl_nocancel		: scno = 0x2000196
-	const Sysselect_nocancel	: scno = 0x2000197
-	const Sysfsync_nocancel		: scno = 0x2000198
-	const Sysconnect_nocancel	: scno = 0x2000199
-	const Syssigsuspend_nocancel	: scno = 0x200019a
-	const Sysreadv_nocancel		: scno = 0x200019b
-	const Syswritev_nocancel	: scno = 0x200019c
-	const Syssendto_nocancel	: scno = 0x200019d
-	const Syspread_nocancel		: scno = 0x200019e
-	const Syspwrite_nocancel	: scno = 0x200019f
-	const Syswaitid_nocancel	: scno = 0x20001a0
-	const Syspoll_nocancel		: scno = 0x20001a1
-	const Sysmsgsnd_nocancel	: scno = 0x20001a2
-	const Sysmsgrcv_nocancel	: scno = 0x20001a3
-	const Syssem_wait_nocancel	: scno = 0x20001a4
-	const Sysaio_suspend_nocancel	: scno = 0x20001a5
-	const Sys__sigwait_nocancel	: scno = 0x20001a6
-	const Sys__semwait_signal_nocancel	: scno = 0x20001a7
-	const Sys__mac_mount		: scno = 0x20001a8
-	const Sys__mac_get_mount	: scno = 0x20001a9
-	const Sys__mac_getfsstat	: scno = 0x20001aa
-	const Sysfsgetpath		: scno = 0x20001ab
-	const Sysaudit_session_self	: scno = 0x20001ac
-	const Sysaudit_session_join	: scno = 0x20001ad
-	const Syspid_suspend		: scno = 0x20001ae
-	const Syspid_resume		: scno = 0x20001af
-	const Sysfileport_makeport	: scno = 0x20001b0
-	const Sysfileport_makefd	: scno = 0x20001b1
-
-	extern const syscall : (sc:scno, args:... -> int64)
-
-	/* process control */
-	const exit	: (status:int -> void)
-	const getpid	: ( -> pid)
-	const kill	: (pid : pid, sig:int64 -> int64)
-	const fork	: (-> pid)
-	const wait4	: (pid : pid, loc:int32#, opt : int64, rusage:rusage#	-> int64)
-	const waitpid	: (pid : pid, loc:int32#, opt : int64	-> int64)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	/* wrappers to extract wait status */
-	const waitstatus	: (st : int32 -> waitstatus)
-
-	/* file manipulation */
-	const open	: (path:byte[:], opts:fdopt -> fd)
-	const openmode	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
-	const close	: (fd:fd -> int64)
-	const creat	: (path:byte[:], mode:int64 -> fd)
-	const unlink	: (path:byte[:] -> int)
-	const read	: (fd:fd, buf:byte[:] -> size)
-	const write	: (fd:fd, buf:byte[:] -> size)
-	const lseek	: (fd:fd, off:off, whence:whence -> off)
-	const stat	: (path:byte[:], sb:statbuf# -> int64)
-	const lstat	: (path:byte[:], sb:statbuf# -> int64)
-	const fstat	: (fd:fd, sb:statbuf# -> int64)
-	const mkdir	: (path : byte[:], mode : int64	-> int64)
-	generic ioctl	: (fd:fd, req : int64, args:@a# -> int64)
-	const getdirentries64	: (fd : fd, buf : byte[:], basep : int64# -> int64)
-	const chdir	: (p : byte[:] -> int64)
-
-	/* fd stuff */
-	const pipe	: (fd : fd[2]# -> int64)
-	const dup	: (fd : fd -> fd)
-	const dup2	: (src : fd, dst : fd -> fd)
-	/* NB: the C ABI uses '...' for the args. */
-	const fcntl	: (fd : fd, cmd : fcntlcmd, args : byte# -> int64)
-
-	/* kqueue */
-	const kqueue	: (-> fd)
-	const kevent	: (q : fd, cl : kevent[:], el : kevent[:], flg : kflags, timeout : timespec# -> int64)
-	const kevent64	: (q : fd, cl : kevent64[:], el : kevent64[:], flg : kflags, timeout : timespec# -> int64)
-
-
-
-	/* networking */
-	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
-	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
-	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
-	const listen	: (sock : fd, backlog : int	-> int)
-	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
-
-
-	/* memory mapping */
-	const munmap	: (addr:byte#, len:size -> int64)
-	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
-
-	/* time */
-	const gettimeofday	: (tv : timeval#, tz : timezone# -> int)
-	const settimeofday	: (tv : timeval#, tz : timezone# -> int)
-	/* faked with gettimeofday */
-	const clock_getres	: (clk : clock, ts : timespec# -> int)
-	const clock_gettime	: (clk : clock, ts : timespec# -> int)
-	const clock_settime	: (clk : clock, ts : timespec# -> int)
-	/* FIXME: HACK HACK HACK -- does nothing */
-	const sleep	: (time : uint64 -> int32)
-
-	/* system information */
-	const uname 	: (buf : utsname# -> int)
-	const sysctl	: (mib : int[:], old : byte[:]#, new : byte[:] -> int)
-
-	/* filled by start code */
-	extern const __cenvp : byte##
-	extern const __environment : byte[:][:]
-;;
-
-/*
-wraps a syscall argument, converting it to 64 bits for the syscall function. This is
-the same as casting, but more concise than writing castto(int64)
-*/
-generic a = {x : @t
-	-> x castto(uint64)
-}
-
-/* OSX has a number of funky syscalls */
-extern const __osx_fork	: (-> pid)
-extern const __osx_pipe : (fd : fd[2]# -> int64)
-extern const __osx_getpid	: (-> pid)
-extern const __osx_lseek	: (fd:fd, off:off, whence:whence -> off)
-extern const __osx_gettimeofday	: (tv : timeval#, tz : timezone# -> int)
-/*
-extern const __osx_ptrace
-extern const __osx_signalstack
-extern const __osx_sigreturn
-extern const __osx_thread_selfid
-extern const __osx_vfork
-*/
-
-extern const cstring : (str : byte[:] -> byte#)
-extern const alloca : (sz : size -> byte#)
-
-/* process control */
-const exit	= {status;		syscall(Sysexit, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
-const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
-const fork	= {;			-> __osx_fork()}
-const wait4	= {pid, loc, opt, rusage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(rusage))}
-const waitpid	= {pid, loc, opt;
-	-> wait4(pid, loc, opt, 0 castto(rusage#))
-}
-
-const sleep = {time;	-> 0}
-
-const execv	= {cmd, args
-	var p, cargs, i
-
-	/* doesn't just call execve() for efficiency's sake. */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
-}
-
-const execve	= {cmd, args, env
-	var cargs, cenv, i
-	var p
-
-	/* copy the args */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-
-	/*
-	 copy the env.
-	 of course we fucking have to duplicate this code everywhere,
-	 since we want to stack allocate...
-	*/
-	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
-	for i = 0; i < env.len; i++
-		cenv[i] = cstring(env[i])
-	;;
-	cenv[env.len] = 0 castto(byte#)
-
-	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
-}
-
-
-/* fd manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
-const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const lseek	= {fd, off, whence;	-> __osx_lseek(fd, off, whence)}
-const stat	= {path, sb;		-> syscall(Sysstat64, cstring(path), a(sb))}
-const lstat	= {path, sb;		-> syscall(Syslstat64, cstring(path), a(sb))}
-const fstat	= {fd, sb;		-> syscall(Sysfstat64, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
-const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries64, a(fd), buf castto(byte#), a(buf.len), a(basep))}
-const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
-
-/* fd stuff */
-const pipe	= {fd;	-> __osx_pipe(fd)}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
-const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}
-
-/* kqueueueueueueue */
-const kqueue	= {;	-> syscall(Syskqueue) castto(fd)}
-const kevent	= {q, cl, el, flg, timeout
-	-> syscall(Syskevent, a(q), \
-		cl castto(kevent#), a(cl.len), \
-		el castto(kevent#), a(el.len), \
-		a(flg), \
-		timeout)
-}
-
-const kevent64	= {q, cl, el, flg, timeout
-	-> syscall(Syskevent, a(q), \
-		cl castto(kevent#), a(cl.len), \
-		el castto(kevent#), a(el.len), \
-		a(flg), \
-		timeout)
-}
-
-/* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-
-/* memory management */
-const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
-const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
-
-/* time */
-const gettimeofday = {tv, tz;	-> __osx_gettimeofday(tv, tz) castto(int)}
-const settimeofday = {tv, tz;	-> syscall(Syssettimeofday, a(tv), a(tz)) castto(int)}
-
-/* faked  with gettimeofday */
-const clock_getres = {clk, ts
-	ts.sec = 0
-	ts.nsec = 1000*10 /* 10ms is reasonable resolution */
-	-> 0
-}
-
-const clock_gettime = {clk, ts
-	var tv
-	var ret
-
-	ret = gettimeofday(&tv, 0 castto(timezone#))
-	ts.sec = tv.sec
-	ts.nsec = tv.usec * 1000
-	-> ret
-}
-
-const clock_settime = {clk, ts
-	var tv
-
-	tv.sec = ts.sec
-	tv.usec = ts.nsec / 1000
-	-> settimeofday(&tv, 0 castto(timezone#))
-}
-
-/* system information */
-const uname	= {buf;
-	var mib : int[2]
-	var ret
-	var sys
-	var nod
-	var rel
-	var ver
-	var mach
-
-	ret = 0
-	mib[0] = 1 /* CTL_KERN */
-	mib[1] = 1 /* KERN_OSTYPE */
-	sys = buf.system[:]
-	ret = sysctl(mib[:], &sys, [][:])
-	if ret < 0
-		-> ret
-	;;
-
-	mib[0] = 1 /* CTL_KERN */
-	mib[1] = 10 /* KERN_HOSTNAME */
-	nod = buf.node[:]
-	ret = sysctl(mib[:], &nod, [][:])
-	if ret < 0
-		-> ret
-	;;
-
-	mib[0] = 1 /* CTL_KERN */
-	mib[1] = 2 /* KERN_OSRELEASE */
-	rel = buf.release[:]
-	ret = sysctl(mib[:], &rel, [][:])
-	if ret < 0
-		-> ret
-	;;
-
-	mib[0] = 1 /* CTL_KERN */
-	mib[1] = 4 /* KERN_VERSION */
-	ver = buf.version[:]
-	ret = sysctl(mib[:], &ver, [][:])
-	if ret < 0
-		-> ret
-	;;
-
-	mib[0] = 6 /* CTL_HW */
-	mib[1] = 1 /* HW_MACHINE */
-	mach = buf.machine[:]
-	ret = sysctl(mib[:], &mach, [][:])
-	if ret < 0
-		-> ret
-	;;
-
-	-> 0
-}
-
-const sysctl = {mib, old, new
-	var mibp
-	var mibsz
-	var o
-	var oldp
-	var oldsz
-	var newp
-	var newsz
-	var ret
-
-	mibp = mib castto(byte#)
-	mibsz = mib.len castto(uint64)
-	o = old#
-	oldp = o castto(byte#)
-	oldsz = (o.len castto(uint64))
-	if new.len > 0
-		newp = new castto(byte#)
-		newsz = new.len castto(uint64)
-	else
-		newp = 0 castto(byte#)
-		newsz = 0
-	;;
-
-	ret = syscall(Sys__sysctl, a(mibp), a(mibsz), a(oldp), a(&oldsz), a(newp), a(newsz)) castto(int)
-
-	old# = o[:oldsz]
-	-> ret
-}
-
-const waitstatus = {st
-	if st < 0
-		-> `Waitfail st
-	;;
-	match st & 0o177
-	| 0:    -> `Waitexit (st >> 8)
-	| 0o177:-> `Waitstop (st >> 8)
-	| sig:  -> `Waitsig sig
-	;;
-}
-
--- a/libstd/sys+plan9-x64.myr
+++ /dev/null
@@ -1,242 +1,0 @@
-use "systypes.use"
-
-pkg sys =
-	type scno	= int64	/* syscall */
-	type pid	= int32 /* process id */
-	type fdopt	= int32	/* fd options */
-	type fd		= int32	/* fd */
-	type rflags	= int32	/* rfork flags */
-
-	type tos = struct
-		prof	: prof
-		cyclefreq	: uint64
-		kcycles	: int64
-		pcycles	: int64
-		pid	: pid
-		clock	: uint32
-	;;
-
-	type prof = struct
-		pp	: byte#	/* plink */
-		next	: byte#	/* plink */
-		last	: byte#	/* plink */
-		first	: byte#	/* plink */
-		pid	: pid	/* plink */
-		what	: uint32	/* plink */
-	;;
-
-
-	const Ordonly	: fdopt = 0
-	const Owronly	: fdopt = 1
-	const Ordwr	: fdopt = 2
-	const Oexec	: fdopt = 3
-
-	const Otrunc	: fdopt = 16
-	const Ocexec	: fdopt = 32
-	const Orclose	: fdopt = 64
-	const Oexcl	: fdopt = 0x1000
-
-	const Qtdir	: int  = 0x80
-	const Qtappend	: int  = 0x40
-	const Qtexcl	: int  = 0x20
-	const Qtmount	: int  = 0x10
-	const Qtauth	: int  = 0x08
-	const Qttmp	: int  = 0x04
-	const Qtfile	: int  = 0x00
-
-	const Dmdir	: int = 0x8000000
-	const Dmappend	: int = 0x4000000
-	const Dmexcl	: int = 0x2000000
-	const Dmmount	: int = 0x1000000
-	const Dmauth	: int = 0x0800000
-	const Dmtmp	: int = 0x0400000
-	const Dmread	: int = 0x4
-	const Dmwrite	: int = 0x2
-	const Dmexec	: int = 0x1
-
-	const Rfnameg	: rflags = 1 << 0
-	const Rfenvg	: rflags = 1 << 1
-	const Rffdg	: rflags = 1 << 2
-	const Rfnoteg	: rflags = 1 << 3
-	const Rfproc	: rflags = 1 << 4
-	const Rfmem	: rflags = 1 << 5
-	const Rfnowait	: rflags = 1 << 6
-	const Rfcnameg	: rflags = 1 << 10
-	const Rfcenvg	: rflags = 1 << 11
-	const Rfcfdg	: rflags = 1 << 12
-	const Rfrend	: rflags = 1 << 13
-	const Rfnomnt	: rflags = 1 << 14
-
-	const Syssysr1		: scno = 0
-	const Sys_errstr	: scno = 1
-	const Sysbind		: scno = 2
-	const Syschdir		: scno = 3
-	const Sysclose		: scno = 4
-	const Sysdup		: scno = 5
-	const Sysalarm		: scno = 6
-	const Sysexec		: scno = 7
-	const Sysexits		: scno = 8
-	const Sys_fsession	: scno = 9
-	const Sysfauth		: scno = 10
-	const Sys_fstat		: scno = 11
-	const Syssegbrk		: scno = 12
-	const Sys_mount		: scno = 13
-	const Sysopen		: scno = 14
-	const Sys_read		: scno = 15
-	const Sysoseek		: scno = 16
-	const Syssleep		: scno = 17
-	const Sys_stat		: scno = 18
-	const Sysrfork		: scno = 19
-	const Sys_write		: scno = 20
-	const Syspipe		: scno = 21
-	const Syscreate		: scno = 22
-	const Sysfd2path	: scno = 23
-	const Sysbrk_		: scno = 24
-	const Sysremove		: scno = 25
-	const Sys_wstat		: scno = 26
-	const Sys_fwstat	: scno = 27
-	const Sysnotify		: scno = 28
-	const Sysnoted		: scno = 29
-	const Syssegattach	: scno = 30
-	const Syssegdetach	: scno = 31
-	const Syssegfree	: scno = 32
-	const Syssegflush	: scno = 33
-	const Sysrendezvous	: scno = 34
-	const Sysunmount	: scno = 35
-	const Sys_wait		: scno = 36
-	const Syssemacquire	: scno = 37
-	const Syssemrelease	: scno = 38
-	const Sysseek		: scno = 39
-	const Sysfversion	: scno = 40
-	const Syserrstr		: scno = 41
-	const Sysstat		: scno = 42
-	const Sysfstat		: scno = 43
-	const Syswstat		: scno = 44
-	const Sysfwstat		: scno = 45
-	const Sysmount		: scno = 46
-	const Sysawait		: scno = 47
-	const Syspread		: scno = 50
-	const Syspwrite		: scno = 51
-	const Systsemacquire	: scno = 52
-	const Sys_nsec		: scno = 53
-
-
-	const sysr1	: (-> int64)
-	const bind	: (nm : byte[:], old : byte[:] -> int64)
-	const chdir	: (dir : byte[:] -> int64)
-	const close	: (fd : fd -> int64)
-	const dup	: (old : fd, new : fd -> fd)
-	const alarm	: (msec : uint32 -> int64)
-	const exits	: (msg : byte[:] -> int64)
-	const fauth	: (fd : fd, name : byte[:] -> int64)
-	const segbrk	: (saddr : void#, addr : void# -> int64)
-	const open	: (path : byte[:], opt : fdopt -> fd)
-	const sleep	: (msec : uint32 -> int64)
-	const rfork	: (rflags : rflags -> pid)
-	const pipe	: (fds : fd[2]# -> int64)
-	const create	: (path : byte[:], opt : fdopt, perm : int -> fd)
-	const fd2path	: (fd : fd, path : byte[:] -> int64)
-	const remove	: (path : byte[:] -> int64)
-	const notify	: (fn : (a : void#, c : char# -> int64) -> int64)
-	const noted	: (v : int32 -> int64)
-	const segattach	: (attr : int32, class : byte[:], va : void#, len : uint32 -> int64)
-	const segdetach	: (va : void# -> int64)
-	const segfree	: (va : byte#, len : size -> int64)
-	const segflush	: (va : void#, len : uint32 -> int64)
-	const unmount	: (name : byte[:], old : byte[:] -> int64)
-	const errstr	: (buf : byte[:] -> int64)
-	const stat	: (name : byte[:], edir : byte[:] -> int64)
-	const fstat	: (fd : fd, edir : byte[:] -> int64)
-	const wstat	: (name : byte[:], edir : byte[:] -> int64)
-	const fwstat	: (fd : byte[:],  edir : byte[:] -> int64)
-	const seek	: (fd : fd, len : off, ty : int64 -> off)
-	const mount	: (fd : fd, afd : fd, old : byte[:], flag : int32, aname : byte[:] -> int64)
-	const await	: (buf : byte[:] -> int64)
-	const pread	: (fd : fd, buf : byte[:], off : off -> size)
-	const pwrite	: (fd : fd, buf : byte[:], off : off -> size)
-	const exec	: (bin : byte[:], args : byte[:][:] -> int64)
-	const brk_	: (endp : byte# -> int64)
-	const nsec	: (-> uint64)
-
-	extern const alloca	: (sz : size	-> byte#)
-
-	extern var tosptr	: tos#
-	extern var curbrk	: byte#
-;;
-
-/* asm stub from syscall.s */
-extern const syscall : (scno : scno, args : ... -> int64)
-/* asm stubs from util+plan9.s */
-extern const cstring	: (str : byte[:] -> byte#)
-extern const alloca	: (sz : size	-> byte#)
-
-
-/*
-ABI mismatch: Plan 9 aligns all arguments individually to
-8 bytes, Myrddin uses natural alignment (min(sizeof(t), 16).
-Cast to a 64 bit type to paper over this.
-*/
-generic a	= {a : @t;	-> a castto(uint64)}
-generic s	= {a : @t;	-> a castto(int64)}
-generic p	= {a : @t;	-> a castto(byte#)}
-
-const sysr1	= {;		-> syscall(Syssysr1)}
-const bind	= {name, old;	-> syscall(Sysbind, cstring(name), cstring(old))}
-const chdir 	= {dir;		-> syscall(Syschdir, cstring(dir)) }
-const close 	= {fd;		-> syscall(Sysclose, a(fd))}
-const dup	= {ofd, nfd;	-> syscall(Sysdup, a(ofd), a(nfd)) castto(fd)}
-const alarm 	= {msec;	-> syscall(Sysalarm, a(msec))}
-const exits 	= {msg;		-> syscall(Sysexits, cstring(msg))}
-const fauth 	= {fd, aname;	-> syscall(Sysfauth, a(fd), cstring(aname))}
-const segbrk 	= {saddr, addr;	-> syscall(Syssegbrk, a(saddr), a(addr))}
-const open 	= {path, opt;	-> syscall(Sysopen, cstring(path), a(opt)) castto(fd)}
-const sleep 	= {msec;	-> syscall(Syssleep, a(msec))}
-const rfork 	= {rflags;	-> syscall(Sysrfork, a(rflags)) castto(pid)}
-const pipe 	= {fds;		-> syscall(Syspipe, a(fds))}
-const create 	= {path, mode, perm;	-> syscall(Syscreate, cstring(path), a(mode), a(perm)) castto(fd)}
-const fd2path	= {fd, buf;	-> syscall(Sysfd2path, a(fd), p(buf), a(buf.len))}
-const remove	= {path;	-> syscall(Sysremove, cstring(path))}
-const notify	= {fn;		-> syscall(Sysnotify, fn)}	/* FIXME: this is likely to break when we do closures... */
-const noted	= {v;		-> syscall(Sysnoted, a(v))}
-const segattach	= {attr, class, va, len;	-> syscall(Syssegattach, a(attr), cstring(class), a(va), a(len))}
-const segdetach	= {va;		-> syscall(Syssegdetach, a(va))}
-const segfree	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
-const segflush	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
-const unmount	= {name, old;	-> syscall(Sysunmount, cstring(name), cstring(old))}
-const errstr	= {buf;		-> syscall(Syserrstr, p(buf), a(buf.len))}
-const stat	= {name, edir;	-> syscall(Sysstat, cstring(name), p(edir), a(edir.len))}
-const fstat	= {fd, edir;	-> syscall(Sysstat, a(fd), p(edir), a(edir.len))}
-const wstat	= {name, edir;	-> syscall(Syswstat, cstring(name), p(edir), a(edir.len))}
-const fwstat	= {fd, edir;	-> syscall(Sysfwstat, a(fd), p(edir), a(edir.len))}
-const mount	= {fd, afd, old, flag, aname;	-> syscall(Sysmount, a(fd), a(afd), cstring(old), a(flag), cstring(aname))}
-const pread	= {fd, buf, off;	-> syscall(Syspread, a(fd), p(buf), a(buf.len), off) castto(size)}
-const pwrite	= {fd, buf, off;	-> syscall(Syspwrite, a(fd), p(buf), a(buf.len), s(off)) castto(size)}
-const await	= {buf;	-> syscall(Sysawait, p(buf), a(buf.len))}
-const brk_	= {endp;	-> syscall(Sysbrk_, p(endp))}
-const nsec	= {;	-> syscall(Sys_nsec) castto(uint64)}
-const seek	= {fd, n, ty
-	var ret : off
-	syscall(Sysseek, a(&ret), a(fd), a(n), a(ty))
-	-> ret
-}
-
-const exec	= {bin, args
-	var p, cargs, i
-
-	/* we need an array of C strings. */
-	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (a(p) castto(byte##))[:args.len + 1]
-	for i = 0; i < args.len; i++
-		cargs[i] = cstring(args[i])
-	;;
-	cargs[args.len] = 0 castto(byte#)
-	-> syscall(Sysexec, cstring(bin), a(cargs))
-}
-
-/* ??? do I care for now?
-const fversion	= {fd, bufsz, vers, nvers;	-> syscall(Sysfversion, fd, bufsz, }
-const rendezvous	= {;}
-const semacquire	= {;}
-const semrelease	= {;}
-const tsemacquire	= {;}
-*/
--- a/libstd/syscall+freebsd-x64.s
+++ /dev/null
@@ -1,21 +1,0 @@
-.globl sys$syscall
-sys$syscall:
-	/*
-	hack: We load 6 args regardless of
-	how many we actually have. This may
-	load junk values, but if the syscall
-	doesn't use them, it's going to be
-	harmless.
-	 */
-	movq %rdi,%rax
-	movq %rsi,%rdi
-	movq %rdx,%rsi
-	movq %rcx,%rdx
-	movq %r8,%r10
-	movq %r9,%r8
-	movq 8(%rsp),%r9
-
-	syscall
-
-	ret
-
--- a/libstd/syscall+linux-x64.s
+++ /dev/null
@@ -1,22 +1,0 @@
-.globl sys$syscall
-sys$syscall:
-	/*
-	hack: We load 6 args regardless of
-	how many we actually have. This may
-	load junk values, but if the syscall
-	doesn't use them, it's going to be
-	harmless.
-	 */
-	movq %rdi,%rax
-        /* 8(%rsp): hidden type arg */
-	movq 16(%rsp),%rdi
-	movq 24(%rsp),%rsi
-	movq 32(%rsp),%rdx
-	movq 40(%rsp),%r10
-	movq 48(%rsp),%r8
-	movq 56(%rsp),%r9
-
-	syscall
-
-	ret
-
--- a/libstd/syscall+osx-x64.s
+++ /dev/null
@@ -1,96 +1,0 @@
-.globl _sys$syscall
-_sys$syscall:
-
-	/*
-	hack: We load 6 args regardless of
-	how many we actually have. This may
-	load junk values, but if the syscall
-	doesn't use them, it's going to be
-	harmless.
-	 */
-	movq %rdi,%rax
-        /* 8(%rsp): hidden type arg */
-	movq 16(%rsp),%rdi
-	movq 24(%rsp),%rsi
-	movq 32(%rsp),%rdx
-	movq 40(%rsp),%r10
-	movq 48(%rsp),%r8
-	movq 56(%rsp),%r9
-
-	syscall
-	jae .success
-	negq %rax
-
-.success:
-	ret
-
-/*
- * OSX is strange about fork, and needs an assembly wrapper.
- * The fork() syscall, when called directly, returns the pid in both
- * processes, which means that both parent and child think they're
- * the parent.
- *
- * checking this involves peeking in %edx, so we need to do this in asm.
- */
-.globl _sys$__osx_fork
-_sys$__osx_fork:
-	movq $0x2000002,%rax
-	syscall
-
-	jae .forksuccess
-	negq %rax
-
-.forksuccess:
-	testl %edx,%edx
-	jz .isparent
-	xorq %rax,%rax
-.isparent:
-	ret
-
-/*
- * OSX is strange about pipe, and needs an assembly wrapper.
- * The pipe() syscall returns the pipes created in eax:edx, and
- * needs to copy them to the destination locations manually.
- */
-.globl _sys$__osx_pipe
-_sys$__osx_pipe:
-	movq $0x200002a,%rax
-	syscall
-
-	jae .pipesuccess
-	negq %rax
-
-.pipesuccess:
-	movl %eax,(%rdi)
-	movl %edx,4(%rdi)
-	xorq %rax,%rax
-	ret
-
-.globl _sys$__osx_lseek
-_sys$__osx_lseek:
-	movq $0x20000C7,%rax
-	syscall
-
-	jae .lseeksuccess
-	negq %rax
-
-.lseeksuccess:
-        shlq $32,%rdx
-        orq  %rdx,%rax
-	ret
-
-
-.globl _sys$__osx_gettimeofday
-_sys$__osx_gettimeofday:
-	movq $0x2000074,%rax
-	syscall
-
-	jae .gettimeofdaysuccess
-	negq %rax
-
-.gettimeofdaysuccess:
-	movq %rax, (%rdi)
-	movl %edx,8(%rdi)
-	xorq %rax,%rax
-	ret
-
--- a/libstd/syscall+plan9-x64.s
+++ /dev/null
@@ -1,33 +1,0 @@
-/*
-Ugly: Kernel is caller-save, Myrddin
-is callee-save. We need to preserve
-registers before entering the kernel.
-
-However, we also need SP to point to the
-start of the arguments.
-
-Luckily, the kernel doesn't touch our stack,
-and we have 256 bytes of gap if we get a note.
-*/
-TEXT sys$syscall+0(SB),1,$0
-	MOVQ	R11,-16(SP)
-	MOVQ	R12,-24(SP)
-	MOVQ	R13,-32(SP)
-	MOVQ	R14,-40(SP)
-	MOVQ	R15,-48(SP)
-	MOVQ	BP,-56(SP)
-	MOVQ	8(SP),RARG
-
-	ADDQ	$8,SP
-	MOVQ	DI, RARG
-	SYSCALL
-	SUBQ	$8,SP
-
-	MOVQ	-16(SP),R11
-	MOVQ	-24(SP),R12
-	MOVQ	-32(SP),R13
-	MOVQ	-40(SP),R14
-	MOVQ	-48(SP),R15
-	MOVQ	-56(SP),BP
-	RET
-
--- a/libstd/syserrno+linux.myr
+++ /dev/null
@@ -1,38 +1,0 @@
-pkg sys =
-	type errno = int
-
-	const Eperm	: errno =	 -1	/* Operation not permitted */
-	const Enoent	: errno =	 -2	/* No such file or directory */
-	const Esrch	: errno =	 -3	/* No such process */
-	const Eintr	: errno =	 -4	/* Interrupted system call */
-	const Eio	: errno =	 -5	/* I/O error */
-	const Enxio	: errno =	 -6	/* No such device or address */
-	const E2big	: errno =	 -7	/* Argument list too long */
-	const Enoexec	: errno =	 -8	/* Exec format error */
-	const Ebadf	: errno =	 -9	/* Bad file number */
-	const Echild	: errno =	-10	/* No child processes */
-	const Eagain	: errno =	-11	/* Try again */
-	const Enomem	: errno =	-12	/* Out of memory */
-	const Eacces	: errno =	-13	/* Permission denied */
-	const Efault	: errno =	-14	/* Bad address */
-	const Enotblk	: errno =	-15	/* Block device required */
-	const Ebusy	: errno =	-16	/* Device or resource busy */
-	const Eexist	: errno =	-17	/* File exists */
-	const Exdev	: errno =	-18	/* Cross-device link */
-	const Enodev	: errno =	-19	/* No such device */
-	const Enotdir	: errno =	-20	/* Not a directory */
-	const Eisdir	: errno =	-21	/* Is a directory */
-	const Einval	: errno =	-22	/* Invalid argument */
-	const Enfile	: errno =	-23	/* File table overflow */
-	const Emfile	: errno =	-24	/* Too many open files */
-	const Enotty	: errno =	-25	/* Not a typewriter */
-	const Etxtbsy	: errno =	-26	/* Text file busy */
-	const Efbig	: errno =	-27	/* File too large */
-	const Enospc	: errno =	-28	/* No space left on device */
-	const Espipe	: errno =	-29	/* Illegal seek */
-	const Erofs	: errno =	-30	/* Read-only file system */
-	const Emlink	: errno =	-31	/* Too many links */
-	const Epipe	: errno =	-32	/* Broken pipe */
-	const Edom	: errno =	-33	/* Math argument out of domain of func */
-	const Erange	: errno =	-34	/* Math result not representable */
-;;
--- a/libstd/syserrno+osx.myr
+++ /dev/null
@@ -1,54 +1,0 @@
-pkg sys =
-	type errno = int
-
-	const Eperm	: errno = -1		/* Operation not permitted */
-	const Enoent	: errno = -2		/* No such file or directory */
-	const Esrch	: errno = -3		/* No such process */
-	const Eintr	: errno = -4		/* Interrupted system call */
-	const Eio	: errno = -5		/* Input/output error */
-	const Enxio	: errno = -6		/* Device not configured */
-	const E2big	: errno = -7		/* Argument list too long */
-	const Enoexec	: errno = -8		/* Exec format error */
-	const Ebadf	: errno = -9		/* Bad file descriptor */
-	const Echild	: errno = -10		/* No child processes */
-	const Edeadlk	: errno = -11		/* Resource deadlock avoided */
-				/* 11 was EAGAIN */
-	const Enomem	: errno = -12		/* Cannot allocate memory */
-	const Eacces	: errno = -13		/* Permission denied */
-	const Efault	: errno = -14		/* Bad address */
-	const Enotblk	: errno = -15		/* Block device required */
-	const Ebusy	: errno = -16		/* Device / Resource busy */
-	const Eexist	: errno = -17		/* File exists */
-	const Exdev	: errno = -18		/* Cross-device link */
-	const Enodev	: errno = -19		/* Operation not supported by device */
-	const Enotdir	: errno = -20		/* Not a directory */
-	const Eisdir	: errno = -21		/* Is a directory */
-	const Einval	: errno = -22		/* Invalid argument */
-	const Enfile	: errno = -23		/* Too many open files in system */
-	const Emfile	: errno = -24		/* Too many open files */
-	const Enotty	: errno = -25		/* Inappropriate ioctl for device */
-	const Etxtbsy	: errno = -26		/* Text file busy */
-	const Efbig	: errno = -27		/* File too large */
-	const Enospc	: errno = -28		/* No space left on device */
-	const Espipe	: errno = -29		/* Illegal seek */
-	const Erofs	: errno = -30		/* Read-only file system */
-	const Emlink	: errno = -31		/* Too many links */
-	const Epipe	: errno = -32		/* Broken pipe */
-
-	/* math software */
-	const Edom	: errno = -33		/* Numerical argument out of domain */
-	const Erange	: errno = -34		/* Result too large */
-
-	/* non-blocking and interrupt i/o */
-	const Eagain	: errno = -35		/* Resource temporarily unavailable */
-	const Einprogress	: errno = -36		/* Operation now in progress */
-	const Ealready	: errno = -37		/* Operation already in progress */
-
-	/* ipc/network software -- argument errors */
-	const Enotsock	: errno = -38		/* Socket operation on non-socket */
-	const Edestaddrreq	: errno = -39		/* Destination address required */
-	const Emsgsize	: errno = -40		/* Message too long */
-	const Eprototype	: errno = -41		/* Protocol wrong type for socket */
-	const Enoprotoopt	: errno = -42		/* Protocol not available */
-	const Eprotonosupport	: errno = -43		/* Protocol not supported */
-;;
--- a/libstd/syserrno+plan9.myr
+++ /dev/null
@@ -1,38 +1,0 @@
-pkg sys =
-	type errno = int
-
-	const Eperm	: errno =	 -1	/* Operation not permitted */
-	const Enoent	: errno =	 -2	/* No such file or directory */
-	const Esrch	: errno =	 -3	/* No such process */
-	const Eintr	: errno =	 -4	/* Interrupted system call */
-	const Eio	: errno =	 -5	/* I/O error */
-	const Enxio	: errno =	 -6	/* No such device or address */
-	const E2big	: errno =	 -7	/* Argument list too long */
-	const Enoexec	: errno =	 -8	/* Exec format error */
-	const Ebadf	: errno =	 -9	/* Bad file number */
-	const Echild	: errno =	-10	/* No child processes */
-	const Eagain	: errno =	-11	/* Try again */
-	const Enomem	: errno =	-12	/* Out of memory */
-	const Eacces	: errno =	-13	/* Permission denied */
-	const Efault	: errno =	-14	/* Bad address */
-	const Enotblk	: errno =	-15	/* Block device required */
-	const Ebusy	: errno =	-16	/* Device or resource busy */
-	const Eexist	: errno =	-17	/* File exists */
-	const Exdev	: errno =	-18	/* Cross-device link */
-	const Enodev	: errno =	-19	/* No such device */
-	const Enotdir	: errno =	-20	/* Not a directory */
-	const Eisdir	: errno =	-21	/* Is a directory */
-	const Einval	: errno =	-22	/* Invalid argument */
-	const Enfile	: errno =	-23	/* File table overflow */
-	const Emfile	: errno =	-24	/* Too many open files */
-	const Enotty	: errno =	-25	/* Not a typewriter */
-	const Etxtbsy	: errno =	-26	/* Text file busy */
-	const Efbig	: errno =	-27	/* File too large */
-	const Enospc	: errno =	-28	/* No space left on device */
-	const Espipe	: errno =	-29	/* Illegal seek */
-	const Erofs	: errno =	-30	/* Read-only file system */
-	const Emlink	: errno =	-31	/* Too many links */
-	const Epipe	: errno =	-32	/* Broken pipe */
-	const Edom	: errno =	-33	/* Math argument out of domain of func */
-	const Erange	: errno =	-34	/* Math result not representable */
-;;
--- a/libstd/systypes.myr
+++ /dev/null
@@ -1,7 +1,0 @@
-pkg sys =
-	type size	= int64	/* spans entire address space */
-	type usize	= int64	/* signed size */
-	type off	= int64	/* file offsets */
-	type intptr	= uint64/* can hold any pointer losslessly */
-	type time	= int64	/* milliseconds since epoch */
-;;
--- a/libstd/syswrap+plan9-x6.myr
+++ /dev/null
@@ -1,104 +1,0 @@
-use sys
-use "types.use"
-
-pkg std =
-	type fd		= sys.fd
-	type pid	= sys.pid
-	type fdopt	= sys.fdopt
-
-	const Failmem	: byte#	= -1 castto(byte#)
-
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
-	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
-	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
-	const Odir	: fdopt = 0x0	/* no-op on plan9 */
-
-	/* fd stuff */
-	const open	: (path : byte[:], opts : fdopt -> fd)
-	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
-	const close	: (fd : fd -> int64)
-	const creat	: (path : byte[:], mode : int64 -> fd)
-	const read	: (fd : fd, buf : byte[:] -> size)
-	const write	: (fd : fd, buf : byte[:] -> size)
-	const pipe	: (fds : fd[2]# -> int64)
-
-	/* path manipulation */
-	const mkdir	: (path : byte[:], mode : int64 -> int64)
-	const unlink	: (path : byte[:] -> int)
-
-	/* process stuff */
-	const getpid	: ( -> pid)
-	const suicide	: ( -> void)
-	const fork	: (-> pid)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	const exit	: (status:int -> void)
-	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
-	const getmem	: (sz : size -> byte#)
-	const freemem	: (p : byte#, sz : size -> void)
-;;
-
-/* fd stuff */
-const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
-const openmode	= {path, opts, mode;
-	var fd
-
-
-	if opts & Ocreat != 0
-		fd = sys.create(path, opts castto(sys.fdopt), mode castto(int))
-	else
-		fd = sys.open(path, opts castto(sys.fdopt))
-	;;
-	if opts & Oappend != 0
-		sys.seek(fd, 0, 2)
-	;;
-	-> fd castto(fd)
-}
-
-const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(int64)}
-const read	= {fd, buf;	-> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
-const write	= {fd, buf;	-> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
-
-/* path manipulation */
-const unlink	= {path;	-> sys.remove(path)}
-const mkdir	= {path, mode;
-	var fd
-
-	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
-	if fd < 0
-		-> -1
-	;;
-	sys.close(fd)
-	-> 0
-}
-
-/* process stuff */
-const getpid	= {;	-> sys.gettos().pid castto(pid)}
-const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
-const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
-const execv	= {cmd, args;	-> sys.exec(cmd, args) castto(int64)}
-const execve	= {cmd, args, env;	-> sys.exec(cmd, args) castto(int64)}
-const exit	= {status;
-	if status == 0
-		sys.exits("")
-	else
-		sys.exits("failure")
-	;;
-}
-
-/* FIXME: horribly broken. We wait for a pid to exit, and lie about which one. */
-const waitpid	= {pid, loc, opt;
-	var buf : byte[512]
-	var n
-
-	n = sys.await(buf[:])
-	-> pid
-}
-
-/* memory stuff */
-const getmem	= {sz;		-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)}
-const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
--- a/libstd/syswrap+plan9.myr
+++ /dev/null
@@ -1,220 +1,0 @@
-use sys
-
-use "option.use"
-use "types.use"
-
-pkg std =
-	type fd		= sys.fd
-	type pid	= sys.pid
-	type fdopt	= sys.fdopt
-	type whence = int64
-
-	type sysinfo = struct
-		system	: byte[:]
-		version	: byte[:]
-		release	: byte[:]
-		arch	: byte[:]
-	;;
-
-	const Seekset	: whence = 0
-	const Seekcur	: whence = 1
-	const Seekend	: whence = 2
-
-	const Failmem	: byte#	= -1 castto(byte#)
-
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
-	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
-	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
-	const Odir	: fdopt = 0x0	/* no-op on plan9 */
-
-	/* fd stuff */
-	const open	: (path : byte[:], opts : fdopt -> fd)
-	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
-	const close	: (fd : fd -> int64)
-	const creat	: (path : byte[:], mode : int64 -> fd)
-	const read	: (fd : fd, buf : byte[:] -> size)
-	const write	: (fd : fd, buf : byte[:] -> size)
-	const seek	: (fd : fd, delta : off, whence : whence -> off)
-	const pipe	: (fds : fd[2]# -> int64)
-	const dup2	: (ofd : fd, nfd : fd -> fd)
-
-	/* useful/portable bits of stat */
-	const fmtime	: (f : byte[:]	-> option(time))
-	const fsize	: (f : byte[:]	-> option(off))
-	const fexists	: (f : byte[:]	-> bool)
-
-	/* the important bits that uname provides */
-	const getsysinfo	: (si : sysinfo# -> void)
-
-	/* path manipulation */
-	const mkdir	: (path : byte[:], mode : int64 -> int64)
-	const chdir	: (path : byte[:] -> bool)
-	const remove	: (path : byte[:] -> bool)
-
-	/* process stuff */
-	const getpid	: ( -> pid)
-	const suicide	: ( -> void)
-	const fork	: (-> pid)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> pid)
-
-	pkglocal const Canunmap	: bool = true
-	pkglocal const getmem	: (sz : size -> byte#)
-	pkglocal const freemem	: (p : byte#, sz : size -> void)
-	pkglocal const curtime	: (-> time)
-	pkglocal const p9errstr	: (buf : byte[:] -> byte[:])
-
-	/* statbuf offsets */
-	pkglocal const Sizeoff	: int64 = 0
-	pkglocal const Typeoff	: int64 = 2
-	pkglocal const Devoff	: int64 = 4
-	pkglocal const Qidtypeoff	: int64 =8
-	pkglocal const Qidversoff	: int64 = 9
-	pkglocal const Qidpathoff	: int64 = 13
-	pkglocal const Modeoff	: int64 = 21
-	pkglocal const Atimeoff	: int64 = 25
-	pkglocal const Mtimeoff	: int64 = 29
-	pkglocal const Lengthoff	: int64 = 31
-	pkglocal const Stringsoff	: int64 = 39
-;;
-
-/* UGLY: circular dependency breaking... */
-extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
-
-/* fd stuff */
-const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
-const openmode	= {path, opts, mode;
-	var fd
-
-
-	if opts & Ocreat != 0
-		fd = sys.create(path, (opts & ~Ocreat) castto(sys.fdopt), mode castto(int))
-	else
-		fd = sys.open(path, opts castto(sys.fdopt))
-	;;
-	if opts & Oappend != 0
-		sys.seek(fd, 0, 2)
-	;;
-	-> fd castto(fd)
-}
-
-
-/* useful/portable bits of stat */
-const fexists = {path
-	var buf : byte[4]	/* big enough for size, nothing else. */
-	-> sys.stat(path, buf[:]) >= 0
-}
-
-const fmtime = {path
-	var buf	: byte[Stringsoff + 512]	/* enough space for some strings */
-
-	if sys.stat(path, buf[:]) < Stringsoff
-		-> `None
-	;;
-	-> `Some (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
-}
-
-const fsize = {path
-	var buf	: byte[Stringsoff + 512]	/* enough space for some strings */
-
-	if sys.stat(path, buf[:]) < Stringsoff
-		-> `None
-	;;
-	-> `Some (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
-}
-
-const getsysinfo = {si
-	si.system = getenvv("osname", "Plan9")
-	si.release = "4"
-	si.version = "0"
-	si.arch = getenvv("objtype", "amd64")
-}
-
-const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(int64)}
-const read	= {fd, buf;	-> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
-const write	= {fd, buf;	-> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
-const seek	= {fd, off, whence; 	-> sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)) castto(off)}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
-const dup2	= {ofd, nfd;	-> sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
-
-/* path manipulation */
-const remove	= {path;	-> sys.remove(path) == 0}
-const chdir	= {path;	-> sys.chdir(path) == 0}
-const mkdir	= {path, mode;
-	var fd
-
-	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
-	if fd < 0
-		-> -1
-	;;
-	sys.close(fd)
-	-> 0
-}
-
-/* process stuff */
-const getpid	= {;	-> sys.tosptr.pid castto(pid)}
-const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
-const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
-const execv	= {cmd, args;	-> sys.exec(cmd, args) castto(int64)}
-const execve	= {cmd, args, env;	-> sys.exec(cmd, args) castto(int64)}
-
-/* memory stuff */
-const getmem	= {sz
-	var endp, oldp
-
-	oldp = sys.curbrk
-	endp = (sys.curbrk castto(intptr)) + (sz castto(intptr))
-	endp = (endp + 4095) & ~4095
-	if sys.brk_(endp castto(byte#)) < 0
-		-> Failmem
-	;;
-	sys.curbrk = endp castto(byte#)
-	-> oldp
-}
-	
-const freemem = {p, sz
-	/* FIXME: we leak address space */
-	sys.segfree(p, sz castto(sys.size))
-}
-
-const curtime = {
-	-> sys.nsec()/1000 castto(time)
-}
-
-const p9errstr = {errbuf
-	var i
-
-	sys.errstr(errbuf)
-	for i = 0; errbuf[i] != 0 && i < errbuf.len; i++
-		continue
-	;;
-	-> errbuf[:i]
-}
-
-/* FIXME: will be needed when we resize stat bufs when statting.
-const statsz = {buf
-	-> (buf[0] castto(int64)) | ((buf[1] << 8) castto(int64))
-}
-*/
-
-const getle32 = {buf
-	-> (buf[0] castto(int32)) \
-		| ((buf[1] castto(int32)) << 8) \
-		| ((buf[2] castto(int32)) << 16) \
-		| ((buf[3] castto(int32)) << 24)
-}
-
-const getle64 = {buf
-	-> (buf[0] castto(int64)) \
-		| ((buf[1] castto(int64)) << 8) \
-		| ((buf[2] castto(int64)) << 16) \
-		| ((buf[3] castto(int64)) << 24) \
-		| ((buf[4] castto(int64)) << 64) \
-		| ((buf[5] castto(int64)) << 40) \
-		| ((buf[6] castto(int64)) << 48) \
-		| ((buf[7] castto(int64)) << 56)
-}
--- a/libstd/syswrap+posixy.myr
+++ /dev/null
@@ -1,148 +1,0 @@
-use sys
-use "cstrconv.use"
-use "option.use"
-use "types.use"
-use "errno.use"
-
-pkg std =
-	type fd		= sys.fd
-	type pid	= sys.pid
-	type fdopt	= sys.fdopt
-	type whence	= sys.whence
-
-	type sysinfo = struct
-		system	: byte[:]
-		version	: byte[:]
-		release	: byte[:]
-		arch	: byte[:]
-		uname	: sys.utsname	/* storage */
-	;;
-
-	const Failmem	: byte#	= -1 castto(byte#)
-
-	const Seekset	: whence = sys.Seekset	castto(whence)
-	const Seekcur	: whence = sys.Seekcur	castto(whence)
-	const Seekend	: whence = sys.Seekend	castto(whence)
-
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Ocreat   	: fdopt = sys.Ocreat	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
-	const Oappend  	: fdopt = sys.Oappend	castto(fdopt)
-	const Odir	: fdopt = sys.Odir	castto(fdopt)
-
-	/* fd stuff */
-	const open	: (path : byte[:], opts : fdopt -> fd)
-	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
-	const close	: (fd : fd -> int64)
-	const creat	: (path : byte[:], mode : int64 -> fd)
-	const read	: (fd : fd, buf : byte[:] -> size)
-	const write	: (fd : fd, buf : byte[:] -> size)
-	const pipe	: (fds : fd[2]# -> int64)
-	const seek	: (fd : fd, delta : off, whence : whence -> off)
-	const dup2	: (ofd : fd, nfd : fd -> fd)
-
-	/* useful/portable bits of stat */
-	const fmtime	: (f : byte[:]	-> option(time))
-	const fsize	: (f : byte[:]	-> option(off))
-	const fexists	: (f : byte[:]	-> bool)
-
-	/* useful/portable bits of uname */
-	const getsysinfo	: (si : sysinfo# -> void)
-
-	/* path manipulation */
-	const mkdir	: (path : byte[:], mode : int64 -> int64)
-	const remove	: (path : byte[:] -> bool)
-	const chdir	: (path : byte[:] -> bool)
-
-	/* process stuff */
-	const getpid	: ( -> pid)
-	const suicide	: ( -> void)
-	const fork	: (-> pid)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
-
-	pkglocal const Canunmap	: bool = true
-	pkglocal const getmem	: (sz : size -> byte#)
-	pkglocal const freemem	: (p : byte#, sz : size -> void)
-	pkglocal const curtime	: (-> time)
-;;
-
-/* fd stuff */
-const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
-const openmode	= {path, opts, mode;	-> sys.openmode(path, opts castto(sys.fdopt), mode) castto(fd)}
-const close	= {fd;		-> sys.close(fd castto(sys.fd))}
-const creat	= {path, mode;	-> sys.creat(path, mode) castto(fd)}
-const read	= {fd, buf;	-> sys.read(fd castto(sys.fd), buf) castto(size)}
-const write	= {fd, buf;	-> sys.write(fd castto(sys.fd), buf) castto(size)}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#))}
-const seek	= {fd, delta, whence;	-> sys.lseek(fd castto(sys.fd), delta castto(sys.off), whence castto(sys.whence)) castto(off)}
-const dup2	= {ofd, nfd;	-> sys.dup2(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
-
-/* path manipulation */
-const mkdir	= {path, mode;	-> sys.mkdir(path, mode)}
-const chdir	= {path;	-> sys.chdir(path) == 0}
-const remove	= {path;	-> sys.unlink(path) == 0}
-
-/* useful/portable bits of uname */
-const getsysinfo = {si
-	sys.uname(&si.uname)
-	si.system = cstrconv(si.uname.system[:])
-	si.version = cstrconv(si.uname.version[:])
-	si.release = cstrconv(si.uname.release[:])
-	si.arch = cstrconv(si.uname.machine[:])
-}
-
-/* process stuff */
-const getpid	= {;		-> sys.getpid() castto(pid)}
-const suicide	= {;		sys.kill(sys.getpid(), 6)}	/* kill self with sigabort */
-const fork	= {;		-> sys.fork() castto(pid)}
-const execv	= {cmd, args;	-> sys.execv(cmd, args)}
-const execve	= {cmd, args, env;	-> sys.execve(cmd, args, env)}
-const sleep	= {time;	sys.sleep(time)}
-
-/* memory stuff */
-const getmem	= {sz;		-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)}
-const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
-const curtime = {
-	var tm, sec, nsec
-
-	if sys.clock_gettime(`sys.Clockrealtime, &tm) == 0
-		sec = tm.sec
-		nsec = tm.nsec castto(uint64)
-		-> (sec*1_000_000 + nsec/1000) castto(time)
-	else
-		-> -1
-	;;
-}
-
-const fexists = {path
-	var sb
-
-	-> sys.stat(path, &sb) == 0
-}
-
-const fmtime = {path
-	var sb
-	var sec, nsec
-
-	if sys.stat(path, &sb) == 0
-		sec = sb.mtime.sec castto(time)
-		nsec = sb.mtime.nsec castto(time)
-		-> `Some sec*1000 + nsec/1_000_000
-	else
-		-> `None
-	;;
-}
-
-const fsize = {path
-	var sb
-
-	if sys.stat(path, &sb) == 0
-		-> `Some (sb.size castto(off))
-	else
-		-> `None
-	;;
-}
--- a/libstd/syswrap-ss+linux.myr
+++ /dev/null
@@ -1,22 +1,0 @@
-use sys
-use "errno.use"
-
-pkg std =
-	const exit	: (status:int -> void)
-	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
-;;
-
-const exit	= {status;	sys.exit_group(status)}
-const bgetcwd	= {buf;
-	var err
-	err = sys.getcwd(buf) castto(errno)
-	/*
-	if we got a length back, it includes
-	the nul byte. chop that off.
-	*/
-	if err > 0
-		-> err - 1
-	else
-		-> err
-	;;
-}
--- a/libstd/syswrap-ss+osx.myr
+++ /dev/null
@@ -1,35 +1,0 @@
-use sys
-use "errno.use"
-use "cstrconv.use"
-use "slcp.use"
-use "die.use"
-
-pkg std =
-	const exit	: (status:int -> void)
-	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
-;;
-
-const exit	= {status;	sys.exit(status)}
-const bgetcwd	= {buf
-	var path : byte[sys.Maxpathlen]
-	var fd, len, err
-
-	fd = sys.open(".", sys.Ordonly)
-	if fd < 0
-		-> fd castto(errno)
-	;;
-	/* 
-	FIXME: if the path is longer than sys.Pathmax, we should fall back to
-	the ugly method of finding the path.
-	*/
-	err = sys.fcntl(fd, sys.Fgetpath, path[:] castto(byte#)) castto(errno)
-	if err < 0
-		-> err
-	;;
-	len = cstrlen(path[:])
-	if len >= buf.len
-		-> Erange
-	;;
-	slcp(buf[:len], path[:len])
-	-> len castto(errno)
-}
--- a/libstd/syswrap-ss+plan9.myr
+++ /dev/null
@@ -1,56 +1,0 @@
-use sys
-
-use "errno.use"
-use "cstrconv.use"
-
-pkg std =
-	const exit	: (status : int -> void)
-	pkglocal const bgetcwd	: (buf : byte[:] -> errno)
-;;
-
-const bgetcwd = {buf
-	var fd
-
-	fd = sys.open(".", sys.Ordonly)
-	if fd < 0
-		-> fd castto(errno)
-	;;
-
-	if sys.fd2path(fd, buf) == 0
-		/*
-		Because we don't return the size, the best we can do is
-		assume that if the buffer is completely full, we have
-		truncated it. Since we truncate at utf8 characters, we
-		can have at most 3 bytes truncated (4 bytes will fit
-		any utf8 char), and one byte for the nul terminator.
-		*/
-		if cstrlen(buf) + 5 == buf.len
-			-> Erange
-		else
-			-> cstrlen(buf) castto(errno)
-		;;
-	;;
-	-> Emisc
-}
-
-const digitchars = "0123456789"
-const exit	= {status
-	var buf : byte[32]	/* big enough for exit status numbers */
-	var n, i
-	
-	if status == 0
-		sys.exits("")
-	else
-		status &= 255
-		i = 100
-		n = 0
-		while i > 0
-			if status >= i
-				buf[n++] = digitchars[(status/i)%10]
-			;;
-			i /= 10
-		;;
-		sys.exits(buf[:n])
-	;;
-}
-
--- a/libstd/test/bigint.myr
+++ /dev/null
@@ -1,136 +1,0 @@
-use std
-
-type cmd = union
-	`Add (cmd#, cmd#)
-	`Sub (cmd#, cmd#)
-	`Mul (cmd#, cmd#)
-	`Div (cmd#, cmd#)
-	`Mod (cmd#, cmd#)
-	`Shl (cmd#, cmd#)
-	`Shr (cmd#, cmd#)
-	`Modpow (cmd#, cmd#, cmd#)
-	`Val byte[:]
-;;
-
-const main = {
-	var a, b, c, d, e
-	var buf : byte[64], n
-
-	/* a few combined ops */
-	a = std.mkbigint(1234)
-	b = std.mkbigint(0x7fffffff)
-	c = std.mkbigint(7919)
-	d = std.mkbigint(113051)
-	e = std.mkbigint(11)
-
-	std.bigmul(a, b)
-	std.bigmul(a, b)
-	std.bigadd(a, c)
-	std.bigsub(a, d)
-	std.bigdiv(a, e)
-
-	std.bigfree(b)
-	std.bigfree(c)
-	std.bigfree(d)
-	std.bigfree(e)
-
-	n = std.bigbfmt(buf[:], a, 0)
-	std.assert(std.sleq(buf[:n], "517347321949036993306"), "simple smoke test failed")
-
-	/* make sure we format '0' correctly */
-	run(std.mk(`Val "0"), "0")
-	/* smoke test for division */
-	run(std.mk(`Div (\
-		std.mk(`Val "1234_5678_1234_6789_6666_7777_8888"), \
-		std.mk(`Val "1234_5678_1234_6789_6666_7777"))), \
-		"10000")
-	run(std.mk(`Div (\
-		std.mk(`Val "0xffff_1234_1234_1234_1234"), \
-		std.mk(`Val "0xf010_1234_2314"))), \
-		"4580035496")
-	run(std.mk(`Div (\
-		std.mk(`Val "5192296858534810493479828944327220"), \
-		std.mk(`Val "75557863709417659441940"))), \
-		"68719476751")
-	run(std.mk(`Div (\
-		std.mk(`Val "75557863709417659441940"), \
-		std.mk(`Val "5192296858534810493479828944327220"))), \
-		"0")
-
-	/* smoke test for mod */
-	run(std.mk(`Mod (\
-		std.mk(`Val "5192296858534810493479828944327220"), \
-		std.mk(`Val "75557863709417659441940"))),\
-		"257025710597479990280")
-
-	run(std.mk(`Modpow (\
-		std.mk(`Val "1"), \
-		std.mk(`Val "3"), \
-		std.mk(`Val "2"))), \
-		"1")
-
-	run(std.mk(`Modpow (\
-		std.mk(`Val "5192296858534810493479828944327220"), \
-		std.mk(`Val "75557863709417659441940"), \
-		std.mk(`Val "755578"))), \
-		"49054")
-	run(std.mk(`Modpow (\
-		std.mk(`Val "7220"), \
-		std.mk(`Val "755578"), \
-		std.mk(`Val "75557863709417659441940"))), \
-		"27076504425474791131220")
-
-}
-
-const run = {e : cmd#, res : byte[:]
-	var buf : byte[4096]
-	var v, n
-
-	v = eval(e)
-	n = std.bigbfmt(buf[:], v, 0)
-	if !std.sleq(buf[:n], res)
-		std.fatal("%s != %s\n", buf[:n], res)
-	;;
-}
-
-const eval = {e : cmd#
-	var buf : byte[2048]
-	var a, b, c	/* scratch vars */
-	var n		/* buf len */
-
-	match e#
-	| `Add (x, y):	-> binop("+", std.bigadd, x, y)
-	| `Sub (x, y):	-> binop("-", std.bigsub, x, y)
-	| `Mul (x, y):	-> binop("*", std.bigmul, x, y)
-	| `Div (x, y):	-> binop("/", std.bigdiv, x, y)
-	| `Mod (x, y):	-> binop("%", std.bigmod, x, y)
-	| `Shl (x, y):	-> binop("<<", std.bigshl, x, y)
-	| `Shr (x, y):	-> binop(">>", std.bigshr, x, y)
-	| `Val x:
-		a = try(std.bigparse(x))
-		n = std.bigbfmt(buf[:], a, 0)
-		-> a
-	| `Modpow (x, y, z):
-		a = eval(x)
-		b = eval(y)
-		c = eval(z)
-		-> std.bigmodpow(a, b, c)
-	;;
-}
-
-const binop = {name, op, x, y
-	var a, b
-
-	a = eval(x)
-	b = eval(y)
-	op(a, b)
-	std.bigfree(b)
-	-> a
-}
-
-generic try = {x : std.option(@a)
-	match x
-	| `std.Some v:	-> v
-	| `std.None:	std.die("failed to get val")
-	;;
-}
--- a/libstd/test/bytebuf.myr
+++ /dev/null
@@ -1,72 +1,0 @@
-use "bytebuf.use"
-
-/* support */
-use "die.use"
-use "fmt.use"
-use "sleq.use"
-
-const main = {
-	var bb, v
-
-	bb = std.mkbytebuf()
-
-	std.bytebufputc(bb, 'a')
-	std.assert(bb.len == 1, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "a"), \
-		"byte buf contents not \"a\"\n")
-
-	std.bytebufputs(bb, "bc")
-	std.assert(bb.len == 3, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abc"), \
-		"byte buf contents not \"abc\"\n")
-
-	std.bytebufputb(bb, 'd' castto(byte))
-	std.assert(bb.len == 4, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcd"), \
-		"byte buf contents not \"abcd\"\n")
-
-	std.bytebufputle8(bb, 'e' castto(int64))
-	std.assert(bb.len == 5, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcde"), \
-		"byte buf contents not \"abcde\"\n")
-
-	std.bytebufputbe8(bb, 'e' castto(int64))
-	std.assert(bb.len == 6, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdee"), \
-		"byte buf contents not \"abcdee\"\n")
-
-	std.bytebufputle16(bb, ('f' | ('g' << 8)) castto(int64))
-	std.assert(bb.len == 8, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefg"), \
-		"byte buf contents not \"abcdeefg\"\n")
-
-	std.bytebufputbe16(bb, ('f' | ('g' << 8)) castto(int64))
-	std.assert(bb.len == 10, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggf"), \
-		"byte buf contents not \"abcdeefggf\"\n")
-
-	std.bytebufputle32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
-	std.assert(bb.len == 14, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijk"), \
-		"byte buf contents not \"abcdeefggfhijk\"\n")
-
-	std.bytebufputbe32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
-	std.assert(bb.len == 18, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjih"), \
-		"byte buf contents not \"abcdeefggfhijkkji\"\n")
-
-	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
-	v |= v << 32
-	std.bytebufputle64(bb, v)
-	std.assert(bb.len == 26, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjihlmnolmno"), \
-		"byte buf contents not \"abcdeefggfhijkkjihlmnolmno\"\n")
-
-	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
-	v |= v << 32
-	std.bytebufputbe64(bb, v)
-	std.assert(bb.len == 34, "byte buf size wrong\n")
-	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjihlmnolmnoonmlonml"), \
-		"byte buf contents not \"abcdeefggfhijkkjilmnolmnoonmlonml\"\n")
-}
-
--- a/libstd/test/chartype.myr
+++ /dev/null
@@ -1,23 +1,0 @@
-use std
-
-const main = {
-	std.assert(std.isalpha('a'), "a should be alpha\n")
-	std.assert(std.isupper('A'), "A should be upper\n")
-	std.assert(std.islower('a'), "a should be lower\n")
-	std.assert(std.isdigit('0'), "0 should be isdigit\n")
-	std.assert(std.isnum('\u{0c66}'), "\u{0c66} should be isnum\n")
-	std.assert(std.isalnum('a'), "a should be isalnum\n")
-	std.assert(std.isalnum('0'), "0 should be isalnum\n")
-	std.assert(std.isspace(' '), "' ' should be isspace\n")
-	std.assert(std.isblank(' '), "' ' should be isblank\n")
-
-	std.assert(!std.isalpha('0'), "0 should not be alpha\n")
-	std.assert(!std.isupper('a'), "a should not be upper\n")
-	std.assert(!std.islower('A'), "A should not be lower\n")
-	std.assert(!std.isdigit('a'), "a should not be isdigit\n")
-	std.assert(!std.isnum('a'), " should not be isnum\n")
-	std.assert(!std.isalnum('}'), "a should not be isalnum\n")
-	std.assert(!std.isalnum('!'), "! should not be isalnum\n")
-	std.assert(!std.isspace('@'), "@ should not be isspace\n")
-	std.assert(!std.isblank('@'), "@ should not be isblank\n")
-}
--- a/libstd/test/fmt.myr
+++ /dev/null
@@ -1,34 +1,0 @@
-use std
-
-const check = {expected, fmt, args : ...
-	var buf : byte[2048]
-	var sl, ap
-
-	ap = std.vastart(&args)
-	sl = std.bfmtv(buf[:], fmt, &ap)
-	if !std.sleq(expected, sl)
-		std.fatal("mismatched fmt: got \"{}\", expected \"{}\"\n", sl, expected)
-	;;
-}
-
-const main = {
-	check("      abcd", "{w=10}", "abcd")
-	check("00000bdcae", "{p=0,w=10}", "bdcae")
-	check("abcdefghijkl", "{p=0,w=10}", "abcdefghijkl")
-	check("a", "{w=0,p=1}", "a")
-	check("        10", "{w=10}", 10)
-	check("0000000010", "{p=0,w=10}", 10)
-	check("4294967295", "{p=0,w=10}", -1 castto(uint))
-	check("-000000001", "{p=0,w=10}", -1)
-	check("xxxxxxxx-1", "{p=x,w=10}", -1)
-	check("        -1", "{w=10}", -1)
-	check("100000"    , "{3}", 100000)
-	check("foobarbaz", "{}bar{}", "foo", "baz")
-	check("{}barbaz", "{{}}bar{}", "baz")
-	check("{barbaz}", "{{bar{}}}", "baz")
-	check("abcd", "{}", "abcd")
-	check("123", "{}", 123)
-	check("7b", "{x}", 123)
-	check("0x7b", "0x{x}", 123)
-}
-
--- a/libstd/test/htab.myr
+++ /dev/null
@@ -1,104 +1,0 @@
-use std
-
-const insertion = {
-	/*
-	var ht
-	var i
-
-	ht = std.mkht(idhash, ideq)
-	/* only a few values; shouldn't trigger growth */
-	for i = 0; i < 5; i++
-		std.htput(ht, i, i)
-	;;
-	for i = 0; i < 5; i++
-		std.assert(std.htgetv(ht, i, -1) == i, "returned incorrect value from hash table")
-	;;
-
-	/* and grow */
-	for i = 0; i < 5000; i++
-		std.htput(ht, i, i)
-	;;
-	for i = 0; i < 5000; i++
-		std.assert(std.htgetv(ht, i, -1) == i, "returned incorrect value from hash table")
-	;;
-	*/
-}
-
-const deletion = {
-	var ht
-	var i
-
-	ht = std.mkht(idhash, ideq)
-	/* create a hash table with a few hundred values */
-	for i = 0; i < 4000; i++
-		std.htput(ht, i, i)
-	;;
-	for i = 0; i < 200; i++
-		std.htdel(ht, i*2)
-	;;
-	for i = 0; i < 200; i++
-		std.assert(!std.hthas(ht, i*2), "deleted item still present")
-	;;
-	for i = 0; i < 200; i++
-		std.assert(std.hthas(ht, i*2+1), "undeleted item missing")
-	;;
-	for i = 400; i < 4000; i++
-		std.assert(std.hthas(ht, i), "undeleted item missing")
-	;;
-
-}
-
-const collision = {
-	var ht
-	var i
-
-	ht = std.mkht(idhash, ideq)
-	/* insert an element a few hundred times */
-	for i = 0; i < 500; i++
-		std.htput(ht, 0, i)
-	;;
-	std.assert(std.hthas(ht, 0), "inserted element not present")
-	std.assert(std.htgetv(ht, 0, -1) == 499, "inserted element has wrong value")
-	std.htdel(ht, 0)
-	std.assert(!std.hthas(ht, 0), "element left in table")
-}
-
-const tombstonefill = {
-	var ht
-	var i
-
-	ht = std.mkht(idhash, ideq)
-	/* 
-	insert an element into each slot in the hash table, and
-	delete it. With direct hashing, this is guaranteed to have
-	put a tombstone into each slot.
-	*/
-	for i = 0; i <= ht.keys.len; i++
-		std.htput(ht, i, i)
-		std.htdel(ht, i)
-	;;
-	/* make sure we haven't actually got anything in the table */
-	std.assert(ht.nelt == 0, "elements left in hash table")
-	std.assert(!std.hthas(ht, 1), "found phantom element")
-}
-
-const main = {
-	/* only a few elements */
-	std.put("insertion\n")
-	insertion()
-	std.put("deletion\n")
-	deletion()
-	std.put("collision\n")
-	collision()
-
-	/* what happens if we try to fill everything up with tombstones? */
-	tombstonefill()
-}
-
-const idhash = {x
-	-> x
-}
-
-const ideq = {a, b
-	-> a == b
-}
--- a/libstd/test/ipparse.myr
+++ /dev/null
@@ -1,64 +1,0 @@
-use std
-
-const main = {
-	/* valid ipv4 address */
-	eq("1.2.3.4", `std.Some `std.Ipv4 [1,2,3,4])
-
-	/* invalid ipv4 address */
-	eq("1.3.4", `std.None)	/* too short */
-	eq("1.2.3.4.5", `std.None)	/* too long */
-	eq("1.3.4.256", `std.None)	/* out of bounds 1 */
-	eq("260.2.3.4", `std.None)	/* out of bounds 2 */
-
-	/* valid ipv6 addresses */
-	eq("2a03:2880:2110:df07:face:b00c:0:1", \
-		`std.Some `std.Ipv6 [0x2a, 0x03, 0x28, 0x80, 0x21, 0x10,
-			0xdf, 0xfa, 0xce, 0xb0, 0x0c, 0x00, 0x00, 0x01, 0x01])
-	eq("abcd::dcba", \
-		`std.Some `std.Ipv6 [0xab, 0xcd, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
-	eq("::abcd:dcba", \
-		`std.Some `std.Ipv6 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd, 0xdc, 0xba])
-	eq("::", `std.Some `std.Ipv6 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
-
-	/* invalid ipv4 addresses */
-	eq("2a03:2880:2110:df07:face:b00c:0:1:abc", `std.None)	/* too long */
-	eq("2a03:2880:2110:df07:face:b00c:0", `std.None)	/* too short */
-	eq("2a03:2880:2110:df07:face:b00c:0:1:", `std.None)	/* trailing ':' */
-}
-
-const eq = {ip, expected
-	var parsed
-	var p, e
-
-	parsed = std.ipparse(ip)
-	p = ipbytes(parsed)
-	e = ipbytes(expected)
-	if !std.sleq(p, e)
-		std.fput(1, "misparsed ip {}\n", ip)
-		std.put("parsed: ")
-		for b in p
-			std.put("{x}, ", b)
-		;;
-		std.put("\nexpected: ")
-		for b in e
-			std.put("{x}, ", b)
-		;;
-		std.put("\n")
-		std.fatal("failed\n")
-	;;
-}
-
-const ipbytes = {ipopt
-	match ipopt
-	| `std.Some ip:
-		match ip
-		| `std.Ipv4 b:	-> b[:]
-		| `std.Ipv6 b:	-> b[:]
-		;;
-	| `std.None:	-> [][:]
-	;;
-}
-
--- a/libstd/test/option.myr
+++ /dev/null
@@ -1,43 +1,0 @@
-use std
-
-const f = {x
-	if x == 123
-		-> `std.Some 42
-	else
-		-> `std.None
-	;;
-}
-
-type t = struct
-	next	: std.option(int)
-;;
-
-const main = {
-	var v, s : t
-	
-	match `std.Some 42
-	| `std.Some x:	std.assert(x == 42, "created wrong value\n")
-	| `std.None:	std.assert(false, "should not be reached\n")
-	;;
-
-	match `std.None
-	| `std.Some x:	std.assert(x, "should not be reached\n")
-	| `std.None:	/* everything ok */
-	;;
-
-	v = f(123)
-	match v
-	| `std.Some x:	std.assert(x == 42, "created wrong value\n")
-	| `std.None:	std.assert(false, "should not be reached\n")
-	;;
-
-	v = f(666)
-	match v
-	| `std.Some x:	std.assert(false, "should not be reached\n")
-	| `std.None:	/* everything ok */
-	;;
-
-	s = [.next = `std.None]
-	s = [.next = `std.Some 123]
-}
-
--- a/libstd/test/pathjoin.myr
+++ /dev/null
@@ -1,61 +1,0 @@
-use std
-
-const main = {
-	/* untouched */
-	norm("foo", "foo")
-	norm("foo/bar", "foo/bar")
-	norm("/foo/bar", "/foo/bar")
-	norm(".", ".")
-
-	/* empty path becomes "." */
-	norm("", ".")
-
-	/* delete //, trailing / */
-	norm("foo/", "foo")
-	norm("foo//bar/baz", "foo/bar/baz")
-	norm("//foo//bar/", "/foo/bar")
-
-	/* delete '.' */
-	norm("foo/./bar", "foo/bar")
-	norm("/foo/bar/.", "/foo/bar")
-	norm("./foo/bar/.", "foo/bar")
-
-	/* elide '..' */
-	norm("/../foo/bar", "/foo/bar")
-	norm("../../foo/bar", "../../foo/bar")
-	norm("foo/bar/..", "foo")
-	norm("foo/bar/../..", ".")
-	norm("foo/../bar/../..", "..")
-	norm("/foo/../bar/../..", "/")
-
-	/* mix all of the above */
-	norm("/../foo//bar", "/foo/bar")
-	norm("..//../foo/bar", "../../foo/bar")
-	norm("foo//./bar/..", "foo")
-	norm("foo/bar/.././..", ".")
-	norm("//foo/../bar/../..", "/")
-	norm("foo/../bar/../..", "..")
-
-	/* vanilla pathjoin */
-	eq(std.pathcat("a", "b"), "a/b")
-	eq(std.pathjoin(["a", "b", "c"][:]), "a/b/c")
-	/* pathjoin with empty dirs */
-	eq(std.pathcat("", "foo"), "foo")
-	eq(std.pathjoin(["", "foo", "bar"][:]), "foo/bar")
-}
-
-const norm = {a, b
-	var p
-
-	p = std.pathnorm(a)
-	if !std.sleq(p, b)
-		std.fatal("mismatched paths: '{}' => '{}' != '{}'\n", a, p, b)
-	;;
-	std.slfree(p)
-}
-
-const eq = {a, b
-	if !std.sleq(a, b)
-		std.fatal("mismatched paths: '{}' != '{}'\n", a, b)
-	;;
-}
--- a/libstd/test/search.myr
+++ /dev/null
@@ -1,34 +1,0 @@
-use std
-
-const sl = [1, 3, 5, 8, 9, 33]
-
-const main = {
-
-	expect(std.lsearch(sl[:], 1, std.numcmp), `std.Some 0)
-	expect(std.lsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
-	expect(std.lsearch(sl[:], 5, std.numcmp), `std.Some 2)
-	expect(std.lsearch(sl[:], 6, std.numcmp), `std.None)
-
-	expect(std.bsearch(sl[:], 1, std.numcmp), `std.Some 0)
-	expect(std.bsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
-	expect(std.bsearch(sl[:], 5, std.numcmp), `std.Some 2)
-	expect(std.bsearch(sl[:], 6, std.numcmp), `std.None)
-}
-
-const expect = {a, b
-	match a
-	| `std.None:
-		match b
-		| `std.Some x: std.fatal("Expected `std.None, `std.None, got `std.None, `std.Some %i\n", x)
-		| `std.None:	/* nothing */
-		;;
-	| `std.Some x:
-		match b
-		| `std.None: std.fatal("Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.None\n", x, x, x)
-		| `std.Some y: 
-			if x != y
-				std.fatal("Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.Some %i\n", x, x, x, y)
-			;;
-		;;
-	;;
-}
--- a/libstd/test/slcp.myr
+++ /dev/null
@@ -1,14 +1,0 @@
-use std
-
-const main = {
-	var a = [1,2,3,4,5]
-	var b = [6,7,8,9,10]
-	var a_cped = [3, 4, 5, 4, 5]
-	var b_cped = [6, 7, 6, 7, 8]
-	
-
-	std.slcp(a[:a.len-2], a[2:])
-	std.slcp(b[2:], b[:b.len-2])
-	std.assert(std.sleq(a[:], a_cped[:]), "slcp of a failed")
-	std.assert(std.sleq(b[:], b_cped[:]), "slcp of a failed")
-}
--- a/libstd/test/sort.myr
+++ /dev/null
@@ -1,38 +1,0 @@
-use std
-
-const main = {
-	var i
-
-	var a = [ 3, 5, 4, 9, 7, 2, 6, 0, 1, 8, ]
-	var a_sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-	var b = [3, 4, 5, 1, 2, 6, 7, 8, 9, 10]
-	var b_sorted = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-	var c = ["a", "aa", "b", "C", "Cc", "cC", "d", "f", "fuckit", "go",]
-	var c_sorted = ["C", "Cc", "a", "aa", "b", "cC", "d", "f", "fuckit", "go"]
-
-	/* with custom intcmp */
-	std.sort(a[:], intcmp)
-	std.assert(std.sleq(a[:], a_sorted[:]), "a was missorted")
-
-	/* with libstd generic numcmp */
-	std.sort(b[:], std.numcmp)
-	std.assert(std.sleq(b[:], b_sorted[:]), "b was missorted")
-
-	/* string sorting */
-	std.sort(c[:], std.strcmp)
-	for i = 0; i < c.len; i++
-		std.assert(std.sleq(c[i], c_sorted[i]), "c was missorted")
-	;;
-}
-
-const intcmp = {a, b
-	if a < b
-		-> `std.Before
-	elif a == b
-		-> `std.Equal
-	else
-		-> `std.After
-	;;
-}
-
-	
--- a/libstd/test/strbuf.myr
+++ /dev/null
@@ -1,40 +1,0 @@
-use std
-
-const main = {
-	var sb
-	var buf : byte[16]
-
-	sb = std.mksb()
-	std.assert(std.sleq(std.sbpeek(sb), ""), "mismatched empty str\n")
-	std.sbputs(sb, "hello")
-	std.assert(std.sleq(std.sbpeek(sb), "hello"), "mismatched hello\n")
-	std.sbputs(sb, ", hello")
-	std.assert(std.sleq(std.sbpeek(sb), "hello, hello"), "mismatched double hello\n")
-	std.sbtrim(sb, 7)
-	std.assert(std.sleq(std.sbpeek(sb), "hello, "), "mismatched trim\n")
-	std.sbputs(sb, "world")
-	std.assert(std.sleq(std.sbpeek(sb), "hello, world"), "mismatched hello world\n")
-	std.sbtrim(sb, -5)
-	std.assert(std.sleq(std.sbpeek(sb), "hello, "), "mismatched rtrim\n")
-	std.sbputc(sb, '世')
-	std.sbputc(sb, '界')
-	std.assert(std.sleq(std.sbpeek(sb), "hello, 世界"), "mismatched unicode\n")
-	std.sbputb(sb, 10)
-	std.assert(std.sleq(std.sbpeek(sb), "hello, 世界\n"), "mismatched byte\n")
-
-	sb = std.mkbufsb(buf[:])
-	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 5 characters */
-	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 10 characters */
-	std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 15 characters */
-	std.assert(!std.sbputs(sb, "hello"), "erronous success\n") /* 16 characters */
-	std.assert(std.sleq(std.sbpeek(sb), "hellohellohelloh"), "failed to copy as much as possible\n")
-	std.sbtrim(sb, -1)
-	std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "failed rtrim\n")
-	std.sbputc(sb, '世')
-	std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "modified overflowed putc\n")
-	std.sbtrim(sb, -2)
-	std.assert(std.sleq(std.sbpeek(sb), "hellohellohel"), "failed rtrim\n")
-	std.sbputc(sb, '世')
-	std.assert(std.sleq(std.sbpeek(sb), "hellohellohel世"), "failed to append with putc\n")
-}
-
--- a/libstd/test/try.myr
+++ /dev/null
@@ -1,8 +1,0 @@
-use std
-
-const main = {
-	var x = `std.Some 123
-	var r : std.result(int, byte[:]) = `std.Ok 666
-	std.assert(std.get(x) == 123, "expected 123 from try")
-	std.assert(std.try(r) == 666, "expected 123 from try")
-}
--- a/libstd/try.myr
+++ /dev/null
@@ -1,38 +1,0 @@
-use "result.use"
-use "option.use"
-use "fmt.use"
-
-pkg std =
-	generic try : (v : result(@a, @b) -> @a)
-	generic tryv : (v : result(@a, @b), d : @a -> @a)
-	generic get : (v : option(@a) -> @a)
-	generic getv : (v : option(@a), d : @a -> @a)
-;;
-
-generic try = {v
-	match v
-	| `Ok x:	-> x
-	| `Fail m:	fatal("error: {}\n", m)
-	;;
-}
-
-generic tryv = {v, d
-	match v
-	| `Ok x:	-> x
-	| `Fail m:	-> d
-	;;
-}
-
-generic get = {v
-	match v
-	| `Some x:	-> x
-	| `None:	fatal("error: option had `None\n")
-	;;
-}
-
-generic getv = {v, d
-	match v
-	| `Some x:	-> x
-	| `None:	-> d
-	;;
-}
--- a/libstd/types.myr
+++ /dev/null
@@ -1,9 +1,0 @@
-use sys
-
-pkg std =
-	type size	= sys.size	/* spans entire address space */
-	type usize	= sys.usize	/* signed size */
-	type off	= sys.off	/* file offsets */
-	type intptr	= sys.intptr	/* can hold any pointer losslessly */
-	type time	= sys.time	/* milliseconds since epoch */
-;;
--- a/libstd/units.myr
+++ /dev/null
@@ -1,11 +1,0 @@
-pkg std =
-	/* JEDEC 100B.1 memory sizes */
-	generic KiB	: @a::(integral,numeric)	= 1024 
-	generic MiB	: @a::(integral,numeric)	= KiB*1024
-	generic GiB	: @a::(integral,numeric)	= MiB*1024
-	generic TiB	: @a::(integral,numeric)	= GiB*1024
-	generic PiB	: @a::(integral,numeric)	= TiB*1024
-	generic EiB	: @a::(integral,numeric)	= PiB*1024
-	generic ZiB	: @a::(integral,numeric)	= EiB*1024
-	generic YiB	: @a::(integral,numeric)	= ZiB*1024
-;;
--- a/libstd/utf.myr
+++ /dev/null
@@ -1,103 +1,0 @@
-use "die.use"
-use "types.use"
-
-pkg std =
-	const Badchar	: char = -1 castto(char)
-	const Maxcharlen : size = 4
-	const Maxcharval : char = 0x10FFFF
-
-	const charlen	: (chr : char -> size)
-	const encode	: (buf : byte[:], chr : char -> size)
-	const decode	: (buf : byte[:] -> char)
-	const striter	: (str : byte[:] -> (char, byte[:]))
-;;
-
-const charlen = {c
-	if c < 0x80
-		-> 1
-	elif c < 0x800
-		-> 2
-	elif c < 0x10000
-		-> 3
-	elif c < 0x200000
-		-> 4
-	else
-		-> -1
-	;;
-}
-
-const encode = {buf, c
-	var len
-	var mark
-	var i
-
-	len = charlen(c)
-	if len < 0 || buf.len < len
-		-> -1
-	;;
-
-	if (len == 1)
-		mark = 0
-	else
-		mark = (((1 << (8 - len)) - 1) ^ 0xff) castto(char)
-	;;
-
-	for i = len - 1; i > 0; i--
-		buf[i] = (c & 0x3f | 0x80) castto(byte)
-		c >>= 6
-	;;
-
-	buf[0] = (c | mark) castto(byte)
-	-> len
-}
-
-const decode = {buf
-	var c
-	var b
-
-	(c, b) = striter(buf)
-	-> c
-}
-
-const striter = {str
-	var len
-	var mask
-	var chr
-	var i
-	var c
-	var tmp
-
-	if str.len == 0
-		/* empty string: no resync needed */
-		-> (Badchar, str)
-	;;
-	c = str[0]
-	len = 0
-	if c & 0x80 == 0	/* 0b0xxx_xxxx */
-		len = 1
-	elif c & 0xe0 == 0xc0	/* 0b110x_xxxx */
-		len = 2
-	elif c & 0xf0 == 0xe0 	/* 0b1110_xxxx */
-		len = 3
-	elif c & 0xf8 == 0xf0 	/* 0b1111_0xxx */
-		len = 4
-	else
-		/* skip one char forward so we can try
-		   resyncing the character stream */
-		-> (Badchar, str[1:])
-	;;
-
-	if len == 0 || len > str.len
-		/* again, we want to try to resync */
-		-> (Badchar, str[1:])
-	;;
-
-	mask = (1 << (8 - len)) - 1
-	chr = (c castto(uint32)) & mask
-	for i = 1; i < len; i++
-		tmp = str[i] castto(uint32)
-		chr = (chr << 6) | (tmp & 0x3f)
-	;;
-
-	-> (chr castto(char), str[len:])
-}
--- a/libstd/util+plan9-x64.s
+++ /dev/null
@@ -1,64 +1,0 @@
-/*
- * Allocates a C string on the stack, for
- * use within system calls, which is the only
- * place the Myrddin stack should need nul-terminated
- * strings.
- *
- * This is in assembly, because for efficiency we
- * allocate the C strings on the stack, and don't adjust
- * SP when returning.
- */
-TEXT sys$cstring+0(SB),$0
-	/* save registers */
-	MOVQ	SP,AX
-	SUBQ	$40,SP
-	MOVQ	BP,-8(AX)
-	MOVQ	R15,-16(AX)
-	MOVQ	SI,-24(AX)
-	MOVQ	DI,-32(AX)
-	MOVQ	CX,-40(AX)
-	MOVQ	AX,BP
-
-	MOVQ 	(BP),R15	/* ret addr */
-	MOVQ	8(BP),SI	/* src */
-	MOVQ	16(BP),CX	/* len */
-
-	SUBQ	CX,SP		/* get stack */
-	SUBQ	$1,SP		/* +1 for nul */
-	MOVQ	SP,DI		/* dest */
-	MOVQ	SP,AX		/* ret val */
-	ANDQ	$(~15),SP	/* align */
-	SUBQ	$32,SP		/* "unpop" the args and make room for return addr */
-
-	CLD
-	REP
-	MOVSB
-	MOVB	$0,(DI)		/* terminate */
-
-	/* Restore registers */
-	MOVQ	R15,0(SP)	/* place ret addr */
-	MOVQ	-40(BP),CX
-	MOVQ	-32(BP),DI
-	MOVQ	-24(BP),SI
-	MOVQ	-16(BP),R15
-	MOVQ	-8(BP) ,BP
-	RET
-
-TEXT sys$alloca+0(SB),$0
-	/* save registers */
-	MOVQ	(SP),R10	/* ret addr */
-
-	/* get stack space */
-	SUBQ	DI,SP		/* get stack space */
-	MOVQ	SP,AX		/* top of stack (return value) */
-	ANDQ	$(~15),SP	/* align */
-	SUBQ	$32,SP		/* "unpop" the args, and make room for ret addr */
-
-	MOVQ	R10,(SP)	/* place ret addr */
-	RET
-
-GLOBL	sys$tosptr+0(SB),$8
-DATA	sys$tosptr+0(SB)/8,$_tos+0(SB)
-GLOBL	sys$curbrk+0(SB),$8
-DATA	sys$curbrk+0(SB)/8,$end+0(SB)
-
--- a/libstd/util+posixy-x64.s
+++ /dev/null
@@ -1,72 +1,0 @@
-/*
- * Allocates a C string on the stack, for
- * use within system calls, which is the only
- * place the Myrddin stack should need nul-terminated
- * strings.
- *
- * This is in assembly, because for efficiency we
- * allocate the C strings on the stack, and don't adjust
- * %rsp when returning.
- */
-.globl sys$cstring
-.globl _sys$cstring
-_sys$cstring:
-sys$cstring:
-	/* save registers */
-	pushq %rbp
-	movq %rsp,%rbp
-	pushq %r15
-	pushq %rsi
-	pushq %rdi
-	pushq %rcx
-
-	movq 8(%rbp),%r15	/* ret addr */
-	movq 16(%rbp),%rsi	/* src */
-	movq 24(%rbp),%rcx	/* len */
-
-	subq %rcx,%rsp		/* get stack */
-	subq $1,%rsp		/* +1 for nul */
-	movq %rsp,%rdi		/* dest */
-	movq %rsp,%rax		/* ret val */
-	subq $31,%rsp		/* "unpop" the args */
-	andq $(~15),%rsp	/* align */
-
-	cld
-	rep movsb
-	movb $0,(%rdi)		/* terminate */
-
-	pushq %r15		/* ret addr */
-
-	/* restore registers */
-	movq -32(%rbp),%rcx
-	movq -24(%rbp),%rdi
-	movq -16(%rbp),%rsi
-	movq -8(%rbp),%r15
-	movq (%rbp),%rbp
-	ret
-
-.globl sys$alloca
-.globl _sys$alloca
-_sys$alloca:
-sys$alloca:
-	/* save registers */
-	pushq %rbp
-	movq %rsp,%rbp
-	pushq %r15
-	pushq %rbx
-
-	movq 8(%rbp),%r15	/* ret addr */
-
-	/* get stack space */
-	subq %rdi,%rsp		/* get stack space */
-	movq %rsp,%rax		/* top of stack (return value) */
-	subq $31,%rsp		/* "unpop" the args for return */
-	andq $(~15),%rsp	/* align */
-
-	pushq %r15		/* ret addr */
-
-	/* restore registers */
-	movq -16(%rbp),%rbx
-	movq -8(%rbp),%r15
-	movq (%rbp),%rbp
-	ret
--- a/libstd/varargs.myr
+++ /dev/null
@@ -1,105 +1,0 @@
-use "types.use"
-use "introspect.use"
-use "sleq.use"
-use "die.use"
-
-pkg std =
-	type valist
-
-	const vastart	: (args : ...# -> valist)
-	const vatype	: (ap : valist# -> byte[:])
-	const vabytes	: (ap : valist# -> byte[:])
-	generic vanext	: (ap : valist# -> @a)
-;;
-
-type valist = struct
-	args	: byte#
-	tc	: typecursor
-;;
-
-/* 
- * a valist is really just a pointer to the varargs.
- * we assume that these sit on the stack nicely,
- * and don't need special handling to get to.
- * 
- * This will be a problem when we switch to a
- * register based convention. We might want to
- * force varargs onto the stack regardless.
- */
-const vastart = {args
-	var tc, a, ip
-
-	/*
-	pull out the args. These are on the stacks like so:
-
-		[ required ]
-		[   args   ]
-	       ---variadic--- 
-		[ typeinfo ] --> type description
-	        ------------
-		[ variadic ]
-		[   args   ]
-		[   here   ]
-
-	&args points to the typeinfo, &args + sizeof(void#)
-	points to the rest argument.
-	*/
-		
-	tc = typeenc(args)
-	ip = (args castto(intptr)) + sizeof(byte#)
-	a = ip castto(byte#)
-	-> [.args = a, .tc = tc]
-}
-
-const vatype = {ap
-	-> tcpeek(&ap.tc)
-}
-
-const vabytes = {ap
-	var sl
-	var ti, align, sz
-	var p
-
-	ti = typeinfo(tcpeek(&ap.tc))
-
-	/* apply the alignment to the arg pointer */
-	align = ti.align castto(intptr)
-	p = ap.args castto(intptr)
-	p = (p + align - 1) & ~(align - 1)
-	ap.args = p castto(byte#)
-
-	sl = ap.args[:ti.size]
-	tcnext(&ap.tc)
-
-	sz = ti.size castto(intptr)
-	ap.args = ((p castto(intptr)) + sz) castto(byte#)
-
-	-> sl
-}
-
-const inspectarg = {x
-}
-
-generic vanext = {ap -> @a
-	var v : @a
-	var ti
-	var align
-	var p
-
-	ti = typeinfo(tcpeek(&ap.tc))
-
-	/* apply the alignment to the arg pointer */
-	align = ti.align castto(intptr)
-	inspectarg(align)
-	p = ap.args castto(intptr)
-	p = (p + align - 1) & ~(align - 1)
-	ap.args = p castto(byte#)
-
-	v = (ap.args castto(@a#))#
-	/* TODO: check for type mismatch */
-	tcnext(&ap.tc)
-
-	/* only move on after we read through the value */
-	ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)
-	-> v
-}
--- a/libstd/wait+plan9.myr
+++ /dev/null
@@ -1,94 +1,0 @@
-use sys
-
-use "alloc.use"
-use "chartype.use"
-use "die.use"
-use "extremum.use"
-use "hashfuncs.use"
-use "hasprefix.use"
-use "htab.use"
-use "intparse.use"
-use "option.use"
-use "strsplit.use"
-use "syswrap.use"
-use "utf.use"
-
-pkg std =
-	type waitstatus = union
-		`Wsuccess
-		`Wfailure
-		`Wsignalled
-		`Waiterror
-	;;
-
-	const wait	: (pid : pid -> waitstatus)
-;;
-
-var statusinit	: bool = false
-var statusmap	: htab(pid, waitstatus)#
-
-const wait = {pid
-	var buf : byte[512]
-	var xpid, status
-	var n
-
-	if !statusinit
-		statusmap = mkht(pidhash, pideq)
-		statusinit = true
-	;;
-		
-	match htget(statusmap, pid)
-	| `Some st:
-		htdel(statusmap, pid)
-		-> st
-	| `None:	/* nothing */
-	;;
-
-	while true
-		n = sys.await(buf[:])
-		if n < 0
-			-> `Waiterror
-		;;
-
-		(status, xpid) = parsestatus(buf[:n])
-		if xpid == pid
-			-> status
-		else
-			htput(statusmap, pid, status)
-		;;
-	;;
-	/* impossible */
-	-> `Waiterror
-}
-
-const parsestatus = {status	-> (waitstatus, pid)
-	var st : waitstatus, xpid, sp
-
-	sp = strsplit(status, " ")
-	if sp.len == 0
-		slfree(sp)
-		-> (`Wfailure, -1)
-	;;
-
-	match intparse(sp[0])
-	| `Some pid:
-		xpid = pid
-		if sp.len == 4 || (sp.len == 5 && sp[4].len > 0)	/* we exited with nil */
-			st = `Wsuccess
-		elif sp.len == 5	/* we have a status */
-			st = `Wfailure
-		else	/* we have a malformed await message */
-			st = `Waiterror
-		;;
-	| `None:
-		xpid = -1
-		st = `Waiterror
-	;;
-
-	slfree(sp)
-	-> (st, xpid)
-
-}
-
-const pidhash	= {x;	-> inthash(x castto(int32))}
-const pideq	= {a, b;	-> a == b}
\ No newline at end of file
--- a/libstd/wait+posixy.myr
+++ /dev/null
@@ -1,41 +1,0 @@
-use sys
-
-use "die.use"
-use "syswrap.use"
-
-pkg std =
-	type waitstatus = union
-		`Wsuccess
-		`Wfailure
-		`Wsignalled
-		`Waiterror
-	;;
-
-	const wait	: (pid : pid -> waitstatus)
-;;
-
-const wait = {pid
-	var st
-
-:again
-	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
-		match sys.waitstatus(st)
-		/* 
-		when a process stops, eg, if paused by a debugger,
-		wait() will return. This API is for waiting until
-		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
-			;;
-		;;
-	;;
-	-> `Waiterror
-}
-
--- a/mbld/bld.sub
+++ b/mbld/bld.sub
@@ -17,10 +17,10 @@
 	# Currently, mbld doesn't add all deps transitively.
 	# Until this gets fixed, we need to list all dependent
 	# libraries here explicitly.
-	lib ../libstd:sys
-	lib ../libstd:std
-	lib ../libbio:bio
-	lib ../libregex:regex
+	lib @/lib/std:sys
+	lib @/lib/std:std
+	lib @/lib/bio:bio
+	lib @/lib/regex:regex
 ;;
 
 man = mbld.1;;