home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i074: Pascal to C translator, Part29/32
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: e2cd7442 ae0d945f bd38715f 243e88b5
-
- Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
- Posting-number: Volume 21, Issue 74
- Archive-name: p2c/part29
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 29 (of 32)."
- # Contents: src/parse.c.1
- # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:52 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/parse.c.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/parse.c.1'\"
- else
- echo shar: Extracting \"'src/parse.c.1'\" \(49384 characters\)
- sed "s/^X//" >'src/parse.c.1' <<'END_OF_FILE'
- X/* "p2c", a Pascal to C translator.
- X Copyright (C) 1989 David Gillespie.
- X Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
- X
- XThis program is free software; you can redistribute it and/or modify
- Xit under the terms of the GNU General Public License as published by
- Xthe Free Software Foundation (any version).
- X
- XThis program is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
- XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- XGNU General Public License for more details.
- X
- XYou should have received a copy of the GNU General Public License
- Xalong with this program; see the file COPYING. If not, write to
- Xthe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- X
- X
- X
- X#define PROTO_PARSE_C
- X#include "trans.h"
- X
- X
- X
- XStatic short candeclare;
- XStatic int trycount;
- XStatic Strlist *includedfiles;
- XStatic char echo_first;
- XStatic int echo_pos;
- X
- X
- X
- Xvoid setup_parse()
- X{
- X candeclare = 0;
- X trycount = 0;
- X includedfiles = NULL;
- X echo_first = 1;
- X echo_pos = 0;
- X fixexpr_tryblock = 0;
- X}
- X
- X
- X
- Xvoid echobreak()
- X{
- X if (echo_pos > 0) {
- X printf("\n");
- X echo_pos = 0;
- X echo_first = 0;
- X }
- X}
- X
- X
- Xvoid echoword(name, comma)
- Xchar *name;
- Xint comma;
- X{
- X FILE *f = (outf == stdout) ? stderr : stdout;
- X
- X if (quietmode || showprogress)
- X return;
- X if (!echo_first) {
- X if (comma) {
- X fprintf(f, ",");
- X echo_pos++;
- X }
- X if (echo_pos + strlen(name) > 77) {
- X fprintf(f, "\n");
- X echo_pos = 0;
- X } else {
- X fprintf(f, " ");
- X echo_pos++;
- X }
- X }
- X echo_first = 0;
- X fprintf(f, "%s", name);
- X echo_pos += strlen(name);
- X fflush(f);
- X}
- X
- X
- X
- Xvoid echoprocname(mp)
- XMeaning *mp;
- X{
- X echoword(mp->name, 1);
- X}
- X
- X
- X
- X
- X
- XStatic void forward_decl(func, isextern)
- XMeaning *func;
- Xint isextern;
- X{
- X if (func->wasdeclared)
- X return;
- X if (isextern && func->constdefn && !checkvarmac(func))
- X return;
- X if (isextern) {
- X output("extern ");
- X } else if (func->ctx->kind == MK_FUNCTION) {
- X if (useAnyptrMacros)
- X output("Local ");
- X else
- X output("static ");
- X } else if ((use_static != 0 && !useAnyptrMacros) ||
- X (findsymbol(func->name)->flags & NEEDSTATIC)) {
- X output("static ");
- X } else if (useAnyptrMacros) {
- X output("Static ");
- X }
- X if (func->type->basetype != tp_void || ansiC != 0) {
- X outbasetype(func->type, ODECL_FORWARD);
- X output(" ");
- X }
- X outdeclarator(func->type, func->name, ODECL_FORWARD);
- X output(";\n");
- X func->wasdeclared = 1;
- X}
- X
- X
- X
- X
- X/* Check if calling a parent procedure, whose body must */
- X/* be declared forward */
- X
- Xvoid need_forward_decl(func)
- XMeaning *func;
- X{
- X Meaning *mp;
- X
- X if (func->wasdeclared)
- X return;
- X for (mp = curctx->ctx; mp; mp = mp->ctx) {
- X if (mp == func) {
- X if (func->ctx->kind == MK_FUNCTION)
- X func->isforward = 1;
- X else
- X forward_decl(func, 0);
- X return;
- X }
- X }
- X}
- X
- X
- X
- X
- Xvoid free_stmt(sp)
- Xregister Stmt *sp;
- X{
- X if (sp) {
- X free_stmt(sp->stm1);
- X free_stmt(sp->stm2);
- X free_stmt(sp->next);
- X freeexpr(sp->exp1);
- X freeexpr(sp->exp2);
- X freeexpr(sp->exp3);
- X FREE(sp);
- X }
- X}
- X
- X
- X
- X
- XStmt *makestmt(kind)
- Xenum stmtkind kind;
- X{
- X Stmt *sp;
- X
- X sp = ALLOC(1, Stmt, stmts);
- X sp->kind = kind;
- X sp->next = NULL;
- X sp->stm1 = NULL;
- X sp->stm2 = NULL;
- X sp->exp1 = NULL;
- X sp->exp2 = NULL;
- X sp->exp3 = NULL;
- X sp->serial = curserial = ++serialcount;
- X return sp;
- X}
- X
- X
- X
- XStmt *makestmt_call(call)
- XExpr *call;
- X{
- X Stmt *sp = makestmt(SK_ASSIGN);
- X sp->exp1 = call;
- X return sp;
- X}
- X
- X
- X
- XStmt *makestmt_assign(lhs, rhs)
- XExpr *lhs, *rhs;
- X{
- X Stmt *sp = makestmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_assign(lhs, rhs);
- X return sp;
- X}
- X
- X
- X
- XStmt *makestmt_if(cond, thn, els)
- XExpr *cond;
- XStmt *thn, *els;
- X{
- X Stmt *sp = makestmt(SK_IF);
- X sp->exp1 = cond;
- X sp->stm1 = thn;
- X sp->stm2 = els;
- X return sp;
- X}
- X
- X
- X
- XStmt *makestmt_seq(s1, s2)
- XStmt *s1, *s2;
- X{
- X Stmt *s1a;
- X
- X if (!s1)
- X return s2;
- X if (!s2)
- X return s1;
- X for (s1a = s1; s1a->next; s1a = s1a->next) ;
- X s1a->next = s2;
- X return s1;
- X}
- X
- X
- X
- XStmt *copystmt(sp)
- XStmt *sp;
- X{
- X Stmt *sp2;
- X
- X if (sp) {
- X sp2 = makestmt(sp->kind);
- X sp2->stm1 = copystmt(sp->stm1);
- X sp2->stm2 = copystmt(sp->stm2);
- X sp2->exp1 = copyexpr(sp->exp1);
- X sp2->exp2 = copyexpr(sp->exp2);
- X sp2->exp3 = copyexpr(sp->exp3);
- X return sp2;
- X } else
- X return NULL;
- X}
- X
- X
- X
- Xvoid nukestmt(sp)
- XStmt *sp;
- X{
- X if (sp) {
- X sp->kind = SK_ASSIGN;
- X sp->exp1 = makeexpr_long(0);
- X }
- X}
- X
- X
- X
- Xvoid splicestmt(sp, spnew)
- XStmt *sp, *spnew;
- X{
- X Stmt *snext;
- X
- X snext = sp->next;
- X *sp = *spnew;
- X while (sp->next)
- X sp = sp->next;
- X sp->next = snext;
- X}
- X
- X
- X
- Xint stmtcount(sp)
- XStmt *sp;
- X{
- X int i = 0;
- X
- X while (sp) {
- X i += 1 + stmtcount(sp->stm1) + stmtcount(sp->stm2);
- X sp = sp->next;
- X }
- X return i;
- X}
- X
- X
- X
- X
- X
- XStmt *close_files_to_ctx(ctx)
- XMeaning *ctx;
- X{
- X Meaning *ctx2, *mp;
- X Stmt *splist = NULL, *sp;
- X
- X ctx2 = curctx;
- X while (ctx2 && ctx2 != ctx && ctx2->kind == MK_FUNCTION) {
- X for (mp = ctx2->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_VAR &&
- X isfiletype(mp->type) && !mp->istemporary) {
- X var_reference(mp);
- X sp = makestmt_if(makeexpr_rel(EK_NE, makeexpr_var(mp),
- X makeexpr_nil()),
- X makestmt_call(
- X makeexpr_bicall_1("fclose", tp_void,
- X makeexpr_var(mp))),
- X NULL);
- X splist = makestmt_seq(splist, sp);
- X }
- X }
- X ctx2 = ctx2->ctx;
- X }
- X return splist;
- X}
- X
- X
- X
- X
- Xint simplewith(ex)
- XExpr *ex;
- X{
- X switch (ex->kind) {
- X case EK_VAR:
- X case EK_CONST:
- X return 1;
- X case EK_DOT:
- X return simplewith(ex->args[0]);
- X default:
- X return 0;
- X }
- X}
- X
- X
- Xint simplefor(sp, ex)
- XStmt *sp;
- XExpr *ex;
- X{
- X return (exprspeed(sp->exp2) <= 3 &&
- X !checkexprchanged(sp->stm1, sp->exp2) &&
- X !exproccurs(sp->exp2, ex));
- X}
- X
- X
- X
- Xint tryfuncmacro(exp, mp)
- XExpr **exp;
- XMeaning *mp;
- X{
- X char *name;
- X Strlist *lp;
- X Expr *ex = *exp, *ex2;
- X
- X ex2 = (mp) ? mp->constdefn : NULL;
- X if (!ex2) {
- X if (ex->kind == EK_BICALL || ex->kind == EK_NAME)
- X name = ex->val.s;
- X else if (ex->kind == EK_FUNCTION)
- X name = ((Meaning *)ex->val.i)->name;
- X else
- X return 0;
- X lp = strlist_cifind(funcmacros, name);
- X ex2 = (lp) ? (Expr *)lp->value : NULL;
- X }
- X if (ex2) {
- X *exp = replacemacargs(copyexpr(ex2), ex);
- X freeexpr(ex);
- X return 1;
- X }
- X return 0;
- X}
- X
- X
- X
- X
- X
- X#define addstmt(kind) \
- X *spp = sp = makestmt(kind), \
- X spp = &(sp->next)
- X
- X#define newstmt(kind) \
- X addstmt(kind), \
- X steal_comments(firstserial, sp->serial, sflags & SF_FIRST), \
- X sflags &= ~SF_FIRST
- X
- X
- X
- X#define SF_FUNC 0x1
- X#define SF_SAVESER 0x2
- X#define SF_FIRST 0x4
- X#define SF_IF 0x8
- X
- XStatic Stmt *p_stmt(slist, sflags)
- XStmt *slist;
- Xint sflags;
- X{
- X Stmt *sbase = NULL, **spp = &sbase, **spp2, **spp3, **savespp;
- X Stmt *defsp, **defsphook;
- X register Stmt *sp;
- X Stmt *sp2;
- X long li1, li2, firstserial = 0, saveserial = 0, saveserial2;
- X int i, forfixed, offset, line1, line2, toobig, isunsafe;
- X Token savetok;
- X char *name;
- X Expr *ep, *ep2, *ep3, *forstep, *range, *swexpr, *trueswexpr;
- X Type *tp;
- X Meaning *mp, *tvar, *tempmark;
- X Symbol *sym;
- X enum exprkind ekind;
- X Stmt *(*prochandler)();
- X Strlist *cmt;
- X
- X tempmark = markstmttemps();
- Xagain:
- X while (findlabelsym()) {
- X newstmt(SK_LABEL);
- X sp->exp1 = makeexpr_name(format_s(name_LABEL, curtokmeaning->name), tp_integer);
- X gettok();
- X wneedtok(TOK_COLON);
- X }
- X firstserial = curserial;
- X checkkeyword(TOK_TRY);
- X checkkeyword(TOK_INLINE);
- X checkkeyword(TOK_LOOP);
- X checkkeyword(TOK_RETURN);
- X if (modula2) {
- X if (sflags & SF_SAVESER)
- X goto stmtSeq;
- X }
- X switch (curtok) {
- X
- X case TOK_BEGIN:
- X stmtSeq:
- X if (sflags & (SF_FUNC|SF_SAVESER)) {
- X saveserial = curserial;
- X cmt = grabcomment(CMT_ONBEGIN);
- X if (sflags & SF_FUNC)
- X cmt = fixbeginendcomment(cmt);
- X strlist_mix(&curcomments, cmt);
- X }
- X i = sflags & SF_FIRST;
- X do {
- X if (modula2) {
- X if (curtok == TOK_BEGIN || curtok == TOK_SEMI)
- X gettok();
- X checkkeyword(TOK_ELSIF);
- X if (curtok == TOK_ELSE || curtok == TOK_ELSIF)
- X break;
- X } else
- X gettok();
- X *spp = p_stmt(sbase, i);
- X i = 0;
- X while (*spp)
- X spp = &((*spp)->next);
- X } while (curtok == TOK_SEMI);
- X if (sflags & (SF_FUNC|SF_SAVESER)) {
- X cmt = grabcomment(CMT_ONEND);
- X changecomments(cmt, -1, -1, -1, saveserial);
- X if (sflags & SF_FUNC)
- X cmt = fixbeginendcomment(cmt);
- X strlist_mix(&curcomments, cmt);
- X if (sflags & SF_FUNC)
- X changecomments(curcomments, -1, saveserial, -1, 10000);
- X curserial = saveserial;
- X }
- X checkkeyword(TOK_ELSIF);
- X if (modula2 && (sflags & SF_IF)) {
- X break;
- X }
- X if (curtok == TOK_VBAR)
- X break;
- X if (!wneedtok(TOK_END))
- X skippasttoken(TOK_END);
- X break;
- X
- X case TOK_CASE:
- X gettok();
- X swexpr = trueswexpr = p_ord_expr();
- X if (nosideeffects(swexpr, 1)) {
- X tvar = NULL;
- X } else {
- X tvar = makestmttempvar(swexpr->val.type, name_TEMP);
- X swexpr = makeexpr_var(tvar);
- X }
- X savespp = spp;
- X newstmt(SK_CASE);
- X saveserial2 = curserial;
- X sp->exp1 = trueswexpr;
- X spp2 = &sp->stm1;
- X tp = swexpr->val.type;
- X defsp = NULL;
- X defsphook = &defsp;
- X if (!wneedtok(TOK_OF)) {
- X skippasttoken(TOK_END);
- X break;
- X }
- X i = 1;
- X while (curtok == TOK_VBAR)
- X gettok();
- X checkkeyword(TOK_OTHERWISE);
- X while (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) {
- X spp3 = spp2;
- X saveserial = curserial;
- X *spp2 = sp = makestmt(SK_CASELABEL);
- X steal_comments(saveserial, sp->serial, i);
- X spp2 = &sp->next;
- X range = NULL;
- X toobig = 0;
- X for (;;) {
- X ep = gentle_cast(p_expr(tp), tp);
- X if (curtok == TOK_DOTS) {
- X li1 = ord_value(eval_expr(ep));
- X gettok();
- X ep2 = gentle_cast(p_expr(tp), tp);
- X li2 = ord_value(eval_expr(ep2));
- X range = makeexpr_or(range,
- X makeexpr_range(copyexpr(swexpr),
- X ep, ep2, 1));
- X if (li2 - li1 >= caselimit)
- X toobig = 1;
- X if (!toobig) {
- X for (;;) {
- X sp->exp1 = makeexpr_val(make_ord(tp, li1));
- X if (li1 >= li2) break;
- X li1++;
- X serialcount--; /* make it reuse the count */
- X sp->stm1 = makestmt(SK_CASELABEL);
- X sp = sp->stm1;
- X }
- X }
- X } else {
- X sp->exp1 = copyexpr(ep);
- X range = makeexpr_or(range,
- X makeexpr_rel(EK_EQ,
- X copyexpr(swexpr),
- X ep));
- X }
- X if (curtok == TOK_COMMA) {
- X gettok();
- X serialcount--; /* make it reuse the count */
- X sp->stm1 = makestmt(SK_CASELABEL);
- X sp = sp->stm1;
- X } else
- X break;
- X }
- X wneedtok(TOK_COLON);
- X if (toobig) {
- X free_stmt(*spp3);
- X spp2 = spp3;
- X *defsphook = makestmt_if(range, p_stmt(NULL, SF_SAVESER),
- X NULL);
- X if (defsphook != &defsp && elseif != 0)
- X (*defsphook)->exp2 = makeexpr_long(1);
- X defsphook = &((*defsphook)->stm2);
- X } else {
- X freeexpr(range);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER);
- X }
- X i = 0;
- X checkkeyword(TOK_OTHERWISE);
- X if (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) {
- X if (curtok == TOK_VBAR) {
- X while (curtok == TOK_VBAR)
- X gettok();
- X } else
- X wneedtok(TOK_SEMI);
- X checkkeyword(TOK_OTHERWISE);
- X }
- X }
- X if (defsp) {
- X *spp2 = defsp;
- X spp2 = defsphook;
- X if (tvar) {
- X sp = makestmt_assign(makeexpr_var(tvar), trueswexpr);
- X sp->next = *savespp;
- X *savespp = sp;
- X sp->next->exp1 = swexpr;
- X }
- X } else {
- X if (tvar) {
- X canceltempvar(tvar);
- X freeexpr(swexpr);
- X }
- X }
- X if (curtok == TOK_OTHERWISE || curtok == TOK_ELSE) {
- X gettok();
- X while (curtok == TOK_SEMI)
- X gettok();
- X/* changecomments(curcomments, CMT_TRAIL, curserial,
- X CMT_POST, -1); */
- X i = SF_FIRST;
- X while (curtok != TOK_END) {
- X *spp2 = p_stmt(NULL, i);
- X while (*spp2)
- X spp2 = &((*spp2)->next);
- X i = 0;
- X if (curtok != TOK_SEMI)
- X break;
- X gettok();
- X }
- X if (!wexpecttok(TOK_END))
- X skiptotoken(TOK_END);
- X } else if (casecheck == 1 || (casecheck == 2 && range_flag)) {
- X *spp2 = makestmt(SK_CASECHECK);
- X }
- X curserial = saveserial2;
- X strlist_mix(&curcomments, grabcomment(CMT_ONEND));
- X gettok();
- X break;
- X
- X case TOK_FOR:
- X forfixed = fixedflag;
- X gettok();
- X newstmt(SK_FOR);
- X ep = p_expr(tp_integer);
- X if (!wneedtok(TOK_ASSIGN)) {
- X skippasttoken(TOK_DO);
- X break;
- X }
- X ep2 = makeexpr_charcast(p_expr(ep->val.type));
- X if (curtok != TOK_DOWNTO) {
- X if (!wexpecttok(TOK_TO)) {
- X skippasttoken(TOK_DO);
- X break;
- X }
- X }
- X savetok = curtok;
- X gettok();
- X sp->exp2 = makeexpr_charcast(p_expr(ep->val.type));
- X checkkeyword(TOK_BY);
- X if (curtok == TOK_BY) {
- X gettok();
- X forstep = p_expr(tp_integer);
- X i = possiblesigns(forstep);
- X if ((i & 5) == 5) {
- X if (expr_is_neg(forstep)) {
- X ekind = EK_GE;
- X note("Assuming FOR loop step is negative [252]");
- X } else {
- X ekind = EK_LE;
- X note("Assuming FOR loop step is positive [252]");
- X }
- X } else {
- X if (!(i & 1))
- X ekind = EK_LE;
- X else
- X ekind = EK_GE;
- X }
- X } else {
- X if (savetok == TOK_DOWNTO) {
- X ekind = EK_GE;
- X forstep = makeexpr_long(-1);
- X } else {
- X ekind = EK_LE;
- X forstep = makeexpr_long(1);
- X }
- X }
- X tvar = NULL;
- X swexpr = NULL;
- X if (ep->kind == EK_VAR) {
- X tp = findbasetype(ep->val.type, 0);
- X if ((tp == tp_char || tp == tp_schar || tp == tp_uchar ||
- X tp == tp_abyte || tp == tp_sbyte || tp == tp_ubyte ||
- X tp == tp_boolean) &&
- X ((checkconst(sp->exp2, 0) &&
- X tp != tp_sbyte && tp != tp_schar) ||
- X checkconst(sp->exp2, -128) ||
- X (checkconst(sp->exp2, 127) &&
- X tp != tp_ubyte && tp != tp_uchar) ||
- X checkconst(sp->exp2, 255) ||
- X (tp == tp_char &&
- X (useAnyptrMacros == 1 || unsignedchar != 1) &&
- X isliteralconst(sp->exp2, NULL) == 2 &&
- X sp->exp2->val.i >= 128))) {
- X swexpr = ep;
- X tvar = makestmttempvar(tp_sshort, name_TEMP);
- X ep = makeexpr_var(tvar);
- X } else if (((tp == tp_sshort &&
- X (checkconst(sp->exp2, -32768) ||
- X checkconst(sp->exp2, 32767))) ||
- X (tp == tp_ushort &&
- X (checkconst(sp->exp2, 0) ||
- X checkconst(sp->exp2, 65535))))) {
- X swexpr = ep;
- X tvar = makestmttempvar(tp_integer, name_TEMP);
- X ep = makeexpr_var(tvar);
- X } else if (tp == tp_integer &&
- X (checkconst(sp->exp2, LONG_MAX) ||
- X (sp->exp2->kind == EK_VAR &&
- X sp->exp2->val.i == (long)mp_maxint))) {
- X swexpr = ep;
- X tvar = makestmttempvar(tp_unsigned, name_TEMP);
- X ep = makeexpr_var(tvar);
- X }
- X }
- X sp->exp3 = makeexpr_assign(copyexpr(ep),
- X makeexpr_inc(copyexpr(ep),
- X copyexpr(forstep)));
- X wneedtok(TOK_DO);
- X forfixed = (fixedflag != forfixed);
- X mp = makestmttempvar(ep->val.type, name_FOR);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER);
- X if (tvar) {
- X if (checkexprchanged(sp->stm1, swexpr))
- X note(format_s("Rewritten FOR loop won't work if it meddles with %s [253]",
- X ((Meaning *)swexpr->val.i)->name));
- X sp->stm1 = makestmt_seq(makestmt_assign(swexpr, makeexpr_var(tvar)),
- X sp->stm1);
- X } else if (offsetforloops && ep->kind == EK_VAR) {
- X offset = checkvaroffset(sp->stm1, (Meaning *)ep->val.i);
- X if (offset != 0) {
- X ep3 = makeexpr_inc(copyexpr(ep), makeexpr_long(-offset));
- X replaceexpr(sp->stm1, ep, ep3);
- X freeexpr(ep3);
- X ep2 = makeexpr_plus(ep2, makeexpr_long(offset));
- X sp->exp2 = makeexpr_inc(sp->exp2, makeexpr_long(offset));
- X }
- X }
- X if (!exprsame(ep, ep2, 1))
- X sp->exp1 = makeexpr_assign(copyexpr(ep), copyexpr(ep2));
- X isunsafe = ((!nodependencies(ep2, 2) &&
- X !nosideeffects(sp->exp2, 1)) ||
- X (!nodependencies(sp->exp2, 2) &&
- X !nosideeffects(ep2, 1)));
- X if (forfixed || (simplefor(sp, ep) && !isunsafe)) {
- X canceltempvar(mp);
- X sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2);
- X } else {
- X ep3 = makeexpr_neg(copyexpr(forstep));
- X if ((checkconst(forstep, 1) || checkconst(forstep, -1)) &&
- X sp->exp2->kind == EK_PLUS &&
- X exprsame(sp->exp2->args[sp->exp2->nargs-1], ep3, 2)) {
- X sp->exp2 = makeexpr_inc(sp->exp2, forstep);
- X } else {
- X freeexpr(forstep);
- X freeexpr(ep3);
- X ep3 = makeexpr_long(0);
- X }
- X if (forevalorder && isunsafe) {
- X if (exprdepends(sp->exp2, ep)) {
- X tvar = makestmttempvar(mp->type, name_TEMP);
- X sp->exp1 = makeexpr_comma(
- X makeexpr_comma(
- X makeexpr_assign(makeexpr_var(tvar),
- X copyexpr(ep2)),
- X makeexpr_assign(makeexpr_var(mp),
- X sp->exp2)),
- X makeexpr_assign(copyexpr(ep),
- X makeexpr_var(tvar)));
- X } else
- X sp->exp1 = makeexpr_comma(
- X sp->exp1,
- X makeexpr_assign(makeexpr_var(mp),
- X sp->exp2));
- X } else {
- X if (isunsafe)
- X note("Evaluating FOR loop limit before initial value [315]");
- X sp->exp1 = makeexpr_comma(
- X makeexpr_assign(makeexpr_var(mp),
- X sp->exp2),
- X sp->exp1);
- X }
- X sp->exp2 = makeexpr_inc(makeexpr_var(mp), ep3);
- X sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2);
- X }
- X freeexpr(ep2);
- X break;
- X
- X case TOK_GOTO:
- X gettok();
- X if (findlabelsym()) {
- X if (curtokmeaning->ctx != curctx) {
- X curtokmeaning->val.i = 1;
- X *spp = close_files_to_ctx(curtokmeaning->ctx);
- X while (*spp)
- X spp = &((*spp)->next);
- X newstmt(SK_ASSIGN);
- X var_reference(curtokmeaning->xnext);
- X if (curtokmeaning->ctx->kind == MK_MODULE &&
- X !curtokmeaning->xnext->wasdeclared) {
- X outsection(minorspace);
- X declarevar(curtokmeaning->xnext, 0x7);
- X curtokmeaning->xnext->wasdeclared = 1;
- X outsection(minorspace);
- X }
- X sp->exp1 = makeexpr_bicall_2("longjmp", tp_void,
- X makeexpr_var(curtokmeaning->xnext),
- X makeexpr_long(1));
- X } else {
- X newstmt(SK_GOTO);
- X sp->exp1 = makeexpr_name(format_s(name_LABEL,
- X curtokmeaning->name),
- X tp_integer);
- X }
- X } else {
- X warning("Expected a label [263]");
- X }
- X gettok();
- X break;
- X
- X case TOK_IF:
- X gettok();
- X newstmt(SK_IF);
- X saveserial = curserial;
- X curserial = ++serialcount;
- X sp->exp1 = p_expr(tp_boolean);
- X wneedtok(TOK_THEN);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF);
- X changecomments(curcomments, -1, saveserial+1, -1, saveserial);
- X checkkeyword(TOK_ELSIF);
- X while (curtok == TOK_ELSIF) {
- X gettok();
- X sp->stm2 = makestmt(SK_IF);
- X sp = sp->stm2;
- X sp->exp1 = p_expr(tp_boolean);
- X wneedtok(TOK_THEN);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF);
- X sp->exp2 = makeexpr_long(1);
- X }
- X if (curtok == TOK_ELSE) {
- X line1 = inf_lnum;
- X strlist_mix(&curcomments, grabcomment(CMT_ONELSE));
- X gettok();
- X line2 = (curtok == TOK_IF) ? inf_lnum : -1;
- X saveserial2 = curserial;
- X sp->stm2 = p_stmt(NULL, SF_SAVESER|SF_IF);
- X changecomments(curcomments, -1, saveserial2, -1, saveserial+1);
- X if (sp->stm2 && sp->stm2->kind == SK_IF &&
- X !sp->stm2->next && !modula2) {
- X sp->stm2->exp2 = makeexpr_long(elseif > 0 ||
- X (elseif < 0 && line1 == line2));
- X }
- X }
- X if (modula2)
- X wneedtok(TOK_END);
- X curserial = saveserial;
- X break;
- X
- X case TOK_INLINE:
- X gettok();
- X note("Inline assembly language encountered [254]");
- X if (curtok != TOK_LPAR) { /* Macintosh style */
- X newstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_bicall_1("inline", tp_void,
- X p_expr(tp_integer));
- X break;
- X }
- X do {
- X name = getinlinepart();
- X if (!*name)
- X break;
- X newstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_bicall_1("asm", tp_void,
- X makeexpr_string(format_s(" inline %s", name)));
- X gettok();
- X } while (curtok == TOK_SLASH);
- X skipcloseparen();
- X break;
- X
- X case TOK_LOOP:
- X gettok();
- X newstmt(SK_WHILE);
- X sp->exp1 = makeexpr_long(1);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER);
- X break;
- X
- X case TOK_REPEAT:
- X newstmt(SK_REPEAT);
- X saveserial = curserial;
- X spp2 = &(sp->stm1);
- X i = SF_FIRST;
- X do {
- X gettok();
- X *spp2 = p_stmt(sp->stm1, i);
- X i = 0;
- X while (*spp2)
- X spp2 = &((*spp2)->next);
- X } while (curtok == TOK_SEMI);
- X if (!wneedtok(TOK_UNTIL))
- X skippasttoken(TOK_UNTIL);
- X sp->exp1 = makeexpr_not(p_expr(tp_boolean));
- X curserial = saveserial;
- X strlist_mix(&curcomments, grabcomment(CMT_ONEND));
- X break;
- X
- X case TOK_RETURN:
- X gettok();
- X newstmt(SK_RETURN);
- X if (curctx->isfunction) {
- X sp->exp1 = gentle_cast(p_expr(curctx->cbase->type),
- X curctx->cbase->type);
- X }
- X break;
- X
- X case TOK_TRY:
- X findsymbol("RECOVER")->flags &= ~KWPOSS;
- X newstmt(SK_TRY);
- X sp->exp1 = makeexpr_long(++trycount);
- X spp2 = &(sp->stm1);
- X i = SF_FIRST;
- X do {
- X gettok();
- X *spp2 = p_stmt(sp->stm1, i);
- X i = 0;
- X while (*spp2)
- X spp2 = &((*spp2)->next);
- X } while (curtok == TOK_SEMI);
- X if (!wneedtok(TOK_RECOVER))
- X skippasttoken(TOK_RECOVER);
- X sp->stm2 = p_stmt(NULL, SF_SAVESER);
- X break;
- X
- X case TOK_WHILE:
- X gettok();
- X newstmt(SK_WHILE);
- X sp->exp1 = p_expr(tp_boolean);
- X wneedtok(TOK_DO);
- X sp->stm1 = p_stmt(NULL, SF_SAVESER);
- X break;
- X
- X case TOK_WITH:
- X gettok();
- X if (withlevel >= MAXWITHS-1)
- X error("Too many nested WITHs");
- X ep = p_expr(NULL);
- X if (ep->val.type->kind != TK_RECORD)
- X warning("Argument of WITH is not a RECORD [264]");
- X withlist[withlevel] = ep->val.type;
- X if (simplewith(ep)) {
- X withexprs[withlevel] = ep;
- X mp = NULL;
- X } else { /* need to save a temporary pointer */
- X tp = makepointertype(ep->val.type);
- X mp = makestmttempvar(tp, name_WITH);
- X withexprs[withlevel] = makeexpr_hat(makeexpr_var(mp), 0);
- X }
- X withlevel++;
- X if (curtok == TOK_COMMA) {
- X curtok = TOK_WITH;
- X sp2 = p_stmt(NULL, sflags & SF_FIRST);
- X } else {
- X wneedtok(TOK_DO);
- X sp2 = p_stmt(NULL, sflags & SF_FIRST);
- X }
- X withlevel--;
- X if (mp) { /* if "with p^" for constant p, don't need temp ptr */
- X if (ep->kind == EK_HAT && ep->args[0]->kind == EK_VAR &&
- X !checkvarchanged(sp2, (Meaning *)ep->args[0]->val.i)) {
- X replaceexpr(sp2, withexprs[withlevel]->args[0],
- X ep->args[0]);
- X freeexpr(ep);
- X canceltempvar(mp);
- X } else {
- X newstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_assign(makeexpr_var(mp),
- X makeexpr_addr(ep));
- X }
- X }
- X freeexpr(withexprs[withlevel]);
- X *spp = sp2;
- X while (*spp)
- X spp = &((*spp)->next);
- X break;
- X
- X case TOK_INCLUDE:
- X badinclude();
- X goto again;
- X
- X case TOK_ADDR: /* flakey Turbo "@procptr := anyptr" assignment */
- X newstmt(SK_ASSIGN);
- X ep = p_expr(tp_void);
- X if (wneedtok(TOK_ASSIGN))
- X sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type));
- X else
- X sp->exp1 = ep;
- X break;
- X
- X case TOK_IDENT:
- X mp = curtokmeaning;
- X if (mp == mp_str_hp)
- X mp = curtokmeaning = mp_str_turbo;
- X if (mp == mp_val_modula)
- X mp = curtokmeaning = mp_val_turbo;
- X if (mp == mp_blockread_ucsd)
- X mp = curtokmeaning = mp_blockread_turbo;
- X if (mp == mp_blockwrite_ucsd)
- X mp = curtokmeaning = mp_blockwrite_turbo;
- X if (mp == mp_dec_dec)
- X mp = curtokmeaning = mp_dec_turbo;
- X if (!mp) {
- X sym = curtoksym; /* make a guess at what the undefined name is... */
- X name = stralloc(curtokcase);
- X gettok();
- X newstmt(SK_ASSIGN);
- X if (curtok == TOK_ASSIGN) {
- X gettok();
- X ep = p_expr(NULL);
- X mp = addmeaning(sym, MK_VAR);
- X mp->name = name;
- X mp->type = ep->val.type;
- X sp->exp1 = makeexpr_assign(makeexpr_var(mp), ep);
- X } else if (curtok == TOK_HAT || curtok == TOK_ADDR ||
- X curtok == TOK_LBR || curtok == TOK_DOT) {
- X ep = makeexpr_name(name, tp_integer);
- X ep = fake_dots_n_hats(ep);
- X if (wneedtok(TOK_ASSIGN))
- X sp->exp1 = makeexpr_assign(ep, p_expr(NULL));
- X else
- X sp->exp1 = ep;
- X } else if (curtok == TOK_LPAR) {
- X ep = makeexpr_bicall_0(name, tp_void);
- X do {
- X gettok();
- X insertarg(&ep, ep->nargs, p_expr(NULL));
- X } while (curtok == TOK_COMMA);
- X skipcloseparen();
- X sp->exp1 = ep;
- X } else {
- X sp->exp1 = makeexpr_bicall_0(name, tp_void);
- X }
- X if (!tryfuncmacro(&sp->exp1, NULL))
- X undefsym(sym);
- X } else if (mp->kind == MK_FUNCTION && !mp->isfunction) {
- X mp->refcount++;
- X gettok();
- X ep = p_funccall(mp);
- X if (!mp->constdefn)
- X need_forward_decl(mp);
- X if (mp->handler && !(mp->sym->flags & LEAVEALONE) &&
- X !mp->constdefn) {
- X prochandler = (Stmt *(*)())mp->handler;
- X *spp = (*prochandler)(ep, slist);
- X while (*spp)
- X spp = &((*spp)->next);
- X } else {
- X newstmt(SK_ASSIGN);
- X sp->exp1 = ep;
- X }
- X } else if (mp->kind == MK_SPECIAL) {
- X gettok();
- X if (mp->handler && !mp->isfunction) {
- X if ((mp->sym->flags & LEAVEALONE) || mp->constdefn) {
- X ep = makeexpr_bicall_0(mp->name, tp_void);
- X if (curtok == TOK_LPAR) {
- X do {
- X gettok();
- X insertarg(&ep, ep->nargs, p_expr(NULL));
- X } while (curtok == TOK_COMMA);
- X skipcloseparen();
- X }
- X newstmt(SK_ASSIGN);
- X tryfuncmacro(&ep, mp);
- X sp->exp1 = ep;
- X } else {
- X prochandler = (Stmt *(*)())mp->handler;
- X *spp = (*prochandler)(mp, slist);
- X while (*spp)
- X spp = &((*spp)->next);
- X }
- X } else
- X symclass(curtoksym);
- X } else {
- X newstmt(SK_ASSIGN);
- X if (curtokmeaning->kind == MK_FUNCTION &&
- X peeknextchar() != '(') {
- X mp = curctx;
- X while (mp && mp != curtokmeaning)
- X mp = mp->ctx;
- X if (mp)
- X curtokmeaning = curtokmeaning->cbase;
- X }
- X ep = p_expr(tp_void);
- X#if 0
- X if (!(ep->kind == EK_SPCALL ||
- X (ep->kind == EK_COND &&
- X ep->args[1]->kind == EK_SPCALL)))
- X wexpecttok(TOK_ASSIGN);
- X#endif
- X if (curtok == TOK_ASSIGN) {
- X gettok();
- X if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "ZERO") &&
- X !curtokmeaning) { /* VAX Pascal foolishness */
- X gettok();
- X ep2 = makeexpr_sizeof(copyexpr(ep), 0);
- X sp->exp1 = makeexpr_bicall_3("memset", tp_void,
- X makeexpr_addr(ep),
- X makeexpr_long(0), ep2);
- X } else
- X sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type));
- X } else
- X sp->exp1 = ep;
- X }
- X break;
- X
- X default:
- X break; /* null statement */
- X }
- X freestmttemps(tempmark);
- X if (sflags & SF_SAVESER)
- X curserial = firstserial;
- X return sbase;
- X}
- X
- X
- X
- X
- X
- X
- X
- X#define BR_NEVER 0x1 /* never use braces */
- X#define BR_FUNCTION 0x2 /* function body */
- X#define BR_THENPART 0x4 /* before an "else" */
- X#define BR_ALWAYS 0x8 /* always use braces */
- X#define BR_REPEAT 0x10 /* "do-while" loop */
- X#define BR_TRY 0x20 /* in a recover block */
- X#define BR_ELSEPART 0x40 /* after an "else" */
- X#define BR_CASE 0x80 /* case of a switch stmt */
- X
- XStatic int usebraces(sp, opts)
- XStmt *sp;
- Xint opts;
- X{
- X if (opts & (BR_FUNCTION|BR_ALWAYS))
- X return 1;
- X if (opts & BR_NEVER)
- X return 0;
- X switch (bracesalways) {
- X case 0:
- X if (sp) {
- X if (sp->next ||
- X sp->kind == SK_TRY ||
- X (sp->kind == SK_IF && !sp->stm2) ||
- X (opts & BR_REPEAT))
- X return 1;
- X }
- X break;
- X
- X case 1:
- X return 1;
- X break;
- X
- X default:
- X if (sp) {
- X if (sp->next ||
- X sp->kind == SK_IF ||
- X sp->kind == SK_WHILE ||
- X sp->kind == SK_REPEAT ||
- X sp->kind == SK_TRY ||
- X sp->kind == SK_CASE ||
- X sp->kind == SK_FOR)
- X return 1;
- X }
- X break;
- X }
- X if (sp != NULL &&
- X findcomment(curcomments, CMT_NOT | CMT_TRAIL, sp->serial) != NULL)
- X return 1;
- X return 0;
- X}
- X
- X
- X
- X#define outspnl(spflag) output((spflag) ? " " : "\n")
- X
- X#define openbrace() \
- X wbraces = (!candeclare); \
- X if (wbraces) { \
- X output("{"); \
- X outspnl(braceline <= 0); \
- X candeclare = 1; \
- X }
- X
- X#define closebrace() \
- X if (wbraces) { \
- X if (sp->next || braces) \
- X output("}\n"); \
- X else \
- X braces = 1; \
- X }
- X
- X
- X
- XMeaning *outcontext;
- X
- XStatic void outnl(serial)
- Xint serial;
- X{
- X outtrailcomment(curcomments, serial, commentindent);
- X}
- X
- X
- XStatic void out_block(spbase, opts, serial)
- XStmt *spbase;
- Xint opts, serial;
- X{
- X int i, j, braces, always, trynum, istrail, hascmt;
- X int gotcomments = 0;
- X int saveindent, saveindent2, delta;
- X Stmt *sp = spbase;
- X Stmt *sp2, *sp3;
- X Meaning *ctx, *mp;
- X Strlist *curcmt, *cmt, *savecurcmt = curcomments;
- X Strlist *trailcmt, *begincmt, *endcmt;
- X
- X if (debug>1) { fprintf(outf, "out_block of:\n"); dumpstmt(spbase,5); }
- X if (opts & BR_FUNCTION) {
- X if (outcontext && outcontext->comments) {
- X gotcomments = 1;
- X curcomments = outcontext->comments;
- X }
- X attach_comments(spbase);
- X }
- X braces = usebraces(sp, opts);
- X trailcmt = findcomment(curcomments, CMT_TRAIL, serial);
- X begincmt = findcomment(curcomments, CMT_ONBEGIN, serial);
- X istrail = 1;
- X if (!trailcmt) {
- X trailcmt = begincmt;
- X begincmt = NULL;
- X istrail = 0;
- X }
- X endcmt = findcomment(curcomments, CMT_ONEND, serial);
- X if ((begincmt || endcmt) && !(opts & BR_NEVER))
- X braces = 1;
- X if (opts & BR_ELSEPART) {
- X cmt = findcomment(curcomments, CMT_ONELSE, serial);
- X if (cmt) {
- X if (trailcmt) {
- X out_spaces(bracecommentindent, commentoverindent,
- X commentlen(cmt), 0);
- X output("\001");
- X outcomment(cmt);
- X } else
- X trailcmt = cmt;
- X }
- X }
- X if (braces) {
- X j = (opts & BR_FUNCTION) ? funcopenindent : openbraceindent;
- X if (!line_start()) {
- X if (trailcmt &&
- X cur_column() + commentlen(trailcmt) + 2 > linewidth &&
- X outindent + commentlen(trailcmt) + 2 < linewidth) /*close enough*/
- X i = 0;
- X else if (opts & BR_ELSEPART)
- X i = ((braceelseline & 2) == 0);
- X else if (braceline >= 0)
- X i = (braceline == 0);
- X else
- X i = ((opts & BR_FUNCTION) == 0);
- X if (trailcmt && begincmt) {
- X out_spaces(commentindent, commentoverindent,
- X commentlen(trailcmt), j);
- X outcomment(trailcmt);
- X trailcmt = begincmt;
- X begincmt = NULL;
- X istrail = 0;
- X } else
- X outspnl(i);
- X }
- X if (line_start())
- X singleindent(j);
- X output("{");
- X candeclare = 1;
- X } else if (!sp) {
- X if (!line_start())
- X outspnl(!nullstmtline && !(opts & BR_TRY));
- X if (line_start())
- X singleindent(tabsize);
- X output(";");
- X }
- X if (opts & BR_CASE)
- X delta = 0;
- X else {
- X delta = tabsize;
- X if (opts & BR_FUNCTION)
- X delta = adddeltas(delta, bodyindent);
- X else if (braces)
- X delta = adddeltas(delta, blockindent);
- X }
- X futureindent(delta);
- X if (bracecombine && braces)
- X i = applydelta(outindent, delta) - cur_column();
- X else
- X i = -1;
- X if (commentvisible(trailcmt)) {
- X if (line_start()) {
- X singleindent(delta);
- X out_spaces(commentoverindent, 1000, commentlen(trailcmt), 0);
- X outcomment(trailcmt);
- X } else /*if (commentlen(trailcmt) + cur_column() + 1 <= linewidth)*/ {
- X out_spaces(istrail ? commentindent : bracecommentindent,
- X commentoverindent, commentlen(trailcmt), delta);
- X outcomment(trailcmt);
- X } /*else {
- X output("\n");
- X singleindent(delta);
- X out_spaces(commentoverindent, 1000, commentlen(trailcmt), 0);
- X outcomment(trailcmt);
- X }*/
- X i = -9999;
- X }
- X if (i > 0)
- X out_spaces(i, 0, 0, 0);
- X else if (i != -9999)
- X output("\n");
- X saveindent = outindent;
- X moreindent(delta);
- X outcomment(begincmt);
- X while (sp) {
- X flushcomments(NULL, CMT_PRE, sp->serial);
- X if (cmtdebug)
- X output(format_d("[%d] ", sp->serial));
- X switch (sp->kind) {
- X
- X case SK_HEADER:
- X ctx = (Meaning *)sp->exp1->val.i;
- X eatblanklines();
- X if (declarevars(ctx, 0))
- X outsection(minorspace);
- X flushcomments(NULL, CMT_NOT | CMT_ONEND, serial);
- X if (ctx->kind == MK_MODULE) {
- X if (ctx->anyvarflag) {
- X output(format_s(name_MAIN, ""));
- X output("(argc, argv);\n");
- X } else {
- X output("static int _was_initialized = 0;\n");
- X output("if (_was_initialized++)\n");
- X singleindent(tabsize);
- X output("return;\n");
- X }
- X while (initialcalls) {
- X output(initialcalls->s);
- X output(";\n");
- X strlist_remove(&initialcalls, initialcalls->s);
- X }
- X } else {
- X if (ctx->varstructflag && ctx->ctx->kind == MK_FUNCTION &&
- X ctx->ctx->varstructflag) {
- X output(format_s(name_VARS, ctx->name));
- X output(".");
- X output(format_s(name_LINK, ctx->ctx->name));
- X output(" = ");
- X output(format_s(name_LINK, ctx->ctx->name));
- X output(";\n");
- X }
- X for (mp = ctx->cbase; mp; mp = mp->cnext) {
- X if ((mp->kind == MK_VAR || /* these are variables with */
- X mp->kind == MK_VARREF) &&
- X mp->varstructflag && /* initializers which were moved */
- X mp->cnext && /* into a varstruct, so they */
- X mp->cnext->snext == mp && /* must be initialized now */
- X mp->cnext->constdefn) {
- X if (mp->type->kind == TK_ARRAY) {
- X output("memcpy(");
- X out_var(mp, 2);
- X output(", ");
- X out_var(mp->cnext, 2);
- X output(", sizeof(");
- X out_type(mp->type, 1);
- X output("))");
- X } else {
- X out_var(mp, 2);
- X output(" = ");
- X out_var(mp->cnext, 2);
- X }
- X output(";\n");
- X }
- X }
- X }
- X break;
- X
- X case SK_RETURN:
- X output("return");
- X if (sp->exp1) {
- X switch (returnparens) {
- X
- X case 0:
- X output(" ");
- X out_expr(sp->exp1);
- X break;
- X
- X case 1:
- X if (spaceexprs != 0)
- X output(" ");
- X out_expr_parens(sp->exp1);
- X break;
- X
- X default:
- X if (sp->exp1->kind == EK_VAR ||
- X sp->exp1->kind == EK_CONST ||
- X sp->exp1->kind == EK_LONGCONST ||
- X sp->exp1->kind == EK_BICALL) {
- X output(" ");
- X out_expr(sp->exp1);
- X } else {
- X if (spaceexprs != 0)
- X output(" ");
- X out_expr_parens(sp->exp1);
- X }
- X break;
- X }
- X }
- X output(";");
- X outnl(sp->serial);
- X break;
- X
- X case SK_ASSIGN:
- X out_expr_stmt(sp->exp1);
- X output(";");
- X outnl(sp->serial);
- X break;
- X
- X case SK_CASE:
- X output("switch (");
- X out_expr(sp->exp1);
- X output(")");
- X outspnl(braceline <= 0);
- X output("{");
- X outnl(sp->serial);
- X saveindent2 = outindent;
- X moreindent(tabsize);
- X moreindent(switchindent);
- X sp2 = sp->stm1;
- X while (sp2 && sp2->kind == SK_CASELABEL) {
- X outsection(casespacing);
- X sp3 = sp2;
- X i = 0;
- X hascmt = (findcomment(curcomments, -1, sp2->serial) != NULL);
- X singleindent(caseindent);
- X flushcomments(NULL, CMT_PRE, sp2->serial);
- X for (;;) {
- X if (i)
- X singleindent(caseindent);
- X i = 0;
- X output("case ");
- X out_expr(sp3->exp1);
- X output(":\001");
- X sp3 = sp3->stm1;
- X if (!sp3 || sp3->kind != SK_CASELABEL)
- X break;
- X if (casetabs != 1000)
- X out_spaces(casetabs, 0, 0, 0);
- X else {
- X output("\n");
- X i = 1;
- X }
- X }
- X if (sp3)
- X out_block(sp3, BR_NEVER|BR_CASE, sp2->serial);
- X else {
- X outnl(sp2->serial);
- X if (!hascmt)
- X output("/* blank case */\n");
- X }
- X output("break;\n");
- X flushcomments(NULL, -1, sp2->serial);
- X sp2 = sp2->next;
- X }
- X if (sp2) {
- X outsection(casespacing);
- X singleindent(caseindent);
- X flushcomments(NULL, CMT_PRE, sp2->serial);
- X output("default:");
- X out_block(sp2, BR_NEVER|BR_CASE, sp2->serial);
- X output("break;\n");
- X flushcomments(NULL, -1, sp2->serial);
- X }
- X outindent = saveindent2;
- X output("}");
- X curcmt = findcomment(curcomments, CMT_ONEND, sp->serial);
- X if (curcmt)
- X outcomment(curcmt);
- X else
- X output("\n");
- X break;
- X
- X case SK_CASECHECK:
- X output(name_CASECHECK);
- X output("(); /* CASE value range error */\n");
- X break;
- X
- X case SK_FOR:
- X output("for (");
- X if (for_allornone)
- X output("\007");
- X if (sp->exp1 || sp->exp2 || sp->exp3 || spaceexprs > 0) {
- X if (sp->exp1)
- X out_expr_top(sp->exp1);
- X else if (spaceexprs > 0)
- X output(" ");
- X output(";\002 ");
- X if (sp->exp2)
- X out_expr(sp->exp2);
- X output(";\002 ");
- X if (sp->exp3)
- X out_expr_top(sp->exp3);
- X } else {
- X output(";;");
- X }
- X output(")");
- X out_block(sp->stm1, 0, sp->serial);
- X break;
- X
- X case SK_LABEL:
- X if (!line_start())
- X output("\n");
- X singleindent(labelindent);
- X out_expr(sp->exp1);
- X output(":");
- X if (!sp->next)
- X output(" ;");
- X outnl(sp->serial);
- X break;
- X
- X case SK_GOTO:
- X /* what about non-local goto's? */
- X output("goto ");
- X out_expr(sp->exp1);
- X output(";");
- X outnl(sp->serial);
- X break;
- X
- X case SK_IF:
- X sp2 = sp;
- X for (;;) {
- X output("if (");
- X out_expr_bool(sp2->exp1);
- X output(")");
- X if (sp2->stm2) {
- X cmt = findcomment(curcomments, CMT_ONELSE, sp->serial+1);
- X i = (!cmt && sp2->stm2->kind == SK_IF &&
- X !sp2->stm2->next &&
- X ((sp2->stm2->exp2)
- X ? checkconst(sp2->stm2->exp2, 1)
- X : (elseif > 0)));
- X if (braceelse &&
- X (usebraces(sp2->stm1, 0) ||
- X usebraces(sp2->stm2, 0) || i))
- X always = BR_ALWAYS;
- X else
- X always = 0;
- X out_block(sp2->stm1, BR_THENPART|always, sp->serial);
- X output("else");
- X sp2 = sp2->stm2;
- X if (i) {
- X output(" ");
- X } else {
- X out_block(sp2, BR_ELSEPART|always, sp->serial+1);
- X break;
- X }
- X } else {
- X out_block(sp2->stm1, 0, sp->serial);
- X break;
- X }
- X }
- X break;
- X
- X case SK_REPEAT:
- X output("do");
- X out_block(sp->stm1, BR_ALWAYS|BR_REPEAT, sp->serial);
- X output("while (");
- X out_expr_bool(sp->exp1);
- X output(");");
- X cmt = findcomment(curcomments, CMT_ONEND, sp->serial);
- X if (commentvisible(cmt)) {
- X out_spaces(commentindent, commentoverindent,
- X commentlen(cmt), 0);
- X output("\001");
- X outcomment(cmt);
- X } else
- X output("\n");
- X break;
- X
- X case SK_TRY:
- X trynum = sp->exp1->val.i;
- X output(format_d("TRY(try%d);", trynum));
- X out_block(sp->stm1, BR_NEVER|BR_TRY, sp->serial);
- X if (sp->exp2)
- X output(format_ds("RECOVER2(try%d,%s);", trynum,
- X format_s(name_LABEL, format_d("try%d", trynum))));
- X else
- X output(format_d("RECOVER(try%d);", trynum));
- X out_block(sp->stm2, BR_NEVER|BR_TRY, sp->serial);
- X output(format_d("ENDTRY(try%d);\n", trynum));
- X break;
- X
- X case SK_WHILE:
- X output("while (");
- X out_expr_bool(sp->exp1);
- X output(")");
- X out_block(sp->stm1, 0, sp->serial);
- X break;
- X
- X case SK_BREAK:
- X output("break;");
- X outnl(sp->serial);
- X break;
- X
- X case SK_CONTINUE:
- X output("continue;");
- X outnl(sp->serial);
- X break;
- X
- X default:
- X intwarning("out_block",
- X format_s("Misplaced statement kind %s [265]",
- X stmtkindname(sp->kind)));
- X break;
- X }
- X flushcomments(NULL, -1, sp->serial);
- X candeclare = 0;
- X if (debug>1) { fprintf(outf, "in out_block:\n"); dumpstmt(spbase,5); }
- X sp = sp->next;
- X }
- X if (opts & BR_FUNCTION) {
- X cmt = extractcomment(&curcomments, CMT_ONEND, serial);
- X if (findcomment(curcomments, -1, -1) != NULL) /* check for non-DONE */
- X output("\n");
- X flushcomments(NULL, -1, -1);
- X curcomments = cmt;
- X }
- X outindent = saveindent;
- X if (braces) {
- X if (line_start()) {
- X if (opts & BR_FUNCTION)
- X singleindent(funccloseindent);
- X else
- X singleindent(closebraceindent);
- X }
- X output("}");
- X i = 1;
- X cmt = findcomment(curcomments, CMT_ONEND, serial);
- X if (!(opts & BR_REPEAT) && commentvisible(cmt)) {
- X out_spaces(bracecommentindent, commentoverindent,
- X commentlen(cmt), 0);
- X output("\001");
- X outcomment(cmt);
- X i = 0;
- X }
- X if (i) {
- X outspnl((opts & BR_REPEAT) ||
- X ((opts & BR_THENPART) && (braceelseline & 1) == 0));
- X }
- X candeclare = 0;
- X }
- X if (gotcomments) {
- X outcontext->comments = curcomments;
- X curcomments = savecurcmt;
- X }
- X}
- X
- X
- X
- X
- X
- X/* Should have a way to convert GOTO's to the end of the function to RETURN's */
- X
- X
- X/* Convert "_RETV = foo;" at end of function to "return foo" */
- X
- XStatic int checkreturns(spp, nearret)
- XStmt **spp;
- Xint nearret;
- X{
- X Stmt *sp;
- X Expr *rvar, *ex;
- X Meaning *mp;
- X int spnearret, spnextreturn;
- X int result = 0;
- X
- X if (debug>2) { fprintf(outf, "checkreturns on:\n"); dumpstmt(*spp, 5); }
- X while ((sp = *spp)) {
- X spnextreturn = (sp->next &&
- X sp->next->kind == SK_RETURN && sp->next->exp1 &&
- X isretvar(sp->next->exp1) == curctx->cbase);
- X spnearret = (nearret && !sp->next) || spnextreturn;
- X result = 0;
- X switch (sp->kind) {
- X
- X case SK_ASSIGN:
- X ex = sp->exp1;
- X if (ex->kind == EK_ASSIGN || structuredfunc(ex)) {
- X rvar = ex->args[0];
- X mp = isretvar(rvar);
- X if (mp == curctx->cbase && spnearret) {
- X if (ex->kind == EK_ASSIGN) {
- X if (mp->kind == MK_VARPARAM) {
- X ex = makeexpr_comma(ex, makeexpr_var(mp));
- X } else {
- X ex = grabarg(ex, 1);
- X mp->refcount--;
- X }
- X }
- X sp->exp1 = ex;
- X sp->kind = SK_RETURN;
- END_OF_FILE
- if test 49384 -ne `wc -c <'src/parse.c.1'`; then
- echo shar: \"'src/parse.c.1'\" unpacked with wrong size!
- fi
- # end of 'src/parse.c.1'
- fi
- echo shar: End of archive 29 \(of 32\).
- cp /dev/null ark29isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 32 archives.
- echo "Now see PACKNOTES and the README"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-