lexbody 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  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. lineno++;
  381. goto l0;
  382. }
  383. if(c == EOF) {
  384. yyerror("eof in comment");
  385. errorexit();
  386. }
  387. }
  388. }
  389. if(c1 == '*') {
  390. for(;;) {
  391. c = GETC();
  392. while(c == '*') {
  393. c = GETC();
  394. if(c == '/')
  395. goto l0;
  396. }
  397. if(c == EOF) {
  398. yyerror("eof in comment");
  399. errorexit();
  400. }
  401. if(c == '\n')
  402. lineno++;
  403. }
  404. }
  405. break;
  406. default:
  407. return c;
  408. }
  409. peekc = c1;
  410. return c;
  411. }
  412. int
  413. getc(void)
  414. {
  415. int c;
  416. c = peekc;
  417. if(c != IGN) {
  418. peekc = IGN;
  419. return c;
  420. }
  421. c = GETC();
  422. if(c == '\n')
  423. lineno++;
  424. if(c == EOF) {
  425. yyerror("End of file");
  426. errorexit();
  427. }
  428. return c;
  429. }
  430. int
  431. getnsc(void)
  432. {
  433. int c;
  434. for(;;) {
  435. c = getc();
  436. if(!isspace(c) || c == '\n')
  437. return c;
  438. }
  439. }
  440. void
  441. unget(int c)
  442. {
  443. peekc = c;
  444. if(c == '\n')
  445. lineno--;
  446. }
  447. int
  448. escchar(int e)
  449. {
  450. int c, l;
  451. loop:
  452. c = getc();
  453. if(c == '\n') {
  454. yyerror("newline in string");
  455. return EOF;
  456. }
  457. if(c != '\\') {
  458. if(c == e)
  459. return EOF;
  460. return c;
  461. }
  462. c = getc();
  463. if(c >= '0' && c <= '7') {
  464. l = c - '0';
  465. c = getc();
  466. if(c >= '0' && c <= '7') {
  467. l = l*8 + c-'0';
  468. c = getc();
  469. if(c >= '0' && c <= '7') {
  470. l = l*8 + c-'0';
  471. return l;
  472. }
  473. }
  474. peekc = c;
  475. return l;
  476. }
  477. switch(c)
  478. {
  479. case '\n': goto loop;
  480. case 'n': return '\n';
  481. case 't': return '\t';
  482. case 'b': return '\b';
  483. case 'r': return '\r';
  484. case 'f': return '\f';
  485. case 'a': return 0x07;
  486. case 'v': return 0x0b;
  487. case 'z': return 0x00;
  488. }
  489. return c;
  490. }
  491. void
  492. pinit(char *f)
  493. {
  494. int i;
  495. Sym *s;
  496. lineno = 1;
  497. newio();
  498. newfile(f, -1);
  499. pc = 0;
  500. peekc = IGN;
  501. sym = 1;
  502. for(i=0; i<NSYM; i++) {
  503. h[i].type = 0;
  504. h[i].sym = S;
  505. }
  506. for(i=0; i<NHASH; i++)
  507. for(s = hash[i]; s != S; s = s->link)
  508. s->macro = 0;
  509. }
  510. int
  511. filbuf(void)
  512. {
  513. Io *i;
  514. loop:
  515. i = iostack;
  516. if(i == I)
  517. return EOF;
  518. if(i->f < 0)
  519. goto pop;
  520. fi.c = read(i->f, i->b, BUFSIZ) - 1;
  521. if(fi.c < 0) {
  522. close(i->f);
  523. linehist(0, 0);
  524. goto pop;
  525. }
  526. fi.p = i->b + 1;
  527. return i->b[0];
  528. pop:
  529. iostack = i->link;
  530. i->link = iofree;
  531. iofree = i;
  532. i = iostack;
  533. if(i == I)
  534. return EOF;
  535. fi.p = i->p;
  536. fi.c = i->c;
  537. if(--fi.c < 0)
  538. goto loop;
  539. return *fi.p++;
  540. }
  541. void
  542. yyerror(char *a, ...)
  543. {
  544. char buf[200];
  545. va_list arg;
  546. /*
  547. * hack to intercept message from yaccpar
  548. */
  549. if(strcmp(a, "syntax error") == 0) {
  550. yyerror("syntax error, last name: %s", symb);
  551. return;
  552. }
  553. prfile(lineno);
  554. va_start(arg, a);
  555. vseprint(buf, buf+sizeof(buf), a, arg);
  556. va_end(arg);
  557. print("%s\n", buf);
  558. nerrors++;
  559. if(nerrors > 10) {
  560. print("too many errors\n");
  561. errorexit();
  562. }
  563. }
  564. void
  565. prfile(long l)
  566. {
  567. int i, n;
  568. Hist a[HISTSZ], *h;
  569. long d;
  570. n = 0;
  571. for(h = hist; h != H; h = h->link) {
  572. if(l < h->line)
  573. break;
  574. if(h->name) {
  575. if(h->offset == 0) {
  576. if(n >= 0 && n < HISTSZ)
  577. a[n] = *h;
  578. n++;
  579. continue;
  580. }
  581. if(n > 0 && n < HISTSZ)
  582. if(a[n-1].offset == 0) {
  583. a[n] = *h;
  584. n++;
  585. } else
  586. a[n-1] = *h;
  587. continue;
  588. }
  589. n--;
  590. if(n >= 0 && n < HISTSZ) {
  591. d = h->line - a[n].line;
  592. for(i=0; i<n; i++)
  593. a[i].line += d;
  594. }
  595. }
  596. if(n > HISTSZ)
  597. n = HISTSZ;
  598. for(i=0; i<n; i++)
  599. print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
  600. }
  601. void
  602. ieeedtod(Ieee *ieee, double native)
  603. {
  604. double fr, ho, f;
  605. int exp;
  606. if(native < 0) {
  607. ieeedtod(ieee, -native);
  608. ieee->h |= 0x80000000L;
  609. return;
  610. }
  611. if(native == 0) {
  612. ieee->l = 0;
  613. ieee->h = 0;
  614. return;
  615. }
  616. fr = frexp(native, &exp);
  617. f = 2097152L; /* shouldnt use fp constants here */
  618. fr = modf(fr*f, &ho);
  619. ieee->h = ho;
  620. ieee->h &= 0xfffffL;
  621. ieee->h |= (exp+1022L) << 20;
  622. f = 65536L;
  623. fr = modf(fr*f, &ho);
  624. ieee->l = ho;
  625. ieee->l <<= 16;
  626. ieee->l |= (long)(fr*f);
  627. }