Files from TOPS-20 <mdl.comp>.
[pdp10-muddle.git] / <mdl.comp> / pass1.mud.45
diff --git a/<mdl.comp>/pass1.mud.45 b/<mdl.comp>/pass1.mud.45
new file mode 100644 (file)
index 0000000..241f431
--- /dev/null
@@ -0,0 +1,1145 @@
+<PACKAGE "PASS1">
+
+<ENTRY PASS1 PCOMP PMACRO PAPPLY-OBJECT PAPPLY-TYPE PTHIS-OBJECT PTHIS-TYPE
+       GEN-D ACT-FIX FIND:DECL SEG? PSUBR-C>
+
+<USE "CHKDCL" "COMPDEC" "CDRIVE">
+
+
+"      This file contains the first pass of the MUDDLE compiler.
+The functions therein take a MUDDLE function and build a more detailed
+model of it.  Each entity in the function is represented by an object
+of type NODE.  The entire function is represented by the functions node
+and it points to the rest of the nodes for the function."
+
+"      Nodes vary in complexity and size depending on what they represent.
+A function or prog/repeat node is contains more information than a node
+for a quoted object.  All nodes have some fields in common to allow
+general programs to traverse the model."
+
+"      The model built by PASS1 is used by the analyzer (SYMANA), the
+variable allocator (VARANA) and the code generator (CODGEN).  In some
+cases the analyzers and generators for certain classes of SUBRs are 
+together in their own files (e.g.  CARITH, STRUCT, ISTRUC)."
+
+"      This the top level program for PASS1.  It takes a function as
+input and returns the data structure representing the model."
+
+<DEFINE PASS1 (FUNC
+              "OPTIONAL" (NAME <>) (JUSTDCL <>) (RNAME .NAME)
+              "AUX" RESULT (VARTBL ,LVARTBL) (DCL #DECL ()) (ARGL ())
+                    (HATOM <>) (TT ()) (FCN .FUNC) TEM (RQRG 0) (TRG 0) INAME)
+       #DECL ((FUNC) FUNCTION (VARTBL) <SPECIAL SYMTAB>
+              (RQRG TRG) <SPECIAL FIX> (FCN) <PRIMTYPE LIST> (ARGL TT) LIST
+              (RESULT) <SPECIAL NODE> (INAME) <UVECTOR [REST ATOM]>)
+       <AND <EMPTY? .FCN> <MESSAGE ERROR " EMPTY FUNCTION ">>
+       <AND <TYPE? <1 .FCN> ATOM>
+           <SET HATOM <1 .FCN>>
+           <SET FCN <REST .FCN>>>
+       <AND <EMPTY? .FCN> <MESSAGE ERROR " NO ARG LIST ">>
+       <SET ARGL <1 .FCN>>
+       <SET FCN <REST .FCN>>
+       <COND (<AND <NOT <EMPTY? .FCN>> <TYPE? <1 .FCN> DECL>>
+              <SET DCL <1 .FCN>>
+              <SET FCN <REST .FCN>>)>
+       <AND <EMPTY? .FCN> <MESSAGE ERROR " NO BODY ">>
+       <COND (<SET TEM <GET .RNAME .IND>>
+              <SET RESULT .TEM>
+              <SET VARTBL <SYMTAB .RESULT>>)
+             (ELSE
+              <SET TT <GEN-D .ARGL .DCL .HATOM>>
+              <SET INAME
+                   <IUVECTOR <- .TRG .RQRG -1> '<MAKE:TAG <PNAME .NAME>>>>
+              <SET RESULT
+                   <NODEF ,FUNCTION-CODE
+                          ()
+                          <FIND:DECL VALUE .DCL>
+                          .INAME
+                          ()
+                          <1 .TT>
+                          <2 .TT>
+                          .HATOM
+                          .VARTBL
+                          <COND (<==? <LENGTH .TT> 3> <3 .TT>)>
+                          .TRG
+                          .RQRG>>
+              <ACT-FIX .RESULT <2 .TT>>
+              <PUT .RNAME .IND .RESULT>
+              <PUT .RESULT
+                   ,RSUBR-DECLS
+                   ("VALUE" <RESULT-TYPE .RESULT> !<RSUBR-DECLS .RESULT>)>)>
+       <OR .JUSTDCL
+               <PUT .RESULT
+                    ,KIDS
+                    <MAPF ,LIST <FUNCTION (O) <PCOMP .O .RESULT>> .FCN>>>
+       .RESULT>
+
+"      This function (and others on this page) take an arg list and
+decls and parses them producing 3 things.
+
+       1) An RSUBR decl list.
+
+       2) A machine readable binding specification.
+
+       3) Possibly an AC call spec.
+
+Atoms are also entered into the symbol table."
+
+<DEFINE GEN-D (ARGL DCL HATOM "OPTIONAL" (ACS:TOP <COND (.GLUE '(() STACK)) (T (()))>)
+              "AUX" (SVTBL .VARTBL) (ACS:BOT <CHTYPE .ACS:TOP LIST>) (NACS 1)
+                    (RES:TOP (())) (RES:BOT .RES:TOP) (ARGN 1) (BNDL:TOP (()))
+                    (BNDL:BOT .BNDL:TOP) (MODE ,TOT-MODES) (DOIT ,INIT-D)
+                    (ST <>) T T1 SVT (IX 0) TIX VIX)
+   #DECL ((ACS:BOT RES:BOT BNDL:TOP BNDL:BOT) <SPECIAL LIST> (RES:TOP) LIST
+         (ACS:TOP) <SPECIAL <PRIMTYPE LIST>> (NACS ARGN) <SPECIAL FIX>
+         (VIX) <VECTOR [REST STRING]> (MODE) <SPECIAL <VECTOR [REST STRING]>>
+         (IX) FIX (DOIT) <SPECIAL ANY> (ARGL) LIST (SVTBL SVT) SYMTAB
+         (DCL) <SPECIAL <PRIMTYPE LIST>>)
+   <REPEAT ()
+          <AND <EMPTY? .ARGL> <RETURN>>
+          <COND (<SET T1 <TYPE? <SET T <1 .ARGL>> ATOM FORM LIST>>
+                 <SET ST <>>
+                 <APPLY .DOIT .T .T1>)
+                (<TYPE? .T STRING>
+                 <AND .ST <MESSAGE ERROR " TWO DECL STRINGS IN A ROW ">>
+                 <SET ST T>
+                 <OR <SET TIX <MEMBER .T .MODE>>
+                         <MESSAGE ERROR " UNRECOGNIZED STRING IN DECL " .T>>
+                 <SET VIX .TIX>
+                 <SET MODE <REST .MODE <NTH ,RESTS <SET IX <LENGTH .VIX>>>>>
+                 <SET DOIT <NTH ,DOITS .IX>>
+                 <COND (<OR <L? .IX 5> <G? .IX 8>>)
+                       (ELSE <PUT-RES (<COND (<=? <1 .ARGL> "OPT">
+                                              "OPTIONAL")
+                                             (ELSE <1 .ARGL>)>)>)>)
+                (ELSE <MESSAGE ERROR " BAD THING IN DECL " .T>)>
+          <SET ARGL <REST .ARGL>>>
+   <AND .HATOM <ACT-D .HATOM <TYPE .HATOM>>>
+   <REPEAT (DC DC1)
+          #DECL ((DC1) FORM (DC) ANY (VARTBL) <SPECIAL SYMTAB>)
+          <COND (<EMPTY? .DCL> <RETURN>)
+                (<EMPTY? <REST .DCL>> <MESSAGE ERROR  "DECL LIST AT END OF DECL">)>
+          <SET DC <2 .DCL>>
+          <COND (<AND <TYPE? .DC FORM>
+                      <SET DC1 .DC>
+                      <==? <LENGTH .DC1> 2>
+                      <OR <==? <1 .DC1> SPECIAL> <==? <1 .DC1> UNSPECIAL>>>
+                 <SET DC <2 .DC1>>)>
+          <MAPF <>
+                <FUNCTION (ATM)
+                        <OR <==? .ATM VALUE>
+                            <SRCH-SYM .ATM>
+                            <ADDVAR .ATM T -1 0 T (.DC) <> <>>>>
+                <CHTYPE <1 .DCL> LIST>>
+          <SET DCL <REST .DCL 2>>>
+   <SET SVT .VARTBL>
+   <SET VARTBL .SVTBL>
+   <COND (<N==? .SVTBL .SVT>
+      <REPEAT ((SV .SVT))
+          #DECL ((SV) SYMTAB)
+          <COND (<==? <NEXT-SYM .SV> .SVTBL>
+                 <PUT .SV ,NEXT-SYM .VARTBL>
+                 <SET VARTBL .SVT>
+                 <RETURN>)
+                (ELSE <SET SV <NEXT-SYM .SV>>)>>)>
+   <AND <L? <SET TRG <- .ARGN 1>> 0> <SET RQRG -1>>
+   <COND (<OR <NOT .ACS:TOP> <=? .ACS:TOP '(() STACK)>>
+         <REPEAT ((BB ()) B (CHNG T) (N1 0) (N2 0) TEM)
+                 #DECL ((BB B) <LIST [REST SYMTAB]> (N1 N2) FIX (TEM) SYMTAB)
+                 <COND (<EMPTY? .BB>
+                        <OR .CHNG <RETURN>>
+                        <SET CHNG <>>
+                        <SET N1 0>
+                        <SET B .BNDL:TOP>
+                        <SET BB <REST .B>>
+                        <AGAIN>)>
+                 <COND (<NOT <0? <SET N2 <ARGNUM-SYM <SET TEM <1 .BB>>>>>>
+                        <COND (<G? .N1 .N2>
+                               <PUT .BB 1 <1 .B>>
+                               <PUT .B 1 .TEM>
+                               <SET CHNG T>)
+                              (ELSE <SET N1 .N2>)>)
+                       (ELSE <SET BB ()> <AGAIN>)>
+                 <SET B <REST .B>>
+                 <SET BB <REST .BB>>>)>
+   (<REST .RES:TOP>
+    <REST .BNDL:TOP>
+    !<COND (.ACS:TOP (<REST .ACS:TOP>)) (ELSE ())!>)>
+
+
+<DEFINE SRCH-SYM (ATM "AUX" (TB .VARTBL))
+       #DECL ((ATM) ATOM (TB) <PRIMTYPE VECTOR>)
+       <REPEAT ()
+               <AND <EMPTY? .TB> <RETURN <>>>
+               <AND <==? .ATM <NAME-SYM .TB>> <RETURN .TB>>
+               <SET TB <NEXT-SYM .TB>>>>
+
+"Vector of legal strings in decl list."
+
+<SETG TOT-MODES
+      ["BIND"
+       "CALL"
+       "OPT"
+       "OPTIONAL"
+       "ARGS"
+       "TUPLE"
+       "AUX"
+       "EXTRA"
+       "ACT"
+       "NAME"]>
+
+"Amount to rest off decl vector after each encounter."
+
+<SETG RESTS ![1 2 1 2 1 2 1 2 1 1!]>
+
+"This function used for normal args when \"BIND\" and \"CALL\" still possible."
+
+<DEFINE INIT-D (OBJ TYP) #DECL ((MODE) <VECTOR STRING>)
+       <SET MODE <REST .MODE>> <INIT1-D .OBJ .TYP>>
+
+"This function for normal args when \"CALL\" still possible."
+
+<DEFINE INIT1-D (OBJ TYP)
+       #DECL ((MODE) <VECTOR STRING>)
+       <SET MODE <REST .MODE>>
+       <SET DOIT ,NORM-D>
+       <NORM-D .OBJ .TYP>>
+\f
+"Handle a normal argument or quoted normal argument."
+
+<DEFINE NORM-D (OBJ TYP) #DECL ((TYP) ATOM (RQRG ARGN) FIX (DCL) DECL)
+       <AND <==? .TYP LIST>
+           <MESSAGE ERROR " LIST NOT IN OPT OR AUX " .OBJ>>
+       <SET RQRG <+ .RQRG 1>>
+       <COND (<==? .TYP ATOM>
+              <PUT-RES (<PUT-DCL 13 .OBJ <><FIND:DECL .OBJ .DCL> T>)>)
+             (<SET OBJ <QUOTCH .OBJ>>
+              <PUT-RES ("QUOTE" <PUT-DCL 12 .OBJ <> <FIND:DECL .OBJ .DCL> T>)>)>
+       <SET ARGN <+ .ARGN 1>>>
+
+"Handle \"BIND\" decl."
+
+<DEFINE BIND-D (OBJ TYP "AUX" DC) #DECL ((TYP) ATOM (ARGN) FIX (DCL) DECL)
+       <SET ACS:TOP <>>
+       <OR <==? .TYP ATOM> <MESSAGE ERROR " BAD BIND " .OBJ>>
+       <SET DC <PUT-DCL 11 .OBJ <> <FIND:DECL .OBJ .DCL> T>>
+       <TYPE-ATOM-OK? .DC ENVIRONMENT .OBJ>
+       <SET DOIT ,INIT1-D>>
+
+"Handle \"CALL\" decl."
+
+<DEFINE CALL-D (OBJ TYP "AUX" DC) #DECL ((TYP) ATOM (RQRG ARGN) FIX (DCL) DECL)
+       <SET RQRG <+ .RQRG 1>>
+       <OR <==? .TYP ATOM> <MESSAGE ERROR " BAD CALL " .OBJ>>
+       <PUT-RES (<SET DC <PUT-DCL 10 .OBJ <> <FIND:DECL .OBJ .DCL> T>>)>
+       <TYPE-ATOM-OK? .DC FORM .OBJ>
+       <SET ARGN <+ .ARGN 1>>
+       <SET DOIT ,ERR-D>>
+
+"Flush on extra atoms after \"CALL\", \"ARGS\" etc."
+
+<DEFINE ERR-D (OBJ TYPE) <MESSAGE ERROR " BAD SYNTAX ARGLIST " .OBJ>>
+
+"Handle \"OPTIONAL\" decl."
+
+<DEFINE OPT-D (OBJ TYP "AUX" DC OBJ1)
+       #DECL ((TYP) ATOM (ARGN) FIX (DCL) DECL)
+       <COND (.ACS:TOP <SET ACS:TOP '(() STACK)>)> ;"Temporary until know how to win."
+       <COND (<==? .TYP ATOM>
+              <PUT-RES (<PUT-DCL 9 .OBJ <><FIND:DECL .OBJ .DCL> <>>)>)
+             (<==? .TYP FORM>
+              <SET OBJ <QUOTCH .OBJ>>
+              <PUT-RES ("QUOTE" <PUT-DCL 8 .OBJ <> <FIND:DECL .OBJ .DCL> <>>)>)
+             (<TYPE? <SET OBJ1 <LISTCH .OBJ>> ATOM>
+              <PUT-RES (<PAUX .OBJ1 <2 <CHTYPE .OBJ LIST>> <FIND:DECL .OBJ1 .DCL> 7>)>)
+             (<TYPE? .OBJ1 FORM>
+              <SET OBJ1 <QUOTCH .OBJ1>>
+              <PUT-RES ("QUOTE"
+                        <PAUX .OBJ1 <2 <CHTYPE .OBJ LIST>> <FIND:DECL .OBJ1 .DCL> 6>)>)
+             (ELSE <MESSAGE ERROR "BAD USE OF OPTIONAL " .OBJ>)>
+       <SET ARGN <+ .ARGN 1>>>
+
+"Handle \"ARGS\" decl."
+
+<DEFINE ARGS-D (OBJ TYP "AUX" DC)
+       #DECL ((TYP) ATOM (RQRG ARGN) FIX (DCL) DECL (BNDL:BOT) <LIST SYMTAB>)
+       <COND (.ACS:TOP <SET ACS:TOP '(() STACK)>)> ;"Temporary until know how to win."
+       <OR <==? .TYP ATOM> <MESSAGE ERROR " BAD ARGS " .OBJ>>
+       <PUT-RES (<SET DC <PUT-DCL 5 .OBJ <> <FIND:DECL .OBJ .DCL> <>>>)>
+       <TYPE-ATOM-OK? .DC LIST .OBJ>
+       <SET DOIT ,ERR-D>
+       <SET ARGN <+ .ARGN 1>>>
+
+"Handle \"TUPLE\" decl."
+
+<DEFINE TUP-D (OBJ TYP "AUX" DC)
+       #DECL ((TYP) ATOM (ARGN) FIX (DCL) DECL)
+       <OR <==? .TYP ATOM> <MESSAGE ERROR " BAD TUPLE " .OBJ>>
+       <COND (<1? .ARGN> <SET ARGN 0> <SET ACS:TOP '(() STACK)>)
+             (ELSE <SET ACS:TOP <>>)>
+       <PUT-RES (<SET DC <PUT-DCL 4 .OBJ <> <FIND:DECL .OBJ .DCL> <>>>)>
+       <TYPE-ATOM-OK? .DC TUPLE .OBJ>
+       <SET DOIT ,ERR-D>>
+
+\f
+"Handle \"AUX\" decl."
+
+<DEFINE AUX-D (OBJ TYP "AUX" DC OBJ1)
+       #DECL ((TYP) ATOM (ARGN) FIX (DCL) DECL)
+       <AND <==? .TYP FORM> <MESSAGE ERROR " QUOTED AUX " .OBJ>>
+       <COND (<==? .TYP ATOM>
+              <PUT-DCL 3 .OBJ <> <FIND:DECL .OBJ .DCL> <>>)
+             (<TYPE? <SET OBJ1 <LISTCH .OBJ>> ATOM>
+              <PAUX .OBJ1 <2 .OBJ> <FIND:DECL .OBJ1 .DCL> 2>)
+             (ELSE <MESSAGE ERROR " QUOTED AUX " .OBJ>)>>
+
+"Handle \"NAME\" and \"ACT\" decl."
+
+<DEFINE ACT-D (OBJ TYP "AUX" DC)
+       #DECL ((TYP) ATOM (ARGN) FIX (DCL) DECL)
+       <OR <==? .TYP ATOM>
+               <MESSAGE ERROR " BAD ACTIVATION " .OBJ>>
+       <SET DC <PUT-DCL 1 .OBJ <> <FIND:DECL .OBJ .DCL> <>>>
+       <TYPE-ATOM-OK? .DC ACTIVATION .OBJ>>
+
+"Fixup activation atoms after node generated."
+
+<DEFINE ACT-FIX (N L "AUX" (FLG <>)) #DECL ((N) NODE (L) <LIST [REST SYMTAB]>)
+       <REPEAT (SYM) #DECL ((SYM) SYMTAB)
+               <AND <EMPTY? .L> <RETURN .FLG>>
+               <COND (<AND <==? <CODE-SYM <SET SYM <1 .L>>> 1>
+                           <SET FLG T>
+                           <NOT <SPEC-SYM .SYM>>>
+                      <PUT .SYM ,RET-AGAIN-ONLY .N>)>
+               <SET L <REST .L>>>>
+
+"Table of varius decl handlers."
+
+<SETG DOITS
+      ![,ACT-D ,ACT-D ,AUX-D ,AUX-D ,TUP-D ,ARGS-D ,OPT-D ,OPT-D ,CALL-D
+       ,BIND-D!]>
+
+<GDECL (DOITS) UVECTOR (TOT-MODES) <VECTOR [REST STRING]> (RESTS) <UVECTOR [REST FIX]>>
+
+"Check for quoted arguments."
+
+<DEFINE QUOTCH (OB) #DECL ((OB) FORM (VALUE) ATOM)
+       <COND (<AND <==? <LENGTH .OB> 2>
+                   <==? <1 .OB> QUOTE>
+                   <TYPE? <2 .OB> ATOM>>
+              <2 .OB>)
+             (ELSE <MESSAGE ERROR " BAD FORM IN ARGLIST " .OB> T)>>
+
+"Chech for (arg init) or ('arg init)."
+
+<DEFINE LISTCH (OB) #DECL ((OB) LIST)
+       <COND (<AND <==? <LENGTH .OB> 2>
+                   <OR <TYPE? <1 .OB> ATOM>
+                       <AND <TYPE? <1 .OB> FORM> <QUOTCH <1 .OB>>>>>
+              <1 .OB>)
+             (ELSE <MESSAGE ERROR " BAD LIST IN ARGLIST " .OB> T)>>
+
+"Add a decl to RSUBR decls and update AC call spec."
+
+<DEFINE PUT-RES (L "AUX" TY)
+    #DECL ((L) LIST (NACS) FIX (ACS:BOT RES:BOT) LIST)
+    <PROG ()
+       <SET RES:BOT <REST <PUTREST .RES:BOT .L> <LENGTH .L>>>
+       <COND (<AND .ACS:TOP <OR <G? .NACS 5> <=? .ACS:TOP '(() STACK)>>>
+              <SET ACS:TOP '(() STACK)> <RETURN>)>
+       <COND (<AND .ACS:TOP
+                   <REPEAT ()
+                       <COND (<EMPTY? .L><RETURN <>>)
+                             (<TYPE? <SET TY <1 .L>> STRING>
+                              <SET L <REST .L>>)
+                             (ELSE <RETURN T>)>>>
+              <COND (<SET TY <ISTYPE-GOOD? .TY>>
+                     <SET ACS:BOT <REST <PUTREST .ACS:BOT
+                                                 ((.TY <NTH ,ALLACS .NACS>))>>>
+                     <SET NACS <+ .NACS 1>>)
+                    (<L? <SET NACS <+ .NACS 2>> 7>
+                     <SET ACS:BOT <REST <PUTREST .ACS:BOT
+                                                 ((<NTH ,ALLACS <- .NACS 2>>
+                                                  <NTH ,ALLACS <- .NACS 1>>))>>>)
+                    (ELSE <SET ACS:TOP '(() STACK)>)>)>
+       T>>
+
+"Add code to set up a certain kind of argument."
+
+<DEFINE PUT-DCL (COD ATM VAL DC COM "AUX" SPC DC1 TT SYM)
+       #DECL ((DC1) FORM (ATM) ATOM (BNDL:BOT BNDL:TOP TT) LIST (COD) FIX
+              (SYM) SYMTAB)
+       <COND (<AND <TYPE? .DC FORM>
+                   <SET DC1 .DC>
+                   <==? <LENGTH .DC1> 2>
+                   <OR <SET SPC <==? <1 .DC1> SPECIAL>>
+                       <==? <1 .DC1> UNSPECIAL>>>
+              <SET DC <2 .DC1>>)
+             (ELSE <SET SPC .GLOSP>)>
+       <SET SYM <ADDVAR .ATM .SPC .COD .ARGN T (.DC) <> .VAL>>
+       <COND (<AND .COM <NOT <SPEC-SYM .SYM>>> ;"Can specials commute?"
+              <SET TT <REST .BNDL:TOP>>
+              <PUTREST .BNDL:TOP (.SYM !.TT)>
+              <AND <EMPTY? .TT> <SET BNDL:BOT <REST .BNDL:TOP>>>)
+             (ELSE <SET BNDL:BOT <REST <PUTREST .BNDL:BOT (.SYM)>>>)>
+       .DC>
+
+"Find decl associated with a variable, if none, use ANY."
+
+<DEFINE FIND:DECL (ATM "OPTIONAL" (DC .DECLS)) 
+       #DECL ((DC) <PRIMTYPE LIST> (ATM) ATOM)
+       <REPEAT (TT)
+               #DECL ((TT) LIST)
+               <AND <OR <EMPTY? .DC> <EMPTY? <SET TT <REST .DC>>>>
+                    <RETURN ANY>>
+               <COND (<NOT <TYPE? <1 .DC> LIST>>
+                      <MESSAGE ERROR " BAD DECL LIST " .DC>)>
+               <AND <MEMQ .ATM <CHTYPE <1 .DC> LIST>> <RETURN <1 .TT>>>
+               <SET DC <REST .TT>>>>
+
+"Add an AUX variable spec to structure."
+
+<DEFINE PAUX (ATM OBJ DC NTUP "AUX" EV TT) 
+       #DECL ((EV TT) NODE (TUP NTUP) FIX (ATM) ATOM)
+       <COND (<AND <TYPE? .OBJ FORM>
+                   <NOT <EMPTY? .OBJ>>
+                   <OR <==? <1 .OBJ> TUPLE> <==? <1 .OBJ> ITUPLE>>>
+              <SET TT
+                   <NODEFM <COND (<==? <1 .OBJ> TUPLE> ,COPY-CODE)
+                                 (ELSE ,ISTRUC-CODE)>
+                           ()
+                           TUPLE
+                           <1 .OBJ>
+                           ()
+                           ,<1 .OBJ>>>
+              <COND (<==? <NODE-TYPE .TT> ,ISTRUC-CODE>
+                     <SET EV
+                          <PCOMP <COND (<==? <LENGTH .OBJ> 3> <3 .OBJ>)
+                                       (ELSE #LOSE *000000000000*)>
+                                 .TT>>
+                     <COND (<==? <NODE-TYPE .EV> ,QUOTE-CODE>
+                            <SET EV <PCOMP <NODE-NAME .EV> .TT>>
+                                                               ;"Reanalyze it."
+                            <PUT .TT ,NODE-TYPE ,ISTRUC2-CODE>)>
+                     <PUT .TT ,KIDS (<PCOMP <2 .OBJ> .TT> .EV)>)
+                    (ELSE
+                     <PUT .TT
+                          ,KIDS
+                          <MAPF ,LIST
+                                <FUNCTION (O) <PCOMP .O .TT>>
+                                <REST .OBJ>>>)>)
+             (ELSE <SET TT <PCOMP .OBJ ()>>)>
+       <PUT-DCL .NTUP .ATM .TT .DC <>>>
+
+"Main dispatch function during pass1."
+
+<DEFINE PCOMP (OBJ PARENT)
+       #DECL ((PARENT) <SPECIAL ANY> (VALUE) NODE)
+       <APPLY <OR <GET .OBJ PTHIS-OBJECT>
+                  <GET <TYPE .OBJ> PTHIS-TYPE>
+                  ,PDEFAULT>
+               .OBJ>>
+
+"Build a node for <> or #FALSE ()."
+
+<DEFINE FALSE-QT (O)
+       #DECL ((VALUE) NODE)
+       <NODE1 ,QUOTE-CODE .PARENT FALSE <> ()>>
+
+<PUT '<> PTHIS-OBJECT ,FALSE-QT>
+
+"Build a node for ()."
+
+<DEFINE NIL-QT (O) #DECL ((VALUE) NODE)
+       <NODE1 ,QUOTE-CODE .PARENT LIST () ()>>
+
+<PUT () PTHIS-OBJECT ,NIL-QT>
+
+"Build a node for a LIST, VECTOR or UVECTOR."
+
+<DEFINE PCOPY (OBJ "AUX" (TT <NODEFM ,COPY-CODE .PARENT <TYPE .OBJ> <TYPE .OBJ> () <>>))
+       #DECL ((VALUE) NODE (TT) NODE)
+       <PUT .TT ,KIDS
+                <MAPF ,LIST <FUNCTION (O) <PCOMP .O .TT>> .OBJ>>>
+
+<PUT VECTOR PTHIS-TYPE ,PCOPY>
+
+<PUT UVECTOR PTHIS-TYPE ,PCOPY>
+
+<PUT LIST PTHIS-TYPE ,PCOPY>
+
+"Build a node for unknown things."
+
+<DEFINE PDEFAULT (OBJ) #DECL ((VALUE) NODE)
+       <NODE1 ,QUOTE-CODE .PARENT <TYPE .OBJ> .OBJ ()>>
+
+"Further analyze a FORM and build appropriate node."
+
+<DEFINE PFORM (OBJ) #DECL ((OBJ) <FORM ANY> (VALUE) NODE)
+       <PROG APPLICATION ((APPLY <1 .OBJ>))
+               #DECL ((APPLICATION) <SPECIAL ACTIVATION>
+                      (APPLY) <SPECIAL ANY>)
+               <APPLY <OR <GET .APPLY PAPPLY-OBJECT>
+                          <GET <TYPE .APPLY> PAPPLY-TYPE>
+                          ,PAPDEF>
+                      .OBJ .APPLY>>>
+
+<PUT FORM PTHIS-TYPE ,PFORM>
+
+"Build a SEGMENT node."
+
+<DEFINE SEG-FCN (OBJ "AUX" (TT <NODE1 ,SEGMENT-CODE .PARENT <> <> ()>))
+       #DECL ((TT VALUE PARENT) NODE)
+       <PUT .TT ,KIDS (<PFORM <CHTYPE .OBJ FORM>>)>>
+
+<PUT SEGMENT PTHIS-TYPE ,SEG-FCN>
+
+"Analyze a form or the form <ATM .....>"
+
+<DEFINE ATOM-FCN (OB AP) #DECL ((AP) ATOM (VALUE) NODE)
+       <COND (<GASSIGNED? .AP>
+              <SET APPLY ,.AP>
+              <AGAIN .APPLICATION>)
+             (<ASSIGNED? .AP>
+              <MESSAGE WARNING " LOCAL VALUE USED FOR " .AP>
+              <SET APPLY ..AP>
+              <AGAIN .APPLICATION>)
+             (.REASONABLE
+              <PSUBR-C .OB DUMMY>)
+             (ELSE <MESSAGE WARNING " NO VALUE FOR " .AP>
+              <PAPDEF .OB .AP>)>>
+
+<PUT ATOM PAPPLY-TYPE ,ATOM-FCN>
+
+"Expand MACRO and process result."
+
+<DEFINE PMACRO (OBJ AP "AUX" ERR TEM)
+       <SET ERR <ON "ERROR" ,MACROERR 100>>    ;"Turn On new Error"
+       <SET TEM <PROG MACACT ()
+                      #DECL ((MACACT) <SPECIAL ACTIVATION>)
+                      <SETG MACACT .MACACT>
+                      <EXPAND .OBJ>>>
+       <OFF .ERR>                              ;"Turn OFF new Error"
+       <COND (<TYPE? .TEM FUNNY>
+              <MESSAGE ERROR " MACRO EXPANSION LOSSAGE " !.TEM>)
+             (ELSE
+              <PCOMP .TEM .PARENT>)>>
+
+<NEWTYPE FUNNY VECTOR>
+<PROG (X)              ;"Find the real Valret Subr"
+      <COND (<TYPE? ,VALRET SUBR> <SETG REAL-VALRET ,VALRET>)
+           (<AND <GASSIGNED? <SET X <PARSE "OVALRET!-COMBAT!-">>>
+                 <TYPE? ,.X SUBR>>
+            <SETG REAL-VALRET ,.X>)
+           (<NOT <GASSIGNED? REAL-VALRET>> <ERROR ',VALRET COMPILE>)>>
+<PUT MACRO PAPPLY-TYPE ,PMACRO>
+
+<DEFINE MACROERR (FR "TUPLE" T)
+       #DECL ((T) TUPLE)
+       <COND (<AND <GASSIGNED? MACACT> <LEGAL? ,MACACT>>
+              <DISMISS <CHTYPE [!.T] FUNNY> ,MACACT>)
+             (ELSE <REAL-VALRET " ">)>>
+
+"Build a node for a form whose 1st element is a form (could be NTH)."
+
+<DEFINE PFORM-FORM (OBJ AP "AUX" TT)
+       #DECL ((TT) NODE (VALUE) NODE (OBJ) FORM)
+       <COND (<AND <==? <LENGTH .OBJ> 2> <NOT <SEG? .OBJ>>>
+              <SET TT <NODEFM ,FORM-F-CODE .PARENT <> .OBJ () .AP>>
+              <PUT .TT ,KIDS
+                   <MAPF ,LIST <FUNCTION (O) <PCOMP .O .TT>> .OBJ>>)
+             (ELSE <PAPDEF .OBJ .AP>)>>
+
+<PUT FORM PAPPLY-TYPE ,PFORM-FORM>
+
+"Build a node for strange forms."
+
+<DEFINE PAPDEF (OBJ AP) #DECL ((VALUE) NODE)
+       <MESSAGE WARNING " FORM NOT BEING COMPILED " .OBJ>
+       <SPECIALIZE .OBJ>
+       <NODEFM ,FORM-CODE .PARENT <> .OBJ  () .AP>>
+
+"For objects that require EVAL, make sure all atoms used are special."
+
+<DEFINE SPECIALIZE (OBJ "AUX" T1 T2 SYM OB)
+       #DECL ((T1) FIX (OB) FORM (T2) <OR FALSE SYMTAB>)
+       <COND (<AND <TYPE? .OBJ FORM SEGMENT>
+                   <SET OB <CHTYPE .OBJ FORM>>
+                   <OR <AND <==? <SET T1 <LENGTH .OB>> 2>
+                            <==? <1 .OB> LVAL>
+                            <TYPE? <SET SYM <2 .OB>> ATOM>>
+                       <AND <==? .T1 3>
+                            <==? <1 .OB> SET>
+                            <TYPE? <SET SYM <2 .OB>> ATOM>>>
+                   <SET T2 <SRCH-SYM .SYM>>>
+              <COND (<NOT <SPEC-SYM .T2>>
+                     <MESSAGE NOTE " REDCLARED SPECIAL " .SYM>
+                     <PUT .T2 ,SPEC-SYM T>)>)>
+       <COND (<MEMQ <PRIMTYPE .OBJ> '![FORM LIST UVECTOR VECTOR!]>
+              <MAPF <> ,SPECIALIZE .OBJ>)>>
+
+"Build a SUBR call node."
+
+<DEFINE PSUBR-C (OBJ AP "AUX" (TT <NODEFM ,SUBR-CODE .PARENT <>
+                                         <SUBR-NAME .AP <1 .OBJ>> () .AP>))
+       #DECL ((TT) NODE (VALUE) NODE (OBJ) FORM)
+       <PUT .TT ,KIDS
+                <MAPF ,LIST <FUNCTION (O) <PCOMP .O .TT>> <REST .OBJ>>>>
+
+<PUT SUBR PAPPLY-TYPE ,PSUBR-C>
+
+<FLOAD "SBRNAM" "NBIN">
+
+<DEFINE SUBR-NAME (THING DEFAULT)
+       <COND (<TYPE? .THING SUBR> <HACK-NAME .THING>)
+             (<TYPE? .THING RSUBR RSUBR-ENTRY> <2 .THING>)
+             (ELSE .DEFAULT)>>
+
+<DEFINE FIX-FCN (OBJ AP "AUX" TT (LN <LENGTH .OBJ>))
+       #DECL ((TT VALUE) NODE (OBJ) FORM)
+       <OR <==? .LN 2> <==? .LN 3>
+           <MESSAGE ERROR " BAD APPLICATION OF A NUMBER ">>
+       <SET TT <NODEFM ,SUBR-CODE .PARENT <> <COND (<==? .LN 2> INTH)(ELSE IPUT)>
+                        () <COND (<==? .LN 2> ,NTH) (ELSE ,PUT)>>>
+       <PUT .TT ,KIDS (<PCOMP <2 .OBJ> .TT><PCOMP .AP .TT>
+                       !<COND (<==? .LN 2> ()) (ELSE (<PCOMP <3 .OBJ> .TT>))>)>>
+
+<PUT FIX PAPPLY-TYPE ,FIX-FCN>
+
+<PUT OFFSET PAPPLY-TYPE ,FIX-FCN>
+
+"PROG/REPEAT node."
+
+<DEFINE PPROG-REPEAT (OBJ AP
+                     "AUX" (NAME <1 .OBJ>) TT (DCL #DECL ()) (HATOM <>) ARGL
+                           (VARTBL .VARTBL))
+       #DECL ((OBJ) <PRIMTYPE LIST> (TT) NODE (VALUE) NODE (DCL) DECL
+              (ARGL) LIST (VARTBL) <SPECIAL SYMTAB>)
+       <AND <EMPTY? <SET OBJ <REST .OBJ>>>
+           <MESSAGE ERROR " EMPTY " .NAME>>
+       <AND <TYPE? <1 .OBJ> ATOM>
+           <SET HATOM <1 .OBJ>>
+           <SET OBJ <REST .OBJ>>>
+       <SET ARGL <1 .OBJ>>
+       <SET OBJ <REST .OBJ>>
+       <AND <NOT <EMPTY? .OBJ>>
+            <TYPE? <1 .OBJ> DECL>
+            <SET DCL <1 .OBJ>>
+            <SET OBJ <REST .OBJ>>>
+       <AND <EMPTY? .OBJ> <MESSAGE ERROR " NO DODY FOR " .NAME>>
+       <SET TT
+            <NODEPR ,PROG-CODE
+                    .PARENT
+                    <FIND:DECL VALUE .DCL>
+                    .NAME
+                    ()
+                    .AP
+                    <2 <GEN-D <COND (<AND <NOT <EMPTY? .ARGL>>
+                                          <TYPE? <1 .ARGL> STRING>>
+                                     .ARGL)
+                                    (ELSE ("AUX" !.ARGL))>
+                              .DCL
+                              .HATOM>>
+                    .HATOM
+                    .VARTBL>>
+       <ACT-FIX .TT <BINDING-STRUCTURE .TT>>
+       <PUT .TT
+            ,KIDS
+            <MAPF ,LIST <FUNCTION (O) <PCOMP .O .TT>> .OBJ>>
+       .TT>
+
+<PUT ,PROG PAPPLY-OBJECT ,PPROG-REPEAT>
+
+<PUT ,REPEAT PAPPLY-OBJECT ,PPROG-REPEAT>
+
+<PUT ,BIND PAPPLY-OBJECT ,PPROG-REPEAT>
+
+"Unwind compiler."
+
+<DEFINE UNWIND-FCN (OBJ AP "AUX" (TT <NODEFM ,UNWIND-CODE .PARENT <>
+                                                <1 .OBJ> () .AP>))
+       #DECL ((PARENT VALUE TT) NODE (OBJ) FORM)
+       <COND (<==? <LENGTH .OBJ> 3>
+              <PUT .TT ,KIDS (<PCOMP <2 .OBJ> .TT> <PCOMP <3 .OBJ> .TT>)>)
+             (ELSE <MESSAGE ERROR "WRONG # OF ARGS TO UNWIND " .OBJ>)>>
+
+<PUT ,UNWIND PAPPLY-OBJECT ,UNWIND-FCN>
+
+"Build a node for a COND."
+
+<DEFINE COND-FCN (OBJ AP "AUX" (PARENT <NODECOND ,COND-CODE .PARENT <> COND ()>))
+       #DECL ((PARENT) <SPECIAL NODE> (OBJ) <FORM ANY> (VALUE) NODE)
+       <PUT .PARENT ,KIDS
+            <MAPF ,LIST
+                   <FUNCTION (CLA "AUX" (TT <NODEB ,BRANCH-CODE .PARENT <> <> ()>))
+                       #DECL ((TT) NODE)
+                       <COND (<AND <TYPE? .CLA LIST> <NOT <EMPTY? .CLA>>>
+                              <PUT .TT ,PREDIC <PCOMP <1 .CLA> .TT>>
+                              <PUT .TT ,CLAUSES
+                                <MAPF ,LIST
+                                      <FUNCTION (O) <PCOMP .O .TT>>
+                                                    <REST .CLA>>>)
+                              (ELSE <MESSAGE ERROR "BAD COND" .OBJ>)>>
+                   <REST .OBJ>>>>
+
+<PUT ,COND PAPPLY-OBJECT ,COND-FCN>
+
+<PUT ,AND PAPPLY-OBJECT <GET SUBR PAPPLY-TYPE>>
+
+<PUT ,OR PAPPLY-OBJECT <GET SUBR PAPPLY-TYPE>>
+
+<PUT ,STACKFORM PAPPLY-OBJECT <GET SUBR PAPPLY-TYPE>>
+
+"Build a node for '<\b-object>\b-."
+
+<DEFINE QUOTE-FCN (OBJ AP "AUX" (TT <NODE1 ,QUOTE-CODE .PARENT <> () ()>))
+       #DECL ((TT VALUE) NODE (OBJ) FORM)
+       <COND (<NOT <EMPTY? <REST .OBJ>>>
+              <PUT .TT ,RESULT-TYPE <TYPE <2 .OBJ>>>
+              <PUT .TT ,NODE-NAME <2 .OBJ>>)>>
+
+<PUT ,QUOTE PAPPLY-OBJECT ,QUOTE-FCN>
+
+"Build a node for a call to an RSUBR."
+
+<DEFINE RSUBR-FCN (OBJ AP "AUX" (PARENT <NODEFM ,RSUBR-CODE .PARENT <><1 .OBJ> () .AP>))
+       #DECL ((OBJ) FORM (AP) <OR RSUBR-ENTRY RSUBR> (PARENT) <SPECIAL NODE>
+              (VALUE) NODE)
+       <COND (<AND <G? <LENGTH .AP> 2>
+                   <TYPE? <3 .AP> DECL>>
+              <PUT .PARENT ,KIDS <PRSUBR-C <1 .OBJ> .OBJ <3 .AP>>>
+              <PUT .PARENT ,TYPE-INFO 
+                   <MAPF ,LIST
+                         <FUNCTION (X) <RESULT-TYPE .X>> <KIDS .PARENT>>>)
+             (ELSE <PSUBR-C .OBJ .AP>)>>
+
+<PUT RSUBR PAPPLY-TYPE ,RSUBR-FCN>
+
+<PUT RSUBR-ENTRY PAPPLY-TYPE <GET RSUBR PAPPLY-TYPE>>
+
+<DEFINE INTERNAL-RSUBR-FCN (OBJ AP
+                           "AUX" (PARENT <NODEFM ,IRSUBR-CODE .PARENT <>
+                                                 <1 .OBJ> () .AP>))
+       #DECL ((OBJ) FORM (AP) IRSUBR (PARENT) <SPECIAL NODE>)
+       <PUT .PARENT ,KIDS <PRSUBR-C <1 .OBJ> .OBJ <1 .AP>>>
+       <PUT .PARENT ,TYPE-INFO 
+                   <MAPF ,LIST
+                         <FUNCTION (X) <RESULT-TYPE .X>> <KIDS .PARENT>>>>
+
+<PUT IRSUBR PAPPLY-TYPE ,INTERNAL-RSUBR-FCN>
+
+"Predicate:  any segments in this object?"
+
+<DEFINE SEG? (OB) #DECL ((OB) <PRIMTYPE LIST>)
+       <REPEAT ()
+               <AND <EMPTY? .OB> <RETURN <>>>
+               <AND <TYPE? <1 .OB> SEGMENT> <RETURN T>>
+               <SET OB <REST .OB>>>>
+
+
+"Analyze a call to an RSUBR with decls checking number of args and types wherever
+ possible."
+
+<DEFINE PRSUBR-C (NAME OBJ RDCL
+                 "AUX" (DOIT ,INIT-R) (SEGSW <>) (SGD '<>) (SGP '(1)) SGN
+                       (IX 0) DC (RM ,RMODES) (ARG-NUMBER 0) (KDS (()))
+                       (TKDS .KDS) RMT (OB <REST .OBJ>) (ST <>))
+   #DECL ((TKDS KDS) <SPECIAL LIST> (OB) LIST (OBJ) <SPECIAL <PRIMTYPE LIST>>
+         (RM) <SPECIAL <VECTOR [REST STRING]>> (ARG-NUMBER) FIX
+         (RDCL) <SPECIAL <PRIMTYPE LIST>> (DOIT SEGSW) <SPECIAL ANY> (IX) FIX
+         (NAME) <SPECIAL ANY> (SGD) FORM (SGP) <LIST ANY> (SGN) NODE)
+   <REPEAT RSB ()
+     #DECL ((RSB) <SPECIAL ACTIVATION>)
+     <COND
+      (<NOT <EMPTY? .RDCL>>
+       <COND (<NOT <EMPTY? .RM>>
+             <SET DC <1 .RDCL>>
+             <SET RDCL <REST .RDCL>>)>
+       <COND
+       (<TYPE? .DC STRING>
+        <COND (<=? .DC "OPT"> <SET DC "OPTIONAL">)>
+        <OR <SET RMT <MEMBER .DC .RM>>
+                <MESSAGE ERROR "BAD STRING IN RSUBR DECL " .NAME>>
+        <SET RM .RMT>
+        <SET DOIT <NTH ,RDOIT <SET IX <LENGTH .RM>>>>
+        <SET ST <APPLY <NTH ,SDOIT .IX> .ST>>
+        <COND (<EMPTY? .RM>                                      ;"TUPLE seen."
+               <SET DC <GET-ELE-TYPE <1 .RDCL> ALL>>)>)
+       (<COND
+         (<EMPTY? .OB>
+          <AND <L? <LENGTH .RM> 4> <RETURN <REST .TKDS>>>
+          <MESSAGE ERROR " TOO FEW ARGS TO " .NAME>)
+         (.SEGSW
+          <SET ST <>>
+          <COND (<EMPTY? .RM>
+                 <PUTREST .SGP ([REST .DC])>
+                 <PUT .SGN ,RESULT-TYPE <TYPE-AND <RESULT-TYPE .SGN> .SGD>>
+                 <RETURN <REST .TKDS>>)
+                (ELSE <SET SGP <REST <PUTREST .SGP (.DC)>>>)>)
+         (<TYPE? <1 .OB> SEGMENT>
+          <SET KDS
+               <REST <PUTREST .KDS (<SET SGN <SEGCHK <1 .OB>>>)>>>
+          <COND
+           (<EMPTY? <REST .OB>>
+            <COND (<EMPTY? .RM>
+                   <PUT .SGN
+                        ,RESULT-TYPE
+                        <SEGCH1 .DC <RESULT-TYPE .SGN> <1 .OB>>>
+                   <RETURN <REST .TKDS>>)
+                  (ELSE <SET SEGSW T>)>)
+           (ELSE
+            <PUTREST
+             .KDS
+             <MAPF ,LIST
+              <FUNCTION (O "AUX" TT) 
+                 <SET TT <PCOMP .O .PARENT>>
+                 <COND
+                  (<EMPTY? .RM>
+                   <COND
+                    (<==? <NODE-TYPE .TT> ,SEGMENT-CODE>
+                     <OR <TYPE-OK? <RESULT-TYPE <1 <KIDS .TT>>>
+                                   <FORM STRUCTURED [REST .DC]>>
+                         <MESSAGE ERROR "BAD ARG TO " .NAME .OB>>)
+                    (ELSE
+                     <OR <TYPE-OK? <RESULT-TYPE .TT> .DC>
+                         <MESSAGE ERROR "BAD ARG TO " .NAME .OB>>
+                     <OR <RESULT-TYPE .TT> <PUT .TT ,RESULT-TYPE .DC>>)>)>
+                 .TT>
+              <REST .OB>>>
+            <RETURN <REST .TKDS>>)>
+          <SET SGP
+               <REST <CHTYPE <SET SGD <FORM STRUCTURED .DC>> LIST>>>
+          <SET ST <>>
+          <AGAIN>)
+         (<SET KDS <REST <PUTREST .KDS (<APPLY .DOIT .DC .OB>)>>>
+          <SET OB <REST .OB>>
+          <SET ARG-NUMBER <+ .ARG-NUMBER 1>>
+          <SET ST <>>)>)>)
+      (<EMPTY? .OB> <RETURN <REST .TKDS>>)
+      (.SEGSW
+       <PUT .SGN
+           ,RESULT-TYPE
+           <COND (<RESULT-TYPE .SGN> <TYPE-AND <RESULT-TYPE .SGN> .SGD>)
+                 (ELSE .SGD)>>
+       <RETURN <REST .TKDS>>)
+      (ELSE <MESSAGE ERROR " TOO MANY ARGS TO " .NAME>)>>>    
+\f
+
+<DEFINE SQUOT (F) T>
+
+"Flush one possible decl away."
+
+<DEFINE CHOPPER (F) #DECL ((RM) <VECTOR [REST STRING]>)
+       <AND .F <MESSAGE ERROR " 2 STRINGS IN ROW IN DCL ">>
+       <SET RM <REST .RM>>
+       T>
+
+"Handle Normal arg when \"VALUE\" still possible."
+
+<DEFINE INIT-R (DC OB)
+       #DECL ((RM) <VECTOR [REST STRING]>)
+       <SET RM <REST .RM 2>> <SET DOIT ,INIT1-R> <INIT1-R .DC .OB>>
+
+"Handle Normal arg when \"CALL\" still possible."
+
+<DEFINE INIT2-R (DC OB)
+       #DECL ((RM) <VECTOR [REST STRING]>)
+       <SET RM <REST .RM>> <SET DOIT ,INIT1-R> <INIT1-R .DC .OB>>
+
+"Handle normal arg."
+
+<DEFINE INIT1-R (DC OB "AUX" TT) #DECL ((TT) NODE (OB) LIST)
+       <OR <TYPE-OK? 
+                   <RESULT-TYPE 
+                       <SET TT <PCOMP <1 .OB> .PARENT>>> .DC>
+               <MESSAGE ERROR "BAD ARG TO " .NAME>>
+       <OR <RESULT-TYPE .TT><PUT .TT ,RESULT-TYPE .DC>>
+       .TT>
+
+"Handle \"QUOTE\" arg."
+
+<DEFINE QINIT-R (DC OB "AUX" TT) #DECL ((TT) NODE (OB) LIST)
+       <OR <TYPE-OK?
+                  <RESULT-TYPE
+                       <SET TT
+                            <NODE1 ,QUOTE-CODE .PARENT <TYPE <1 .OB>>
+                                   <1 .OB> ()>>> .DC>
+               <MESSAGE ERROR "BAD ARG TO " .NAME>>
+       <SET DOIT ,INIT1-R>
+       .TT>
+
+"Handle \"CALL\" decl."
+
+<DEFINE CAL-R (DC OB "AUX" TT) #DECL ((TKDS KDS) LIST (TT) NODE)
+       <OR <TYPE-OK?
+                  <RESULT-TYPE
+                       <SET TT
+                            <NODE1 ,QUOTE-CODE .PARENT FORM .OBJ ()>>> .DC>
+               <MESSAGE ERROR "BAD ARG TO " .NAME>>
+       <PUTREST .KDS (.TT)>
+       <RETURN <REST .TKDS> .RSB>>
+
+"Handle \"ARGS\" decl."
+
+<DEFINE ARGS-R (DC OB "AUX" TT) #DECL ((TT) NODE (KDS TKDS) LIST)
+       <OR <TYPE-OK?
+                    <RESULT-TYPE
+                       <SET TT
+                            <NODE1 ,QUOTE-CODE .PARENT LIST .OB ()>>> .DC>
+               <MESSAGE "BAD CALL TO " .NAME>>
+       <PUTREST .KDS (.TT)>
+       <RETURN <REST .TKDS> .RSB>>
+
+"Handle \"TUPLE\" decl."
+
+<DEFINE TUPL-R (DC OB "AUX" TT) #DECL ((OB) LIST (TT) NODE)
+       <OR <TYPE-OK? <RESULT-TYPE <SET TT <PCOMP <1 .OB> .PARENT>>> .DC>
+          <MESSAGE ERROR "BAD ARG TO " .NAME>>
+       <OR <RESULT-TYPE .TT> <PUT .TT ,RESULT-TYPE .DC>>
+       .TT>
+
+"Handle stuff with segments in arguments."
+
+<DEFINE SEGCHK (OB "AUX" TT) #DECL ((TT) NODE)
+       <OR <TYPE-OK? <RESULT-TYPE <SET TT <PCOMP .OB .PARENT>>> STRUCTURED>
+           <MESSAGE ERROR "BAD SEGMENT GOODIE. " .OB>>
+       .TT>
+
+
+<DEFINE SEGCH1 (DC RT OB)
+       <OR <TYPE-AND .RT <FORM STRUCTURED [REST .DC]>>
+           <MESSAGE ERROR "BAD ARG TO " .NAME .OB>>>
+
+"Handle \"VALUE\" chop decl and do the rest."
+
+<DEFINE VAL-R (F) #DECL ((RDCL) <PRIMTYPE LIST> (PARENT) NODE)
+       <CHOPPER .F>
+       <PUT .PARENT ,RESULT-TYPE <1 .RDCL>>
+       <SET DOIT ,INIT2-R>
+       <SET F <TYPE? <1 .RDCL> STRING>>
+       <SET RDCL <REST .RDCL>> .F>
+
+<DEFINE ERR-R (DC OB)
+       <MESSAGE INCONISTANCY "SHOULDN'T GET HERE ">>
+
+<SETG RMODES ["VALUE" "CALL" "QUOTE" "OPTIONAL" "QUOTE" "ARGS" "TUPLE"]>
+
+<SETG RDOIT ![,TUPL-R ,ARGS-R ,QINIT-R ,INIT1-R ,QINIT-R ,CAL-R ,ERR-R!]>
+
+<SETG SDOIT ![,CHOPPER ,CHOPPER ,SQUOT ,CHOPPER ,SQUOT ,CHOPPER ,VAL-R!]>
+
+<GDECL (RMODES) <VECTOR [REST STRING]> (RDOIT SDOIT) UVECTOR>
+
+"Create a node for a call to a function."
+
+<DEFINE PFUNC (OB AP "AUX" TEM NAME)
+       #DECL ((OB) <PRIMTYPE LIST> (VALUE) NODE)
+       <COND (<TYPE? <1 .OB> ATOM>
+              <COND (<OR <==? <1 .OB> .FCNS>
+                         <AND <TYPE? .FCNS LIST> <MEMQ <1 .OB> <CHTYPE .FCNS LIST>>>>
+                     <RSUBR-CALL2 ,<1 .OB> <1 .OB> .OB>)
+                    (<SET TEM <GET <1 .OB> RSUB-DEC>>
+                     <RSUBR-CALL3 .TEM <1 .OB> .OB>)
+                    (.REASONABLE <PSUBR-C .OB DUMMY>)
+                    (ELSE
+                     <MESSAGE WARNING "UNCOMPILED FUNCTION CALLED " <1 .OB>>
+                     <PAPDEF .OB ,<1 .OB>>)>)
+             (<TYPE? <1 .OB> FUNCTION>
+              <SET NAME <MAKE:TAG "ANONF">>
+              <ANONF .NAME <1 .OB>>
+              <RSUBR-CALL1 ,.NAME .NAME .OB>)>>
+
+"Call compiler recursively to compile anonymous function."
+
+<DEFINE ANONF (NAME BODY "AUX" (INT? <>) T GROUP-NAME)
+       #DECL ((INT? GROUP-NAME) <SPECIAL <OR FALSE ATOM>> (VALUE) NODE)
+       <MESSAGE NOTE " COMPILING ANONYMOUS FUNCTION ">
+       <SETG .NAME .BODY>
+       <APPLY ,COMP2 .NAME T> ; "Use APPLY to avoid compilation probs."
+       <SET T ,.NAME>
+       <MESSAGE NOTE " FINISHED ANONYMOUS FUNCTION ">
+       <GUNASSIGN .NAME>
+       <NODE1 ,QUOTE-CODE .PARENT RSUBR  .T ()>>
+
+"#FUNCTION (....) compiler -- call ANONF."
+
+<DEFINE FCN-FCN (OB "AUX" (NAME <MAKE:TAG "ANONF">)) <ANONF .NAME .OB>>
+
+<PUT FUNCTION PTHIS-TYPE ,FCN-FCN>
+
+<PUT FUNCTION PAPPLY-TYPE ,PFUNC>
+
+"<FUNCTION (..) ....> compiler -- call ANONF."
+
+<DEFINE FCN-FCN1 (OB AP "AUX" (NAME <MAKE:TAG "ANONF">))
+       #DECL ((OB) <PRIMTYPE LIST>)
+       <ANONF .NAME <CHTYPE <REST .OB> FUNCTION>>>
+
+<PUT ,FUNCTION PAPPLY-OBJECT ,FCN-FCN1>
+
+"Handle RSUBR that is really a function."
+
+<DEFINE RSUBR-CALL2 (BODY NAME OBJ "AUX" ACF
+                       (PARENT <NODEFM ,RSUBR-CODE .PARENT <> .NAME () .BODY>))
+       #DECL ((PARENT) <SPECIAL NODE> (VALUE) NODE)
+       <PUT .PARENT
+            ,KIDS
+            <PRSUBR-C .NAME .OBJ <RSUBR-DECLS <SET ACF <PASS1 .BODY .NAME T .NAME>>>>>
+       <PUT .PARENT ,TYPE-INFO 
+                   <MAPF ,LIST
+                         <FUNCTION (X) <RESULT-TYPE .X>> <KIDS .PARENT>>>>
+
+"Handle an RSUBR that is already an RSUBR."
+
+<DEFINE RSUBR-CALL1 (BODY NAME OBJ "AUX"
+                       (PARENT <NODEFM ,RSUBR-CODE .PARENT <> .NAME () .BODY>))
+       #DECL ((BODY) <PRIMTYPE LIST> (PARENT) <SPECIAL NODE>
+              (VALUE) NODE)
+       <PUT .PARENT ,KIDS <PRSUBR-C .NAME .OBJ <3 .BODY>>>
+       <PUT .PARENT ,TYPE-INFO 
+                   <MAPF ,LIST
+                         <FUNCTION (X) <RESULT-TYPE .X>> <KIDS .PARENT>>>>
+
+<DEFINE RSUBR-CALL3 (DC NAME OBJ "AUX"
+                       (PARENT <NODEFM ,RSUBR-CODE .PARENT <> .NAME () FOO>))
+       #DECL ((PARENT) <SPECIAL NODE>
+              (VALUE) NODE)
+       <PUT .PARENT ,KIDS <PRSUBR-C .NAME .OBJ .DC>>
+       <PUT .PARENT ,TYPE-INFO 
+                   <MAPF ,LIST
+                         <FUNCTION (X) <RESULT-TYPE .X>> <KIDS .PARENT>>>>
+
+\f
+;"ILIST, ISTRING, IVECTOR AND IUVECTOR"
+
+<DEFINE PLIST (O A) <PSTRUC .O .A ILIST LIST>>
+
+<PUT ,ILIST PAPPLY-OBJECT ,PLIST>
+
+<DEFINE PIVECTOR (O A) <PSTRUC .O .A IVECTOR VECTOR>>
+
+<PUT ,IVECTOR PAPPLY-OBJECT ,PIVECTOR>
+
+<DEFINE PISTRING (O A) <PSTRUC .O .A ISTRING STRING>>
+
+<PUT ,ISTRING PAPPLY-OBJECT ,PISTRING>
+
+<DEFINE PIUVECTOR (O A) <PSTRUC .O .A IUVECTOR UVECTOR>>
+
+<PUT ,IUVECTOR PAPPLY-OBJECT ,PIUVECTOR>
+
+<DEFINE PIFORM (O A) <PSTRUC .O .A IFORM FORM>>
+
+<PUT ,IFORM PAPPLY-OBJECT ,PIFORM>
+
+<DEFINE PIBYTES (O A) <PSTRUC .O .A IBYTES BYTES>>
+
+<PUT ,IBYTES PAPPLY-OBJECT ,PIBYTES>
+
+<DEFINE PSTRUC (OBJ AP NAME TYP "AUX" (TT <NODEFM ,ISTRUC-CODE .PARENT .TYP .NAME
+                                                 () ,.NAME>) 
+                                     (LN <LENGTH .OBJ>) N EV SIZ)
+       #DECL ((VALUE N EV TT) NODE (LN) FIX (OBJ) <PRIMTYPE LIST>)
+       <COND (<SEG? .OBJ><PSUBR-C .OBJ .AP>)
+             (ELSE
+              <COND (<==? .NAME IBYTES>
+                     <COND (<L=? .LN 2> <ARGCHK 2 3 .NAME>)
+                           (<G? .LN 4> <ARGCHK .LN 4 .NAME>)>)
+                    (<1? .LN><ARGCHK 1 2 .NAME>)
+                    (<G? .LN 3><ARGCHK .LN 3 .NAME>)>
+              <COND (<==? .NAME IBYTES>
+                     <SET SIZ <PCOMP <2 .OBJ> .TT>>
+                     <SET OBJ <REST .OBJ>>
+                     <SET LN <- .LN 1>>)>
+              <SET N <PCOMP <2 .OBJ> .TT>>
+              <SET EV <PCOMP <COND (<==? .LN 3> <3 .OBJ>)
+                                   (<==? .TYP STRING> <ASCII 0>)
+                                   (<==? .TYP BYTES> 0)
+                                   (ELSE #LOSE 0)> .TT>>
+              <COND (<==? <NODE-TYPE .EV> ,QUOTE-CODE>
+                     <SET EV <PCOMP <NODE-NAME .EV> .TT>>      ;"Reanalyze it."
+                     <PUT .TT ,NODE-TYPE ,ISTRUC2-CODE>)>
+              <PUT .TT ,RESULT-TYPE .TYP>
+              <COND (<ASSIGNED? SIZ> <PUT .TT ,KIDS (.SIZ .N .EV)>)
+                    (ELSE <PUT .TT ,KIDS (.N .EV)>)>)>>
+
+\f
+"READ, READCHR, READSTRING, NEXTCHR, READB, GET, GETL, GETPROP, GETPL"
+
+<PUT ,READ PAPPLY-OBJECT <FUNCTION (O A) <CHANFCNS .O .A READ 2 ANY>>>
+
+<PUT ,GC-READ PAPPLY-OBJECT <FUNCTION (O A) <CHANFCNS .O .A GC-READ 2 ANY>>>
+
+<PUT ,READCHR PAPPLY-OBJECT <FUNCTION (O A) <CHANFCNS .O .A READCHR 2 ANY>>>
+
+<PUT ,NEXTCHR PAPPLY-OBJECT <FUNCTION (O A) <CHANFCNS .O .A NEXTCHR 2 ANY>>>
+
+<PUT ,READB PAPPLY-OBJECT <FUNCTION (O A) <CHANFCNS .O .A READB 3 ANY>>>
+
+<PUT ,READSTRING
+     PAPPLY-OBJECT
+     <FUNCTION (O A) <CHANFCNS .O .A READSTRING 4 ANY>>>
+
+<DEFINE CHANFCNS (OBJ AP NAME ARGN TYP "AUX" TT (LN <LENGTH .OBJ>) N (TEM 0))
+       #DECL ((VALUE) NODE (TT) NODE (N) <LIST [REST NODE]>
+              (LN) FIX (TEM ARGN) FIX (OBJ) <PRIMTYPE LIST>)
+       <COND (<OR <SEG? .OBJ> <L? <- .LN 1> .ARGN>>
+              <PSUBR-C .OBJ .AP>)
+             (ELSE
+              <SET TT <NODEFM ,READ-EOF-CODE .PARENT .TYP .NAME () ,.NAME>>
+              <SET N
+                   <MAPF ,LIST
+                         <FUNCTION (OB "AUX" (EV <PCOMP .OB .TT>))
+                               #DECL ((EV) NODE)
+                               <COND (<==? <SET TEM <+ .TEM 1>> .ARGN>
+                                      <COND (<==? <NODE-TYPE .EV> ,QUOTE-CODE>
+                                             <SET EV <PCOMP <NODE-NAME .EV> .TT>>
+                                             <PUT .TT ,NODE-TYPE ,READ-EOF2-CODE>)>
+                                      <SET EV
+                                           <NODE1 ,EOF-CODE .TT
+                                                  <RESULT-TYPE .EV> <> (.EV)>>)>
+                               .EV>
+                          <REST .OBJ>>>
+              <PUT .TT ,KIDS .N>)>>
+
+<PUT ,GET PAPPLY-OBJECT <FUNCTION (O A) <GETFCNS .O .A GET>>>
+
+<PUT ,GETL PAPPLY-OBJECT <FUNCTION (O A) <GETFCNS .O .A GETL>>>
+
+<PUT ,GETPROP PAPPLY-OBJECT <FUNCTION (O A) <GETFCNS .O .A GETPROP>>>
+
+<PUT ,GETPL PAPPLY-OBJECT <FUNCTION (O A) <GETFCNS .O .A GETPL>>>
+
+<DEFINE GETFCNS (OBJ AP NAME "AUX" EV TEM T2 (LN <LENGTH .OBJ>) TT)
+       #DECL ((OBJ) FORM (LN) FIX (TT VALUE TEM T2 EV) NODE)
+       <COND (<OR <AND <N==? .LN 4>
+                       <N==? .LN 3>> <SEG? .OBJ>>
+              <PSUBR-C .OBJ .AP>)
+             (ELSE
+              <SET TT <NODEFM ,GET-CODE .PARENT ANY .NAME () ,.NAME>>
+              <SET TEM <PCOMP <2 .OBJ> .TT>>
+              <SET T2 <PCOMP <3 .OBJ> .TT>>
+              <COND (<==? .LN 3>
+                     <PUT .TT ,NODE-TYPE ,GET2-CODE>
+                     <PUT .TT ,KIDS (.TEM .T2)>)
+                    (ELSE
+                     <SET EV <PCOMP <4 .OBJ> .TT>>
+                     <COND (<==? <NODE-TYPE .EV> ,QUOTE-CODE>
+                            <SET EV <PCOMP <NODE-NAME .EV> .TT>>
+                            <PUT .TT ,NODE-TYPE ,GET2-CODE>)>
+                     <PUT .TT ,KIDS (.TEM .T2 .EV)>)>
+              .TT)>>
+
+<DEFINE ARGCHK (GIV REQ NAME "AUX" (HI .REQ) (LO .REQ))
+       #DECL ((GIV) FIX (REQ HI LO) <OR <LIST FIX FIX> FIX>)
+       <COND (<TYPE? .REQ LIST>
+              <SET HI <2 .REQ>>
+              <SET LO <1 .REQ>>)>
+       <COND (<L? .GIV .LO>
+              <MESSAGE ERROR "TOO FEW ARGS TO " .NAME>)
+             (<G? .GIV .HI>
+              <MESSAGE ERROR "TOO MANY ARGS TO " .NAME>)> T>
+
+<ENDPACKAGE>
+