home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / p2c / part24 < prev    next >
Encoding:
Internet Message Format  |  1990-04-05  |  50.8 KB

  1. Subject:  v21i069:  Pascal to C translator, Part24/32
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: d5d5c7a5 18de3346 733250fa e68ad403
  5.  
  6. Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
  7. Posting-number: Volume 21, Issue 69
  8. Archive-name: p2c/part24
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 24 (of 32)."
  17. # Contents:  src/pexpr.c.2
  18. # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:47 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'src/pexpr.c.2' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'src/pexpr.c.2'\"
  22. else
  23. echo shar: Extracting \"'src/pexpr.c.2'\" \(48796 characters\)
  24. sed "s/^X//" >'src/pexpr.c.2' <<'END_OF_FILE'
  25. X                    ex = makeexpr_var(tvar);
  26. X                } else
  27. X                    ex3 = NULL;
  28. X                ex4 = copyexpr(ex);
  29. X                if (ex->kind == EK_CONST && smallsetconst)
  30. X                    ex = makesmallsetconst(1<<ex->val.i, ex2->val.type);
  31. X                else
  32. X                    ex = makeexpr_bin(EK_LSH, ex2->val.type,
  33. X                                      makeexpr_longcast(makeexpr_long(1), 1),
  34. X                                      enum_to_int(ex));
  35. X                ex = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, ex, ex2),
  36. X                                         makeexpr_long(0));
  37. X                if (*name_SETBITS ||
  38. X                    ((ex4->kind == EK_CONST) ? ((unsigned long)ex4->val.i >= setbits)
  39. X                                             : !(0 <= smin && smax < setbits))) {
  40. X                    ex = makeexpr_and(makeexpr_range(enum_to_int(ex4),
  41. X                                                     makeexpr_long(0),
  42. X                                                     makeexpr_setbits(), 0),
  43. X                                      ex);
  44. X                } else
  45. X                    freeexpr(ex4);
  46. X                ex = makeexpr_comma(ex3, ex);
  47. X                return ex;
  48. X            } else {
  49. X                ex3 = ex2;
  50. X                while (ex3->kind == EK_BICALL &&
  51. X                       (!strcmp(ex3->val.s, setaddname) ||
  52. X                        !strcmp(ex3->val.s, setaddrangename)))
  53. X                    ex3 = ex3->args[0];
  54. X                if (ex3->kind == EK_BICALL && !strcmp(ex3->val.s, setexpandname) &&
  55. X                    (tvar = istempvar(ex3->args[0])) != NULL && 
  56. X                    isconstexpr(ex3->args[1], &mask)) {
  57. X                    canceltempvar(tvar);
  58. X                    if (!nosideeffects(ex, 0)) {
  59. X                        tvar = makestmttempvar(ex->val.type, name_TEMP);
  60. X                        ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
  61. X                        ex = makeexpr_var(tvar);
  62. X                    } else
  63. X                        ex3 = NULL;
  64. X                    type = ord_type(ex2->val.type->indextype);
  65. X                    ex4 = NULL;
  66. X                    i = 0;
  67. X                    while (i < setbits) {
  68. X                        if (mask & (1<<i++)) {
  69. X                            if (i+1 < setbits && (mask & (2<<i))) {
  70. X                                for (j = i; j < setbits && (mask & (1<<j)); j++) ;
  71. X                                ex4 = makeexpr_or(ex4,
  72. X                                        makeexpr_range(copyexpr(ex),
  73. X                                                       makeexpr_val(make_ord(type, i-1)),
  74. X                                                       makeexpr_val(make_ord(type, j-1)), 1));
  75. X                                i = j;
  76. X                            } else {
  77. X                                ex4 = makeexpr_or(ex4,
  78. X                                        makeexpr_rel(EK_EQ, copyexpr(ex),
  79. X                                                            makeexpr_val(make_ord(type, i-1))));
  80. X                            }
  81. X                        }
  82. X                    }
  83. X                    mask = 0;
  84. X                    for (;;) {
  85. X                        if (!strcmp(ex2->val.s, setaddrangename)) {
  86. X                            if (checkconst(ex2->args[1], 'a') &&
  87. X                                checkconst(ex2->args[2], 'z')) {
  88. X                                mask |= 0x1;
  89. X                            } else if (checkconst(ex2->args[1], 'A') &&
  90. X                                       checkconst(ex2->args[2], 'Z')) {
  91. X                                mask |= 0x2;
  92. X                            } else if (checkconst(ex2->args[1], '0') &&
  93. X                                       checkconst(ex2->args[2], '9')) {
  94. X                                mask |= 0x4;
  95. X                            } else {
  96. X                                ex4 = makeexpr_or(ex4,
  97. X                                        makeexpr_range(copyexpr(ex), ex2->args[1], ex2->args[2], 1));
  98. X                            }
  99. X                        } else if (!strcmp(ex2->val.s, setaddname)) {
  100. X                            ex4 = makeexpr_or(ex4,
  101. X                                    makeexpr_rel(EK_EQ, copyexpr(ex), ex2->args[1]));
  102. X                        } else
  103. X                            break;
  104. X                        ex2 = ex2->args[0];
  105. X                    }
  106. X                    /* do these now so that EK_OR optimizations will work: */
  107. X                    if (mask & 0x1)
  108. X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  109. X                                                              makeexpr_char('a'),
  110. X                                                              makeexpr_char('z'), 1));
  111. X                    if (mask & 0x2)
  112. X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  113. X                                                              makeexpr_char('A'),
  114. X                                                              makeexpr_char('Z'), 1));
  115. X                    if (mask & 0x4)
  116. X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  117. X                                                              makeexpr_char('0'),
  118. X                                                              makeexpr_char('9'), 1));
  119. X                    freeexpr(ex);
  120. X                    return makeexpr_comma(ex3, ex4);
  121. X                }
  122. X                return makeexpr_bicall_2(setinname, tp_boolean,
  123. X                                         makeexpr_arglong(ex, 0), ex2);
  124. X            }
  125. X
  126. X    default:
  127. X        return ex;
  128. X    }
  129. X}
  130. X
  131. X
  132. X
  133. X
  134. X
  135. X
  136. X
  137. X/* Parse a C expression; used by VarMacro, etc. */
  138. X
  139. XType *nametotype(name)
  140. Xchar *name;
  141. X{
  142. X    if (!strcicmp(name, "malloc") ||
  143. X    !strcicmp(name, mallocname)) {
  144. X    return tp_anyptr;
  145. X    }
  146. X    return tp_integer;
  147. X}
  148. X
  149. X
  150. Xint istypespec()
  151. X{
  152. X    switch (curtok) {
  153. X
  154. X        case TOK_CONST:
  155. X            return 1;
  156. X
  157. X        case TOK_IDENT:
  158. X            return !strcmp(curtokcase, "volatile") ||
  159. X                   !strcmp(curtokcase, "void") ||
  160. X                   !strcmp(curtokcase, "char") ||
  161. X                   !strcmp(curtokcase, "short") ||
  162. X                   !strcmp(curtokcase, "int") ||
  163. X                   !strcmp(curtokcase, "long") ||
  164. X                   !strcmp(curtokcase, "float") ||
  165. X                   !strcmp(curtokcase, "double") ||
  166. X                   !strcmp(curtokcase, "signed") ||
  167. X                   !strcmp(curtokcase, "unsigned") ||
  168. X                   !strcmp(curtokcase, "struct") ||
  169. X                   !strcmp(curtokcase, "union") ||
  170. X                   !strcmp(curtokcase, "class") ||
  171. X                   !strcmp(curtokcase, "enum") ||
  172. X                   !strcmp(curtokcase, "typedef") ||
  173. X                   (curtokmeaning &&
  174. X                    curtokmeaning->kind == MK_TYPE);
  175. X
  176. X        default:
  177. X            return 0;
  178. X    }
  179. X}
  180. X
  181. X
  182. X
  183. XExpr *pc_parentype(cp)
  184. Xchar *cp;
  185. X{
  186. X    Expr *ex;
  187. X
  188. X    if (curtok == TOK_IDENT &&
  189. X         curtokmeaning &&
  190. X         curtokmeaning->kind == MK_TYPE) {
  191. X        ex = makeexpr_type(curtokmeaning->type);
  192. X        gettok();
  193. X        skipcloseparen();
  194. X    } else if (curtok == TOK_IDENT && !strcmp(curtokcase, "typedef")) {
  195. X        ex = makeexpr_name(getparenstr(inbufptr), tp_integer);
  196. X        gettok();
  197. X    } else {
  198. X        ex = makeexpr_name(getparenstr(cp), tp_integer);
  199. X        gettok();
  200. X    }
  201. X    return ex;
  202. X}
  203. X
  204. X
  205. X
  206. X
  207. XExpr *pc_expr2();
  208. X
  209. XExpr *pc_factor()
  210. X{
  211. X    Expr *ex;
  212. X    char *cp;
  213. X    Strlist *sl;
  214. X    int i;
  215. X
  216. X    switch (curtok) {
  217. X
  218. X        case TOK_BANG:
  219. X            gettok();
  220. X            return makeexpr_not(pc_expr2(14));
  221. X
  222. X        case TOK_TWIDDLE:
  223. X            gettok();
  224. X            return makeexpr_un(EK_BNOT, tp_integer, pc_expr2(14));
  225. X
  226. X        case TOK_PLPL:
  227. X            gettok();
  228. X            ex = pc_expr2(14);
  229. X            return makeexpr_assign(ex, makeexpr_plus(copyexpr(ex), makeexpr_long(1)));
  230. X
  231. X        case TOK_MIMI:
  232. X            gettok();
  233. X            ex = pc_expr2(14);
  234. X            return makeexpr_assign(ex, makeexpr_minus(copyexpr(ex), makeexpr_long(1)));
  235. X
  236. X        case TOK_STAR:
  237. X            gettok();
  238. X            ex = pc_expr2(14);
  239. X            if (ex->val.type->kind != TK_POINTER)
  240. X                ex->val.type = makepointertype(ex->val.type);
  241. X            return makeexpr_hat(ex, 0);
  242. X
  243. X        case TOK_AMP:
  244. X            gettok();
  245. X            return makeexpr_addr(pc_expr2(14));
  246. X
  247. X        case TOK_PLUS:
  248. X            gettok();
  249. X            return pc_expr2(14);
  250. X
  251. X        case TOK_MINUS:
  252. X            gettok();
  253. X            return makeexpr_neg(pc_expr2(14));
  254. X
  255. X        case TOK_LPAR:
  256. X            cp = inbufptr;
  257. X            gettok();
  258. X            if (istypespec()) {
  259. X                ex = pc_parentype(cp);
  260. X                return makeexpr_bin(EK_LITCAST, tp_integer, ex, pc_expr2(14));
  261. X            }
  262. X            ex = pc_expr();
  263. X            skipcloseparen();
  264. X            return ex;
  265. X
  266. X        case TOK_IDENT:
  267. X            if (!strcmp(curtokcase, "sizeof")) {
  268. X                gettok();
  269. X                if (curtok != TOK_LPAR)
  270. X                    return makeexpr_sizeof(pc_expr2(14), 1);
  271. X                cp = inbufptr;
  272. X                gettok();
  273. X                if (istypespec()) {
  274. X                    ex = makeexpr_sizeof(pc_parentype(cp), 1);
  275. X                } else {
  276. X                    ex = makeexpr_sizeof(pc_expr(), 1);
  277. X                    skipcloseparen();
  278. X                }
  279. X                return ex;
  280. X            }
  281. X            if (curtoksym->flags & FMACREC) {
  282. X                ex = makeexpr(EK_MACARG, 0);
  283. X                ex->val.type = tp_integer;
  284. X                ex->val.i = 0;
  285. X                for (sl = funcmacroargs, i = 1; sl; sl = sl->next, i++) {
  286. X                    if (sl->value == (long)curtoksym) {
  287. X                        ex->val.i = i;
  288. X                        break;
  289. X                    }
  290. X                }
  291. X            } else
  292. X                ex = makeexpr_name(curtokcase, nametotype(curtokcase));
  293. X            gettok();
  294. X            return ex;
  295. X
  296. X        case TOK_INTLIT:
  297. X            ex = makeexpr_long(curtokint);
  298. X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  299. X                ex = makeexpr_longcast(ex, 1);
  300. X            gettok();
  301. X            return ex;
  302. X
  303. X        case TOK_HEXLIT:
  304. X            ex = makeexpr_long(curtokint);
  305. X            insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  306. X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  307. X                ex = makeexpr_longcast(ex, 1);
  308. X            gettok();
  309. X            return ex;
  310. X
  311. X        case TOK_OCTLIT:
  312. X            ex = makeexpr_long(curtokint);
  313. X            insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
  314. X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  315. X                ex = makeexpr_longcast(ex, 1);
  316. X            gettok();
  317. X            return ex;
  318. X
  319. X        case TOK_REALLIT:
  320. X            ex = makeexpr_real(curtokbuf);
  321. X            gettok();
  322. X            return ex;
  323. X
  324. X        case TOK_STRLIT:
  325. X            ex = makeexpr_lstring(curtokbuf, curtokint);
  326. X            gettok();
  327. X            return ex;
  328. X
  329. X        case TOK_CHARLIT:
  330. X            ex = makeexpr_char(curtokint);
  331. X            gettok();
  332. X            return ex;
  333. X
  334. X        default:
  335. X        wexpected("a C expression");
  336. X        return makeexpr_long(0);
  337. X    }
  338. X}
  339. X
  340. X
  341. X
  342. X
  343. X#define pc_prec(pr)  if (prec > (pr)) return ex; gettok();
  344. X
  345. XExpr *pc_expr2(prec)
  346. Xint prec;
  347. X{
  348. X    Expr *ex, *ex2;
  349. X    int i;
  350. X
  351. X    ex = pc_factor();
  352. X    for (;;) {
  353. X        switch (curtok) {
  354. X
  355. X            case TOK_COMMA:
  356. X                pc_prec(1);
  357. X                ex = makeexpr_comma(ex, pc_expr2(2));
  358. X                break;
  359. X
  360. X            case TOK_EQ:
  361. X                pc_prec(2);
  362. X                ex = makeexpr_assign(ex, pc_expr2(2));
  363. X                break;
  364. X
  365. X            case TOK_QM:
  366. X                pc_prec(3);
  367. X                ex2 = pc_expr();
  368. X                if (wneedtok(TOK_COLON))
  369. X            ex = makeexpr_cond(ex, ex2, pc_expr2(3));
  370. X        else
  371. X            ex = makeexpr_cond(ex, ex2, makeexpr_long(0));
  372. X                break;
  373. X
  374. X            case TOK_OROR:
  375. X                pc_prec(4);
  376. X                ex = makeexpr_or(ex, pc_expr2(5));
  377. X                break;
  378. X
  379. X            case TOK_ANDAND:
  380. X                pc_prec(5);
  381. X                ex = makeexpr_and(ex, pc_expr2(6));
  382. X                break;
  383. X
  384. X            case TOK_VBAR:
  385. X                pc_prec(6);
  386. X                ex = makeexpr_bin(EK_BOR, tp_integer, ex, pc_expr2(7));
  387. X                break;
  388. X
  389. X            case TOK_HAT:
  390. X                pc_prec(7);
  391. X                ex = makeexpr_bin(EK_BXOR, tp_integer, ex, pc_expr2(8));
  392. X                break;
  393. X
  394. X            case TOK_AMP:
  395. X                pc_prec(8);
  396. X                ex = makeexpr_bin(EK_BAND, tp_integer, ex, pc_expr2(9));
  397. X                break;
  398. X
  399. X            case TOK_EQEQ:
  400. X                pc_prec(9);
  401. X                ex = makeexpr_rel(EK_EQ, ex, pc_expr2(10));
  402. X                break;
  403. X
  404. X            case TOK_BANGEQ:
  405. X                pc_prec(9);
  406. X                ex = makeexpr_rel(EK_NE, ex, pc_expr2(10));
  407. X                break;
  408. X
  409. X            case TOK_LT:
  410. X                pc_prec(10);
  411. X                ex = makeexpr_rel(EK_LT, ex, pc_expr2(11));
  412. X                break;
  413. X
  414. X            case TOK_LE:
  415. X                pc_prec(10);
  416. X                ex = makeexpr_rel(EK_LE, ex, pc_expr2(11));
  417. X                break;
  418. X
  419. X            case TOK_GT:
  420. X                pc_prec(10);
  421. X                ex = makeexpr_rel(EK_GT, ex, pc_expr2(11));
  422. X                break;
  423. X
  424. X            case TOK_GE:
  425. X                pc_prec(10);
  426. X                ex = makeexpr_rel(EK_GE, ex, pc_expr2(11));
  427. X                break;
  428. X
  429. X            case TOK_LTLT:
  430. X                pc_prec(11);
  431. X                ex = makeexpr_bin(EK_LSH, tp_integer, ex, pc_expr2(12));
  432. X                break;
  433. X
  434. X            case TOK_GTGT:
  435. X                pc_prec(11);
  436. X                ex = makeexpr_bin(EK_RSH, tp_integer, ex, pc_expr2(12));
  437. X                break;
  438. X
  439. X            case TOK_PLUS:
  440. X                pc_prec(12);
  441. X                ex = makeexpr_plus(ex, pc_expr2(13));
  442. X                break;
  443. X
  444. X            case TOK_MINUS:
  445. X                pc_prec(12);
  446. X                ex = makeexpr_minus(ex, pc_expr2(13));
  447. X                break;
  448. X
  449. X            case TOK_STAR:
  450. X                pc_prec(13);
  451. X                ex = makeexpr_times(ex, pc_expr2(14));
  452. X                break;
  453. X
  454. X            case TOK_SLASH:
  455. X                pc_prec(13);
  456. X                ex = makeexpr_div(ex, pc_expr2(14));
  457. X                break;
  458. X
  459. X            case TOK_PERC:
  460. X                pc_prec(13);
  461. X                ex = makeexpr_mod(ex, pc_expr2(14));
  462. X                break;
  463. X
  464. X            case TOK_PLPL:
  465. X                pc_prec(15);
  466. X                ex = makeexpr_un(EK_POSTINC, tp_integer, ex);
  467. X                break;
  468. X
  469. X            case TOK_MIMI:
  470. X                pc_prec(15);
  471. X                ex = makeexpr_un(EK_POSTDEC, tp_integer, ex);
  472. X                break;
  473. X
  474. X            case TOK_LPAR:
  475. X                pc_prec(16);
  476. X                if (ex->kind == EK_NAME) {
  477. X                    ex->kind = EK_BICALL;
  478. X                } else {
  479. X                    ex = makeexpr_un(EK_SPCALL, tp_integer, ex);
  480. X                }
  481. X                while (curtok != TOK_RPAR) {
  482. X                    insertarg(&ex, ex->nargs, pc_expr2(2));
  483. X                    if (curtok != TOK_RPAR)
  484. X                        if (!wneedtok(TOK_COMMA))
  485. X                skiptotoken2(TOK_RPAR, TOK_SEMI);
  486. X                }
  487. X                gettok();
  488. X                break;
  489. X
  490. X            case TOK_LBR:
  491. X                pc_prec(16);
  492. X                ex = makeexpr_index(ex, pc_expr(), NULL);
  493. X                if (!wneedtok(TOK_RBR))
  494. X            skippasttoken(TOK_RBR);
  495. X                break;
  496. X
  497. X            case TOK_ARROW:
  498. X                pc_prec(16);
  499. X                if (!wexpecttok(TOK_IDENT))
  500. X            break;
  501. X                if (ex->val.type->kind != TK_POINTER)
  502. X                    ex->val.type = makepointertype(ex->val.type);
  503. X                ex = makeexpr_dotq(makeexpr_hat(ex, 0),
  504. X                                   curtokcase, tp_integer);
  505. X                gettok();
  506. X                break;
  507. X
  508. X            case TOK_DOT:
  509. X                pc_prec(16);
  510. X                if (!wexpecttok(TOK_IDENT))
  511. X            break;
  512. X                ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  513. X                gettok();
  514. X                break;
  515. X
  516. X        case TOK_COLONCOLON:
  517. X        if (prec > 16)
  518. X            return ex;
  519. X        i = C_lex;
  520. X        C_lex = 0;
  521. X        gettok();
  522. X        if (curtok == TOK_IDENT &&
  523. X            curtokmeaning && curtokmeaning->kind == MK_TYPE) {
  524. X            ex->val.type = curtokmeaning->type;
  525. X        } else if (curtok == TOK_LPAR) {
  526. X            gettok();
  527. X            ex->val.type = p_type(NULL);
  528. X            if (!wexpecttok(TOK_RPAR))
  529. X            skiptotoken(TOK_RPAR);
  530. X        } else
  531. X            wexpected("a type name");
  532. X        C_lex = i;
  533. X        gettok();
  534. X        break;
  535. X
  536. X            default:
  537. X                return ex;
  538. X        }
  539. X    }
  540. X}
  541. X
  542. X
  543. X
  544. X
  545. XExpr *pc_expr()
  546. X{
  547. X    return pc_expr2(0);
  548. X}
  549. X
  550. X
  551. X
  552. XExpr *pc_expr_str(buf)
  553. Xchar *buf;
  554. X{
  555. X    Strlist *defsl, *sl;
  556. X    Expr *ex;
  557. X
  558. X    defsl = NULL;
  559. X    sl = strlist_append(&defsl, buf);
  560. X    C_lex++;
  561. X    push_input_strlist(defsl, buf);
  562. X    ex = pc_expr();
  563. X    if (curtok != TOK_EOF)
  564. X        warning(format_s("Junk (%s) at end of C expression [306]",
  565. X             tok_name(curtok)));
  566. X    pop_input();
  567. X    C_lex--;
  568. X    strlist_empty(&defsl);
  569. X    return ex;
  570. X}
  571. X
  572. X
  573. X
  574. X
  575. X
  576. X
  577. X/* Simplify an expression */
  578. X
  579. XExpr *fixexpr(ex, env)
  580. XExpr *ex;
  581. Xint env;
  582. X{
  583. X    Expr *ex2, *ex3, **ep;
  584. X    Type *type, *type2;
  585. X    Meaning *mp;
  586. X    char *cp;
  587. X    char sbuf[5];
  588. X    int i;
  589. X    Value val;
  590. X
  591. X    if (!ex)
  592. X        return NULL;
  593. X    switch (ex->kind) {
  594. X
  595. X        case EK_BICALL:
  596. X            ex2 = fix_bicall(ex, env);
  597. X            if (ex2) {
  598. X                ex = ex2;
  599. X                break;
  600. X            }
  601. X            cp = ex->val.s;
  602. X            if (!strcmp(cp, "strlen")) {
  603. X                if (ex->args[0]->kind == EK_BICALL &&
  604. X                    !strcmp(ex->args[0]->val.s, "sprintf") &&
  605. X                    sprintf_value == 0) {     /* does sprintf return char count? */
  606. X                    ex = grabarg(ex, 0);
  607. X                    strchange(&ex->val.s, "*sprintf");
  608. X                    ex = fixexpr(ex, env);
  609. X                } else {
  610. X                    ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  611. X                }
  612. X            } else if (!strcmp(cp, name_SETIO)) {
  613. X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  614. X            } else if (!strcmp(cp, "~~SETIO")) {
  615. X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  616. X                ex = makeexpr_cond(ex->args[0],
  617. X                                   makeexpr_long(0),
  618. X                                   makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]));
  619. X            } else if (!strcmp(cp, name_CHKIO)) {
  620. X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  621. X                ex->args[2] = fixexpr(ex->args[2], env);
  622. X                ex->args[3] = fixexpr(ex->args[3], env);
  623. X            } else if (!strcmp(cp, "~~CHKIO")) {
  624. X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  625. X                ex->args[2] = fixexpr(ex->args[2], env);
  626. X                ex->args[3] = fixexpr(ex->args[3], env);
  627. X                ex2 = makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]);
  628. X                if (ord_type(ex->args[3]->val.type)->kind != TK_INTEGER)
  629. X                    ex2 = makeexpr_cast(ex2, ex->args[3]->val.type);
  630. X                ex = makeexpr_cond(ex->args[0], ex->args[2], ex2);
  631. X            } else if (!strcmp(cp, "assert")) {
  632. X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  633. X            } else {
  634. X                for (i = 0; i < ex->nargs; i++)
  635. X                    ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  636. X        ex = cleansprintf(ex);
  637. X                if (!strcmp(cp, "sprintf")) {
  638. X                    if (checkstring(ex->args[1], "%s")) {
  639. X                        delfreearg(&ex, 1);
  640. X                        strchange(&ex->val.s, "strcpy");
  641. X                        ex = fixexpr(ex, env);
  642. X                    } else if (sprintf_value != 1 && env != ENV_STMT) {
  643. X                        if (*sprintfname) {
  644. X                            strchange(&ex->val.s, format_s("*%s", sprintfname));
  645. X                        } else {
  646. X                            strchange(&ex->val.s, "*sprintf");
  647. X                            ex = makeexpr_comma(ex, copyexpr(ex->args[0]));
  648. X                        }
  649. X                    }
  650. X                } else if (!strcmp(cp, "strcpy")) {
  651. X                    if (env == ENV_STMT &&
  652. X                         ex->args[1]->kind == EK_BICALL &&
  653. X                         !strcmp(ex->args[1]->val.s, "strcpy") &&
  654. X                         nosideeffects(ex->args[1]->args[0], 1)) {
  655. X                        ex2 = ex->args[1];
  656. X                        ex->args[1] = copyexpr(ex2->args[0]);
  657. X                        ex = makeexpr_comma(ex2, ex);
  658. X                    }
  659. X                } else if (!strcmp(cp, "memcpy")) {
  660. X                    strchange(&ex->val.s, format_s("*%s", memcpyname));
  661. X                    if (!strcmp(memcpyname, "*bcopy")) {
  662. X                        swapexprs(ex->args[0], ex->args[1]);
  663. X                        if (env != ENV_STMT)
  664. X                            ex = makeexpr_comma(ex, copyexpr(ex->args[1]));
  665. X                    }
  666. X        } else if (!strcmp(cp, setunionname) &&
  667. X               (ex3 = singlevar(ex->args[0])) != NULL &&
  668. X               ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
  669. X                (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
  670. X               !exproccurs(ex3, ex->args[3-i])) {
  671. X            ep = &ex->args[3-i];
  672. X            while ((ex2 = *ep)->kind == EK_BICALL &&
  673. X               (!strcmp(ex2->val.s, setaddname) ||
  674. X                !strcmp(ex2->val.s, setaddrangename)))
  675. X            ep = &ex2->args[0];
  676. X            if (ex2->kind == EK_BICALL &&
  677. X            !strcmp(ex2->val.s, setexpandname) &&
  678. X            checkconst(ex2->args[1], 0) &&
  679. X            (mp = istempvar(ex2->args[0])) != NULL) {
  680. X            if (ex2 == ex->args[3-i]) {
  681. X                ex = grabarg(ex, i);
  682. X            } else {
  683. X                freeexpr(ex2);
  684. X                *ep = ex->args[i];
  685. X                ex = ex->args[3-i];
  686. X            }
  687. X            }
  688. X        } else if (!strcmp(cp, setdiffname) && *setremname &&
  689. X               (ex3 = singlevar(ex->args[0])) != NULL &&
  690. X               exprsame(ex->args[0], ex->args[1], 0) &&
  691. X               !exproccurs(ex3, ex->args[2])) {
  692. X            ep = &ex->args[2];
  693. X            while ((ex2 = *ep)->kind == EK_BICALL &&
  694. X               !strcmp(ex2->val.s, setaddname))
  695. X            ep = &ex2->args[0];
  696. X            if (ex2->kind == EK_BICALL &&
  697. X            !strcmp(ex2->val.s, setexpandname) &&
  698. X            checkconst(ex2->args[1], 0) &&
  699. X            (mp = istempvar(ex2->args[0])) != NULL) {
  700. X            if (ex2 == ex->args[2]) {
  701. X                ex = grabarg(ex, 1);
  702. X            } else {
  703. X                ex2 = ex->args[2];
  704. X                while (ex2->kind == EK_BICALL &&
  705. X                   !strcmp(ex2->val.s, setaddname)) {
  706. X                strchange(&ex2->val.s, setremname);
  707. X                ex2 = ex2->args[0];
  708. X                }
  709. X                freeexpr(ex2);
  710. X                *ep = ex->args[1];
  711. X                ex = ex->args[2];
  712. X            }
  713. X            }
  714. X                } else if (!strcmp(cp, setexpandname) && env == ENV_STMT &&
  715. X                           checkconst(ex->args[1], 0)) {
  716. X                    ex = makeexpr_assign(makeexpr_hat(ex->args[0], 0),
  717. X                                         ex->args[1]);
  718. X                } else if (!strcmp(cp, getbitsname)) {
  719. X            type = ex->args[0]->val.type;
  720. X            if (type->kind == TK_POINTER)
  721. X            type = type->basetype;
  722. X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
  723. X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  724. X                    sbuf[2] = 0;
  725. X                    if (sbuf[1] == 'S' &&
  726. X                        type->smax->val.type == tp_boolean) {
  727. X                        ex = makeexpr_rel(EK_NE,
  728. X                                          makeexpr_bin(EK_BAND, tp_integer,
  729. X                                                       ex->args[0],
  730. X                                                       makeexpr_bin(EK_LSH, tp_integer,
  731. X                                                                    makeexpr_longcast(makeexpr_long(1),
  732. X                                                                                      type->basetype
  733. X                                                                                            == tp_unsigned),
  734. X                                                                    ex->args[1])),
  735. X                                          makeexpr_long(0));
  736. X                        ex = fixexpr(ex, env);
  737. X                    } else
  738. X                        strchange(&ex->val.s, format_s(cp, sbuf));
  739. X                } else if (!strcmp(cp, putbitsname)) {
  740. X            type = ex->args[0]->val.type;
  741. X            if (type->kind == TK_POINTER)
  742. X            type = type->basetype;
  743. X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
  744. X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  745. X                    sbuf[2] = 0;
  746. X                    if (sbuf[1] == 'S' &&
  747. X                        type->smax->val.type == tp_boolean) {
  748. X                        ex = makeexpr_assign(ex->args[0],
  749. X                                             makeexpr_bin(EK_BOR, tp_integer,
  750. X                                                          copyexpr(ex->args[0]),
  751. X                                                          makeexpr_bin(EK_LSH, tp_integer,
  752. X                                                                       makeexpr_longcast(ex->args[2],
  753. X                                                                                         type->basetype
  754. X                                                                                               == tp_unsigned),
  755. X                                                                       ex->args[1])));
  756. X                    } else
  757. X                        strchange(&ex->val.s, format_s(cp, sbuf));
  758. X                } else if (!strcmp(cp, storebitsname)) {
  759. X            type = ex->args[0]->val.type;
  760. X            if (type->kind == TK_POINTER)
  761. X            type = type->basetype;
  762. X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
  763. X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  764. X                    sbuf[2] = 0;
  765. X                    strchange(&ex->val.s, format_s(cp, sbuf));
  766. X                } else if (!strcmp(cp, clrbitsname)) {
  767. X            type = ex->args[0]->val.type;
  768. X            if (type->kind == TK_POINTER)
  769. X            type = type->basetype;
  770. X                    sbuf[0] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  771. X                    sbuf[1] = 0;
  772. X                    if (sbuf[0] == 'S' &&
  773. X                        type->smax->val.type == tp_boolean) {
  774. X                        ex = makeexpr_assign(ex->args[0],
  775. X                                             makeexpr_bin(EK_BAND, tp_integer,
  776. X                                                   copyexpr(ex->args[0]),
  777. X                                                   makeexpr_un(EK_BNOT, tp_integer,
  778. X                                                          makeexpr_bin(EK_LSH, tp_integer,
  779. X                                                                       makeexpr_longcast(makeexpr_long(1),
  780. X                                                                                         type->basetype
  781. X                                                                                               == tp_unsigned),
  782. X                                                                       ex->args[1]))));
  783. X                    } else
  784. X                        strchange(&ex->val.s, format_s(cp, sbuf));
  785. X                } else if (!strcmp(cp, "fopen")) {
  786. X            if (which_lang == LANG_HP &&
  787. X            ex->args[0]->kind == EK_CONST &&
  788. X            ex->args[0]->val.type->kind == TK_STRING &&
  789. X            ex->args[0]->val.i >= 1 &&
  790. X            ex->args[0]->val.i <= 2 &&
  791. X            isdigit(ex->args[0]->val.s[0]) &&
  792. X            (ex->args[0]->val.i == 1 ||
  793. X             isdigit(ex->args[0]->val.s[1]))) {
  794. X            strchange(&ex->val.s, "fdopen");
  795. X            ex->args[0] = makeexpr_long(atoi(ex->args[0]->val.s));
  796. X            }
  797. X        }
  798. X            }
  799. X            break;
  800. X
  801. X        case EK_NOT:
  802. X            ex = makeexpr_not(fixexpr(grabarg(ex, 0), ENV_BOOL));
  803. X            break;
  804. X
  805. X        case EK_AND:
  806. X        case EK_OR:
  807. X            for (i = 0; i < ex->nargs; i++)
  808. X                ex->args[i] = fixexpr(ex->args[i], ENV_BOOL);
  809. X            break;
  810. X
  811. X        case EK_EQ:
  812. X        case EK_NE:
  813. X            ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  814. X            ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  815. X            if (checkconst(ex->args[1], 0) && env == ENV_BOOL &&
  816. X                ord_type(ex->args[1]->val.type)->kind != TK_ENUM &&
  817. X                (implicitzero > 0 ||
  818. X                 (implicitzero < 0 && ex->args[0]->kind == EK_BICALL &&
  819. X                                      boolean_bicall(ex->args[0]->val.s)))) {
  820. X                if (ex->kind == EK_EQ)
  821. X                    ex = makeexpr_not(grabarg(ex, 0));
  822. X                else {
  823. X                    ex = grabarg(ex, 0);
  824. X                    ex->val.type = tp_boolean;
  825. X                }
  826. X            }
  827. X            break;
  828. X
  829. X        case EK_COND:
  830. X            ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  831. X#if 0
  832. X            val = eval_expr(ex->args[0]);
  833. X#else
  834. X        val = ex->args[0]->val;
  835. X        if (ex->args[0]->kind != EK_CONST)
  836. X        val.type = NULL;
  837. X#endif
  838. X            if (val.type == tp_boolean) {
  839. X                ex = grabarg(ex, (val.i) ? 1 : 2);
  840. X                ex = fixexpr(ex, env);
  841. X            } else {
  842. X                ex->args[1] = fixexpr(ex->args[1], env);
  843. X                ex->args[2] = fixexpr(ex->args[2], env);
  844. X            }
  845. X            break;
  846. X
  847. X        case EK_COMMA:
  848. X            for (i = 0; i < ex->nargs-1; ) {
  849. X                ex->args[i] = fixexpr(ex->args[i], ENV_STMT);
  850. X                if (nosideeffects(ex->args[i], 1))
  851. X                    delfreearg(&ex, i);
  852. X                else
  853. X                    i++;
  854. X            }
  855. X            ex->args[ex->nargs-1] = fixexpr(ex->args[ex->nargs-1], env);
  856. X            if (ex->nargs == 1)
  857. X                ex = grabarg(ex, 0);
  858. X            break;
  859. X
  860. X        case EK_CHECKNIL:
  861. X            ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  862. X            if (ex->nargs == 2) {
  863. X                ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  864. X                ex2 = makeexpr_assign(copyexpr(ex->args[1]), ex->args[0]);
  865. X                ex3 = ex->args[1];
  866. X            } else {
  867. X                ex2 = copyexpr(ex->args[0]);
  868. X                ex3 = ex->args[0];
  869. X            }
  870. X            type = ex->args[0]->val.type;
  871. X            type2 = ex->val.type;
  872. X            ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
  873. X                               ex3,
  874. X                               makeexpr_cast(makeexpr_bicall_0(name_NILCHECK,
  875. X                                                               tp_int),
  876. X                                             type));
  877. X            ex->val.type = type2;
  878. X            ex = fixexpr(ex, env);
  879. X            break;
  880. X
  881. X        case EK_CAST:
  882. X        case EK_ACTCAST:
  883. X            if (env == ENV_STMT) {
  884. X                ex = fixexpr(grabarg(ex, 0), ENV_STMT);
  885. X            } else {
  886. X                ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  887. X            }
  888. X            break;
  889. X
  890. X        default:
  891. X            for (i = 0; i < ex->nargs; i++)
  892. X                ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  893. X            break;
  894. X    }
  895. X    return fix_expression(ex, env);
  896. X}
  897. X
  898. X
  899. X
  900. X
  901. X
  902. X
  903. X
  904. X
  905. X/* Output an expression */
  906. X
  907. X
  908. X#define bitOp(k)  ((k)==EK_BAND || (k)==EK_BOR || (k)==EK_BXOR)
  909. X
  910. X#define shfOp(k)  ((k)==EK_LSH || (k)==EK_RSH)
  911. X
  912. X#define logOp(k)  ((k)==EK_AND || (k)==EK_OR)
  913. X
  914. X#define relOp(k)  ((k)==EK_EQ || (k)==EK_LT || (k)==EK_GT ||    \
  915. X           (k)==EK_NE || (k)==EK_GE || (k)==EK_LE)
  916. X
  917. X#define mathOp(k) ((k)==EK_PLUS || (k)==EK_TIMES || (k)==EK_NEG ||   \
  918. X           (k)==EK_DIV || (k)==EK_DIVIDE || (k)==EK_MOD)
  919. X
  920. X#define divOp(k)  ((k)==EK_DIV || (k)==EK_DIVIDE)
  921. X
  922. X
  923. XStatic int incompat(ex, num, prec)
  924. XExpr *ex;
  925. Xint num, prec;
  926. X{
  927. X    Expr *subex = ex->args[num];
  928. X
  929. X    if (extraparens == 0)
  930. X    return prec;
  931. X    if (ex->kind == subex->kind) {
  932. X    if (logOp(ex->kind) || bitOp(ex->kind) ||
  933. X        (divOp(ex->kind) && num == 0))
  934. X        return -99;   /* not even invisible parens */
  935. X    else if (extraparens != 2)
  936. X        return prec;
  937. X    }
  938. X    if (extraparens == 2)
  939. X    return 15;
  940. X    if (divOp(ex->kind) && num == 0 &&
  941. X    (subex->kind == EK_TIMES || divOp(subex->kind)))
  942. X    return -99;
  943. X    if (bitOp(ex->kind) || shfOp(ex->kind))
  944. X    return 15;
  945. X    if (relOp(ex->kind) && relOp(subex->kind))
  946. X    return 15;
  947. X    if ((relOp(ex->kind) || logOp(ex->kind)) && bitOp(subex->kind))
  948. X    return 15;
  949. X    if (ex->kind == EK_COMMA)
  950. X    return 15;
  951. X    if (ex->kind == EK_ASSIGN && relOp(subex->kind))
  952. X    return 15;
  953. X    if (extraparens != 1)
  954. X    return prec;
  955. X    if (ex->kind == EK_ASSIGN)
  956. X    return prec;
  957. X    if (relOp(ex->kind) && mathOp(subex->kind))
  958. X    return prec;
  959. X    return 15;
  960. X}
  961. X
  962. X
  963. X
  964. X
  965. X#define EXTRASPACE() if (spaceexprs == 1) output(" ")
  966. X#define NICESPACE()  if (spaceexprs != 0) output(" ")
  967. X
  968. X#define setprec(p) \
  969. X    if ((subprec=(p)) <= prec) { \
  970. X        parens = 1; output("("); \
  971. X    }
  972. X
  973. X#define setprec2(p) \
  974. X    if ((subprec=(p)) <= prec) { \
  975. X        parens = 1; output("("); \
  976. X    } else if (prec != -99) { \
  977. X        parens = 2; output((breakparens == 1) ? "\010" : "\003"); \
  978. X    }
  979. X
  980. X#define setprec3(p) \
  981. X    if ((subprec=(p)) <= prec) { \
  982. X         parens = 1; output("("); \
  983. X    } else if (prec != -99) { \
  984. X         parens = 2; output((prec > 2 && breakparens != 0) ? "\010" \
  985. X                                               : "\003"); \
  986. X    }
  987. X
  988. X
  989. XStatic void outop3(breakbefore, name)
  990. Xint breakbefore;
  991. Xchar *name;
  992. X{
  993. X    if (breakbefore & BRK_LEFT) {
  994. X    output("\002");
  995. X    if (breakbefore & BRK_RPREF)
  996. X        output("\013");
  997. X    }
  998. X    output(name);
  999. X    if (breakbefore & BRK_HANG)
  1000. X    output("\015");
  1001. X    if (breakbefore & BRK_RIGHT) {
  1002. X    output("\002");
  1003. X    if (breakbefore & BRK_LPREF)
  1004. X        output("\013");
  1005. X    }
  1006. X}
  1007. X
  1008. X#define outop(name) do { \
  1009. X    NICESPACE(); outop3(breakflag, name); NICESPACE(); \
  1010. X} while (0)
  1011. X
  1012. X#define outop2(name) do { \
  1013. X    EXTRASPACE(); outop3(breakflag, name); EXTRASPACE(); \
  1014. X} while (0)
  1015. X
  1016. X#define checkbreak(code) do { \
  1017. X    breakflag=(code); \
  1018. X    if ((prec != -99) && (breakflag & BRK_ALLNONE)) output("\007"); \
  1019. X} while (0)
  1020. X
  1021. X
  1022. XStatic void out_ctx(ctx, address)
  1023. XMeaning *ctx;
  1024. Xint address;
  1025. X{
  1026. X    Meaning *ctx2;
  1027. X    int breakflag = breakbeforedot;
  1028. X
  1029. X    if (ctx->kind == MK_FUNCTION && ctx->varstructflag) {
  1030. X        if (curctx != ctx) {
  1031. X        if (address && curctx->ctx && curctx->ctx != ctx) {
  1032. X        output("\003");
  1033. X        if (breakflag & BRK_ALLNONE)
  1034. X            output("\007");
  1035. X        }
  1036. X            output(format_s(name_LINK, curctx->ctx->name));
  1037. X            ctx2 = curctx->ctx;
  1038. X            while (ctx2 && ctx2 != ctx) {
  1039. X                outop2("->");
  1040. X                output(format_s(name_LINK, ctx2->ctx->name));
  1041. X                ctx2 = ctx2->ctx;
  1042. X            }
  1043. X            if (ctx2 != ctx)
  1044. X                intwarning("out_ctx",
  1045. X                           format_s("variable from %s not present in context path [307]",
  1046. X                                     ctx->name));
  1047. X        if (address && curctx->ctx && curctx->ctx != ctx)
  1048. X        output("\004");
  1049. X            if (!address)
  1050. X                outop2("->");
  1051. X        } else {
  1052. X            if (address) {
  1053. X                output("&");
  1054. X        EXTRASPACE();
  1055. X        }
  1056. X            output(format_s(name_VARS, curctx->name));
  1057. X            if (!address) {
  1058. X                outop2(".");
  1059. X        }
  1060. X        }
  1061. X    } else {
  1062. X        if (address)
  1063. X            output("NULL");
  1064. X    }
  1065. X}
  1066. X
  1067. X
  1068. X
  1069. Xvoid out_var(mp, prec)
  1070. XMeaning *mp;
  1071. Xint prec;
  1072. X{
  1073. X    switch (mp->kind) {
  1074. X
  1075. X        case MK_CONST:
  1076. X            output(mp->name);
  1077. X            return;
  1078. X
  1079. X        case MK_VAR:
  1080. X        case MK_VARREF:
  1081. X        case MK_VARMAC:
  1082. X        case MK_PARAM:
  1083. X        case MK_VARPARAM:
  1084. X            if (mp->varstructflag) {
  1085. X        output("\003");
  1086. X                out_ctx(mp->ctx, 0);
  1087. X        output(mp->name);
  1088. X        output("\004");
  1089. X        } else
  1090. X        output(mp->name);
  1091. X            return;
  1092. X
  1093. X    default:
  1094. X        if (mp->name)
  1095. X        output(mp->name);
  1096. X        else
  1097. X        intwarning("out_var", "mp->sym == NULL [308]");
  1098. X        return;
  1099. X    }
  1100. X}
  1101. X
  1102. X
  1103. X
  1104. XStatic int scanfield(variants, unions, lev, mp, field)
  1105. XMeaning **variants, *mp, *field;
  1106. Xshort *unions;
  1107. Xint lev;
  1108. X{
  1109. X    int i, num, breakflag;
  1110. X    Value v;
  1111. X
  1112. X    unions[lev] = (mp && mp->kind == MK_VARIANT);
  1113. X    while (mp && mp->kind == MK_FIELD) {
  1114. X        if (mp == field) {
  1115. X            for (i = 0; i < lev; i++) {
  1116. X        v = variants[i]->val;    /* sidestep a Sun 386i compiler bug */
  1117. X                num = ord_value(v);
  1118. X        breakflag = breakbeforedot;
  1119. X                if (!unions[i]) {
  1120. X                    output(format_s(name_UNION, ""));
  1121. X            outop2(".");
  1122. X                }
  1123. X                if (variants[i]->ctx->cnext ||
  1124. X                    variants[i]->ctx->kind != MK_FIELD) {
  1125. X                    output(format_s(name_VARIANT, variantfieldname(num)));
  1126. X            outop2(".");
  1127. X                }
  1128. X            }
  1129. X            output(mp->name);
  1130. X            return 1;
  1131. X        }
  1132. X        mp = mp->cnext;
  1133. X    }
  1134. X    while (mp && mp->kind == MK_VARIANT) {
  1135. X        variants[lev] = mp;
  1136. X        if (scanfield(variants, unions, lev+1, mp->ctx, field))
  1137. X            return 1;
  1138. X        mp = mp->cnext;
  1139. X    }
  1140. X    return 0;
  1141. X}
  1142. X
  1143. X
  1144. Xvoid out_field(mp)
  1145. XMeaning *mp;
  1146. X{
  1147. X    Meaning *variants[50];
  1148. X    short unions[51];
  1149. X
  1150. X    if (!scanfield(variants, unions, 0, mp->rectype->fbase, mp))
  1151. X        intwarning("out_field", "field name not in tree [309]");
  1152. X    else if (mp->warnifused) {
  1153. X        if (mp->rectype->meaning)
  1154. X            note(format_ss("Reference to field %s of record %s [282]", 
  1155. X                           mp->name, mp->rectype->meaning->name));
  1156. X        else
  1157. X            note(format_s("Reference to field %s [282]", mp->name));
  1158. X    }
  1159. X}
  1160. X
  1161. X
  1162. X
  1163. X
  1164. XStatic void wrexpr(ex, prec)
  1165. XExpr *ex;
  1166. Xint prec;
  1167. X{
  1168. X    short parens = 0;
  1169. X    int subprec, i, j, minusflag, breakflag = 0;
  1170. X    int saveindent;
  1171. X    Expr *ex2, *ex3;
  1172. X    char *cp;
  1173. X    Meaning *mp;
  1174. X    Symbol *sp;
  1175. X
  1176. X    if (debug>2) { fprintf(outf,"wrexpr{"); dumpexpr(ex); fprintf(outf,", %d}\n", prec); }
  1177. X    switch (ex->kind) {
  1178. X
  1179. X        case EK_VAR:
  1180. X            mp = (Meaning *)ex->val.i;
  1181. X            if (mp->warnifused)
  1182. X                note(format_s("Reference to %s [283]", mp->name));
  1183. X            out_var(mp, prec);
  1184. X            break;
  1185. X
  1186. X        case EK_NAME:
  1187. X            output(ex->val.s);
  1188. X            break;
  1189. X
  1190. X        case EK_MACARG:
  1191. X            output("<meef>");
  1192. X            intwarning("wrexpr", "Stray EK_MACARG encountered [310]");
  1193. X            break;
  1194. X
  1195. X        case EK_CTX:
  1196. X            out_ctx((Meaning *)ex->val.i, 1);
  1197. X            break;
  1198. X
  1199. X        case EK_CONST:
  1200. X            if (ex->nargs > 0)
  1201. X                cp = value_name(ex->val, ex->args[0]->val.s, 0);
  1202. X            else
  1203. X                cp = value_name(ex->val, NULL, 0);
  1204. X            if (*cp == '-')
  1205. X                setprec(14);
  1206. X            output(cp);
  1207. X            break;
  1208. X
  1209. X        case EK_LONGCONST:
  1210. X            if (ex->nargs > 0)
  1211. X                cp = value_name(ex->val, ex->args[0]->val.s, 1);
  1212. X            else
  1213. X                cp = value_name(ex->val, NULL, 1);
  1214. X            if (*cp == '-')
  1215. X                setprec(14);
  1216. X            output(cp);
  1217. X            break;
  1218. X
  1219. X        case EK_STRUCTCONST:
  1220. X            ex3 = NULL;
  1221. X            for (i = 0; i < ex->nargs; i++) {
  1222. X                ex2 = ex->args[i];
  1223. X                if (ex2->kind == EK_STRUCTOF) {
  1224. X                    j = ex2->val.i;
  1225. X                    ex2 = ex2->args[0];
  1226. X                } else
  1227. X                    j = 1;
  1228. X                if (ex2->kind == EK_VAR) {
  1229. X                    mp = (Meaning *)ex2->val.i;
  1230. X                    if (mp->kind == MK_CONST &&
  1231. X                        (mp->val.type->kind == TK_RECORD ||
  1232. X                         mp->val.type->kind == TK_ARRAY)) {
  1233. X                        if (foldconsts != 1)
  1234. X                            note(format_s("Expanding constant %s into another constant [284]",
  1235. X                                          mp->name));
  1236. X                        ex2 = (Expr *)mp->val.i;
  1237. X                    }
  1238. X                }
  1239. X                while (--j >= 0) {
  1240. X                    if (ex3) {
  1241. X                        if (ex3->kind == EK_STRUCTCONST ||
  1242. X                            ex2->kind == EK_STRUCTCONST)
  1243. X                            output(",\n");
  1244. X                        else
  1245. X                            output(",\001 ");
  1246. X                    }
  1247. X                    if (ex2->kind == EK_STRUCTCONST) {
  1248. X                        output("{ \005");
  1249. X            saveindent = outindent;
  1250. X            moreindent(extrainitindent);
  1251. X                        out_expr(ex2);
  1252. X                        outindent = saveindent;
  1253. X                        output(" }");
  1254. X                    } else
  1255. X                        out_expr(ex2);
  1256. X                    ex3 = ex2;
  1257. X                }
  1258. X            }
  1259. X            break;
  1260. X
  1261. X        case EK_FUNCTION:
  1262. X            mp = (Meaning *)ex->val.i;
  1263. X        sp = findsymbol_opt(mp->name);
  1264. X        if ((sp && (sp->flags & WARNLIBR)) || mp->warnifused)
  1265. X                note(format_s("Called procedure %s [285]", mp->name));
  1266. X            output(mp->name);
  1267. X            output("(\002");
  1268. X        j = sp ? (sp->flags & FUNCBREAK) : 0;
  1269. X        if (j == FALLBREAK)
  1270. X        output("\007");
  1271. X            for (i = 0; i < ex->nargs; i++) {
  1272. X        if ((j == FSPCARG1 && i == 1) ||
  1273. X            (j == FSPCARG2 && i == 2) ||
  1274. X            (j == FSPCARG3 && i == 3))
  1275. X            output(",\011 ");
  1276. X                else if (i > 0)
  1277. X                    output(",\002 ");
  1278. X                out_expr(ex->args[i]);
  1279. X            }
  1280. X            if (mp->ctx->kind == MK_FUNCTION && mp->ctx->varstructflag) {
  1281. X                if (i > 0)
  1282. X                    output(",\002 ");
  1283. X                out_ctx(mp->ctx, 1);
  1284. X            }
  1285. X            output(")");
  1286. X            break;
  1287. X
  1288. X        case EK_BICALL:
  1289. X            cp = ex->val.s;
  1290. X            while (*cp == '*')
  1291. X                cp++;
  1292. X        sp = findsymbol_opt(cp);
  1293. X        if (sp && (sp->flags & WARNLIBR))
  1294. X                note(format_s("Called library procedure %s [286]", cp));
  1295. X            output(cp);
  1296. X            output("(\002");
  1297. X        j = sp ? (sp->flags & FUNCBREAK) : 0;
  1298. X        if (j == FALLBREAK)
  1299. X        output("\007");
  1300. X            for (i = 0; i < ex->nargs; i++) {
  1301. X        if ((j == FSPCARG1 && i == 1) ||
  1302. X            (j == FSPCARG2 && i == 2) ||
  1303. X            (j == FSPCARG3 && i == 3))
  1304. X            output(",\011 ");
  1305. X                else if (i > 0)
  1306. X                    output(",\002 ");
  1307. X                out_expr(ex->args[i]);
  1308. X            }
  1309. X            output(")");
  1310. X            break;
  1311. X
  1312. X        case EK_SPCALL:
  1313. X            setprec(16);
  1314. X            if (starfunctions) {
  1315. X                output("(\002*");
  1316. X                wrexpr(ex->args[0], 13);
  1317. X                output(")");
  1318. X            } else
  1319. X                wrexpr(ex->args[0], subprec-1);
  1320. X            output("(\002");
  1321. X            for (i = 1; i < ex->nargs; i++) {
  1322. X                if (i > 1)
  1323. X                    output(",\002 ");
  1324. X                out_expr(ex->args[i]);
  1325. X            }
  1326. X            output(")");
  1327. X            break;
  1328. X
  1329. X        case EK_INDEX:
  1330. X            setprec(16);
  1331. X            wrexpr(ex->args[0], subprec-1);
  1332. X        if (lookback(1) == ']')
  1333. X        output("\001");
  1334. X            output("[");
  1335. X            out_expr(ex->args[1]);
  1336. X            output("]");
  1337. X            break;
  1338. X
  1339. X        case EK_DOT:
  1340. X            setprec2(16);
  1341. X        checkbreak(breakbeforedot);
  1342. X            if (ex->args[0]->kind == EK_HAT) {
  1343. X                wrexpr(ex->args[0]->args[0], subprec-1);
  1344. X                outop2("->");
  1345. X            } else if (ex->args[0]->kind == EK_CTX) {
  1346. X                out_ctx((Meaning *)ex->args[0]->val.i, 0);
  1347. X            } else {
  1348. X                wrexpr(ex->args[0], subprec-1);
  1349. X                outop2(".");
  1350. X            }
  1351. X            if (ex->val.i)
  1352. X                out_field((Meaning *)ex->val.i);
  1353. X            else
  1354. X                output(ex->val.s);
  1355. X            break;
  1356. X
  1357. X        case EK_POSTINC:
  1358. X        if (prec == 0 && !postincrement) {
  1359. X        setprec(14);
  1360. X        output("++");
  1361. X        EXTRASPACE();
  1362. X        wrexpr(ex->args[0], subprec);
  1363. X        } else {
  1364. X        setprec(15);
  1365. X        wrexpr(ex->args[0], subprec);
  1366. X        EXTRASPACE();
  1367. X        output("++");
  1368. X        }
  1369. X            break;
  1370. X
  1371. X        case EK_POSTDEC:
  1372. X        if (prec == 0 && !postincrement) {
  1373. X        setprec(14);
  1374. X        output("--");
  1375. X        EXTRASPACE();
  1376. X        wrexpr(ex->args[0], subprec);
  1377. X        } else {
  1378. X        setprec(15);
  1379. X        wrexpr(ex->args[0], subprec);
  1380. X        EXTRASPACE();
  1381. X        output("--");
  1382. X        }
  1383. X            break;
  1384. X
  1385. X        case EK_HAT:
  1386. X            setprec(14);
  1387. X        if (lookback_prn(1) == '/')
  1388. X        output(" ");
  1389. X            output("*");
  1390. X            EXTRASPACE();
  1391. X            wrexpr(ex->args[0], subprec-1);
  1392. X            break;
  1393. X
  1394. X        case EK_ADDR:
  1395. X            setprec(14);
  1396. X        if (lookback_prn(1) == '&')
  1397. X        output(" ");
  1398. X            output("&");
  1399. X            EXTRASPACE();
  1400. X            wrexpr(ex->args[0], subprec-1);
  1401. X            break;
  1402. X
  1403. X        case EK_NEG:
  1404. X            setprec(14);
  1405. X            output("-");
  1406. X            EXTRASPACE();
  1407. X            if (ex->args[0]->kind == EK_TIMES)
  1408. X                wrexpr(ex->args[0], 12);
  1409. X            else
  1410. X                wrexpr(ex->args[0], subprec-1);
  1411. X            break;
  1412. X
  1413. X        case EK_NOT:
  1414. X            setprec(14);
  1415. X            output("!");
  1416. X            EXTRASPACE();
  1417. X            wrexpr(ex->args[0], subprec-1);
  1418. X            break;
  1419. X
  1420. X        case EK_BNOT:
  1421. X            setprec(14);
  1422. X            output("~");
  1423. X            EXTRASPACE();
  1424. X            wrexpr(ex->args[0], subprec-1);
  1425. X            break;
  1426. X
  1427. X        case EK_CAST:
  1428. X        case EK_ACTCAST:
  1429. X            if (similartypes(ex->val.type, ex->args[0]->val.type)) {
  1430. X                wrexpr(ex->args[0], prec);
  1431. X            } else if (ord_type(ex->args[0]->val.type)->kind == TK_ENUM &&
  1432. X                       ex->val.type == tp_int && !useenum) {
  1433. X                wrexpr(ex->args[0], prec);
  1434. X            } else {
  1435. X                setprec2(14);
  1436. X                output("(");
  1437. X                out_type(ex->val.type, 0);
  1438. X                output(")\002");
  1439. X                EXTRASPACE();
  1440. X                if (extraparens != 0)
  1441. X                    wrexpr(ex->args[0], 15);
  1442. X                else
  1443. X                    wrexpr(ex->args[0], subprec-1);
  1444. X            }
  1445. X            break;
  1446. X
  1447. X        case EK_LITCAST:
  1448. X            setprec2(14);
  1449. X            output("(");
  1450. X            out_expr(ex->args[0]);
  1451. X            output(")\002");
  1452. X            EXTRASPACE();
  1453. X            if (extraparens != 0)
  1454. X                wrexpr(ex->args[1], 15);
  1455. X            else
  1456. X                wrexpr(ex->args[1], subprec-1);
  1457. X            break;
  1458. X
  1459. X        case EK_SIZEOF:
  1460. X            setprec(14);
  1461. X            output("sizeof(");
  1462. X        out_expr(ex->args[0]);
  1463. X            output(")");
  1464. X            break;
  1465. X
  1466. X    case EK_TYPENAME:
  1467. X        out_type(ex->val.type, 1);
  1468. X        break;
  1469. X
  1470. X        case EK_TIMES:
  1471. X        setprec2(13);
  1472. X        checkbreak(breakbeforearith);
  1473. X            ex2 = copyexpr(ex);
  1474. X            if (expr_looks_neg(ex2->args[ex2->nargs-1])) {
  1475. X                ex2->args[0] = makeexpr_neg(ex2->args[0]);
  1476. X                ex2->args[ex2->nargs-1] = makeexpr_neg(ex2->args[ex2->nargs-1]);
  1477. X            }
  1478. X            wrexpr(ex2->args[0], incompat(ex2, 0, subprec-1));
  1479. X            for (i = 1; i < ex2->nargs; i++) {
  1480. X                outop("*");
  1481. X                wrexpr(ex2->args[i], incompat(ex2, i, subprec));
  1482. X            }
  1483. X            freeexpr(ex2);
  1484. X            break;
  1485. X
  1486. X        case EK_DIV:
  1487. X        case EK_DIVIDE:
  1488. X            setprec2(13);
  1489. X        checkbreak(breakbeforearith);
  1490. X        wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  1491. X            outop("/");
  1492. X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1493. X            break;
  1494. X
  1495. X        case EK_MOD:
  1496. X            setprec2(13);
  1497. X        checkbreak(breakbeforearith);
  1498. X            wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  1499. X            outop("%");
  1500. X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1501. X            break;
  1502. X
  1503. X        case EK_PLUS:
  1504. X            setprec2(12);
  1505. X        checkbreak(breakbeforearith);
  1506. X            ex2 = copyexpr(ex);
  1507. X            minusflag = 0;
  1508. X            if (expr_looks_neg(ex2->args[0])) {
  1509. X                j = 1;
  1510. X                while (j < ex2->nargs && expr_looks_neg(ex2->args[j])) j++;
  1511. X                if (j < ex2->nargs)
  1512. X                    swapexprs(ex2->args[0], ex2->args[j]);
  1513. X            } else if (ex2->val.i && ex2->nargs == 2) {   /* this was originally "a-b" */
  1514. X                if (isliteralconst(ex2->args[1], NULL) != 2) {
  1515. X                    if (expr_neg_cost(ex2->args[1]) <= 0) {
  1516. X                        minusflag = 1;
  1517. X                    } else if (expr_neg_cost(ex2->args[0]) <= 0) {
  1518. X                        swapexprs(ex2->args[0], ex2->args[1]);
  1519. X                        if (isliteralconst(ex2->args[0], NULL) != 2)
  1520. X                            minusflag = 1;
  1521. X                    }
  1522. X                }
  1523. X            }
  1524. X            wrexpr(ex2->args[0], incompat(ex, 0, subprec));
  1525. X            for (i = 1; i < ex2->nargs; i++) {
  1526. X                if (expr_looks_neg(ex2->args[i]) || minusflag) {
  1527. X                    outop("-");
  1528. X                    ex2->args[i] = makeexpr_neg(ex2->args[i]);
  1529. X                } else
  1530. X                    outop("+");
  1531. X                wrexpr(ex2->args[i], incompat(ex, i, subprec));
  1532. X            }
  1533. X            freeexpr(ex2);
  1534. X            break;
  1535. X
  1536. X        case EK_LSH:
  1537. X            setprec3(11);
  1538. X        checkbreak(breakbeforearith);
  1539. X            wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1540. X            outop("<<");
  1541. X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1542. X            break;
  1543. X
  1544. X        case EK_RSH:
  1545. X            setprec3(11);
  1546. X        checkbreak(breakbeforearith);
  1547. X        wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1548. X            outop(">>");
  1549. X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1550. X            break;
  1551. X
  1552. X        case EK_LT:
  1553. X            setprec2(10);
  1554. X        checkbreak(breakbeforerel);
  1555. X            wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1556. X            outop("<");
  1557. X            wrexpr(ex->args[1], incompat(ex, 0, subprec));
  1558. X            break;
  1559. X
  1560. X        case EK_GT:
  1561. END_OF_FILE
  1562. if test 48796 -ne `wc -c <'src/pexpr.c.2'`; then
  1563.     echo shar: \"'src/pexpr.c.2'\" unpacked with wrong size!
  1564. fi
  1565. # end of 'src/pexpr.c.2'
  1566. fi
  1567. echo shar: End of archive 24 \(of 32\).
  1568. cp /dev/null ark24isdone
  1569. MISSING=""
  1570. 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
  1571.     if test ! -f ark${I}isdone ; then
  1572.     MISSING="${MISSING} ${I}"
  1573.     fi
  1574. done
  1575. if test "${MISSING}" = "" ; then
  1576.     echo You have unpacked all 32 archives.
  1577.     echo "Now see PACKNOTES and the README"
  1578.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1579. else
  1580.     echo You still need to unpack the following archives:
  1581.     echo "        " ${MISSING}
  1582. fi
  1583. ##  End of shell archive.
  1584. exit 0
  1585.