From d915b961000acdc2fc3f4ad726c540e1fc1e6aa2 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Thu, 3 Jul 2008 16:41:32 -0700 Subject: [PATCH] new iota SVN=125984 --- src/cmd/gc/go.h | 3 +++ src/cmd/gc/go.y | 28 +++++++++++++++++++++------- src/cmd/gc/subr.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 42285550af..828ebbb712 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -114,6 +114,7 @@ struct Node 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; @@ -393,6 +394,7 @@ EXTERN int inimportsys; EXTERN Node* booltrue; EXTERN Node* boolfalse; EXTERN ulong iota; +EXTERN Node* lastconst; EXTERN long vargen; EXTERN long exportgen; EXTERN long maxarg; @@ -479,6 +481,7 @@ void badtype(int, Type*, Type*); Type* ptrto(Type*); Node* cleanidlist(Node*); Node* syslook(char*, int); +Node* treecopy(Node*); Type** getthis(Type*); Type** getoutarg(Type*); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index 587486003b..5f223f5056 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -40,7 +40,7 @@ %type range_header range_body range_stmt %type simple_stmt osimple_stmt semi_stmt %type expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r -%type name name_name new_name new_name_list_r +%type name name_name new_name new_name_list_r conexpr %type vardcl_list_r vardcl Avardcl Bvardcl %type interfacedcl_list_r interfacedcl %type structdcl_list_r structdcl @@ -166,6 +166,7 @@ Acommon_dcl: { $$ = N; iota = 0; + lastconst = N; } | LTYPE Atypedcl { @@ -185,6 +186,7 @@ Bcommon_dcl: { $$ = N; iota = 0; + lastconst = N; } | LTYPE Btypedcl { @@ -224,22 +226,33 @@ Bvardcl: 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; } @@ -653,6 +666,7 @@ pexpr: | LIOTA { $$ = literal(iota); + $$->iota = 1; // flag to reevaluate on copy } | name | '(' expr ')' diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 2a2da5b7c3..6bf97911e4 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1092,6 +1092,40 @@ out: 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) { -- 2.50.0