📄 parser.c
字号:
}
static void jump_stmt(token_t * e1)
{
extern int EiC_INFUNC;
extern int EiC_RETURNON;
extern token_t *EiC_RETURNEXPR;
val_t v;
v.ival = e1->Code.nextinst;
switch (token->Tok) {
case gotosym:
if(!EiC_INFUNC)
EiC_error("Misplaced goto statement");
else {
if(EiC_lexan() != ID)
EiC_error("expected goto label");
else {
EiC_generate(&e1->Code, jmpu, &v, 0);
e1->Code.gotos = EiCp_addLabel(e1->Code.gotos,
token->Val.sym->id,
v.ival, 0);
if(EiC_gettype(token->Val.sym->type) == ID)
EiC_remsym(token->Val.sym);
}
}
break;
case breaksym:
if (!BREAK)
EiC_error("Misplaced break statement");
else
EiC_eicpush(&breakstack, v);
EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
EiC_match(';', " ;");
break;
case continuesym:
if (!CONT)
EiC_error("Misplaced continue statement");
else
EiC_eicpush(&contstack, v);
EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
EiC_match(';', " ;");
break;
case returnsym:
if (!EiC_RETURNON)
EiC_error("Misplaced return statement");
else {
token_t e2;
if (EiC_lexan() != ';') {
retractlexan();
EiC_inittoken(&e2);
expr(&e2);
/* catch dangling pointers */
if(EiC_gettype(e2.Type) == t_pointer && e2.Sym)
if((EiC_gettype(e2.Sym->type) != t_pointer &&
EiC_gettype(e2.Sym->type) != t_array) && EiC_GI(&e2))
EiC_warningerror("Possible dangling pointer");
EiC_match(';', " ;");
if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) == t_void &&
EiC_gettype(e2.Type) != t_void)
EiC_error("Illegal return type, expected void");
if (isconst(e2.Type)) {
EiC_castconst(&e2, EiC_RETURNEXPR, 1);
EiC_output(&e2);
} else {
EiC_output(&e2);
EiC_castvar(&e2, EiC_RETURNEXPR, 0);
}
if(EiC_HasHiddenParm(EiC_RETURNEXPR->Type)) {
val_t v;
v.ival = -1;
EiC_generate(&e1->Code,rvalptr,&v,1);
v.ival = 1;
EiC_generate(&e1->Code,bump,&v,0);
EiC_contoken(e1, &e2);
v.ival = EiC_get_sizeof(nextType(EiC_RETURNEXPR->Type));
EiC_generate(&e1->Code,refmem,&v,0);
} else
EiC_contoken(e1, &e2);
} else
if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) != t_void)
EiC_warningerror("missing return value");
EiC_generate(&e1->Code, eicreturn, &e1->Val, 0);
}
break;
}
}
static void generatePtr(token_t * e1)
{
if(!NoPTR && EiC_gettype(e1->Type) == t_array && !e1->Pflag) {
EiC_exchtype(t_pointer, e1->Type);
if(!EiC_GI(e1)) { /* static of global variable */
setConst(e1->Type);
e1->Val.p = EiC_ENV->AR[e1->Val.ival].v.p;
}
}
}
static void expr(token_t * e1)
{
/* really a comma expression */
token_t e2;
int c = 0;
do {
EiC_inittoken(&e2);
EiC_assign_expr(&e2);
if(nextinst(&e1->Code))
EiC_output(e1);
EiC_concode(&e1->Code,&e2.Code);
EiC_freetype(e1->Type);
e1->Type = EiC_copytype(e2.Type);
e1->Pflag = e2.Pflag;
EiC_freetoken(&e2);
c++;
} while (EiC_lexan() == ',');
retractlexan();
e1->Pflag = e2.Pflag;
e1->Sym = e2.Sym;
e1->Val = e2.Val;
if(c > 1)
setConstp(e1->Type);
}
static void Outexpr(token_t * e1)
{
/* really a comma expression */
token_t e2;
int c = 0;
do {
EiC_inittoken(&e2);
EiC_assign_expr(&e2);
EiC_output(&e2);
EiC_freetype(e1->Type);
EiC_concode(&e1->Code,&e2.Code);
e1->Type = EiC_copytype(e2.Type);
EiC_freetoken(&e2);
c++;
} while (EiC_lexan() == ',');
retractlexan();
e1->Pflag = e2.Pflag;
e1->Sym = e2.Sym;
e1->Val = e2.Val;
if(c > 1)
setConstp(e1->Type);
}
void EiC_assign_expr(token_t * e1)
{
#if 1
int t = EiC_lexan();
/* handle longjmp and setjmp */
if(t == eiclongjmpsym) {
EiC_generate(&e1->Code, __eiclongjmp, &e1->Val, EiC_GI(e1));
e1->Type = EiC_freetype(e1->Type);
e1->Type = EiC_addtype(t_void, e1->Type);
e1->Pflag = 1;
return;
} else if (t == eicsetjmpsym) {
EiC_generate(&e1->Code, __eicsetjmp, &e1->Val, EiC_GI(e1));
e1->Type = EiC_freetype(e1->Type);
e1->Type = EiC_addtype(t_int, e1->Type);
e1->Pflag = 1;
return;
} else
retractlexan();
#endif
cond_expr(e1);
while (1)
switch (EiC_lexan()) {
case ASS: /* = */
case ADDEQ: /* += */
case SUBEQ: /* -= */
case DIVEQ: /* /= */
case MULEQ: /* *= */
case MODEQ: /* %= */
case RSHTEQ: /* >>= */
case LSHTEQ: /* <<= */
case ANDEQ: /* &= */
case BOREQ: /* |= */
case XOREQ: /* ^= */
assignop(EiC_assign_expr, e1, token->Tok);
break;
default:
retractlexan();
generatePtr(e1);
return;
}
}
extern void cond_expr(token_t * e1)
{
log_or_expr(e1);
if (EiC_lexan() == '?') {
val_t v;
int rt;
token_t e2, e3;
EiC_inittoken(&e2);
out_expr(&e2);
EiC_match(':', " :");
EiC_inittoken(&e3);
cond_expr(&e3);
if(!isconst(e3.Type))
EiC_output(&e3);
EiC_cast2comm(&e2, &e3);
EiC_output(&e3);
EiC_output(e1);
rt = EiC_gettype(e1->Type);
e1->Type = EiC_freetype(e1->Type);
e1->Type = EiC_copytype(e2.Type);
v.ival = e2.Code.nextinst + 2;
#if 0
EiC_generate(&e1->Code, jmpFint, &v, 0);
#else
genJump(e1,&v,rt,0);
#endif
EiC_contoken(e1, &e2);
v.ival = e1->Code.nextinst;
EiC_generate(&e1->Code, jmpu, &v, 0);
setInst(&e1->Code,v.ival,val.ival,e3.Code.nextinst+1);
EiC_contoken(e1, &e3);
/* conditional's can't form lvalues */
setConstp(e1->Type);
} else
retractlexan();
}
static void fixit(code_t *C, int s)
{
int i;
for(i = s; i < C->nextinst;i++)
switch(C->inst[i].opcode) {
case jmpFint:
case jmpFlng:
case jmpFdbl:
case jmpFptr:
case jmpTint:
case jmpTlng:
case jmpTdbl:
case jmpTptr:
if(C->inst[i].val.ival == INT_MAX)
C->inst[i].val.ival = C->nextinst - i;
}
}
static void log_or_expr(token_t * e1)
{
void EiC_do_lor(token_t *, int);
log_and_expr(e1);
if(EiC_lexan() == LOR) {
token_t e2;
int nxt = e1->Code.nextinst;
EiC_do_lor(e1, INT_MAX);
do {
EiC_inittoken(&e2);
log_and_expr(&e2);
EiC_do_lor(&e2,INT_MAX);
EiC_contoken(e1,&e2);
} while (EiC_lexan() == LOR);
fixit(&e1->Code,nxt);
}
retractlexan();
}
static void log_and_expr(token_t * e1)
{
void EiC_do_land(token_t *, int);
inc_or_expr(e1);
if(EiC_lexan() == LAND) {
token_t e2;
int nxt = e1->Code.nextinst;
EiC_do_land(e1, INT_MAX);
do {
EiC_inittoken(&e2);
inc_or_expr(&e2);
EiC_do_land(&e2,INT_MAX);
EiC_contoken(e1,&e2);
} while (EiC_lexan() == LAND);
fixit(&e1->Code,nxt);
}
retractlexan();
}
static void inc_or_expr(token_t * e1)
{
xor_expr(e1);
while (EiC_lexan() == BOR)
process_binary(xor_expr, e1, BOR);
retractlexan();
}
static void xor_expr(token_t * e1)
{
and_expr(e1);
while (EiC_lexan() == XOR)
process_binary(and_expr, e1, XOR);
retractlexan();
}
static void and_expr(token_t * e1)
{
equal_expr(e1);
while (EiC_lexan() == AND)
process_binary(equal_expr, e1, AND);
retractlexan();
}
static void equal_expr(token_t * e1)
{
rel_expr(e1);
while (1)
switch (EiC_lexan()) {
case EQ:
case NE:
process_binary(rel_expr, e1, token->Tok);
break;
default:
retractlexan();
return;
}
}
static void rel_expr(token_t * e1)
{
shift_expr(e1);
while (1)
switch (EiC_lexan()) {
case LT:
case LE:
case GT:
case GE:
process_binary(shift_expr, e1, token->Tok);
break;
default:
retractlexan();
return;
}
}
static void shift_expr(token_t * e1)
{
add_expr(e1);
while (1)
switch (EiC_lexan()) {
case LSHT:
case RSHT:
process_binary(add_expr, e1, token->Tok);
break;
default:
retractlexan();
return;
}
}
static void add_expr(token_t * e1)
{
mult_expr(e1);
while (1)
switch (EiC_lexan()) {
case '+':
case '-':
process_binary(mult_expr, e1, token->Tok);
break;
default:
retractlexan();
return;
}
}
static void mult_expr(token_t * e1)
{
cast_expr(e1);
while (1)
switch (EiC_lexan()) {
case '*':
case '/':
case '%':
process_binary(cast_expr, e1, token->Tok);
break;
default:
retractlexan();
return;
}
}
static void cast_expr(token_t * e1)
{
if (EiC_lexan() != '(') {
retractlexan();
EiC_unary_expr(e1);
} else {
f_cast_expr(e1);
}
}
static void f_cast_expr(token_t * e1)
{
token_t e2;
switch (EiC_lexan()) {
TYPESPEC:
TYPEQUAL:
EiC_inittoken(&e2);
retractlexan();
EiC_type_name(e1);
EiC_match(')', " )");
cast_expr(&e2);
if (isconst(e2.Type)) {
setConst(e1->Type);
EiC_castconst(&e2, e1, 1);
e1->Val = e2.Val;
} else {
EiC_output(&e2);
EiC_castvar(&e2, e1, 1);
e1->Pflag = e2.Pflag;
e1->Sym = e2.Sym;
/*e1->Val = e2.Val;*/
}
EiC_contoken(e1, &e2);
break;
/* cast can't form lvalues */
setConstp(e1->Type);
default:
retractlexan();
expr(e1);
EiC_match(')', " )");
EiC_r_postfix_expr(e1);
break;
}
}
static void EiC_unary_expr(token_t * e1)
{
int t;
t = EiC_lexan();
switch (t) {
case '+': /* unary - */
case '-': /* unary + */
case '*': /* indirection */
case '~': /* ones complement */
case NOT: /* */
cast_expr(e1);
EiC_unaryop(e1, t);
return;
case INC: /* ++ lval */
case DEC: /* -- lval */
EiC_unary_expr(e1);
EiC_unaryop(e1, t);
return;
case sizeofsym:
NoPTR++;
if(EiC_lexan() == '(') {
switch(EiC_lexan()) {
TYPESPEC:
TYPEQUAL:
retractlexan();
e1->Type = EiC_freetype(e1->Type);
EiC_type_name(e1);
break;
default: /* must be unary expr, i.e. ( expr ) */
retractlexan();
expr(e1);
}
EiC_match(')', " )");
} else {
retractlexan();
EiC_unary_expr(e1);
}
EiC_freecode(&e1->Code);
if(isconst(e1->Type) &&
EiC_gettype(e1->Type) == t_pointer &&
EiC_gettype(e1->Type->nxt) == t_char) /* hack for char */
/* constants */
e1->Val.uival = strlen(e1->Val.p.p) + 1;
else
e1->Val.uival = EiC_get_sizeof(e1->Type);
if(!e1->Val.uival || !e1->Type)
EiC_error("Invalid argument to sizeof");
e1->Type = EiC_freetype(e1->Type);
e1->Type = EiC_addtype(t_uint, e1->Type);
setConst(e1->Type);
e1->Pflag = 0;
NoPTR--;
return;
case AND:
#if 0
/* this section of code is an attempt to
* to have constant addresses determined
* at compile time (not finished)
*/
NoPTR++;
cast_expr(e1);
t = EiC_gettype(e1->Type);
if(e1->Sclass == c_register)
EiC_error("Cannot apply & to a register variable");
/* check for global or static variable class */
if(EiC_GI(e1) == 0 && !isconst(e1->Type) && t != t_lval) {
void * EiC_getaddress(token_t * e1);
ptr_t *p;
if(t == t_union || t == t_struct)
e1->Type = EiC_addtype(t_pointer,e1->Type);
p = EiC_getaddress(e1);
e1->Val.p.sp = e1->Val.p.p = p;
e1->Val.p.ep = (char *) p + SIZEOFTHETYPE;
setConst(e1->Type);
}
if(!isconst(e1->Type)) {
switch (t) {
case t_char:
case t_uchar:
case t_short:
case t_ushort:
case t_int:
case t_uint:
CASE_LONG:
CASE_ULONG:
CASE_FLOAT:
case t_pointer:
if (e1->Pflag)
EiC_error("Must have lvalue");
else {
if(isUnSafe(e1->Type))
e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
}
break;
case t_lval:
e1->Type = EiC_succType(e1->Type);
break;
case t_struct:
case t_union:
case t_array:
EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
break;
case t_funcdec:
EiC_exchtype(t_func, e1->Type);
case t_func:
v.p.p = e1->Sym;
EiC_generate(&e1->Code, pushptr, &v, 0);
break;
default:
EiC_error("Must have lvalue");
}
e1->Type = EiC_addtype(t_pointer, e1->Type);
e1->Pflag = 1;
} else /* nothing much to do */
if(EiC_gettype(e1->Type) != t_pointer)
EiC_error("Must have lvalue");
NoPTR--;
return;
}
#else
NoPTR++;
cast_expr(e1);
NoPTR--;
if(e1->Sclass == c_register)
EiC_error("Cannot apply & to a register variable");
switch (EiC_gettype(e1->Type)) {
case t_char:
case t_uchar:
case t_short:
case t_ushort:
case t_int:
case t_uint:
CASE_LONG:
CASE_ULONG:
CASE_FLOAT:
case t_pointer:
if (e1->Pflag)
EiC_error("Must have lvalue");
else {
e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
}
break;
case t_lval:
e1->Type = EiC_succType(e1->Type);
break;
case t_struct:
case t_union:
case t_array:
EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
break;
case t_funcdec:
case t_func:
case t_builtin:
EiC_output(e1);
return;
default:
EiC_error("Must have lvalue");
}
e1->Type = EiC_addtype(t_pointer, e1->Type);
e1->Pflag = 1;
return;
}
#endif
retractlexan();
postfix_expr(e1);
}
static void postfix_expr(token_t * e1)
{
primary_expr(e1);
EiC_r_postfix_expr(e1);
}
static void EiC_r_postfix_expr(token_t * e1)
{
void derefConst(token_t *);
void EiC_binhlval(int, token_t *, token_t *);
int t,c = 0;
switch ((t = EiC_lexan())) {
case INC:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -