[hackers] [scc] Add designated initializers syntax || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 14 Sep 2015 16:24:47 +0200 (CEST)

commit 7ba972cc2abea4cb7399b463d22f5dae705d2aa6
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Sep 14 16:03:33 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon Sep 14 16:21:42 2015 +0200

    Add designated initializers syntax
    
    At this point we accept designated initializer but we are not emiting them.
    The reason is because we have to build a full tree with the information of
    the initializer list, and emit first the nested elements.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index addbea9..3d0d427 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -52,7 +52,7 @@ struct type {
         } p;
         union {
                 unsigned char rank; /* convertion rank */
- short elem; /* number of type parameters */
+ TINT elem; /* number of type parameters */
         } n;
 };
 
diff --git a/cc1/expr.c b/cc1/expr.c
index 6d3ed17..f66b08a 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -978,13 +978,95 @@ condexpr(void)
         return np;
 }
 
+struct designator {
+ TINT pos;
+ struct designator *next;
+};
+
+static TINT
+arydesig(Type *tp)
+{
+ TINT npos;
+ Node *np;
+
+ if (tp->op != ARY)
+ errorp("array index in non-array initializer");
+ next();
+ np = iconstexpr();
+ npos = np->sym->u.i;
+ freetree(np);
+ expect(']');
+ return npos;
+}
+
+static TINT
+fielddesig(Type *tp)
+{
+ TINT npos;
+ int ons;
+ Symbol *sym, **p;
+
+ if (tp->op != STRUCT || tp->op != UNION)
+ errorp("field name not in record or union initializer");
+ ons = namespace;
+ namespace = tp->ns;
+ next();
+ namespace = ons;
+ if (yytoken != IDEN)
+ unexpected();
+ sym = yylval.sym;
+ if ((sym->flags & ISDECLARED) == 0) {
+ errorp(" unknown field '%s' specified in initializer",
+ sym->name);
+ return 0;
+ }
+ for (p = tp->p.fields; *p != sym; ++p)
+ /* nothing */;
+ return p - tp->p.fields;
+}
+
+static struct designator *
+designation(Type *tp)
+{
+ struct designator *des = NULL, *d;
+ TINT (*fun)(Type *);
+
+ for (;;) {
+ switch (yytoken) {
+ case '[': fun = arydesig; break;
+ case '.': fun = fielddesig; break;
+ default:
+ if (des)
+ expect('=');
+ return des;
+ }
+ d = xmalloc(sizeof(*d));
+ d->next = NULL;
+
+ if (!des) {
+ des = d;
+ } else {
+ des->next = d;
+ des = d;
+ }
+ des->pos = (*fun)(tp);
+ }
+}
+
 static void
 initlist(Symbol *sym, Type *tp)
 {
+ struct designator *des;
         int n, toomany = 0;
         Type *newtp;
 
         for (n = 0; ; ++n) {
+ if ((des = designation(tp)) == NULL) {
+ des = xmalloc(sizeof(*des));
+ des->pos = n;
+ } else {
+ n = des->pos;
+ }
                 switch (tp->op) {
                 case ARY:
                         if (tp->defined && n >= tp->n.elem && !toomany) {
_AT_@ -1043,6 +1125,9 @@ initializer(Symbol *sym, Type *tp, int nelem)
         /* if !sym it means there are too much initializers */
         if (!sym)
                 return;
+ if (nelem >= 0)
+ return;
+
         np = assignop(OINIT, varnode(sym), np);
 
         if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
_AT_@ -1052,8 +1137,6 @@ initializer(Symbol *sym, Type *tp, int nelem)
         } else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
                 errorp("'%s' has both '%s' and initializer",
                        sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
- } else if (flags & ISFIELD) {
- ;
         } else {
                 np->op = OASSIGN;
                 emit(OEXPR, np);
Received on Mon Sep 14 2015 - 16:24:47 CEST

This archive was generated by hypermail 2.3.0 : Mon Sep 14 2015 - 16:36:12 CEST