Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / as / comm2.y
1 /* $Id: comm2.y,v 2.12 1994/06/24 13:21:58 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /* @(#)comm2.y  1.7 */
7
8 /*
9  * delay inclusion of machine dependent stuff (see comm0.h)
10  */
11 #define _include        #include
12
13 %{
14 #include        "comm0.h"
15 #include        "comm1.h"
16
17 static item_t   *last_it, *o_it;
18 %}
19
20 /* ========== Machine independent Yacc definitions ========== */
21
22 %union {
23         word_t  y_word;
24         valu_t  y_valu;
25         expr_t  y_expr;
26         item_t  *y_item;
27 #ifdef ASLD
28         char    *y_strp;
29 #endif
30 };
31
32 #ifdef ASLD
33 %token <y_strp> MODULE
34 #endif
35 %token STRING
36 %token <y_item> IDENT
37 %token <y_item> FBSYM
38 %token <y_valu> CODE1
39 %token <y_valu> CODE2
40 %token <y_valu> CODE4
41 %token NUMBER0          /* keep NUMBER* in this order */
42 %token NUMBER1
43 %token NUMBER2
44 %token NUMBER3
45 %token <y_valu> NUMBER
46 %token DOT
47 %token EXTERN
48 %token <y_word> DATA
49 %token <y_word> ASCII
50 %token SECTION
51 %token COMMON
52 %token BASE
53 %token SYMB
54 %token SYMD
55 %token ALIGN
56 %token ASSERT
57 %token SPACE
58 %token <y_word> LINE
59 %token FILe
60 %token <y_word> LIST
61 %token OP_EQ
62 %token OP_NE
63 %token OP_LE
64 %token OP_GE
65 %token OP_LL
66 %token OP_RR
67 %token OP_OO
68 %token OP_AA
69
70 %left OP_OO
71 %left OP_AA
72 %left '|'
73 %left '^'
74 %left '&'
75 %left OP_EQ OP_NE
76 %left '<' '>' OP_LE OP_GE
77 %left OP_LL OP_RR
78 %left '+' '-'
79 %left '*' '/' '%' 
80 %nonassoc '~'
81
82 %type <y_valu> absexp optabs1 optabs2
83 %type <y_expr> expr
84 %type <y_item> id_fb
85
86 /* ========== Machine dependent Yacc definitions ========== */
87
88 #include        "mach2.c"
89
90 %%
91
92 /* ========== Machine independent rules ========== */
93
94 #ifdef LISTING
95 #define LISTLINE(n)     if (listflag) listline(n); \
96                         else if (listtemp) { listflag = listtemp; listeoln = 1; }
97 #else
98 #define LISTLINE(n)     /* empty */
99 #endif /* LISTING */
100
101 #ifdef ASLD
102 #define RELODONE        /* empty */
103 #else
104 #define RELODONE        assert(relonami == 0)
105 #endif
106
107 program :       /* empty */
108 #ifdef ASLD
109         |       program MODULE /* not in PASS_1 */
110                         {       newmodule($2);}
111 #endif
112         |       program IDENT ':'
113                         {       newident($2, DOTTYP); newlabel($2);}
114         |       program NUMBER ':'
115                         {       if ($2 < 0 || $2 > 9) {
116                                         serror("bad f/b label");
117                                         $2 = 0;
118                                 }
119                                 newlabel(fb_shift((int)$2));
120                         }
121         |       program CODE1
122                         {       emit1((int)$2); LISTLINE(0);}
123         |       program CODE2
124                         {       emit2((int)$2); LISTLINE(0);}
125         |       program CODE4
126                         {       emit4((long)$2); LISTLINE(0);}
127         |       program operation ';'
128         |       program operation '\n'
129                         {       lineno++; LISTLINE(1); RELODONE;}
130         |       program '#' NUMBER STRING '\n'
131                         {       lineno = $3;
132                                 if (modulename) strncpy(modulename, stringbuf, STRINGMAX-1);
133                                 LISTLINE(1); RELODONE;
134                         }
135         |       program error '\n'
136                         {       serror("syntax error"); yyerrok;
137                                 lineno++; LISTLINE(1); RELODONE;
138                         }
139         ;
140 #undef LISTLINE
141 #undef RELODONE
142 operation
143         :       /* empty */
144         |       IDENT '=' expr
145                         {
146 #ifdef LISTING
147                                 if (listflag & 1)
148                                         listcolm += printx(VALWIDTH, $3.val);
149 #endif
150                                 newequate($1, $3.typ);
151                                 store($1, $3.val);
152                         }
153 #ifdef LISTING
154         |       LIST
155                         {       if ($1)
156                                         listtemp = listmode;
157                                 else if ((dflag & 01000) == 0)
158                                         listtemp = 0;
159                         }
160 #endif
161         |       SECTION IDENT
162                         {       newsect($2);}
163         |       COMMON IDENT ',' absexp
164                         {       newcomm($2, $4);}
165         |       BASE absexp
166                         {       if (pass == PASS_1) newbase($2);}
167         |       ASSERT expr
168                         {       if ($2.val == 0 && pass == PASS_3)
169                                         warning("assertion failed");
170                         }
171         |       SYMB STRING ',' expr    { o_it = last_it; }
172                 optabs2 optabs2
173                         {       if ((sflag & SYM_SMB) && PASS_SYMB) {
174 #ifndef ASLD
175                                         if (
176                                                 pass == PASS_3
177                                                 &&
178                                                 ($4.typ & S_TYP) == S_UND
179                                            ) {
180                                                 serror("expression undefined");
181                                                 relonami = -1;
182                                         }
183                                         if (
184                                                 PASS_SYMB
185                                                 &&
186                                                 ($4.typ & S_COM)
187                                            ) {
188                                                 /* No value is known at
189                                                    assembler time.
190                                                    Generate reference to other
191                                                    entry in name table
192                                                 */
193                                                 $4.typ = S_CRS;
194                                                 $4.val = new_string(o_it->i_name);
195                                                 relonami = 0;
196                                         }
197 #endif
198                                             
199                                         newsymb(
200                                                 *stringbuf ? stringbuf : (char *) 0,
201                                                 (short)(
202                                                         ($4.typ & (S_EXT|S_TYP))
203                                                         |
204                                                         ((unsigned short)$6<<8)
205                                                 ),
206                                                 (short)$7,
207                                                 $4.val
208                                         );
209                                 }
210                         }
211         |       SYMD STRING ','  absexp ',' absexp
212                         {       if ((sflag & SYM_SMB) && PASS_SYMB) {
213                                         newsymb(
214                                                 *stringbuf ? stringbuf : (char *) 0,
215                                                 (short)(
216                                                         (DOTTYP & (S_EXT|S_TYP))
217                                                         |
218                                                         ((unsigned short)$4<<8)
219                                                 ),
220                                                 (short)$6,
221                                                 (valu_t)DOTVAL
222                                         );
223                                 }
224                         }
225         |       LINE optabs1
226                         {       if ((sflag & SYM_LIN) && PASS_SYMB) {
227                                         if ($2)
228                                                 hllino = (short)$2;
229                                         else
230                                                 hllino++;
231                                         newsymb(
232                                                 (char *)0,
233                                                 (DOTTYP | S_LIN),
234                                                 hllino,
235                                                 (valu_t)DOTVAL
236                                         );
237                                 }
238                         }
239         |       FILe STRING
240                         {       if ((sflag & SYM_LIN) && PASS_SYMB) {
241                                         hllino = 0;
242                                         newsymb(
243                                                 stringbuf,
244                                                 (DOTTYP | S_FIL),
245                                                 0,
246                                                 (valu_t)DOTVAL
247                                         );
248                                 }
249                         }
250         |       EXTERN externlist
251         |       ALIGN optabs1
252                         {       align($2);}
253         |       SPACE absexp
254                         {       if (DOTSCT == NULL)
255                                         nosect();
256                                 DOTVAL += $2;
257                                 DOTSCT->s_zero += $2;
258                         }
259         |       DATA datalist
260         |       ASCII STRING
261                         {       emitstr($1);}
262         ;
263 externlist
264         :       IDENT
265                         {       $1->i_type |= S_EXT;}
266         |       externlist ',' IDENT
267                         {       $3->i_type |= S_EXT;}
268         ;
269 datalist
270         :       expr
271                         {
272 #ifdef RELOCATION
273                                 if (rflag != 0 && PASS_RELO)
274                                         newrelo($1.typ, (int)$<y_word>0|MACHREL_BWR);
275 #endif
276                                 emitx($1.val, (int)$<y_word>0);
277                         }
278         |       datalist ',' expr
279                         {
280 #ifdef RELOCATION
281                                 if (rflag != 0 && PASS_RELO)
282                                         newrelo($3.typ, (int)$<y_word>0|MACHREL_BWR);
283 #endif
284                                 emitx($3.val, (int)$<y_word>0);
285                         }
286         ;
287 expr    :       error
288                         {       serror("expr syntax err");
289                                 $$.val = 0; $$.typ = S_UND;
290                         }
291         |       NUMBER
292                         {       $$.val = $1; $$.typ = S_ABS;}
293         |       id_fb
294                         {       $$.val = load($1); 
295                                 last_it = $1;
296                                 $$.typ = $1->i_type & ~S_EXT;
297                         }
298         |       STRING
299                         {       if (stringlen != 1)
300                                         serror("too many chars");
301                                 $$.val = stringbuf[0];
302                                 $$.typ = S_ABS;
303                         }
304         |       ASC_LPAR expr ASC_RPAR
305                         {       $$ = $2;}
306         |       expr OP_OO expr
307                         {       $$.val = ($1.val || $3.val);
308                                 $$.typ = combine($1.typ, $3.typ, 0);
309                         }
310         |       expr OP_AA expr
311                         {       $$.val = ($1.val && $3.val);
312                                 $$.typ = combine($1.typ, $3.typ, 0);
313                         }
314         |       expr '|' expr
315                         {       $$.val = ($1.val | $3.val);
316                                 $$.typ = combine($1.typ, $3.typ, 0);
317                         }
318         |       expr '^' expr
319                         {       $$.val = ($1.val ^ $3.val);
320                                 $$.typ = combine($1.typ, $3.typ, 0);
321                         }
322         |       expr '&' expr
323                         {       $$.val = ($1.val & $3.val);
324                                 $$.typ = combine($1.typ, $3.typ, 0);
325                         }
326         |       expr OP_EQ expr
327                         {       $$.val = ($1.val == $3.val);
328                                 $$.typ = combine($1.typ, $3.typ, '>');
329                         }
330         |       expr OP_NE expr
331                         {       $$.val = ($1.val != $3.val);
332                                 $$.typ = combine($1.typ, $3.typ, '>');
333                         }
334         |       expr '<' expr
335                         {       $$.val = ($1.val < $3.val);
336                                 $$.typ = combine($1.typ, $3.typ, '>');
337                         }
338         |       expr '>' expr
339                         {       $$.val = ($1.val > $3.val);
340                                 $$.typ = combine($1.typ, $3.typ, '>');
341                         }
342         |       expr OP_LE expr
343                         {       $$.val = ($1.val <= $3.val);
344                                 $$.typ = combine($1.typ, $3.typ, '>');
345                         }
346         |       expr OP_GE expr
347                         {       $$.val = ($1.val >= $3.val);
348                                 $$.typ = combine($1.typ, $3.typ, '>');
349                         }
350         |       expr OP_RR expr
351                         {       $$.val = ($1.val >> $3.val);
352                                 $$.typ = combine($1.typ, $3.typ, 0);
353                         }
354         |       expr OP_LL expr
355                         {       $$.val = ($1.val << $3.val);
356                                 $$.typ = combine($1.typ, $3.typ, 0);
357                         }
358         |       expr '+' expr
359                         {       $$.val = ($1.val + $3.val);
360                                 $$.typ = combine($1.typ, $3.typ, '+');
361                         }
362         |       expr '-' expr
363                         {       $$.val = ($1.val - $3.val);
364                                 $$.typ = combine($1.typ, $3.typ, '-');
365                         }
366         |       expr '*' expr
367                         {       $$.val = ($1.val * $3.val);
368                                 $$.typ = combine($1.typ, $3.typ, 0);
369                         }
370         |       expr '/' expr
371                         {       if ($3.val == 0) {
372                                         if (pass == PASS_3)
373                                                 serror("divide by zero");
374                                         $$.val = 0;
375                                 } else
376                                         $$.val = ($1.val / $3.val);
377                                 $$.typ = combine($1.typ, $3.typ, 0);
378                         }
379         |       expr '%' expr
380                         {       if ($3.val == 0) {
381                                         if (pass == PASS_3)
382                                                 serror("divide by zero");
383                                         $$.val = 0;
384                                 } else
385                                         $$.val = ($1.val % $3.val);
386                                 $$.typ = combine($1.typ, $3.typ, 0);
387                         }
388         |       '+' expr %prec '*'
389                         {       $$.val = $2.val;
390                                 $$.typ = combine(S_ABS, $2.typ, 0);
391                         }
392         |       '-' expr %prec '*'
393                         {       $$.val = -$2.val;
394                                 $$.typ = combine(S_ABS, $2.typ, 0);
395                         }
396         |       '~' expr
397                         {       $$.val = ~$2.val;
398                                 $$.typ = combine(S_ABS, $2.typ, 0);
399                         }
400         |       DOT
401                         {       $$.val = DOTVAL;
402                                 $$.typ = DOTTYP|S_DOT;
403                         }
404         ;
405 id_fb   :       IDENT
406         |       FBSYM
407         ;
408 absexp  :       expr
409                         {       if (($1.typ & ~S_EXT) != S_ABS)
410                                         serror("must be absolute");
411                                 $$ = $1.val;
412                         }
413         ;
414 optabs1
415         :       /* empty */
416                         {       $$ = 0;}
417         |       absexp
418                         {       $$ = $1;}
419         ;
420 optabs2
421         :       /* empty */
422                         {       $$ = 0;}
423         |       ',' absexp
424                         {       $$ = $2;}
425         ;
426
427 /* ========== Machine dependent rules ========== */
428
429 #include        "mach4.c"
430
431 %%