summaryrefslogtreecommitdiff
path: root/parse/type.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2018-01-20 13:07:34 -0500
committerOri Bernstein <ori@eigenstate.org>2018-01-21 14:29:38 -0800
commit720cc29f19477550800adf5539837fec15296bbc (patch)
tree34efa93381a753b3b0c06090b84116f7cc9e7967 /parse/type.c
parentd8b909066008d478a8abd30cb329c88d44194730 (diff)
downloadmc-720cc29f19477550800adf5539837fec15296bbc.tar.gz
Cheap enums.
Diffstat (limited to 'parse/type.c')
-rw-r--r--parse/type.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/parse/type.c b/parse/type.c
index c31fbbe..8674d8c 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -44,7 +44,37 @@ char stackness[] = {
int
isstacktype(Type *t)
{
- return stackness[tybase(t)->type];
+ t = tybase(t);
+ if (t->type == Tyunion)
+ return !isenum(t);
+ return stackness[t->type];
+}
+
+int
+isenum(Type *t)
+{
+ size_t i;
+ char isenum;
+
+ assert(t->type == Tyunion);
+
+ /* t->isenum is lazily set:
+ * a value of 0 means that it was not computed,
+ * a value of 1 means that the type is an enum
+ * (i.e., it only has nullary constructors)
+ * a value of 2 means that the type is not an enum
+ */
+ if (t->isenum == 0) {
+ /* initialize it */
+ isenum = 1;
+ for (i = 0; i < t->nmemb; i++)
+ if (t->udecls[i]->etype) {
+ isenum = 2;
+ break;
+ }
+ t->isenum = isenum;
+ }
+ return t->isenum == 1;
}
Type *