perm filename TEXHDR.SAI[VLI,LSP] blob sn#382074 filedate 1978-09-08 generic text, type C, neo UTF8
C00001 00001
C00002 00002	The following declarations are used in all of TEX's modules.
C00005 00003	Declarations internal to TEXSYS
C00013 00004	Declarations internal to TEXSYN
C00032 00005	Declarations internal to TEXSEM
C00044 00006	Declarations internal to TEXOUT
C00046 00007	Declarations internal to TEXEXT
C00048 ENDMK
comment The following declarations are used in all of TEX's modules.
Only brief explanatory comments appear here -- fuller documentation appears
in each individual module.

This page lists several standard abbreviation conventions.
The next five pages include declarations of everything external that is
internal to TEXSYS, TEXSYN, TEXSEM, TEXOUT, TEXEXT, respectively;

require "⊂⊃⊂⊃" delimiters; "used for macros"
define # = ⊂;comment⊃; "used henceforth instead of quoted comments like this"
define nextline = ⊂('15&'12)⊃ # carriage-return and line-feed in print commands;
define epsilon = ⊂10↑-20⊃    # a rather small but positive number;
define thru = ⊂step 1 until⊃ # abbreviation for for clauses;
define DEBUGONLY = ⊂⊃        # changed to ⊂comment⊃ when not debugging TEX;
DEBUGONLY external procedure bail # the SAIL debugger in case of need;
DEBUGONLY require 300 system_pdl # bail needs extra room sometimes;

define bitsperwd = 36	     # word size in this implementation;
comment The TEX programs can be adapted for machines with somewhat smaller
word size (e.g. 32 bits), so all word-size dependent quantities are
defined symbolically to aid in this conversion;

define internaldef = ⊂comment⊃ #
	When a quantity is defined below, e.g. "define parsize=25", the
	TEX module where it is appropriate to introduce the quantity will
	include an internal definition for documentation purposes,
	e.g. "internaldef parsize = 25". The internal definitions are
	not necessarily up-to-date, however... for example, the TEXSYN
	module might say "internaldef parsize = 100" but parsize might
	really be only 25, as defined here;

define FIXTHIS = ⊂comment⊃ # marks things that still need to be done;

FIXTHIS: Make all of the TEX documentation crystal clear;

FIXTHIS: All arrays should be declared SAFE when TEX has been proved correct
	in its references to them;
comment Declarations internal to TEXSYS;

comment The first two definitions are really internal to TEXSEM, but had to
be moved here so that they are defined before their use;
define alignsize=4 # max number of simultaneous alignments*;
define gluespecsize=4 # number of words allocated in glue specifications*;

external procedure quit # closes output files and terminates TEX;
external boolean pausing_on_errors # should TEX wait after error messages?;
external boolean deletions_allowed # is it safe for error routine to call getnext?;
external procedure error(string s) # prints an error message;
external procedure backerror(string s) # error followed by backinput;
external procedure reportoverflow(string s; integer n)
	# for fatal errors when a TEX table is undersized;
define overflow(s)=⊂reportoverflow("s",s)⊃ # specifies inadequate table size;
external procedure memoverflow # overflow(memsize);
external procedure confusion # TEX consistency check failure;
external procedure mustquit # user input is really wild;

define links = 15 # number of bits per pointer;
define memsize=26000 # size of dynamic list memory, must be ≤ 2↑links;
define varsize=11000 # size of variable node memory, must be << memsize;
external integer array mem[0:memsize-1] # dynamic list memory;
define memreal(p)=⊂memory[location(mem[p]),real]⊃ # mem[p] as type real;
DEBUGONLY external integer dynused,varused # how much memory is in use;
define fs(f) = ⊂f⊃&"s" # field size of f, in bits;
define fd(f) = ⊂f⊃&"d" # field displacement of f, in bits;
define field(f,x) = ⊂ifc fd(f)=0 thenc ((x) land (2↑fs(f)-1))
	elsec ifc fs(f)+fd(f)≥bitsperwd thenc ((x) lsh -fd(f))
	elsec (((x) lsh -fd(f)) land (2↑fs(f)-1)) endc endc⊃ # field f of x;
