PageRenderTime 97ms CodeModel.GetById 54ms RepoModel.GetById 1ms app.codeStats 0ms

/zmac/zmac.y

https://bitbucket.org/sgraham/sayyoho
Happy | 3886 lines | 3489 code | 397 blank | 0 comment | 0 complexity | f0d98eb2827095270fc65d3e7d32019e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. %{
  2. /*
  3. * zmac -- macro cross-assembler for the Zilog Z80 microprocessor
  4. *
  5. * Bruce Norskog 4/78
  6. *
  7. * Last modification 2000-07-01 by mgr
  8. *
  9. * This assembler is modeled after the Intel 8080 macro cross-assembler
  10. * for the Intel 8080 by Ken Borgendale. The major features are:
  11. * 1. Full macro capabilities
  12. * 2. Conditional assembly
  13. * 3. A very flexible set of listing options and pseudo-ops
  14. * 4. Symbol table output
  15. * 5. Error report
  16. * 6. Elimination of sequential searching
  17. * 7. Commenting of source
  18. * 8. Facilities for system definiton files
  19. *
  20. * (Revision history is now in ChangeLog. -rjm)
  21. */
  22. #define ZMAC_VERSION "1.3"
  23. /* #define ZMAC_BETA "b4" */
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <stdarg.h>
  28. #include <time.h>
  29. #include "mio.h"
  30. #include "getoptn.h"
  31. #define UNUSED(var) ((void) var)
  32. #if defined (__riscos__) && !defined (__riscos)
  33. #define __riscos
  34. #endif
  35. #ifdef __riscos
  36. #include "swis.h"
  37. #define DDEUtils_Prefix 0x42580
  38. #define DDEUtils_ThrowbackStart 0x42587
  39. #define DDEUtils_ThrowbackSend 0x42588
  40. #define DDEUtils_ThrowbackEnd 0x42589
  41. #endif
  42. #ifndef OS_DIR_SEP
  43. #if defined (MSDOS)
  44. #define OS_DIR_SEP '\\'
  45. #elif defined (__riscos)
  46. #define OS_DIR_SEP '.'
  47. #else
  48. #define OS_DIR_SEP '/'
  49. #endif
  50. #endif
  51. #ifndef OS_EXT_SEP
  52. #if defined (__riscos)
  53. #define OS_EXT_SEP '/'
  54. #else
  55. #define OS_EXT_SEP '.'
  56. #endif
  57. #endif
  58. /*
  59. * DEBUG turns on pass reporting.
  60. * Macro debug and Token debug enables.
  61. #define DEBUG
  62. #define M_DEBUG
  63. #define T_DEBUG
  64. */
  65. #define ITEMTABLESIZE 2000
  66. #define TEMPBUFSIZE 200
  67. #define LINEBUFFERSIZE 200
  68. #define EMITBUFFERSIZE 200
  69. #define MAXSYMBOLSIZE 40
  70. #define IFSTACKSIZE 20
  71. #define MAXIFS 1024
  72. #define TITLELEN 50
  73. #define BINPERLINE 16
  74. #define PARMMAX 25
  75. #define MAXEXP 25
  76. #define SYMMAJIC 07203
  77. #define NEST_IN 8
  78. #define loop for(;;)
  79. void yyerror(char *err)
  80. {
  81. UNUSED (err); /* we will do our own error printing */
  82. /* printf ("Oops! %s\n", err); */
  83. }
  84. struct item {
  85. char *i_string;
  86. int i_value;
  87. int i_token;
  88. int i_uses;
  89. int i_equbad;
  90. };
  91. FILE *fout,
  92. *fbuf,
  93. *fin[NEST_IN],
  94. *now_file ;
  95. int pass2; /* set when pass one completed */
  96. int dollarsign ; /* location counter */
  97. int olddollar ; /* kept to put out binary */
  98. /* program counter save for PHASE/DEPHASE */
  99. int phdollar, phbegin, phaseflag ;
  100. char *src_name[NEST_IN] ;
  101. int linein[NEST_IN] ;
  102. int now_in ;
  103. #define bflag 0 /* balance error */
  104. #define eflag 1 /* expression error */
  105. #define fflag 2 /* syntax error */
  106. #define iflag 3 /* bad digits */
  107. #define mflag 4 /* multiply defined */
  108. #define pflag 5 /* phase error */
  109. #define uflag 6 /* undeclared used */
  110. #define vflag 7 /* value out of range */
  111. #define oflag 8 /* phase/dephase error */
  112. #define frflag 9 /* double forward ref. via equ error */
  113. #define zflag 10 /* Z80-only instruction (when `-z' option in use) */
  114. #define orgflag 11 /* retrograde org error (when `-h' option not in use) */
  115. #define FLAGS 12 /* number of flags */
  116. char err[FLAGS];
  117. int keeperr[FLAGS];
  118. char errlet[FLAGS]="BEFIMPUVORZG";
  119. char *errname[FLAGS]={
  120. "Balance",
  121. "Expression",
  122. "Syntax",
  123. "Digit",
  124. "Mult. def.",
  125. "Phase",
  126. "Undeclared",
  127. "Value",
  128. "Phase/Dephase",
  129. "Forward ref. to EQU with forward ref.",
  130. "Z80-specific instruction",
  131. "Retrograde ORG"
  132. };
  133. char *warnname[]={
  134. "Symbol length exceeded",
  135. "Non-standard syntax",
  136. "Could replace JP with JR",
  137. "Could replace LD A, 0 with XOR A if flags unimportant",
  138. "Could replace RLC A with RLCA if S, Z and P/V flags unimportant",
  139. "Could replace RRC A with RRCA if S, Z and P/V flags unimportant",
  140. "Could replace RL A with RLA if S, Z and P/V flags unimportant",
  141. "Could replace RR A with RRA if S, Z and P/V flags unimportant",
  142. "Could replace SLA A with ADD A, A if H and P/V flags unimportant"
  143. };
  144. /* for "0 symbols", "1 symbol", "2 symbols", etc. */
  145. #define DO_PLURAL(x) (x),((x)==1)?"":"s"
  146. char linebuf[LINEBUFFERSIZE];
  147. char *lineptr;
  148. char *linemax = linebuf+LINEBUFFERSIZE;
  149. char outbin[BINPERLINE];
  150. char *outbinp = outbin;
  151. char *outbinm = outbin+BINPERLINE;
  152. char emitbuf[EMITBUFFERSIZE];
  153. char *emitptr;
  154. char ifstack[IFSTACKSIZE];
  155. char *ifptr;
  156. char *ifstmax = ifstack+IFSTACKSIZE-1;
  157. char expif[MAXIFS];
  158. char *expifp;
  159. char *expifmax = expif+MAXIFS;
  160. char hexadec[] = "0123456789ABCDEF" ;
  161. char *expstack[MAXEXP];
  162. int expptr;
  163. int nitems;
  164. int linecnt;
  165. int nbytes;
  166. int invented;
  167. char tempbuf[TEMPBUFSIZE];
  168. char *tempmax = tempbuf+TEMPBUFSIZE-1;
  169. char inmlex;
  170. char arg_flag;
  171. char quoteflag;
  172. int parm_number;
  173. int exp_number;
  174. char symlong[] = "Symbol too long";
  175. int disp;
  176. #define FLOC PARMMAX
  177. #define TEMPNUM PARMMAX+1
  178. char **est;
  179. char **est2;
  180. char *floc;
  181. int mfptr;
  182. FILE *mfile;
  183. char *title;
  184. char titlespace[TITLELEN];
  185. char *timp;
  186. char *sourcef;
  187. /* changed to cope with filenames longer than 14 chars -rjm 1998-12-15 */
  188. char src[1024];
  189. char bin[1024];
  190. char mtmp[1024];
  191. char listf[1024];
  192. char writesyms[1024];
  193. #ifdef __riscos
  194. char riscos_thbkf[1024];
  195. #endif
  196. char bopt = 1,
  197. edef = 1,
  198. eopt = 1,
  199. fdef = 0,
  200. fopt = 0,
  201. gdef = 1,
  202. gopt = 1,
  203. iopt = 0 , /* list include files */
  204. lstoff = 0,
  205. lston = 0, /* flag to force listing on */
  206. lopt = 0,
  207. mdef = 0,
  208. mopt = 0,
  209. nopt = 1, /* line numbers on as default */
  210. oldoopt = 0,
  211. popt = 1, /* form feed as default page eject */
  212. sopt = 0, /* turn on symbol table listing */
  213. output_hex = 0, /* `-h', output .hex rather than .bin -rjm */
  214. output_8080_only = 0, /* `-z', output 8080-compat. ops only -rjm */
  215. show_error_line = 0, /* `-S', show line which caused error -rjm */
  216. terse_lst_errors = 0, /* `-t', terse errors in listing -rjm */
  217. continuous_listing = 1, /* `-d', discontinuous - with page breaks */
  218. suggest_optimise = 0, /* `-O', suggest optimisations -mgr */
  219. #ifdef __riscos
  220. riscos_thbk = 0, /* `-T', RISC OS throwback -mep */
  221. #endif
  222. output_amsdos = 0, /* `-A', AMSDOS binary file output -mep */
  223. saveopt;
  224. char xeq_flag = 0;
  225. int xeq;
  226. time_t now;
  227. int line;
  228. int page = 1;
  229. int had_errors = 0; /* if program had errors, do exit(1) */
  230. #ifdef __riscos
  231. int riscos_throwback_started = 0;
  232. #endif
  233. int not_seen_org = 1;
  234. int first_org_store = 0;
  235. struct stab {
  236. char t_name[MAXSYMBOLSIZE+1];
  237. int t_value;
  238. int t_token;
  239. };
  240. /*
  241. * push back character
  242. */
  243. int peekc;
  244. /* function prototypes */
  245. int addtoline(int ac);
  246. int iflist(void);
  247. int yylex(void);
  248. int tokenofitem(int deftoken);
  249. int nextchar(void);
  250. int skipline(int ac);
  251. void usage(void);
  252. int main(int argc, char *argv[]);
  253. int getarg(void);
  254. int getm(void);
  255. void yyerror(char *err);
  256. void emit(int num, ...);
  257. void emit1(int opcode,int regvalh,int data16,int type);
  258. void emitdad(int rp1,int rp2);
  259. void emitjr(int opcode,int expr);
  260. void emitjp(int opcode,int expr);
  261. void putbin(int v);
  262. void flushbin(void);
  263. void puthex(char byte, FILE *buf);
  264. void list(int optarg);
  265. void lineout(void);
  266. void eject(void);
  267. void space(int n);
  268. void lsterr1(void);
  269. void lsterr2(int lst);
  270. void errorprt(int errnum);
  271. void warnprt(int warnnum, int warnoff);
  272. void list1(void);
  273. void interchange(int i, int j);
  274. void custom_qsort(int m, int n);
  275. void setvars(void);
  276. void error(char *as);
  277. void fileerror(char *as,char *filename);
  278. void justerror(char *as);
  279. void putsymtab(void);
  280. void erreport(void);
  281. void mlex(void);
  282. void suffix_if_none(char *str,char *suff);
  283. void suffix(char *str,char *suff);
  284. void decanonicalise(char *str);
  285. void putm(char c);
  286. void popsi(void);
  287. char *getlocal(int c, int n);
  288. void insymtab(char *name);
  289. void outsymtab(char *name);
  290. void copyname(char *st1, char *st2);
  291. void next_source(char *sp);
  292. void doatexit (void);
  293. #ifdef __riscos
  294. void riscos_set_csd(char *sp);
  295. void riscos_throwback(int severity, char *file, int line, char *error);
  296. #endif
  297. /*
  298. * add a character to the output line buffer
  299. */
  300. int addtoline(int ac)
  301. {
  302. /* check for EOF from stdio */
  303. if (ac == -1)
  304. ac = 0 ;
  305. if (inmlex)
  306. return(ac);
  307. if (lineptr >= linemax)
  308. error("line buffer overflow");
  309. *lineptr++ = ac;
  310. return(ac);
  311. }
  312. /*
  313. * put values in buffer for outputing
  314. */
  315. void emit(int bytes, ...)
  316. {
  317. va_list ap;
  318. unsigned char *oldemitptr=(unsigned char *)emitptr;
  319. int c;
  320. va_start(ap,bytes);
  321. while (--bytes >= 0)
  322. if (emitptr >= &emitbuf[EMITBUFFERSIZE])
  323. error("emit buffer overflow");
  324. else {
  325. *emitptr++ = va_arg(ap,int);
  326. }
  327. if (output_8080_only) {
  328. /* test for Z80-specific ops. These start with one of
  329. * sixteen byte values, listed below. The values were
  330. * taken from "A Z80 Workshop Manual" by E. A. Parr. -rjm
  331. */
  332. /* As far as I can tell from my own literature
  333. * review, 0x02, 0x0a, 0x12 and 0x1a are valid
  334. * 8080 opcodes (LDAX/STAX B/D) -mgr
  335. */
  336. c=*oldemitptr;
  337. if (/* c==0x02 || */ c==0x08 || /* c==0x0a || */ c==0x10 ||
  338. /* c==0x12 || */ c==0x18 || /* c==0x1a || */ c==0x20 ||
  339. c==0x28 || c==0x30 || c==0x38 || c==0xcb ||
  340. c==0xd9 || c==0xdd || c==0xed || c==0xfd)
  341. err[zflag]++;
  342. }
  343. va_end(ap);
  344. }
  345. /* for emitted data - as above, without 8080 test.
  346. * Duplicating the code was easier than putting an extra arg in all
  347. * those emit()s. :-} Hopefully this isn't too unbearably nasty. -rjm
  348. */
  349. void dataemit(int bytes, ...)
  350. {
  351. va_list ap;
  352. va_start(ap,bytes);
  353. while (--bytes >= 0)
  354. if (emitptr >= &emitbuf[EMITBUFFERSIZE])
  355. error("emit buffer overflow");
  356. else {
  357. *emitptr++ = va_arg(ap,int);
  358. }
  359. va_end(ap);
  360. }
  361. void emit1(int opcode,int regvalh,int data16,int type)
  362. {
  363. if ((regvalh & 0x8000)) { /* extra brackets to silence -Wall */
  364. if ((type & 1) == 0 && (disp > 127 || disp < -128))
  365. err[vflag]++;
  366. switch(type) {
  367. case 0:
  368. if (opcode & 0x8000)
  369. emit(4, regvalh >> 8, opcode >> 8, disp, opcode);
  370. else
  371. emit(3, regvalh >> 8, opcode, disp);
  372. break;
  373. case 1:
  374. emit(2, regvalh >> 8, opcode);
  375. break;
  376. case 2:
  377. if (data16 > 255 || data16 < -128)
  378. err[vflag]++;
  379. emit(4, regvalh >> 8, opcode, disp, data16);
  380. break;
  381. case 5:
  382. emit(4, regvalh >> 8, opcode, data16, data16 >> 8);
  383. }
  384. } else
  385. switch(type) {
  386. case 0:
  387. if (opcode & 0100000)
  388. emit(2, opcode >> 8, opcode);
  389. else
  390. emit(1, opcode);
  391. break;
  392. case 1:
  393. if (opcode & 0100000)
  394. emit(2, opcode >> 8, opcode);
  395. else
  396. emit(1, opcode);
  397. break;
  398. case 2:
  399. if (data16 > 255 || data16 < -128)
  400. err[vflag]++;
  401. emit(2, opcode, data16);
  402. break;
  403. case 3:
  404. if (data16 >255 || data16 < -128)
  405. err[vflag]++;
  406. emit(2, opcode, data16);
  407. break;
  408. case 5:
  409. if (opcode & 0100000)
  410. emit(4, opcode >> 8, opcode, data16, data16 >> 8);
  411. else
  412. emit(3, opcode, data16, data16 >> 8);
  413. }
  414. }
  415. void emitdad(int rp1,int rp2)
  416. {
  417. if (rp1 & 0x8000)
  418. emit(2,rp1 >> 8, rp2 + 9);
  419. else
  420. emit(1,rp2 + 9);
  421. }
  422. void emitjr(int opcode,int expr)
  423. {
  424. disp = expr - dollarsign - 2;
  425. if (disp > 127 || disp < -128)
  426. err[vflag]++;
  427. emit(2, opcode, disp);
  428. }
  429. void emitjp(int opcode,int expr)
  430. {
  431. if (suggest_optimise && pass2 && opcode <= 0xda && !output_8080_only) {
  432. disp = expr - dollarsign - 2;
  433. if (disp <= 127 && disp >= -128)
  434. warnprt (2, 0);
  435. }
  436. emit(3, opcode, expr, expr >> 8);
  437. }
  438. /*
  439. * put out a byte of binary
  440. */
  441. void putbin(int v)
  442. {
  443. if(!pass2 || !bopt) return;
  444. *outbinp++ = v;
  445. if (outbinp >= outbinm) flushbin();
  446. }
  447. /*
  448. * output one line of binary in INTEL standard form
  449. */
  450. void flushbin()
  451. {
  452. char *p;
  453. int check=outbinp-outbin;
  454. if (!pass2 || !bopt)
  455. return;
  456. nbytes += check;
  457. if (check) {
  458. if (output_hex) {
  459. putc(':', fbuf);
  460. puthex(check, fbuf);
  461. puthex(olddollar>>8, fbuf);
  462. puthex(olddollar, fbuf);
  463. puthex(0, fbuf);
  464. }
  465. check += (olddollar >> 8) + olddollar;
  466. olddollar += (outbinp-outbin);
  467. for (p=outbin; p<outbinp; p++) {
  468. if (output_hex)
  469. puthex(*p, fbuf);
  470. else
  471. fputc(*p, fbuf);
  472. check += *p;
  473. }
  474. if (output_hex) {
  475. puthex(256-check, fbuf);
  476. putc('\n', fbuf);
  477. }
  478. outbinp = outbin;
  479. }
  480. }
  481. /*
  482. * put out one byte of hex
  483. */
  484. void puthex(char byte, FILE *buf)
  485. {
  486. putc(hexadec[(byte >> 4) & 017], buf);
  487. putc(hexadec[byte & 017], buf);
  488. }
  489. /*
  490. * put out a line of output -- also put out binary
  491. */
  492. void list(int optarg)
  493. {
  494. char * p;
  495. int i;
  496. int lst;
  497. if (!expptr)
  498. linecnt++;
  499. addtoline('\0');
  500. if (pass2) {
  501. lst = iflist();
  502. if (lst) {
  503. lineout();
  504. if (nopt)
  505. fprintf(fout, "%4d:\t", linein[now_in]);
  506. puthex(optarg >> 8, fout);
  507. puthex(optarg, fout);
  508. fputs(" ", fout);
  509. for (p = emitbuf; (p < emitptr) && (p - emitbuf < 4); p++) {
  510. puthex(*p, fout);
  511. }
  512. for (i = 4 - (p-emitbuf); i > 0; i--)
  513. fputs(" ", fout);
  514. putc('\t', fout);
  515. fputs(linebuf, fout);
  516. }
  517. if (bopt) {
  518. for (p = emitbuf; p < emitptr; p++)
  519. putbin(*p);
  520. }
  521. p = emitbuf+4;
  522. while (lst && gopt && p < emitptr) {
  523. lineout();
  524. if (nopt) putc('\t', fout);
  525. fputs(" ", fout);
  526. for (i = 0; (i < 4) && (p < emitptr);i++) {
  527. puthex(*p, fout);
  528. p++;
  529. }
  530. putc('\n', fout);
  531. }
  532. lsterr2(lst);
  533. } else
  534. lsterr1();
  535. dollarsign += emitptr - emitbuf;
  536. emitptr = emitbuf;
  537. lineptr = linebuf;
  538. }
  539. /*
  540. * keep track of line numbers and put out headers as necessary
  541. */
  542. void lineout()
  543. {
  544. if (continuous_listing) {
  545. line = 1;
  546. return;
  547. }
  548. if (line == 60) {
  549. if (popt)
  550. putc('\014', fout); /* send the form feed */
  551. else
  552. fputs("\n\n\n\n\n", fout);
  553. line = 0;
  554. }
  555. if (line == 0) {
  556. fprintf(fout, "\n\n%s %s\t%s\t Page %d\n\n\n",
  557. &timp[4], &timp[20], title, page++);
  558. line = 4;
  559. }
  560. line++;
  561. }
  562. /*
  563. * cause a page eject
  564. */
  565. void eject()
  566. {
  567. if (pass2 && !continuous_listing && iflist()) {
  568. if (popt) {
  569. putc('\014', fout); /* send the form feed */
  570. } else {
  571. while (line < 65) {
  572. line++;
  573. putc('\n', fout);
  574. }
  575. }
  576. }
  577. line = 0;
  578. }
  579. /*
  580. * space n lines on the list file
  581. */
  582. void space(int n)
  583. {
  584. int i ;
  585. if (pass2 && iflist())
  586. for (i = 0; i<n; i++) {
  587. lineout();
  588. putc('\n', fout);
  589. }
  590. }
  591. /*
  592. * Error handling - pass 1
  593. */
  594. void lsterr1()
  595. {
  596. int i;
  597. for (i = 0; i <= 4; i++)
  598. if (err[i]) {
  599. errorprt(i);
  600. err[i] = 0;
  601. }
  602. }
  603. /*
  604. * Error handling - pass 2.
  605. */
  606. void lsterr2(int lst)
  607. {
  608. int i;
  609. for (i=0; i<FLAGS; i++)
  610. if (err[i]) {
  611. if (lst) {
  612. lineout();
  613. /* verbose inline error messages now,
  614. * must override with `-t' to get old
  615. * behaviour. -rjm
  616. */
  617. if (terse_lst_errors)
  618. putc(errlet[i], fout);
  619. else
  620. fprintf(fout,"*** %s error ***",
  621. errname[i]);
  622. putc('\n', fout);
  623. }
  624. err[i] = 0;
  625. keeperr[i]++;
  626. if (i > 4)
  627. errorprt(i);
  628. }
  629. fflush(fout); /* to avoid putc(har) mix bug */
  630. }
  631. /*
  632. * print diagnostic to error terminal
  633. */
  634. void errorprt(int errnum)
  635. {
  636. had_errors=1;
  637. fprintf(stderr,"%s:%d: %s error\n",
  638. src_name[now_in], linein[now_in], errname[errnum]);
  639. if(show_error_line)
  640. fprintf(stderr, "%s\n", linebuf);
  641. #ifdef __riscos
  642. if (riscos_thbk)
  643. riscos_throwback (1, src_name[now_in], linein[now_in], errname[errnum]);
  644. #endif
  645. }
  646. /*
  647. * print warning to error terminal
  648. */
  649. void warnprt(int warnnum, int warnoff)
  650. {
  651. fprintf(stderr,"%s:%d: warning: %s\n",
  652. src_name[now_in], linein[now_in] + warnoff, warnname[warnnum]);
  653. /* Offset needed if warning issued while line is being parsed */
  654. #ifdef __riscos
  655. if (riscos_thbk)
  656. riscos_throwback (0, src_name[now_in], linein[now_in] + warnoff, warnname[warnnum]);
  657. #endif
  658. /* if(show_error_line)
  659. Can't show line because it isn't necessarily complete
  660. fprintf(stderr, "%s\n", linebuf); */
  661. }
  662. /*
  663. * list without address -- for comments and if skipped lines
  664. */
  665. void list1()
  666. {
  667. int lst;
  668. addtoline('\0');
  669. lineptr = linebuf;
  670. if (!expptr) linecnt++;
  671. if (pass2)
  672. {
  673. if ((lst = iflist())) {
  674. lineout();
  675. if (nopt)
  676. fprintf(fout, "%4d:\t", linein[now_in]);
  677. fprintf(fout, "\t\t%s", linebuf);
  678. lsterr2(lst);
  679. }
  680. } else
  681. lsterr1();
  682. }
  683. /*
  684. * see if listing is desired
  685. */
  686. int iflist()
  687. {
  688. int i, j;
  689. if (lston)
  690. return(1) ;
  691. if (lopt)
  692. return(0);
  693. if (*ifptr && !fopt)
  694. return(0);
  695. if (!lstoff && !expptr)
  696. return(1);
  697. j = 0;
  698. for (i=0; i<FLAGS; i++)
  699. if (err[i])
  700. j++;
  701. if (expptr)
  702. return(mopt || j);
  703. if (eopt && j)
  704. return(1);
  705. return(0);
  706. }
  707. /* moved out of %{..%} bit in parse routine because `bison -y'
  708. * didn't like it... -rjm
  709. */
  710. char *cp;
  711. int list_tmp1,list_tmp2;
  712. int equ_bad_label=0;
  713. %}
  714. %union {
  715. struct item *itemptr;
  716. int ival;
  717. char *cval;
  718. }
  719. %token <cval> STRING
  720. %token <itemptr> NOOPERAND
  721. %token <itemptr> ARITHC
  722. %token ADD
  723. %token <itemptr> LOGICAL
  724. %token <itemptr> AND
  725. %token <itemptr> OR
  726. %token <itemptr> XOR
  727. %token <itemptr> BIT
  728. %token CALL
  729. %token <itemptr> INCDEC
  730. %token <itemptr> DJNZ
  731. %token EX
  732. %token <itemptr> IM
  733. %token PHASE
  734. %token DEPHASE
  735. %token <itemptr> IN
  736. %token JP
  737. %token <itemptr> JR
  738. %token LD
  739. %token <itemptr> OUT
  740. %token <itemptr> PUSHPOP
  741. %token <itemptr> RET
  742. %token <itemptr> SHIFT
  743. %token <itemptr> RST
  744. %token <itemptr> REGNAME
  745. %token <itemptr> ACC
  746. %token <itemptr> C
  747. %token <itemptr> RP
  748. %token <itemptr> HL
  749. %token <itemptr> INDEX
  750. %token <itemptr> AF
  751. %token <itemptr> SP
  752. %token <itemptr> MISCREG
  753. %token F
  754. %token <itemptr> COND
  755. %token <itemptr> SPCOND
  756. %token <ival> NUMBER
  757. %token <itemptr> UNDECLARED
  758. %token END
  759. %token ORG
  760. %token DEFB
  761. %token DEFS
  762. %token DEFW
  763. %token EQU
  764. %token DEFL
  765. %token <itemptr> LABEL
  766. %token <itemptr> EQUATED
  767. %token <itemptr> WASEQUATED
  768. %token <itemptr> DEFLED
  769. %token <itemptr> MULTDEF
  770. %token <ival> MOD
  771. %token <ival> SHL
  772. %token <ival> SHR
  773. %token <ival> NOT
  774. %token <ival> LT
  775. %token <ival> GT
  776. %token <ival> EQ
  777. %token <ival> LE
  778. %token <ival> GE
  779. %token <ival> NE
  780. %token IF
  781. %token ELSE
  782. %token ENDIF
  783. %token <itemptr> ARGPSEUDO
  784. %token <itemptr> LIST
  785. %token <itemptr> MINMAX
  786. %token MACRO
  787. %token <itemptr> MNAME
  788. %token <itemptr> OLDMNAME
  789. %token ARG
  790. %token ENDM
  791. %token MPARM
  792. %token <ival> ONECHAR
  793. %token <ival> TWOCHAR
  794. %type <itemptr> label.part symbol
  795. %type <ival> reg evenreg realreg mem pushable bcdesp bcdehlsp mar condition
  796. %type <ival> spcondition noparenexpr parenexpr expression lxexpression
  797. %left '|' OR
  798. %left '^' XOR
  799. %left '&' AND
  800. %left '=' EQ NE
  801. %left '<' '>' LT GT LE GE
  802. %left SHL SHR
  803. %left '+' '-'
  804. %left '*' '/' '%' MOD
  805. %right '!' '~' NOT UNARY
  806. %%
  807. statements:
  808. /* Empty file! */
  809. |
  810. statements statement
  811. ;
  812. statement:
  813. label.part '\n' {
  814. if ($1) list(dollarsign);
  815. else list1();
  816. }
  817. |
  818. label.part operation '\n' {
  819. list(dollarsign);
  820. }
  821. |
  822. symbol EQU expression '\n' {
  823. /* a forward reference to a label in the expression cannot
  824. * be fixed in a forward reference to the EQU;
  825. * it would need three passes. -rjm
  826. */
  827. if(!pass2 && equ_bad_label) {
  828. /* this indicates that the equ has an incorrect
  829. * (i.e. pass 1) value.
  830. */
  831. $1->i_equbad = 1;
  832. } else {
  833. /* but if 2nd pass or no forward reference, it's ok. */
  834. $1->i_equbad = 0;
  835. }
  836. equ_bad_label=0;
  837. switch($1->i_token) {
  838. case UNDECLARED: case WASEQUATED:
  839. $1->i_token = EQUATED;
  840. $1->i_value = $3;
  841. break;
  842. case EQUATED:
  843. if ($1->i_value == $3)
  844. break; /* Allow benign redefinition -mgr */
  845. /* Drop-through intentional */
  846. default:
  847. err[mflag]++;
  848. $1->i_token = MULTDEF;
  849. }
  850. list($3);
  851. }
  852. |
  853. symbol DEFL expression '\n' {
  854. switch($1->i_token) {
  855. case UNDECLARED: case DEFLED:
  856. $1->i_token = DEFLED;
  857. $1->i_value = $3;
  858. break;
  859. default:
  860. err[mflag]++;
  861. $1->i_token = MULTDEF;
  862. }
  863. list($3);
  864. }
  865. |
  866. symbol MINMAX expression ',' expression '\n' {
  867. switch ($1->i_token) {
  868. case UNDECLARED: case DEFLED:
  869. $1->i_token = DEFLED;
  870. if ($2->i_value) /* max */
  871. list($1->i_value = ($3 > $5? $3:$5));
  872. else list($1->i_value = ($3 < $5? $3:$5));
  873. break;
  874. default:
  875. err[mflag]++;
  876. $1->i_token = MULTDEF;
  877. list($1->i_value);
  878. }
  879. }
  880. |
  881. IF expression '\n' {
  882. /* all $2's here were yypc[2].ival before.
  883. * I think the idea was perhaps to allow constants
  884. * only...? Anyway, it now allows any expression -
  885. * which would seem to make sense given the definition
  886. * above, right? :-) -rjm
  887. */
  888. if (ifptr >= ifstmax)
  889. error("Too many ifs");
  890. else {
  891. if (pass2) {
  892. *++ifptr = *expifp++;
  893. if (*ifptr != !($2)) err[pflag]++;
  894. } else {
  895. if (expifp >= expifmax)
  896. error("Too many ifs!");
  897. *expifp++ = !($2);
  898. *++ifptr = !($2);
  899. }
  900. }
  901. saveopt = fopt;
  902. fopt = 1;
  903. list($2);
  904. fopt = saveopt;
  905. }
  906. |
  907. ELSE '\n' {
  908. /* FIXME: it would be nice to spot repeated ELSEs, but how? */
  909. *ifptr = !*ifptr;
  910. saveopt = fopt;
  911. fopt = 1;
  912. list1();
  913. fopt = saveopt;
  914. }
  915. |
  916. ENDIF '\n' {
  917. if (ifptr == ifstack) err[bflag]++;
  918. else --ifptr;
  919. list1();
  920. }
  921. |
  922. label.part END '\n' {
  923. list(dollarsign);
  924. peekc = 0;
  925. }
  926. |
  927. label.part END expression '\n' {
  928. xeq_flag++;
  929. xeq = $3;
  930. list($3);
  931. peekc = 0;
  932. }
  933. |
  934. label.part DEFS expression '\n' {
  935. if ($3 < 0) err[vflag]++;
  936. list(dollarsign);
  937. if ($3) {
  938. flushbin();
  939. dollarsign += $3;
  940. olddollar = dollarsign;
  941. /* if it's not hex output though, we also need
  942. * to output zeroes as appropriate. -rjm
  943. */
  944. if(!output_hex && pass2) {
  945. int f;
  946. for (f=0;f<($3);f++)
  947. fputc(0, fbuf);
  948. }
  949. }
  950. }
  951. |
  952. ARGPSEUDO arg_on ARG arg_off '\n' {
  953. list1();
  954. switch ($1->i_value) {
  955. case 0: /* title */
  956. lineptr = linebuf;
  957. cp = tempbuf;
  958. title = titlespace;
  959. while ((*title++ = *cp++) && (title < &titlespace[TITLELEN]));
  960. *title = 0;
  961. title = titlespace;
  962. break;
  963. case 1: /* rsym */
  964. if (pass2) break;
  965. insymtab(tempbuf);
  966. break;
  967. case 2: /* wsym */
  968. strcpy(writesyms, tempbuf);
  969. break;
  970. case 3: /* include file */
  971. if (*tempbuf == '"' || *tempbuf == '\'')
  972. {
  973. if (tempbuf[strlen (tempbuf) - 1] == '"' || tempbuf[strlen (tempbuf) - 1] == '\'')
  974. tempbuf[strlen (tempbuf) - 1] = 0;
  975. next_source(tempbuf + 1) ;
  976. }
  977. else
  978. {
  979. next_source(tempbuf) ;
  980. }
  981. break ;
  982. }
  983. }
  984. |
  985. ARGPSEUDO arg_on arg_off '\n' {
  986. fprintf(stderr,"ARGPSEUDO error\n");
  987. err[fflag]++;
  988. list(dollarsign);
  989. }
  990. |
  991. LIST '\n' {
  992. list_tmp1=$1->i_value;
  993. list_tmp2=1;
  994. goto dolopt;
  995. }
  996. |
  997. LIST expression '\n' {
  998. list_tmp1=$1->i_value;
  999. list_tmp2=$2;
  1000. dolopt:
  1001. linecnt++;
  1002. if (pass2) {
  1003. lineptr = linebuf;
  1004. switch (list_tmp1) {
  1005. case 0: /* list */
  1006. if (list_tmp2 < 0) lstoff = 1;
  1007. if (list_tmp2 > 0) lstoff = 0;
  1008. break;
  1009. case 1: /* eject */
  1010. if (list_tmp2) eject();
  1011. break;
  1012. case 2: /* space */
  1013. if ((line + list_tmp2) > 60) eject();
  1014. else space(list_tmp2);
  1015. break;
  1016. case 3: /* elist */
  1017. eopt = edef;
  1018. if (list_tmp2 < 0) eopt = 0;
  1019. if (list_tmp2 > 0) eopt = 1;
  1020. break;
  1021. case 4: /* fopt */
  1022. fopt = fdef;
  1023. if (list_tmp2 < 0) fopt = 0;
  1024. if (list_tmp2 > 0) fopt = 1;
  1025. break;
  1026. case 5: /* gopt */
  1027. gopt = gdef;
  1028. if (list_tmp2 < 0) gopt = 1;
  1029. if (list_tmp2 > 0) gopt = 0;
  1030. break;
  1031. case 6: /* mopt */
  1032. mopt = mdef;
  1033. if (list_tmp2 < 0) mopt = 0;
  1034. if (list_tmp2 > 0) mopt = 1;
  1035. }
  1036. }
  1037. }
  1038. |
  1039. UNDECLARED MACRO parm.list '\n' {
  1040. $1->i_token = MNAME;
  1041. $1->i_value = mfptr;
  1042. #ifdef M_DEBUG
  1043. fprintf (stderr, "[UNDECLARED MACRO %s]\n", $1->i_string);
  1044. #endif
  1045. mfseek(mfile, (long)mfptr, 0);
  1046. list1();
  1047. mlex() ;
  1048. parm_number = 0;
  1049. }
  1050. |
  1051. OLDMNAME MACRO {
  1052. $1->i_token = MNAME;
  1053. #ifdef M_DEBUG
  1054. fprintf (stderr, "[OLDNAME MACRO %s]\n", $1->i_string);
  1055. #endif
  1056. while (yychar != ENDM && yychar) {
  1057. while (yychar != '\n' && yychar)
  1058. yychar = yylex();
  1059. list1();
  1060. yychar = yylex();
  1061. }
  1062. while (yychar != '\n' && yychar) yychar = yylex();
  1063. list1();
  1064. yychar = yylex();
  1065. }
  1066. |
  1067. label.part MNAME al arg.list '\n' {
  1068. #ifdef M_DEBUG
  1069. fprintf (stderr, "[MNAME %s]\n", $2->i_string);
  1070. #endif
  1071. $2->i_uses++ ;
  1072. arg_flag = 0;
  1073. parm_number = 0;
  1074. list(dollarsign);
  1075. expptr++;
  1076. est = est2;
  1077. est2 = NULL;
  1078. est[FLOC] = floc;
  1079. est[TEMPNUM] = (char *)(long)exp_number++;
  1080. floc = (char *)(long)($2->i_value);
  1081. mfseek(mfile, (long)floc, 0);
  1082. }
  1083. |
  1084. error {
  1085. err[fflag]++;
  1086. quoteflag = 0;
  1087. arg_flag = 0;
  1088. parm_number = 0;
  1089. if (est2)
  1090. {
  1091. int i;
  1092. for (i=0; i<PARMMAX; i++) {
  1093. if (est2[i])
  1094. #ifdef M_DEBUG
  1095. fprintf (stderr, "[Freeing2 arg%u(%p)]\n", i, est2[i]),
  1096. #endif
  1097. free(est2[i]);
  1098. }
  1099. free(est2);
  1100. est2 = NULL;
  1101. }
  1102. while(yychar != '\n' && yychar != '\0') yychar = yylex();
  1103. list(dollarsign);
  1104. yyclearin;yyerrok;
  1105. }
  1106. ;
  1107. colonordot:
  1108. ':'
  1109. |
  1110. '.'
  1111. ;
  1112. maybecolon:
  1113. /* empty */
  1114. |
  1115. ':'
  1116. ;
  1117. label.part:
  1118. /* empty */
  1119. { $$ = NULL; }
  1120. |
  1121. colonordot symbol {
  1122. switch($2->i_token) {
  1123. case UNDECLARED:
  1124. if (pass2)
  1125. err[pflag]++;
  1126. else {
  1127. $2->i_token = LABEL;
  1128. $2->i_value = dollarsign;
  1129. }
  1130. break;
  1131. case LABEL:
  1132. if (!pass2) {
  1133. $2->i_token = MULTDEF;
  1134. err[mflag]++;
  1135. } else if ($2->i_value != dollarsign)
  1136. err[pflag]++;
  1137. break;
  1138. default:
  1139. err[mflag]++;
  1140. $2->i_token = MULTDEF;
  1141. }
  1142. }
  1143. |
  1144. symbol maybecolon {
  1145. switch($1->i_token) {
  1146. case UNDECLARED:
  1147. if (pass2)
  1148. err[pflag]++;
  1149. else {
  1150. $1->i_token = LABEL;
  1151. $1->i_value = dollarsign;
  1152. }
  1153. break;
  1154. case LABEL:
  1155. if (!pass2) {
  1156. $1->i_token = MULTDEF;
  1157. err[mflag]++;
  1158. } else if ($1->i_value != dollarsign)
  1159. err[pflag]++;
  1160. break;
  1161. default:
  1162. err[mflag]++;
  1163. $1->i_token = MULTDEF;
  1164. }
  1165. }
  1166. ;
  1167. operation:
  1168. NOOPERAND
  1169. { emit1($1->i_value, 0, 0, 1); }
  1170. |
  1171. JP expression
  1172. { emitjp(0303, $2); }
  1173. |
  1174. CALL expression
  1175. { emit(3, 0315, $2, $2 >> 8); }
  1176. |
  1177. RST expression
  1178. { int a = $2, doneerr=0;
  1179. /* added support for normal RST form -rjm */
  1180. if (a >= 8) {
  1181. if ((a&7)!=0) doneerr=1,err[vflag]++;
  1182. a >>= 3;
  1183. }
  1184. if ((a > 7 || a < 0) && !doneerr) /* don't give two errs... */
  1185. err[vflag]++;
  1186. emit(1, $1->i_value + (a << 3));
  1187. }
  1188. |
  1189. ADD expression
  1190. { emit1(0306, 0, $2, 3); if (pass2) warnprt (1, 0); }
  1191. |
  1192. ADD ACC ',' expression
  1193. { emit1(0306, 0, $4, 3); }
  1194. |
  1195. ARITHC expression
  1196. { emit1(0306 + ($1->i_value << 3), 0, $2, 3); if (pass2) warnprt (1, 0); }
  1197. |
  1198. ARITHC ACC ',' expression
  1199. { emit1(0306 + ($1->i_value << 3), 0, $4, 3); }
  1200. |
  1201. LOGICAL expression
  1202. { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
  1203. |
  1204. AND expression
  1205. { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
  1206. |
  1207. OR expression
  1208. { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
  1209. |
  1210. XOR expression
  1211. { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
  1212. |
  1213. LOGICAL ACC ',' expression /* -cdk */
  1214. { emit1(0306 | ($1->i_value << 3), 0, $4, 3); if (pass2) warnprt (1, 0); }
  1215. |
  1216. AND ACC ',' expression /* -cdk */
  1217. { emit1(0306 | ($1->i_value << 3), 0, $4, 3); if (pass2) warnprt (1, 0); }
  1218. |
  1219. OR ACC ',' expression /* -cdk */
  1220. { emit1(0306 | ($1->i_value << 3), 0, $4, 3); if (pass2) warnprt (1, 0); }
  1221. |
  1222. XOR ACC ',' expression /* -cdk */
  1223. { emit1(0306 | ($1->i_value << 3), 0, $4, 3); if (pass2) warnprt (1, 0); }
  1224. |
  1225. ADD reg
  1226. { emit1(0200 + ($2 & 0377), $2, 0, 0); if (pass2) warnprt (1, 0); }
  1227. |
  1228. ADD ACC ',' reg
  1229. { emit1(0200 + ($4 & 0377), $4, 0, 0); }
  1230. |
  1231. ARITHC reg
  1232. { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); if (pass2) warnprt (1, 0); }
  1233. |
  1234. ARITHC ACC ',' reg
  1235. { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); }
  1236. |
  1237. LOGICAL reg
  1238. { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
  1239. |
  1240. AND reg
  1241. { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
  1242. |
  1243. OR reg
  1244. { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
  1245. |
  1246. XOR reg
  1247. { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
  1248. |
  1249. LOGICAL ACC ',' reg /* -cdk */
  1250. { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); if (pass2) warnprt (1, 0); }
  1251. |
  1252. AND ACC ',' reg /* -cdk */
  1253. { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); if (pass2) warnprt (1, 0); }
  1254. |
  1255. OR ACC ',' reg /* -cdk */
  1256. { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); if (pass2) warnprt (1, 0); }
  1257. |
  1258. XOR ACC ',' reg /* -cdk */
  1259. { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); if (pass2) warnprt (1, 0); }
  1260. |
  1261. SHIFT reg
  1262. {
  1263. if (suggest_optimise && pass2 && ($2 & 0377) == 7 && $1->i_value <= 4)
  1264. warnprt ($1->i_value + 4, 0);
  1265. if (pass2 && $1->i_value == 6)
  1266. warnprt (1, 0);
  1267. emit1(0145400 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0);
  1268. }
  1269. |
  1270. INCDEC reg
  1271. { emit1($1->i_value + (($2 & 0377) << 3) + 4, $2, 0, 0); }
  1272. |
  1273. ARITHC HL ',' bcdehlsp
  1274. { if ($1->i_value == 1)
  1275. emit(2,0355,0112+$4);
  1276. else
  1277. emit(2,0355,0102+$4);
  1278. }
  1279. |
  1280. ADD mar ',' bcdesp
  1281. { emitdad($2,$4); }
  1282. |
  1283. ADD mar ',' mar
  1284. {
  1285. if ($2 != $4) {
  1286. fprintf(stderr,"ADD mar, mar error\n");
  1287. err[fflag]++;
  1288. }
  1289. emitdad($2,$4);
  1290. }
  1291. |
  1292. INCDEC evenreg
  1293. { emit1(($1->i_value << 3) + ($2 & 0377) + 3, $2, 0, 1); }
  1294. |
  1295. PUSHPOP pushable
  1296. { emit1($1->i_value + ($2 & 0377), $2, 0, 1); }
  1297. |
  1298. BIT expression ',' reg
  1299. {
  1300. if ($2 < 0 || $2 > 7)
  1301. err[vflag]++;
  1302. emit1($1->i_value + (($2 & 7) << 3) + ($4 & 0377), $4, 0, 0);
  1303. }
  1304. |
  1305. JP condition ',' expression
  1306. { emitjp(0302 + $2, $4); }
  1307. |
  1308. JP '(' mar ')'
  1309. { emit1(0351, $3, 0, 1); }
  1310. |
  1311. JP mar
  1312. { emit1(0351, $2, 0, 1); if (pass2) warnprt (1, 0); }
  1313. |
  1314. CALL condition ',' expression
  1315. { emit(3, 0304 + $2, $4, $4 >> 8); }
  1316. |
  1317. JR expression
  1318. { emitjr(030,$2); }
  1319. |
  1320. JR spcondition ',' expression
  1321. { emitjr($1->i_value + $2, $4); }
  1322. |
  1323. DJNZ expression
  1324. { emitjr($1->i_value, $2); }
  1325. |
  1326. RET
  1327. { emit(1, $1->i_value); }
  1328. |
  1329. RET condition
  1330. { emit(1, 0300 + $2); }
  1331. |
  1332. LD reg ',' reg
  1333. {
  1334. if (($2 & 0377) == 6 && ($4 & 0377) == 6) {
  1335. fprintf(stderr,"LD reg, reg error\n");
  1336. err[fflag]++;
  1337. }
  1338. emit1(0100 + (($2 & 7) << 3) + ($4 & 7),$2 | $4, 0, 0);
  1339. }
  1340. |
  1341. LD reg ',' noparenexpr
  1342. {
  1343. if (suggest_optimise && pass2 && $4 == 0 && ($2 & 0377) == 7)
  1344. warnprt (3, 0);
  1345. emit1(6 + (($2 & 0377) << 3), $2, $4, 2);
  1346. }
  1347. |
  1348. LD reg ',' '(' RP ')'
  1349. { if ($2 != 7) {
  1350. fprintf(stderr,"LD reg, (RP) error\n");
  1351. err[fflag]++;
  1352. }
  1353. else emit(1, 012 + $5->i_value);
  1354. }
  1355. |
  1356. LD reg ',' parenexpr
  1357. {
  1358. if ($2 != 7) {
  1359. fprintf(stderr,"LD reg, (expr) error\n");
  1360. err[fflag]++;
  1361. }
  1362. else emit(3, 072, $4, $4 >> 8);
  1363. }
  1364. |
  1365. LD '(' RP ')' ',' ACC
  1366. { emit(1, 2 + $3->i_value); }
  1367. |
  1368. LD parenexpr ',' ACC
  1369. { emit(3, 062, $2, $2 >> 8); }
  1370. |
  1371. LD reg ',' MISCREG
  1372. {
  1373. if ($2 != 7) {
  1374. fprintf(stderr,"LD reg, MISCREG error\n");
  1375. err[fflag]++;
  1376. }
  1377. else emit(2, 0355, 0127 + $4->i_value);
  1378. }
  1379. |
  1380. LD MISCREG ',' ACC
  1381. { emit(2, 0355, 0107 + $2->i_value); }
  1382. |
  1383. LD evenreg ',' lxexpression
  1384. { emit1(1 + ($2 & 060), $2, $4, 5); }
  1385. |
  1386. LD evenreg ',' parenexpr
  1387. {
  1388. if (($2 & 060) == 040)
  1389. emit1(052, $2, $4, 5);
  1390. else
  1391. emit(4, 0355, 0113 + $2, $4, $4 >> 8);
  1392. }
  1393. |
  1394. LD parenexpr ',' evenreg
  1395. {
  1396. if (($4 & 060) == 040)
  1397. emit1(042, $4, $2, 5);
  1398. else
  1399. emit(4, 0355, 0103 + $4, $2, $2 >> 8);
  1400. }
  1401. |
  1402. LD evenreg ',' mar
  1403. {
  1404. if ($2 != 060) {
  1405. fprintf(stderr,"LD evenreg error\n");
  1406. err[fflag]++;
  1407. }
  1408. else
  1409. emit1(0371, $4, 0, 1);
  1410. }
  1411. |
  1412. EX RP ',' HL
  1413. {
  1414. if ($2->i_value != 020) {
  1415. fprintf(stderr,"EX RP, HL error\n");
  1416. err[fflag]++;
  1417. }
  1418. else
  1419. emit(1, 0353);
  1420. }
  1421. |
  1422. EX AF ',' AF setqf '\'' clrqf
  1423. { emit(1, 010); }
  1424. |
  1425. EX '(' SP ')' ',' mar
  1426. { emit1(0343, $6, 0, 1); }
  1427. |
  1428. IN realreg ',' parenexpr
  1429. {
  1430. if ($2 != 7) {
  1431. fprintf(stderr,"IN reg, (expr) error\n");
  1432. err[fflag]++;
  1433. }
  1434. else {
  1435. if ($4 < 0 || $4 > 255)
  1436. err[vflag]++;
  1437. emit(2, $1->i_value, $4);
  1438. }
  1439. }
  1440. |
  1441. IN realreg ',' '(' C ')'
  1442. { emit(2, 0355, 0100 + ($2 << 3)); }
  1443. |
  1444. IN F ',' '(' C ')'
  1445. { emit(2, 0355, 0160); }
  1446. |
  1447. OUT parenexpr ',' ACC
  1448. {
  1449. if ($2 < 0 || $2 > 255)
  1450. err[vflag]++;
  1451. emit(2, $1->i_value, $2);
  1452. }
  1453. |
  1454. OUT '(' C ')' ',' realreg
  1455. { emit(2, 0355, 0101 + ($6 << 3)); }
  1456. |
  1457. IM expression
  1458. {
  1459. if ($2 > 2 || $2 < 0)
  1460. err[vflag]++;
  1461. else
  1462. emit(2, $1->i_value >> 8, $1->i_value + (($2 + ($2 > 0)) << 3));
  1463. }
  1464. |
  1465. PHASE expression
  1466. {
  1467. if (phaseflag) {
  1468. err[oflag]++;
  1469. } else {
  1470. phaseflag = 1;
  1471. phdollar = dollarsign;
  1472. dollarsign = $2;
  1473. phbegin = dollarsign;
  1474. }
  1475. }
  1476. |
  1477. DEPHASE
  1478. {
  1479. if (!phaseflag) {
  1480. err[oflag]++;
  1481. } else {
  1482. phaseflag = 0;
  1483. dollarsign = phdollar + dollarsign - phbegin;
  1484. }
  1485. }
  1486. |
  1487. ORG expression
  1488. {
  1489. if (not_seen_org)
  1490. first_org_store=yyvsp[0].ival;
  1491. not_seen_org=0;
  1492. if (phaseflag) {
  1493. err[oflag]++;
  1494. dollarsign = phdollar + dollarsign - phbegin;
  1495. phaseflag = 0;
  1496. }
  1497. if ($2-dollarsign) {
  1498. flushbin();
  1499. if (pass2 && !output_hex && dollarsign != 0) {
  1500. if (yyvsp[0].ival < dollarsign) {
  1501. err[orgflag]++;
  1502. } else {
  1503. int f;
  1504. for (f=0;f<(yyvsp[0].ival - dollarsign);f++)
  1505. fputc(0, fbuf);
  1506. }
  1507. }
  1508. olddollar = $2;
  1509. dollarsign = $2;
  1510. }
  1511. }
  1512. |
  1513. DEFB db.list
  1514. |
  1515. DEFW dw.list
  1516. |
  1517. ENDM
  1518. ;
  1519. parm.list:
  1520. |
  1521. parm.element
  1522. |
  1523. parm.list ',' parm.element
  1524. ;
  1525. parm.element:
  1526. UNDECLARED
  1527. {
  1528. $1->i_token = MPARM;
  1529. if (parm_number >= PARMMAX)
  1530. error("Too many parameters");
  1531. $1->i_value = parm_number++;
  1532. }
  1533. ;
  1534. arg.list:
  1535. /* empty */
  1536. |
  1537. arg.element
  1538. |
  1539. arg.list ',' arg.element
  1540. ;
  1541. arg.element:
  1542. ARG
  1543. {
  1544. cp = malloc(strlen(tempbuf)+1);
  1545. #ifdef M_DEBUG
  1546. fprintf (stderr, "[Arg%u(%p): %s]\n", parm_number, cp, tempbuf);
  1547. #endif
  1548. est2[parm_number++] = cp;
  1549. strcpy(cp, tempbuf);
  1550. }
  1551. ;
  1552. reg:
  1553. realreg
  1554. |
  1555. mem
  1556. ;
  1557. realreg:
  1558. REGNAME
  1559. {
  1560. $$ = $1->i_value;
  1561. }
  1562. |
  1563. ACC
  1564. {
  1565. $$ = $1->i_value;
  1566. }
  1567. |
  1568. C
  1569. {
  1570. $$ = $1->i_value;
  1571. }
  1572. ;
  1573. mem:
  1574. '(' HL ')'
  1575. {
  1576. $$ = 6;
  1577. }
  1578. |
  1579. '(' INDEX expression ')'
  1580. {
  1581. disp = $3;
  1582. $$ = ($2->i_value & 0177400) | 6;
  1583. }
  1584. |
  1585. '(' INDEX ')'
  1586. {
  1587. disp = 0;
  1588. $$ = ($2->i_value & 0177400) | 6;
  1589. }
  1590. ;
  1591. evenreg:
  1592. bcdesp
  1593. |
  1594. mar
  1595. ;
  1596. pushable:
  1597. RP
  1598. {
  1599. $$ = $1->i_value;
  1600. }
  1601. |
  1602. AF
  1603. {
  1604. $$ = $1->i_value;
  1605. }
  1606. |
  1607. mar
  1608. ;
  1609. bcdesp:
  1610. RP
  1611. {
  1612. $$ = $1->i_value;
  1613. }
  1614. |
  1615. SP
  1616. {
  1617. $$ = $1->i_value;
  1618. }
  1619. ;
  1620. bcdehlsp:
  1621. bcdesp
  1622. |
  1623. HL
  1624. {
  1625. $$ = $1->i_value;
  1626. }
  1627. ;
  1628. mar:
  1629. HL
  1630. {
  1631. $$ = $1->i_value;
  1632. }
  1633. |
  1634. INDEX
  1635. {
  1636. $$ = $1->i_value;
  1637. }
  1638. ;
  1639. condition:
  1640. spcondition
  1641. |
  1642. COND
  1643. {
  1644. $$ = $1->i_value;
  1645. }
  1646. ;
  1647. spcondition:
  1648. SPCOND
  1649. {
  1650. $$ = $1->i_value;
  1651. }
  1652. |
  1653. C
  1654. { $$ = 030; }
  1655. ;
  1656. db.list:
  1657. db.list.element
  1658. |
  1659. db.list ',' db.list.element
  1660. ;
  1661. db.list.element:
  1662. TWOCHAR
  1663. {
  1664. dataemit(2, $1, $1>>8);
  1665. }
  1666. |
  1667. STRING
  1668. {
  1669. cp = $1;
  1670. while (*cp != '\0')
  1671. dataemit(1,*cp++);
  1672. }
  1673. |
  1674. expression
  1675. {
  1676. if ($1 < -128 || $1 > 255)
  1677. err[vflag]++;
  1678. dataemit(1, $1 & 0377);
  1679. }
  1680. ;
  1681. dw.list:
  1682. dw.list.element
  1683. |
  1684. dw.list ',' dw.list.element
  1685. ;
  1686. dw.list.element:
  1687. expression
  1688. {
  1689. dataemit(2, $1, $1>>8);
  1690. }
  1691. ;
  1692. lxexpression:
  1693. noparenexpr
  1694. |
  1695. TWOCHAR
  1696. ;
  1697. expression:
  1698. parenexpr
  1699. |
  1700. noparenexpr
  1701. ;
  1702. parenexpr:
  1703. '(' expression ')'
  1704. { $$ = $2; }
  1705. ;
  1706. noparenexpr:
  1707. LABEL
  1708. { $$ = $1->i_value; $1->i_uses++ ; }
  1709. |
  1710. NUMBER
  1711. |
  1712. ONECHAR
  1713. |
  1714. EQUATED
  1715. { $$ = $1->i_value; $1->i_uses++ ; }
  1716. |
  1717. WASEQUATED
  1718. {
  1719. $$ = $1->i_value; $1->i_uses++ ;
  1720. if ($1->i_equbad) {
  1721. /* forward reference to equ with a forward
  1722. * reference of its own cannot be resolved
  1723. * in two passes. -rjm
  1724. */
  1725. err[frflag]++;
  1726. }
  1727. }
  1728. |
  1729. DEFLED
  1730. { $$ = $1->i_value; $1->i_uses++ ; }
  1731. |
  1732. '$'
  1733. { $$ = dollarsign; }
  1734. |
  1735. UNDECLARED
  1736. {
  1737. err[uflag]++;
  1738. equ_bad_label=1;
  1739. $$ = 0;
  1740. }
  1741. |
  1742. MULTDEF
  1743. { $$ = $1->i_value; }
  1744. |
  1745. expression '+' expression
  1746. { $$ = $1 + $3; }
  1747. |
  1748. expression '-' expression
  1749. { $$ = $1 - $3; }
  1750. |
  1751. expression '/' expression
  1752. { if ($3 == 0) err[eflag]++; else $$ = $1 / $3; }
  1753. |
  1754. expression '*' expression
  1755. { $$ = $1 * $3; }
  1756. |
  1757. expression '%' expression
  1758. { if ($3 == 0) err[eflag]++; else $$ = $1 % $3; }
  1759. |
  1760. expression MOD expression
  1761. { if ($3 == 0) err[eflag]++; else $$ = $1 % $3; }
  1762. |
  1763. expression '&' expression
  1764. { $$ = $1 & $3; }
  1765. |
  1766. expression AND expression
  1767. { $$ = $1 & $3; }
  1768. |
  1769. expression '|' expression
  1770. { $$ = $1 | $3; }
  1771. |
  1772. expression OR expression
  1773. { $$ = $1 | $3; }
  1774. |
  1775. expression '^' expression
  1776. { $$ = $1 ^ $3; }
  1777. |
  1778. expression XOR expression
  1779. { $$ = $1 ^ $3; }
  1780. |
  1781. expression SHL expression
  1782. { $$ = $1 << $3; }
  1783. |
  1784. expression SHR expression
  1785. { $$ = (($1 >> 1) & 077777) >> ($3 - 1); }
  1786. |
  1787. expression '<' expression
  1788. { $$ = $1 < $3; }
  1789. |
  1790. expression '=' expression
  1791. { $$ = $1 == $3; }
  1792. |
  1793. expression '>' expression
  1794. { $$ = $1 > $3; }
  1795. |
  1796. expression LT expression
  1797. { $$ = $1 < $3; }
  1798. |
  1799. expression EQ expression
  1800. { $$ = $1 == $3; }
  1801. |
  1802. expression GT expression
  1803. { $$ = $1 > $3; }
  1804. |
  1805. expression LE expression
  1806. { $$ = $1 <= $3; }
  1807. |
  1808. expression GE expression
  1809. { $$ = $1 >= $3; }
  1810. |
  1811. expression NE expression
  1812. { $$ = $1 != $3; }
  1813. |
  1814. '[' expression ']'
  1815. { $$ = $2; }
  1816. |
  1817. NOT expression
  1818. { $$ = ~$2; }
  1819. |
  1820. '~' expression
  1821. { $$ = ~$2; }
  1822. |
  1823. '!' expression
  1824. { $$ = !$2; }
  1825. |
  1826. '+' expression %prec UNARY
  1827. { $$ = $2; }
  1828. |
  1829. '-' expression %prec UNARY
  1830. { $$ = -$2; }
  1831. ;
  1832. symbol:
  1833. UNDECLARED
  1834. |
  1835. LABEL
  1836. |
  1837. MULTDEF
  1838. |
  1839. EQUATED
  1840. |
  1841. WASEQUATED
  1842. |
  1843. DEFLED
  1844. ;
  1845. al:
  1846. { int i;
  1847. if (expptr >= MAXEXP)
  1848. error("Macro expansion level");
  1849. est2 = (char **) malloc((PARMMAX +4) * sizeof(char *));
  1850. expstack[expptr] = (char *)est2 ;
  1851. for (i=0; i<PARMMAX; i++)
  1852. est2[i] = 0;
  1853. arg_flag++;
  1854. }
  1855. ;
  1856. arg_on:
  1857. { arg_flag++; }
  1858. ;
  1859. arg_off:
  1860. { arg_flag = 0; }
  1861. ;
  1862. setqf:
  1863. { quoteflag++; }
  1864. ;
  1865. clrqf:
  1866. { quoteflag = 0; }
  1867. ;
  1868. %%
  1869. #define F_END 0
  1870. #define OTHER 1
  1871. #define SPACE 2
  1872. #define DIGIT 3
  1873. #define LETTER 4
  1874. #define STARTER 5
  1875. #define HEXIN 6
  1876. /*
  1877. * This is the table of character classes. It is used by the lexical
  1878. * analyser. (yylex())
  1879. */
  1880. char charclass[] = {
  1881. F_END, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
  1882. OTHER, SPACE, OTHER, OTHER, OTHER, SPACE, OTHER, OTHER,
  1883. OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
  1884. OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
  1885. SPACE, OTHER, OTHER, HEXIN, HEXIN, OTHER, HEXIN, OTHER,
  1886. OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
  1887. DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
  1888. DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER, STARTER,
  1889. STARTER,LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1890. LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1891. LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1892. LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, LETTER,
  1893. OTHER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1894. LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1895. LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  1896. LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, OTHER,
  1897. };
  1898. /*
  1899. * the following table tells which characters are parts of numbers.
  1900. * The entry is non-zero for characters which can be parts of numbers.
  1901. */
  1902. char numpart[] = {
  1903. 0, 0, 0, 0, 0, 0, 0, 0,
  1904. 0, 0, 0, 0, 0, 0, 0, 0,
  1905. 0, 0, 0, 0, 0, 0, 0, 0,
  1906. 0, 0, 0, 0, 0, 0, 0, 0,
  1907. 0, 0, 0, 0, 0, 0, 0, 0,
  1908. 0, 0, 0, 0, 0, 0, 0, 0,
  1909. '0', '1', '2', '3', '4', '5', '6', '7',
  1910. '8', '9', 0, 0, 0, 0, 0, 0,
  1911. 0, 'A', 'B', 'C', 'D', 'E', 'F', 0,
  1912. 'H', 0, 0, 0, 0, 0, 0, 'O',
  1913. 0, 'Q', 0, 0, 0, 0, 0, 0,
  1914. 0, 0, 0, 0, 0, 0, 0, 0,
  1915. 0, 'a', 'b', 'c', 'd', 'e', 'f', 0,
  1916. 'h', 0, 0, 0, 0, 0, 0, 'o',
  1917. 0, 'q', 0, 0, 0, 0, 0, 0,
  1918. 0, 0, 0, 0, 0, 0, 0, 0,
  1919. 0};
  1920. /*
  1921. * the following table is a list of assembler mnemonics;
  1922. * for each mnemonic the associated machine-code bit pattern
  1923. * and symbol type are given.
  1924. */
  1925. struct item keytab[] = {
  1926. {"a", 7, ACC, 0},
  1927. {"adc", 1, ARITHC, 0},
  1928. {"add", 0, ADD, 0},
  1929. {"af", 060, AF, 0},
  1930. {"and", 4, AND, 0},
  1931. {"ascii",0, DEFB, 0},
  1932. {"b", 0, REGNAME, 0},
  1933. {"bc", 0, RP, 0},
  1934. {"bit", 0145500,BIT, 0},
  1935. {"block",0, DEFS, 0},
  1936. {"byte",0, DEFB, 0},
  1937. {"c", 1, C, 0},
  1938. {"call",0315, CALL, 0},
  1939. {"ccf", 077, NOOPERAND, 0},
  1940. {"cmp", 7, LOGICAL, 0}, /* -cdk */
  1941. {"cond",0, IF, 0},
  1942. {"cp", 7, LOGICAL, 0},
  1943. {"cpd", 0166651,NOOPERAND, 0},
  1944. {"cpdr",0166671,NOOPERAND, 0},
  1945. {"cpi", 0166641,NOOPERAND, 0},
  1946. {"cpir",0166661,NOOPERAND, 0},
  1947. {"cpl", 057, NOOPERAND, 0},
  1948. {"d", 2, REGNAME, 0},
  1949. {"daa", 0047, NOOPERAND, 0},
  1950. {"db", 0, DEFB, 0},
  1951. {"de", 020, RP, 0},
  1952. {"dec", 1, INCDEC, 0},
  1953. {"defb",0, DEFB, 0},
  1954. {"defl",0, DEFL, 0},
  1955. {"defm",0, DEFB, 0},
  1956. {"defs",0, DEFS, 0},
  1957. {"defw",0, DEFW, 0},
  1958. {"dephase",0, DEPHASE, 0},
  1959. {"di", 0363, NOOPERAND, 0},
  1960. {"djnz",020, DJNZ, 0},
  1961. {"ds", 0, DEFS, 0},
  1962. {"dw", 0, DEFW, 0},
  1963. {"e", 3, REGNAME, 0},
  1964. {"ei", 0373, NOOPERAND, 0},
  1965. {"eject",1, LIST, 0},
  1966. {"elist",3, LIST, 0},
  1967. {"else",0, ELSE, 0},
  1968. {"end", 0, END, 0},
  1969. {"endc",0, ENDIF, 0},
  1970. {"endif",0, ENDIF, 0},
  1971. {"endm", 0, ENDM, 0},
  1972. {"eq", 0, EQ, 0},
  1973. {"equ", 0, EQU, 0},
  1974. {"ex", 0, EX, 0},
  1975. {"exx", 0331, NOOPERAND, 0},
  1976. {"f", 0, F, 0},
  1977. {"flist",4, LIST, 0},
  1978. {"ge", 0, GE, 0},
  1979. {"glist",5, LIST, 0},
  1980. {"gt", 0, GT, 0},
  1981. {"h", 4, REGNAME, 0},
  1982. {"halt",0166, NOOPERAND, 0},
  1983. {"hl", 040, HL, 0},
  1984. {"i", 0, MISCREG, 0},
  1985. {"if", 0, IF, 0},
  1986. {"im", 0166506,IM, 0},
  1987. {"in", 0333, IN, 0},
  1988. {"inc", 0, INCDEC, 0},
  1989. {"include", 3, ARGPSEUDO, 0},
  1990. {"ind", 0166652,NOOPERAND, 0},
  1991. {"indr",0166672,NOOPERAND, 0},
  1992. {"ini", 0166642,NOOPERAND, 0},
  1993. {"inir",0166662,NOOPERAND, 0},
  1994. {"ix", 0156440,INDEX, 0},
  1995. {"iy", 0176440,INDEX, 0},
  1996. {"jmp", 0303, JP, 0}, /* -cdk */
  1997. {"jp", 0303, JP, 0},
  1998. {"jr", 040, JR, 0},
  1999. {"l", 5, REGNAME, 0},
  2000. {"ld", 0, LD, 0},
  2001. {"ldd", 0166650,NOOPERAND, 0},
  2002. {"lddr",0166670,NOOPERAND, 0},
  2003. {"ldi", 0166640,NOOPERAND, 0},
  2004. {"ldir",0166660,NOOPERAND, 0},
  2005. {"le", 0, LE, 0},
  2006. {"list",0, LIST, 0},
  2007. {"lt", 0, LT, 0},
  2008. {"m", 070, COND, 0},
  2009. {"macro",0, MACRO, 0},
  2010. {"max", 1, MINMAX, 0},
  2011. {"min", 0, MINMAX, 0},
  2012. {"mlist",6, LIST, 0},
  2013. {"mod", 0, MOD, 0},
  2014. {"nc", 020, SPCOND, 0},
  2015. {"ne", 0, NE, 0},
  2016. {"neg", 0166504,NOOPERAND, 0},
  2017. {"nolist",-1, LIST, 0},
  2018. {"nop", 0, NOOPERAND, 0},
  2019. {"not", 0, NOT, 0},
  2020. {"nv", 040, COND, 0},
  2021. {"nz", 0, SPCOND, 0},
  2022. {"or", 6, OR, 0},
  2023. {"org", 0, ORG, 0},
  2024. {"otdr",0166673,NOOPERAND, 0},
  2025. {"otir",0166663,NOOPERAND, 0},
  2026. {"out", 0323, OUT, 0},
  2027. {"outd",0166653,NOOPERAND, 0},
  2028. {"outi",0166643,NOOPERAND, 0},
  2029. {"p", 060, COND, 0},
  2030. {"pe", 050, COND, 0},
  2031. {"phase",0, PHASE, 0},
  2032. {"po", 040, COND, 0},
  2033. {"pop", 0301, PUSHPOP, 0},
  2034. {"push", 0305, PUSHPOP, 0},
  2035. {"r", 010, MISCREG, 0},
  2036. {"read", 3, ARGPSEUDO, 0},
  2037. {"res", 0145600,BIT, 0},
  2038. {"ret", 0311, RET, 0},
  2039. {"reti",0166515,NOOPERAND, 0},
  2040. {"retn",0166505,NOOPERAND, 0},
  2041. {"rl", 2, SHIFT, 0},
  2042. {"rla", 027, NOOPERAND, 0},
  2043. {"rlc", 0, SHIFT, 0},
  2044. {"rlca",07, NOOPERAND, 0},
  2045. {"rld", 0166557,NOOPERAND, 0},
  2046. {"rmem",0, DEFS, 0},
  2047. {"rr", 3, SHIFT, 0},
  2048. {"rra", 037, NOOPERAND, 0},
  2049. {"rrc", 1, SHIFT, 0},
  2050. {"rrca",017, NOOPERAND, 0},
  2051. {"rrd", 0166547,NOOPERAND, 0},
  2052. {"rst", 0307, RST, 0},
  2053. {"rsym",1, ARGPSEUDO, 0},
  2054. {"sbc", 3, ARITHC, 0},
  2055. {"scf", 067, NOOPERAND, 0},
  2056. {"set", 0145700,BIT, 0},
  2057. {"shl", 0, SHL, 0},
  2058. {"shr", 0, SHR, 0},
  2059. {"sla", 4, SHIFT, 0},
  2060. {"sll", 6, SHIFT, 0}, /* Undocumented */
  2061. {"sp", 060, SP, 0},
  2062. {"space",2, LIST, 0},
  2063. {"sra", 5, SHIFT, 0},
  2064. {"srl", 7, SHIFT, 0},
  2065. {"sub", 2, LOGICAL, 0},
  2066. {"text",0, DEFB, 0},
  2067. {"title",0, ARGPSEUDO, 0},
  2068. {"v", 050, COND, 0},
  2069. {"word",0, DEFW, 0},
  2070. {"wsym",2, ARGPSEUDO, 0},
  2071. {"xor", 5, XOR, 0},
  2072. {"z", 010, SPCOND, 0}
  2073. };
  2074. /*
  2075. * user-defined items are tabulated in the following table.
  2076. */
  2077. struct item itemtab[ITEMTABLESIZE];
  2078. struct item *itemmax = itemtab+ITEMTABLESIZE;
  2079. /*
  2080. * lexical analyser, called by yyparse.
  2081. */
  2082. int yylex()
  2083. {
  2084. int c;
  2085. char *p;
  2086. int radix;
  2087. int limit;
  2088. int leadinghex = 0;
  2089. if (arg_flag)
  2090. return(getarg());
  2091. loop switch(charclass[c = nextchar()]) {
  2092. case F_END:
  2093. if (expptr) {
  2094. popsi();
  2095. continue;
  2096. } else return(0);
  2097. case SPACE:
  2098. break;
  2099. case LETTER:
  2100. case STARTER:
  2101. p = tempbuf;
  2102. do {
  2103. if (p >= tempmax)
  2104. error(symlong);
  2105. *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  2106. while ((c = nextchar()) == '$')
  2107. ;
  2108. } while (charclass[c]==LETTER || charclass[c]==DIGIT);
  2109. if (p - tempbuf > MAXSYMBOLSIZE)
  2110. {
  2111. if (pass2) warnprt (0, 1);
  2112. p = tempbuf + MAXSYMBOLSIZE;
  2113. }
  2114. *p++ = '\0';
  2115. peekc = c;
  2116. return(tokenofitem(UNDECLARED));
  2117. case HEXIN:
  2118. {
  2119. int corig = c;
  2120. if (*ifptr) return (skipline(c));
  2121. while ((c = nextchar ()) == '$');
  2122. if (!numpart[c])
  2123. {
  2124. peekc = c;
  2125. return (corig);
  2126. }
  2127. leadinghex = 1;
  2128. /* fall through */
  2129. }
  2130. case DIGIT:
  2131. if (*ifptr) return (skipline(c));
  2132. p = tempbuf;
  2133. do {
  2134. if (p >= tempmax)
  2135. error(symlong);
  2136. *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  2137. while ((c = nextchar()) == '$');
  2138. }
  2139. while(numpart[c]);
  2140. peekc = c;
  2141. if (leadinghex)
  2142. {
  2143. *p++ = 'h';
  2144. }
  2145. *p-- = '\0';
  2146. switch(*p) {
  2147. case 'o':
  2148. case 'q':
  2149. radix = 8;
  2150. limit = 020000;
  2151. *p = '\0';
  2152. break;
  2153. case 'd':
  2154. radix = 10;
  2155. limit = 6553;
  2156. *p = '\0';
  2157. break;
  2158. case 'h':
  2159. radix = 16;
  2160. limit = 010000;
  2161. *p = '\0';
  2162. break;
  2163. case 'b':
  2164. radix = 2;
  2165. limit = 077777;
  2166. *p = '\0';
  2167. break;
  2168. default:
  2169. radix = 10;
  2170. limit = 6553;
  2171. p++;
  2172. break;
  2173. }
  2174. /*
  2175. * tempbuf now points to the number, null terminated
  2176. * with radix 'radix'.
  2177. */
  2178. yylval.ival = 0;
  2179. p = tempbuf;
  2180. do {
  2181. c = *p - (*p > '9' ? ('a' - 10) : '0');
  2182. if (c >= radix)
  2183. {
  2184. err[iflag]++;
  2185. yylval.ival = 0;
  2186. break;
  2187. }
  2188. if (yylval.ival < limit ||
  2189. (radix == 10 && yylval.ival == 6553 && c < 6) ||
  2190. (radix == 2 && yylval.ival == limit))
  2191. yylval.ival = yylval.ival * radix + c;
  2192. else {
  2193. err[vflag]++;
  2194. yylval.ival = 0;
  2195. break;
  2196. }
  2197. }
  2198. while(*++p != '\0');
  2199. return(NUMBER);
  2200. default:
  2201. if (*ifptr)
  2202. return(skipline(c));
  2203. switch(c) {
  2204. int corig;
  2205. case ';':
  2206. return(skipline(c));
  2207. case '\'':
  2208. if (quoteflag) return('\'');
  2209. case '"':
  2210. corig = c;
  2211. p = tempbuf;
  2212. p[1] = 0;
  2213. do switch(c = nextchar()) {
  2214. case '\0':
  2215. case '\n':
  2216. err[bflag]++;
  2217. goto retstring;
  2218. case '\'':
  2219. case '"':
  2220. if (c == corig && (c = nextchar()) != corig) {
  2221. retstring:
  2222. peekc = c;
  2223. *p = '\0';
  2224. if ((p-tempbuf) >2) {
  2225. yylval.cval = tempbuf;
  2226. return(STRING);
  2227. } else if (p-tempbuf == 2) {
  2228. p = tempbuf;
  2229. yylval.ival = *p++ ;
  2230. yylval.ival |= *p<<8;
  2231. return(TWOCHAR);
  2232. } else {
  2233. p = tempbuf;
  2234. yylval.ival = *p++;
  2235. return(ONECHAR);
  2236. }
  2237. }
  2238. default:
  2239. *p++ = c;
  2240. } while (p < tempmax);
  2241. /*
  2242. * if we break out here, our string is longer than
  2243. * our input line
  2244. */
  2245. error("string buffer overflow");
  2246. case '<':
  2247. corig = c;
  2248. switch (c = nextchar ()) {
  2249. case '=':
  2250. return LE;
  2251. case '<':
  2252. return SHL;
  2253. case '>':
  2254. return NE;
  2255. default:
  2256. peekc = c;
  2257. return corig;
  2258. }
  2259. /* break; suppress "unreachable" warning for tcc */
  2260. case '>':
  2261. corig = c;
  2262. switch (c = nextchar ()) {
  2263. case '=':
  2264. return GE;
  2265. case '>':
  2266. return SHR;
  2267. default:
  2268. peekc = c;
  2269. return corig;
  2270. }
  2271. /* break; suppress "unreachable" warning for tcc */
  2272. case '!':
  2273. corig = c;
  2274. switch (c = nextchar ()) {
  2275. case '=':
  2276. return NE;
  2277. default:
  2278. peekc = c;
  2279. return corig;
  2280. }
  2281. /* break; suppress "unreachable" warning for tcc */
  2282. case '=':
  2283. corig = c;
  2284. switch (c = nextchar ()) {
  2285. case '=':
  2286. return EQ;
  2287. default:
  2288. peekc = c;
  2289. return corig;
  2290. }
  2291. /* break; suppress "unreachable" warning for tcc */
  2292. default:
  2293. return(c);
  2294. }
  2295. }
  2296. }
  2297. /*
  2298. * return the token associated with the string pointed to by
  2299. * tempbuf. if no token is associated with the string, associate
  2300. * deftoken with the string and return deftoken.
  2301. * in either case, cause yylval to point to the relevant
  2302. * symbol table entry.
  2303. */
  2304. int tokenofitem(int deftoken)
  2305. {
  2306. char *p;
  2307. struct item * ip;
  2308. int i;
  2309. int r, l, u, hash;
  2310. #ifdef T_DEBUG
  2311. fputs("'tokenofitem entry' ", stderr) ;
  2312. fputs(tempbuf, stderr) ;
  2313. #endif
  2314. if (strcmp (tempbuf, "cmp") == 0 ||
  2315. strcmp (tempbuf, "jmp") == 0 ||
  2316. strcmp (tempbuf, "v") == 0 ||
  2317. strcmp (tempbuf, "nv") == 0)
  2318. if (pass2) warnprt (1, 1);
  2319. /*
  2320. * binary search
  2321. */
  2322. l = 0;
  2323. u = (sizeof keytab/sizeof keytab[0])-1;
  2324. while (l <= u) {
  2325. i = (l+u)/2;
  2326. ip = &keytab[i];
  2327. if ((r = strcmp(tempbuf, ip->i_string)) == 0)
  2328. goto found;
  2329. if (r < 0)
  2330. u = i-1;
  2331. else
  2332. l = i+1;
  2333. }
  2334. /*
  2335. * hash into item table
  2336. */
  2337. hash = 0;
  2338. p = tempbuf;
  2339. while (*p) hash += *p++;
  2340. hash %= ITEMTABLESIZE;
  2341. ip = &itemtab[hash];
  2342. loop {
  2343. if (ip->i_token == 0)
  2344. break;
  2345. if (strcmp(tempbuf, ip->i_string) == 0)
  2346. goto found;
  2347. if (++ip >= itemmax)
  2348. ip = itemtab;
  2349. }
  2350. if (!deftoken) {
  2351. i = 0 ;
  2352. goto token_done ;
  2353. }
  2354. if (++nitems > ITEMTABLESIZE-20)
  2355. error("item table overflow");
  2356. ip->i_string = malloc(strlen(tempbuf)+1);
  2357. ip->i_token = deftoken;
  2358. ip->i_uses = 0;
  2359. ip->i_equbad = 0;
  2360. strcpy(ip->i_string, tempbuf);
  2361. found:
  2362. if (*ifptr) {
  2363. if (ip->i_token == ENDIF) {
  2364. i = ENDIF ;
  2365. goto token_done ;
  2366. }
  2367. if (ip->i_token == ELSE) {
  2368. /* We must only honour the ELSE if it is not
  2369. in a nested failed IF/ELSE */
  2370. char forbid = 0;
  2371. char *ifstackptr;
  2372. for (ifstackptr = ifstack; ifstackptr != ifptr; ++ifstackptr) {
  2373. if (*ifstackptr) {
  2374. forbid = 1;
  2375. break;
  2376. }
  2377. }
  2378. if (!forbid) {
  2379. i = ELSE;
  2380. goto token_done;
  2381. }
  2382. }
  2383. if (ip->i_token == IF) {
  2384. if (ifptr >= ifstmax)
  2385. error("Too many ifs");
  2386. else *++ifptr = 1;
  2387. }
  2388. i = skipline(' ');
  2389. goto token_done ;
  2390. }
  2391. yylval.itemptr = ip;
  2392. i = ip->i_token;
  2393. if (i == EQU) equ_bad_label=0;
  2394. token_done:
  2395. #ifdef T_DEBUG
  2396. fputs("\t'tokenofitem exit'\n", stderr) ;
  2397. #endif
  2398. return(i) ;
  2399. }
  2400. /*
  2401. * interchange two entries in the item table -- used by custom_qsort
  2402. */
  2403. void interchange(int i, int j)
  2404. {
  2405. struct item *fp, *tp;
  2406. struct item temp;
  2407. fp = &itemtab[i];
  2408. tp = &itemtab[j];
  2409. temp.i_string = fp->i_string;
  2410. temp.i_value = fp->i_value;
  2411. temp.i_token = fp->i_token;
  2412. temp.i_uses = fp->i_uses;
  2413. temp.i_equbad = fp->i_equbad;
  2414. fp->i_string = tp->i_string;
  2415. fp->i_value = tp->i_value;
  2416. fp->i_token = tp->i_token;
  2417. fp->i_uses = tp->i_uses;
  2418. fp->i_equbad = tp->i_equbad;
  2419. tp->i_string = temp.i_string;
  2420. tp->i_value = temp.i_value;
  2421. tp->i_token = temp.i_token;
  2422. tp->i_uses = temp.i_uses;
  2423. tp->i_equbad = temp.i_equbad;
  2424. }
  2425. /*
  2426. * quick sort -- used by putsymtab to sort the symbol table
  2427. */
  2428. void custom_qsort(int m, int n)
  2429. {
  2430. int i, j;
  2431. if (m < n) {
  2432. i = m;
  2433. j = n+1;
  2434. loop {
  2435. do i++; while(strcmp(itemtab[i].i_string,
  2436. itemtab[m].i_string) < 0);
  2437. do j--; while(strcmp(itemtab[j].i_string,
  2438. itemtab[m].i_string) > 0);
  2439. if (i < j) interchange(i, j); else break;
  2440. }
  2441. interchange(m, j);
  2442. custom_qsort(m, j-1);
  2443. custom_qsort(j+1, n);
  2444. }
  2445. }
  2446. /*
  2447. * get the next character
  2448. */
  2449. int nextchar()
  2450. {
  2451. int c, ch;
  2452. static char *earg;
  2453. if (peekc != -1) {
  2454. c = peekc;
  2455. peekc = -1;
  2456. return(c);
  2457. }
  2458. start:
  2459. if (earg) {
  2460. if (*earg)
  2461. return(addtoline(*earg++));
  2462. earg = 0;
  2463. }
  2464. if (expptr) {
  2465. if ((ch = getm()) == '\1') { /* expand argument */
  2466. ch = getm() - 'A';
  2467. if (ch >= 0 && ch < PARMMAX && est[ch])
  2468. earg = est[ch];
  2469. goto start;
  2470. }
  2471. if (ch == '\2') { /* local symbol */
  2472. ch = getm() - 'A';
  2473. if (ch >= 0 && ch < PARMMAX && est[ch]) {
  2474. earg = est[ch];
  2475. goto start;
  2476. }
  2477. earg = getlocal(ch, (int)(long)est[TEMPNUM]);
  2478. goto start

Large files files are truncated, but you can click here to view the full file