📄 parse.c
字号:
sp->stm2 = makestmt(SK_IF); sp = sp->stm2; sp->exp1 = p_expr(tp_boolean); wneedtok(TOK_THEN); sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF); sp->exp2 = makeexpr_long(1); } if (curtok == TOK_ELSE) { line1 = inf_lnum; strlist_mix(&curcomments, grabcomment(CMT_ONELSE)); gettok(); line2 = (curtok == TOK_IF) ? inf_lnum : -1; saveserial2 = curserial; sp->stm2 = p_stmt(NULL, SF_SAVESER|SF_IF); if (sp->stm2 && sp->stm2->kind == SK_IF && !sp->stm2->next && !modula2) { sp->stm2->exp2 = makeexpr_long(elseif > 0 || (elseif < 0 && line1 == line2)); } saveserial = ++serialcount; changecomments(curcomments, -1, saveserial2, -1, saveserial); } if (modula2) wneedtok(TOK_END); curserial = saveserial; break; case TOK_INLINE: gettok(); note("Inline assembly language encountered [254]"); if (curtok != TOK_LPAR) { /* Macintosh style */ newstmt(SK_ASSIGN); sp->exp1 = makeexpr_bicall_1("inline", tp_void, p_expr(tp_integer)); while (curtok == TOK_COMMA) { gettok(); newstmt(SK_ASSIGN); sp->exp1 = makeexpr_bicall_1("inline", tp_void, p_expr(tp_integer)); } break; } do { name = getinlinepart(); if (!*name) break; newstmt(SK_ASSIGN); sp->exp1 = makeexpr_bicall_1("asm", tp_void, makeexpr_string(format_s(" inline %s", name))); gettok(); } while (curtok == TOK_SLASH); skipcloseparen(); break; case TOK_LOOP: gettok(); newstmt(SK_WHILE); sp->exp1 = makeexpr_long(1); sp->stm1 = p_stmt(NULL, SF_SAVESER); break; case TOK_REPEAT: newstmt(SK_REPEAT); saveserial = curserial; spp2 = &(sp->stm1); i = SF_FIRST; do { gettok(); *spp2 = p_stmt(sp->stm1, i); i = 0; while (*spp2) spp2 = &((*spp2)->next); } while (curtok == TOK_SEMI); if (!wneedtok(TOK_UNTIL)) skippasttoken(TOK_UNTIL); sp->exp1 = makeexpr_not(p_expr(tp_boolean)); curserial = saveserial; strlist_mix(&curcomments, grabcomment(CMT_ONEND)); break; case TOK_RETURN: gettok(); newstmt(SK_RETURN); if (curctx->isfunction) { sp->exp1 = gentle_cast(p_expr(curctx->cbase->type), curctx->cbase->type); } break; case TOK_TRY: findsymbol("RECOVER")->flags &= ~KWPOSS; newstmt(SK_TRY); sp->exp1 = makeexpr_long(++trycount); spp2 = &(sp->stm1); i = SF_FIRST; do { gettok(); *spp2 = p_stmt(sp->stm1, i); i = 0; while (*spp2) spp2 = &((*spp2)->next); } while (curtok == TOK_SEMI); if (!wneedtok(TOK_RECOVER)) skippasttoken(TOK_RECOVER); sp->stm2 = p_stmt(NULL, SF_SAVESER); break; case TOK_WHILE: gettok(); newstmt(SK_WHILE); sp->exp1 = p_expr(tp_boolean); wneedtok(TOK_DO); sp->stm1 = p_stmt(NULL, SF_SAVESER); break; case TOK_WITH: gettok(); newstmt(SK_ASSIGN); sp->exp1 = makeexpr_long(0); ep = p_expr(NULL); if (ep->val.type->kind != TK_RECORD) warning("Argument of WITH is not a RECORD [264]"); i = withlevel; if (simplewith(ep)) { withrecordtype(ep->val.type, ep); mp = NULL; } else { /* need to save a temporary pointer */ tp = makepointertype(ep->val.type); mp = makestmttempvar(tp, name_WITH); withrecordtype(ep->val.type, makeexpr_hat(makeexpr_var(mp), 0)); } if (curtok == TOK_COMMA) { curtok = TOK_WITH; sp2 = p_stmt(NULL, (sflags & SF_FIRST) | SF_SAVESER); } else { wneedtok(TOK_DO); sp2 = p_stmt(NULL, (sflags & SF_FIRST) | SF_SAVESER); } withlevel = i; if (mp) { /* if "with p^" for constant p, don't need temp ptr */ if (ep->kind == EK_HAT && ep->args[0]->kind == EK_VAR && !checkvarchanged(sp2, (Meaning *)ep->args[0]->val.i)) { replaceexpr(sp2, withexprs[withlevel]->args[0], ep->args[0]); freeexpr(ep); canceltempvar(mp); } else { freeexpr(sp->exp1); sp->exp1 = makeexpr_assign(makeexpr_var(mp), makeexpr_addr(ep)); } } freeexpr(withexprs[withlevel]); *spp = sp2; while (*spp) spp = &((*spp)->next); break; case TOK_INCLUDE: badinclude(); goto again; case TOK_ADDR: /* flakey Turbo "@procptr := anyptr" assignment */ newstmt(SK_ASSIGN); ep = p_expr(tp_void); if (wneedtok(TOK_ASSIGN)) sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type)); else sp->exp1 = ep; break; case TOK_INHERITED: newstmt(SK_ASSIGN); sp->exp1 = p_expr(tp_void); break; case TOK_IDENT: mp = curtokmeaning; if (mp == mp_str_hp) mp = curtokmeaning = mp_str_turbo; if (mp == mp_val_modula) mp = curtokmeaning = mp_val_turbo; if (mp == mp_blockread_ucsd) mp = curtokmeaning = mp_blockread_turbo; if (mp == mp_blockwrite_ucsd) mp = curtokmeaning = mp_blockwrite_turbo; if (mp == mp_dec_dec) mp = curtokmeaning = mp_dec_turbo; if (mp == mp_self_func) { gettok(); wneedtok(TOK_DOT); if (!wexpecttok(TOK_IDENT)) break; mp = curtokmeaning; } if (!mp) { sym = curtoksym; /* make a guess at what the undefined name is... */ name = stralloc(curtokcase); gettok(); newstmt(SK_ASSIGN); if (curtok == TOK_ASSIGN) { gettok(); ep = p_expr(NULL); mp = addmeaning(sym, MK_VAR); mp->name = name; mp->type = ep->val.type; sp->exp1 = makeexpr_assign(makeexpr_var(mp), ep); } else if (curtok == TOK_HAT || curtok == TOK_ADDR || curtok == TOK_LBR || curtok == TOK_DOT) { ep = makeexpr_name(name, tp_integer); ep = fake_dots_n_hats(ep); if (wneedtok(TOK_ASSIGN)) sp->exp1 = makeexpr_assign(ep, p_expr(NULL)); else sp->exp1 = ep; } else if (curtok == TOK_LPAR) { ep = makeexpr_bicall_0(name, tp_void); do { gettok(); insertarg(&ep, ep->nargs, p_expr(NULL)); } while (curtok == TOK_COMMA); skipcloseparen(); sp->exp1 = ep; } else { sp->exp1 = makeexpr_bicall_0(name, tp_void); } if (!tryfuncmacro(&sp->exp1, NULL)) undefsym(sym); } else if (mp->kind == MK_FUNCTION && !mp->isfunction) { mp->refcount++; if (curtokint >= 0) { ep = p_variable(tp_void); } else { gettok(); ep = p_funccall(mp); } if (!mp->constdefn) need_forward_decl(mp); if (mp->handler && !(mp->sym->flags & LEAVEALONE) && !mp->constdefn) { prochandler = (Stmt *(*)())mp->handler; *spp = (*prochandler)(ep, slist); while (*spp) spp = &((*spp)->next); } else { newstmt(SK_ASSIGN); sp->exp1 = ep; } } else if (mp->kind == MK_SPECIAL) { gettok(); if (mp->handler && !mp->isfunction) { if ((mp->sym->flags & LEAVEALONE) || mp->constdefn) { ep = makeexpr_bicall_0(mp->name, tp_void); if (curtok == TOK_LPAR) { do { gettok(); insertarg(&ep, ep->nargs, p_expr(NULL)); } while (curtok == TOK_COMMA); skipcloseparen(); } newstmt(SK_ASSIGN); tryfuncmacro(&ep, mp); sp->exp1 = ep; } else { prochandler = (Stmt *(*)())mp->handler; *spp = (*prochandler)(mp, slist); while (*spp) spp = &((*spp)->next); } } else symclass(curtoksym); } else { newstmt(SK_ASSIGN); if (curtokmeaning->kind == MK_FUNCTION && peeknextchar() != '(') { Meaning *mp2 = curtokmeaning; if (mp2->xnext) mp2 = mp2->xnext; mp = curctx; while (mp && mp != mp2) mp = mp->ctx; if (mp) curtokmeaning = curtokmeaning->cbase; } ep = p_expr(tp_void);#if 0 if (!(ep->kind == EK_SPCALL || (ep->kind == EK_COND && ep->args[1]->kind == EK_SPCALL))) wexpecttok(TOK_ASSIGN);#endif if (curtok == TOK_ASSIGN) { gettok(); if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "ZERO") && !curtokmeaning) { /* VAX Pascal foolishness */ gettok(); ep2 = makeexpr_sizeof(copyexpr(ep), 0); sp->exp1 = makeexpr_bicall_3("memset", tp_void, makeexpr_addr(ep), makeexpr_long(0), ep2); } else sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type)); } else sp->exp1 = ep; } break; default: break; /* null statement */ } freestmttemps(tempmark); if (sflags & SF_SAVESER) curserial = firstserial; if (tiplabel) { newstmt(SK_LABEL); sp->exp1 = makeexpr_name(format_s(name_LABEL, tiplabel->name), tp_integer); tiplabel->isactive = 0; } return sbase;}#define BR_NEVER 0x1 /* never use braces */#define BR_FUNCTION 0x2 /* function body */#define BR_THENPART 0x4 /* before an "else" */#define BR_ALWAYS 0x8 /* always use braces */#define BR_REPEAT 0x10 /* "do-while" loop */#define BR_TRY 0x20 /* in a recover block */#define BR_ELSEPART 0x40 /* after an "else" */#define BR_CASE 0x80 /* case of a switch stmt */Static int usebraces(sp, opts)Stmt *sp;int opts;{ if (opts & (BR_FUNCTION|BR_ALWAYS)) return 1; if (opts & BR_NEVER) return 0; if (sp && sp->doinit) return 1; switch (bracesalways) { case 0: if (sp) { if (sp->next || sp->kind == SK_TRY || (sp->kind == SK_IF && !sp->stm2) || (opts & BR_REPEAT)) return 1; } break; case 1: return 1; default: if (sp) { if (sp->next || sp->kind == SK_IF || sp->kind == SK_WHILE || sp->kind == SK_REPEAT || sp->kind == SK_TRY || sp->kind == SK_CASE || sp->kind == SK_FOR) return 1; } break; } if (sp != NULL && findcomment(curcomments, CMT_NOT | CMT_TRAIL, sp->serial) != NULL) return 1; return 0;}#define outspnl(spflag) output((spflag) ? " " : "\n")Meaning *outcontext;Static void outnl(serial)int serial;{ outtrailcomment(curcomments, serial, commentindent);}Static void out_block(spbase, opts, serial)Stmt *spbase;int opts, serial;{ int i, j, braces, always, trynum, istrail, hascmt; int gotcomments = 0; int saveindent, saveindent2, delta, declspc; Stmt *sp = spbase; Stmt *sp2, *sp3; Meaning *ctx, *mp; Strlist *curcmt, *cmt, *savecurcmt = curcomments; Strlist *trailcmt, *begincmt, *endcmt; if (debug>1) { fprintf(outf, "out_block of:\n"); dumpstmt(spbase,5); } if (opts & BR_FUNCTION) { if (outcontext && outcontext->comments) { gotcomments = 1; curcomments = outcontext->comments; } attach_comments(spbase); } braces = usebraces(sp, opts); trailcmt = findcomment(curcomments, CMT_TRAIL, serial); begincmt = findcomment(curcomments, CMT_ONBEGIN, serial); istrail = 1; if (!trailcmt) { trailcmt = begincmt; begincmt = NULL; istrail = 0; } endcmt = findcomment(curcomments, CMT_ONEND, serial); if ((begincmt || endcmt) && !(opts & BR_NEVER)) braces = 1; if (opts & BR_ELSEPART) { cmt = findcomment(curcomments, CMT_ONELSE, serial); if (cmt) { if (trailcmt) { out_spaces(bracecommentindent, commentoverindent, commentlen(cmt), 0); output("\001"); outcomment(cmt); } else trailcmt = cmt; } } if (braces) { j = (opts & BR_FUNCTION) ? funcopenindent : openbraceindent; if (!line_start()) { if (trailcmt && cur_column() + commentlen(trailcmt) + 2 > linewidth && outindent + commentlen(trailcmt) + 2 < linewidth) /*close enough*/ i = 0; else if (opts & BR_ELSEPART) i = ((braceelseline & 2) == 0); else if (braceline >= 0) i = (braceline == 0); else i = ((opts & BR_FUNCTION) == 0); if (trailcmt && begincmt) { out_spaces(commentindent, commentoverindent, commentlen(trailcmt), j); outcomment(trailcmt); trailcmt = begincmt; begincmt = NULL; istrail = 0; } else outspnl(i); } if (line_start()) singleindent(j);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -