lexbody 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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((uintptr)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. if(sizeof(yylval.lval) == sizeof(vlong))
  312. yylval.lval = strtoll(symb, nil, 10);
  313. else
  314. yylval.lval = strtol(symb, nil, 10);
  315. ncu:
  316. while(c == 'U' || c == 'u' || c == 'l' || c == 'L')
  317. c = GETC();
  318. peekc = c;
  319. return LCONST;
  320. casedot:
  321. for(;;) {
  322. *cp++ = c;
  323. c = GETC();
  324. if(!isdigit(c))
  325. break;
  326. }
  327. if(c == 'e' || c == 'E')
  328. goto casee;
  329. goto caseout;
  330. casee:
  331. *cp++ = 'e';
  332. c = GETC();
  333. if(c == '+' || c == '-') {
  334. *cp++ = c;
  335. c = GETC();
  336. }
  337. while(isdigit(c)) {
  338. *cp++ = c;
  339. c = GETC();
  340. }
  341. caseout:
  342. *cp = 0;
  343. peekc = c;
  344. if(FPCHIP) {
  345. yylval.dval = atof(symb);
  346. return LFCONST;
  347. }
  348. yyerror("assembler cannot interpret fp constants");
  349. yylval.lval = 1L;
  350. return LCONST;
  351. case '"':
  352. memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
  353. cp = yylval.sval;
  354. c1 = 0;
  355. for(;;) {
  356. c = escchar('"');
  357. if(c == EOF)
  358. break;
  359. if(c1 < sizeof(yylval.sval))
  360. *cp++ = c;
  361. c1++;
  362. }
  363. if(c1 > sizeof(yylval.sval))
  364. yyerror("string constant too long");
  365. return LSCONST;
  366. case '\'':
  367. c = escchar('\'');
  368. if(c == EOF)
  369. c = '\'';
  370. if(escchar('\'') != EOF)
  371. yyerror("missing '");
  372. yylval.lval = c;
  373. return LCONST;
  374. case '/':
  375. c1 = GETC();
  376. if(c1 == '/') {
  377. for(;;) {
  378. c = GETC();
  379. if(c == '\n')
  380. goto l1;
  381. if(c == EOF) {
  382. yyerror("eof in comment");
  383. errorexit();
  384. }
  385. }
  386. }
  387. if(c1 == '*') {
  388. for(;;) {
  389. c = GETC();
  390. while(c == '*') {
  391. c = GETC();
  392. if(c == '/')
  393. goto l0;
  394. }
  395. if(c == EOF) {
  396. yyerror("eof in comment");
  397. errorexit();
  398. }
  399. if(c == '\n')
  400. lineno++;
  401. }
  402. }
  403. break;
  404. default:
  405. return c;
  406. }
  407. peekc = c1;
  408. return c;
  409. }
  410. int
  411. getc(void)
  412. {
  413. int c;
  414. c = peekc;
  415. if(c != IGN) {
  416. peekc = IGN;
  417. return c;
  418. }
  419. c = GETC();
  420. if(c == '\n')
  421. lineno++;
  422. if(c == EOF) {
  423. yyerror("End of file");
  424. errorexit();
  425. }
  426. return c;
  427. }
  428. int
  429. getnsc(void)
  430. {
  431. int c;
  432. for(;;) {
  433. c = getc();
  434. if(!isspace(c) || c == '\n')
  435. return c;
  436. }
  437. }
  438. void
  439. unget(int c)
  440. {
  441. peekc = c;
  442. if(c == '\n')
  443. lineno--;
  444. }
  445. int
  446. escchar(int e)
  447. {
  448. int c, l;
  449. loop:
  450. c = getc();
  451. if(c == '\n') {
  452. yyerror("newline in string");
  453. return EOF;
  454. }
  455. if(c != '\\') {
  456. if(c == e)
  457. return EOF;
  458. return c;
  459. }
  460. c = getc();
  461. if(c >= '0' && c <= '7') {
  462. l = c - '0';
  463. c = getc();
  464. if(c >= '0' && c <= '7') {
  465. l = l*8 + c-'0';
  466. c = getc();
  467. if(c >= '0' && c <= '7') {
  468. l = l*8 + c-'0';
  469. return l;
  470. }
  471. }
  472. peekc = c;
  473. return l;
  474. }
  475. switch(c)
  476. {
  477. case '\n': goto loop;
  478. case 'n': return '\n';
  479. case 't': return '\t';
  480. case 'b': return '\b';
  481. case 'r': return '\r';
  482. case 'f': return '\f';
  483. case 'a': return 0x07;
  484. case 'v': return 0x0b;
  485. case 'z': return 0x00;
  486. }
  487. return c;
  488. }
  489. void
  490. pinit(char *f)
  491. {
  492. int i;
  493. Sym *s;
  494. lineno = 1;
  495. newio();
  496. newfile(f, -1);
  497. pc = 0;
  498. peekc = IGN;
  499. sym = 1;
  500. for(i=0; i<NSYM; i++) {
  501. h[i].type = 0;
  502. h[i].sym = S;
  503. }
  504. for(i=0; i<NHASH; i++)
  505. for(s = hash[i]; s != S; s = s->link)
  506. s->macro = 0;
  507. }
  508. int
  509. filbuf(void)
  510. {
  511. Io *i;
  512. loop:
  513. i = iostack;
  514. if(i == I)
  515. return EOF;
  516. if(i->f < 0)
  517. goto pop;
  518. fi.c = read(i->f, i->b, BUFSIZ) - 1;
  519. if(fi.c < 0) {
  520. close(i->f);
  521. linehist(0, 0);
  522. goto pop;
  523. }
  524. fi.p = i->b + 1;
  525. return i->b[0];
  526. pop:
  527. iostack = i->link;
  528. i->link = iofree;
  529. iofree = i;
  530. i = iostack;
  531. if(i == I)
  532. return EOF;
  533. fi.p = i->p;
  534. fi.c = i->c;
  535. if(--fi.c < 0)
  536. goto loop;
  537. return *fi.p++;
  538. }
  539. void
  540. yyerror(char *a, ...)
  541. {
  542. char buf[200];
  543. va_list arg;
  544. /*
  545. * hack to intercept message from yaccpar
  546. */
  547. if(strcmp(a, "syntax error") == 0) {
  548. yyerror("syntax error, last name: %s", symb);
  549. return;
  550. }
  551. prfile(lineno);
  552. va_start(arg, a);
  553. vseprint(buf, buf+sizeof(buf), a, arg);
  554. va_end(arg);
  555. print("%s\n", buf);
  556. nerrors++;
  557. if(nerrors > 10) {
  558. print("too many errors\n");
  559. errorexit();
  560. }
  561. }
  562. void
  563. prfile(long l)
  564. {
  565. int i, n;
  566. Hist a[HISTSZ], *h;
  567. long d;
  568. n = 0;
  569. for(h = hist; h != H; h = h->link) {
  570. if(l < h->line)
  571. break;
  572. if(h->name) {
  573. if(h->offset == 0) {
  574. if(n >= 0 && n < HISTSZ)
  575. a[n] = *h;
  576. n++;
  577. continue;
  578. }
  579. if(n > 0 && n < HISTSZ)
  580. if(a[n-1].offset == 0) {
  581. a[n] = *h;
  582. n++;
  583. } else
  584. a[n-1] = *h;
  585. continue;
  586. }
  587. n--;
  588. if(n >= 0 && n < HISTSZ) {
  589. d = h->line - a[n].line;
  590. for(i=0; i<n; i++)
  591. a[i].line += d;
  592. }
  593. }
  594. if(n > HISTSZ)
  595. n = HISTSZ;
  596. for(i=0; i<n; i++)
  597. print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
  598. }
  599. void
  600. ieeedtod(Ieee *ieee, double native)
  601. {
  602. double fr, ho, f;
  603. int exp;
  604. if(native < 0) {
  605. ieeedtod(ieee, -native);
  606. ieee->h |= 0x80000000L;
  607. return;
  608. }
  609. if(native == 0) {
  610. ieee->l = 0;
  611. ieee->h = 0;
  612. return;
  613. }
  614. fr = frexp(native, &exp);
  615. f = 2097152L; /* shouldnt use fp constants here */
  616. fr = modf(fr*f, &ho);
  617. ieee->h = ho;
  618. ieee->h &= 0xfffffL;
  619. ieee->h |= (exp+1022L) << 20;
  620. f = 65536L;
  621. fr = modf(fr*f, &ho);
  622. ieee->l = ho;
  623. ieee->l <<= 16;
  624. ieee->l |= (long)(fr*f);
  625. }