define setfield(f,x,y) = ⊂ifc fd(f)=0 thenc x←(x land(-2↑fs(f)))+(y)
	elsec ifc fs(f)+fd(f)≥bitsperwd thenc 
		x←((x lsh(bitsperwd-fd(f)))+(y))rot fd(f)
	elsec x←(((x rot -fd(f))land(-2↑fs(f)))+(y))rot fd(f) endc endc⊃
		# sets field f of x equal to y, 0 ≤ y < 2↑fs(f);
define ufield(f,x) = ⊂((x) land((1 lsh(fs(f)+fd(f)))-2↑fd(f)))⊃
		# unshifted field f of x;
define setufield(f,x,y) = ⊂x←(x land lnot((1 lsh(fs(f)+fd(f)))-2↑fd(f)))+(y)⊃
		# field f of x set to unshifted value y;
define linkd = 0 # displacement of link field;
define link(p) = ⊂field(link,mem[p])⊃ # link field of mem[p];
define setlink(p,y) = ⊂setfield(link,mem[p],y)⊃ # sets link(p)←y;
define infod = links, infos = bitsperwd-infod # definition of info field;
define info(p) = ⊂field(info,mem[p])⊃ # info field of mem[p];
define setinfo(p,y) = ⊂setfield(info,mem[p],y)⊃ # sets info(p)←y;

external integer avail # head of available space list for one-word nodes;
define getavail(p) = ⊂begin if(p←avail)then avail←mem[avail]
	else memoverflow; DEBUGONLY dynused←dynused+1; end⊃ # p ← new node;
define freeavail(p) = ⊂begin mem[p]←avail; avail←p;
	DEBUGONLY dynused←dynused-1; end⊃ # node p now available;
external integer procedure getnode(integer size) # variable-size node allocation;
external procedure freenode(integer p,size) # variable-size node liberation;

external procedure dslist(integer p) # makes list of 1-word nodes available;
define refct1 = 1 lsh infod # 1 in the information (reference count) field;
external simple procedure delrclink(integer p) # remove ptr to list with ref ct;
external simple procedure delgluelink(integer p) # remove pointer to glue node;
DEBUGONLY external procedure checkmem(boolean printlocs) # checks links in mem;
define fillglue=0 # location of glue specification 0pt plus 10↑10 pt;
define lowerfillglue=gluespecsize # loc of glue specification
		0pt plus 10↑6pt minus 10↑6 pt;
define zeroglue=lowerfillglue+gluespecsize # loc of glue specification 0pt;
define fontglue=zeroglue+gluespecsize # location of glue for variable spaces;
define firstmem=fontglue+32*gluespecsize # location of 
		first usable mem word, must be >0;
define waitinghead=varsize # head of list of inserts too big for current page;
define contribhead=waitinghead+1 # head of contribution vlist for current page;
define pagehead=contribhead+1 # head of vlist for current page;
define temphead=pagehead+1 # temporary head of a miscellaneous list;
define holdhead=temphead+1 # temporary head of another miscellaneous list;
define alignhead=holdhead+1 # alignhead+j is head of jth alignrecordlist;
define inserts=alignhead+alignsize # head of insert list returned by packager;
define secondmem=inserts+1 # first usable mem word in 1-word area;
external procedure initmem # initializes the memory system;
comment Declarations internal to TEXSYN;

