📄 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 + -