void statement(int loop, Swtch swp, int lev) { float ref = refinc; if (Aflag >= 2 && lev == 15) warning("more than 15 levels of nested statements\n"); switch (t) { case IF: ifstmt(genlabel(2), loop, swp, lev + 1); break; case WHILE: whilestmt(genlabel(3), swp, lev + 1); break; case DO: dostmt(genlabel(3), swp, lev + 1); expect(';'); break; case FOR: forstmt(genlabel(4), swp, lev + 1); break; case BREAK: walk(NULL, 0, 0); definept(NULL); if (swp && swp->lab > loop) branch(swp->lab + 1); else if (loop) branch(loop + 2); else error("illegal break statement\n"); t = gettok(); expect(';'); break; case CONTINUE: walk(NULL, 0, 0); definept(NULL); if (loop) branch(loop + 1); else error("illegal continue statement\n"); t = gettok(); expect(';'); break; case SWITCH: swstmt(loop, genlabel(2), lev + 1); break; case CASE: { int lab = genlabel(1); if (swp == NULL) error("illegal case label\n"); definelab(lab); while (t == CASE) { static char stop[] = { IF, ID, 0 }; Tree p; t = gettok(); p = constexpr(0); if (generic(p->op) == CNST && isint(p->type)) { if (swp) { needconst++; p = cast(p, swp->sym->type); if (p->type->op == UNSIGNED) p->u.v.i = extend(p->u.v.u, p->type); needconst--; caselabel(swp, p->u.v.i, lab); } } else error("case label must be a constant integer expression\n"); test(':', stop); } statement(loop, swp, lev); } break; case DEFAULT: if (swp == NULL) error("illegal default label\n"); else if (swp->deflab) error("extra default label\n"); else { swp->deflab = findlabel(swp->lab); definelab(swp->deflab->u.l.label); } t = gettok(); expect(':'); statement(loop, swp, lev); break; case RETURN: { Type rty = freturn(cfunc->type); t = gettok(); definept(NULL); if (t != ';') if (rty == voidtype) { error("extraneous return value\n"); expr(0); retcode(NULL); } else retcode(expr(0)); else { if (rty != voidtype) warning("missing return value\n"); retcode(NULL); } branch(cfunc->u.f.label); } expect(';'); break; case '{': compound(loop, swp, lev + 1); break; case ';': definept(NULL); t = gettok(); break; case GOTO: walk(NULL, 0, 0); definept(NULL); t = gettok(); if (t == ID) { Symbol p = lookup(token, stmtlabs); if (p == NULL) { p = install(token, &stmtlabs, 0, FUNC); p->scope = LABELS; p->u.l.label = genlabel(1); p->src = src; } use(p, src); branch(p->u.l.label); t = gettok(); } else error("missing label in goto\n"); expect(';'); break; case ID: if (getchr() == ':') { stmtlabel(); statement(loop, swp, lev); break; } default: definept(NULL); if (kind[t] != ID) { error("unrecognized statement\n"); t = gettok(); } else { Tree e = expr0(0); listnodes(e, 0, 0); if (nodecount == 0 || nodecount > 200) walk(NULL, 0, 0); else if (glevel) walk(NULL, 0, 0); deallocate(STMT); } expect(';'); break; } if (kind[t] != IF && kind[t] != ID && t != '}' && t != EOI) { static char stop[] = { IF, ID, '}', 0 }; error("illegal statement termination\n"); skipto(0, stop); } refinc = ref; }
SNODE *statement(void) /* * statement figures out which of the statement processors * should be called and transfers control to the proper * routine. */ { SNODE *snp, *snp2, **psnp; SNODE *snp3=snp_line(); switch( lastst ) { case kw_asm: asmline = TRUE; getsym(); if (lastst == begin) { getsym(); snp = snp3; if (snp) psnp = &snp->next; else psnp = &snp; *psnp = 0; while (lastst != end && lastst != eof) { *psnp = asm_statement(TRUE); while (*psnp) psnp=&(*psnp)->next; *psnp = snp_line(); while (*psnp) psnp=&(*psnp)->next; } asmline = FALSE; if (lastst == end) getsym(); return snp; } snp = asm_statement(FALSE); asmline = FALSE; break; case semicolon: getsym(); snp = 0; break; case begin: getsym(); snp2 = compoundblock(); snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->exp = snp2; snp->stype = st_block; break; case kw_if: snp = ifstmt(); break; case kw_while: snp = whilestmt(); snp->lst = snp3; snp3 = 0; break; case kw_for: snp = forstmt(); snp->lst = snp3; snp3 = 0; break; case kw_return: snp = retstmt(); goodcode |= GF_RETURN; break; case kw_break: goodcode |= GF_BREAK; switchbreak = 1; snp = breakstmt(); break; case kw_goto: goodcode |= GF_GOTO; snp = gotostmt(); break; case kw_continue: goodcode |= GF_CONTINUE; snp = contstmt(); break; case kw_do: snp = dostmt(); break; case kw_switch: snp = switchstmt(); break; case kw_else: generror(ERR_ELSE,0,0); getsym(); break; case kw__genword: snp = _genwordstmt(); break; case id: while( isspace(lastch) ) getch(); if( lastch == ':') return labelstmt(TRUE); /* else fall through to process expression */ default: #ifdef CPLUSPLUS if (castbegin(lastst)) { if (prm_cplusplus) { cbautoinithead = cbautoinittail = 0; dodecl(sc_auto); snp = cbautoinithead; } else { generror(ERR_NODECLARE,0,skm_semi); snp = 0; } } else #endif { snp = exprstmt(); } break; } if( snp != 0 ) { if (snp3) { snp3->next = snp; snp = snp3; } } return snp; }
/* statements: * stmt -> beginblock */ void stmt (void) { {printf("\t<stm.asm.list>\n");} switch (lookahead) { case BEGIN: beginblock (); break; /* | ifstmt */ case IF: ifstmt (); break; /* | whlstmt */ case WHILE: whlstmt (); break; /* | repstmt */ case REPEAT: repstmt (); break; /* | forstmt */ case FOR: forstmt (); break; /* | casestmt */ case CASE: casestmt (); break; /* | prccall */ /* | assgstm */ case ID: /*ação semântica*/ {printf("\t<idstm.asm.list>\n");} match (ID); if (lookahead == '[' || lookahead == ASGNM) { while (lookahead == '[') { idxsynt (); } /* ':=' == ASGNM */ match (ASGNM); expr (); } else { if (lookahead == '(') { match ('('); exprlist (); match (')'); } } break; /* | "" */ default: ; } /*end switch */ }