external integer curcmd # the current command code appearing in the input;
external integer curchar # the current character code appearing in the input;
define escape=0	# escape delimiter (\ in TEX manual);
define lbrace=1	# begin block symbol ( { );
define rbrace=2	# end block symbol ( } );
define mathbr=3    # math break ( $ );
define tabmrk=4	# tab mark ( ⊗ );
define carret=5	# carriage return and comment mark ( % );
define macprm=6	# macro parameter ( # );
define supmrk=7	# superscript ( ↑ );
define submrk=8	# subscript ( ↓ );
define ignore=9	# chars to ignore;
define spacer=10	# chars treated as blank space;
define letter=11	# chars treated as letters;
define otherchar=12 # none of the above character types;
define parend=13	# end of paragraph;
define match=14	# macro parameter matching;
define outpar=ignore # output a macro parameter;
define endv=15	# end of vlist in halign or valign template;
define call=16	# call a user-defined macro;
define xt=17 	# extensions to basic TEX (\x);
define assignglue=18 # user-defined glue;
define font=19	# user-defined current font;
define assignreal=20 # user-defined length;
define def=21	# macro definition (\def,\gdef);
define output=22	# output routine definition (\output);
define innput=23	# required input file (\input);
comment code 24 is currently unused;
define stop=25	# end of input (\end);
define ddt=26	# emergency debugging (\ddt);
define ascii=27	# code for possibly untypeable character (\char);
define chcode=28	# change chartype table (\chcode);
define fntfam=29	# declare font family (\mathrm,etc.);
define setcpage=30 # set current page number (\setcpage);
define advcpage=31 # increase current page number (\advcpage);
define cpage=32	# insert current page number (\cpage);
define ifeven=33	# conditional on cpage even (\ifeven);
define ifT=34	# conditional on character T (\ifT);
define elsecode=35	# delimiter for conditionals (\else);
define box=36	# saved box (\box,\page) or justification(\hjust,\vjust);
define hmove=37	# horizontal motion of box (\moveleft,\moveright);
define vmove=38	# vertical motion of box (\raise,\lower);
define save=39	# save a box (\save);
define leaders=40	# define leaders (\leaders);
define halign=41	# horizontal table alignment (\halign);
define valign=42	# vertical table alignment (\valign);
define noalign=43	# insertion into halign or valign (\noalign);
define vskip=44	# vertical glue (\vskip,\vfill);
define hskip=45	# horizontal glue (\hskip,\hfill);
define vrule=46	# vertical rule (\vrule);
define hrule=47	# horizontal rule (\hrule);
define topbotins=48 # inserted vlist (\topinsert or \botinsert);
define topbotmark=49 # insert mark (\topmark,\botmark);
define mark=50	# define a mark (\mark);
define penlty=51	# specify badness of break (\penalty);
define noindent=52	# begin nonindented paragraph (\noindent);
define eject=53	# eject page here (\eject);
define discr=54	# discretionary hyphen (\-,\*);
define accent=55	# attach accent to character (\+);
define newaccent=56 # define nonstandard accent (\accent);
define eqno=57	# insert equation number (\eqno);
define mathonly=58	# character or token allowed in mathmode only;
define exspace=59	# explicit space (\ );
define nonmathletter=60 # letter except in mmode;
define leftright=61 # variable delimiter (\left, \right);
comment there is presently no code 62;
define mathinput=63 # component of math formula (\mathop,\mathbin, etc.);
define limsw=64	# modify limit conventions (\limitswitch);
define above=65	# numerator-denominator separator(\above,\atop,\over,\comb);
define mathstyle=66 # style or space specification (\dispstyle,\,,etc.);
define italcorr=67 # italic correction (\/);
define vcenter=68  # vjust centered on axis (\vcenter);
define hangindent=69 # specifies hanging indentation (\hangindent);
define maxopcode=hangindent # the largest code number;
define charcodes=otherchar+1 # number of distinct codes allowed in chartype;
define texpars=8 # number of distinct parameters settable by \chpar command;

