[llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.am Makefile.in binary_readme.txt essay.html extending.txt mkdoc mkhtml mkpdf texinfo.tex treecc.1 treecc.texi

John Criswell criswell at cs.uiuc.edu
Tue Apr 6 12:56:06 PDT 2004


Changes in directory llvm/test/Programs/MultiSource/Applications/treecc/doc:

Makefile.am added (r1.1)
Makefile.in added (r1.1)
binary_readme.txt added (r1.1)
essay.html added (r1.1)
extending.txt added (r1.1)
mkdoc added (r1.1)
mkhtml added (r1.1)
mkpdf added (r1.1)
texinfo.tex added (r1.1)
treecc.1 added (r1.1)
treecc.texi added (r1.1)

---
Log message:

Adding in documentation for good measure.



---
Diffs of the changes:  (+9697 -0)

Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.am
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.am:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.am	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,3 ----
+ man_MANS = treecc.1
+ info_TEXINFOS = treecc.texi
+ CLEANFILES = treecc.info treecc.info-1 treecc.info-2 treecc.info-3


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.in
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.in:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/Makefile.in	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,360 ----
+ # Makefile.in generated automatically by automake 1.4 from Makefile.am
+ 
+ # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+ # This Makefile.in is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+ # with or without modifications, as long as this notice is preserved.
+ 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ # PARTICULAR PURPOSE.
+ 
+ 
+ SHELL = @SHELL@
+ 
+ srcdir = @srcdir@
+ top_srcdir = @top_srcdir@
+ VPATH = @srcdir@
+ prefix = @prefix@
+ exec_prefix = @exec_prefix@
+ 
+ bindir = @bindir@
+ sbindir = @sbindir@
+ libexecdir = @libexecdir@
+ datadir = @datadir@
+ sysconfdir = @sysconfdir@
+ sharedstatedir = @sharedstatedir@
+ localstatedir = @localstatedir@
+ libdir = @libdir@
+ infodir = @infodir@
+ mandir = @mandir@
+ includedir = @includedir@
+ oldincludedir = /usr/include
+ 
+ DESTDIR =
+ 
+ pkgdatadir = $(datadir)/@PACKAGE@
+ pkglibdir = $(libdir)/@PACKAGE@
+ pkgincludedir = $(includedir)/@PACKAGE@
+ 
+ top_builddir = ..
+ 
+ ACLOCAL = @ACLOCAL@
+ AUTOCONF = @AUTOCONF@
+ AUTOMAKE = @AUTOMAKE@
+ AUTOHEADER = @AUTOHEADER@
+ 
+ INSTALL = @INSTALL@
+ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+ INSTALL_DATA = @INSTALL_DATA@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ transform = @program_transform_name@
+ 
+ NORMAL_INSTALL = :
+ PRE_INSTALL = :
+ POST_INSTALL = :
+ NORMAL_UNINSTALL = :
+ PRE_UNINSTALL = :
+ POST_UNINSTALL = :
+ build_alias = @build_alias@
+ build_triplet = @build@
+ host_alias = @host_alias@
+ host_triplet = @host@
+ target_alias = @target_alias@
+ target_triplet = @target@
+ AWK = @AWK@
+ CC = @CC@
+ EXEEXT = @EXEEXT@
+ EXPR_CPP = @EXPR_CPP@
+ LEX = @LEX@
+ LN_S = @LN_S@
+ MAINT = @MAINT@
+ MAKEINFO = @MAKEINFO@
+ OBJEXT = @OBJEXT@
+ PACKAGE = @PACKAGE@
+ RANLIB = @RANLIB@
+ VERSION = @VERSION@
+ YACC = @YACC@
+ 
+ man_MANS = treecc.1
+ info_TEXINFOS = treecc.texi
+ CLEANFILES = treecc.info treecc.info-1 treecc.info-2 treecc.info-3
+ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+ CONFIG_HEADER = ../config.h
+ CONFIG_CLEAN_FILES = 
+ TEXI2DVI = texi2dvi
+ INFO_DEPS = treecc.info
+ DVIS = treecc.dvi
+ TEXINFOS = treecc.texi
+ man1dir = $(mandir)/man1
+ MANS = $(man_MANS)
+ 
+ NROFF = nroff
+ DIST_COMMON =  Makefile.am Makefile.in texinfo.tex
+ 
+ 
+ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+ 
+ TAR = gtar
+ GZIP_ENV = --best
+ all: all-redirect
+ .SUFFIXES:
+ .SUFFIXES: .dvi .info .ps .texi .texinfo .txi
+ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+ 	cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile
+ 
+ Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+ 	cd $(top_builddir) \
+ 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+ 
+ 
+ treecc.info: treecc.texi
+ treecc.dvi: treecc.texi
+ 
+ 
+ DVIPS = dvips
+ 
+ .texi.info:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ 
+ .texi.dvi:
+ 	TEXINPUTS=.:$$TEXINPUTS \
+ 	  MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+ 
+ .texi:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ 
+ .texinfo.info:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ 
+ .texinfo:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ 
+ .texinfo.dvi:
+ 	TEXINPUTS=.:$$TEXINPUTS \
+ 	  MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+ 
+ .txi.info:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ 
+ .txi.dvi:
+ 	TEXINPUTS=.:$$TEXINPUTS \
+ 	  MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+ 
+ .txi:
+ 	@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ 	cd $(srcdir) \
+ 	  && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+ .dvi.ps:
+ 	$(DVIPS) $< -o $@
+ 
+ install-info-am: $(INFO_DEPS)
+ 	@$(NORMAL_INSTALL)
+ 	$(mkinstalldirs) $(DESTDIR)$(infodir)
+ 	@list='$(INFO_DEPS)'; \
+ 	for file in $$list; do \
+ 	  d=$(srcdir); \
+ 	  for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ 	    if test -f $$d/$$ifile; then \
+ 	      echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ 	      $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ 	    else : ; fi; \
+ 	  done; \
+ 	done
+ 	@$(POST_INSTALL)
+ 	@if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ 	  list='$(INFO_DEPS)'; \
+ 	  for file in $$list; do \
+ 	    echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ 	    install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ 	  done; \
+ 	else : ; fi
+ 
+ uninstall-info:
+ 	$(PRE_UNINSTALL)
+ 	@if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ 	  ii=yes; \
+ 	else ii=; fi; \
+ 	list='$(INFO_DEPS)'; \
+ 	for file in $$list; do \
+ 	  test -z "$ii" \
+ 	    || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ 	done
+ 	@$(NORMAL_UNINSTALL)
+ 	list='$(INFO_DEPS)'; \
+ 	for file in $$list; do \
+ 	  (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ 	done
+ 
+ dist-info: $(INFO_DEPS)
+ 	list='$(INFO_DEPS)'; \
+ 	for base in $$list; do \
+ 	  d=$(srcdir); \
+ 	  for file in `cd $$d && eval echo $$base*`; do \
+ 	    test -f $(distdir)/$$file \
+ 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ 	    || cp -p $$d/$$file $(distdir)/$$file; \
+ 	  done; \
+ 	done
+ 
+ mostlyclean-aminfo:
+ 	-rm -f treecc.aux treecc.cp treecc.cps treecc.dvi treecc.fn treecc.fns \
+ 	  treecc.ky treecc.kys treecc.ps treecc.log treecc.pg \
+ 	  treecc.toc treecc.tp treecc.tps treecc.vr treecc.vrs \
+ 	  treecc.op treecc.tr treecc.cv treecc.cn
+ 
+ clean-aminfo:
+ 
+ distclean-aminfo:
+ 
+ maintainer-clean-aminfo:
+ 	cd $(srcdir) && for i in $(INFO_DEPS); do \
+ 	  rm -f $$i; \
+ 	  if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ 	    rm -f $$i-[0-9]*; \
+ 	  fi; \
+ 	done
+ 
+ install-man1:
+ 	$(mkinstalldirs) $(DESTDIR)$(man1dir)
+ 	@list='$(man1_MANS)'; \
+ 	l2='$(man_MANS)'; for i in $$l2; do \
+ 	  case "$$i" in \
+ 	    *.1*) list="$$list $$i" ;; \
+ 	  esac; \
+ 	done; \
+ 	for i in $$list; do \
+ 	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ 	  else file=$$i; fi; \
+ 	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ 	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ 	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ 	  echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ 	  $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ 	done
+ 
+ uninstall-man1:
+ 	@list='$(man1_MANS)'; \
+ 	l2='$(man_MANS)'; for i in $$l2; do \
+ 	  case "$$i" in \
+ 	    *.1*) list="$$list $$i" ;; \
+ 	  esac; \
+ 	done; \
+ 	for i in $$list; do \
+ 	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ 	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ 	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ 	  echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ 	  rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ 	done
+ install-man: $(MANS)
+ 	@$(NORMAL_INSTALL)
+ 	$(MAKE) $(AM_MAKEFLAGS) install-man1
+ uninstall-man:
+ 	@$(NORMAL_UNINSTALL)
+ 	$(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+ tags: TAGS
+ TAGS:
+ 
+ 
+ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+ 
+ subdir = doc
+ 
+ distdir: $(DISTFILES)
+ 	here=`cd $(top_builddir) && pwd`; \
+ 	top_distdir=`cd $(top_distdir) && pwd`; \
+ 	distdir=`cd $(distdir) && pwd`; \
+ 	cd $(top_srcdir) \
+ 	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu doc/Makefile
+ 	@for file in $(DISTFILES); do \
+ 	  d=$(srcdir); \
+ 	  if test -d $$d/$$file; then \
+ 	    cp -pr $$d/$$file $(distdir)/$$file; \
+ 	  else \
+ 	    test -f $(distdir)/$$file \
+ 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ 	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+ 	  fi; \
+ 	done
+ 	$(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+ info-am: $(INFO_DEPS)
+ info: info-am
+ dvi-am: $(DVIS)
+ dvi: dvi-am
+ check-am: all-am
+ check: check-am
+ installcheck-am:
+ installcheck: installcheck-am
+ install-exec-am:
+ install-exec: install-exec-am
+ 
+ install-data-am: install-info-am install-man
+ install-data: install-data-am
+ 
+ install-am: all-am
+ 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+ install: install-am
+ uninstall-am: uninstall-info uninstall-man
+ uninstall: uninstall-am
+ all-am: Makefile $(INFO_DEPS) $(MANS)
+ all-redirect: all-am
+ install-strip:
+ 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+ installdirs:
+ 	$(mkinstalldirs)  $(DESTDIR)$(infodir) $(DESTDIR)$(mandir)/man1
+ 
+ 
+ mostlyclean-generic:
+ 
+ clean-generic:
+ 	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+ 
+ distclean-generic:
+ 	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+ 	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ 
+ maintainer-clean-generic:
+ mostlyclean-am:  mostlyclean-aminfo mostlyclean-generic
+ 
+ mostlyclean: mostlyclean-am
+ 
+ clean-am:  clean-aminfo clean-generic mostlyclean-am
+ 
+ clean: clean-am
+ 
+ distclean-am:  distclean-aminfo distclean-generic clean-am
+ 
+ distclean: distclean-am
+ 
+ maintainer-clean-am:  maintainer-clean-aminfo maintainer-clean-generic \
+ 		distclean-am
+ 	@echo "This command is intended for maintainers to use;"
+ 	@echo "it deletes files that may require special tools to rebuild."
+ 
+ maintainer-clean: maintainer-clean-am
+ 
+ .PHONY: install-info-am uninstall-info mostlyclean-aminfo \
+ distclean-aminfo clean-aminfo maintainer-clean-aminfo install-man1 \
+ uninstall-man1 install-man uninstall-man tags distdir info-am info \
+ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+ install-exec install-data-am install-data install-am install \
+ uninstall-am uninstall all-redirect all-am all installdirs \
+ mostlyclean-generic distclean-generic clean-generic \
+ maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+ 
+ 
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+ .NOEXPORT:


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/binary_readme.txt
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/binary_readme.txt:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/binary_readme.txt	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,58 ----
+ 
+ Tree Compiler-Compiler
+ ======================
+ 
+ The treecc program is designed to assist in the development of compilers
+ and other language-based tools.  It manages the generation of code to handle
+ abstract syntax trees and operations upon the trees.
+ 
+ A fuller account of why treecc exists and what it can be used for can
+ be found in the HTML documentation within the "doc\html" subdirectory,
+ and in the introductory article "doc\intro.html".
+ 
+ Installing Treecc
+ -----------------
+ 
+ The zip file should be unpacked in a new directory on your hard drive.
+ For example, "C:\Treecc".  Then add "C:\Treecc\bin" to your PATH to
+ be able to run the tool.
+ 
+ To uninstall treecc, simply delete the entire contents of the install
+ directory.
+ 
+ Obtaining the source and more recent versions
+ ---------------------------------------------
+ 
+ The latest version of treecc can be obtained from the following Web site:
+ 
+     http://www.southern-storm.com.au/treecc/
+ 
+ The source code is also available from this site, under the terms of the
+ GNU General Public License.
+ 
+ The authors can be contacted via e-mail at the following address:
+ 
+     treecc at southern-storm.com.au
+ 
+ Copyright Considerations
+ ------------------------
+ 
+ Treecc is distributed under the terms of the GNU General Public License.
+ A copy of this can be found in the "COPYING" file.
+ 
+ However, it is not our intention to restrict the use of treecc to only
+ free software providers.  Use by commercial software vendors is welcome.
+ 
+ When you use treecc on your own input files to generate source code as
+ output, the resulting source code files are also owned by you.  You may
+ re-distribute unmodified copies of these output source files, and any
+ binaries derived from them, in any way you see fit.  Executing treecc on
+ your input files does not automatically incur obligations under the GPL.
+ 
+ If you modify treecc itself, and generate new output files as a result,
+ then you must release all source modifications to treecc with your program
+ so that other users can benefit from your changes under the terms of the GPL.
+ 
+ Contact the authors if you have any questions regarding the above.
+ It is our intention to allow the same amount of access to treecc output
+ files as is currently available using the GNU Bison and Flex programs.


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/essay.html
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/essay.html:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/essay.html	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,596 ----
+ <html>
+ <head>
+ <title>Treecc: An Aspect-Oriented Approach to Writing Compilers</title>
+ </head>
+ <body bgcolor="#ffffff">
+ <h1>Treecc: An Aspect-Oriented Approach to Writing Compilers</h1>
+ 
+ Rhys Weatherley, <a href="mailto:rweather at southern-storm.com.au">rweather at southern-storm.com.au</a>.<p>
+ 
+ Copyright © 2001, 2002 Rhys Weatherley<br>
+ Verbatim copying and distribution of this entire article is permitted
+ in any medium, provided this copyright notice is preserved.<p>
+ 
+ This is a copy of an article that was published in
+ <a href="http://www.rons.net.cn/english/FSM/issue02">Issue 2</a>
+ of Free Software Magazine.<p>
+ 
+ <h2>1. Introduction</h2>
+ 
+ The C# compiler in Portable.NET <a href="#pnetref">[1]</a> is built on top
+ of the "Tree Compiler Compiler" (treecc) utility program.
+ Treecc <a href="#treeccref">[2]</a> is distributed as Free Software
+ under the terms of the GNU General Public License.<p>
+ 
+ This article provides some background of why treecc came about.  It discusses
+ two common compiler implementation techniques, and the reasons why they
+ often fail to manage the complexity of large programming languages like C#.<p>
+ 
+ We then discuss a new programming technique called "Aspect-Oriented
+ Programming".  Treecc is an example of applying this technique to managing
+ the complexity of compiler construction.<p>
+ 
+ <h2>2. Patterns and Compiler Design</h2>
+ 
+ Compiler writing is generally seen as a black art, but in reality it isn't
+ all that hard.  The basic compilation steps are:<p>
+ 
+ <ol>
+ 	<li>Convert the program into an abstract syntax tree.</li>
+ 	<li>Perform type-checking and semantic analysis on the tree.</li>
+ 	<li>Rearrange the tree to perform optimisations.</li>
+ 	<li>Convert the tree into the target code.</li>
+ </ol>
+ 
+ The difficulty in writing compilers is not the steps involved, but rather
+ the sheer number of tiny little details to keep straight.  Modern languages
+ contain large numbers of operators, which are all very similar, but slightly
+ different:<p>
+ 
+ <blockquote>
+ Add, substract, multiply, divide, remainder, shift left, shift right,
+ shift right unsigned, bitwise and, bitwise or, exclusive-or, negate,
+ bitwise not, logical not, logical and, logical or, ...
+ </blockquote>
+ 
+ And that's just the operators.  Introduce statements, arrays, type coercion,
+ method invocation, and class definition, and it becomes very easy to
+ forget something amongst the forest of code.<p>
+ 
+ In an attempt to control this complexity, two common pattern-based
+ approaches have arisen over the years: Inheritance and Visitor.<p>
+ 
+ The inheritance pattern can be characterised as follows:<p>
+ 
+ <ol>
+ 	<li>Declare a node type for every syntactic element in the language.
+ 	    All types ultimately inherit from "<code>Node</code>".</li>
+ 	<li>Declare virtual methods in "<code>Node</code>" for
+ 	    operations on node types: semantic analysis, optimization,
+ 		code generation, etc.</li>
+ 	<li>Override the virtuals in sub-classes to provide the
+ 	    compiler implementation.</li>
+ </ol><p>
+ 
+ The visitor pattern can be characterised as follows:<p>
+ 
+ <ol>
+ 	<li>Declare a node type for every syntactic element in the language.
+ 	    All types ultimately inherit from "<code>Node</code>".</li>
+ 	<li>Declare a "<code>Visitor</code>" class with abstract virtual
+ 		methods such as "<code>VisitAdd</code>", "<code>VisitSub</code>",
+ 		"<code>VisitIf</code>", "<code>VisitFunction</code>",
+ 		etc for all of the node types.</li>
+ 	<li>Define a "walking procedure" over "<code>Node</code>" objects for
+ 	    walking around a syntax tree, making callbacks on a supplied
+ 		visitor object.</li>
+ 	<li>Create multiple classes that inherit from "<code>Visitor</code>",
+ 	    one for each operation.  Implement the "<code>Visit*</code>"
+ 		functions for that type of operation.</li>
+ </ol>
+ 
+ In the following sections, we will explore why these two patterns often
+ fail to manage compiler complexity, even when the programmer applies them
+ rigorously.<p>
+ 
+ <h2>3. The implementation language is your worst enemy</h2>
+ 
+ We will start with the inheritance pattern.  Consider that we've written
+ the following C# code during the "declare all the node types" phase of
+ the project:<p>
+ 
+ <blockquote>
+ <pre>public class UnaryExpression : Expression
+ {
+     protected Expression expr;
+ 
+     public UnaryExpression(Expression _expr) { expr = _expr; }
+ }
+ 
+ public class NegateExpression : UnaryExpression
+ {
+     public NegateExpression(Expression _expr) : base(_expr) {}
+ }
+ 
+ public class UnaryPlusExpression : UnaryExpression
+ {
+     public UnaryPlusExpression(Expression _expr) : base(_expr) {}
+ }
+ 
+ public class BitwiseNotExpression : UnaryExpression
+ {
+     public BitwiseNotExpression(Expression _expr) : base(_expr) {}
+ }</pre>
+ </blockquote>
+ 
+ We continue this process for several hundred other node types, gradually
+ building up the entire syntax tree.  This will probably take several weeks
+ to complete for a substantial language like C#, assuming that we are writing
+ the parser alongside the node types.<p>
+ 
+ We now want to go in and implement type-checking, so we modify the
+ "<code>UnaryExpression</code>" class as follows:<p>
+ 
+ <blockquote>
+ <pre>public class UnaryExpression : Expression
+ {
+     protected Expression expr;
+ 
+     public UnaryExpression(Expression _expr) { expr = _expr; }
+ 
+     public override LanguageType TypeCheck()
+     {
+         LanguageType type = expr.TypeCheck();
+         if(type.IsInteger() || type.IsFloat())
+         {
+             return type;
+         }
+         throw new TypeCheckException();
+     }
+ }</pre>
+ </blockquote>
+ 
+ We've put the common unary expression type-checking code in a common base
+ class.  This makes it easier to maintain because there is only one copy.
+ We continue the process over the next few weeks and months for all the
+ other operators, statements, and declarations in the language.  So far,
+ so good.<p>
+ 
+ Unfortunately, we've made a mistake.  The "<code>BitwiseNot</code>"
+ operator is only legal on integer values; not floating-point.<p>
+ 
+ But will we find this bug?  It was several weeks ago when we first wrote
+ the "<code>BitwiseNotExpression</code>" class, and we have since forgotten
+ all about it.  It may even have been written by another programmer on the
+ team, who has also forgotten all about it.  When we build our compiler,
+ we don't get any errors because the implemention language is perfectly
+ happy with the above code.<p>
+ 
+ Surely testing will find it?  We are building a test suite alongside
+ the code, right?  Unfortunately, that doesn't help either.  The test
+ suite for a major language will be at least as complex as the compiler
+ itself, and so there is always the temptation to abstract common tests
+ into common test classes.  We've just shifted the bug into the test suite
+ and given ourselves a false sense of security.<p>
+ 
+ So we keep coding for several more months, adding lots more code.  And then
+ a really nasty bug pops up.  The "<code>BitwiseNot</code>" operator is acting
+ strangely, and we have no idea why.  The system is now so complex, with
+ so many common base classes implementing fallback defaults, that tracking
+ this down becomes very hard.<p>
+ 
+ The inheritance pattern has a fatal flaw.  Adding a new operation entails
+ a very large maintainence burden, because hundreds of classes must be
+ modified.  This is very error-prone, so we try to abstract details into
+ common base classes.  But this introduces other errors.<p>
+ 
+ The problem basically boils down to semantic analysis: the implementation
+ language does not have enough knowledge about the application domain to
+ spot the problem and warn us about it.  So it happily compiles the code
+ and leaves us to hang ourselves on the system's complexity later.
+ Programming languages are supposed to help us manage complexity, not
+ make the problem worse!<p>
+ 
+ I wrote a number of compilers using the inheritance approach, and every
+ single time the complexity killed me.  I needed fallback defaults for
+ code maintainence reasons, but using fallbacks introduced massive numbers
+ of bugs.  I was stuck.<p>
+ 
+ <h2>4. Design patterns aren't always what they are cracked up to be</h2>
+ 
+ After much hair-pulling, I searched <em>Design Patterns</em>
+ by Gamma, et al <a href="#gammaref">[3]</a>.  "<em>Is there a better
+ way of doing this?</em>".  Visitor patterns are the answer:
+ the book even gives a compiler example.<p>
+ 
+ Visitors solve the "<em>I forgot to implement the <code>BitwiseNot</code></em>"
+ problem.  Because every node type has its own "<code>Visit*</code>" method,
+ we will get an error when we try to build the compiler without implementing
+ the operation for a node type.  Of course, this assumes that we haven't
+ been dumb and implemented fallback defaults in the "<code>Visitor</code>"
+ base class.<p>
+ 
+ Instead of using virtual methods, we can implement visitors using
+ switch statements over node types.  e.g.<p>
+ 
+ <blockquote>
+ <pre>switch(node.type)
+ {
+     case Negate: ...
+     case UnaryPlus: ...
+     case BinaryNot: ...
+     ...
+ }</pre>
+ </blockquote>
+ 
+ However, switch statements have a similar flaw to inheritance: the
+ implementation language will not warn us if we forget to put in
+ a case for every node type.  It will happily fall out through the
+ "<code>default</code>" case with no warning.  Tracking down these bugs
+ can be just as hard as tracking down inheritance fallback bugs.
+ Using virtual methods is "safer", if not quite as efficient.<p>
+ 
+ Unfortunately, there is a catch with visitors, as explained in
+ <em>Design Patterns</em>:<p>
+ 
+ <blockquote>
+ <em>Use the Visitor pattern when ... the classes defining the object
+ structure rarely change, but you often want to define new operations
+ over the structure.  Changing the object structure classes requires
+ redefining the interface to all visitors, which is potentially
+ costly.  If the object structure classes change often, then it's
+ probably better to define the operations in those classes.</em>
+ </blockquote>
+ 
+ During the early stages of writing a compiler, the node types change very
+ frequently.  This activates the Achilles heel of the Visitor pattern,
+ and creates a maintainence nightmare.  The book suggests that we should
+ use the inheritance approach to solve this problem.<p>
+ 
+ <h2>5. So which one do we use?  Inheritance or Visitor?</h2>
+ 
+ The inheritance pattern becomes a problem when new operations are needed.
+ The solution is visitors.  Visitors become a problem when new node types
+ are needed.  The solution is inheritance.<p>
+ 
+ What we have is a situation that the design patterns gurus didn't
+ consider: if the set of nodes and operations are both changing rapidly,
+ then we will have problems no matter what we do.<p>
+ 
+ We need a solution that combines the strengths of both patterns without
+ the drawbacks of either.  We want the implementation language to catch
+ us when we forget something, but we also want it to handle large numbers
+ of nodes and operations smoothly.  We want to split different operations
+ into different modules, but also keep them closely associated with the
+ node type.<p>
+ 
+ None of the standard patterns provide this combination of functionality,
+ because none of the existing implementation languages support both styles
+ of program design at the same time.<p>
+ 
+ <h2>6. Aspect-Oriented Programming</h2>
+ 
+ A new field in language design has emerged in recent years called
+ "Aspect-Oriented Programming" (AOP).  A good review of the field
+ can be found in the October 2001 issue of the "<em>Communications of
+ the ACM</em>" <a href="#aopref">[4]</a>, and on the AspectJ Web site
+ <a href="#aspectjref">[5]</a>.<p>
+ 
+ The following excerpt from the introduction to the AOP section in the
+ CACM issue describes the essential aspects of AOP, and the difference
+ between OOP and AOP:<p>
+ 
+ <blockquote>
+ <em>AOP is based on the idea that computer systems are better programmed
+ by separately specifying the various concerns (properties or areas
+ of interest) of a system and some description of their relationships,
+ and then relying on mechanisms in the underlying AOP environment to
+ weave or compose them together into a coherent program. ...
+ While the tendancy in OOP's is to find commonality among classes
+ and push it up the inheritance tree, AOP attempts to realize
+ scattered concerns as first-class elements, and eject them
+ horizontally from the object structure.</em>
+ </blockquote>
+ 
+ Aspect-orientation gives us some hope of solving our compiler
+ complexity problems.  When we moved from the inheritance pattern
+ to the visitor pattern, we were attempting to eject the operations
+ horizontally.  But it didn't quite work as well as we had hoped: the
+ intrinsic complexity of the set of nodes kept interfering.  AOP
+ allows us to take the idea further, without re-introducing the problems
+ that visitors have.<p>
+ 
+ We can view each operation on node types (semantic analysis,
+ optimization, code generation, etc) as an "aspect" of the compiler's
+ construction.  The AOP language weaves these aspects with the node
+ types to create the final compiler.<p>
+ 
+ However, we don't really want to invent a completely new programming
+ language for compiler construction.  We would have to implement this
+ new language using all of the flawed techniques that makes writing
+ compilers hard.  It's a classic chicken and egg problem: we don't
+ want to replace a buggy compiler with a buggy compiler implementation
+ language.<p>
+ 
+ We can strike a compromise, similar to that used by lex and yacc.
+ Those tools use a custom syntax for the difficult parts, and a
+ pre-existing underlying language (usually C) to implement everything
+ else.  The code is expanded by the tool and then compiled with the
+ underlying language's compiler.<p>
+ 
+ Treecc uses a domain-specific aspect-oriented programming language for
+ declaring and managing nodes and operations, and uses an underlying language
+ to implement the body of the operations.  C, C++, C#, or Java can be used
+ as the underlying language, depending upon your personal preference.<p>
+ 
+ Treecc is about 13,000 lines of code in size, which is relatively
+ easy to debug by hand.<p>
+ 
+ <em>Aside:</em> treecc does not support all of the AOP features that are
+ described in the literature.  Treecc weaves together classes from multiple
+ method definitions.  Other AOP languages can also weave together methods
+ from fragments in multiple aspects.  We concentrated on those AOP features
+ that were useful for compiler construction.  Other features could be
+ incorporated at a later date.<p>
+ 
+ <h2>7. Using Treecc to Beat Inheritance Bugs</h2>
+ 
+ Now that we've identified the problems of inheritance and visitor patterns
+ for compiler implementation, we will show how treecc helps the programmer
+ avoid these traps.<p>
+ 
+ The following is the treecc definition of our example node types:
+ 
+ <blockquote>
+ <pre>%option lang = "C#"
+ 
+ %node Expression %abstract %typedef
+ 
+ %node UnaryExpression Expression %abstract =
+ {
+     Expression expr;
+ }
+ 
+ %node NegateExpression UnaryExpression
+ %node UnaryPlusExpression UnaryExpression
+ %node BitwiseNotExpression UnaryExpression</pre>
+ </blockquote>
+ 
+ Treecc converts this into a number of C# classes, one for each
+ node type.  It also inserts helper methods for testing the type
+ of a node and for tracking source line numbers.  If the output language
+ is C or C++, treecc will also insert code for allocating large numbers
+ of nodes efficiently.<p>
+ 
+ The type-checking operation (or "aspect") is declared as follows:<p>
+ 
+ <blockquote>
+ <pre>%operation %virtual LanguageType TypeCheck(Expression e)
+ 
+ TypeCheck(NegateExpression),
+ TypeCheck(UnaryPlusExpression)
+ {
+     LanguageType type = e.expr.TypeCheck();
+     if(type.IsInteger() || type.IsFloat())
+     {
+         return type;
+     }
+     throw new TypeCheckException();
+ }
+ 
+ TypeCheck(BitwiseNotExpression)
+ {
+     LanguageType type = e.expr.TypeCheck();
+     if(type.IsInteger())
+     {
+         return type;
+     }
+     throw new TypeCheckException();
+ }</pre>
+ </blockquote>
+ 
+ We have not declared the operation to cover "<code>Expression</code>" or
+ "<code>UnaryExpression</code>".  Instead, we list all of the applicable
+ subtypes explicitly.  When treecc is run on the above file, it will check
+ that every non-abstract node type is handled by an operation case.  If it finds
+ a missing type, it will report an error.  Let's demonstrate that by adding a
+ new unary expression type:<p>
+ 
+ <blockquote><code>
+ %node LogicalNotExpression UnaryExpression<br>
+ <br>
+ eg.tc:17: node type `LogicalNotExpression' is not handled in operation `TypeCheck'<br>
+ </code></blockquote>
+ 
+ This is at the heart of treecc's power: it performs a large amount of
+ semantic analysis over the node types to determine if the programmer has
+ forgotten something.  The programmer is notified of this early in
+ development process, when it is easier to fix the problem.<p>
+ 
+ As we discussed earlier, we want to implement common code in common
+ base classes to improve code sharing.  However, this introduces
+ hard to find bugs.  Treecc avoids the need to do this by allowing
+ the programmer to attach multiple cases to the same code block,
+ as in the case of "<code>NegateExpression</code>" and
+ "<code>UnaryPlusExpression</code>" above.<p>
+ 
+ An important feature of aspect-oriented languages is aspect modularity:
+ it should be possible to implement separate aspects in different parts
+ of the code.  Treecc supports this by separating node and operation
+ definitions.  Operations do not need to be implemented in the same
+ file as the nodes to which they apply, and multiple operations on
+ the same node types can be scattered through-out the code.<p>
+ 
+ Portable.NET takes this even further by separating individual operations
+ across multiple files for expressions, statements, declarations, etc.
+ This introduces a clearer structure to the code that makes it easier
+ to navigate the source during compiler construction.  The semantic analysis
+ routines in treecc ensure that nothing is missed when all of the
+ separate modules are recombined.<p>
+ 
+ <h2>8. Painless Visitors</h2>
+ 
+ The previous example used a "<code>%virtual</code>" operation, which
+ is defined over all node types.  Treecc inserts the virtual method
+ body wherever it is required.<p>
+ 
+ Sometimes we don't want to define an operation as a virtual method.
+ We would prefer to use the visitor approach.  The following is what
+ a visitor version of "<code>TypeCheck</code>" would look like:
+ 
+ <blockquote>
+ <pre>%operation LanguageType TypeChecker::TypeCheck(Expression e) = {null}
+ 
+ TypeCheck(NegateExpression),
+ TypeCheck(UnaryPlusExpression)
+ {
+     LanguageType type = TypeCheck(e.expr);
+     if(type.IsInteger() || type.IsFloat())
+     {
+         return type;
+     }
+     throw new TypeCheckException();
+ }
+ 
+ TypeCheck(BitwiseNotExpression)
+ {
+     LanguageType type = TypeCheck(e.expr);
+     if(type.IsInteger())
+     {
+         return type;
+     }
+     throw new TypeCheckException();
+ }</pre>
+ </blockquote>
+ 
+ This is almost identical to the previous version, except for the
+ definition of the operation, and the calling conventions for
+ "<code>TypeCheck</code>".  Behind the scenes, treecc creates
+ a class called "<code>TypeChecker</code>" that contains a static
+ method called "<code>TypeCheck</code>".  This is the visitor.<p>
+ 
+ Interestingly, if we had used C as the underlying language, then no
+ changes are necessary to the bodies of the operation cases.  Only
+ the "<code>%virtual</code>" keyword changes.  The C macro pre-processor
+ is used to smooth out the differences.<p>
+ 
+ This illustrates another useful property of treecc: it is very simple
+ to flip operations between inhertance-based virtuals and visitor-based
+ non-virtuals.  This allows the programmer to start developing the compiler
+ one way, change their mind, and quickly flip to the other way.<p>
+ 
+ Normally, changing inheritance-based code into visitor-based code
+ would entail a complete system rewrite.  Changing patterns with
+ treecc is trivial.<p>
+ 
+ This is a common property of aspect-oriented programming languages:
+ because the language takes care of the inserting the aspects into
+ the main classes, it is easier to change the style of insertion
+ without a major system overhaul.<p>
+ 
+ Non-virtual operations can be applied to multiple arguments, which
+ can be very useful when implementing coercions:
+ 
+ <blockquote>
+ <pre>%enum SimpleType =
+ {
+     Integer,
+     Long,
+     Float,
+     Error
+ }
+ 
+ %operation %inline SimpleType Binary::Coerce
+         ([SimpleType type1], [SimpleType type2]) = {Error}
+ 
+ Coerce(Integer, Integer)
+ {
+     return Integer;
+ }
+ 
+ Coerce(Integer, Long),
+ Coerce(Long, Integer),
+ Coerce(Long, Long)
+ {
+     return Long;
+ }
+ 
+ Coerce(Integer, Float),
+ Coerce(Float, Integer),
+ Coerce(Long, Float),
+ Coerce(Float, Float)
+ {
+     return Float;
+ }
+ 
+ Coerce(Integer, Error),
+ Coerce(Error, Integer),
+ Coerce(Long, Error),
+ Coerce(Error, Long),
+ Coerce(Float, Error),
+ Coerce(Error, Float),
+ Coerce(Error, Error)
+ {
+     return Error;
+ }</pre>
+ </blockquote>
+ 
+ Treecc turns this into a highly efficient nested switch statement,
+ which would be extremely difficult to debug by hand.  We actually
+ left out one of the cases above, so we get an error:
+ 
+ <blockquote><code>eg.tc:48: case `Float, Long' is missing from operation `Coerce'</code></blockquote>
+ 
+ Casts and coercions on primitive types can now be implemented as
+ simple table lookups, with treecc checking the completeness of the
+ table for us.<p>
+ 
+ <h2>9. Conclusion and Future Directions</h2>
+ 
+ Treecc provides a new way to attack the complexity of compiler implementation
+ by automating error-prone tasks.  It performs a large amount of semantic
+ analysis on the program to ensure that common problems are caught early
+ in the development cycle.<p>
+ 
+ Because treecc is based on an aspect-oriented foundation, it allows the
+ programmer to separate out concerns and deal with them individually.
+ Treecc puts the whole system back together in the most efficient manner
+ possible.<p>
+ 
+ The system is not necessarily complete.  We'd like to experiment with
+ rule-based code generation techniques.  At present, optimizers and
+ code generators must be written by hand, as operations on node types.<p>
+ 
+ A rule-based system would make it easier to build clever optimizers
+ as a set of pattern matching directives.  Operations are already a
+ special class of pattern matcher, but they don't have any back-tracking
+ and retry capabilities.<p>
+ 
+ Another area that treecc can be applied to is the construction of
+ "Just In Time" compilers.  The first phase of the JIT process is the
+ reconstruction of the intermediate code form of the program.  This
+ intermediate code typically takes the form of abstract syntax trees or
+ three-address statements.<p>
+ 
+ Treecc is well-suited to the management of JIT intermediate forms.
+ Register allocation, dynamic flow analysis, and machine-dependent
+ code generation can be added as JIT aspects.  We are currently
+ exploring the use of treecc to assist in the construction of a
+ JIT for Portable.NET<p>
+ 
+ <h2>References</h2>
+ 
+ <a name="pnetref">[1] Portable.NET Web Site, <a href="http://www.southern-storm.com.au/portable_net.html">http://www.southern-storm.com.au/portable_net.html</a>.<p>
+ 
+ <a name="treeccref">[2] Treecc Web Site, <a href="http://www.southern-storm.com.au/treecc.html">http://www.southern-storm.com.au/treecc.html</a>.<p>
+ 
+ <a name="gammaref">[3] Gamma, et al., <em>Design Patterns: Elements of
+ Reusable Object-Oriented Software</em>, Addison-Wesley, 1995.<p>
+ 
+ <a name="aopref">[4] Aspect-Oriented Programming, <em>Communications of
+ the ACM</em>, October 2001.<p>
+ 
+ <a name="aspectjref">[5] AspectJ Web Site, <a href="http://www.aspectj.org/">http://www.aspectj.org/</a>.<p>
+ 
+ </body>
+ </html>


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/extending.txt
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/extending.txt:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/extending.txt	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,99 ----
+        Quick and Dirty Guide to Extending and Testing Treecc
+ 
+ 1. Adding a new output language - Scaffolding
+ 
+ The following is the bare scaffolding to link a new language into treecc:
+ 
+     - Add a new identifier to the TREECC_LANG_* list in "info.h".
+     - Recognise the language name for the "lang" option in "options.c",
+       function "LangOption".
+     - Add a new case to the switch statement in "TreeCCGenerate" function
+       in the file "gen.c" for the language identifier, which calls a
+       function called "TreeCCGenerateLang", which you should prototype
+       in "gen.h".
+     - Add a new "gen_lang.c" file to the project (don't forget to
+       update Makefile.am), which implements the output routines.
+ 
+ 2. Adding a new output language - Details
+ 
+ The "gen_lang.c" file needs to export a single function called
+ "TreeCCGenerateLang", which iterates over all the nodes and operations
+ to output the final code.
+ 
+ The "TreeCCGenerateLang" function must perform the following tasks,
+ roughly in this order:
+ 
+     - Output any source header information that is required.
+     - Output node kinds, which are used to uniquely identify each
+       node type (e.g. "#define expression_kind 1" in C).  In an OO
+       language, you can output these kind values 
+     - Perform forward declaration of the node classes and operations,
+       if required by the output language (C# and Java don't need this,
+       but C does).
+     - Output the node allocation skeleton (normally not needed if
+       your language is garbage-collected).
+     - Define the node classes, and any factory create methods that
+       are required.  You may also need to define a "state type" which
+       holds common allocation information.
+     - Output non-virtual operations, by calling "TreeCCGenerateNonVirtuals",
+       and passing it a function block ("TreeCCNonVirtual" type) to
+       assist with the output process.
+     - Output any source footer information that is required, including
+       helper functions for node allocation, kind testing, etc.
+ 
+ It is usually easiest to start with one of the existing output languages
+ and then cut-and-paste yourself a new one.  If you are using a non garbage
+ collected language such as C or C++, then start with either "gen_c.c" or
+ "gen_cpp.c" as a base.  If you are using a garbage collected language
+ like C# or Java, then start with either "gen_cs.c" or "gen_java.c".
+ 
+ The function "TreeCCNodeVisitAll" can be very useful for iterating over
+ all node types in the system: pass it a callback that provides your
+ language-specific node handling code.  See "info.h" and "gen.h" for
+ other helper functions.
+ 
+ Nodes and operations can be written to multiple output files, and you
+ must handle this properly.  The functions in "stream.h" can assist with
+ this.  The "header" and "source" fields in "TreeCCNode" and "TreeCCOperation"
+ describe where to output node and operation implementations.
+ 
+ The actual API to nodes and operations is language-specific, but try
+ to follow the existing styles where possible.  See "doc/treecc.texi"
+ for documentation on the existing API styles.
+ 
+ 2. Testing all possible variants.
+ 
+ There are lots of different output modes (re-entrant vs non re-entrant,
+ line tracking vs no line tracking, abstract factories, virtual vs non-virtual
+ operations, inline vs non-inline, etc).
+ 
+ Your test cases in the "tests" directory should attempt to cover the
+ major areas.  See the "output*.tst" files for the existing tests.  You
+ shouldn't need to create "input" or "parse" tests, as they are generic.
+ 
+ Once you have written a new "outputN.tst" file, generate test output
+ using "./test_output outputN.tst >outputN.out".  Then hand-inspect the
+ "outputN.out" file for problems.  Once you are satisfied that your
+ "gen_lang.c" code is generating the right output, add the following
+ line to "tests/test_list":
+ 
+     test_output outputN
+ 
+ After you have done this, you can run "make check" to verify that you
+ haven't broken anything as you made changes to the system.
+ 
+ 3. Add an example.
+ 
+ Go into the "examples" directory and add a new version of the expression
+ example for your language, to demonstrate how to use treecc with the
+ language.  The examples doesn't necessarily need to compile - just give
+ a guide as to how to use the tool.
+ 
+ 4. Write documentation.
+ 
+ Add a new section to "doc/treecc.texi" describing the API for your
+ language, using the existing sections as to a guide to the text.
+ 
+ 5. It's not as hard as your think!
+ 
+ The above may look daunting, but it's mostly a cut-and-paste exercise.


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/mkdoc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/mkdoc:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/mkdoc	Tue Apr  6 12:54:44 2004
***************
*** 0 ****
--- 1,34 ----
+ #!/bin/sh
+ #
+ # mkdoc - Make all forms of documentation for treecc from Texinfo input.
+ #
+ # Usage: mkdir outdir
+ 
+ # Check the command-line.
+ if [ -z "$1" ]; then
+ 	echo "Usage: $0 outdir"
+ 	exit 1
+ fi
+ 
+ # Check that we are executed in the correct directory.
+ if [ ! -f treecc.texi ]; then
+ 	echo "Cannot find treecc.texi"
+ 	exit 1
+ fi
+ 
+ # Create the output directory.
+ if [ ! -d "$1" ]; then
+ 	mkdir "$1"
+ fi
+ 
+ # Create the online HTML documentation.
+ ./mkhtml "$1"
+ 
+ # Create the PDF documentation.
+ ./mkpdf
+ cp treecc.pdf "$1"
+ 
+ # Pack up the HTML documentation into a tar.gz file.
+ cd "$1"
+ tar cfz treecc-doc.tar.gz *.html
+ exit 0


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/mkhtml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/mkhtml:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/mkhtml	Tue Apr  6 12:54:45 2004
***************
*** 0 ****
--- 1,29 ----
+ #!/bin/sh
+ #
+ # mkhtml - Make html documentation for treecc from Texinfo input.
+ #
+ # Usage: mkhtml outdir
+ 
+ # Check the command-line.
+ if [ -z "$1" ]; then
+ 	echo "Usage: $0 outdir"
+ 	exit 1
+ fi
+ 
+ # Check that we are executed in the correct directory.
+ if [ ! -f treecc.texi ]; then
+ 	echo "Cannot find treecc.texi"
+ 	exit 1
+ fi
+ 
+ # Create the output directory.
+ if [ ! -d "$1" ]; then
+ 	mkdir "$1"
+ fi
+ 
+ # Get the full pathname of the input file.
+ PATHNAME=`pwd`/treecc.texi
+ 
+ # Change to the output directory and execute "texi2html".
+ cd "$1"
+ exec texi2html -split_chapter "$PATHNAME"


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/mkpdf
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/mkpdf:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/mkpdf	Tue Apr  6 12:54:45 2004
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ #
+ # mkpdf - Make the PDF version of the treecc documentation
+ 
+ exec texi2dvi --pdf treecc.texi


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/texinfo.tex
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/texinfo.tex:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/texinfo.tex	Tue Apr  6 12:54:45 2004
***************
*** 0 ****
--- 1,5484 ----
+ % texinfo.tex -- TeX macros to handle Texinfo files.
+ %
+ % Load plain if necessary, i.e., if running under initex.
+ \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+ %
+ \def\texinfoversion{1999-01-05}%
+ %
+ % Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98
+ % Free Software Foundation, Inc.
+ %
+ % This texinfo.tex file is free software; you can redistribute it and/or
+ % modify it under the terms of the GNU General Public License as
+ % published by the Free Software Foundation; either version 2, or (at
+ % your option) any later version.
+ %
+ % This texinfo.tex file is distributed in the hope that it will be
+ % useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ % General Public License for more details.
+ %
+ % You should have received a copy of the GNU General Public License
+ % along with this texinfo.tex file; see the file COPYING.  If not, write
+ % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ % Boston, MA 02111-1307, USA.
+ %
+ % In other words, you are welcome to use, share and improve this program.
+ % You are forbidden to forbid anyone else to use, share and improve
+ % what you give them.   Help stamp out software-hoarding!
+ %
+ % Please try the latest version of texinfo.tex before submitting bug
+ % reports; you can get the latest version from:
+ %   ftp://ftp.gnu.org/pub/gnu/texinfo.tex
+ %   /home/gd/gnu/doc/texinfo.tex on the GNU machines.
+ %   (and all GNU mirrors, see http://www.gnu.org/order/ftp.html)
+ %   ftp://tug.org/tex/texinfo.tex
+ %   ftp://ctan.org/macros/texinfo/texinfo.tex
+ %   (and all CTAN mirrors, finger ctan at ctan.org for a list).
+ % The texinfo.tex in the texinfo distribution itself could well be out
+ % of date, so if that's what you're using, please check.
+ % 
+ % Send bug reports to bug-texinfo at gnu.org.
+ % Please include a precise test case in each bug report,
+ % including a complete document with which we can reproduce the problem.
+ % 
+ % To process a Texinfo manual with TeX, it's most reliable to use the
+ % texi2dvi shell script that comes with the distribution.  For simple
+ % manuals, however, you can get away with:
+ %   tex foo.texi
+ %   texindex foo.??
+ %   tex foo.texi
+ %   tex foo.texi
+ %   dvips foo.dvi -o # or whatever, to process the dvi file.
+ % The extra runs of TeX get the cross-reference information correct.
+ % Sometimes one run after texindex suffices, and sometimes you need more
+ % than two; texi2dvi does it as many times as necessary.
+ 
+ \message{Loading texinfo [version \texinfoversion]:}
+ 
+ % If in a .fmt file, print the version number
+ % and turn on active characters that we couldn't do earlier because
+ % they might have appeared in the input file name.
+ \everyjob{\message{[Texinfo version \texinfoversion]}%
+   \catcode`+=\active \catcode`\_=\active}
+ 
+ % Save some parts of plain tex whose names we will redefine.
+ 
+ \let\ptexb=\b
+ \let\ptexbullet=\bullet
+ \let\ptexc=\c
+ \let\ptexcomma=\,
+ \let\ptexdot=\.
+ \let\ptexdots=\dots
+ \let\ptexend=\end
+ \let\ptexequiv=\equiv
+ \let\ptexexclam=\!
+ \let\ptexi=\i
+ \let\ptexlbrace=\{
+ \let\ptexrbrace=\}
+ \let\ptexstar=\*
+ \let\ptext=\t
+ 
+ % We never want plain's outer \+ definition in Texinfo.
+ % For @tex, we can use \tabalign.
+ \let\+ = \relax
+ 
+ 
+ \message{Basics,}
+ \chardef\other=12
+ 
+ % If this character appears in an error message or help string, it
+ % starts a new line in the output.
+ \newlinechar = `^^J
+ 
+ % Set up fixed words for English if not already set.
+ \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+ \ifx\putwordChapter\undefined  \gdef\putwordChapter{Chapter}\fi
+ \ifx\putwordfile\undefined     \gdef\putwordfile{file}\fi
+ \ifx\putwordInfo\undefined     \gdef\putwordInfo{Info}\fi
+ \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+ \ifx\putwordon\undefined       \gdef\putwordon{on}\fi
+ \ifx\putwordpage\undefined     \gdef\putwordpage{page}\fi
+ \ifx\putwordsection\undefined  \gdef\putwordsection{section}\fi
+ \ifx\putwordSection\undefined  \gdef\putwordSection{Section}\fi
+ \ifx\putwordsee\undefined      \gdef\putwordsee{see}\fi
+ \ifx\putwordSee\undefined      \gdef\putwordSee{See}\fi
+ \ifx\putwordShortContents\undefined  \gdef\putwordShortContents{Short Contents}\fi
+ \ifx\putwordTableofContents\undefined\gdef\putwordTableofContents{Table of Contents}\fi
+ 
+ % Ignore a token.
+ %
+ \def\gobble#1{}
+ 
+ \hyphenation{ap-pen-dix}
+ \hyphenation{mini-buf-fer mini-buf-fers}
+ \hyphenation{eshell}
+ \hyphenation{white-space}
+ 
+ % Margin to add to right of even pages, to left of odd pages.
+ \newdimen \bindingoffset
+ \newdimen \normaloffset
+ \newdimen\pagewidth \newdimen\pageheight
+ 
+ % Sometimes it is convenient to have everything in the transcript file
+ % and nothing on the terminal.  We don't just call \tracingall here,
+ % since that produces some useless output on the terminal.
+ %
+ \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+ \ifx\eTeXversion\undefined
+ \def\loggingall{\tracingcommands2 \tracingstats2
+    \tracingpages1 \tracingoutput1 \tracinglostchars1
+    \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+    \showboxbreadth\maxdimen\showboxdepth\maxdimen
+ }%
+ \else
+ \def\loggingall{\tracingcommands3 \tracingstats2
+    \tracingpages1 \tracingoutput1 \tracinglostchars1
+    \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+    \tracingscantokens1 \tracingassigns1 \tracingifs1
+    \tracinggroups1 \tracingnesting2
+    \showboxbreadth\maxdimen\showboxdepth\maxdimen
+ }%
+ \fi
+ 
+ % For @cropmarks command.
+ % Do @cropmarks to get crop marks.
+ % 
+ \newif\ifcropmarks
+ \let\cropmarks = \cropmarkstrue
+ %
+ % Dimensions to add cropmarks at corners.
+ % Added by P. A. MacKay, 12 Nov. 1986
+ %
+ \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+ \newdimen\cornerlong  \cornerlong=1pc
+ \newdimen\cornerthick \cornerthick=.3pt
+ \newdimen\topandbottommargin \topandbottommargin=.75in
+ 
+ % Main output routine.
+ \chardef\PAGE = 255
+ \output = {\onepageout{\pagecontents\PAGE}}
+ 
+ \newbox\headlinebox
+ \newbox\footlinebox
+ 
+ % \onepageout takes a vbox as an argument.  Note that \pagecontents
+ % does insertions, but you have to call it yourself.
+ \def\onepageout#1{%
+   \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+   %
+   \ifodd\pageno  \advance\hoffset by \bindingoffset
+   \else \advance\hoffset by -\bindingoffset\fi
+   %
+   % Do this outside of the \shipout so @code etc. will be expanded in
+   % the headline as they should be, not taken literally (outputting ''code).
+   \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+   \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+   %
+   {%
+     % Have to do this stuff outside the \shipout because we want it to
+     % take effect in \write's, yet the group defined by the \vbox ends
+     % before the \shipout runs.
+     %
+     \escapechar = `\\     % use backslash in output files.
+     \indexdummies         % don't expand commands in the output.
+     \normalturnoffactive  % \ in index entries must not stay \, e.g., if
+                    % the page break happens to be in the middle of an example.
+     \shipout\vbox{%
+       \ifcropmarks \vbox to \outervsize\bgroup
+         \hsize = \outerhsize
+         \vskip-\topandbottommargin
+         \vtop to0pt{%
+           \line{\ewtop\hfil\ewtop}%
+           \nointerlineskip
+           \line{%
+             \vbox{\moveleft\cornerthick\nstop}%
+             \hfill
+             \vbox{\moveright\cornerthick\nstop}%
+           }%
+           \vss}%
+         \vskip\topandbottommargin
+         \line\bgroup
+           \hfil % center the page within the outer (page) hsize.
+           \ifodd\pageno\hskip\bindingoffset\fi
+           \vbox\bgroup
+       \fi
+       %
+       \unvbox\headlinebox
+       \pagebody{#1}%
+       \ifdim\ht\footlinebox > 0pt
+         % Only leave this space if the footline is nonempty.
+         % (We lessened \vsize for it in \oddfootingxxx.)
+         % The \baselineskip=24pt in plain's \makefootline has no effect.
+         \vskip 2\baselineskip
+         \unvbox\footlinebox
+       \fi
+       %
+       \ifcropmarks
+           \egroup % end of \vbox\bgroup
+         \hfil\egroup % end of (centering) \line\bgroup
+         \vskip\topandbottommargin plus1fill minus1fill
+         \boxmaxdepth = \cornerthick
+         \vbox to0pt{\vss
+           \line{%
+             \vbox{\moveleft\cornerthick\nsbot}%
+             \hfill
+             \vbox{\moveright\cornerthick\nsbot}%
+           }%
+           \nointerlineskip
+           \line{\ewbot\hfil\ewbot}%
+         }%
+       \egroup % \vbox from first cropmarks clause
+       \fi
+     }% end of \shipout\vbox
+   }% end of group with \turnoffactive
+   \advancepageno
+   \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+ }
+ 
+ \newinsert\margin \dimen\margin=\maxdimen
+ 
+ \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+ {\catcode`\@ =11
+ \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+ % marginal hacks, juha at viisa.uucp (Juha Takala)
+ \ifvoid\margin\else % marginal info is present
+   \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+ \dimen@=\dp#1 \unvbox#1
+ \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+ \ifr at ggedbottom \kern-\dimen@ \vfil \fi}
+ }
+ 
+ % Here are the rules for the cropmarks.  Note that they are
+ % offset so that the space between them is truly \outerhsize or \outervsize
+ % (P. A. MacKay, 12 November, 1986)
+ %
+ \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+ \def\nstop{\vbox
+   {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+ \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+ \def\nsbot{\vbox
+   {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+ 
+ % Parse an argument, then pass it to #1.  The argument is the rest of
+ % the input line (except we remove a trailing comment).  #1 should be a
+ % macro which expects an ordinary undelimited TeX argument.
+ %
+ \def\parsearg#1{%
+   \let\next = #1%
+   \begingroup
+     \obeylines
+     \futurelet\temp\parseargx
+ }
+ 
+ % If the next token is an obeyed space (from an @example environment or
+ % the like), remove it and recurse.  Otherwise, we're done.
+ \def\parseargx{%
+   % \obeyedspace is defined far below, after the definition of \sepspaces.
+   \ifx\obeyedspace\temp
+     \expandafter\parseargdiscardspace
+   \else
+     \expandafter\parseargline
+   \fi
+ }
+ 
+ % Remove a single space (as the delimiter token to the macro call).
+ {\obeyspaces %
+  \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
+ 
+ {\obeylines %
+   \gdef\parseargline#1^^M{%
+     \endgroup % End of the group started in \parsearg.
+     %
+     % First remove any @c comment, then any @comment.
+     % Result of each macro is put in \toks0.
+     \argremovec #1\c\relax %
+     \expandafter\argremovecomment \the\toks0 \comment\relax %
+     %
+     % Call the caller's macro, saved as \next in \parsearg.
+     \expandafter\next\expandafter{\the\toks0}%
+   }%
+ }
+ 
+ % Since all \c{,omment} does is throw away the argument, we can let TeX
+ % do that for us.  The \relax here is matched by the \relax in the call
+ % in \parseargline; it could be more or less anything, its purpose is
+ % just to delimit the argument to the \c.
+ \def\argremovec#1\c#2\relax{\toks0 = {#1}}
+ \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+ 
+ % \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+ %    @end itemize  @c foo
+ % will have two active spaces as part of the argument with the
+ % `itemize'.  Here we remove all active spaces from #1, and assign the
+ % result to \toks0.
+ %
+ % This loses if there are any *other* active characters besides spaces
+ % in the argument -- _ ^ +, for example -- since they get expanded.
+ % Fortunately, Texinfo does not define any such commands.  (If it ever
+ % does, the catcode of the characters in questionwill have to be changed
+ % here.)  But this means we cannot call \removeactivespaces as part of
+ % \argremovec{,omment}, since @c uses \parsearg, and thus the argument
+ % that \parsearg gets might well have any character at all in it.
+ %
+ \def\removeactivespaces#1{%
+   \begingroup
+     \ignoreactivespaces
+     \edef\temp{#1}%
+     \global\toks0 = \expandafter{\temp}%
+   \endgroup
+ }
+ 
+ % Change the active space to expand to nothing.
+ %
+ \begingroup
+   \obeyspaces
+   \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
+ \endgroup
+ 
+ 
+ \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+ 
+ %% These are used to keep @begin/@end levels from running away
+ %% Call \inENV within environments (after a \begingroup)
+ \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+ \def\ENVcheck{%
+ \ifENV\errmessage{Still within an environment; press RETURN to continue}
+ \endgroup\fi} % This is not perfect, but it should reduce lossage
+ 
+ % @begin foo  is the same as @foo, for now.
+ \newhelp\EMsimple{Press RETURN to continue.}
+ 
+ \outer\def\begin{\parsearg\beginxxx}
+ 
+ \def\beginxxx #1{%
+ \expandafter\ifx\csname #1\endcsname\relax
+ {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
+ \csname #1\endcsname\fi}
+ 
+ % @end foo executes the definition of \Efoo.
+ %
+ \def\end{\parsearg\endxxx}
+ \def\endxxx #1{%
+   \removeactivespaces{#1}%
+   \edef\endthing{\the\toks0}%
+   %
+   \expandafter\ifx\csname E\endthing\endcsname\relax
+     \expandafter\ifx\csname \endthing\endcsname\relax
+       % There's no \foo, i.e., no ``environment'' foo.
+       \errhelp = \EMsimple
+       \errmessage{Undefined command `@end \endthing'}%
+     \else
+       \unmatchedenderror\endthing
+     \fi
+   \else
+     % Everything's ok; the right environment has been started.
+     \csname E\endthing\endcsname
+   \fi
+ }
+ 
+ % There is an environment #1, but it hasn't been started.  Give an error.
+ %
+ \def\unmatchedenderror#1{%
+   \errhelp = \EMsimple
+   \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+ }
+ 
+ % Define the control sequence \E#1 to give an unmatched @end error.
+ %
+ \def\defineunmatchedend#1{%
+   \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+ }
+ 
+ 
+ % Single-spacing is done by various environments (specifically, in
+ % \nonfillstart and \quotations).
+ \newskip\singlespaceskip \singlespaceskip = 12.5pt
+ \def\singlespace{%
+   % Why was this kern here?  It messes up equalizing space above and below
+   % environments.  --karl, 6may93
+   %{\advance \baselineskip by -\singlespaceskip
+   %\kern \baselineskip}%
+   \setleading \singlespaceskip
+ }
+ 
+ %% Simple single-character @ commands
+ 
+ % @@ prints an @
+ % Kludge this until the fonts are right (grr).
+ \def\@{{\tt\char64}}
+ 
+ % This is turned off because it was never documented
+ % and you can use @w{...} around a quote to suppress ligatures.
+ %% Define @` and @' to be the same as ` and '
+ %% but suppressing ligatures.
+ %\def\`{{`}}
+ %\def\'{{'}}
+ 
+ % Used to generate quoted braces.
+ \def\mylbrace {{\tt\char123}}
+ \def\myrbrace {{\tt\char125}}
+ \let\{=\mylbrace
+ \let\}=\myrbrace
+ \begingroup
+   % Definitions to produce actual \{ & \} command in an index.
+   \catcode`\{ = 12 \catcode`\} = 12
+   \catcode`\[ = 1 \catcode`\] = 2
+   \catcode`\@ = 0 \catcode`\\ = 12
+   @gdef at lbracecmd[\{]%
+   @gdef at rbracecmd[\}]%
+ @endgroup
+ 
+ % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+ % Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H.
+ \let\, = \c
+ \let\dotaccent = \.
+ \def\ringaccent#1{{\accent23 #1}}
+ \let\tieaccent = \t
+ \let\ubaraccent = \b
+ \let\udotaccent = \d
+ 
+ % Other special characters: @questiondown @exclamdown
+ % Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss.
+ \def\questiondown{?`}
+ \def\exclamdown{!`}
+ 
+ % Dotless i and dotless j, used for accents.
+ \def\imacro{i}
+ \def\jmacro{j}
+ \def\dotless#1{%
+   \def\temp{#1}%
+   \ifx\temp\imacro \ptexi
+   \else\ifx\temp\jmacro \j
+   \else \errmessage{@dotless can be used only with i or j}%
+   \fi\fi
+ }
+ 
+ % Be sure we're in horizontal mode when doing a tie, since we make space
+ % equivalent to this in @example-like environments. Otherwise, a space
+ % at the beginning of a line will start with \penalty -- and
+ % since \penalty is valid in vertical mode, we'd end up putting the
+ % penalty on the vertical list instead of in the new paragraph.
+ {\catcode`@ = 11
+  % Avoid using \@M directly, because that causes trouble
+  % if the definition is written into an index file.
+  \global\let\tiepenalty = \@M
+  \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+ }
+ 
+ % @: forces normal size whitespace following.
+ \def\:{\spacefactor=1000 }
+ 
+ % @* forces a line break.
+ \def\*{\hfil\break\hbox{}\ignorespaces}
+ 
+ % @. is an end-of-sentence period.
+ \def\.{.\spacefactor=3000 }
+ 
+ % @! is an end-of-sentence bang.
+ \def\!{!\spacefactor=3000 }
+ 
+ % @? is an end-of-sentence query.
+ \def\?{?\spacefactor=3000 }
+ 
+ % @w prevents a word break.  Without the \leavevmode, @w at the
+ % beginning of a paragraph, when TeX is still in vertical mode, would
+ % produce a whole line of output instead of starting the paragraph.
+ \def\w#1{\leavevmode\hbox{#1}}
+ 
+ % @group ... @end group forces ... to be all on one page, by enclosing
+ % it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+ % to keep its height that of a normal line.  According to the rules for
+ % \topskip (p.114 of the TeXbook), the glue inserted is
+ % max (\topskip - \ht (first item), 0).  If that height is large,
+ % therefore, no glue is inserted, and the space between the headline and
+ % the text is small, which looks bad.
+ %
+ \def\group{\begingroup
+   \ifnum\catcode13=\active \else
+     \errhelp = \groupinvalidhelp
+     \errmessage{@group invalid in context where filling is enabled}%
+   \fi
+   %
+   % The \vtop we start below produces a box with normal height and large
+   % depth; thus, TeX puts \baselineskip glue before it, and (when the
+   % next line of text is done) \lineskip glue after it.  (See p.82 of
+   % the TeXbook.)  Thus, space below is not quite equal to space
+   % above.  But it's pretty close.
+   \def\Egroup{%
+     \egroup           % End the \vtop.
+     \endgroup         % End the \group.
+   }%
+   %
+   \vtop\bgroup
+     % We have to put a strut on the last line in case the @group is in
+     % the midst of an example, rather than completely enclosing it.
+     % Otherwise, the interline space between the last line of the group
+     % and the first line afterwards is too small.  But we can't put the
+     % strut in \Egroup, since there it would be on a line by itself.
+     % Hence this just inserts a strut at the beginning of each line.
+     \everypar = {\strut}%
+     %
+     % Since we have a strut on every line, we don't need any of TeX's
+     % normal interline spacing.
+     \offinterlineskip
+     %
+     % OK, but now we have to do something about blank
+     % lines in the input in @example-like environments, which normally
+     % just turn into \lisppar, which will insert no space now that we've
+     % turned off the interline space.  Simplest is to make them be an
+     % empty paragraph.
+     \ifx\par\lisppar
+       \edef\par{\leavevmode \par}%
+       %
+       % Reset ^^M's definition to new definition of \par.
+       \obeylines
+     \fi
+     %
+     % Do @comment since we are called inside an environment such as
+     % @example, where each end-of-line in the input causes an
+     % end-of-line in the output.  We don't want the end-of-line after
+     % the `@group' to put extra space in the output.  Since @group
+     % should appear on a line by itself (according to the Texinfo
+     % manual), we don't worry about eating any user text.
+     \comment
+ }
+ %
+ % TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+ % message, so this ends up printing `@group can only ...'.
+ %
+ \newhelp\groupinvalidhelp{%
+ group can only be used in environments such as @example,^^J%
+ where each line of input produces a line of output.}
+ 
+ % @need space-in-mils
+ % forces a page break if there is not space-in-mils remaining.
+ 
+ \newdimen\mil  \mil=0.001in
+ 
+ \def\need{\parsearg\needx}
+ 
+ % Old definition--didn't work.
+ %\def\needx #1{\par %
+ %% This method tries to make TeX break the page naturally
+ %% if the depth of the box does not fit.
+ %{\baselineskip=0pt%
+ %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+ %\prevdepth=-1000pt
+ %}}
+ 
+ \def\needx#1{%
+   % Go into vertical mode, so we don't make a big box in the middle of a
+   % paragraph.
+   \par
+   %
+   % Don't add any leading before our big empty box, but allow a page
+   % break, since the best break might be right here.
+   \allowbreak
+   \nointerlineskip
+   \vtop to #1\mil{\vfil}%
+   %
+   % TeX does not even consider page breaks if a penalty added to the
+   % main vertical list is 10000 or more.  But in order to see if the
+   % empty box we just added fits on the page, we must make it consider
+   % page breaks.  On the other hand, we don't want to actually break the
+   % page after the empty box.  So we use a penalty of 9999.
+   %
+   % There is an extremely small chance that TeX will actually break the
+   % page at this \penalty, if there are no other feasible breakpoints in
+   % sight.  (If the user is using lots of big @group commands, which
+   % almost-but-not-quite fill up a page, TeX will have a hard time doing
+   % good page breaking, for example.)  However, I could not construct an
+   % example where a page broke at this \penalty; if it happens in a real
+   % document, then we can reconsider our strategy.
+   \penalty9999
+   %
+   % Back up by the size of the box, whether we did a page break or not.
+   \kern -#1\mil
+   %
+   % Do not allow a page break right after this kern.
+   \nobreak
+ }
+ 
+ % @br   forces paragraph break
+ 
+ \let\br = \par
+ 
+ % @dots{} output an ellipsis using the current font.
+ % We do .5em per period so that it has the same spacing in a typewriter
+ % font as three actual period characters.
+ %
+ \def\dots{%
+   \leavevmode
+   \hbox to 1.5em{%
+     \hskip 0pt plus 0.25fil minus 0.25fil
+     .\hss.\hss.%
+     \hskip 0pt plus 0.5fil minus 0.5fil
+   }%
+ }
+ 
+ % @enddots{} is an end-of-sentence ellipsis.
+ % 
+ \def\enddots{%
+   \leavevmode
+   \hbox to 2em{%
+     \hskip 0pt plus 0.25fil minus 0.25fil
+     .\hss.\hss.\hss.%
+     \hskip 0pt plus 0.5fil minus 0.5fil
+   }%
+   \spacefactor=3000
+ }
+ 
+ 
+ % @page    forces the start of a new page
+ %
+ \def\page{\par\vfill\supereject}
+ 
+ % @exdent text....
+ % outputs text on separate line in roman font, starting at standard page margin
+ 
+ % This records the amount of indent in the innermost environment.
+ % That's how much \exdent should take out.
+ \newskip\exdentamount
+ 
+ % This defn is used inside fill environments such as @defun.
+ \def\exdent{\parsearg\exdentyyy}
+ \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+ 
+ % This defn is used inside nofill environments such as @example.
+ \def\nofillexdent{\parsearg\nofillexdentyyy}
+ \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+ 
+ % @inmargin{TEXT} puts TEXT in the margin next to the current paragraph.
+ 
+ \def\inmargin#1{%
+ \strut\vadjust{\nobreak\kern-\strutdepth
+   \vtop to \strutdepth{\baselineskip\strutdepth\vss
+   \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}}
+ \newskip\inmarginspacing \inmarginspacing=1cm
+ \def\strutdepth{\dp\strutbox}
+ 
+ %\hbox{{\rm#1}}\hfil\break}}
+ 
+ % @include file    insert text of that file as input.
+ % Allow normal characters that  we make active in the argument (a file name).
+ \def\include{\begingroup
+   \catcode`\\=12
+   \catcode`~=12
+   \catcode`^=12
+   \catcode`_=12
+   \catcode`|=12
+   \catcode`<=12
+   \catcode`>=12
+   \catcode`+=12
+   \parsearg\includezzz}
+ % Restore active chars for included file.
+ \def\includezzz#1{\endgroup\begingroup
+   % Read the included file in a group so nested @include's work.
+   \def\thisfile{#1}%
+   \input\thisfile
+ \endgroup}
+ 
+ \def\thisfile{}
+ 
+ % @center line   outputs that line, centered
+ 
+ \def\center{\parsearg\centerzzz}
+ \def\centerzzz #1{{\advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \centerline{#1}}}
+ 
+ % @sp n   outputs n lines of vertical space
+ 
+ \def\sp{\parsearg\spxxx}
+ \def\spxxx #1{\vskip #1\baselineskip}
+ 
+ % @comment ...line which is ignored...
+ % @c is the same as @comment
+ % @ignore ... @end ignore  is another way to write a comment
+ 
+ \def\comment{\begingroup \catcode`\^^M=\other%
+ \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+ \commentxxx}
+ {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+ 
+ \let\c=\comment
+ 
+ % @paragraphindent  is defined for the Info formatting commands only.
+ \let\paragraphindent=\comment
+ 
+ % Prevent errors for section commands.
+ % Used in @ignore and in failing conditionals.
+ \def\ignoresections{%
+ \let\chapter=\relax
+ \let\unnumbered=\relax
+ \let\top=\relax
+ \let\unnumberedsec=\relax
+ \let\unnumberedsection=\relax
+ \let\unnumberedsubsec=\relax
+ \let\unnumberedsubsection=\relax
+ \let\unnumberedsubsubsec=\relax
+ \let\unnumberedsubsubsection=\relax
+ \let\section=\relax
+ \let\subsec=\relax
+ \let\subsubsec=\relax
+ \let\subsection=\relax
+ \let\subsubsection=\relax
+ \let\appendix=\relax
+ \let\appendixsec=\relax
+ \let\appendixsection=\relax
+ \let\appendixsubsec=\relax
+ \let\appendixsubsection=\relax
+ \let\appendixsubsubsec=\relax
+ \let\appendixsubsubsection=\relax
+ \let\contents=\relax
+ \let\smallbook=\relax
+ \let\titlepage=\relax
+ }
+ 
+ % Used in nested conditionals, where we have to parse the Texinfo source
+ % and so want to turn off most commands, in case they are used
+ % incorrectly.
+ %
+ \def\ignoremorecommands{%
+   \let\defcodeindex = \relax
+   \let\defcv = \relax
+   \let\deffn = \relax
+   \let\deffnx = \relax
+   \let\defindex = \relax
+   \let\defivar = \relax
+   \let\defmac = \relax
+   \let\defmethod = \relax
+   \let\defop = \relax
+   \let\defopt = \relax
+   \let\defspec = \relax
+   \let\deftp = \relax
+   \let\deftypefn = \relax
+   \let\deftypefun = \relax
+   \let\deftypevar = \relax
+   \let\deftypevr = \relax
+   \let\defun = \relax
+   \let\defvar = \relax
+   \let\defvr = \relax
+   \let\ref = \relax
+   \let\xref = \relax
+   \let\printindex = \relax
+   \let\pxref = \relax
+   \let\settitle = \relax
+   \let\setchapternewpage = \relax
+   \let\setchapterstyle = \relax
+   \let\everyheading = \relax
+   \let\evenheading = \relax
+   \let\oddheading = \relax
+   \let\everyfooting = \relax
+   \let\evenfooting = \relax
+   \let\oddfooting = \relax
+   \let\headings = \relax
+   \let\include = \relax
+   \let\lowersections = \relax
+   \let\down = \relax
+   \let\raisesections = \relax
+   \let\up = \relax
+   \let\set = \relax
+   \let\clear = \relax
+   \let\item = \relax
+ }
+ 
+ % Ignore @ignore ... @end ignore.
+ %
+ \def\ignore{\doignore{ignore}}
+ 
+ % Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text.
+ %
+ \def\ifinfo{\doignore{ifinfo}}
+ \def\ifhtml{\doignore{ifhtml}}
+ \def\ifnottex{\doignore{ifnottex}}
+ \def\html{\doignore{html}}
+ \def\menu{\doignore{menu}}
+ \def\direntry{\doignore{direntry}}
+ 
+ % @dircategory CATEGORY  -- specify a category of the dir file
+ % which this file should belong to.  Ignore this in TeX.
+ \let\dircategory = \comment
+ 
+ % Ignore text until a line `@end #1'.
+ %
+ \def\doignore#1{\begingroup
+   % Don't complain about control sequences we have declared \outer.
+   \ignoresections
+   %
+   % Define a command to swallow text until we reach `@end #1'.
+   % This @ is a catcode 12 token (that is the normal catcode of @ in
+   % this texinfo.tex file).  We change the catcode of @ below to match.
+   \long\def\doignoretext##1 at end #1{\enddoignore}%
+   %
+   % Make sure that spaces turn into tokens that match what \doignoretext wants.
+   \catcode32 = 10
+   %
+   % Ignore braces, too, so mismatched braces don't cause trouble.
+   \catcode`\{ = 9
+   \catcode`\} = 9
+   %
+   % We must not have @c interpreted as a control sequence.
+   \catcode`\@ = 12
+   %
+   % Make the letter c a comment character so that the rest of the line
+   % will be ignored. This way, the document can have (for example)
+   %   @c @end ifinfo
+   % and the @end ifinfo will be properly ignored.
+   % (We've just changed @ to catcode 12.)
+   \catcode`\c = 14
+   %
+   % And now expand that command.
+   \doignoretext
+ }
+ 
+ % What we do to finish off ignored text.
+ %
+ \def\enddoignore{\endgroup\ignorespaces}%
+ 
+ \newif\ifwarnedobs\warnedobsfalse
+ \def\obstexwarn{%
+   \ifwarnedobs\relax\else
+   % We need to warn folks that they may have trouble with TeX 3.0.
+   % This uses \immediate\write16 rather than \message to get newlines.
+     \immediate\write16{}
+     \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
+     \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
+     \immediate\write16{If you are running another version of TeX, relax.}
+     \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
+     \immediate\write16{  Then upgrade your TeX installation if you can.}
+     \immediate\write16{  (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)}
+     \immediate\write16{If you are stuck with version 3.0, run the}
+     \immediate\write16{  script ``tex3patch'' from the Texinfo distribution}
+     \immediate\write16{  to use a workaround.}
+     \immediate\write16{}
+     \global\warnedobstrue
+     \fi
+ }
+ 
+ % **In TeX 3.0, setting text in \nullfont hangs tex.  For a
+ % workaround (which requires the file ``dummy.tfm'' to be installed),
+ % uncomment the following line:
+ %%%%%\font\nullfont=dummy\let\obstexwarn=\relax
+ 
+ % Ignore text, except that we keep track of conditional commands for
+ % purposes of nesting, up to an `@end #1' command.
+ %
+ \def\nestedignore#1{%
+   \obstexwarn
+   % We must actually expand the ignored text to look for the @end
+   % command, so that nested ignore constructs work.  Thus, we put the
+   % text into a \vbox and then do nothing with the result.  To minimize
+   % the change of memory overflow, we follow the approach outlined on
+   % page 401 of the TeXbook: make the current font be a dummy font.
+   %
+   \setbox0 = \vbox\bgroup
+     % Don't complain about control sequences we have declared \outer.
+     \ignoresections
+     %
+     % Define `@end #1' to end the box, which will in turn undefine the
+     % @end command again.
+     \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
+     %
+     % We are going to be parsing Texinfo commands.  Most cause no
+     % trouble when they are used incorrectly, but some commands do
+     % complicated argument parsing or otherwise get confused, so we
+     % undefine them.
+     %
+     % We can't do anything about stray @-signs, unfortunately;
+     % they'll produce `undefined control sequence' errors.
+     \ignoremorecommands
+     %
+     % Set the current font to be \nullfont, a TeX primitive, and define
+     % all the font commands to also use \nullfont.  We don't use
+     % dummy.tfm, as suggested in the TeXbook, because not all sites
+     % might have that installed.  Therefore, math mode will still
+     % produce output, but that should be an extremely small amount of
+     % stuff compared to the main input.
+     %
+     \nullfont
+     \let\tenrm = \nullfont  \let\tenit = \nullfont  \let\tensl = \nullfont
+     \let\tenbf = \nullfont  \let\tentt = \nullfont  \let\smallcaps = \nullfont
+     \let\tensf = \nullfont
+     % Similarly for index fonts (mostly for their use in
+     % smallexample)
+     \let\indrm = \nullfont  \let\indit = \nullfont  \let\indsl = \nullfont
+     \let\indbf = \nullfont  \let\indtt = \nullfont  \let\indsc = \nullfont
+     \let\indsf = \nullfont
+     %
+     % Don't complain when characters are missing from the fonts.
+     \tracinglostchars = 0
+     %
+     % Don't bother to do space factor calculations.
+     \frenchspacing
+     %
+     % Don't report underfull hboxes.
+     \hbadness = 10000
+     %
+     % Do minimal line-breaking.
+     \pretolerance = 10000
+     %
+     % Do not execute instructions in @tex
+     \def\tex{\doignore{tex}}%
+     % Do not execute macro definitions.
+     % `c' is a comment character, so the word `macro' will get cut off.
+     \def\macro{\doignore{ma}}%
+ }
+ 
+ % @set VAR sets the variable VAR to an empty value.
+ % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+ %
+ % Since we want to separate VAR from REST-OF-LINE (which might be
+ % empty), we can't just use \parsearg; we have to insert a space of our
+ % own to delimit the rest of the line, and then take it out again if we
+ % didn't need it.  Make sure the catcode of space is correct to avoid
+ % losing inside @example, for instance.
+ %
+ \def\set{\begingroup\catcode` =10
+   \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
+   \parsearg\setxxx}
+ \def\setxxx#1{\setyyy#1 \endsetyyy}
+ \def\setyyy#1 #2\endsetyyy{%
+   \def\temp{#2}%
+   \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
+   \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
+   \fi
+   \endgroup
+ }
+ % Can't use \xdef to pre-expand #2 and save some time, since \temp or
+ % \next or other control sequences that we've defined might get us into
+ % an infinite loop. Consider `@set foo @cite{bar}'.
+ \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}}
+ 
+ % @clear VAR clears (i.e., unsets) the variable VAR.
+ %
+ \def\clear{\parsearg\clearxxx}
+ \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+ 
+ % @value{foo} gets the text saved in variable foo.
+ %
+ {
+   \catcode`\_ = \active
+   %
+   % We might end up with active _ or - characters in the argument if
+   % we're called from @code, as @code{@value{foo-bar_}}.  So \let any
+   % such active characters to their normal equivalents.
+   \gdef\value{\begingroup
+     \catcode`\-=12 \catcode`\_=12
+     \indexbreaks \let_\normalunderscore
+     \valuexxx}
+ }
+ \def\valuexxx#1{\expandablevalue{#1}\endgroup}
+ 
+ % We have this subroutine so that we can handle at least some @value's
+ % properly in indexes (we \let\value to this in \indexdummies).  Ones
+ % whose names contain - or _ still won't work, but we can't do anything
+ % about that.  The command has to be fully expandable, since the result
+ % winds up in the index file.  This means that if the variable's value
+ % contains other Texinfo commands, it's almost certain it will fail
+ % (although perhaps we could fix that with sufficient work to do a
+ % one-level expansion on the result, instead of complete).
+ % 
+ \def\expandablevalue#1{%
+   \expandafter\ifx\csname SET#1\endcsname\relax
+     {[No value for ``#1'']}%
+   \else
+     \csname SET#1\endcsname
+   \fi
+ }
+ 
+ % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+ % with @set.
+ %
+ \def\ifset{\parsearg\ifsetxxx}
+ \def\ifsetxxx #1{%
+   \expandafter\ifx\csname SET#1\endcsname\relax
+     \expandafter\ifsetfail
+   \else
+     \expandafter\ifsetsucceed
+   \fi
+ }
+ \def\ifsetsucceed{\conditionalsucceed{ifset}}
+ \def\ifsetfail{\nestedignore{ifset}}
+ \defineunmatchedend{ifset}
+ 
+ % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+ % defined with @set, or has been undefined with @clear.
+ %
+ \def\ifclear{\parsearg\ifclearxxx}
+ \def\ifclearxxx #1{%
+   \expandafter\ifx\csname SET#1\endcsname\relax
+     \expandafter\ifclearsucceed
+   \else
+     \expandafter\ifclearfail
+   \fi
+ }
+ \def\ifclearsucceed{\conditionalsucceed{ifclear}}
+ \def\ifclearfail{\nestedignore{ifclear}}
+ \defineunmatchedend{ifclear}
+ 
+ % @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text
+ % following, through the first @end iftex (etc.).  Make `@end iftex'
+ % (etc.) valid only after an @iftex.
+ %
+ \def\iftex{\conditionalsucceed{iftex}}
+ \def\ifnothtml{\conditionalsucceed{ifnothtml}}
+ \def\ifnotinfo{\conditionalsucceed{ifnotinfo}}
+ \defineunmatchedend{iftex}
+ \defineunmatchedend{ifnothtml}
+ \defineunmatchedend{ifnotinfo}
+ 
+ % We can't just want to start a group at @iftex (for example) and end it
+ % at @end iftex, since then @set commands inside the conditional have no
+ % effect (they'd get reverted at the end of the group).  So we must
+ % define \Eiftex to redefine itself to be its previous value.  (We can't
+ % just define it to fail again with an ``unmatched end'' error, since
+ % the @ifset might be nested.)
+ %
+ \def\conditionalsucceed#1{%
+   \edef\temp{%
+     % Remember the current value of \E#1.
+     \let\nece{prevE#1} = \nece{E#1}%
+     %
+     % At the `@end #1', redefine \E#1 to be its previous value.
+     \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
+   }%
+   \temp
+ }
+ 
+ % We need to expand lots of \csname's, but we don't want to expand the
+ % control sequences after we've constructed them.
+ %
+ \def\nece#1{\expandafter\noexpand\csname#1\endcsname}
+ 
+ % @asis just yields its argument.  Used with @table, for example.
+ %
+ \def\asis#1{#1}
+ 
+ % @math means output in math mode.
+ % We don't use $'s directly in the definition of \math because control
+ % sequences like \math are expanded when the toc file is written.  Then,
+ % we read the toc file back, the $'s will be normal characters (as they
+ % should be, according to the definition of Texinfo).  So we must use a
+ % control sequence to switch into and out of math mode.
+ %
+ % This isn't quite enough for @math to work properly in indices, but it
+ % seems unlikely it will ever be needed there.
+ %
+ \let\implicitmath = $
+ \def\math#1{\implicitmath #1\implicitmath}
+ 
+ % @bullet and @minus need the same treatment as @math, just above.
+ \def\bullet{\implicitmath\ptexbullet\implicitmath}
+ \def\minus{\implicitmath-\implicitmath}
+ 
+ % @refill is a no-op.
+ \let\refill=\relax
+ 
+ % If working on a large document in chapters, it is convenient to
+ % be able to disable indexing, cross-referencing, and contents, for test runs.
+ % This is done with @novalidate (before @setfilename).
+ %
+ \newif\iflinks \linkstrue % by default we want the aux files.
+ \let\novalidate = \linksfalse
+ 
+ % @setfilename is done at the beginning of every texinfo file.
+ % So open here the files we need to have open while reading the input.
+ % This makes it possible to make a .fmt file for texinfo.
+ \def\setfilename{%
+    \iflinks 
+      \readauxfile
+    \fi % \openindices needs to do some work in any case.
+    \openindices
+    \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+    \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+    %
+    % If texinfo.cnf is present on the system, read it.
+    % Useful for site-wide @afourpaper, etc.
+    % Just to be on the safe side, close the input stream before the \input.
+    \openin 1 texinfo.cnf
+    \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi
+    \closein1
+    \temp
+    %
+    \comment % Ignore the actual filename.
+ }
+ 
+ % Called from \setfilename.
+ % 
+ \def\openindices{%
+   \newindex{cp}%
+   \newcodeindex{fn}%
+   \newcodeindex{vr}%
+   \newcodeindex{tp}%
+   \newcodeindex{ky}%
+   \newcodeindex{pg}%
+ }
+ 
+ % @bye.
+ \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+ 
+ 
+ \message{fonts,}
+ % Font-change commands.
+ 
+ % Texinfo sort of supports the sans serif font style, which plain TeX does not.
+ % So we set up a \sf analogous to plain's \rm, etc.
+ \newfam\sffam
+ \def\sf{\fam=\sffam \tensf}
+ \let\li = \sf % Sometimes we call it \li, not \sf.
+ 
+ % We don't need math for this one.
+ \def\ttsl{\tenttsl}
+ 
+ % Use Computer Modern fonts at \magstephalf (11pt).
+ \newcount\mainmagstep
+ \mainmagstep=\magstephalf
+ 
+ % Set the font macro #1 to the font named #2, adding on the
+ % specified font prefix (normally `cm').
+ % #3 is the font's design size, #4 is a scale factor
+ \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+ 
+ % Use cm as the default font prefix.
+ % To specify the font prefix, you must define \fontprefix
+ % before you read in texinfo.tex.
+ \ifx\fontprefix\undefined
+ \def\fontprefix{cm}
+ \fi
+ % Support font families that don't use the same naming scheme as CM.
+ \def\rmshape{r}
+ \def\rmbshape{bx}               %where the normal face is bold
+ \def\bfshape{b}
+ \def\bxshape{bx}
+ \def\ttshape{tt}
+ \def\ttbshape{tt}
+ \def\ttslshape{sltt}
+ \def\itshape{ti}
+ \def\itbshape{bxti}
+ \def\slshape{sl}
+ \def\slbshape{bxsl}
+ \def\sfshape{ss}
+ \def\sfbshape{ss}
+ \def\scshape{csc}
+ \def\scbshape{csc}
+ 
+ \ifx\bigger\relax
+ \let\mainmagstep=\magstep1
+ \setfont\textrm\rmshape{12}{1000}
+ \setfont\texttt\ttshape{12}{1000}
+ \else
+ \setfont\textrm\rmshape{10}{\mainmagstep}
+ \setfont\texttt\ttshape{10}{\mainmagstep}
+ \fi
+ % Instead of cmb10, you many want to use cmbx10.
+ % cmbx10 is a prettier font on its own, but cmb10
+ % looks better when embedded in a line with cmr10.
+ \setfont\textbf\bfshape{10}{\mainmagstep}
+ \setfont\textit\itshape{10}{\mainmagstep}
+ \setfont\textsl\slshape{10}{\mainmagstep}
+ \setfont\textsf\sfshape{10}{\mainmagstep}
+ \setfont\textsc\scshape{10}{\mainmagstep}
+ \setfont\textttsl\ttslshape{10}{\mainmagstep}
+ \font\texti=cmmi10 scaled \mainmagstep
+ \font\textsy=cmsy10 scaled \mainmagstep
+ 
+ % A few fonts for @defun, etc.
+ \setfont\defbf\bxshape{10}{\magstep1} %was 1314
+ \setfont\deftt\ttshape{10}{\magstep1}
+ \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+ 
+ % Fonts for indices and small examples (9pt).
+ % We actually use the slanted font rather than the italic,
+ % because texinfo normally uses the slanted fonts for that.
+ % Do not make many font distinctions in general in the index, since they
+ % aren't very useful.
+ \setfont\ninett\ttshape{9}{1000}
+ \setfont\ninettsl\ttslshape{10}{900}
+ \setfont\indrm\rmshape{9}{1000}
+ \setfont\indit\itshape{9}{1000}
+ \setfont\indsl\slshape{9}{1000}
+ \let\indtt=\ninett
+ \let\indttsl=\ninettsl
+ \let\indsf=\indrm
+ \let\indbf=\indrm
+ \setfont\indsc\scshape{10}{900}
+ \font\indi=cmmi9
+ \font\indsy=cmsy9
+ 
+ % Fonts for title page:
+ \setfont\titlerm\rmbshape{12}{\magstep3}
+ \setfont\titleit\itbshape{10}{\magstep4}
+ \setfont\titlesl\slbshape{10}{\magstep4}
+ \setfont\titlett\ttbshape{12}{\magstep3}
+ \setfont\titlettsl\ttslshape{10}{\magstep4}
+ \setfont\titlesf\sfbshape{17}{\magstep1}
+ \let\titlebf=\titlerm
+ \setfont\titlesc\scbshape{10}{\magstep4}
+ \font\titlei=cmmi12 scaled \magstep3
+ \font\titlesy=cmsy10 scaled \magstep4
+ \def\authorrm{\secrm}
+ 
+ % Chapter (and unnumbered) fonts (17.28pt).
+ \setfont\chaprm\rmbshape{12}{\magstep2}
+ \setfont\chapit\itbshape{10}{\magstep3}
+ \setfont\chapsl\slbshape{10}{\magstep3}
+ \setfont\chaptt\ttbshape{12}{\magstep2}
+ \setfont\chapttsl\ttslshape{10}{\magstep3}
+ \setfont\chapsf\sfbshape{17}{1000}
+ \let\chapbf=\chaprm
+ \setfont\chapsc\scbshape{10}{\magstep3}
+ \font\chapi=cmmi12 scaled \magstep2
+ \font\chapsy=cmsy10 scaled \magstep3
+ 
+ % Section fonts (14.4pt).
+ \setfont\secrm\rmbshape{12}{\magstep1}
+ \setfont\secit\itbshape{10}{\magstep2}
+ \setfont\secsl\slbshape{10}{\magstep2}
+ \setfont\sectt\ttbshape{12}{\magstep1}
+ \setfont\secttsl\ttslshape{10}{\magstep2}
+ \setfont\secsf\sfbshape{12}{\magstep1}
+ \let\secbf\secrm
+ \setfont\secsc\scbshape{10}{\magstep2}
+ \font\seci=cmmi12 scaled \magstep1
+ \font\secsy=cmsy10 scaled \magstep2
+ 
+ % \setfont\ssecrm\bxshape{10}{\magstep1}    % This size an font looked bad.
+ % \setfont\ssecit\itshape{10}{\magstep1}    % The letters were too crowded.
+ % \setfont\ssecsl\slshape{10}{\magstep1}
+ % \setfont\ssectt\ttshape{10}{\magstep1}
+ % \setfont\ssecsf\sfshape{10}{\magstep1}
+ 
+ %\setfont\ssecrm\bfshape{10}{1315}      % Note the use of cmb rather than cmbx.
+ %\setfont\ssecit\itshape{10}{1315}      % Also, the size is a little larger than
+ %\setfont\ssecsl\slshape{10}{1315}      % being scaled magstep1.
+ %\setfont\ssectt\ttshape{10}{1315}
+ %\setfont\ssecsf\sfshape{10}{1315}
+ 
+ %\let\ssecbf=\ssecrm
+ 
+ % Subsection fonts (13.15pt).
+ \setfont\ssecrm\rmbshape{12}{\magstephalf}
+ \setfont\ssecit\itbshape{10}{1315}
+ \setfont\ssecsl\slbshape{10}{1315}
+ \setfont\ssectt\ttbshape{12}{\magstephalf}
+ \setfont\ssecttsl\ttslshape{10}{1315}
+ \setfont\ssecsf\sfbshape{12}{\magstephalf}
+ \let\ssecbf\ssecrm
+ \setfont\ssecsc\scbshape{10}{\magstep1}
+ \font\sseci=cmmi12 scaled \magstephalf
+ \font\ssecsy=cmsy10 scaled 1315
+ % The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+ % but that is not a standard magnification.
+ 
+ % In order for the font changes to affect most math symbols and letters,
+ % we have to define the \textfont of the standard families.  Since
+ % texinfo doesn't allow for producing subscripts and superscripts, we
+ % don't bother to reset \scriptfont and \scriptscriptfont (which would
+ % also require loading a lot more fonts).
+ %
+ \def\resetmathfonts{%
+   \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
+   \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
+   \textfont\ttfam = \tentt \textfont\sffam = \tensf
+ }
+ 
+ 
+ % The font-changing commands redefine the meanings of \tenSTYLE, instead
+ % of just \STYLE.  We do this so that font changes will continue to work
+ % in math mode, where it is the current \fam that is relevant in most
+ % cases, not the current font.  Plain TeX does \def\bf{\fam=\bffam
+ % \tenbf}, for example.  By redefining \tenbf, we obviate the need to
+ % redefine \bf itself.
+ \def\textfonts{%
+   \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+   \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+   \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
+   \resetmathfonts}
+ \def\titlefonts{%
+   \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+   \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+   \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+   \let\tenttsl=\titlettsl
+   \resetmathfonts \setleading{25pt}}
+ \def\titlefont#1{{\titlefonts\rm #1}}
+ \def\chapfonts{%
+   \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+   \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+   \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+   \resetmathfonts \setleading{19pt}}
+ \def\secfonts{%
+   \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+   \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+   \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+   \resetmathfonts \setleading{16pt}}
+ \def\subsecfonts{%
+   \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+   \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+   \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+   \resetmathfonts \setleading{15pt}}
+ \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
+ \def\indexfonts{%
+   \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
+   \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
+   \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl
+   \resetmathfonts \setleading{12pt}}
+ 
+ % Set up the default fonts, so we can use them for creating boxes.
+ %
+ \textfonts
+ 
+ % Define these so they can be easily changed for other fonts.
+ \def\angleleft{$\langle$}
+ \def\angleright{$\rangle$}
+ 
+ % Count depth in font-changes, for error checks
+ \newcount\fontdepth \fontdepth=0
+ 
+ % Fonts for short table of contents.
+ \setfont\shortcontrm\rmshape{12}{1000}
+ \setfont\shortcontbf\bxshape{12}{1000}
+ \setfont\shortcontsl\slshape{12}{1000}
+ 
+ %% Add scribe-like font environments, plus @l for inline lisp (usually sans
+ %% serif) and @ii for TeX italic
+ 
+ % \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+ % unless the following character is such as not to need one.
+ \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
+ \def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx}
+ \def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx}
+ 
+ \let\i=\smartitalic
+ \let\var=\smartslanted
+ \let\dfn=\smartslanted
+ \let\emph=\smartitalic
+ \let\cite=\smartslanted
+ 
+ \def\b#1{{\bf #1}}
+ \let\strong=\b
+ 
+ % We can't just use \exhyphenpenalty, because that only has effect at
+ % the end of a paragraph.  Restore normal hyphenation at the end of the
+ % group within which \nohyphenation is presumably called.
+ %
+ \def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+ \def\restorehyphenation{\hyphenchar\font = `- }
+ 
+ \def\t#1{%
+   {\tt \rawbackslash \frenchspacing #1}%
+   \null
+ }
+ \let\ttfont=\t
+ \def\samp#1{`\tclose{#1}'\null}
+ \setfont\smallrm\rmshape{8}{1000}
+ \font\smallsy=cmsy9
+ \def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{%
+   \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+     \vbox{\hrule\kern-0.4pt
+      \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+     \kern-0.4pt\hrule}%
+   \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+ % The old definition, with no lozenge:
+ %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+ \def\ctrl #1{{\tt \rawbackslash \hat}#1}
+ 
+ % @file, @option are the same as @samp.
+ \let\file=\samp
+ \let\option=\samp
+ 
+ % @code is a modification of @t,
+ % which makes spaces the same size as normal in the surrounding text.
+ \def\tclose#1{%
+   {%
+     % Change normal interword space to be same as for the current font.
+     \spaceskip = \fontdimen2\font
+     %
+     % Switch to typewriter.
+     \tt
+     %
+     % But `\ ' produces the large typewriter interword space.
+     \def\ {{\spaceskip = 0pt{} }}%
+     %
+     % Turn off hyphenation.
+     \nohyphenation
+     %
+     \rawbackslash
+     \frenchspacing
+     #1%
+   }%
+   \null
+ }
+ 
+ % We *must* turn on hyphenation at `-' and `_' in \code.
+ % Otherwise, it is too hard to avoid overfull hboxes
+ % in the Emacs manual, the Library manual, etc.
+ 
+ % Unfortunately, TeX uses one parameter (\hyphenchar) to control
+ % both hyphenation at - and hyphenation within words.
+ % We must therefore turn them both off (\tclose does that)
+ % and arrange explicitly to hyphenate at a dash.
+ %  -- rms.
+ {
+   \catcode`\-=\active
+   \catcode`\_=\active
+   %
+   \global\def\code{\begingroup
+     \catcode`\-=\active \let-\codedash
+     \catcode`\_=\active \let_\codeunder
+     \codex
+   }
+   %
+   % If we end up with any active - characters when handling the index,
+   % just treat them as a normal -.
+   \global\def\indexbreaks{\catcode`\-=\active \let-\realdash}
+ }
+ 
+ \def\realdash{-}
+ \def\codedash{-\discretionary{}{}{}}
+ \def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}}
+ \def\codex #1{\tclose{#1}\endgroup}
+ 
+ %\let\exp=\tclose  %Was temporary
+ 
+ % @kbd is like @code, except that if the argument is just one @key command,
+ % then @kbd has no effect.
+ 
+ % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+ %   `example' (@kbd uses ttsl only inside of @example and friends),
+ %   or `code' (@kbd uses normal tty font always).
+ \def\kbdinputstyle{\parsearg\kbdinputstylexxx}
+ \def\kbdinputstylexxx#1{%
+   \def\arg{#1}%
+   \ifx\arg\worddistinct
+     \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+   \else\ifx\arg\wordexample
+     \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+   \else\ifx\arg\wordcode
+     \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+   \fi\fi\fi
+ }
+ \def\worddistinct{distinct}
+ \def\wordexample{example}
+ \def\wordcode{code}
+ 
+ % Default is kbdinputdistinct.  (Too much of a hassle to call the macro,
+ % the catcodes are wrong for parsearg to work.)
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}
+ 
+ \def\xkey{\key}
+ \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\look}}\fi
+ \else{\tclose{\kbdfont\look}}\fi}
+ 
+ % For @url, @env, @command quotes seem unnecessary, so use \code.
+ \let\url=\code
+ \let\env=\code
+ \let\command=\code
+ 
+ % @uref (abbreviation for `urlref') takes an optional second argument
+ % specifying the text to display.  First (mandatory) arg is the url.
+ % Perhaps eventually put in a hypertex \special here.
+ % 
+ \def\uref#1{\urefxxx #1,,\finish}
+ \def\urefxxx#1,#2,#3\finish{%
+   \setbox0 = \hbox{\ignorespaces #2}%
+   \ifdim\wd0 > 0pt
+     \unhbox0\ (\code{#1})%
+   \else
+     \code{#1}%
+   \fi
+ }
+ 
+ % rms does not like the angle brackets --karl, 17may97.
+ % So now @email is just like @uref.
+ %\def\email#1{\angleleft{\tt #1}\angleright}
+ \let\email=\uref
+ 
+ % Check if we are currently using a typewriter font.  Since all the
+ % Computer Modern typewriter fonts have zero interword stretch (and
+ % shrink), and it is reasonable to expect all typewriter fonts to have
+ % this property, we can check that font parameter.
+ %
+ \def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+ 
+ % Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+ % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+ %
+ \def\dmn#1{\thinspace #1}
+ 
+ \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+ 
+ % @l was never documented to mean ``switch to the Lisp font'',
+ % and it is not used as such in any manual I can find.  We need it for
+ % Polish suppressed-l.  --karl, 22sep96.
+ %\def\l#1{{\li #1}\null}
+ 
+ % Explicit font changes: @r, @sc, undocumented @ii.
+ \def\r#1{{\rm #1}}              % roman font
+ \def\sc#1{{\smallcaps#1}}       % smallcaps font
+ \def\ii#1{{\it #1}}             % italic font
+ 
+ % @acronym downcases the argument and prints in smallcaps.
+ \def\acronym#1{{\smallcaps \lowercase{#1}}}
+ 
+ % @pounds{} is a sterling sign.
+ \def\pounds{{\it\$}}
+ 
+ 
+ \message{page headings,}
+ 
+ \newskip\titlepagetopglue \titlepagetopglue = 1.5in
+ \newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+ 
+ % First the title page.  Must do @settitle before @titlepage.
+ \newif\ifseenauthor
+ \newif\iffinishedtitlepage
+ 
+ % Do an implicit @contents or @shortcontents after @end titlepage if the
+ % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+ % 
+ \newif\ifsetcontentsaftertitlepage
+  \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+ \newif\ifsetshortcontentsaftertitlepage
+  \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+ 
+ \def\shorttitlepage{\parsearg\shorttitlepagezzz}
+ \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+         \endgroup\page\hbox{}\page}
+ 
+ \def\titlepage{\begingroup \parindent=0pt \textfonts
+    \let\subtitlerm=\tenrm
+    \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
+    %
+    \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
+    %
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    %
+    % Now you can print the title using @title.
+    \def\title{\parsearg\titlezzz}%
+    \def\titlezzz##1{\leftline{\titlefonts\rm ##1}
+                     % print a rule at the page bottom also.
+                     \finishedtitlepagefalse
+                     \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Now you can put text using @subtitle.
+    \def\subtitle{\parsearg\subtitlezzz}%
+    \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
+    %
+    % @author should come last, but may come many times.
+    \def\author{\parsearg\authorzzz}%
+    \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+       {\authorfont \leftline{##1}}}%
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+       \iffinishedtitlepage\else
+          \finishtitlepage
+       \fi
+       \oldpage
+       \let\page = \oldpage
+       \hbox{}}%
+ %   \def\page{\oldpage \hbox{}}
+ }
+ 
+ \def\Etitlepage{%
+    \iffinishedtitlepage\else
+       \finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+    \endgroup
+    %
+    % If they want short, they certainly want long too.
+    \ifsetshortcontentsaftertitlepage
+      \shortcontents
+      \contents
+      \global\let\shortcontents = \relax
+      \global\let\contents = \relax
+    \fi
+    %
+    \ifsetcontentsaftertitlepage
+      \contents
+      \global\let\contents = \relax
+      \global\let\shortcontents = \relax
+    \fi
+    %
+    \HEADINGSon
+ }
+ 
+ \def\finishtitlepage{%
+    \vskip4pt \hrule height 2pt width \hsize
+    \vskip\titlepagebottomglue
+    \finishedtitlepagetrue
+ }
+ 
+ %%% Set up page headings and footings.
+ 
+ \let\thispage=\folio
+ 
+ \newtoks\evenheadline    % headline on even pages
+ \newtoks\oddheadline     % headline on odd pages
+ \newtoks\evenfootline    % footline on even pages
+ \newtoks\oddfootline     % footline on odd pages
+ 
+ % Now make Tex use those variables
+ \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                             \else \the\evenheadline \fi}}
+ \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                             \else \the\evenfootline \fi}\HEADINGShook}
+ \let\HEADINGShook=\relax
+ 
+ % Commands to set those variables.
+ % For example, this is what  @headings on  does
+ % @evenheading @thistitle|@thispage|@thischapter
+ % @oddheading @thischapter|@thispage|@thistitle
+ % @evenfooting @thisfile||
+ % @oddfooting ||@thisfile
+ 
+ \def\evenheading{\parsearg\evenheadingxxx}
+ \def\oddheading{\parsearg\oddheadingxxx}
+ \def\everyheading{\parsearg\everyheadingxxx}
+ 
+ \def\evenfooting{\parsearg\evenfootingxxx}
+ \def\oddfooting{\parsearg\oddfootingxxx}
+ \def\everyfooting{\parsearg\everyfootingxxx}
+ 
+ {\catcode`\@=0 %
+ 
+ \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
+ \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+ \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+ 
+ \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
+ \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+ \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+ 
+ \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+ 
+ \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
+ \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+ \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+ 
+ \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
+ \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+   \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+   %
+   % Leave some space for the footline.  Hopefully ok to assume
+   % @evenfooting will not be used by itself.
+   \global\advance\pageheight by -\baselineskip
+   \global\advance\vsize by -\baselineskip
+ }
+ 
+ \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+ %
+ }% unbind the catcode of @.
+ 
+ % @headings double      turns headings on for double-sided printing.
+ % @headings single      turns headings on for single-sided printing.
+ % @headings off         turns them off.
+ % @headings on          same as @headings double, retained for compatibility.
+ % @headings after       turns on double-sided headings after this page.
+ % @headings doubleafter turns on double-sided headings after this page.
+ % @headings singleafter turns on single-sided headings after this page.
+ % By default, they are off at the start of a document,
+ % and turned `on' after @end titlepage.
+ 
+ \def\headings #1 {\csname HEADINGS#1\endcsname}
+ 
+ \def\HEADINGSoff{
+ \global\evenheadline={\hfil} \global\evenfootline={\hfil}
+ \global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+ \HEADINGSoff
+ % When we turn headings on, set the page number to 1.
+ % For double-sided printing, put current file name in lower left corner,
+ % chapter name on inside top of right hand pages, document
+ % title on inside top of left hand pages, and page numbers on outside top
+ % edge of all pages.
+ \def\HEADINGSdouble{
+ \global\pageno=1
+ \global\evenfootline={\hfil}
+ \global\oddfootline={\hfil}
+ \global\evenheadline={\line{\folio\hfil\thistitle}}
+ \global\oddheadline={\line{\thischapter\hfil\folio}}
+ \global\let\contentsalignmacro = \chapoddpage
+ }
+ \let\contentsalignmacro = \chappager
+ 
+ % For single-sided printing, chapter title goes across top left of page,
+ % page number on top right.
+ \def\HEADINGSsingle{
+ \global\pageno=1
+ \global\evenfootline={\hfil}
+ \global\oddfootline={\hfil}
+ \global\evenheadline={\line{\thischapter\hfil\folio}}
+ \global\oddheadline={\line{\thischapter\hfil\folio}}
+ \global\let\contentsalignmacro = \chappager
+ }
+ \def\HEADINGSon{\HEADINGSdouble}
+ 
+ \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+ \let\HEADINGSdoubleafter=\HEADINGSafter
+ \def\HEADINGSdoublex{%
+ \global\evenfootline={\hfil}
+ \global\oddfootline={\hfil}
+ \global\evenheadline={\line{\folio\hfil\thistitle}}
+ \global\oddheadline={\line{\thischapter\hfil\folio}}
+ \global\let\contentsalignmacro = \chapoddpage
+ }
+ 
+ \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+ \def\HEADINGSsinglex{%
+ \global\evenfootline={\hfil}
+ \global\oddfootline={\hfil}
+ \global\evenheadline={\line{\thischapter\hfil\folio}}
+ \global\oddheadline={\line{\thischapter\hfil\folio}}
+ \global\let\contentsalignmacro = \chappager
+ }
+ 
+ % Subroutines used in generating headings
+ % Produces Day Month Year style of output.
+ \def\today{\number\day\space
+ \ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\year}
+ 
+ % Use this if you want the Month Day, Year style of output.
+ %\def\today{\ifcase\month\or
+ %January\or February\or March\or April\or May\or June\or
+ %July\or August\or September\or October\or November\or December\fi
+ %\space\number\day, \number\year}
+ 
+ % @settitle line...  specifies the title of the document, for headings
+ % It generates no output of its own
+ 
+ \def\thistitle{No Title}
+ \def\settitle{\parsearg\settitlezzz}
+ \def\settitlezzz #1{\gdef\thistitle{#1}}
+ 
+ 
+ \message{tables,}
+ % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+ 
+ % default indentation of table text
+ \newdimen\tableindent \tableindent=.8in
+ % default indentation of @itemize and @enumerate text
+ \newdimen\itemindent  \itemindent=.3in
+ % margin between end of table item and start of table text.
+ \newdimen\itemmargin  \itemmargin=.1in
+ 
+ % used internally for \itemindent minus \itemmargin
+ \newdimen\itemmax
+ 
+ % Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+ % these defs.
+ % They also define \itemindex
+ % to index the item name in whatever manner is desired (perhaps none).
+ 
+ \newif\ifitemxneedsnegativevskip
+ 
+ \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+ 
+ \def\internalBitem{\smallbreak \parsearg\itemzzz}
+ \def\internalBitemx{\itemxpar \parsearg\itemzzz}
+ 
+ \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
+ \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
+ 
+ \def\internalBkitem{\smallbreak \parsearg\kitemzzz}
+ \def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
+ 
+ \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
+                  \itemzzz {#1}}
+ 
+ \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
+                  \itemzzz {#1}}
+ 
+ \def\itemzzz #1{\begingroup %
+   \advance\hsize by -\rightskip
+   \advance\hsize by -\tableindent
+   \setbox0=\hbox{\itemfont{#1}}%
+   \itemindex{#1}%
+   \nobreak % This prevents a break before @itemx.
+   %
+   % If the item text does not fit in the space we have, put it on a line
+   % by itself, and do not allow a page break either before or after that
+   % line.  We do not start a paragraph here because then if the next
+   % command is, e.g., @kindex, the whatsit would get put into the
+   % horizontal list on a line by itself, resulting in extra blank space.
+   \ifdim \wd0>\itemmax
+     %
+     % Make this a paragraph so we get the \parskip glue and wrapping,
+     % but leave it ragged-right.
+     \begingroup
+       \advance\leftskip by-\tableindent
+       \advance\hsize by\tableindent
+       \advance\rightskip by0pt plus1fil
+       \leavevmode\unhbox0\par
+     \endgroup
+     %
+     % We're going to be starting a paragraph, but we don't want the
+     % \parskip glue -- logically it's part of the @item we just started.
+     \nobreak \vskip-\parskip
+     %
+     % Stop a page break at the \parskip glue coming up.  Unfortunately
+     % we can't prevent a possible page break at the following
+     % \baselineskip glue.
+     \nobreak
+     \endgroup
+     \itemxneedsnegativevskipfalse
+   \else
+     % The item text fits into the space.  Start a paragraph, so that the
+     % following text (if any) will end up on the same line.  
+     \noindent
+     % Do this with kerns and \unhbox so that if there is a footnote in
+     % the item text, it can migrate to the main vertical list and
+     % eventually be printed.
+     \nobreak\kern-\tableindent
+     \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+     \unhbox0
+     \nobreak\kern\dimen0
+     \endgroup
+     \itemxneedsnegativevskiptrue
+   \fi
+ }
+ 
+ \def\item{\errmessage{@item while not in a table}}
+ \def\itemx{\errmessage{@itemx while not in a table}}
+ \def\kitem{\errmessage{@kitem while not in a table}}
+ \def\kitemx{\errmessage{@kitemx while not in a table}}
+ \def\xitem{\errmessage{@xitem while not in a table}}
+ \def\xitemx{\errmessage{@xitemx while not in a table}}
+ 
+ % Contains a kludge to get @end[description] to work.
+ \def\description{\tablez{\dontindex}{1}{}{}{}{}}
+ 
+ % @table, @ftable, @vtable.
+ \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
+ {\obeylines\obeyspaces%
+ \gdef\tablex #1^^M{%
+ \tabley\dontindex#1        \endtabley}}
+ 
+ \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
+ {\obeylines\obeyspaces%
+ \gdef\ftablex #1^^M{%
+ \tabley\fnitemindex#1        \endtabley
+ \def\Eftable{\endgraf\afterenvbreak\endgroup}%
+ \let\Etable=\relax}}
+ 
+ \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
+ {\obeylines\obeyspaces%
+ \gdef\vtablex #1^^M{%
+ \tabley\vritemindex#1        \endtabley
+ \def\Evtable{\endgraf\afterenvbreak\endgroup}%
+ \let\Etable=\relax}}
+ 
+ \def\dontindex #1{}
+ \def\fnitemindex #1{\doind {fn}{\code{#1}}}%
+ \def\vritemindex #1{\doind {vr}{\code{#1}}}%
+ 
+ {\obeyspaces %
+ \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
+ \tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
+ 
+ \def\tablez #1#2#3#4#5#6{%
+ \aboveenvbreak %
+ \begingroup %
+ \def\Edescription{\Etable}% Necessary kludge.
+ \let\itemindex=#1%
+ \ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
+ \ifnum 0#4>0 \tableindent=#4\mil \fi %
+ \ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
+ \def\itemfont{#2}%
+ \itemmax=\tableindent %
+ \advance \itemmax by -\itemmargin %
+ \advance \leftskip by \tableindent %
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi%
+ \def\Etable{\endgraf\afterenvbreak\endgroup}%
+ \let\item = \internalBitem %
+ \let\itemx = \internalBitemx %
+ \let\kitem = \internalBkitem %
+ \let\kitemx = \internalBkitemx %
+ \let\xitem = \internalBxitem %
+ \let\xitemx = \internalBxitemx %
+ }
+ 
+ % This is the counter used by @enumerate, which is really @itemize
+ 
+ \newcount \itemno
+ 
+ \def\itemize{\parsearg\itemizezzz}
+ 
+ \def\itemizezzz #1{%
+   \begingroup % ended by the @end itemize
+   \itemizey {#1}{\Eitemize}
+ }
+ 
+ \def\itemizey #1#2{%
+ \aboveenvbreak %
+ \itemmax=\itemindent %
+ \advance \itemmax by -\itemmargin %
+ \advance \leftskip by \itemindent %
+ \exdentamount=\itemindent
+ \parindent = 0pt %
+ \parskip = \smallskipamount %
+ \ifdim \parskip=0pt \parskip=2pt \fi%
+ \def#2{\endgraf\afterenvbreak\endgroup}%
+ \def\itemcontents{#1}%
+ \let\item=\itemizeitem}
+ 
+ % Set sfcode to normal for the chars that usually have another value.
+ % These are `.?!:;,'
+ \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+   \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+ 
+ % \splitoff TOKENS\endmark defines \first to be the first token in
+ % TOKENS, and \rest to be the remainder.
+ %
+ \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+ 
+ % Allow an optional argument of an uppercase letter, lowercase letter,
+ % or number, to specify the first label in the enumerated list.  No
+ % argument is the same as `1'.
+ %
+ \def\enumerate{\parsearg\enumeratezzz}
+ \def\enumeratezzz #1{\enumeratey #1  \endenumeratey}
+ \def\enumeratey #1 #2\endenumeratey{%
+   \begingroup % ended by the @end enumerate
+   %
+   % If we were given no argument, pretend we were given `1'.
+   \def\thearg{#1}%
+   \ifx\thearg\empty \def\thearg{1}\fi
+   %
+   % Detect if the argument is a single token.  If so, it might be a
+   % letter.  Otherwise, the only valid thing it can be is a number.
+   % (We will always have one token, because of the test we just made.
+   % This is a good thing, since \splitoff doesn't work given nothing at
+   % all -- the first parameter is undelimited.)
+   \expandafter\splitoff\thearg\endmark
+   \ifx\rest\empty
+     % Only one token in the argument.  It could still be anything.
+     % A ``lowercase letter'' is one whose \lccode is nonzero.
+     % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+     %   not equal to itself.
+     % Otherwise, we assume it's a number.
+     %
+     % We need the \relax at the end of the \ifnum lines to stop TeX from
+     % continuing to look for a <number>.
+     %
+     \ifnum\lccode\expandafter`\thearg=0\relax
+       \numericenumerate % a number (we hope)
+     \else
+       % It's a letter.
+       \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+         \lowercaseenumerate % lowercase letter
+       \else
+         \uppercaseenumerate % uppercase letter
+       \fi
+     \fi
+   \else
+     % Multiple tokens in the argument.  We hope it's a number.
+     \numericenumerate
+   \fi
+ }
+ 
+ % An @enumerate whose labels are integers.  The starting integer is
+ % given in \thearg.
+ %
+ \def\numericenumerate{%
+   \itemno = \thearg
+   \startenumeration{\the\itemno}%
+ }
+ 
+ % The starting (lowercase) letter is in \thearg.
+ \def\lowercaseenumerate{%
+   \itemno = \expandafter`\thearg
+   \startenumeration{%
+     % Be sure we're not beyond the end of the alphabet.
+     \ifnum\itemno=0
+       \errmessage{No more lowercase letters in @enumerate; get a bigger
+                   alphabet}%
+     \fi
+     \char\lccode\itemno
+   }%
+ }
+ 
+ % The starting (uppercase) letter is in \thearg.
+ \def\uppercaseenumerate{%
+   \itemno = \expandafter`\thearg
+   \startenumeration{%
+     % Be sure we're not beyond the end of the alphabet.
+     \ifnum\itemno=0
+       \errmessage{No more uppercase letters in @enumerate; get a bigger
+                   alphabet}
+     \fi
+     \char\uccode\itemno
+   }%
+ }
+ 
+ % Call itemizey, adding a period to the first argument and supplying the
+ % common last two arguments.  Also subtract one from the initial value in
+ % \itemno, since @item increments \itemno.
+ %
+ \def\startenumeration#1{%
+   \advance\itemno by -1
+   \itemizey{#1.}\Eenumerate\flushcr
+ }
+ 
+ % @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+ % to @enumerate.
+ %
+ \def\alphaenumerate{\enumerate{a}}
+ \def\capsenumerate{\enumerate{A}}
+ \def\Ealphaenumerate{\Eenumerate}
+ \def\Ecapsenumerate{\Eenumerate}
+ 
+ % Definition of @item while inside @itemize.
+ 
+ \def\itemizeitem{%
+ \advance\itemno by 1
+ {\let\par=\endgraf \smallbreak}%
+ \ifhmode \errmessage{In hmode at itemizeitem}\fi
+ {\parskip=0in \hskip 0pt
+ \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+ \vadjust{\penalty 1200}}%
+ \flushcr}
+ 
+ % @multitable macros
+ % Amy Hendrickson, 8/18/94, 3/6/96
+ %
+ % @multitable ... @end multitable will make as many columns as desired.
+ % Contents of each column will wrap at width given in preamble.  Width
+ % can be specified either with sample text given in a template line,
+ % or in percent of \hsize, the current width of text on page.
+ 
+ % Table can continue over pages but will only break between lines.
+ 
+ % To make preamble:
+ %
+ % Either define widths of columns in terms of percent of \hsize:
+ %   @multitable @columnfractions .25 .3 .45
+ %   @item ...
+ %
+ %   Numbers following @columnfractions are the percent of the total
+ %   current hsize to be used for each column. You may use as many
+ %   columns as desired.
+ 
+ 
+ % Or use a template:
+ %   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+ %   @item ...
+ %   using the widest term desired in each column.
+ %
+ % For those who want to use more than one line's worth of words in
+ % the preamble, break the line within one argument and it
+ % will parse correctly, i.e.,
+ %
+ %     @multitable {Column 1 template} {Column 2 template} {Column 3
+ %      template}
+ % Not:
+ %     @multitable {Column 1 template} {Column 2 template}
+ %      {Column 3 template}
+ 
+ % Each new table line starts with @item, each subsequent new column
+ % starts with @tab. Empty columns may be produced by supplying @tab's
+ % with nothing between them for as many times as empty columns are needed,
+ % ie, @tab at tab@tab will produce two empty columns.
+ 
+ % @item, @tab, @multitable or @end multitable do not need to be on their
+ % own lines, but it will not hurt if they are.
+ 
+ % Sample multitable:
+ 
+ %   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+ %   @item first col stuff @tab second col stuff @tab third col
+ %   @item
+ %   first col stuff
+ %   @tab
+ %   second col stuff
+ %   @tab
+ %   third col
+ %   @item first col stuff @tab second col stuff
+ %   @tab Many paragraphs of text may be used in any column.
+ %
+ %         They will wrap at the width determined by the template.
+ %   @item at tab@tab This will be in third column.
+ %   @end multitable
+ 
+ % Default dimensions may be reset by user.
+ % @multitableparskip is vertical space between paragraphs in table.
+ % @multitableparindent is paragraph indent in table.
+ % @multitablecolmargin is horizontal space to be left between columns.
+ % @multitablelinespace is space to leave between table items, baseline
+ %                                                            to baseline.
+ %   0pt means it depends on current normal line spacing.
+ %
+ \newskip\multitableparskip
+ \newskip\multitableparindent
+ \newdimen\multitablecolspace
+ \newskip\multitablelinespace
+ \multitableparskip=0pt
+ \multitableparindent=6pt
+ \multitablecolspace=12pt
+ \multitablelinespace=0pt
+ 
+ % Macros used to set up halign preamble:
+ % 
+ \let\endsetuptable\relax
+ \def\xendsetuptable{\endsetuptable}
+ \let\columnfractions\relax
+ \def\xcolumnfractions{\columnfractions}
+ \newif\ifsetpercent
+ 
+ % #1 is the part of the @columnfraction before the decimal point, which
+ % is presumably either 0 or the empty string (but we don't check, we
+ % just throw it away).  #2 is the decimal part, which we use as the
+ % percent of \hsize for this column.
+ \def\pickupwholefraction#1.#2 {%
+   \global\advance\colcount by 1
+   \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}%
+   \setuptable
+ }
+ 
+ \newcount\colcount
+ \def\setuptable#1{%
+   \def\firstarg{#1}%
+   \ifx\firstarg\xendsetuptable
+     \let\go = \relax
+   \else
+     \ifx\firstarg\xcolumnfractions
+       \global\setpercenttrue
+     \else
+       \ifsetpercent
+          \let\go\pickupwholefraction
+       \else
+          \global\advance\colcount by 1
+          \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator;
+                             % typically that is always in the input, anyway.
+          \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+       \fi
+     \fi
+     \ifx\go\pickupwholefraction
+       % Put the argument back for the \pickupwholefraction call, so
+       % we'll always have a period there to be parsed.
+       \def\go{\pickupwholefraction#1}%
+     \else
+       \let\go = \setuptable
+     \fi%
+   \fi
+   \go
+ }
+ 
+ % multitable syntax
+ \def\tab{&\hskip1sp\relax} % 2/2/96
+                            % tiny skip here makes sure this column space is
+                            % maintained, even if it is never used.
+ 
+ % @multitable ... @end multitable definitions:
+ %
+ \def\multitable{\parsearg\dotable}
+ \def\dotable#1{\bgroup
+   \vskip\parskip
+   \let\item\crcr
+   \tolerance=9500
+   \hbadness=9500
+   \setmultitablespacing
+   \parskip=\multitableparskip
+   \parindent=\multitableparindent
+   \overfullrule=0pt
+   \global\colcount=0
+   \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}%
+   %
+   % To parse everything between @multitable and @item:
+   \setuptable#1 \endsetuptable
+   %
+   % \everycr will reset column counter, \colcount, at the end of
+   % each line. Every column entry will cause \colcount to advance by one.
+   % The table preamble
+   % looks at the current \colcount to find the correct column width.
+   \everycr{\noalign{%
+   %
+   % \filbreak%% keeps underfull box messages off when table breaks over pages.
+   % Maybe so, but it also creates really weird page breaks when the table
+   % breaks over pages. Wouldn't \vfil be better?  Wait until the problem
+   % manifests itself, so it can be fixed for real --karl.
+     \global\colcount=0\relax}}%
+   %
+   % This preamble sets up a generic column definition, which will
+   % be used as many times as user calls for columns.
+   % \vtop will set a single line and will also let text wrap and
+   % continue for many paragraphs if desired.
+   \halign\bgroup&\global\advance\colcount by 1\relax
+     \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+   %
+   % In order to keep entries from bumping into each other
+   % we will add a \leftskip of \multitablecolspace to all columns after
+   % the first one.
+   % 
+   % If a template has been used, we will add \multitablecolspace
+   % to the width of each template entry.
+   % 
+   % If the user has set preamble in terms of percent of \hsize we will
+   % use that dimension as the width of the column, and the \leftskip
+   % will keep entries from bumping into each other.  Table will start at
+   % left margin and final column will justify at right margin.
+   % 
+   % Make sure we don't inherit \rightskip from the outer environment.
+   \rightskip=0pt
+   \ifnum\colcount=1
+     % The first column will be indented with the surrounding text.
+     \advance\hsize by\leftskip
+   \else
+     \ifsetpercent \else
+       % If user has not set preamble in terms of percent of \hsize
+       % we will advance \hsize by \multitablecolspace.
+       \advance\hsize by \multitablecolspace
+     \fi
+    % In either case we will make \leftskip=\multitablecolspace:
+   \leftskip=\multitablecolspace
+   \fi
+   % Ignoring space at the beginning and end avoids an occasional spurious
+   % blank line, when TeX decides to break the line at the space before the
+   % box from the multistrut, so the strut ends up on a line by itself.
+   % For example:
+   % @multitable @columnfractions .11 .89
+   % @item @code{#}
+   % @tab Legal holiday which is valid in major parts of the whole country.
+   % Is automatically provided with highlighting sequences respectively marking
+   % characters.
+   \noindent\ignorespaces##\unskip\multistrut}\cr
+ }
+ 
+ \def\setmultitablespacing{% test to see if user has set \multitablelinespace.
+ % If so, do nothing. If not, give it an appropriate dimension based on
+ % current baselineskip.
+ \ifdim\multitablelinespace=0pt
+ %% strut to put in table in case some entry doesn't have descenders,
+ %% to keep lines equally spaced
+ \let\multistrut = \strut
+ %% Test to see if parskip is larger than space between lines of
+ %% table. If not, do nothing.
+ %%        If so, set to same dimension as multitablelinespace.
+ \else
+ \gdef\multistrut{\vrule height\multitablelinespace depth\dp0
+ width0pt\relax} \fi
+ \ifdim\multitableparskip>\multitablelinespace
+ \global\multitableparskip=\multitablelinespace
+ \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                       %% than skip between lines in the table.
+ \fi%
+ \ifdim\multitableparskip=0pt
+ \global\multitableparskip=\multitablelinespace
+ \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                       %% than skip between lines in the table.
+ \fi}
+ 
+ 
+ \message{indexing,}
+ % Index generation facilities
+ 
+ % Define \newwrite to be identical to plain tex's \newwrite
+ % except not \outer, so it can be used within \newindex.
+ {\catcode`\@=11
+ \gdef\newwrite{\alloc at 7\write\chardef\sixt@@n}}
+ 
+ % \newindex {foo} defines an index named foo.
+ % It automatically defines \fooindex such that
+ % \fooindex ...rest of line... puts an entry in the index foo.
+ % It also defines \fooindfile to be the number of the output channel for
+ % the file that accumulates this index.  The file's extension is foo.
+ % The name of an index should be no more than 2 characters long
+ % for the sake of vms.
+ %
+ \def\newindex#1{%
+   \iflinks
+     \expandafter\newwrite \csname#1indfile\endcsname
+     \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+   \fi
+   \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+     \noexpand\doindex{#1}}
+ }
+ 
+ % @defindex foo  ==  \newindex{foo}
+ 
+ \def\defindex{\parsearg\newindex}
+ 
+ % Define @defcodeindex, like @defindex except put all entries in @code.
+ 
+ \def\newcodeindex#1{%
+   \iflinks
+     \expandafter\newwrite \csname#1indfile\endcsname
+     \openout \csname#1indfile\endcsname \jobname.#1
+   \fi
+   \expandafter\xdef\csname#1index\endcsname{%
+     \noexpand\docodeindex{#1}}
+ }
+ 
+ \def\defcodeindex{\parsearg\newcodeindex}
+ 
+ % @synindex foo bar    makes index foo feed into index bar.
+ % Do this instead of @defindex foo if you don't want it as a separate index.
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \def\synindex#1 #2 {%
+   \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+   \expandafter\closeout\csname#1indfile\endcsname
+   \expandafter\let\csname#1indfile\endcsname=\synindexfoo
+   \expandafter\xdef\csname#1index\endcsname{% define \xxxindex
+     \noexpand\doindex{#2}}%
+ }
+ 
+ % @syncodeindex foo bar   similar, but put all entries made for index foo
+ % inside @code.
+ \def\syncodeindex#1 #2 {%
+   \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+   \expandafter\closeout\csname#1indfile\endcsname
+   \expandafter\let\csname#1indfile\endcsname=\synindexfoo
+   \expandafter\xdef\csname#1index\endcsname{% define \xxxindex
+     \noexpand\docodeindex{#2}}%
+ }
+ 
+ % Define \doindex, the driver for all \fooindex macros.
+ % Argument #1 is generated by the calling \fooindex macro,
+ %  and it is "foo", the name of the index.
+ 
+ % \doindex just uses \parsearg; it calls \doind for the actual work.
+ % This is because \doind is more useful to call from other macros.
+ 
+ % There is also \dosubind {index}{topic}{subtopic}
+ % which makes an entry in a two-level index such as the operation index.
+ 
+ \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+ \def\singleindexer #1{\doind{\indexname}{#1}}
+ 
+ % like the previous two, but they put @code around the argument.
+ \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+ \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+ 
+ \def\indexdummies{%
+ \def\ { }%
+ % Take care of the plain tex accent commands.
+ \def\"{\realbackslash "}%
+ \def\`{\realbackslash `}%
+ \def\'{\realbackslash '}%
+ \def\^{\realbackslash ^}%
+ \def\~{\realbackslash ~}%
+ \def\={\realbackslash =}%
+ \def\b{\realbackslash b}%
+ \def\c{\realbackslash c}%
+ \def\d{\realbackslash d}%
+ \def\u{\realbackslash u}%
+ \def\v{\realbackslash v}%
+ \def\H{\realbackslash H}%
+ % Take care of the plain tex special European modified letters.
+ \def\oe{\realbackslash oe}%
+ \def\ae{\realbackslash ae}%
+ \def\aa{\realbackslash aa}%
+ \def\OE{\realbackslash OE}%
+ \def\AE{\realbackslash AE}%
+ \def\AA{\realbackslash AA}%
+ \def\o{\realbackslash o}%
+ \def\O{\realbackslash O}%
+ \def\l{\realbackslash l}%
+ \def\L{\realbackslash L}%
+ \def\ss{\realbackslash ss}%
+ % Take care of texinfo commands likely to appear in an index entry.
+ % (Must be a way to avoid doing expansion at all, and thus not have to
+ % laboriously list every single command here.)
+ \def\@{@}% will be @@ when we switch to @ as escape char.
+ % Need these in case \tex is in effect and \{ is a \delimiter again.
+ % But can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters.
+ \let\{ = \mylbrace
+ \let\} = \myrbrace
+ \def\_{{\realbackslash _}}%
+ \def\w{\realbackslash w }%
+ \def\bf{\realbackslash bf }%
+ %\def\rm{\realbackslash rm }%
+ \def\sl{\realbackslash sl }%
+ \def\sf{\realbackslash sf}%
+ \def\tt{\realbackslash tt}%
+ \def\gtr{\realbackslash gtr}%
+ \def\less{\realbackslash less}%
+ \def\hat{\realbackslash hat}%
+ \def\TeX{\realbackslash TeX}%
+ \def\dots{\realbackslash dots }%
+ \def\result{\realbackslash result}%
+ \def\equiv{\realbackslash equiv}%
+ \def\expansion{\realbackslash expansion}%
+ \def\print{\realbackslash print}%
+ \def\error{\realbackslash error}%
+ \def\point{\realbackslash point}%
+ \def\copyright{\realbackslash copyright}%
+ \def\tclose##1{\realbackslash tclose {##1}}%
+ \def\code##1{\realbackslash code {##1}}%
+ \def\uref##1{\realbackslash uref {##1}}%
+ \def\url##1{\realbackslash url {##1}}%
+ \def\env##1{\realbackslash env {##1}}%
+ \def\command##1{\realbackslash command {##1}}%
+ \def\option##1{\realbackslash option {##1}}%
+ \def\dotless##1{\realbackslash dotless {##1}}%
+ \def\samp##1{\realbackslash samp {##1}}%
+ \def\,##1{\realbackslash ,{##1}}%
+ \def\t##1{\realbackslash t {##1}}%
+ \def\r##1{\realbackslash r {##1}}%
+ \def\i##1{\realbackslash i {##1}}%
+ \def\b##1{\realbackslash b {##1}}%
+ \def\sc##1{\realbackslash sc {##1}}%
+ \def\cite##1{\realbackslash cite {##1}}%
+ \def\key##1{\realbackslash key {##1}}%
+ \def\file##1{\realbackslash file {##1}}%
+ \def\var##1{\realbackslash var {##1}}%
+ \def\kbd##1{\realbackslash kbd {##1}}%
+ \def\dfn##1{\realbackslash dfn {##1}}%
+ \def\emph##1{\realbackslash emph {##1}}%
+ \def\acronym##1{\realbackslash acronym {##1}}%
+ %
+ % Handle some cases of @value -- where the variable name does not
+ % contain - or _, and the value does not contain any
+ % (non-fully-expandable) commands.
+ \let\value = \expandablevalue
+ %
+ \unsepspaces
+ }
+ 
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\\leavevmode \penalty \@M \ ).
+ {\obeyspaces
+  \gdef\unsepspaces{\obeyspaces\let =\space}}
+ 
+ % \indexnofonts no-ops all font-change commands.
+ % This is used when outputting the strings to sort the index by.
+ \def\indexdummyfont#1{#1}
+ \def\indexdummytex{TeX}
+ \def\indexdummydots{...}
+ 
+ \def\indexnofonts{%
+ % Just ignore accents.
+ \let\,=\indexdummyfont
+ \let\"=\indexdummyfont
+ \let\`=\indexdummyfont
+ \let\'=\indexdummyfont
+ \let\^=\indexdummyfont
+ \let\~=\indexdummyfont
+ \let\==\indexdummyfont
+ \let\b=\indexdummyfont
+ \let\c=\indexdummyfont
+ \let\d=\indexdummyfont
+ \let\u=\indexdummyfont
+ \let\v=\indexdummyfont
+ \let\H=\indexdummyfont
+ \let\dotless=\indexdummyfont
+ % Take care of the plain tex special European modified letters.
+ \def\oe{oe}%
+ \def\ae{ae}%
+ \def\aa{aa}%
+ \def\OE{OE}%
+ \def\AE{AE}%
+ \def\AA{AA}%
+ \def\o{o}%
+ \def\O{O}%
+ \def\l{l}%
+ \def\L{L}%
+ \def\ss{ss}%
+ \let\w=\indexdummyfont
+ \let\t=\indexdummyfont
+ \let\r=\indexdummyfont
+ \let\i=\indexdummyfont
+ \let\b=\indexdummyfont
+ \let\emph=\indexdummyfont
+ \let\strong=\indexdummyfont
+ \let\cite=\indexdummyfont
+ \let\sc=\indexdummyfont
+ %Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |...
+ %\let\tt=\indexdummyfont
+ \let\tclose=\indexdummyfont
+ \let\code=\indexdummyfont
+ \let\url=\indexdummyfont
+ \let\uref=\indexdummyfont
+ \let\env=\indexdummyfont
+ \let\command=\indexdummyfont
+ \let\option=\indexdummyfont
+ \let\file=\indexdummyfont
+ \let\samp=\indexdummyfont
+ \let\kbd=\indexdummyfont
+ \let\key=\indexdummyfont
+ \let\var=\indexdummyfont
+ \let\TeX=\indexdummytex
+ \let\dots=\indexdummydots
+ \def\@{@}%
+ }
+ 
+ % To define \realbackslash, we must make \ not be an escape.
+ % We must first make another character (@) an escape
+ % so we do not become unable to do a definition.
+ 
+ {\catcode`\@=0 \catcode`\\=\other
+  @gdef at realbackslash{\}}
+ 
+ \let\indexbackslash=0  %overridden during \printindex.
+ \let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+ 
+ % For \ifx comparisons.
+ \def\emptymacro{\empty}
+ 
+ % Most index entries go through here, but \dosubind is the general case.
+ % 
+ \def\doind#1#2{\dosubind{#1}{#2}\empty}
+ 
+ % Workhorse for all \fooindexes.
+ % #1 is name of index, #2 is stuff to put there, #3 is subentry --
+ % \empty if called from \doind, as we usually are.  The main exception
+ % is with defuns, which call us directly.
+ % 
+ \def\dosubind#1#2#3{%
+   % Put the index entry in the margin if desired.
+   \ifx\SETmarginindex\relax\else
+     \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+   \fi
+   {%
+     \count255=\lastpenalty
+     {%
+       \indexdummies % Must do this here, since \bf, etc expand at this stage
+       \escapechar=`\\
+       {%
+         \let\folio = 0% We will expand all macros now EXCEPT \folio.
+         \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+         % so it will be output as is; and it will print as backslash.
+         %
+         \def\thirdarg{#3}%
+         %
+         % If third arg is present, precede it with space in sort key.
+         \ifx\thirdarg\emptymacro
+           \let\subentry = \empty
+         \else
+           \def\subentry{ #3}%
+         \fi
+         %
+         % First process the index-string with all font commands turned off
+         % to get the string to sort by.
+         {\indexnofonts \xdef\indexsorttmp{#2\subentry}}%
+         %
+         % Now produce the complete index entry, with both the sort key and the
+         % original text, including any font commands.
+         \toks0 = {#2}%
+         \edef\temp{%
+           \write\csname#1indfile\endcsname{%
+             \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
+         }%
+         %
+         % If third (subentry) arg is present, add it to the index string.
+         \ifx\thirdarg\emptymacro \else
+           \toks0 = {#3}%
+           \edef\temp{\temp{\the\toks0}}%
+         \fi
+         %
+         % If a skip is the last thing on the list now, preserve it
+         % by backing up by \lastskip, doing the \write, then inserting
+         % the skip again.  Otherwise, the whatsit generated by the
+         % \write will make \lastskip zero.  The result is that sequences
+         % like this:
+         % @end defun
+         % @tindex whatever
+         % @defun ...
+         % will have extra space inserted, because the \medbreak in the
+         % start of the @defun won't see the skip inserted by the @end of
+         % the previous defun.
+         % 
+         % But don't do any of this if we're not in vertical mode.  We
+         % don't want to do a \vskip and prematurely end a paragraph.
+         % 
+         % Avoid page breaks due to these extra skips, too.
+         % 
+         \iflinks
+           \ifvmode
+             \skip0 = \lastskip
+             \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi
+           \fi
+           %
+           \temp % do the write
+           %
+           % 
+           \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi
+         \fi
+       }%
+     }%
+     \penalty\count255
+   }%
+ }
+ 
+ % The index entry written in the file actually looks like
+ %  \entry {sortstring}{page}{topic}
+ % or
+ %  \entry {sortstring}{page}{topic}{subtopic}
+ % The texindex program reads in these files and writes files
+ % containing these kinds of lines:
+ %  \initial {c}
+ %     before the first topic whose initial is c
+ %  \entry {topic}{pagelist}
+ %     for a topic that is used without subtopics
+ %  \primary {topic}
+ %     for the beginning of a topic that is used with subtopics
+ %  \secondary {subtopic}{pagelist}
+ %     for each subtopic.
+ 
+ % Define the user-accessible indexing commands
+ % @findex, @vindex, @kindex, @cindex.
+ 
+ \def\findex {\fnindex}
+ \def\kindex {\kyindex}
+ \def\cindex {\cpindex}
+ \def\vindex {\vrindex}
+ \def\tindex {\tpindex}
+ \def\pindex {\pgindex}
+ 
+ \def\cindexsub {\begingroup\obeylines\cindexsub}
+ {\obeylines %
+ \gdef\cindexsub "#1" #2^^M{\endgroup %
+ \dosubind{cp}{#2}{#1}}}
+ 
+ % Define the macros used in formatting output of the sorted index material.
+ 
+ % @printindex causes a particular index (the ??s file) to get printed.
+ % It does not print any chapter heading (usually an @unnumbered).
+ %
+ \def\printindex{\parsearg\doprintindex}
+ \def\doprintindex#1{\begingroup
+   \dobreak \chapheadingskip{10000}%
+   %
+   \indexfonts \rm
+   \tolerance = 9500
+   \indexbreaks
+   %
+   % See if the index file exists and is nonempty.
+   % Change catcode of @ here so that if the index file contains
+   % \initial {@}
+   % as its first line, TeX doesn't complain about mismatched braces
+   % (because it thinks @} is a control sequence).
+   \catcode`\@ = 11
+   \openin 1 \jobname.#1s
+   \ifeof 1
+     % \enddoublecolumns gets confused if there is no text in the index,
+     % and it loses the chapter title and the aux file entries for the
+     % index.  The easiest way to prevent this problem is to make sure
+     % there is some text.
+     (Index is nonexistent)
+   \else
+     %
+     % If the index file exists but is empty, then \openin leaves \ifeof
+     % false.  We have to make TeX try to read something from the file, so
+     % it can discover if there is anything in it.
+     \read 1 to \temp
+     \ifeof 1
+       (Index is empty)
+     \else
+       % Index files are almost Texinfo source, but we use \ as the escape
+       % character.  It would be better to use @, but that's too big a change
+       % to make right now.
+       \def\indexbackslash{\rawbackslashxx}%
+       \catcode`\\ = 0
+       \escapechar = `\\
+       \begindoublecolumns
+       \input \jobname.#1s
+       \enddoublecolumns
+     \fi
+   \fi
+   \closein 1
+ \endgroup}
+ 
+ % These macros are used by the sorted index file itself.
+ % Change them to control the appearance of the index.
+ 
+ \def\initial#1{{%
+   % Some minor font changes for the special characters.
+   \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+   %
+   % Remove any glue we may have, we'll be inserting our own.
+   \removelastskip
+   % 
+   % We like breaks before the index initials, so insert a bonus.
+   \penalty -300
+   %
+   % Typeset the initial.  Making this add up to a whole number of
+   % baselineskips increases the chance of the dots lining up from column
+   % to column.  It still won't often be perfect, because of the stretch
+   % we need before each entry, but it's better.
+   % 
+   % No shrink because it confuses \balancecolumns.
+   \vskip 1.67\baselineskip plus .5\baselineskip
+   \leftline{\secbf #1}%
+   \vskip .33\baselineskip plus .1\baselineskip
+   %
+   % Do our best not to break after the initial.
+   \nobreak
+ }}
+ 
+ % This typesets a paragraph consisting of #1, dot leaders, and then #2
+ % flush to the right margin.  It is used for index and table of contents
+ % entries.  The paragraph is indented by \leftskip.
+ %
+ \def\entry#1#2{\begingroup
+   %
+   % Start a new paragraph if necessary, so our assignments below can't
+   % affect previous text.
+   \par
+   %
+   % Do not fill out the last line with white space.
+   \parfillskip = 0in
+   %
+   % No extra space above this paragraph.
+   \parskip = 0in
+   %
+   % Do not prefer a separate line ending with a hyphen to fewer lines.
+   \finalhyphendemerits = 0
+   %
+   % \hangindent is only relevant when the entry text and page number
+   % don't both fit on one line.  In that case, bob suggests starting the
+   % dots pretty far over on the line.  Unfortunately, a large
+   % indentation looks wrong when the entry text itself is broken across
+   % lines.  So we use a small indentation and put up with long leaders.
+   %
+   % \hangafter is reset to 1 (which is the value we want) at the start
+   % of each paragraph, so we need not do anything with that.
+   \hangindent = 2em
+   %
+   % When the entry text needs to be broken, just fill out the first line
+   % with blank space.
+   \rightskip = 0pt plus1fil
+   %
+   % A bit of stretch before each entry for the benefit of balancing columns.
+   \vskip 0pt plus1pt
+   %
+   % Start a ``paragraph'' for the index entry so the line breaking
+   % parameters we've set above will have an effect.
+   \noindent
+   %
+   % Insert the text of the index entry.  TeX will do line-breaking on it.
+   #1%
+   % The following is kludged to not output a line of dots in the index if
+   % there are no page numbers.  The next person who breaks this will be
+   % cursed by a Unix daemon.
+   \def\tempa{{\rm }}%
+   \def\tempb{#2}%
+   \edef\tempc{\tempa}%
+   \edef\tempd{\tempb}%
+   \ifx\tempc\tempd\ \else%
+     %
+     % If we must, put the page number on a line of its own, and fill out
+     % this line with blank space.  (The \hfil is overwhelmed with the
+     % fill leaders glue in \indexdotfill if the page number does fit.)
+     \hfil\penalty50
+     \null\nobreak\indexdotfill % Have leaders before the page number.
+     %
+     % The `\ ' here is removed by the implicit \unskip that TeX does as
+     % part of (the primitive) \par.  Without it, a spurious underfull
+     % \hbox ensues.
+     \ #2% The page number ends the paragraph.
+   \fi%
+   \par
+ \endgroup}
+ 
+ % Like \dotfill except takes at least 1 em.
+ \def\indexdotfill{\cleaders
+   \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+ 
+ \def\primary #1{\line{#1\hfil}}
+ 
+ \newskip\secondaryindent \secondaryindent=0.5cm
+ 
+ \def\secondary #1#2{
+ {\parfillskip=0in \parskip=0in
+ \hangindent =1in \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
+ }}
+ 
+ % Define two-column mode, which we use to typeset indexes.
+ % Adapted from the TeXbook, page 416, which is to say,
+ % the manmac.tex format used to print the TeXbook itself.
+ \catcode`\@=11
+ 
+ \newbox\partialpage
+ \newdimen\doublecolumnhsize
+ 
+ \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+   % Grab any single-column material above us.
+   \output = {\global\setbox\partialpage = \vbox{%
+     % 
+     % Here is a possibility not foreseen in manmac: if we accumulate a
+     % whole lot of material, we might end up calling this \output
+     % routine twice in a row (see the doublecol-lose test, which is
+     % essentially a couple of indexes with @setchapternewpage off).  In
+     % that case, we must prevent the second \partialpage from
+     % simply overwriting the first, causing us to lose the page.
+     % This will preserve it until a real output routine can ship it
+     % out.  Generally, \partialpage will be empty when this runs and
+     % this will be a no-op.
+     \unvbox\partialpage
+     %
+     % Unvbox the main output page.
+     \unvbox255
+     \kern-\topskip \kern\baselineskip
+   }}%
+   \eject % run that output routine to set \partialpage
+   %
+   % Use the double-column output routine for subsequent pages.
+   \output = {\doublecolumnout}%
+   %
+   % Change the page size parameters.  We could do this once outside this
+   % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+   % format, but then we repeat the same computation.  Repeating a couple
+   % of assignments once per index is clearly meaningless for the
+   % execution time, so we may as well do it in one place.
+   %
+   % First we halve the line length, less a little for the gutter between
+   % the columns.  We compute the gutter based on the line length, so it
+   % changes automatically with the paper format.  The magic constant
+   % below is chosen so that the gutter has the same value (well, +-<1pt)
+   % as it did when we hard-coded it.
+   %
+   % We put the result in a separate register, \doublecolumhsize, so we
+   % can restore it in \pagesofar, after \hsize itself has (potentially)
+   % been clobbered.
+   %
+   \doublecolumnhsize = \hsize
+     \advance\doublecolumnhsize by -.04154\hsize
+     \divide\doublecolumnhsize by 2
+   \hsize = \doublecolumnhsize
+   %
+   % Double the \vsize as well.  (We don't need a separate register here,
+   % since nobody clobbers \vsize.)
+   \advance\vsize by -\ht\partialpage
+   \vsize = 2\vsize
+ }
+ 
+ % The double-column output routine for all double-column pages except
+ % the last.
+ % 
+ \def\doublecolumnout{%
+   \splittopskip=\topskip \splitmaxdepth=\maxdepth
+   % Get the available space for the double columns -- the normal
+   % (undoubled) page height minus any material left over from the
+   % previous page.
+   \dimen@ = \vsize
+   \divide\dimen@ by 2
+   %
+   % box0 will be the left-hand column, box2 the right.
+   \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+   \onepageout\pagesofar
+   \unvbox255
+   \penalty\outputpenalty
+ }
+ \def\pagesofar{%
+   % Re-output the contents of the output page -- any previous material,
+   % followed by the two boxes we just split, in box0 and box2.
+   \advance\vsize by \ht\partialpage
+   \unvbox\partialpage
+   %
+   \hsize = \doublecolumnhsize
+   \wd0=\hsize \wd2=\hsize
+   \hbox to\pagewidth{\box0\hfil\box2}%
+ }
+ \def\enddoublecolumns{%
+   \output = {%
+     % Split the last of the double-column material.  Leave it on the
+     % current page, no automatic page break.
+     \balancecolumns
+     %
+     % If we end up splitting too much material for the current page,
+     % though, there will be another page break right after this \output
+     % invocation ends.  Having called \balancecolumns once, we do not
+     % want to call it again.  Therefore, reset \output to its normal
+     % definition right away.  (We hope \balancecolumns will never be
+     % called on to balance too much material, but if it is, this makes
+     % the output somewhat more palatable.)
+     \global\output = {\onepageout{\pagecontents\PAGE}}%
+   }%
+   \eject
+   \endgroup % started in \begindoublecolumns
+   %
+   % \pagegoal was set to the doubled \vsize above, since we restarted
+   % the current page.  We're now back to normal single-column
+   % typesetting, so reset \pagegoal to the normal \vsize (after the
+   % \endgroup where \vsize got restored).
+   \pagegoal = \vsize
+ }
+ \def\balancecolumns{%
+   % Called at the end of the double column material.
+   \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+   \dimen@ = \ht0
+   \advance\dimen@ by \topskip
+   \advance\dimen@ by-\baselineskip
+   \divide\dimen@ by 2 % target to split to
+   %debug\message{final 2-column material height=\the\ht0, target=\the\dimen at .}%
+   \splittopskip = \topskip
+   % Loop until we get a decent breakpoint.
+   {%
+     \vbadness = 10000
+     \loop
+       \global\setbox3 = \copy0
+       \global\setbox1 = \vsplit3 to \dimen@
+     \ifdim\ht3>\dimen@
+       \global\advance\dimen@ by 1pt
+     \repeat
+   }%
+   %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+   \setbox0=\vbox to\dimen@{\unvbox1}%
+   \setbox2=\vbox to\dimen@{\unvbox3}%
+   %
+   \pagesofar
+ }
+ \catcode`\@ = \other
+ 
+ 
+ \message{sectioning,}
+ % Define chapters, sections, etc.
+ 
+ \newcount\chapno
+ \newcount\secno        \secno=0
+ \newcount\subsecno     \subsecno=0
+ \newcount\subsubsecno  \subsubsecno=0
+ 
+ % This counter is funny since it counts through charcodes of letters A, B, ...
+ \newcount\appendixno  \appendixno = `\@
+ \def\appendixletter{\char\the\appendixno}
+ 
+ % Each @chapter defines this as the name of the chapter.
+ % page headings and footings can use it.  @section does likewise.
+ \def\thischapter{}
+ \def\thissection{}
+ 
+ \newcount\absseclevel % used to calculate proper heading level
+ \newcount\secbase\secbase=0 % @raise/lowersections modify this count
+ 
+ % @raisesections: treat @section as chapter, @subsection as section, etc.
+ \def\raisesections{\global\advance\secbase by -1}
+ \let\up=\raisesections % original BFox name
+ 
+ % @lowersections: treat @chapter as section, @section as subsection, etc.
+ \def\lowersections{\global\advance\secbase by 1}
+ \let\down=\lowersections % original BFox name
+ 
+ % Choose a numbered-heading macro
+ % #1 is heading level if unmodified by @raisesections or @lowersections
+ % #2 is text for heading
+ \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+ \ifcase\absseclevel
+   \chapterzzz{#2}
+ \or
+   \seczzz{#2}
+ \or
+   \numberedsubseczzz{#2}
+ \or
+   \numberedsubsubseczzz{#2}
+ \else
+   \ifnum \absseclevel<0
+     \chapterzzz{#2}
+   \else
+     \numberedsubsubseczzz{#2}
+   \fi
+ \fi
+ }
+ 
+ % like \numhead, but chooses appendix heading levels
+ \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+ \ifcase\absseclevel
+   \appendixzzz{#2}
+ \or
+   \appendixsectionzzz{#2}
+ \or
+   \appendixsubseczzz{#2}
+ \or
+   \appendixsubsubseczzz{#2}
+ \else
+   \ifnum \absseclevel<0
+     \appendixzzz{#2}
+   \else
+     \appendixsubsubseczzz{#2}
+   \fi
+ \fi
+ }
+ 
+ % like \numhead, but chooses numberless heading levels
+ \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+ \ifcase\absseclevel
+   \unnumberedzzz{#2}
+ \or
+   \unnumberedseczzz{#2}
+ \or
+   \unnumberedsubseczzz{#2}
+ \or
+   \unnumberedsubsubseczzz{#2}
+ \else
+   \ifnum \absseclevel<0
+     \unnumberedzzz{#2}
+   \else
+     \unnumberedsubsubseczzz{#2}
+   \fi
+ \fi
+ }
+ 
+ % @chapter, @appendix, @unnumbered.
+ \def\thischaptername{No Chapter Title}
+ \outer\def\chapter{\parsearg\chapteryyy}
+ \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+ \def\chapterzzz #1{%
+ \secno=0 \subsecno=0 \subsubsecno=0
+ \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}%
+ \chapmacro {#1}{\the\chapno}%
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now.
+ \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}%
+                                   {\the\chapno}}}%
+ \temp
+ \donoderef
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+ }
+ 
+ \outer\def\appendix{\parsearg\appendixyyy}
+ \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
+ \def\appendixzzz #1{%
+ \secno=0 \subsecno=0 \subsubsecno=0
+ \global\advance \appendixno by 1
+ \message{\putwordAppendix\space \appendixletter}%
+ \chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}%
+                        {\putwordAppendix{} \appendixletter}}}%
+ \temp
+ \appendixnoderef
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+ }
+ 
+ % @centerchap is like @unnumbered, but the heading is centered.
+ \outer\def\centerchap{\parsearg\centerchapyyy}
+ \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
+ 
+ % @top is like @unnumbered.
+ \outer\def\top{\parsearg\unnumberedyyy}
+ 
+ \outer\def\unnumbered{\parsearg\unnumberedyyy}
+ \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+ \def\unnumberedzzz #1{%
+ \secno=0 \subsecno=0 \subsubsecno=0
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message.  Therefore, if #1 contained @-commands, TeX
+ % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself.  We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>.  (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}\message{(\the\toks0)}%
+ %
+ \unnumbchapmacro {#1}%
+ \gdef\thischapter{#1}\gdef\thissection{#1}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}%
+ \temp
+ \unnumbnoderef
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+ }
+ 
+ % Sections.
+ \outer\def\numberedsec{\parsearg\secyyy}
+ \def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+ \def\seczzz #1{%
+ \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+ \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}%
+                                   {\the\chapno}{\the\secno}}}%
+ \temp
+ \donoderef
+ \nobreak
+ }
+ 
+ \outer\def\appendixsection{\parsearg\appendixsecyyy}
+ \outer\def\appendixsec{\parsearg\appendixsecyyy}
+ \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+ \def\appendixsectionzzz #1{%
+ \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+ \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}%
+                                   {\appendixletter}{\the\secno}}}%
+ \temp
+ \appendixnoderef
+ \nobreak
+ }
+ 
+ \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+ \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+ \def\unnumberedseczzz #1{%
+ \plainsecheading {#1}\gdef\thissection{#1}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}%
+ \temp
+ \unnumbnoderef
+ \nobreak
+ }
+ 
+ % Subsections.
+ \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+ \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+ \def\numberedsubseczzz #1{%
+ \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+ \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}%
+                                     {\the\chapno}{\the\secno}{\the\subsecno}}}%
+ \temp
+ \donoderef
+ \nobreak
+ }
+ 
+ \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+ \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+ \def\appendixsubseczzz #1{%
+ \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+ \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}%
+                                 {\appendixletter}{\the\secno}{\the\subsecno}}}%
+ \temp
+ \appendixnoderef
+ \nobreak
+ }
+ 
+ \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+ \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+ \def\unnumberedsubseczzz #1{%
+ \plainsubsecheading {#1}\gdef\thissection{#1}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry%
+                                     {\the\toks0}}}%
+ \temp
+ \unnumbnoderef
+ \nobreak
+ }
+ 
+ % Subsubsections.
+ \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+ \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+ \def\numberedsubsubseczzz #1{%
+ \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+ \subsubsecheading {#1}
+   {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}%
+   {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}%
+ \temp
+ \donoderef
+ \nobreak
+ }
+ 
+ \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+ \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+ \def\appendixsubsubseczzz #1{%
+ \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+ \subsubsecheading {#1}
+   {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}%
+   {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}%
+ \temp
+ \appendixnoderef
+ \nobreak
+ }
+ 
+ \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+ \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+ \def\unnumberedsubsubseczzz #1{%
+ \plainsubsubsecheading {#1}\gdef\thissection{#1}%
+ \toks0 = {#1}%
+ \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry%
+                                     {\the\toks0}}}%
+ \temp
+ \unnumbnoderef
+ \nobreak
+ }
+ 
+ % These are variants which are not "outer", so they can appear in @ifinfo.
+ % Actually, they should now be obsolete; ordinary section commands should work.
+ \def\infotop{\parsearg\unnumberedzzz}
+ \def\infounnumbered{\parsearg\unnumberedzzz}
+ \def\infounnumberedsec{\parsearg\unnumberedseczzz}
+ \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+ \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+ 
+ \def\infoappendix{\parsearg\appendixzzz}
+ \def\infoappendixsec{\parsearg\appendixseczzz}
+ \def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+ \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+ 
+ \def\infochapter{\parsearg\chapterzzz}
+ \def\infosection{\parsearg\sectionzzz}
+ \def\infosubsection{\parsearg\subsectionzzz}
+ \def\infosubsubsection{\parsearg\subsubsectionzzz}
+ 
+ % These macros control what the section commands do, according
+ % to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+ % Define them by default for a numbered chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+ 
+ % Define @majorheading, @heading and @subheading
+ 
+ % NOTE on use of \vbox for chapter headings, section headings, and such:
+ %       1) We use \vbox rather than the earlier \line to permit
+ %          overlong headings to fold.
+ %       2) \hyphenpenalty is set to 10000 because hyphenation in a
+ %          heading is obnoxious; this forbids it.
+ %       3) Likewise, headings look best if no \parindent is used, and
+ %          if justification is not attempted.  Hence \raggedright.
+ 
+ 
+ \def\majorheading{\parsearg\majorheadingzzz}
+ \def\majorheadingzzz #1{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                   \parindent=0pt\raggedright
+                   \rm #1\hfill}}\bigskip \par\penalty 200}
+ 
+ \def\chapheading{\parsearg\chapheadingzzz}
+ \def\chapheadingzzz #1{\chapbreak %
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                   \parindent=0pt\raggedright
+                   \rm #1\hfill}}\bigskip \par\penalty 200}
+ 
+ % @heading, @subheading, @subsubheading.
+ \def\heading{\parsearg\plainsecheading}
+ \def\subheading{\parsearg\plainsubsecheading}
+ \def\subsubheading{\parsearg\plainsubsubsecheading}
+ 
+ % These macros generate a chapter, section, etc. heading only
+ % (including whitespace, linebreaking, etc. around it),
+ % given all the information in convenient, parsed form.
+ 
+ %%% Args are the skip and penalty (usually negative)
+ \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+ 
+ \def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+ 
+ %%% Define plain chapter starts, and page on/off switching for it
+ % Parameter controlling skip before chapter headings (if needed)
+ 
+ \newskip\chapheadingskip
+ 
+ \def\chapbreak{\dobreak \chapheadingskip {-4000}}
+ \def\chappager{\par\vfill\supereject}
+ \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+ 
+ \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+ 
+ \def\CHAPPAGoff{%
+ \global\let\contentsalignmacro = \chappager
+ \global\let\pchapsepmacro=\chapbreak
+ \global\let\pagealignmacro=\chappager}
+ 
+ \def\CHAPPAGon{%
+ \global\let\contentsalignmacro = \chappager
+ \global\let\pchapsepmacro=\chappager
+ \global\let\pagealignmacro=\chappager
+ \global\def\HEADINGSon{\HEADINGSsingle}}
+ 
+ \def\CHAPPAGodd{
+ \global\let\contentsalignmacro = \chapoddpage
+ \global\let\pchapsepmacro=\chapoddpage
+ \global\let\pagealignmacro=\chapoddpage
+ \global\def\HEADINGSon{\HEADINGSdouble}}
+ 
+ \CHAPPAGon
+ 
+ \def\CHAPFplain{
+ \global\let\chapmacro=\chfplain
+ \global\let\unnumbchapmacro=\unnchfplain
+ \global\let\centerchapmacro=\centerchfplain}
+ 
+ % Plain chapter opening.
+ % #1 is the text, #2 the chapter number or empty if unnumbered.
+ \def\chfplain#1#2{%
+   \pchapsepmacro
+   {%
+     \chapfonts \rm
+     \def\chapnum{#2}%
+     \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
+     \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+           \hangindent = \wd0 \centerparametersmaybe
+           \unhbox0 #1\par}%
+   }%
+   \nobreak\bigskip % no page break after a chapter title
+   \nobreak
+ }
+ 
+ % Plain opening for unnumbered.
+ \def\unnchfplain#1{\chfplain{#1}{}}
+ 
+ % @centerchap -- centered and unnumbered.
+ \let\centerparametersmaybe = \relax
+ \def\centerchfplain#1{{%
+   \def\centerparametersmaybe{%
+     \advance\rightskip by 3\rightskip
+     \leftskip = \rightskip
+     \parfillskip = 0pt
+   }%
+   \chfplain{#1}{}%
+ }}
+ 
+ \CHAPFplain % The default
+ 
+ \def\unnchfopen #1{%
+ \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                        \parindent=0pt\raggedright
+                        \rm #1\hfill}}\bigskip \par\nobreak
+ }
+ 
+ \def\chfopen #1#2{\chapoddpage {\chapfonts
+ \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+ \par\penalty 5000 %
+ }
+ 
+ \def\centerchfopen #1{%
+ \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                        \parindent=0pt
+                        \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+ }
+ 
+ \def\CHAPFopen{
+ \global\let\chapmacro=\chfopen
+ \global\let\unnumbchapmacro=\unnchfopen
+ \global\let\centerchapmacro=\centerchfopen}
+ 
+ 
+ % Section titles.
+ \newskip\secheadingskip
+ \def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+ \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
+ \def\plainsecheading#1{\sectionheading{sec}{}{#1}}
+ 
+ % Subsection titles.
+ \newskip \subsecheadingskip
+ \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+ \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
+ \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
+ 
+ % Subsubsection titles.
+ \let\subsubsecheadingskip = \subsecheadingskip
+ \let\subsubsecheadingbreak = \subsecheadingbreak
+ \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
+ \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
+ 
+ 
+ % Print any size section title.
+ %
+ % #1 is the section type (sec/subsec/subsubsec), #2 is the section
+ % number (maybe empty), #3 the text.
+ \def\sectionheading#1#2#3{%
+   {%
+     \expandafter\advance\csname #1headingskip\endcsname by \parskip
+     \csname #1headingbreak\endcsname
+   }%
+   {%
+     % Switch to the right set of fonts.
+     \csname #1fonts\endcsname \rm
+     %
+     % Only insert the separating space if we have a section number.
+     \def\secnum{#2}%
+     \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
+     %
+     \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+           \hangindent = \wd0 % zero if no section number
+           \unhbox0 #3}%
+   }%
+   \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak
+ }
+ 
+ 
+ \message{toc,}
+ \newwrite\tocfile
+ 
+ % Write an entry to the toc file, opening it if necessary.
+ % Called from @chapter, etc.  We supply {\folio} at the end of the
+ % argument, which will end up as the last argument to the \...entry macro.
+ % 
+ % We open the .toc file here instead of at @setfilename or any other
+ % given time so that @contents can be put in the document anywhere.
+ % 
+ \newif\iftocfileopened
+ \def\writetocentry#1{%
+   \iftocfileopened\else
+     \immediate\openout\tocfile = \jobname.toc
+     \global\tocfileopenedtrue
+   \fi
+   \iflinks \write\tocfile{#1{\folio}}\fi
+ }
+ 
+ \newskip\contentsrightmargin \contentsrightmargin=1in
+ \newcount\savepageno
+ \newcount\lastnegativepageno \lastnegativepageno = -1
+ 
+ % Finish up the main text and prepare to read what we've written
+ % to \tocfile.
+ % 
+ \def\startcontents#1{%
+    % If @setchapternewpage on, and @headings double, the contents should
+    % start on an odd page, unlike chapters.  Thus, we maintain
+    % \contentsalignmacro in parallel with \pagealignmacro.
+    % From: Torbjorn Granlund <tege at matematik.su.se>
+    \contentsalignmacro
+    \immediate\closeout\tocfile
+    %
+    % Don't need to put `Contents' or `Short Contents' in the headline.
+    % It is abundantly clear what they are.
+    \unnumbchapmacro{#1}\def\thischapter{}%
+    \savepageno = \pageno
+    \begingroup                  % Set up to handle contents files properly.
+       \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
+       % We can't do this, because then an actual ^ in a section
+       % title fails, e.g., @chapter ^ -- exponentiation.  --karl, 9jul97.
+       %\catcode`\^=7 % to see ^^e4 as \"a etc. juha at piuha.ydi.vtt.fi
+       \raggedbottom             % Worry more about breakpoints than the bottom.
+       \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+       %
+       % Roman numerals for page numbers.
+       \ifnum \pageno>0 \pageno = \lastnegativepageno \fi
+ }
+ 
+ 
+ % Normal (long) toc.
+ \def\contents{%
+    \startcontents{\putwordTableofContents}%
+      \openin 1 \jobname.toc
+      \ifeof 1 \else
+        \closein 1
+        \input \jobname.toc
+      \fi
+      \vfill \eject
+    \endgroup
+    \lastnegativepageno = \pageno
+    \pageno = \savepageno
+ }
+ 
+ % And just the chapters.
+ \def\summarycontents{%
+    \startcontents{\putwordShortContents}%
+       %
+       \let\chapentry = \shortchapentry
+       \let\unnumbchapentry = \shortunnumberedentry
+       % We want a true roman here for the page numbers.
+       \secfonts
+       \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
+       \rm
+       \hyphenpenalty = 10000
+       \advance\baselineskip by 1pt % Open it up a little.
+       \def\secentry ##1##2##3##4{}
+       \def\unnumbsecentry ##1##2{}
+       \def\subsecentry ##1##2##3##4##5{}
+       \def\unnumbsubsecentry ##1##2{}
+       \def\subsubsecentry ##1##2##3##4##5##6{}
+       \def\unnumbsubsubsecentry ##1##2{}
+       \openin 1 \jobname.toc
+       \ifeof 1 \else
+         \closein 1
+         \input \jobname.toc
+       \fi
+      \vfill \eject
+    \endgroup
+    \lastnegativepageno = \pageno
+    \pageno = \savepageno
+ }
+ \let\shortcontents = \summarycontents
+ 
+ % These macros generate individual entries in the table of contents.
+ % The first argument is the chapter or section name.
+ % The last argument is the page number.
+ % The arguments in between are the chapter number, section number, ...
+ 
+ % Chapter-level things, for both the long and short contents.
+ \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+ 
+ % See comments in \dochapentry re vbox and related settings
+ \def\shortchapentry#1#2#3{%
+   \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
+ }
+ 
+ % Typeset the label for a chapter or appendix for the short contents.
+ % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
+ % We could simplify the code here by writing out an \appendixentry
+ % command in the toc file for appendices, instead of using \chapentry
+ % for both, but it doesn't seem worth it.
+ \setbox0 = \hbox{\shortcontrm \putwordAppendix }
+ \newdimen\shortappendixwidth \shortappendixwidth = \wd0
+ 
+ \def\shortchaplabel#1{%
+   % We typeset #1 in a box of constant width, regardless of the text of
+   % #1, so the chapter titles will come out aligned.
+   \setbox0 = \hbox{#1}%
+   \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
+   %
+   % This space should be plenty, since a single number is .5em, and the
+   % widest letter (M) is 1em, at least in the Computer Modern fonts.
+   % (This space doesn't include the extra space that gets added after
+   % the label; that gets put in by \shortchapentry above.)
+   \advance\dimen0 by 1.1em
+   \hbox to \dimen0{#1\hfil}%
+ }
+ 
+ \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
+ \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
+ 
+ % Sections.
+ \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
+ \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
+ 
+ % Subsections.
+ \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
+ \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
+ 
+ % And subsubsections.
+ \def\subsubsecentry#1#2#3#4#5#6{%
+   \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
+ \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
+ 
+ % This parameter controls the indentation of the various levels.
+ \newdimen\tocindent \tocindent = 3pc
+ 
+ % Now for the actual typesetting. In all these, #1 is the text and #2 is the
+ % page number.
+ %
+ % If the toc has to be broken over pages, we want it to be at chapters
+ % if at all possible; hence the \penalty.
+ \def\dochapentry#1#2{%
+    \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+    \begingroup
+      \chapentryfonts
+      \tocentry{#1}{\dopageno{#2}}%
+    \endgroup
+    \nobreak\vskip .25\baselineskip plus.1\baselineskip
+ }
+ 
+ \def\dosecentry#1#2{\begingroup
+   \secentryfonts \leftskip=\tocindent
+   \tocentry{#1}{\dopageno{#2}}%
+ \endgroup}
+ 
+ \def\dosubsecentry#1#2{\begingroup
+   \subsecentryfonts \leftskip=2\tocindent
+   \tocentry{#1}{\dopageno{#2}}%
+ \endgroup}
+ 
+ \def\dosubsubsecentry#1#2{\begingroup
+   \subsubsecentryfonts \leftskip=3\tocindent
+   \tocentry{#1}{\dopageno{#2}}%
+ \endgroup}
+ 
+ % Final typesetting of a toc entry; we use the same \entry macro as for
+ % the index entries, but we want to suppress hyphenation here.  (We
+ % can't do that in the \entry macro, since index entries might consist
+ % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
+ \def\tocentry#1#2{\begingroup
+   \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
+   % Do not use \turnoffactive in these arguments.  Since the toc is
+   % typeset in cmr, so characters such as _ would come out wrong; we
+   % have to do the usual translation tricks.
+   \entry{#1}{#2}%
+ \endgroup}
+ 
+ % Space between chapter (or whatever) number and the title.
+ \def\labelspace{\hskip1em \relax}
+ 
+ \def\dopageno#1{{\rm #1}}
+ \def\doshortpageno#1{{\rm #1}}
+ 
+ \def\chapentryfonts{\secfonts \rm}
+ \def\secentryfonts{\textfonts}
+ \let\subsecentryfonts = \textfonts
+ \let\subsubsecentryfonts = \textfonts
+ 
+ 
+ \message{environments,}
+ 
+ % Since these characters are used in examples, it should be an even number of
+ % \tt widths. Each \tt character is 1en, so two makes it 1em.
+ % Furthermore, these definitions must come after we define our fonts.
+ \newbox\dblarrowbox    \newbox\longdblarrowbox
+ \newbox\pushcharbox    \newbox\bullbox
+ \newbox\equivbox       \newbox\errorbox
+ 
+ %{\tentt
+ %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+ %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+ %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+ %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+ % Adapted from the manmac format (p.420 of TeXbook)
+ %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+ %                                      depth .1ex\hfil}
+ %}
+ 
+ % @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+ \def\point{$\star$}
+ \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+ \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+ \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+ \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+ 
+ % Adapted from the TeXbook's \boxit.
+ {\tentt \global\dimen0 = 3em}% Width of the box.
+ \dimen2 = .55pt % Thickness of rules
+ % The text. (`r' is open on the right, `e' somewhat less so on the left.)
+ \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+ 
+ \global\setbox\errorbox=\hbox to \dimen0{\hfil
+    \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+    \advance\hsize by -2\dimen2 % Rules.
+    \vbox{
+       \hrule height\dimen2
+       \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+          \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+          \kern3pt\vrule width\dimen2}% Space to right.
+       \hrule height\dimen2}
+     \hfil}
+ 
+ % The @error{} command.
+ \def\error{\leavevmode\lower.7ex\copy\errorbox}
+ 
+ % @tex ... @end tex    escapes into raw Tex temporarily.
+ % One exception: @ is still an escape character, so that @end tex works.
+ % But \@ or @@ will get a plain tex @ character.
+ 
+ \def\tex{\begingroup
+   \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+   \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+   \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
+   \catcode `\%=14
+   \catcode 43=12 % plus
+   \catcode`\"=12
+   \catcode`\==12
+   \catcode`\|=12
+   \catcode`\<=12
+   \catcode`\>=12
+   \escapechar=`\\
+   %
+   \let\b=\ptexb
+   \let\bullet=\ptexbullet
+   \let\c=\ptexc
+   \let\,=\ptexcomma
+   \let\.=\ptexdot
+   \let\dots=\ptexdots
+   \let\equiv=\ptexequiv
+   \let\!=\ptexexclam
+   \let\i=\ptexi
+   \let\{=\ptexlbrace
+   \let\+=\tabalign
+   \let\}=\ptexrbrace
+   \let\*=\ptexstar
+   \let\t=\ptext
+   %
+   \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+   \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+   \def\@{@}%
+ \let\Etex=\endgroup}
+ 
+ % Define @lisp ... @endlisp.
+ % @lisp does a \begingroup so it can rebind things,
+ % including the definition of @endlisp (which normally is erroneous).
+ 
+ % Amount to narrow the margins by for @lisp.
+ \newskip\lispnarrowing \lispnarrowing=0.4in
+ 
+ % This is the definition that ^^M gets inside @lisp, @example, and other
+ % such environments.  \null is better than a space, since it doesn't
+ % have any width.
+ \def\lisppar{\null\endgraf}
+ 
+ % Make each space character in the input produce a normal interword
+ % space in the output.  Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ {\obeyspaces %
+ \gdef\sepspaces{\obeyspaces\let =\tie}}
+ 
+ % Define \obeyedspace to be our active space, whatever it is.  This is
+ % for use in \parsearg.
+ {\sepspaces%
+ \global\let\obeyedspace= }
+ 
+ % This space is always present above and below environments.
+ \newskip\envskipamount \envskipamount = 0pt
+ 
+ % Make spacing and below environment symmetrical.  We use \parskip here
+ % to help in doing that, since in @example-like environments \parskip
+ % is reset to zero; thus the \afterenvbreak inserts no space -- but the
+ % start of the next paragraph will insert \parskip
+ %
+ \def\aboveenvbreak{{\advance\envskipamount by \parskip
+ \endgraf \ifdim\lastskip<\envskipamount
+ \removelastskip \penalty-50 \vskip\envskipamount \fi}}
+ 
+ \let\afterenvbreak = \aboveenvbreak
+ 
+ % \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
+ \let\nonarrowing=\relax
+ 
+ % @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+ % environment contents.
+ \font\circle=lcircle10
+ \newdimen\circthick
+ \newdimen\cartouter\newdimen\cartinner
+ \newskip\normbskip\newskip\normpskip\newskip\normlskip
+ \circthick=\fontdimen8\circle
+ %
+ \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+ \def\ctr{{\hskip 6pt\circle\char'010}}
+ \def\cbl{{\circle\char'012\hskip -6pt}}
+ \def\cbr{{\hskip 6pt\circle\char'011}}
+ \def\carttop{\hbox to \cartouter{\hskip\lskip
+         \ctl\leaders\hrule height\circthick\hfil\ctr
+         \hskip\rskip}}
+ \def\cartbot{\hbox to \cartouter{\hskip\lskip
+         \cbl\leaders\hrule height\circthick\hfil\cbr
+         \hskip\rskip}}
+ %
+ \newskip\lskip\newskip\rskip
+ 
+ \long\def\cartouche{%
+ \begingroup
+         \lskip=\leftskip \rskip=\rightskip
+         \leftskip=0pt\rightskip=0pt %we want these *outside*.
+         \cartinner=\hsize \advance\cartinner by-\lskip
+                           \advance\cartinner by-\rskip
+         \cartouter=\hsize
+         \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ %                                    side, and for 6pt waste from
+ %                                    each corner char, and rule thickness
+         \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+         % Flag to tell @lisp, etc., not to narrow margin.
+         \let\nonarrowing=\comment
+         \vbox\bgroup
+                 \baselineskip=0pt\parskip=0pt\lineskip=0pt
+                 \carttop
+                 \hbox\bgroup
+                         \hskip\lskip
+                         \vrule\kern3pt
+                         \vbox\bgroup
+                                 \hsize=\cartinner
+                                 \kern3pt
+                                 \begingroup
+                                         \baselineskip=\normbskip
+                                         \lineskip=\normlskip
+                                         \parskip=\normpskip
+                                         \vskip -\parskip
+ \def\Ecartouche{%
+                                 \endgroup
+                                 \kern3pt
+                         \egroup
+                         \kern3pt\vrule
+                         \hskip\rskip
+                 \egroup
+                 \cartbot
+         \egroup
+ \endgroup
+ }}
+ 
+ 
+ % This macro is called at the beginning of all the @example variants,
+ % inside a group.
+ \def\nonfillstart{%
+   \aboveenvbreak
+   \inENV % This group ends at the end of the body
+   \hfuzz = 12pt % Don't be fussy
+   \sepspaces % Make spaces be word-separators rather than space tokens.
+   \singlespace
+   \let\par = \lisppar % don't ignore blank lines
+   \obeylines % each line of input is a line of output
+   \parskip = 0pt
+   \parindent = 0pt
+   \emergencystretch = 0pt % don't try to avoid overfull boxes
+   % @cartouche defines \nonarrowing to inhibit narrowing
+   % at next level down.
+   \ifx\nonarrowing\relax
+     \advance \leftskip by \lispnarrowing
+     \exdentamount=\lispnarrowing
+     \let\exdent=\nofillexdent
+     \let\nonarrowing=\relax
+   \fi
+ }
+ 
+ % Define the \E... control sequence only if we are inside the particular
+ % environment, so the error checking in \end will work.
+ % 
+ % To end an @example-like environment, we first end the paragraph (via
+ % \afterenvbreak's vertical glue), and then the group.  That way we keep
+ % the zero \parskip that the environments set -- \parskip glue will be
+ % inserted at the beginning of the next paragraph in the document, after
+ % the environment.
+ %
+ \def\nonfillfinish{\afterenvbreak\endgroup}
+ 
+ % @lisp: indented, narrowed, typewriter font.
+ \def\lisp{\begingroup
+   \nonfillstart
+   \let\Elisp = \nonfillfinish
+   \tt
+   \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+   \gobble       % eat return
+ }
+ 
+ % @example: Same as @lisp.
+ \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+ 
+ % @small... is usually equivalent to the non-small (@smallbook
+ % redefines).  We must call \example (or whatever) last in the
+ % definition, since it reads the return following the @example (or
+ % whatever) command.
+ % 
+ % This actually allows (for example) @end display inside an
+ % @smalldisplay.  Too bad, but makeinfo will catch the error anyway.
+ %
+ \def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display}
+ \def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+ \def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format}
+ \def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+ 
+ % Real @smallexample and @smalllisp (when @smallbook): use smaller fonts.
+ % Originally contributed by Pavel at xerox.
+ \def\smalllispx{\begingroup
+   \def\Esmalllisp{\nonfillfinish\endgroup}%
+   \def\Esmallexample{\nonfillfinish\endgroup}%
+   \indexfonts
+   \lisp
+ }
+ 
+ % @display: same as @lisp except keep current font.
+ %
+ \def\display{\begingroup
+   \nonfillstart
+   \let\Edisplay = \nonfillfinish
+   \gobble
+ }
+ 
+ % @smalldisplay (when @smallbook): @display plus smaller fonts.
+ %
+ \def\smalldisplayx{\begingroup
+   \def\Esmalldisplay{\nonfillfinish\endgroup}%
+   \indexfonts \rm
+   \display
+ }
+ 
+ % @format: same as @display except don't narrow margins.
+ %
+ \def\format{\begingroup
+   \let\nonarrowing = t
+   \nonfillstart
+   \let\Eformat = \nonfillfinish
+   \gobble
+ }
+ 
+ % @smallformat (when @smallbook): @format plus smaller fonts.
+ %
+ \def\smallformatx{\begingroup
+   \def\Esmallformat{\nonfillfinish\endgroup}%
+   \indexfonts \rm
+   \format
+ }
+ 
+ % @flushleft (same as @format).
+ %
+ \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format}
+ 
+ % @flushright.
+ % 
+ \def\flushright{\begingroup
+   \let\nonarrowing = t
+   \nonfillstart
+   \let\Eflushright = \nonfillfinish
+   \advance\leftskip by 0pt plus 1fill
+   \gobble
+ }
+ 
+ % @quotation does normal linebreaking (hence we can't use \nonfillstart)
+ % and narrows the margins.
+ %
+ \def\quotation{%
+   \begingroup\inENV %This group ends at the end of the @quotation body
+   {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+   \singlespace
+   \parindent=0pt
+   % We have retained a nonzero parskip for the environment, since we're
+   % doing normal filling. So to avoid extra space below the environment...
+   \def\Equotation{\parskip = 0pt \nonfillfinish}%
+   %
+   % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+   \ifx\nonarrowing\relax
+     \advance\leftskip by \lispnarrowing
+     \advance\rightskip by \lispnarrowing
+     \exdentamount = \lispnarrowing
+     \let\nonarrowing = \relax
+   \fi
+ }
+ 
+ 
+ \message{defuns,}
+ % Define formatter for defuns
+ % First, allow user to change definition object font (\df) internally
+ \def\setdeffont #1 {\csname DEF#1\endcsname}
+ 
+ \newskip\defbodyindent \defbodyindent=.4in
+ \newskip\defargsindent \defargsindent=50pt
+ \newskip\deftypemargin \deftypemargin=12pt
+ \newskip\deflastargmargin \deflastargmargin=18pt
+ 
+ \newcount\parencount
+ % define \functionparens, which makes ( and ) and & do special things.
+ % \functionparens affects the group it is contained in.
+ \def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
+ \catcode`\[=\active \catcode`\]=\active}
+ 
+ % Make control sequences which act like normal parenthesis chars.
+ \let\lparen = ( \let\rparen = )
+ 
+ {\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
+ 
+ % Be sure that we always have a definition for `(', etc.  For example,
+ % if the fn name has parens in it, \boldbrax will not be in effect yet,
+ % so TeX would otherwise complain about undefined control sequence.
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ 
+ \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ % This is used to turn on special parens
+ % but make & act ordinary (given that it's active).
+ \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr}
+ 
+ % Definitions of (, ) and & used in args for functions.
+ % This is the definition of ( outside of all parentheses.
+ \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested
+   \global\advance\parencount by 1
+ }
+ %
+ % This is the definition of ( when already inside a level of parens.
+ \gdef\opnested{\char`\(\global\advance\parencount by 1 }
+ %
+ \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
+   % also in that case restore the outer-level definition of (.
+   \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
+   \global\advance \parencount by -1 }
+ % If we encounter &foo, then turn on ()-hacking afterwards
+ \gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
+ %
+ \gdef\normalparens{\boldbrax\let&=\ampnr}
+ } % End of definition inside \activeparens
+ %% These parens (in \boldbrax) actually are a little bolder than the
+ %% contained text.  This is especially needed for [ and ]
+ \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 }
+ \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 }
+ \def\ampnr{\&}
+ \def\lbrb{{\bf\char`\[}}
+ \def\rbrb{{\bf\char`\]}}
+ 
+ % First, defname, which formats the header line itself.
+ % #1 should be the function name.
+ % #2 should be the type of definition, such as "Function".
+ 
+ \def\defname #1#2{%
+ % Get the values of \leftskip and \rightskip as they were
+ % outside the @def...
+ \dimen2=\leftskip
+ \advance\dimen2 by -\defbodyindent
+ \noindent
+ \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
+ \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
+ \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
+ \parshape 2 0in \dimen0 \defargsindent \dimen1
+ % Now output arg 2 ("Function" or some such)
+ % ending at \deftypemargin from the right margin,
+ % but stuck inside a box of width 0 so it does not interfere with linebreaking
+ {% Adjust \hsize to exclude the ambient margins,
+ % so that \rightline will obey them.
+ \advance \hsize by -\dimen2
+ \rlap{\rightline{{\rm #2}\hskip -1.25pc }}}%
+ % Make all lines underfull and no complaints:
+ \tolerance=10000 \hbadness=10000
+ \advance\leftskip by -\defbodyindent
+ \exdentamount=\defbodyindent
+ {\df #1}\enskip        % Generate function name
+ }
+ 
+ % Actually process the body of a definition
+ % #1 should be the terminating control sequence, such as \Edefun.
+ % #2 should be the "another name" control sequence, such as \defunx.
+ % #3 should be the control sequence that actually processes the header,
+ %    such as \defunheader.
+ 
+ \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup %
+ \catcode 61=\active % 61 is `='
+ \obeylines\activeparens\spacesplit#3}
+ 
+ % #1 is the \E... control sequence to end the definition (which we define).
+ % #2 is the \...x control sequence for consecutive fns (which we define).
+ % #3 is the control sequence to call to resume processing.
+ % #4, delimited by the space, is the class name.
+ % 
+ \def\defmethparsebody#1#2#3#4 {\begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+ 
+ % @deftypemethod has an extra argument that nothing else does.  Sigh.
+ % #1 is the \E... control sequence to end the definition (which we define).
+ % #2 is the \...x control sequence for consecutive fns (which we define).
+ % #3 is the control sequence to call to resume processing.
+ % #4, delimited by the space, is the class name.
+ % #5 is the method's return type.
+ % 
+ \def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}}
+ 
+ \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 ##2 {\def#4{##1}%
+ \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+ 
+ % These parsing functions are similar to the preceding ones
+ % except that they do not make parens into active characters.
+ % These are used for "variables" since they have no arguments.
+ 
+ \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2{\begingroup\obeylines\spacesplit#3}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup %
+ \catcode 61=\active %
+ \obeylines\spacesplit#3}
+ 
+ % This is used for \def{tp,vr}parsebody.  It could probably be used for
+ % some of the others, too, with some judicious conditionals.
+ %
+ \def\parsebodycommon#1#2#3{%
+   \begingroup\inENV %
+   \medbreak %
+   % Define the end token that this defining construct specifies
+   % so that it will exit this group.
+   \def#1{\endgraf\endgroup\medbreak}%
+   \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
+   \parindent=0in
+   \advance\leftskip by \defbodyindent
+   \exdentamount=\defbodyindent
+   \begingroup\obeylines
+ }
+ 
+ \def\defvrparsebody#1#2#3#4 {%
+   \parsebodycommon{#1}{#2}{#3}%
+   \spacesplit{#3{#4}}%
+ }
+ 
+ % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
+ % type is just `struct', because we lose the braces in `{struct
+ % termios}' when \spacesplit reads its undelimited argument.  Sigh.
+ % \let\deftpparsebody=\defvrparsebody
+ %
+ % So, to get around this, we put \empty in with the type name.  That
+ % way, TeX won't find exactly `{...}' as an undelimited argument, and
+ % won't strip off the braces.
+ %
+ \def\deftpparsebody #1#2#3#4 {%
+   \parsebodycommon{#1}{#2}{#3}%
+   \spacesplit{\parsetpheaderline{#3{#4}}}\empty
+ }
+ 
+ % Fine, but then we have to eventually remove the \empty *and* the
+ % braces (if any).  That's what this does.
+ %
+ \def\removeemptybraces\empty#1\relax{#1}
+ 
+ % After \spacesplit has done its work, this is called -- #1 is the final
+ % thing to call, #2 the type name (which starts with \empty), and #3
+ % (which might be empty) the arguments.
+ %
+ \def\parsetpheaderline#1#2#3{%
+   #1{\removeemptybraces#2\relax}{#3}%
+ }%
+ 
+ \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 ##2 {\def#4{##1}%
+ \begingroup\obeylines\spacesplit{#3{##2}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines\spacesplit{#3{#5}}}
+ 
+ % Split up #2 at the first space token.
+ % call #1 with two arguments:
+ %  the first is all of #2 before the space token,
+ %  the second is all of #2 after that space token.
+ % If #2 contains no space token, all of it is passed as the first arg
+ % and the second is passed as empty.
+ 
+ {\obeylines
+ \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
+ \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
+ \ifx\relax #3%
+ #1{#2}{}\else #1{#2}{#3#4}\fi}}
+ 
+ % So much for the things common to all kinds of definitions.
+ 
+ % Define @defun.
+ 
+ % First, define the processing that is wanted for arguments of \defun
+ % Use this to expand the args and terminate the paragraph they make up
+ 
+ \def\defunargs #1{\functionparens \sl
+ % Expand, preventing hyphenation at `-' chars.
+ % Note that groups don't affect changes in \hyphenchar.
+ \hyphenchar\tensl=0
+ #1%
+ \hyphenchar\tensl=45
+ \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi%
+ \interlinepenalty=10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf\nobreak\vskip -\parskip\nobreak
+ }
+ 
+ \def\deftypefunargs #1{%
+ % Expand, preventing hyphenation at `-' chars.
+ % Note that groups don't affect changes in \hyphenchar.
+ % Use \boldbraxnoamp, not \functionparens, so that & is not special.
+ \boldbraxnoamp
+ \tclose{#1}% avoid \code because of side effects on active chars
+ \interlinepenalty=10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf\nobreak\vskip -\parskip\nobreak
+ }
+ 
+ % Do complete processing of one @defun or @defunx line already parsed.
+ 
+ % @deffn Command forward-char nchars
+ 
+ \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+ 
+ \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
+ \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % @defun == @deffn Function
+ 
+ \def\defun{\defparsebody\Edefun\defunx\defunheader}
+ 
+ \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+ \begingroup\defname {#1}{Function}%
+ \defunargs {#2}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % @deftypefun int foobar (int @var{foo}, float @var{bar})
+ 
+ \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+ 
+ % #1 is the data type.  #2 is the name and args.
+ \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
+ % #1 is the data type, #2 the name, #3 the args.
+ \def\deftypefunheaderx #1#2 #3\relax{%
+ \doind {fn}{\code{#2}}% Make entry in function index
+ \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
+ \deftypefunargs {#3}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
+ 
+ \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+ 
+ % \defheaderxcond#1\relax$$$
+ % puts #1 in @code, followed by a space, but does nothing if #1 is null.
+ \def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
+ 
+ % #1 is the classification.  #2 is the data type.  #3 is the name and args.
+ \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
+ % #1 is the classification, #2 the data type, #3 the name, #4 the args.
+ \def\deftypefnheaderx #1#2#3 #4\relax{%
+ \doind {fn}{\code{#3}}% Make entry in function index
+ \begingroup
+ \normalparens % notably, turn off `&' magic, which prevents
+ %               at least some C++ text from working
+ \defname {\defheaderxcond#2\relax$$$#3}{#1}%
+ \deftypefunargs {#4}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % @defmac == @deffn Macro
+ 
+ \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
+ 
+ \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+ \begingroup\defname {#1}{Macro}%
+ \defunargs {#2}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % @defspec == @deffn Special Form
+ 
+ \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+ 
+ \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+ \begingroup\defname {#1}{Special Form}%
+ \defunargs {#2}\endgroup %
+ \catcode 61=\other % Turn off change made in \defparsebody
+ }
+ 
+ % This definition is run if you use @defunx
+ % anywhere other than immediately after a @defun or @defunx.
+ 
+ \def\deffnx #1 {\errmessage{@deffnx in invalid context}}
+ \def\defunx #1 {\errmessage{@defunx in invalid context}}
+ \def\defmacx #1 {\errmessage{@defmacx in invalid context}}
+ \def\defspecx #1 {\errmessage{@defspecx in invalid context}}
+ \def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
+ \def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}}
+ \def\deftypefunx #1 {\errmessage{@deftypefunx in invalid context}}
+ 
+ % @defmethod, and so on
+ 
+ % @defop CATEGORY CLASS OPERATION ARG...
+ 
+ \def\defop #1 {\def\defoptype{#1}%
+ \defopparsebody\Edefop\defopx\defopheader\defoptype}
+ 
+ \def\defopheader #1#2#3{%
+ \dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index
+ \begingroup\defname {#2}{\defoptype{} on #1}%
+ \defunargs {#3}\endgroup %
+ }
+ 
+ % @deftypemethod CLASS RETURN-TYPE METHOD ARG...
+ %
+ \def\deftypemethod{%
+   \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader}
+ %
+ % #1 is the class name, #2 the data type, #3 the method name, #4 the args.
+ \def\deftypemethodheader#1#2#3#4{%
+   \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
+   \begingroup
+     \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}%
+     \deftypefunargs{#4}%
+   \endgroup
+ }
+ 
+ % @defmethod == @defop Method
+ %
+ \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+ %
+ % #1 is the class name, #2 the method name, #3 the args.
+ \def\defmethodheader#1#2#3{%
+   \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index
+   \begingroup
+     \defname{#2}{\putwordMethodon\ \code{#1}}%
+     \defunargs{#3}%
+   \endgroup
+ }
+ 
+ % @defcv {Class Option} foo-class foo-flag
+ 
+ \def\defcv #1 {\def\defcvtype{#1}%
+ \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
+ 
+ \def\defcvarheader #1#2#3{%
+ \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+ \begingroup\defname {#2}{\defcvtype{} of #1}%
+ \defvarargs {#3}\endgroup %
+ }
+ 
+ % @defivar == @defcv {Instance Variable}
+ 
+ \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
+ 
+ \def\defivarheader #1#2#3{%
+ \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+ \begingroup\defname {#2}{Instance Variable of #1}%
+ \defvarargs {#3}\endgroup %
+ }
+ 
+ % These definitions are run if you use @defmethodx, etc.,
+ % anywhere other than immediately after a @defmethod, etc.
+ 
+ \def\defopx #1 {\errmessage{@defopx in invalid context}}
+ \def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
+ \def\defcvx #1 {\errmessage{@defcvx in invalid context}}
+ \def\defivarx #1 {\errmessage{@defivarx in invalid context}}
+ 
+ % Now @defvar
+ 
+ % First, define the processing that is wanted for arguments of @defvar.
+ % This is actually simple: just print them in roman.
+ % This must expand the args and terminate the paragraph they make up
+ \def\defvarargs #1{\normalparens #1%
+ \interlinepenalty=10000
+ \endgraf\nobreak\vskip -\parskip\nobreak}
+ 
+ % @defvr Counter foo-count
+ 
+ \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
+ 
+ \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
+ \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
+ 
+ % @defvar == @defvr Variable
+ 
+ \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
+ 
+ \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+ \begingroup\defname {#1}{Variable}%
+ \defvarargs {#2}\endgroup %
+ }
+ 
+ % @defopt == @defvr {User Option}
+ 
+ \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
+ 
+ \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+ \begingroup\defname {#1}{User Option}%
+ \defvarargs {#2}\endgroup %
+ }
+ 
+ % @deftypevar int foobar
+ 
+ \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
+ 
+ % #1 is the data type.  #2 is the name, perhaps followed by text that
+ % is actually part of the data type, which should not be put into the index.
+ \def\deftypevarheader #1#2{%
+ \dovarind#2 \relax% Make entry in variables index
+ \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+ \interlinepenalty=10000
+ \endgraf\nobreak\vskip -\parskip\nobreak
+ \endgroup}
+ \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}}
+ 
+ % @deftypevr {Global Flag} int enable
+ 
+ \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+ 
+ \def\deftypevrheader #1#2#3{\dovarind#3 \relax%
+ \begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+ \interlinepenalty=10000
+ \endgraf\nobreak\vskip -\parskip\nobreak
+ \endgroup}
+ 
+ % This definition is run if you use @defvarx
+ % anywhere other than immediately after a @defvar or @defvarx.
+ 
+ \def\defvrx #1 {\errmessage{@defvrx in invalid context}}
+ \def\defvarx #1 {\errmessage{@defvarx in invalid context}}
+ \def\defoptx #1 {\errmessage{@defoptx in invalid context}}
+ \def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
+ \def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
+ 
+ % Now define @deftp
+ % Args are printed in bold, a slight difference from @defvar.
+ 
+ \def\deftpargs #1{\bf \defvarargs{#1}}
+ 
+ % @deftp Class window height width ...
+ 
+ \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
+ 
+ \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
+ \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
+ 
+ % This definition is run if you use @deftpx, etc
+ % anywhere other than immediately after a @deftp, etc.
+ 
+ \def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+ 
+ 
+ \message{macros,}
+ % @macro.
+ 
+ % To do this right we need a feature of e-TeX, \scantokens, 
+ % which we arrange to emulate with a temporary file in ordinary TeX.
+ \ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scanmacro#1{%
+    \begingroup \newlinechar`\^^M
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{#1}%
+    \immediate\closeout\macscribble
+    \let\xeatspaces\eatspaces
+    \input \jobname.tmp
+    \endgroup
+ }
+ \else
+ \def\scanmacro#1{%
+ \begingroup \newlinechar`\^^M
+ \let\xeatspaces\eatspaces\scantokens{#1}\endgroup}
+ \fi
+ 
+ \newcount\paramno   % Count of parameters
+ \newtoks\macname    % Macro name
+ \newif\ifrecursive  % Is it recursive?
+ 
+ % Utility routines.
+ % Thisdoes \let #1 = #2, except with \csnames.
+ \def\cslet#1#2{%
+ \expandafter\expandafter
+ \expandafter\let
+ \expandafter\expandafter
+ \csname#1\endcsname
+ \csname#2\endcsname}
+ 
+ % Trim leading and trailing spaces off a string.
+ % Concepts from aro-bend problem 15 (see CTAN).
+ {\catcode`\@=11
+ \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+ \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+ \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+ \def\unbrace#1{#1}
+ \unbrace{\gdef\trim@@@ #1 } #2@{#1}
+ }
+ 
+ % Trim a single trailing ^^M off a string.
+ {\catcode`\^^M=12\catcode`\Q=3%
+ \gdef\eatcr #1{\eatcra #1Q^^MQ}%
+ \gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+ \gdef\eatcrb#1Q#2Q{#1}%
+ }
+ 
+ % Macro bodies are absorbed as an argument in a context where
+ % all characters are catcode 10, 11 or 12, except \ which is active
+ % (as in normal texinfo). It is necessary to change the definition of \.
+ 
+ % It's necessary to have hard CRs when the macro is executed. This is 
+ % done by  making ^^M (\endlinechar) catcode 12 when reading the macro 
+ % body, and then making it the \newlinechar in \scanmacro.
+ 
+ \def\macrobodyctxt{%
+   \catcode`\~=12
+   \catcode`\^=12
+   \catcode`\_=12
+   \catcode`\|=12
+   \catcode`\<=12
+   \catcode`\>=12
+   \catcode`\+=12
+   \catcode`\{=12
+   \catcode`\}=12
+   \catcode`\@=12
+   \catcode`\^^M=12
+   \usembodybackslash}
+ 
+ \def\macroargctxt{%
+   \catcode`\~=12
+   \catcode`\^=12
+   \catcode`\_=12
+   \catcode`\|=12
+   \catcode`\<=12
+   \catcode`\>=12
+   \catcode`\+=12
+   \catcode`\@=12
+   \catcode`\\=12}
+ 
+ % \mbodybackslash is the definition of \ in @macro bodies.
+ % It maps \foo\ => \csname macarg.foo\endcsname => #N 
+ % where N is the macro parameter number.
+ % We define \csname macarg.\endcsname to be \realbackslash, so
+ % \\ in macro replacement text gets you a backslash.
+ 
+ {\catcode`@=0 @catcode`@\=@active
+  @gdef at usembodybackslash{@let\=@mbodybackslash}
+  @gdef at mbodybackslash#1\{@csname macarg.#1 at endcsname}
+ }
+ \expandafter\def\csname macarg.\endcsname{\realbackslash}
+ 
+ \def\macro{\recursivefalse\parsearg\macroxxx}
+ \def\rmacro{\recursivetrue\parsearg\macroxxx}
+ 
+ \def\macroxxx#1{%
+   \getargs{#1}%           now \macname is the macname and \argl the arglist
+   \ifx\argl\empty       % no arguments
+      \paramno=0%
+   \else
+      \expandafter\parsemargdef \argl;% 
+   \fi
+   \expandafter\ifx \csname macsave.\the\macname\endcsname \relax
+      \cslet{macsave.\the\macname}{\the\macname}%
+   \else
+      \message{Warning: redefining \the\macname}%
+   \fi
+   \begingroup \macrobodyctxt
+   \ifrecursive \expandafter\parsermacbody
+   \else \expandafter\parsemacbody 
+   \fi}
+ 
+ \def\unmacro{\parsearg\unmacroxxx}
+ \def\unmacroxxx#1{%
+   \expandafter\ifx \csname macsave.\the\macname\endcsname \relax
+     \errmessage{Macro \the\macname\ not defined.}%
+   \else
+     \cslet{#1}{macsave.#1}%
+     \expandafter\let \csname macsave.\the\macname\endcsname \undefined
+   \fi
+ }
+ 
+ % This makes use of the obscure feature that if the last token of a
+ % <parameter list> is #, then the preceding argument is delimited by
+ % an opening brace, and that opening brace is not consumed.
+ \def\getargs#1{\getargsxxx#1{}}
+ \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+ \def\getmacname #1 #2\relax{\macname={#1}}
+ \def\getmacargs#1{\def\argl{#1}}
+ 
+ % Parse the optional {params} list.  Set up \paramno and \paramlist
+ % so \defmacro knows what to do.  Define \macarg.blah for each blah
+ % in the params list, to be ##N where N is the position in that list.
+ % That gets used by \mbodybackslash (above).
+ 
+ % We need to get `macro parameter char #' into several definitions.
+ % The technique used is stolen from LaTeX:  let \hash be something
+ % unexpandable, insert that wherever you need a #, and then redefine
+ % it to # just before using the token list produced.
+ %
+ % The same technique is used to protect \eatspaces till just before
+ % the macro is used.
+ 
+ \def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+         \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+ \def\parsemargdefxxx#1,{%
+   \if#1;\let\next=\relax
+   \else \let\next=\parsemargdefxxx
+     \advance\paramno by 1%
+     \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+         {\xeatspaces{\hash\the\paramno}}%
+     \edef\paramlist{\paramlist\hash\the\paramno,}%
+   \fi\next}
+ 
+ % These two commands read recursive and nonrecursive macro bodies.
+ % (They're different since rec and nonrec macros end differently.)
+ 
+ \long\def\parsemacbody#1 at end macro%
+ {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+ \long\def\parsermacbody#1 at end rmacro%
+ {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+ 
+ % This defines the macro itself. There are six cases: recursive and
+ % nonrecursive macros of zero, one, and many arguments.
+ % Much magic with \expandafter here.
+ % \xdef is used so that macro definitions will survive the file
+ % they're defined in; @include reads the file inside a group.
+ \def\defmacro{%
+   \let\hash=##% convert placeholders to macro parameter chars
+   \ifrecursive
+     \ifcase\paramno
+     % 0
+       \expandafter\xdef\csname\the\macname\endcsname{%
+         \noexpand\scanmacro{\temp}}%
+     \or % 1
+       \expandafter\xdef\csname\the\macname\endcsname{%
+          \bgroup\noexpand\macroargctxt
+          \noexpand\braceorline\csname\the\macname xxx\endcsname}%
+       \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+          \egroup\noexpand\scanmacro{\temp}}%
+     \else % many
+       \expandafter\xdef\csname\the\macname\endcsname{%
+          \bgroup\noexpand\macroargctxt
+          \noexpand\csname\the\macname xx\endcsname}
+       \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+           \csname\the\macname xxx\endcsname ##1,}%
+       \expandafter\expandafter
+       \expandafter\xdef
+       \expandafter\expandafter
+         \csname\the\macname xxx\endcsname 
+           \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+     \fi
+   \else
+     \ifcase\paramno
+     % 0
+       \expandafter\xdef\csname\the\macname\endcsname{%
+         \noexpand\norecurse{\the\macname}%
+         \noexpand\scanmacro{\temp}\egroup}%
+     \or % 1
+       \expandafter\xdef\csname\the\macname\endcsname{%
+          \bgroup\noexpand\macroargctxt
+          \noexpand\braceorline\csname\the\macname xxx\endcsname}%
+       \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup
+         \noexpand\norecurse{\the\macname}%
+         \noexpand\scanmacro{\temp}\egroup}%
+     \else % many
+       \expandafter\xdef\csname\the\macname\endcsname{%
+          \bgroup\noexpand\macroargctxt
+          \noexpand\csname\the\macname xx\endcsname}
+       \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+           \csname\the\macname xxx\endcsname ##1,}%
+       \expandafter\expandafter
+       \expandafter\xdef
+       \expandafter\expandafter
+       \csname\the\macname xxx\endcsname
+       \paramlist{%
+           \egroup
+           \noexpand\norecurse{\the\macname}%
+           \noexpand\scanmacro{\temp}\egroup}%
+     \fi
+   \fi}
+ 
+ \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+ 
+ % \braceorline decides whether the next nonwhitespace character is a
+ % {.  If so it reads up to the closing }, if not, it reads the whole
+ % line.  Whatever was read is then fed to the next control sequence
+ % as an argument (by \parsebrace or \parsearg)
+ \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+ \def\braceorlinexxx{%
+   \ifx\nchar\bgroup\else
+     \expandafter\parsearg 
+   \fi \next}
+ 
+ 
+ \message{cross references,}
+ \newwrite\auxfile
+ 
+ \newif\ifhavexrefs    % True if xref values are known.
+ \newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+ 
+ % @inforef is relatively simple.
+ \def\inforef #1{\inforefzzz #1,,,,**}
+ \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+   node \samp{\ignorespaces#1{}}}
+ 
+ % @node's job is to define \lastnode.
+ \def\node{\ENVcheck\parsearg\nodezzz}
+ \def\nodezzz#1{\nodexxx [#1,]}
+ \def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+ \let\nwnode=\node
+ \let\lastnode=\relax
+ 
+ % The sectioning commands (@chapter, etc.) call these.
+ \def\donoderef{%
+   \ifx\lastnode\relax\else
+     \expandafter\expandafter\expandafter\setref{\lastnode}%
+       {Ysectionnumberandtype}%
+     \global\let\lastnode=\relax
+   \fi
+ }
+ \def\unnumbnoderef{%
+   \ifx\lastnode\relax\else
+     \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}%
+     \global\let\lastnode=\relax
+   \fi
+ }
+ \def\appendixnoderef{%
+   \ifx\lastnode\relax\else
+     \expandafter\expandafter\expandafter\setref{\lastnode}%
+       {Yappendixletterandtype}%
+     \global\let\lastnode=\relax
+   \fi
+ }
+ 
+ 
+ % @anchor{NAME} -- define xref target at arbitrary point.
+ % 
+ \def\anchor#1{\setref{#1}{Ynothing}}
+ 
+ 
+ % \setref{NAME}{SNT} defines a cross-reference point NAME, namely
+ % NAME-title, NAME-pg, and NAME-SNT.  Called from \foonoderef.  We have
+ % to set \indexdummies so commands such as @code in a section title
+ % aren't expanded.  It would be nicer not to expand the titles in the
+ % first place, but there's so many layers that that is hard to do.
+ % 
+ \def\setref#1#2{{%
+   \indexdummies
+   \dosetq{#1-title}{Ytitle}%
+   \dosetq{#1-pg}{Ypagenumber}%
+   \dosetq{#1-snt}{#2}
+ }}
+ 
+ % @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+ % the node name, #2 the name of the Info cross-reference, #3 the printed
+ % node name, #4 the name of the Info file, #5 the name of the printed
+ % manual.  All but the node name can be omitted.
+ %
+ \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+ \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+ \def\ref#1{\xrefX[#1,,,,,,,]}
+ \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+   \def\printedmanual{\ignorespaces #5}%
+   \def\printednodename{\ignorespaces #3}%
+   \setbox1=\hbox{\printedmanual}%
+   \setbox0=\hbox{\printednodename}%
+   \ifdim \wd0 = 0pt
+     % No printed node name was explicitly given.
+     \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+       % Use the node name inside the square brackets.
+       \def\printednodename{\ignorespaces #1}%
+     \else
+       % Use the actual chapter/section title appear inside
+       % the square brackets.  Use the real section title if we have it.
+       \ifdim \wd1 > 0pt
+         % It is in another manual, so we don't have it.
+         \def\printednodename{\ignorespaces #1}%
+       \else
+         \ifhavexrefs
+           % We know the real title if we have the xref values.
+           \def\printednodename{\refx{#1-title}{}}%
+         \else
+           % Otherwise just copy the Info node name.
+           \def\printednodename{\ignorespaces #1}%
+         \fi%
+       \fi
+     \fi
+   \fi
+   %
+   % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+   % insert empty discretionaries after hyphens, which means that it will
+   % not find a line break at a hyphen in a node names.  Since some manuals
+   % are best written with fairly long node names, containing hyphens, this
+   % is a loss.  Therefore, we give the text of the node name again, so it
+   % is as if TeX is seeing it for the first time.
+   \ifdim \wd1 > 0pt
+     \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
+   \else
+     % _ (for example) has to be the character _ for the purposes of the
+     % control sequence corresponding to the node, but it has to expand
+     % into the usual \leavevmode...\vrule stuff for purposes of
+     % printing. So we \turnoffactive for the \refx-snt, back on for the
+     % printing, back off for the \refx-pg.
+     {\normalturnoffactive
+      % Only output a following space if the -snt ref is nonempty; for
+      % @unnumbered and @anchor, it won't be.
+      \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+      \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+     }%
+     % [mynode], 
+     [\printednodename],\space
+     % page 3
+     \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+   \fi
+ \endgroup}
+ 
+ % \dosetq is the interface for calls from other macros
+ 
+ % Use \normalturnoffactive so that punctuation chars such as underscore
+ % and backslash work in node names.  (\turnoffactive doesn't do \.)
+ \def\dosetq#1#2{%
+   {\let\folio=0
+    \normalturnoffactive
+    \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}%
+    \iflinks
+      \next
+    \fi
+   }%
+ }
+ 
+ % \internalsetq {foo}{page} expands into
+ % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
+ % When the aux file is read, ' is the escape character
+ 
+ \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
+ 
+ % Things to be expanded by \internalsetq
+ 
+ \def\Ypagenumber{\folio}
+ 
+ \def\Ytitle{\thissection}
+ 
+ \def\Ynothing{}
+ 
+ \def\Ysectionnumberandtype{%
+ \ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
+ \else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
+ \else \ifnum \subsubsecno=0 %
+ \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
+ \else %
+ \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
+ \fi \fi \fi }
+ 
+ \def\Yappendixletterandtype{%
+ \ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
+ \else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
+ \else \ifnum \subsubsecno=0 %
+ \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+ \else %
+ \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+ \fi \fi \fi }
+ 
+ \gdef\xreftie{'tie}
+ 
+ % Use TeX 3.0's \inputlineno to get the line number, for better error
+ % messages, but if we're using an old version of TeX, don't do anything.
+ %
+ \ifx\inputlineno\thisisundefined
+   \let\linenumber = \empty % Non-3.0.
+ \else
+   \def\linenumber{\the\inputlineno:\space}
+ \fi
+ 
+ % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+ % If its value is nonempty, SUFFIX is output afterward.
+ 
+ \def\refx#1#2{%
+   \expandafter\ifx\csname X#1\endcsname\relax
+     % If not defined, say something at least.
+     \angleleft un\-de\-fined\angleright
+     \iflinks
+       \ifhavexrefs
+         \message{\linenumber Undefined cross reference `#1'.}%
+       \else
+         \ifwarnedxrefs\else
+           \global\warnedxrefstrue
+           \message{Cross reference values unknown; you must run TeX again.}%
+         \fi
+       \fi
+     \fi
+   \else
+     % It's defined, so just use it.
+     \csname X#1\endcsname
+   \fi
+   #2% Output the suffix in any case.
+ }
+ 
+ % This is the macro invoked by entries in the aux file.
+ % 
+ \def\xrdef#1{\begingroup
+   % Reenable \ as an escape while reading the second argument.
+   \catcode`\\ = 0
+   \afterassignment\endgroup
+   \expandafter\gdef\csname X#1\endcsname
+ }
+ 
+ % Read the last existing aux file, if any.  No error if none exists.
+ \def\readauxfile{\begingroup
+   \catcode`\^^@=\other
+   \catcode`\^^A=\other
+   \catcode`\^^B=\other
+   \catcode`\^^C=\other
+   \catcode`\^^D=\other
+   \catcode`\^^E=\other
+   \catcode`\^^F=\other
+   \catcode`\^^G=\other
+   \catcode`\^^H=\other
+   \catcode`\^^K=\other
+   \catcode`\^^L=\other
+   \catcode`\^^N=\other
+   \catcode`\^^P=\other
+   \catcode`\^^Q=\other
+   \catcode`\^^R=\other
+   \catcode`\^^S=\other
+   \catcode`\^^T=\other
+   \catcode`\^^U=\other
+   \catcode`\^^V=\other
+   \catcode`\^^W=\other
+   \catcode`\^^X=\other
+   \catcode`\^^Z=\other
+   \catcode`\^^[=\other
+   \catcode`\^^\=\other
+   \catcode`\^^]=\other
+   \catcode`\^^^=\other
+   \catcode`\^^_=\other
+   \catcode`\@=\other
+   \catcode`\^=\other
+   % It was suggested to define this as 7, which would allow ^^e4 etc.
+   % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+   % supported in the main text, it doesn't seem desirable.  Furthermore,
+   % that is not enough: for node names that actually contain a ^
+   % character, we would end up writing a line like this: 'xrdef {'hat
+   % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+   % argument, and \hat is not an expandable control sequence.  It could
+   % all be worked out, but why?  Either we support ^^ or we don't.
+   %
+   % The other change necessary for this was to define \auxhat:
+   % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+   % and then to call \auxhat in \setq.
+   %
+   \catcode`\~=\other
+   \catcode`\[=\other
+   \catcode`\]=\other
+   \catcode`\"=\other
+   \catcode`\_=\other
+   \catcode`\|=\other
+   \catcode`\<=\other
+   \catcode`\>=\other
+   \catcode`\$=\other
+   \catcode`\#=\other
+   \catcode`\&=\other
+   \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+   % Make the characters 128-255 be printing characters
+   {%
+     \count 1=128
+     \def\loop{%
+       \catcode\count 1=\other
+       \advance\count 1 by 1
+       \ifnum \count 1<256 \loop \fi
+     }%
+   }%
+   % The aux file uses ' as the escape (for now).
+   % Turn off \ as an escape so we do not lose on
+   % entries which were dumped with control sequences in their names.
+   % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+   % Reference to such entries still does not work the way one would wish,
+   % but at least they do not bomb out when the aux file is read in.
+   \catcode`\{=1
+   \catcode`\}=2
+   \catcode`\%=\other
+   \catcode`\'=0
+   \catcode`\\=\other
+   %
+   \openin 1 \jobname.aux
+   \ifeof 1 \else
+     \closein 1
+     \input \jobname.aux
+     \global\havexrefstrue
+     \global\warnedobstrue
+   \fi
+   % Open the new aux file.  TeX will close it automatically at exit.
+   \openout\auxfile=\jobname.aux
+ \endgroup}
+ 
+ 
+ % Footnotes.
+ 
+ \newcount \footnoteno
+ 
+ % The trailing space in the following definition for supereject is
+ % vital for proper filling; pages come out unaligned when you do a
+ % pagealignmacro call if that space before the closing brace is
+ % removed. (Generally, numeric constants should always be followed by a
+ % space to prevent strange expansion errors.)
+ \def\supereject{\par\penalty -20000\footnoteno =0 }
+ 
+ % @footnotestyle is meaningful for info output only.
+ \let\footnotestyle=\comment
+ 
+ \let\ptexfootnote=\footnote
+ 
+ {\catcode `\@=11
+ %
+ % Auto-number footnotes.  Otherwise like plain.
+ \gdef\footnote{%
+   \global\advance\footnoteno by \@ne
+   \edef\thisfootno{$^{\the\footnoteno}$}%
+   %
+   % In case the footnote comes at the end of a sentence, preserve the
+   % extra spacing after we do the footnote number.
+   \let\@sf\empty
+   \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+   %
+   % Remove inadvertent blank space before typesetting the footnote number.
+   \unskip
+   \thisfootno\@sf
+   \footnotezzz
+ }%
+ 
+ % Don't bother with the trickery in plain.tex to not require the
+ % footnote text as a parameter.  Our footnotes don't need to be so general.
+ %
+ % Oh yes, they do; otherwise, @ifset and anything else that uses
+ % \parseargline fail inside footnotes because the tokens are fixed when
+ % the footnote is read.  --karl, 16nov96.
+ %
+ \long\gdef\footnotezzz{\insert\footins\bgroup
+   % We want to typeset this text as a normal paragraph, even if the
+   % footnote reference occurs in (for example) a display environment.
+   % So reset some parameters.
+   \interlinepenalty\interfootnotelinepenalty
+   \splittopskip\ht\strutbox % top baseline for broken footnotes
+   \splitmaxdepth\dp\strutbox
+   \floatingpenalty\@MM
+   \leftskip\z at skip
+   \rightskip\z at skip
+   \spaceskip\z at skip
+   \xspaceskip\z at skip
+   \parindent\defaultparindent
+   %
+   % Hang the footnote text off the number.
+   \hang
+   \textindent{\thisfootno}%
+   %
+   % Don't crash into the line above the footnote text.  Since this
+   % expands into a box, it must come within the paragraph, lest it
+   % provide a place where TeX can split the footnote.
+   \footstrut
+   \futurelet\next\fo at t
+ }
+ \def\fo at t{\ifcat\bgroup\noexpand\next \let\next\f@@t
+   \else\let\next\f at t\fi \next}
+ \def\f@@t{\bgroup\aftergroup\@foot\let\next}
+ \def\f at t#1{#1\@foot}
+ \def\@foot{\strut\egroup}
+ 
+ }%end \catcode `\@=11
+ 
+ % Set the baselineskip to #1, and the lineskip and strut size
+ % correspondingly.  There is no deep meaning behind these magic numbers
+ % used as factors; they just match (closely enough) what Knuth defined.
+ %
+ \def\lineskipfactor{.08333}
+ \def\strutheightpercent{.70833}
+ \def\strutdepthpercent {.29167}
+ %
+ \def\setleading#1{%
+   \normalbaselineskip = #1\relax
+   \normallineskip = \lineskipfactor\normalbaselineskip
+   \normalbaselines
+   \setbox\strutbox =\hbox{%
+     \vrule width0pt height\strutheightpercent\baselineskip
+                     depth \strutdepthpercent \baselineskip
+   }%
+ }
+ 
+ % @| inserts a changebar to the left of the current line.  It should
+ % surround any changed text.  This approach does *not* work if the
+ % change spans more than two lines of output.  To handle that, we would
+ % have adopt a much more difficult approach (putting marks into the main
+ % vertical list for the beginning and end of each change).
+ %
+ \def\|{%
+   % \vadjust can only be used in horizontal mode.
+   \leavevmode
+   %
+   % Append this vertical mode material after the current line in the output.
+   \vadjust{%
+     % We want to insert a rule with the height and depth of the current
+     % leading; that is exactly what \strutbox is supposed to record.
+     \vskip-\baselineskip
+     %
+     % \vadjust-items are inserted at the left edge of the type.  So
+     % the \llap here moves out into the left-hand margin.
+     \llap{%
+       %
+       % For a thicker or thinner bar, change the `1pt'.
+       \vrule height\baselineskip width1pt
+       %
+       % This is the space between the bar and the text.
+       \hskip 12pt
+     }%
+   }%
+ }
+ 
+ % For a final copy, take out the rectangles
+ % that mark overfull boxes (in case you have decided
+ % that the text looks ok even though it passes the margin).
+ %
+ \def\finalout{\overfullrule=0pt}
+ 
+ % @image.  We use the macros from epsf.tex to support this.
+ % If epsf.tex is not installed and @image is used, we complain.
+ % 
+ % Check for and read epsf.tex up front.  If we read it only at @image
+ % time, we might be inside a group, and then its definitions would get
+ % undone and the next image would fail.
+ \openin 1 = epsf.tex
+ \ifeof 1 \else
+   \closein 1
+   % Do not bother showing banner with post-v2.7 epsf.tex (available in
+   % doc/epsf.tex until it shows up on ctan).
+   \def\epsfannounce{\toks0 = }%
+   \input epsf.tex
+ \fi
+ %
+ \newif\ifwarnednoepsf
+ \newhelp\noepsfhelp{epsf.tex must be installed for images to
+   work.  It is also included in the Texinfo distribution, or you can get
+   it from ftp://ftp.tug.org/tex/epsf.tex.}
+ %
+ % Only complain once about lack of epsf.tex.
+ \def\image#1{%
+   \ifx\epsfbox\undefined
+     \ifwarnednoepsf \else
+       \errhelp = \noepsfhelp
+       \errmessage{epsf.tex not found, images will be ignored}%
+       \global\warnednoepsftrue
+     \fi
+   \else
+     \imagexxx #1,,,\finish
+   \fi
+ }
+ %
+ % Arguments to @image:
+ % #1 is (mandatory) image filename; we tack on .eps extension.
+ % #2 is (optional) width, #3 is (optional) height.
+ % #4 is just the usual extra ignored arg for parsing this stuff.
+ \def\imagexxx#1,#2,#3,#4\finish{%
+   % \epsfbox itself resets \epsf?size at each figure.
+   \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+   \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+   % If the image is by itself, center it.
+   \ifvmode
+     \nobreak\medskip
+     \nobreak
+     \centerline{\epsfbox{#1.eps}}%
+     \bigbreak
+   \else
+     \epsfbox{#1.eps}%
+   \fi
+ }
+ 
+ 
+ \message{paper sizes,}
+ % And other related parameters.
+ 
+ \newdimen\defaultparindent \defaultparindent = 15pt
+ 
+ \chapheadingskip = 15pt plus 4pt minus 2pt
+ \secheadingskip = 12pt plus 3pt minus 2pt
+ \subsecheadingskip = 9pt plus 2pt minus 2pt
+ 
+ % Prevent underfull vbox error messages.
+ \vbadness = 10000
+ 
+ % Don't be so finicky about underfull hboxes, either.
+ \hbadness = 2000
+ 
+ % Following George Bush, just get rid of widows and orphans.
+ \widowpenalty=10000
+ \clubpenalty=10000
+ 
+ % Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+ % using an old version of TeX, don't do anything.  We want the amount of
+ % stretch added to depend on the line length, hence the dependence on
+ % \hsize.  This makes it come to about 9pt for the 8.5x11 format.  We
+ % call this whenever the paper size is set.
+ %
+ \def\setemergencystretch{%
+   \ifx\emergencystretch\thisisundefined
+     % Allow us to assign to \emergencystretch anyway.
+     \def\emergencystretch{\dimen0}%
+   \else
+     \emergencystretch = \hsize
+     \divide\emergencystretch by 45
+   \fi
+ }
+ 
+ % Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
+ % 4) hoffset; 5) binding offset; 6) topskip.  Then whoever calls us can
+ % set \parskip and call \setleading for \baselineskip.
+ %
+ \def\internalpagesizes#1#2#3#4#5#6{%
+   \voffset = #3\relax
+   \topskip = #6\relax
+   \splittopskip = \topskip
+   %
+   \vsize = #1\relax
+   \advance\vsize by \topskip
+   \outervsize = \vsize
+   \advance\outervsize by 2\topandbottommargin
+   \pageheight = \vsize
+   %
+   \hsize = #2\relax
+   \outerhsize = \hsize
+   \advance\outerhsize by 0.5in
+   \pagewidth = \hsize
+   %
+   \normaloffset = #4\relax
+   \bindingoffset = #5\relax
+   %
+   \parindent = \defaultparindent
+   \setemergencystretch
+ }
+ 
+ % @letterpaper (the default).
+ \def\letterpaper{{\globaldefs = 1
+   \parskip = 3pt plus 2pt minus 1pt
+   \setleading{13.2pt}%
+   %
+   % If page is nothing but text, make it come out even.
+   \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}%
+ }}
+ 
+ % Use @smallbook to reset parameters for 7x9.5 (or so) format.
+ \def\smallbook{{\globaldefs = 1
+   \parskip = 2pt plus 1pt
+   \setleading{12pt}%
+   %
+   \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}%
+   %
+   \lispnarrowing = 0.3in
+   \tolerance = 700
+   \hfuzz = 1pt
+   \contentsrightmargin = 0pt
+   \deftypemargin = 0pt
+   \defbodyindent = .5cm
+   %
+   \let\smalldisplay = \smalldisplayx
+   \let\smallexample = \smalllispx
+   \let\smallformat = \smallformatx
+   \let\smalllisp = \smalllispx
+ }}
+ 
+ % Use @afourpaper to print on European A4 paper.
+ \def\afourpaper{{\globaldefs = 1
+   \setleading{12pt}%
+   \parskip = 3pt plus 2pt minus 1pt
+   %
+   \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}%
+   %
+   \tolerance = 700
+   \hfuzz = 1pt
+ }}
+ 
+ % A specific text layout, 24x15cm overall, intended for A4 paper.  Top margin
+ % 29mm, hence bottom margin 28mm, nominal side margin 3cm.
+ \def\afourlatex{{\globaldefs = 1
+   \setleading{13.6pt}%
+   %
+   \afourpaper
+   \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}%
+   %
+   \globaldefs = 0
+ }}
+ 
+ % Use @afourwide to print on European A4 paper in wide format.
+ \def\afourwide{%
+   \afourpaper
+   \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}%
+   %
+   \globaldefs = 0
+ }
+ 
+ % @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+ % Perhaps we should allow setting the margins, \topskip, \parskip,
+ % and/or leading, also. Or perhaps we should compute them somehow.
+ % 
+ \def\pagesizes{\parsearg\pagesizesxxx}
+ \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish}
+ \def\pagesizesyyy#1,#2,#3\finish{{%
+   \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+   \globaldefs = 1
+   %
+   \parskip = 3pt plus 2pt minus 1pt
+   \setleading{13.2pt}%
+   %
+   \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}%
+ }}
+ 
+ % Set default to letter.
+ % 
+ \letterpaper
+ 
+ \message{and turning on texinfo input format.}
+ 
+ % Define macros to output various characters with catcode for normal text.
+ \catcode`\"=\other
+ \catcode`\~=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\+=\other
+ \def\normaldoublequote{"}
+ \def\normaltilde{~}
+ \def\normalcaret{^}
+ \def\normalunderscore{_}
+ \def\normalverticalbar{|}
+ \def\normalless{<}
+ \def\normalgreater{>}
+ \def\normalplus{+}
+ 
+ % This macro is used to make a character print one way in ttfont
+ % where it can probably just be output, and another way in other fonts,
+ % where something hairier probably needs to be done.
+ %
+ % #1 is what to print if we are indeed using \tt; #2 is what to print
+ % otherwise.  Since all the Computer Modern typewriter fonts have zero
+ % interword stretch (and shrink), and it is reasonable to expect all
+ % typewriter fonts to have this, we can check that font parameter.
+ %
+ \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
+ 
+ % Turn off all special characters except @
+ % (and those which the user can use as if they were ordinary).
+ % Most of these we simply print from the \tt font, but for some, we can
+ % use math or other variants that look better in normal text.
+ 
+ \catcode`\"=\active
+ \def\activedoublequote{{\tt\char34}}
+ \let"=\activedoublequote
+ \catcode`\~=\active
+ \def~{{\tt\char126}}
+ \chardef\hat=`\^
+ \catcode`\^=\active
+ \def^{{\tt \hat}}
+ 
+ \catcode`\_=\active
+ \def_{\ifusingtt\normalunderscore\_}
+ % Subroutine for the previous macro.
+ \def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}}
+ 
+ \catcode`\|=\active
+ \def|{{\tt\char124}}
+ \chardef \less=`\<
+ \catcode`\<=\active
+ \def<{{\tt \less}}
+ \chardef \gtr=`\>
+ \catcode`\>=\active
+ \def>{{\tt \gtr}}
+ \catcode`\+=\active
+ \def+{{\tt \char 43}}
+ %\catcode 27=\active
+ %\def^^[{$\diamondsuit$}
+ 
+ % Set up an active definition for =, but don't enable it most of the time.
+ {\catcode`\==\active
+ \global\def={{\tt \char 61}}}
+ 
+ \catcode`+=\active
+ \catcode`\_=\active
+ 
+ % If a .fmt file is being used, characters that might appear in a file
+ % name cannot be active until we have parsed the command line.
+ % So turn them off again, and have \everyjob (or @setfilename) turn them on.
+ % \otherifyactive is called near the end of this file.
+ \def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+ 
+ \catcode`\@=0
+ 
+ % \rawbackslashxx output one backslash character in current font
+ \global\chardef\rawbackslashxx=`\\
+ %{\catcode`\\=\other
+ %@gdef at rawbackslashxx{\}}
+ 
+ % \rawbackslash redefines \ as input to do \rawbackslashxx.
+ {\catcode`\\=\active
+ @gdef at rawbackslash{@let\=@rawbackslashxx }}
+ 
+ % \normalbackslash outputs one backslash in fixed width font.
+ \def\normalbackslash{{\tt\rawbackslashxx}}
+ 
+ % Say @foo, not \foo, in error messages.
+ \escapechar=`\@
+ 
+ % \catcode 17=0   % Define control-q
+ \catcode`\\=\active
+ 
+ % Used sometimes to turn off (effectively) the active characters
+ % even after parsing them.
+ @def at turnoffactive{@let"=@normaldoublequote
+ @let\=@realbackslash
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus}
+ 
+ @def at normalturnoffactive{@let"=@normaldoublequote
+ @let\=@normalbackslash
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus}
+ 
+ % Make _ and + \other characters, temporarily.
+ % This is canceled by @fixbackslash.
+ @otherifyactive
+ 
+ % If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+ % That is what \eatinput is for; after that, the `\' should revert to printing
+ % a backslash.
+ %
+ @gdef at eatinput input texinfo{@fixbackslash}
+ @global at let\ = @eatinput
+ 
+ % On the other hand, perhaps the file did not have a `\input texinfo'. Then
+ % the first `\{ in the file would cause an error. This macro tries to fix
+ % that, assuming it is called before the first `\' could plausibly occur.
+ % Also back turn on active characters that might appear in the input
+ % file name, in case not using a pre-dumped format.
+ %
+ @gdef at fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi
+   @catcode`+=@active @catcode`@_=@active}
+ 
+ % These look ok in all fonts, so just make them not special.  The @rm below
+ % makes sure that the current font starts out as the newly loaded cmr10
+ @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
+ 
+ @textfonts
+ @rm
+ 
+ @c Local variables:
+ @c eval: (add-hook 'write-file-hooks 'time-stamp)
+ @c page-delimiter: "^\\\\message"
+ @c time-stamp-start: "def\\\\texinfoversion{"
+ @c time-stamp-format: "%:y-%02m-%02d"
+ @c time-stamp-end: "}"
+ @c End:


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.1
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.1:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.1	Tue Apr  6 12:54:45 2004
***************
*** 0 ****
--- 1,113 ----
+ .\" Copyright (c) 2001 Southern Storm Software, Pty Ltd.
+ .\"
+ .\" This program is free software; you can redistribute it and/or modify
+ .\" it under the terms of the GNU General Public License as published by
+ .\" the Free Software Foundation; either version 2 of the License, or
+ .\" (at your option) any later version.
+ .\"
+ .\" This program is distributed in the hope that it will be useful,
+ .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\" GNU General Public License for more details.
+ .\"
+ .\" You should have received a copy of the GNU General Public License
+ .\" along with this program; if not, write to the Free Software
+ .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ .TH treecc 1 "19 June 2001" "Southern Storm Software" ""
+ .SH NAME
+ treecc \- tree compiler-compiler
+ .SH SYNOPSIS
+ .ll +8
+ .B treecc
+ [ options ]
+ .I input
+ \&...
+ .SH DESCRIPTION
+ .B Treecc
+ converts input files in the treecc syntax into source
+ code that permits creating and walking abstract syntax trees.
+ It is intended for use in developing compilers, in concert with
+ existing tools such as \fBlex\fR(1) and \fByacc\fR(1).
+ The treecc syntax is described in the \fBtreecc\fR texinfo
+ topic.
+ .SH OPTIONS
+ .TP
+ .B \-o \fIfile\fB, \-\-output \fIfile\fR
+ Set the name of the output file.  If this option is not supplied,
+ then the name of the first input file will be used, with its
+ extension changed to ".c".  If the input is stdin, the default
+ output file is "yy_tree.c".
+ 
+ This option may be overridden using the "%output" keyword in
+ the input files.
+ .TP
+ .B \-h \fIfile\fB, \-\-header \fIfile\fR
+ Set the name of the header output file.  This is only used for
+ the C and C++ languages.  If this option is not supplied,
+ then the name of the output file will be used, with its extension
+ changed to ".h".  If the input is stdin, the default header output
+ file is "yy_tree.h".
+ 
+ This option may be overriden using the "%header" keyword in the
+ input files.
+ 
+ If this option is used with a language that does not require
+ headers, it will be ignored.
+ .TP
+ .B \-d \fIdir\fB, \-\-output\-dir \fIdir\fR
+ Set the name of the Java output directory.  This is only used for
+ the Java language.  If this option is not supplied, then the directory
+ corresponding to the first input file is used.  If the input is stdin,
+ the default is the current directory.
+ 
+ This option may be overriden using the "%outdir" keyword in the
+ input files.
+ 
+ If this option is used with a language other than Java, it will be ignored.
+ .TP
+ .B \-e \fIext\fB, \-\-extension \fIext\fR
+ Change the default output file extension to \fIext\fR, instead of
+ ".c".  The value \fIext\fR can have a leading dot, but this is
+ not required.
+ .TP
+ .B \-f, \-\-force\-create
+ \fBTreecc\fR attempts to optimise the creation of output files
+ so that they are only modified if a non-trivial change has
+ occurred in the input.  This can reduce the number of source
+ code recompiles when \fBtreecc\fR is used in combination
+ with \fBmake\fR(1).
+ 
+ This option forces the output files to be created, even if they
+ are the same as existing files with the same name.
+ 
+ The directive "%option force" can be used in the input files
+ to achieve the same effect as this option.
+ .TP
+ .B \-O \fIopt\fB, \-\-option \fIopt\fR
+ Set a treecc option value.  This is a command-line version of
+ the "%option" keyword in the input files.
+ .TP
+ .B \-n, \-\-no\-output
+ Suppress the generation of output files.  \fBTreecc\fR parses the
+ input files, checks for errors, and then stops.
+ .TP
+ .B \-\-help
+ Print a usage message for the \fBtreecc\fR program.
+ .TP
+ .B \-v, \-\-version
+ Print the version of the \fBtreecc\fR program.
+ .TP
+ .B \-\-
+ Marks the end of the command-line options, and the beginning of
+ the input filenames.  You may need to use this if your filename
+ begins with '-'.  e.g. "treecc -- -input.tc".  This is not needed
+ if the input is stdin: "treecc -" is perfectly valid.
+ .SH "AUTHOR"
+ Written by Southern Storm Software, Pty Ltd.
+ 
+ http://www.southern-storm.com.au/
+ .SH "SEE ALSO"
+ lex(1), yacc(1), make(1)
+ .SH "DIAGNOSTICS"
+ Exit status is 1 if an error occurred while processing the input.
+ Otherwise the exit status is 0.


Index: llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.texi
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.texi:1.1
*** /dev/null	Tue Apr  6 12:54:55 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/doc/treecc.texi	Tue Apr  6 12:54:45 2004
***************
*** 0 ****
--- 1,2916 ----
+ \input texinfo	@c -*-texinfo-*-
+ @c %** start of header
+ @setfilename treecc.info
+ @settitle Tree Compiler-Compiler
+ @setchapternewpage off
+ @c %** end of header
+ 
+ @dircategory DotGNU
+ @direntry
+ * TreeCC: (treecc).             Generate code for compilers to build
+                                 abstract syntax trees.
+ @end direntry
+ 
+ @ifinfo
+ The treecc program converts descriptions of abstract syntax
+ trees into source code that can be used to support compiler
+ development.
+ 
+ @noindent
+ Copyright @copyright{} 2001 Southern Storm Software, Pty Ltd
+ @*Copyright @copyright{} 2003 Free Software Foundation, Inc.
+ @end ifinfo
+ 
+ @titlepage
+ @sp 10
+ @center @titlefont{Tree Compiler-Compiler}
+ 
+ @vskip 50pt
+ 
+ @center{Rhys Weatherley}
+ 
+ @vskip 50pt
+ @center{Copyright @copyright{} 2001, 2002 Southern Storm Software, Pty Ltd}
+ @center{Copyright @copyright{} 2003 Free Software Foundation, Inc.}
+ @end titlepage
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Top, Overview, , (dir)
+ @menu
+ * Overview::                Treecc in brief
+ * Expression Example::      A simple example of using treecc
+ * Invoking Treecc::         Invoking treecc from the command-line
+ * Syntax::                  Syntax of input files
+ * Line Tracking::           Tracking line numbers in source files
+ * Output APIs::             API's that are available in the generated output
+ * Full Expression Example:: Full code for the expression example
+ * EBNF Syntax::             Full EBNF syntax for treecc input files
+ * Index::                   Index of concepts and facilities
+ @end menu
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Overview, Expression Example, Top, Top
+ @chapter Overview
+ @cindex Overview
+ 
+ @section Introduction
+ 
+ Traditional compiler construction tools such as lex and yacc focus on
+ the lexical analysis and parsing phases of compilation.  But they
+ provide very little to support semantic analysis and code generation.
+ 
+ Yacc allows grammar rules to be tagged with semantic actions and values,
+ but it doesn't provide any routines that assist in the process of tree
+ building, semantic analysis, or code generation.  Because those processes
+ are language-specific, yacc leaves the details to the programmer.
+ 
+ Support for semantic analysis was also a lot simpler in the languages
+ that were prevalent when lex and yacc were devised.  C and Pascal
+ require declare before use, which allows the semantic information
+ about a statement to be determined within the parser at the point of
+ use. at footnote{K&R C did allow functions that weren't declared to be called,
+ but only if they returned an "int".  This allowed the compiler to
+ guess the declaration if it wasn't available, and to proceed as
+ though all symbols were declared before use.}  If extensive optimization
+ is not required, then code generation can also be performed within
+ the grammar, leading to a simple one-pass compiler structure.
+ 
+ Modern languages allow deferred declaration of methods, fields, and
+ types.  For example, Java allows a method to refer to a field that
+ is declared further down the .java source file.  A field can be
+ declared with a type whose class definition has not yet been parsed.
+ 
+ Hence, most of the semantic analysis that used to be performed inline
+ within a yacc grammar must now be performed after the entire program
+ has been parsed.  Tree building and walking is now more important
+ than it was in older declare before use languages.
+ 
+ @section Tree walking: the need for something better
+ 
+ Building parse tree data structures and walking them is not terribly
+ difficult, but it is extremely time-consuming and error-prone.  A
+ modern programming language may have hundreds of node types, divided
+ into categories for statements, expressions, types, declarations, etc.
+ When a new programming language is being devised, new node types may
+ be added quite frequently.  This has ramifications in trying to manage
+ the code's complexity. at footnote{Implementing an existing programming
+ language has the same problems as a new language.  Most programming
+ languages are too large to be implemented all at once, and so the problem
+ must be tackled in stages.  These stages are very similar to those the
+ programmer goes through implementing a new language.}
+ 
+ For example, consider nodes that correspond to programming language
+ types in a C-like language.  There will be node types for integer
+ types, floating-point types, pointers, structures, functions, etc.
+ There will be semantic analysis routines for testing types for
+ equality, comparing types for coercions and casts, evaluating the
+ size of a type for memory layout purposes, determining if the type
+ falls into a general category such as "integer" or "pointer", etc.
+ 
+ Let's say we wanted to add a new "128-bit integer" type to this
+ language.  Adding a new node type is fairly straight-forward.
+ But we also need to track down every place in the code where the
+ compiler walks a type or deals with integers and add an appropriate
+ case for the new type.  This is very error-prone.  Such code is
+ likely to be split over many files, and good coding practices only
+ help to a certain extent.
+ 
+ This problem gets worse when new kinds of expressions and statements
+ are added to the language.  The change not only affects semantic
+ analysis, but also optimization and code generation.  Some compilers
+ use multiple passes over the tree to perform optimization, with
+ different algorithms used in each pass.  Code generation may use a
+ number of different strategies, depending upon how an expression or
+ statement is used.  If even one of these places is missed when the
+ new node type is added, then there is the potential for a very nasty
+ bug that may go unnoticed for months or years.
+ 
+ Object-oriented languages such as C++ can help a bit in constructing
+ robust tree structures.  The base class can declare abstract methods
+ for any semantic analysis, optimization, or code generation routine
+ that needs to be implemented for all members of the node category.
+ But another code maintainence problem arises.  What happens when
+ we want to add a new optimization pass in the future?  We must go
+ into hundreds of classes and implement the methods.
+ 
+ To avoid changing hundreds of classes, texts on Design Patterns
+ suggest using a Visitor pattern.  Then the new optimization pass
+ can be encapsulated in a visitor.  This would work, except for
+ the following drawback of visitor patterns, as described in Gamma,
+ et al:
+ 
+ @quotation
+ @emph{The Visitor pattern makes it hard to add new subclasses of
+ Element.  Each new ConcreteElement gives rise to a new abstract
+ operation on Visitor and a corresponding implementation in
+ every ConcreteVisitor class.}
+ 
+ @emph{... The Visitor class hierarchy can be difficult to maintain
+ when new ConcreteElement classes are added frequently.  In such
+ cases, it's probably easier just to define operations on the
+ classes that make up the structure.}
+ @end quotation
+ 
+ That is, if we add a new node type in the future, we have a large
+ maintainence problem on our hands.  The solution is to scatter the
+ implementation through-out every class, which is the situation we
+ were trying to avoid by using the Visitor pattern.
+ 
+ Because compiler construction deals with a large set of rapidly
+ changing node types and operations, neither of the usual approaches
+ work very well.
+ 
+ The ideal programming language for designing compilers needs to have
+ some way to detect when the programmer forgets to implement an operation
+ for a new node type, and to ensure that a new operation covers all
+ existing node types adequately.  Existing OO languages do not perform
+ this kind of global error checking.  What few checking procedures they
+ have change the maintainence problem into a different problem of
+ similar complexity.
+ 
+ @section Aspect-oriented programming
+ 
+ A new field in language design has emerged in recent years called
+ "Aspect-Oriented Programming" (AOP).  A good review of the field
+ can be found in the October 2001 issue of the @emph{Communications of
+ the ACM}, and on the AspectJ Web site, @url{http://www.aspectj.org/}.
+ 
+ The following excerpt from the introduction to the AOP section in the
+ CACM issue describes the essential aspects of AOP, and the difference
+ between OOP and AOP:
+ 
+ @quotation
+ @emph{AOP is based on the idea that computer systems are better programmed
+ by separately specifying the various concerns (properties or areas
+ of interest) of a system and some description of their relationships,
+ and then relying on mechanisms in the underlying AOP environment to
+ weave or compose them together into a coherent program. ...
+ While the tendancy in OOP's is to find commonality among classes
+ and push it up the inheritance tree, AOP attempts to realize
+ scattered concerns as first-class elements, and eject them
+ horizontally from the object structure.}
+ @end quotation
+ 
+ Aspect-orientation gives us some hope of solving our compiler
+ complexity problems.  We can view each operation on node types
+ (semantic analysis, optimization, code generation, etc) as an
+ "aspect" of the compiler's construction.  The AOP language weaves
+ these aspects with the node types to create the final compiler.
+ 
+ @section The treecc approach
+ 
+ We don't really want to implement a new programming language
+ just for compiler construction.  Especially since the new language's
+ implementation would have all of the problems described above and would
+ therefore also be difficult to debug and maintain.
+ 
+ The approach that we take with "treecc" is similar to that used by
+ "yacc".  A simple rule-based language is devised that is used to describe
+ the intended behaviour declaratively.  Embedded code is used to provide
+ the specific implementation details.  A translator then converts the input
+ into source code that can be compiled in the usual fashion.
+ 
+ The translator is responsible for generating the tree building and
+ walking code, and for checking that all relevant operations have been
+ implemented on the node types.  Functions are provided that make
+ it easier to build and walk the tree data structures from within
+ a "yacc" grammar and other parts of the compiler.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Expression Example, Invoking Treecc, Overview, Top
+ @chapter A simple example for expressions
+ @cindex Expression example
+ 
+ Consider the following yacc grammar for a simple expression language:
+ 
+ @example
+ %token INT FLOAT
+ 
+ %%
+ 
+ expr: INT
+     | FLOAT
+     | '(' expr ')'
+     | expr '+' expr
+     | expr '-' expr
+     | expr '*' expr
+     | expr '/' expr
+     | '-' expr
+     ;
+ @end example
+ 
+ (We will ignore the problems of precedence and associativity and
+ assume that the reader is familiar with how to resolve such issues
+ in yacc grammars).
+ 
+ There are 7 types of nodes for this grammar: @samp{intnum}, @samp{floatnum},
+ @samp{plus}, @samp{minus}, @samp{multiply}, @samp{divide}, and @samp{negate}.
+ They are defined in treecc as follows:
+ 
+ @example
+ %node expression %abstract %typedef
+ 
+ %node binary expression %abstract =
+ @{
+     expression *expr1;
+     expression *expr2;
+ @}
+ 
+ %node unary expression %abstract =
+ @{
+     expression *expr;
+ @}
+ 
+ %node intnum expression =
+ @{
+     int num;
+ @}
+ 
+ %node floatnum expression =
+ @{
+     float num;
+ @}
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node negate unary
+ @end example
+ 
+ We have introduced three extra node types that refer
+ to any expression, binary expressions, and unary expressions.  These
+ can be seen as superclasses in an OO-style framework.  We have
+ declared these node types as @samp{abstract} because the yacc grammar
+ will not be permitted to create instances of these classes directly.
+ 
+ The @samp{binary}, @samp{unary}, @samp{intnum}, and @samp{floatnum}
+ node types have field definitions associated with them.  These have
+ a similar syntax to C @code{struct} declarations.
+ 
+ The yacc grammar is augmented as follows to build the parse tree:
+ 
+ @example
+ %union @{
+     expression *node;
+     int         inum;
+     float       fnum;
+ @}
+ 
+ %token INT FLOAT
+ 
+ %type <node> expr
+ %type <inum> INT
+ %type <fnum> FLOAT
+ 
+ %%
+ 
+ expr: INT               @{ $$ = intnum_create($1); @}
+     | FLOAT             @{ $$ = floatnum_create($1); @}
+     | '(' expr ')'      @{ $$ = $2; @}
+     | expr '+' expr     @{ $$ = plus_create($1, $3); @}
+     | expr '-' expr     @{ $$ = minus_create($1, $3); @}
+     | expr '*' expr     @{ $$ = multiply_create($1, $3); @}
+     | expr '/' expr     @{ $$ = divide_create($1, $3); @}
+     | '-' expr          @{ $$ = negate_create($2); @}
+     ;
+ @end example
+ 
+ The treecc translator generates the @samp{*_create} functions so that
+ the rest of the compiler can build the necessary data structures
+ on demand.  The parameters to the @samp{*_create} functions
+ are identical in type and order to the members of the structure for
+ that node type.
+ 
+ Because @samp{expression}, @samp{binary}, and @samp{unary} are abstract,
+ there will be no @samp{*_create} functions associated with them.  This will
+ help the programmer catch certain kinds of errors.
+ 
+ The type that is returned from a @samp{*_create} function is the first
+ superclass of the node that has a @samp{%typedef} keyword associated with it;
+ @samp{expression *} in this case.
+ 
+ @section Storing extra information
+ 
+ Normally we will want to store extra information with a node beyond
+ that which is extracted by the yacc grammar.  In our expression
+ example, we probably want to store type information in the nodes
+ so that we can determine if the whole expression is integer or
+ floating point during semantic analysis.  We can add type information
+ to the @samp{expression} node type as follows:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ @end example
+ 
+ The @samp{%nocreate} flag indicates that the field should not be passed
+ to the @samp{*_create} functions as a parameter.  i.e. it provides semantic
+ information that isn't present in the grammar.  When nodes are created,
+ any fields that are declared as @samp{%nocreate} will be undefined in value.
+ A default value can be specified as follows:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type = @{int_type@};
+ @}
+ @end example
+ 
+ Default values must be enclosed in @samp{@{} and @samp{@}} because they are
+ pieces of code in the underlying source language (C, C++, etc), instead
+ of tokens in the treecc syntax.  Any legitimate expression in the
+ underlying source language may be used.
+ 
+ We also need to arrange for @samp{type_code} to be declared.  One way to
+ do this is by adding a @samp{%decls} section to the front of the treecc
+ input file:
+ 
+ @example
+ %decls %@{
+ 
+ typedef enum
+ @{
+     int_type,
+     float_type
+ 
+ @} type_code;
+ 
+ %@}
+ @end example
+ 
+ We could have introduced the definition by placing a @samp{#include}
+ directive into the @samp{%decls} section instead, or by defining a
+ treecc enumerated type:
+ 
+ @example
+ %enum type_code =
+ @{
+     int_type,
+     float_type
+ @}
+ @end example
+ 
+ Now that we have these definitions, type-inferencing can be implemented
+ as follows:
+ 
+ @example
+ %operation void infer_type(expression *e)
+ 
+ infer_type(binary)
+ @{
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr1->type == float_type || e->expr2->type == float_type)
+     @{
+         e->type = float_type;
+     @}
+     else
+     @{
+         e->type = int_type;
+     @}
+ @}
+ 
+ infer_type(unary)
+ @{
+     infer_type(e->expr);
+     e->type = e->expr->type;
+ @}
+ 
+ infer_type(intnum)
+ @{
+     e->type = int_type;
+ @}
+ @end example
+ 
+ This example demonstrates using the abstract node types @samp{binary} and
+ @samp{unary} to define operations on all subclasses.  The treecc translator
+ will generate code for a full C function called @samp{infer_type} that
+ incorporates all of the cases.
+ 
+ But hang on a second!  What happened to @samp{floatnum}?  Where did it
+ go?  It turns out that treecc will catch this.  It will report
+ an error to the effect that @samp{node type `floatnum' is not handled in
+ operation `infer_type'}.  Here is its definition:
+ 
+ @example
+ infer_type(floatnum)
+ @{
+     e->type = float_type;
+ @}
+ @end example
+ 
+ As we can see, treecc has just caught a bug in the language
+ implementation and reported it to us as soon as we introduced it.
+ 
+ Let's now extend the language with a @samp{power} operator:
+ 
+ @example
+ yacc:
+ 
+ expr: expr '^' expr     @{ $$ = create_power($1, $3); @}
+     ;
+ 
+ treecc:
+ 
+ %node power binary
+ @end example
+ 
+ That's all there is to it!  When treecc re-translates the input
+ file, it will modify the definition of @samp{infer_type} to include the
+ extra case for @samp{power} nodes.  Because @samp{power} is a subclass of
+ @samp{binary}, treecc already knows how to perform type inferencing for the
+ new node and it doesn't warn us about a missing declaration.
+ 
+ What if we wanted to restrict the second argument of @samp{power} to be
+ an integer value?  We can add the following case to @samp{infer_type}:
+ 
+ @example
+ infer_type(power)
+ @{
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr2->type != int_type)
+     @{
+         error("second argument to `^' is not an integer");
+     @}
+ 
+     e->type = e->expr1->type;
+ @}
+ @end example
+ 
+ The translator now notices that there is a more specific implementation
+ of @samp{infer_type} for @samp{power}, and won't use the @samp{binary}
+ case for it.
+ 
+ The most important thing to realise here is that the translator always
+ checks that there are sufficient declarations for @samp{infer_type} to cover
+ all relevant node types.  If it detects a lack, it will immediately
+ raise an error to the user.  This allows tree coverage problems to
+ be found a lot sooner than with the traditional approach.
+ 
+ @xref{Full Expression Example}, for a complete listing of the above
+ example files.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Invoking Treecc, Syntax, Expression Example, Top
+ @chapter Invoking treecc from the command-line
+ @cindex Invoking treecc
+ @cindex Command-line options
+ 
+ The general form of treecc's command-line syntax is as follows:
+ 
+ @example
+ treecc [OPTIONS] INPUT ...
+ @end example
+ 
+ Treecc accepts the following command-line options:
+ 
+ @table @code
+ @item -o FILE
+ @itemx --output FILE
+ Set the name of the output file to @samp{FILE}.  If this option is not
+ supplied, then the name of the first input file will be used, with its
+ extension changed to @samp{.c}.  If the input is standard input,
+ the default output file is @samp{yy_tree.c}.
+ 
+ This option may be overridden using the @samp{%output} keyword in
+ the input files.
+ 
+ @item -h FILE
+ @itemx --header FILE
+ Set the name of the header output file to @samp{FILE}.  This is only
+ used for the C and C++ output languages.  If this option is not supplied,
+ then the name of the output file will be used, with its extension
+ changed to @samp{.h}.  If the input is standard input, the default header
+ output file is @samp{yy_tree.h}.
+ 
+ This option may be overriden using the @samp{%header} keyword in the
+ input files.  If this option is used with a language that does not require
+ headers, it will be ignored.
+ 
+ @item -d DIR
+ @itemx --output-dir DIR
+ Set the name of the Java output directory to @samp{DIR}.  This is only
+ used for the Java language.  If this option is not supplied, then the
+ directory corresponding to the first input file is used.  If the input
+ is standard input, the default is the current directory.
+ 
+ This option may be overriden using the @samp{%outdir} keyword in the
+ input files.  If this option is used with a language other than Java,
+ it will be ignored.
+ 
+ @item -e EXT
+ @itemx --extension EXT
+ Change the default output file extension to @samp{ext}, instead of
+ @samp{.c}.  The value @samp{ext} can have a leading dot, but this is
+ not required.
+ 
+ @item -f
+ @itemx --force-create
+ Treecc normally attempts to optimise the creation of output files
+ so that they are only modified if a non-trivial change has
+ occurred in the input.  This can reduce the number of source
+ code recompiles when treecc is used in combination with make.
+ 
+ This option forces the output files to be created, even if they
+ are the same as existing files with the same name.
+ 
+ The declaration @samp{%option force} can be used in the input files
+ to achieve the same effect as this option.
+ 
+ @item -O OPT
+ @itemx --option OPT
+ Set a treecc option value.  This is a command-line version of
+ the @samp{%option} keyword in the input files.
+ 
+ @item -n
+ @itemx --no-output
+ Suppress the generation of output files.  Treecc parses the
+ input files, checks for errors, and then stops.
+ 
+ @item --help
+ Print a usage message for the treecc program.
+ 
+ @item -v
+ @itemx --version
+ Print the version of the treecc program.
+ 
+ @item --
+ Marks the end of the command-line options, and the beginning of
+ the input filenames.  You may need to use this if your filename
+ begins with @samp{-}.  e.g. @samp{treecc -- -input.tc}.  This is
+ not needed if the input is standard input: @samp{treecc -}
+ is perfectly valid.
+ @end table
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Syntax, Nodes, Invoking Treecc, Top
+ @chapter Syntax of input files
+ @cindex Syntax
+ 
+ Treecc input files consist of zero or more declarations that define
+ nodes, operations, options, etc.  The following sections describe each
+ of these elements.
+ 
+ @menu
+ * Nodes::          Node declarations
+ * Types::          Types used in fields and parameters
+ * Enumerations::   Enumerated type declarations
+ * Operations::     Operation declarations
+ * Options::        Options that modify treecc's behaviour
+ * Literal Code::   Literal code declarations
+ * Changing Files:: Changing input and output files
+ @end menu
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Nodes, Types, Syntax, Syntax
+ @section Node declarations
+ @cindex Nodes
+ @cindex %node keyword
+ @cindex Fields
+ 
+ Node types are defined using the @samp{node} keyword in input files.
+ The general form of the declaration is:
+ 
+ @example
+ %node NAME [ PNAME ] [ FLAGS ] [ = FIELDS ]
+ @end example
+ 
+ @table @samp
+ @item NAME
+ An identifier that is used to refer to the node type elsewhere
+ in the treecc definition.  It is also the name of the type that will be
+ visible to the programmer in literal code blocks.
+ 
+ @item PNAME
+ An identifier that refers to the parent node type that @samp{NAME} inherits
+ from.  If @samp{PNAME} is not supplied, then @samp{NAME} is a top-level
+ declaration.  It is legal to supply a @samp{PNAME} that has not yet
+ been defined in the input.
+ 
+ @item FLAGS
+ Any combination of @samp{%abstract} and @samp{%typedef}:
+ 
+ @table @samp
+ @item %abstract
+ @cindex %abstract keyword
+ The node type cannot be constructed by the programmer.  In addition,
+ the programmer does not need to define operation cases for this node
+ type if all subtypes have cases associated with them.
+ 
+ @item %typedef
+ @cindex %typedef keyword
+ The node type is used as the common return type for node creation
+ functions.  Top-level declarations must have a @samp{%typedef} keyword.
+ @end table
+ @end table
+ 
+ The @samp{FIELDS} part of a node declaration defines the fields that
+ make up the node type.  Each field has the following general form:
+ 
+ @example
+ [ %nocreate ] TYPE FNAME [ = VALUE ] ';'
+ @end example
+ 
+ @table @samp
+ @item %nocreate
+ @cindex %nocreate keyword
+ The field is not used in the node's constructor.  When the node is
+ constructed, the value of this field will be undefined unless
+ @samp{VALUE} is specified.
+ 
+ @item TYPE
+ The type that is associated with the field.  Types can be declared
+ using a subset of the C declaration syntax, augmented with some C++
+ and Java features.  @xref{Types}, for more information.
+ 
+ @item FNAME
+ The name to associate with the field.  Treecc verifies that the field
+ does not currently exist in this node type, or in any of its ancestor
+ node types.
+ 
+ @item VALUE
+ The default value to assign to the field in the node's constructor.
+ This can only be used on fields that are declared with @samp{%nocreate}.
+ The value must be enclosed in braces.  For example @samp{@{NULL@}} would
+ be used to initialize a field with @samp{NULL}.
+ 
+ The braces are required because the default value is expressed in
+ the underlying source language, and can use any of the usual constant
+ declaration features present in that language.
+ @end table
+ 
+ When the output language is C, treecc creates a struct-based type
+ called @samp{NAME} that contains the fields for @samp{NAME} and 
+ all of its ancestor classes.  The type also contains some house-keeping
+ fields that are used internally by the generated code.  The following
+ is an example:
+ 
+ @example
+ typedef struct binary__ binary;
+ struct binary__ @{
+     const struct binary_vtable__ *vtable__;
+     int kind__;
+     char *filename__;
+     long linenum__;
+     type_code type;
+     expression * expr1;
+     expression * expr2;
+ @};
+ @end example
+ 
+ The programmer should avoid using any identifier that
+ ends with @samp{__}, because it may clash with house-keeping
+ identifiers that are generated by treecc.
+ 
+ When the output language is C++, Java, or C#, treecc creates a class
+ called @samp{NAME}, that inherits from the class @samp{PNAME}.
+ The field definitions for @samp{NAME} are converted into public members
+ in the output.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Types, Enumerations, Nodes, Syntax
+ @section Types used in fields and parameters
+ @cindex Types
+ 
+ Types that are used in field and parameter declarations have a
+ syntax which is subset of features found in C, C++, and Java:
+ 
+ @example
+ TypeAndName ::= Type [ IDENTIFIER ]
+ 
+ Type ::= TypeName
+        | Type '*'
+        | Type '&'
+        | Type '[' ']'
+ 
+ TypeName ::= IDENTIFIER @{ IDENTIFIER @}
+ @end example
+ 
+ Types are usually followed by an identifier that names the field or
+ parameter.  The name is required for fields and is optional for parameters.
+ For example @samp{int} is usually equivalent to @samp{int x} in parameter
+ declarations.
+ 
+ The following are some examples of using types:
+ 
+ @example
+ int
+ int x
+ const char *str
+ expression *expr
+ Element[][] array
+ Item&
+ unsigned int y
+ const Element
+ @end example
+ 
+ The grammar used by treecc is slightly ambiguous.  The last example above
+ declares a parameter called @samp{Element}, that has type @samp{const}.
+ The programmer probably intended to declare an anonymous parameter with type 
+ @samp{const Element} instead.
+ 
+ This ambiguity is unavoidable given that treecc is not fully
+ aware of the underlying language's type system.  When treecc
+ sees a type that ends in a sequence of identifiers, it will
+ always interpret the last identifier as the field or parameter
+ name.  Thus, the programmer must write the following instead:
+ 
+ @example
+ const Element e
+ @end example
+ 
+ Treecc cannot declare types using the full power of C's type system.
+ The most common forms of declarations are supported, and the rest
+ can usually be obtained by defining a @samp{typedef} within a
+ literal code block.  @xref{Literal Code}, for more information
+ on literal code blocks.
+ 
+ It is the responsibility of the programmer to use type constructs
+ that are supported by the underlying programming language.  Types such
+ as @samp{const char *} will give an error when the output is compiled
+ with a Java compiler, for example.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Enumerations, Operations, Types, Syntax
+ @section Enumerated type declarations
+ @cindex Enumerations
+ @cindex enum declaration
+ @cindex %enum keyword
+ 
+ Enumerated types are a special kind of node type that can be used
+ by the programmer for simple values that don't require a full abstract
+ syntax tree node.  The following is an example of defining a list
+ of the primitive machine types used in a Java virtual machine:
+ 
+ @example
+ %enum JavaType =
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ @}
+ @end example
+ 
+ Enumerations are useful when writing code generators and type
+ inferencing routines.  The general form is:
+ 
+ @example
+ %enum NAME = @{ VALUES @}
+ @end example
+ 
+ @table @samp
+ @item NAME
+ An identifier to be used to name the enumerated type.  The name must
+ not have been previously used as a node type, an enumerated type, or
+ an enumerated value.
+ 
+ @item VALUES
+ A comma-separated list of identifiers that name the values within
+ the enumeration.  Each of the names must be unique, and must not have
+ been used previously as a node type, an enumerated type, or an
+ enumerated value.
+ @end table
+ 
+ Logically, each enumerated value is a special node type that inherits from
+ a parent node type corresponding to the enumerated type @samp{NAME}.
+ 
+ When the output language is C or C++, treecc generates an enumerated
+ typedef for @samp{NAME} that contains the enumerated values in the
+ same order as was used in the input file.  The typedef name can be
+ used elsewhere in the code as the type of the enumeration.
+ 
+ When the output language is Java, treecc generates a class called
+ @samp{NAME} that contains the enumerated values as integer constants.
+ Elsewhere in the code, the type @samp{int} must be used to declare
+ variables of the enumerated type.  Enumerated values are referred
+ to as @samp{NAME.VALUE}.  If the enumerated type is used as a trigger
+ parameter, then @samp{NAME} must be used instead of @samp{int}:
+ treecc will convert the type when the Java code is output.
+ 
+ When the output language is C#, treecc generates an enumerated value
+ type called @samp{NAME} that contains the enumerated values as
+ members.  The C# type @samp{NAME} can be used elsewhere in the code
+ as the type of the enumeration.  Enumerated values are referred to
+ as @samp{NAME.VALUE}.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Operations, Options, Enumerations, Syntax
+ @section Operation declarations
+ @cindex Operations
+ @cindex operation declarations
+ @cindex operation cases
+ @cindex %operation keyword
+ @cindex trigger parameters
+ 
+ Operations are declared in two parts: the declaration, and the
+ cases.  The declaration part defines the prototype for the
+ operation and the cases define how to handle specific kinds of
+ nodes for the operation.
+ 
+ Operations are defined over one or more trigger parameters.  Each
+ trigger parameter specifies a node type or an enumerated type that
+ is selected upon to determine what course of action to take.  The
+ following are some examples of operation declarations:
+ 
+ @example
+ %operation void infer_type(expression *e)
+ %operation type_code common_type([type_code t1], [type_code t2])
+ @end example
+ 
+ Trigger parameters are specified by enclosing them in square
+ brackets.  If none of the parameters are enclosed in square
+ brackets, then treecc assumes that the first parameter is the
+ trigger.
+ 
+ The general form of an operation declaration is as follows:
+ 
+ @example
+ %operation @{ %virtual | %inline | %split @} RTYPE [CLASS::]NAME(PARAMS)
+ @end example
+ 
+ @table @samp
+ @item %virtual
+ @cindex %virtual keyword
+ Specifies that the operation is associated with a node type as
+ a virtual method.  There must be only one trigger parameter,
+ and it must be the first parameter.
+ 
+ Non-virtual operations are written to the output source files
+ as global functions.
+ 
+ @item %inline
+ @cindex %inline keyword
+ Optimise the generation of the operation code so that all cases
+ are inline within the code for the function itself.  This can
+ only be used with non-virtual operations, and may improve
+ code efficiency if there are lots of operation cases with a
+ small amount of code in each.
+ 
+ @item %split
+ @cindex %split keyword
+ Split the generation of the multi-trigger operation code across
+ multiple functions, to reduce the size of each individual function.
+ It is sometimes necessary to split large @code{%inline} operations
+ to avoid compiler limits on function size.
+ 
+ @item RTYPE
+ The type of the return value for the operation.  This should be
+ @samp{void} if the operation does not have a return value.
+ 
+ @item CLASS
+ The name of the class to place the operation's definition within.
+ This can only be used with non-virtual operations, and is
+ intended for languages such as Java and C# that cannot declare
+ methods outside of classes.  The class name will be ignored if
+ the output language is C.
+ 
+ If a class name is required, but the programmer did not supply it,
+ then @samp{NAME} will be used as the default.  The exception to
+ this is the C# language: @samp{CLASS} must always be supplied and
+ it must be different from @samp{NAME}.  This is due to a "feature"
+ in some C# compilers that forbid a method with the same name as
+ its enclosing class.
+ 
+ @item NAME
+ The name of the operation.
+ 
+ @item PARAMS
+ The parameters to the operation.  Trigger parameters may be
+ enclosed in square brackets.  Trigger parameters must be
+ either node types or enumerated types.
+ @end table
+ 
+ Once an operation has been declared, the programmer can specify
+ its cases anywhere in the input files.  It is not necessary that
+ the cases appear after the operation, or that they be contiguous
+ within the input files.  This permits the programmer to place
+ operation cases where they are logically required for maintainence
+ reasons.
+ 
+ There must be sufficient operation cases defined to cover every
+ possible combination of node types and enumerated values that
+ inherit from the specified trigger types.  An operation case
+ has the following general form:
+ 
+ @example
+ NAME(TRIGGERS) [, NAME(TRIGGERS2) ...]
+ @{
+     CODE
+ @}
+ @end example
+ 
+ @table @samp
+ @item NAME
+ The name of the operation for which this case applies.
+ 
+ @item TRIGGERS
+ A comma-separated list of node types or enumerated values that
+ define the specific case that is handled by the following code.
+ 
+ @item CODE
+ Source code in the output source language that implements the
+ operation case.
+ @end table
+ 
+ Multiple trigger combinations can be associated with a single
+ block of code, by listing them all, separated by commas.  For
+ example:
+ 
+ @example
+ common_type(int_type, int_type)
+ @{
+     return int_type;
+ @}
+ 
+ common_type(int_type, float_type),
+ common_type(float_type, int_type),
+ common_type(float_type, float_type)
+ @{
+     return float_type;
+ @}
+ @end example
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Options, Literal Code, Operations, Syntax
+ @section Options that modify treecc's behaviour
+ @cindex Options
+ @cindex option declaration
+ @cindex %option keyword
+ 
+ "(*)" is used below to indicate an option that is enabled by default.
+ 
+ @table @samp
+ @item %option track_lines
+ @cindex track_lines option
+ Enable the generation of code that can track the current filename and
+ line number when nodes are created.  @xref{Line Tracking}, for more
+ information. (*)
+ 
+ @item %option no_track_lines
+ @cindex no_track_lines option
+ Disable the generation of code that performs line number tracking.
+ 
+ @item %option singletons
+ @cindex singletons option
+ Optimise the creation of singleton node types.  These are
+ node types without any fields.  Treecc can optimise the code
+ so that only one instance of a singleton node type exists in
+ the system.  This can speed up the creation of nodes for
+ constants within compilers. (*)
+ 
+ Singleton optimisations will have no effect if @samp{track_lines}
+ is enabled, because line tracking uses special hidden fields in
+ every node.
+ 
+ @item %option no_singletons
+ @cindex no_singletons option
+ Disable the optimisation of singleton node types.
+ 
+ @item %option reentrant
+ @cindex reentrant option
+ Enable the generation of reentrant code that does not rely
+ upon any global variables.  Separate copies of the compiler
+ state can be used safely in separate threads.  However, the
+ same copy of the compiler state cannot be used safely in two or
+ more threads.
+ 
+ @item %option no_reentrant
+ @cindex no_reentrant option
+ Disable the generation of reentrant code.  The interface to
+ node management functions is simpler, but cannot be used
+ in a threaded environment. (*)
+ 
+ @item %option force
+ @cindex force option
+ Force output source files to be written, even if they are
+ unchanged.  This option can also be set using the @samp{-f}
+ command-line option.
+ 
+ @item %option no_force
+ @cindex no_force option
+ Don't force output source files to be written if they are the
+ same as before. (*)
+ 
+ This option can help smooth integration of treecc with make.
+ Only those output files that have changed will be modified.
+ This reduces the number of files that the underlying source
+ language compiler must process after treecc is executed.
+ 
+ @item %option virtual_factory
+ @cindex virtual_factory option
+ Use virtual methods in the node type factories, so that the
+ programmer can subclass the factory and provide new
+ implementations of node creation functions.  This option is
+ ignored for C, which does not use factories.
+ 
+ @item %option no_virtual_factory
+ @cindex no_virtual_factory option
+ Don't use virtual methods in the node type factories. (*)
+ 
+ @item %option abstract_factory
+ @cindex abstract_factory option
+ Use abstract virtual methods in the node type factories.
+ The programmer is responsible for subclassing the factory
+ to provide node creation functionality.
+ 
+ @item %option no_abstract_factory
+ @cindex no_abstract_factory option
+ Don't use abstract virtual methods in the node type factories. (*)
+ 
+ @item %option kind_in_node
+ @cindex kind_in_node option
+ Put the kind field in the node, for more efficient access at runtime. (*)
+ 
+ @item %option kind_in_vtable
+ @cindex kind_in_vtable option
+ Put the kind field in the vtable, and not the node.  This saves some
+ memory, at the cost of slower access to the kind value at runtime.
+ This option only applies when the language is C.  The kind field is
+ always placed in the node in other languages, because it isn't possible
+ to modify the vtable.
+ 
+ @item %option prefix = PREFIX
+ @cindex prefix option
+ Specify the prefix to be used in output files in place of "yy".
+ 
+ @item %option state_type = NAME
+ @cindex state_type option
+ Specify the name of the state type.  The state type is generated
+ by treecc to perform centralised memory management and reentrancy
+ support.  The default value is @samp{YYNODESTATE}.  If the output language
+ uses factories, then this will also be the name of the factory
+ base class.
+ 
+ @item %option namespace = NAME
+ @cindex namespace option
+ Specify the namespace to write definitions to in the output
+ source files.  This option is ignored when the output language
+ is C.
+ 
+ @item %option package = NAME
+ @cindex package option
+ Same as @samp{%option namespace = NAME}.  Provided because @samp{package}
+ is more natural for Java programmers.
+ 
+ @item %option base = NUM
+ @cindex base option
+ Specify the numeric base to use for allocating numeric values to
+ node types.  By default, node type allocation begins at 1.
+ 
+ @item %option lang = LANGUAGE
+ @cindex lang option
+ Specify the output language.  Must be one of @code{"C"}, @code{"C++"},
+ @code{"Java"}, or @code{"C#"}.  The default is @code{"C"}.
+ 
+ @item %option block_size = NUM
+ @cindex block_size option
+ Specify the size of the memory blocks to use in C and C++ node allocators.
+ 
+ @item %option strip_filenames
+ @cindex strip_filenames option
+ Strip filenames down to their base name in @code{#line} directives.
+ i.e. strip off the directory component.  This can be helpful in
+ combination with the @code{%include %readonly} command when
+ treecc input files may processed from different directories,
+ causing common output files to change unexpectedly.
+ 
+ @item %option no_strip_filenames
+ @cindex no_strip_filenames option
+ Don't strip filenames in @code{#line} directives. (*)
+ 
+ @item %option internal_access
+ @cindex internal_access option
+ Use @code{internal} as the access mode for classes in C#, rather than
+ @code{public}.
+ 
+ @item %option public_access
+ @cindex public_access option
+ Use @code{public} as the access mode for classes in C#, rather than
+ @code{internal}. (*)
+ 
+ @item %option print_lines
+ @cindex print_lines option
+ Print @code{#line} markers in languages that use them. (*)
+ 
+ @item %option no_print_lines
+ @cindex no_print_lines option
+ Do not print @code{#line} markers, even in languages that normally
+ use them.
+ 
+ @item %option allocator
+ @cindex allocator option
+ Use treecc's standard node allocator for C and C++.  This option has
+ no effect for other output languages. (*)
+ 
+ @item %option no_allocator
+ @cindex no_allocator option
+ Do not use treecc's standard node allocator for C and C++.  This can be
+ useful when the programmer wants to redirect node allocation to their
+ own routines.
+ 
+ @item %option gc_allocator
+ @cindex gc_allocator option
+ Use libgc as a garbage-collecting node allocator for C and C++.  This
+ option has no effect for other output languages.
+ 
+ @item %option no_gc_allocator
+ @cindex no_gc_allocator option
+ Do not use libgc as a garbage-collecting node allocator for C and C++. (*)
+ 
+ @item %option base_type
+ @cindex base_type option
+ Specify the base type for the root node of the treecc node heirarchy.
+ The default is no base type.
+ 
+ @end table
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Literal Code, Changing Files, Options, Syntax
+ @section Literal code declarations
+ @cindex Literal code
+ 
+ Sometimes it is necessary to embed literal code within output @samp{.h}
+ and source files.  Usually this is to @samp{#include} definitions
+ from other files, or to define functions that cannot be easily expressed
+ as operations.
+ 
+ A literal code block is specified by enclosing it in @samp{%@{} and
+ @samp{%@}}.  The block can also be prefixed with the following flags:
+ 
+ @table @samp
+ @item %decls
+ @cindex %decls keyword
+ Write the literal code to the currently active declaration header file,
+ instead of the source file.
+ 
+ @item %both
+ @cindex %both keyword
+ Write the literal code to both the currently active declaration header file
+ and the currently active source file.
+ 
+ @item %end
+ @cindex %end keyword
+ Write the literal code to the end of the file, instead of the beginning.
+ @end table
+ 
+ Another form of literal code block is one which begins with @samp{%%} and
+ extends to the end of the current input file.  This form implicitly has
+ the @samp{%end} flag.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Changing Files, Line Tracking, Literal Code, Syntax
+ @section Changing input and output files
+ @cindex Changing files
+ 
+ Most treecc compiler definitions will be too large to be manageable
+ in a single input file.  They also will be too large to write to a
+ single output file, because that may overload the source language
+ compiler.
+ 
+ Multiple input files can be specified on the command-line, or
+ they can be explicitly included by other input files with
+ the following declarations:
+ 
+ @table @samp
+ @item %include [ %readonly ] FILENAME
+ @cindex include declaration
+ @cindex %include keyword
+ @cindex %readonly keyword
+ Include the contents of the specified file at the current point
+ within the current input file.  @samp{FILENAME} is interpreted
+ relative to the name of the current input file.
+ 
+ If the @samp{%readonly} keyword is supplied, then any output
+ files that are generated by the included file must be read-only.
+ That is, no changes are expected by performing the inclusion.
+ 
+ The @samp{%readonly} keyword is useful for building compilers
+ in layers.  The programmer may group a large number of useful
+ node types and operations together that are independent of the
+ particulars of a given language.  The programmer then defines
+ language-specific compilers that "inherit" the common definitions.
+ 
+ Read-only inclusions ensure that any extensions that are added
+ by the language-specific parts do not "leak" into the common code.
+ @end table
+ 
+ Output files can be changed using the follow declarations:
+ 
+ @table @samp
+ @item %header FILENAME
+ @cindex header declaration
+ @cindex %header keyword
+ Change the currently active declaration header file to @samp{FILENAME},
+ which is interpreted relative to the current input file.  This option
+ has no effect for languages without header files (Java and C#).
+ 
+ Any node types and operations that are defined after a @samp{%header}
+ declaration will be declared in @samp{FILENAME}.
+ 
+ @item %output FILENAME
+ @cindex output declaration
+ @cindex %output keyword
+ Change the currently active source file to @samp{FILENAME},
+ which is interpreted relative to the current input file.  This option
+ has no effect for languages that require a single class per file (Java).
+ 
+ Any node types and operations that are defined after a @samp{%header}
+ declaration will have their implementations placed in @samp{FILENAME}.
+ 
+ @item %outdir DIRNAME
+ @cindex outdir declaration
+ @cindex %outdir keyword
+ Change the output source directory to @samp{DIRNAME}.  This is only
+ used for Java, which requires that a single file be used for each class.
+ All classes are written to the specified directory.  By default,
+ @samp{DIRNAME} is the current directory where treecc was invoked.
+ @end table
+ 
+ When treecc generates the output source code, it must insert several
+ common house-keeping functions and classes into the code.  By default,
+ these are written to the first header and source files.  This can
+ be changed with the @samp{%common} declaration:
+ 
+ @table @samp
+ @item %common
+ @cindex common declaration
+ @cindex %common keyword
+ Output the common house-keeping code to the currently active
+ declaration header file and the currently active source file.
+ This is typically used as follows:
+ 
+ @example
+ %header "common.h"
+ %output "common.c"
+ %common
+ @end example
+ @end table
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Line Tracking, Output APIs, Changing Files, Top
+ @chapter Tracking line numbers in source files
+ @cindex Line tracking
+ 
+ When compilers emit error messages to the programmer, it is generally
+ a good idea to indicate which file and which line gave rise to the
+ error.  Syntax errors can be emitted fairly easily because the parser
+ usually has access to the current line number.  However, semantic
+ errors are harder to report because the parser may no longer be
+ active when the error is detected.
+ 
+ Treecc can generate code that automatically keeps track of what line
+ in the source file was active when a node is created.  Every node
+ has two extra private fields that specify the name of the file and the
+ line number.  Semantic analysis routines can query this information
+ when reporting errors.
+ 
+ Because treecc is not aware of how to obtain this information, the
+ programmer must supply some additional functions.  @xref{Output APIs},
+ for more information.
+ 
+ @xref{Output APIs}, for more information.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Output APIs, C Language, Line Tracking, Top
+ @chapter API's available in the generated output
+ @cindex Output APIs
+ 
+ The source code that is generated by treecc exports a number of
+ application programmer interfaces (API's) to the programmer.  These
+ can be used elsewhere in the compiler implementation to manipulate
+ abstract syntax trees.  The following sections describe the API's
+ for each of the output languages.
+ 
+ @menu
+ * C Language::     C Language API's
+ * C++ Language::   C++ Language API's
+ * Java Language::  Java Language API's
+ * C# Language::    C# Language API's
+ * Ruby Language::  Ruby Language API's
+ @end menu
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node C Language, C++ Language, Output APIs, Output APIs
+ @section C Language APIs
+ @cindex C APIs
+ 
+ In the C output language, each node type is converted into a @samp{typedef}
+ that contains the node's fields, and the fields of its ancestor node
+ types.  The following example demonstrates how treecc node declarations
+ are converted into C source code:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ %node binary expression %abstract =
+ @{
+     expression *expr1;
+     expression *expr2;
+ @}
+ %node plus binary
+ @end example
+ 
+ becomes:
+ 
+ @example
+ typedef struct expression__ expression;
+ typedef struct binary__ binary;
+ typedef struct plus__ plus;
+ 
+ struct expression__ @{
+     const struct expression_vtable__ *vtable__;
+     int kind__;
+     char *filename__;
+     long linenum__;
+     type_code type;
+ @};
+ struct binary__ @{
+     const struct binary_vtable__ *vtable__;
+     int kind__;
+     char *filename__;
+     long linenum__;
+     type_code type;
+     expression * expr1;
+     expression * expr2;
+ @};
+ struct plus__ @{
+     const struct plus_vtable__ *vtable__;
+     int kind__;
+     char *filename__;
+     long linenum__;
+     type_code type;
+     expression * expr1;
+     expression * expr2;
+ @};
+ @end example
+ 
+ Programmers should avoid using any identifiers that end in
+ @samp{__}.  Such identifiers are reserved for internal use by treecc
+ and its support routines.
+ 
+ For each non-abstract node type called @samp{NAME}, treecc generates a
+ function called @samp{NAME_create} that creates nodes of that type.
+ The general form of the function's prototype is as follows:
+ 
+ @example
+ TYPE *NAME_create([YYNODESTATE *state,] PARAMS)
+ @end example
+ 
+ @table @samp
+ @item TYPE
+ The return node type, which is the nearest ancestor that has the
+ @samp{%typedef} flag.
+ 
+ @item NAME
+ The name of the node type that is being created.
+ 
+ @item state
+ The system state, if reentrant code is being generated.
+ 
+ @item PARAMS
+ The create parameters, consisting of every field that does not
+ have the @samp{%nocreate} flag.  The parameters appear in the
+ same order as the fields in the node types, from the top-most
+ ancestor down to the node type itself.  For example:
+ 
+ @example
+ expression *plus_create(expression * expr1, expression * expr2);
+ @end example
+ @end table
+ 
+ Enumerated types are converted into a C @samp{typedef} with the
+ same name and values:
+ 
+ @example
+ %enum JavaType =
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ @}
+ @end example
+ 
+ becomes:
+ 
+ @example
+ typedef enum
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ 
+ @} JavaType;
+ @end example
+ 
+ Virtual operations are converted into C macros that invoke the
+ correct vtable entry on a node type:
+ 
+ @example
+ %operation %virtual void infer_type(expression *e)
+ @end example
+ 
+ becomes:
+ 
+ @example
+ #define infer_type(this__) \
+     ((*(((struct expression_vtable__ *) \
+         ((this__)->vtable__))->infer_type_v__)) \
+             ((expression *)(this__)))
+ @end example
+ 
+ Calls to @samp{infer_type} can then be made with @samp{infer_type(node)}.
+ 
+ Non-virtual operations are converted into C functions:
+ 
+ @example
+ %operation void infer_type(expression *e)
+ @end example
+ 
+ becomes:
+ 
+ @example
+ extern void infer_type(expression *e);
+ @end example
+ 
+ Because virtual and non-virtual operations use a similar call syntax,
+ it is very easy to convert a virtual operation into a non-virtual
+ operation when the output language is C.  This isn't possible with
+ the other output languages.
+ 
+ Other house-keeping tasks are performed by the following functions
+ and macros.  Some of these must be supplied by the programmer.
+ The @samp{state} parameter is required only if a reentrant compiler is
+ being built.
+ 
+ @table @code
+ @item int yykind(ANY *node)
+ @cindex yykind macro
+ Gets the numeric kind value associated with a particular node.
+ The kind value for node type @samp{NAME} is called @samp{NAME_kind}.
+ 
+ @item const char *yykindname(ANY *node)
+ @cindex yykindname macro
+ Gets the name of the node kind associated with a particular node.
+ This may be helpful for debugging and logging code.
+ 
+ @item int yyisa(ANY *node, type)
+ @cindex yyisa macro
+ Determines if @samp{node} is an instance of the node type @samp{type}.
+ 
+ @item char *yygetfilename(ANY *node)
+ @cindex yygetfilename macro
+ Gets the filename corresponding to where @samp{node} was created
+ during parsing.  This macro is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item long yygetlinenum(ANY *node)
+ @cindex yygetlinenum macro
+ Gets the line number corresponding to where @samp{node} was created
+ during parsing.  This macro is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item void yysetfilename(ANY *node, char *value)
+ @cindex yysetfilename macro
+ Sets the filename associated with @samp{node} to @samp{value}.  The
+ string is not copied, so @samp{value} must persist for the lifetime
+ of the node.  This macro will rarely be required, unless a node
+ corresponds to a different line than the current parse line.  This
+ macro is only generated if @samp{%option track_lines} was specified.
+ 
+ @item void yysetlinenum(ANY *node, long value)
+ @cindex yysetlinenum macro
+ Sets the line number associated with @samp{node} to @samp{value}.
+ This macro will rarely be required, unless a node corresponds to a
+ different line than the current parse line.  This macro is only
+ generated if @samp{%option track_lines} was specified.
+ 
+ @item char *yycurrfilename([YYNODESTATE *state])
+ @cindex yycurrfilename function
+ Get the name of the current input file from the parser.  The pointer
+ that is returned from this function is stored as-is: the string is
+ not copied.  Therefore, the value must persist for at least as long
+ as the node will persist.  This function must be supplied by the programmer
+ if @samp{%option track_lines} was specified.
+ 
+ @item long yycurrlinenum([YYNODESTATE *state])
+ @cindex yycurrlinenum function
+ Get the number of the current input line from the parser.  This
+ function must be supplied by the programmer if @samp{%option track_lines}
+ was specified.
+ 
+ @item void yynodeinit([YYNODESTATE *state])
+ @cindex yynodeinit function
+ Initializes the node memory manager.  If the system is reentrant, then
+ the node memory manager is @samp{state}.  Otherwise a global node
+ memory manager is used.
+ 
+ @item void *yynodealloc([YYNODESTATE *state,] unsigned int size)
+ @cindex yynodealloc function
+ Allocates a block of memory of @samp{size} bytes in size from the
+ node memory manager.  This function is called automatically from
+ the node-specific @samp{*_create} functions.  The programmer will
+ not normally need to call this function.
+ 
+ This function will return @code{NULL} if the system is out of
+ memory, or if @samp{size} is too large to be allocated within
+ the node memory manager.  If the system is out of memory, then
+ @samp{yynodealloc} will call @samp{yynodefailed} prior to
+ returning @code{NULL}.
+ 
+ @item int yynodepush([YYNODESTATE *state])
+ @cindex yynodepush function
+ Pushes the current node memory manager position.  The next time
+ @code{yynodepop} is called, the node memory manager will reset to
+ the pushed position.  This function returns zero if the system
+ is out of memory.
+ 
+ @item void yynodepop([YYNODESTATE *state])
+ @cindex yynodepop function
+ Pops the current node memory manager position.  This function has
+ no effect if @code{yynodepush} was not called previously.
+ 
+ The @code{yynodepush} and @code{yynodepop} functions can be used
+ to perform a simple kind of garbage collection on nodes.  When
+ the parser enters a scope, it pushes the node memory manager
+ position.  After all definitions in the scope have been dealt
+ with, the parser pops the node memory manager to reclaim all
+ of the memory used.
+ 
+ @item void yynodeclear([YYNODESTATE *state])
+ @cindex yynodeclear function
+ Clears the entire node memory manager and returns it to the
+ state it had after calling @code{yynodeinit}.  This is typically
+ used upon program shutdown to free all remaining node memory.
+ 
+ @item void yynodefailed([YYNODESTATE *state])
+ @cindex yynodefailed function
+ Called when @code{yynodealloc} or @code{yynodepush} detects that
+ the system is out of memory.  This function must be supplied by
+ the programmer.  The programmer may choose to exit to program
+ when the system is out of memory; in which case @code{yynodealloc}
+ will never return @code{NULL}.
+ @end table
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node C++ Language, Java Language, C Language, Output APIs
+ @section C++ Language APIs
+ @cindex C++ APIs
+ 
+ In the C++ output language, each node type is converted into a @samp{class}
+ that contains the node's fields, virtual operations, and other house-keeping
+ definitions.  The following example demonstrates how treecc node declarations
+ are converted into C++ source code:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ %node binary expression %abstract =
+ @{
+     expression *expr1;
+     expression *expr2;
+ @}
+ %node plus binary
+ @end example
+ 
+ becomes:
+ 
+ @example
+ class expression
+ @{
+ protected:
+ 
+     int kind__;
+     char *filename__;
+     long linenum__;
+ 
+ public:
+ 
+     int getKind() const @{ return kind__; @}
+     const char *getFilename() const @{ return filename__; @}
+     int getLinenum() const @{ return linenum__; @}
+     void setFilename(char *filename) @{ filename__ = filename; @}
+     void setLinenum(long linenum) @{ linenum__ = linenum; @}
+ 
+     void *operator new(size_t);
+     void operator delete(void *, size_t);
+ 
+ protected:
+ 
+     expression();
+ 
+ public:
+ 
+     type_code type;
+ 
+     virtual int isA(int kind) const;
+     virtual const char *getKindName() const;
+ 
+ protected:
+ 
+     virtual ~expression();
+ 
+ @};
+ 
+ class binary : public expression
+ @{
+ protected:
+ 
+     binary(expression * expr1, expression * expr2);
+ 
+ public:
+ 
+     expression * expr1;
+     expression * expr2;
+ 
+     virtual int isA(int kind) const;
+     virtual const char *getKindName() const;
+ 
+ protected:
+ 
+     virtual ~binary();
+ 
+ @};
+ 
+ class plus : public binary
+ @{
+ public:
+ 
+     plus(expression * expr1, expression * expr2);
+ 
+ public:
+ 
+     virtual int isA(int kind) const;
+     virtual const char *getKindName() const;
+ 
+ protected:
+ 
+     virtual ~plus();
+ 
+ @};
+ @end example
+ 
+ The following standard methods are available on every node type:
+ 
+ @table @code
+ @item int getKind()
+ @cindex getKind method (C++)
+ Gets the numeric kind value associated with a particular node.
+ The kind value for node type @samp{NAME} is called @samp{NAME_kind}.
+ 
+ @item virtual const char *getKindName()
+ @cindex getKindName method (C++)
+ Gets the name of the node kind associated with a particular node.
+ This may be helpful for debugging and logging code.
+ 
+ @item virtual int isA(int kind)
+ @cindex isA method (C++)
+ Determines if the node is a member of the node type that corresponds
+ to the numeric kind value @samp{kind}.
+ 
+ @item const char *getFilename()
+ @cindex getFilename method (C++)
+ Gets the filename corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item long getLinenum()
+ @cindex getLinenum method (C++)
+ Gets the line number corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item void setFilename(char *value)
+ @cindex setFilename method (C++)
+ Sets the filename associated with the node to @samp{value}.  The
+ string is not copied, so @samp{value} must persist for the lifetime
+ of the node.  This method will rarely be required, unless a node
+ corresponds to a different line than the current parse line.  This
+ method is only generated if @samp{%option track_lines} was specified.
+ 
+ @item void setLinenum(long value)
+ @cindex setLinenum method (C++)
+ Sets the line number associated with the node to @samp{value}.
+ This method will rarely be required, unless a node corresponds to a
+ different line than the current parse line.  This method is only
+ generated if @samp{%option track_lines} was specified.
+ @end table
+ 
+ If the generated code is non-reentrant, then the constructor for the
+ class can be used to construct nodes of the specified node type.  The
+ constructor parameters are the same as the fields within the node type's
+ definition, except for @samp{%nocreate} fields.
+ 
+ If the generated code is reentrant, then nodes cannot be constructed
+ using the C++ @samp{new} operator.  The @samp{*Create} methods
+ on the @samp{YYNODESTATE} factory class must be used instead.
+ 
+ The @samp{YYNODESTATE} class contains a number of house-keeping methods
+ that are used to manage nodes:
+ 
+ @table @code
+ @item static YYNODESTATE *getState()
+ @cindex getState method (C++)
+ Gets the global @samp{YYNODESTATE} instance that is being used by
+ non-reentrant code.  If an instance has not yet been created,
+ this method will create one.
+ 
+ When using non-reentrant code, the programmer will normally subclass
+ @samp{YYNODESTATE}, override some of the methods below, and then
+ construct an instance of the subclass.  This constructed instance
+ will then be returned by future calls to @samp{getState}.
+ 
+ @item void *alloc(size_t size)
+ @cindex alloc method (C++)
+ Allocates a block of memory of @samp{size} bytes in size from the
+ node memory manager.  This function is called automatically from
+ the node-specific constructors and @samp{*Create} methods.  The programmer
+ will not normally need to call this function.
+ 
+ This function will return @code{NULL} if the system is out of
+ memory, or if @samp{size} is too large to be allocated within
+ the node memory manager.  If the system is out of memory, then
+ @samp{alloc} will call @samp{failed} prior to returning @code{NULL}.
+ 
+ @item int push()
+ @cindex push method (C++)
+ Pushes the current node memory manager position.  The next time
+ @code{pop} is called, the node memory manager will reset to
+ the pushed position.  This function returns zero if the system
+ is out of memory.
+ 
+ @item void pop()
+ @cindex pop method (C++)
+ Pops the current node memory manager position.  This function has
+ no effect if @code{push} was not called previously.
+ 
+ The @code{push} and @code{pop} methods can be used
+ to perform a simple kind of garbage collection on nodes.  When
+ the parser enters a scope, it pushes the node memory manager
+ position.  After all definitions in the scope have been dealt
+ with, the parser pops the node memory manager to reclaim all
+ of the memory used.
+ 
+ @item void clear()
+ @cindex clear method (C++)
+ Clears the entire node memory manager and returns it to the
+ state it had after construction.
+ 
+ @item virtual void failed()
+ @cindex failed method (C++)
+ Called when @code{alloc} or @code{push} detects that
+ the system is out of memory.  This method is typically
+ overridden by the programmer in subclasses.  The programmer may
+ choose to exit to program when the system is out of memory; in
+ which case @code{alloc} will never return @code{NULL}.
+ 
+ @item virtual char *currFilename()
+ @cindex currFilename method (C++)
+ Get the name of the current input file from the parser.  The pointer
+ that is returned from this function is stored as-is: the string is
+ not copied.  Therefore, the value must persist for at least as long
+ as the node will persist.  This method is usually overrriden by
+ the programmer in subclasses if @samp{%option track_lines} was specified.
+ 
+ @item virtual long currLinenum()
+ @cindex currLinenum method (C++)
+ Get the number of the current input line from the parser.  This
+ method is usually overridden by the programmer in subclasses
+ if @samp{%option track_lines} was specified.
+ @end table
+ 
+ The programmer will typically subclass @samp{YYNODESTATE} to provide
+ additional functionality, and then create an instance of this class
+ to act as the node memory manager and node creation factory.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Java Language, C# Language, C++ Language, Output APIs
+ @section Java Language APIs
+ @cindex Java APIs
+ 
+ In the Java output language, each node type is converted into a @samp{class}
+ that contains the node's fields, virtual operations, and other house-keeping
+ definitions.  The following example demonstrates how treecc node declarations
+ are converted into Java source code:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ %node binary expression %abstract =
+ @{
+     expression expr1;
+     expression expr2;
+ @}
+ %node plus binary
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public class expression
+ @{
+     protected int kind__;
+     protected String filename__;
+     protected long linenum__;
+ 
+     public int getKind() @{ return kind__; @}
+     public String getFilename() @{ return filename__; @}
+     public long getLinenum() const @{ return linenum__; @}
+     public void setFilename(String filename) @{ filename__ = filename; @}
+     public void setLinenum(long linenum) @{ linenum__ = linenum; @}
+ 
+     public static final int KIND = 1;
+ 
+     public type_code type;
+ 
+     protected expression()
+     @{
+         this.kind__ = KIND;
+         this.filename__ = YYNODESTATE.getState().currFilename();
+         this.linenum__ = YYNODESTATE.getState().currLinenum();
+     @}
+ 
+     public int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return 0;
+     @}
+ 
+     public String getKindName()
+     @{
+         return "expression";
+     @}
+ @}
+ 
+ public class binary extends expression
+ @{
+     public static final int KIND = 2;
+ 
+     public expression expr1;
+     public expression expr2;
+ 
+     protected binary(expression expr1, expression expr2)
+     @{
+         super();
+         this.kind__ = KIND;
+         this.expr1 = expr1;
+         this.expr2 = expr2;
+     @}
+ 
+     public int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return super.isA(kind);
+     @}
+ 
+     public String getKindName()
+     @{
+         return "binary";
+     @}
+ @}
+ 
+ public class plus extends binary
+ @{
+     public static final int KIND = 3;
+ 
+     public plus(expression expr1, expression expr2)
+     @{
+         super(expr1, expr2);
+         this.kind__ = KIND;
+     @}
+ 
+     public int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return super.isA(kind);
+     @}
+ 
+     public String getKindName()
+     @{
+         return "plus";
+     @}
+ @}
+ @end example
+ 
+ The following standard members are available on every node type:
+ 
+ @table @code
+ @item int KIND
+ @cindex KIND field (Java)
+ The kind value for the node type corresponding to this class.
+ 
+ @item int getKind()
+ @cindex getKind method (Java)
+ Gets the numeric kind value associated with a particular node.
+ The kind value for node type @samp{NAME} is called @samp{NAME.KIND}.
+ 
+ @item String getKindName()
+ @cindex getKindName method (Java)
+ Gets the name of the node kind associated with a particular node.
+ This may be helpful for debugging and logging code.
+ 
+ @item int isA(int kind)
+ @cindex isA method (Java)
+ Determines if the node is a member of the node type that corresponds
+ to the numeric kind value @samp{kind}.
+ 
+ @item String getFilename()
+ @cindex getFilename method (Java)
+ Gets the filename corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item long getLinenum()
+ @cindex getLinenum method (Java)
+ Gets the line number corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item void setFilename(String value)
+ @cindex setFilename method (Java)
+ Sets the filename associated with the node to @samp{value}.
+ This method will rarely be required, unless a node corresponds to
+ a different line than the current parse line.  This method is only
+ generated if @samp{%option track_lines} was specified.
+ 
+ @item void setLinenum(long value)
+ @cindex setLinenum method (Java)
+ Sets the line number associated with the node to @samp{value}.
+ This method will rarely be required, unless a node corresponds to a
+ different line than the current parse line.  This method is only
+ generated if @samp{%option track_lines} was specified.
+ @end table
+ 
+ If the generated code is non-reentrant, then the constructor for the
+ class can be used to construct nodes of the specified node type.  The
+ constructor parameters are the same as the fields within the node type's
+ definition, except for @samp{%nocreate} fields.
+ 
+ If the generated code is reentrant, then nodes cannot be constructed
+ using the Java @samp{new} operator.  The @samp{*Create} methods
+ on the @samp{YYNODESTATE} factory class must be used instead.
+ 
+ Enumerated types are converted into a Java @samp{class}:
+ 
+ @example
+ %enum JavaType =
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ @}
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public class JavaType
+ @{
+     public static final int JT_BYTE = 0;
+     public static final int JT_SHORT = 1;
+     public static final int JT_CHAR = 2;
+     public static final int JT_INT = 3;
+     public static final int JT_LONG = 4;
+     public static final int JT_FLOAT = 5;
+     public static final int JT_DOUBLE = 6;
+     public static final int JT_OBJECT_REF = 7;
+ @}
+ @end example
+ 
+ References to enumerated types in fields and operation parameters
+ are replaced with the type @samp{int}.
+ 
+ Virtual operations are converted into public methods on the Java
+ node classes.
+ 
+ Non-virtual operations are converted into a static method within
+ a class named for the operation.  For example,
+ 
+ @example
+ %operation void InferType::infer_type(expression e)
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public class InferType
+ @{
+     public static void infer_type(expression e)
+     @{
+         ...
+     @}
+ @}
+ @end example
+ 
+ If the class name (@samp{InferType} in the above example) is omitted,
+ then the name of the operation is used as both the class name and the
+ the method name.
+ 
+ The @samp{YYNODESTATE} class contains a number of house-keeping methods
+ that are used to manage nodes:
+ 
+ @table @code
+ @item static YYNODESTATE getState()
+ @cindex getState method (Java)
+ Gets the global @samp{YYNODESTATE} instance that is being used by
+ non-reentrant code.  If an instance has not yet been created,
+ this method will create one.
+ 
+ When using non-reentrant code, the programmer will normally subclass
+ @samp{YYNODESTATE}, override some of the methods below, and then
+ construct an instance of the subclass.  This constructed instance
+ will then be returned by future calls to @samp{getState}.
+ 
+ This method will not be present if a reentrant system is being
+ generated.
+ 
+ @item String currFilename()
+ @cindex currFilename method (Java)
+ Get the name of the current input file from the parser.  This method
+ is usually overrriden by the programmer in subclasses if
+ @samp{%option track_lines} was specified.
+ 
+ @item long currLinenum()
+ @cindex currLinenum method (Java)
+ Get the number of the current input line from the parser.  This
+ method is usually overridden by the programmer in subclasses
+ if @samp{%option track_lines} was specified.
+ @end table
+ 
+ The programmer will typically subclass @samp{YYNODESTATE} to provide
+ additional functionality, and then create an instance of this class
+ to act as the global state and node creation factory.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node C# Language, Ruby Language, Java Language, Output APIs
+ @section C# Language APIs
+ @cindex C# APIs
+ 
+ In the C# output language, each node type is converted into a @samp{class}
+ that contains the node's fields, virtual operations, and other house-keeping
+ definitions.  The following example demonstrates how treecc node declarations
+ are converted into C# source code:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ %node binary expression %abstract =
+ @{
+     expression expr1;
+     expression expr2;
+ @}
+ %node plus binary
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public class expression
+ @{
+     protected int kind__;
+     protected String filename__;
+     protected long linenum__;
+ 
+     public int getKind() @{ return kind__; @}
+     public String getFilename() @{ return filename__; @}
+     public long getLinenum() const @{ return linenum__; @}
+     public void setFilename(String filename) @{ filename__ = filename; @}
+     public void setLinenum(long linenum) @{ linenum__ = linenum; @}
+ 
+     public const int KIND = 1;
+ 
+     public type_code type;
+ 
+     protected expression()
+     @{
+         this.kind__ = KIND;
+         this.filename__ = YYNODESTATE.getState().currFilename();
+         this.linenum__ = YYNODESTATE.getState().currLinenum();
+     @}
+ 
+     public virtual int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return 0;
+     @}
+ 
+     public virtual String getKindName()
+     @{
+         return "expression";
+     @}
+ @}
+ 
+ public class binary : expression
+ @{
+     public const int KIND = 2;
+ 
+     public expression expr1;
+     public expression expr2;
+ 
+     protected binary(expression expr1, expression expr2)
+         : expression()
+     @{
+         this.kind__ = KIND;
+         this.expr1 = expr1;
+         this.expr2 = expr2;
+     @}
+ 
+     public override int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return base.isA(kind);
+     @}
+ 
+     public override String getKindName()
+     @{
+         return "binary";
+     @}
+ @}
+ 
+ public class plus : binary
+ @{
+     public const int KIND = 5;
+ 
+     public plus(expression expr1, expression expr2)
+         : binary(expr1, expr2)
+     @{
+         this.kind__ = KIND;
+     @}
+ 
+     public override int isA(int kind)
+     @{
+         if(kind == KIND)
+             return 1;
+         else
+             return base.isA(kind);
+     @}
+ 
+     public override String getKindName()
+     @{
+         return "plus";
+     @}
+ @}
+ @end example
+ 
+ The following standard members are available on every node type:
+ 
+ @table @code
+ @item const int KIND
+ @cindex KIND field (C#)
+ The kind value for the node type corresponding to this class.
+ 
+ @item int getKind()
+ @cindex getKind method (C#)
+ Gets the numeric kind value associated with a particular node.
+ The kind value for node type @samp{NAME} is called @samp{NAME.KIND}.
+ 
+ @item virtual String getKindName()
+ @cindex getKindName method (C#)
+ Gets the name of the node kind associated with a particular node.
+ This may be helpful for debugging and logging code.
+ 
+ @item virtual int isA(int kind)
+ @cindex isA method (C#)
+ Determines if the node is a member of the node type that corresponds
+ to the numeric kind value @samp{kind}.
+ 
+ @item String getFilename()
+ @cindex getFilename method (C#)
+ Gets the filename corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item long getLinenum()
+ @cindex getLinenum method (C#)
+ Gets the line number corresponding to where the node was created
+ during parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @item void setFilename(String value)
+ @cindex setFilename method (C#)
+ Sets the filename associated with the node to @samp{value}.
+ This method will rarely be required, unless a node corresponds to
+ a different line than the current parse line.  This method is only
+ generated if @samp{%option track_lines} was specified.
+ 
+ @item void setLinenum(long value)
+ @cindex setLinenum method (C#)
+ Sets the line number associated with the node to @samp{value}.
+ This method will rarely be required, unless a node corresponds to a
+ different line than the current parse line.  This method is only
+ generated if @samp{%option track_lines} was specified.
+ @end table
+ 
+ If the generated code is non-reentrant, then the constructor for the
+ class can be used to construct nodes of the specified node type.  The
+ constructor parameters are the same as the fields within the node type's
+ definition, except for @samp{%nocreate} fields.
+ 
+ If the generated code is reentrant, then nodes cannot be constructed
+ using the C# @samp{new} operator.  The @samp{*Create} methods
+ on the @samp{YYNODESTATE} factory class must be used instead.
+ 
+ Enumerated types are converted into a C# @samp{enum} definition:
+ 
+ @example
+ %enum JavaType =
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ @}
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public enum JavaType
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF,
+ @}
+ @end example
+ 
+ Virtual operations are converted into public virtual methods on the C#
+ node classes.
+ 
+ Non-virtual operations are converted into a static method within
+ a class named for the operation.  For example,
+ 
+ @example
+ %operation void InferType::infer_type(expression e)
+ @end example
+ 
+ becomes:
+ 
+ @example
+ public class InferType
+ @{
+     public static void infer_type(expression e)
+     @{
+         ...
+     @}
+ @}
+ @end example
+ 
+ If the class name (@samp{InferType} in the above example) is omitted,
+ then the name of the operation is used as both the class name and the
+ the method name.
+ 
+ The @samp{YYNODESTATE} class contains a number of house-keeping methods
+ that are used to manage nodes:
+ 
+ @table @code
+ @item static YYNODESTATE getState()
+ @cindex getState method (C#)
+ Gets the global @samp{YYNODESTATE} instance that is being used by
+ non-reentrant code.  If an instance has not yet been created,
+ this method will create one.
+ 
+ When using non-reentrant code, the programmer will normally subclass
+ @samp{YYNODESTATE}, override some of the methods below, and then
+ construct an instance of the subclass.  This constructed instance
+ will then be returned by future calls to @samp{getState}.
+ 
+ This method will not be present if a reentrant system is being
+ generated.
+ 
+ @item virtual String currFilename()
+ @cindex currFilename method (C#)
+ Get the name of the current input file from the parser.  This method
+ is usually overrriden by the programmer in subclasses if
+ @samp{%option track_lines} was specified.
+ 
+ @item virtual long currLinenum()
+ @cindex currLinenum method (C#)
+ Get the number of the current input line from the parser.  This
+ method is usually overridden by the programmer in subclasses
+ if @samp{%option track_lines} was specified.
+ @end table
+ 
+ The programmer will typically subclass @samp{YYNODESTATE} to provide
+ additional functionality, and then create an instance of this class
+ to act as the global state and node creation factory.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Ruby Language, Full Expression Example, C# Language, Output APIs
+ @section Ruby Language APIs
+ @cindex Ruby APIs
+ 
+ In the Ruby output language, each node type is converted into a
+ @samp{class} that contains the node's fields, operations, and other
+ house-keeping definitions.  The following example demonstrates how
+ treecc node declarations are converted into Ruby source code:
+ 
+ @example
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type;
+ @}
+ %node binary expression %abstract =
+ @{
+     expression expr1;
+     expression expr2;
+ @}
+ %node plus binary
+ @end example
+ 
+ becomes:
+ 
+ @example
+ class YYNODESTATE
+ 
+   @@@@state = nil
+ 
+   def YYNODESTATE.state
+     return @@@@state unless @@@@state.nil?
+     @@@@state = YYNODESTATE.new()
+     return @@@@state
+   end
+ 
+   def intialize 
+      @@@@state = self 
+    end
+ 
+   def currFilename 
+      return nil
+   end
+ 
+   def currLinenum 
+      return 0 
+   end
+ end
+ 
+ class Expression
+   protected
+   attr_reader :kind
+   public 
+ 
+   attr_accessor :Linenum, :Filename
+ 
+   attr_accessor :type
+ 
+   KIND = 1
+ 
+   def initialize()
+     @@kind = KIND
+     @@Filename = YYNODESTATE.state.currFilename()
+     @@Linenum = YYNODESTATE.state.currLinenum()
+   end
+ 
+   def isA(kind)
+     if(@@kind == KIND) then
+       return true
+     else
+       return 0
+     end
+   end
+ 
+   def KindName
+     return "Expression"
+   end
+ 
+ end
+ 
+ class Binary < Expression
+ 
+   attr_accessor :expr1
+   attr_accessor :expr2
+ 
+   KIND = 2
+ 
+   def initialize(expr1, expr2)
+   super(expr1, expr2)
+     @@kind = KIND
+     self.expr1 = expr1
+     self.expr2 = expr2
+   end
+ 
+   def isA(kind)
+     if(@@kind == Kind) then
+       return true
+     else
+       return super(kind)
+     end
+   end
+ 
+   def KindName
+     return "Binary"
+   end
+ 
+ end
+ 
+ class Plus < Binary
+ 
+   KIND = 3
+ 
+   def initialize(expr1, expr2)
+   super(expr1, expr2expr1, expr2)
+     @@kind = KIND
+   end
+ 
+   def isA(kind)
+     if(@@kind == KIND) then
+       return true
+     else
+       return super(kind)
+     end
+   end
+ 
+   def KindName
+     return "Plus"
+   end
+ 
+ end
+ @end example
+ 
+ The following standard members are available on every node type:
+ 
+ @table @code
+ @item KIND
+ @cindex KIND field (Ruby)
+ The kind value for the node type corresponding to this class.
+ The kind value for node type @samp{NAME} is called @samp{NAME::KIND}.
+ 
+ @item KindName
+ @cindex KindName field (Ruby)
+ The name of the node kind associated with a particular node.  This may
+ be helpful for debugging and logging code.
+ 
+ @item isA(int kind)
+ @cindex isA method (Ruby)
+ Determines if the node is a member of the node type that corresponds
+ to the numeric kind value @samp{kind}.
+ 
+ @item Filename
+ @cindex Filename field (Ruby)
+ The filename corresponding to where the node was created during parsing.
+ This method is only generated if @samp{%option track_lines} was
+ specified.
+ 
+ @item Linenum()
+ @cindex Linenum field (Ruby)
+ The line number corresponding to where the node was created during
+ parsing.  This method is only generated if @samp{%option track_lines}
+ was specified.
+ 
+ @end table
+ 
+ @c Don't know if this is true for ruby
+ @ignore
+ If the generated code is non-reentrant, then the constructor for the
+ class can be used to construct nodes of the specified node type.  The
+ constructor parameters are the same as the fields within the node type's
+ definition, except for @samp{%nocreate} fields.
+ 
+ If the generated code is reentrant, then nodes cannot be constructed
+ using the C# @samp{new} operator.  The @samp{*Create} methods
+ on the @samp{YYNODESTATE} factory class must be used instead.
+ @end ignore
+ 
+ Enumerated types are converted into a Ruby @samp{class} definition:
+ 
+ @example
+ %enum JavaType =
+ @{
+     JT_BYTE,
+     JT_SHORT,
+     JT_CHAR,
+     JT_INT,
+     JT_LONG,
+     JT_FLOAT,
+     JT_DOUBLE,
+     JT_OBJECT_REF
+ @}
+ @end example
+ 
+ becomes:
+ 
+ @example
+ 
+ class JavaType 
+   JT_BYTE = 0
+   JT_SHORT = 1
+   JT_CHAR = 2
+   JT_INT = 3
+   JT_LONG = 4
+   JT_FLOAT = 5
+   JT_DOUBLE = 6
+   JT_OBJECT_REF = 7
+ end
+ 
+ @end example
+ 
+ @c 
+ Virtual operations are converted into public methods on the Ruby
+ node classes.
+ 
+ Non-virtual operations are converted into a class method within
+ a class named for the operation.  For example,
+ 
+ @example
+ %operation void InferType::infer_type(expression e)
+ @end example
+ 
+ becomes:
+ 
+ @example
+ class InferType
+     def InferType.infer_type(expression e)   
+         ...
+     end
+ end
+ @end example
+ 
+ If the class name (@samp{InferType} in the above example) is omitted,
+ then the name of the operation is used as both the class name and the
+ the method name. You then get a method with a name starting with an
+ uppercase letter. However, Ruby methods start with lowercase methods.
+ So never forget the class name.
+ 
+ The @samp{YYNODESTATE} class contains a number of house-keeping methods
+ that are used to manage nodes:
+ 
+ @table @code
+ @item YYNODESTATE::state()
+ @cindex state field (Ruby)
+ Gets the global @samp{YYNODESTATE} instance that is being used by
+ non-reentrant code.  If an instance has not yet been created,
+ this method will create one.
+ 
+ @c Don't know if the following is correct
+ @ignore
+ 
+ When using non-reentrant code, the programmer will normally subclass
+ @samp{YYNODESTATE}, override some of the methods below, and then
+ construct an instance of the subclass.  This constructed instance
+ will then be returned by future calls to @samp{getState}.
+ 
+ This method will not be present if a reentrant system is being
+ generated.
+ 
+ @end ignore
+ 
+ @item currFilename
+ @cindex currFilename field (Ruby)
+ The name of the current input file from the parser.  This fields
+ accessor method is usually overrriden by the programmer in subclasses if
+ @samp{%option track_lines} was specified.
+ 
+ @item currLinenum
+ @cindex currLinenum field (Ruby)
+ The number of the current input line from the parser.  This fields
+ accessor method is usually overridden by the programmer in subclasses if
+ @samp{%option track_lines} was specified.
+ @end table
+ 
+ The programmer will typically subclass @samp{YYNODESTATE} to provide
+ additional functionality, and then create an instance of this class
+ to act as the global state and node creation factory.
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node Full Expression Example, EBNF Syntax, Ruby Language, Top
+ @appendix Full expression example code
+ @cindex Full expression example
+ 
+ The full treecc input file for the expression example is as follows:
+ 
+ @example
+ %enum type_code =
+ @{
+     int_type,
+     float_type
+ @}
+ 
+ %node expression %abstract %typedef =
+ @{
+     %nocreate type_code type = @{int_type@};
+ @}
+ 
+ %node binary expression %abstract =
+ @{
+     expression *expr1;
+     expression *expr2;
+ @}
+ 
+ %node unary expression %abstract =
+ @{
+     expression *expr;
+ @}
+ 
+ %node intnum expression =
+ @{
+     int num;
+ @}
+ 
+ %node floatnum expression =
+ @{
+     float num;
+ @}
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node power binary
+ %node negate unary
+ 
+ %operation void infer_type(expression *e)
+ 
+ infer_type(binary)
+ @{
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr1->type == float_type || e->expr2->type == float_type)
+     @{
+         e->type = float_type;
+     @}
+     else
+     @{
+         e->type = int_type;
+     @}
+ @}
+ 
+ infer_type(unary)
+ @{
+     infer_type(e->expr);
+     e->type = e->expr->type;
+ @}
+ 
+ infer_type(intnum)
+ @{
+     e->type = int_type;
+ @}
+ 
+ infer_type(floatnum)
+ @{
+     e->type = float_type;
+ @}
+ 
+ infer_type(power)
+ @{
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr2->type != int_type)
+     @{
+         error("second argument to `^' is not an integer");
+     @}
+ 
+     e->type = e->expr1->type;
+ @}
+ @end example
+ 
+ The full yacc grammar is as follows:
+ 
+ @example
+ %union @{
+     expression *node;
+     int         inum;
+     float       fnum;
+ @}
+ 
+ %token INT FLOAT
+ 
+ %type <node> expr
+ %type <inum> INT
+ %type <fnum> FLOAT
+ 
+ %%
+ 
+ expr: INT               @{ $$ = intnum_create($1); @}
+     | FLOAT             @{ $$ = floatnum_create($1); @}
+     | '(' expr ')'      @{ $$ = $2; @}
+     | expr '+' expr     @{ $$ = plus_create($1, $3); @}
+     | expr '-' expr     @{ $$ = minus_create($1, $3); @}
+     | expr '*' expr     @{ $$ = multiply_create($1, $3); @}
+     | expr '/' expr     @{ $$ = divide_create($1, $3); @}
+     | expr '^' expr     @{ $$ = power_create($1, $3); @}
+     | '-' expr          @{ $$ = negate_create($2); @}
+     ;
+ @end example
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @node EBNF Syntax, Index, Full Expression Example, Top
+ @appendix EBNF syntax for treecc input files
+ @cindex EBNF syntax
+ 
+ The EBNF syntax for treecc input files uses the following
+ lexical tokens:
+ 
+ @example
+ IDENTIFIER ::= <A-Za-z_> @{ <A-Za-z0-9_> @}
+ 
+ STRING ::= '"' <anything that does not include '"'> '"'
+          | "'" <anything that does not include "'"> "'"
+ 
+ LITERAL_DEFNS ::= "%@{" <anything except "%@}"> "%@}"
+ 
+ LITERAL_END ::= "%%" <any character sequence until EOF>
+ 
+ LITERAL_CODE ::= '@{' <anything with matched '@{' and '@}'> '@}'
+ @end example
+ 
+ In addition, anything that begins with "%" in the following syntax
+ is a lexical keyword.
+ 
+ The EBNF syntax is as follows:
+ 
+ @example
+ File ::= @{ Declaration @}
+ 
+ Declaration ::= Node
+               | Operation
+               | OperationCase
+               | Option
+               | Enum
+               | Literal
+               | Header
+               | Output
+               | Common
+               | Include
+ 
+ Node ::= %node IDENTIFIER [ IDENTIFIER ] @{ NodeFlag @} [ '=' Fields ]
+ 
+ NodeFlag ::= %abstract | %typedef
+ 
+ Fields ::= '@{' @{ Field @} '@}'
+ 
+ Field ::= [ %nocreate ] TypeAndName [ '=' LITERAL_CODE ] ';'
+ 
+ TypeAndName ::= Type [ IDENTIFIER ]
+ 
+ Type ::= TypeName
+        | Type '*'
+        | Type '&'
+        | Type '[' ']'
+ 
+ TypeName ::= IDENTIFIER @{ IDENTIFIER @}
+ 
+ Operation ::= %operation @{ OperFlag @} Type
+                    [ ClassName ] IDENTIFIER '(' [ Params ] ')'
+                    [ '=' LITERAL_CODE ] [ ';' ]
+ 
+ OperFlag ::= %virtual | %inline | %split
+ 
+ ClassName ::= IDENTIFIER "::"
+ 
+ Params ::= Param @{ ',' Param @}
+ 
+ Param ::= TypeAndName | '[' TypeAndName ']'
+ 
+ OperationCase ::= OperationHead @{ ',' OperationHead @} LITERAL_CODE
+ 
+ OperationHead ::= IDENTIFIER '(' [ TypeList ] ')'
+ 
+ TypeList ::= IDENTIFIER @{ ',' IDENTIFIER @}
+ 
+ Option ::= %option IDENTIFIER [ '=' Value ]
+ 
+ Value ::= IDENTIFIER | STRING
+ 
+ Enum ::= %enum IDENTIFIER '=' '@{' EnumBody [ ',' ] '@}'
+ 
+ EnumBody ::= IDENTIFIER @{ ',' IDENTIFIER @}
+ 
+ Literal ::= @{ LiteralFlag @} (LITERAL_DEFNS | LITERAL_END)
+ 
+ LiteralFlag ::= %both | %decls | %end
+ 
+ Header ::= %header STRING
+ 
+ Output ::= %output STRING
+ 
+ Common ::= %common
+ 
+ Include ::= %include [ %readonly ] STRING
+ 
+ @end example
+ 
+ @c -----------------------------------------------------------------------
+ 
+ @page
+ 
+ @node Index, , EBNF Syntax, Top
+ @unnumbered Index
+ 
+ @printindex cp
+ 
+ @contents
+ @bye





More information about the llvm-commits mailing list