[hackers] [scc] Add mkcompound() || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Tue, 19 Jan 2016 10:55:46 +0100 (CET)

commit e6ef99231498cfcd683a5132b7de6f266e50444d
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Jan 18 22:29:11 2016 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon Jan 18 22:29:11 2016 +0100

    Add mkcompound()
    
    This function takes an initializer structure and it creates
    an array of expressions which will be used in the symbol
    created for the compound literal.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index 84bd68a..0ffab7e 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -17,7 +17,6 @@ typedef struct symbol Symbol;
 typedef struct caselist Caselist;
 typedef struct node Node;
 typedef struct input Input;
-typedef struct init Init;
 
 struct limits {
         union {
_AT_@ -62,14 +61,6 @@ struct type {
         } n;
 };
 
-struct designator;
-
-struct init {
- Type *type;
- TUINT pos;
- struct designator *head;
-};
-
 struct symbol {
         char *name;
         Type *type;
_AT_@ -84,7 +75,7 @@ struct symbol {
                 TFLOAT f;
                 char *s;
                 unsigned char token;
- Init *init;
+ Node **init;
                 Symbol **pars;
         } u;
         struct symbol *next;
_AT_@ -175,7 +166,8 @@ enum {
         ISEMITTED = 1024,
         ISDEFINED = 2048,
         ISSTRING = 4096,
- ISTYPEDEF = 8192
+ ISTYPEDEF = 8192,
+ ISINITLST = 16384
 };
 
 /* lexer mode, compiler or preprocessor directive */
diff --git a/cc1/code.c b/cc1/code.c
index 884223b..9535004 100644
--- a/cc1/code.c
+++ b/cc1/code.c
_AT_@ -291,13 +291,9 @@ emittype(Type *tp)
 static void
 emitinit(unsigned op, void *arg)
 {
- Node *np = arg;
-
         puts("(");
- emitexp(OEXPR, np->right);
+ emitexp(OEXPR, arg);
         puts(")");
- np->right = NULL;
- freetree(np);
 }
 
 static void
diff --git a/cc1/init.c b/cc1/init.c
index eb59365..079b4cc 100644
--- a/cc1/init.c
+++ b/cc1/init.c
_AT_@ -1,18 +1,29 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "../inc/cc.h"
 #include "../inc/sizes.h"
 #include "cc1.h"
 
 
+typedef struct init Init;
+
 struct designator {
         TINT pos;
         Node *expr;
         struct designator *next;
 };
 
+struct init {
+ Type *type;
+ size_t pos;
+ size_t max;
+ struct designator *tail;
+ struct designator *head;
+};
+
 
 static TINT
 arydesig(Init *ip)
_AT_@ -63,10 +74,6 @@ designation(Init *ip)
         struct designator *dp;
         TINT (*fun)(Init *);
 
- dp = xmalloc(sizeof(*dp));
- dp->next = ip->head;
- ip->head = dp;
-
         switch (yytoken) {
         case '[': fun = arydesig; break;
         case '.': fun = fielddesig; break;
_AT_@ -85,79 +92,144 @@ initialize(Type *tp)
 {
         Node *np;
 
- np = (accept('{')) ? initlist(tp) : assign();
- if ((np = convert(decay(np), tp, 0)) == NULL)
+ np = (accept('{')) ? initlist(tp) : decay(assign());
+ if ((np = convert(np, tp, 0)) == NULL) {
                 errorp("incorrect initializer");
+ np = constnode(zero);
+ }
         return np;
 }
 
 static Node *
-initlist(Type *tp)
+mkcompound(Init *ip)
 {
- Init *ip;
+ Node **v, **p;
+ size_t n;
+ struct designator *dp, *next;
         Symbol *sym;
+
+ n = ip->max;
+ if (n >= n * sizeof(*v)) {
+ errorp("compound literal too big");
+ return constnode(zero);
+ }
+ n *= sizeof(*v);
+ v = memset(xmalloc(n), 0, n);
+
+ for (dp = ip->head; dp; dp = next) {
+ p = &v[dp->pos];
+ freetree(*p);
+ *p = dp->expr;
+ next = dp->next;
+ free(dp);
+ }
+
+ sym = newsym(NS_IDEN);
+ sym->u.init = v;
+ sym->type = ip->type;
+ sym->flags |= ISINITLST;
+
+ return constnode(sym);
+}
+
+static void
+newdesig(Init *ip, Node *np)
+{
         struct designator *dp;
- int toomany = 0;
- Type *newtp;
 
- ip = xmalloc(sizeof(*ip));
- ip->head = NULL;
- ip->pos = 0;
- ip->type = tp;
+ if (ip->pos > ip->max)
+ ip->max = ip->pos;
+
+ dp = xmalloc(sizeof(*dp));
+ dp->pos = ip->pos;
+ dp->expr = np;
+ dp->next = NULL;
+
+ if (ip->head == NULL) {
+ ip->head = ip->tail = dp;
+ } else {
+ ip->tail->next = dp;
+ ip->tail = dp;
+ }
+}
 
- if (accept('}'))
- goto end_of_initializer;
+static Node *
+initlist(Type *tp)
+{
+ Init in;
+ int toomany = 0, outbound;
+ Type *newtp;
+ Node *np;
 
- for (ip->pos = 1; ; ++ip->pos) {
- designation(ip);
+ in.tail = in.head = NULL;
+ in.type = tp;
+ in.pos = 0;
+ in.max = 0;
+
+ do {
+ if (yytoken == '}')
+ break;
+ outbound = 0;
+ designation(&in);
                 switch (tp->op) {
                 case ARY:
- newtp = sym->type;
- if (!tp->defined || ip->pos <= tp->n.elem)
+ newtp = tp->type;
+ if (!tp->defined || in.pos < tp->n.elem)
                                 break;
                         if (!toomany)
                                 warn("excess elements in array initializer");
+ outbound = 1;
                         toomany = 1;
                         break;
+ /* TODO: case UNION: */
                 case STRUCT:
- if (ip->pos <= tp->n.elem) {
- sym = tp->p.fields[ip->pos-1];
- newtp = sym->type;
+ if (in.pos < tp->n.elem) {
+ newtp = tp->p.fields[in.pos]->type;
                                 break;
                         }
                         newtp = inttype;
                         if (!toomany)
                                 warn("excess elements in struct initializer");
                         toomany = 1;
+ outbound = 1;
                         break;
                 default:
                         newtp = tp;
                         warn("braces around scalar initializer");
- if (ip->pos == 1)
+ if (in.pos == 0)
                                 break;
                         if (!toomany)
                                 warn("excess elements in scalar initializer");
                         toomany = 1;
+ outbound = 1;
                         break;
                 }
- dp = ip->head;
- dp->pos = ip->pos;
- dp->expr = initialize(newtp);
 
- if (!accept(','))
- break;
- }
+ np = initialize(newtp);
+ if (outbound)
+ freetree(np);
+ else
+ newdesig(&in, np);
+
+ if (++in.pos == 0)
+ errorp("compound literal too big");
+
+ } while (accept(','));
+
         expect('}');
 
-end_of_initializer:
         if (tp->op == ARY && !tp->defined) {
- tp->n.elem = ip->pos;
+ tp->n.elem = in.pos;
                 tp->defined = 1;
         }
- sym = newsym(NS_IDEN);
- sym->u.init = ip;
- sym->type = tp;
- return constnode(sym);
+ if (tp->op == ARY || tp->op == STRUCT)
+ in.max = tp->n.elem;
+ else if (in.max == 0) {
+ errorp("empty scalar initializer");
+ return constnode(zero);
+ }
+
+ return mkcompound(&in);
 }
 
 void
_AT_@ -168,7 +240,6 @@ initializer(Symbol *sym, Type *tp, int nelem)
 
         if (tp->op == FTN)
                 errorp("function '%s' is initialized like a variable", sym->name);
-
         np = initialize(tp);
 
         if (flags & ISDEFINED) {
Received on Tue Jan 19 2016 - 10:55:46 CET

This archive was generated by hypermail 2.3.0 : Tue Jan 19 2016 - 11:00:19 CET