comm5.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /* @(#)comm5.c 1.1 */
  2. #include "comm0.h"
  3. #include "comm1.h"
  4. #include "y.tab.h"
  5. extern YYSTYPE yylval;
  6. yylex()
  7. {
  8. register c;
  9. if (pass == PASS_1) {
  10. /* scan the input file */
  11. do
  12. c = nextchar();
  13. while (isspace(c) && c != '\n');
  14. if (ISALPHA(c))
  15. c = inident(c);
  16. else if (isdigit(c))
  17. c = innumber(c);
  18. else switch (c) {
  19. case '=':
  20. case '<':
  21. case '>':
  22. case '|':
  23. case '&':
  24. c = induo(c); break;
  25. case ASC_SQUO:
  26. case ASC_DQUO:
  27. c = instring(c); break;
  28. case ASC_COMM:
  29. do
  30. c = nextchar();
  31. while (c != '\n' && c != '\0');
  32. break;
  33. case CTRL('A'):
  34. c = CODE1; readcode(1); break;
  35. case CTRL('B'):
  36. c = CODE2; readcode(2); break;
  37. case CTRL('C'):
  38. c = CODE4; readcode(4); break;
  39. }
  40. /* produce the intermediate token file */
  41. if (c <= 0)
  42. return(0);
  43. if (c <= 127)
  44. putc(c, tempfile);
  45. else
  46. putval(c);
  47. } else {
  48. /* read from intermediate token file */
  49. c = getc(tempfile);
  50. if (c == EOF)
  51. return(0);
  52. if (c > 127) {
  53. c += 128;
  54. c = getval(c);
  55. }
  56. }
  57. return(c);
  58. }
  59. putval(c)
  60. {
  61. register valu_t v;
  62. register n;
  63. register char *p;
  64. assert(c >= 256 && c < 256+128);
  65. switch (c) {
  66. case CODE1:
  67. n = 1; goto putnum;
  68. case CODE2:
  69. n = 2; goto putnum;
  70. case CODE4:
  71. n = 4; goto putnum;
  72. case NUMBER:
  73. v = yylval.y_valu;
  74. for (n = 0; n < sizeof(v); n++) {
  75. if (v == 0)
  76. break;
  77. v >>= 8;
  78. }
  79. c = NUMBER0 + n;
  80. putnum:
  81. putc(c-128, tempfile);
  82. v = yylval.y_valu;
  83. while (--n >= 0)
  84. putc(v >> (n*8), tempfile);
  85. return;
  86. case IDENT:
  87. case FBSYM:
  88. n = sizeof(item_t *);
  89. p = (char *) &yylval.y_item; break;
  90. #ifdef ASLD
  91. case MODULE:
  92. n = sizeof(char *);
  93. p = (char *) &yylval.y_strp; break;
  94. #endif
  95. case STRING:
  96. p = stringbuf;
  97. n = (*p & 0377) + 1; break;
  98. case OP_EQ:
  99. case OP_NE:
  100. case OP_LE:
  101. case OP_GE:
  102. case OP_LL:
  103. case OP_RR:
  104. case OP_OO:
  105. case OP_AA:
  106. n = 0; break;
  107. default:
  108. n = sizeof(word_t);
  109. p = (char *) &yylval.y_word; break;
  110. }
  111. putc(c-128, tempfile);
  112. while (--n >= 0)
  113. putc(*p++, tempfile);
  114. }
  115. getval(c)
  116. {
  117. register n;
  118. register valu_t v;
  119. register char *p;
  120. switch (c) {
  121. case CODE1:
  122. n = 1; goto getnum;
  123. case CODE2:
  124. n = 2; goto getnum;
  125. case CODE4:
  126. n = 4; goto getnum;
  127. case NUMBER0:
  128. n = 0; c = NUMBER; goto getnum;
  129. case NUMBER1:
  130. n = 1; c = NUMBER; goto getnum;
  131. case NUMBER2:
  132. n = 2; c = NUMBER; goto getnum;
  133. case NUMBER3:
  134. n = 3; c = NUMBER; goto getnum;
  135. case NUMBER:
  136. n = 4;
  137. getnum:
  138. v = 0;
  139. while (--n >= 0) {
  140. v <<= 8;
  141. v |= getc(tempfile);
  142. }
  143. yylval.y_valu = v;
  144. return(c);
  145. case IDENT:
  146. case FBSYM:
  147. n = sizeof(item_t *);
  148. p = (char *) &yylval.y_item; break;
  149. #ifdef ASLD
  150. case MODULE:
  151. n = sizeof(char *);
  152. p = (char *) &yylval.y_strp; break;
  153. #endif
  154. case STRING:
  155. p = stringbuf;
  156. #ifdef DUK
  157. *p++ = n = getc(tempfile);
  158. p[n] = '\0';
  159. break;
  160. #else DUK
  161. *p++ = n = getc(tempfile); break;
  162. #endif DUK
  163. case OP_EQ:
  164. case OP_NE:
  165. case OP_LE:
  166. case OP_GE:
  167. case OP_LL:
  168. case OP_RR:
  169. case OP_OO:
  170. case OP_AA:
  171. n = 0; break;
  172. default:
  173. n = sizeof(word_t);
  174. p = (char *) &yylval.y_word; break;
  175. }
  176. while (--n >= 0)
  177. *p++ = getc(tempfile);
  178. return(c);
  179. }
  180. /* ---------- lexical scan in pass 1 ---------- */
  181. nextchar()
  182. {
  183. register c;
  184. if (peekc != -1) {
  185. c = peekc;
  186. peekc = -1;
  187. return(c);
  188. }
  189. #ifdef ASLD
  190. if (archmode && --archsize < 0)
  191. return(0);
  192. #endif
  193. if ((c = getc(input)) == EOF)
  194. return(0);
  195. if (isascii(c) == 0)
  196. fatal("non-ascii character");
  197. #ifdef LISTING
  198. if (listflag & 0440)
  199. putc(c, listfile);
  200. #endif
  201. return(c);
  202. }
  203. readcode(n)
  204. {
  205. register c;
  206. yylval.y_valu = 0;
  207. do {
  208. if (
  209. #ifdef ASLD
  210. (archmode && --archsize < 0)
  211. ||
  212. #endif
  213. (c = getc(input)) == EOF
  214. )
  215. fatal("unexpected EOF in compact input");
  216. yylval.y_valu <<= 8;
  217. yylval.y_valu |= c;
  218. } while (--n);
  219. }
  220. induo(c)
  221. register c;
  222. {
  223. static short duo[] = {
  224. ('='<<8) | '=', OP_EQ,
  225. ('<'<<8) | '>', OP_NE,
  226. ('<'<<8) | '=', OP_LE,
  227. ('>'<<8) | '=', OP_GE,
  228. ('<'<<8) | '<', OP_LL,
  229. ('>'<<8) | '>', OP_RR,
  230. ('|'<<8) | '|', OP_OO,
  231. ('&'<<8) | '&', OP_AA,
  232. };
  233. register short *p;
  234. c = (c<<8) | nextchar();
  235. for (p = duo; *p; p++)
  236. if (*p++ == c)
  237. return(*p++);
  238. peekc = c & 0377;
  239. return(c>>8);
  240. }
  241. inident(c)
  242. char c;
  243. {
  244. register char *p;
  245. register item_t *ip;
  246. p = readident(c);
  247. ip = item_search(p);
  248. if (ip == 0) {
  249. ip = item_alloc(S_UND);
  250. ip->i_name = remember(p);
  251. /* printf("ident %s %o\n", ip->i_name, ip); */
  252. unresolved++;
  253. item_insert(ip, H_LOCAL + (hashindex%H_SIZE));
  254. } else if (hashindex < H_SIZE) {
  255. assert(H_KEY == 0);
  256. yylval.y_word = (word_t) ip->i_valu;
  257. return(ip->i_type);
  258. }
  259. yylval.y_item = ip;
  260. return(IDENT);
  261. }
  262. char *
  263. readident(c)
  264. register c;
  265. {
  266. static char name[NAMEMAX+1];
  267. register n = NAMEMAX;
  268. register char *p = name;
  269. do {
  270. if (--n >= 0)
  271. *p++ = c;
  272. c = nextchar();
  273. } while (ISALNUM(c));
  274. *p++ = '\0';
  275. peekc = c;
  276. return(name);
  277. }
  278. innumber(c)
  279. register c;
  280. {
  281. register char *p;
  282. register radix;
  283. static char num[20+1];
  284. p = num;
  285. radix = 20;
  286. do {
  287. if (--radix < 0)
  288. fatal("number too long");
  289. if (isupper(c))
  290. c += ('a' - 'A');
  291. *p++ = c;
  292. c = nextchar();
  293. } while (ISALNUM(c));
  294. peekc = c;
  295. *p = '\0';
  296. c = *--p;
  297. p = num;
  298. radix = 10;
  299. if (*p == '0') {
  300. radix = 8;
  301. p++;
  302. if (*p == 'x') {
  303. radix = 16;
  304. p++;
  305. } else if (*p == 'b') {
  306. radix = 2;
  307. p++;
  308. }
  309. }
  310. if (radix != 16 && (c == 'f' || c == 'b'))
  311. return(infbsym(num));
  312. yylval.y_valu = 0;
  313. while (c = *p++) {
  314. if (c > '9')
  315. c -= ('a' - '9' - 1);
  316. c -= '0';
  317. if (c >= radix)
  318. serror("digit exceeds radix");
  319. yylval.y_valu = yylval.y_valu * radix + c;
  320. }
  321. return(NUMBER);
  322. }
  323. instring(termc)
  324. {
  325. register char *p;
  326. register c;
  327. p = stringbuf+1;
  328. for (;;) {
  329. c = nextchar();
  330. if (c == '\n' || c == '\0') {
  331. peekc = c;
  332. serror("non-terminated string");
  333. break;
  334. }
  335. if (c == termc)
  336. break;
  337. if (c == '\\')
  338. c = inescape();
  339. #ifdef DUK
  340. if (p >= &stringbuf[STRINGMAX - 1])
  341. #else DUK
  342. if (p >= &stringbuf[STRINGMAX])
  343. #endif DUK
  344. fatal("string buffer overflow");
  345. *p++ = c;
  346. }
  347. stringbuf[0] = p - stringbuf - 1;
  348. #ifdef DUK
  349. *p = '\0';
  350. #endif DUK
  351. return(STRING);
  352. }
  353. inescape()
  354. {
  355. register c, j, r;
  356. c = nextchar();
  357. if (c >= '0' && c <= '7') {
  358. r = c - '0';
  359. for (j = 0; j < 2; j++) {
  360. c = nextchar();
  361. if (c < '0' || c > '7') {
  362. peekc = c;
  363. return(r);
  364. }
  365. r <<= 3;
  366. r += (c - '0');
  367. }
  368. return(r);
  369. }
  370. switch (c) {
  371. case 'b': return('\b');
  372. case 'f': return('\f');
  373. case 'n': return('\n');
  374. case 'r': return('\r');
  375. case 't': return('\t');
  376. case '\'': return('\'');
  377. case '"': return('"');
  378. }
  379. return(c);
  380. }
  381. infbsym(p)
  382. register char *p;
  383. {
  384. register lab;
  385. register item_t *ip;
  386. lab = *p++ - '0';
  387. if ((unsigned)lab < 10) {
  388. if (*p++ == 'f') {
  389. ip = fb_ptr[FB_FORW+lab];
  390. if (ip == 0) {
  391. ip = fb_alloc(lab);
  392. fb_ptr[FB_FORW+lab] = ip;
  393. }
  394. goto ok;
  395. }
  396. ip = fb_ptr[FB_BACK+lab];
  397. if (ip != 0 && *p == 0)
  398. goto ok;
  399. }
  400. serror("bad numeric label");
  401. ip = fb_alloc(0);
  402. ok:
  403. yylval.y_item = ip;
  404. return(FBSYM);
  405. }
  406. hash(p)
  407. register char *p;
  408. {
  409. register unsigned h;
  410. register c;
  411. h = 0;
  412. while (c = *p++) {
  413. h <<= 2;
  414. h += c;
  415. }
  416. return(h % H_SIZE);
  417. }
  418. item_t *
  419. item_search(p)
  420. register char *p;
  421. {
  422. register h;
  423. register item_t *ip;
  424. for (h = hash(p); h < H_TOTAL; h += H_SIZE) {
  425. ip = hashtab[h];
  426. while (ip != 0) {
  427. if (strcmp(p, ip->i_name) == 0)
  428. goto done;
  429. ip = ip->i_next;
  430. }
  431. }
  432. done:
  433. hashindex = h;
  434. return(ip);
  435. }
  436. item_insert(ip, h)
  437. item_t *ip;
  438. {
  439. ip->i_next = hashtab[h];
  440. hashtab[h] = ip;
  441. }
  442. item_t *
  443. item_alloc(typ)
  444. {
  445. register item_t *ip;
  446. static nleft = 0;
  447. static item_t *next;
  448. if (--nleft < 0) {
  449. next = (item_t *) sbrk(MEMINCR);
  450. if ((int) next == -1)
  451. fatal("out of memory");
  452. nleft += (MEMINCR / sizeof(item_t));
  453. }
  454. ip = next++;
  455. ip->i_next = 0;
  456. ip->i_type = typ;
  457. ip->i_name = 0;
  458. ip->i_valu = 0;
  459. return(ip);
  460. }
  461. item_t *
  462. fb_alloc(lab)
  463. register lab;
  464. {
  465. register item_t *ip, *p;
  466. ip = item_alloc(S_UND);
  467. p = fb_ptr[FB_TAIL+lab];
  468. if (p == 0)
  469. fb_ptr[FB_HEAD+lab] = ip;
  470. else
  471. p->i_next = ip;
  472. fb_ptr[FB_TAIL+lab] = ip;
  473. return(ip);
  474. }
  475. item_t *
  476. fb_shift(lab)
  477. register lab;
  478. {
  479. register item_t *ip;
  480. ip = fb_ptr[FB_FORW+lab];
  481. if (ip == 0)
  482. if (pass == PASS_1)
  483. ip = fb_alloc(lab);
  484. else
  485. ip = fb_ptr[FB_HEAD+lab];
  486. fb_ptr[FB_BACK+lab] = ip;
  487. fb_ptr[FB_FORW+lab] = ip->i_next;
  488. return(ip);
  489. }