Update the changelog
[opencv] / apps / cvenv / EiC / parser.c
1 /* parser.c
2  *
3  *      (C) Copyright Apr 15 1995, Edmond J. Breen.
4  *                 ALL RIGHTS RESERVED.
5  * This code may be copied for personal, non-profit use only.
6  *
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <limits.h>
12
13 #include "MachSet.h"
14 #include "global.h"
15 #include "lexer.h"
16 #include "func.h"
17 #include "typemod.h"
18 #include "xalloc.h"
19 #include "typesets.h"
20 #include "cdecl.h"
21 #include "error.h"
22 #include "symbol.h"
23 #include "parser.h"
24
25 typedef struct {
26     val_t match, loc;
27 } pair_t;
28
29 static int STRUCT_MEMBER_TYPE =0;
30
31 #define out_expr  Outexpr
32 #define setInst(code,idx,mem,val)  do { code_t *C__C = code;\
33                                             if(C__C->binst) \
34                                         C__C->inst[idx].mem = val;\
35                                     } while(0)
36
37
38 void EiC_reset_env_pointers(token_t *e1,int bp);
39
40 /** PROTOTYPES parser.c **/
41 static void correctit(code_t * C, eicstack_t * S, int nxt, int loc);
42 static void fixcasestack(token_t * e1, int nxt, int loc);
43 static void block(token_t * e1);
44 static void addinlocals(token_t * e1,int n);
45 static void label_stmt(token_t * e1);
46 static void testfortype(token_t *e1, int NoVoid);
47 static void genJump(token_t *e1, val_t *v, int t,int T);
48 static void select_stmt(token_t * e1);
49 static void iter_stmt(token_t * e1);
50 static void jump_stmt(token_t * e1);
51 static void Outexpr(token_t * e1);
52 static void expr(token_t * e1);
53 static void log_or_expr(token_t * e1);
54 static void log_and_expr(token_t * e1);
55 static void inc_or_expr(token_t * e1);
56 static void xor_expr(token_t * e1);
57 static void and_expr(token_t * e1);
58 static void equal_expr(token_t * e1);
59 static void rel_expr(token_t * e1);
60 static void shift_expr(token_t * e1);
61 static void add_expr(token_t * e1);
62 static void mult_expr(token_t * e1);
63 static void cast_expr(token_t * e1);
64 static void f_cast_expr(token_t * e1);
65 static void EiC_unary_expr(token_t * e1);
66 static void postfix_expr(token_t * e1);
67 static void EiC_r_postfix_expr(token_t * e1);
68 static int arg_expr_list(token_t * E1, token_t * e1);
69 static void primary_expr(token_t * e1);
70 static void process_binary(void (*func) (token_t * e),
71                     token_t * e1, int op);
72 static void assignop(void (*func) (token_t * e),
73               token_t * e1, int op);
74 static int findmem(type_expr * t, char *id);
75 static int check4constmem(type_expr * t);
76
77
78 int EiC_S_LEVEL;
79
80 static int NoPTR = 0;
81
82 static eicstack_t breakstack = {0, NULL};
83 static eicstack_t contstack = {0, NULL};
84 static eicstack_t *casestack;
85
86 static int BREAK = 0, CONT = 0, CASEON;
87
88 #if 1
89
90 void EiCp_freeLabels(Label_t *lab)
91 {
92     if(lab) {
93         EiCp_freeLabels(lab->nxt);
94         xfree(lab->name);
95         xfree(lab);
96     }
97 }
98
99 Label_t * EiCp_addLabel(Label_t *lab, 
100                         char *name, 
101                         int loc, int chck)
102 {
103     Label_t *nlab;
104
105     if(chck) { /* check 4 duplicated labels */
106         nlab = lab;
107         while(nlab) {   
108             if(strcmp(name, nlab->name) == 0) 
109                 EiC_error("Duplicate label %s",name);
110             nlab = nlab->nxt;
111         }
112     }
113     
114     nlab = xmalloc(sizeof(*nlab));
115     nlab->name = xmalloc(strlen(name)+1);
116     strcpy(nlab->name,name);
117     nlab->loc = loc;
118     
119     nlab->nxt = lab;
120
121     return nlab;
122 }
123
124 #endif
125
126     
127 void addoffset(eicstack_t * S, int nxt, int offset)
128 {
129     unsigned i;
130     val_t *v;
131     for (i = nxt, v = &S->val[nxt]; i < S->n; ++v, ++i)
132         v->ival += offset;
133 }
134
135
136 static void correctit(code_t * C, eicstack_t * S, int nxt, int loc)
137 {
138     val_t addr;
139     if(!C->binst)
140         return;
141     while (S->n > nxt) {
142         EiC_eicpop(S, &addr);
143         C->inst[addr.ival].val.ival =  loc-addr.ival;
144     }
145 }
146
147 static int comppair(const void * p1,const void * p2)
148 {
149     return ((pair_t*)p1)->match.ival - 
150         ((pair_t*)p2)->match.ival;
151 }
152
153 void fixcasestack(token_t * e1, int nxt, int loc)
154 {
155     void qsort(void *base, size_t nm, size_t sz,
156                int (*f)());
157     int i;
158     if (casestack->n > 0) {
159         correctit(&e1->Code, &breakstack, nxt, e1->Code.nextinst);
160         if (casestack->val[0].ival == 0)
161             casestack->val[0].ival = e1->Code.nextinst - loc;
162         else
163             casestack->val[0].ival -= loc;
164         for (i = 2; i < casestack->n; i += 2)
165             casestack->val[i].ival -= loc;
166         qsort(&casestack->val[1],
167               (casestack->n - 1) >> 1,
168               sizeof(val_t) << 1,
169               comppair);
170     } else
171         EiC_error("Illegal switch statement");
172 }
173
174 void EiC_initparser()
175 {
176     extern int EiC_ErrorRecover;
177     EiC_work_tab = stand_tab;
178     EiC_ErrorRecover = 0;
179 }
180
181 void EiC_parse(environ_t * env)
182 {
183     void EiC_comm_switch(void);
184     token_t e1;
185
186     val_t v;
187     int t;
188     EiC_S_LEVEL = 1;
189     EiC_inittoken(&e1);
190     while ((t = EiC_lexan()) != DONE) {
191         EiC_freetoken(&e1);
192         
193         if (t == ':') {         /* get an EiC command */
194             int h;
195             h = EiC_work_tab;
196             EiC_work_tab = eic_tab;
197             if (EiC_lexan() == ID) {
198                 if (EiC_gettype(token->Val.sym->type) == t_eic)
199                     (*token->Val.sym->val.func) ();
200                 else {
201                     EiC_remsym(token->Val.sym);
202                     EiC_error("Unknown EiC command");
203                 }
204             } else if(token->Tok == '-')
205                 EiC_comm_switch();
206             else
207                 EiC_error("Expected an EiC command");
208             EiC_work_tab = h;
209             continue;
210         } else if(t == '?') {
211           printf("\t If you want help, enter :help\n\n");
212           continue;
213         }
214           
215         retractlexan();
216
217 #if 1
218         switch(t) {
219           TYPEQUAL:
220           STORECLASS:
221           TYPESPEC:
222             EiC_ext_decl(&e1);
223             break;
224           default:
225             EiC_stmt(&e1);
226         }
227 #else
228         block(&e1);
229 #endif
230         EiC_concode(&env->CODE, &e1.Code);
231     }
232     EiC_concode(&env->CODE, &e1.Code);
233
234     if (e1.Type)
235         v.p.p = EiC_copytype(e1.Type);
236     else
237         v.p.p = EiC_addtype(t_void, NULL);
238
239     EiC_freetoken(&e1);
240     EiC_generate(&env->CODE, halt, &v, 0);
241 }
242 /*
243  * Globals used for
244  * local aggregate data
245  */
246
247 unsigned int EiC_ASPOT = 0;
248 static unsigned int MASPOT = 0, ADDLOCALS = 0;
249     
250 void EiC_updateLocals(void)
251 {    
252     if (EiC_ASPOT > MASPOT)
253         MASPOT = EiC_ASPOT;
254     if (EiC_ENV->lsp > ADDLOCALS)
255         ADDLOCALS = EiC_ENV->lsp;
256 }
257
258 static void addinlocals(token_t * e1,int n)
259 {
260     val_t v;
261     token_t e2;
262     
263     EiC_inittoken(&e2);
264     v.ival = n + (MASPOT>0);
265     EiC_generate(&e2.Code, checkar, &v, 0);
266     setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
267     if (MASPOT) {
268         v.ival = MASPOT;
269         EiC_generate(&e2.Code, pushint, &v, 0);
270         setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
271         v.ival = n;
272
273         { /* correct for AAA location */
274             int i, N;
275             code_t *c = &e1->Code;
276             N = nextinst(c);
277             for(i = 0; i < N; ++i)
278                 if(opcode(c,i) == lda && ivalcode(c,i) == -1)
279                     ivalcode(c,i) = n;
280         }
281         EiC_generate(&e2.Code, massign, &v, 1);
282         setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
283         EiC_generate(&e1->Code, fmem, &v, 1);
284         setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
285         v.ival = n;
286     }
287     EiC_generate(&e1->Code, reducear, &v, 0);
288     setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
289
290     EiC_concode(&e2.Code, &e1->Code);
291     e1->Code = e2.Code;
292     ADDLOCALS = EiC_ASPOT = MASPOT = 0;
293 }
294
295 static void block(token_t * e1)
296 {
297     token_t e2;
298     EiC_inittoken(&e2);
299     while(EiC_ext_decl(&e2)) {
300         EiC_contoken(e1,&e2);
301         EiC_inittoken(&e2);
302     }
303     while (EiC_lexan() != '}' && token->Tok != DONE) {
304         retractlexan();
305         EiC_stmt(e1);
306     }
307     if (token->Tok == DONE)
308         EiC_error("Expected }");
309 }
310
311 static void stmt1(token_t * e1)
312 {
313     void EiC_clearTempories();
314     int bp;
315     unsigned aspot;
316
317     switch (EiC_lexan()) {
318     case '{':                   /* compound statement */
319         EiC_S_LEVEL++;
320         bp = EiC_ENV->lsp;
321
322         aspot = EiC_ASPOT;
323
324             block(e1);
325
326         EiC_updateLocals();
327         EiC_clearTempories();
328         
329         EiC_ASPOT = aspot;
330
331         EiC_reset_env_pointers(e1, bp);
332         EiC_remlevel(EiC_S_LEVEL);
333         EiC_S_LEVEL--;
334         break;
335     case casesym:
336     case defaultsym:
337         label_stmt(e1);
338         break;
339     case gotosym:
340     case breaksym:
341     case continuesym:
342     case returnsym:
343         jump_stmt(e1);
344         break;
345     case ifsym:
346     case switchsym:
347         select_stmt(e1);
348         break;
349     case whilesym:
350     case dosym:
351     case forsym:
352         iter_stmt(e1);
353         break;
354     TYPEQUAL:
355     STORECLASS:
356     TYPESPEC:
357             
358         EiC_error("Unexpected declaration");
359         retractlexan();
360         EiC_ext_decl(e1);
361         break;
362
363 #if defined(ILOOKAHEAD) && (MAX_TOKENS > 1)
364
365         case ID: /* handle label statements */
366             if(EiC_lexan() == ':') {
367                 extern int EiC_INFUNC;
368                 retractlexan();
369                 if(!EiC_INFUNC) 
370                     EiC_error("Misplaced label statement");
371                 else {
372                     e1->Code.labels = EiCp_addLabel(e1->Code.labels,
373                                                 token->Val.sym->id,
374                                                 e1->Code.nextinst, 1);
375                     EiC_lexan();
376                 }
377                 break;
378             } else 
379                 retractlexan();
380 #endif
381
382         default:
383             retractlexan();
384             out_expr(e1);
385             EiC_match(';', " ; ");
386             return;
387     }
388     /* to get here a statement was executed, therefore */
389     e1->Type = EiC_addtype(t_void, e1->Type);    
390     EiC_clearTempories();
391 }
392
393 void EiC_stmt(token_t *e1)
394 {
395     static int Stmts = 0;
396     Stmts++;
397     
398     stmt1(e1);
399
400     Stmts--;
401     if (EiC_S_LEVEL == 1 && Stmts == 0) {
402         EiC_updateLocals();
403         if(ADDLOCALS > 0) 
404             addinlocals(e1,ADDLOCALS);
405     }
406 }
407
408 static void label_stmt(token_t * e1)
409 {
410     if (!CASEON) {
411         EiC_error("Illegal label");
412         return;
413     }
414     if (token->Tok == casesym) {
415         token_t e2;
416         int t;
417         val_t v;
418
419         EiC_inittoken(&e2);
420         EiC_assign_expr(&e2);
421         EiC_match(':', " :");
422         if (isconst(e2.Type)) {
423             t = EiC_gettype(e2.Type);
424             if (t >= t_char && t <= t_uint) {
425                 for (t = 1; t < casestack->n; t += 2)
426                     if (e2.Val.ival == casestack->val[t].ival)
427                         EiC_error("Duplicate case in switch");
428                 EiC_eicpush(casestack, e2.Val);
429                 v.ival = e1->Code.nextinst;
430                 EiC_eicpush(casestack, v);
431             } else
432                 EiC_error("Must be integer type");
433         } else
434             EiC_error("Must be const_expr type");
435         EiC_stmt(e1);
436         EiC_freetoken(&e2);
437     } else {                    /* default */
438         if (casestack->val[0].ival != 0)
439             EiC_error("Duplicate default in switch");
440         EiC_match(':', " :");
441         casestack->val[0].ival = e1->Code.nextinst;
442         EiC_stmt(e1);
443     }
444 }
445
446
447 static void select_stmt(token_t * e1)
448 {
449     int t;
450     token_t e2;
451     val_t u1;
452
453     EiC_inittoken(&e2);
454     if (token->Tok == ifsym) {
455         EiC_match('(', " ( ");
456         out_expr(&e2);
457
458         testfortype(&e2,1);
459         t = EiC_gettype(e2.Type);
460         
461         EiC_match(')', " ) ");
462         EiC_contoken(e1, &e2);
463         u1.ival = e1->Code.nextinst;
464         genJump(e1,&u1,t,0);
465         EiC_stmt(e1);
466
467         if (EiC_lexan() == elsesym) {
468             setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival+1);
469             u1.ival = e1->Code.nextinst;
470             EiC_generate(&e1->Code, jmpu, &u1, 0);
471             setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
472             EiC_stmt(e1);
473             setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
474         } else {
475             setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
476             retractlexan();
477         }
478
479     } else {/* switchsym */
480         int nxtbreak, loc;
481         eicstack_t *hold;
482
483         BREAK++;
484         CASEON++;
485         nxtbreak = breakstack.n;
486         EiC_match('(', " (");
487         out_expr(&e2);
488         EiC_match(')', " )");
489         hold = casestack;
490         casestack = (eicstack_t *) xcalloc(1, sizeof(eicstack_t));
491         u1.ival = 0;
492         EiC_eicpush(casestack, u1);     /* push dummy for default */
493         EiC_contoken(e1, &e2);
494         u1.p.p = casestack;
495         loc = e1->Code.nextinst;
496         EiC_generate(&e1->Code, jmptab, &u1, 0);
497         EiC_stmt(e1);
498         fixcasestack(e1, nxtbreak, loc);
499         casestack = hold;
500         BREAK--;
501         CASEON--;
502     }
503 }
504
505 static void testfortype(token_t *e1, int NoVoid)
506 {
507     int t = EiC_gettype(e1->Type);
508     if(!isArithmetic(t) && t != t_pointer) {
509         if(t == t_void) {
510             if(NoVoid)
511                 EiC_error("Void expression");
512         }else 
513             EiC_warningerror("Possible non relational operation");
514     }
515 }
516
517 static void genJump(token_t *e1, val_t *v, int t,int T)
518 {
519     /* 0 for false and 1 for True */
520     static int tab[2][5] = {{ jmpFint,jmpFlng,jmpFdbl,jmpFptr, jmpFllng},
521                             { jmpTint,jmpTlng,jmpTdbl,jmpTptr, jmpTllng}};
522     switch(t) {
523         default:
524             EiC_error("Undefined type for relational operation");
525         case t_char: case t_uchar: 
526         case t_short:case t_ushort:
527         case t_int:  case t_uint:
528             EiC_generate(&e1->Code, tab[T][0], v, 0);
529             break;
530         case t_long: case t_ulong:
531             EiC_generate(&e1->Code, tab[T][1], v, 0);
532             break;
533         case t_float: case t_double:
534             EiC_generate(&e1->Code, tab[T][2], v, 0);
535             break;
536         case t_pointer:
537             EiC_generate(&e1->Code, tab[T][3], v, 0);
538             break;
539         case t_llong:
540             EiC_generate(&e1->Code, tab[T][4], v, 0);
541             break;    
542
543     }
544 }
545
546
547 static void iter_stmt(token_t * e1)
548 {
549     int t, rt,nxtbreak, nxtcont;
550     val_t u1;
551     token_t e2, e3;
552     EiC_inittoken(&e2);
553     BREAK++, CONT++;
554     nxtbreak = breakstack.n;
555     nxtcont = contstack.n;
556
557     switch (token->Tok) {
558       case dosym:
559         u1.ival = e1->Code.nextinst;
560         EiC_stmt(e1);
561         if (EiC_lexan() != whilesym)
562             EiC_error("Missing while in do while statement");
563         EiC_match('(', " (");
564         correctit(&e1->Code, &contstack, nxtcont, e1->Code.nextinst);
565         out_expr(&e2);
566         EiC_match(')', ")");
567         EiC_match(';', " ;");
568         
569         testfortype(&e2,1);
570         rt = EiC_gettype(e2.Type);
571
572         EiC_contoken(e1, &e2);
573         u1.ival = u1.ival - e1->Code.nextinst;
574         genJump(e1,&u1,rt,1);
575         /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
576         correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);
577         break;
578       case whilesym:
579         u1.ival = e1->Code.nextinst;
580         EiC_generate(&e1->Code, jmpu, &u1, 0);
581         setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
582         EiC_match('(', " ( ");
583         out_expr(&e2);          /* <expr> */
584
585         testfortype(&e2,1);
586         rt = EiC_gettype(e2.Type);
587
588         EiC_match(')', " ) ");
589         EiC_stmt(e1);           /* <stmt> */
590         setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
591         t = e1->Code.nextinst;
592         EiC_contoken(e1, &e2);
593         u1.ival -= e1->Code.nextinst - 1;
594         genJump(e1,&u1,rt,1);
595         /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
596         setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
597         correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);
598         correctit(&e1->Code, &contstack, nxtcont, t);
599         break;
600       case forsym:
601         EiC_inittoken(&e3);
602
603         EiC_match('(', " ( ");
604         out_expr(e1);           /* expr1 */
605         EiC_match(';', " ; ");
606         u1.ival = e1->Code.nextinst;
607         EiC_generate(&e1->Code, jmpu, &u1, 0);
608         out_expr(&e2);          /* expr2 */
609
610         testfortype(&e2,0);
611         rt = EiC_gettype(e2.Type);
612         
613         EiC_match(';', " ; ");
614         out_expr(&e3);          /* expr3 */
615         EiC_match(')', " ; ");
616
617         EiC_stmt(e1);
618         correctit(&e1->Code, &contstack,
619                   nxtcont, e1->Code.nextinst);
620         
621         EiC_contoken(e1, &e3);
622         setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
623         EiC_contoken(e1, &e2);
624         u1.ival -= (e1->Code.nextinst - 1);
625         if (rt ==  t_void)
626             EiC_generate(&e1->Code, jmpu, &u1, 0);
627         else
628             genJump(e1,&u1,rt,1);
629            /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
630         
631         setCodeLineNo(&e1->Code,e1->Code.nextinst -1, 0);
632         
633         correctit(&e1->Code, &breakstack, nxtbreak,
634                   e1->Code.nextinst);
635         break;
636     }
637     BREAK--, CONT--;
638 }
639
640 static void jump_stmt(token_t * e1)
641 {
642     extern int EiC_INFUNC;
643     extern int EiC_RETURNON;
644     extern token_t *EiC_RETURNEXPR;
645     val_t v;
646     v.ival = e1->Code.nextinst;
647     switch (token->Tok) {
648         case gotosym:
649             if(!EiC_INFUNC) 
650                 EiC_error("Misplaced goto statement");
651             else {
652                 if(EiC_lexan() != ID)
653                     EiC_error("expected goto label");
654                 else {
655                     EiC_generate(&e1->Code, jmpu, &v, 0);
656                     e1->Code.gotos = EiCp_addLabel(e1->Code.gotos,
657                                                     token->Val.sym->id,
658                                                    v.ival, 0);
659                     if(EiC_gettype(token->Val.sym->type) == ID)
660                         EiC_remsym(token->Val.sym);
661                 }
662             }
663             break;
664
665             
666         case breaksym:
667             if (!BREAK)
668                 EiC_error("Misplaced break statement");
669             else
670                 EiC_eicpush(&breakstack, v);
671             EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
672             EiC_match(';', " ;");
673             break;
674         case continuesym:
675             if (!CONT)
676                 EiC_error("Misplaced continue statement");
677             else
678                 EiC_eicpush(&contstack, v);
679             EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
680             EiC_match(';', " ;");
681             break;
682         case returnsym:
683             if (!EiC_RETURNON)
684                 EiC_error("Misplaced return statement");
685             else {
686                 token_t e2;
687                 if (EiC_lexan() != ';') {
688                     retractlexan();
689                     EiC_inittoken(&e2);
690                     expr(&e2);
691                     /* catch dangling pointers */
692                     if(EiC_gettype(e2.Type) == t_pointer && e2.Sym) 
693                         if((EiC_gettype(e2.Sym->type) != t_pointer &&
694                             EiC_gettype(e2.Sym->type) != t_array)  && EiC_GI(&e2)) 
695                             EiC_warningerror("Possible dangling pointer");
696                     EiC_match(';', " ;");
697                     if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) == t_void &&
698                        EiC_gettype(e2.Type) != t_void)
699                         EiC_error("Illegal return type, expected void");
700                     
701                     if (isconst(e2.Type)) {
702                         EiC_castconst(&e2, EiC_RETURNEXPR, 1);
703                         EiC_output(&e2);
704                     } else {
705                         EiC_output(&e2);
706                         EiC_castvar(&e2, EiC_RETURNEXPR, 0);
707                     }
708                     if(EiC_HasHiddenParm(EiC_RETURNEXPR->Type)) {
709                         val_t v;
710                         v.ival = -1;
711                         EiC_generate(&e1->Code,rvalptr,&v,1);
712                         v.ival = 1;
713                         EiC_generate(&e1->Code,bump,&v,0);
714                         EiC_contoken(e1, &e2);
715                         v.ival = EiC_get_sizeof(nextType(EiC_RETURNEXPR->Type));
716                         EiC_generate(&e1->Code,refmem,&v,0);
717                     } else
718                         EiC_contoken(e1, &e2);
719                 } else
720                     if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) != t_void)
721                         EiC_warningerror("missing return value");
722                 EiC_generate(&e1->Code, eicreturn, &e1->Val, 0);
723             }
724             break;
725     }
726 }
727
728 static void generatePtr(token_t * e1)
729 {
730     if(!NoPTR && EiC_gettype(e1->Type) == t_array && !e1->Pflag) {
731         EiC_exchtype(t_pointer, e1->Type);
732         if(!EiC_GI(e1)) { /* static of global variable */
733             setConst(e1->Type);
734             e1->Val.p = EiC_ENV->AR[e1->Val.ival].v.p;
735         }
736     }
737 }
738
739 static void expr(token_t * e1)  
740 {
741     /* really a comma expression */
742     token_t e2;
743     int c = 0;
744     do {
745         EiC_inittoken(&e2);
746         EiC_assign_expr(&e2);
747         if(nextinst(&e1->Code))
748             EiC_output(e1);
749         EiC_concode(&e1->Code,&e2.Code);
750         EiC_freetype(e1->Type); 
751         e1->Type = EiC_copytype(e2.Type);
752         e1->Pflag = e2.Pflag;
753         EiC_freetoken(&e2);
754         c++;
755
756     } while (EiC_lexan() == ',');
757     retractlexan();
758     e1->Pflag = e2.Pflag;
759     e1->Sym = e2.Sym;
760     e1->Val = e2.Val;
761     if(c > 1)
762         setConstp(e1->Type);
763 }
764
765 static void Outexpr(token_t * e1) 
766 {
767     /* really a comma expression */
768     token_t e2;
769     int c = 0;
770     do {
771         EiC_inittoken(&e2);
772         EiC_assign_expr(&e2);
773         EiC_output(&e2);
774         EiC_freetype(e1->Type);
775         EiC_concode(&e1->Code,&e2.Code);
776         e1->Type = EiC_copytype(e2.Type);
777         EiC_freetoken(&e2);
778         c++;
779
780     } while (EiC_lexan() == ',');
781     retractlexan();
782     e1->Pflag = e2.Pflag;
783     e1->Sym = e2.Sym;
784     e1->Val = e2.Val;
785     if(c > 1)
786         setConstp(e1->Type);
787 }
788
789
790 void EiC_assign_expr(token_t * e1)
791 {
792
793 #if 1
794     int t = EiC_lexan();
795     
796     /* handle longjmp and setjmp */
797
798     if(t == eiclongjmpsym) {
799         EiC_generate(&e1->Code, __eiclongjmp, &e1->Val, EiC_GI(e1));
800         e1->Type = EiC_freetype(e1->Type);
801         e1->Type = EiC_addtype(t_void, e1->Type);
802         e1->Pflag = 1;
803         return;
804
805     } else if (t == eicsetjmpsym) {
806         EiC_generate(&e1->Code, __eicsetjmp, &e1->Val, EiC_GI(e1));
807         e1->Type = EiC_freetype(e1->Type);
808         e1->Type = EiC_addtype(t_int, e1->Type);
809         e1->Pflag = 1;
810         return;
811     } else
812         retractlexan();
813
814 #endif
815
816     cond_expr(e1);
817     while (1)
818         switch (EiC_lexan()) {
819           case ASS:             /* = */
820           case ADDEQ:           /* += */
821           case SUBEQ:           /* -= */
822           case DIVEQ:           /* /= */
823           case MULEQ:           /* *= */
824           case MODEQ:           /* %= */
825           case RSHTEQ:          /* >>= */
826           case LSHTEQ:          /* <<= */
827           case ANDEQ:           /* &= */
828           case BOREQ:           /* |= */
829           case XOREQ:           /* ^= */
830             assignop(EiC_assign_expr, e1, token->Tok);
831             break;
832           default:
833             retractlexan();
834             generatePtr(e1);
835             return;
836         }
837 }
838
839 extern void cond_expr(token_t * e1)
840 {
841     log_or_expr(e1);
842     if (EiC_lexan() == '?') {
843         val_t v;
844         int rt;
845         token_t e2, e3;
846         EiC_inittoken(&e2);
847         out_expr(&e2);
848         EiC_match(':', " :");
849         EiC_inittoken(&e3);
850         cond_expr(&e3);
851         if(!isconst(e3.Type))
852             EiC_output(&e3);
853         EiC_cast2comm(&e2, &e3);
854         EiC_output(&e3);
855         EiC_output(e1);
856         rt = EiC_gettype(e1->Type);
857         e1->Type = EiC_freetype(e1->Type);
858         e1->Type = EiC_copytype(e2.Type);
859         v.ival = e2.Code.nextinst + 2;
860 #if 0
861           EiC_generate(&e1->Code, jmpFint, &v, 0);
862 #else
863           genJump(e1,&v,rt,0);
864
865 #endif
866         EiC_contoken(e1, &e2);
867
868         v.ival = e1->Code.nextinst;
869         EiC_generate(&e1->Code, jmpu, &v, 0);
870         setInst(&e1->Code,v.ival,val.ival,e3.Code.nextinst+1);
871         EiC_contoken(e1, &e3);
872          /* conditional's  can't form lvalues */
873         setConstp(e1->Type);
874     } else
875         retractlexan();
876 }
877
878 static void fixit(code_t *C, int s)
879 {
880     int i;
881     for(i = s; i < C->nextinst;i++)
882         switch(C->inst[i].opcode) {
883           case jmpFint:
884           case jmpFlng:
885           case jmpFdbl:
886           case jmpFptr:
887           case jmpTint:
888           case jmpTlng:
889           case jmpTdbl:
890           case jmpTptr:
891             if(C->inst[i].val.ival == INT_MAX)
892                 C->inst[i].val.ival = C->nextinst - i;
893         }
894 }
895
896 static void log_or_expr(token_t * e1)
897 {
898     void EiC_do_lor(token_t *, int);
899     log_and_expr(e1);
900     if(EiC_lexan() == LOR) {
901         token_t e2;
902         int nxt = e1->Code.nextinst;
903         EiC_do_lor(e1, INT_MAX);
904         do {
905             EiC_inittoken(&e2);
906             log_and_expr(&e2);
907             EiC_do_lor(&e2,INT_MAX);
908             EiC_contoken(e1,&e2);
909         } while (EiC_lexan() == LOR);
910         fixit(&e1->Code,nxt);
911     }
912     retractlexan();
913 }
914
915 static void log_and_expr(token_t * e1)
916 {
917     void EiC_do_land(token_t *, int);
918     inc_or_expr(e1);
919     if(EiC_lexan() == LAND) {
920         token_t e2;
921         int nxt = e1->Code.nextinst;
922         EiC_do_land(e1, INT_MAX);
923         do {
924             EiC_inittoken(&e2);
925             inc_or_expr(&e2);
926             EiC_do_land(&e2,INT_MAX);
927             EiC_contoken(e1,&e2);
928         } while (EiC_lexan() == LAND);
929         fixit(&e1->Code,nxt);
930     }
931     retractlexan();
932 }
933
934 static void inc_or_expr(token_t * e1)
935 {
936     xor_expr(e1);
937     while (EiC_lexan() == BOR)
938         process_binary(xor_expr, e1, BOR);
939     retractlexan();
940 }
941
942 static void xor_expr(token_t * e1)
943 {
944     and_expr(e1);
945     while (EiC_lexan() == XOR)
946         process_binary(and_expr, e1, XOR);
947     retractlexan();
948 }
949
950 static void and_expr(token_t * e1)
951 {
952     equal_expr(e1);
953     while (EiC_lexan() == AND)
954         process_binary(equal_expr, e1, AND);
955     retractlexan();
956 }
957
958 static void equal_expr(token_t * e1)
959 {
960     rel_expr(e1);
961     while (1)
962         switch (EiC_lexan()) {
963           case EQ:
964           case NE:
965             process_binary(rel_expr, e1, token->Tok);
966             break;
967           default:
968             retractlexan();
969             return;
970         }
971 }
972
973 static void rel_expr(token_t * e1)
974 {
975     shift_expr(e1);
976     while (1)
977         switch (EiC_lexan()) {
978           case LT:
979           case LE:
980           case GT:
981           case GE:
982             process_binary(shift_expr, e1, token->Tok);
983             break;
984           default:
985             retractlexan();
986             return;
987         }
988 }
989
990 static void shift_expr(token_t * e1)
991 {
992     add_expr(e1);
993     while (1)
994         switch (EiC_lexan()) {
995           case LSHT:
996           case RSHT:
997             process_binary(add_expr, e1, token->Tok);
998             break;
999           default:
1000             retractlexan();
1001             return;
1002         }
1003 }
1004
1005 static void add_expr(token_t * e1)
1006 {
1007     mult_expr(e1);
1008     while (1)
1009         switch (EiC_lexan()) {
1010           case '+':
1011           case '-':
1012             process_binary(mult_expr, e1, token->Tok);
1013             break;
1014           default:
1015             retractlexan();
1016             return;
1017         }
1018 }
1019
1020 static void mult_expr(token_t * e1)
1021 {
1022     cast_expr(e1);
1023     while (1)
1024         switch (EiC_lexan()) {
1025           case '*':
1026           case '/':
1027           case '%':
1028             process_binary(cast_expr, e1, token->Tok);
1029             break;
1030           default:
1031             retractlexan();
1032             return;
1033         }
1034 }
1035
1036 static void cast_expr(token_t * e1)
1037 {
1038     if (EiC_lexan() != '(') {
1039         retractlexan();
1040         EiC_unary_expr(e1);
1041     } else {
1042         f_cast_expr(e1);
1043     }
1044 }
1045
1046 static void f_cast_expr(token_t * e1)
1047 {
1048     token_t e2;
1049     switch (EiC_lexan()) {
1050       TYPESPEC:
1051       TYPEQUAL:
1052         EiC_inittoken(&e2);
1053         retractlexan();
1054         EiC_type_name(e1);
1055         EiC_match(')', " )");
1056         cast_expr(&e2);
1057         if (isconst(e2.Type)) {
1058             setConst(e1->Type);
1059             EiC_castconst(&e2, e1, 1);
1060             e1->Val = e2.Val;
1061         } else {
1062             EiC_output(&e2);
1063             EiC_castvar(&e2, e1, 1);
1064             e1->Pflag = e2.Pflag;
1065             e1->Sym = e2.Sym;
1066             /*e1->Val = e2.Val;*/
1067         }
1068         EiC_contoken(e1, &e2);
1069         break;
1070         /* cast can't form lvalues */
1071         setConstp(e1->Type);
1072       default:
1073         retractlexan();
1074         expr(e1);
1075         EiC_match(')', " )");
1076         EiC_r_postfix_expr(e1);
1077         break;
1078     }
1079 }
1080
1081
1082 static void EiC_unary_expr(token_t * e1)
1083 {
1084     int t;
1085     
1086     t = EiC_lexan();
1087     switch (t) {
1088       case '+':                 /* unary - */
1089       case '-':                 /* unary + */
1090       case '*':                 /* indirection */
1091       case '~':                 /* ones complement */
1092       case NOT:                 /* */
1093         cast_expr(e1);
1094         EiC_unaryop(e1, t);
1095         return;
1096       case INC:                 /* ++ lval */
1097       case DEC:                 /* -- lval */
1098         EiC_unary_expr(e1);
1099         EiC_unaryop(e1, t);
1100         return;
1101       case sizeofsym:
1102         NoPTR++;
1103         if(EiC_lexan() == '(') {
1104             switch(EiC_lexan()) {
1105               TYPESPEC:
1106               TYPEQUAL:
1107                 retractlexan();
1108                 e1->Type = EiC_freetype(e1->Type);
1109                 EiC_type_name(e1);
1110                 break;
1111               default: /* must be unary expr, i.e. ( expr ) */
1112                 retractlexan();
1113                 expr(e1);
1114             }
1115             EiC_match(')', " )");
1116         } else {
1117             retractlexan();
1118             EiC_unary_expr(e1);
1119         }
1120         EiC_freecode(&e1->Code);
1121         if(isconst(e1->Type)  && 
1122            EiC_gettype(e1->Type) == t_pointer &&
1123            EiC_gettype(e1->Type->nxt) == t_char) /* hack for char */
1124                                                   /* constants */
1125                 e1->Val.uival = strlen(e1->Val.p.p) + 1;
1126             else
1127                 e1->Val.uival = EiC_get_sizeof(e1->Type);
1128    
1129         if(!e1->Val.uival || !e1->Type)
1130             EiC_error("Invalid argument to sizeof");
1131             
1132         e1->Type = EiC_freetype(e1->Type);
1133         
1134         e1->Type = EiC_addtype(t_uint, e1->Type);
1135         setConst(e1->Type);
1136         e1->Pflag = 0;
1137         NoPTR--;
1138         return;
1139
1140     case AND:
1141 #if 0
1142         /* this section of code is an attempt to
1143          * to have constant addresses determined
1144          * at compile time (not finished)
1145          */
1146         NoPTR++;
1147         cast_expr(e1);
1148         t = EiC_gettype(e1->Type);
1149         if(e1->Sclass == c_register)
1150             EiC_error("Cannot apply & to a register variable");
1151         /* check for global or static variable class */
1152         if(EiC_GI(e1) == 0 && !isconst(e1->Type) && t != t_lval) {
1153             void * EiC_getaddress(token_t * e1);
1154             ptr_t *p;
1155             if(t == t_union || t == t_struct)
1156                 e1->Type = EiC_addtype(t_pointer,e1->Type);
1157             p = EiC_getaddress(e1);
1158             e1->Val.p.sp = e1->Val.p.p = p;
1159             e1->Val.p.ep = (char *) p + SIZEOFTHETYPE;
1160             setConst(e1->Type);
1161         }
1162         
1163         if(!isconst(e1->Type)) {
1164             switch (t) {
1165             case t_char:
1166             case t_uchar:
1167             case t_short:
1168             case t_ushort:
1169             case t_int:
1170             case t_uint:
1171             CASE_LONG:
1172             CASE_ULONG:
1173             CASE_FLOAT:
1174             case t_pointer:
1175                 if (e1->Pflag)
1176                     EiC_error("Must have lvalue");
1177                 else {
1178                   if(isUnSafe(e1->Type))
1179                     e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
1180                   EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
1181                 }
1182                 break;
1183             case t_lval:
1184                 e1->Type = EiC_succType(e1->Type);
1185                 break;
1186             case t_struct:
1187             case t_union:
1188             case t_array:
1189                 EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
1190                 break;
1191             case t_funcdec:
1192                 EiC_exchtype(t_func, e1->Type);
1193             case t_func:
1194                 v.p.p = e1->Sym;
1195                 EiC_generate(&e1->Code, pushptr, &v, 0);
1196                 break;
1197             default:
1198                 EiC_error("Must have lvalue");
1199             }
1200             e1->Type = EiC_addtype(t_pointer, e1->Type);
1201             e1->Pflag = 1;
1202         } else  /* nothing much to do */
1203             if(EiC_gettype(e1->Type) != t_pointer)
1204                 EiC_error("Must have lvalue");
1205         NoPTR--;
1206         return;
1207     }
1208
1209 #else
1210         NoPTR++;
1211         cast_expr(e1);
1212         NoPTR--;
1213         if(e1->Sclass == c_register)
1214             EiC_error("Cannot apply & to a register variable");
1215         switch (EiC_gettype(e1->Type)) {
1216             case t_char:
1217             case t_uchar:
1218             case t_short:
1219             case t_ushort:
1220             case t_int:
1221             case t_uint:
1222         CASE_LONG:
1223         CASE_ULONG:
1224         CASE_FLOAT:
1225             case t_pointer:
1226                 if (e1->Pflag)
1227                     EiC_error("Must have lvalue");
1228                 else {
1229                     e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
1230                     EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
1231                 }       
1232                 break;
1233             case t_lval:
1234                 e1->Type = EiC_succType(e1->Type);
1235                 break;
1236             case t_struct:
1237             case t_union:
1238             case t_array:
1239                 EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
1240                 break;
1241
1242             case t_funcdec:
1243             case t_func:
1244             case t_builtin:
1245                 EiC_output(e1);
1246                 return;
1247
1248             default:
1249                 EiC_error("Must have lvalue");
1250         }
1251         e1->Type = EiC_addtype(t_pointer, e1->Type);
1252         e1->Pflag = 1;
1253         return;
1254     }
1255 #endif
1256
1257     retractlexan();
1258     postfix_expr(e1);
1259 }
1260
1261 static void postfix_expr(token_t * e1)
1262 {
1263     primary_expr(e1);
1264     EiC_r_postfix_expr(e1);
1265 }
1266
1267 static void EiC_r_postfix_expr(token_t * e1)
1268 {
1269     void derefConst(token_t *);
1270     void EiC_binhlval(int, token_t *, token_t *);
1271     
1272     int t,c = 0;
1273     switch ((t = EiC_lexan())) {
1274       case INC:
1275       case DEC:
1276         EiC_unaryop(e1, t);
1277         if (t == INC)
1278             EiC_do_inc_dec(e1, DEC);
1279         else
1280             EiC_do_inc_dec(e1, INC);
1281         EiC_r_postfix_expr(e1);
1282         break;
1283       case '[':                 /* handle array indexing */
1284
1285         process_binary(expr,e1,'+');
1286         EiC_unaryop(e1, '*');
1287         
1288         EiC_match(']', " ]");
1289         EiC_r_postfix_expr(e1);
1290
1291         break;
1292
1293     case RARROW:
1294
1295 #if 0   /* this section of code was the start
1296          * of get EiC to determine where possible
1297          * addresses at compile time.
1298          */
1299         if(!isconst(e1->Type))
1300             EiC_output(e1);
1301         else  /* else delay output */
1302             ;
1303             
1304         if (EiC_gettype(e1->Type) != t_pointer) {
1305             EiC_error("Pointer required");
1306             break;
1307         }
1308         if(isconst(e1->Type)) 
1309             c = 1;
1310         else if(isconstp(e1->Type))
1311             c = 2;
1312         e1->Type = EiC_succType(e1->Type);
1313         if(c==1)
1314             setConst(e1->Type);
1315         else if(c==2)
1316             setConstp(e1->Type);
1317         
1318       case '.':
1319         if(isconst(e1->Type)) 
1320             c  = 1;
1321         else if( isconstp(e1->Type))
1322             c = 2;
1323
1324         if(!isconst(e1->Type))
1325             EiC_output(e1);
1326         if (EiC_gettype(e1->Type) == t_lval) {
1327             e1->Type = EiC_succType(e1->Type);
1328             e1->Pflag = 1;
1329         }
1330         if (EiC_gettype(e1->Type) == t_struct ||
1331             EiC_gettype(e1->Type) == t_union) {
1332             STRUCT_MEMBER_TYPE++;
1333             if (EiC_lexan() == ID &&
1334                 (t = findmem(e1->Type, token->Val.sym->id)) >= 0) {
1335                 struct_t *S;
1336                 val_t v;
1337                 S = (void *) EiC_getInf(e1->Type);
1338                 if(!isconst(e1->Type)) {
1339                     EiC_output(e1);
1340                     if (S->offset[t] > 0) {
1341                         v.ival = 1;
1342                         EiC_generate(&e1->Code, bump, &v, 0);
1343                         v.ival = S->offset[t];
1344                         EiC_generate(&e1->Code, pushint, &v, 0);
1345                         EiC_generate(&e1->Code, addptr2int, &v, 0);
1346                     }
1347                 } else if (S->offset[t] > 0) {
1348                     /* handle constants */
1349
1350                     e1->Val.p.p = (char*) e1->Val.p.p + S->offset[t];
1351                     e1->Val.p.sp = e1->Val.p.p;
1352                     e1->Val.p.ep = (char *) e1->Val.p.p + 1;
1353                         
1354
1355                 }
1356                     
1357                 EiC_freetype(e1->Type);
1358                 e1->Type = EiC_copytype(S->type[t]);
1359                 if(c == 1)
1360                     e1->Type = EiC_addtype(t_pointer,e1->Type);             
1361                 else
1362                     e1->Type = EiC_addtype(t_lval, e1->Type);
1363                 e1->Pflag = 0;
1364                 if (EiC_gettype(token->Val.sym->type) == ID)
1365                     EiC_remsym(token->Val.sym);
1366             } else
1367                 EiC_error("Illegal structure operation");
1368             STRUCT_MEMBER_TYPE--;
1369         } else
1370             EiC_error("Illegal structure operation");
1371         if(c==1)
1372             setConst(e1->Type);
1373         else if(c==2)
1374             setConstp(e1->Type);
1375
1376         EiC_r_postfix_expr(e1);
1377         break;
1378 #else   
1379         EiC_output(e1);
1380         if (EiC_gettype(e1->Type) != t_pointer) {
1381             EiC_error("Pointer required");
1382             break;
1383         }
1384         if(isconst(e1->Type) || isconstp(e1->Type)) 
1385             c = 1;
1386         e1->Type = EiC_succType(e1->Type);
1387         if(c)
1388             setConstp(e1->Type);
1389       case '.':
1390         if(isconst(e1->Type) || isconstp(e1->Type))
1391             c  = 1;
1392         EiC_output(e1);
1393         if (EiC_gettype(e1->Type) == t_lval) {
1394             e1->Type = EiC_succType(e1->Type);
1395             e1->Pflag = 1;
1396         }
1397         if (EiC_gettype(e1->Type) == t_struct ||
1398             EiC_gettype(e1->Type) == t_union) {
1399             STRUCT_MEMBER_TYPE++;
1400             if (EiC_lexan() == ID &&
1401                 (t = findmem(e1->Type, token->Val.sym->id)) >= 0) {
1402                 struct_t *S;
1403                 val_t v;
1404                 S = (void *) EiC_getInf(e1->Type);
1405                 EiC_output(e1);
1406                 if (S->offset[t] > 0) {
1407                     v.ival = 1;
1408                     EiC_generate(&e1->Code, bump, &v, 0);
1409                     v.ival = S->offset[t];
1410                     EiC_generate(&e1->Code, pushint, &v, 0);
1411                     EiC_generate(&e1->Code, addptr2int, &v, 0);
1412                 }
1413                 EiC_freetype(e1->Type);
1414                 e1->Type = EiC_copytype(S->type[t]);
1415                 e1->Type = EiC_addtype(t_lval, e1->Type);
1416                 e1->Pflag = 0;
1417                 if (EiC_gettype(token->Val.sym->type) == ID)
1418                     EiC_remsym(token->Val.sym);
1419             } else
1420                 EiC_error("Illegal structure operation");
1421             STRUCT_MEMBER_TYPE--;
1422         } else
1423             EiC_error("Illegal structure operation");
1424         if(c)
1425             setConstp(e1->Type);
1426         EiC_r_postfix_expr(e1);
1427         break;
1428 #endif
1429         case '(':               /* handle function calls */
1430
1431             if(isconst(e1->Type)) {
1432                 EiC_error("Function names cannot be constants");
1433                 EiC_match(')', " )"); /* ignore up to next paren */
1434                 break;
1435             }
1436
1437             if (EiC_gettype(e1->Type) != t_lval)
1438                 EiC_output(e1);
1439         
1440
1441             if(nextType(e1->Type)) 
1442                 e1->Type = EiC_succType(e1->Type);
1443             t=EiC_gettype(e1->Type);
1444
1445             if(EiC_gettype(e1->Type) == t_pointer) {
1446                 EiC_generate(&e1->Code,
1447                          issafe(e1->Type)?drefptr:drefuptr,
1448                          &e1->Val,0);
1449                 e1->Type = EiC_succType(e1->Type);
1450             }
1451
1452             t=EiC_gettype(e1->Type);
1453
1454         
1455             if(t == t_func || t == t_funcdec || t == t_builtin) {
1456               
1457                 if(EiC_getInf(e1->Type)) {
1458                     val_t v;
1459                     token_t e2;
1460                     int c;
1461
1462                     EiC_inittoken(&e2);
1463
1464                     c = arg_expr_list(e1,&e2);
1465
1466                     v.ival = 1;
1467                     EiC_generate(&e1->Code, bump, &v, 0);
1468                     if (c) {
1469                         v.ival = c;
1470                         EiC_generate(&e1->Code, checkar, &v, 1);
1471                     }
1472                     EiC_contoken(e1, &e2);
1473                 
1474                     e1->Type = EiC_addtype(t_lval, e1->Type);
1475                     e1->Pflag = 0;
1476                 } else
1477                     EiC_error("Incorrect function usage: %s",
1478                           e1->Sym->id);
1479             } else
1480                 EiC_error("Incorrect function usage: %s",
1481                       e1->Sym->id);
1482         
1483             EiC_match(')', " )");
1484             setConstp(e1->Type);
1485             EiC_r_postfix_expr(e1);
1486             break;
1487         default:
1488             retractlexan();
1489     }    
1490 }
1491
1492
1493
1494 static int arg_expr_list(token_t * E1, token_t * e1)
1495 {
1496     int EiC_genCallBackCode(token_t * e1);
1497     token_t * EiC_genTemporay(type_expr *type, int level);
1498     token_t e2;
1499     int t, t2, Svar = 0, aggparm = 0;
1500     val_t v;
1501     int ext = 0,count = 0;
1502     func_t *f;
1503     token_t *e3;
1504     int EiC_IsFunc(int);
1505     int BuiltIn;
1506
1507
1508     if(EiC_HasHiddenParm(E1->Type)) {
1509         /* need to now generate temporary variable */
1510         e3 =  EiC_genTemporay(nextType(E1->Type),EiC_S_LEVEL);
1511         EiC_output(e3);
1512         /* concatenate code */
1513         EiC_concode(&e1->Code,&e3->Code);
1514         xfree(e3);
1515         EiC_generate(&e1->Code, stoval, &e1->Val, t_hidden);
1516         count++;
1517         ext = -1;
1518     }
1519
1520     f = EiC_getInf(E1->Type);
1521     BuiltIn = EiC_gettype(E1->Type) == t_builtin;
1522
1523     do {
1524         EiC_inittoken(&e2);
1525         EiC_assign_expr(&e2);
1526         if(BuiltIn) 
1527             if(EiC_IsFunc(EiC_gettype(e2.Type))) {
1528                 if(EiC_gettype(e2.Type) == t_pointer && EiC_IsFunc(EiC_gettype(nextType(e2.Type))))
1529                     e2.Type = EiC_succType(e2.Type);
1530                 EiC_genCallBackCode(&e2);
1531             }
1532         
1533         if ((t = EiC_gettype(e2.Type)) != t_void) {
1534
1535             e1->Type = getFPty(f,Svar);
1536
1537             t2 = EiC_gettype(e1->Type);
1538             if(t2 == t_void)
1539                 EiC_error("Illegal parameter no. [%d]",count+1);            
1540
1541             if(t == t_struct || t== t_union) {
1542                 if(!isconst(e2.Type) && !IsTemp(e2.Type)) {
1543                     e3 =  EiC_genTemporay(e2.Type,EiC_S_LEVEL);
1544                     EiC_output(e3);
1545                     /* concatenate code */
1546                     EiC_concode(&e2.Code,&e3->Code);
1547                     xfree(e3);
1548                     aggparm = 1;
1549                     v.ival = 1;
1550                     EiC_generate(&e2.Code, bump, &v, t_hidden);
1551                 }
1552                 if(t2 == t_var) /* EiC doesn't allow this */
1553                     EiC_error("passing a struct/union to variadic"
1554                                  " function `%s'",E1->Sym->id);
1555             }
1556                 
1557             if (!isconst(e2.Type)) {
1558                 if(BuiltIn && (EiC_IsFunc(EiC_gettype(e2.Type)))) { /* call back code */
1559                     v.p.p = getFcallBack((func_t*)EiC_getInf(e2.Type));
1560                     EiC_generate(&e2.Code,pushptr,&v,0);
1561                     e2.Type = EiC_addtype(t_pointer, e2.Type);
1562                 } else
1563                     EiC_output(&e2);
1564                 if (t2 != t_var)
1565                     EiC_castvar(&e2, e1, 0);
1566             } else {            /* small bit of optimisation */
1567                 if (t2 != t_var)
1568                     EiC_castconst(&e2, e1, 0);
1569                 EiC_output(&e2);
1570             }
1571             if(aggparm) { /* passing a structure or union */
1572                 v.ival = EiC_get_sizeof(e2.Type);
1573                 EiC_generate(&e2.Code,refmem,&v,0);
1574                 aggparm = 0;
1575             }
1576             v.ival = count;
1577             EiC_generate(&e2.Code, stoval, &v, EiC_gettype(e1->Type));
1578             
1579
1580             /* collect parameters in reverse order */
1581             EiC_concode(&e2.Code, &e1->Code);
1582             e1->Code = e2.Code;
1583             EiC_freetype(e2.Type);
1584             e1->Type = NULL;
1585             count++;
1586             if ((t2 != t_var) && (Svar < getFNp(f)-1))
1587                 Svar++;
1588         } else {
1589             EiC_freetype(e2.Type);
1590             if (count + ext != 0) {
1591                 EiC_error("Illegal void parameter no [%d]",count+1);
1592             } else
1593                 ext++;
1594         }
1595         if (EiC_lexan() != ',') {
1596             v.ival = count;
1597             EiC_generate(&e1->Code, pushint, &v, 0);
1598         }
1599     } while (token->Tok == ',');
1600     retractlexan();
1601
1602     t = EiC_gettype(getFPty(f,0));
1603
1604
1605     if((count == 0 && t != t_void && t != t_var) ||
1606        (count+ext != getFNp(f) && !EiC_IsVariadic(f) && t != t_var))
1607         EiC_error("Wrong number of arguments for %s",
1608               E1->Sym->id);                   
1609     
1610     return count;
1611 }
1612
1613
1614 static void primary_expr(token_t * e1)
1615 {
1616     extern int EiC_RETURNON;
1617     extern token_t *EiC_RETURNEXPR;
1618     
1619     switch (EiC_lexan()) {
1620       case '(':
1621         /*EiC_assign_expr(e1);*/
1622         expr(e1);
1623         EiC_match(')', " ) ");
1624         return;
1625       case CHAR:
1626         *e1 = *token;
1627         e1->Type = EiC_addtype(t_char, NULL);
1628         setConst(e1->Type);
1629         break;
1630       case INT:
1631         *e1 = *token;
1632         e1->Type = EiC_addtype(t_int, NULL);
1633         setConst(e1->Type);
1634         break;
1635       case UINT:
1636         *e1 = *token;
1637         e1->Type = EiC_addtype(t_uint, NULL);
1638         setConst(e1->Type);
1639         break;
1640       case LONG:
1641         *e1 = *token;
1642         e1->Type = EiC_addtype(t_long, NULL);
1643         setConst(e1->Type);
1644         break;
1645       case ULONG:
1646         *e1 = *token;
1647         e1->Type = EiC_addtype(t_ulong, NULL);
1648         setConst(e1->Type);
1649         break;
1650         
1651       case DOUBLE:
1652         *e1 = *token;
1653         e1->Type = EiC_addtype(t_double, NULL);
1654         setConst(e1->Type);
1655         break;  
1656       case FLOAT:
1657         *e1 = *token;
1658         e1->Type = EiC_addtype(t_float, NULL);
1659         setConst(e1->Type);
1660         break;
1661       case STR:
1662         *e1 = *token;
1663         e1->Type = EiC_addtype(t_pointer, EiC_addtype(t_char,NULL));
1664         setConst(e1->Type);
1665         if (!EiC_RETURNON)
1666             xmark(e1->Val.p.p, eicgstring); /* garbage */
1667         else    /* store string */
1668             EiC_add_func_str(EiC_getInf(EiC_RETURNEXPR->Type),
1669                          e1->Val.p.p);
1670         break;
1671       case ID:
1672
1673         e1->Type = EiC_copytype(token->Val.sym->type);
1674         e1->Val = token->Val.sym->val;
1675         e1->Sym = token->Val.sym;
1676         e1->Sclass = token->Val.sym->sclass;
1677  
1678
1679         if(EiC_gettype(e1->Type) == t_ref) {
1680           int t = EiC_gettype(nextType(e1->Type));
1681           if(t == t_funcdec) { 
1682             /* convert to builtin type
1683              *  happens only once 
1684              */
1685             e1->Type = EiC_succType(e1->Type);
1686             e1->Sym->type = EiC_succType(e1->Sym->type);
1687             EiC_exchtype(t_builtin,e1->Type);
1688             EiC_exchtype(t_builtin,e1->Sym->type);
1689             e1->Sym->val.vfunc = EiC_ENV->AR[e1->Val.ival].v.vfunc;
1690           } else if(t != t_array) { /* treat as an lvalue */
1691             EiC_output(e1);
1692             e1->Pflag = 0;
1693             e1->Type = EiC_succType(e1->Type);
1694             /*if(EiC_gettype(e1->Type) != t_pointer)*/
1695               e1->Type = EiC_addtype(t_lval,e1->Type);
1696           } else { /* make a safe pointer */
1697             e1->Type = EiC_succType(e1->Type);
1698             EiC_ENV->AR[e1->Val.ival].v.p.ep = 
1699              (char*) EiC_ENV->AR[e1->Val.ival].v.p.sp + EiC_get_sizeof(e1->Type);
1700             generatePtr(e1);
1701           }
1702         } /*else
1703             generatePtr(e1);*/
1704         
1705         break;
1706       default:
1707         retractlexan();
1708         e1->Pflag = 0;
1709         e1->Type = EiC_addtype(t_void, e1->Type);
1710         break;
1711     }
1712 }
1713
1714 int EiC_GI(token_t * e1)
1715 {
1716     /* returns -1 on error,
1717      *         1 if the type is automatic
1718      *         0  otherwise
1719      */
1720     if(e1 && e1->Sym)
1721         return (e1->Sym->level > 1 && !(e1->Sym->sclass & c_static));
1722     else
1723         return -1;
1724 }
1725
1726
1727 static void process_binary(void (*func) (token_t * e),
1728                     token_t * e1, int op)
1729 {
1730     extern int EiC_checkPeepHole(token_t *e1,int op);
1731     token_t e2;
1732     val_t v;
1733
1734
1735     EiC_inittoken(&e2);
1736
1737     (*func) (&e2);
1738
1739     generatePtr(&e2);
1740     generatePtr(e1);
1741     
1742     if (!isconst(e1->Type))
1743         EiC_output(e1);
1744     if (!isconst(e2.Type))
1745         EiC_output(&e2);
1746
1747     if(EiC_checkPeepHole(e1,op)) {
1748         if(EiC_gettype(e2.Type) < EiC_gettype(e1->Type)) {
1749             if(isconst(e2.Type))
1750                 EiC_castconst(&e2,e1,1);
1751             else
1752                 EiC_castvar(&e2,e1,1);
1753         }       
1754         EiC_freetype(e1->Type);
1755         *e1 = e2;
1756         return;
1757     }
1758     if(EiC_checkPeepHole(&e2,op)) {
1759         if(EiC_gettype(e2.Type) > EiC_gettype(e1->Type)) {
1760             if(isconst(e1->Type))
1761                 EiC_castconst(e1,&e2,1);
1762             else
1763                 EiC_castvar(e1,&e2,1);
1764         }
1765         EiC_freetoken(&e2);
1766         return;
1767     }
1768
1769     EiC_bin_validate(op, e1, &e2);
1770
1771     if (isconst(e1->Type) && isconst(e2.Type)) {
1772         EiC_contoken(e1, &e2);
1773         e1->Pflag = 0;
1774         return;
1775     }
1776     if (/*isconst(e1->Type) && */ !e1->Pflag)
1777         EiC_output(e1);
1778
1779     if(op != LAND) {
1780         v.ival = 1;
1781         EiC_generate(&e1->Code, bump, &v, 0);
1782     }
1783     EiC_contoken(e1, &e2);
1784 }
1785
1786
1787 static void assignop(void (*func) (token_t * e),
1788               token_t * e1, int op)
1789 {
1790     int t;
1791     token_t e2;
1792     val_t v;
1793     int op2;
1794
1795     if (e1->Pflag || isconst(e1->Type) || isconstp(e1->Type))
1796         EiC_error("Illegal assignment operation");
1797
1798     EiC_inittoken(&e2);
1799     
1800     generatePtr(&e2);
1801
1802     switch (op) {
1803       case ADDEQ: op2 = '+'; break;
1804       case SUBEQ: op2 = '-'; break;
1805       case DIVEQ: op2 = '/'; break;
1806       case MULEQ: op2 = '*'; break;
1807       case MODEQ: op2 = '%'; break;
1808       case RSHTEQ: op2 = RSHT; break;
1809       case LSHTEQ: op2 = LSHT; break;
1810       case ANDEQ: op2 = AND; break;
1811       case BOREQ: op2 = BOR; break;
1812       case XOREQ: op2 = XOR; break;
1813       default:                  /* do equals */
1814         op2 = 0;
1815         (*func) (&e2);
1816     }
1817
1818     t = EiC_gettype(e1->Type);
1819     if((t == t_struct || t == t_union) && check4constmem(e1->Type))
1820         EiC_error("Illegal assignment operation");
1821     
1822     if (op2) {
1823         e2.Type = EiC_copytype(e1->Type);
1824         e2.Val = e1->Val;
1825         e2.Sym = e1->Sym;
1826         if (t == t_lval || t == t_struct || t == t_union)  {
1827             v.ival = 1;
1828             EiC_generate(&e1->Code, dupval, &v, 0);
1829         }
1830         EiC_concode(&e2.Code, &e1->Code);
1831         process_binary(func, &e2, op2);
1832     }   
1833
1834     /*
1835      * check 4 assignment of pointer to const X to
1836      * pointer to X: this is illegal.
1837      */
1838     if(t == t_pointer && EiC_gettype(e2.Type) == t_pointer) {
1839         if(ConstIntegrity(nextType(e1->Type),nextType(e2.Type)))
1840             EiC_error("Assignment loses a const qualifier");
1841         if(!EiC_compareSafe(nextType(e1->Type),nextType(e2.Type)))
1842             EiC_error("Casting between safe and unsafe address");
1843     }
1844     
1845     if (isconst(e2.Type)) {
1846         void EiC_SaveGlobalString(ptr_t *s);
1847         extern int EiC_RETURNON;
1848         EiC_castconst(&e2, e1, 0);
1849         if(!EiC_RETURNON && EiC_gettype(e2.Type) == t_pointer
1850            && EiC_gettype(nextType(e2.Type)) == t_char &&
1851             !e2.Sym) {
1852             /* got string */
1853             /* Note: string is markged for garbage collector */
1854             EiC_SaveGlobalString(&e2.Val.p);
1855         }
1856         EiC_output(&e2);
1857     } else {
1858         EiC_output(&e2);
1859         EiC_castvar(&e2, e1, 0);
1860     }
1861     if (!e2.Pflag)
1862         EiC_error("Invalid assignment");
1863
1864     if (t == t_lval || t == t_struct || t == t_union) {
1865         if(!op2) {
1866             v.ival = 1;
1867             if(!e1->Code.nextinst) {
1868                 EiC_output(e1);
1869             }
1870             if(t==t_struct || t == t_union) {
1871                 EiC_generate(&e1->Code, bump, &v, 0);
1872                 v.ival = EiC_get_sizeof(e2.Type);
1873                 EiC_generate(&e2.Code,refmem,&v,0);
1874             } else
1875                 EiC_generate(&e1->Code, bump, &v, 0);
1876             
1877
1878         } else 
1879             EiC_concode(&e2.Code, &e1->Code);
1880     }
1881     EiC_contoken(e1, &e2);
1882     EiC_do_stooutput(e1);
1883     /* assignments can't form lvalues */
1884     setConstp(e1->Type);
1885 }
1886
1887 static int findmem(type_expr * t, char *id)
1888 {
1889     int i;
1890     struct_t *S = (struct_t *)EiC_getInf(t);
1891     for (i = 0; i < S->n; i++)
1892         if (strcmp(id, S->id[i]) == 0)
1893             return i;
1894
1895     return -1;
1896 }
1897
1898 static int check4constmem(type_expr *t)
1899 {
1900     struct_t *S = (struct_t *)EiC_getInf(t);
1901     int i;
1902     for(i=0;i<S->n;i++)
1903         if(isconstp(S->type[i]))
1904             return 1;
1905     return 0;
1906 }
1907         
1908