shithub: mc

Download patch

ref: 2ffd051d75978386e2c63b5d0812dd9be982c38c
parent: 69d83a1be81a97e50f1b83a2cf327f96064f1152
author: Mura Li <mura_li@castech.com.tw>
date: Mon Apr 13 07:44:52 EDT 2020

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.

--- a/parse/fold.c
+++ b/parse/fold.c
@@ -247,6 +247,9 @@
 		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:
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2293,6 +2293,12 @@
 			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]));