ref: 68b18a7fba8313ad5b1d8b4c6be61e3b8b126304
parent: c158da43321893956e4be405ed04af37f86259fa
author: Ori Bernstein <[email protected]>
date: Mon Feb 10 18:26:32 EST 2014
Do some sanitization on traits. - Remove tctest: all tests now take a boolean. - Rename traits to more sensible names: tcnum => numeric tcint => integral tcfloat => floating tcidx => indexable tcslice => sliceable - Remove duplicate trait setting. We were setting traits twice in some places, adding ones that didn't belong, which was making pointers look indexable.
--- a/libstd/bitset.myr
+++ b/libstd/bitset.myr
@@ -13,9 +13,9 @@
const bsdup : (bs : bitset# -> bitset#)
const bsfree : (bs : bitset# -> void)
- generic bsput : (bs : bitset#, v : @a::(tcint,tctest,tcnum) -> void)
- generic bsdel : (bs : bitset#, v : @a::(tcint,tctest,tcnum) -> void)
- generic bshas : (bs : bitset#, v : @a::(tcint,tctest,tcnum) -> bool)
+ 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)
--- a/libstd/chartype.myr
+++ b/libstd/chartype.myr
@@ -22,7 +22,7 @@
const toupper : (c : char -> char)
const totitle : (c : char -> char)
- generic charval : (c : char, base : int -> @a::(tcint,tcnum,tctest))
+ generic charval : (c : char, base : int -> @a::(integral,numeric))
;;
/*
@@ -1209,18 +1209,18 @@
-> c
}
-generic charval = {c, base -> @a::(tcnum,tcint,tctest)
+generic charval = {c, base -> @a::(numeric,integral)
var v = -1
if c >= '0' && c <= '9'
- v = (c - '0') castto(@a::(tcint,tcnum,tctest))
+ v = (c - '0') castto(@a::(integral,numeric))
elif c >= 'a' && c <= 'z'
- v = (c - 'a' + 10) castto(@a::(tcint,tcnum,tctest))
+ v = (c - 'a' + 10) castto(@a::(integral,numeric))
elif c >= 'A' && c <= 'Z'
- v = (c - 'A' + 10) castto(@a::(tcint,tcnum,tctest))
+ v = (c - 'A' + 10) castto(@a::(integral,numeric))
;;
- if v < 0 || v > (base castto(@a::(tcint,tcnum,tctest)))
+ if v < 0 || v > (base castto(@a::(integral,numeric)))
-> -1
;;
-> v
--- a/libstd/endian.myr
+++ b/libstd/endian.myr
@@ -5,7 +5,7 @@
/* FIXME: we only support little endian platforms right now,
so we assume a little endian machine. FIX THIS. */
-generic hosttonet = {v : @a::(tcint,tcnum,tctest)
+generic hosttonet = {v : @a::(integral,numeric)
var i
var ret
@@ -18,7 +18,7 @@
-> ret
}
-generic nettohost = {v : @a::(tcint,tcnum,tctest)
+generic nettohost = {v : @a::(integral,numeric)
var i
var ret
--- a/libstd/extremum.myr
+++ b/libstd/extremum.myr
@@ -1,6 +1,6 @@
pkg std =
- generic min : (a : @a::tcnum, b : @a::tcnum -> @a::tcnum)
- generic max : (a : @a::tcnum, b : @a::tcnum -> @a::tcnum)
+ generic min : (a : @a::numeric, b : @a::numeric -> @a::numeric)
+ generic max : (a : @a::numeric, b : @a::numeric -> @a::numeric)
;;
generic min = {a, b
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -85,7 +85,7 @@
const digitchars = [
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
]
-generic intfmt = {buf : byte[:], bits : @a::(tcint,tctest,tcnum), base, signed
+generic intfmt = {buf : byte[:], bits : @a::(integral,numeric), base, signed
var isneg
var val
var b : char[32]
@@ -142,7 +142,7 @@
var f_val : float64, F_val : float32
n = 0
- while fmt.len
+ while fmt.len != 0
(c, fmt) = striter(fmt)
if c == '%'
base = 10
--- a/libstd/hashfuncs.myr
+++ b/libstd/hashfuncs.myr
@@ -8,8 +8,8 @@
generic ptrhash : (p : @a# -> uint32)
generic ptreq : (a : @a#, b : @a# -> bool)
- generic inthash : (v : @a::(tcint,tcnum,tctest) -> uint32)
- generic inteq : (a : @a::(tcint,tcnum,tctest), b : @a::(tcint,tcnum,tctest) -> bool)
+ generic inthash : (v : @a::(integral,numeric) -> uint32)
+ generic inteq : (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
;;
/* Supremely simple djb hash. */
--- a/libstd/intparse.myr
+++ b/libstd/intparse.myr
@@ -7,8 +7,8 @@
use "utf.use"
pkg std =
- generic intparsebase : (s : byte[:], base : int -> option(@a::(tcint,tcnum,tctest)))
- generic intparse : (s : byte[:] -> option(@a::(tcint,tcnum,tctest)))
+ generic intparsebase : (s : byte[:], base : int -> option(@a::(integral,numeric)))
+ generic intparse : (s : byte[:] -> option(@a::(integral,numeric)))
;;
generic intparse = {s
@@ -55,7 +55,7 @@
;;
cv = charval(c, base)
if cv >= 0
- v *= (base castto(@a::(tcint,tcnum,tctest)))
+ v *= (base castto(@a::(integral,numeric)))
v += cv
else
-> `None
--- a/libstd/rand.myr
+++ b/libstd/rand.myr
@@ -49,8 +49,8 @@
type rng
const mksrng : (seed : uint32 -> rng#)
- generic rand : (rng : rng#, lo : @a::(tcnum,tctest,tcint), hi : @a::(tcnum,tctest,tcint) -> @a::(tcnum,tctest,tcint))
- generic randN : (rng : rng# -> @a::(tcnum,tctest,tcint))
+ generic rand : (rng : rng#, lo : @a::(numeric,integral), hi : @a::(numeric,integral) -> @a::(numeric,integral))
+ generic randN : (rng : rng# -> @a::(numeric,integral))
const rand32 : (rng : rng# -> uint32)
;;
@@ -85,7 +85,7 @@
nonempty, and the difference between hi and lo must be
less then 2^(type_bits - 1)
*/
-generic rand = {rng, lo, hi -> @a::(tcint,tcnum,tctest)
+generic rand = {rng, lo, hi -> @a::(integral,numeric)
var span, lim
var maxrand
var val
@@ -111,13 +111,13 @@
random number generator `rng`. The returned value
may be negative, if the type is signed.
*/
-generic randN = {rng -> @a::(tcint,tcnum,tctest)
+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::(tcint,tcnum,tctest))
+ val |= rand32(rng) castto(@a::(integral,numeric))
;;
-> val
}
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -424,7 +424,7 @@
if seglen > 63
-> false
;;
- if host[i] & 0x80
+ if host[i] & 0x80 != 0
-> false
;;
;;
--- a/libstd/units.myr
+++ b/libstd/units.myr
@@ -1,11 +1,11 @@
pkg std =
/* JEDEC 100B.1 memory sizes */
- generic KiB : @a::(tcint,tcnum,tctest) = 1024
- generic MiB : @a::(tcint,tcnum,tctest) = KiB*1024
- generic GiB : @a::(tcint,tcnum,tctest) = MiB*1024
- generic TiB : @a::(tcint,tcnum,tctest) = GiB*1024
- generic PiB : @a::(tcint,tcnum,tctest) = TiB*1024
- generic EiB : @a::(tcint,tcnum,tctest) = PiB*1024
- generic ZiB : @a::(tcint,tcnum,tctest) = EiB*1024
- generic YiB : @a::(tcint,tcnum,tctest) = ZiB*1024
+ 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/parse/gram.y
+++ b/parse/gram.y
@@ -532,7 +532,7 @@
cmpop : Teq | Tgt | Tlt | Tge | Tle | Tne ;
-castexpr: unionexpr Tcast Toparen type Tcparen
+castexpr: castexpr Tcast Toparen type Tcparen
{$$ = mkexpr($1->line, Ocast, $1, NULL);
$$->expr.type = $4;}
| unionexpr
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1369,7 +1369,7 @@
infernode(st, n->ifstmt.cond, NULL, sawret);
infernode(st, n->ifstmt.iftrue, ret, sawret);
infernode(st, n->ifstmt.iffalse, ret, sawret);
- constrain(st, n, type(st, n->ifstmt.cond), traittab[Tctest]);
+ unify(st, n, type(st, n->ifstmt.cond), mktype(n->line, Tybool));
break;
case Nloopstmt:
infernode(st, n->loopstmt.init, ret, sawret);
@@ -1376,7 +1376,7 @@
infernode(st, n->loopstmt.cond, NULL, sawret);
infernode(st, n->loopstmt.step, ret, sawret);
infernode(st, n->loopstmt.body, ret, sawret);
- constrain(st, n, type(st, n->loopstmt.cond), traittab[Tctest]);
+ unify(st, n, type(st, n->loopstmt.cond), mktype(n->line, Tybool));
break;
case Niterstmt:
bound = NULL;
@@ -1514,7 +1514,6 @@
if (!strcmp(namestr(memb), "len")) {
constrain(st, n, type(st, n), traittab[Tcnum]);
constrain(st, n, type(st, n), traittab[Tcint]);
- constrain(st, n, type(st, n), traittab[Tctest]);
found = 1;
}
/* otherwise, we search aggregate types for the member, and unify
--- a/parse/trait.def
+++ b/parse/trait.def
@@ -1,8 +1,7 @@
/* Definitions of built in constraints */
-Tc(Tcnum, "tcnum") /* arith ops */
-Tc(Tcint, "tcint") /* behaves like an int, defaults to int as fallback */
-Tc(Tcfloat, "tcfloat") /* behaves like a float, defaults to float as fallback */
-Tc(Tctest, "tctest") /* if condition */
-Tc(Tcidx, "tcidx") /* indexable */
-Tc(Tcslice, "tcslice") /* sliceable */
-Tc(Ncstr, "")
+Tc(Tcnum, "numeric") /* arith ops */
+Tc(Tcint, "integral") /* behaves like an int, defaults to int as fallback */
+Tc(Tcfloat, "floating") /* behaves like a float, defaults to float as fallback */
+Tc(Tcidx, "indexable") /* indexable */
+Tc(Tcslice, "sliceable") /* sliceable */
+Tc(Ncstr, "") /* constraint count */
--- a/parse/type.c
+++ b/parse/type.c
@@ -648,51 +648,35 @@
#include "trait.def"
#undef Tc
- /* bool :: tctest */
- traits[Tybool][0] = traittab[Tctest];
-
+ /* char::(numeric,integral) */
traits[Tychar][0] = traittab[Tcnum];
traits[Tychar][1] = traittab[Tcint];
- traits[Tychar][2] = traittab[Tctest];
traits[Tybyte][0] = traittab[Tcnum];
traits[Tybyte][1] = traittab[Tcint];
- traits[Tybyte][2] = traittab[Tctest];
- /* <integer types> :: tcnum, tcint, tctest */
+ /* <integer types>::(numeric,integral) */
for (i = Tyint8; i < Tyfloat32; i++) {
traits[i][0] = traittab[Tcnum];
traits[i][1] = traittab[Tcint];
- traits[i][2] = traittab[Tctest];
}
- /* <floats> :: tcnum */
+ /* <floats>::(numeric,floating) */
traits[Tyfloat32][0] = traittab[Tcnum];
traits[Tyfloat32][1] = traittab[Tcfloat];
traits[Tyfloat64][0] = traittab[Tcnum];
traits[Tyfloat64][1] = traittab[Tcfloat];
- /* @a* :: tctest[0] = tcslice */
- traits[Typtr][0] = traittab[Tctest];
- traits[Typtr][1] = traittab[Tcslice];
+ /* @a*::(sliceable) */
+ traits[Typtr][0] = traittab[Tcslice];
- /* @a[,] :: tctest[0] = tcslice[0] = tcidx */
- traits[Tyslice][0] = traittab[Tctest];
- traits[Tyslice][1] = traittab[Tcslice];
- traits[Tyslice][2] = traittab[Tcidx];
+ /* @a[:]::(indexable,sliceable) */
+ traits[Tyslice][0] = traittab[Tcslice];
+ traits[Tyslice][1] = traittab[Tcidx];
- /* array :: tcidx, tcslice */
+ /* @a[SZ]::(indexable,sliceable) */
traits[Tyarray][0] = traittab[Tcidx];
traits[Tyarray][1] = traittab[Tcslice];
-
- /* ptr :: tcslice, tctest */
- traits[Typtr][0] = traittab[Tcidx];
- traits[Typtr][1] = traittab[Tctest];
-
- /* slice :: tcidx, tcslice, tctest */
- traits[Tyslice][0] = traittab[Tcidx];
- traits[Tyslice][1] = traittab[Tcslice];
- traits[Tyslice][1] = traittab[Tctest];
/* Definining and registering the types has to go after we define the
* constraints, otherwise they will have no constraints set on them. */
--- a/test/generictype.myr
+++ b/test/generictype.myr
@@ -2,7 +2,7 @@
/* checks that parameterized types work. exits with 0. */
type option(@a) = union
- `Some @a::(tcint,tcnum,tctest)
+ `Some @a::(integral,numeric)
`None
;;
--- a/test/genericval.myr
+++ b/test/genericval.myr
@@ -1,6 +1,6 @@
use std
-generic Foo : @a::(tctest,tcint,tcnum) = 42
+generic Foo : @a::(integral,numeric) = 42
const main = {
std.exit(Foo)
--- a/test/trait-builtin.myr
+++ b/test/trait-builtin.myr
@@ -1,6 +1,6 @@
use std
/* checks that generic types with traits are compiled correctly.
-without the 'tcnum' trait on '@a', the '>' operator would not work
+without the 'numeric' trait on '@a', the '>' operator would not work
within max. without the 'tctest' trait on '@a' in intlike_is42,
comparing to 42 wouldn't work.
@@ -7,7 +7,7 @@
exits with 42.
*/
-generic max = {a:@a::tcnum, b:@a::tcnum
+generic max = {a:@a::numeric, b:@a::numeric
if a > b
-> a
else
@@ -15,7 +15,7 @@
;;
}
-generic intlike_is42 = {a : @a::(tcnum,tctest,tcint)
+generic intlike_is42 = {a : @a::(numeric,integral)
-> a == 42
}