home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
p2c
/
part29
< prev
next >
Wrap
Text File
|
1990-04-05
|
53KB
|
1,749 lines
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