📄 parse.c
字号:
} tiplabel = NULL; if (curtok == TOK_IDENT && which_lang == LANG_TIP && peeknextchar() == ':') { distinctdef++; tiplabel = addmeaning(curtoksym, MK_LABEL); tiplabel->isreturn = 1; distinctdef--; gettok(); wneedtok(TOK_COLON); } firstserial = curserial; checkkeyword(TOK_TRY); checkkeyword(TOK_INLINE); checkkeyword(TOK_LOOP); checkkeyword(TOK_RETURN); if (modula2) { if (sflags & SF_SAVESER) goto stmtSeq; } switch (curtok) { case TOK_BEGIN: stmtSeq: if (sflags & (SF_FUNC|SF_SAVESER)) { saveserial = curserial; cmt = grabcomment(CMT_ONBEGIN); if (sflags & SF_FUNC) cmt = fixbeginendcomment(cmt); strlist_mix(&curcomments, cmt); } i = sflags & SF_FIRST; do { if (modula2) { if (curtok == TOK_BEGIN || curtok == TOK_SEMI) gettok(); checkkeyword(TOK_ELSIF); if (curtok == TOK_ELSE || curtok == TOK_ELSIF) break; } else gettok(); *spp = p_stmt(sbase, i); i = 0; while (*spp) spp = &((*spp)->next); } while (curtok == TOK_SEMI); if (sflags & (SF_FUNC|SF_SAVESER)) { cmt = grabcomment(CMT_ONEND); changecomments(cmt, -1, -1, -1, saveserial); if (sflags & SF_FUNC) cmt = fixbeginendcomment(cmt); strlist_mix(&curcomments, cmt); if (sflags & SF_FUNC) changecomments(curcomments, -1, saveserial, -1, 10000); curserial = saveserial; } checkkeyword(TOK_ELSIF); if (modula2 && (sflags & SF_IF)) break; cmt = curcomments; curcomments = NULL; if (!wneedtok(TOK_END)) skippasttoken(TOK_END); if ((sflags & SF_IF) && curtok == TOK_ELSE) changecomments(curcomments, CMT_POST, saveserial, CMT_PREELSE, -1); strlist_mix(&cmt, curcomments); curcomments = cmt; break; case TOK_CASE: gettok(); swexpr = trueswexpr = p_ord_expr(); if (nosideeffects(swexpr, 1)) { tvar = NULL; } else { tvar = makestmttempvar(swexpr->val.type, name_TEMP); swexpr = makeexpr_var(tvar); } savespp = spp; newstmt(SK_CASE); saveserial2 = curserial; sp->exp1 = trueswexpr; spp2 = &sp->stm1; tp = swexpr->val.type; defsp = NULL; defsphook = &defsp; if (!wneedtok(TOK_OF)) { skippasttoken(TOK_END); break; } i = 1; while (curtok == TOK_VBAR) gettok(); checkkeyword(TOK_OTHERWISE); while (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) { spp3 = spp2; saveserial = curserial; *spp2 = sp = makestmt(SK_CASELABEL); steal_comments(saveserial, sp->serial, i); spp2 = &sp->next; range = NULL; toobig = 0; for (;;) { ep = gentle_cast(p_expr(tp), tp); if (curtok == TOK_DOTS) { li1 = ord_value(eval_expr(ep)); gettok(); ep2 = gentle_cast(p_expr(tp), tp); li2 = ord_value(eval_expr(ep2)); range = makeexpr_or(range, makeexpr_range(copyexpr(swexpr), ep, ep2, 1)); if (li2 - li1 >= caselimit) toobig = 1; if (!toobig) { for (;;) { sp->exp1 = makeexpr_val(make_ord(tp, li1)); if (li1 >= li2) break; li1++; serialcount--; /* make it reuse the count */ sp->stm1 = makestmt(SK_CASELABEL); sp = sp->stm1; } } } else { sp->exp1 = copyexpr(ep); range = makeexpr_or(range, makeexpr_rel(EK_EQ, copyexpr(swexpr), ep)); } if (curtok == TOK_COMMA) { gettok(); serialcount--; /* make it reuse the count */ sp->stm1 = makestmt(SK_CASELABEL); sp = sp->stm1; } else break; } wneedtok(TOK_COLON); if (toobig) { free_stmt(*spp3); spp2 = spp3; *defsphook = makestmt_if(range, p_stmt(NULL, SF_SAVESER|SF_IF), NULL); if (defsphook != &defsp && elseif != 0) (*defsphook)->exp2 = makeexpr_long(1); defsphook = &((*defsphook)->stm2); } else { freeexpr(range); sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF); } i = 0; checkkeyword(TOK_OTHERWISE); if (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) { if (curtok == TOK_VBAR) { while (curtok == TOK_VBAR) gettok(); } else wneedtok(TOK_SEMI); checkkeyword(TOK_OTHERWISE); } } if (defsp) { *spp2 = defsp; spp2 = defsphook; if (tvar) { sp = makestmt_assign(makeexpr_var(tvar), trueswexpr); sp->next = *savespp; *savespp = sp; sp->next->exp1 = swexpr; } } else { if (tvar) { canceltempvar(tvar); freeexpr(swexpr); } } if (curtok == TOK_OTHERWISE || curtok == TOK_ELSE) { gettok(); while (curtok == TOK_SEMI || curtok == TOK_COLON) gettok();/* changecomments(curcomments, CMT_TRAIL, curserial, CMT_POST, -1); */ i = SF_FIRST; while (curtok != TOK_END) { *spp2 = p_stmt(NULL, i); while (*spp2) spp2 = &((*spp2)->next); i = 0; if (curtok != TOK_SEMI) break; gettok(); } if (!wexpecttok(TOK_END)) skiptotoken(TOK_END); } else if (casecheck == 1 || (casecheck == 2 && range_flag)) { *spp2 = makestmt(SK_CASECHECK); } curserial = saveserial2; strlist_mix(&curcomments, grabcomment(CMT_ONEND)); gettok(); break; case TOK_FOR: forfixed = fixedflag; gettok(); newstmt(SK_FOR); i = 0; if (which_lang == LANG_TIP) { wexpecttok(TOK_IDENT); ep = makeexpr_long(0); name = stralloc(curtokcase); sym = curtoksym; gettok(); } else ep = p_sexpr(tp_integer); if (curtok == TOK_IN) { gettok(); ep3 = p_expr(NULL); ord_range_expr(ep3->val.type->indextype, &ep2, &sp->exp2); ep2 = copyexpr(ep2); sp->exp2 = copyexpr(sp->exp2); ep2->val.type = sp->exp2->val.type = ep3->val.type->indextype; } else { if (!wneedtok(TOK_ASSIGN)) { skippasttoken(TOK_DO); break; } ep2 = makeexpr_charcast(p_expr(ep->val.type)); if (curtok != TOK_DOWNTO) { if (!wexpecttok(TOK_TO)) { skippasttoken(TOK_DO); break; } } savetok = curtok; gettok(); sp->exp2 = makeexpr_charcast(p_expr(ep->val.type)); ep3 = NULL; } if (which_lang == LANG_TIP) { freeexpr(ep); mp2 = sym->mbase; if (mp2 && mp2->ctx == curctx && mp2->kind == MK_VAR && mp2->anyvarflag && !mp2->isactive && mp2->type == ep2->val.type) { mp2->isactive = 1; } else { distinctdef++; strcpy(curtokcase, name); curtoksym = sym; mp2 = addmeaning(sym, MK_VAR); distinctdef--; mp2->type = ep2->val.type; } mp2->anyvarflag = 0; ep = makeexpr_var(mp2); FREE(name); } else mp2 = NULL; checkkeyword(TOK_BY); if (curtok == TOK_BY) { gettok(); forstep = p_expr(tp_integer); i = possiblesigns(forstep); if ((i & 5) == 5) { if (expr_is_neg(forstep)) { ekind = EK_GE; note("Assuming FOR loop step is negative [252]"); } else { ekind = EK_LE; note("Assuming FOR loop step is positive [252]"); } } else { if (!(i & 1)) ekind = EK_LE; else ekind = EK_GE; } } else { if (savetok == TOK_DOWNTO) { ekind = EK_GE; forstep = makeexpr_long(-1); } else { ekind = EK_LE; forstep = makeexpr_long(1); } } tvar = NULL; swexpr = NULL; if (ep->kind == EK_VAR) { tp = findbasetype(ep->val.type, ODECL_NOPRES); if ((tp == tp_char || tp == tp_schar || tp == tp_uchar || tp == tp_abyte || tp == tp_sbyte || tp == tp_ubyte || tp == tp_boolean) && ((checkconst(sp->exp2, 0) && tp != tp_sbyte && tp != tp_schar) || checkconst(sp->exp2, -128) || (checkconst(sp->exp2, 127) && tp != tp_ubyte && tp != tp_uchar) || checkconst(sp->exp2, 255) || (tp == tp_char && (useAnyptrMacros == 1 || unsignedchar != 1) && isliteralconst(sp->exp2, NULL) == 2 && sp->exp2->val.i >= 128))) { swexpr = ep; tvar = makestmttempvar(tp_sshort, name_TEMP); ep = makeexpr_var(tvar); } else if (((tp == tp_sshort && (checkconst(sp->exp2, -32768) || checkconst(sp->exp2, 32767))) || (tp == tp_ushort && (checkconst(sp->exp2, 0) || checkconst(sp->exp2, 65535))))) { swexpr = ep; tvar = makestmttempvar(tp_integer, name_TEMP); ep = makeexpr_var(tvar); } else if (tp == tp_integer && (checkconst(sp->exp2, LONG_MAX) || (sp->exp2->kind == EK_VAR && sp->exp2->val.i == (long)mp_maxint))) { swexpr = ep; tvar = makestmttempvar(tp_unsigned, name_TEMP); ep = makeexpr_var(tvar); } } sp->exp3 = makeexpr_assign(copyexpr(ep), makeexpr_inc(copyexpr(ep), copyexpr(forstep))); wneedtok(TOK_DO); forfixed = (fixedflag != forfixed); mp = makestmttempvar(ep->val.type, name_FOR); sp->stm1 = p_stmt(NULL, SF_SAVESER); if (mp2) { mp2->anyvarflag = 1; mp2->isactive = 0; } if (ep3) { if (ep3->val.type->kind == TK_SMALLSET) { range = makeexpr_bin(EK_LSH, ep->val.type, makeexpr_longcast(makeexpr_long(1), 1), enum_to_int(copyexpr(ep))); ep3 = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, range, ep3), makeexpr_long(0)); } else { ep3 = makeexpr_bicall_2(setinname, tp_boolean, makeexpr_arglong(copyexpr(ep), 0), ep3); } sp->stm1 = makestmt_if(ep3, sp->stm1, NULL); } if (tvar) { if (checkexprchanged(sp->stm1, swexpr)) note(format_s("Rewritten FOR loop won't work if it meddles with %s [253]", ((Meaning *)swexpr->val.i)->name)); sp->stm1 = makestmt_seq(makestmt_assign(swexpr, makeexpr_var(tvar)), sp->stm1); } else if (offsetforloops && ep->kind == EK_VAR) { offset = checkvaroffset(sp->stm1, (Meaning *)ep->val.i); if (offset != 0) { ep3 = makeexpr_inc(copyexpr(ep), makeexpr_long(-offset)); replaceexpr(sp->stm1, ep, ep3); freeexpr(ep3); ep2 = makeexpr_plus(ep2, makeexpr_long(offset)); sp->exp2 = makeexpr_inc(sp->exp2, makeexpr_long(offset)); } } if (!exprsame(ep, ep2, 1)) sp->exp1 = makeexpr_assign(copyexpr(ep), copyexpr(ep2)); isunsafe = ((!nodependencies(ep2, 2) && !nosideeffects(sp->exp2, 1)) || (!nodependencies(sp->exp2, 2) && !nosideeffects(ep2, 1))); if (forfixed || (simplefor(sp, ep) && !isunsafe)) { canceltempvar(mp); sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2); } else { ep3 = makeexpr_neg(copyexpr(forstep)); if ((checkconst(forstep, 1) || checkconst(forstep, -1)) && sp->exp2->kind == EK_PLUS && exprsame(sp->exp2->args[sp->exp2->nargs-1], ep3, 2)) { sp->exp2 = makeexpr_inc(sp->exp2, forstep); } else { freeexpr(forstep); freeexpr(ep3); ep3 = makeexpr_long(0); } if (forevalorder && isunsafe) { if (exprdepends(sp->exp2, ep)) { tvar = makestmttempvar(mp->type, name_TEMP); sp->exp1 = makeexpr_comma( makeexpr_comma( makeexpr_assign(makeexpr_var(tvar), copyexpr(ep2)), makeexpr_assign(makeexpr_var(mp), sp->exp2)), makeexpr_assign(copyexpr(ep), makeexpr_var(tvar))); } else sp->exp1 = makeexpr_comma( sp->exp1, makeexpr_assign(makeexpr_var(mp), sp->exp2)); } else { if (isunsafe) note("Evaluating FOR loop limit before initial value [315]"); sp->exp1 = makeexpr_comma( makeexpr_assign(makeexpr_var(mp), sp->exp2), sp->exp1); } sp->exp2 = makeexpr_inc(makeexpr_var(mp), ep3); sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2); } freeexpr(ep2); break; case TOK_GOTO: gettok(); if (findlabelsym()) { if (curtokmeaning->ctx != curctx) { curtokmeaning->val.i = 1; *spp = close_files_to_ctx(curtokmeaning->ctx); while (*spp) spp = &((*spp)->next); newstmt(SK_ASSIGN); var_reference(curtokmeaning->xnext); if (curtokmeaning->ctx->kind == MK_MODULE && !curtokmeaning->xnext->wasdeclared) { outsection(minorspace); declarevar(curtokmeaning->xnext, VDECL_ALL); curtokmeaning->xnext->wasdeclared = 1; outsection(minorspace); } sp->exp1 = makeexpr_bicall_2("longjmp", tp_void, makeexpr_var(curtokmeaning->xnext), makeexpr_long(1)); } else { newstmt(SK_GOTO); sp->exp1 = makeexpr_name(format_s(name_LABEL, curtokmeaning->name), tp_integer); } } else { warning("Expected a label [263]"); } gettok(); break; case TOK_IF: gettok(); newstmt(SK_IF); saveserial = curserial; curserial = ++serialcount; sp->exp1 = p_expr(tp_boolean); wneedtok(TOK_THEN); sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF); changecomments(curcomments, -1, saveserial+1, -1, saveserial); checkkeyword(TOK_ELSIF); while (curtok == TOK_ELSIF) { gettok();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -