[comp.sources.unix] v10i075: Pascal to C translator, Part11/12

rs@uunet.UU.NET (Rich Salz) (07/30/87)

Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
Posting-number: Volume 10, Issue 75
Archive-name: ptoc/Part11


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 11 (of 12)."
# Contents:  ptc.p.4
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ptc.p.4' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ptc.p.4'\"
else
echo shar: Extracting \"'ptc.p.4'\" \(54467 characters\)
sed "s/^X//" >'ptc.p.4' <<'END_OF_FILE'
X				    end
X			until	tq = nil;
X		555:
X			writeln(';');
X			if tp^.tt = nvarpar then
X				if tp^.tbind^.tt = nconfarr then
X				    begin
X					indent;
X					etypedef(tp^.tbind^.tindtyp);
X					write(tab1);
X					tq := tp^.tbind^.tcindx^.thi;
X					printid(tq^.tsym^.lid);
X					writeln(';')
X				    end;
X			tp := tp^.tnext
X		    end
X	end;	(* evar *)
X
X	(*	Emit code for a statment.				*)
X	procedure estmt(tp : treeptr);
X
X	var	tq	: treeptr;
X		locid1,
X		locid2	: idptr;
X		stusd	: boolean;
X		opc1,
X		opc2	: char;
X
X		(*	Emit typename for with-variable.		*)
X		procedure ewithtype(tp : treeptr);
X
X		var	tq	: treeptr;
X
X		begin
X			tq := typeof(tp);
X			write('struct ');
X			printid(tq^.tuid)
X		end;
X
X		(*	Emit code for a case-choise.		*)
X		procedure echoise(tp : treeptr);
X
X		var	tq	: treeptr;
X			i	: integer;
X
X		begin
X			while tp <> nil do
X			    begin
X				tq := tp^.tchocon;
X				i := 0;
X				indent;
X				while tq <> nil do
X				    begin
X					write('  case ');
X					conflag := true;
X					eexpr(tq);
X					conflag := false;
X					write(':');
X					i := i + 1;
X					tq := tq^.tnext;
X					if (tq = nil) or (i mod 4 = 0) then
X					    begin
X						writeln;
X						if tq <> nil then
X							indent;
X						i := 0
X					    end
X				    end;
X				increment;
X				if tp^.tchostmt^.tt = nbegin then
X					estmt(tp^.tchostmt^.tbegin)
X				else
X					estmt(tp^.tchostmt);
X				indent;
X				writeln('break ;');
X				decrement;
X				tp := tp^.tnext;
X				if tp <> nil then
X					if tp^.tchocon = nil then
X						tp := nil
X			    end
X		end;	(* echoise *)
X
X		(*	Rename all accessible record-fields to include	*)
X		(*	pointer name.					*)
X		procedure cenv(ip : idptr; dp : declptr);
X
X		var	tp	: treeptr;
X			sp	: symptr;
X			np	: idptr;
X			h	: hashtyp;
X
X		begin
X			with dp^ do
X			  for h := 0 to hashmax - 1 do
X			    begin
X				sp := ddecl[h];
X				while sp <> nil do
X				    begin
X					if sp^.lt = lfield  then
X					    begin
X						np := sp^.lid;
X						tp := sp^.lsymdecl^.tup^.tup;
X						if (tp^.tup^.tt = nvariant) and
X							(tp^.tuid <> nil) then
X							np := mkconc('.',
X								tp^.tuid, np);
X						np := mkconc('>', ip, np);
X						sp^.lid := np
X					    end;
X					sp := sp^.lnext
X				    end
X			    end
X		end;	(* cenv *)
X
X		(*	Emit identifiers for push/pop of global ptrs.	*)
X		procedure eglobid(tp : treeptr);
X
X		var	j	: toknidx;
X			w	: toknbuf;
X
X		begin
X			gettokn(tp^.tsym^.lid^.istr, w);
X			j := 1;
X			if w[1] = '*' then
X				j := 2;
X			while w[j] <> chr(null) do
X			    begin
X				write(w[j]);
X				j := j + 1
X			    end
X		end;
X
X	begin	(* estmt *)
X		while tp <> nil do
X		    begin
X			case tp^.tt of
X			  nbegin:
X			    begin
X				if tp^.tup^.tt in [nbegin, nrepeat,
X						nproc, nfunc, npgm] then
X					indent;
X				writeln('{');
X				increment;
X				estmt(tp^.tbegin);
X				decrement;
X				indent;
X				write('}');
X				if tp^.tup^.tt <> nif then
X					writeln
X			    end;
X			  nrepeat:
X			    begin
X				indent;
X				writeln('do {');
X				increment;
X				estmt(tp^.treptstmt);
X				decrement;
X				indent;
X				write('} while (!(');
X				eexpr(tp^.treptxp);
X				writeln('));')
X			    end;
X			  nwhile:
X			    begin
X				indent;
X				write('while (');
X				increment;
X				eexpr(tp^.twhixp);
X				stusd := setused;
X				if tp^.twhistmt^.tt = nbegin then
X				    begin
X					decrement;
X					write(') ');
X					estmt(tp^.twhistmt)
X				    end
X				else begin
X					writeln(')');
X					estmt(tp^.twhistmt);
X					decrement
X				     end;
X				setused := stusd or setused
X			    end;
X			  nfor:
X			    begin
X				indent;
X				if tp^.tincr then
X				    begin
X					opc1 := '+';	(* increment variable *)
X					opc2 := '<'	(* test for <= *)
X				    end
X				else begin
X					opc1 := '-';	(* decrement variable *)
X					opc2 := '>';	(* test for >= *)
X				     end;
X				if not lazyfor then
X				    begin
X					locid1 := mkvariable('B');
X					locid2 := mkvariable('B');
X					writeln('{');
X					increment;
X					indent;
X					tq := idup(tp^.tforid);
X					etypedef(tq^.tbind);
X					tq := typeof(tq^.tbind);
X					write(tab1);
X					printid(locid1);
X					write(' = ');
X					eexpr(tp^.tfrom);
X					writeln(',');
X					indent;
X					write(tab1);
X					printid(locid2);
X					write(' = ');
X					eexpr(tp^.tto);
X					writeln(';');
X					writeln;
X					indent;
X					write('if (');
X					if tq^.tt = nscalar then
X					    begin
X						write('(int)(');
X						printid(locid1);
X						write(')')
X					    end
X					else
X						printid(locid1);
X					write(' ', opc2, '= ');
X					if tq^.tt = nscalar then
X					    begin
X						write('(int)(');
X						printid(locid2);
X						write(')')
X					    end
X					else
X						printid(locid2);
X					writeln(')');
X					increment;
X					indent;
X					tp^.tfrom := newid(locid1);
X					tp^.tfrom^.tup := tp
X				    end;
X				write('for (');
X				increment;
X				eexpr(tp^.tforid);
X				tq := typeof(tp^.tforid);
X				write(' = ');
X				eexpr(tp^.tfrom);
X				write('; ');
X				if lazyfor then
X				    begin
X					if tq^.tt = nscalar then
X					    begin
X						write('(int)(');
X						eexpr(tp^.tforid);
X						write(')')
X					    end
X					else
X						eexpr(tp^.tforid);
X					write(' ', opc2, '= ');
X					if tq^.tt = nscalar then
X					    begin
X						write('(int)(');
X						eexpr(tp^.tto);
X						write(')')
X					    end
X					else
X						eexpr(tp^.tto)
X				    end;
X				write('; ');
X				eexpr(tp^.tforid);
X				if tq^.tt = nscalar then
X				    begin
X					write(' = (');
X					eexpr(tq^.tup^.tidl);
X					write(')((int)(');
X					eexpr(tp^.tforid);
X					write(')', opc1, '1)')
X				    end
X				else
X					write(opc1, opc1);
X				if not lazyfor then
X				    begin
X					if tp^.tforstmt^.tt <> nbegin then
X					    begin
X						(* create compund stmt *)
X						tq := mknode(nbegin);
X						tq^.tbegin := tp^.tforstmt;
X						tq^.tbegin^.tup := tq;
X						tp^.tforstmt := tq;
X						tq^.tup := tp
X					    end;
X					(* find end of loop *)
X					tq := tp^.tforstmt^.tbegin;
X					while tq^.tnext <> nil do
X						tq := tq^.tnext;
X					(* add break stmt *)
X					tq^.tnext := mknode(nbreak);
X					tq := tq^.tnext;
X					tq^.tup := tp^.tforstmt;
X					tq^.tbrkid := tp^.tforid;
X					tq^.tbrkxp := newid(locid2);
X					tq^.tbrkxp^.tup := tq
X				    end;
X				if tp^.tforstmt^.tt = nbegin then
X				    begin
X					decrement;
X					write(') ');
X					estmt(tp^.tforstmt)
X				    end
X				else begin
X					writeln(')');
X					estmt(tp^.tforstmt);
X					decrement
X				     end;
X				if not lazyfor then
X				    begin
X					decrement;
X					decrement;
X					indent;
X					writeln('}')
X				    end
X			    end;
X			  nif:
X			    begin
X				indent;
X				write('if (');
X				increment;
X				eexpr(tp^.tifxp);
X				stusd := setused;
X				setused := false;
X				if tp^.tthen^.tt = nbegin then
X				    begin
X					decrement;
X					write(') ');
X					estmt(tp^.tthen);
X					if tp^.telse <> nil then
X						write(space)
X					else
X						writeln
X				    end
X				else begin
X					writeln(')');
X					estmt(tp^.tthen);
X					decrement;
X					if tp^.telse <> nil then
X						indent
X				     end;
X				if tp^.telse <> nil then
X				    begin
X					write('else');
X					if tp^.telse^.tt = nbegin then
X					    begin
X						write(space);
X						estmt(tp^.telse);
X						writeln
X					    end
X					else begin
X						increment;
X						writeln;
X						estmt(tp^.telse);
X						decrement
X					     end;
X				    end;
X				setused := stusd or setused
X			    end;
X			  ncase:
X			    begin
X				indent;
X				write('switch (');
X				increment;
X				eexpr(tp^.tcasxp);
X				writeln(') {');
X				decrement;
X				echoise(tp^.tcaslst);
X				indent;
X				writeln('  default:');
X				increment;
X				if tp^.tcasother = nil then
X				    begin
X					indent;
X					writeln('Caseerror(Line);')
X				    end
X				else
X					estmt(tp^.tcasother);
X				decrement;
X				indent;
X				writeln('}')
X			    end;
X			  nwith:
X			    begin
X				indent;
X				writeln('{');
X				increment;
X				tq := tp^.twithvar;
X				while tq <> nil do
X				    begin
X					indent;
X					write(registr);
X					ewithtype(tq^.texpw);
X					write(' *');
X					locid1 := mkvariable('W');
X					printid(locid1);
X					write(' = ');
X					eaddr(tq^.texpw);
X					writeln(';');
X					cenv(locid1, tq^.tenv);
X					tq := tq^.tnext
X				    end;
X				writeln;
X				if tp^.twithstmt^.tt = nbegin then
X					estmt(tp^.twithstmt^.tbegin)
X				else
X					estmt(tp^.twithstmt);
X				decrement;
X				indent;
X				writeln('}')
X			    end;
X			  ngoto:
X			    begin
X				indent;
X				if islocal(tp^.tlabel) then
X					writeln('goto L',
X						tp^.tlabel^.tsym^.lno:1, ';')
X				else begin
X					tq := idup(tp^.tlabel);
X					writeln('longjmp(J[',	(* LIB *)
X						tq^.tstat:1, '].jb, ',
X						tp^.tlabel^.tsym^.lno:1, ');')
X				     end
X			    end;
X			  nlabstmt:
X			    begin
X				decrement;
X				indent;
X				writeln('L', tp^.tlabno^.tsym^.lno:1, ':');
X				increment;
X				estmt(tp^.tstmt)
X			    end;
X			  nassign:
X			    begin
X				indent;
X				eexpr(tp);
X				writeln(';')
X			    end;
X			  ncall:
X			    begin
X				indent;
X				tq := idup(tp^.tcall);
X				if (tq^.tt in [nfunc, nproc]) and
X						(tq^.tsubstmt <> nil) then
X					if tq^.tsubstmt^.tt = npredef then
X						epredef(tq, tp)
X					else begin
X						ecall(tp);
X						writeln(';')
X					     end
X				else begin
X					ecall(tp);
X					writeln(';')
X				     end
X			    end;
X			  npush:
X			    begin
X				indent;
X				eglobid(tp^.ttmp);
X				write(' = ');
X				eglobid(tp^.tglob);
X				writeln(';');
X				indent;
X				eglobid(tp^.tglob);
X				write(' = ');
X				if tp^.tloc^.tt = nid then
X				    begin
X					tq := idup(tp^.tloc);
X					if tq^.tt in [nparproc, nparfunc] then
X						printid(tp^.tloc^.tsym^.lid)
X					else
X						eaddr(tp^.tloc)
X				    end
X				else
X					eaddr(tp^.tloc);
X				writeln(';')
X			    end;
X			  npop:
X			    begin
X				indent;
X				eglobid(tp^.tglob);
X				write(' = ');
X				eglobid(tp^.ttmp);
X				writeln(';')
X			    end;
X			  nbreak:
X			    begin
X				indent;
X				write('if (');
X				eexpr(tp^.tbrkid);
X				write(' == ');
X				eexpr(tp^.tbrkxp);
X				writeln(') break;')
X			    end;
X			  nempty:
X				if not (tp^.tup^.tt in [npgm, nproc, nfunc,
X						nchoise, nbegin, nrepeat]) then
X				    begin
X					indent;
X					writeln(';')
X				    end
X			end;(* case *)
X			if setused and
X				(tp^.tup^.tt in [npgm, nproc, nfunc, nrepeat,
X						nbegin, nchoise, nwith]) then
X			    begin
X				indent;
X				writeln('Claimset();');
X				setused := false
X			    end;
X			tp := tp^.tnext
X		    end
X	end;	(* estmt *)
X
X	(*	Emit initialization for non-local gotos.		*)
X	procedure elabel(tp : treeptr);
X
X	var	tq	: treeptr;
X		i	: integer;
X
X	begin
X		i := 0;
X		tq := tp^.tsublab;
X		while tq <> nil do
X		    begin
X			if tq^.tsym^.lgo then
X				i := i + 1;
X			tq := tq^.tnext
X		    end;
X		if i =1 then
X		    begin
X			tq := tp^.tsublab;
X			while not tq^.tsym^.lgo do
X				tq := tq^.tnext;
X			indent;
X			writeln('if (',
X				'setjmp(J[', tp^.tstat:1, '].jb))'); (* LIB *)
X			writeln(tab1, 'goto L', tq^.tsym^.lno:1, ';')
X		    end
X		else if i > 1 then
X		    begin
X			indent;
X			writeln('switch (',
X				'setjmp(J[', tp^.tstat:1, '].jb)) {'); (* LIB *)
X			indent;
X			writeln('  case 0:');
X			indent;
X			writeln(tab1, 'break');
X			tq := tp^.tsublab;
X			while tq <> nil do
X			    begin
X				if tq^.tsym^.lgo then
X				    begin
X					(* label used in non-local goto *)
X					indent;
X					writeln('  case ',
X							tq^.tsym^.lno:1, ':');
X					indent;
X					writeln(tab1, 'goto L',
X							tq^.tsym^.lno:1, ';')
X				    end;
X				tq := tq^.tnext
X			    end;
X			indent;
X			writeln('  default:');
X			indent;
X			writeln(tab1, 'Caseerror(Line)');
X			indent;
X			writeln('}')
X		    end
X	end;	(* elabel *)
X
X	(*	Emit declaration for lower bound of conformant array.	*)
X	procedure econf(tp : treeptr);
X
X	var	tq	: treeptr;
X
X	begin
X		while tp <> nil do
X		    begin
X			if tp^.tt = nvarpar then
X				if tp^.tbind^.tt = nconfarr then
X				    begin
X					indent;
X					etypedef(tp^.tbind^.tindtyp);
X					write(tab1);
X					tq := tp^.tbind^.tcindx^.tlo;
X					printid(tq^.tsym^.lid);
X					write(' = (');
X					etypedef(tp^.tbind^.tindtyp);
X					writeln(')0;')
X				    end;
X			tp := tp^.tnext
X		    end
X	end;	(* econf *)
X
X	(*	Emit code for subroutines.				*)
X	procedure esubr(tp : treeptr);
X
X	label	999;
X
X	var	tq, ti	: treeptr;
X
X	begin
X		while tp <> nil do
X		    begin
X			(* emit nested subroutines *)
X			if tp^.tsubsub <> nil then
X			    begin
X				(* emit forward declaration of this subroutine
X				   in case of recursion *)
X				etypedef(tp^.tfuntyp);
X				write(space);
X				printid(tp^.tsubid^.tsym^.lid);
X				writeln('();');
X				writeln;
X				esubr(tp^.tsubsub)
X			    end;
X			(* emit this subroutine *)
X			if tp^.tsubstmt = nil then
X			    begin
X				(* forward/external decl *)
X				if tp^.tsubid^.tsym^.lsymdecl^.tup = tp then
X					write(xtern);
X				etypedef(tp^.tfuntyp);
X				write(space);
X				printid(tp^.tsubid^.tsym^.lid);
X				writeln('();');
X				goto 999
X			    end;
X			write(space);
X			etypedef(tp^.tfuntyp);
X			writeln;
X			printid(tp^.tsubid^.tsym^.lid);
X			write('(');
X			tq := tp^.tsubpar;
X			while tq <> nil do
X			    begin
X				case tq^.tt of
X				  nvarpar,
X				  nvalpar:
X				    begin
X					ti := tq^.tidl;
X					while ti <> nil do
X					    begin
X						printid(ti^.tsym^.lid);
X						ti := ti^.tnext;
X						if ti <> nil then
X							write(', ');
X					    end;
X					if tq^.tbind^.tt = nconfarr then
X					    begin
X						(* add upper bound parameter *)
X						ti := tq^.tbind^.tcindx^.thi;
X						write(', ');
X						printid(ti^.tsym^.lid)
X					    end;
X				    end;
X				  nparproc,
X				  nparfunc:
X				    begin
X					ti := tq^.tparid;
X					printid(ti^.tsym^.lid)
X				    end
X				end;(* case *)
X				tq := tq^.tnext;
X				if tq <> nil then
X					write(', ');
X			    end;
X			writeln(')');
X			increment;
X			evar(tp^.tsubpar);
X			writeln('{');
X			econf(tp^.tsubpar);
X			econst(tp^.tsubconst);
X			etype(tp^.tsubtype);
X			evar(tp^.tsubvar);
X
X			if (tp^.tsubconst <> nil) or (tp^.tsubtype <> nil) or
X					(tp^.tsubvar <> nil) then
X				writeln;
X			elabel(tp);
X			estmt(tp^.tsubstmt);
X			if tp^.tt = nfunc then
X			    begin
X				(* return value in the FIRST variable,
X				   see renamf() above *)
X				indent;
X				write('return ');
X				printid(tp^.tsubvar^.tidl^.tsym^.lid);
X				writeln(';');
X			    end;
X			decrement;
X			writeln('}');
X		999:
X			writeln;
X			tp := tp^.tnext
X		    end
X	end;	(* esubr *)
X
X	function use(d : predefs) : boolean;
X
X	begin
X		use := defnams[d]^.lused
X	end;
X
X	(*	Emit code for main program.				*)
X	procedure eprogram(tp : treeptr);
X
X		(*	Symbol that sp refers to is renamed if it has	*)
X		(*	been redefined in source program.		*)
X		procedure capital(sp : symptr);
X
X		var	tb	: toknbuf;
X
X		begin
X			if sp^.lid^.inref > 1 then
X			    begin
X				gettokn(sp^.lid^.istr, tb);
X				tb[1] := uppercase(tb[1]);
X				sp^.lid := saveid(tb)
X			    end
X		end;
X
X		procedure etextdef;
X
X		var	tq	: treeptr;
X
X		begin
X			write('typedef ');
X			tq := mknode(nfileof);
X			tq^.tof := typnods[tchar];
X			etypedef(tq);
X			writeln(tab1, 'text;')
X		end;
X
X	begin	(* eprogram *)
X		if tp^.tsubid <> nil then
X		    begin
X			(* program heading was seen *)
X			writeln('/', '*');
X			write('**	Code derived from program ');
X			printid(tp^.tsubid^.tsym^.lid);
X			writeln;
X			writeln('*', '/');
X			writeln(xtern, voidtyp, tab1, 'exit();')
X		    end;
X		if usecase or usesets or
X		   use(dinput) or use(doutput) or
X		   use(dwrite) or use(dwriteln) or use(dmessage) or
X		   use(deof) or use(deoln) or use(dflush) or use(dpage) or
X		   use(dread) or use(dreadln) or use(dclose) or
X		   use(dreset) or use(drewrite) or use(dget) or use(dput) then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for i/o');
X			writeln('*', '/');
X			writeln(include, '<stdio.h>')	(* LIB *)
X		    end;
X		if use(dinput) or use(doutput) or use(dtext) then
X		    begin
X			etextdef;
X			if use(dinput) then
X			    begin
X				if tp^.tsubid = nil then
X					write(xtern);
X				write('text', tab1);
X				printid(defnams[dinput]^.lid);
X				if tp^.tsubid <> nil then
X					write(' = { stdin, 0, 0 }');
X				writeln(';')
X			    end;
X			if use(doutput) then
X			    begin
X				if tp^.tsubid = nil then
X					write(xtern);
X				write('text', tab1);
X				printid(defnams[doutput]^.lid);
X				if tp^.tsubid <> nil then
X					write(' = { stdout, 0, 0 }');
X				writeln(';')
X			    end
X		    end;
X		if use(dinput) or use(dget) or use(dread) or use(dreadln) or
X		   use(deof) or use(deoln) or use(dreset) or use(drewrite) then
X		    begin
X			writeln(define, 'Fread(x, f) ',
X				'fread((char *)&x, sizeof(x), 1, f)'); (* LIB *)
X			writeln(define, 'Get(f) Fread((f).buf, (f).fp)');
X			writeln(define, 'Getx(f) (f).init = 1, ',
X				'(f).eoln = (((f).buf = ',
X					'fgetc((f).fp)',	(* LIB *)
X					') == ', nlchr, ') ? (((f).buf = ',
X						spchr, '), 1) : 0');
X			writeln(define, 'Getchr(f) (f).buf, Getx(f)')
X		    end;
X		if use(dread) or use(dreadln) then
X		    begin
X			writeln(static, 'FILE', tab1, '*Tmpfil;');
X			writeln(static, 'long', tab1, 'Tmplng;');
X			writeln(static, 'double', tab1, 'Tmpdbl;');
X			writeln(define, 'Fscan(f) (f).init ? ',
X				'ungetc((f).buf, (f).fp)',	(* LIB *)
X					' : 0, Tmpfil = (f).fp');
X			writeln(define, 'Scan(p, a) ',
X				'Scanck(fscanf(Tmpfil, p, a))'); (* LIB *)
X			writeln(voidtyp, tab1, 'Scanck();');
X			if use(dreadln) then
X				writeln(voidtyp, tab1, 'Getl();');
X		    end;
X		if use(deoln) then
X			writeln(define, 'Eoln(f) ((f).eoln ? true : false)');
X		if use(deof) then
X			writeln(define, 'Eof(f) ',
X				'((((f).init == 0) ? (Get(f)) : 0, ',
X					'((f).eof ? 1 : ',
X						'feof((f).fp))) ? ', (* LIB *)
X							'true : false)');
X		if use(doutput) or use(dput) or
X				use(dwrite) or use(dwriteln) or
X				use(dreset) or use(drewrite) or use(dclose) then
X		    begin
X			writeln(define, 'Fwrite(x, f) ',
X				'fwrite((char *)&x, sizeof(x), 1, f)');(* LIB *)
X			writeln(define, 'Put(f) Fwrite((f).buf, (f).fp)');
X			writeln(define, 'Putx(f) (f).eoln = ((f).buf == ',
X			    nlchr, '), ', voidcast,
X				'fputc((f).buf, (f).fp)'); (* LIB *)
X			writeln(define, 'Putchr(c, f) (f).buf = (c), Putx(f)');
X			writeln(define, 'Putl(f, v) (f).eoln = v')
X		    end;
X		if use(dreset) or use(drewrite) or use(dclose) then
X			writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ',
X				'(Putchr(', nlchr, ', f), 0) : 0, ',
X					'rewind((f).fp)');	(* LIB *)
X		if use(dclose) then
X		    begin
X			writeln(define, 'Close(f) (f).init = ',
X				'((f).init ? (',
X					'fclose((f).fp), ',	(* LIB *)
X						'0) : 0), (f).fp = NULL');
X			writeln(define, 'Closex(f) (f).init = ',
X				'((f).init ? ',
X					'(Finish(f), ',
X					'fclose((f).fp), ',	(* LIB *)
X						'0) : 0), (f).fp = NULL')
X		    end;
X		if use(dreset) then
X		    begin
X			writeln(ifdef, 'READONLY');
X			writeln(static, chartyp, tab1, 'Rmode[] = "r";');
X			writeln(elsif);
X			writeln(static, chartyp, tab1, 'Rmode[] = "r+";');
X			writeln(endif);
X			writeln(define, 'Reset(f, n) (f).init = ',
X			    '(f).init ? rewind((f).fp) : ',	(* LIB *)
X				'(((f).fp = Fopen(n, Rmode)), 1), ',
X					'(f).eof = (f).out = 0, Get(f)');
X			writeln(define, 'Resetx(f, n) (f).init = ',
X			    '(f).init ? (Finish(f)) : ',
X				'(((f).fp = Fopen(n, Rmode)), 1), ',
X					'(f).eof = (f).out = 0, Getx(f)');
X			usefopn := true
X		    end;
X		if use(drewrite) then
X		    begin
X			writeln(ifdef, 'WRITEONLY');
X			writeln(static, chartyp, tab1, 'Wmode[] = "w";');
X			writeln(elsif);
X			writeln(static, chartyp, tab1, 'Wmode[] = "w+";');
X			writeln(endif);
X			writeln(define, 'Rewrite(f, n) (f).init = ',
X			    '(f).init ? rewind((f).fp) : ',	(* LIB *)
X				'(((f).fp = Fopen(n, Wmode)), 1), ',
X					'(f).out = (f).eof = 1');
X			writeln(define, 'Rewritex(f, n) (f).init = ',
X			    '(f).init ? (Finish(f)) : ',
X				'(((f).fp = Fopen(n, Wmode)), 1), ',
X					'(f).out = (f).eof = (f).eoln = 1');
X			usefopn := true
X		    end;
X		if usefopn then
X		    begin
X			writeln('FILE	*Fopen();');
X			writeln(define, 'MAXFILENAME 256')
X		    end;
X		if usecase or usejmps then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for case-statements');
X			writeln('**	and for non-local gotos');
X			writeln('*', '/');
X			writeln(define, 'Line __LINE__');
X			writeln(voidtyp, tab1, 'Caseerror();')
X		    end;
X		if usejmps then
X		    begin
X			writeln(include, '<setjmp.h>');	(* LIB *)
X			writeln(static, 'struct Jb { jmp_buf', tab1, 'jb; } J[',
X							(maxlevel+1):1, '];')
X		    end;
X		if use(dinteger) or use(dmaxint) or 
X			use(dboolean) or use(dfalse) or use(dtrue) or
X				use(deof) or use(deoln) or use(dexp) or
X				use(dln) or use(dsqr) or use(dsin) or
X				use(dcos) or use(dtan) or use(darctan) or
X				use(dsqrt) or use(dreal) then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for standard types');
X			writeln('*', '/')
X		    end;
X		if usecomp then
X		    begin
X			writeln(xtern, inttyp, ' strncmp();');	(* LIB *)
X			writeln(define,
X				'Cmpstr(x, y) ',
X				'strncmp((x), (y), sizeof(x))')	(* LIB *)
X		    end;
X		if use(dboolean) or use(dfalse) or use(dtrue) or
X			use(deof) or use(deoln) or usesets then
X		    begin
X			capital(defnams[dboolean]);
X			write(typdef, chartyp, tab1);
X			printid(defnams[dboolean]^.lid);
X			writeln(';');
X			capital(defnams[dfalse]);
X			write(define);
X			printid(defnams[dfalse]^.lid);
X			write(' (');
X			printid(defnams[dboolean]^.lid);
X			writeln(')0');
X			capital(defnams[dtrue]);
X			write(define);
X			printid(defnams[dtrue]^.lid);
X			write(' (');
X			printid(defnams[dboolean]^.lid);
X			writeln(')1');
X			writeln(xtern, chartyp, tab1, '*Bools[];')
X		    end;
X		capital(defnams[dinteger]);
X		if use(dinteger) then
X		    begin
X			write(typdef, inttyp, tab1);
X			printid(defnams[dinteger]^.lid);
X			writeln(';')
X		    end;
X		if use(dmaxint) then
X			writeln(define, 'maxint', tab1, maxint:1);
X		capital(defnams[dreal]);
X		if use(dreal) then
X		    begin
X			write(typdef, realtyp, tab1);
X			printid(defnams[dreal]^.lid);
X			writeln(';')
X		    end;
X		if use(dexp) then
X			writeln(xtern, doubletyp, ' exp();');	(* LIB *)
X		if use(dln) then
X			writeln(xtern, doubletyp, ' log();');	(* LIB *)
X		if use(dsqr) then
X			writeln(xtern, doubletyp, ' pow();');	(* LIB *)
X		if use(dsin) then
X			writeln(xtern, doubletyp, ' sin();');	(* LIB *)
X		if use(dcos) then
X			writeln(xtern, doubletyp, ' cos();');	(* LIB *)
X		if use(dtan) then
X			writeln(xtern, doubletyp, ' tan();');	(* LIB *)
X		if use(darctan) then
X			writeln(xtern, doubletyp, ' atan();');	(* LIB *)
X		if use(dsqrt) then
X			writeln(xtern, doubletyp, ' sqrt();');	(* LIB *)
X		if use(dabs) and use(dreal) then
X			writeln(xtern, doubletyp, ' fabs();');	(* LIB *)
X		if use(dhalt) then
X			writeln(xtern, voidtyp, ' abort();');	(* LIB *)
X		if use(dnew) or usenilp then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for pointers');
X			writeln('*', '/');
X		    end;
X		if use(dnew) then
X		    begin
X			writeln(ifndef, 'Unionoffs');
X			writeln(define, 'Unionoffs(p, m) ',
X			    '(((long)(&(p)->m))-((long)(p)))');	(* CPU *)
X			writeln(endif)
X		    end;
X		if usenilp then
X			writeln(define, 'NIL 0');		(* CPU *)
X		if use(dnew) then
X			writeln(xtern, chartyp, ' *malloc();');	(* LIB *)
X		if use(ddispose) then
X			writeln(xtern, voidtyp, ' free();');	(* LIB *)
X		if usesets then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for set-operations');
X			writeln('*', '/');
X			writeln(define, 'Claimset() ',
X				voidcast, 'Currset(0, (', setptyp, ')0)');
X			writeln(define, 'Newset() ',
X					'Currset(1, (', setptyp, ')0)');
X			writeln(define, 'Saveset(s) Currset(2, s)');
X			writeln(define, 'setbits ', setbits:1);
X			writeln(typdef, wordtype, tab1, setwtyp, ';');
X			writeln(typdef, setwtyp, ' *', tab1, setptyp, ';');
X			printid(defnams[dboolean]^.lid);
X			writeln(tab1, 'Member(), Le(), Ge(), Eq(), Ne();');
X			writeln(setptyp, tab1, 'Union(), Diff();');
X			writeln(setptyp, tab1, 'Insmem(), Mksubr();');
X			writeln(setptyp, tab1, 'Currset(), Inter();');
X			writeln(static, setptyp, tab1, 'Tmpset;');
X			writeln(xtern, setptyp, tab1, 'Conset[];');
X			writeln(voidtyp, tab1, 'Setncpy();')
X		    end;
X		writeln(xtern, chartyp, ' *strncpy();');	(* LIB *)
X		if use(dargc) or use(dargv) then
X		    begin
X			writeln('/', '*');
X			writeln('**	Definitions for argv-operations');
X			writeln('*', '/');
X			writeln(inttyp, tab1, 'argc;');		(* OS *)
X			writeln(chartyp, tab1, '**argv;');
X			writeln(' void');
X			writeln('Argvgt(n, cp, l)');
X			writeln(inttyp, tab1, 'n;');
X			writeln(registr, inttyp, tab1, 'l;');
X			writeln(registr, chartyp, tab1, '*cp;');
X			writeln('{');
X			writeln(tab1, registr, chartyp, tab1, '*sp;');
X			writeln;
X			writeln(tab1, 'for (sp = argv[n]; l > 0 && *sp; l--)');
X			writeln(tab2, '*cp++ = *sp++;');
X			writeln(tab1, 'while (l-- > 0)');
X			writeln(tab2, '*cp++ = ', spchr, ';');
X			writeln('}');
X		    end;
X		if (tp^.tsubconst <> nil) or (tp^.tsubtype<> nil) or
X			(tp^.tsubvar <> nil) or (tp^.tsubsub <> nil) then
X		    begin
X			writeln('/', '*');
X			writeln('**	Start of program definitions');
X			writeln('*', '/');
X		    end;
X		econst(tp^.tsubconst);
X		etype(tp^.tsubtype);
X		evar(tp^.tsubvar);
X		if tp^.tsubsub <> nil then
X			writeln;
X		esubr(tp^.tsubsub);
X		if tp^.tsubid <> nil then
X		    begin
X			(* program heading was seen *)
X			writeln('/', '*');
X			writeln('**	Start of program code');
X			writeln('*', '/');
X			if use(dargc) or use(dargv) then
X			    begin
X				writeln('main(_ac, _av)');	(* OS *)
X				writeln(inttyp, tab1, '_ac;');
X				writeln(chartyp, tab1, '*_av[];');
X				writeln('{');
X				writeln;
X				writeln(tab1, 'argc = _ac;');
X				writeln(tab1, 'argv = _av;')
X			    end
X			else begin
X				writeln('main()');
X				writeln('{')
X			     end;
X			increment;
X			elabel(tp);
X			estmt(tp^.tsubstmt);
X			indent;
X			writeln('exit(0);');
X			decrement;
X			writeln('}');
X			writeln('/', '*');
X			writeln('**	End of program code');
X			writeln('*', '/')
X		    end
X	end;	(* eprogram *)
X
X	(*	Emit definitions for constant sets	*)
X	procedure econset(tp : treeptr; len : integer);
X
X	var	i	: integer;
X
X		function size(tp : treeptr) : integer;
X
X		var	r, x	: integer;
X
X		begin
X			r := 0;
X			while tp <> nil do
X			    begin
X				if tp^.tt = nrange then
X					x := cvalof(tp^.texpr)
X				else if tp^.tt = nempty then
X					x := 0
X				else
X					x := cvalof(tp);
X				if x > r then
X					r := x;
X				tp := tp^.tnext
X			    end;
X			size := csetwords(r+1)
X		end;
X
X		(*	Emit bits in a constant set	*)
X		procedure ebits(tp : treeptr);
X
X		type	bitset	= set of 0 .. setbits;
X
X		var	sets	: array [ 0 .. maxsetrange ] of bitset;
X			s, m, n	: integer;
X
X			procedure eword(s : bitset);
X
X			const	bitshex	= 4;	(* nr of bits in a hex-digit *)
X
X			var	n, i	: integer;
X				x	: 0 .. setbits;
X
X			begin
X				n := 0;
X				while n <= setbits do
X					n := n + bitshex;
X				n := n - bitshex;
X				while n >= 0 do
X				    begin
X					(* compute 1 hexdigit *)
X					x := 0;
X					for i := 0 to bitshex - 1 do
X						if (n + i) in s then
X							case i of
X							  0:	x := x + 1;
X							  1:	x := x + 2;
X							  2:	x := x + 4;
X							  3:	x := x + 8
X							end;(* case *)
X					(* print it *)
X					write(hexdig[x]);
X					n := n - bitshex
X				    end
X			end;
X
X		begin
X			s := size(tp);
X			for n := 0 to s - 1 do
X				sets[n] := [];
X			while tp <> nil do
X			    begin
X				if tp^.tt = nrange then
X					for m := cvalof(tp^.texpl) to
X							cvalof(tp^.texpr) do
X					    begin
X						n := m div (setbits+1);
X						sets[n] := sets[n] +
X							[m mod (setbits+1)]
X					    end
X				else if tp^.tt <> nempty then
X				    begin
X					m := cvalof(tp);
X					n := m div (setbits+1);
X					sets[n] := sets[n] +
X						[m mod (setbits+1)]
X				    end;
X				tp := tp^.tnext
X			    end;
X			write(tab1, s:1);
X			for n := 0 to s - 1 do
X			    begin
X				write(',');
X				if n mod 6 = 0 then
X					writeln;
X				write(tab1, '0x');
X				eword(sets[n]);
X			    end;
X			writeln
X		end;
X
X	begin
X		i := 0;
X		while tp <> nil do
X		    begin
X			writeln(static, setwtyp, tab1, 'Q', i:1, '[] = {');
X			ebits(tp^.texps);
X			writeln('};');
X			i := i + 1;
X			tp := tp^.tnext
X		    end;
X		writeln(static, setwtyp, tab1, '*Conset[] = {');
X		for i := len - 1 downto 1 do
X		    begin
X			write(tab1, 'Q', i:1, ',');
X			if i mod 6 = 5 then
X				writeln
X		    end;
X		writeln(tab1, 'Q0');
X		writeln('};');
X	end;
X
Xbegin	(* emit *)
X	indnt := 0;
X	varno := 0;
X	conflag := false;
X	setused := false;
X	dropset := false;
X	doarrow := 0;
X	eprogram(top);
X	if usebool then
X		writeln(chartyp, tab1, '*Bools[] = { "false", "true" };');
X	if usescan then
X	    begin
X		writeln;
X		writeln(static, voidtyp);
X		writeln('Scanck(n)');
X		writeln(inttyp, tab1, 'n;');
X		writeln('{');
X		writeln(tab1, 'if (n != 1) {');
X		writeln(tab2, voidcast, 'fprintf(stderr, "Bad input\n");');
X		writeln(tab2, 'exit(1);');
X		writeln(tab1, '}');
X		writeln('}')
X	    end;
X	if usegetl then
X	    begin
X		writeln;
X		writeln(static, voidtyp);
X		writeln('Getl(f)');
X		writeln(' text', tab1, '*f;');
X		writeln('{');
X		writeln(tab1, 'while (f->eoln == 0)');
X		writeln(tab2, 'Getx(*f);');
X		writeln(tab1, 'Getx(*f);');
X		writeln('}')
X	    end;
X	if usefopn then
X	    begin
X		writeln;
X		writeln(static, 'FILE *');
X		writeln('Fopen(n, m)');
X		writeln(chartyp, tab1, '*n, *m;');
X		writeln('{');
X		writeln(tab1, 'FILE', tab2, '*f;');
X		writeln(tab1, registr, chartyp, tab1, '*s;');
X		writeln(tab1, static, chartyp, tab1, 'ch = ',
X						quote, 'A', quote, ';');
X		writeln(tab1, static, chartyp, tab1, 'tmp[MAXFILENAME];');
X		writeln(tab1, xtern , inttyp, tab1, 'unlink();'); (* OS *)
X		writeln;
X		writeln(tab1, 'if (n == NULL)');
X		writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);');
X		writeln(tab1, 'else {');
X		writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));');
X		writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ',
X			spchr, ' || *s == ', nulchr, '; )');
X		writeln(tab3, '*s-- = ', nulchr, ';');
X		writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {');
X		writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ',
X			quote, '%s', quote, '\n", n);');
X		writeln(tab3, 'exit(1);');
X		writeln(tab2, '}');
X		writeln(tab1, '}');
X		writeln(tab1, 's = tmp;');
X		writeln(tab1, 'if ((f = fopen(s, m)) == NULL) {');
X		writeln(tab2, voidcast,
X				'fprintf(stderr, "Cannot open: %s\n", s);');
X		writeln(tab2, 'exit(1);');
X		writeln(tab1, '}');
X		writeln(tab1, 'if (n == NULL)');
X		writeln(tab2, 'unlink(tmp);');	(* OS *)
X		writeln(tab1, 'return (f);');
X		writeln('}');
X		writeln(xtern, inttyp, tab1, 'rewind();')
X	    end;
X	if setcnt > 0 then
X		econset(setlst, setcnt);
X	if useunion then
X	    begin
X		writeln;
X		writeln(static, setptyp);
X		writeln('Union(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
X		writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
X		writeln(tab4, 'p3 = sp;');
X		writeln;
X		writeln(tab1, 'j = *p1;');
X		writeln(tab1, '*p3 = j;');
X		writeln(tab1, 'if (j > *p2)');
X		writeln(tab2, 'j = *p2;');
X		writeln(tab1, 'else');
X		writeln(tab2, '*p3 = *p2;');
X		writeln(tab1, 'k = *p1 - *p2;');
X		writeln(tab1, 'p1++, p2++, p3++;');
X		writeln(tab1, 'for (i = 0; i < j; i++)');
X		writeln(tab2, '*p3++ = (*p1++ | *p2++);');
X		writeln(tab1, 'while (k > 0) {');
X		writeln(tab2, '*p3++ = *p1++;');
X		writeln(tab2, 'k--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (k < 0) {');
X		writeln(tab2, '*p3++ = *p2++;');
X		writeln(tab2, 'k++;');
X		writeln(tab1, '}');
X		writeln(tab1, 'return (Saveset(sp));');
X		writeln('}')
X	    end;
X	if usediff then
X	    begin
X		writeln;
X		writeln(static, setptyp);
X		writeln('Diff(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
X		writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
X		writeln(tab4, 'p3 = sp;');
X		writeln;
X		writeln(tab1, 'j = *p1;');
X		writeln(tab1, '*p3 = j;');
X		writeln(tab1, 'if (j > *p2)');
X		writeln(tab2, 'j = *p2;');
X		writeln(tab1, 'k = *p1 - *p2;');
X		writeln(tab1, 'p1++, p2++, p3++;');
X		writeln(tab1, 'for (i = 0; i < j; i++)');
X		writeln(tab2, '*p3++ = (*p1++ & ~ (*p2++));');
X		writeln(tab1, 'while (k > 0) {');
X		writeln(tab2, '*p3++ = *p1++;');
X		writeln(tab2, 'k--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'return (Saveset(sp));');
X		writeln('}')
X	    end;
X	if useintr then
X	    begin
X		writeln;
X		writeln(static, setptyp);
X		writeln('Inter(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
X		writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
X		writeln(tab4, 'p3 = sp;');
X		writeln;
X		writeln(tab1, 'if ((j = *p1) > *p2)');
X		writeln(tab2, 'j = *p2;');
X		writeln(tab1, '*p3 = j;');
X		writeln(tab1, 'p1++, p2++, p3++;');
X		writeln(tab1, 'for (i = 0; i < j; i++)');
X		writeln(tab2, '*p3++ = (*p1++ & *p2++);');
X		writeln(tab1, 'return (Saveset(sp));');
X		writeln('}')
X	    end;
X	if usememb then
X	    begin
X		writeln;
X		write(static);
X		printid(defnams[dboolean]^.lid);
X		writeln;
X		writeln('Member(m, sp)');
X		writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
X		writeln(tab1, registr, setptyp, tab1, 'sp;');
X		writeln('{');
X		writeln(tab1, registr, usigned, inttyp,
X					tab1, 'i = m / (setbits+1) + 1;');
X		writeln;
X		writeln(tab1, 'if ((i <= *sp) &&',
X					' (sp[i] & (1 << (m % (setbits+1)))))');
X		write(tab2, 'return (');
X		printid(defnams[dtrue]^.lid);
X		writeln(');');
X		write(tab1, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln('}')
X	    end;
X	if useseq or usesne then
X	    begin
X		writeln;
X		write(static);
X		printid(defnams[dboolean]^.lid);
X		writeln;
X		writeln('Eq(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab1, 'i, j;');
X		writeln;
X		writeln(tab1, 'i = *p1++;');
X		writeln(tab1, 'j = *p2++;');
X		writeln(tab1, 'while (i != 0 && j != 0) {');
X		writeln(tab2, 'if (*p1++ != *p2++)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'i--, j--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (i != 0) {');
X		writeln(tab2, 'if (*p1++ != 0)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'i--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (j != 0) {');
X		writeln(tab2, 'if (*p2++ != 0)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'j--;');
X		writeln(tab1, '}');
X		write(tab1, 'return (');
X		printid(defnams[dtrue]^.lid);
X		writeln(');');
X		writeln('}')
X	    end;
X	if usesne then
X	    begin
X		writeln;
X		write(static);
X		printid(defnams[dboolean]^.lid);
X		writeln;
X		writeln('Ne(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		write(tab1, 'return (!Eq(p1, p2));');
X		writeln('}')
X	    end;
X	if usesle then
X	    begin
X		writeln;
X		write(static);
X		printid(defnams[dboolean]^.lid);
X		writeln;
X		writeln('Le(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab1, 'i, j;');
X		writeln;
X		writeln(tab1, 'i = *p1++;');
X		writeln(tab1, 'j = *p2++;');
X		writeln(tab1, 'while (i != 0 && j != 0) {');
X		writeln(tab2, 'if ((*p1++ & ~ *p2++) != 0)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'i--, j--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (i != 0) {');
X		writeln(tab2, 'if (*p1++ != 0)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'i--;');
X		writeln(tab1, '}');
X		write(tab1, 'return (');
X		printid(defnams[dtrue]^.lid);
X		writeln(');');
X		writeln('}')
X	    end;
X	if usesge then
X	    begin
X		writeln;
X		write(static);
X		printid(defnams[dboolean]^.lid);
X		writeln;
X		writeln('Ge(p1, p2)');
X		writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab1, 'i, j;');
X		writeln;
X		writeln(tab1, 'i = *p1++;');
X		writeln(tab1, 'j = *p2++;');
X		writeln(tab1, 'while (i != 0 && j != 0) {');
X		writeln(tab2, 'if ((*p2++ & ~ *p1++) != 0)');
X		writeln(tab3, 'return (false);');
X		writeln(tab2, 'i--, j--;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (j != 0) {');
X		writeln(tab2, 'if (*p2++ != 0)');
X		write(tab3, 'return (');
X		printid(defnams[dfalse]^.lid);
X		writeln(');');
X		writeln(tab2, 'j--;');
X		writeln(tab1, '}');
X		write(tab1, 'return (');
X		printid(defnams[dtrue]^.lid);
X		writeln(');');
X		writeln('}')
X	    end;
X	if usemksub then
X	    begin
X		writeln;
X		writeln(static, setptyp);
X		writeln('Mksubr(lo, hi, sp)');
X		writeln(tab1, registr, usigned, inttyp, tab1, 'lo, hi;');
X		writeln(tab1, registr, setptyp, tab1, 'sp;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab1, 'i, k;');
X		writeln;
X		writeln(tab1, 'if (hi < lo)');
X		writeln(tab2, 'return (sp);');
X		writeln(tab1, 'i = hi / (setbits+1) + 1;');
X		writeln(tab1, 'for (k = *sp + 1; k <= i; k++)');
X		writeln(tab2, 'sp[k] = 0;');
X		writeln(tab1, 'if (*sp < i)');
X		writeln(tab2, '*sp = i;');
X		writeln(tab1, 'for (k = lo; k <= hi; k++)');
X		writeln(tab2, 'sp[k / (setbits+1) + 1] |= ',
X						'(1 << (k % (setbits+1)));');
X		writeln(tab1, 'return (sp);');
X		writeln('}')
X	    end;
X	if useins then
X	    begin
X		writeln;
X		writeln(static, setptyp);
X		writeln('Insmem(m, sp)');
X		writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
X		writeln(tab1, registr, setptyp, tab1, 'sp;');
X		writeln('{');
X		writeln(tab1, registr, inttyp, tab1, 'i,');
X		writeln(tab3, tab1, 'j = m / (setbits+1) + 1;');
X		writeln;
X		writeln(tab1, 'if (*sp < j)');
X		writeln(tab2, 'for (i = *sp + 1, *sp = j; i <= *sp; i++)');
X		writeln(tab3, 'sp[i] = 0;');
X		writeln(tab1, 'sp[j] |= (1 << (m % (setbits+1)));');
X		writeln(tab1, 'return (sp);');
X		writeln('}')
X	    end;
X	if usesets then
X	    begin
X		writeln;
X		writeln(ifndef, 'SETSPACE');
X		writeln(define, 'SETSPACE 256');
X		writeln(endif);
X		writeln(static, setptyp);
X		writeln('Currset(n,sp)');
X		writeln(tab1, inttyp, tab1, 'n;');
X		writeln(tab1, setptyp, tab1, 'sp;');
X		writeln('{');
X		writeln(tab1, static, setwtyp, tab1, 'Space[SETSPACE];');
X		writeln(tab1, static, setptyp, tab1, 'Top = Space;');
X		writeln;
X		writeln(tab1, 'switch (n) {');
X		writeln(tab1, '  case 0:');
X		writeln(tab2, 'Top = Space;');
X		writeln(tab2, 'return (0);');
X		writeln(tab1, '  case 1:');
X		writeln(tab2, 'if (&Space[SETSPACE] - Top <= ',
X							maxsetrange:1, ') {');
X		writeln(tab3,
X			voidcast, 'fprintf(stderr, "Set-space exhausted\n");');
X		writeln(tab3, 'exit(1);');
X		writeln(tab2, '}');
X		writeln(tab2, '*Top = 0;');
X		writeln(tab2, 'return (Top);');
X		writeln(tab1, '  case 2:');
X		writeln(tab2, 'if (Top <= &sp[*sp])');
X		writeln(tab3, 'Top = &sp[*sp + 1];');
X		writeln(tab2, 'return (sp);');
X		writeln(tab1, '}');
X		writeln(tab1, '/', '* NOTREACHED *', '/');
X		writeln('}')
X	    end;
X	if usescpy then
X	    begin
X		writeln;
X		writeln(static, voidtyp);
X		writeln('Setncpy(S1, S2, N)');
X		writeln(tab1, registr, setptyp, tab1, 'S1, S2;');
X		writeln(tab1, registr, usigned, inttyp, tab1, 'N;');
X		writeln('{');
X		writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
X		writeln;
X		writeln(tab1, 'N /= sizeof(', setwtyp, ');');
X		writeln(tab1, '*S1++ = --N;');
X		writeln(tab1, 'm = *S2++;');
X		writeln(tab1, 'while (m != 0 && N != 0) {');
X		writeln(tab2, '*S1++ = *S2++;');
X		writeln(tab2, '--N;');
X		writeln(tab2, '--m;');
X		writeln(tab1, '}');
X		writeln(tab1, 'while (N-- != 0)');
X		writeln(tab2, '*S1++ = 0;');
X		writeln('}')
X	    end;
X	if usecase then
X	    begin
X		writeln;
X		writeln(static, voidtyp);
X		writeln('Caseerror(n)');
X		writeln(tab1, inttyp, tab1, 'n;');
X		writeln('{');
X		writeln(tab1, voidcast,
X			'fprintf(stderr, "Missing case limb: line %d\n", n);');
X		writeln(tab1, 'exit(1);');
X		writeln('}')
X	    end;
X	if usemax then
X	    begin
X		writeln;
X		writeln(static, inttyp);
X		writeln('Max(m, n)');
X		writeln(tab1, inttyp, tab1, 'm, n;');
X		writeln('{');
X		writeln(tab1, 'if (m > n)');
X		writeln(tab2, 'return (m);');
X		writeln(tab1, 'return (n);');
X		writeln('}')
X	    end;
X	if use(dtrunc) then
X	    begin
X		writeln(static, inttyp);
X		writeln('Trunc(f)');
X		printid(defnams[dreal]^.lid);
X		writeln(tab1, 'f;');
X		writeln('{');
X		writeln(tab1, 'return f;');
X		writeln('}')
X	    end;
X	if use(dround) then
X	    begin
X		writeln(static, inttyp);
X		writeln('Round(f)');
X		printid(defnams[dreal]^.lid);
X		writeln(tab1, 'f;');
X		writeln('{');
X		writeln(tab1, xtern, doubletyp, ' floor();');	(* LIB *)
X		writeln(tab1,
X			'return floor(', dblcast, '(0.5+f));');	(* LIB *)
X		writeln('}')
X	    end
Xend;	(* emit *)
X
X(*	Initialize all global structures used in translator.		*)
Xprocedure initialize;
X
Xvar	s	: hashtyp;
X	t	: pretyps;
X	d	: predefs;
X
X	(*	Define names in ctable.					*)
X	procedure defname(cn : cnames; str : keyword);
X
X	label	999;
X
X	var	w	: toknbuf;
X		i	: toknidx;
X
X	begin
X		unpack(str, w, 1);
X		for i := 1 to keywordlen do
X			if w[i] = space then
X			    begin
X				w[i] := chr(null);
X				goto 999
X			    end;
X		w[keywordlen+1] := chr(null);
X	999:
X		ctable[cn] := saveid(w)
X	end;
X
X	(*	Define predefined identifiers.				*)
X	procedure defid(nt : treetyp; did : predefs; str : keyword);
X
X	label	999;
X
X	var	w	: toknbuf;
X		i	: toknidx;
X		tp, tq,
X		tv	: treeptr;
X
X	begin
X		for i := 1 to keywordlen do
X			if str[i] = space then
X			    begin
X				w[i] := chr(null);
X				goto 999
X			    end
X			else
X				w[i] := str[i];
X		w[keywordlen+1] := chr(null);
X	999:
X		tp := newid(saveid(w));
X		defnams[did] := tp^.tsym;
X		if nt in [ntype, nfunc, nproc] then
X		    begin
X			(* predefined types, procedures and functions
X				are marked with a particular node *)
X			tv := mknode(npredef);
X			tv^.tdef := did;
X			tv^.tobtyp := tnone
X		    end
X		else
X			tv := nil; (* predefined constants and variables will
X					eventually be bound to something *)
X		case nt of
X		  nscalar:
X		    begin
X			tv := mknode(nscalar);
X			tv^.tscalid := nil;
X			tq := mknode(ntype);
X			tq^.tbind := tv;
X			tq^.tidl := tp;
X			tp := tq
X		    end;
X		  nconst,
X		  ntype,
X		  nfield,
X		  nvar:
X		    begin
X			tq := mknode(nt);
X			tq^.tbind := tv;
X			tq^.tidl := tp;
X			tq^.tattr := anone;
X			tp := tq
X		    end;
X		  nfunc,
X		  nproc:
X		    begin
X			tq := mknode(nt);
X			tq^.tsubid := tp;
X			tq^.tsubstmt := tv;
X			tq^.tfuntyp := nil;
X			tq^.tsubpar := nil;
X			tq^.tsublab := nil;
X			tq^.tsubconst := nil;
X			tq^.tsubtype := nil;
X			tq^.tsubvar := nil;
X			tq^.tsubsub := nil;
X			tq^.tscope := nil;
X			tq^.tstat := 0;
X			tp := tq
X		    end;
X		  nid:
X		end;(* case *)
X		deftab[did] := tp
X	end;	(* defid *)
X
X	(*	Define keywords.					*)
X	procedure defkey(s : symtyp; w : keyword);
X
X	var	i	: 1 .. keywordlen;
X
X	begin
X		for i := 1 to keywordlen do
X			if w[i] = space then
X				w[i] := chr(null);
X		(* relies on symtyp being sorted *)
X		with keytab[ord(s)] do
X		    begin
X			wrd := w;
X			sym := s
X		    end;
X	end;
X
X	procedure fixinit(i : strindx);
X
X	var	t	: toknbuf;
X
X	begin
X		gettokn(i, t);
X		t[1] := 'i';
X		puttokn(i, t);
X	end;
X
X	(*	Add a cpu word type description.			*)
X	(*	Parameters lo and hi gives the range of a machine-	*)
X	(*	dependant integer type. Parameter str gives the corres-	*)
X	(*	ponding C-language type-name.				*)
X	procedure defmach(lo, hi : integer; str : machdefstr);
X
X	label	999;
X
X	var	i	: toknidx;
X		w	: toknbuf;
X
X	begin
X		unpack(str, w, 1);
X		if w[machdeflen] <> space then
X			error(ebadmach);
X		for i := machdeflen - 1 downto 1 do
X			if w[i] <> space then
X			    begin
X				w[i+1] := chr(null);
X				goto 999
X			    end;
X		error(ebadmach);
X	999:
X		if nmachdefs >= maxmachdefs then
X			error(emanymachs);
X		nmachdefs := nmachdefs + 1;
X		with machdefs[nmachdefs] do
X		    begin
X			lolim := lo;
X			hilim := hi;
X			typstr := savestr(w)
X		    end
X	end;
X
X	procedure initstrstore;
X
X	var	i	: strbcnt;
X
X	begin
X		for i := 1 to maxblkcnt do
X			strstor[i] := nil;
X		new(strstor[0]);
X		strstor[0]^[0] := chr(null);
X		strfree := 1;
X		strleft := maxstrblk
X	end;
X
Xbegin	(* initialize *)
X	lineno := 1;
X	colno := 0;
X
X	initstrstore;
X
X	setlst := nil;
X	setcnt := 0;
X	hexdig := '0123456789ABCDEF';
X
X	symtab := nil;
X	statlvl := 0;
X	maxlevel := -1;
X	enterscope(nil);
X	varno:= 0;
X
X	usenilp := false;
X
X	usesets := false;
X	useunion := false;
X	usediff := false;
X	usemksub := false;
X	useintr := false;
X	usesge := false;
X	usesle := false;
X	usesne := false;
X	useseq := false;
X	usememb := false;
X	useins := false;
X	usescpy := false;
X	usefopn := false;
X	usescan := false;
X	usegetl := false;
X
X	usecase := false;
X	usejmps := false;
X
X	usebool := false;
X
X	usecomp := false;
X	usemax	:= false;
X
X	for s := 0 to hashmax do
X		idtab[s] := nil;
X	for d := dabs to dztring do
X	    begin
X		deftab[d] := nil;
X		defnams[d] := nil
X	    end;
X
X	(* Pascal keywords *)
X	defkey(sand,	'and       ');
X	defkey(sarray,	'array     ');
X	defkey(sbegin,	'begin     ');
X	defkey(scase,	'case      ');
X	defkey(sconst,	'const     ');
X	defkey(sdiv,	'div       ');
X	defkey(sdo,	'do        ');
X	defkey(sdownto,	'downto    ');
X	defkey(selse,	'else      ');
X	defkey(send,	'end       ');
X	defkey(sextern,	externsym);	(* non-standard *)
X	defkey(sfile,	'file      ');
X	defkey(sfor,	'for       ');
X	defkey(sforward,'forward   ');
X	defkey(sfunc,	'function  ');
X	defkey(sgoto,	'goto      ');
X	defkey(sif,	'if        ');
X	defkey(sinn,	'in        ');
X	defkey(slabel,	'label     ');
X	defkey(smod,	'mod       ');
X	defkey(snil,	'nil       ');
X	defkey(snot,	'not       ');
X	defkey(sof,	'of        ');
X	defkey(sor,	'or        ');
X	defkey(sother,	othersym);	(* non-standard *)
X	defkey(spacked,	'packed    ');
X	defkey(sproc,	'procedure ');
X	defkey(spgm,	'program   ');
X	defkey(srecord,	'record    ');
X	defkey(srepeat,	'repeat    ');
X	defkey(sset,	'set       ');
X	defkey(sthen,	'then      ');
X	defkey(sto,	'to        ');
X	defkey(stype,	'type      ');
X	defkey(suntil,	'until     ');
X	defkey(svar,	'var       ');
X	defkey(swhile,	'while     ');
X	defkey(swith,	'with      ');
X	defkey(seof,	dummysym);	(* dummy entry *)
X
X	(* C language operator priorities *)
X	cprio[nformat]	:= 0;
X	cprio[nrange]	:= 0;
X	cprio[nin]	:= 0;
X	cprio[nset]	:= 0;
X	cprio[nassign]	:= 0;
X	cprio[nor]	:= 1;
X	cprio[nand]	:= 2;
X	cprio[neq]	:= 3;
X	cprio[nne]	:= 3;
X	cprio[nlt]	:= 3;
X	cprio[nle]	:= 3;
X	cprio[ngt]	:= 3;
X	cprio[nge]	:= 3;
X	cprio[nplus]	:= 4;
X	cprio[nminus]	:= 4;
X	cprio[nmul]	:= 5;
X	cprio[ndiv]	:= 5;
X	cprio[nmod]	:= 5;
X	cprio[nquot]	:= 5;
X	cprio[nnot]	:= 6;
X	cprio[numinus]	:= 6;
X	cprio[nuplus]	:= 7;
X	cprio[nindex]	:= 7;
X	cprio[nselect]	:= 7;
X	cprio[nderef]	:= 7;
X	cprio[ncall]	:= 7;
X	cprio[nid]	:= 7;
X	cprio[nchar]	:= 7;
X	cprio[ninteger]	:= 7;
X	cprio[nreal]	:= 7;
X	cprio[nstring]	:= 7;
X	cprio[nnil]	:= 7;
X
X	(* Pascal language operator priorities *)
X	pprio[nassign]	:= 0;
X	pprio[nformat]	:= 0;
X	pprio[nrange]	:= 1;
X	pprio[nin]	:= 1;
X	pprio[neq]	:= 1;
X	pprio[nne]	:= 1;
X	pprio[nlt]	:= 1;
X	pprio[nle]	:= 1;
X	pprio[ngt]	:= 1;
X	pprio[nge]	:= 1;
X	pprio[nor]	:= 2;
X	pprio[nplus]	:= 2;
X	pprio[nminus]	:= 2;
X	pprio[nand]	:= 3;
X	pprio[nmul]	:= 3;
X	pprio[ndiv]	:= 3;
X	pprio[nmod]	:= 3;
X	pprio[nquot]	:= 3;
X	pprio[nnot]	:= 4;
X	pprio[numinus]	:= 4;
X	pprio[nuplus]	:= 5;
X	pprio[nset]	:= 6;
X	pprio[nindex]	:= 6;
X	pprio[nselect]	:= 6;
X	pprio[nderef]	:= 6;
X	pprio[ncall]	:= 6;
X	pprio[nid]	:= 6;
X	pprio[nchar]	:= 6;
X	pprio[ninteger]	:= 6;
X	pprio[nreal]	:= 6;
X	pprio[nstring]	:= 6;
X	pprio[nnil]	:= 6;
X
X	(* table of C keywords/functions (which Pascal doesn't know about) *)
X	defname(cabort,		'abort     ');	(* OS *)
X	defname(cbreak,		'break     ');
X	defname(ccontinue,	'continue  ');
X	defname(cdefine,	'define    ');
X	defname(cdefault,	'default   ');
X	defname(cdouble,	'double    ');
X	defname(cedata,		'edata     ');	(* OS *)
X	defname(cenum,		'enum      ');
X	defname(cetext,		'etext     ');	(* OS *)
X	defname(cextern,	'extern    ');
X	defname(cfclose,	'fclose    ');	(* LIB *)
X	defname(cfflush,	'fflush    ');	(* LIB *)
X	defname(cfgetc,		'fgetc     ');	(* LIB *)
X	defname(cfloat,		'float     ');
X	defname(cfloor,		'floor     ');	(* OS *)
X	defname(cfprintf,	'fprintf   ');	(* LIB *)
X	defname(cfputc,		'fputc     ');	(* LIB *)
X	defname(cfread,		'fread     ');	(* LIB *)
X	defname(cfscanf,	'fscanf    ');	(* LIB *)
X	defname(cfwrite,	'fwrite    ');	(* LIB *)
X	defname(cgetc,		'getc      ');	(* OS *)
X	defname(cgetpid,	'getpid    ');	(* OS *)
X	defname(cint,		'int       ');
X	defname(cinclude,	'include   ');
X	defname(clong,		'long      ');
X	defname(clog,		'log       ');	(* OS *)
X	defname(cmain,		'main      ');
X	defname(cmalloc,	'malloc    ');	(* LIB *)
X	defname(cprintf,	'printf    ');	(* LIB *)
X	defname(cpower,		'pow       ');	(* OS *)
X	defname(cputc,		'putc      ');	(* LIB *)
X	defname(cread,		'read      ');	(* OS *)
X	defname(creturn,	'return    ');
X	defname(cregister,	'register  ');
X	defname(crewind,	'rewind    ');	(* LIB *)
X	defname(cscanf,		'scanf     ');	(* LIB *)
X	defname(csetbits,	'setbits   ');
X	defname(csetword,	'setword   ');
X	defname(csetptr,	'setptr    ');
X	defname(cshort,		'short     ');
X	defname(csigned,	'signed    ');
X	defname(csizeof,	'sizeof    ');
X	defname(csprintf,	'sprintf   ');	(* LIB *)
X	defname(cstatic,	'static    ');
X	defname(cstdin,		'stdin     ');	(* LIB *)
X	defname(cstdout,	'stdout    ');	(* LIB *)
X	defname(cstderr,	'stderr    ');	(* LIB *)
X	defname(cstrncmp,	'strncmp   ');	(* OS *)
X	defname(cstrncpy,	'strncpy   ');	(* OS *)
X	defname(cstruct,	'struct    ');
X	defname(cswitch,	'switch    ');
X	defname(ctypedef,	'typedef   ');
X	defname(cundef,		'undef     ');
X	defname(cungetc,	'ungetc    ');	(* LIB *)
X	defname(cunion,		'union     ');
X	defname(cunlink,	'unlink    ');	(* OS *)
X	defname(cunsigned,	'unsigned  ');
X	defname(cwrite,		'write     ');	(* OS *)
X
X	(* create predefined identifiers *)
X	defid(nfunc,	dabs,		'abs       ');
X	defid(nfunc,	darctan,	'arctan    ');
X	defid(nvar,	dargc,		'argc      ');	(* OS *)
X	defid(nproc,	dargv,		'argv      ');	(* OS *)
X	defid(nscalar,	dboolean,	'boolean   ');
X	defid(ntype,	dchar,		'char      ');
X	defid(nfunc,	dchr,		'chr       ');
X	defid(nproc,	dclose,		'close     ');	(* OS *)
X	defid(nfunc,	dcos,		'cos       ');
X	defid(nproc,	ddispose,	'dispose   ');
X	defid(nid,	dfalse,		'false     ');
X	defid(nfunc,	deof,		'eof       ');
X	defid(nfunc,	deoln,		'eoln      ');
X	defid(nproc,	dexit,		'exit      ');	(* OS *)
X	defid(nfunc,	dexp,		'exp       ');
X	defid(nproc,	dflush,		'flush     ');	(* OS *)
X	defid(nproc,	dget,		'get       ');
X	defid(nproc,	dhalt,		'halt      ');	(* OS *)
X	defid(nvar,	dinput,		'input     ');
X	defid(ntype,	dinteger,	'integer   ');
X	defid(nfunc,	dln,		'ln        ');
X	defid(nconst,	dmaxint,	'maxint    ');
X	defid(nproc,	dmessage,	'message   ');	(* OS *)
X	defid(nproc,	dnew,		'new       ');
X	defid(nfunc,	dodd,		'odd       ');
X	defid(nfunc,	dord,		'ord       ');
X	defid(nvar,	doutput,	'output    ');
X	defid(nproc,	dpack,		'pack      ');
X	defid(nproc,	dpage,		'page      ');
X	defid(nfunc,	dpred,		'pred      ');
X	defid(nproc,	dput,		'put       ');
X	defid(nproc,	dread,		'read      ');
X	defid(nproc,	dreadln,	'readln    ');
X	defid(ntype,	dreal,		'real      ');
X	defid(nproc,	dreset,		'reset     ');
X	defid(nproc,	drewrite,	'rewrite   ');
X	defid(nfunc,	dround,		'round     ');
X	defid(nfunc,	dsin,		'sin       ');
X	defid(nfunc,	dsqr,		'sqr       ');
X	defid(nfunc,	dsqrt,		'sqrt      ');
X	defid(nfunc,	dsucc,		'succ      ');
X	defid(ntype,	dtext,		'text      ');
X	defid(nid,	dtrue,		'true      ');
X	defid(nfunc,	dtrunc,		'trunc     ');
X	defid(nfunc,	dtan,		'tan       ');
X	defid(nproc,	dunpack,	'unpack    ');
X	defid(nproc,	dwrite,		'write     ');
X	defid(nproc,	dwriteln,	'writeln   ');
X
X	defid(nfield,	dzinit,		'$nit      ');	(* for internal use *)
X	defid(ntype,	dztring,	'$ztring   ');
X
X	(* bind constants and variables *)
X	deftab[dboolean]^.tbind^.tscalid := deftab[dfalse];
X	deftab[dfalse]^.tnext := deftab[dtrue];
X	currsym.st := sinteger;
X	currsym.vint := maxint;
X	deftab[dmaxint]^.tbind := mklit;
X	deftab[dargc]^.tbind := deftab[dinteger]^.tbind;
X	deftab[dinput]^.tbind := deftab[dtext]^.tbind;
X	deftab[doutput]^.tbind := deftab[dtext]^.tbind;
X
X	for t := tnone to terror do
X	    begin
X		(* for predefined types: set up pointers to "npredef" nodes
X		   describing type, fill in constant identifying type *)
X		case t of
X		  tboolean:
X			typnods[t] := deftab[dboolean]; (* scalar type *)
X		  tchar:
X			typnods[t] := deftab[dchar]^.tbind;
X		  tinteger:
X			typnods[t] := deftab[dinteger]^.tbind;
X		  treal:
X			typnods[t] := deftab[dreal]^.tbind;
X		  ttext:
X			typnods[t] := deftab[dtext]^.tbind;
X		  tstring:
X			typnods[t] := deftab[dztring]^.tbind;
X		  tnil,
X		  tset,
X		  tpoly,
X		  tnone:
X			typnods[t] := mknode(npredef);
X		  terror:
X			(* no op *)
X		end;(* case *)
X		if t in [tchar, tinteger, treal, ttext, tnone, tpoly,
X						tstring, tnil, tset] then
X			typnods[t]^.tobtyp := t
X	    end;
X
X	(* fix name and type of field "init" *)
X	fixinit(defnams[dzinit]^.lid^.istr);
X	deftab[dzinit]^.tbind := deftab[dinteger]^.tbind;
X
X	for d := dabs to dztring do
X		linkup(nil, deftab[d]);
X
X	deftab[dchr]^.tfuntyp := typnods[tchar];
X
X	deftab[deof]^.tfuntyp := typnods[tboolean];
X	deftab[deoln]^.tfuntyp := typnods[tboolean];
X	deftab[dodd]^.tfuntyp := typnods[tboolean];
X
X	deftab[dord]^.tfuntyp := typnods[tinteger];
X	deftab[dround]^.tfuntyp := typnods[tinteger];
X	deftab[dtrunc]^.tfuntyp := typnods[tinteger];
X
X	deftab[darctan]^.tfuntyp := typnods[treal];
X	deftab[dcos]^.tfuntyp := typnods[treal];
X	deftab[dsin]^.tfuntyp := typnods[treal];
X	deftab[dtan]^.tfuntyp := typnods[treal];
X	deftab[dsqrt]^.tfuntyp := typnods[treal];
X	deftab[dexp]^.tfuntyp := typnods[treal];
X	deftab[dln]^.tfuntyp := typnods[treal];
X
X	deftab[dsqr]^.tfuntyp := typnods[tpoly];
X	deftab[dabs]^.tfuntyp := typnods[tpoly];
X	deftab[dpred]^.tfuntyp := typnods[tpoly];
X	deftab[dsucc]^.tfuntyp := typnods[tpoly];
X
X	deftab[dargv]^.tfuntyp := typnods[tnone];
X	deftab[ddispose]^.tfuntyp := typnods[tnone];
X	deftab[dexit]^.tfuntyp := typnods[tnone];
X	deftab[dget]^.tfuntyp := typnods[tnone];
X	deftab[dhalt]^.tfuntyp := typnods[tnone];
X	deftab[dnew]^.tfuntyp := typnods[tnone];
X	deftab[dpack]^.tfuntyp := typnods[tnone];
X	deftab[dput]^.tfuntyp := typnods[tnone];
X	deftab[dread]^.tfuntyp := typnods[tnone];
X	deftab[dreadln]^.tfuntyp := typnods[tnone];
X	deftab[dreset]^.tfuntyp := typnods[tnone];
X	deftab[drewrite]^.tfuntyp := typnods[tnone];
X	deftab[dwrite]^.tfuntyp := typnods[tnone];
X	deftab[dwriteln]^.tfuntyp := typnods[tnone];
X	deftab[dmessage]^.tfuntyp := typnods[tnone];
X	deftab[dunpack]^.tfuntyp := typnods[tnone];
X
X	(* set up definitions for integer subranges *)
X	nmachdefs := 0;
X	defmach(0,		255,		'unsigned char   '); (* CPU *)
X	defmach(-128,		127,		'char            '); (* CPU *)
X	defmach(0,		65535,		'unsigned short  '); (* CPU *)
X	defmach(-32768,		32767,		'short           '); (* CPU *)
X	defmach(-2147483647,	2147483647,	'long            '); (* CPU *)
X{	defmach(0,		4294967295,	'unsigned long   ');}(* CPU *)
Xend;	(* initialize *)
X
Xprocedure exit(i : integer); external;	(* OS *)
X
X(*	Action to take when an error is detected.			*)
Xprocedure error;
X
Xbegin
X	prtmsg(m);
X	exit(1);	(* OS *)
X	goto 9999
Xend;
X
X(*	Action to take when a fatal error is detected.			*)
Xprocedure fatal;
X
Xbegin
X	prtmsg(m);
X	halt		(* OS *)
X	(* goto 9999	*)
Xend;
X
X
Xbegin	(* program *)
X	initialize;
X	if echo then
X		writeln('# ifdef PASCAL');
X	parse;
X	if echo then
X		writeln('# else');
X	lineno := 0; lastline := 0;
X	transform;
X	emit;
X	if echo then
X		writeln('# endif');
X9999:
X	(* the very *)
Xend.
X
END_OF_FILE
if test 54467 -ne `wc -c <'ptc.p.4'`; then
    echo shar: \"'ptc.p.4'\" unpacked with wrong size!
fi
# end of 'ptc.p.4'
fi
echo shar: End of archive 11 \(of 12\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 12 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 

Rich $alz			"Anger is an energy"
Cronus Project, BBN Labs	rsalz@bbn.com
Moderator, comp.sources.unix	sources@uunet.ul de(*