diff options
author | Ori Bernstein <ori@eigenstate.org> | 2018-01-01 21:09:50 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2018-01-11 22:16:11 -0800 |
commit | 90e26e0f687da28530b3b967df0cedf20407c071 (patch) | |
tree | 09c85ff396a5f235dbcbd5db2df911b5217bb472 | |
parent | 94448201527e0c47c2924219bf1a8d0c0c2406b7 (diff) | |
download | mc-90e26e0f687da28530b3b967df0cedf20407c071.tar.gz |
Move to new trait syntax.
34 files changed, 358 insertions, 246 deletions
diff --git a/lib/bio/bio.myr b/lib/bio/bio.myr index 4db8ec9..1f44bf8 100644 --- a/lib/bio/bio.myr +++ b/lib/bio/bio.myr @@ -283,7 +283,7 @@ const ensurecodepoint = {f writes a single integer-like value to the output stream, in little endian format */ -generic putle = {f, v : @a::(numeric,integral) +generic putle = {f, v : @a :: numeric,integral @a for var i = 0; i < sizeof(@a); i++ putb(f, (v & 0xff : byte)) v >>= 8 @@ -295,7 +295,7 @@ generic putle = {f, v : @a::(numeric,integral) writes a single integer-like value to the output stream, in big endian format */ -generic putbe = {f, v : @a::(numeric,integral) +generic putbe = {f, v : @a :: numeric,integral @a for var i = sizeof(@a); i != 0; i-- putb(f, ((v >> ((i-1)*8)) & 0xff : byte)) ;; diff --git a/lib/bio/geti.myr b/lib/bio/geti.myr index ee9a631..4e9faca 100644 --- a/lib/bio/geti.myr +++ b/lib/bio/geti.myr @@ -5,23 +5,23 @@ use "types" pkg bio = /* unsigned big endian */ - generic getbe8 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getbe16 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getbe32 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getbe64 : (f : file# -> std.result(@a::(numeric,integral), err)) + generic getbe8 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getbe16 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getbe32 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getbe64 : (f : file# -> std.result(@a, err)) :: numeric,integral @a /* signed big endian */ - generic getle8 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getle16 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getle32 : (f : file# -> std.result(@a::(numeric,integral), err)) - generic getle64 : (f : file# -> std.result(@a::(numeric,integral), err)) + generic getle8 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getle16 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getle32 : (f : file# -> std.result(@a, err)) :: numeric,integral @a + generic getle64 : (f : file# -> std.result(@a, err)) :: numeric,integral @a ;; /* reads a single integer-like value to the output stream, in little endian format */ -generic getle = {f, n -> std.result(@a::(numeric,integral), err) +generic getle = {f, n -> std.result(@a, err) :: numeric,integral @a match ensureread(f, n) | `std.Err e : -> `std.Err e | `std.Ok _: @@ -29,7 +29,7 @@ generic getle = {f, n -> std.result(@a::(numeric,integral), err) for var i = 0; i < n; i++ v |= (f.rbuf[f.rstart++] : uint64) << (8*(i : uint64)) ;; - -> `std.Ok (v : @a::(numeric,integral)) + -> `std.Ok (v : @a) ;; } @@ -37,7 +37,7 @@ generic getle = {f, n -> std.result(@a::(numeric,integral), err) reads a single integer-like value to the output stream, in big endian format */ -generic getbe = {f, n -> std.result(@a::(numeric,integral), err) +generic getbe = {f, n -> std.result(@a, err) :: numeric,integral @a match ensureread(f, n) | `std.Err e : -> `std.Err e | `std.Ok _: @@ -46,7 +46,7 @@ generic getbe = {f, n -> std.result(@a::(numeric,integral), err) v <<= 8 v |= (f.rbuf[f.rstart++] : uint64) ;; - -> `std.Ok (v : @a::(numeric,integral)) + -> `std.Ok (v : @a) ;; } diff --git a/lib/bio/puti.myr b/lib/bio/puti.myr index 2f07414..38fddcd 100644 --- a/lib/bio/puti.myr +++ b/lib/bio/puti.myr @@ -5,16 +5,16 @@ use "types" pkg bio = /* unsigned big endian */ - generic putbe8 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putbe16 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putbe32 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putbe64 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) + generic putbe8 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putbe16 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putbe32 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putbe64 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a /* unsigned little endian */ - generic putle8 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putle16 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putle32 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) - generic putle64 : (f : file#, v : @a::(numeric,integral) -> std.result(std.size, err)) + generic putle8 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putle16 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putle32 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a + generic putle64 : (f : file#, v : @a -> std.result(std.size, err)) :: numeric,integral @a ;; generic putbe8 = {f, v; -> putbe(f, (v : uint64), 1)} diff --git a/lib/crypto/rand.myr b/lib/crypto/rand.myr index 21c3844..2cc6832 100644 --- a/lib/crypto/rand.myr +++ b/lib/crypto/rand.myr @@ -8,8 +8,8 @@ use "chacha20" pkg crypto = /* designed to mirror std.rand() */ const randbytes : (buf : byte[:] -> void) - generic rand : (lo : @a::(integral,numeric), hi : @a::(integral,numeric) -> @a::(numeric,integral)) - generic randnum : (-> @a::(numeric,integral)) + generic rand : (lo : @a, hi : @a -> @a) ::numeric,integral @a + generic randnum : (-> @a) :: numeric,integral @a ;; const Stirinterval = 16*std.MiB diff --git a/lib/date/parse.myr b/lib/date/parse.myr index 6c6d0d7..398dbae 100644 --- a/lib/date/parse.myr +++ b/lib/date/parse.myr @@ -239,9 +239,8 @@ const matchampm = {d, s, am, err -> s ;; } -generic intval = {dst : @a::(numeric,integral)#, s : byte[:], \ - min : @a::(numeric,integral), max : @a::(numeric,integral), \ - err : std.option(parsefail)# -> byte[:] + +generic intval = {dst : @a#, s : byte[:], min : @a, max : @a, err : std.option(parsefail)# -> byte[:] :: numeric,integral @a var i, c, num num = s diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr index 129890c..bdc040c 100644 --- a/lib/std/bigint.myr +++ b/lib/std/bigint.myr @@ -22,7 +22,7 @@ pkg std = ;; /* administrivia */ - generic mkbigint : (v : @a::(numeric,integral) -> bigint#) + generic mkbigint : (v : @a -> bigint#) :: numeric,integral @a const bigfrombytes : (isneg : bool, v : byte[:] -> bigint#) const bigfree : (a : bigint# -> void) const bigdup : (a : bigint# -> bigint#) @@ -40,7 +40,7 @@ pkg std = const bigiszero : (a : bigint# -> bool) const bigiseven : (a : bigint# -> bool) const bigcmp : (a : bigint#, b : bigint# -> order) - generic bigcmpi : (a : bigint#, b : @a::(numeric,integral) -> order) + generic bigcmpi : (a : bigint#, b : @a -> order) :: numeric,integral @a /* shorthand for comparisons */ const bigeq : (a : bigint#, b : bigint# -> bool) @@ -48,11 +48,11 @@ pkg std = const bigle : (a : bigint#, b : bigint# -> bool) const biggt : (a : bigint#, b : bigint# -> bool) const bigge : (a : bigint#, b : bigint# -> bool) - generic bigeqi : (a : bigint#, b : @a::(numeric,integral) -> bool) - generic biglti : (a : bigint#, b : @a::(numeric,integral) -> bool) - generic biglei : (a : bigint#, b : @a::(numeric,integral) -> bool) - generic biggti : (a : bigint#, b : @a::(numeric,integral) -> bool) - generic biggei : (a : bigint#, b : @a::(numeric,integral) -> bool) + generic bigeqi : (a : bigint#, b : @a -> bool) :: numeric,integral @a + generic biglti : (a : bigint#, b : @a -> bool) :: numeric,integral @a + generic biglei : (a : bigint#, b : @a -> bool) :: numeric,integral @a + generic biggti : (a : bigint#, b : @a -> bool) :: numeric,integral @a + generic biggei : (a : bigint#, b : @a -> bool) :: numeric,integral @a /* bigint*bigint -> bigint ops */ const bigadd : (a : bigint#, b : bigint# -> bigint#) @@ -71,15 +71,15 @@ pkg std = /* 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 bigmodi : (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#) - generic bigandi : (a : bigint#, b : @a::(integral,numeric) -> bigint#) - generic bigori : (a : bigint#, b : @a::(integral,numeric) -> bigint#) + generic bigaddi : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigsubi : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigmuli : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigdivi : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigmodi : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigshli : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigshri : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigandi : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a + generic bigori : (a : bigint#, b : @a -> bigint#) :: integral,numeric @a //const bigpowi : (a : bigint#, b : uint64 -> bigint#) //const bigmodpowi : (b : bigint#, e : bigint#, m : bigint# -> bigint#) @@ -93,7 +93,7 @@ extern const put : (fmt : byte[:], args : ... -> size) const Base = 0x100000000ul -generic mkbigint = {v : @a::(integral,numeric) +generic mkbigint = {v : @a :: integral,numeric @a var a var val @@ -771,7 +771,7 @@ generic bigaddi = {a, b -> a } -generic bigsubi = {a, b : @a::(numeric,integral) +generic bigsubi = {a, b : @a :: numeric,integral @a var bigb : bigint var dig : uint32[2] @@ -811,7 +811,7 @@ generic bigmodi = {a, b a << s, with integer arg. logical left shift. any other type would be illogical. */ -generic bigshli = {a, s : @a::(numeric,integral) +generic bigshli = {a, s : @a :: numeric,integral @a var off, shift var t, carry diff --git a/lib/std/bitset.myr b/lib/std/bitset.myr index ce750db..3d8c2ff 100644 --- a/lib/std/bitset.myr +++ b/lib/std/bitset.myr @@ -22,9 +22,9 @@ pkg std = const bsmax : (a : bitset# -> size) const bscount : (a : bitset# -> size) - generic bsput : (bs : bitset#, v : @a::(integral,numeric) -> bool) - generic bsdel : (bs : bitset#, v : @a::(integral,numeric) -> bool) - generic bshas : (bs : bitset#, v : @a::(integral,numeric) -> bool) + generic bsput : (bs : bitset#, v : @a -> bool) :: integral,numeric @a + generic bsdel : (bs : bitset#, v : @a -> bool) :: integral,numeric @a + generic bshas : (bs : bitset#, v : @a -> bool) :: integral,numeric @a const bsdiff : (a : bitset#, b : bitset# -> void) const bsintersect : (a : bitset#, b : bitset# -> void) diff --git a/lib/std/chartype.myr b/lib/std/chartype.myr index bf01d9a..9832fc5 100644 --- a/lib/std/chartype.myr +++ b/lib/std/chartype.myr @@ -25,7 +25,7 @@ pkg std = const toupper : (c : char -> char) const totitle : (c : char -> char) - generic charval : (c : char, base : int -> @a::(integral,numeric)) + generic charval : (c : char, base : int -> @a) :: integral,numeric @a const cellwidth : (c : char -> int) ;; @@ -1670,18 +1670,18 @@ const totitle = {c -> c } -generic charval = {c, base -> @a::(numeric,integral) +generic charval = {c, base -> @a :: numeric,integral @a var v = -1 if c >= '0' && c <= '9' - v = (c - '0' : @a::(integral,numeric)) + v = (c - '0' : @a) elif c >= 'a' && c <= 'z' - v = (c - 'a' + 10 : @a::(integral,numeric)) + v = (c - 'a' + 10 : @a) elif c >= 'A' && c <= 'Z' - v = (c - 'A' + 10 : @a::(integral,numeric)) + v = (c - 'A' + 10 : @a) ;; - if v < 0 || v >= (base : @a::(integral,numeric)) + if v < 0 || v >= (base : @a) -> -1 ;; -> v diff --git a/lib/std/endian.myr b/lib/std/endian.myr index 874ab71..c896dd8 100644 --- a/lib/std/endian.myr +++ b/lib/std/endian.myr @@ -1,16 +1,16 @@ pkg std = - generic hosttonet : (v : @a::(integral,numeric) -> @a::(integral,numeric)) - generic nettohost : (v : @a::(integral,numeric) -> @a::(integral,numeric)) + generic hosttonet : (v : @a -> @a) :: integral,numeric @a + generic nettohost : (v : @a -> @a) :: integral,numeric @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) +generic hosttonet = {v : @a :: integral,numeric @a var i var ret ret = 0 - for i = 0; i < sizeof(@a::(integral,numeric)); i++ + for i = 0; i < sizeof(@a); i++ ret <<= 8 ret |= v & 0xff v >>= 8 @@ -18,12 +18,12 @@ generic hosttonet = {v : @a::(integral,numeric) -> ret } -generic nettohost = {v : @a::(integral,numeric) +generic nettohost = {v : @a :: integral,numeric @a var i var ret ret = 0 - for i = 0; i < sizeof(@a::(integral,numeric)); i++ + for i = 0; i < sizeof(@a); i++ ret <<= 8 ret |= v & 0xff v >>= 8 diff --git a/lib/std/extremum.myr b/lib/std/extremum.myr index b8afc01..2c46ae1 100644 --- a/lib/std/extremum.myr +++ b/lib/std/extremum.myr @@ -1,8 +1,8 @@ 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 : @a, b : @a -> @a) :: numeric @a + generic max : (a : @a, b : @a -> @a) :: numeric @a + generic clamp : (a : @a, min : @a, max : @a -> @a) :: numeric @a + generic abs : (a : @a -> @a) :: numeric @a ;; generic min = {a, b @@ -31,8 +31,8 @@ generic clamp = {a, min, max ;; } -generic abs = {a : @a::numeric - if a < (0 : @a::numeric) +generic abs = {a : @a :: numeric @a + if a < (0 : @a) -> -a else -> a diff --git a/lib/std/fltbits.myr b/lib/std/fltbits.myr index 0d7169b..765ce04 100644 --- a/lib/std/fltbits.myr +++ b/lib/std/fltbits.myr @@ -6,7 +6,7 @@ pkg std = const flt32inf : (-> flt32) const flt32nan : (-> flt32) - generic isnan : (f : @a::floating -> bool) + generic isnan : (f : @a -> bool) ::floating @a const flt64frombits : (bits : uint64 -> flt64) const flt32frombits : (bits : uint32 -> flt32) const flt64explode : (flt : flt64 -> (bool, int64, int64)) diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr index 5c94542..005d1d3 100644 --- a/lib/std/fmt.myr +++ b/lib/std/fmt.myr @@ -537,7 +537,7 @@ const digitchars = [ '5','6','7','8','9', 'a','b','c','d','e','f' ] -generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric) +generic intfmt = {sb, opts, signed, bits : @a :: integral,numeric @a var isneg var sval, val var b : char[32] @@ -557,7 +557,7 @@ generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric) ;; else val = (bits : uint64) - val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a::(integral,numeric)))) + val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a))) isneg = false ;; diff --git a/lib/std/fndup.myr b/lib/std/fndup.myr index 4bbed61..b4799e0 100644 --- a/lib/std/fndup.myr +++ b/lib/std/fndup.myr @@ -5,10 +5,10 @@ use "slcp" use "types" pkg std = - generic fnenvsz : (fn : @fn::function -> size) - generic fndup : (fn : @fn::function -> @fn::function) - generic fnbdup : (fn : @fn::function, buf : byte[:] -> @fn::function) - generic fnfree : (fn : @fn::function -> void) + generic fnenvsz : (fn : @fn -> size) :: function @fn + generic fndup : (fn : @fn -> @fn) :: function @fn + generic fnbdup : (fn : @fn, buf : byte[:] -> @fn) :: function @fn + generic fnfree : (fn : @fn -> void) :: function @fn ;; generic fndup = {fn @@ -27,7 +27,7 @@ generic fnenvsz = {fn extern const put : (fmt : byte[:], args : ... -> int64) -generic fnbdup = {fn, buf +generic fnbdup = {fn : @fn, buf :: function @fn var repr : intptr[2] var env @@ -35,7 +35,7 @@ generic fnbdup = {fn, buf env = envslice(repr[0]) slcp(buf[:env.len], env) repr[0] = (buf : intptr) - -> (&repr : @fn::function#)# + -> (&repr : @fn#)# } generic fnfree = {fn diff --git a/lib/std/getint.myr b/lib/std/getint.myr index 4445c4a..3499c4d 100644 --- a/lib/std/getint.myr +++ b/lib/std/getint.myr @@ -2,95 +2,95 @@ use "die" use "memops" pkg std = - generic gethost64 : (buf : byte[:] -> @a::(numeric,integral)) - generic getle64 : (buf : byte[:] -> @a::(numeric,integral)) - generic getbe64 : (buf : byte[:] -> @a::(numeric,integral)) - generic gethost32 : (buf : byte[:] -> @a::(numeric,integral)) - generic getle32 : (buf : byte[:] -> @a::(numeric,integral)) - generic getbe32 : (buf : byte[:] -> @a::(numeric,integral)) - generic gethost16 : (buf : byte[:] -> @a::(numeric,integral)) - generic getle16 : (buf : byte[:] -> @a::(numeric,integral)) - generic getbe16 : (buf : byte[:] -> @a::(numeric,integral)) - generic gethost8 : (buf : byte[:] -> @a::(numeric,integral)) - generic getle8 : (buf : byte[:] -> @a::(numeric,integral)) - generic getbe8 : (buf : byte[:] -> @a::(numeric,integral)) + generic gethost64 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getle64 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getbe64 : (buf : byte[:] -> @a) :: numeric,integral @a + generic gethost32 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getle32 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getbe32 : (buf : byte[:] -> @a) :: numeric,integral @a + generic gethost16 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getle16 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getbe16 : (buf : byte[:] -> @a) :: numeric,integral @a + generic gethost8 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getle8 : (buf : byte[:] -> @a) :: numeric,integral @a + generic getbe8 : (buf : byte[:] -> @a) :: numeric,integral @a ;; -generic gethost64 = {buf -> @a::(numeric,integral) +generic gethost64 = {buf -> @a :: numeric,integral @a var val : int64 iassert(buf.len >= 8, "gethost64: index out of bounds") memblit((&val : byte#), (buf : byte#), 8) - -> (val : @a::(numeric,integral)) + -> (val : @a) } -generic getbe64 = {buf -> @a::(numeric,integral) - -> ((buf[0] : @a::(numeric,integral)) << 56) | \ - ((buf[1] : @a::(numeric,integral)) << 48) | \ - ((buf[2] : @a::(numeric,integral)) << 40) | \ - ((buf[3] : @a::(numeric,integral)) << 32) | \ - ((buf[4] : @a::(numeric,integral)) << 24) | \ - ((buf[5] : @a::(numeric,integral)) << 16) | \ - ((buf[6] : @a::(numeric,integral)) << 8) | \ - ((buf[7] : @a::(numeric,integral)) << 0) +generic getbe64 = {buf -> @a :: numeric,integral @a + -> ((buf[0] : @a) << 56) | \ + ((buf[1] : @a) << 48) | \ + ((buf[2] : @a) << 40) | \ + ((buf[3] : @a) << 32) | \ + ((buf[4] : @a) << 24) | \ + ((buf[5] : @a) << 16) | \ + ((buf[6] : @a) << 8) | \ + ((buf[7] : @a) << 0) } generic getle64 = {buf - -> ((buf[0] : @a::(numeric,integral)) << 0) | \ - ((buf[1] : @a::(numeric,integral)) << 8) | \ - ((buf[2] : @a::(numeric,integral)) << 16) | \ - ((buf[3] : @a::(numeric,integral)) << 24) | \ - ((buf[4] : @a::(numeric,integral)) << 32) | \ - ((buf[5] : @a::(numeric,integral)) << 40) | \ - ((buf[6] : @a::(numeric,integral)) << 48) | \ - ((buf[7] : @a::(numeric,integral)) << 56) + -> ((buf[0] : @a) << 0) | \ + ((buf[1] : @a) << 8) | \ + ((buf[2] : @a) << 16) | \ + ((buf[3] : @a) << 24) | \ + ((buf[4] : @a) << 32) | \ + ((buf[5] : @a) << 40) | \ + ((buf[6] : @a) << 48) | \ + ((buf[7] : @a) << 56) } -generic gethost32 = {buf -> @a::(numeric,integral) +generic gethost32 = {buf -> @a :: numeric,integral @a var val : int32 iassert(buf.len >= 4, "gethost32: index out of bounds") memblit((&val : byte#), (buf : byte#), 4) - -> (val : @a::(numeric,integral)) + -> (val : @a) } -generic getbe32 = {buf - -> ((buf[0] : @a::(numeric,integral)) << 24) | \ - ((buf[1] : @a::(numeric,integral)) << 16) | \ - ((buf[2] : @a::(numeric,integral)) << 8) | \ - ((buf[3] : @a::(numeric,integral)) << 0) +generic getbe32 = {buf -> @a :: numeric, integral @a + -> ((buf[0] : @a) << 24) | \ + ((buf[1] : @a) << 16) | \ + ((buf[2] : @a) << 8) | \ + ((buf[3] : @a) << 0) } -generic getle32 = {buf - -> ((buf[0] : @a::(numeric,integral)) << 0) | \ - ((buf[1] : @a::(numeric,integral)) << 8) | \ - ((buf[2] : @a::(numeric,integral)) << 16) | \ - ((buf[3] : @a::(numeric,integral)) << 24) +generic getle32 = {buf -> @a :: numeric, integral @a + -> ((buf[0] : @a) << 0) | \ + ((buf[1] : @a) << 8) | \ + ((buf[2] : @a) << 16) | \ + ((buf[3] : @a) << 24) } -generic gethost16 = {buf -> @a::(numeric,integral) +generic gethost16 = {buf -> @a :: numeric,integral @a var val : int16 iassert(buf.len >= 2, "gethost16: index out of bounds") memblit((&val : byte#), (buf : byte#), 4) - -> (val : @a::(numeric,integral)) + -> (val : @a) } -generic getbe16 = {buf - -> ((buf[0] : @a::(numeric,integral)) << 8) | \ - ((buf[1] : @a::(numeric,integral)) << 0) +generic getbe16 = {buf -> @a :: numeric,integral @a + -> ((buf[0] : @a) << 8) | \ + ((buf[1] : @a) << 0) } -generic getle16 = {buf - -> ((buf[0] : @a::(numeric,integral)) << 0) | \ - ((buf[1] : @a::(numeric,integral)) << 8) +generic getle16 = {buf -> @a :: numeric,integral @a + -> ((buf[0] : @a) << 0) | \ + ((buf[1] : @a) << 8) } -generic gethost8 = {buf - -> (buf[0] : @a::(numeric,integral)) << 0 +generic gethost8 = {buf -> @a :: numeric,integral @a + -> (buf[0] : @a) << 0 } -generic getbe8 = {buf - -> (buf[0] : @a::(numeric,integral)) << 0 +generic getbe8 = {buf -> @a :: numeric,integral @a + -> (buf[0] : @a) << 0 } -generic getle8 = {buf - -> (buf[0] : @a::(numeric,integral)) << 0 +generic getle8 = {buf -> @a :: numeric,integral @a + -> (buf[0] : @a) << 0 } diff --git a/lib/std/hashfuncs.myr b/lib/std/hashfuncs.myr index 5ad1180..a7d61c4 100644 --- a/lib/std/hashfuncs.myr +++ b/lib/std/hashfuncs.myr @@ -23,13 +23,13 @@ pkg std = } ;; - impl equatable @a::(integral,numeric) = + impl equatable @a :: integral,numeric @a = eq = {a, b -> a == b } ;; - impl hashable @a::(integral,numeric) = + impl hashable @a :: integral,numeric @a = hash = {a -> siphash24((&a : byte#)[:sizeof(@a)], Seed) } diff --git a/lib/std/intparse.myr b/lib/std/intparse.myr index 18cc478..446abc8 100644 --- a/lib/std/intparse.myr +++ b/lib/std/intparse.myr @@ -7,8 +7,8 @@ use "types" use "utf" pkg std = - generic intparsebase : (s : byte[:], base : int -> option(@a::(integral,numeric))) - generic intparse : (s : byte[:] -> option(@a::(integral,numeric))) + generic intparsebase : (s : byte[:], base : int -> option(@a)) :: integral,numeric @a + generic intparse : (s : byte[:] -> option(@a)) :: integral,numeric @a ;; generic intparse = {s @@ -47,7 +47,7 @@ generic intparsebase = {s, base -> doparse(s, isneg, base) } -generic doparse = {s, isneg, base -> option(@a::(integral,numeric)) +generic doparse = {s, isneg, base -> option(@a) :: integral,numeric @a var v var cv : int32 @@ -58,8 +58,8 @@ generic doparse = {s, isneg, base -> option(@a::(integral,numeric)) ;; cv = charval(c, base) if cv >= 0 - v *= (base : @a::(integral,numeric)) - v += (cv : @a::(integral,numeric)) + v *= (base : @a) + v += (cv : @a) else -> `None ;; diff --git a/lib/std/ipparse.myr b/lib/std/ipparse.myr index 78cb619..16da94e 100644 --- a/lib/std/ipparse.myr +++ b/lib/std/ipparse.myr @@ -116,7 +116,7 @@ const delim = {ip, sep, ok ;; } -generic num = {ip, lo, hi, base, sep, ok -> (@a::(numeric,integral), byte[:], bool) +generic num = {ip, lo, hi, base, sep, ok -> (@a, byte[:], bool) :: numeric,integral @a var len if !ok @@ -133,7 +133,7 @@ generic num = {ip, lo, hi, base, sep, ok -> (@a::(numeric,integral), byte[:], bo if v < lo || v > hi -> (0, "", false) ;; - -> ((v : @a::(numeric,integral)), ip[len:], true) + -> ((v : @a), ip[len:], true) | `std.None: -> (0, "", false) ;; diff --git a/lib/std/putint.myr b/lib/std/putint.myr index c6e48e9..c05ee7a 100644 --- a/lib/std/putint.myr +++ b/lib/std/putint.myr @@ -3,21 +3,21 @@ use "memops" use "types" pkg std = - generic puthost64 : (buf : byte[:], v : @a::(numeric,integral) -> size) - generic putle64 : (buf : byte[:], v : @a::(numeric,integral) -> size) - generic putbe64 : (buf : byte[:], v : @a::(numeric,integral) -> size) - generic puthost32 : (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 puthost16 : (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 puthost8 : (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 puthost64 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putle64 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putbe64 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic puthost32 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putle32 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putbe32 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic puthost16 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putle16 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putbe16 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic puthost8 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putle8 : (buf : byte[:], v : @a -> size) :: numeric,integral @a + generic putbe8 : (buf : byte[:], v : @a -> size) :: numeric,integral @a ;; -generic puthost = {buf, val : @a::(integral, numeric) +generic puthost = {buf, val : @a :: integral, numeric @a iassert(buf.len >= sizeof(@a), "buffer too small") memblit((buf : byte#), (&val : byte#), sizeof(@a)) -> sizeof(@a) diff --git a/lib/std/rand.myr b/lib/std/rand.myr index c2a03fd..9cea564 100644 --- a/lib/std/rand.myr +++ b/lib/std/rand.myr @@ -13,12 +13,12 @@ pkg std = const mksrng : (seed : uint32 -> rng#) const freerng : (rng : rng# -> void) - generic rand : (lo : @a::(numeric,integral), hi : @a::(numeric,integral) -> @a::(numeric,integral)) - generic randnum : (-> @a::(numeric,integral)) + generic rand : (lo : @a, hi : @a -> @a) :: numeric,integral @a + generic randnum : (-> @a) :: numeric,integral @a const randbytes : (buf : byte[:] -> void) - generic rngrand : (rng : rng#, lo : @a::(numeric,integral), hi : @a::(numeric,integral) -> @a::(numeric,integral)) - generic rngrandnum : (rng : rng# -> @a::(numeric,integral)) + generic rngrand : (rng : rng#, lo : @a, hi : @a -> @a) ::numeric,integral @a + generic rngrandnum : (rng : rng# -> @a) :: numeric,integral @a const rngrandbytes : (rng : rng#, buf : byte[:] -> void) ;; @@ -90,7 +90,7 @@ designed by David Blackman and Sebastiano Vigna. See http://xoroshiro.di.unimi.it/ for details. */ -generic rngrandnum = {rng -> @a::(numeric,integral) +generic rngrandnum = {rng -> @a :: numeric,integral @a var s0, s1, r s0 = rng.s0 @@ -101,5 +101,5 @@ generic rngrandnum = {rng -> @a::(numeric,integral) rng.s0 = (s0 << 55 | s0 >> 9) ^ s1 ^ (s1 << 14) rng.s1 = (s1 << 36 | s1 >> 28) - -> (r : @a::(numeric,integral)) + -> (r : @a) } diff --git a/lib/std/search.myr b/lib/std/search.myr index 8ae364f..5e3865b 100644 --- a/lib/std/search.myr +++ b/lib/std/search.myr @@ -3,8 +3,8 @@ use "option" use "types" pkg std = - generic lsearch : (sl : @t[:], key : @k, cmp : (v : @t, k : @k -> order) -> option(@idx::(integral,numeric))) - generic bsearch : (sl : @t[:], key : @k, cmp : (v : @t, k : @k -> order) -> option(@idx::(integral,numeric))) + generic lsearch : (sl : @t[:], key : @k, cmp : (v : @t, k : @k -> order) -> option(@idx)) :: integral,numeric @idx + generic bsearch : (sl : @t[:], key : @k, cmp : (v : @t, k : @k -> order) -> option(@idx)) :: integral,numeric @idx ;; /* linear search over a list of values */ diff --git a/lib/std/syswrap+posixy.myr b/lib/std/syswrap+posixy.myr index f49f9b8..4dd97fd 100644 --- a/lib/std/syswrap+posixy.myr +++ b/lib/std/syswrap+posixy.myr @@ -179,7 +179,7 @@ const fsize = {path ;; } -generic check = {e : @a::(integral, numeric) -> result(@b, errno) +generic check = {e : @a -> result(@b, errno) :: integral,numeric @a if e < 0 -> `Err (e : errno) else diff --git a/lib/std/units.myr b/lib/std/units.myr index 67eab81..76d9e5a 100644 --- a/lib/std/units.myr +++ b/lib/std/units.myr @@ -2,14 +2,14 @@ use "types" 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 + generic KiB : @a = 1024 :: integral,numeric @a + generic MiB : @a = KiB*1024 :: integral,numeric @a + generic GiB : @a = MiB*1024 :: integral,numeric @a + generic TiB : @a = GiB*1024 :: integral,numeric @a + generic PiB : @a = TiB*1024 :: integral,numeric @a + generic EiB : @a = PiB*1024 :: integral,numeric @a + generic ZiB : @a = EiB*1024 :: integral,numeric @a + generic YiB : @a = ZiB*1024 :: integral,numeric @a generic Sec : time = 1_000_000 generic Msec : time = 1_000 diff --git a/lib/thread/atomic.myr b/lib/thread/atomic.myr index b9678c7..c3c8124 100644 --- a/lib/thread/atomic.myr +++ b/lib/thread/atomic.myr @@ -1,7 +1,7 @@ use std pkg thread = - trait atomic @a::(integral,numeric) = + trait atomic @a :: integral,numeric @a = xget : (p : @a# -> @a) xset : (p : @a#, v : @a -> void) xadd : (p : @a#, v : @a -> @a) diff --git a/parse/gram.y b/parse/gram.y index dc17314..c3db284 100644 --- a/parse/gram.y +++ b/parse/gram.y @@ -18,10 +18,11 @@ #include "parse.h" -Stab *curscope; #define LBLSTKSZ 64 static Node **lbls[LBLSTKSZ]; static size_t nlbls[LBLSTKSZ]; +Stab *curscope; + /* the first time we see a label, we increment to 0 */ static int lbldepth = -1; @@ -32,6 +33,7 @@ static Op binop(int toktype); static Node *mkpseudodecl(Srcloc l, Type *t); static void installucons(Stab *st, Type *t); static void setattrs(Node *dcl, char **attrs, size_t nattrs); +static void setwith(Type *ty, Traitspec **spec, size_t nspec); static void setupinit(Node *n); %} @@ -132,7 +134,9 @@ static void setupinit(Node *n); %type <ty> type structdef uniondef tupledef compoundtype functype funcsig %type <ty> generictype %type <tylist> typelist typarams optauxtypes -%type <nodelist> typaramlist +%type <traitspecs> traitspec traits +%type <traitspec> traitvar +%type <nodelist> traitlist %type <tok> asnop cmpop addop mulop shiftop optident obrace @@ -207,6 +211,11 @@ but warnings suck. Type **params; size_t nparams; } tydef; + struct { + Traitspec **spec; + size_t nspec; + } traitspecs; + Traitspec *traitspec; Trait *trait; Node *node; Tok *tok; @@ -254,14 +263,14 @@ toplev : package | /* empty */ ; -decl : attrs Tvar decllist { +decl : attrs Tvar decllist traitspec { size_t i; for (i = 0; i < $3.nn; i++) setattrs($3.nl[i], $1.str, $1.nstr); $$ = $3; } - | attrs Tconst decllist { + | attrs Tconst decllist traitspec { size_t i; for (i = 0; i < $3.nn; i++) { setattrs($3.nl[i], $1.str, $1.nstr); @@ -269,11 +278,12 @@ decl : attrs Tvar decllist { } $$ = $3; } - | attrs Tgeneric decllist { + | attrs Tgeneric decllist traitspec { size_t i; for (i = 0; i < $3.nn; i++) { setattrs($3.nl[i], $1.str, $1.nstr); + setwith($3.nl[i]->decl.type, $4.spec, $4.nspec); $3.nl[i]->decl.isconst = 1; $3.nl[i]->decl.isgeneric = 1; } @@ -288,6 +298,50 @@ attrs : /* empty */ {$$.nstr = 0; $$.str = NULL;} } ; +traitspec + : Twith traits {$$ = $2;} + | /* nothing */ {$$.nspec = 0;} + ; + +traits : traitvar { + $$.spec = NULL; + $$.nspec = 0; + lappend(&$$.spec, &$$.nspec, $1); + } + | traits listsep traitvar { + $$ = $1; + lappend(&$$.spec, &$$.nspec, $3); + } + ; + +traitvar + : traitlist generictype { + $$ = calloc(sizeof(Traitspec), 1); + $$->traits = $1.nl; + $$->ntraits = $1.nn; + $$->param = $2; + $$->aux = NULL; + } + | traitlist generictype Tret type { + $$ = calloc(sizeof(Traitspec), 1); + $$->traits = $1.nl; + $$->ntraits = $1.nn; + $$->param = $2; + $$->aux = $4; + } + ; + +traitlist + : name { + $$.nl = 0; + $$.nn = 0; + lappend(&$$.nl, &$$.nn, $1); + } + | traitlist listsep name { + lappend(&$$.nl, &$$.nn, $3); + } + ; + decllist: declbody { $$.loc = $1->loc; $$.nl = NULL; $$.nn = 0; lappend(&$$.nl, &$$.nn, $1); @@ -388,12 +442,22 @@ name : Tident {$$ = mkname($1->loc, $1->id);} ; implstmt - : Timpl name type optauxtypes { + : Timpl name type optauxtypes traitspec { + size_t i; + $$ = mkimplstmt($1->loc, $2, $3, $4.types, $4.ntypes, NULL, 0); $$->impl.isproto = 1; + setwith($3, $5.spec, $5.nspec); + for (i = 0; i < $4.ntypes; i++) + setwith($4.types[i], $5.spec, $5.nspec); } - | Timpl name type optauxtypes Tasn Tendln implbody Tendblk { - $$ = mkimplstmt($1->loc, $2, $3, $4.types, $4.ntypes, $7.nl, $7.nn); + | Timpl name type optauxtypes traitspec Tasn Tendln implbody Tendblk { + size_t i; + + $$ = mkimplstmt($1->loc, $2, $3, $4.types, $4.ntypes, $8.nl, $8.nn); + setwith($3, $5.spec, $5.nspec); + for (i = 0; i < $4.ntypes; i++) + setwith($4.types[i], $5.spec, $5.nspec); } ; @@ -411,25 +475,32 @@ implbody ; traitdef - : Ttrait Tident generictype optauxtypes { /* trait prototype */ + : Ttrait Tident generictype optauxtypes traitspec { /* trait prototype */ + size_t i; $$ = mktrait($1->loc, mkname($2->loc, $2->id), $3, $4.types, $4.ntypes, NULL, 0, 1); + setwith($3, $5.spec, $5.nspec); + for (i = 0; i < $4.ntypes; i++) + setwith($4.types[i], $5.spec, $5.nspec); } - | Ttrait Tident generictype optauxtypes Tasn traitbody Tendblk /* trait definition */ { + | Ttrait Tident generictype optauxtypes traitspec Tasn traitbody Tendblk /* trait definition */ { size_t i; $$ = mktrait($1->loc, mkname($2->loc, $2->id), $3, $4.types, $4.ntypes, - $6.nl, $6.nn, + $7.nl, $7.nn, 0); - for (i = 0; i < $6.nn; i++) { - $6.nl[i]->decl.trait = $$; - $6.nl[i]->decl.impls = mkht(tyhash, tyeq); - $6.nl[i]->decl.isgeneric = 1; + for (i = 0; i < $7.nn; i++) { + $7.nl[i]->decl.trait = $$; + $7.nl[i]->decl.impls = mkht(tyhash, tyeq); + $7.nl[i]->decl.isgeneric = 1; } + setwith($3, $5.spec, $5.nspec); + for (i = 0; i < $4.ntypes; i++) + setwith($4.types[i], $5.spec, $5.nspec); } ; @@ -452,14 +523,14 @@ traitbody ; -tydef : Ttype typeid {$$ = $2;} - | Ttype typeid Tasn type { +tydef : Ttype typeid traitspec {$$ = $2;} + | Ttype typeid traitspec Tasn type { $$ = $2; - if ($$.nparams == 0) { - $$.type = mktyname($2.loc, mkname($2.loc, $2.name), $4); - } else { - $$.type = mktygeneric($2.loc, mkname($2.loc, $2.name), $2.params, $2.nparams, $4); - } + if ($$.nparams == 0) + $$.type = mktyname($2.loc, mkname($2.loc, $2.name), $5); + else + $$.type = mktygeneric($2.loc, mkname($2.loc, $2.name), $2.params, $2.nparams, $5); + setwith($$.type, $3.spec, $3.nspec); } ; @@ -498,35 +569,17 @@ type : structdef generictype : Ttyparam {$$ = mktyparam($1->loc, $1->id);} - | Ttyparam Twith name { - $$ = mktyparam($1->loc, $1->id); - lappend(&$$->traits, &$$->ntraits, $3); - } - | Ttyparam Twith Toparen typaramlist Tcparen { - size_t i; - $$ = mktyparam($1->loc, $1->id); - for (i = 0; i < $4.nn; i++) - lappend(&$$->traits, &$$->ntraits, $4.nl[i]); - } - ; - -typaramlist - : name { - $$.nl = NULL; $$.nn = 0; - lappend(&$$.nl, &$$.nn, $1); - } - | typaramlist listsep name {lappend(&$$.nl, &$$.nn, $3);} ; compoundtype - : functype {$$ = $1;} - | type Tosqbrac Tcolon Tcsqbrac {$$ = mktyslice($2->loc, $1);} - | type Tosqbrac expr Tcsqbrac {$$ = mktyarray($2->loc, $1, $3);} - | type Tosqbrac Tellipsis Tcsqbrac {$$ = mktyarray($2->loc, $1, NULL);} - | name Toparen typelist Tcparen {$$ = mktyunres($1->loc, $1, $3.types, $3.ntypes);} - | type Tderef {$$ = mktyptr($2->loc, $1);} - | Tvoidlit {$$ = mktyunres($1->loc, mkname($1->loc, $1->id), NULL, 0);} - | name {$$ = mktyunres($1->loc, $1, NULL, 0);} + : functype {$$ = $1;} + | type Tosqbrac Tcolon Tcsqbrac {$$ = mktyslice($2->loc, $1);} + | type Tosqbrac expr Tcsqbrac {$$ = mktyarray($2->loc, $1, $3);} + | type Tosqbrac Tellipsis Tcsqbrac {$$ = mktyarray($2->loc, $1, NULL);} + | name Toparen typelist Tcparen {$$ = mktyunres($1->loc, $1, $3.types, $3.ntypes);} + | type Tderef {$$ = mktyptr($2->loc, $1);} + | Tvoidlit {$$ = mktyunres($1->loc, mkname($1->loc, $1->id), NULL, 0);} + | name {$$ = mktyunres($1->loc, $1, NULL, 0);} ; functype: Toparen funcsig Tcparen {$$ = $2;} @@ -826,11 +879,13 @@ obrace : Tobrace { } ; -funclit : obrace params Tendln blkbody Tcbrace { +funclit : obrace params traitspec Tendln blkbody Tcbrace { size_t i; Node *fn, *lit; - $$ = mkfunc($1->loc, $2.nl, $2.nn, mktyvar($3->loc), $4); + for (i = 0; i < $2.nn; i++) + setwith($2.nl[i]->decl.type, $3.spec, $3.nspec); + $$ = mkfunc($1->loc, $2.nl, $2.nn, mktyvar($4->loc), $5); fn = $$->lit.fnval; for (i = 0; i < nlbls[lbldepth]; i++) { lit = lbls[lbldepth][i]->expr.args[0]; @@ -840,11 +895,14 @@ funclit : obrace params Tendln blkbody Tcbrace { assert(lbldepth >= 0); lbldepth--; } - | obrace params Tret type Tendln blkbody Tcbrace { + | obrace params Tret type traitspec Tendln blkbody Tcbrace { size_t i; Node *fn, *lit; - $$ = mkfunc($1->loc, $2.nl, $2.nn, $4, $6); + setwith($4, $5.spec, $5.nspec); + for (i = 0; i < $2.nn; i++) + setwith($2.nl[i]->decl.type, $5.spec, $5.nspec); + $$ = mkfunc($1->loc, $2.nl, $2.nn, $4, $7); fn = $$->lit.fnval; for (i = 0; i < nlbls[lbldepth]; i++) { lit = lbls[lbldepth][i]->expr.args[0]; @@ -1101,6 +1159,48 @@ static void setattrs(Node *dcl, char **attrs, size_t nattrs) } } +static void setwith(Type *ty, Traitspec **ts, size_t nts) +{ + size_t i, j; + + if (!ty) + return; + for (i = 0; i < nts; i++) { + switch (ty->type) { + case Typaram: + if (tyeq(ty, ts[i]->param)) + lappend(&ty->spec, &ty->nspec, ts[i]); + + break; + case Tyname: + case Tyunres: + for (j = 0; j < ty->ngparam; j++) + setwith(ty->gparam[j], ts, nts); + for (j = 0; j < ty->narg; j++) + setwith(ty->arg[j], ts, nts); + break; + case Tystruct: + for (j = 0; j < ty->nmemb; j++) + setwith(ty->sdecls[j]->decl.type, ts, nts); + break; + case Tyunion: + for (j = 0; j < ty->nmemb; j++) + setwith(ty->udecls[j]->etype, ts, nts); + break; + case Typtr: + case Tyarray: + case Tyslice: + case Tyfunc: + case Tytuple: + for (j = 0; j < ty->nsub; j++) + setwith(ty->sub[j], ts, nts); + break; + default: + break; + } + } +} + static void installucons(Stab *st, Type *t) { Type *b; diff --git a/parse/infer.c b/parse/infer.c index 55628a5..69419d3 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -66,7 +66,6 @@ static Node **specializations; static size_t nspecializations; static Stab **specializationscope; static size_t nspecializationscope; -static Htab *seqbase; static Traitmap *traitmap; static void @@ -482,7 +481,7 @@ tyfreshen(Tysubst *subst, Type *orig) static void tyresolve(Type *t) { - size_t i; + size_t i, j; Trait *tr; if (t->resolved) @@ -526,13 +525,15 @@ tyresolve(Type *t) break; } - for (i = 0; i < t->ntraits; i++) { - tr = gettrait(curstab(), t->traits[i]); - if (!tr) - lfatal(t->loc, "trait %s does not exist", ctxstr(t->traits[i])); - if (!t->trneed) - t->trneed = mkbs(); - bsput(t->trneed, tr->uid); + for (i = 0; i < t->nspec; i++) { + for (j = 0; j < t->spec[i]->ntraits; j++) { + tr = gettrait(curstab(), t->spec[i]->traits[j]); + if (!tr) + lfatal(t->loc, "trait %s does not exist", ctxstr(t->spec[i]->traits[j])); + if (!t->trneed) + t->trneed = mkbs(); + bsput(t->trneed, tr->uid); + } } for (i = 0; i < t->nsub; i++) { @@ -2898,7 +2899,6 @@ void infer(void) { delayed = mkht(tyhash, tyeq); - seqbase = mkht(tyhash, tyeq); loaduses(); initimpl(); diff --git a/parse/parse.h b/parse/parse.h index 0bae957..c8db0f5 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -2,6 +2,7 @@ typedef struct Srcloc Srcloc; typedef struct Tysubst Tysubst; +typedef struct Traitspec Traitspec; typedef struct Tok Tok; typedef struct Node Node; @@ -118,6 +119,13 @@ struct Tyenv { Htab *tab; }; +struct Traitspec { + Node **traits; + size_t ntraits; + Type *param; + Type *aux; +}; + struct Type { Ty type; uint32_t tid; @@ -125,8 +133,10 @@ struct Type { Vis vis; - Node **traits; /* trait list */ - size_t ntraits; /* trait list size */ + Traitspec **spec; + size_t nspec; + //Node **traits; /* trait list */ + //size_t ntraits; /* trait list size */ Type **gparam; /* Tygeneric: type parameters that match the type args */ size_t ngparam; /* Tygeneric: count of type parameters */ @@ -350,6 +360,7 @@ struct Node { }; /* globals */ +extern Htab *seqbase; extern Srcloc curloc; extern char *filename; extern Tok *curtok; /* the last token we tokenized */ diff --git a/parse/type.c b/parse/type.c index c31fbbe..ab033cb 100644 --- a/parse/type.c +++ b/parse/type.c @@ -24,6 +24,7 @@ size_t ntraittab; Node **impltab; size_t nimpltab; Htab *eqcache; +Htab *seqbase; struct Typair { uint32_t atid; @@ -1083,6 +1084,7 @@ tyinit(Stab *st) Type *ty; Trait *tr; + seqbase = mkht(tyhash, tyeq); eqcache = mkht(typairhash, typaireq); tydeduptab = mkht(tyhash, tystricteq); /* this must be done after all the types are created, otherwise we will diff --git a/test/emptytrait.myr b/test/emptytrait.myr index e3c3c91..f4a1f38 100644 --- a/test/emptytrait.myr +++ b/test/emptytrait.myr @@ -6,7 +6,7 @@ trait fooable @a = impl fooable int = ;; -generic foo = {x : @a::fooable +generic foo = {x : @a::fooable @a -> x } diff --git a/test/generictype.myr b/test/generictype.myr index 68a6508..3e62af4 100644 --- a/test/generictype.myr +++ b/test/generictype.myr @@ -1,8 +1,8 @@ use std /* checks that parameterized types work. exits with 0. */ -type option(@a::(integral,numeric)) = union - `Some @a::(integral,numeric) +type option(@a) :: integral,numeric @a = union + `Some @a `None ;; diff --git a/test/genericval.myr b/test/genericval.myr index ca7a925..fbe2038 100644 --- a/test/genericval.myr +++ b/test/genericval.myr @@ -1,6 +1,6 @@ use std -generic Foo : @a::(integral,numeric) = 42 +generic Foo : @a = 42 :: integral,numeric @a const main = { std.exit(Foo) diff --git a/test/gtrait.myr b/test/gtrait.myr index 5131ccc..9d84b45 100644 --- a/test/gtrait.myr +++ b/test/gtrait.myr @@ -4,7 +4,7 @@ trait comparable @a = cmp : (a : @a, b : @a -> std.order) ;; -impl comparable @a::numeric = +impl comparable @a :: numeric @a = cmp = {a, b -> std.numcmp(a, b) } diff --git a/test/recgeneric.myr b/test/recgeneric.myr index 28b9fab..ac5f13b 100644 --- a/test/recgeneric.myr +++ b/test/recgeneric.myr @@ -1,6 +1,6 @@ use std -type o(@a::integral) = union +type o(@a) :: integral @a = union `S @a ;; diff --git a/test/trait-builtin.myr b/test/trait-builtin.myr index 93c5bda..cdb8735 100644 --- a/test/trait-builtin.myr +++ b/test/trait-builtin.myr @@ -7,7 +7,7 @@ comparing to 42 wouldn't work. exits with 42. */ -generic max = {a:@a::numeric, b:@a::numeric +generic max = {a : @a, b : @a :: numeric @a if a > b -> a else @@ -15,7 +15,7 @@ generic max = {a:@a::numeric, b:@a::numeric ;; } -generic intlike_is42 = {a : @a::(numeric,integral) +generic intlike_is42 = {a : @a :: numeric,integral @a -> a == 42 } diff --git a/test/traitimpl.myr b/test/traitimpl.myr index e0d1eca..c3293c1 100644 --- a/test/traitimpl.myr +++ b/test/traitimpl.myr @@ -22,7 +22,7 @@ impl frobable byte[:] = } ;; -generic foo = {x : @a::frobable +generic foo = {x : @a :: frobable @a -> frob(x) } |