c.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /* $Header$ */
  2. /* Language dependant support; this one is for C */
  3. #include <stdio.h>
  4. #include <alloc.h>
  5. #include "position.h"
  6. #include "class.h"
  7. #include "langdep.h"
  8. #include "Lpars.h"
  9. #include "idf.h"
  10. #include "token.h"
  11. #include "expr.h"
  12. #include "tree.h"
  13. #include "operator.h"
  14. extern FILE *db_out, *db_in;
  15. extern int
  16. get_name();
  17. extern double
  18. atof();
  19. static int
  20. print_string(),
  21. print_char(),
  22. get_number(),
  23. get_string(),
  24. get_token(),
  25. print_op(),
  26. unop_prio(),
  27. binop_prio(),
  28. fix_bin_to_pref();
  29. static long
  30. array_elsize();
  31. static struct langdep c = {
  32. 0,
  33. "%ld",
  34. "0%lo",
  35. "0x%lX",
  36. "%lu",
  37. "0x%lX",
  38. "%.14g",
  39. "{",
  40. "}",
  41. "{",
  42. "}",
  43. "{",
  44. "}",
  45. print_string,
  46. print_char,
  47. array_elsize,
  48. binop_prio,
  49. unop_prio,
  50. get_string,
  51. get_name,
  52. get_number,
  53. get_token,
  54. print_op,
  55. fix_bin_to_pref
  56. };
  57. struct langdep *c_dep = &c;
  58. static int
  59. printchar(f, c, esc)
  60. FILE *f;
  61. int c;
  62. {
  63. c &= 0377;
  64. switch(c) {
  65. case '\n':
  66. fputs("\\n", f);
  67. break;
  68. case '\t':
  69. fputs("\\t", f);
  70. break;
  71. case '\b':
  72. fputs("\\b", f);
  73. break;
  74. case '\r':
  75. fputs("\\r", f);
  76. break;
  77. case '\f':
  78. fputs("\\f", f);
  79. break;
  80. case '\\':
  81. fputs("\\\\", f);
  82. break;
  83. case '\'':
  84. case '"':
  85. fprintf(f, c == esc ? "\\%c" : "%c", c);
  86. break;
  87. default:
  88. fprintf(f, (c >= 040 && c < 0177) ? "%c" : "\\%03o", c);
  89. break;
  90. }
  91. }
  92. static int
  93. print_char(c)
  94. int c;
  95. {
  96. putc('\'', db_out);
  97. printchar(db_out, c, '\'');
  98. putc('\'', db_out);
  99. }
  100. static int
  101. print_string(f, s, len)
  102. FILE *f;
  103. char *s;
  104. int len;
  105. {
  106. register char *str = s;
  107. putc('"', f);
  108. while (*str && len-- > 0) printchar(f, *str++, '"');
  109. putc('"', f);
  110. }
  111. extern long int_size;
  112. static long
  113. array_elsize(size)
  114. long size;
  115. {
  116. if (! (int_size % size)) return size;
  117. if (! (size % int_size)) return size;
  118. return ((size + int_size - 1) / int_size) * int_size;
  119. }
  120. static int
  121. unop_prio(op)
  122. int op;
  123. {
  124. switch(op) {
  125. case E_NOT:
  126. case E_BNOT:
  127. case E_MIN:
  128. case E_DEREF:
  129. case E_PLUS:
  130. case E_ADDR:
  131. return 12;
  132. }
  133. return 1;
  134. }
  135. static int
  136. binop_prio(op)
  137. int op;
  138. {
  139. switch(op) {
  140. case E_OR:
  141. return 2;
  142. case E_AND:
  143. return 3;
  144. case E_BOR:
  145. return 4;
  146. case E_BXOR:
  147. return 5;
  148. case E_BAND:
  149. return 6;
  150. case E_EQUAL:
  151. case E_NOTEQUAL:
  152. return 7;
  153. case E_LT:
  154. case E_LTEQUAL:
  155. case E_GT:
  156. case E_GTEQUAL:
  157. return 8;
  158. case E_LSFT:
  159. case E_RSFT:
  160. return 9;
  161. case E_MIN:
  162. case E_PLUS:
  163. return 10;
  164. case E_MUL:
  165. case E_DIV:
  166. case E_ZDIV:
  167. case E_MOD:
  168. case E_ZMOD:
  169. return 11;
  170. case E_ARRAY:
  171. case E_SELECT:
  172. return 12;
  173. case E_DERSELECT:
  174. return 13;
  175. }
  176. return 1;
  177. }
  178. static int
  179. val_in_base(c, base)
  180. register int c;
  181. {
  182. return is_dig(c)
  183. ? c - '0'
  184. : base != 16
  185. ? -1
  186. : is_hex(c)
  187. ? (c - 'a' + 10) & 017
  188. : -1;
  189. }
  190. static int
  191. get_number(c)
  192. register int c;
  193. {
  194. char buf[512+1];
  195. register int base = 10;
  196. register char *p = &buf[0];
  197. register long val = 0;
  198. register int val_c;
  199. if (c == '0') {
  200. /* check if next char is an 'x' or an 'X' */
  201. c = getc(db_in);
  202. if (c == 'x' || c == 'X') {
  203. base = 16;
  204. c = getc(db_in);
  205. }
  206. else base = 8;
  207. }
  208. while (val_c = val_in_base(c, base), val_c >= 0) {
  209. val = val * base + val_c;
  210. if (p - buf < 512) *p++ = c;
  211. c = getc(db_in);
  212. }
  213. if (base == 16 || !((c == '.' || c == 'e' || c == 'E'))) {
  214. ungetc(c, db_in);
  215. tok.ival = val;
  216. return INTEGER;
  217. }
  218. if (c == '.') {
  219. if (p - buf < 512) *p++ = c;
  220. c = getc(db_in);
  221. }
  222. while (is_dig(c)) {
  223. if (p - buf < 512) *p++ = c;
  224. c = getc(db_in);
  225. }
  226. if (c == 'e' || c == 'E') {
  227. if (p - buf < 512) *p++ = c;
  228. c = getc(db_in);
  229. if (c == '+' || c == '-') {
  230. if (p - buf < 512) *p++ = c;
  231. c = getc(db_in);
  232. }
  233. if (! is_dig(c)) {
  234. error("malformed floating constant");
  235. }
  236. while (is_dig(c)) {
  237. if (p - buf < 512) *p++ = c;
  238. c = getc(db_in);
  239. }
  240. }
  241. ungetc(c, db_in);
  242. *p++ = 0;
  243. if (p == &buf[512+1]) {
  244. error("floating point constant too long");
  245. }
  246. tok.fval = atof(buf);
  247. return REAL;
  248. }
  249. static int
  250. get_token(c)
  251. register int c;
  252. {
  253. switch(c) {
  254. case '[':
  255. tok.ival = E_ARRAY;
  256. /* fall through */
  257. case '(':
  258. case ')':
  259. case ']':
  260. case '`':
  261. case ':':
  262. case ',':
  263. case '}':
  264. case '{':
  265. case '\\':
  266. return c;
  267. case '.':
  268. tok.ival = E_SELECT;
  269. return SEL_OP;
  270. case '+':
  271. tok.ival = E_PLUS;
  272. return PREF_OR_BIN_OP;
  273. case '-':
  274. c = getc(db_in);
  275. if (c == '>') {
  276. tok.ival = E_DERSELECT;
  277. return BIN_OP;
  278. }
  279. ungetc(c, db_in);
  280. tok.ival = E_MIN;
  281. return PREF_OR_BIN_OP;
  282. case '*':
  283. tok.ival = E_MUL;
  284. return PREF_OR_BIN_OP;
  285. case '/':
  286. tok.ival = E_ZDIV;
  287. return BIN_OP;
  288. case '%':
  289. tok.ival = E_ZMOD;
  290. return BIN_OP;
  291. case '&':
  292. c = getc(db_in);
  293. if (c == '&') {
  294. tok.ival = E_AND;
  295. return BIN_OP;
  296. }
  297. ungetc(c, db_in);
  298. tok.ival = E_BAND;
  299. return PREF_OR_BIN_OP;
  300. case '^':
  301. tok.ival = E_BXOR;
  302. return BIN_OP;
  303. case '|':
  304. c = getc(db_in);
  305. if (c == '|') {
  306. tok.ival = E_OR;
  307. }
  308. else {
  309. ungetc(c, db_in);
  310. tok.ival = E_BOR;
  311. }
  312. return BIN_OP;
  313. case '=':
  314. c = getc(db_in);
  315. if (c == '=') {
  316. }
  317. else {
  318. ungetc(c, db_in);
  319. warning("== assumed");
  320. }
  321. tok.ival = E_EQUAL;
  322. return BIN_OP;
  323. case '<':
  324. c = getc(db_in);
  325. if (c == '=') {
  326. tok.ival = E_LTEQUAL;
  327. return BIN_OP;
  328. }
  329. if (c == '<') {
  330. tok.ival = E_LSFT;
  331. return BIN_OP;
  332. }
  333. ungetc(c, db_in);
  334. tok.ival = E_LT;
  335. return BIN_OP;
  336. case '>':
  337. c = getc(db_in);
  338. if (c == '=') {
  339. tok.ival = E_GTEQUAL;
  340. return BIN_OP;
  341. }
  342. if (c == '>') {
  343. tok.ival = E_RSFT;
  344. return BIN_OP;
  345. }
  346. ungetc(c, db_in);
  347. tok.ival = E_GT;
  348. return BIN_OP;
  349. case '!':
  350. c = getc(db_in);
  351. if (c == '=') {
  352. tok.ival = E_NOTEQUAL;
  353. return BIN_OP;
  354. }
  355. ungetc(c, db_in);
  356. tok.ival = E_NOT;
  357. return PREF_OP;
  358. case '~':
  359. tok.ival = E_BNOT;
  360. return PREF_OP;
  361. default:
  362. error((c >= 040 && c < 0177) ? "%s'%c'" : "%s'\\0%o'", "illegal character ", c);
  363. return LLlex();
  364. }
  365. }
  366. static int
  367. quoted(ch)
  368. int ch;
  369. {
  370. /* quoted() replaces an escaped character sequence by the
  371. character meant.
  372. */
  373. /* first char after backslash already in ch */
  374. if (!is_oct(ch)) { /* a quoted char */
  375. switch (ch) {
  376. case 'n':
  377. ch = '\n';
  378. break;
  379. case 't':
  380. ch = '\t';
  381. break;
  382. case 'b':
  383. ch = '\b';
  384. break;
  385. case 'r':
  386. ch = '\r';
  387. break;
  388. case 'f':
  389. ch = '\f';
  390. break;
  391. }
  392. }
  393. else { /* a quoted octal */
  394. register int oct = 0, cnt = 0;
  395. do {
  396. oct = oct*8 + (ch-'0');
  397. ch = getc(db_in);
  398. } while (is_oct(ch) && ++cnt < 3);
  399. ungetc(ch, db_in);
  400. ch = oct;
  401. }
  402. return ch&0377;
  403. }
  404. static int
  405. get_string(c)
  406. int c;
  407. {
  408. register int ch;
  409. char buf[512];
  410. register int len = 0;
  411. while (ch = getc(db_in), ch != c) {
  412. if (ch == '\n') {
  413. error("newline in string");
  414. ungetc(ch, db_in);
  415. break;
  416. }
  417. if (ch == '\\') {
  418. ch = getc(db_in);
  419. ch = quoted(ch);
  420. }
  421. buf[len++] = ch;
  422. }
  423. buf[len++] = 0;
  424. if (c == '\'') {
  425. long val = 0;
  426. ch = 0;
  427. while (buf[ch] != 0) {
  428. val = (val << 8) + (buf[ch++] & 0377);
  429. }
  430. tok.ival = val;
  431. return INTEGER;
  432. }
  433. tok.str = Salloc(buf, (unsigned) len);
  434. return STRING;
  435. }
  436. static int
  437. print_op(f, p)
  438. FILE *f;
  439. p_tree p;
  440. {
  441. switch(p->t_oper) {
  442. case OP_UNOP:
  443. switch(p->t_whichoper) {
  444. case E_MIN:
  445. fputs("-(", f);
  446. print_node(f, p->t_args[0], 0);
  447. putc(')', f);
  448. break;
  449. case E_PLUS:
  450. fputs("+(", f);
  451. print_node(f, p->t_args[0], 0);
  452. putc(')', f);
  453. break;
  454. case E_NOT:
  455. fputs("!(", f);
  456. print_node(f, p->t_args[0], 0);
  457. putc(')', f);
  458. break;
  459. case E_DEREF:
  460. fputs("*(", f);
  461. print_node(f, p->t_args[0], 0);
  462. putc(')', f);
  463. break;
  464. case E_BNOT:
  465. fputs("~(", f);
  466. print_node(f, p->t_args[0], 0);
  467. putc(')', f);
  468. break;
  469. case E_ADDR:
  470. fputs("&(", f);
  471. print_node(f, p->t_args[0], 0);
  472. putc(')', f);
  473. break;
  474. }
  475. break;
  476. case OP_BINOP:
  477. if (p->t_whichoper == E_ARRAY) {
  478. print_node(f, p->t_args[0], 0);
  479. fputs("[", f);
  480. print_node(f, p->t_args[1], 0);
  481. fputs("]", f);
  482. break;
  483. }
  484. if (p->t_whichoper == E_DERSELECT) {
  485. print_node(f, p->t_args[0], 0);
  486. fputs("->", f);
  487. print_node(f, p->t_args[1], 0);
  488. break;
  489. }
  490. if (p->t_whichoper == E_SELECT) {
  491. print_node(f, p->t_args[0], 0);
  492. fputs(".", f);
  493. print_node(f, p->t_args[1], 0);
  494. break;
  495. }
  496. fputs("(", f);
  497. print_node(f, p->t_args[0], 0);
  498. switch(p->t_whichoper) {
  499. case E_LSFT:
  500. fputs("<<", f);
  501. break;
  502. case E_RSFT:
  503. fputs(">>", f);
  504. break;
  505. case E_AND:
  506. fputs("&&", f);
  507. break;
  508. case E_BAND:
  509. fputs("&", f);
  510. break;
  511. case E_OR:
  512. fputs("||", f);
  513. break;
  514. case E_BOR:
  515. fputs("|", f);
  516. break;
  517. case E_BXOR:
  518. fputs("^", f);
  519. break;
  520. case E_ZDIV:
  521. fputs("/", f);
  522. break;
  523. case E_ZMOD:
  524. fputs("%", f);
  525. break;
  526. case E_PLUS:
  527. fputs("+", f);
  528. break;
  529. case E_MIN:
  530. fputs("-", f);
  531. break;
  532. case E_MUL:
  533. fputs("*", f);
  534. break;
  535. case E_EQUAL:
  536. fputs("==", f);
  537. break;
  538. case E_NOTEQUAL:
  539. fputs("!=", f);
  540. break;
  541. case E_LTEQUAL:
  542. fputs("<=", f);
  543. break;
  544. case E_GTEQUAL:
  545. fputs(">=", f);
  546. break;
  547. case E_LT:
  548. fputs("<", f);
  549. break;
  550. case E_GT:
  551. fputs(">", f);
  552. break;
  553. }
  554. print_node(f, p->t_args[1], 0);
  555. fputs(")", f);
  556. break;
  557. }
  558. }
  559. static int
  560. fix_bin_to_pref(p)
  561. p_tree p;
  562. {
  563. switch(p->t_whichoper) {
  564. case E_MUL:
  565. p->t_whichoper = E_DEREF;
  566. break;
  567. case E_BAND:
  568. p->t_whichoper = E_ADDR;
  569. break;
  570. }
  571. }