%
%  Overheads for TeX talk #2
%
\font\hugerm=cmr10 at 24.867pt
\font\rm=cmr17
\font\tt=cmtt10 at 17.267pt
\font\big=cmssbx10 at 24.867pt
\rm
\hsize=10in
\vsize=7.5in
\hoffset=-.5in
\voffset=-.5in
\nopagenumbers
\parskip=0pt
\parindent=0pt
%
\def\title#1{\vfil\supereject\centerline{\big #1}\medskip\hrule\bigskip}
\def\verbatim#1{\begingroup\tt\catcode`#1=0 \catcode`\\=12
\catcode`\{=12 \catcode`\}=12 \catcode`\$=12 \catcode`\&=12
\catcode`\#=12 \catcode`\^=12 \catcode`\_=12 \catcode32=13
\catcode`\~=12 \catcode`\%=12 \obeylines}
\catcode32=13\let \ \catcode32=10
\let\endverb\endgroup
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%
\def\BaSiX{B\kern-.18em\lower.45ex\hbox{A}\kern-.15em
S\kern-.1em\lower.45ex\hbox{I}\kern-.1em X}
%
\null
\bigskip
\centerline{\hugerm\BaSiX}
\smallskip
\centerline{An Interpreter Written in \TeX}
\bigskip
\hrule
\bigskip
\centerline{Andrew Marc Greene}
\bigskip
\centerline{M.I.T. Project Athena}
\bigskip
\centerline{\tt amgreene@mit.edu}
%
\title{Character-String Calls}
\verbatim@
\newcount\strtmp
\def\ascii#1{\strtmp`#1}
\def\chr#1{\begingroup\uccode65=#1\uppercase{\gdef\tmp{A}}\endgroup}
@endverb
%
\title{Evaluator (Dispatch)}
\verbatim|
\def\mathbranch{\diw{EXPRESS:\expandafter\noexpand\word:}
\let\next\matherr
\ifx\empty\word\let\next\mathHardEnd\else                   % Expr. end?
\expandafter\if\numberP\word\let\next\mathLiteral\diw{@@}\fi  % Number?
\expandafter\if\stringP\word\let\next\mathLiteral\fi        % String literal?
\expandafter\if\identifierP\word\let\next\mathIdentifier\fi % Identifier?
\expandafter\if\stringvarP\word\let\next\mathIdentifier\fi  % :-(
\expandafter\if\macroP\word\let\next\mathMacro\fi           % Macro?
\ifx\word\Oleft\let\next\mathRecurse\fi                     % Open paren?
\ifx\word\Oright\let\next\mathEndRecurse\fi                 % Close paren?
\ifx\word\Ocomma\let\next\mathComma\fi                      % Comma?
%
%  Operator?
%
\ifx\word\Oplus\let\next\mathOp\diw{!+}\fi
\ifx\word\Ominus\let\next\mathOp\diw{!-}\fi
\ifx\word\Otimes\let\next\mathOp\diw{!*}\fi
\ifx\word\Odiv\let\next\mathOp\diw{!/}\fi
\ifx\word\Olt\let\next\mathOp\diw{!<}\fi
\ifx\word\Oeq\let\next\mathOp\diw{!=}\fi
\ifx\word\Ogt\let\next\mathOp\diw{!>}\fi
%
\fi\next}
|endverb
%
\title{Evaluator (Operators)}
\verbatim|
\def\mathOp{%
\if\word+
  \mathFlushAdd\let\mathlhAdd\mathAcc\let\mathOpAdd\mathAdd\fi
\if\word-
  \mathFlushAdd\let\mathlhAdd\mathAcc\let\mathOpAdd\mathSub\fi
\if\word*
  \mathFlushMul\let\mathlhMul\mathAcc\let\mathOpMul\mathMul\fi
\if\word/
  \mathFlushMul\let\mathlhMul\mathAcc\let\mathOpMul\mathDiv\fi
\if\word=
  \mathFlushRel\let\mathlhRel\mathAcc\let\mathOpRel\mathEQ\fi
\if\word>
  \mathFlushRel\let\mathlhRel\mathAcc\let\mathOpRel\mathGT\fi
\if\word<
  \mathFlushRel\let\mathlhRel\mathAcc\let\mathOpRel\mathLT\fi
\let\mathAcc\empty
\matheval}
|endverb
\title{Evaluator (Calculations)}
\verbatim|
\def\mathAdd{\advance\matha by \mathb}
\def\mathSub{\advance\matha by -\mathb}
\def\mathMul{\multiply\matha by \mathb}
\def\mathDiv{\divide\matha by \mathb}
\def\mathEQ{\ifnum\matha=\mathb\matha-1\else\matha0\fi}
\def\mathGT{\ifnum\matha>\mathb\matha-1\else\matha0\fi}
\def\mathLT{\ifnum\matha<\mathb\matha-1\else\matha0\fi}
%
\def\mathFlushRel{\mathFlushAdd\ifx\empty\mathOpRel\else
  \matha=\mathlhRel\relax\mathb=\mathAcc\relax\mathOpRel
  \edef\mathAcc{\number\matha}\let\mathOpRel\empty\fi}
%
\def\mathFlushAdd{\mathFlushMul\ifx\empty\mathOpAdd\else
  \matha=\mathlhAdd\relax\mathb=\mathAcc\relax\mathOpAdd
  \edef\mathAcc{\number\matha}\let\mathOpAdd\empty\fi}
%
\def\mathFlushMul{\mathFlushRef\ifx\empty\mathOpMul\else
  \matha=\mathlhMul\relax\mathb=\mathAcc\relax\mathOpMul
  \edef\mathAcc{\number\matha}\let\mathOpMul\empty\fi}
%
\def\mathFlushRef{\ifx\empty\mathlhRef\else
  \mathParam
  \mathlhRef\let\mathlhRef\empty\fi}
|endverb
%
\title{Scanner (First Character)}
\verbatim|
\newif\ifscan  %  shall we continue scanning?
%
\def\scan{\def\word{}\futurelet\q\scanFirst}
%
\def\scanFirst{%  Checks the first character to determine type.
\let\next\scanIter
\expandafter\if\spc\noexpand\q         %  Space -- ignore it
  \let\next\scanSpace\else
\if\eol\noexpand\q                     %  End of line -- no word here
  \let\next\scanEnd\else
\ifcat A\noexpand\q                    %  Then we have an identifier
  \let\scanTest\scanIdentifier\else 
\expandafter\if\digit\q
  \let\scanTest\scanNumericConstant\else
\if"\noexpand\q
  \let\scanTest\scanStringConstant\else
\expandafter\if\relationP\q
  \let\scanTest\scanRelation
\else
  \let\scanTest\scanfalse
\fi\fi\fi\fi\fi\fi\next}
|endverb
\title{Scanner (Iterator)}
\verbatim|
\def\scanIter#1{\expandafter\def\expandafter\word\expandafter{\word #1}
  \futurelet\q\scanContinueP}
