summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2012-10-21 17:17:12 -0400
committerOri Bernstein <ori@eigenstate.org>2012-10-21 17:17:12 -0400
commita3f00eee7003eae5aaf6c91fd674915e098b8b18 (patch)
treebf0c97fa0ed0f10262a2b915706445f87704f0a2
parent90ed95ded198b9c57dfb6bf172cfd975da73e66f (diff)
downloadmc-a3f00eee7003eae5aaf6c91fd674915e098b8b18.tar.gz
Don't specialize generics into other generics.
-rw-r--r--libstd/Makefile1
-rw-r--r--libstd/alloc.myr27
-rw-r--r--libstd/extremum.myr20
-rw-r--r--libstd/fmt.myr9
-rw-r--r--parse/infer.c4
5 files changed, 45 insertions, 16 deletions
diff --git a/libstd/Makefile b/libstd/Makefile
index c321e2a..47e3987 100644
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -3,6 +3,7 @@ MYRSRC= \
alloc.myr \
chartype.myr \
die.myr \
+ extremum.myr \
fmt.myr \
option.myr \
rand.myr \
diff --git a/libstd/alloc.myr b/libstd/alloc.myr
index 30421f6..21c337e 100644
--- a/libstd/alloc.myr
+++ b/libstd/alloc.myr
@@ -1,13 +1,15 @@
use "die.use"
use "sys.use"
use "types.use"
+use "extremum.use"
pkg std =
generic alloc : ( -> @a*)
generic free : (v:@a* -> void)
- generic mkslice : (len : size -> @a[:])
- generic freeslice: (sl : @a[:] -> void)
+ generic slalloc : (len : size -> @a[:])
+ generic slfree : (sl : @a[:] -> void)
+ generic slgrow : (sl : @a[:], len : size -> @a[:])
const bytealloc : (sz:size -> byte*)
const bytefree : (m:byte*, sz:size -> void)
@@ -35,8 +37,8 @@ type bucket = struct
;;
type slab = struct
- head : byte* /* head of virtual addresses, so we don't leak address space */
- next : slab* /* the next slab on the chain */
+ 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 */
;;
@@ -53,17 +55,30 @@ generic free = {v:@a* -> void
bytefree(v castto(byte*), sizeof(@a))
}
-generic mkslice = {len
+generic slalloc = {len
var p
p = bytealloc(len*sizeof(@a)) castto(@a*)
-> p[0:len]
}
-generic freeslice = {sl
+generic slfree = {sl
-> bytefree(sl castto(byte*), sl.len * sizeof(@a))
}
+generic slgrow = {sl, len
+ var i
+ var n
+ var new
+
+ new = slalloc(len)
+ n = min(len, sl.len)
+ for i = 0; i < n; i++
+ new[i] = sl[i]
+ ;;
+ -> new
+}
+
const bytealloc = {sz
var i
var bkt
diff --git a/libstd/extremum.myr b/libstd/extremum.myr
new file mode 100644
index 0000000..5d63acd
--- /dev/null
+++ b/libstd/extremum.myr
@@ -0,0 +1,20 @@
+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, b
+ if a < b
+ -> a
+ else
+ -> b
+ ;;
+}
+
+generic max = {a, b
+ if a > b
+ -> a
+ else
+ -> b
+ ;;
+}
diff --git a/libstd/fmt.myr b/libstd/fmt.myr
index d257d0a..0ab8056 100644
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -3,6 +3,7 @@ use "sys.use"
use "types.use"
use "utf.use"
use "varargs.use"
+use "extremum.use"
pkg std =
const bfmt : (buf : byte[:], fmt : byte[:], args:... -> size)
@@ -125,11 +126,3 @@ const intfmt = {buf, val, base
-> n
}
-const min = {a : size, b : size
- if a < b
- -> a
- else
- -> b
- ;;
-}
-
diff --git a/parse/infer.c b/parse/infer.c
index 0e6ea40..055a7eb 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -689,7 +689,7 @@ static void checkns(Inferstate *st, Node *n, Node **ret)
settype(st, var, tyfreshen(st, s->decl.type));
else
settype(st, var, s->decl.type);
- if (s->decl.isgeneric) {
+ if (s->decl.isgeneric && !st->ingeneric) {
lappend(&st->specializationscope, &st->nspecializationscope, curstab());
lappend(&st->specializations, &st->nspecializations, var);
lappend(&st->genericdecls, &st->ngenericdecls, s);
@@ -913,7 +913,7 @@ static void inferexpr(Inferstate *st, Node *n, Type *ret, int *sawret)
t = s->decl.type;
settype(st, n, t);
n->expr.did = s->decl.did;
- if (s->decl.isgeneric) {
+ if (s->decl.isgeneric && !st->ingeneric) {
lappend(&st->specializationscope, &st->nspecializationscope, curstab());
lappend(&st->specializations, &st->nspecializations, n);
lappend(&st->genericdecls, &st->ngenericdecls, s);