home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i075: Pascal to C translator, Part30/32
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: d140c78b e19ae830 375027e7 9a3c700a
-
- Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
- Posting-number: Volume 21, Issue 75
- Archive-name: p2c/part30
-
- #! /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 30 (of 32)."
- # Contents: src/parse.c.2
- # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:53 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/parse.c.2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/parse.c.2'\"
- else
- echo shar: Extracting \"'src/parse.c.2'\" \(49392 characters\)
- sed "s/^X//" >'src/parse.c.2' <<'END_OF_FILE'
- X if (spnextreturn) {
- X mp->refcount--;
- X sp->next = sp->next->next;
- X }
- X result = 1;
- X }
- X }
- X break;
- X
- X case SK_RETURN:
- X case SK_GOTO:
- X result = 1;
- X break;
- X
- X case SK_IF:
- X result = checkreturns(&sp->stm1, spnearret) & /* NOT && */
- X checkreturns(&sp->stm2, spnearret);
- X break;
- X
- X case SK_TRY:
- X (void) checkreturns(&sp->stm1, 0);
- X (void) checkreturns(&sp->stm2, spnearret);
- X break;
- X
- X /* should handle CASE statements as well */
- X
- X default:
- X (void) checkreturns(&sp->stm1, 0);
- X (void) checkreturns(&sp->stm2, 0);
- X break;
- X }
- X spp = &sp->next;
- X }
- X return result;
- X}
- X
- X
- X
- X
- X
- X
- X
- X/* Replace all occurrences of one expression with another expression */
- X
- XExpr *replaceexprexpr(ex, oldex, newex)
- XExpr *ex, *oldex, *newex;
- X{
- X int i;
- X Type *type;
- X
- X for (i = 0; i < ex->nargs; i++)
- X ex->args[i] = replaceexprexpr(ex->args[i], oldex, newex);
- X if (exprsame(ex, oldex, 2)) {
- X if (ex->val.type->kind == TK_POINTER &&
- X ex->val.type->basetype == oldex->val.type) {
- X freeexpr(ex);
- X return makeexpr_addr(copyexpr(newex));
- X } else if (oldex->val.type->kind == TK_POINTER &&
- X oldex->val.type->basetype == ex->val.type) {
- X freeexpr(ex);
- X return makeexpr_hat(copyexpr(newex), 0);
- X } else {
- X type = ex->val.type;
- X freeexpr(ex);
- X ex = copyexpr(newex);
- X ex->val.type = type;
- X return ex;
- X }
- X }
- X return resimplify(ex);
- X}
- X
- X
- Xvoid replaceexpr(sp, oldex, newex)
- XStmt *sp;
- XExpr *oldex, *newex;
- X{
- X while (sp) {
- X replaceexpr(sp->stm1, oldex, newex);
- X replaceexpr(sp->stm2, oldex, newex);
- X if (sp->exp1)
- X sp->exp1 = replaceexprexpr(sp->exp1, oldex, newex);
- X if (sp->exp2)
- X sp->exp2 = replaceexprexpr(sp->exp2, oldex, newex);
- X if (sp->exp3)
- X sp->exp3 = replaceexprexpr(sp->exp3, oldex, newex);
- X sp = sp->next;
- X }
- X}
- X
- X
- X
- X
- X
- X
- XStmt *mixassignments(sp, mp)
- XStmt *sp;
- XMeaning *mp;
- X{
- X if (!sp)
- X return NULL;
- X sp->next = mixassignments(sp->next, mp);
- X if (sp->next &&
- X sp->kind == SK_ASSIGN &&
- X sp->exp1->kind == EK_ASSIGN &&
- X sp->exp1->args[0]->kind == EK_VAR &&
- X (!mp || mp == (Meaning *)sp->exp1->args[0]->val.i) &&
- X ord_type(sp->exp1->args[0]->val.type)->kind == TK_INTEGER &&
- X nodependencies(sp->exp1->args[1], 0) &&
- X sp->next->kind == SK_ASSIGN &&
- X sp->next->exp1->kind == EK_ASSIGN &&
- X (exprsame(sp->exp1->args[0], sp->next->exp1->args[0], 1) ||
- X (mp && mp->istemporary)) &&
- X exproccurs(sp->next->exp1->args[1], sp->exp1->args[0]) == 1) {
- X sp->next->exp1->args[1] = replaceexprexpr(sp->next->exp1->args[1],
- X sp->exp1->args[0],
- X sp->exp1->args[1]);
- X if (mp && mp->istemporary)
- X canceltempvar(mp);
- X return sp->next;
- X }
- X return sp;
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- X/* Do various simple (sometimes necessary) massages on the statements */
- X
- X
- XStatic Stmt bogusreturn = { SK_RETURN, NULL, NULL, NULL, NULL, NULL, NULL };
- X
- X
- X
- XStatic int isescape(ex)
- XExpr *ex;
- X{
- X if (ex->kind == EK_BICALL && (!strcmp(ex->val.s, name_ESCAPE) ||
- X !strcmp(ex->val.s, name_ESCIO) ||
- X !strcmp(ex->val.s, name_OUTMEM) ||
- X !strcmp(ex->val.s, name_CASECHECK) ||
- X !strcmp(ex->val.s, name_NILCHECK) ||
- X !strcmp(ex->val.s, "_exit") ||
- X !strcmp(ex->val.s, "exit")))
- X return 1;
- X if (ex->kind == EK_CAST)
- X return isescape(ex->args[0]);
- X return 0;
- X}
- X
- X
- X/* check if a block can never exit by falling off the end */
- XStatic int deadendblock(sp)
- XStmt *sp;
- X{
- X if (!sp)
- X return 0;
- X while (sp->next)
- X sp = sp->next;
- X return (sp->kind == SK_GOTO ||
- X sp->kind == SK_BREAK ||
- X sp->kind == SK_CONTINUE ||
- X sp->kind == SK_RETURN ||
- X sp->kind == SK_CASECHECK ||
- X (sp->kind == SK_IF && deadendblock(sp->stm1) &&
- X deadendblock(sp->stm2)) ||
- X (sp->kind == SK_ASSIGN && isescape(sp->exp1)));
- X}
- X
- X
- X
- X
- Xint expr_is_bool(ex, want)
- XExpr *ex;
- Xint want;
- X{
- X long val;
- X
- X if (ex->val.type == tp_boolean && isconstexpr(ex, &val))
- X return (val == want);
- X return 0;
- X}
- X
- X
- X
- X
- X/* Returns 1 if c1 implies c2, 0 otherwise */
- X/* If not1 is true, then checks if (!c1) implies c2; similarly for not2 */
- X
- X/* Identities used:
- X c1 -> (c2a && c2b) <=> (c1 -> c2a) && (c1 -> c2b)
- X c1 -> (c2a || c2b) <=> (c1 -> c2a) || (c1 -> c2b)
- X (c1a && c1b) -> c2 <=> (c1a -> c2) || (c1b -> c2)
- X (c1a || c1b) -> c2 <=> (c1a -> c2) && (c1b -> c2)
- X (!c1) -> (!c2) <=> c2 -> c1
- X (a == b) -> c2(b) <=> c2(a)
- X !(c1 && c2) <=> (!c1) || (!c2)
- X !(c1 || c2) <=> (!c1) && (!c2)
- X*/
- X/* This could be smarter about, e.g., (a>5) -> (a>0) */
- X
- Xint implies(c1, c2, not1, not2)
- XExpr *c1, *c2;
- Xint not1, not2;
- X{
- X Expr *ex;
- X int i;
- X
- X if (c1->kind == EK_EQ && c1->args[0]->val.type == tp_boolean) {
- X if (checkconst(c1->args[0], 1)) { /* things like "flag = true" */
- X return implies(c1->args[1], c2, not1, not2);
- X } else if (checkconst(c1->args[1], 1)) {
- X return implies(c1->args[0], c2, not1, not2);
- X } else if (checkconst(c1->args[0], 0)) {
- X return implies(c1->args[1], c2, !not1, not2);
- X } else if (checkconst(c1->args[1], 0)) {
- X return implies(c1->args[0], c2, !not1, not2);
- X }
- X }
- X if (c2->kind == EK_EQ && c2->args[0]->val.type == tp_boolean) {
- X if (checkconst(c2->args[0], 1)) {
- X return implies(c1, c2->args[1], not1, not2);
- X } else if (checkconst(c2->args[1], 1)) {
- X return implies(c1, c2->args[0], not1, not2);
- X } else if (checkconst(c2->args[0], 0)) {
- X return implies(c1, c2->args[1], not1, !not2);
- X } else if (checkconst(c2->args[1], 0)) {
- X return implies(c1, c2->args[0], not1, !not2);
- X }
- X }
- X switch (c2->kind) {
- X
- X case EK_AND:
- X if (not2) /* c1 -> (!c2a || !c2b) */
- X return (implies(c1, c2->args[0], not1, 1) ||
- X implies(c1, c2->args[1], not1, 1));
- X else /* c1 -> (c2a && c2b) */
- X return (implies(c1, c2->args[0], not1, 0) &&
- X implies(c1, c2->args[1], not1, 0));
- X
- X case EK_OR:
- X if (not2) /* c1 -> (!c2a && !c2b) */
- X return (implies(c1, c2->args[0], not1, 1) &&
- X implies(c1, c2->args[1], not1, 1));
- X else /* c1 -> (c2a || c2b) */
- X return (implies(c1, c2->args[0], not1, 0) ||
- X implies(c1, c2->args[1], not1, 0));
- X
- X case EK_NOT: /* c1 -> (!c2) */
- X return (implies(c1, c2->args[0], not1, !not2));
- X
- X case EK_CONST:
- X if ((c2->val.i != 0) != not2) /* c1 -> true */
- X return 1;
- X break;
- X
- X default:
- X break;
- X }
- X switch (c1->kind) {
- X
- X case EK_AND:
- X if (not1) /* (!c1a || !c1b) -> c2 */
- X return (implies(c1->args[0], c2, 1, not2) &&
- X implies(c1->args[1], c2, 1, not2));
- X else /* (c1a && c1b) -> c2 */
- X return (implies(c1->args[0], c2, 0, not2) ||
- X implies(c1->args[1], c2, 0, not2));
- X
- X case EK_OR:
- X if (not1) /* (!c1a && !c1b) -> c2 */
- X return (implies(c1->args[0], c2, 1, not2) ||
- X implies(c1->args[1], c2, 1, not2));
- X else /* (c1a || c1b) -> c2 */
- X return (implies(c1->args[0], c2, 0, not2) &&
- X implies(c1->args[1], c2, 0, not2));
- X
- X case EK_NOT: /* (!c1) -> c2 */
- X return (implies(c1->args[0], c2, !not1, not2));
- X
- X case EK_CONST:
- X if ((c1->val.i != 0) == not1) /* false -> c2 */
- X return 1;
- X break;
- X
- X case EK_EQ: /* (a=b) -> c2 */
- X case EK_ASSIGN: /* (a:=b) -> c2 */
- X case EK_NE: /* (a<>b) -> c2 */
- X if ((c1->kind == EK_NE) == not1) {
- X if (c1->args[0]->kind == EK_VAR) {
- X ex = replaceexprexpr(copyexpr(c2), c1->args[0], c1->args[1]);
- X i = expr_is_bool(ex, !not2);
- X freeexpr(ex);
- X if (i)
- X return 1;
- X }
- X if (c1->args[1]->kind == EK_VAR) {
- X ex = replaceexprexpr(copyexpr(c2), c1->args[1], c1->args[0]);
- X i = expr_is_bool(ex, !not2);
- X freeexpr(ex);
- X if (i)
- X return 1;
- X }
- X }
- X break;
- X
- X default:
- X break;
- X }
- X if (not1 == not2 && exprequiv(c1, c2)) { /* c1 -> c1 */
- X return 1;
- X }
- X return 0;
- X}
- X
- X
- X
- X
- X
- Xvoid infiniteloop(sp)
- XStmt *sp;
- X{
- X switch (infloopstyle) {
- X
- X case 1: /* write "for (;;) ..." */
- X sp->kind = SK_FOR;
- X freeexpr(sp->exp1);
- X sp->exp1 = NULL;
- X break;
- X
- X case 2: /* write "while (1) ..." */
- X sp->kind = SK_WHILE;
- X freeexpr(sp->exp1);
- X sp->exp1 = makeexpr_val(make_ord(tp_boolean, 1));
- X break;
- X
- X case 3: /* write "do ... while (1)" */
- X sp->kind = SK_REPEAT;
- X freeexpr(sp->exp1);
- X sp->exp1 = makeexpr_val(make_ord(tp_boolean, 1));
- X break;
- X
- X default: /* leave it alone */
- X break;
- X
- X }
- X}
- X
- X
- X
- X
- X
- XExpr *print_func(ex)
- XExpr *ex;
- X{
- X if (!ex || ex->kind != EK_BICALL)
- X return NULL;
- X if ((!strcmp(ex->val.s, "printf") &&
- X ex->args[0]->kind == EK_CONST) ||
- X !strcmp(ex->val.s, "putchar") ||
- X !strcmp(ex->val.s, "puts"))
- X return ex_output;
- X if ((!strcmp(ex->val.s, "fprintf") ||
- X !strcmp(ex->val.s, "sprintf")) &&
- X ex->args[1]->kind == EK_CONST)
- X return ex->args[0];
- X if (!strcmp(ex->val.s, "putc") ||
- X !strcmp(ex->val.s, "fputc") ||
- X !strcmp(ex->val.s, "fputs"))
- X return ex->args[1];
- X return NULL;
- X}
- X
- X
- X
- Xint printnl_func(ex)
- XExpr *ex;
- X{
- X char *cp, ch;
- X int i, len;
- X
- X if (debug>2) { fprintf(outf,"printnl_func("); dumpexpr(ex); fprintf(outf, ")\n"); }
- X if (!strcmp(ex->val.s, "printf") ||
- X !strcmp(ex->val.s, "puts") ||
- X !strcmp(ex->val.s, "fputs")) {
- X if (ex->args[0]->kind != EK_CONST)
- X return 0;
- X cp = ex->args[0]->val.s;
- X len = ex->args[0]->val.i;
- X } else if (!strcmp(ex->val.s, "fprintf")) {
- X if (ex->args[1]->kind != EK_CONST)
- X return 0;
- X cp = ex->args[1]->val.s;
- X len = ex->args[1]->val.i;
- X } else if (!strcmp(ex->val.s, "putchar") ||
- X !strcmp(ex->val.s, "putc") ||
- X !strcmp(ex->val.s, "fputc")) {
- X if (ex->args[0]->kind != EK_CONST)
- X return 0;
- X ch = ex->args[0]->val.i;
- X cp = &ch;
- X len = 1;
- X } else
- X return 0;
- X for (i = 1; i <= len; i++)
- X if (*cp++ != '\n')
- X return 0;
- X return len + (!strcmp(ex->val.s, "puts"));
- X}
- X
- X
- X
- XExpr *chg_printf(ex)
- XExpr *ex;
- X{
- X Expr *fex;
- X
- X if (debug>2) { fprintf(outf,"chg_printf("); dumpexpr(ex); fprintf(outf, ")\n"); }
- X if (!strcmp(ex->val.s, "putchar")) {
- X ex = makeexpr_sprintfify(grabarg(ex, 0));
- X canceltempvar(istempvar(ex->args[0]));
- X strchange(&ex->val.s, "printf");
- X delfreearg(&ex, 0);
- X ex->val.type = tp_void;
- X } else if (!strcmp(ex->val.s, "putc") ||
- X !strcmp(ex->val.s, "fputc") ||
- X !strcmp(ex->val.s, "fputs")) {
- X fex = copyexpr(ex->args[1]);
- X ex = makeexpr_sprintfify(grabarg(ex, 0));
- X canceltempvar(istempvar(ex->args[0]));
- X strchange(&ex->val.s, "fprintf");
- X ex->args[0] = fex;
- X ex->val.type = tp_void;
- X } else if (!strcmp(ex->val.s, "puts")) {
- X ex = makeexpr_concat(makeexpr_sprintfify(grabarg(ex, 0)),
- X makeexpr_string("\n"), 1);
- X strchange(&ex->val.s, "printf");
- X delfreearg(&ex, 0);
- X ex->val.type = tp_void;
- X }
- X if (!strcmp(ex->val.s, "fprintf") && exprsame(ex->args[0], ex_output, 1)) {
- X delfreearg(&ex, 0);
- X strchange(&ex->val.s, "printf");
- X }
- X return ex;
- X}
- X
- X
- XExpr *mix_printf(ex, ex2)
- XExpr *ex, *ex2;
- X{
- X int i;
- X
- X ex = chg_printf(ex);
- X if (debug>2) { fprintf(outf,"chg_printf returns "); dumpexpr(ex); fprintf(outf, "\n"); }
- X ex2 = chg_printf(copyexpr(ex2));
- X if (debug>2) { fprintf(outf,"chg_printf returns "); dumpexpr(ex2);fprintf(outf, "\n"); }
- X i = (!strcmp(ex->val.s, "printf")) ? 0 : 1;
- X ex->args[i] = makeexpr_concat(ex->args[i], ex2->args[i], 0);
- X for (i++; i < ex2->nargs; i++) {
- X insertarg(&ex, ex->nargs, ex2->args[i]);
- X }
- X return ex;
- X}
- X
- X
- X
- X
- X
- X
- Xvoid eatstmt(spp)
- XStmt **spp;
- X{
- X Stmt *sp = *spp;
- X
- X if (debug>2) { fprintf(outf, "eatstmt on:\n"); dumpstmt(sp, 5); }
- X *spp = sp->next;
- X sp->next = NULL;
- X free_stmt(sp);
- X}
- X
- X
- X
- Xint haslabels(sp)
- XStmt *sp;
- X{
- X if (!sp)
- X return 0;
- X if (haslabels(sp->stm1) || haslabels(sp->stm2))
- X return 1;
- X return (sp->kind == SK_LABEL);
- X}
- X
- X
- X
- Xvoid fixblock(spp, thereturn)
- XStmt **spp, *thereturn;
- X{
- X Stmt *sp, *sp1, *sp2, *sp3, **spp2, *thisreturn;
- X Expr *ex;
- X Meaning *tvar, *mp;
- X int save_tryblock;
- X short save_tryflag;
- X int i, j, de1, de2;
- X long saveserial = curserial;
- X
- X while ((sp = *spp)) {
- X sp2 = sp->next;
- X sp->next = NULL;
- X sp = fix_statement(*spp);
- X if (!sp) {
- X *spp = sp2;
- X continue;
- X }
- X *spp = sp;
- X for (sp3 = sp; sp3->next; sp3 = sp3->next) ;
- X sp3->next = sp2;
- X if (!sp->next)
- X thisreturn = thereturn;
- X else if (sp->next->kind == SK_RETURN ||
- X (sp->next->kind == SK_ASSIGN &&
- X isescape(sp->next->exp1)))
- X thisreturn = sp->next;
- X else
- X thisreturn = NULL;
- X if (sp->serial >= 0)
- X curserial = sp->serial;
- X switch (sp->kind) {
- X
- X case SK_ASSIGN:
- X if (sp->exp1)
- X sp->exp1 = fixexpr(sp->exp1, ENV_STMT);
- X if (!sp->exp1)
- X intwarning("fixblock", "sp->exp1 == NULL in SK_ASSIGN");
- X if (!sp->exp1 || nosideeffects(sp->exp1, 1)) {
- X eatstmt(spp);
- X continue;
- X } else {
- X switch (sp->exp1->kind) {
- X
- X case EK_COND:
- X *spp = makestmt_if(sp->exp1->args[0],
- X makestmt_call(sp->exp1->args[1]),
- X makestmt_call(sp->exp1->args[2]));
- X (*spp)->next = sp->next;
- X continue; /* ... to fix this new if statement */
- X
- X case EK_ASSIGN:
- X if (sp->exp1->args[1]->kind == EK_COND && usecommas != 1) {
- X *spp = makestmt_if(sp->exp1->args[1]->args[0],
- X makestmt_assign(copyexpr(sp->exp1->args[0]),
- X sp->exp1->args[1]->args[1]),
- X makestmt_assign(sp->exp1->args[0],
- X sp->exp1->args[1]->args[2]));
- X (*spp)->next = sp->next;
- X continue;
- X }
- X if (isescape(sp->exp1->args[1])) {
- X sp->exp1 = grabarg(sp->exp1, 1);
- X continue;
- X }
- X if (exprsame(sp->exp1->args[0], sp->exp1->args[1], 1)) {
- X /* *spp = sp->next; */
- X sp->exp1 = grabarg(sp->exp1, 0);
- X continue;
- X }
- X if (sp->exp1->args[1]->kind == EK_BICALL) {
- X if (!strcmp(sp->exp1->args[1]->val.s,
- X getfbufname) &&
- X buildreads == 1 &&
- X sp->next &&
- X sp->next->kind == SK_ASSIGN &&
- X sp->next->exp1->kind == EK_BICALL &&
- X !strcmp(sp->next->exp1->val.s,
- X getname) &&
- X expr_has_address(sp->exp1->args[0]) &&
- X similartypes(sp->exp1->args[0]->val.type,
- X sp->exp1->args[1]->args[0]->val.type->basetype->basetype) &&
- X exprsame(sp->exp1->args[1]->args[0],
- X sp->next->exp1->args[0], 1)) {
- X eatstmt(&sp->next);
- X ex = makeexpr_bicall_4("fread", tp_integer,
- X makeexpr_addr(sp->exp1->args[0]),
- X makeexpr_sizeof(sp->exp1->args[1]->args[1], 0),
- X makeexpr_long(1),
- X sp->exp1->args[1]->args[0]);
- X FREE(sp->exp1);
- X sp->exp1 = ex;
- X continue;
- X }
- X if (!strcmp(sp->exp1->args[1]->val.s,
- X chargetfbufname) &&
- X buildreads != 0 &&
- X sp->next &&
- X sp->next->kind == SK_ASSIGN &&
- X sp->next->exp1->kind == EK_BICALL &&
- X !strcmp(sp->next->exp1->val.s,
- X chargetname) &&
- X expr_has_address(sp->exp1->args[0]) &&
- X exprsame(sp->exp1->args[1]->args[0],
- X sp->next->exp1->args[0], 1)) {
- X eatstmt(&sp->next);
- X strchange(&sp->exp1->args[1]->val.s,
- X "getc");
- X continue;
- X }
- X }
- X break;
- X
- X case EK_BICALL:
- X if (!strcmp(sp->exp1->val.s, name_ESCAPE)) {
- X if (fixexpr_tryblock) {
- X *spp = makestmt_assign(makeexpr_var(mp_escapecode),
- X grabarg(sp->exp1, 0));
- X (*spp)->next = makestmt(SK_GOTO);
- X (*spp)->next->exp1 = makeexpr_name(format_s(name_LABEL,
- X format_d("try%d",
- X fixexpr_tryblock)),
- X tp_integer);
- X (*spp)->next->next = sp->next;
- X fixexpr_tryflag = 1;
- X continue;
- X }
- X } else if (!strcmp(sp->exp1->val.s, name_ESCIO)) {
- X if (fixexpr_tryblock) {
- X *spp = makestmt_assign(makeexpr_var(mp_escapecode),
- X makeexpr_long(-10));
- X (*spp)->next = makestmt_assign(makeexpr_var(mp_ioresult),
- X grabarg(sp->exp1, 0));
- X (*spp)->next->next = makestmt(SK_GOTO);
- X (*spp)->next->next->exp1 = makeexpr_name(format_s(name_LABEL,
- X format_d("try%d",
- X fixexpr_tryblock)),
- X tp_integer);
- X (*spp)->next->next->next = sp->next;
- X fixexpr_tryflag = 1;
- X continue;
- X }
- X }
- X if (!strcmp(sp->exp1->val.s, putfbufname) &&
- X buildwrites == 1 &&
- X sp->next &&
- X sp->next->kind == SK_ASSIGN &&
- X sp->next->exp1->kind == EK_BICALL &&
- X !strcmp(sp->next->exp1->val.s,
- X putname) &&
- X exprsame(sp->exp1->args[0],
- X sp->next->exp1->args[0], 1)) {
- X eatstmt(&sp->next);
- X if (!expr_has_address(sp->exp1->args[2]) ||
- X sp->exp1->args[2]->val.type !=
- X sp->exp1->args[1]->val.type) {
- X tvar = maketempvar(sp->exp1->args[1]->val.type,
- X name_TEMP);
- X sp2 = makestmt_assign(makeexpr_var(tvar),
- X sp->exp1->args[2]);
- X sp2->next = sp;
- X *spp = sp2;
- X sp->exp1->args[2] = makeexpr_var(tvar);
- X freetempvar(tvar);
- X }
- X ex = makeexpr_bicall_4("fwrite", tp_integer,
- X makeexpr_addr(sp->exp1->args[2]),
- X makeexpr_sizeof(sp->exp1->args[1], 0),
- X makeexpr_long(1),
- X sp->exp1->args[0]);
- X FREE(sp->exp1);
- X sp->exp1 = ex;
- X continue;
- X }
- X if (!strcmp(sp->exp1->val.s, charputfbufname) &&
- X buildwrites != 0 &&
- X sp->next &&
- X sp->next->kind == SK_ASSIGN &&
- X sp->next->exp1->kind == EK_BICALL &&
- X !strcmp(sp->next->exp1->val.s,
- X charputname) &&
- X exprsame(sp->exp1->args[0],
- X sp->next->exp1->args[0], 1)) {
- X eatstmt(&sp->next);
- X swapexprs(sp->exp1->args[0],
- X sp->exp1->args[1]);
- X strchange(&sp->exp1->val.s, "putc");
- X continue;
- X }
- X if ((!strcmp(sp->exp1->val.s, resetbufname) ||
- X !strcmp(sp->exp1->val.s, setupbufname)) &&
- X (mp = isfilevar(sp->exp1->args[0])) != NULL &&
- X !mp->bufferedfile) {
- X eatstmt(spp);
- X continue;
- X }
- X ex = print_func(sp->exp1);
- X if (ex && sp->next && mixwritelns &&
- X sp->next->kind == SK_ASSIGN &&
- X exprsame(ex, print_func(sp->next->exp1), 1) &&
- X (printnl_func(sp->exp1) ||
- X printnl_func(sp->next->exp1))) {
- X sp->exp1 = mix_printf(sp->exp1,
- X sp->next->exp1);
- X eatstmt(&sp->next);
- X continue;
- X }
- X break;
- X
- X case EK_FUNCTION:
- X case EK_SPCALL:
- X case EK_POSTINC:
- X case EK_POSTDEC:
- X case EK_AND:
- X case EK_OR:
- X break;
- X
- X default:
- X spp2 = spp;
- X for (i = 0; i < sp->exp1->nargs; i++) {
- X *spp2 = makestmt_call(sp->exp1->args[i]);
- X spp2 = &(*spp2)->next;
- X }
- X *spp2 = sp->next;
- X continue; /* ... to fix these new statements */
- X
- X }
- X }
- X break;
- X
- X case SK_IF:
- X fixblock(&sp->stm1, thisreturn);
- X fixblock(&sp->stm2, thisreturn);
- X if (!sp->stm1) {
- X if (!sp->stm2) {
- X sp->kind = SK_ASSIGN;
- X continue;
- X } else {
- X if (sp->stm2->kind == SK_IF && sp->stm2->exp2) {
- X freeexpr(sp->stm2->exp2);
- X sp->stm2->exp2 = NULL;
- X }
- X sp->exp1 = makeexpr_not(sp->exp1); /* if (x) else foo => if (!x) foo */
- X swapstmts(sp->stm1, sp->stm2);
- X /* Ought to exchange comments for then/else parts */
- X }
- X }
- X /* At this point we know sp1 != NULL */
- X if (thisreturn) {
- X if (thisreturn->kind == SK_WHILE) {
- X if (usebreaks) {
- X sp1 = sp->stm1;
- X while (sp1->next)
- X sp1 = sp1->next;
- X if (sp->stm2) {
- X sp2 = sp->stm2;
- X while (sp2->next)
- X sp2 = sp2->next;
- X i = stmtcount(sp->stm1);
- X j = stmtcount(sp->stm2);
- X if (j >= breaklimit && i <= 2 && j > i*2 &&
- X ((implies(sp->exp1, thisreturn->exp1, 0, 1) &&
- X !checkexprchanged(sp->stm1, sp->exp1)) ||
- X (sp1->kind == SK_ASSIGN &&
- X implies(sp1->exp1, thisreturn->exp1, 0, 1)))) {
- X sp1->next = makestmt(SK_BREAK);
- X } else if (i >= breaklimit && j <= 2 && i > j*2 &&
- X ((implies(sp->exp1, thisreturn->exp1, 1, 1) &&
- X !checkexprchanged(sp->stm2, sp->exp1)) ||
- X (sp2->kind == SK_ASSIGN &&
- X implies(sp2->exp1, thisreturn->exp1, 0, 1)))) {
- X sp2->next = makestmt(SK_BREAK);
- X } else if (!checkconst(sp->exp2, 1)) {
- X /* not part of an else-if */
- X if (j >= continuelimit) {
- X sp1->next = makestmt(SK_CONTINUE);
- X } else if (i >= continuelimit) {
- X sp2->next = makestmt(SK_CONTINUE);
- X }
- X }
- X } else {
- X i = stmtcount(sp->stm1);
- X if (i >= breaklimit &&
- X implies(sp->exp1, thisreturn->exp1, 1, 1)) {
- X sp->exp1 = makeexpr_not(sp->exp1);
- X sp1->next = sp->next;
- X sp->next = sp->stm1;
- X sp->stm1 = makestmt(SK_BREAK);
- X } else if (i >= continuelimit) {
- X sp->exp1 = makeexpr_not(sp->exp1);
- X sp1->next = sp->next;
- X sp->next = sp->stm1;
- X sp->stm1 = makestmt(SK_CONTINUE);
- X }
- X }
- X }
- X } else {
- X if (usereturns) {
- X sp2 = sp->stm1;
- X while (sp2->next)
- X sp2 = sp2->next;
- X if (sp->stm2) {
- X /* if (x) foo; else bar; (return;) => if (x) {foo; return;} bar; */
- X if (stmtcount(sp->stm2) >= returnlimit) {
- X if (!deadendblock(sp->stm1))
- X sp2->next = copystmt(thisreturn);
- X } else if (stmtcount(sp->stm1) >= returnlimit) {
- X sp2 = sp->stm2;
- X while (sp2->next)
- X sp2 = sp2->next;
- X if (!deadendblock(sp->stm2))
- X sp2->next = copystmt(thisreturn);
- X }
- X } else { /* if (x) foo; (return;) => if (!x) return; foo; */
- X if (stmtcount(sp->stm1) >= returnlimit) {
- X sp->exp1 = makeexpr_not(sp->exp1);
- X sp2->next = sp->next;
- X sp->next = sp->stm1;
- X sp->stm1 = copystmt(thisreturn);
- X }
- X }
- X }
- X }
- X }
- X if (!checkconst(sp->exp2, 1)) { /* not part of an else-if */
- X de1 = deadendblock(sp->stm1);
- X de2 = deadendblock(sp->stm2);
- X if (de2 && !de1) {
- X sp->exp1 = makeexpr_not(sp->exp1);
- X swapstmts(sp->stm1, sp->stm2);
- X de1 = 1, de2 = 0;
- X }
- X if (de1 && !de2 && sp->stm2) {
- X if (sp->stm2->kind == SK_IF && sp->stm2->exp2) {
- X freeexpr(sp->stm2->exp2);
- X sp->stm2->exp2 = NULL;
- X }
- X for (sp2 = sp->stm2; sp2->next; sp2 = sp2->next) ;
- X sp2->next = sp->next;
- X sp->next = sp->stm2; /* if (x) ESCAPE else foo => if (x) ESCAPE; foo */
- X sp->stm2 = NULL;
- X }
- X }
- X sp->exp1 = fixexpr(sp->exp1, ENV_BOOL);
- X break;
- X
- X case SK_WHILE:
- X if (whilefgets && /* handle "while eof(f) do readln(f,...)" */
- X sp->stm1->kind == SK_ASSIGN &&
- X sp->stm1->exp1->kind == EK_BICALL &&
- X !strcmp(sp->stm1->exp1->val.s, "fgets") &&
- X nosideeffects(sp->stm1->exp1->args[0], 1) &&
- X nosideeffects(sp->stm1->exp1->args[1], 1) &&
- X nosideeffects(sp->stm1->exp1->args[2], 1)) {
- X if ((sp->exp1->kind == EK_NOT &&
- X sp->exp1->args[0]->kind == EK_BICALL && *eofname &&
- X !strcmp(sp->exp1->args[0]->val.s, eofname) &&
- X exprsame(sp->exp1->args[0]->args[0],
- X sp->stm1->exp1->args[2], 1)) ||
- X (sp->exp1->kind == EK_EQ &&
- X sp->exp1->args[0]->kind == EK_BICALL &&
- X !strcmp(sp->exp1->args[0]->val.s, "feof") &&
- X checkconst(sp->exp1->args[1], 0) &&
- X exprsame(sp->exp1->args[0]->args[0],
- X sp->stm1->exp1->args[2], 1))) {
- X sp->stm1->exp1->val.type = tp_strptr;
- X sp->exp1 = makeexpr_rel(EK_NE,
- X sp->stm1->exp1,
- X makeexpr_nil());
- X sp->stm1 = sp->stm1->next;
- X }
- X }
- X fixblock(&sp->stm1, sp);
- X sp->exp1 = fixexpr(sp->exp1, ENV_BOOL);
- X if (checkconst(sp->exp1, 1))
- X infiniteloop(sp);
- X break;
- X
- X case SK_REPEAT:
- X fixblock(&sp->stm1, NULL);
- X sp->exp1 = fixexpr(sp->exp1, ENV_BOOL);
- X if (checkconst(sp->exp1, 1))
- X infiniteloop(sp);
- X break;
- X
- X case SK_TRY:
- X save_tryblock = fixexpr_tryblock;
- X save_tryflag = fixexpr_tryflag;
- X fixexpr_tryblock = sp->exp1->val.i;
- X fixexpr_tryflag = 0;
- X fixblock(&sp->stm1, NULL);
- X if (fixexpr_tryflag)
- X sp->exp2 = makeexpr_long(1);
- X fixexpr_tryblock = save_tryblock;
- X fixexpr_tryflag = save_tryflag;
- X fixblock(&sp->stm2, NULL);
- X break;
- X
- X case SK_BODY:
- X fixblock(&sp->stm1, thisreturn);
- X break;
- X
- X case SK_CASE:
- X fixblock(&sp->stm1, NULL);
- X sp->exp1 = fixexpr(sp->exp1, ENV_EXPR);
- X if (!sp->stm1) { /* empty case */
- X sp->kind = SK_ASSIGN;
- X continue;
- X } else if (sp->stm1->kind != SK_CASELABEL) { /* default only */
- X for (sp2 = sp->stm1; sp2->next; sp2 = sp2->next) ;
- X sp2->next = sp->next;
- X sp->next = sp->stm1;
- X sp->kind = SK_ASSIGN;
- X sp->stm1 = NULL;
- X continue;
- X }
- X break;
- X
- X default:
- X fixblock(&sp->stm1, NULL);
- X fixblock(&sp->stm2, NULL);
- X sp->exp1 = fixexpr(sp->exp1, ENV_EXPR);
- X sp->exp2 = fixexpr(sp->exp2, ENV_EXPR);
- X sp->exp3 = fixexpr(sp->exp3, ENV_EXPR);
- X if (sp->next &&
- X (sp->kind == SK_GOTO ||
- X sp->kind == SK_BREAK ||
- X sp->kind == SK_CONTINUE ||
- X sp->kind == SK_RETURN) &&
- X !haslabels(sp->next)) {
- X if (elimdeadcode) {
- X note("Deleting unreachable code [255]");
- X while (sp->next && !haslabels(sp->next))
- X eatstmt(&sp->next);
- X } else {
- X note("Code is unreachable [256]");
- X }
- X } else if (sp->kind == SK_RETURN &&
- X thisreturn &&
- X thisreturn->kind == SK_RETURN &&
- X exprsame(sp->exp1, thisreturn->exp1, 1)) {
- X eatstmt(spp);
- X continue;
- X }
- X break;
- X }
- X spp = &sp->next;
- X }
- X saveserial = curserial;
- X}
- X
- X
- X
- X
- X/* Convert comma expressions into multiple statements */
- X
- XStatic int checkcomma_expr(spp, exp)
- XStmt **spp;
- XExpr **exp;
- X{
- X Stmt *sp;
- X Expr *ex = *exp;
- X int i, res;
- X
- X switch (ex->kind) {
- X
- X case EK_COMMA:
- X if (spp) {
- X res = checkcomma_expr(spp, &ex->args[ex->nargs-1]);
- X for (i = ex->nargs-1; --i >= 0; ) {
- X sp = makestmt(SK_ASSIGN);
- X sp->exp1 = ex->args[i];
- X sp->next = *spp;
- X *spp = sp;
- X res = checkcomma_expr(spp, &ex->args[i]);
- X }
- X *exp = ex->args[ex->nargs-1];
- X }
- X return 1;
- X
- X case EK_COND:
- X if (isescape(ex->args[1]) && spp &&
- X !isescape(ex->args[2])) {
- X swapexprs(ex->args[1], ex->args[2]);
- X ex->args[0] = makeexpr_not(ex->args[0]);
- X }
- X if (isescape(ex->args[2])) {
- X if (spp) {
- X res = checkcomma_expr(spp, &ex->args[1]);
- X if (ex->args[0]->kind == EK_ASSIGN) {
- X sp = makestmt(SK_ASSIGN);
- X sp->exp1 = copyexpr(ex->args[0]);
- X sp->next = makestmt(SK_IF);
- X sp->next->next = *spp;
- X *spp = sp;
- X res = checkcomma_expr(spp, &sp->exp1);
- X ex->args[0] = grabarg(ex->args[0], 0);
- X sp = sp->next;
- X } else {
- X sp = makestmt(SK_IF);
- X sp->next = *spp;
- X *spp = sp;
- X }
- X sp->exp1 = makeexpr_not(ex->args[0]);
- X sp->stm1 = makestmt(SK_ASSIGN);
- X sp->stm1->exp1 = eatcasts(ex->args[2]);
- X res = checkcomma_expr(&sp->stm1, &ex->args[2]);
- X res = checkcomma_expr(spp, &sp->exp1);
- X *exp = ex->args[1];
- X }
- X return 1;
- X }
- X return checkcomma_expr(spp, &ex->args[0]);
- X
- X case EK_AND:
- X case EK_OR:
- X return checkcomma_expr(spp, &ex->args[0]);
- X
- X default:
- X res = 0;
- X for (i = ex->nargs; --i >= 0; ) {
- X res += checkcomma_expr(spp, &ex->args[i]);
- X }
- X return res;
- X
- X }
- X}
- X
- X
- X
- XStatic void checkcommas(spp)
- XStmt **spp;
- X{
- X Stmt *sp;
- X int res;
- X
- X while ((sp = *spp)) {
- X checkcommas(&sp->stm1);
- X checkcommas(&sp->stm2);
- X switch (sp->kind) {
- X
- X case SK_ASSIGN:
- X case SK_IF:
- X case SK_CASE:
- X case SK_RETURN:
- X if (sp->exp1)
- X res = checkcomma_expr(spp, &sp->exp1);
- X break;
- X
- X case SK_WHILE:
- X /* handle the argument */
- X break;
- X
- X case SK_REPEAT:
- X /* handle the argument */
- X break;
- X
- X case SK_FOR:
- X if (sp->exp1)
- X res = checkcomma_expr(spp, &sp->exp1);
- X /* handle the other arguments */
- X break;
- X
- X default:
- X break;
- X }
- X spp = &sp->next;
- X }
- X}
- X
- X
- X
- X
- XStatic int checkvarchangeable(ex, mp)
- XExpr *ex;
- XMeaning *mp;
- X{
- X switch (ex->kind) {
- X
- X case EK_VAR:
- X return (mp == (Meaning *)ex->val.i);
- X
- X case EK_DOT:
- X case EK_INDEX:
- X return checkvarchangeable(ex->args[0], mp);
- X
- X default:
- X return 0;
- X }
- X}
- X
- X
- X
- Xint checkvarchangedexpr(ex, mp, addrokay)
- XExpr *ex;
- XMeaning *mp;
- Xint addrokay;
- X{
- X int i;
- X Meaning *mp3;
- X unsigned int safemask = 0;
- X
- X switch (ex->kind) {
- X
- X case EK_FUNCTION:
- X case EK_SPCALL:
- X if (ex->kind == EK_FUNCTION) {
- X i = 0;
- X mp3 = ((Meaning *)ex->val.i)->type->fbase;
- X } else {
- X i = 1;
- X if (ex->args[0]->val.type->kind != TK_PROCPTR)
- X return 1;
- X mp3 = ex->args[0]->val.type->basetype->fbase;
- X }
- X for ( ; i < ex->nargs && i < 16; i++) {
- X if (!mp3) {
- X intwarning("checkvarchangedexpr", "Too many arguments for EK_FUNCTION [266]");
- X break;
- X }
- X if (mp3->kind == MK_PARAM &&
- X (mp3->type->kind == TK_ARRAY ||
- X mp3->type->kind == TK_STRING ||
- X mp3->type->kind == TK_SET))
- X safemask |= 1<<i;
- X if (mp3->kind == MK_VARPARAM &&
- X mp3->type == tp_strptr && mp3->anyvarflag)
- X i++;
- X mp3 = mp3->xnext;
- X }
- X if (mp3)
- X intwarning("checkvarchangedexpr", "Too few arguments for EK_FUNCTION [267]");
- X break;
- X
- X case EK_VAR:
- X if (mp == (Meaning *)ex->val.i) {
- X if ((mp->type->kind == TK_ARRAY ||
- X mp->type->kind == TK_STRING ||
- X mp->type->kind == TK_SET) &&
- X ex->val.type->kind == TK_POINTER && !addrokay)
- X return 1; /* must be an implicit & */
- X }
- X break;
- X
- X case EK_ADDR:
- X case EK_ASSIGN:
- X case EK_POSTINC:
- X case EK_POSTDEC:
- X if (checkvarchangeable(ex->args[0], mp))
- X return 1;
- X break;
- X
- X case EK_BICALL:
- X if (structuredfunc(ex) && checkvarchangeable(ex->args[0], mp))
- X return 1;
- X safemask = safemask_bicall(ex->val.s);
- X break;
- X /* In case calls to these functions were lazy and passed
- X the array rather than its (implicit) address. Other
- X BICALLs had better be careful about their arguments. */
- X
- X case EK_PLUS:
- X if (addrokay) /* to keep from being scared by pointer */
- X safemask = ~0; /* arithmetic on string being passed */
- X break; /* to functions. */
- X
- X default:
- X break;
- X }
- X for (i = 0; i < ex->nargs; i++) {
- X if (checkvarchangedexpr(ex->args[i], mp, safemask&1))
- X return 1;
- X safemask >>= 1;
- X }
- X return 0;
- X}
- X
- X
- X
- Xint checkvarchanged(sp, mp)
- XStmt *sp;
- XMeaning *mp;
- X{
- X if (mp->constqual)
- X return 0;
- X if (mp->varstructflag || !mp->ctx || mp->ctx->kind != MK_FUNCTION ||
- X mp->volatilequal || alwayscopyvalues)
- X return 1;
- X while (sp) {
- X if (/* sp->kind == SK_GOTO || */
- X sp->kind == SK_LABEL ||
- X checkvarchanged(sp->stm1, mp) ||
- X checkvarchanged(sp->stm2, mp) ||
- X (sp->exp1 && checkvarchangedexpr(sp->exp1, mp, 1)) ||
- X (sp->exp2 && checkvarchangedexpr(sp->exp2, mp, 1)) ||
- X (sp->exp3 && checkvarchangedexpr(sp->exp3, mp, 1)))
- X return 1;
- X sp = sp->next;
- X }
- X return 0;
- X}
- X
- X
- X
- Xint checkexprchanged(sp, ex)
- XStmt *sp;
- XExpr *ex;
- X{
- X Meaning *mp;
- X int i;
- X
- X for (i = 0; i < ex->nargs; i++) {
- X if (checkexprchanged(sp, ex->args[i]))
- X return 1;
- X }
- X switch (ex->kind) {
- X
- X case EK_VAR:
- X mp = (Meaning *)ex->val.i;
- X if (mp->kind == MK_CONST)
- X return 0;
- X else
- X return checkvarchanged(sp, mp);
- X
- X case EK_HAT:
- X case EK_INDEX:
- X case EK_SPCALL:
- X return 1;
- X
- X case EK_FUNCTION:
- X case EK_BICALL:
- X return !nosideeffects_func(ex);
- X
- X default:
- X return 0;
- X }
- X}
- X
- X
- X
- X
- X
- X/* Check if a variable always occurs with a certain offset added, e.g. "i+1" */
- X
- XStatic int theoffset, numoffsets, numzerooffsets;
- X#define BadOffset (-999)
- X
- Xvoid checkvaroffsetexpr(ex, mp, myoffset)
- XExpr *ex;
- XMeaning *mp;
- Xint myoffset;
- X{
- X int i, nextoffset = 0;
- X Expr *ex2;
- X
- X if (!ex)
- X return;
- X switch (ex->kind) {
- X
- X case EK_VAR:
- X if (ex->val.i == (long)mp) {
- X if (myoffset == 0)
- X numzerooffsets++;
- X else if (numoffsets == 0 || myoffset == theoffset) {
- X theoffset = myoffset;
- X numoffsets++;
- X } else
- X theoffset = BadOffset;
- X }
- X break;
- X
- X case EK_PLUS:
- X ex2 = ex->args[ex->nargs-1];
- X if (ex2->kind == EK_CONST &&
- X ex2->val.type->kind == TK_INTEGER) {
- X nextoffset = ex2->val.i;
- X }
- X break;
- X
- X case EK_HAT:
- X case EK_POSTINC:
- X case EK_POSTDEC:
- X nextoffset = BadOffset;
- X break;
- X
- X case EK_ASSIGN:
- X checkvaroffsetexpr(ex->args[0], mp, BadOffset);
- X checkvaroffsetexpr(ex->args[1], mp, 0);
- X return;
- X
- X default:
- X break;
- X }
- X i = ex->nargs;
- X while (--i >= 0)
- X checkvaroffsetexpr(ex->args[i], mp, nextoffset);
- X}
- X
- X
- Xvoid checkvaroffsetstmt(sp, mp)
- XStmt *sp;
- XMeaning *mp;
- X{
- X while (sp) {
- X checkvaroffsetstmt(sp->stm1, mp);
- X checkvaroffsetstmt(sp->stm1, mp);
- X checkvaroffsetexpr(sp->exp1, mp, 0);
- X checkvaroffsetexpr(sp->exp2, mp, 0);
- X checkvaroffsetexpr(sp->exp3, mp, 0);
- X sp = sp->next;
- X }
- X}
- X
- X
- Xint checkvaroffset(sp, mp)
- XStmt *sp;
- XMeaning *mp;
- X{
- X if (mp->varstructflag || !mp->ctx || mp->ctx->kind != MK_FUNCTION)
- X return 0;
- X numoffsets = 0;
- X numzerooffsets = 0;
- X checkvaroffsetstmt(sp, mp);
- X if (numoffsets == 0 || theoffset == BadOffset ||
- X numoffsets <= numzerooffsets * 3)
- X return 0;
- X else
- X return theoffset;
- X}
- X
- X
- X
- X
- Xvoid initfilevars(mp, sppp, exbase)
- XMeaning *mp;
- XStmt ***sppp;
- XExpr *exbase;
- X{
- X Stmt *sp;
- X Type *tp;
- X Expr *ex;
- X
- X while (mp) {
- X if ((mp->kind == MK_VAR && mp->refcount > 0 && !mp->istemporary) ||
- X mp->kind == MK_FIELD) {
- X tp = mp->type;
- X if (isfiletype(tp)) {
- X mp->refcount++;
- X sp = makestmt(SK_ASSIGN);
- X sp->next = **sppp;
- X **sppp = sp;
- X if (exbase)
- X ex = makeexpr_dot(copyexpr(exbase), mp);
- X else
- X ex = makeexpr_var(mp);
- X sp->exp1 = makeexpr_assign(copyexpr(ex), makeexpr_nil());
- X } else if (tp->kind == TK_RECORD) {
- X if (exbase)
- X ex = makeexpr_dot(copyexpr(exbase), mp);
- X else
- X ex = makeexpr_var(mp);
- X initfilevars(tp->fbase, sppp, ex);
- X freeexpr(ex);
- X } else if (tp->kind == TK_ARRAY) {
- X while (tp->kind == TK_ARRAY)
- X tp = tp->basetype;
- X if (isfiletype(tp))
- X note(format_s("Array of files %s should be initialized [257]",
- X mp->name));
- X }
- X }
- X mp = mp->cnext;
- X }
- X}
- X
- X
- X
- X
- X
- XStatic Stmt *p_body()
- X{
- X Stmt *sp, **spp, *spbody, **sppbody, *spbase, *thereturn;
- X Meaning *mp;
- X Expr *ex;
- X int haspostamble;
- X long saveserial;
- X
- X if (verbose)
- X fprintf(logf, "%s, %d/%d: Translating %s (in %s)\n",
- X infname, inf_lnum, outf_lnum,
- X curctx->name, curctx->ctx->name);
- X notephase = 1;
- X spp = &spbase;
- X addstmt(SK_HEADER);
- X sp->exp1 = makeexpr_var(curctx);
- X checkkeyword(TOK_INLINE);
- X if (curtok != TOK_END && curtok != TOK_BEGIN && curtok != TOK_INLINE) {
- X if (curctx->kind == MK_FUNCTION || curctx->anyvarflag)
- X wexpecttok(TOK_BEGIN);
- X else
- X wexpecttok(TOK_END);
- X skiptotoken2(TOK_BEGIN, TOK_END);
- X }
- X if (curtok == TOK_END) {
- X gettok();
- X spbody = NULL;
- X } else {
- X spbody = p_stmt(NULL, SF_FUNC); /* parse the procedure/program body */
- X }
- X if (curtok == TOK_IDENT && curtokmeaning == curctx) {
- X gettok(); /* Modula-2 */
- X }
- X notephase = 2;
- X saveserial = curserial;
- X curserial = 10000;
- X if (curctx->kind == MK_FUNCTION) { /* handle copy parameters */
- X for (mp = curctx->type->fbase; mp; mp = mp->xnext) {
- X if (!mp->othername && mp->varstructflag) {
- X mp->othername = stralloc(format_s(name_COPYPAR, mp->name));
- X mp->rectype = mp->type;
- X addstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_assign(makeexpr_var(mp),
- X makeexpr_name(mp->othername, mp->rectype));
- X mp->refcount++;
- X } else if (mp->othername) {
- X if (checkvarchanged(spbody, mp)) {
- X addstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_assign(makeexpr_var(mp),
- X makeexpr_hat(makeexpr_name(mp->othername,
- X mp->rectype), 0));
- X mp->refcount++;
- X } else { /* don't need to copy it after all */
- X strchange(&mp->othername, mp->name);
- X ex = makeexpr_var(mp);
- X ex->val.type = mp->rectype;
- X replaceexpr(spbody, makeexpr_var(mp), makeexpr_hat(ex, 0));
- X }
- X }
- X }
- X }
- X for (mp = curctx->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_LABEL && mp->val.i) {
- X addstmt(SK_IF);
- X sp->exp1 = makeexpr_bicall_1("setjmp", tp_int,
- X makeexpr_var(mp->xnext));
- X sp->stm1 = makestmt(SK_GOTO);
- X sp->stm1->exp1 = makeexpr_name(format_s(name_LABEL, mp->name),
- X tp_integer);
- X }
- X }
- X *spp = spbody;
- X sppbody = spp;
- X while (*spp)
- X spp = &((*spp)->next);
- X haspostamble = 0;
- X initfilevars(curctx->cbase, &sppbody, NULL);
- X for (mp = curctx->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_VAR && mp->refcount > 0 && isfiletype(mp->type) &&
- X !mp->istemporary) {
- X if (curctx->kind != MK_MODULE || curctx->anyvarflag) {
- X addstmt(SK_IF); /* close file variables */
- X sp->exp1 = makeexpr_rel(EK_NE, makeexpr_var(mp), makeexpr_nil());
- X sp->stm1 = makestmt(SK_ASSIGN);
- X sp->stm1->exp1 = makeexpr_bicall_1("fclose", tp_void, makeexpr_var(mp));
- X }
- X haspostamble = 1;
- X }
- X }
- X thereturn = &bogusreturn;
- X if (curctx->kind == MK_FUNCTION && curctx->type->basetype != tp_void) {
- X if ((haspostamble || !checkreturns(&spbase, 1)) &&
- X curctx->cbase->refcount > 0) { /* add function return code */
- X addstmt(SK_RETURN);
- X sp->exp1 = makeexpr_var(curctx->cbase);
- X }
- X thereturn = NULL;
- X } else if (curctx->kind == MK_MODULE && curctx->anyvarflag) {
- X addstmt(SK_ASSIGN);
- X sp->exp1 = makeexpr_bicall_1("exit", tp_void, makeexpr_long(0));
- X thereturn = NULL;
- X }
- X if (debug>2) { fprintf(outf, "calling fixblock/usecommas on:\n"); dumpstmt(spbase, 5); }
- X curserial = saveserial;
- X sp = makestmt(SK_BODY);
- X sp->stm1 = spbase;
- X fixblock(&sp, thereturn); /* finishing touches to statements and expressions */
- X spbase = sp->stm1;
- X FREE(sp);
- X if (usecommas != 1)
- X checkcommas(&spbase); /* unroll ugly EK_COMMA and EK_COND expressions */
- X if (debug>1) { fprintf(outf, "p_body returns:\n"); dumpstmt(spbase, 5); }
- X notephase = 0;
- X return spbase;
- X}
- X
- X
- X
- X
- X#define checkWord() if (anywords) output(" "); anywords = 1
- X
- XStatic void out_function(func)
- XMeaning *func;
- X{
- X Meaning *mp;
- X Symbol *sym;
- X int opts, anywords, spacing, saveindent;
- X
- X if (func->varstructflag) {
- X makevarstruct(func);
- X }
- X if (collectnest) {
- X for (mp = func->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_FUNCTION && mp->isforward) {
- X forward_decl(mp, 0);
- X }
- X }
- X for (mp = func->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_FUNCTION && mp->type) {
- X pushctx(mp);
- X out_function(mp); /* generate the sub-procedures first */
- X popctx();
- X }
- X }
- X }
- X spacing = functionspace;
- X for (mp = func; mp->ctx->kind == MK_FUNCTION; mp = mp->ctx) {
- X if (spacing > minfuncspace)
- X spacing--;
- X }
- X outsection(spacing);
- X flushcomments(&func->comments, -1, 0);
- X if (usePPMacros == 1) {
- X forward_decl(func, 0);
- X outsection(minorspace);
- X }
- X opts = ODECL_HEADER;
- X anywords = 0;
- X if (func->namedfile) {
- X checkWord();
- X if (useAnyptrMacros || ansiC < 2)
- X output("Inline");
- X else
- X output("inline");
- X }
- X if (!func->exported) {
- X if (func->ctx->kind == MK_FUNCTION) {
- X if (useAnyptrMacros) {
- X checkWord();
- X output("Local");
- X } else if (use_static) {
- X checkWord();
- X output("static");
- X }
- X } else if ((findsymbol(func->name)->flags & NEEDSTATIC) ||
- X (use_static != 0 && !useAnyptrMacros)) {
- X checkWord();
- X output("static");
- X } else if (useAnyptrMacros) {
- X checkWord();
- X output("Static");
- X }
- X }
- X if (func->type->basetype != tp_void || ansiC != 0) {
- X checkWord();
- X outbasetype(func->type, 0);
- X }
- X if (anywords) {
- X if (newlinefunctions)
- X opts |= ODECL_FUNCTION;
- X else
- X output(" ");
- X }
- X outdeclarator(func->type, func->name, opts);
- X if (fullprototyping == 0) {
- X saveindent = outindent;
- X moreindent(argindent);
- X out_argdecls(func->type);
- X outindent = saveindent;
- X }
- X for (mp = func->type->fbase; mp; mp = mp->xnext) {
- X if (mp->othername && strcmp(mp->name, mp->othername))
- X mp->wasdeclared = 0; /* make sure we also declare the copy */
- X }
- X func->wasdeclared = 1;
- X outcontext = func;
- X out_block((Stmt *)func->val.i, BR_FUNCTION, 10000);
- X if (useundef) {
- X anywords = 0;
- X for (mp = func->cbase; mp; mp = mp->cnext) {
- X if (mp->kind == MK_CONST &&
- END_OF_FILE
- if test 49392 -ne `wc -c <'src/parse.c.2'`; then
- echo shar: \"'src/parse.c.2'\" unpacked with wrong size!
- fi
- # end of 'src/parse.c.2'
- fi
- echo shar: End of archive 30 \(of 32\).
- cp /dev/null ark30isdone
- 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
-