define hashsize = 397 # hashtable size, should be prime and < 2↑chars-127;
external integer array hash[0:hashsize-1] # hash table for packed names;
define eqtbsize=hashsize+128+128+12+texpars # size of table for current values;
external integer array eqtb[0:eqtbsize-1] # equivalents of symbols and parameters;
define chartype(c) = ⊂eqtb[c+(hashsize+128)]⊃ # cmds associated with chars;
define tracing = ⊂eqtb[hashsize+268]⊃ # controls diagnostics, see TEXSEM p.4;
define jpar = ⊂eqtb[hashsize+269]⊃ # controls justification, see TEXSEM p.13;
define hpen = ⊂eqtb[hashsize+270]⊃ # hyphenation penalty, see TEXSEM p.13;
define penpen = ⊂eqtb[hashsize+271]⊃ # penultimate penalty, see TEXSEM p.13;
define wpen = ⊂eqtb[hashsize+272]⊃ # widow-line penalty, see TEXSEM p.13;
define bpen = ⊂eqtb[hashsize+273]⊃ # broken-line penalty, see TEXSEM p.13;
define mbpen = ⊂eqtb[hashsize+274]⊃ # binary-op-break penalty, see TEXSEM p.15;
define mrpen = ⊂eqtb[hashsize+275]⊃ # relation-break penalty, see TEXSEM p.15;
define idlens=3,idlend=links 			# idlen field in eqtb;
define idlevs=5,idlevd=idlens+idlend		# idlev field in eqtb;
define idcmdd=idlevs+idlevd,idcmds=bitsperwd-idcmdd # idcmd field in eqtb;

external integer curlev # the current level of nesting, times 2↑idlevd;
define savesize = 100 # size of savestack;
external integer saveptr # first unused entry on savestack;
external integer array savestack[0:savesize+1] # place to save dormant eqtb entries;
define level1 = 1 lsh idlevd;
external procedure initsave # initialize the save-restore mechanism;
external simple procedure eqdefine(integer index,cmd,lnk) # change eqtb entry;
external procedure chcodedef(integer index,value) # eqdefine for char codes;
external integer procedure unsave # clears off top nesting level of savestack
	and returns the ending-routine code;
external simple procedure newsavelevel(integer endcode) # starts new nesting level;
define bottomlevel=1,simpleblock=2,trueend=3,aligncode=4,mathcode=5,

external integer hashentry # the most recent hash table location;
external procedure idlookup(integer id,len) # searches the hashtable;
external string procedure idname(integer h) # the name associated with eqtb[h];
external simple procedure controlseq # gets a packed name from the input;
define locsize=14 # size of locs array for storing eqtb locations;
external integer array locs[0:locsize-1];
define lineskiploc=⊂locs[0]⊃, baselineskiploc=⊂locs[1]⊃, parskiploc=⊂locs[2]⊃,
dispskiploc=⊂locs[3]⊃, topskiploc=⊂locs[4]⊃, botskiploc=⊂locs[5]⊃,
tabskiploc=⊂locs[6]⊃, dispaskiploc=⊂locs[7]⊃, dispbskiploc=⊂locs[8]⊃
	# allocation of the "loc" variables;
define fontloc = hashsize+":" # eqtb location for \:;
define xloc(x) = ⊂x⊃&"loc" # eqtb location for x;
define eqlink(x) = ⊂field(link,eqtb[xloc(x)])⊃ # stored link field for x;
external integer escapechar # set to the first character of user input;

define stacksize=20 # maximum number of simultaneous input sources;
external string array inbufstack[0:stacksize]; external string inbuf
	# current lines being input from a character file;
external string array curbfstack[0:stacksize]; external string curbuf
	# the parts of inbuf that haven't yet been input;
external string array filenmstack[0:stacksize]; external string filename
	# the names of the current character files;
external integer array statestack[0:stacksize]; external integer state
	# current scanner state codes;
external integer array locstack[0:stacksize]; external integer loc
	# current scanner locations;
external integer array recvrystack[0:stacksize]; external integer recovery
	# information about what to do when done on each level;
external integer inptr # first unused location in input stacks;
define tokenlist=0 # scanning a token list;
define midline=1 # scanning a line of characters;
define skipblanks=1+charcodes # like midline but ignoring blanks;
define newline=1+2*charcodes # beginning a new line of characters;
define parsize=13 # max number of simultaneous parameters;
external integer array parstack[0:parsize-1] # token-list pointers for parameters;
external integer parptr # first unused location in parstack;

