parse.c.1
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:48k
- /* "p2c", a Pascal to C translator.
- Copyright (C) 1989 David Gillespie.
- Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation (any version).
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- #define PROTO_PARSE_C
- #include "trans.h"
- Static short candeclare;
- Static int trycount;
- Static Strlist *includedfiles;
- Static char echo_first;
- Static int echo_pos;
- void setup_parse()
- {
- candeclare = 0;
- trycount = 0;
- includedfiles = NULL;
- echo_first = 1;
- echo_pos = 0;
- fixexpr_tryblock = 0;
- }
- void echobreak()
- {
- if (echo_pos > 0) {
- printf("n");
- echo_pos = 0;
- echo_first = 0;
- }
- }
- void echoword(name, comma)
- char *name;
- int comma;
- {
- FILE *f = (outf == stdout) ? stderr : stdout;
- if (quietmode || showprogress)
- return;
- if (!echo_first) {
- if (comma) {
- fprintf(f, ",");
- echo_pos++;
- }
- if (echo_pos + strlen(name) > 77) {
- fprintf(f, "n");
- echo_pos = 0;
- } else {
- fprintf(f, " ");
- echo_pos++;
- }
- }
- echo_first = 0;
- fprintf(f, "%s", name);
- echo_pos += strlen(name);
- fflush(f);
- }
- void echoprocname(mp)
- Meaning *mp;
- {
- echoword(mp->name, 1);
- }
- Static void forward_decl(func, isextern)
- Meaning *func;
- int isextern;
- {
- if (func->wasdeclared)
- return;
- if (isextern && func->constdefn && !checkvarmac(func))
- return;
- if (isextern) {
- output("extern ");
- } else if (func->ctx->kind == MK_FUNCTION) {
- if (useAnyptrMacros)
- output("Local ");
- else
- output("static ");
- } else if ((use_static != 0 && !useAnyptrMacros) ||
- (findsymbol(func->name)->flags & NEEDSTATIC)) {
- output("static ");
- } else if (useAnyptrMacros) {
- output("Static ");
- }
- if (func->type->basetype != tp_void || ansiC != 0) {
- outbasetype(func->type, ODECL_FORWARD);
- output(" ");
- }
- outdeclarator(func->type, func->name, ODECL_FORWARD);
- output(";n");
- func->wasdeclared = 1;
- }
- /* Check if calling a parent procedure, whose body must */
- /* be declared forward */
- void need_forward_decl(func)
- Meaning *func;
- {
- Meaning *mp;
- if (func->wasdeclared)
- return;
- for (mp = curctx->ctx; mp; mp = mp->ctx) {
- if (mp == func) {
- if (func->ctx->kind == MK_FUNCTION)
- func->isforward = 1;
- else
- forward_decl(func, 0);
- return;
- }
- }
- }
- void free_stmt(sp)
- register Stmt *sp;
- {
- if (sp) {
- free_stmt(sp->stm1);
- free_stmt(sp->stm2);
- free_stmt(sp->next);
- freeexpr(sp->exp1);
- freeexpr(sp->exp2);
- freeexpr(sp->exp3);
- FREE(sp);
- }
- }
- Stmt *makestmt(kind)
- enum stmtkind kind;
- {
- Stmt *sp;
- sp = ALLOC(1, Stmt, stmts);
- sp->kind = kind;
- sp->next = NULL;
- sp->stm1 = NULL;
- sp->stm2 = NULL;
- sp->exp1 = NULL;
- sp->exp2 = NULL;
- sp->exp3 = NULL;
- sp->serial = curserial = ++serialcount;
- return sp;
- }
- Stmt *makestmt_call(call)
- Expr *call;
- {
- Stmt *sp = makestmt(SK_ASSIGN);
- sp->exp1 = call;
- return sp;
- }
- Stmt *makestmt_assign(lhs, rhs)
- Expr *lhs, *rhs;
- {
- Stmt *sp = makestmt(SK_ASSIGN);
- sp->exp1 = makeexpr_assign(lhs, rhs);
- return sp;
- }
- Stmt *makestmt_if(cond, thn, els)
- Expr *cond;
- Stmt *thn, *els;
- {
- Stmt *sp = makestmt(SK_IF);
- sp->exp1 = cond;
- sp->stm1 = thn;
- sp->stm2 = els;
- return sp;
- }
- Stmt *makestmt_seq(s1, s2)
- Stmt *s1, *s2;
- {
- Stmt *s1a;
- if (!s1)
- return s2;
- if (!s2)
- return s1;
- for (s1a = s1; s1a->next; s1a = s1a->next) ;
- s1a->next = s2;
- return s1;
- }
- Stmt *copystmt(sp)
- Stmt *sp;
- {
- Stmt *sp2;
- if (sp) {
- sp2 = makestmt(sp->kind);
- sp2->stm1 = copystmt(sp->stm1);
- sp2->stm2 = copystmt(sp->stm2);
- sp2->exp1 = copyexpr(sp->exp1);
- sp2->exp2 = copyexpr(sp->exp2);
- sp2->exp3 = copyexpr(sp->exp3);
- return sp2;
- } else
- return NULL;
- }
- void nukestmt(sp)
- Stmt *sp;
- {
- if (sp) {
- sp->kind = SK_ASSIGN;
- sp->exp1 = makeexpr_long(0);
- }
- }
- void splicestmt(sp, spnew)
- Stmt *sp, *spnew;
- {
- Stmt *snext;
- snext = sp->next;
- *sp = *spnew;
- while (sp->next)
- sp = sp->next;
- sp->next = snext;
- }
- int stmtcount(sp)
- Stmt *sp;
- {
- int i = 0;
- while (sp) {
- i += 1 + stmtcount(sp->stm1) + stmtcount(sp->stm2);
- sp = sp->next;
- }
- return i;
- }
- Stmt *close_files_to_ctx(ctx)
- Meaning *ctx;
- {
- Meaning *ctx2, *mp;
- Stmt *splist = NULL, *sp;
- ctx2 = curctx;
- while (ctx2 && ctx2 != ctx && ctx2->kind == MK_FUNCTION) {
- for (mp = ctx2->cbase; mp; mp = mp->cnext) {
- if (mp->kind == MK_VAR &&
- isfiletype(mp->type) && !mp->istemporary) {
- var_reference(mp);
- sp = makestmt_if(makeexpr_rel(EK_NE, makeexpr_var(mp),
- makeexpr_nil()),
- makestmt_call(
- makeexpr_bicall_1("fclose", tp_void,
- makeexpr_var(mp))),
- NULL);
- splist = makestmt_seq(splist, sp);
- }
- }
- ctx2 = ctx2->ctx;
- }
- return splist;
- }
- int simplewith(ex)
- Expr *ex;
- {
- switch (ex->kind) {
- case EK_VAR:
- case EK_CONST:
- return 1;
- case EK_DOT:
- return simplewith(ex->args[0]);
- default:
- return 0;
- }
- }
- int simplefor(sp, ex)
- Stmt *sp;
- Expr *ex;
- {
- return (exprspeed(sp->exp2) <= 3 &&
- !checkexprchanged(sp->stm1, sp->exp2) &&
- !exproccurs(sp->exp2, ex));
- }
- int tryfuncmacro(exp, mp)
- Expr **exp;
- Meaning *mp;
- {
- char *name;
- Strlist *lp;
- Expr *ex = *exp, *ex2;
- ex2 = (mp) ? mp->constdefn : NULL;
- if (!ex2) {
- if (ex->kind == EK_BICALL || ex->kind == EK_NAME)
- name = ex->val.s;
- else if (ex->kind == EK_FUNCTION)
- name = ((Meaning *)ex->val.i)->name;
- else
- return 0;
- lp = strlist_cifind(funcmacros, name);
- ex2 = (lp) ? (Expr *)lp->value : NULL;
- }
- if (ex2) {
- *exp = replacemacargs(copyexpr(ex2), ex);
- freeexpr(ex);
- return 1;
- }
- return 0;
- }
- #define addstmt(kind)
- *spp = sp = makestmt(kind),
- spp = &(sp->next)
- #define newstmt(kind)
- addstmt(kind),
- steal_comments(firstserial, sp->serial, sflags & SF_FIRST),
- sflags &= ~SF_FIRST
- #define SF_FUNC 0x1
- #define SF_SAVESER 0x2
- #define SF_FIRST 0x4
- #define SF_IF 0x8
- Static Stmt *p_stmt(slist, sflags)
- Stmt *slist;
- int sflags;
- {
- Stmt *sbase = NULL, **spp = &sbase, **spp2, **spp3, **savespp;
- Stmt *defsp, **defsphook;
- register Stmt *sp;
- Stmt *sp2;
- long li1, li2, firstserial = 0, saveserial = 0, saveserial2;
- int i, forfixed, offset, line1, line2, toobig, isunsafe;
- Token savetok;
- char *name;
- Expr *ep, *ep2, *ep3, *forstep, *range, *swexpr, *trueswexpr;
- Type *tp;
- Meaning *mp, *tvar, *tempmark;
- Symbol *sym;
- enum exprkind ekind;
- Stmt *(*prochandler)();
- Strlist *cmt;
- tempmark = markstmttemps();
- again:
- while (findlabelsym()) {
- newstmt(SK_LABEL);
- sp->exp1 = makeexpr_name(format_s(name_LABEL, curtokmeaning->name), tp_integer);
- 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;
- }
- if (curtok == TOK_VBAR)
- break;
- if (!wneedtok(TOK_END))
- skippasttoken(TOK_END);
- 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),
- NULL);
- if (defsphook != &defsp && elseif != 0)
- (*defsphook)->exp2 = makeexpr_long(1);
- defsphook = &((*defsphook)->stm2);
- } else {
- freeexpr(range);
- sp->stm1 = p_stmt(NULL, SF_SAVESER);
- }
- 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)
- 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);
- ep = p_expr(tp_integer);
- 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));
- 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, 0);
- 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 (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, 0x7);
- 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();
- 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);
- changecomments(curcomments, -1, saveserial2, -1, saveserial+1);
- if (sp->stm2 && sp->stm2->kind == SK_IF &&
- !sp->stm2->next && !modula2) {
- sp->stm2->exp2 = makeexpr_long(elseif > 0 ||
- (elseif < 0 && line1 == line2));
- }
- }
- 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));
- 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();
- if (withlevel >= MAXWITHS-1)
- error("Too many nested WITHs");
- ep = p_expr(NULL);
- if (ep->val.type->kind != TK_RECORD)
- warning("Argument of WITH is not a RECORD [264]");
- withlist[withlevel] = ep->val.type;
- if (simplewith(ep)) {
- withexprs[withlevel] = ep;
- mp = NULL;
- } else { /* need to save a temporary pointer */
- tp = makepointertype(ep->val.type);
- mp = makestmttempvar(tp, name_WITH);
- withexprs[withlevel] = makeexpr_hat(makeexpr_var(mp), 0);
- }
- withlevel++;
- if (curtok == TOK_COMMA) {
- curtok = TOK_WITH;
- sp2 = p_stmt(NULL, sflags & SF_FIRST);
- } else {
- wneedtok(TOK_DO);
- sp2 = p_stmt(NULL, sflags & SF_FIRST);
- }
- withlevel--;
- 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 {
- newstmt(SK_ASSIGN);
- 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_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) {
- 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++;
- 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() != '(') {
- mp = curctx;
- while (mp && mp != curtokmeaning)
- 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;
- 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;
- 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;
- break;
- 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")
- #define openbrace()
- wbraces = (!candeclare);
- if (wbraces) {
- output("{");
- outspnl(braceline <= 0);
- candeclare = 1;
- }
- #define closebrace()
- if (wbraces) {
- if (sp->next || braces)
- output("}n");
- else
- braces = 1;
- }
- 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;
- 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("