\def\scanContinueP{\scanTest\ifscan\let\next\scanIter
  \else\let\next\scanEnd\fi\next}
%
\def\scanSpace#1{\scan}% If the first char is a space, gobble it and try again.
\def\scanIdentifier{\ifcat A\noexpand\q\scantrue\else
\expandafter\if\digit\q\scantrue
\else\if$\noexpand\q\scantrue
  \expandafter\def\expandafter\word\expandafter{\expandafter$\word}
  \let\scanTest\scanfalse\else
\scanfalse\fi\fi\fi}
\def\scanEndString{\scanfalse}
\def\scanNumericConstant{\expandafter\if\digit\q\scantrue\else\scanfalse\fi}
\def\scanStringConstant{\scantrue\if"\q\let\scanTest\scanfalse\fi}
\def\scanRelation{\if<\q\scantrue\else\if>\q\scantrue\else\if=\q\scantrue
\else\scanfalse\fi\fi\fi}
%
\def\scanEnd#1{\relax\diw{SCANNED:\word:}
\afterscan #1}% dumps trailing spaces.
\def\after{\let\afterscan}%
|endverb
%
\title{Example: ``If''}
\verbatim|
\def\Cif{\after\getift\expression}
\def\Cthen{\errmessage{Syntax error: THEN without IF}}
\def\getift{\after\getifh\mandatory t}
\def\getifh{\after\getife\mandatory h}
\def\getife{\after\getifn\mandatory e}
\def\getifn{\after\consequent\mandatory n}
\def\consequent{\ifnum\value=0\let\next=\endeval\else\let\next=\evalconsq\fi
\next}
\def\evalconsq{\after\evalline\scan}
|endverb
\bye
