shithub: mc

Download patch

ref: 86f9ba03d2175620b8de6295c9bd074010e792bf
parent: 382c5d3af7b86565637b73333038f8dde981bb94
author: Ori Bernstein <[email protected]>
date: Tue Oct 7 12:38:25 EDT 2014

Generalize grammar: specific attrs ar now lists.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -24,6 +24,7 @@
 static Node *mkpseudodecl(Type *t);
 static void installucons(Stab *st, Type *t);
 static void addtrait(Type *t, char *str);
+static void setattrs(Node *dcl, char **attrs, size_t nattrs);
 
 %}
 
@@ -102,7 +103,6 @@
 %token<tok> Tconst   /* const */
 %token<tok> Tvar     /* var */
 %token<tok> Tgeneric /* var */
-%token<tok> Textern  /* extern */
 %token<tok> Tcast    /* castto */
 
 %token<tok> Texport  /* export */
@@ -118,7 +118,6 @@
 %token<tok> Tret     /* -> */
 %token<tok> Tuse     /* use */
 %token<tok> Tpkg     /* pkg */
-%token<tok> Tpkglocal/* pkglocal */
 %token<tok> Tattr    /* $attr */
 %token<tok> Tsizeof  /* sizeof */
 
@@ -154,6 +153,7 @@
 %type <nodelist> tupbody tuprest
 %type <nodelist> decl pkgdecl decllist
 %type <nodelist> traitbody implbody
+%type <strlist> attrs
 
 %type <uconlist> unionbody
 
