uchar etype; // op for OASOP, etype for OTYPE, exclam for export
uchar class; // PPARAM, PAUTO, PEXTERN, PSTATIC
uchar method; // OCALLMETH name
+ uchar iota; // OLITERAL made from iota
// most nodes
Node* left;
EXTERN Node* booltrue;
EXTERN Node* boolfalse;
EXTERN ulong iota;
+EXTERN Node* lastconst;
EXTERN long vargen;
EXTERN long exportgen;
EXTERN long maxarg;
Type* ptrto(Type*);
Node* cleanidlist(Node*);
Node* syslook(char*, int);
+Node* treecopy(Node*);
Type** getthis(Type*);
Type** getoutarg(Type*);
%type <node> range_header range_body range_stmt
%type <node> simple_stmt osimple_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
-%type <node> name name_name new_name new_name_list_r
+%type <node> name name_name new_name new_name_list_r conexpr
%type <node> vardcl_list_r vardcl Avardcl Bvardcl
%type <node> interfacedcl_list_r interfacedcl
%type <node> structdcl_list_r structdcl
{
$$ = N;
iota = 0;
+ lastconst = N;
}
| LTYPE Atypedcl
{
{
$$ = N;
iota = 0;
+ lastconst = N;
}
| LTYPE Btypedcl
{
walktype($3, Erv); // this is a little harry
defaultlit($3);
dodclvar($1, $3->type);
-
$$ = nod(OAS, $1, $3);
}
constdcl:
- new_name '=' expr
+ new_name conexpr
+ {
+ walktype($2, Erv);
+ dodclconst($1, $2);
+ }
+| new_name type conexpr
{
walktype($3, Erv);
+ convlit($3, $2);
dodclconst($1, $3);
+ }
+
+conexpr:
+ {
+ if(lastconst == N)
+ yyerror("first constant must evaluate an expression");
+ $$ = treecopy(lastconst);
iota += 1;
}
-| new_name type '=' expr
+| '=' expr
{
- walktype($4, Erv);
- convlit($4, $2);
- dodclconst($1, $4);
+ $$ = $2;
+ lastconst = treecopy($$);
iota += 1;
}
| LIOTA
{
$$ = literal(iota);
+ $$->iota = 1; // flag to reevaluate on copy
}
| name
| '(' expr ')'
return fmtstrcpy(fp, buf);
}
+Node*
+treecopy(Node *n)
+{
+ Node *m;
+
+ if(n == N)
+ return N;
+
+ switch(n->op) {
+ default:
+ m = nod(OXXX, N, N);
+ *m = *n;
+ m->left = treecopy(n->left);
+ m->right = treecopy(n->right);
+ break;
+
+ case OLITERAL:
+ if(n->iota) {
+ m = literal(iota);
+ m->iota = 1; // flag to reevaluate on copy
+ break;
+ }
+ m = nod(OXXX, N, N);
+ *m = *n;
+ break;
+
+ case ONAME:
+ m = nod(OXXX, N, N);
+ *m = *n;
+ break;
+ }
+ return m;
+}
+
int
Zconv(Fmt *fp)
{