SNODE *ifstmt(void) /* * ifstmt parses the c if statement and an else clause if * one is present. */ { SNODE *snp; int ogc = goodcode; int temp=0,temp1 = 0; snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->stype = st_if; getsym(); needpunc(openpa,0); doassign(&snp->exp,TRUE,0); needpunc( closepa,skm_closepa ); snp->s1 = cppblockedstatement(); temp1 = goodcode & (GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO); if( lastst == kw_else ) { temp = goodcode & (GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO); goodcode = ogc; getsym(); snp->s2 = cppblockedstatement(); temp = temp & goodcode; } else snp->s2 = 0; goodcode = ogc | (temp & temp1); return snp; }
SNODE *dostmt(void) /* * dostmt parses the c do-while construct. */ { SNODE *snp; int ogc = goodcode,oswb = switchbreak; goodcode |= GF_INLOOP; snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->stype = st_do; getsym(); goodcode |= GF_CONTINUABLE; snp->s1 = cppblockedstatement(); goodcode = ogc; if( lastst != kw_while ) gensymerror(ERR_IDENTEXPECT,lastid); else getsym(); needpunc(openpa,0); doassign(&snp->exp,TRUE,0); needpunc(closepa,skm_closepa); if( lastst != eof) needpunc( semicolon,0 ); switchbreak = oswb; return snp; }
int expr() { int mode; int id1; int ixarr; int ids; if (istoken(T_CONST)) {doconst(); return 1; } mode=typeName(); /*0=V,1=*,2=&*/ if (token=='(') {docall1(); goto e1; } if (isreg()) goto e1; id1=searchname(); gettypes(id1); ids=signi; ixarr=0; if (istoken('[')) { ixarr=searchname(); expect(T_NAME); expect(']'); gettypes(ixarr); if (widthi==0) error1("Arrayindex muss int sein"); } if (istoken(T_PLUSPLUS )) {if(mode)error1("Nur var erlaubt");doinc();goto e1;} if (istoken(T_MINUSMINUS)) {if(mode)error1("Nur var erlaubt");dodec();goto e1;} if (istoken(T_PLUSASS )) {compoundass("add", mode); goto e1;} if (istoken(T_MINUSASS )) {compoundass("sub", mode); goto e1;} if (istoken(T_ANDASS )) {compoundass("and", mode); goto e1;} if (istoken(T_ORASS )) {compoundass("or" , mode); goto e1;} if (istoken(T_MULASS )) {error1("nicht implementiert");} if (istoken(T_DIVASS )) {error1("nicht implementiert");} if (istoken('=')) { isconst=expr(); if (isconst) { if(mode==0) {prs("\n;++++ mov "); printName(id1); prs(", "); prnum(lexval); } } doassign(mode, id1, ixarr); goto e1;} dovar1(mode, "mov", ixarr, id1); e1: if (istoken('+')) rterm("add"); else if (istoken('-')) rterm("sub" ); else if (istoken('&')) rterm("and" ); else if (istoken('|')) rterm("or" ); else if (istoken(T_LESSLESS)) rterm("shl"); else if (istoken(T_GREATGREAT)) rterm("shr"); else if (istoken('*')) domul (ids); else if (istoken('/')) doidiv(ids); else if (istoken('%')) domod (ids); if (isrelational()) { rterm("cmp"); cmpneg(ids);} return 0; }
SNODE *whilestmt(void) /* * whilestmt parses the c while statement. */ { SNODE *snp; int ogc = goodcode; goodcode |= GF_INLOOP; snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->stype = st_while; snp->s1 = 0; getsym(); needpunc(openpa,0); doassign(&snp->exp,TRUE,0); needpunc( closepa,skm_closepa ); goodcode |= GF_CONTINUABLE; snp->s1 = cppblockedstatement(); goodcode = ogc; return snp; }
SNODE *switchstmt(void) /* * Handle the SWITCH statement */ { SNODE *snp; SNODE *head, *tail; TYP *tp; SNODE *lst = 0; int ogc = goodcode,oswb=switchbreak; TABLE oldoldlsym; switchbreak = 0; #ifdef CPLUSPLUS if (prm_cplusplus) { oldoldlsym = oldlsym; oldlsym = lsyms; } #endif snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->stype = st_switch; getsym(); needpunc(openpa,0); tp = doassign(&snp->exp,TRUE,0); if (tp) { switch (tp->type) { case bt_char: case bt_unsignedchar: case bt_short: case bt_unsignedshort: case bt_long: case bt_unsigned: case bt_enum: break; default: generror(ERR_SWITCHINT,0,0); } } needpunc(closepa, skm_closepa); needpunc(begin,0); head = 0; goodcode |= GF_UNREACH; goodcode &= ~GF_DEF; if (lastst == id) if (lastch == ':') lst = labelstmt(FALSE); while( lastst != end && lastst != eof) { goodcode &= ~(GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO); if( head == 0 ) head = tail = casestmt(lst); else { tail->next = casestmt(lst); if( tail->next != 0 ) tail = tail->next; } lst = 0; if (tail) tail->next = 0; } if (!switchbreak && goodcode & GF_RETURN) { if ((goodcode & GF_UNREACH) && (goodcode & GF_DEF)) ogc |= GF_RETURN; } goodcode = ogc; snp->s1 = head; getsym(); checkcases(head); switchbreak = oswb; #ifdef CPLUSPLUS if (prm_cplusplus) { check_funcused(&oldlsym,&lsyms); gather_labels(&oldlsym,&lsyms); cseg(); lsyms = oldlsym; oldlsym.head = oldoldlsym.head; } #endif return snp; }
SNODE *forstmt(void) /* * Generate a block for a for statement */ { SNODE *snp; int ogc = goodcode,oswb = switchbreak; int plussemi = 0; goodcode |= GF_INLOOP; snp = xalloc(sizeof(SNODE)); snp->next = 0; getsym(); snp->label = snp->exp = snp->s2 = 0; snp->stype = st_for; if (needpunc(openpa,skm_closepa)) { #ifdef CPLUSPLUS /* CPLUSPLUS allows you to declare a variable here */ if (castbegin(lastst)) { if (prm_cplusplus) { ENODE *exp=0,**next = &exp; cbautoinithead = cbautoinittail = 0; dodecl(sc_auto); while (cbautoinithead) { if (*next) { *next = makenode(en_void,(*next),cbautoinithead->exp); next = &(*next)->v.p[1]; } else *next = cbautoinithead->exp; cbautoinithead = cbautoinithead->next; } snp->label = exp; plussemi = 1; } else { generror(ERR_NODECLARE,0,0); while (castbegin(lastst)) getsym(); goto forjoin; } } else forjoin: #endif { if( expression(&snp->label) == 0 ) snp->label = 0; plussemi = needpunc(semicolon,0); } if (plussemi) { doassign(&snp->exp,FALSE,0); if (needpunc(semicolon,0)) { if( expression(&snp->s2) == 0 ) { snp->s2 = 0; } } } needpunc(closepa,skm_closepa); } goodcode |= GF_CONTINUABLE; snp->s1 = cppblockedstatement(); goodcode = ogc; switchbreak = oswb; return snp; }