parse.c.1
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:48k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989 David Gillespie.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation (any version).
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; see the file COPYING.  If not, write to
  13. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  14. #define PROTO_PARSE_C
  15. #include "trans.h"
  16. Static short candeclare;
  17. Static int trycount;
  18. Static Strlist *includedfiles;
  19. Static char echo_first;
  20. Static int echo_pos;
  21. void setup_parse()
  22. {
  23.     candeclare = 0;
  24.     trycount = 0;
  25.     includedfiles = NULL;
  26.     echo_first = 1;
  27.     echo_pos = 0;
  28.     fixexpr_tryblock = 0;
  29. }
  30. void echobreak()
  31. {
  32.     if (echo_pos > 0) {
  33. printf("n");
  34. echo_pos = 0;
  35. echo_first = 0;
  36.     }
  37. }
  38. void echoword(name, comma)
  39. char *name;
  40. int comma;
  41. {
  42.     FILE *f = (outf == stdout) ? stderr : stdout;
  43.     if (quietmode || showprogress)
  44.         return;
  45.     if (!echo_first) {
  46. if (comma) {
  47.     fprintf(f, ",");
  48.     echo_pos++;
  49. }
  50.         if (echo_pos + strlen(name) > 77) {
  51.             fprintf(f, "n");
  52.             echo_pos = 0;
  53.         } else {
  54.             fprintf(f, " ");
  55.             echo_pos++;
  56.         }
  57.     }
  58.     echo_first = 0;
  59.     fprintf(f, "%s", name);
  60.     echo_pos += strlen(name);
  61.     fflush(f);
  62. }
  63. void echoprocname(mp)
  64. Meaning *mp;
  65. {
  66.     echoword(mp->name, 1);
  67. }
  68. Static void forward_decl(func, isextern)
  69. Meaning *func;
  70. int isextern;
  71. {
  72.     if (func->wasdeclared)
  73.         return;
  74.     if (isextern && func->constdefn && !checkvarmac(func))
  75. return;
  76.     if (isextern) {
  77.         output("extern ");
  78.     } else if (func->ctx->kind == MK_FUNCTION) {
  79. if (useAnyptrMacros)
  80.     output("Local ");
  81. else
  82.     output("static ");
  83.     } else if ((use_static != 0 && !useAnyptrMacros) ||
  84.        (findsymbol(func->name)->flags & NEEDSTATIC)) {
  85. output("static ");
  86.     } else if (useAnyptrMacros) {
  87. output("Static ");
  88.     }
  89.     if (func->type->basetype != tp_void || ansiC != 0) {
  90.         outbasetype(func->type, ODECL_FORWARD);
  91.         output(" ");
  92.     }
  93.     outdeclarator(func->type, func->name, ODECL_FORWARD);
  94.     output(";n");
  95.     func->wasdeclared = 1;
  96. }
  97. /* Check if calling a parent procedure, whose body must */
  98. /*   be declared forward */
  99. void need_forward_decl(func)
  100. Meaning *func;
  101. {
  102.     Meaning *mp;
  103.     if (func->wasdeclared)
  104.         return;
  105.     for (mp = curctx->ctx; mp; mp = mp->ctx) {
  106.         if (mp == func) {
  107.     if (func->ctx->kind == MK_FUNCTION)
  108. func->isforward = 1;
  109.     else
  110. forward_decl(func, 0);
  111.             return;
  112.         }
  113.     }
  114. }
  115. void free_stmt(sp)
  116. register Stmt *sp;
  117. {
  118.     if (sp) {
  119.         free_stmt(sp->stm1);
  120.         free_stmt(sp->stm2);
  121.         free_stmt(sp->next);
  122.         freeexpr(sp->exp1);
  123.         freeexpr(sp->exp2);
  124.         freeexpr(sp->exp3);
  125.         FREE(sp);
  126.     }
  127. }
  128. Stmt *makestmt(kind)
  129. enum stmtkind kind;
  130. {
  131.     Stmt *sp;
  132.     sp = ALLOC(1, Stmt, stmts);
  133.     sp->kind = kind;
  134.     sp->next = NULL;
  135.     sp->stm1 = NULL;
  136.     sp->stm2 = NULL;
  137.     sp->exp1 = NULL;
  138.     sp->exp2 = NULL;
  139.     sp->exp3 = NULL;
  140.     sp->serial = curserial = ++serialcount;
  141.     return sp;
  142. }
  143. Stmt *makestmt_call(call)
  144. Expr *call;
  145. {
  146.     Stmt *sp = makestmt(SK_ASSIGN);
  147.     sp->exp1 = call;
  148.     return sp;
  149. }
  150. Stmt *makestmt_assign(lhs, rhs)
  151. Expr *lhs, *rhs;
  152. {
  153.     Stmt *sp = makestmt(SK_ASSIGN);
  154.     sp->exp1 = makeexpr_assign(lhs, rhs);
  155.     return sp;
  156. }
  157. Stmt *makestmt_if(cond, thn, els)
  158. Expr *cond;
  159. Stmt *thn, *els;
  160. {
  161.     Stmt *sp = makestmt(SK_IF);
  162.     sp->exp1 = cond;
  163.     sp->stm1 = thn;
  164.     sp->stm2 = els;
  165.     return sp;
  166. }
  167. Stmt *makestmt_seq(s1, s2)
  168. Stmt *s1, *s2;
  169. {
  170.     Stmt *s1a;
  171.     if (!s1)
  172.         return s2;
  173.     if (!s2)
  174.         return s1;
  175.     for (s1a = s1; s1a->next; s1a = s1a->next) ;
  176.     s1a->next = s2;
  177.     return s1;
  178. }
  179. Stmt *copystmt(sp)
  180. Stmt *sp;
  181. {
  182.     Stmt *sp2;
  183.     if (sp) {
  184.         sp2 = makestmt(sp->kind);
  185.         sp2->stm1 = copystmt(sp->stm1);
  186.         sp2->stm2 = copystmt(sp->stm2);
  187.         sp2->exp1 = copyexpr(sp->exp1);
  188.         sp2->exp2 = copyexpr(sp->exp2);
  189.         sp2->exp3 = copyexpr(sp->exp3);
  190.         return sp2;
  191.     } else
  192.         return NULL;
  193. }
  194. void nukestmt(sp)
  195. Stmt *sp;
  196. {
  197.     if (sp) {
  198.         sp->kind = SK_ASSIGN;
  199.         sp->exp1 = makeexpr_long(0);
  200.     }
  201. }
  202. void splicestmt(sp, spnew)
  203. Stmt *sp, *spnew;
  204. {
  205.     Stmt *snext;
  206.     snext = sp->next;
  207.     *sp = *spnew;
  208.     while (sp->next)
  209.         sp = sp->next;
  210.     sp->next = snext;
  211. }
  212. int stmtcount(sp)
  213. Stmt *sp;
  214. {
  215.     int i = 0;
  216.     while (sp) {
  217.         i += 1 + stmtcount(sp->stm1) + stmtcount(sp->stm2);
  218.         sp = sp->next;
  219.     }
  220.     return i;
  221. }
  222. Stmt *close_files_to_ctx(ctx)
  223. Meaning *ctx;
  224. {
  225.     Meaning *ctx2, *mp;
  226.     Stmt *splist = NULL, *sp;
  227.     ctx2 = curctx;
  228.     while (ctx2 && ctx2 != ctx && ctx2->kind == MK_FUNCTION) {
  229. for (mp = ctx2->cbase; mp; mp = mp->cnext) {
  230.     if (mp->kind == MK_VAR &&
  231. isfiletype(mp->type) && !mp->istemporary) {
  232. var_reference(mp);
  233. sp = makestmt_if(makeexpr_rel(EK_NE, makeexpr_var(mp),
  234.       makeexpr_nil()),
  235.  makestmt_call(
  236.      makeexpr_bicall_1("fclose", tp_void,
  237.        makeexpr_var(mp))),
  238.  NULL);
  239. splist = makestmt_seq(splist, sp);
  240.     }
  241. }
  242. ctx2 = ctx2->ctx;
  243.     }
  244.     return splist;
  245. }
  246. int simplewith(ex)
  247. Expr *ex;
  248. {
  249.     switch (ex->kind) {
  250.         case EK_VAR:
  251.         case EK_CONST:
  252.             return 1;
  253.         case EK_DOT:
  254.             return simplewith(ex->args[0]);
  255.         default:
  256.             return 0;
  257.     }
  258. }
  259. int simplefor(sp, ex)
  260. Stmt *sp;
  261. Expr *ex;
  262. {
  263.     return (exprspeed(sp->exp2) <= 3 &&
  264.             !checkexprchanged(sp->stm1, sp->exp2) &&
  265.     !exproccurs(sp->exp2, ex));
  266. }
  267. int tryfuncmacro(exp, mp)
  268. Expr **exp;
  269. Meaning *mp;
  270. {
  271.     char *name;
  272.     Strlist *lp;
  273.     Expr *ex = *exp, *ex2;
  274.     ex2 = (mp) ? mp->constdefn : NULL;
  275.     if (!ex2) {
  276. if (ex->kind == EK_BICALL || ex->kind == EK_NAME)
  277.     name = ex->val.s;
  278. else if (ex->kind == EK_FUNCTION)
  279.     name = ((Meaning *)ex->val.i)->name;
  280. else
  281.     return 0;
  282. lp = strlist_cifind(funcmacros, name);
  283. ex2 = (lp) ? (Expr *)lp->value : NULL;
  284.     }
  285.     if (ex2) {
  286.         *exp = replacemacargs(copyexpr(ex2), ex);
  287. freeexpr(ex);
  288.         return 1;
  289.     }
  290.     return 0;
  291. }
  292. #define addstmt(kind)   
  293.     *spp = sp = makestmt(kind),   
  294.     spp = &(sp->next)
  295. #define newstmt(kind)   
  296.     addstmt(kind),   
  297.     steal_comments(firstserial, sp->serial, sflags & SF_FIRST),   
  298.     sflags &= ~SF_FIRST
  299. #define SF_FUNC    0x1
  300. #define SF_SAVESER 0x2
  301. #define SF_FIRST   0x4
  302. #define SF_IF    0x8
  303. Static Stmt *p_stmt(slist, sflags)
  304. Stmt *slist;
  305. int sflags;
  306. {
  307.     Stmt *sbase = NULL, **spp = &sbase, **spp2, **spp3, **savespp;
  308.     Stmt *defsp, **defsphook;
  309.     register Stmt *sp;
  310.     Stmt *sp2;
  311.     long li1, li2, firstserial = 0, saveserial = 0, saveserial2;
  312.     int i, forfixed, offset, line1, line2, toobig, isunsafe;
  313.     Token savetok;
  314.     char *name;
  315.     Expr *ep, *ep2, *ep3, *forstep, *range, *swexpr, *trueswexpr;
  316.     Type *tp;
  317.     Meaning *mp, *tvar, *tempmark;
  318.     Symbol *sym;
  319.     enum exprkind ekind;
  320.     Stmt *(*prochandler)();
  321.     Strlist *cmt;
  322.     tempmark = markstmttemps();
  323. again:
  324.     while (findlabelsym()) {
  325.         newstmt(SK_LABEL);
  326.         sp->exp1 = makeexpr_name(format_s(name_LABEL, curtokmeaning->name), tp_integer);
  327.         gettok();
  328.         wneedtok(TOK_COLON);
  329.     }
  330.     firstserial = curserial;
  331.     checkkeyword(TOK_TRY);
  332.     checkkeyword(TOK_INLINE);
  333.     checkkeyword(TOK_LOOP);
  334.     checkkeyword(TOK_RETURN);
  335.     if (modula2) {
  336. if (sflags & SF_SAVESER)
  337.     goto stmtSeq;
  338.     }
  339.     switch (curtok) {
  340.         case TOK_BEGIN:
  341.         stmtSeq:
  342.     if (sflags & (SF_FUNC|SF_SAVESER)) {
  343. saveserial = curserial;
  344. cmt = grabcomment(CMT_ONBEGIN);
  345. if (sflags & SF_FUNC)
  346.     cmt = fixbeginendcomment(cmt);
  347. strlist_mix(&curcomments, cmt);
  348.     }
  349.     i = sflags & SF_FIRST;
  350.             do {
  351. if (modula2) {
  352.     if (curtok == TOK_BEGIN || curtok == TOK_SEMI)
  353. gettok();
  354.     checkkeyword(TOK_ELSIF);
  355.     if (curtok == TOK_ELSE || curtok == TOK_ELSIF)
  356. break;
  357. } else
  358.     gettok();
  359.                 *spp = p_stmt(sbase, i);
  360. i = 0;
  361.                 while (*spp)
  362.                     spp = &((*spp)->next);
  363.             } while (curtok == TOK_SEMI);
  364.     if (sflags & (SF_FUNC|SF_SAVESER)) {
  365. cmt = grabcomment(CMT_ONEND);
  366. changecomments(cmt, -1, -1, -1, saveserial);
  367. if (sflags & SF_FUNC)
  368.     cmt = fixbeginendcomment(cmt);
  369. strlist_mix(&curcomments, cmt);
  370. if (sflags & SF_FUNC)
  371.     changecomments(curcomments, -1, saveserial, -1, 10000);
  372. curserial = saveserial;
  373.     }
  374.     checkkeyword(TOK_ELSIF);
  375.     if (modula2 && (sflags & SF_IF)) {
  376. break;
  377.     }
  378.     if (curtok == TOK_VBAR)
  379. break;
  380.             if (!wneedtok(TOK_END))
  381. skippasttoken(TOK_END);
  382.             break;
  383.         case TOK_CASE:
  384.             gettok();
  385.             swexpr = trueswexpr = p_ord_expr();
  386.             if (nosideeffects(swexpr, 1)) {
  387.                 tvar = NULL;
  388.             } else {
  389.                 tvar = makestmttempvar(swexpr->val.type, name_TEMP);
  390.                 swexpr = makeexpr_var(tvar);
  391.             }
  392.             savespp = spp;
  393.             newstmt(SK_CASE);
  394.     saveserial2 = curserial;
  395.             sp->exp1 = trueswexpr;
  396.             spp2 = &sp->stm1;
  397.             tp = swexpr->val.type;
  398.             defsp = NULL;
  399.             defsphook = &defsp;
  400.             if (!wneedtok(TOK_OF)) {
  401. skippasttoken(TOK_END);
  402. break;
  403.     }
  404.     i = 1;
  405.     while (curtok == TOK_VBAR)
  406. gettok();
  407.     checkkeyword(TOK_OTHERWISE);
  408.             while (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) {
  409.                 spp3 = spp2;
  410. saveserial = curserial;
  411.                 *spp2 = sp = makestmt(SK_CASELABEL);
  412. steal_comments(saveserial, sp->serial, i);
  413.                 spp2 = &sp->next;
  414.                 range = NULL;
  415.                 toobig = 0;
  416.                 for (;;) {
  417.                     ep = gentle_cast(p_expr(tp), tp);
  418.                     if (curtok == TOK_DOTS) {
  419.                         li1 = ord_value(eval_expr(ep));
  420.                         gettok();
  421.                         ep2 = gentle_cast(p_expr(tp), tp);
  422.                         li2 = ord_value(eval_expr(ep2));
  423.                         range = makeexpr_or(range,
  424.                                             makeexpr_range(copyexpr(swexpr),
  425.                                                            ep, ep2, 1));
  426.                         if (li2 - li1 >= caselimit)
  427.                             toobig = 1;
  428.                         if (!toobig) {
  429.                             for (;;) {
  430.                                 sp->exp1 = makeexpr_val(make_ord(tp, li1));
  431.                                 if (li1 >= li2) break;
  432.                                 li1++;
  433. serialcount--;   /* make it reuse the count */
  434.                                 sp->stm1 = makestmt(SK_CASELABEL);
  435.                                 sp = sp->stm1;
  436.                             }
  437.                         }
  438.                     } else {
  439.                         sp->exp1 = copyexpr(ep);
  440.                         range = makeexpr_or(range,
  441.                                             makeexpr_rel(EK_EQ, 
  442.                                                          copyexpr(swexpr),
  443.                                                          ep));
  444.                     }
  445.                     if (curtok == TOK_COMMA) {
  446.                         gettok();
  447. serialcount--;   /* make it reuse the count */
  448.                         sp->stm1 = makestmt(SK_CASELABEL);
  449.                         sp = sp->stm1;
  450.                     } else
  451.                         break;
  452.                 }
  453.                 wneedtok(TOK_COLON);
  454.                 if (toobig) {
  455.                     free_stmt(*spp3);
  456.                     spp2 = spp3;
  457.                     *defsphook = makestmt_if(range, p_stmt(NULL, SF_SAVESER),
  458.      NULL);
  459.                     if (defsphook != &defsp && elseif != 0)
  460.                         (*defsphook)->exp2 = makeexpr_long(1);
  461.                     defsphook = &((*defsphook)->stm2);
  462.                 } else {
  463.                     freeexpr(range);
  464.                     sp->stm1 = p_stmt(NULL, SF_SAVESER);
  465.                 }
  466. i = 0;
  467. checkkeyword(TOK_OTHERWISE);
  468.                 if (curtok != TOK_END && curtok != TOK_OTHERWISE && curtok != TOK_ELSE) {
  469.     if (curtok == TOK_VBAR) {
  470. while (curtok == TOK_VBAR)
  471.     gettok();
  472.     } else
  473. wneedtok(TOK_SEMI);
  474.     checkkeyword(TOK_OTHERWISE);
  475. }
  476.             }
  477.             if (defsp) {
  478.                 *spp2 = defsp;
  479.                 spp2 = defsphook;
  480.                 if (tvar) {
  481.                     sp = makestmt_assign(makeexpr_var(tvar), trueswexpr);
  482.                     sp->next = *savespp;
  483.                     *savespp = sp;
  484.                     sp->next->exp1 = swexpr;
  485.                 }
  486.             } else {
  487.                 if (tvar) {
  488.                     canceltempvar(tvar);
  489.                     freeexpr(swexpr);
  490.                 }
  491.             }
  492.             if (curtok == TOK_OTHERWISE || curtok == TOK_ELSE) {
  493.                 gettok();
  494.                 while (curtok == TOK_SEMI)
  495.                     gettok();
  496. /* changecomments(curcomments, CMT_TRAIL, curserial,
  497.                     CMT_POST, -1);   */
  498. i = SF_FIRST;
  499. while (curtok != TOK_END) {
  500.                     *spp2 = p_stmt(NULL, i);
  501.                     while (*spp2)
  502.                         spp2 = &((*spp2)->next);
  503.     i = 0;
  504.                     if (curtok != TOK_SEMI)
  505.                         break;
  506.                     gettok();
  507.                 }
  508.                 if (!wexpecttok(TOK_END))
  509.     skiptotoken(TOK_END);
  510.             } else if (casecheck == 1 || (casecheck == 2 && range_flag)) {
  511.                 *spp2 = makestmt(SK_CASECHECK);
  512.             }
  513.     curserial = saveserial2;
  514.     strlist_mix(&curcomments, grabcomment(CMT_ONEND));
  515.             gettok();
  516.             break;
  517.         case TOK_FOR:
  518.             forfixed = fixedflag;
  519.             gettok();
  520.             newstmt(SK_FOR);
  521.             ep = p_expr(tp_integer);
  522.             if (!wneedtok(TOK_ASSIGN)) {
  523. skippasttoken(TOK_DO);
  524. break;
  525.     }
  526.             ep2 = makeexpr_charcast(p_expr(ep->val.type));
  527.             if (curtok != TOK_DOWNTO) {
  528. if (!wexpecttok(TOK_TO)) {
  529.     skippasttoken(TOK_DO);
  530.     break;
  531. }
  532.     }
  533.             savetok = curtok;
  534.             gettok();
  535.             sp->exp2 = makeexpr_charcast(p_expr(ep->val.type));
  536.     checkkeyword(TOK_BY);
  537.     if (curtok == TOK_BY) {
  538. gettok();
  539. forstep = p_expr(tp_integer);
  540. i = possiblesigns(forstep);
  541. if ((i & 5) == 5) {
  542.     if (expr_is_neg(forstep)) {
  543. ekind = EK_GE;
  544. note("Assuming FOR loop step is negative [252]");
  545.     } else {
  546. ekind = EK_LE;
  547. note("Assuming FOR loop step is positive [252]");
  548.     }
  549. } else {
  550.     if (!(i & 1))
  551. ekind = EK_LE;
  552.     else
  553. ekind = EK_GE;
  554. }
  555.     } else {
  556. if (savetok == TOK_DOWNTO) {
  557.     ekind = EK_GE;
  558.     forstep = makeexpr_long(-1);
  559. } else {
  560.     ekind = EK_LE;
  561.     forstep = makeexpr_long(1);
  562. }
  563.     }
  564.             tvar = NULL;
  565.     swexpr = NULL;
  566.             if (ep->kind == EK_VAR) {
  567.                 tp = findbasetype(ep->val.type, 0);
  568.                 if ((tp == tp_char || tp == tp_schar || tp == tp_uchar ||
  569.                      tp == tp_abyte || tp == tp_sbyte || tp == tp_ubyte ||
  570.      tp == tp_boolean) &&
  571.                     ((checkconst(sp->exp2, 0) &&
  572.       tp != tp_sbyte && tp != tp_schar) ||
  573.                      checkconst(sp->exp2, -128) ||
  574.                      (checkconst(sp->exp2, 127) &&
  575.       tp != tp_ubyte && tp != tp_uchar) ||
  576.                      checkconst(sp->exp2, 255) ||
  577.                      (tp == tp_char &&
  578.                       (useAnyptrMacros == 1 || unsignedchar != 1) &&
  579.                       isliteralconst(sp->exp2, NULL) == 2 &&
  580.                       sp->exp2->val.i >= 128))) {
  581.                     swexpr = ep;
  582.                     tvar = makestmttempvar(tp_sshort, name_TEMP);
  583.                     ep = makeexpr_var(tvar);
  584.                 } else if (((tp == tp_sshort &&
  585.                              (checkconst(sp->exp2, -32768) ||
  586.                               checkconst(sp->exp2, 32767))) ||
  587.                             (tp == tp_ushort &&
  588.                              (checkconst(sp->exp2, 0) ||
  589.                               checkconst(sp->exp2, 65535))))) {
  590.                     swexpr = ep;
  591.                     tvar = makestmttempvar(tp_integer, name_TEMP);
  592.                     ep = makeexpr_var(tvar);
  593.                 } else if (tp == tp_integer &&
  594.    (checkconst(sp->exp2, LONG_MAX) ||
  595.     (sp->exp2->kind == EK_VAR &&
  596.      sp->exp2->val.i == (long)mp_maxint))) {
  597.                     swexpr = ep;
  598.                     tvar = makestmttempvar(tp_unsigned, name_TEMP);
  599.                     ep = makeexpr_var(tvar);
  600.                 }
  601.             }
  602.     sp->exp3 = makeexpr_assign(copyexpr(ep),
  603.        makeexpr_inc(copyexpr(ep),
  604.     copyexpr(forstep)));
  605.             wneedtok(TOK_DO);
  606.             forfixed = (fixedflag != forfixed);
  607.             mp = makestmttempvar(ep->val.type, name_FOR);
  608.             sp->stm1 = p_stmt(NULL, SF_SAVESER);
  609.             if (tvar) {
  610.                 if (checkexprchanged(sp->stm1, swexpr))
  611.                     note(format_s("Rewritten FOR loop won't work if it meddles with %s [253]",
  612.                                   ((Meaning *)swexpr->val.i)->name));
  613.                 sp->stm1 = makestmt_seq(makestmt_assign(swexpr, makeexpr_var(tvar)),
  614.                                         sp->stm1);
  615.             } else if (offsetforloops && ep->kind == EK_VAR) {
  616. offset = checkvaroffset(sp->stm1, (Meaning *)ep->val.i);
  617. if (offset != 0) {
  618.     ep3 = makeexpr_inc(copyexpr(ep), makeexpr_long(-offset));
  619.     replaceexpr(sp->stm1, ep, ep3);
  620.     freeexpr(ep3);
  621.     ep2 = makeexpr_plus(ep2, makeexpr_long(offset));
  622.     sp->exp2 = makeexpr_inc(sp->exp2, makeexpr_long(offset));
  623. }
  624.     }
  625.             if (!exprsame(ep, ep2, 1))
  626.                 sp->exp1 = makeexpr_assign(copyexpr(ep), copyexpr(ep2));
  627.     isunsafe = ((!nodependencies(ep2, 2) &&
  628.  !nosideeffects(sp->exp2, 1)) ||
  629. (!nodependencies(sp->exp2, 2) &&
  630.  !nosideeffects(ep2, 1)));
  631.             if (forfixed || (simplefor(sp, ep) && !isunsafe)) {
  632.                 canceltempvar(mp);
  633.                 sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2);
  634.             } else {
  635. ep3 = makeexpr_neg(copyexpr(forstep));
  636. if ((checkconst(forstep, 1) || checkconst(forstep, -1)) &&
  637.     sp->exp2->kind == EK_PLUS &&
  638.     exprsame(sp->exp2->args[sp->exp2->nargs-1], ep3, 2)) {
  639.     sp->exp2 = makeexpr_inc(sp->exp2, forstep);
  640. } else {
  641.     freeexpr(forstep);
  642.     freeexpr(ep3);
  643.     ep3 = makeexpr_long(0);
  644. }
  645. if (forevalorder && isunsafe) {
  646.     if (exprdepends(sp->exp2, ep)) {
  647. tvar = makestmttempvar(mp->type, name_TEMP);
  648. sp->exp1 = makeexpr_comma(
  649.      makeexpr_comma(
  650.        makeexpr_assign(makeexpr_var(tvar),
  651.        copyexpr(ep2)),
  652.        makeexpr_assign(makeexpr_var(mp),
  653.        sp->exp2)),
  654.      makeexpr_assign(copyexpr(ep),
  655.      makeexpr_var(tvar)));
  656.     } else
  657. sp->exp1 = makeexpr_comma(
  658.      sp->exp1,
  659.      makeexpr_assign(makeexpr_var(mp),
  660.      sp->exp2));
  661. } else {
  662.     if (isunsafe)
  663. note("Evaluating FOR loop limit before initial value [315]");
  664.     sp->exp1 = makeexpr_comma(
  665.          makeexpr_assign(makeexpr_var(mp),
  666.  sp->exp2),
  667.          sp->exp1);
  668. }
  669. sp->exp2 = makeexpr_inc(makeexpr_var(mp), ep3);
  670.                 sp->exp2 = makeexpr_rel(ekind, ep, sp->exp2);
  671.             }
  672.     freeexpr(ep2);
  673.             break;
  674.         case TOK_GOTO:
  675.             gettok();
  676.             if (findlabelsym()) {
  677.                 if (curtokmeaning->ctx != curctx) {
  678.     curtokmeaning->val.i = 1;
  679.     *spp = close_files_to_ctx(curtokmeaning->ctx);
  680.     while (*spp)
  681. spp = &((*spp)->next);
  682.     newstmt(SK_ASSIGN);
  683.     var_reference(curtokmeaning->xnext);
  684.     if (curtokmeaning->ctx->kind == MK_MODULE &&
  685. !curtokmeaning->xnext->wasdeclared) {
  686. outsection(minorspace);
  687. declarevar(curtokmeaning->xnext, 0x7);
  688. curtokmeaning->xnext->wasdeclared = 1;
  689. outsection(minorspace);
  690.     }
  691.     sp->exp1 = makeexpr_bicall_2("longjmp", tp_void,
  692.  makeexpr_var(curtokmeaning->xnext),
  693.  makeexpr_long(1));
  694. } else {
  695.     newstmt(SK_GOTO);
  696.     sp->exp1 = makeexpr_name(format_s(name_LABEL,
  697.       curtokmeaning->name),
  698.      tp_integer);
  699. }
  700.             } else {
  701.                 warning("Expected a label [263]");
  702.     }
  703.     gettok();
  704.             break;
  705.         case TOK_IF:
  706.             gettok();
  707.             newstmt(SK_IF);
  708.     saveserial = curserial;
  709.     curserial = ++serialcount;
  710.             sp->exp1 = p_expr(tp_boolean);
  711.             wneedtok(TOK_THEN);
  712.             sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF);
  713.     changecomments(curcomments, -1, saveserial+1, -1, saveserial);
  714.     checkkeyword(TOK_ELSIF);
  715.     while (curtok == TOK_ELSIF) {
  716. gettok();
  717. sp->stm2 = makestmt(SK_IF);
  718. sp = sp->stm2;
  719. sp->exp1 = p_expr(tp_boolean);
  720. wneedtok(TOK_THEN);
  721. sp->stm1 = p_stmt(NULL, SF_SAVESER|SF_IF);
  722. sp->exp2 = makeexpr_long(1);
  723.     }
  724.     if (curtok == TOK_ELSE) {
  725.                 line1 = inf_lnum;
  726. strlist_mix(&curcomments, grabcomment(CMT_ONELSE));
  727.                 gettok();
  728.                 line2 = (curtok == TOK_IF) ? inf_lnum : -1;
  729. saveserial2 = curserial;
  730.                 sp->stm2 = p_stmt(NULL, SF_SAVESER|SF_IF);
  731. changecomments(curcomments, -1, saveserial2, -1, saveserial+1);
  732.                 if (sp->stm2 && sp->stm2->kind == SK_IF &&
  733.     !sp->stm2->next && !modula2) {
  734.                     sp->stm2->exp2 = makeexpr_long(elseif > 0 ||
  735.                                                    (elseif < 0 && line1 == line2));
  736.                 }
  737.             }
  738.     if (modula2)
  739. wneedtok(TOK_END);
  740.     curserial = saveserial;
  741.             break;
  742.         case TOK_INLINE:
  743.             gettok();
  744.             note("Inline assembly language encountered [254]");
  745.             if (curtok != TOK_LPAR) {   /* Macintosh style */
  746. newstmt(SK_ASSIGN);
  747. sp->exp1 = makeexpr_bicall_1("inline", tp_void,
  748.      p_expr(tp_integer));
  749. break;
  750.     }
  751.             do {
  752.                 name = getinlinepart();
  753.                 if (!*name)
  754.                     break;
  755.                 newstmt(SK_ASSIGN);
  756.                 sp->exp1 = makeexpr_bicall_1("asm", tp_void,
  757.                             makeexpr_string(format_s(" inline %s", name)));
  758.                 gettok();
  759.             } while (curtok == TOK_SLASH);
  760.             skipcloseparen();
  761.             break;
  762. case TOK_LOOP:
  763.     gettok();
  764.     newstmt(SK_WHILE);
  765.     sp->exp1 = makeexpr_long(1);
  766.             sp->stm1 = p_stmt(NULL, SF_SAVESER);
  767.     break;
  768.         case TOK_REPEAT:
  769.             newstmt(SK_REPEAT);
  770.     saveserial = curserial;
  771.             spp2 = &(sp->stm1);
  772.     i = SF_FIRST;
  773.             do {
  774.                 gettok();
  775.                 *spp2 = p_stmt(sp->stm1, i);
  776. i = 0;
  777.                 while (*spp2)
  778.                     spp2 = &((*spp2)->next);
  779.             } while (curtok == TOK_SEMI);
  780.             if (!wneedtok(TOK_UNTIL))
  781. skippasttoken(TOK_UNTIL);
  782.             sp->exp1 = makeexpr_not(p_expr(tp_boolean));
  783.     curserial = saveserial;
  784.     strlist_mix(&curcomments, grabcomment(CMT_ONEND));
  785.             break;
  786. case TOK_RETURN:
  787.     gettok();
  788.     newstmt(SK_RETURN);
  789.     if (curctx->isfunction) {
  790. sp->exp1 = gentle_cast(p_expr(curctx->cbase->type),
  791.        curctx->cbase->type);
  792.     }
  793.     break;
  794.         case TOK_TRY:
  795.     findsymbol("RECOVER")->flags &= ~KWPOSS;
  796.             newstmt(SK_TRY);
  797.             sp->exp1 = makeexpr_long(++trycount);
  798.             spp2 = &(sp->stm1);
  799.     i = SF_FIRST;
  800.             do {
  801.                 gettok();
  802.                 *spp2 = p_stmt(sp->stm1, i);
  803. i = 0;
  804.                 while (*spp2)
  805.                     spp2 = &((*spp2)->next);
  806.             } while (curtok == TOK_SEMI);
  807.             if (!wneedtok(TOK_RECOVER))
  808. skippasttoken(TOK_RECOVER);
  809.             sp->stm2 = p_stmt(NULL, SF_SAVESER);
  810.             break;
  811.         case TOK_WHILE:
  812.             gettok();
  813.             newstmt(SK_WHILE);
  814.             sp->exp1 = p_expr(tp_boolean);
  815.             wneedtok(TOK_DO);
  816.             sp->stm1 = p_stmt(NULL, SF_SAVESER);
  817.             break;
  818.         case TOK_WITH:
  819.             gettok();
  820.             if (withlevel >= MAXWITHS-1)
  821.                 error("Too many nested WITHs");
  822.             ep = p_expr(NULL);
  823.             if (ep->val.type->kind != TK_RECORD)
  824.                 warning("Argument of WITH is not a RECORD [264]");
  825.             withlist[withlevel] = ep->val.type;
  826.             if (simplewith(ep)) {
  827.                 withexprs[withlevel] = ep;
  828.                 mp = NULL;
  829.             } else {           /* need to save a temporary pointer */
  830.                 tp = makepointertype(ep->val.type);
  831.                 mp = makestmttempvar(tp, name_WITH);
  832.                 withexprs[withlevel] = makeexpr_hat(makeexpr_var(mp), 0);
  833.             }
  834.             withlevel++;
  835.             if (curtok == TOK_COMMA) {
  836.                 curtok = TOK_WITH;
  837.                 sp2 = p_stmt(NULL, sflags & SF_FIRST);
  838.             } else {
  839.                 wneedtok(TOK_DO);
  840.                 sp2 = p_stmt(NULL, sflags & SF_FIRST);
  841.             }
  842.             withlevel--;
  843.             if (mp) {    /* if "with p^" for constant p, don't need temp ptr */
  844.                 if (ep->kind == EK_HAT && ep->args[0]->kind == EK_VAR &&
  845.                     !checkvarchanged(sp2, (Meaning *)ep->args[0]->val.i)) {
  846.                     replaceexpr(sp2, withexprs[withlevel]->args[0],
  847.                                      ep->args[0]);
  848.                     freeexpr(ep);
  849.                     canceltempvar(mp);
  850.                 } else {
  851.                     newstmt(SK_ASSIGN);
  852.                     sp->exp1 = makeexpr_assign(makeexpr_var(mp),
  853.                                                makeexpr_addr(ep));
  854.                 }
  855.             }
  856.             freeexpr(withexprs[withlevel]);
  857.             *spp = sp2;
  858.             while (*spp)
  859.                 spp = &((*spp)->next);
  860.             break;
  861.         case TOK_INCLUDE:
  862.             badinclude();
  863.             goto again;
  864. case TOK_ADDR:   /* flakey Turbo "@procptr := anyptr" assignment */
  865.     newstmt(SK_ASSIGN);
  866.     ep = p_expr(tp_void);
  867.     if (wneedtok(TOK_ASSIGN))
  868. sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type));
  869.     else
  870. sp->exp1 = ep;
  871.     break;
  872.         case TOK_IDENT:
  873.             mp = curtokmeaning;
  874.     if (mp == mp_str_hp)
  875. mp = curtokmeaning = mp_str_turbo;
  876.     if (mp == mp_val_modula)
  877. mp = curtokmeaning = mp_val_turbo;
  878.     if (mp == mp_blockread_ucsd)
  879. mp = curtokmeaning = mp_blockread_turbo;
  880.     if (mp == mp_blockwrite_ucsd)
  881. mp = curtokmeaning = mp_blockwrite_turbo;
  882.     if (mp == mp_dec_dec)
  883. mp = curtokmeaning = mp_dec_turbo;
  884.             if (!mp) {
  885.                 sym = curtoksym;     /* make a guess at what the undefined name is... */
  886.                 name = stralloc(curtokcase);
  887.                 gettok();
  888.                 newstmt(SK_ASSIGN);
  889.                 if (curtok == TOK_ASSIGN) {
  890.                     gettok();
  891.                     ep = p_expr(NULL);
  892.                     mp = addmeaning(sym, MK_VAR);
  893.                     mp->name = name;
  894.                     mp->type = ep->val.type;
  895.                     sp->exp1 = makeexpr_assign(makeexpr_var(mp), ep);
  896.                 } else if (curtok == TOK_HAT || curtok == TOK_ADDR ||
  897.                            curtok == TOK_LBR || curtok == TOK_DOT) {
  898.                     ep = makeexpr_name(name, tp_integer);
  899.                     ep = fake_dots_n_hats(ep);
  900.                     if (wneedtok(TOK_ASSIGN))
  901. sp->exp1 = makeexpr_assign(ep, p_expr(NULL));
  902.     else
  903. sp->exp1 = ep;
  904.                 } else if (curtok == TOK_LPAR) {
  905.                     ep = makeexpr_bicall_0(name, tp_void);
  906.                     do {
  907.                         gettok();
  908.                         insertarg(&ep, ep->nargs, p_expr(NULL));
  909.                     } while (curtok == TOK_COMMA);
  910.                     skipcloseparen();
  911.                     sp->exp1 = ep;
  912.                 } else {
  913.                     sp->exp1 = makeexpr_bicall_0(name, tp_void);
  914.                 }
  915. if (!tryfuncmacro(&sp->exp1, NULL))
  916.     undefsym(sym);
  917.             } else if (mp->kind == MK_FUNCTION && !mp->isfunction) {
  918.                 mp->refcount++;
  919.                 gettok();
  920.                 ep = p_funccall(mp);
  921.                 if (!mp->constdefn)
  922.                     need_forward_decl(mp);
  923.                 if (mp->handler && !(mp->sym->flags & LEAVEALONE) &&
  924.                                    !mp->constdefn) {
  925.                     prochandler = (Stmt *(*)())mp->handler;
  926.                     *spp = (*prochandler)(ep, slist);
  927.                     while (*spp)
  928.                         spp = &((*spp)->next);
  929.                 } else {
  930.                     newstmt(SK_ASSIGN);
  931.                     sp->exp1 = ep;
  932.                 }
  933.             } else if (mp->kind == MK_SPECIAL) {
  934.                 gettok();
  935.                 if (mp->handler && !mp->isfunction) {
  936.                     if ((mp->sym->flags & LEAVEALONE) || mp->constdefn) {
  937.                         ep = makeexpr_bicall_0(mp->name, tp_void);
  938.                         if (curtok == TOK_LPAR) {
  939.                             do {
  940.                                 gettok();
  941.                                 insertarg(&ep, ep->nargs, p_expr(NULL));
  942.                             } while (curtok == TOK_COMMA);
  943.                             skipcloseparen();
  944.                         }
  945.                         newstmt(SK_ASSIGN);
  946. tryfuncmacro(&ep, mp);
  947. sp->exp1 = ep;
  948.                     } else {
  949.                         prochandler = (Stmt *(*)())mp->handler;
  950.                         *spp = (*prochandler)(mp, slist);
  951.                         while (*spp)
  952.                             spp = &((*spp)->next);
  953.                     }
  954.                 } else
  955.                     symclass(curtoksym);
  956.             } else {
  957.                 newstmt(SK_ASSIGN);
  958.                 if (curtokmeaning->kind == MK_FUNCTION &&
  959.     peeknextchar() != '(') {
  960.                     mp = curctx;
  961.                     while (mp && mp != curtokmeaning)
  962.                         mp = mp->ctx;
  963.                     if (mp)
  964.                         curtokmeaning = curtokmeaning->cbase;
  965.                 }
  966.                 ep = p_expr(tp_void);
  967. #if 0
  968. if (!(ep->kind == EK_SPCALL ||
  969.       (ep->kind == EK_COND &&
  970.        ep->args[1]->kind == EK_SPCALL)))
  971.     wexpecttok(TOK_ASSIGN);
  972. #endif
  973. if (curtok == TOK_ASSIGN) {
  974.     gettok();
  975.     if (curtok == TOK_IDENT && !strcicmp(curtokbuf, "ZERO") &&
  976. !curtokmeaning) {   /* VAX Pascal foolishness */
  977. gettok();
  978. ep2 = makeexpr_sizeof(copyexpr(ep), 0);
  979. sp->exp1 = makeexpr_bicall_3("memset", tp_void,
  980.      makeexpr_addr(ep),
  981.      makeexpr_long(0), ep2);
  982.     } else
  983. sp->exp1 = makeexpr_assign(ep, p_expr(ep->val.type));
  984. } else
  985.     sp->exp1 = ep;
  986.             }
  987.             break;
  988. default:
  989.     break;    /* null statement */
  990.     }
  991.     freestmttemps(tempmark);
  992.     if (sflags & SF_SAVESER)
  993. curserial = firstserial;
  994.     return sbase;
  995. }
  996. #define BR_NEVER        0x1     /* never use braces */
  997. #define BR_FUNCTION     0x2     /* function body */
  998. #define BR_THENPART     0x4     /* before an "else" */
  999. #define BR_ALWAYS       0x8     /* always use braces */
  1000. #define BR_REPEAT       0x10    /* "do-while" loop */
  1001. #define BR_TRY          0x20    /* in a recover block */
  1002. #define BR_ELSEPART     0x40    /* after an "else" */
  1003. #define BR_CASE         0x80    /* case of a switch stmt */
  1004. Static int usebraces(sp, opts)
  1005. Stmt *sp;
  1006. int opts;
  1007. {
  1008.     if (opts & (BR_FUNCTION|BR_ALWAYS))
  1009.         return 1;
  1010.     if (opts & BR_NEVER)
  1011.         return 0;
  1012.     switch (bracesalways) {
  1013.         case 0:
  1014.             if (sp) {
  1015.                 if (sp->next ||
  1016.                     sp->kind == SK_TRY ||
  1017.                     (sp->kind == SK_IF && !sp->stm2) ||
  1018.                     (opts & BR_REPEAT))
  1019.                     return 1;
  1020.             }
  1021.             break;
  1022.         case 1:
  1023.             return 1;
  1024.             break;
  1025.         default:
  1026.             if (sp) {
  1027.                 if (sp->next ||
  1028.                     sp->kind == SK_IF ||
  1029.                     sp->kind == SK_WHILE ||
  1030.                     sp->kind == SK_REPEAT ||
  1031.                     sp->kind == SK_TRY ||
  1032.     sp->kind == SK_CASE ||
  1033.                     sp->kind == SK_FOR)
  1034.                     return 1;
  1035.             }
  1036.             break;
  1037.     }
  1038.     if (sp != NULL &&
  1039. findcomment(curcomments, CMT_NOT | CMT_TRAIL, sp->serial) != NULL)
  1040. return 1;
  1041.     return 0;
  1042. }
  1043. #define outspnl(spflag) output((spflag) ? " " : "n")
  1044. #define openbrace()                 
  1045.     wbraces = (!candeclare);        
  1046.     if (wbraces) {                  
  1047.         output("{");                
  1048.         outspnl(braceline <= 0);    
  1049.         candeclare = 1;             
  1050.     }
  1051. #define closebrace()                
  1052.     if (wbraces) {                  
  1053.         if (sp->next || braces)     
  1054.             output("}n");          
  1055.         else                        
  1056.             braces = 1;             
  1057.     }
  1058. Meaning *outcontext;
  1059. Static void outnl(serial)
  1060. int serial;
  1061. {
  1062.     outtrailcomment(curcomments, serial, commentindent);
  1063. }
  1064. Static void out_block(spbase, opts, serial)
  1065. Stmt *spbase;
  1066. int opts, serial;
  1067. {
  1068.     int i, j, braces, always, trynum, istrail, hascmt;
  1069.     int gotcomments = 0;
  1070.     int saveindent, saveindent2, delta;
  1071.     Stmt *sp = spbase;
  1072.     Stmt *sp2, *sp3;
  1073.     Meaning *ctx, *mp;
  1074.     Strlist *curcmt, *cmt, *savecurcmt = curcomments;
  1075.     Strlist *trailcmt, *begincmt, *endcmt;
  1076.     if (debug>1) { fprintf(outf, "out_block of:n"); dumpstmt(spbase,5); }
  1077.     if (opts & BR_FUNCTION) {
  1078. if (outcontext && outcontext->comments) {
  1079.     gotcomments = 1;
  1080.     curcomments = outcontext->comments;
  1081. }
  1082. attach_comments(spbase);
  1083.     }
  1084.     braces = usebraces(sp, opts);
  1085.     trailcmt = findcomment(curcomments, CMT_TRAIL, serial);
  1086.     begincmt = findcomment(curcomments, CMT_ONBEGIN, serial);
  1087.     istrail = 1;
  1088.     if (!trailcmt) {
  1089. trailcmt = begincmt;
  1090. begincmt = NULL;
  1091. istrail = 0;
  1092.     }
  1093.     endcmt = findcomment(curcomments, CMT_ONEND, serial);
  1094.     if ((begincmt || endcmt) && !(opts & BR_NEVER))
  1095. braces = 1;
  1096.     if (opts & BR_ELSEPART) {
  1097. cmt = findcomment(curcomments, CMT_ONELSE, serial);
  1098. if (cmt) {
  1099.     if (trailcmt) {
  1100. out_spaces(bracecommentindent, commentoverindent,
  1101.    commentlen(cmt), 0);
  1102. output("01");
  1103. outcomment(cmt);
  1104.     } else
  1105. trailcmt = cmt;
  1106. }
  1107.     }
  1108.     if (braces) {
  1109. j = (opts & BR_FUNCTION) ? funcopenindent : openbraceindent;
  1110.         if (!line_start()) {
  1111.     if (trailcmt &&
  1112. cur_column() + commentlen(trailcmt) + 2 > linewidth &&
  1113. outindent + commentlen(trailcmt) + 2 < linewidth)  /*close enough*/
  1114. i = 0;
  1115.     else if (opts & BR_ELSEPART)
  1116. i = ((braceelseline & 2) == 0);
  1117.     else if (braceline >= 0)
  1118. i = (braceline == 0);
  1119.     else
  1120.                 i = ((opts & BR_FUNCTION) == 0);
  1121.     if (trailcmt && begincmt) {
  1122. out_spaces(commentindent, commentoverindent,
  1123.    commentlen(trailcmt), j);
  1124. outcomment(trailcmt);
  1125. trailcmt = begincmt;
  1126. begincmt = NULL;
  1127. istrail = 0;
  1128.     } else
  1129. outspnl(i);
  1130.         }
  1131. if (line_start())
  1132.     singleindent(j);
  1133.         output("{");
  1134.         candeclare = 1;
  1135.     } else if (!sp) {
  1136.         if (!line_start())
  1137.             outspnl(!nullstmtline && !(opts & BR_TRY));
  1138. if (line_start())
  1139.     singleindent(tabsize);
  1140.         output(";");
  1141.     }
  1142.     if (opts & BR_CASE)
  1143. delta = 0;
  1144.     else {
  1145. delta = tabsize;
  1146. if (opts & BR_FUNCTION)
  1147.     delta = adddeltas(delta, bodyindent);
  1148. else if (braces)
  1149.     delta = adddeltas(delta, blockindent);
  1150.     }
  1151.     futureindent(delta);
  1152.     if (bracecombine && braces)
  1153. i = applydelta(outindent, delta) - cur_column();
  1154.     else
  1155. i = -1;
  1156.     if (commentvisible(trailcmt)) {
  1157. if (line_start()) {
  1158.     singleindent(delta);
  1159.     out_spaces(commentoverindent, 1000, commentlen(trailcmt), 0);
  1160.     outcomment(trailcmt);
  1161. } else /*if (commentlen(trailcmt) + cur_column() + 1 <= linewidth)*/ {
  1162.     out_spaces(istrail ? commentindent : bracecommentindent,
  1163.        commentoverindent, commentlen(trailcmt), delta);
  1164.     outcomment(trailcmt);
  1165. } /*else {
  1166.     output("n");
  1167.     singleindent(delta);
  1168.     out_spaces(commentoverindent, 1000, commentlen(trailcmt), 0);
  1169.     outcomment(trailcmt);
  1170. }*/
  1171. i = -9999;
  1172.     }
  1173.     if (i > 0)
  1174. out_spaces(i, 0, 0, 0);
  1175.     else if (i != -9999)
  1176. output("n");
  1177.     saveindent = outindent;
  1178.     moreindent(delta);
  1179.     outcomment(begincmt);
  1180.     while (sp) {
  1181. flushcomments(NULL, CMT_PRE, sp->serial);
  1182. if (cmtdebug)
  1183.     output(format_d("[%d] ", sp->serial));
  1184.         switch (sp->kind) {
  1185.             case SK_HEADER:
  1186.                 ctx = (Meaning *)sp->exp1->val.i;
  1187. eatblanklines();
  1188.                 if (declarevars(ctx, 0))
  1189.                     outsection(minorspace);
  1190. flushcomments(NULL, CMT_NOT | CMT_ONEND, serial);
  1191.                 if (ctx->kind == MK_MODULE) {
  1192.                     if (ctx->anyvarflag) {
  1193.                         output(format_s(name_MAIN, ""));
  1194.                         output("(argc, argv);n");
  1195.                     } else {
  1196.                         output("static int _was_initialized = 0;n");
  1197.                         output("if (_was_initialized++)n");
  1198. singleindent(tabsize);
  1199.                         output("return;n");
  1200.                     }
  1201.     while (initialcalls) {
  1202. output(initialcalls->s);
  1203. output(";n");
  1204. strlist_remove(&initialcalls, initialcalls->s);
  1205.     }
  1206.                 } else {
  1207.                     if (ctx->varstructflag && ctx->ctx->kind == MK_FUNCTION &&
  1208.                                               ctx->ctx->varstructflag) {
  1209.                         output(format_s(name_VARS, ctx->name));
  1210.                         output(".");
  1211.                         output(format_s(name_LINK, ctx->ctx->name));
  1212.                         output(" = ");
  1213.                         output(format_s(name_LINK, ctx->ctx->name));
  1214.                         output(";n");
  1215.                     }
  1216.                     for (mp = ctx->cbase; mp; mp = mp->cnext) {
  1217.                         if ((mp->kind == MK_VAR ||    /* these are variables with */
  1218.      mp->kind == MK_VARREF) &&
  1219.     mp->varstructflag &&      /* initializers which were moved */
  1220.     mp->cnext &&              /* into a varstruct, so they */
  1221.     mp->cnext->snext == mp && /* must be initialized now */
  1222.     mp->cnext->constdefn) {
  1223.                             if (mp->type->kind == TK_ARRAY) {
  1224.                                 output("memcpy(");
  1225.                                 out_var(mp, 2);
  1226.                                 output(", ");
  1227.                                 out_var(mp->cnext, 2);
  1228.                                 output(", sizeof(");
  1229.                                 out_type(mp->type, 1);
  1230.                                 output("))");
  1231.                             } else {
  1232.                                 out_var(mp, 2);
  1233.                                 output(" = ");
  1234.                                 out_var(mp->cnext, 2);
  1235.                             }
  1236.                             output(";n");
  1237.                         }
  1238.                     }
  1239.                 }
  1240.                 break;
  1241.             case SK_RETURN:
  1242.                 output("return");
  1243. if (sp->exp1) {
  1244.     switch (returnparens) {
  1245.       case 0:
  1246. output(" ");
  1247. out_expr(sp->exp1);
  1248. break;
  1249.       case 1:
  1250. if (spaceexprs != 0)
  1251.     output(" ");
  1252. out_expr_parens(sp->exp1);
  1253. break;
  1254.       default:
  1255. if (sp->exp1->kind == EK_VAR ||
  1256.     sp->exp1->kind == EK_CONST ||
  1257.     sp->exp1->kind == EK_LONGCONST ||
  1258.     sp->exp1->kind == EK_BICALL) {
  1259.     output(" ");
  1260.     out_expr(sp->exp1);
  1261. } else {
  1262.     if (spaceexprs != 0)
  1263. output(" ");
  1264.     out_expr_parens(sp->exp1);
  1265. }
  1266. break;
  1267.     }
  1268. }
  1269. output(";");
  1270. outnl(sp->serial);
  1271.                 break;
  1272.             case SK_ASSIGN:
  1273.                 out_expr_stmt(sp->exp1);
  1274.                 output(";");
  1275. outnl(sp->serial);
  1276.                 break;
  1277.             case SK_CASE:
  1278.                 output("switch (");
  1279.                 out_expr(sp->exp1);
  1280.                 output(")");
  1281.                 outspnl(braceline <= 0);
  1282.                 output("{");
  1283. outnl(sp->serial);
  1284. saveindent2 = outindent;
  1285. moreindent(tabsize);
  1286. moreindent(switchindent);
  1287.                 sp2 = sp->stm1;
  1288.                 while (sp2 && sp2->kind == SK_CASELABEL) {
  1289.                     outsection(casespacing);
  1290.                     sp3 = sp2;
  1291.     i = 0;
  1292.     hascmt = (findcomment(curcomments, -1, sp2->serial) != NULL);
  1293.     singleindent(caseindent);
  1294.     flushcomments(NULL, CMT_PRE, sp2->serial);
  1295.                     for (;;) {
  1296. if (i)
  1297.     singleindent(caseindent);
  1298. i = 0;
  1299.                         output("case ");
  1300.                         out_expr(sp3->exp1);
  1301.                         output(":01");
  1302.                         sp3 = sp3->stm1;
  1303.                         if (!sp3 || sp3->kind != SK_CASELABEL)
  1304.                             break;
  1305.                         if (casetabs != 1000)
  1306.                             out_spaces(casetabs, 0, 0, 0);
  1307.                         else {
  1308.                             output("n");
  1309.     i = 1;
  1310. }
  1311.                     }
  1312.                     if (sp3)
  1313.                         out_block(sp3, BR_NEVER|BR_CASE, sp2->serial);
  1314.                     else {
  1315. outnl(sp2->serial);
  1316. if (!hascmt)
  1317.     output("/* blank case */n");
  1318.     }
  1319.                     output("break;n");
  1320.     flushcomments(NULL, -1, sp2->serial);
  1321.                     sp2 = sp2->next;
  1322.                 }
  1323.                 if (sp2) {
  1324.                     outsection(casespacing);
  1325.     singleindent(caseindent);
  1326.     flushcomments(NULL, CMT_PRE, sp2->serial);
  1327.                     output("default:");
  1328.                     out_block(sp2, BR_NEVER|BR_CASE, sp2->serial);
  1329.                     output("break;n");
  1330.     flushcomments(NULL, -1, sp2->serial);
  1331.                 }
  1332.                 outindent = saveindent2;
  1333.                 output("}");
  1334. curcmt = findcomment(curcomments, CMT_ONEND, sp->serial);
  1335. if (curcmt)
  1336.     outcomment(curcmt);
  1337. else
  1338.     output("n");
  1339.                 break;
  1340.             case SK_CASECHECK:
  1341. output(name_CASECHECK);
  1342.                 output("();   /* CASE value range error */n");
  1343.                 break;
  1344.             case SK_FOR:
  1345.                 output("for (");
  1346. if (for_allornone)
  1347.     output("07");
  1348.                 if (sp->exp1 || sp->exp2 || sp->exp3 || spaceexprs > 0) {
  1349.                     if (sp->exp1)
  1350.                         out_expr_top(sp->exp1);
  1351.                     else if (spaceexprs > 0)
  1352.                         output(" ");
  1353.                     output(";02 ");
  1354.                     if (sp->exp2)
  1355.                         out_expr(sp->exp2);
  1356.                     output(";02 ");
  1357.                     if (sp->exp3)
  1358.                         out_expr_top(sp->exp3);
  1359.                 } else {
  1360.                     output(";;");
  1361.                 }
  1362.                 output(")");
  1363.                 out_block(sp->stm1, 0, sp->serial);
  1364.                 break;
  1365.             case SK_LABEL:
  1366.                 if (!line_start())
  1367.                     output("n");
  1368. singleindent(labelindent);
  1369.                 out_expr(sp->exp1);
  1370.                 output(":");
  1371.                 if (!sp->next)
  1372.                     output(" ;");
  1373.                 outnl(sp->serial);
  1374.                 break;
  1375.             case SK_GOTO:
  1376.                 /* what about non-local goto's? */
  1377.                 output("goto ");
  1378.                 out_expr(sp->exp1);
  1379.                 output(";");
  1380. outnl(sp->serial);
  1381.                 break;
  1382.             case SK_IF:
  1383.                 sp2 = sp;
  1384.                 for (;;) {
  1385.                     output("if (");
  1386.                     out_expr_bool(sp2->exp1);
  1387.                     output(")");
  1388.                     if (sp2->stm2) {
  1389. cmt = findcomment(curcomments, CMT_ONELSE, sp->serial+1);
  1390.                         i = (!cmt && sp2->stm2->kind == SK_IF &&
  1391.      !sp2->stm2->next &&
  1392.      ((sp2->stm2->exp2)
  1393.       ? checkconst(sp2->stm2->exp2, 1)
  1394.       : (elseif > 0)));
  1395. if (braceelse &&
  1396.                             (usebraces(sp2->stm1, 0) ||
  1397.                              usebraces(sp2->stm2, 0) || i))
  1398.                             always = BR_ALWAYS;
  1399.                         else
  1400.                             always = 0;
  1401.                         out_block(sp2->stm1, BR_THENPART|always, sp->serial);
  1402.                         output("else");
  1403.                         sp2 = sp2->stm2;
  1404.                         if (i) {
  1405.                             output(" ");
  1406.                         } else {
  1407.                             out_block(sp2, BR_ELSEPART|always, sp->serial+1);
  1408.                             break;
  1409.                         }
  1410.                     } else {
  1411.                         out_block(sp2->stm1, 0, sp->serial);
  1412.                         break;
  1413.                     }
  1414.                 }
  1415.                 break;
  1416.             case SK_REPEAT:
  1417.                 output("do");
  1418.                 out_block(sp->stm1, BR_ALWAYS|BR_REPEAT, sp->serial);
  1419.                 output("while (");
  1420.                 out_expr_bool(sp->exp1);
  1421.                 output(");");
  1422. cmt = findcomment(curcomments, CMT_ONEND, sp->serial);
  1423. if (commentvisible(cmt)) {
  1424.     out_spaces(commentindent, commentoverindent,
  1425.        commentlen(cmt), 0);
  1426.     output("01");
  1427.     outcomment(cmt);
  1428. } else
  1429.     output("n");
  1430.                 break;
  1431.             case SK_TRY:
  1432.                 trynum = sp->exp1->val.i;
  1433.                 output(format_d("TRY(try%d);", trynum));
  1434.                 out_block(sp->stm1, BR_NEVER|BR_TRY, sp->serial);
  1435.                 if (sp->exp2)
  1436.                     output(format_ds("RECOVER2(try%d,%s);", trynum,
  1437.                                      format_s(name_LABEL, format_d("try%d", trynum))));
  1438.                 else
  1439.                     output(format_d("RECOVER(try%d);", trynum));
  1440.                 out_block(sp->stm2, BR_NEVER|BR_TRY, sp->serial);
  1441.                 output(format_d("ENDTRY(try%d);n", trynum));
  1442.                 break;
  1443.             case SK_WHILE:
  1444.                 output("while (");
  1445.                 out_expr_bool(sp->exp1);
  1446.                 output(")");
  1447.                 out_block(sp->stm1, 0, sp->serial);
  1448.                 break;
  1449.             case SK_BREAK:
  1450.                 output("break;");
  1451. outnl(sp->serial);
  1452.                 break;
  1453.             case SK_CONTINUE:
  1454.                 output("continue;");
  1455. outnl(sp->serial);
  1456.                 break;
  1457.     default:
  1458.         intwarning("out_block",
  1459.    format_s("Misplaced statement kind %s [265]",
  1460.     stmtkindname(sp->kind)));
  1461. break;
  1462.         }
  1463. flushcomments(NULL, -1, sp->serial);
  1464.         candeclare = 0;
  1465.         if (debug>1) { fprintf(outf, "in out_block:n"); dumpstmt(spbase,5); }
  1466.         sp = sp->next;
  1467.     }
  1468.     if (opts & BR_FUNCTION) {
  1469. cmt = extractcomment(&curcomments, CMT_ONEND, serial);
  1470. if (findcomment(curcomments, -1, -1) != NULL)  /* check for non-DONE */
  1471.     output("n");
  1472. flushcomments(NULL, -1, -1);
  1473. curcomments = cmt;
  1474.     }
  1475.     outindent = saveindent;
  1476.     if (braces) {
  1477. if (line_start()) {
  1478.     if (opts & BR_FUNCTION)
  1479. singleindent(funccloseindent);
  1480.     else
  1481. singleindent(closebraceindent);
  1482. }
  1483.         output("}");
  1484. i = 1;
  1485. cmt = findcomment(curcomments, CMT_ONEND, serial);
  1486. if (!(opts & BR_REPEAT) && commentvisible(cmt)) {
  1487.     out_spaces(bracecommentindent, commentoverindent,
  1488.        commentlen(cmt), 0);
  1489.     output("01");
  1490.     outcomment(cmt);
  1491.     i = 0;
  1492. }
  1493. if (i) {
  1494.     outspnl((opts & BR_REPEAT) ||
  1495.     ((opts & BR_THENPART) && (braceelseline & 1) == 0));
  1496. }
  1497.         candeclare = 0;
  1498.     }
  1499.     if (gotcomments) {
  1500. outcontext->comments = curcomments;
  1501. curcomments = savecurcmt;
  1502.     }
  1503. }
  1504. /* Should have a way to convert GOTO's to the end of the function to RETURN's */
  1505. /* Convert "_RETV = foo;" at end of function to "return foo" */
  1506. Static int checkreturns(spp, nearret)
  1507. Stmt **spp;
  1508. int nearret;
  1509. {
  1510.     Stmt *sp;
  1511.     Expr *rvar, *ex;
  1512.     Meaning *mp;
  1513.     int spnearret, spnextreturn;
  1514.     int result = 0;
  1515.     if (debug>2) { fprintf(outf, "checkreturns on:n"); dumpstmt(*spp, 5); }
  1516.     while ((sp = *spp)) {
  1517.         spnextreturn = (sp->next &&
  1518.                         sp->next->kind == SK_RETURN && sp->next->exp1 &&
  1519.                         isretvar(sp->next->exp1) == curctx->cbase);
  1520.         spnearret = (nearret && !sp->next) || spnextreturn;
  1521.         result = 0;
  1522.         switch (sp->kind) {
  1523.             case SK_ASSIGN:
  1524.                 ex = sp->exp1;
  1525.                 if (ex->kind == EK_ASSIGN || structuredfunc(ex)) {
  1526.                     rvar = ex->args[0];
  1527.                     mp = isretvar(rvar);
  1528.                     if (mp == curctx->cbase && spnearret) {
  1529.                         if (ex->kind == EK_ASSIGN) {
  1530.                             if (mp->kind == MK_VARPARAM) {
  1531.                                 ex = makeexpr_comma(ex, makeexpr_var(mp));
  1532.                             } else {
  1533.                                 ex = grabarg(ex, 1);
  1534.                                 mp->refcount--;
  1535.                             }
  1536.                         }
  1537.                         sp->exp1 = ex;
  1538.                         sp->kind = SK_RETURN;