3 * (C) Copyright Apr 15 1995, Edmond J. Breen.
5 * This code may be copied for personal, non-profit use only.
29 static int STRUCT_MEMBER_TYPE =0;
31 #define out_expr Outexpr
32 #define setInst(code,idx,mem,val) do { code_t *C__C = code;\
34 C__C->inst[idx].mem = val;\
38 void EiC_reset_env_pointers(token_t *e1,int bp);
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);
82 static eicstack_t breakstack = {0, NULL};
83 static eicstack_t contstack = {0, NULL};
84 static eicstack_t *casestack;
86 static int BREAK = 0, CONT = 0, CASEON;
90 void EiCp_freeLabels(Label_t *lab)
93 EiCp_freeLabels(lab->nxt);
99 Label_t * EiCp_addLabel(Label_t *lab,
105 if(chck) { /* check 4 duplicated labels */
108 if(strcmp(name, nlab->name) == 0)
109 EiC_error("Duplicate label %s",name);
114 nlab = xmalloc(sizeof(*nlab));
115 nlab->name = xmalloc(strlen(name)+1);
116 strcpy(nlab->name,name);
127 void addoffset(eicstack_t * S, int nxt, int offset)
131 for (i = nxt, v = &S->val[nxt]; i < S->n; ++v, ++i)
136 static void correctit(code_t * C, eicstack_t * S, int nxt, int loc)
142 EiC_eicpop(S, &addr);
143 C->inst[addr.ival].val.ival = loc-addr.ival;
147 static int comppair(const void * p1,const void * p2)
149 return ((pair_t*)p1)->match.ival -
150 ((pair_t*)p2)->match.ival;
153 void fixcasestack(token_t * e1, int nxt, int loc)
155 void qsort(void *base, size_t nm, size_t sz,
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;
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,
171 EiC_error("Illegal switch statement");
174 void EiC_initparser()
176 extern int EiC_ErrorRecover;
177 EiC_work_tab = stand_tab;
178 EiC_ErrorRecover = 0;
181 void EiC_parse(environ_t * env)
183 void EiC_comm_switch(void);
190 while ((t = EiC_lexan()) != DONE) {
193 if (t == ':') { /* get an EiC command */
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) ();
201 EiC_remsym(token->Val.sym);
202 EiC_error("Unknown EiC command");
204 } else if(token->Tok == '-')
207 EiC_error("Expected an EiC command");
210 } else if(t == '?') {
211 printf("\t If you want help, enter :help\n\n");
230 EiC_concode(&env->CODE, &e1.Code);
232 EiC_concode(&env->CODE, &e1.Code);
235 v.p.p = EiC_copytype(e1.Type);
237 v.p.p = EiC_addtype(t_void, NULL);
240 EiC_generate(&env->CODE, halt, &v, 0);
244 * local aggregate data
247 unsigned int EiC_ASPOT = 0;
248 static unsigned int MASPOT = 0, ADDLOCALS = 0;
250 void EiC_updateLocals(void)
252 if (EiC_ASPOT > MASPOT)
254 if (EiC_ENV->lsp > ADDLOCALS)
255 ADDLOCALS = EiC_ENV->lsp;
258 static void addinlocals(token_t * e1,int n)
264 v.ival = n + (MASPOT>0);
265 EiC_generate(&e2.Code, checkar, &v, 0);
266 setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
269 EiC_generate(&e2.Code, pushint, &v, 0);
270 setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
273 { /* correct for AAA location */
275 code_t *c = &e1->Code;
277 for(i = 0; i < N; ++i)
278 if(opcode(c,i) == lda && ivalcode(c,i) == -1)
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);
287 EiC_generate(&e1->Code, reducear, &v, 0);
288 setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
290 EiC_concode(&e2.Code, &e1->Code);
292 ADDLOCALS = EiC_ASPOT = MASPOT = 0;
295 static void block(token_t * e1)
299 while(EiC_ext_decl(&e2)) {
300 EiC_contoken(e1,&e2);
303 while (EiC_lexan() != '}' && token->Tok != DONE) {
307 if (token->Tok == DONE)
308 EiC_error("Expected }");
311 static void stmt1(token_t * e1)
313 void EiC_clearTempories();
317 switch (EiC_lexan()) {
318 case '{': /* compound statement */
327 EiC_clearTempories();
331 EiC_reset_env_pointers(e1, bp);
332 EiC_remlevel(EiC_S_LEVEL);
358 EiC_error("Unexpected declaration");
363 #if defined(ILOOKAHEAD) && (MAX_TOKENS > 1)
365 case ID: /* handle label statements */
366 if(EiC_lexan() == ':') {
367 extern int EiC_INFUNC;
370 EiC_error("Misplaced label statement");
372 e1->Code.labels = EiCp_addLabel(e1->Code.labels,
374 e1->Code.nextinst, 1);
385 EiC_match(';', " ; ");
388 /* to get here a statement was executed, therefore */
389 e1->Type = EiC_addtype(t_void, e1->Type);
390 EiC_clearTempories();
393 void EiC_stmt(token_t *e1)
395 static int Stmts = 0;
401 if (EiC_S_LEVEL == 1 && Stmts == 0) {
404 addinlocals(e1,ADDLOCALS);
408 static void label_stmt(token_t * e1)
411 EiC_error("Illegal label");
414 if (token->Tok == casesym) {
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);
432 EiC_error("Must be integer type");
434 EiC_error("Must be const_expr type");
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;
447 static void select_stmt(token_t * e1)
454 if (token->Tok == ifsym) {
455 EiC_match('(', " ( ");
459 t = EiC_gettype(e2.Type);
461 EiC_match(')', " ) ");
462 EiC_contoken(e1, &e2);
463 u1.ival = e1->Code.nextinst;
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);
473 setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
475 setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
479 } else {/* switchsym */
485 nxtbreak = breakstack.n;
486 EiC_match('(', " (");
488 EiC_match(')', " )");
490 casestack = (eicstack_t *) xcalloc(1, sizeof(eicstack_t));
492 EiC_eicpush(casestack, u1); /* push dummy for default */
493 EiC_contoken(e1, &e2);
495 loc = e1->Code.nextinst;
496 EiC_generate(&e1->Code, jmptab, &u1, 0);
498 fixcasestack(e1, nxtbreak, loc);
505 static void testfortype(token_t *e1, int NoVoid)
507 int t = EiC_gettype(e1->Type);
508 if(!isArithmetic(t) && t != t_pointer) {
511 EiC_error("Void expression");
513 EiC_warningerror("Possible non relational operation");
517 static void genJump(token_t *e1, val_t *v, int t,int T)
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}};
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);
530 case t_long: case t_ulong:
531 EiC_generate(&e1->Code, tab[T][1], v, 0);
533 case t_float: case t_double:
534 EiC_generate(&e1->Code, tab[T][2], v, 0);
537 EiC_generate(&e1->Code, tab[T][3], v, 0);
540 EiC_generate(&e1->Code, tab[T][4], v, 0);
547 static void iter_stmt(token_t * e1)
549 int t, rt,nxtbreak, nxtcont;
554 nxtbreak = breakstack.n;
555 nxtcont = contstack.n;
557 switch (token->Tok) {
559 u1.ival = e1->Code.nextinst;
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);
567 EiC_match(';', " ;");
570 rt = EiC_gettype(e2.Type);
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);
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> */
586 rt = EiC_gettype(e2.Type);
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);
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 */
611 rt = EiC_gettype(e2.Type);
613 EiC_match(';', " ; ");
614 out_expr(&e3); /* expr3 */
615 EiC_match(')', " ; ");
618 correctit(&e1->Code, &contstack,
619 nxtcont, e1->Code.nextinst);
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);
626 EiC_generate(&e1->Code, jmpu, &u1, 0);
628 genJump(e1,&u1,rt,1);
629 /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
631 setCodeLineNo(&e1->Code,e1->Code.nextinst -1, 0);
633 correctit(&e1->Code, &breakstack, nxtbreak,
640 static void jump_stmt(token_t * e1)
642 extern int EiC_INFUNC;
643 extern int EiC_RETURNON;
644 extern token_t *EiC_RETURNEXPR;
646 v.ival = e1->Code.nextinst;
647 switch (token->Tok) {
650 EiC_error("Misplaced goto statement");
652 if(EiC_lexan() != ID)
653 EiC_error("expected goto label");
655 EiC_generate(&e1->Code, jmpu, &v, 0);
656 e1->Code.gotos = EiCp_addLabel(e1->Code.gotos,
659 if(EiC_gettype(token->Val.sym->type) == ID)
660 EiC_remsym(token->Val.sym);
668 EiC_error("Misplaced break statement");
670 EiC_eicpush(&breakstack, v);
671 EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
672 EiC_match(';', " ;");
676 EiC_error("Misplaced continue statement");
678 EiC_eicpush(&contstack, v);
679 EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
680 EiC_match(';', " ;");
684 EiC_error("Misplaced return statement");
687 if (EiC_lexan() != ';') {
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");
701 if (isconst(e2.Type)) {
702 EiC_castconst(&e2, EiC_RETURNEXPR, 1);
706 EiC_castvar(&e2, EiC_RETURNEXPR, 0);
708 if(EiC_HasHiddenParm(EiC_RETURNEXPR->Type)) {
711 EiC_generate(&e1->Code,rvalptr,&v,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);
718 EiC_contoken(e1, &e2);
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);
728 static void generatePtr(token_t * e1)
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 */
734 e1->Val.p = EiC_ENV->AR[e1->Val.ival].v.p;
739 static void expr(token_t * e1)
741 /* really a comma expression */
746 EiC_assign_expr(&e2);
747 if(nextinst(&e1->Code))
749 EiC_concode(&e1->Code,&e2.Code);
750 EiC_freetype(e1->Type);
751 e1->Type = EiC_copytype(e2.Type);
752 e1->Pflag = e2.Pflag;
756 } while (EiC_lexan() == ',');
758 e1->Pflag = e2.Pflag;
765 static void Outexpr(token_t * e1)
767 /* really a comma expression */
772 EiC_assign_expr(&e2);
774 EiC_freetype(e1->Type);
775 EiC_concode(&e1->Code,&e2.Code);
776 e1->Type = EiC_copytype(e2.Type);
780 } while (EiC_lexan() == ',');
782 e1->Pflag = e2.Pflag;
790 void EiC_assign_expr(token_t * e1)
796 /* handle longjmp and setjmp */
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);
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);
818 switch (EiC_lexan()) {
825 case RSHTEQ: /* >>= */
826 case LSHTEQ: /* <<= */
830 assignop(EiC_assign_expr, e1, token->Tok);
839 extern void cond_expr(token_t * e1)
842 if (EiC_lexan() == '?') {
848 EiC_match(':', " :");
851 if(!isconst(e3.Type))
853 EiC_cast2comm(&e2, &e3);
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;
861 EiC_generate(&e1->Code, jmpFint, &v, 0);
866 EiC_contoken(e1, &e2);
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 */
878 static void fixit(code_t *C, int s)
881 for(i = s; i < C->nextinst;i++)
882 switch(C->inst[i].opcode) {
891 if(C->inst[i].val.ival == INT_MAX)
892 C->inst[i].val.ival = C->nextinst - i;
896 static void log_or_expr(token_t * e1)
898 void EiC_do_lor(token_t *, int);
900 if(EiC_lexan() == LOR) {
902 int nxt = e1->Code.nextinst;
903 EiC_do_lor(e1, INT_MAX);
907 EiC_do_lor(&e2,INT_MAX);
908 EiC_contoken(e1,&e2);
909 } while (EiC_lexan() == LOR);
910 fixit(&e1->Code,nxt);
915 static void log_and_expr(token_t * e1)
917 void EiC_do_land(token_t *, int);
919 if(EiC_lexan() == LAND) {
921 int nxt = e1->Code.nextinst;
922 EiC_do_land(e1, INT_MAX);
926 EiC_do_land(&e2,INT_MAX);
927 EiC_contoken(e1,&e2);
928 } while (EiC_lexan() == LAND);
929 fixit(&e1->Code,nxt);
934 static void inc_or_expr(token_t * e1)
937 while (EiC_lexan() == BOR)
938 process_binary(xor_expr, e1, BOR);
942 static void xor_expr(token_t * e1)
945 while (EiC_lexan() == XOR)
946 process_binary(and_expr, e1, XOR);
950 static void and_expr(token_t * e1)
953 while (EiC_lexan() == AND)
954 process_binary(equal_expr, e1, AND);
958 static void equal_expr(token_t * e1)
962 switch (EiC_lexan()) {
965 process_binary(rel_expr, e1, token->Tok);
973 static void rel_expr(token_t * e1)
977 switch (EiC_lexan()) {
982 process_binary(shift_expr, e1, token->Tok);
990 static void shift_expr(token_t * e1)
994 switch (EiC_lexan()) {
997 process_binary(add_expr, e1, token->Tok);
1005 static void add_expr(token_t * e1)
1009 switch (EiC_lexan()) {
1012 process_binary(mult_expr, e1, token->Tok);
1020 static void mult_expr(token_t * e1)
1024 switch (EiC_lexan()) {
1028 process_binary(cast_expr, e1, token->Tok);
1036 static void cast_expr(token_t * e1)
1038 if (EiC_lexan() != '(') {
1046 static void f_cast_expr(token_t * e1)
1049 switch (EiC_lexan()) {
1055 EiC_match(')', " )");
1057 if (isconst(e2.Type)) {
1059 EiC_castconst(&e2, e1, 1);
1063 EiC_castvar(&e2, e1, 1);
1064 e1->Pflag = e2.Pflag;
1066 /*e1->Val = e2.Val;*/
1068 EiC_contoken(e1, &e2);
1070 /* cast can't form lvalues */
1071 setConstp(e1->Type);
1075 EiC_match(')', " )");
1076 EiC_r_postfix_expr(e1);
1082 static void EiC_unary_expr(token_t * e1)
1088 case '+': /* unary - */
1089 case '-': /* unary + */
1090 case '*': /* indirection */
1091 case '~': /* ones complement */
1096 case INC: /* ++ lval */
1097 case DEC: /* -- lval */
1103 if(EiC_lexan() == '(') {
1104 switch(EiC_lexan()) {
1108 e1->Type = EiC_freetype(e1->Type);
1111 default: /* must be unary expr, i.e. ( expr ) */
1115 EiC_match(')', " )");
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 */
1125 e1->Val.uival = strlen(e1->Val.p.p) + 1;
1127 e1->Val.uival = EiC_get_sizeof(e1->Type);
1129 if(!e1->Val.uival || !e1->Type)
1130 EiC_error("Invalid argument to sizeof");
1132 e1->Type = EiC_freetype(e1->Type);
1134 e1->Type = EiC_addtype(t_uint, e1->Type);
1142 /* this section of code is an attempt to
1143 * to have constant addresses determined
1144 * at compile time (not finished)
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);
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;
1163 if(!isconst(e1->Type)) {
1176 EiC_error("Must have lvalue");
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));
1184 e1->Type = EiC_succType(e1->Type);
1189 EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
1192 EiC_exchtype(t_func, e1->Type);
1195 EiC_generate(&e1->Code, pushptr, &v, 0);
1198 EiC_error("Must have lvalue");
1200 e1->Type = EiC_addtype(t_pointer, e1->Type);
1202 } else /* nothing much to do */
1203 if(EiC_gettype(e1->Type) != t_pointer)
1204 EiC_error("Must have lvalue");
1213 if(e1->Sclass == c_register)
1214 EiC_error("Cannot apply & to a register variable");
1215 switch (EiC_gettype(e1->Type)) {
1227 EiC_error("Must have lvalue");
1229 e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
1230 EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
1234 e1->Type = EiC_succType(e1->Type);
1239 EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
1249 EiC_error("Must have lvalue");
1251 e1->Type = EiC_addtype(t_pointer, e1->Type);
1261 static void postfix_expr(token_t * e1)
1264 EiC_r_postfix_expr(e1);
1267 static void EiC_r_postfix_expr(token_t * e1)
1269 void derefConst(token_t *);
1270 void EiC_binhlval(int, token_t *, token_t *);
1273 switch ((t = EiC_lexan())) {
1278 EiC_do_inc_dec(e1, DEC);
1280 EiC_do_inc_dec(e1, INC);
1281 EiC_r_postfix_expr(e1);
1283 case '[': /* handle array indexing */
1285 process_binary(expr,e1,'+');
1286 EiC_unaryop(e1, '*');
1288 EiC_match(']', " ]");
1289 EiC_r_postfix_expr(e1);
1295 #if 0 /* this section of code was the start
1296 * of get EiC to determine where possible
1297 * addresses at compile time.
1299 if(!isconst(e1->Type))
1301 else /* else delay output */
1304 if (EiC_gettype(e1->Type) != t_pointer) {
1305 EiC_error("Pointer required");
1308 if(isconst(e1->Type))
1310 else if(isconstp(e1->Type))
1312 e1->Type = EiC_succType(e1->Type);
1316 setConstp(e1->Type);
1319 if(isconst(e1->Type))
1321 else if( isconstp(e1->Type))
1324 if(!isconst(e1->Type))
1326 if (EiC_gettype(e1->Type) == t_lval) {
1327 e1->Type = EiC_succType(e1->Type);
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) {
1337 S = (void *) EiC_getInf(e1->Type);
1338 if(!isconst(e1->Type)) {
1340 if (S->offset[t] > 0) {
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);
1347 } else if (S->offset[t] > 0) {
1348 /* handle constants */
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;
1357 EiC_freetype(e1->Type);
1358 e1->Type = EiC_copytype(S->type[t]);
1360 e1->Type = EiC_addtype(t_pointer,e1->Type);
1362 e1->Type = EiC_addtype(t_lval, e1->Type);
1364 if (EiC_gettype(token->Val.sym->type) == ID)
1365 EiC_remsym(token->Val.sym);
1367 EiC_error("Illegal structure operation");
1368 STRUCT_MEMBER_TYPE--;
1370 EiC_error("Illegal structure operation");
1374 setConstp(e1->Type);
1376 EiC_r_postfix_expr(e1);
1380 if (EiC_gettype(e1->Type) != t_pointer) {
1381 EiC_error("Pointer required");
1384 if(isconst(e1->Type) || isconstp(e1->Type))
1386 e1->Type = EiC_succType(e1->Type);
1388 setConstp(e1->Type);
1390 if(isconst(e1->Type) || isconstp(e1->Type))
1393 if (EiC_gettype(e1->Type) == t_lval) {
1394 e1->Type = EiC_succType(e1->Type);
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) {
1404 S = (void *) EiC_getInf(e1->Type);
1406 if (S->offset[t] > 0) {
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);
1413 EiC_freetype(e1->Type);
1414 e1->Type = EiC_copytype(S->type[t]);
1415 e1->Type = EiC_addtype(t_lval, e1->Type);
1417 if (EiC_gettype(token->Val.sym->type) == ID)
1418 EiC_remsym(token->Val.sym);
1420 EiC_error("Illegal structure operation");
1421 STRUCT_MEMBER_TYPE--;
1423 EiC_error("Illegal structure operation");
1425 setConstp(e1->Type);
1426 EiC_r_postfix_expr(e1);
1429 case '(': /* handle function calls */
1431 if(isconst(e1->Type)) {
1432 EiC_error("Function names cannot be constants");
1433 EiC_match(')', " )"); /* ignore up to next paren */
1437 if (EiC_gettype(e1->Type) != t_lval)
1441 if(nextType(e1->Type))
1442 e1->Type = EiC_succType(e1->Type);
1443 t=EiC_gettype(e1->Type);
1445 if(EiC_gettype(e1->Type) == t_pointer) {
1446 EiC_generate(&e1->Code,
1447 issafe(e1->Type)?drefptr:drefuptr,
1449 e1->Type = EiC_succType(e1->Type);
1452 t=EiC_gettype(e1->Type);
1455 if(t == t_func || t == t_funcdec || t == t_builtin) {
1457 if(EiC_getInf(e1->Type)) {
1464 c = arg_expr_list(e1,&e2);
1467 EiC_generate(&e1->Code, bump, &v, 0);
1470 EiC_generate(&e1->Code, checkar, &v, 1);
1472 EiC_contoken(e1, &e2);
1474 e1->Type = EiC_addtype(t_lval, e1->Type);
1477 EiC_error("Incorrect function usage: %s",
1480 EiC_error("Incorrect function usage: %s",
1483 EiC_match(')', " )");
1484 setConstp(e1->Type);
1485 EiC_r_postfix_expr(e1);
1494 static int arg_expr_list(token_t * E1, token_t * e1)
1496 int EiC_genCallBackCode(token_t * e1);
1497 token_t * EiC_genTemporay(type_expr *type, int level);
1499 int t, t2, Svar = 0, aggparm = 0;
1501 int ext = 0,count = 0;
1504 int EiC_IsFunc(int);
1508 if(EiC_HasHiddenParm(E1->Type)) {
1509 /* need to now generate temporary variable */
1510 e3 = EiC_genTemporay(nextType(E1->Type),EiC_S_LEVEL);
1512 /* concatenate code */
1513 EiC_concode(&e1->Code,&e3->Code);
1515 EiC_generate(&e1->Code, stoval, &e1->Val, t_hidden);
1520 f = EiC_getInf(E1->Type);
1521 BuiltIn = EiC_gettype(E1->Type) == t_builtin;
1525 EiC_assign_expr(&e2);
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);
1533 if ((t = EiC_gettype(e2.Type)) != t_void) {
1535 e1->Type = getFPty(f,Svar);
1537 t2 = EiC_gettype(e1->Type);
1539 EiC_error("Illegal parameter no. [%d]",count+1);
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);
1545 /* concatenate code */
1546 EiC_concode(&e2.Code,&e3->Code);
1550 EiC_generate(&e2.Code, bump, &v, t_hidden);
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);
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);
1565 EiC_castvar(&e2, e1, 0);
1566 } else { /* small bit of optimisation */
1568 EiC_castconst(&e2, e1, 0);
1571 if(aggparm) { /* passing a structure or union */
1572 v.ival = EiC_get_sizeof(e2.Type);
1573 EiC_generate(&e2.Code,refmem,&v,0);
1577 EiC_generate(&e2.Code, stoval, &v, EiC_gettype(e1->Type));
1580 /* collect parameters in reverse order */
1581 EiC_concode(&e2.Code, &e1->Code);
1583 EiC_freetype(e2.Type);
1586 if ((t2 != t_var) && (Svar < getFNp(f)-1))
1589 EiC_freetype(e2.Type);
1590 if (count + ext != 0) {
1591 EiC_error("Illegal void parameter no [%d]",count+1);
1595 if (EiC_lexan() != ',') {
1597 EiC_generate(&e1->Code, pushint, &v, 0);
1599 } while (token->Tok == ',');
1602 t = EiC_gettype(getFPty(f,0));
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",
1614 static void primary_expr(token_t * e1)
1616 extern int EiC_RETURNON;
1617 extern token_t *EiC_RETURNEXPR;
1619 switch (EiC_lexan()) {
1621 /*EiC_assign_expr(e1);*/
1623 EiC_match(')', " ) ");
1627 e1->Type = EiC_addtype(t_char, NULL);
1632 e1->Type = EiC_addtype(t_int, NULL);
1637 e1->Type = EiC_addtype(t_uint, NULL);
1642 e1->Type = EiC_addtype(t_long, NULL);
1647 e1->Type = EiC_addtype(t_ulong, NULL);
1653 e1->Type = EiC_addtype(t_double, NULL);
1658 e1->Type = EiC_addtype(t_float, NULL);
1663 e1->Type = EiC_addtype(t_pointer, EiC_addtype(t_char,NULL));
1666 xmark(e1->Val.p.p, eicgstring); /* garbage */
1667 else /* store string */
1668 EiC_add_func_str(EiC_getInf(EiC_RETURNEXPR->Type),
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;
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
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 */
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);
1709 e1->Type = EiC_addtype(t_void, e1->Type);
1714 int EiC_GI(token_t * e1)
1716 /* returns -1 on error,
1717 * 1 if the type is automatic
1721 return (e1->Sym->level > 1 && !(e1->Sym->sclass & c_static));
1727 static void process_binary(void (*func) (token_t * e),
1728 token_t * e1, int op)
1730 extern int EiC_checkPeepHole(token_t *e1,int op);
1742 if (!isconst(e1->Type))
1744 if (!isconst(e2.Type))
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);
1752 EiC_castvar(&e2,e1,1);
1754 EiC_freetype(e1->Type);
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);
1763 EiC_castvar(e1,&e2,1);
1769 EiC_bin_validate(op, e1, &e2);
1771 if (isconst(e1->Type) && isconst(e2.Type)) {
1772 EiC_contoken(e1, &e2);
1776 if (/*isconst(e1->Type) && */ !e1->Pflag)
1781 EiC_generate(&e1->Code, bump, &v, 0);
1783 EiC_contoken(e1, &e2);
1787 static void assignop(void (*func) (token_t * e),
1788 token_t * e1, int op)
1795 if (e1->Pflag || isconst(e1->Type) || isconstp(e1->Type))
1796 EiC_error("Illegal assignment operation");
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 */
1818 t = EiC_gettype(e1->Type);
1819 if((t == t_struct || t == t_union) && check4constmem(e1->Type))
1820 EiC_error("Illegal assignment operation");
1823 e2.Type = EiC_copytype(e1->Type);
1826 if (t == t_lval || t == t_struct || t == t_union) {
1828 EiC_generate(&e1->Code, dupval, &v, 0);
1830 EiC_concode(&e2.Code, &e1->Code);
1831 process_binary(func, &e2, op2);
1835 * check 4 assignment of pointer to const X to
1836 * pointer to X: this is illegal.
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");
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 &&
1853 /* Note: string is markged for garbage collector */
1854 EiC_SaveGlobalString(&e2.Val.p);
1859 EiC_castvar(&e2, e1, 0);
1862 EiC_error("Invalid assignment");
1864 if (t == t_lval || t == t_struct || t == t_union) {
1867 if(!e1->Code.nextinst) {
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);
1875 EiC_generate(&e1->Code, bump, &v, 0);
1879 EiC_concode(&e2.Code, &e1->Code);
1881 EiC_contoken(e1, &e2);
1882 EiC_do_stooutput(e1);
1883 /* assignments can't form lvalues */
1884 setConstp(e1->Type);
1887 static int findmem(type_expr * t, char *id)
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)
1898 static int check4constmem(type_expr *t)
1900 struct_t *S = (struct_t *)EiC_getInf(t);
1903 if(isconstp(S->type[i]))