summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMura Li <mura_li@castech.com.tw>2020-04-13 11:44:52 +0000
committerOri Bernstein <ori@eigenstate.org>2020-04-14 22:00:12 -0400
commit2ffd051d75978386e2c63b5d0812dd9be982c38c (patch)
tree869920b7b4162e60ef8a21c696a2d7e564e9833e
parent69d83a1be81a97e50f1b83a2cf327f96064f1152 (diff)
downloadmc-2ffd051d75978386e2c63b5d0812dd9be982c38c.tar.gz
Support the pseudo-member 'tag' for union types
Similar to `x.len` which reads the element count of a sequence, `x.tag` reads the tag id of a union value.
-rw-r--r--parse/fold.c3
-rw-r--r--parse/infer.c6
2 files changed, 9 insertions, 0 deletions
diff --git a/parse/fold.c b/parse/fold.c
index 2518a4b..4094c49 100644
--- a/parse/fold.c
+++ b/parse/fold.c
@@ -247,6 +247,9 @@ fold(Node *n, int foldvar)
if (t->type == Tyarray && !strcmp(namestr(args[1]), "len")) {
r = t->asize;
r->expr.type = exprtype(n);
+ } else if (t->type == Tyunion && !strcmp(namestr(args[1]), "tag")) {
+ r = mkexpr(n->loc, Outag, args[0], NULL);
+ r->expr.type = mktype(n->loc, Tyint32);
}
break;
case Oarr:
diff --git a/parse/infer.c b/parse/infer.c
index 6415cb3..0053c19 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2293,6 +2293,12 @@ infercompn(Node *n, Postcheck ***post, size_t *npost)
constrain(n, type(n), traittab[Tcint]);
found = 1;
}
+ } else if (ismemb && t->type == Tyunion) {
+ if (!strcmp(namestr(memb), "tag")) {
+ constrain(n, type(n), traittab[Tcnum]);
+ constrain(n, type(n), traittab[Tcint]);
+ found = 1;
+ }
} else {
if (tybase(t)->type == Typtr)
t = tybase(tf(t->sub[0]));