[hackers] [scc] Make enumerations usable || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 22 Jul 2015 18:01:42 +0200 (CEST)

commit 585dc6d025dabe3e95271084e27e6c833c8c3dbf
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Jul 22 10:51:43 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Jul 22 11:18:41 2015 +0200

    Make enumerations usable

diff --git a/cc1/TODO b/cc1/TODO
index 8383cab..4f6bbd9 100644
--- a/cc1/TODO
+++ b/cc1/TODO
_AT_@ -2,7 +2,6 @@
 * Verify correctness in initializators
 * emit initializators
 * emit structures definition
-* Assign const expression value to enum members
 * Define array types based in the value of constant expressions
 * Rewrite decl.c and use only one decl function with a function pointer
   parameter
_AT_@ -13,7 +12,6 @@
 * Rewrite error recovery code, and ensure correct state after recovery
 * Allow comparisions between pointers and 0
 * Implement function calls
-* Implement enum type in eqtype()
 * Parse correctly all integer and float constants
 * Add C99 features (almost all the new features of C99 are missed)
 * Add correct emit for any kind of constant
diff --git a/cc1/cc1.h b/cc1/cc1.h
index a41e0ac..544122e 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -130,7 +130,8 @@ enum {
         ISFIELD = 32,
         ISPARAM = 64,
         ISEXTERN = 128,
- ISUSED = 256
+ ISUSED = 256,
+ ISCONSTANT = 512
 };
 
 
diff --git a/cc1/decl.c b/cc1/decl.c
index 1e18d61..6390a41 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -295,7 +295,7 @@ static Symbol *
 newtag(void)
 {
         Symbol *sym;
- unsigned tag = yylval.token;
+ int op, tag = yylval.token;
         static unsigned ns = NS_STRUCTS;
 
         setnamespace(NS_TAG);
_AT_@ -304,6 +304,7 @@ newtag(void)
         case IDEN:
         case TYPEIDEN:
                 sym = yylval.sym;
+ install(NS_TAG);
                 next();
                 break;
         default:
_AT_@ -318,8 +319,8 @@ newtag(void)
         }
 
         sym->flags |= ISDEFINED;
- if (sym->type->op != tag)
- error("'%s' defined as wrong kind of tag", yytext);
+ if ((op = sym->type->op) != tag && op != INT)
+ error("'%s' defined as wrong kind of tag", sym->name);
         return sym;
 }
 
_AT_@ -390,28 +391,36 @@ static Type *
 enumdcl(void)
 {
         Type *tp;
- Symbol *sym;
- int val = 0;
+ Symbol *sym, *tagsym;
+ int val;
 
- tp = newtag()->type;
+ tagsym = newtag();
+ tp = tagsym->type;
 
- if (yytoken == ';')
+ if (!accept('{'))
                 return tp;
-
- expect('{');
         if (tp->defined)
- error("redefinition of enumeration '%s'", yytext);
+ error("redefinition of enumeration '%s'", tagsym->name);
         tp->defined = 1;
- while (yytoken != '}') {
+ for (val = 0; yytoken != ')'; ++val) {
                 if (yytoken != IDEN)
                         unexpected();
                 if ((sym = install(NS_IDEN)) == NULL)
                         error("'%s' redeclared as different kind of symbol", yytext);
                 next();
+ sym->flags |= ISCONSTANT;
                 sym->type = inttype;
- if (accept('='))
- constexpr();
- sym->u.i = val++;
+ if (accept('=')) {
+ Node *np = constexpr();
+ /*
+ * TODO: check that the type of the constant
+ * expression is the correct, that in this
+ * case should be int
+ */
+ val = np->sym->u.i;
+ freetree(np);
+ }
+ sym->u.i = val;
                 if (!accept(','))
                         break;
         }
diff --git a/cc1/lex.c b/cc1/lex.c
index df1ba69..1f83071 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -231,6 +231,7 @@ convert:
         tp = ctype(INT, sign, size);
         sym = newsym(NS_IDEN);
         sym->type = tp;
+ sym->flags |= ISCONSTANT;
         v = strtol(s, NULL, base);
         if (tp == inttype)
                 sym->u.i = v;
_AT_@ -358,6 +359,7 @@ repeat:
 
         yylen = bp - yytext + 1;
         yylval.sym = newsym(NS_IDEN);
+ yylval.sym->flags |= ISCONSTANT;
         yylval.sym->u.s = xstrdup(yytext+1);
         yylval.sym->type = mktype(chartype, ARY, yylen - 2, NULL);
         *bp++ = '"';
_AT_@ -387,6 +389,8 @@ iden(void)
                  */
                 sym = nextsym(sym, lex_ns);
         }
+ if (sym->flags & ISCONSTANT)
+ return CONSTANT;
         if (sym->token != IDEN)
                 yylval.token = sym->u.token;
         return sym->token;
diff --git a/cc1/types.c b/cc1/types.c
index 59100e8..6eaabcd 100644
--- a/cc1/types.c
+++ b/cc1/types.c
_AT_@ -292,10 +292,25 @@ mktype(Type *tp, unsigned op, short nelem, void *data)
         type.n.elem = nelem;
         type.ns = 0;
 
- if (op == ARY && nelem == 0 || op == STRUCT || op == UNION)
- type.defined = 0;
- else
+
+ switch (op) {
+ case ARY:
+ if (nelem == 0)
+ goto no_defined;
+ /* PASSTROUGH */
+ case FTN:
+ case PTR:
                 type.defined = 1;
+ break;
+ case ENUM:
+ type.printed = 1;
+ /* PASSTROUGH */
+ case STRUCT:
+ case UNION:
+ no_defined:
+ type.defined = 0;
+ break;
+ }
 
         t = (op ^ (uintptr_t) tp >> 3) & NR_TYPE_HASH-1;
         tbl = &typetab[t];
_AT_@ -336,7 +351,7 @@ eqtype(Type *tp1, Type *tp2)
                 }
                 return 1;
         case ENUM:
- /* TODO: Check when two enum are the same type */
+ break;
         case INT: case FLOAT:
                 return tp1->letter == tp2->letter;
         default:
Received on Wed Jul 22 2015 - 18:01:42 CEST

This archive was generated by hypermail 2.3.0 : Wed Jul 22 2015 - 18:12:15 CEST