define chars=10,chard=0 # definition of char field in packed tokens;
define cmds=4,cmdd=chars # definition of cmd field in packed tokens;
external string array tokstring[0:1] # output of displaylist;
external procedure dumplist(integer p,q) # makes strings out of a token list;
external string procedure dumptokens(integer p) # simple special case of dumplist;

external simple procedure pushinput # save current input status on the stacks;
define inslist(p)=⊂begin pushinput;state←tokenlist;loc←recovery←p end⊃;
external simple procedure insrclist(integer l) # like inslist for lists with
	reference counts;
external simple procedure popinput # finish input level, restore the previous;
external integer brchar # break character stored by system input;
external integer eof # end-of-file code stored by system input;
external procedure initin # get TEX input system ready to start;
external string curfile # current input file name, set by dumpcontext;
external integer curfpage,curfline # set by dumpcontext;
external procedure dumpcontext # prints where the scanner is;

external simple procedure getnext # sends next input token to curcmd,curchar;
external integer curtok # current token set by gettok and getnctok;
external simple procedure getncnext # gets next non-call input token;
external simple procedure gettok # set curcmd, curchar, and curtok;
external simple procedure getnctok # get next non-call token and sets curtok;

external procedure macrodef(integer gdef);
external integer procedure scantoks # build tokenlist for output and mark;

external procedure macrocall # invoke a user-defined control sequence;
external procedure inputfile;
external string array fontname[0:31] # user name for each font code;
external procedure definefont(integer f) # Do this after seeing "=" of font def;

external simple procedure backinput # puts curtok back into the input;
external simple integer procedure scandigit # scans "0"..."9";
external simple procedure scanlb # scans {;
external boolean procedure scanstring(string s) # scans a given letter string;
external integer nbrlength # length of scanned number;
external integer nbrsign # sign, if any, preceding scanned number;
external simple integer procedure scannumber # scans a decimal or octal number;

external real procedure scanlength # scans a length specification;
external integer procedure scanglue # scans a glue specification;
external procedure scanspec # scans a justification specification and a {;

external simple integer procedure scanfont # scan a font code;
external integer array delimtable[0:127] # contains 18-bit delimiter codes
	for all known delimiters, or -1 for nondelimiters;
external integer procedure scandelim # scans a math delimiter;
external integer procedure scanrulespec # scans rule dimensions;

external procedure passblock # scans past an entire {} block and optional space;
external procedure insnum(integer n) # puts string version of n into input;
external procedure scancond(boolean b) # scanning for if-then-else constructs;
comment Declarations internal to TEXSEM;

define types=5, typed=bitsperwd-types # definition of type field;
define values=typed-links, valued=links # definition of value field;
comment values must be ≥ links;
define type(p)=⊂field(type,mem[p])⊃  # shorthand for type field;
define value(p)=⊂field(value,mem[p])⊃  # shorthand for value field;
define charnode=0 # type code for a character box;
define hlistnode=1 # type code for a box made from an hlist;
define vlistnode=2 # type code for a box made from a vlist;
define boxnodesize=6 # number of words to allocate for a box node;
define width(p)=⊂memreal(p+1)⊃ # width field in nodes;
define depth(p)=⊂memreal(p+2)⊃ # depth field in nodes;
define height(p)=⊂memreal(p+3)⊃ # height field in nodes;
define shiftamt(p)=⊂memreal(p+4)⊃ # amount to shift this box;
define glueset(p)=⊂memreal(p+5)⊃ # glueset field in box nodes;
define rulenode=3 # type code for a "black box";
define rulenodesize=4 # number of words to allocate for it;
define whatsitnode=4 # type code for special nodes used by extensions;
define gluenode=5 # type code for a node that points to glue specification;
internaldef gluespecsize=4 # number of words allocated in glue specifications*;
define gluespace(p)=⊂memreal(p+1)⊃ # normal spacing of glue;
define gluestretch(p)=⊂memreal(p+2)⊃ # stretching factor of glue;
define glueshrink(p)=⊂memreal(p+3)⊃ # shrinking factor of glue;
define leadernode=6 # type code for leaders node;
define kernnode=7 # type code for kerning node;
define kernnodesize=2 # number of words in kern node;

