📄 parser.c
字号:
case DEC: EiC_unaryop(e1, t); if (t == INC) EiC_do_inc_dec(e1, DEC); else EiC_do_inc_dec(e1, INC); EiC_r_postfix_expr(e1); break; case '[': /* handle array indexing */ process_binary(expr,e1,'+'); EiC_unaryop(e1, '*'); EiC_match(']', " ]"); EiC_r_postfix_expr(e1); break; case RARROW:#if 0 /* this section of code was the start * of get EiC to determine where possible * addresses at compile time. */ if(!isconst(e1->Type)) EiC_output(e1); else /* else delay output */ ; if (EiC_gettype(e1->Type) != t_pointer) { EiC_error("Pointer required"); break; } if(isconst(e1->Type)) c = 1; else if(isconstp(e1->Type)) c = 2; e1->Type = EiC_succType(e1->Type); if(c==1) setConst(e1->Type); else if(c==2) setConstp(e1->Type); case '.': if(isconst(e1->Type)) c = 1; else if( isconstp(e1->Type)) c = 2; if(!isconst(e1->Type)) EiC_output(e1); if (EiC_gettype(e1->Type) == t_lval) { e1->Type = EiC_succType(e1->Type); e1->Pflag = 1; } if (EiC_gettype(e1->Type) == t_struct || EiC_gettype(e1->Type) == t_union) { STRUCT_MEMBER_TYPE++; if (EiC_lexan() == ID && (t = findmem(e1->Type, token->Val.sym->id)) >= 0) { struct_t *S; val_t v; S = (void *) EiC_getInf(e1->Type); if(!isconst(e1->Type)) { EiC_output(e1); if (S->offset[t] > 0) { v.ival = 1; EiC_generate(&e1->Code, bump, &v, 0); v.ival = S->offset[t]; EiC_generate(&e1->Code, pushint, &v, 0); EiC_generate(&e1->Code, addptr2int, &v, 0); } } else if (S->offset[t] > 0) { /* handle constants */ e1->Val.p.p = (char*) e1->Val.p.p + S->offset[t]; e1->Val.p.sp = e1->Val.p.p; e1->Val.p.ep = (char *) e1->Val.p.p + 1; } EiC_freetype(e1->Type); e1->Type = EiC_copytype(S->type[t]); if(c == 1) e1->Type = EiC_addtype(t_pointer,e1->Type); else e1->Type = EiC_addtype(t_lval, e1->Type); e1->Pflag = 0; if (EiC_gettype(token->Val.sym->type) == ID) EiC_remsym(token->Val.sym); } else EiC_error("Illegal structure operation"); STRUCT_MEMBER_TYPE--; } else EiC_error("Illegal structure operation"); if(c==1) setConst(e1->Type); else if(c==2) setConstp(e1->Type); EiC_r_postfix_expr(e1); break;#else EiC_output(e1); if (EiC_gettype(e1->Type) != t_pointer) { EiC_error("Pointer required"); break; } if(isconst(e1->Type) || isconstp(e1->Type)) c = 1; e1->Type = EiC_succType(e1->Type); if(c) setConstp(e1->Type); case '.': if(isconst(e1->Type) || isconstp(e1->Type)) c = 1; EiC_output(e1); if (EiC_gettype(e1->Type) == t_lval) { e1->Type = EiC_succType(e1->Type); e1->Pflag = 1; } if (EiC_gettype(e1->Type) == t_struct || EiC_gettype(e1->Type) == t_union) { STRUCT_MEMBER_TYPE++; if (EiC_lexan() == ID && (t = findmem(e1->Type, token->Val.sym->id)) >= 0) { struct_t *S; val_t v; S = (void *) EiC_getInf(e1->Type); EiC_output(e1); if (S->offset[t] > 0) { v.ival = 1; EiC_generate(&e1->Code, bump, &v, 0); v.ival = S->offset[t]; EiC_generate(&e1->Code, pushint, &v, 0); EiC_generate(&e1->Code, addptr2int, &v, 0); } EiC_freetype(e1->Type); e1->Type = EiC_copytype(S->type[t]); e1->Type = EiC_addtype(t_lval, e1->Type); e1->Pflag = 0; if (EiC_gettype(token->Val.sym->type) == ID) EiC_remsym(token->Val.sym); } else EiC_error("Illegal structure operation"); STRUCT_MEMBER_TYPE--; } else EiC_error("Illegal structure operation"); if(c) setConstp(e1->Type); EiC_r_postfix_expr(e1); break;#endif case '(': /* handle function calls */ if(isconst(e1->Type)) { EiC_error("Function names cannot be constants"); EiC_match(')', " )"); /* ignore up to next paren */ break; } if (EiC_gettype(e1->Type) != t_lval) EiC_output(e1); if(nextType(e1->Type)) e1->Type = EiC_succType(e1->Type); t=EiC_gettype(e1->Type); if(EiC_gettype(e1->Type) == t_pointer) { EiC_generate(&e1->Code, issafe(e1->Type)?drefptr:drefuptr, &e1->Val,0); e1->Type = EiC_succType(e1->Type); } t=EiC_gettype(e1->Type); if(t == t_func || t == t_funcdec || t == t_builtin) { if(EiC_getInf(e1->Type)) { val_t v; token_t e2; int c; EiC_inittoken(&e2); c = arg_expr_list(e1,&e2); v.ival = 1; EiC_generate(&e1->Code, bump, &v, 0); if (c) { v.ival = c; EiC_generate(&e1->Code, checkar, &v, 1); } EiC_contoken(e1, &e2); e1->Type = EiC_addtype(t_lval, e1->Type); e1->Pflag = 0; } else EiC_error("Incorrect function usage: %s", e1->Sym->id); } else EiC_error("Incorrect function usage: %s", e1->Sym->id); EiC_match(')', " )"); setConstp(e1->Type); EiC_r_postfix_expr(e1); break; default: retractlexan(); } }static int arg_expr_list(token_t * E1, token_t * e1){ int EiC_genCallBackCode(token_t * e1); token_t * EiC_genTemporay(type_expr *type, int level); token_t e2; int t, t2, Svar = 0, aggparm = 0; val_t v; int ext = 0,count = 0; func_t *f; token_t *e3; int EiC_IsFunc(int); int BuiltIn; if(EiC_HasHiddenParm(E1->Type)) { /* need to now generate temporary variable */ e3 = EiC_genTemporay(nextType(E1->Type),EiC_S_LEVEL); EiC_output(e3); /* concatenate code */ EiC_concode(&e1->Code,&e3->Code); xfree(e3); EiC_generate(&e1->Code, stoval, &e1->Val, t_hidden); count++; ext = -1; } f = EiC_getInf(E1->Type); BuiltIn = EiC_gettype(E1->Type) == t_builtin; do { EiC_inittoken(&e2); EiC_assign_expr(&e2); if(BuiltIn) if(EiC_IsFunc(EiC_gettype(e2.Type))) { if(EiC_gettype(e2.Type) == t_pointer && EiC_IsFunc(EiC_gettype(nextType(e2.Type)))) e2.Type = EiC_succType(e2.Type); EiC_genCallBackCode(&e2); } if ((t = EiC_gettype(e2.Type)) != t_void) { e1->Type = getFPty(f,Svar); t2 = EiC_gettype(e1->Type); if(t2 == t_void) EiC_error("Illegal parameter no. [%d]",count+1); if(t == t_struct || t== t_union) { if(!isconst(e2.Type) && !IsTemp(e2.Type)) { e3 = EiC_genTemporay(e2.Type,EiC_S_LEVEL); EiC_output(e3); /* concatenate code */ EiC_concode(&e2.Code,&e3->Code); xfree(e3); aggparm = 1; v.ival = 1; EiC_generate(&e2.Code, bump, &v, t_hidden); } if(t2 == t_var) /* EiC doesn't allow this */ EiC_error("passing a struct/union to variadic" " function `%s'",E1->Sym->id); } if (!isconst(e2.Type)) { if(BuiltIn && (EiC_IsFunc(EiC_gettype(e2.Type)))) { /* call back code */ v.p.p = getFcallBack((func_t*)EiC_getInf(e2.Type)); EiC_generate(&e2.Code,pushptr,&v,0); e2.Type = EiC_addtype(t_pointer, e2.Type); } else EiC_output(&e2); if (t2 != t_var) EiC_castvar(&e2, e1, 0); } else { /* small bit of optimisation */ if (t2 != t_var) EiC_castconst(&e2, e1, 0); EiC_output(&e2); } if(aggparm) { /* passing a structure or union */ v.ival = EiC_get_sizeof(e2.Type); EiC_generate(&e2.Code,refmem,&v,0); aggparm = 0; } v.ival = count; EiC_generate(&e2.Code, stoval, &v, EiC_gettype(e1->Type)); /* collect parameters in reverse order */ EiC_concode(&e2.Code, &e1->Code); e1->Code = e2.Code; EiC_freetype(e2.Type); e1->Type = NULL; count++; if ((t2 != t_var) && (Svar < getFNp(f)-1)) Svar++; } else { EiC_freetype(e2.Type); if (count + ext != 0) { EiC_error("Illegal void parameter no [%d]",count+1); } else ext++; } if (EiC_lexan() != ',') { v.ival = count; EiC_generate(&e1->Code, pushint, &v, 0); } } while (token->Tok == ','); retractlexan(); t = EiC_gettype(getFPty(f,0)); if((count == 0 && t != t_void && t != t_var) || (count+ext != getFNp(f) && !EiC_IsVariadic(f) && t != t_var)) EiC_error("Wrong number of arguments for %s", E1->Sym->id); return count;}static void primary_expr(token_t * e1){ extern int EiC_RETURNON; extern token_t *EiC_RETURNEXPR; switch (EiC_lexan()) { case '(': /*EiC_assign_expr(e1);*/ expr(e1); EiC_match(')', " ) "); return; case CHAR: *e1 = *token; e1->Type = EiC_addtype(t_char, NULL); setConst(e1->Type); break; case INT: *e1 = *token; e1->Type = EiC_addtype(t_int, NULL); setConst(e1->Type); break; case UINT: *e1 = *token; e1->Type = EiC_addtype(t_uint, NULL); setConst(e1->Type); break; case LONG: *e1 = *token; e1->Type = EiC_addtype(t_long, NULL); setConst(e1->Type); break; case ULONG: *e1 = *token; e1->Type = EiC_addtype(t_ulong, NULL); setConst(e1->Type); break; case DOUBLE: *e1 = *token; e1->Type = EiC_addtype(t_double, NULL); setConst(e1->Type); break; case FLOAT: *e1 = *token; e1->Type = EiC_addtype(t_float, NULL); setConst(e1->Type); break; case STR: *e1 = *token; e1->Type = EiC_addtype(t_pointer, EiC_addtype(t_char,NULL)); setConst(e1->Type); if (!EiC_RETURNON) xmark(e1->Val.p.p, eicgstring); /* garbage */ else /* store string */ EiC_add_func_str(EiC_getInf(EiC_RETURNEXPR->Type), e1->Val.p.p); break; case ID: e1->Type = EiC_copytype(token->Val.sym->type); e1->Val = token->Val.sym->val; e1->Sym = token->Val.sym; e1->Sclass = token->Val.sym->sclass; if(EiC_gettype(e1->Type) == t_ref) { int t = EiC_gettype(nextType(e1->Type)); if(t == t_funcdec) { /* convert to builtin type * happens only once */ e1->Type = EiC_succType(e1->Type); e1->Sym->type = EiC_succType(e1->Sym->type); EiC_exchtype(t_builtin,e1->Type); EiC_exchtype(t_builtin,e1->Sym->type); e1->Sym->val.vfunc = EiC_ENV->AR[e1->Val.ival].v.vfunc; } else if(t != t_array) { /* treat as an lvalue */ EiC_output(e1); e1->Pflag = 0; e1->Type = EiC_succType(e1->Type); /*if(EiC_gettype(e1->Type) != t_pointer)*/ e1->Type = EiC_addtype(t_lval,e1->Type); } else { /* make a safe pointer */ e1->Type = EiC_succType(e1->Type); EiC_ENV->AR[e1->Val.ival].v.p.ep = (char*) EiC_ENV->AR[e1->Val.ival].v.p.sp + EiC_get_sizeof(e1->Type); generatePtr(e1); } } /*else generatePtr(e1);*/ break; default: retractlexan(); e1->Pflag = 0; e1->Type = EiC_addtype(t_void, e1->Type); break; }}int EiC_GI(token_t * e1){ /* returns -1 on error, * 1 if the type is automatic * 0 otherwise */ if(e1 && e1->Sym) return (e1->Sym->level > 1 && !(e1->Sym->sclass & c_static)); else return -1;}static void process_binary(void (*func) (token_t * e), token_t * e1, int op){ extern int EiC_checkPeepHole(token_t *e1,int op); token_t e2; val_t v; EiC_inittoken(&e2); (*func) (&e2); generatePtr(&e2); generatePtr(e1); if (!isconst(e1->Type)) EiC_output(e1); if (!isconst(e2.Type)) EiC_output(&e2); if(EiC_checkPeepHole(e1,op)) { if(EiC_gettype(e2.Type) < EiC_gettype(e1->Type)) { if(isconst(e2.Type)) EiC_castconst(&e2,e1,1); else EiC_castvar(&e2,e1,1); } EiC_freetype(e1->Type); *e1 = e2; return; } if(EiC_checkPeepHole(&e2,op)) { if(EiC_gettype(e2.Type) > EiC_gettype(e1->Type)) { if(isconst(e1->Type)) EiC_castconst(e1,&e2,1); else EiC_castvar(e1,&e2,1); } EiC_freetoken(&e2); return; } EiC_bin_validate(op, e1, &e2); if (isconst(e1->Type) && isconst(e2.Type)) { EiC_contoken(e1, &e2); e1->Pflag = 0; return; } if (/*isconst(e1->Type) && */ !e1->Pflag) EiC_output(e1); if(op != LAND) { v.ival = 1; EiC_generate(&e1->Code, bump, &v, 0); } EiC_contoken(e1, &e2);}static void assignop(void (*func) (token_t * e), token_t * e1, int op){ int t; token_t e2; val_t v; int op2; if (e1->Pflag || isconst(e1->Type) || isconstp(e1->Type)) EiC_error("Illegal assignment operation"); EiC_inittoken(&e2); generatePtr(&e2); switch (op) { case ADDEQ: op2 = '+'; break; case SUBEQ: op2 = '-'; break; case DIVEQ: op2 = '/'; break; case MULEQ: op2 = '*'; break; case MODEQ: op2 = '%'; break; case RSHTEQ: op2 = RSHT; break; case LSHTEQ: op2 = LSHT; break; case ANDEQ: op2 = AND; break; case BOREQ: op2 = BOR; break; case XOREQ: op2 = XOR; break; default: /* do equals */ op2 = 0; (*func) (&e2); } t = EiC_gettype(e1->Type); if((t == t_struct || t == t_union) && check4constmem(e1->Type)) EiC_error("Illegal assignment operation"); if (op2) { e2.Type = EiC_copytype(e1->Type); e2.Val = e1->Val; e2.Sym = e1->Sym; if (t == t_lval || t == t_struct || t == t_union) { v.ival = 1; EiC_generate(&e1->Code, dupval, &v, 0); } EiC_concode(&e2.Code, &e1->Code); process_binary(func, &e2, op2); } /* * check 4 assignment of pointer to const X to * pointer to X: this is illegal. */ if(t == t_pointer && EiC_gettype(e2.Type) == t_pointer) { if(ConstIntegrity(nextType(e1->Type),nextType(e2.Type))) EiC_error("Assignment loses a const qualifier"); if(!EiC_compareSafe(nextType(e1->Type),nextType(e2.Type))) EiC_error("Casting between safe and unsafe address"); } if (isconst(e2.Type)) { void EiC_SaveGlobalString(ptr_t *s); extern int EiC_RETURNON; EiC_castconst(&e2, e1, 0); if(!EiC_RETURNON && EiC_gettype(e2.Type) == t_pointer && EiC_gettype(nextType(e2.Type)) == t_char && !e2.Sym) { /* got string */ /* Note: string is markged for garbage collector */ EiC_SaveGlobalString(&e2.Val.p); } EiC_output(&e2); } else { EiC_output(&e2); EiC_castvar(&e2, e1, 0); } if (!e2.Pflag) EiC_error("Invalid assignment"); if (t == t_lval || t == t_struct || t == t_union) { if(!op2) { v.ival = 1; if(!e1->Code.nextinst) { EiC_output(e1); } if(t==t_struct || t == t_union) { EiC_generate(&e1->Code, bump, &v, 0); v.ival = EiC_get_sizeof(e2.Type); EiC_generate(&e2.Code,refmem,&v,0); } else EiC_generate(&e1->Code, bump, &v, 0); } else EiC_concode(&e2.Code, &e1->Code); } EiC_contoken(e1, &e2); EiC_do_stooutput(e1); /* assignments can't form lvalues */ setConstp(e1->Type);}static int findmem(type_expr * t, char *id){ int i; struct_t *S = (struct_t *)EiC_getInf(t); for (i = 0; i < S->n; i++) if (strcmp(id, S->id[i]) == 0) return i; return -1;}static int check4constmem(type_expr *t){ struct_t *S = (struct_t *)EiC_getInf(t); int i; for(i=0;i<S->n;i++) if(isconstp(S->type[i])) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -