1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 *
7 *	@(#)gram.expr	5.3 (Berkeley) 04/12/91
8 */
9
10/*
11 * gram.expr
12 *
13 * Grammar for expressions, f77 compiler pass 1, 4.2 BSD.
14 *
15 * University of Utah CS Dept modification history:
16 *
17 * $Log:	gram.expr,v $
18 * Revision 5.2  85/12/21  07:26:39  donn
19 * Permit CHARACTER*(4) in function declarations by eliminating parentheses
20 * more appropriately.
21 *
22 * Revision 5.1  85/08/10  03:47:25  donn
23 * 4.3 alpha
24 *
25 * Revision 3.2  85/02/15  19:08:53  donn
26 * Put OPPAREN operators in trees when not optimizing as well as when
27 * optimizing -- this allows '(1)' to produce a writable temporary instead
28 * of a read-only constant when passed as an argument to a subroutine.
29 *
30 * Revision 3.1  84/10/13  00:42:08  donn
31 * Installed Jerry Berkman's version with cosmetic changes.
32 *
33 * Revision 1.2  84/08/04  21:27:05  donn
34 * Added Jerry Berkman's fix to stop complaints about parentheses in
35 * declarations.
36 *
37 */
38
39funarglist:
40		{ $$ = 0; }
41	| funargs
42	;
43
44funargs:  expr
45		{ $$ = mkchain($1, CHNULL); }
46	| funargs SCOMMA expr
47		{ $$ = hookup($1, mkchain($3,CHNULL) ); }
48	;
49
50
51expr:	  uexpr
52	| SLPAR expr SRPAR
53		{ if (parstate > INDCL)
54			$$ = mkexpr(OPPAREN, $2, ENULL);
55		  else $$ = $2;
56		}
57	| complex_const
58	;
59
60uexpr:	  lhs
61	| simple_const
62	| expr addop expr   %prec SPLUS
63		{ $$ = mkexpr($2, $1, $3); }
64	| expr SSTAR expr
65		{ $$ = mkexpr(OPSTAR, $1, $3); }
66	| expr SSLASH expr
67		{ $$ = mkexpr(OPSLASH, $1, $3); }
68	| expr SPOWER expr
69		{ $$ = mkexpr(OPPOWER, $1, $3); }
70	| addop expr  %prec SSTAR
71		{ if($1 == OPMINUS)
72			$$ = mkexpr(OPNEG, $2, ENULL);
73		  else 	$$ = $2;
74		}
75	| expr relop expr  %prec SEQ
76		{ $$ = mkexpr($2, $1, $3); }
77	| expr SEQV expr
78		{ NO66(".EQV. operator");
79		  $$ = mkexpr(OPEQV, $1,$3); }
80	| expr SNEQV expr
81		{ NO66(".NEQV. operator");
82		  $$ = mkexpr(OPNEQV, $1, $3); }
83	| expr SOR expr
84		{ $$ = mkexpr(OPOR, $1, $3); }
85	| expr SAND expr
86		{ $$ = mkexpr(OPAND, $1, $3); }
87	| SNOT expr
88		{ $$ = mkexpr(OPNOT, $2, ENULL); }
89	| expr SCONCAT expr
90		{ NO66("concatenation operator //");
91		  $$ = mkexpr(OPCONCAT, $1, $3); }
92	;
93
94addop:	  SPLUS		{ $$ = OPPLUS; }
95	| SMINUS	{ $$ = OPMINUS; }
96	;
97
98relop:	  SEQ	{ $$ = OPEQ; }
99	| SGT	{ $$ = OPGT; }
100	| SLT	{ $$ = OPLT; }
101	| SGE	{ $$ = OPGE; }
102	| SLE	{ $$ = OPLE; }
103	| SNE	{ $$ = OPNE; }
104	;
105
106lhs:	 name
107		{ $$ = mkprim($1, PNULL, CHNULL); }
108	| name substring
109		{ NO66("substring operator :");
110		  if( $1->vclass != CLPARAM ) {
111		  	$$ = mkprim($1, PNULL, $2);
112		  } else {
113			errstr("substring of parameter %s",
114				varstr(VL,$1->varname) );
115			YYERROR ;
116		  }
117		}
118	| name SLPAR funarglist SRPAR
119		{ if( $1->vclass != CLPARAM ) {
120		  	$$ = mkprim($1, mklist($3), CHNULL);
121		  } else {
122			errstr("can not subscript parameter %s",
123				varstr(VL,$1->varname) );
124			YYERROR ;
125		  }
126		}
127	| name SLPAR funarglist SRPAR substring
128		{ if( $1->vclass != CLPARAM ) {
129		  	NO66("substring operator :");
130		  	$$ = mkprim($1, mklist($3), $5);
131		  } else {
132			errstr("can not subscript parameter %s",
133				varstr(VL,$1->varname) );
134			YYERROR ;
135		  }
136		}
137	;
138
139substring:  SLPAR opt_expr SCOLON opt_expr SRPAR
140		{ $$ = mkchain($2, mkchain($4,CHNULL)); }
141	;
142
143opt_expr:
144		{ $$ = 0; }
145	| expr
146	;
147
148
149simple_const:   STRUE	{ $$ = mklogcon(1); }
150	| SFALSE	{ $$ = mklogcon(0); }
151	| SHOLLERITH  { $$ = mkstrcon(toklen, token); }
152	| SICON	= { $$ = mkintcon( convci(toklen, token) ); }
153	| SRCON	= { $$ = mkrealcon(TYREAL, convcd(toklen, token)); }
154	| SDCON	= { $$ = mkrealcon(TYDREAL, convcd(toklen, token)); }
155	;
156
157complex_const:  SLPAR uexpr SCOMMA uexpr SRPAR
158		{ $$ = mkcxcon($2,$4); }
159	;
160
161
162fexpr:	  unpar_fexpr
163	| SLPAR fexpr SRPAR
164		{ if (optimflag && parstate > INDCL)
165			$$ = mkexpr(OPPAREN, $2, ENULL);
166		  else $$ = $2;
167		}
168	;
169
170unpar_fexpr:	  lhs
171	| simple_const
172	| fexpr addop fexpr   %prec SPLUS
173		{ $$ = mkexpr($2, $1, $3); }
174	| fexpr SSTAR fexpr
175		{ $$ = mkexpr(OPSTAR, $1, $3); }
176	| fexpr SSLASH fexpr
177		{ $$ = mkexpr(OPSLASH, $1, $3); }
178	| fexpr SPOWER fexpr
179		{ $$ = mkexpr(OPPOWER, $1, $3); }
180	| addop fexpr  %prec SSTAR
181		{ if($1 == OPMINUS)
182			$$ = mkexpr(OPNEG, $2, ENULL);
183		  else	$$ = $2;
184		}
185	| fexpr SCONCAT fexpr
186		{ NO66("concatenation operator //");
187		  $$ = mkexpr(OPCONCAT, $1, $3); }
188	;
189