shithub: mc

Download patch

ref: 07c78ed9c77feed62b7f306049ed3c90d4753024
parent: 543b764108c7bb18759d7db4058636f98972cbfb
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Dec 16 15:09:44 EST 2015

Add in builtin iterable trait.

--- a/parse/trait.def
+++ b/parse/trait.def
@@ -1,7 +1,8 @@
 /* Definitions of built in constraints */
-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(Tcfunc,      "function")     /* behaves like a function */
+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(Tcfunc,	"function")     /* behaves like a function */
+Tc(Tciter,	"iterable")     /* behaves like a function */
--- a/parse/type.c
+++ b/parse/type.c
@@ -854,18 +854,69 @@
 	return p - buf;
 }
 
+void iterableinit(Stab *st, Trait *tr)
+{
+	Node *func, *arg, **args;
+	Type *ty;
+	size_t nargs;
+
+	/* trait iter @a -> @b = ... */
+	tr->param = mktyparam(Zloc, "a");
+	tr->aux = malloc(sizeof(Type*));
+	tr->aux[0] = mktyparam(Zloc, "b");
+	tr->naux = 1;
+
+	/* __iternext__ : (it : @a#, outval : @b# -> bool) */
+	args = NULL;
+	nargs = 0;
+	arg = mkdecl(Zloc, mkname(Zloc, "iter"), mktyptr(Zloc, mktyparam(Zloc, "a")));
+	lappend(&args, &nargs, arg);
+	arg = mkdecl(Zloc, mkname(Zloc, "ret"), mktyptr(Zloc, mktyparam(Zloc, "b")));
+	lappend(&args, &nargs, arg);
+	ty = mktyfunc(Zloc, args, nargs, mktype(Zloc, Tybool));
+
+	func = mkdecl(Zloc, mkname(Zloc, "__iternext__"), ty);
+	func->decl.trait = tr;
+	func->decl.impls = mkht(tyhash, tyeq); 
+	func->decl.isgeneric = 1;
+
+	lappend(&tr->funcs, &tr->nfuncs, func);
+	putdcl(st, func);
+
+	/* __iterfin__ : (it : @a#, outval : @b# -> void) */
+	args = NULL;
+	nargs = 0;
+	arg = mkdecl(Zloc, mkname(Zloc, "iter"), mktyptr(Zloc, mktyparam(Zloc, "a")));
+	lappend(&args, &nargs, arg);
+	arg = mkdecl(Zloc, mkname(Zloc, "val"), mktyptr(Zloc, mktyparam(Zloc, "b")));
+	lappend(&args, &nargs, arg);
+	ty = mktyfunc(Zloc, args, nargs, mktype(Zloc, Tyvoid));
+
+	func = mkdecl(Zloc, mkname(Zloc, "__iterfin__"), ty);
+	func->decl.trait = tr;
+	func->decl.impls = mkht(tyhash, tyeq); 
+	func->decl.isgeneric = 1;
+
+	lappend(&tr->funcs, &tr->nfuncs, func);
+	putdcl(st, func);
+}
+
 void tyinit(Stab *st)
 {
 	int i;
 	Type *ty;
+	Trait *tr;
 
 	/* this must be done after all the types are created, otherwise we will
 	 * clobber the memoized bunch of types with the type params. */
-#define Tc(c, n) mktrait(Zloc, mkname(Zloc, n), NULL, \
-			 NULL, 0, \
-			 NULL, 0, \
-			 NULL, 0, \
-			 0);
+#define Tc(c, n) \
+	tr = mktrait(Zloc, \
+		mkname(Zloc, n), NULL, \
+		NULL, 0, \
+		NULL, 0, \
+		NULL, 0, \
+		0); \
+	puttrait(st, tr->name, tr);
 #include "trait.def"
 #undef Tc
 
@@ -913,4 +964,11 @@
 	}
 #include "types.def"
 #undef Ty
+
+	/*
+	 * finally, initializing the builtin traits for use in user code
+	 * comes last, since this needs both the types and the traits set up
+	 */
+	iterableinit(st, traittab[Tciter]);
+
 }