c.c 8.9 KB

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