summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2018-07-17 08:57:58 +0000
committerOri Bernstein <ori@eigenstate.org>2018-07-19 21:29:35 -0700
commitf4a43f90e3ffe1712aec13566e8ac545da4161c4 (patch)
tree57a3edcd99ff2cae6ab74b6435af32d3182174ba /6
parent8a3e8add6e0180565312d1079395ad39de4d9ce3 (diff)
downloadmc-f4a43f90e3ffe1712aec13566e8ac545da4161c4.tar.gz
Support direct tuple access operators "tuple.N"
This patch adds tuple access expressions. If t is a tuple, its N-th component can be retrieved with the syntax t.N. Of course, the components are zero indexed. I believe the code also works if 't' is a pointer to a tuple (but I have not checked this).
Diffstat (limited to '6')
-rw-r--r--6/isel.c2
-rw-r--r--6/simp.c4
-rw-r--r--6/typeinfo.c35
3 files changed, 28 insertions, 13 deletions
diff --git a/6/isel.c b/6/isel.c
index 7b30b04..bb111ad 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -945,7 +945,7 @@ selexpr(Isel *s, Node *n)
case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
case Oslbase: case Osllen: case Ocast: case Outag: case Oudata:
case Otup: case Oarr: case Ostruct:
- case Oslice: case Oidx: case Osize: case Otupget:
+ case Oslice: case Oidx: case Osize: case Otupget: case Otupmemb:
case Obreak: case Ocontinue:
case Numops:
dump(n, stdout);
diff --git a/6/simp.c b/6/simp.c
index 457227e..7ab6f15 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -540,6 +540,7 @@ lval(Simp *s, Node *n)
case Ovar: r = loadvar(s, n, NULL); break;
case Oidx: r = loadidx(s, args[0], args[1]); break;
case Oderef: r = deref(rval(s, args[0], NULL), NULL); break;
+ case Otupmemb: r = rval(s, n, NULL); break;
case Omemb: r = rval(s, n, NULL); break;
case Ostruct: r = rval(s, n, NULL); break;
case Oucon: r = rval(s, n, NULL); break;
@@ -1137,8 +1138,7 @@ rval(Simp *s, Node *n, Node *dst)
u = idxaddr(s, t, n->expr.args[1]);
r = load(u);
break;
- /* array.len slice.len are magic 'virtual' members.
- * they need to be special cased. */
+ case Otupmemb:
case Omemb:
t = membaddr(s, n);
r = load(t);
diff --git a/6/typeinfo.c b/6/typeinfo.c
index 312aefb..0a7045b 100644
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -349,7 +349,7 @@ tyalign(Type *ty)
return min(align, Ptrsz);
}
-/* gets the byte offset of 'memb' within the aggregate type 'aggr' */
+/* gets the byte offset of 'memb' within the aggregate type 'ty' */
ssize_t
tyoffset(Type *ty, Node *memb)
{
@@ -360,16 +360,31 @@ tyoffset(Type *ty, Node *memb)
if (ty->type == Typtr)
ty = tybase(ty->sub[0]);
- assert(ty->type == Tystruct);
- off = 0;
- for (i = 0; i < ty->nmemb; i++) {
- off = alignto(off, decltype(ty->sdecls[i]));
- if (!strcmp(namestr(memb), declname(ty->sdecls[i])))
- return off;
- off += size(ty->sdecls[i]);
+ switch (memb->type) {
+ case Nname:
+ assert(ty->type == Tystruct);
+ off = 0;
+ for (i = 0; i < ty->nmemb; i++) {
+ off = alignto(off, decltype(ty->sdecls[i]));
+ if (!strcmp(namestr(memb), declname(ty->sdecls[i])))
+ return off;
+ off += size(ty->sdecls[i]);
+ }
+ die("bad offset");
+ return 0;
+ case Nlit:
+ assert(ty->type == Tytuple);
+ assert(memb->lit.intval < ty->nsub);
+ off = 0;
+ for (i = 0; i < memb->lit.intval; i++) {
+ off += tysize(ty->sub[i]);
+ off = alignto(off, ty->sub[i+1]);
+ }
+ return off;
+ default:
+ die("bad offset node type");
+ return 0;
}
- die("bad offset");
- return 0;
}
size_t