lexbody 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /*
  2. * common code for all the assemblers
  3. */
  4. void
  5. pragpack(void)
  6. {
  7. while(getnsc() != '\n')
  8. ;
  9. }
  10. void
  11. pragvararg(void)
  12. {
  13. while(getnsc() != '\n')
  14. ;
  15. }
  16. void
  17. pragfpround(void)
  18. {
  19. while(getnsc() != '\n')
  20. ;
  21. }
  22. void
  23. pragprofile(void)
  24. {
  25. while(getnsc() != '\n')
  26. ;
  27. }
  28. void
  29. pragincomplete(void)
  30. {
  31. while(getnsc() != '\n')
  32. ;
  33. }
  34. /*
  35. * real allocs
  36. */
  37. void*
  38. alloc(long n)
  39. {
  40. void *p;
  41. while((ulong)hunk & MAXALIGN) {
  42. hunk++;
  43. nhunk--;
  44. }
  45. while(nhunk < n)
  46. gethunk();
  47. p = hunk;
  48. nhunk -= n;
  49. hunk += n;
  50. return p;
  51. }
  52. void*
  53. allocn(void *p, long on, long n)
  54. {
  55. void *q;
  56. q = (uchar*)p + on;
  57. if(q != hunk || nhunk < n) {
  58. while(nhunk < on+n)
  59. gethunk();
  60. memmove(hunk, p, on);
  61. p = hunk;
  62. hunk += on;
  63. nhunk -= on;
  64. }
  65. hunk += n;
  66. nhunk -= n;
  67. return p;
  68. }
  69. void
  70. setinclude(char *p)
  71. {
  72. int i;
  73. if(p == 0)
  74. return;
  75. for(i=1; i < ninclude; i++)
  76. if(strcmp(p, include[i]) == 0)
  77. return;
  78. if(ninclude >= nelem(include)) {
  79. yyerror("ninclude too small %d", nelem(include));
  80. exits("ninclude");
  81. }
  82. include[ninclude++] = p;
  83. }
  84. void
  85. errorexit(void)
  86. {
  87. if(outfile)
  88. remove(outfile);
  89. exits("error");
  90. }
  91. void
  92. pushio(void)
  93. {
  94. Io *i;
  95. i = iostack;
  96. if(i == I) {
  97. yyerror("botch in pushio");
  98. errorexit();
  99. }
  100. i->p = fi.p;
  101. i->c = fi.c;
  102. }
  103. void
  104. newio(void)
  105. {
  106. Io *i;
  107. static int pushdepth = 0;
  108. i = iofree;
  109. if(i == I) {
  110. pushdepth++;
  111. if(pushdepth > 1000) {
  112. yyerror("macro/io expansion too deep");
  113. errorexit();
  114. }
  115. i = alloc(sizeof(*i));
  116. } else
  117. iofree = i->link;
  118. i->c = 0;
  119. i->f = -1;
  120. ionext = i;
  121. }
  122. void
  123. newfile(char *s, int f)
  124. {
  125. Io *i;
  126. i = ionext;
  127. i->link = iostack;
  128. iostack = i;
  129. i->f = f;
  130. if(f < 0)
  131. i->f = open(s, 0);
  132. if(i->f < 0) {
  133. yyerror("%ca: %r: %s", thechar, s);
  134. errorexit();
  135. }
  136. fi.c = 0;
  137. linehist(s, 0);
  138. }
  139. Sym*
  140. slookup(char *s)
  141. {
  142. strcpy(symb, s);
  143. return lookup();
  144. }
  145. Sym*
  146. lookup(void)
  147. {
  148. Sym *s;
  149. long h;
  150. char *p;
  151. int c, l;
  152. h = 0;
  153. for(p=symb; c = *p; p++)
  154. h = h+h+h + c;
  155. l = (p - symb) + 1;
  156. if(h < 0)
  157. h = ~h;
  158. h %= NHASH;
  159. c = symb[0];
  160. for(s = hash[h]; s != S; s = s->link) {
  161. if(s->name[0] != c)
  162. continue;
  163. if(memcmp(s->name, symb, l) == 0)
  164. return s;
  165. }
  166. s = alloc(sizeof(*s));
  167. s->name = alloc(l);
  168. memmove(s->name, symb, l);
  169. s->link = hash[h];
  170. hash[h] = s;
  171. syminit(s);
  172. return s;
  173. }
  174. long
  175. yylex(void)
  176. {
  177. int c, c1;
  178. char *cp;
  179. Sym *s;
  180. c = peekc;
  181. if(c != IGN) {
  182. peekc = IGN;
  183. goto l1;
  184. }
  185. l0:
  186. c = GETC();
  187. l1:
  188. if(c == EOF) {
  189. peekc = EOF;
  190. return -1;
  191. }
  192. if(isspace(c)) {
  193. if(c == '\n') {
  194. lineno++;
  195. return ';';
  196. }
  197. goto l0;
  198. }
  199. if(isalpha(c))
  200. goto talph;
  201. if(isdigit(c))
  202. goto tnum;
  203. switch(c)
  204. {
  205. case '\n':
  206. lineno++;
  207. return ';';
  208. case '#':
  209. domacro();
  210. goto l0;
  211. case '.':
  212. c = GETC();
  213. if(isalpha(c)) {
  214. cp = symb;
  215. *cp++ = '.';
  216. goto aloop;
  217. }
  218. if(isdigit(c)) {
  219. cp = symb;
  220. *cp++ = '.';
  221. goto casedot;
  222. }
  223. peekc = c;
  224. return '.';
  225. talph:
  226. case '_':
  227. case '@':
  228. cp = symb;
  229. aloop:
  230. *cp++ = c;
  231. c = GETC();
  232. if(isalpha(c) || isdigit(c) || c == '_' || c == '$')
  233. goto aloop;
  234. *cp = 0;
  235. peekc = c;
  236. s = lookup();
  237. if(s->macro) {
  238. newio();
  239. cp = ionext->b;
  240. macexpand(s, cp);
  241. pushio();
  242. ionext->link = iostack;
  243. iostack = ionext;
  244. fi.p = cp;
  245. fi.c = strlen(cp);
  246. if(peekc != IGN) {
  247. cp[fi.c++] = peekc;
  248. cp[fi.c] = 0;
  249. peekc = IGN;
  250. }
  251. goto l0;
  252. }
  253. if(s->type == 0)
  254. s->type = LNAME;
  255. if(s->type == LNAME ||
  256. s->type == LVAR ||
  257. s->type == LLAB) {
  258. yylval.sym = s;
  259. return s->type;
  260. }
  261. yylval.lval = s->value;
  262. return s->type;
  263. tnum:
  264. cp = symb;
  265. if(c != '0')
  266. goto dc;
  267. *cp++ = c;
  268. c = GETC();
  269. c1 = 3;
  270. if(c == 'x' || c == 'X') {
  271. c1 = 4;
  272. c = GETC();
  273. } else
  274. if(c < '0' || c > '7')
  275. goto dc;
  276. yylval.lval = 0;
  277. for(;;) {
  278. if(c >= '0' && c <= '9') {
  279. if(c > '7' && c1 == 3)
  280. break;
  281. yylval.lval <<= c1;
  282. yylval.lval += c - '0';
  283. c = GETC();
  284. continue;
  285. }
  286. if(c1 == 3)
  287. break;
  288. if(c >= 'A' && c <= 'F')
  289. c += 'a' - 'A';
  290. if(c >= 'a' && c <= 'f') {
  291. yylval.lval <<= c1;
  292. yylval.lval += c - 'a' + 10;
  293. c = GETC();
  294. continue;
  295. }
  296. break;
  297. }
  298. goto ncu;
  299. dc:
  300. for(;;) {
  301. if(!isdigit(c))
  302. break;
  303. *cp++ = c;
  304. c = GETC();
  305. }
  306. if(c == '.')
  307. goto casedot;
  308. if(c == 'e' || c == 'E')
  309. goto casee;
  310. *cp = 0;
  311. yylval.lval = atol(symb);
  312. ncu:
  313. peekc = c;
  314. return LCONST;
  315. casedot:
  316. for(;;) {
  317. *cp++ = c;
  318. c = GETC();
  319. if(!isdigit(c))
  320. break;
  321. }
  322. if(c == 'e' || c == 'E')
  323. goto casee;
  324. goto caseout;
  325. casee:
  326. *cp++ = 'e';
  327. c = GETC();
  328. if(c == '+' || c == '-') {
  329. *cp++ = c;
  330. c = GETC();
  331. }
  332. while(isdigit(c)) {
  333. *cp++ = c;
  334. c = GETC();
  335. }
  336. caseout:
  337. *cp = 0;
  338. peekc = c;
  339. if(FPCHIP) {
  340. yylval.dval = atof(symb);
  341. return LFCONST;
  342. }
  343. yyerror("assembler cannot interpret fp constants");
  344. yylval.lval = 1L;
  345. return LCONST;
  346. case '"':
  347. memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
  348. cp = yylval.sval;
  349. c1 = 0;
  350. for(;;) {
  351. c = escchar('"');
  352. if(c == EOF)
  353. break;
  354. if(c1 < sizeof(yylval.sval))
  355. *cp++ = c;
  356. c1++;
  357. }
  358. if(c1 > sizeof(yylval.sval))
  359. yyerror("string constant too long");
  360. return LSCONST;
  361. case '\'':
  362. c = escchar('\'');
  363. if(c == EOF)
  364. c = '\'';
  365. if(escchar('\'') != EOF)
  366. yyerror("missing '");
  367. yylval.lval = c;
  368. return LCONST;
  369. case '/':
  370. c1 = GETC();
  371. if(c1 == '/') {
  372. for(;;) {
  373. c = GETC();
  374. if(c == '\n') {
  375. lineno++;
  376. goto l0;
  377. }
  378. if(c == EOF) {
  379. yyerror("eof in comment");
  380. errorexit();
  381. }
  382. }
  383. }
  384. if(c1 == '*') {
  385. for(;;) {
  386. c = GETC();
  387. while(c == '*') {
  388. c = GETC();
  389. if(c == '/')
  390. goto l0;
  391. }
  392. if(c == EOF) {
  393. yyerror("eof in comment");
  394. errorexit();
  395. }
  396. if(c == '\n')
  397. lineno++;
  398. }
  399. }
  400. break;
  401. default:
  402. return c;
  403. }
  404. peekc = c1;
  405. return c;
  406. }
  407. int
  408. getc(void)
  409. {
  410. int c;
  411. c = peekc;
  412. if(c != IGN) {
  413. peekc = IGN;
  414. return c;
  415. }
  416. c = GETC();
  417. if(c == '\n')
  418. lineno++;
  419. if(c == EOF) {
  420. yyerror("End of file");
  421. errorexit();
  422. }
  423. return c;
  424. }
  425. int
  426. getnsc(void)
  427. {
  428. int c;
  429. for(;;) {
  430. c = getc();
  431. if(!isspace(c) || c == '\n')
  432. return c;
  433. }
  434. }
  435. void
  436. unget(int c)
  437. {
  438. peekc = c;
  439. if(c == '\n')
  440. lineno--;
  441. }
  442. int
  443. escchar(int e)
  444. {
  445. int c, l;
  446. loop:
  447. c = getc();
  448. if(c == '\n') {
  449. yyerror("newline in string");
  450. return EOF;
  451. }
  452. if(c != '\\') {
  453. if(c == e)
  454. return EOF;
  455. return c;
  456. }
  457. c = getc();
  458. if(c >= '0' && c <= '7') {
  459. l = c - '0';
  460. c = getc();
  461. if(c >= '0' && c <= '7') {
  462. l = l*8 + c-'0';
  463. c = getc();
  464. if(c >= '0' && c <= '7') {
  465. l = l*8 + c-'0';
  466. return l;
  467. }
  468. }
  469. peekc = c;
  470. return l;
  471. }
  472. switch(c)
  473. {
  474. case '\n': goto loop;
  475. case 'n': return '\n';
  476. case 't': return '\t';
  477. case 'b': return '\b';
  478. case 'r': return '\r';
  479. case 'f': return '\f';
  480. case 'a': return 0x07;
  481. case 'v': return 0x0b;
  482. case 'z': return 0x00;
  483. }
  484. return c;
  485. }
  486. void
  487. pinit(char *f)
  488. {
  489. int i;
  490. Sym *s;
  491. lineno = 1;
  492. newio();
  493. newfile(f, -1);
  494. pc = 0;
  495. peekc = IGN;
  496. sym = 1;
  497. for(i=0; i<NSYM; i++) {
  498. h[i].type = 0;
  499. h[i].sym = S;
  500. }
  501. for(i=0; i<NHASH; i++)
  502. for(s = hash[i]; s != S; s = s->link)
  503. s->macro = 0;
  504. }
  505. int
  506. filbuf(void)
  507. {
  508. Io *i;
  509. loop:
  510. i = iostack;
  511. if(i == I)
  512. return EOF;
  513. if(i->f < 0)
  514. goto pop;
  515. fi.c = read(i->f, i->b, BUFSIZ) - 1;
  516. if(fi.c < 0) {
  517. close(i->f);
  518. linehist(0, 0);
  519. goto pop;
  520. }
  521. fi.p = i->b + 1;
  522. return i->b[0];
  523. pop:
  524. iostack = i->link;
  525. i->link = iofree;
  526. iofree = i;
  527. i = iostack;
  528. if(i == I)
  529. return EOF;
  530. fi.p = i->p;
  531. fi.c = i->c;
  532. if(--fi.c < 0)
  533. goto loop;
  534. return *fi.p++;
  535. }
  536. void
  537. yyerror(char *a, ...)
  538. {
  539. char buf[200];
  540. va_list arg;
  541. /*
  542. * hack to intercept message from yaccpar
  543. */
  544. if(strcmp(a, "syntax error") == 0) {
  545. yyerror("syntax error, last name: %s", symb);
  546. return;
  547. }
  548. prfile(lineno);
  549. va_start(arg, a);
  550. vseprint(buf, buf+sizeof(buf), a, arg);
  551. va_end(arg);
  552. print("%s\n", buf);
  553. nerrors++;
  554. if(nerrors > 10) {
  555. print("too many errors\n");
  556. errorexit();
  557. }
  558. }
  559. void
  560. prfile(long l)
  561. {
  562. int i, n;
  563. Hist a[HISTSZ], *h;
  564. long d;
  565. n = 0;
  566. for(h = hist; h != H; h = h->link) {
  567. if(l < h->line)
  568. break;
  569. if(h->name) {
  570. if(h->offset == 0) {
  571. if(n >= 0 && n < HISTSZ)
  572. a[n] = *h;
  573. n++;
  574. continue;
  575. }
  576. if(n > 0 && n < HISTSZ)
  577. if(a[n-1].offset == 0) {
  578. a[n] = *h;
  579. n++;
  580. } else
  581. a[n-1] = *h;
  582. continue;
  583. }
  584. n--;
  585. if(n >= 0 && n < HISTSZ) {
  586. d = h->line - a[n].line;
  587. for(i=0; i<n; i++)
  588. a[i].line += d;
  589. }
  590. }
  591. if(n > HISTSZ)
  592. n = HISTSZ;
  593. for(i=0; i<n; i++)
  594. print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
  595. }
  596. void
  597. ieeedtod(Ieee *ieee, double native)
  598. {
  599. double fr, ho, f;
  600. int exp;
  601. if(native < 0) {
  602. ieeedtod(ieee, -native);
  603. ieee->h |= 0x80000000L;
  604. return;
  605. }
  606. if(native == 0) {
  607. ieee->l = 0;
  608. ieee->h = 0;
  609. return;
  610. }
  611. fr = frexp(native, &exp);
  612. f = 2097152L; /* shouldnt use fp constants here */
  613. fr = modf(fr*f, &ho);
  614. ieee->h = ho;
  615. ieee->h &= 0xfffffL;
  616. ieee->h |= (exp+1022L) << 20;
  617. f = 65536L;
  618. fr = modf(fr*f, &ho);
  619. ieee->l = ho;
  620. ieee->l <<= 16;
  621. ieee->l |= (long)(fr*f);
  622. }