external recursive procedure dsnodelist(integer p) # frees a list of boxes;

external integer nestptr # points to first unused in semantic stacks;
define nestsize = 20 # max number of things going on simultaneously;
external integer array modestack[0:nestsize-1]; external integer mode
	# current activity modes;
external integer array headstack[0:nestsize-1]; external integer head
	# pointers to list heads for lists being constructed;
external integer array curndstack[0:nestsize-1]; external integer curnode
	# pointers to nodes most recently added to the current lists;
external real array auxstack[0:nestsize-1]; external real aux;
	# auxiliary parameter (either spacefactor or prevdepth or incompleatnoad);
define prevdepth=⊂aux⊃, spacefactor=⊂aux⊃,
define vmode=1 # vertical mode;
define hmode=2+maxopcode # horizontal mode;
define mmode=3+2*maxopcode # math mode;
define flag=⊂(1 rot -1)⊃ # most significant bit of word;
define fflag=⊂(3 rot -2)⊃ # two most significant bits of word;

define pagememsize=5 # number of page parameters;
external real array pagemem[0:pagememsize-1] # page parameters;
define hsizemem=0 # location where hsize is stored in pagemem;
define vsizemem=1 # location where vsize is stored in pagemem;
define maxdepthmem=2 # location where maxdepth is stored in pagemem;
define parindentmem=3 # location where parindent is stored in pagemem;
define topbaselinemem=4 # loc where topbaseline is stored in pagemem;

define dispstyle=0,textstyle=1,scriptstyle=2,scriptscriptstyle=3;
define mathfonttable(f)=⊂eqtb[f+hashsize+256]⊃ # font numbers for math setting;
define boxnoad=0, opnoad=1, binnoad=2, relnoad=3, opennoad=4, closenoad=5,
define sqrtnoad=7,overnoad=8,undernoad=9,accentnoad=10,abovenoad=11;
define leftnoad=12,rightnoad=13;
define nodenoad=14, stylenoad=15;
define thinspace=8,thickspace=9,quadspace=10,negthinspace=11,negthickspace=12,
define bin(x)=⊂x+(binnoad lsh 9)⊃, op(x)=⊂x+(opnoad lsh 9)⊃,
	rel(x)=⊂x+(relnoad lsh 9)⊃, opn(x)=⊂x+(opennoad lsh 9)⊃,
	cls(x)=⊂x+(closenoad lsh 9)⊃, punct(x)=⊂x+(punctnoad lsh 9)⊃;
