lexbody 8.5 KB

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