1	
     2	#define DEBUG	error(-1)
     3	
     4	/*#include "CCLIB.TXT"
     5	*/
     6	#include <stdio.h>
     7	
     8	#define INT	(-1)
     9	#define CHAR	(-2)
    10	#define UNSIGNED	(-3)
    11	#define POINTER (-4)
    12	#define ARRAY	(-5)
    13	#define STRUCT	(-6)
    14	#define UNION	(-7)
    15	#define FUNCTION	(-8)
    16	#define EMPTY	(-9)
    17	
    18	#define STATIC	(-10)
    19	#define GOTO	(-11)
    20	#define RETURN	(-12)
    21	#define BREAK	(-13)
    22	#define CONTINUE	(-14)
    23	#define IF	(-15)
    24	#define ELSE	(-16)
    25	#define FOR	(-17)
    26	#define DO	(-18)
    27	#define WHILE	(-19)
    28	#define SWITCH	(-20)
    29	#define CASE	(-21)
    30	#define DEFAULT (-22)
    31	#define RESERVE (-23)
    32	#define TAG	(-24)
    33	#define FIELD	(-25)
    34	#define IDENT	(-26)
    35	#define STRING	(-27)
    36	#define MACRO	(-28)
    37	#define BLABEL	(-29)
    38	#define FLABEL	(-30)
    39	#define TYPEDEF (-31)
    40	#define SIZEOF	(-32)
    41	#define TYPE	(-33)
    42	#define LONG	(-34)
    43	#define SHORT	(-35)
    44	
    45	#define TOP	0
    46	#define GDECL	1
    47	#define GSDECL	2
    48	#define GUDECL	3
    49	#define ADECL	4
    50	#define LDECL	5
    51	#define LSDECL	6
    52	#define LUDECL	7
    53	#define STADECL 8
    54	#define STAT	9
    55	#define GTDECL	10
    56	#define LTDECL	11
    57	
    58	#define GVAR	1
    59	#define RGVAR	2
    60	#define CRGVAR	3
    61	#define LVAR	4
    62	#define RLVAR	5
    63	#define CRLVAR	6
    64	#define CONST	7
    65	#define FNAME	8
    66	#define INDIRECT	9
    67	#define RINDIRECT	10
    68	#define CRINDIRECT	11
    69	#define ADDRESS 12
    70	#define MINUS	13
    71	#define LNOT	14
    72	#define BNOT	15
    73	#define INC	16
    74	#define POSTINC 17
    75	#define PREINC	18
    76	#define CPOSTINC	19
    77	#define CPREINC 20
    78	#define DEC	21
    79	#define CPOSTDEC	22
    80	#define CPREDEC 23
    81	#define MUL	24
    82	#define UMUL	25
    83	#define DIV	26
    84	#define UDIV	27
    85	#define MOD	28
    86	#define UMOD	29
    87	#define ADD	30
    88	#define SUB	31
    89	#define RSHIFT	32
    90	#define URSHIFT 33
    91	#define LSHIFT	34
    92	#define ULSHIFT 35
    93	#define GT	36
    94	#define UGT	37
    95	#define GE	38
    96	#define UGE	39
    97	#define LT	40
    98	#define ULT	41
    99	#define LE	42
   100	#define ULE	43
   101	#define EQ	44
   102	#define NEQ	45
   103	#define BAND	46
   104	#define EOR	47
   105	#define BOR	48
   106	#define LAND	49
   107	#define LOR	50
   108	#define COND	51
   109	#define ASS	52
   110	#define CASS	53
   111	#define ASSOP	54
   112	#define CASSOP	55
   113	#define COMMA	56
   114	#define LPAR	57
   115	#define RPAR	58
   116	#define LBRA	59
   117	#define RBRA	60
   118	#define LC	61
   119	#define RC	62
   120	#define COLON	63
   121	#define SM	64
   122	#define PERIOD	65
   123	#define ARROW	66
   124	
   125	#define US	1
   126	#define AS	100
   127	
   128	#define FILERR	1
   129	#define DCERR	2
   130	#define STERR	3
   131	#define EXERR	4
   132	#define CNERR	5
   133	#define CHERR	6
   134	#define GSERR	7
   135	#define LSERR	8
   136	#define STRERR	9
   137	#define LNERR	10
   138	#define EOFERR	11
   139	#define MCERR	12
   140	#define INCERR	13
   141	#define HPERR	14
   142	#define TYERR	15
   143	#define LVERR	16
   144	#define UDERR	17
   145	#define OPTION	18
   146	
   147	#define GSYMS	450
   148	#define LSYMS	50
   149	
   150	#define HEAPSIZE	1000
   151	#define CHEAPSIZE	3000
   152	#define LBUFSIZE	256
   153	
   154	#define FILES 3
   155	
   156	int sym,ch,chsave,type,mode,gfree,lfree,mflag,lineno,glineno;
   157	int labelno,gpc,lvar,disp;
   158	int symval,args,heap[HEAPSIZE];
   159	int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf;
   160	
   161	unsigned hash;
   162	
   163	char linebuf[LBUFSIZE],cheap[CHEAPSIZE],*chptr,*chptrsave;
   164	char name[9],*cheapp,**av,/*obuf[320],*/*sptr,escape();
   165	
   166	FILE *obuf;
   167	
   168	typedef struct nametable {
   169		char nm[9];
   170		int sc,ty,dsp; } NMTBL;
   171	
   172	NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch();
   173	
   174	struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES];
   175	
   176	main(argc,argv)
   177	int argc;
   178	char **argv;
   179	{NMTBL *nptr;
   180	int i;
   181	char *ccout;
   182		if(argc==1) exit(1);
   183		lsrc = chk = asmf = 0;
   184		ccout = "c.out";
   185		ac=argc;
   186		av=argv;
   187		for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2)
   188			switch (*(av[ac2]+1))
   189			{case 'S': case 's':
   190				lsrc = 1;
   191				break;
   192			case 'O': case 'o':
   193				ccout = av[ac2]+2;
   194				break;
   195			case 'C': case 'c':
   196				chk = 1;
   197				break;
   198			default:
   199				error(OPTION);
   200				exit(1);
   201			}
   202		fclose(stdout);
   203		if (!chk)
   204			if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR);
   205		init();
   206		while(1)
   207		{	for (nptr = &ntable[GSYMS],i=LSYMS; i--;)
   208				(nptr++)->sc = EMPTY;
   209			mode=TOP;
   210			while(getsym()==SM);
   211			mode=GDECL;
   212			args=0;
   213			decl();
   214		}
   215	}
   216	error(n)
   217	int n;
   218	{	if(n == EOFERR)
   219			if(filep!=filestack)
   220			{	lineno=filep->ln;
   221				fclose(filep->fcb);
   222				fprintf(stderr,"End of inclusion.\n");
   223				--filep;
   224				return;
   225			}
   226			else if(ac2!=ac)
   227			{	fclose(filep->fcb);
   228				newfile();
   229				return;
   230			}
   231			else if(mode == TOP)
   232			{	fprintf(stderr,"\nCompiled %u lines.\n",glineno-1);
   233				if (!chk) fprintf(stderr,
   234					"Total internal labels	: %u.\n",labelno-1);
   235				fprintf(stderr,
   236					"Total global variables : %u bytes.\n\n",gpc);
   237				printf("_%d\tRTS\n_INITIALIZE\tEQU\t_1\n",ilabel);
   238				printf("_GLOBALS\tEQU\t%u\n\tEND\n",gpc);
   239				exit(0);
   240			}
   241		fprintf(stderr,"%5d:%s.\n",lineno,
   242			(n==FILERR) ? "Can't open specified file" :
   243			(n==DCERR) ? "Declaration syntax" :
   244			(n==STERR) ? "Statement syntax" :
   245			(n==EXERR) ? "Expression syntax" :
   246			(n==CNERR) ? "Constant required" :
   247			(n==CHERR) ? "Illegal character" :
   248			(n==GSERR) ? "Too many global symbols" :
   249			(n==LSERR) ? "Too many local symbols" :
   250			(n==STRERR) ? "Too many strings or macros" :
   251			(n==LNERR) ? "Line too long" :
   252			(n==EOFERR) ? "Unexpected end of file" :
   253			(n==MCERR) ? "Macro syntax" :
   254			(n==INCERR) ? "Include syntax" :
   255			(n==HPERR) ? "Too long expression" :
   256			(n==TYERR) ? "Type mismatch" :
   257			(n==LVERR) ? "Lvalue required" :
   258			(n==UDERR) ? "Undeclared identifier" :
   259			(n==OPTION) ? "Illegal option" :
   260			"Bug of compiler");
   261		errmsg();
   262		exit(1);
   263	}
   264	errmsg()
   265	{char *p,*lim;
   266		if(lineno==0) return;
   267		fprintf(stderr,"%s",linebuf);
   268		lim=(mflag?chptrsave:chptr);
   269		for (p=linebuf; p < lim;)
   270			fprintf(stderr,(*p++ == '\t') ? "\t" : " ");
   271		fprintf (stderr,"^\n");
   272	}
   273	checksym(s)
   274	int s;
   275	{char *p;
   276		if (sym != s)
   277		{	p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'":
   278			  (s==LPAR) ? "'('": (s==WHILE) ? "'while'":
   279			  (s==COLON) ? "':'": "Identifier";
   280			fprintf(stderr,"%d:%s expected.\n",lineno,p);
   281			errmsg();
   282		}
   283		else getsym();
   284	}
   285	init()
   286	{NMTBL *nptr;
   287	int i;
   288		for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = EMPTY;
   289		reserve("int",INT);
   290		reserve("void",INT);
   291		reserve("char",CHAR);
   292		reserve("struct",STRUCT);
   293		reserve("union",UNION);
   294		reserve("unsigned",UNSIGNED);
   295		reserve("static",STATIC);
   296		reserve("goto",GOTO);
   297		reserve("return",RETURN);
   298		reserve("break",BREAK);
   299		reserve("continue",CONTINUE);
   300		reserve("if",IF);
   301		reserve("else",ELSE);
   302		reserve("for",FOR);
   303		reserve("do",DO);
   304		reserve("while",WHILE);
   305		reserve("switch",SWITCH);
   306		reserve("case",CASE);
   307		reserve("default",DEFAULT);
   308		reserve("typedef",TYPEDEF);
   309		reserve("sizeof",SIZEOF);
   310		reserve("long",LONG);
   311		reserve("short",SHORT);
   312		gpc=glineno=mflag=0;
   313		gfree=ilabel=1;
   314		labelno=2;
   315		cheapp=cheap;
   316		lfree=HEAPSIZE;
   317		filep=filestack;
   318		newfile();
   319		getline();
   320		getch();
   321	}
   322	newfile()
   323	{	lineno=0;
   324		fprintf(stderr,"%s:\n",av[ac2]);
   325		if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR);
   326	}
   327	reserve(s,d)
   328	char *s;
   329	int d;
   330	{NMTBL *nptr;
   331	char *t;
   332		hash=0;
   333		t=name;
   334		while(*t++ = *s) hash=7*(hash+*s++);
   335		(nptr = gsearch())->sc = RESERVE;
   336		nptr->dsp = d;
   337	}
   338	
   339	decl()
   340	{NMTBL *n;
   341	int t;
   342		if(sym==STATIC)
   343			if(mode==LDECL)
   344			{	getsym();
   345				mode=STADECL;
   346			}
   347			else error(DCERR);
   348		else if(sym==TYPEDEF)
   349			if(mode==GDECL)
   350			{	getsym();
   351				mode=GTDECL;
   352			}
   353			else if(mode==LDECL)
   354			{	getsym();
   355				mode=LTDECL;
   356			}
   357			else error(DCERR);
   358		if((t=typespec())==0) return;
   359		if(sym==SM) return;
   360		type=t;
   361		n=decl0();
   362		reverse(t);
   363		if(args||sym==LC) {fdecl(n);return;}
   364		def(n);
   365		while(sym==COMMA)
   366		{	getsym();
   367			type=t;
   368			n=decl0();
   369			reverse(t);
   370			if(args) error(DCERR);
   371			def(n);
   372		}
   373		if(sym!=SM) error(DCERR);
   374		if(mode==GTDECL) mode=GDECL;
   375		if(mode==STADECL||mode==LTDECL) mode=LDECL;
   376	}
   377	typespec()
   378	{int t;
   379		switch(sym)
   380		{case INT:
   381		case CHAR:
   382			t= sym;
   383			getsym();
   384			break;
   385		case STRUCT:
   386		case UNION:
   387			t=sdecl(sym);
   388			break;
   389		case UNSIGNED:
   390			t = UNSIGNED;
   391			if(getsym()==INT) getsym();
   392			break;
   393		case SHORT:
   394			t=CHAR;
   395			if(getsym()==INT) getsym();
   396			break;
   397		case LONG:
   398			t=INT;
   399			if(getsym()==INT) getsym();
   400			break;
   401		default:
   402			if(sym==IDENT)
   403				if(nptr->sc==TYPE)
   404				{	t=nptr->ty;
   405					getsym();
   406					break;
   407				}
   408				else if(nptr->sc==EMPTY && gnptr->sc==TYPE)
   409				{	t=gnptr->ty;
   410					getsym();
   411					break;
   412				}
   413			if(mode==LDECL) return 0;
   414			t= INT;
   415		}
   416		return t;
   417	}
   418	struct nametable *decl0()
   419	{NMTBL *n;
   420		if(sym==MUL)
   421		{	getsym();
   422			n=decl0();
   423			type=list2(POINTER,type);
   424			return n;
   425		}
   426		return decl1();
   427	}
   428	NMTBL *decl1()
   429	{NMTBL *n;
   430	int i,t;
   431		if(sym==LPAR)
   432		{	getsym();
   433			n=decl0();
   434			checksym(RPAR);
   435		}
   436		else if (sym == IDENT)
   437		{	n=nptr;
   438			getsym();
   439		}
   440		else error(DCERR);
   441		while(1)
   442			if(sym==LBRA)
   443				if(getsym()==RBRA)
   444				{	getsym();
   445					if(mode!=ADECL) error(DCERR);
   446					t=type;
   447					type=list2(POINTER,type);
   448				}
   449				else
   450				{	t=type;
   451					i=cexpr(expr());
   452					checksym(RBRA);
   453					type=list3(ARRAY,t,i);
   454				}
   455			else if(sym==LPAR)
   456			{	if(mode==GDECL) {mode=ADECL;getsym();mode=GDECL;}
   457				else getsym();
   458				if(sym==RPAR) getsym();
   459				else
   460				{	n->sc=FUNCTION;
   461					adecl();
   462					n->sc=EMPTY;
   463				}
   464				type=list2(FUNCTION,type);
   465			}
   466			else return n;
   467	}
   468	adecl()
   469	{	if(mode!=GDECL) error(DCERR);
   470		mode=ADECL;
   471		args= 2;
   472		while(1)
   473		{	if(sym!=IDENT) error(DCERR);
   474			nptr->ty = INT;
   475			nptr->sc = LVAR;
   476			nptr->dsp = (args += 2);
   477			if(getsym()!=COMMA) break;
   478			getsym();
   479		}
   480		checksym(RPAR);
   481		mode=GDECL;
   482		return;
   483	}
   484	reverse(t1)
   485	int t1;
   486	{int t2,t3;
   487		t2=t1;
   488		while(type!=t1)
   489		{	t3=cadr(type);
   490			rplacad(type,t2);
   491			t2=type;
   492			type=t3;
   493		}
   494		type=t2;
   495	}
   496	size(t)
   497	int t;
   498	{	if(t==CHAR) return 1;
   499		if(scalar(t)) return 2;
   500		if(car(t)==STRUCT||car(t)==UNION)
   501		{	if(cadr(t)==-1) error(DCERR);
   502			return(cadr(t));
   503		}
   504		if(car(t)==ARRAY) return(size(cadr(t))*caddr(t));
   505		else error(DCERR);
   506		/*NOTREACHED*/
   507	}
   508	def(n)
   509	NMTBL *n;
   510	{int sz,nsc,ndsp,slfree,l,t,e;
   511		if(car(type)==FUNCTION)
   512		{	fcheck(n);
   513			return;
   514		}
   515		if (n->sc!=EMPTY &&
   516		    (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) &&
   517		    (mode!=GSDECL&&mode!=LSDECL || n->sc!=FIELD || n->dsp!=disp) &&
   518		    (mode!=GUDECL&&mode!=LUDECL || n->sc!=FIELD || n->dsp!=0) )
   519			 error(DCERR);
   520		sz = size(n->ty = type);
   521		switch(mode)
   522		{case GDECL:
   523			printf("%s\tEQU\t%u\n",n->nm,gpc);
   524		case STADECL:
   525			nsc = GVAR;
   526			ndsp = gpc;
   527			if(sym==ASS)
   528			{	t=type;
   529				if(!scalar(t))
   530					error(TYERR);
   531				if(mode==STADECL) printf("\tBRA\t_%d\n",l=fwdlabel());
   532				fwddef(ilabel);
   533				getsym();
   534				slfree=lfree;
   535				e=expr1();
   536				if(car(e)==CONST)
   537				{	lddim(cadr(e));
   538					indexy(t==CHAR?"STB":"STD",gpc);
   539				}
   540				else if(t!=CHAR)
   541				{	if(car(e)==ADDRESS&&car(cadr(e))==GVAR)
   542						leaxy(cadr(cadr(e)));
   543					else if(car(e)==FNAME)
   544						leaxpcr((NMTBL *)cadr(e));
   545					else error(TYERR);
   546					stxy(gpc);
   547				}
   548				else error(TYERR);
   549				lfree=slfree;
   550				jmp(ilabel=fwdlabel());
   551				if(mode==STADECL) fwddef(l);
   552				type=t;
   553			}
   554			gpc +=sz;
   555			break;
   556		case GSDECL:
   557			nsc = FIELD;
   558			ndsp = disp;
   559			disp += sz;
   560			break;
   561		case GUDECL:
   562			nsc = FIELD;
   563			ndsp = 0;
   564			if (disp < sz) disp = sz;
   565			break;
   566		case GTDECL:
   567			nsc = TYPE;
   568			break;
   569		case ADECL:
   570			if(type==CHAR) ++(n->dsp);
   571			else if (!scalar(type)) error(TYERR);
   572			return;
   573		case LDECL:
   574			nsc = LVAR;
   575			ndsp = (disp -= sz);
   576			break;
   577		case LSDECL:
   578			nsc = FIELD;
   579			ndsp = disp;
   580			disp += sz;
   581			break;
   582		case LUDECL:
   583			nsc = FIELD;
   584			ndsp = 0;
   585			if (disp < sz) disp = sz;
   586			break;
   587		case LTDECL:
   588			nsc = TYPE;
   589			break;
   590		default:
   591			error(DCERR);
   592		}
   593		n->sc = nsc;
   594		n->dsp = ndsp;
   595	}
   596	sdecl(s)
   597	int s;
   598	{int smode,sdisp,type;
   599	NMTBL *nptr0;
   600		smode=mode;
   601		if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL)
   602			mode=(s==STRUCT?GSDECL:GUDECL);
   603		else mode=(s==STRUCT?LSDECL:LUDECL);
   604		sdisp=disp;
   605		disp=0;
   606		if (getsym() == IDENT)
   607		{	nptr0 = nptr;
   608			if (getsym() == LC)
   609			{	if (nptr0->sc != EMPTY) error(DCERR);
   610				nptr0->sc = TAG;
   611				nptr0->ty = list2(s,-1);
   612				while (getsym() != RC) decl();
   613				getsym();
   614				rplacad(type = nptr0->ty,disp);
   615			}
   616			else
   617			{	if(nptr0->sc == EMPTY) nptr0=gnptr;
   618				if(nptr0->sc == EMPTY) error(UDERR);
   619				if(nptr0->sc != TAG) error(TYERR);
   620				type = nptr0->ty;
   621			}
   622		}
   623		else if(sym==LC)
   624		{	while(getsym() != RC) decl();
   625			getsym();
   626			type = list2(s,disp);
   627		}
   628		else error(DCERR);
   629		disp=sdisp;
   630		mode=smode;
   631		return type;
   632	}
   633	fdecl(n)
   634	NMTBL *n;
   635	{	args=0;
   636		fcheck(n);
   637		mode=ADECL;
   638		lfree= HEAPSIZE;
   639		while (sym!=LC) {decl(); getsym();}
   640		disp=0;
   641		mode=STAT;
   642		while (typeid(getsym()) || sym==STATIC || sym==TYPEDEF)
   643		{	mode=LDECL;
   644			decl();
   645			mode=STAT;
   646		}
   647		control=1;
   648		printf("%s\n\tPSHS\tU\n\tLEAU\t,S\n",n->nm);
   649		if(disp) printf("\tLEAS\t%d,S\n",disp);
   650		lvar= -disp;
   651		while(sym!=RC) statement();
   652		if (control) return2();
   653	}
   654	fcheck(n)
   655	NMTBL *n;
   656	{	if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR);
   657		if(n->sc==FUNCTION) compatible(n->ty,cadr(type));
   658		else if(n->sc!=EMPTY) error(DCERR);
   659		n->sc=FUNCTION;
   660		n->ty=cadr(type);
   661	}
   662	compatible(t1,t2)
   663	int t1,t2;
   664	{	if(integral(t1))
   665		{	if(t1!=t2) error(TYERR);
   666		}
   667		else if(car(t1)!=car(t2)) error(TYERR);
   668		else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2))
   669			error(TYERR);
   670		else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION)
   671			compatible(cadr(t1),cadr(t2));
   672	}
   673	scalar(t)
   674	int t;
   675	{	return(integral(t)||car(t)==POINTER);
   676	}
   677	integral(t)
   678	int t;
   679	{	return(t==INT||t==CHAR||t==UNSIGNED);
   680	}
   681	
   682	statement()
   683	{int slfree;
   684		switch(sym)
   685		{case IF:
   686			doif();
   687			return;
   688		case WHILE:
   689			dowhile();
   690			return;
   691		case DO:
   692			dodo();
   693			return;
   694		case FOR:
   695			dofor();
   696			return;
   697		case SWITCH:
   698			doswitch();
   699			return;
   700		case LC:
   701			docomp();
   702			return;
   703		case BREAK:
   704			jmp(blabel);
   705			getsym();
   706			checksym(SM);
   707			return;
   708		case CONTINUE:
   709			jmp(clabel);
   710			getsym();
   711			checksym(SM);
   712			return;
   713		case CASE:
   714			docase();
   715			statement();
   716			return;
   717		case DEFAULT:
   718			dodefault();
   719			statement();
   720			return;
   721		case RETURN:
   722			doreturn();
   723			return;
   724		case GOTO:
   725			dogoto();
   726			return;
   727		case SM:
   728			getsym();
   729			return;
   730		default:if(sym==IDENT&&skipspc()==':')
   731			{	dolabel();
   732				statement();
   733			}
   734			else
   735			{	slfree=lfree;
   736				gexpr(expr());
   737				lfree=slfree;
   738				checksym(SM);
   739			}
   740		}
   741	}
   742	doif()
   743	{int l1,l2,slfree;
   744		getsym();
   745		checksym(LPAR);
   746		slfree=lfree;
   747		bexpr(expr(),0,l1=fwdlabel());
   748		lfree=slfree;
   749		checksym(RPAR);
   750		statement();
   751		if(sym==ELSE)
   752		{	if (l2 = control) jmp(l2=fwdlabel());
   753			fwddef(l1);
   754			getsym();
   755			statement();
   756			if (l2) fwddef(l2);
   757		}
   758		else fwddef(l1);
   759	}
   760	dowhile()
   761	{int sbreak,scontinue,slfree,e;
   762		sbreak=blabel;
   763		scontinue=clabel;
   764		blabel=fwdlabel();
   765		clabel=backdef();
   766		getsym();
   767		checksym(LPAR);
   768		slfree=lfree;
   769		e=expr();
   770		checksym(RPAR);
   771		if(sym==SM)
   772		{	bexpr(e,1,clabel);
   773			lfree=slfree;
   774			getsym();
   775		}
   776		else
   777		{	bexpr(e,0,blabel);
   778			lfree=slfree;
   779			statement();
   780			jmp(clabel);
   781		}
   782		fwddef(blabel);
   783		clabel=scontinue;
   784		blabel=sbreak;
   785	}
   786	dodo()
   787	{int sbreak,scontinue,l,slfree;
   788		sbreak=blabel;
   789		scontinue=clabel;
   790		blabel=fwdlabel();
   791		clabel=fwdlabel();
   792		l=backdef();
   793		getsym();
   794		statement();
   795		fwddef(clabel);
   796		checksym(WHILE);
   797		checksym(LPAR);
   798		slfree=lfree;
   799		bexpr(expr(),1,l);
   800		lfree=slfree;
   801		checksym(RPAR);
   802		checksym(SM);
   803		fwddef(blabel);
   804		clabel=scontinue;
   805		blabel=sbreak;
   806	}
   807	dofor()
   808	{int sbreak,scontinue,l,e,slfree;
   809		sbreak=blabel;
   810		scontinue=clabel;
   811		blabel=fwdlabel();
   812		getsym();
   813		checksym(LPAR);
   814		slfree=lfree;
   815		if(sym!=SM)
   816		{	gexpr(expr());
   817			checksym(SM);
   818		}
   819		else getsym();
   820		lfree=slfree;
   821		l=backdef();
   822		if(sym!=SM)
   823		{	bexpr(expr(),0,blabel);
   824			checksym(SM);
   825		}
   826		else getsym();
   827		lfree=slfree;
   828		if(sym==RPAR)
   829		{	clabel=l;
   830			getsym();
   831			statement();
   832		}
   833		else
   834		{	clabel=fwdlabel();
   835			e=expr();
   836			checksym(RPAR);
   837			statement();
   838			fwddef(clabel);
   839			gexpr(e);
   840			lfree=slfree;
   841		}
   842		jmp(l);
   843		fwddef(blabel);
   844		clabel=scontinue;
   845		blabel=sbreak;
   846	}
   847	doswitch()
   848	{int sbreak,scase,sdefault,slfree;
   849		sbreak=blabel;
   850		blabel=fwdlabel();
   851		sdefault=dlabel;
   852		dlabel=0;
   853		scase=cslabel;
   854		getsym();
   855		checksym(LPAR);
   856		slfree=lfree;
   857		gexpr(expr());
   858		lfree=slfree;
   859		checksym(RPAR);
   860		cslabel = control = 0;
   861		statement();
   862		if(dlabel) printf("_%d\tEQU\t_%d\n",cslabel,dlabel);
   863		else fwddef(cslabel);
   864		cslabel=scase;
   865		dlabel=sdefault;
   866		fwddef(blabel);
   867		blabel=sbreak;
   868	}
   869	docomp()
   870	{	getsym();
   871		while(sym!=RC) statement();
   872		getsym();
   873	}
   874	docase()
   875	{int c,n,l,slfree;
   876		c=0;
   877		n=2;
   878		slfree=lfree;
   879		while(sym==CASE)
   880		{	getsym();
   881			c=list2(cexpr(expr()),c);
   882			n+=6;
   883			checksym(COLON);
   884		}
   885		l=fwdlabel();
   886		if (control)
   887		{	control=0;
   888			if (n>127) jmp(l);
   889			else printf("\tBRA\t_%d\n",l);
   890		}
   891		if (cslabel) fwddef(cslabel);
   892		while(cadr(c))
   893		{	cmpdimm(car(c));
   894			if((n-=6)>127) jcond(l,0);
   895			else printf("\tBEQ\t_%d\n",l);
   896			c=cadr(c);
   897		}
   898		lfree=slfree;
   899		cmpdimm(car(c));
   900		jcond(cslabel=fwdlabel(),1);
   901		fwddef(l);
   902	}
   903	dodefault()
   904	{	getsym();
   905		checksym(COLON);
   906		if (dlabel) error(STERR);
   907		if (!cslabel) jmp(cslabel = fwdlabel());
   908		dlabel = backdef();
   909	}
   910	doreturn()
   911	{int slfree;
   912		if(getsym()==SM)
   913		{	getsym();
   914			return2();
   915			return;
   916		}
   917		slfree=lfree;
   918		gexpr(expr());
   919		lfree=slfree;
   920		checksym(SM);
   921		control=0;
   922		switch(lvar)
   923		{case 0:
   924			ret("");
   925			return;
   926		case 2:
   927			ret("X,");
   928			return;
   929		default:unlink();
   930			return;
   931		}
   932	}
   933	return2()
   934	{	control=0;
   935		switch(lvar)
   936		{case 0:
   937			ret("");
   938			return;
   939		case 1:
   940			ret("A,");
   941			return;
   942		case 2:
   943			ret("D,");
   944			return;
   945		case 3:
   946			ret("A,X,");
   947			return;
   948		case 4:
   949			ret("D,X,");
   950			return;
   951		default:unlink();
   952			return;
   953		}
   954	}
   955	ret(reg)
   956	char *reg;
   957	{	printf("\tPULS\t%sU,PC\n",reg);
   958	}
   959	unlink()
   960	{	printf("\tLEAS\t,U\n");
   961		ret("");
   962	}
   963	dogoto()
   964	{NMTBL *nptr0;
   965		getsym();
   966		nptr0=nptr;
   967		checksym(IDENT);
   968		if(nptr0->sc == BLABEL || nptr0->sc == FLABEL) jmp(nptr0->dsp);
   969		else if(nptr0->sc == EMPTY)
   970		{	nptr0->sc = FLABEL;
   971			jmp(nptr0->dsp = fwdlabel());
   972		}
   973		else error(STERR);
   974		checksym(SM);
   975	}
   976	dolabel()
   977	{	if(nptr->sc == FLABEL) fwddef(nptr->dsp);
   978		else if(nptr->sc != EMPTY) error(TYERR);
   979		nptr->sc = BLABEL;
   980		nptr->dsp = backdef();
   981		getsym();
   982		checksym(COLON);
   983	}
   984	
   985	expr()
   986	{	return(rvalue(expr0()));
   987	}
   988	expr0()
   989	{int e;
   990		e=expr1();
   991		while(sym==COMMA) {getsym();e=list3(COMMA,e,rvalue(expr1()));}
   992		return e;
   993	}
   994	expr1()
   995	{int e1,e2,t,op;
   996		e1=expr2();
   997		switch (sym)
   998		{case ASS:
   999			lcheck(e1);
  1000			t=type;
  1001			getsym();
  1002			e2=rvalue(expr1());
  1003			if(t==CHAR) {type= INT;return(list3(CASS,e1,e2));}
  1004			type=t;
  1005			return(list3(ASS,e1,e2));
  1006		case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS:
  1007		case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS:
  1008			op = sym-AS;
  1009			lcheck(e1);
  1010			t=type;
  1011			getsym();
  1012			e2=rvalue(expr1());
  1013			if(!integral(type)) error(TYERR);
  1014			if((t==UNSIGNED||type==UNSIGNED)&&
  1015				(op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT))
  1016				op=op+US;
  1017			if(t==CHAR)
  1018			{	type= INT;
  1019				return(list4(CASSOP,e1,e2,op));
  1020			}
  1021			type=t;
  1022			if(integral(t)) return(list4(ASSOP,e1,e2,op));
  1023			if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
  1024			e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
  1025			type=t;
  1026			return list4(ASSOP,e1,e2,op);
  1027		default:
  1028			return(e1);
  1029		}
  1030	}
  1031	expr2()
  1032	{int e1,e2,e3,t;
  1033		e1=expr3();
  1034		if(sym==COND)
  1035		{	e1=rvalue(e1);
  1036			getsym();
  1037			e2=rvalue(expr2());
  1038			t=type;
  1039			checksym(COLON);
  1040			e3=rvalue(expr2());
  1041			if(car(e1)==CONST)
  1042				if(cadr(e1)) {type=t;return e2;}
  1043				else return e3;
  1044			if(type==INT||t!=INT&&type==UNSIGNED) type=t;
  1045			return(list4(COND,e1,e2,e3));
  1046		}
  1047		return(e1);
  1048	}
  1049	expr3()
  1050	{int e;
  1051		e=expr4();
  1052		while(sym==LOR)
  1053		{	e=rvalue(e);
  1054			getsym();
  1055			e=list3(LOR,e,rvalue(expr4()));
  1056			type= INT;
  1057		}
  1058		return(e);
  1059	}
  1060	expr4()
  1061	{int e;
  1062		e=expr5();
  1063		while(sym==LAND)
  1064		{	e=rvalue(e);
  1065			getsym();
  1066			e=list3(LAND,e,rvalue(expr5()));
  1067			type= INT;
  1068		}
  1069		return(e);
  1070	}
  1071	expr5()
  1072	{int e1,e2,t;
  1073		e1=expr6();
  1074		while(sym==BOR)
  1075		{	e1=rvalue(e1);
  1076			t=type;
  1077			getsym();
  1078			e2=rvalue(expr6());
  1079			e1=binop(BOR,e1,e2,t,type);
  1080		}
  1081		return(e1);
  1082	}
  1083	expr6()
  1084	{int e1,e2,t;
  1085		e1=expr7();
  1086		while(sym==EOR)
  1087		{	e1=rvalue(e1);
  1088			t=type;
  1089			getsym();
  1090			e2=rvalue(expr7());
  1091			e1=binop(EOR,e1,e2,t,type);
  1092		}
  1093		return(e1);
  1094	}
  1095	expr7()
  1096	{int e1,e2,t;
  1097		e1=expr8();
  1098		while(sym==BAND)
  1099		{	e1=rvalue(e1);
  1100			t=type;
  1101			getsym();
  1102			e2=rvalue(expr8());
  1103			e1=binop(BAND,e1,e2,t,type);
  1104		}
  1105		return(e1);
  1106	}
  1107	expr8()
  1108	{int e,op;
  1109		e=expr9();
  1110		while((op=sym)==EQ||op==NEQ)
  1111		{	e=rvalue(e);
  1112			getsym();
  1113			e=list3(op,e,rvalue(expr9()));
  1114			type= INT;
  1115		}
  1116		return e;
  1117	}
  1118	expr9()
  1119	{int e1,e2,t,op;
  1120		e1=expr10();
  1121		while((op=sym)==GT||op==GE||op==LT||op==LE)
  1122		{	e1=rvalue(e1);
  1123			t=type;
  1124			getsym();
  1125			e2=rvalue(expr10());
  1126			if(t==INT&&type==INT) e1=list3(op,e1,e2);
  1127			else e1=list3(op+US,e1,e2);
  1128			type= INT;
  1129		}
  1130		return e1;
  1131	}
  1132	expr10()
  1133	{int e1,e2,t,op;
  1134		e1=expr11();
  1135		while((op=sym)==RSHIFT||op==LSHIFT)
  1136		{	e1=rvalue(e1);
  1137			t=type;
  1138			getsym();
  1139			e2=rvalue(expr11());
  1140			e1=binop(op,e1,e2,t,type);
  1141		}
  1142		return e1;
  1143	}
  1144	expr11()
  1145	{int e1,e2,t,op;
  1146		e1=expr12();
  1147		while((op=sym)==ADD||op==SUB)
  1148		{	e1=rvalue(e1);
  1149			t=type;
  1150			getsym();
  1151			e2=rvalue(expr12());
  1152			e1=binop(op,e1,e2,t,type);
  1153		}
  1154		return e1;
  1155	}
  1156	expr12()
  1157	{int e1,e2,t,op;
  1158		e1=expr13();
  1159		while((op=sym)==MUL||op==DIV||op==MOD)
  1160		{	e1=rvalue(e1);
  1161			t=type;
  1162			getsym();
  1163			e2=rvalue(expr13());
  1164			e1=binop(op,e1,e2,t,type);
  1165		}
  1166		return e1;
  1167	}
  1168	expr13()
  1169	{int e,op;
  1170		switch (op = sym)
  1171		{case INC: case DEC:
  1172			getsym();
  1173			lcheck(e=expr13());
  1174			if(type==CHAR)
  1175			{	type= INT;
  1176				return(list2(op==INC?CPREINC:CPREDEC,e));
  1177			}
  1178			if(integral(type))
  1179				return(list3(PREINC,e,op==INC?1:-1));
  1180			if(car(type)!=POINTER) error(TYERR);
  1181			return(list3(PREINC,e,
  1182				op==INC?size(cadr(type)):-size(cadr(type)) ));
  1183		case MUL:
  1184			getsym();
  1185			e=rvalue(expr13());
  1186			return(indop(e));
  1187		case BAND:
  1188			getsym();
  1189			switch(car(e=expr13()))
  1190			{case INDIRECT:
  1191				e=cadr(e);
  1192				break;
  1193			case GVAR:
  1194			case LVAR:
  1195				e=list2(ADDRESS,e);
  1196				break;
  1197			case FNAME:
  1198				return e;
  1199			default:error(LVERR);
  1200			}
  1201			type=list2(POINTER,type);
  1202			return e;
  1203		case SUB:
  1204			getsym();
  1205			e=rvalue(expr13());
  1206			if(!integral(type)) error(TYERR);
  1207			return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e));
  1208		case BNOT:
  1209			getsym();
  1210			e=rvalue(expr13());
  1211			if(!integral(type)) error(TYERR);
  1212			return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e));
  1213		case LNOT:
  1214			getsym();
  1215			return(list2(LNOT,rvalue(expr13())));
  1216		case SIZEOF:
  1217			if(getsym()==LPAR)
  1218				if(typeid(getsym()))
  1219				{	e=list2(CONST,size(typename()));
  1220					type=INT;
  1221					checksym(RPAR);
  1222					return e;
  1223				}
  1224				else
  1225				{	e=expr0();
  1226					checksym(RPAR);
  1227					expr16(e);
  1228					if(sym==INC||sym==DEC)
  1229					{	getsym();
  1230						if(type==CHAR) type=INT;
  1231						else if(!scalar(type))
  1232							error(TYERR);
  1233					}
  1234				}
  1235			else expr13();
  1236			e=list2(CONST,size(type));
  1237			type=INT;
  1238			return e;
  1239		}
  1240		e=expr14();
  1241		if((op=sym)==INC||op==DEC)
  1242		{	lcheck(e);
  1243			getsym();
  1244			if(type==CHAR)
  1245			{	type= INT;
  1246				return(list2(op==INC?CPOSTINC:CPOSTDEC,e));
  1247			}
  1248			if(integral(type))
  1249				return(list3(POSTINC,e,op==INC?1:-1));
  1250			if(car(type)!=POINTER) error(TYERR);
  1251			return (list3(POSTINC,e,
  1252				op == INC ? size(cadr(type)): -size(cadr(type)) ));
  1253		}
  1254		return e;
  1255	}
  1256	expr14()
  1257	{int e1,t;
  1258		switch(sym)
  1259		{case IDENT:
  1260			switch(nptr->sc)
  1261			{case GVAR:
  1262				e1=list2(GVAR,nptr->dsp);
  1263				type=nptr->ty;
  1264				getsym();
  1265				break;
  1266			case LVAR:
  1267				e1=list2(LVAR,nptr->dsp);
  1268				type=nptr->ty;
  1269				getsym();
  1270				break;
  1271			case FUNCTION:
  1272				e1=list2(FNAME,(int)nptr);
  1273				type=list2(FUNCTION,nptr->ty);
  1274				getsym();
  1275				break;
  1276			case EMPTY:
  1277				if(getsym()==LPAR)
  1278				{	nptr->sc = FUNCTION;
  1279					nptr->ty= INT;
  1280					type= list2(FUNCTION,INT);
  1281					e1=expr15(list2(FNAME,(int)nptr));
  1282					break;
  1283				}
  1284			default:error(UDERR);
  1285			}
  1286			break;
  1287		case STRING:
  1288			e1=list3(STRING,(int)sptr,symval);
  1289			type=list3(ARRAY,CHAR,symval);
  1290			getsym();
  1291			break;
  1292		case CONST:
  1293			type= INT;
  1294			e1=list2(CONST,symval);
  1295			getsym();
  1296			break;
  1297		case LPAR:
  1298			if(typeid(getsym()))
  1299			{	t=typename();
  1300				checksym(RPAR);
  1301				e1=expr13();
  1302				type=t;
  1303				return e1;
  1304			}
  1305			e1=expr0();
  1306			checksym(RPAR);
  1307			break;
  1308		default:error(EXERR);
  1309		}
  1310		return expr16(e1);
  1311	}
  1312	expr16(e1)
  1313	int e1;
  1314	{int e2,t;
  1315		while(1)
  1316			if(sym==LBRA)
  1317			{	e1=rvalue(e1);
  1318				t=type;
  1319				getsym();
  1320				e2=rvalue(expr0());
  1321				checksym(RBRA);
  1322				e1=binop(ADD,e1,e2,t,type);
  1323				e1=indop(e1);
  1324			}
  1325			else if(sym==LPAR) e1=expr15(e1);
  1326			else if(sym==PERIOD) e1=strop(e1);
  1327			else if(sym==ARROW) e1=strop(indop(rvalue(e1)));
  1328			else break;
  1329		if(car(e1)==FNAME) type=list2(POINTER,type);
  1330		return e1;
  1331	}
  1332	rvalue(e)
  1333	int e;
  1334	{	if(type==CHAR)
  1335		{	type= INT;
  1336			switch(car(e))
  1337			{case GVAR:
  1338				return(list2(CRGVAR,cadr(e)));
  1339			case LVAR:
  1340				return(list2(CRLVAR,cadr(e)));
  1341			case INDIRECT:
  1342				return(list2(CRINDIRECT,cadr(e)));
  1343			default:return(e);
  1344			}
  1345		}
  1346		if(!integral(type))
  1347			if(car(type)==ARRAY)
  1348			{	type=list2(POINTER,cadr(type));
  1349				if(car(e)==INDIRECT) return cadr(e);
  1350				return list2(ADDRESS,e);
  1351			}
  1352			else if(car(type)!=POINTER) error(TYERR);
  1353		switch(car(e))
  1354		{case GVAR:
  1355			return(list2(RGVAR,cadr(e)));
  1356		case LVAR:
  1357			return(list2(RLVAR,cadr(e)));
  1358		case INDIRECT:
  1359			return(list2(RINDIRECT,cadr(e)));
  1360		default:return(e);
  1361		}
  1362	}
  1363	lcheck(e)
  1364	int e;
  1365	{	if(!scalar(type)||car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT)
  1366			error(LVERR);
  1367	}
  1368	indop(e)
  1369	int e;
  1370	{	if(type!=INT&&type!=UNSIGNED)
  1371			if(car(type)==POINTER) type=cadr(type);
  1372			else error(TYERR);
  1373		else type= CHAR;
  1374		if(car(e)==ADDRESS) return(cadr(e));
  1375		return(list2(INDIRECT,e));
  1376	}
  1377	strop(e)
  1378	{	getsym();
  1379		if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR);
  1380		if (integral(type)||car(type)!=STRUCT && car(type)!=UNION)
  1381			e=rvalue(e);
  1382		type = nptr->ty;
  1383		switch(car(e))
  1384		{case GVAR:
  1385		case LVAR:
  1386			e=list2(car(e),cadr(e) + nptr->dsp);
  1387			break;
  1388		case INDIRECT:
  1389			if(!nptr->dsp) break;
  1390			e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp)));
  1391			break;
  1392		default:
  1393			e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
  1394		}
  1395		getsym();
  1396		return e;
  1397	}
  1398	binop(op,e1,e2,t1,t2)
  1399	int op,e1,e2,t1,t2;
  1400	{int e;
  1401		if(car(e1)==CONST&&car(e2)==CONST)
  1402		{	e1=cadr(e1);
  1403			e2=cadr(e2);
  1404			type= INT;
  1405			switch(op)
  1406			{case BOR:
  1407				e=e1|e2;break;
  1408			case EOR:
  1409				e=e1^e2;break;
  1410			case BAND:
  1411				e=e1&e2;break;
  1412			case ADD:
  1413				if(integral(t1))
  1414				{	if(integral(t2))
  1415						e=e1+e2;
  1416					else
  1417					{	if(car(t2)!=POINTER) error(TYERR);
  1418						e=size(cadr(t2))*e1+e2;
  1419						type=t2;
  1420					}
  1421				}
  1422				else
  1423				{	if(car(t1)!=POINTER) error(TYERR);
  1424					e=e1+size(cadr(t1))*e2;
  1425					type=t1;
  1426				}
  1427				break;
  1428			case SUB:
  1429				if(integral(t1))
  1430					e=e1-e2;
  1431				else
  1432				{	if(car(t1)!=POINTER) error(TYERR);
  1433					e=e1-size(cadr(t1))*e2;
  1434					type=t1;
  1435				}
  1436				break;
  1437			case MUL:
  1438				e=e1*e2;break;
  1439			case DIV:
  1440				if(!e2) error(EXERR);e=e1/e2;break;
  1441			case MOD:
  1442				if(!e2) error(EXERR);e=e1%e2;break;
  1443			case RSHIFT:
  1444				e=e1>>e2;break;
  1445			case LSHIFT:
  1446				e=e1<<e2;
  1447			}
  1448			return list2(CONST,e);
  1449		}
  1450		if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&&
  1451			(car(e1)==CONST||car(e2)!=CONST&&
  1452			(car(e1)==RGVAR||car(e1)==RLVAR)))
  1453			{e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;}
  1454		if(op==ADD)
  1455		{	if(integral(t1))
  1456			{	if(integral(t2))
  1457				{	if(t1==INT) type=t2;else type=t1;
  1458					return(list3(ADD,e1,e2));
  1459				}
  1460				if(car(t2)!=POINTER) error(TYERR);
  1461				e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT);
  1462				type=t2;
  1463				return(list3(ADD,e,e2));
  1464			}
  1465			if(car(t1)!=POINTER||!integral(t2)) error(TYERR);
  1466			e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
  1467			type=t1;
  1468			if(car(e1)==ADDRESS&&car(e)==CONST)
  1469				return(list2(ADDRESS,list2(car(cadr(e1)),
  1470					cadr(cadr(e1))+cadr(e))));
  1471			return(list3(ADD,e1,e));
  1472		}
  1473		if(op==SUB)
  1474		{	if(integral(t1))
  1475			{	if(!integral(t2)) error(TYERR);
  1476				if(t1==INT) type=t2;else type=t1;
  1477				return(list3(SUB,e1,e2));
  1478			}
  1479			if(car(t1)!=POINTER) error(TYERR);
  1480			if(integral(t2))
  1481			{	e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
  1482				type=t1;
  1483				return(list3(SUB,e1,e));
  1484			}
  1485			if(car(t2)!=POINTER)
  1486				error(TYERR);
  1487			compatible(t1,t2);
  1488			e=list3(SUB,e1,e2);
  1489			e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT);
  1490			type= INT;
  1491			return e;
  1492		}
  1493		if(!integral(t1)||!integral(t2)) error(TYERR);
  1494		if(t1==INT) type=t2;else type=t1;
  1495		if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1;
  1496		if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2));
  1497		return(list3(type==UNSIGNED?op+US:op,e1,e2));
  1498	}
  1499	expr15(e1)
  1500	int e1;
  1501	{int t,args;
  1502		t=type;
  1503		if(integral(t)||car(t)!=FUNCTION)
  1504			error(TYERR);
  1505		t=cadr(t);
  1506		getsym();
  1507		args=0;
  1508		while(sym!=RPAR)
  1509		{	args=list2(rvalue(expr1()),args);
  1510			if(sym!=COMMA) break;
  1511			getsym();
  1512		}
  1513		checksym(RPAR);
  1514		if(t==CHAR) type= INT;else type=t;
  1515		return list3(FUNCTION,e1,args);
  1516	}
  1517	typeid(s)
  1518	int s;
  1519	{	return (integral(s) || s==SHORT || s==LONG || s==STRUCT || s==UNION ||
  1520			(s==IDENT && nptr->sc==TYPE));
  1521	}
  1522	typename()
  1523	{int t;
  1524		type=t=typespec();
  1525		ndecl0();
  1526		reverse(t);
  1527		return type;
  1528	}
  1529	ndecl0()
  1530	{	if(sym==MUL)
  1531		{	getsym();
  1532			return type=list2(POINTER,ndecl0());
  1533		}
  1534		return ndecl1();
  1535	}
  1536	ndecl1()
  1537	{int i,t;
  1538		if(sym==LPAR)
  1539			if(getsym()==RPAR) {type=list2(FUNCTION,type); getsym();}
  1540			else
  1541			{	ndecl0();
  1542				checksym(RPAR);
  1543			}
  1544		while(1)
  1545			if(sym==LBRA)
  1546			{	getsym();
  1547				t=type;
  1548				i=cexpr(expr());
  1549				checksym(RBRA);
  1550				type=list3(ARRAY,t,i);
  1551			}
  1552			else if(sym==LPAR)
  1553			{	getsym();
  1554				checksym(RPAR);
  1555				type=list2(FUNCTION,type);
  1556			}
  1557			else return type;
  1558	}
  1559	
  1560	bexpr(e1,cond,l1)
  1561	int e1,l1;
  1562	char cond;
  1563	{int e2,l2;
  1564		if (chk) return;
  1565		e2=cadr(e1);
  1566		switch(car(e1))
  1567		{case LNOT:
  1568			bexpr(e2,!cond,l1);
  1569			return;
  1570		case GT:
  1571			rexpr(e1,l1,cond?"GT":"LE");
  1572			return;
  1573		case UGT:
  1574			rexpr(e1,l1,cond?"HI":"LS");
  1575			return;
  1576		case GE:
  1577			rexpr(e1,l1,cond?"GE":"LT");
  1578			return;
  1579		case UGE:
  1580			rexpr(e1,l1,cond?"HS":"LO");
  1581			return;
  1582		case LT:
  1583			rexpr(e1,l1,cond?"LT":"GE");
  1584			return;
  1585		case ULT:
  1586			rexpr(e1,l1,cond?"LO":"HS");
  1587			return;
  1588		case LE:
  1589			rexpr(e1,l1,cond?"LE":"GT");
  1590			return;
  1591		case ULE:
  1592			rexpr(e1,l1,cond?"LS":"HI");
  1593			return;
  1594		case EQ:
  1595			rexpr(e1,l1,cond?"EQ":"NE");
  1596			return;
  1597		case NEQ:
  1598			rexpr(e1,l1,cond?"NE":"EQ");
  1599			return;
  1600		case LAND:
  1601			bexpr(e2,0,cond?(l2=fwdlabel()):l1);
  1602			bexpr(caddr(e1),cond,l1);
  1603			if(cond) fwddef(l2);
  1604			return;
  1605		case LOR:
  1606			bexpr(e2,1,cond?l1:(l2=fwdlabel()));
  1607			bexpr(caddr(e1),cond,l1);
  1608			if(!cond) fwddef(l2);
  1609			return;
  1610		case CRGVAR:
  1611			ldby(e2);
  1612			jcond(l1,cond);
  1613			return;
  1614		case CRLVAR:
  1615			ldbu(e2);
  1616			jcond(l1,cond);
  1617			return;
  1618		case CONST:
  1619			if(cond&&e2||!cond&&!e2) jmp(l1);
  1620			return;
  1621		case RGVAR:
  1622		case RLVAR:
  1623		case CRINDIRECT:
  1624			gexpr(e1);
  1625			jcond(l1,cond);
  1626			return;
  1627		default:gexpr(e1);
  1628			subdim(0);
  1629			jcond(l1,cond);
  1630			return;
  1631		}
  1632	}
  1633	rexpr(e1,l1,s)
  1634	int e1,l1;
  1635	char *s;
  1636	{	gexpr(list3(SUB,cadr(e1),caddr(e1)));
  1637		printf("\tLB%s\t_%d\n",s,l1);
  1638	}
  1639	jcond(l,cond)
  1640	int l;
  1641	char cond;
  1642	{	printf("\tLB%s\t_%d\n",cond?"NE":"EQ",l);
  1643	}
  1644	jmp(l)
  1645	int l;
  1646	{	control=0;
  1647		printf("\tLBRA\t_%d\n",l);
  1648	}
  1649	fwdlabel()
  1650	{	return labelno++;
  1651	}
  1652	fwddef(l)
  1653	int l;
  1654	{	control=1;
  1655		printf("_%d\n",l);
  1656	}
  1657	backdef()
  1658	{	control=1;
  1659		printf("_%d\n",labelno);
  1660		return labelno++;
  1661	}
  1662	
  1663	gexpr(e1)
  1664	int e1;
  1665	{int e2,e3;
  1666		if (chk) return;
  1667		e2 = cadr(e1);
  1668		switch (car(e1))
  1669		{case GVAR:
  1670			leaxy(e2);
  1671			return;
  1672		case RGVAR:
  1673			lddy(e2);
  1674			return;
  1675		case CRGVAR:
  1676			ldby(e2);
  1677			sex();
  1678			return;
  1679		case LVAR:
  1680			leaxu(e2);
  1681			return;
  1682		case RLVAR:
  1683			lddu(e2);
  1684			return;
  1685		case CRLVAR:
  1686			ldbu(e2);
  1687			sex();
  1688			return;
  1689		case FNAME:
  1690			leaxpcr((NMTBL *)e2);
  1691			tfrxd();
  1692			return;
  1693		case CONST:
  1694			if (e2) lddim(e2);
  1695			else clrd();
  1696			return;
  1697		case STRING:
  1698			string(e1);
  1699			return;
  1700		case FUNCTION:
  1701			function(e1);
  1702			return;
  1703		case INDIRECT:
  1704			indirect(e1);
  1705			return;
  1706		case RINDIRECT: case CRINDIRECT:
  1707			rindirect(e1);
  1708			return;
  1709		case ADDRESS:
  1710			gexpr(e2);
  1711			tfrxd();
  1712			return;
  1713		case MINUS:
  1714			gexpr(e2);
  1715			printf("\tNEGA\n\tNEGB\n\tSBCA\t#0\n");
  1716			return;
  1717		case BNOT:
  1718			gexpr(e2);
  1719			printf("\tCOMA\n\tCOMB\n");
  1720			return;
  1721		case PREINC:
  1722			switch (car(e2))
  1723			{case GVAR: case LVAR:
  1724				ldd(e2);
  1725				adddim(caddr(e1));
  1726				std(e2);
  1727				return;
  1728			default:
  1729				gexpr(e2);
  1730				lddx();
  1731				adddim(caddr(e1));
  1732				stdx();
  1733				return;
  1734			}
  1735		case POSTINC:
  1736			switch (car(e2))
  1737			{case GVAR: case LVAR:
  1738				ldd(e2);
  1739				adddim(e3 = caddr(e1));
  1740				std(e2);
  1741				subdim(e3);
  1742				return;
  1743			default:
  1744				gexpr(e2);
  1745				lddx();
  1746				adddim(e3=caddr(e1));
  1747				stdx();
  1748				subdim(e3);
  1749				return;
  1750			}
  1751		case CPOSTINC:
  1752			gexpr(e2);
  1753			ldbx();
  1754			incx();
  1755			sex();
  1756			return;
  1757		case CPREINC:
  1758			gexpr(e2);
  1759			incx();
  1760			ldbx();
  1761			sex();
  1762			return;
  1763		case CPOSTDEC:
  1764			gexpr(e2);
  1765			ldbx();
  1766			decx();
  1767			sex();
  1768			return;
  1769		case CPREDEC:
  1770			gexpr(e2);
  1771			decx();
  1772			ldbx();
  1773			sex();
  1774			return;
  1775		case MUL: case UMUL:
  1776			if (car(e3=caddr(e1)) == CONST)
  1777			{	if (0 < (e3 = cadr(e3)) && e3 <= 10)
  1778				{	gexpr(e2);
  1779					switch (e3)
  1780					{case 8:
  1781						asld();
  1782					case 4:
  1783						asld();
  1784					case 2:
  1785						asld();
  1786					case 1:
  1787						return;
  1788					case 10:
  1789						asld();
  1790					case 5:
  1791						pushd();
  1792						asld();
  1793						asld();
  1794						addds();
  1795						return;
  1796					case 6:
  1797						asld();
  1798					case 3:
  1799						pushd();
  1800						asld();
  1801						addds();
  1802						return;
  1803					case 9: case 7:
  1804						pushd();
  1805						asld();
  1806						asld();
  1807						asld();
  1808						if (e3 == 9) addds(); else subds();
  1809						return;
  1810					}
  1811				}
  1812			}
  1813		case DIV:    case UDIV:	   case MOD:	case UMOD:
  1814		case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
  1815			binexpr(e1);
  1816			return;
  1817		case ADD: case SUB: case BAND: case EOR: case BOR:
  1818			machinop(e1);
  1819			return;
  1820		case COND:
  1821			e2=fwdlabel();
  1822			bexpr(cadr(e1),0,e2);
  1823			gexpr(caddr(e1));
  1824			jmp(e3=fwdlabel());
  1825			fwddef(e2);
  1826			gexpr(cadddr(e1));
  1827			fwddef(e3);
  1828			return;
  1829		case ASS: case CASS:
  1830			assign(e1);
  1831			return;
  1832		case ASSOP: case CASSOP:
  1833			assop(e1);
  1834			return;
  1835		case COMMA:
  1836			gexpr(e2);
  1837			gexpr(caddr(e1));
  1838			return;
  1839		default:
  1840			bexpr(e1,1,e2=fwdlabel());
  1841			clrd();
  1842			printf("\tBRA\t*+5\n");
  1843			fwddef(e2);
  1844			lddim(1);
  1845		}
  1846	}
  1847	string(e1)
  1848	int e1;
  1849	{char *s;
  1850	int i,l,lb;
  1851		s=(char *)cadr(e1);
  1852		lb=fwdlabel();
  1853		if ((l = caddr(e1)) < 128)
  1854			printf("\tLEAX\t2,PC\n\tBRA\t_%d\n",lb);
  1855		else
  1856			printf("\tLEAX\t3,PC\n\tLBRA\t_%d\n",lb);
  1857		do
  1858		{	printf("\tFCB\t%d",*s++);
  1859			for (i=8; --l && --i;) printf(",%d",*s++);
  1860			printf("\n");
  1861		}
  1862		while (l);
  1863		fwddef(lb);
  1864	}
  1865	function(e1)
  1866	int e1;
  1867	{int e2,e3,e4,e5,nargs;
  1868	NMTBL *n;
  1869		e2 = cadr(e1);
  1870		nargs = 0;
  1871		for (e3 = caddr(e1); e3; e3 = cadr(e3))
  1872		{	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
  1873			switch(car(e4))
  1874			{case FNAME:
  1875				leaxpcr(n);
  1876				pushx();
  1877				break;
  1878			case ADDRESS:
  1879				gexpr(e5);
  1880				pushx();
  1881				break;
  1882			default:gexpr(e4);
  1883				pushd();
  1884			}
  1885			++nargs;
  1886		}
  1887		if (car(e2) == FNAME)
  1888		{	n=(NMTBL *)cadr(e2);
  1889			printf("\tLBSR\t%s\n",n->nm);
  1890		}
  1891		else
  1892		{	gexpr(e2);
  1893			printf("\tJSR\t,X\n");
  1894		}
  1895		if (nargs) printf("\tLEAS\t%d,S\n",2*nargs);
  1896	}
  1897	indirect(e1)
  1898	int e1;
  1899	{int e2,e3,e4;
  1900		e3 = cadr(e2 = cadr(e1));
  1901		switch(car(e2))
  1902		{case RGVAR: case RLVAR:
  1903			ldx(e2);
  1904			return;
  1905		case ADD:
  1906			if(car(e3)==ADDRESS)
  1907			{	gexpr(caddr(e2));
  1908				gexpr(cadr(e3));
  1909				opdx("LEAX");
  1910				return;
  1911			}
  1912			switch(car(e4 = caddr(e2)))
  1913			{case RGVAR: case RLVAR:
  1914				gexpr(e3);
  1915				ldx(e4);
  1916				opdx("LEAX");
  1917				return;
  1918			}
  1919		default:
  1920			gexpr(e2);
  1921			tfrdx();
  1922		}
  1923	}
  1924	
  1925	machinop(e1)
  1926	int e1;
  1927	{int e2,e3;
  1928		e2 = cadr(e1);
  1929		switch (car(e3 = caddr(e1)))
  1930		{case RGVAR: case RLVAR: case CONST:
  1931			gexpr(e2);
  1932			oprt(car(e1),e3);
  1933			return;
  1934		default:
  1935			gexpr(e3);
  1936			pushd();
  1937			gexpr(e2);
  1938			tosop(car(e1));
  1939			return;
  1940		}
  1941	}
  1942	
  1943	rindirect(e1)
  1944	int e1;
  1945	{char *op;
  1946	int e2,e3,e4,byte,l;
  1947		op = ((byte = (car(e1) == CRINDIRECT)) ? "LDB" : "LDD");
  1948		e3 = cadr(e2 = cadr(e1));
  1949		switch (car(e2))
  1950		{case RGVAR: case RLVAR:
  1951			indir(op,e2);
  1952			sextend(byte);
  1953			return;
  1954		case ADD:
  1955			if(car(e3)==ADDRESS)
  1956			{	gexpr(caddr(e2));
  1957				gexpr(cadr(e3));
  1958				opdx(op);
  1959				sextend(byte);
  1960				return;
  1961			}
  1962			switch(car(e4=caddr(e2)))
  1963			{case RGVAR: case RLVAR:
  1964				gexpr(e3);
  1965				ldx(e4);
  1966				opdx(op);
  1967				sextend(byte);
  1968				return;
  1969			case CONST:
  1970				switch (car(e3))
  1971				{case RGVAR: case RLVAR:
  1972					ldx(e3);
  1973					indexx(op,cadr(e4));
  1974					sextend(byte);
  1975					return;
  1976				}
  1977			default:
  1978				gexpr(e3);
  1979				pushd();
  1980				gexpr(e4);
  1981				pulx();
  1982				opdx(op);
  1983				sextend(byte);
  1984				return;
  1985			}
  1986		case PREINC:
  1987			if ((l = caddr(e2)) == -1 || l == -2)
  1988				switch (car(e3))
  1989				{case GVAR: case LVAR:
  1990					ldx(e3);
  1991					predecx(op,l);
  1992					stx(e3);
  1993					sextend(byte);
  1994					return;
  1995				}
  1996			break;
  1997		case POSTINC:
  1998			if ((l = caddr(e2)) == 1 || l == 2)
  1999				switch (car(e3))
  2000				{case GVAR: case LVAR:
  2001					ldx(e3);
  2002					postincx(op,l);
  2003					stx(e3);
  2004					sextend(byte);
  2005					return;
  2006				}
  2007			break;
  2008		}
  2009		gexpr(e2);
  2010		tfrdx();
  2011		indexx(op,0);
  2012		sextend(byte);
  2013	}
  2014	assign(e1)
  2015	int e1;
  2016	{char *op;
  2017	int e2,e3,e4,e5,l;
  2018		op = (car(e1) == CASS ? "STB" : "STD");
  2019		e3 = cadr(e2 = cadr(e1));
  2020		e4 = caddr(e1);
  2021		switch(car(e2))
  2022		{case GVAR: case LVAR:
  2023			gexpr(e4);
  2024			index(op,e2);
  2025			return;
  2026		case INDIRECT:
  2027			switch(car(e3))
  2028			{case RGVAR: case RLVAR:
  2029				gexpr(e4);
  2030				indir(op,e3);
  2031				return;
  2032			case ADD:
  2033				if (car(caddr(e3)) == CONST)
  2034					switch (car(e5=cadr(e3)))
  2035					{case RGVAR: case RLVAR:
  2036						gexpr(e4);
  2037						ldx(e5);
  2038						indexx(op,cadr(caddr(e3)));
  2039						return;
  2040					}
  2041				break;
  2042			case PREINC:
  2043				if ((l = caddr(e3)) == -1 || l == -2)
  2044					switch (car(e5=cadr(e3)))
  2045					{case GVAR: case LVAR:
  2046						gexpr(e4);
  2047						ldx(e5);
  2048						predecx(op,l);
  2049						stx(e5);
  2050						return;
  2051					}
  2052				break;
  2053			case POSTINC:
  2054				if ((l = caddr(e3)) == 1 || l == 2)
  2055					switch (car(e5=cadr(e3)))
  2056					{case GVAR: case LVAR:
  2057						gexpr(e4);
  2058						ldx(e5);
  2059						postincx(op,l);
  2060						stx(e5);
  2061						return;
  2062					}
  2063				break;
  2064			}
  2065		}
  2066		switch (car(e4))
  2067		{case RGVAR: case CRGVAR: case RLVAR: case CRLVAR: case CONST:
  2068			gexpr(e2);
  2069			gexpr(e4);
  2070			break;
  2071		default:
  2072			gexpr(e4);
  2073			pushd();
  2074			gexpr(e2);
  2075			pulld();
  2076		}
  2077		indexx(op,0);
  2078		return;
  2079	}
  2080	assop(e1)
  2081	int e1;
  2082	{int e2,e3,byte,op;
  2083	char *ldop,*stop;
  2084		ldop = ((byte = (car(e1) == CASSOP)) ? "LDB" : "LDD");
  2085		stop = (byte ? "STB" : "STD");
  2086		e2 = cadr(e1);
  2087		e3 = caddr(e1);
  2088		op = cadddr(e1);
  2089		switch (car(e2))
  2090		{case GVAR: case LVAR:
  2091			switch (car(e3))
  2092			{case RGVAR: case RLVAR: case CONST:
  2093				if (simpop(op))
  2094				{	index(ldop,e2);
  2095					sextend(byte);
  2096					oprt(op,e3);
  2097					index(stop,e2);
  2098					return;
  2099				}
  2100			default:
  2101				gexpr(e3);
  2102				pushd();
  2103				index(ldop,e2);
  2104				sextend(byte);
  2105				tosop(op);
  2106				index(stop,e2);
  2107				return;
  2108			}
  2109		default:
  2110			switch (car(e3))
  2111			{case RGVAR: case RLVAR: case CONST:
  2112				if (simpop(op))
  2113				{	gexpr(e2);
  2114					indexx(ldop,0);
  2115					sextend(byte);
  2116					oprt(op,e3);
  2117					indexx(stop,0);
  2118					return;
  2119				}
  2120			default:
  2121				gexpr(e3);
  2122				pushd();
  2123				gexpr(e2);
  2124				indexx(ldop,0);
  2125				sextend(byte);
  2126				tosop(op);
  2127				indexx(stop,0);
  2128				return;
  2129			}
  2130		}
  2131	}
  2132	simpop(op)
  2133	int op;
  2134	{	return (op == ADD || op == SUB ||
  2135			op == BAND || op == EOR || op == BOR);
  2136	}
  2137	oprt(op,e1)
  2138	int op,e1;
  2139	{int e2;
  2140		e2 = cadr(e1);
  2141		switch (car(e1))
  2142		{case RGVAR:
  2143			oprt1(op,"Y",e2);
  2144			return;
  2145		case RLVAR:
  2146			oprt1(op,"U",e2);
  2147			return;
  2148		case CONST:
  2149			oprtc(op,e2);
  2150			return;
  2151		}
  2152	}
  2153	oprt1(op,index,n)
  2154	int op,n;
  2155	char *index;
  2156	{	switch (op)
  2157		{case ADD:
  2158			printf("\tADDD\t%d,%s\n",n,index);
  2159			return;
  2160		case SUB:
  2161			printf("\tSUBD\t%d,%s\n",n,index);
  2162			return;
  2163		case BAND: case EOR: case BOR:
  2164			dualop(op,index,n);
  2165			return;
  2166		}
  2167	}
  2168	dualop(op,index,n)
  2169	int op;
  2170	char *index;
  2171	int n;
  2172	{char *ops;
  2173		ops =  ((op == BAND) ? "AND" :
  2174			(op == EOR)  ? "EOR" :
  2175			(op == BOR)  ? "OR"  : (char *)DEBUG);
  2176		printf("\t%sA\t%d,%s\n\t%sB\t%d+1,%s\n",ops,n,index,ops,n,index);
  2177	}
  2178	
  2179	oprtc(op,n)
  2180	int op,n;
  2181	{	switch (op)
  2182		{case ADD:
  2183			adddim(n);
  2184			return;
  2185		case SUB:
  2186			subdim(n);
  2187			return;
  2188		case BAND: case EOR: case BOR:
  2189			dualc(op,n);
  2190			return;
  2191		}
  2192	}
  2193	dualc(op,n)
  2194	int op;
  2195	int n;
  2196	{char *ops;
  2197		ops =  ((op == BAND) ? "AND" :
  2198			(op == EOR)  ? "EOR" :
  2199			(op == BOR)  ? "OR"  : (char *)DEBUG);
  2200		printf("\t%sA\t#%d\n\t%sB\t#%d\n",ops,(n >> 8) & 0xff,ops,n & 0xff);
  2201	}
  2202	tosop(op)
  2203	int op;
  2204	{	switch (op)
  2205		{case ADD:
  2206			addds();
  2207			return;
  2208		case SUB:
  2209			subds();
  2210			return;
  2211		case BAND: case EOR: case BOR:
  2212			dualtosop(op);
  2213			return;
  2214		default:
  2215			pulx();
  2216			library(op);
  2217		}
  2218	}
  2219	dualtosop(op)
  2220	int op;
  2221	{char *ops;
  2222		ops =  ((op == BAND) ? "AND" :
  2223			(op == EOR)  ? "EOR" :
  2224			(op == BOR)  ? "OR"  : (char *)DEBUG);
  2225		printf("\t%sA\t,S+\n\t%sB\t,S+\n",ops,ops);
  2226	}
  2227	pushd()
  2228	{	printf("\tPSHS\tD\n");
  2229	}
  2230	pushx()
  2231	{	printf("\tPSHS\tX\n");
  2232	}
  2233	pulld()
  2234	{	printf("\tPULS\tD\n");
  2235	}
  2236	pulx()
  2237	{	printf("\tPULS\tX\n");
  2238	}
  2239	tfrdx()
  2240	{	printf("\tTFR\tD,X\n");
  2241	}
  2242	tfrxd()
  2243	{	printf("\tTFR\tX,D\n");
  2244	}
  2245	/*
  2246	exgdx()
  2247	{	printf("\tEXG\tD,X\n");
  2248	}
  2249	*/
  2250	asld()
  2251	{	printf("\tASLB\n\tROLA\n");
  2252	}
  2253	adddim(n)
  2254	{	printf("\tADDD\t#%d\n",n);
  2255	}
  2256	subdim(n)
  2257	{	printf("\tSUBD\t#%d\n",n);
  2258	}
  2259	cmpdimm(n)
  2260	int n;
  2261	{	printf("\tCMPD\t#%d\n",n);
  2262	}
  2263	addds()
  2264	{	printf("\tADDD\t,S++\n");
  2265	}
  2266	subds()
  2267	{	printf("\tSUBD\t,S++\n");
  2268	}
  2269	clrd()
  2270	{	printf("\tCLRA\n\tCLRB\n");
  2271	}
  2272	lddim(n)
  2273	int n;
  2274	{	printf("\tLDD\t#%d\n",n);
  2275	}
  2276	
  2277	ldd(e)
  2278	int e;
  2279	{	switch (car(e))
  2280		{case GVAR:
  2281			lddy(cadr(e));
  2282			return;
  2283		case LVAR:
  2284			lddu(cadr(e));
  2285			return;
  2286		default:
  2287			DEBUG;
  2288		}
  2289	}
  2290	
  2291	lddx()
  2292	{	printf("\tLDD\t,X\n");
  2293	}
  2294	lddy(n)
  2295	int n;
  2296	{	printf("\tLDD\t%d,Y\n",n);
  2297	}
  2298	lddu(n)
  2299	int n;
  2300	{	printf("\tLDD\t%d,U\n",n);
  2301	}
  2302	
  2303	std(e)
  2304	int e;
  2305	{	switch (car(e))
  2306		{case GVAR:
  2307			stdy(cadr(e));
  2308			return;
  2309		case LVAR:
  2310			stdu(cadr(e));
  2311			return;
  2312		default:
  2313			DEBUG;
  2314		}
  2315	}
  2316	stdx()
  2317	{	printf("\tSTD\t,X\n");
  2318	}
  2319	stdy(n)
  2320	int n;
  2321	{	printf("\tSTD\t%d,Y\n",n);
  2322	}
  2323	stdu(n)
  2324	int n;
  2325	{	printf("\tSTD\t%d,U\n",n);
  2326	}
  2327	
  2328	ldbx()
  2329	{	printf("\tLDB\t,X\n");
  2330	}
  2331	/*
  2332	stbx()
  2333	{	printf("\tSTB\t,X\n");
  2334	}
  2335	*/
  2336	ldby(n)
  2337	int n;
  2338	{	printf("\tLDB\t%d,Y\n",n);
  2339	}
  2340	ldbu(n)
  2341	int n;
  2342	{	printf("\tLDB\t%d,U\n",n);
  2343	}
  2344	predecx(op,l)
  2345	char *op;
  2346	int l;
  2347	{	printf("\t%s\t,%sX\n",op,(l == -1 ? "-" : "--"));
  2348	}
  2349	postincx(op,l)
  2350	char *op;
  2351	int l;
  2352	{	printf("\t%s\t,X%s\n",op,(l == 1 ? "+" : "++"));
  2353	}
  2354	leaxy(n)
  2355	int n;
  2356	{	printf("\tLEAX\t%d,Y\n",n);
  2357	}
  2358	leaxu(n)
  2359	int n;
  2360	{	printf("\tLEAX\t%d,U\n",n);
  2361	}
  2362	leaxpcr(n)
  2363	NMTBL *n;
  2364	{	printf("\tLEAX\t%s,PCR\n",n->nm);
  2365	}
  2366	
  2367	ldx(e)
  2368	int e;
  2369	{	switch (car(e))
  2370		{case GVAR: case RGVAR:
  2371			ldxy(cadr(e));
  2372			return;
  2373		case LVAR: case RLVAR:
  2374			ldxu(cadr(e));
  2375			return;
  2376		default:
  2377			DEBUG;
  2378		}
  2379	}
  2380	
  2381	ldxy(n)
  2382	int n;
  2383	{	printf("\tLDX\t%d,Y\n",n);
  2384	}
  2385	ldxu(n)
  2386	int n;
  2387	{	printf("\tLDX\t%d,U\n",n);
  2388	}
  2389	/*
  2390	ldxi(n)
  2391	int n;
  2392	{	printf("\tLDX\t#%d\n",n);
  2393	}
  2394	*/
  2395	stx(e)
  2396	int e;
  2397	{	switch (car(e))
  2398		{case GVAR:
  2399			stxy(cadr(e));
  2400			return;
  2401		case LVAR:
  2402			stxu(cadr(e));
  2403			return;
  2404		default:
  2405			DEBUG;
  2406		}
  2407	}
  2408	
  2409	stxy(n)
  2410	int n;
  2411	{	printf("\tSTX\t%d,Y\n",n);
  2412	}
  2413	stxu(n)
  2414	int n;
  2415	{	printf("\tSTX\t%d,U\n",n);
  2416	}
  2417	
  2418	sex()
  2419	{	printf("\tSEX\n");
  2420	}
  2421	incx()
  2422	{	printf("\tINC\t,X\n");
  2423	}
  2424	decx()
  2425	{	printf("\tDEC\t,X\n");
  2426	}
  2427	opdx(op)
  2428	char *op;
  2429	{	printf("\t%s\tD,X\n",op);
  2430	}
  2431	indexx(op,n)
  2432	char *op;
  2433	int n;
  2434	{	printf("\t%s\t%d,X\n",op,n);
  2435	}
  2436	
  2437	index(op,e)
  2438	char *op;
  2439	int e;
  2440	{	switch (car(e))
  2441		{case GVAR:
  2442			indexy(op,cadr(e));
  2443			return;
  2444		case LVAR:
  2445			indexu(op,cadr(e));
  2446			return;
  2447		default:
  2448			DEBUG;
  2449		}
  2450	}
  2451	
  2452	indexy(op,n)
  2453	char *op;
  2454	int n;
  2455	{	printf("\t%s\t%d,Y\n",op,n);
  2456	}
  2457	indexu(op,n)
  2458	char *op;
  2459	int n;
  2460	{	printf("\t%s\t%d,U\n",op,n);
  2461	}
  2462	
  2463	
  2464	indir(op,e)
  2465	char *op;
  2466	int e;
  2467	{	switch (car(e))
  2468		{case RGVAR:
  2469			indiry(op,cadr(e));
  2470			return;
  2471		case RLVAR:
  2472			indiru(op,cadr(e));
  2473			return;
  2474		default:
  2475			DEBUG;
  2476		}
  2477	}
  2478	
  2479	indiry(op,n)
  2480	char *op;
  2481	int n;
  2482	{	printf("\t%s\t[%d,Y]\n",op,n);
  2483	}
  2484	indiru(op,n)
  2485	char *op;
  2486	int n;
  2487	{	printf("\t%s\t[%d,U]\n",op,n);
  2488	}
  2489	sextend(byte)
  2490	int byte;
  2491	{	if (byte) sex();
  2492	}
  2493	binexpr(e1)
  2494	int e1;
  2495	{	gexpr(caddr(e1));
  2496		pushd();
  2497		gexpr(cadr(e1));
  2498		pulx();
  2499		library(car(e1));
  2500	}
  2501	library(op)
  2502	int op;
  2503	{	printf("\tLBSR\t_0000%d\n",
  2504		       ((op == MUL || op == UMUL) ? 1 :
  2505			(op == DIV)	? 2 :
  2506			(op == UDIV)	? 3 :
  2507			(op == MOD)	? 4 :
  2508			(op == UMOD)	? 5 :
  2509			(op == LSHIFT)	? 6 :
  2510			(op == ULSHIFT) ? 7 :
  2511			(op == RSHIFT)	? 8 :
  2512			(op == URSHIFT) ? 9 : DEBUG));
  2513	}
  2514	cexpr(e)
  2515	int e;
  2516	{	if (car(e) != CONST) error(CNERR);
  2517		return (cadr(e));
  2518	}
  2519	
  2520	getsym()
  2521	{NMTBL *nptr0,*nptr1;
  2522	int i;
  2523	char c;
  2524		if (alpha(skipspc()))
  2525		{	i = hash = 0;
  2526			while (alpha(ch) || digit(ch))
  2527			{	if (i <= 7) hash=7*(hash+(name[i++]=ch));
  2528				getch();
  2529			}
  2530			name[i] = '\0';
  2531			nptr0 = gsearch();
  2532			if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
  2533			if (nptr0->sc == MACRO && !mflag)
  2534			{	mflag++;
  2535				chsave = ch;
  2536				chptrsave = chptr;
  2537				chptr = (char *)nptr0->dsp;
  2538				getch();
  2539				return getsym();
  2540			}
  2541			sym = IDENT;
  2542			gnptr=nptr=nptr0;
  2543			if (mode==GDECL || mode==GSDECL || mode==GUDECL ||
  2544			    mode==GTDECL || mode==TOP)
  2545				return sym;
  2546			nptr1=lsearch();
  2547			if (mode==STAT)
  2548				if (nptr1->sc == EMPTY) return sym;
  2549				else { nptr=nptr1; return sym;}
  2550			nptr=nptr1;
  2551			return sym;
  2552		}
  2553		else if (digit(ch))
  2554		{	symval=0;
  2555			if (ch == '0')
  2556			{	if (getch() == 'x' || ch == 'X')
  2557					while(1)
  2558						if(digit(getch()))
  2559							symval=symval*16+ch-'0';
  2560						else if('a'<=ch&&ch<='f')
  2561							symval=symval*16+ch-'a'+10;
  2562						else if('A'<=ch&&ch<='F')
  2563							symval=symval*16+ch-'A'+10;
  2564						else break;
  2565				else while (digit(ch)) {symval=symval*8+ch-'0';getch();}
  2566			}
  2567			else while(digit(ch)) {symval=symval*10+ch-'0';getch();}
  2568			return sym=CONST;
  2569		}
  2570		else if(ch=='\'')
  2571		{	getch();
  2572			symval=escape();
  2573			if(ch!='\'') error(CHERR);
  2574			getch();
  2575			return sym=CONST;
  2576		}
  2577		else if(ch=='"')
  2578		{	getstring();
  2579			return sym= STRING;
  2580		}
  2581		c=ch;
  2582		getch();
  2583		switch(c)
  2584		{case '*':
  2585			return postequ(MUL,MUL+AS);
  2586		case '&':
  2587			if(ch=='&') {getch();return sym=LAND;}
  2588			return postequ(BAND,BAND+AS);
  2589		case '-':
  2590			if(ch=='>') {getch();return sym=ARROW;}
  2591			if(ch=='-') {getch();return sym=DEC;}
  2592			return postequ(SUB,SUB+AS);
  2593		case '!':
  2594			return postequ(LNOT,NEQ);
  2595		case '~':
  2596			return sym=BNOT;
  2597		case '+':
  2598			if(ch=='+') {getch();return sym=INC;}
  2599			return postequ(ADD,ADD+AS);
  2600		case '%':
  2601			return postequ(MOD,MOD+AS);
  2602		case '^':
  2603			return postequ(EOR,EOR+AS);
  2604		case '|':
  2605			if(ch=='|') {getch();return sym=LOR;}
  2606			return postequ(BOR,BOR+AS);
  2607		case '=':
  2608			return postequ(ASS,EQ);
  2609		case '>':
  2610			if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);}
  2611			return postequ(GT,GE);
  2612		case '<':
  2613			if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);}
  2614			return postequ(LT,LE);
  2615		case '(':
  2616			return sym=LPAR;
  2617		case ')':
  2618			return sym=RPAR;
  2619		case '[':
  2620			return sym=LBRA;
  2621		case ']':
  2622			return sym=RBRA;
  2623		case '{':
  2624			return sym=LC;
  2625		case '}':
  2626			return sym=RC;
  2627		case ',':
  2628			return sym=COMMA;
  2629		case ';':
  2630			return sym=SM;
  2631		case ':':
  2632			return sym=COLON;
  2633		case '?':
  2634			return sym=COND;
  2635		case '.':
  2636			return sym=PERIOD;
  2637		case '/':
  2638			if(ch!='*') return postequ(DIV,DIV+AS);
  2639			getch();
  2640			while(ch=='*'?getch()!='/':getch());
  2641			getch();
  2642			return getsym();
  2643		default:
  2644			error(CHERR);
  2645			return getsym();
  2646		}
  2647	}
  2648	postequ(s1,s2)
  2649	int s1,s2;
  2650	{	if(ch=='=') {getch();return sym=s2;}
  2651		return sym=s1;
  2652	}
  2653	alpha(c)
  2654	char c;
  2655	{	return('a'<=c&&c<='z'||'A'<=c&&c<='Z'||c=='_');
  2656	}
  2657	digit(c)
  2658	char c;
  2659	{	return('0'<=c&&c<='9');
  2660	}
  2661	NMTBL *gsearch()
  2662	{NMTBL *nptr,*iptr;
  2663		iptr=nptr= &ntable[hash % GSYMS];
  2664		while(nptr->sc!=EMPTY && neqname(nptr->nm))
  2665		{	if (++nptr== &ntable[GSYMS]) nptr=ntable;
  2666			if (nptr==iptr) error(GSERR);
  2667		}
  2668		if (nptr->sc == EMPTY) copy(nptr->nm);
  2669		return nptr;
  2670	}
  2671	NMTBL *lsearch()
  2672	{NMTBL *nptr,*iptr;
  2673		iptr=nptr= &ntable[hash%LSYMS+GSYMS];
  2674		while(nptr->sc!=EMPTY && neqname(nptr->nm))
  2675		{	if (++nptr== &ntable[LSYMS+GSYMS]) nptr= &ntable[GSYMS];
  2676			if (nptr==iptr) error(LSERR);
  2677		}
  2678		if (nptr->sc == EMPTY) copy(nptr->nm);
  2679		return nptr;
  2680	}
  2681	neqname(p)
  2682	char *p;
  2683	{char *q;
  2684		q=name;
  2685		while(*p) if(*p++ != *q++) return 1;
  2686		return *q!=0;
  2687	}
  2688	copy(p)
  2689	char *p;
  2690	{char *q;
  2691		q=name;
  2692		while(*p++= *q++);
  2693	}
  2694	getstring()
  2695	{	getch();
  2696		symval = 0;
  2697		sptr = cheapp;
  2698		while (ch != '"')
  2699		{	*cheapp++ = escape();
  2700			symval++;
  2701			if (cheapp >= cheap+CHEAPSIZE) error(STRERR);
  2702		}
  2703		getch();
  2704		*cheapp++ = '\0';
  2705		symval++;
  2706	}
  2707	skipspc()
  2708	{	while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') getch();
  2709		return ch;
  2710	}
  2711	getch()
  2712	{	if(*chptr) return ch= *chptr++;
  2713		if(mflag) {mflag=0;chptr=chptrsave;return ch=chsave;}
  2714		getline();
  2715		return getch();
  2716	}
  2717	char escape()
  2718	{char c;
  2719		if ((c=ch) == '\\')
  2720		{	if (digit(c=getch()))
  2721			{	c = ch-'0';
  2722				if (digit(getch()))
  2723				{	c = c*8+ch-'0';
  2724					if (digit(getch())) {c=c*8+ch-'0';getch();}
  2725				}
  2726				return c;
  2727			}
  2728			getch();
  2729			switch(c)
  2730			{case 'n':
  2731				return '\n';
  2732			case 't':
  2733				return '\t';
  2734			case 'b':
  2735				return '\b';
  2736			case 'r':
  2737				return '\r';
  2738			case 'f':
  2739				return '\f';
  2740			case '\n':
  2741				return escape();
  2742			default:
  2743				return c;
  2744			}
  2745		}
  2746		if (c == '\n') error(EXERR);
  2747		getch();
  2748		return c;
  2749	}
  2750	FILE *getfname()
  2751	{int i;
  2752	char name[LBUFSIZE];
  2753		getch();
  2754		if(skipspc()!='"') error(INCERR);
  2755		for(i=0;(getch()!='"' && ch!='\n');)
  2756			if(i<LBUFSIZE-1) name[i++]=ch;
  2757		if(ch=='\n') error(INCERR);
  2758		name[i]=0;
  2759		return ( (filep+1)->fcb = fopen(name,"r") );
  2760	}
  2761	getline()
  2762	{int i;
  2763	int c;
  2764		lineno++;
  2765		glineno++;
  2766		chptr=linebuf;
  2767		i=0;
  2768		while ((*chptr++ = c = getc(filep->fcb)) != '\n')
  2769		{	if (++i > LBUFSIZE-2) error(LNERR);
  2770			if (c==EOF)
  2771			{	error(EOFERR);
  2772				--chptr;
  2773			}
  2774		}
  2775		*chptr = '\0';
  2776		if (lsrc && !asmf) printf("* %s",linebuf);
  2777		if (*(chptr = linebuf) == '#')
  2778		{	++chptr;
  2779			if (macroeq("define"))
  2780			{	i=mode;
  2781				mode=GDECL;
  2782				ch= *chptr;
  2783				if (getsym() == IDENT)
  2784				{	if (nptr->sc == EMPTY)
  2785					{	nptr->sc = MACRO;
  2786						nptr->dsp = (int)cheapp;
  2787						while ((*cheapp++ = c = *chptr++)
  2788								&& c != '\n');
  2789						*cheapp++ = '\0';
  2790						if (cheapp >= cheap+CHEAPSIZE)
  2791							error(STRERR);
  2792						if (!c) error(EOFERR);
  2793					}
  2794					else error(MCERR);
  2795				}
  2796				else error(MCERR);
  2797				mode=i;
  2798				*(chptr = linebuf) = '\0';
  2799			}
  2800			else if (macroeq("include"))
  2801			{	fprintf(stderr,"%s",linebuf);
  2802				if(filep+1 >= filestack + FILES) error(FILERR);
  2803				if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
  2804				(filep+1)->ln=lineno;
  2805				lineno=0;
  2806				++filep;
  2807				*(chptr = linebuf) = '\0';
  2808			}
  2809			else if (macroeq("asm"))
  2810			{	if (asmf) error(MCERR);
  2811				asmf = 1;
  2812				getline();
  2813				while (asmf)
  2814				{	printf("%s",linebuf);
  2815					getline();
  2816				}
  2817			}
  2818			else if (macroeq("endasm"))
  2819			{	if (!asmf) error(MCERR);
  2820				asmf = 0;
  2821			}
  2822			else if (macroeq(" "))
  2823				getline();
  2824			else error(MCERR);
  2825		}
  2826	}
  2827	
  2828	macroeq(s)
  2829	char *s;
  2830	{char *p;
  2831		for (p = chptr; *s;) if (*s++ != *p++) return 0;
  2832		chptr = p;
  2833		return 1;
  2834	}
  2835	
  2836	car(e)
  2837	int e;
  2838	{	return heap[e];
  2839	}
  2840	cadr(e)
  2841	int e;
  2842	{	return heap[e+1];
  2843	}
  2844	caddr(e)
  2845	int e;
  2846	{	return heap[e+2];
  2847	}
  2848	cadddr(e)
  2849	int e;
  2850	{	return heap[e+3];
  2851	}
  2852	list2(e1,e2)
  2853	int e1,e2;
  2854	{int e;
  2855		e=getfree(2);
  2856		heap[e]=e1;
  2857		heap[e+1]=e2;
  2858		return e;
  2859	}
  2860	list3(e1,e2,e3)
  2861	int e1,e2,e3;
  2862	{int e;
  2863		e=getfree(3);
  2864		heap[e]=e1;
  2865		heap[e+1]=e2;
  2866		heap[e+2]=e3;
  2867		return e;
  2868	}
  2869	list4(e1,e2,e3,e4)
  2870	int e1,e2,e3,e4;
  2871	{int e;
  2872		e=getfree(4);
  2873		heap[e]=e1;
  2874		heap[e+1]=e2;
  2875		heap[e+2]=e3;
  2876		heap[e+3]=e4;
  2877		return e;
  2878	}
  2879	getfree(n)
  2880	int n;
  2881	{int e;
  2882		switch (mode)
  2883		{case GDECL: case GSDECL: case GUDECL: case GTDECL:
  2884			e=gfree;
  2885			gfree+=n;
  2886			break;
  2887		default:
  2888			lfree-=n;
  2889			e=lfree;
  2890		}
  2891		if(lfree<gfree) error(HPERR);
  2892		return e;
  2893	}
  2894	rplacad(e,n)
  2895	int e,n;
  2896	{	heap[e+1]=n;
  2897		return e;
  2898	}