ref: eee351ec4167b3d70cd704edb38f85c63a7eca4d
parent: 346c26a93cb79f89c3d0fb12d0a2d749956cebdb
author: Ori Bernstein <ori@eigenstate.org>
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();
--
⑨