define fmemsize=3200 # size of font memory for secondary tables;
external integer array fmem[0:fmemsize-1] # font memory for secondary font tables;
external integer fmemptr # first unused location in fmem;
define fmemreal(k)=⊂memory[location(fmem[k]),real]⊃;
external integer array fontinfo[0:'7777] # primary font information table;
external integer array wdbase,htbase,dpbase,lgbase,msbase,dwbase,parbase[0:31]
	# base addresses in fmem for secondary font tables;
define wdd=0,wds=6,htd=6,hts=4,dpd=10,dps=4,lgd=14,lgs=5,msd=19,mss=6,
define charwd(f,t)=⊂fmemreal(wdbase[f]+field(wd,t))⊃
	# width in font f, fontinfo t;
define charht(f,t)=⊂fmemreal(htbase[f]+field(ht,t))⊃
	# height in font f, fontinfo t;
define chardp(f,t)=⊂fmemreal(dpbase[f]+field(dp,t))⊃
	# depth in font f, fontinfo t;
define fontpar(f,t)=⊂fmemreal(parbase[f]+t)⊃ # parameter no. t in font f;
define slant=0,spacewd=1,spacestr=2,spaceshr=3,xheight=4,quad=5;
define device1=6,device2=7,device3=8;
external procedure readfontinfo(integer chan,f) # reads font information file;

external real str,shr # total stretch,shrink found by packaging routine;
external integer procedure hpackage(integer head; real desiredwidth; boolean trial);
external integer procedure vpackage(integer head; real desiredheight; boolean page);

external real array sftable[0:127] # spacefactor table;
external procedure initsftable(real period,query,excl,colon,semi,comma);

define excepsize=373,sufsize=109,prefsize=109,btabsize=30 
	# hyphenation table sizes;
external integer array exceptable[0:excepsize-1] 
	# ordered hash table for exceptional words;
external integer array excephyph[1:excepsize-1] 
	# corresponding hyphenation patterns;
external integer array suffix[0:sufsize-1] # interpretive commands for suffixes;
external integer array prefix[0:prefsize-1] # interpretive commands for prefixes;
external integer array btable[2:btabsize+1] # consonant-pair exception table;

external real hangwidth # amount to indent lines (negative if at right margin);
external integer hangbegin # number of lines to wait before indentation changes;
external boolean hangfirst # does hanging indent occur before hangbegin or not;
define prevbrk(p)=⊂mem[p+4]⊃ # break node for best previous break leading here;
define lineno(p)=⊂mem[p+5]⊃ # number of lines up to this break;
define curbrk(p)=⊂mem[p+6]⊃ # hlist position of this break;
define target(p)=⊂memreal(p+7)⊃ # best curwd for the next break after here;
define totbad(p)=⊂memreal(p+8)⊃ # best sum of badness↑2 up to here;
define breaknodesize=9 # number of words in a break node;
external boolean autobreaking # automatic line breaking not shut off by hyphnode;
external real curwd,curst,cursh # current total width, stretch, and shrink;
external integer topopen,botopen # boundary of the active break nodes;
external procedure justification(real initwidth; integer linechange;
	real hangwidth) # routine to break hlists almost optimally;

internaldef alignsize=4 # max number of simultaneous alignments*;
external integer array algnlststack[0:alignsize-1];
external integer alignlist # points to beginning of alignment record list;
external integer array algnrcrdstack[0:alignsize-1];
external integer alignrecord # points to alignment record in the list;
external integer array algnststack[0:alignsize-1];
external integer alignstate # if zero, getnext should interrupt ⊗ and \cr tokens;
external integer alignptr # stack pointer for alignments;
external procedure aligndelim # do this when ⊗ or \cr is scanned;

external procedure maincontrol # governs all the activities;

comment * means this definition was moved to previous page (topological sort);
comment Declarations internal to TEXOUT;

external string ofilext # filename extension for output;
external string deviceext # extension to use in font information files;
external string ofilname # output file name, set by first \input;
external string libraryarea # default system area for fonts;
external procedure initout # get TEXOUT started properly;
external procedure declareofil(string s) # initializes the output on file s;

define stringsize=1500;
external integer array strinfo[0:stringsize-1];
external string array strings[0:stringsize-1];
external integer nstrs # pointers to the current string being generated;

external procedure shipout(integer p) # the main output procedure,produces one page;

external procedure closeout # just before TEX stops, do this;
comment Declarations internal to TEXEXT;

external procedure initext # do this when initializing TEX;
external procedure extop # do this when "\x" sensed in user input;
external procedure dumpext(integer p) # do this in procedure dumpnodelist;
external procedure destroyext(integer p) # do this in procedure dsnodelist;
external procedure eqdestroyext(integer p) # do this in procedure eqdestroy;
external procedure hpackext(integer p) # do this in procedure hpackage;
external procedure vpackext(integer p) # do this in procedure vpackage;
external procedure pageext(integer p) # do this in the addtopage routine;
external procedure justext(integer p) # do this in the justification routine;
external procedure houtext(integer p; reference real x,y) # do this in shipout;
external procedure voutext(integer p; reference real x,y) # do this in shipout;
external procedure finishext # do this just before terminating TEX;