c.c 8.8 KB

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