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