shithub: mc

Download patch

ref: 91ad7689b0645c5bf0b860412c96d10016d80293
parent: f0f1654937b0bd8944189c15c76169ca02ff88e9
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Feb 6 10:41:43 EST 2016

Work towards generic iterables.

	Keep track of base types.

--- a/lib/std/htab.myr
+++ b/lib/std/htab.myr
@@ -25,6 +25,13 @@
 	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[:])
+
+	generic htbykeyvals	: (ht : htab(@k, @v)# -> htkviter(@k, @v))
+	impl iterable htkviter(@k, @v) -> (@k, @v)
+	type htkviter(@k, @v) = struct
+		ht	: std.htab(@k, @v)#
+		idx	: size
+	;;
 ;;
 
 const Initsz = 32
@@ -202,3 +209,29 @@
 	-> keys
 }
 
+generic htbykeyvals = {ht
+	-> [.ht = ht, .idx = 0]
+}
+
+impl iterable htkviter(@k, @v) -> (@k, @v) =
+	__iternext__ = {itp, valp
+		var i, ht
+
+		ht = itp.ht
+		for i = itp.idx; i < ht.keys.len; i++
+			if ht.hashes[i] != 0 && !ht.dead[i]
+				break
+			;;
+		;;
+		itp.idx = i
+		if i < ht.hashes.len
+			valp# = (ht.keys[i], ht.vals[i])
+			-> true
+		else
+			-> false
+		;;
+	}
+
+	__iterfin__ = {itp, valp
+	}
+;;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -359,10 +359,10 @@
 	tybind(st, t);
 	if (!subst) {
 		subst = mksubst();
-		t = tyspecialize(t, subst, st->delayed);
+		t = tyspecialize(t, subst, st->delayed, st->seqbase);
 		substfree(subst);
 	} else {
-		t = tyspecialize(t, subst, st->delayed);
+		t = tyspecialize(t, subst, st->delayed, st->seqbase);
 	}
 	tyunbind(st, t);
 	if (debugopt['u']) {
@@ -1695,7 +1695,7 @@
 		substput(subst, t->param, n->impl.type);
 		for (j = 0; j < t->naux; j++)
 			substput(subst, t->aux[j], n->impl.aux[j]);
-		ty = tyspecialize(type(st, proto), subst, st->delayed);
+		ty = tyspecialize(type(st, proto), subst, st->delayed, NULL);
 		substfree(subst);
 
 		inferdecl(st, dcl);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -628,7 +628,7 @@
 void substpush(Tysubst *subst);
 void substpop(Tysubst *subst);
 Node *specializedcl(Node *n, Type *to, Node **name);
-Type *tyspecialize(Type *t, Tysubst *tymap, Htab *delayed);
+Type *tyspecialize(Type *t, Tysubst *tymap, Htab *delayed, Htab *tybase);
 Node *genericname(Node *n, Type *t);
 void geninit(Node *file);
 
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -82,9 +82,10 @@
  * parameters (type schemes in most literature)
  * replaced with type variables that we can unify
  * against */
-Type *tyspecialize(Type *orig, Tysubst *tsmap, Htab *delayed)
+Type *tyspecialize(Type *orig, Tysubst *tsmap, Htab *delayed, Htab *trbase)
 {
-	Type *t, *ret, *tmp, **arg, *var;
+	Type *t, *ret, *tmp, *var, *base;
+	Type **arg;
 	size_t i, narg;
 
 	t = tysearch(orig);
@@ -108,8 +109,8 @@
 				substput(tsmap, t->gparam[i], orig->arg[i]);
 		}
 		for (i = 0; i < t->ngparam; i++)
-			lappend(&arg, &narg, tyspecialize(t->gparam[i], tsmap, delayed));
-		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
+			lappend(&arg, &narg, tyspecialize(t->gparam[i], tsmap, delayed, trbase));
+		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed, trbase));
 		if (orig->type == Tyunres)
 			substpop(tsmap);
 		ret->issynth = 1;
@@ -123,11 +124,15 @@
 		var = mktyvar(t->loc);
 		substput(tsmap, t, var);
 		for (i = 0; i < t->narg; i++)
-			lappend(&arg, &narg, tyspecialize(t->arg[i], tsmap, delayed));
-		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
+			lappend(&arg, &narg, tyspecialize(t->arg[i], tsmap, delayed, trbase));
+		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed, trbase));
 		ret->traits = bsdup(t->traits);
 		ret->arg = arg;
 		ret->narg = narg;
+		if (trbase && hthas(trbase, orig) && !hthas(trbase, ret)) {
+			base = htget(trbase, orig);
+			htput(trbase, ret, tyspecialize(base, tsmap, delayed, trbase));
+		}
 		tytab[var->tid] = ret;
 		break;
 	case Tystruct:
@@ -144,7 +149,7 @@
 		for (i = 0; i < t->nmemb; i++) {
 			tmp = NULL;
 			if (ret->udecls[i]->etype)
-				tmp = tyspecialize(t->udecls[i]->etype, tsmap, delayed);
+				tmp = tyspecialize(t->udecls[i]->etype, tsmap, delayed, trbase);
 			ret->udecls[i] = mkucon(t->loc, t->udecls[i]->name, ret, tmp);
 			ret->udecls[i]->utype = ret;
 			ret->udecls[i]->id = i;
@@ -155,7 +160,7 @@
 		ret = t;
 		if (delayed && hthas(delayed, t)) {
 			tmp = htget(delayed, t);
-			htput(delayed, ret, tyspecialize(tmp, tsmap, delayed));
+			htput(delayed, ret, tyspecialize(tmp, tsmap, delayed, trbase));
 		} 
 		break;
 	default:
@@ -163,7 +168,7 @@
 			ret = tydup(t);
 			substput(tsmap, t, ret);
 			for (i = 0; i < t->nsub; i++)
-				ret->sub[i] = tyspecialize(t->sub[i], tsmap, delayed);
+				ret->sub[i] = tyspecialize(t->sub[i], tsmap, delayed, trbase);
 		} else {
 			ret = t;
 		}
@@ -178,7 +183,7 @@
 static Type *tysubst(Type *t, Tysubst *tsmap)
 {
 	if (hasparams(t))
-		return tyspecialize(t, tsmap, NULL);
+		return tyspecialize(t, tsmap, NULL, NULL);
 	else
 		return t;
 }