@@ -164,6 +164,10 @@
         size_t nn;
     } nodelist;
     struct {
+        char **str;
+        size_t nstr;
+    } strlist;
+    struct {
         int line;
         Ucon **ucl;
         size_t nucl;
@@ -220,33 +224,36 @@
         | /* empty */
         ;
 
-decl    : Tvar decllist {$$ = $2;}
-        | Tconst decllist {
+decl    : attrs Tvar decllist {
                 size_t i;
-                for (i = 0; i < $2.nn; i++)
-                    $2.nl[i]->decl.isconst = 1;
-                $$ = $2;
+
+                for (i = 0; i < $3.nn; i++)
+                    setattrs($3.nl[i], $1.str, $1.nstr);
+                $$ = $3;
             }
-        | Tgeneric decllist {
+        | attrs Tconst decllist {
                 size_t i;
-             for (i = 0; i < $2.nn; i++) {
-                $2.nl[i]->decl.isconst = 1;
-                $2.nl[i]->decl.isgeneric = 1;
-             }
-             $$ = $2;}
-        | Textern Tvar decllist {
-                size_t i;
-                for (i = 0; i < $3.nn; i++)
-                    $3.nl[i]->decl.isextern = 1;
+                for (i = 0; i < $3.nn; i++) {
+                    setattrs($3.nl[i], $1.str, $1.nstr);
+                    $3.nl[i]->decl.isconst = 1;
+                }
                 $$ = $3;
             }
-        | Textern Tconst decllist {
+        | attrs Tgeneric decllist {
                 size_t i;
+
                 for (i = 0; i < $3.nn; i++) {
+                    setattrs($3.nl[i], $1.str, $1.nstr);
                     $3.nl[i]->decl.isconst = 1;
-                    $3.nl[i]->decl.isextern = 1;
+                    $3.nl[i]->decl.isgeneric = 1;
                 }
                 $$ = $3;
+             }
+
+attrs   : /* empty */ {$$.nstr = 0; $$.str = NULL;}
+        | Tattr attrs {
+                $$ = $2;
+                lappend(&$$.str, &$$.nstr, strdup($1->str));
             }
         ;
 
@@ -282,7 +289,7 @@
         | pkgbody Tendln pkgitem
         ;
 
-pkgitem : pkgdecl {
+pkgitem : decl {
                 size_t i;
                 for (i = 0; i < $1.nn; i++) {
                     putdcl(file->file.exports, $1.nl[i]);
@@ -305,30 +312,26 @@
                 $1->impl.vis = Visexport;
                 putimpl(file->file.exports, $1);
             }
-        | visdef {die("Unimplemented visdef");}
         | /* empty */
         ;
 
-pkgdecl : Tpkglocal decl {
-                size_t i;
-                $$ = $2;
-                for (i = 0; i < $$.nn; i++)
-                    $$.nl[i]->decl.ispkglocal = 1;
-            }
-        | decl {$$ = $1;}
+pkgdecl : decl {$$ = $1;}
         ;
 
-pkgtydef: Tpkglocal tydef {
+pkgtydef: attrs tydef {
+                size_t i;
                 $$ = $2;
-                $$.type->ispkglocal = 1;
+                for (i = 0; i < $1.nstr; i++) {
+                    if (!strcmp($1.str[i], "pkglocal"))
+                        $$.type->ispkglocal = 1;
+                    else
+                        fatal($$.line, "invalid type attribute '%s'", $1.str[i]);
+                }
+
           }
         | tydef {$$ = $1;}
         ;
 
-visdef  : Texport Tcolon
-        | Tprotect Tcolon
-        ;
-
 declbody: declcore Tasn expr {$$ = $1; $1->decl.init = $3;}
         | declcore
         ;
@@ -513,7 +516,6 @@
 
 structent
         : declcore Tendln {$$ = $1;}
-        | visdef Tendln {$$ = NULL;}
         | Tendln {$$ = NULL;}
         ;
 
@@ -538,7 +540,6 @@
 unionelt /* nb: the ucon union type gets filled in when we have context */
         : Ttick name type Tendln {$$ = mkucon($2->line, $2, NULL, $3);}
         | Ttick name Tendln {$$ = mkucon($2->line, $2, NULL, NULL);}
-        | visdef Tendln {$$ = NULL;}
         | Tendln {$$ = NULL;}
         ;
 
@@ -910,6 +911,20 @@
 
     snprintf(buf, 128, ".pdecl%d", nextpseudoid++);
     return mkdecl(-1, mkname(-1, buf), t);
+}
+
+static void setattrs(Node *dcl, char **attrs, size_t nattrs)
+{
+    size_t i;
+
+    for (i = 0; i < nattrs; i++) {
+        if (!strcmp(attrs[i], "extern"))
+            dcl->decl.isextern = 1;
+        else if (!strcmp(attrs[i], "$noret"))
+            dcl->decl.isnoret = 1;
+        else if (!strcmp(attrs[i], "pkglocal"))
+            dcl->decl.ispkglocal = 1;
+    }
 }
 
 static void installucons(Stab *st, Type *t)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -276,6 +276,7 @@
             char  ispkglocal;
             char  ishidden;
             char  isimport;
+            char  isnoret;
             char  isexportinit;
         } decl;
 
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -161,7 +161,7 @@
 static int kwd(char *s)
 {
     static const struct {char* kw; int tt;} kwmap[] = {
-        {"$nonret",     Tattr},
+        {"$noret",      Tattr},
         {"break",       Tbreak},
         {"castto",      Tcast},
         {"const",       Tconst},
@@ -169,7 +169,7 @@
         {"elif",        Telif},
         {"else",        Telse},
         {"export",      Texport},
-        {"extern",      Textern},
+        {"extern",      Tattr},
         {"false",       Tboollit},
         {"for",         Tfor},
         {"generic",     Tgeneric},
@@ -179,7 +179,7 @@
         {"in",          Tin},
         {"match",       Tmatch},
         {"pkg",         Tpkg},
-        {"pkglocal",    Tpkglocal},
+        {"pkglocal",    Tattr},
         {"protect",     Tprotect},
         {"sizeof",      Tsizeof},
         {"struct",      Tstruct},
@@ -765,7 +765,7 @@
         line++;
         next();
         t =  mktok(Tendln);
-    } else if (isalpha(c) || c == '_') {
+    } else if (isalpha(c) || c == '_' || c == '$') {
         t =  kwident();
     } else if (c == '"') {
         t =  strlit();