Pristine Ack-5.5
[Ack-5.5.git] / lang / basic / src / basic.g
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5
6 %token ILLEGAL ;
7 %token ASSYM ;
8 %token BASESYM ;
9 %token CALLSYM ;
10 %token CLEARSYM ;
11 %token CLOSESYM ;
12 %token DATASYM ;
13 %token DEFINTSYM ;
14 %token DEFSNGSYM ;
15 %token DEFDBLSYM ;
16 %token DEFSTRSYM ;
17 %token DEFSYM ;
18 %token DIMSYM ;
19 %token ELSESYM ;
20 %token ERRSYM ;
21 %token ERLSYM ;
22 %token ERRORSYM ;
23 %token FIELDSYM ;
24 %token FORSYM ;
25 %token FUNCTION ;
26 %token FUNCTID ;
27 %token INKEYSYM ;
28 %token GETSYM ;
29 %token GOSUBSYM ;
30 %token GOTOSYM ;
31 %token IFSYM ;
32 %token INPUTSYM ;
33 %token LETSYM ;
34 %token LINESYM ;
35 %token LSETSYM ;
36 %token MIDSYM ;
37 %token NEXTSYM ;
38 %token ONSYM ;
39 %token OPENSYM ;
40 %token OPTIONSYM ;
41 %token PRINTSYM ;
42 %token POKESYM ;
43 %token PUTSYM ;
44 %token RANDOMIZESYM ;
45 %token READSYM ;
46 %token REMSYM ;
47 %token RESTORESYM ;
48 %token RETURNSYM ;
49 %token ENDSYM ;
50 %token STOPSYM ;
51 %token STEPSYM ;
52 %token SWAPSYM ;
53 %token THENSYM ;
54 %token TOSYM ;
55 %token TRONOFFSYM ;
56 %token USINGSYM ;
57 %token USRSYM ;
58 %token WHILESYM ;
59 %token WENDSYM ;
60 %token WRITESYM ;
61 /* special tokens */
62 %token EOLN ;
63 %token INTVALUE ;
64 %token FLTVALUE ;
65 %token DBLVALUE ;
66 %token STRVALUE ;
67 %token UNARYSYM ;
68 %token IDENTIFIER ;
69 %token ANDSYM ;
70 %token ORSYM ;
71 %token IMPSYM ;
72 %token EQVSYM ;
73 %token XORSYM ;
74 %token VARPTR ;
75
76 /* Those were originally %left */
77 %token BOOLOP ;
78 %token NOTSYM ;
79 %token RELOP ;
80 %token MODSYM ;
81
82 /* Some contstant declared as tokens (?) */
83 %token LESYM ;
84 %token GESYM ;
85 %token NESYM ;
86 %token UNARYMINUS ;
87
88 {
89 #define YYDEBUG
90 #include "bem.h"
91 #include "llmess.c"
92
93 typedef union {
94         int     integer ;
95         Symbol  *Sptr ;
96         char    *cptr ;
97 } YYSTYPE ;
98
99 int basicline;
100  
101 int yydebug;
102
103 YYSTYPE yylval;
104
105 int     ival;
106 char    *dval;
107 char    *sval;
108 int     in_data = 0;    /* set if processing DATA statement */
109
110 char    *formatstring;  /* formatstring used for printing */
111 Symbol  *s;             /* Symbol dummy */
112
113 #include "yylexp.c"
114 #include "basic.lex"
115 }
116
117 %lexical yylexp;
118
119 %start LLparse,programline ;
120
121 programline
122         : INTVALUE
123           { basicline = ival;newblock(ival); newemblock(ival); }
124           stmts EOLN
125         | '#' INTVALUE STRVALUE EOLN
126         | EOLN
127         ;
128
129
130 stmts   : singlestmt
131         [ %while ( LLsymb == ':' ) ':' singlestmt ]*
132         ;
133
134 singlestmt { int d2 ; }
135         : callstmt
136         | clearstmt
137         | CLOSESYM closestmt
138         | datastmt
139         | defstmt
140         | defvarstmt
141         | dimstmt               
142         | ERRORSYM expression(&d2)      { errorstmt(d2); }
143         | fieldstmt
144         | forstmt
145         | getstmt
146         | gosubstmt
147         | onstmt
148         | ifstmt
149         | illegalstmt
150         | inputstmt
151         | letstmt
152         | lineinputstmt
153         | lsetstmt
154         | midstmt
155         | NEXTSYM nextstmt
156         | GOTOSYM INTVALUE                      { gotostmt(ival); }
157         | openstmt
158         | optionstmt
159         | pokestmt
160         | printstmt
161         | randomizestmt
162         | readstmt
163         | REMSYM                
164         | restorestmt
165         | returnstmt
166         | ENDSYM                { C_loc((arith) 0 );
167                                   C_cal("_hlt");
168                                   C_asp((arith) BEMINTSIZE);
169                                 }
170         | STOPSYM               { C_cal("_stop"); }
171         | swapstmt
172         | TRONOFFSYM            { tronoff=yylval.integer; }
173         | whilestmt
174         | wendstmt
175         | writestmt
176         | /* EMPTY STATEMENT */
177         ;
178
179 illegalstmt:    ILLEGAL         { illegalcmd(); }
180            ;
181
182 callstmt { Symbol *id; int i; }
183         :       CALLSYM
184                 IDENTIFIER      { id = yylval.Sptr; }
185                 [ parmlist(&i) 
186                                 { C_cal(id->symname);
187                                   C_asp((arith) (i*BEMPTRSIZE));
188                                 } 
189                 | /* empty */ 
190                                 { C_cal(id->symname); }
191                 ]
192         ;
193
194 parmlist(int *ip;)  { int var ; }
195         : '('
196           variable(&var)        { *ip = 1; }
197           [ ',' variable(&var)  { *ip = *ip + 1; } ]*
198           ')'
199         ;
200
201
202 clearstmt { int exp; }
203         :       CLEARSYM [ ',' expression(&exp) ]*2
204                                 { warning("statement ignored"); }
205         ;
206
207 closestmt:      filelist                
208         |       /* empty */     { C_cal("_close"); }
209         ;
210
211 filelist { int intv; }
212         :       cross
213                 intvalue(&intv)
214                                 { C_loc((arith) ival);
215                                   C_cal("_clochn");
216                                   C_asp((arith) BEMINTSIZE);
217                                 }
218                 [       ','
219                         cross
220                         intvalue(&intv)
221                                 { C_loc((arith) ival);
222                                   C_cal("_clochn");
223                                   C_asp((arith) BEMINTSIZE);
224                                 }
225                 ]* ;
226
227 datastmt:       DATASYM         { datastmt(); in_data = 1;}
228                 datalist        { fprint(datfile,"\n"); in_data = 0; }
229         ;
230
231 dataelm : INTVALUE              { fprint(datfile,"%d",ival); }
232         | '-' [ INTVALUE        { fprint(datfile,"%d",-ival); }
233               | FLTVALUE        { fprint(datfile,"-%s",dval); }
234               ]
235         | FLTVALUE              { fprint(datfile,dval); }
236         | STRVALUE              { fprint(datfile,"\"%s\"",sval); }
237         | IDENTIFIER            { fprint(datfile,"\"%s\"",sval); }
238         ;
239
240 datalist: dataelm
241           [ ','                 { fprint(datfile,","); } 
242           dataelm ]*
243         ;
244
245 defstmt : DEFSYM 
246           [ deffnstmt  
247           | defusrstmt
248           ]
249         ;
250
251 deffnstmt { int exp; }
252         : heading '=' expression(&exp) 
253                                 { endscope(exp); }
254         ;
255
256 heading : FUNCTID               { newscope(yylval.Sptr); }
257           [ '(' idlist ')' ]?   { heading(); }
258         ;
259
260 idlist : IDENTIFIER             { dclparm(yylval.Sptr); }
261          [ ',' IDENTIFIER       { dclparm(yylval.Sptr); } 
262          ]*
263         ;
264
265 defvarstmt:     DEFINTSYM       { setdefaulttype( INTTYPE); }
266         |       DEFSNGSYM       { setdefaulttype( FLOATTYPE); }
267         |       DEFDBLSYM       { setdefaulttype( DOUBLETYPE); }
268         |       DEFSTRSYM       { setdefaulttype( STRINGTYPE); }
269         ;
270
271 defusrstmt:     USRSYM ':'      { illegalcmd(); }
272           ;
273
274 dimstmt { Symbol *symp; }
275         :       DIMSYM arraydcl(&symp) ')'      { dclarray(symp); }
276         [       ',' arraydcl(&symp) ')'         { dclarray(symp); } 
277         ]*
278         ;
279
280 arraydcl(Symbol **sympp;)
281         : IDENTIFIER            { *sympp = s = yylval.Sptr; }
282           '('
283           INTVALUE
284                                 {
285                                         s->dimlimit[s->dimensions]=ival;
286                                         s->dimensions++;
287                                 }
288           [     ','
289                 INTVALUE
290                                 {
291                                         if(s->dimensions<MAXDIMENSIONS) {
292                                                 s->dimlimit[s->dimensions]=ival;
293                                                 s->dimensions++;
294                                         } else error("too many dimensions");
295                                 }
296           ]* ;
297
298 fieldstmt { int intv; }
299         :       FIELDSYM cross intvalue(&intv) 
300                                         { setchannel(ival); }
301                 ',' fieldlist           { notyetimpl(); }
302         ;
303
304 fieldlist { int intv; int var; }
305         :       intvalue(&intv) ASSYM variable(&var)
306                 [ ',' intvalue(&intv) ASSYM variable(&var) ]*
307         ;
308
309 forstmt { int exp; }
310         : FORSYM IDENTIFIER             { forinit(yylval.Sptr); }
311           '=' expression(&exp)          { forexpr(exp); }
312           TOSYM expression(&exp)        { forlimit(exp); }
313           step
314         ;
315
316 step { int exp; }
317         : STEPSYM expression(&exp)      { forstep(exp); }
318         | /*EMPTY*/                     { 
319                                                 C_loc((arith) 1);
320                                                 forstep(INTTYPE); 
321                                         }
322         ;
323
324 nextstmt: [ IDENTIFIER                  { nextstmt(yylval.Sptr); } 
325           | /* empty */                 { nextstmt((Symbol *)0); }
326           ]
327           [ ',' IDENTIFIER              { nextstmt(yylval.Sptr); } 
328           ]*
329           ;
330
331 getstmt { char *cp; int intv; }
332         : getput(&cp)
333           [ /* empty */ 
334                                 { C_loc((arith) 0);
335                                   C_cal(cp);
336                                   C_asp((arith) BEMINTSIZE);
337                                 }
338         | ',' intvalue(&intv)
339                                 { C_loc((arith) ival);
340                                   C_cal(cp);
341                                   C_asp((arith) BEMINTSIZE);
342                                 }
343         ]
344         ;
345
346 getput(char **cpp;) { int intv; }
347         : GETSYM cross intvalue(&intv)
348                                 { setchannel(ival); 
349                                   *cpp = "$_getrec";
350                                 }
351         | PUTSYM cross intvalue(&intv)
352                                 { setchannel(ival); 
353                                   *cpp = "$_putsym";
354                                 }
355         ;
356
357 gosubstmt:      GOSUBSYM INTVALUE       { gosubstmt(ival); } 
358          ;
359
360 returnstmt:     RETURNSYM               { returnstmt(); } 
361           ;
362
363 ifstmt { int exp; int d1; }
364         :       IFSYM expression(&exp)  { d1=ifstmt(exp); }
365                 thenpart                { d1=thenpart(d1); }
366                 elsepart                { elsepart(d1); }
367         ;
368
369 thenpart:       THENSYM [ INTVALUE      { gotostmt(ival); }
370                         | stmts
371                         ]
372         |       GOTOSYM INTVALUE        { gotostmt(ival); }
373         ;
374
375 elsepart:       %prefer ELSESYM 
376                         [ INTVALUE      { gotostmt(ival); }
377                         | stmts
378                         ]
379         |       /* empty */
380         ;
381
382 inputstmt { int intv; }
383         :       INPUTSYM  [ semiprompt  readlist 
384                           | '#' intvalue(&intv)
385                                         { setchannel(ival); }
386                             ',' readlist
387                           ]
388         ;
389
390 semiprompt { int str; }
391         : semi STRVALUE         { str = yylval.integer; }
392           [ ';'                 { loadstr(str); 
393                                   prompt(1); 
394                                 }
395           | ','                 { loadstr(str); 
396                                   prompt(0); 
397                                 }
398           ]
399         | /*EMPTY*/
400                                 { setchannel(-1);
401                                   C_cal("_qstmark"); 
402                                 }
403         ;
404
405 semi    : ';'
406         | /* empty */
407         ;
408
409 letstmt { int var; int exp; }
410         :       LETSYM          
411                 variable(&var)           { save_address(); }
412                 '=' expression(&exp)     { assign(var,exp); }
413         |
414                 variable(&var)           { save_address(); }
415                 '=' expression(&exp)     { assign(var,exp); }
416         ;
417
418 lineinputstmt { int var; int intv; }
419         :       LINESYM
420                 [ INPUTSYM
421                   semiprompt             { setchannel(-1); }
422                   variable(&var)         { linestmt(var); } 
423                 | '#'
424                   intvalue(&intv)        { setchannel(ival); }
425                   ','
426                   variable(&var)         { linestmt(var); }
427                 ]
428         ;
429
430 readlist: readelm               
431           [ ',' readelm ]*
432           ;
433
434 readelm { int var; }
435         : variable(&var)        { readelm(var); }
436         ;
437
438 lsetstmt { int var; int exp; }
439         :       LSETSYM variable(&var) '=' expression(&exp)
440                                 { notyetimpl(); }
441         ;
442
443 midstmt { int exp; }
444         :       MIDSYM '$'  midparms '=' expression(&exp) 
445                                 { C_cal("_midstmt");
446                                   C_asp((arith) (2*BEMINTSIZE + 2*BEMPTRSIZE));
447                                 }
448         ;
449
450 midparms:       '(' midfirst midsec midthird ')' 
451         ;
452
453 midfirst { int exp; }
454         : expression(&exp)      { conversion(exp,STRINGTYPE); } 
455         ;
456
457 midsec { int exp; }
458         : ',' expression(&exp)  { conversion(exp,INTTYPE); } 
459         ;
460
461 midthird { int exp; }
462         : ',' expression(&exp)  { conversion(exp,INTTYPE); }
463         | /* empty */           { C_loc((arith) -1); }
464         ;
465
466 onstmt : ONSYM 
467          [ exceptionstmt
468          | ongotostmt
469          ]
470          ;
471
472 exceptionstmt:  ERRORSYM GOTOSYM INTVALUE       { exceptstmt(ival); }
473              ;
474
475 ongotostmt { int exp; }
476         :       expression(&exp) 
477                 [ GOSUBSYM constantlist         { ongosubstmt(exp); }
478                 | GOTOSYM constantlist          { ongotostmt(exp); }
479                 ]
480         ;
481         
482 constantlist: INTVALUE          { jumpelm(ival); }
483               [ ',' INTVALUE    { jumpelm(ival); } 
484               ]* 
485             ;
486
487 openstmt { int exp; }
488         :       OPENSYM mode openchannel expression(&exp) 
489                                 { conversion(exp,STRINGTYPE); }
490                 [ /* empty */   { openstmt(0);  }
491                 | INTVALUE      { openstmt(ival); }
492                 ]
493         ;
494
495 openchannel: cross INTVALUE ',' { setchannel(ival); } 
496            ;
497
498 mode { int exp; }
499         : expression(&exp) ','  { conversion(exp,STRINGTYPE); }
500         | ','                   { C_lae_dnam("_iomode",(arith)0); }
501         ;
502
503 optionstmt { int intv; }
504         :       OPTIONSYM BASESYM intvalue(&intv) { optionbase(ival); }
505         ;
506
507 printstmt { int plist; }
508         :       PRINTSYM
509                 [ /* empty */   { setchannel(-1);
510                                   C_cal("_nl"); 
511                                 }
512                 | file format printlist(&plist) 
513                                 { if(plist) 
514                                   C_cal("_nl");            
515                                 }
516                 ]
517         ;
518
519 file { int intv; }
520         : '#' intvalue(&intv) ','       { setchannel(ival); }
521         | /* empty */                   { setchannel(-1); }
522         ;
523
524 format { int var ; }
525         : USINGSYM
526           [ STRVALUE            { loadstr(yylval.integer); } ';'                
527           | variable(&var) ';'
528                                 { if(var!=STRINGTYPE) 
529                                         error("string variable expected"); 
530                                 }
531           ]
532         | /* empty */           { formatstring=0; }
533         ;
534
535 printlist(int *ip;) { int exp; }
536         : [ expression(&exp)            { printstmt(exp); *ip=1; }
537           | ','                         { zone(1); *ip=0; }
538           | ';'                         { zone(0); *ip=0; }
539           ]+
540         ;
541
542 pokestmt { int exp1; int exp2 ; }
543         : POKESYM
544           expression(&exp1)
545           ','
546           expression(&exp2)     { pokestmt(exp1,exp2); }
547         ;
548
549 randomizestmt { int exp; }
550         :       RANDOMIZESYM 
551                 [ /* empty */           { C_cal("_randomi"); }
552                 | expression(&exp)
553                                         { conversion(exp,INTTYPE);
554                                           C_cal("_setrand");
555                                           C_asp((arith) BEMINTSIZE);     
556                                         } 
557                 ]
558         ;
559
560 readstmt { int var; }
561         :       READSYM                 { setchannel(0); }
562                 variable(&var)          { readelm(var); }
563                 [ ',' variable(&var)    { readelm(var); } 
564                 ]*
565         ;
566
567 restorestmt :   RESTORESYM
568                 [ INTVALUE      { restore(ival); }
569                 | /* empty */   { restore(0); }
570                 ]
571             ;
572         
573 swapstmt { int var1; int var2; }
574         : SWAPSYM
575           variable(&var1)
576           ','
577           variable(&var2)       { swapstmt(var1,var2); }
578         ;
579
580 whilestmt { int exp; }
581         : WHILESYM               { whilestart(); }
582           expression(&exp)       { whiletst(exp); }
583         ;
584
585 wendstmt :      WENDSYM          { wend(); }
586          ;
587
588 writestmt:      WRITESYM
589                 [ /* empty */           { setchannel(-1);
590                                           C_cal("_wrnl");    
591                                         }
592                 | file writelist        { C_cal("_wrnl");  }
593                 ]
594         ;
595
596 writelist { int exp; }
597         : expression(&exp)              { writestmt(exp,0); }
598           [ ',' expression(&exp)        { writestmt(exp,1); } 
599           ]*
600         ;
601
602 cross: '#' | /* empty */ ;      
603
604 intvalue(int *ip;)
605         : INTVALUE      { *ip = yylval.integer; } 
606         ;
607
608 variable(int *ip;) { Symbol *symp; int exp; }
609         : identifier(&symp)
610           [ %avoid /* empty */          { *ip = loadaddr(symp); }
611           | '('                         { newarrayload(symp); } 
612             expression(&exp)            { loadarray(exp); }
613             [ ',' expression(&exp)      { loadarray(exp); } ]*
614             ')'                         { *ip = endarrayload(); }
615           ]
616         | ERRSYM                        { C_lae_dnam("_errsym",(arith) 0); 
617                                           *ip = INTTYPE; 
618                                         } 
619         | ERLSYM                        { C_lae_dnam("_erlsym",(arith) 0); 
620                                           *ip = INTTYPE; 
621                                         }
622         ;
623
624 expression(int *ip;) { int neg; } /* NIEUW */
625         : expression1(&neg)             { *ip = neg; } 
626           [
627             IMPSYM
628             expression(&neg)            { *ip = boolop(*ip,neg,IMPSYM); }
629           ]?
630         ;
631
632
633 expression1(int *ip;) { int neg; }
634         : expression2(&neg)     { *ip = neg; } 
635           [ EQVSYM
636             expression2(&neg)   { *ip = boolop(*ip,neg,EQVSYM); }
637           ]*
638         ;
639
640 expression2(int *ip;) { int neg; } 
641         : expression3(&neg)     { *ip = neg; } 
642           [ XORSYM
643             expression3(&neg)   { *ip = boolop(*ip,neg,XORSYM); }
644           ]*
645         ;
646
647 expression3(int *ip;) { int neg; }
648         : expression4(&neg)     { *ip = neg; } 
649           [ ORSYM
650             expression4(&neg)   { *ip = boolop(*ip,neg,ORSYM); }
651           ]*
652         ;
653
654 expression4(int *ip;) { int neg; }
655         : negation(&neg)     { *ip = neg; } 
656           [ ANDSYM
657             negation(&neg)   { *ip = boolop(*ip,neg,ANDSYM); }
658           ]*
659         ;
660
661 negation(int *ip;) { int comp; }
662         : NOTSYM compare(&comp)         { *ip=boolop(comp,0,NOTSYM); }
663         | compare(ip)
664         ;
665
666 compare(int *ip;) { int sum1,sum2,rel; }
667         : sum(&sum1)
668           [ /* empty */      { *ip = sum1; }
669           | RELOP            { rel=yylval.integer; } 
670             sum(&sum2)       { *ip=relop(sum1,sum2,rel); }
671           | '=' sum(&sum2)   { *ip=relop(sum1,sum2,'='); }
672           ]
673         ;
674
675 sum(int *ip;) { int term1; }
676         : term(&term1)       { *ip = term1; }
677           [ %while(1)  
678             '-' term(&term1) { *ip=plusmin(*ip,term1,'-'); }
679           | '+' term(&term1) { *ip=plusmin(*ip,term1,'+'); }
680           ]*
681         ;
682
683 term(int *ip;) { int fac1; }    
684         : factor(&fac1)            { *ip = fac1; }
685           [ '*'    factor(&fac1)   { *ip=muldiv(*ip,fac1,'*'); }
686           | '\\'   factor(&fac1)   { *ip=muldiv(*ip,fac1,'\\'); }
687           | '/'    factor(&fac1)   { *ip=muldiv(*ip,fac1,'/'); }
688           | MODSYM factor(&fac1)   { *ip=muldiv(*ip,fac1,MODSYM); }
689           ]*
690         ;
691
692 factor(int *ip;)
693         : '-' factor(ip)         { *ip=negate(*ip); }
694         | factor1(ip)
695         ;
696
697 factor1(int *ip;)  { int mant,exp; }
698         : factor2(&mant)
699           [ /* empty */          { *ip = mant; } 
700           | '^' factor1(&exp)    { *ip = power(mant,exp); }
701           ]
702         ;
703
704 factor2(int *ip;)
705     { int var,func,expl,funcc,exp,intv,funcn,inpt; int typetable[10]; }
706         : INTVALUE                      { *ip=loadint(ival); }
707         | '(' expression(&exp) ')'      { *ip=exp; }
708         | FLTVALUE                      { *ip=loaddbl(dval); }
709         | STRVALUE              
710                                         { *ip= STRINGTYPE; 
711                                           loadstr(yylval.integer); 
712                                         }
713         | variable(&var)
714                                         { *ip=var; 
715                                           loadvar(var); 
716                                         }
717         | INKEYSYM '$'                  { C_cal("_inkey");
718                                           C_lfr((arith) BEMPTRSIZE);
719                                           *ip= STRINGTYPE;
720                                         }
721         | VARPTR '(' '#' intvalue(&intv) ')'
722                                         { warning("Not supported"); 
723                                           *ip=INTTYPE; 
724                                         }
725         | FUNCTION                      { func=yylval.integer; }                
726           [ %avoid /* empty */          { *ip= callfcn(yylval.integer,0, typetable); }
727           | '(' cross exprlist(&expl, typetable) ')' 
728                                         { *ip=callfcn(func,expl, typetable); }
729           ]
730         | funcname(&funcn)
731           [ %avoid /* empty */          { *ip=fcnend(0); }
732           | funccall(&funcc) ')'        { *ip=fcnend(funcc); }
733           ]
734         | MIDSYM '$' midparms   
735                                         { 
736                                           C_cal("_mid");
737                                           C_asp((arith) (2*BEMINTSIZE+BEMPTRSIZE));
738                                           C_lfr((arith) BEMPTRSIZE);
739                                           *ip= STRINGTYPE;
740                                         }
741         | INPUTSYM '$' '(' expression(&exp) inputtail(&inpt)
742                                         { /*waar worden inpt en  exp gebruikt?*/
743                                           C_cal("_inpfcn");
744                                           C_asp((arith) (2*BEMINTSIZE+BEMPTRSIZE));
745                                           *ip= STRINGTYPE;
746                                         }
747         ;
748
749 inputtail(int *ip;) { int exp; }
750         : ',' cross expression(&exp) ')'
751                                         { conversion(exp,INTTYPE); 
752                                           *ip= INTTYPE; 
753                                         }
754         | ')'
755                                         { C_loc((arith) -1);  
756                                           *ip= INTTYPE; 
757                                         }
758         ;
759
760 funcname(int *ip;)
761         : FUNCTID               { *ip=fcncall(yylval.Sptr); }
762         ;
763
764 funccall(int *ip;) { int exp; }
765         :  '(' expression(&exp) { callparm(0,exp);*ip=1; }
766         [ ',' expression(&exp)  { callparm(*ip,exp); 
767                                   *ip = *ip+1; 
768                                 } 
769         ]*
770         ;
771         
772 identifier(Symbol **ident;)
773         : IDENTIFIER            { dcltype(yylval.Sptr); 
774                                   *ident=yylval.Sptr; 
775                                 }
776         ;
777
778 exprlist(int *ip; int *typetable;) { int exp; }
779         : expression(&exp)              { typetable[0]=exp; 
780                                           *ip=1; 
781                                         }
782           [ ',' expression(&exp)        { typetable[*ip]=exp;
783                                           *ip = *ip+1; 
784                                         } 
785           ]*
786         ;
787
788 {
789 #ifndef NORCSID
790 static char rcs_id[]    = "$Id: basic.g,v 1.3 1994/06/24 11:30:24 ceriel Exp $" ;
791 #endif
792 }