summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-12-16 20:09:44 -0800
committerOri Bernstein <ori@eigenstate.org>2015-12-16 20:50:19 -0800
commit07c78ed9c77feed62b7f306049ed3c90d4753024 (patch)
tree63e5feb6cb00a0af68de9ce3f71b01dda0eb682c
parent543b764108c7bb18759d7db4058636f98972cbfb (diff)
downloadmc-07c78ed9c77feed62b7f306049ed3c90d4753024.tar.gz
Add in builtin iterable trait.
-rw-r--r--parse/trait.def13
-rw-r--r--parse/type.c68
2 files changed, 70 insertions, 11 deletions
diff --git a/parse/trait.def b/parse/trait.def
index 627ca9c..eacf685 100644
--- 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 */
diff --git a/parse/type.c b/parse/type.c
index 617511a..88b4a30 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -854,18 +854,69 @@ size_t tyidfmt(char *buf, size_t sz, Type *ty)
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 @@ void tyinit(Stab *st)
}
#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]);
+
}