--- /dev/null
+
+<PACKAGE "SYMANA">
+
+<ENTRY ANA
+ EANA
+ SET-CURRENT-TYPE
+ TYPE-NTH-REST
+ WHO
+ TMPS
+ GET-TMP
+ TRUTH
+ UNTRUTH
+ SEGFLUSH
+ KILL-REM
+ BUILD-TYPE-LIST
+ GET-CURRENT-TYPE
+ ADD-TYPE-LIST
+ PUT-FLUSH
+ WHON
+ SAVE-SURVIVORS
+ SEQ-AN
+ ARGCHK
+ ASSUM-OK?
+ FREST-L-D-STATE
+ HTMPS
+ ORUPC
+ APPLTYP
+ MSAVE-L-D-STATE
+ SHTMPS
+ RESET-VARS
+ STMPS
+ ASSERT-TYPES
+ SAVE-L-D-STATE
+ MUNG-L-D-STATE
+ NORM-BAN
+ SUBR-C-AN
+ ENTROPY
+ NAUX-BAN
+ TUP-BAN
+ ARGS-BAN
+ LIFE
+ MANIFESTQ
+ SPEC-FLUSH
+ UPDATE-SIDE-EFFECTS>
+
+<USE "CHKDCL"
+ "COMPDEC"
+ "STRANA"
+ "CARANA"
+ "NOTANA"
+ "ADVMESS"
+ "MAPANA"
+ "SUBRTY"
+ "BITSANA"
+ "CDRIVE">
+
+" This is the main file associated with the type analysis phase of
+the compilation. It is called by calling FUNC-ANA with the main data structure
+pointer. ANA is the FUNCTION that dispatches to the various special handlers
+and the SUBR call analyzer further dispatches for specific functions."
+
+" Many analyzers for specific SUBRs appear in their own files
+(CARITH, STRUCT etc.). Currently no special hacks are done for TYPE?, EMPTY?
+etc. in COND, ANDS and ORS."
+
+" All analysis functions are called with 2 args, a NODE and a desired
+type specification. These args are usually called NOD and RTYP or
+N and R."
+
+" ANA is the main analysis dispatcher (see ANALYZERS at the end of
+ this file for its dispatch table."
+
+<GDECL (TEMPLATES SUBRS) VECTOR>
+
+<DEFINE ANA (NOD RTYP "AUX" (P <PARENT .NOD>))
+ #DECL ((NOD) NODE (P) ANY (TEM TT) <OR FALSE LIST>)
+ <COND (<G=? <LENGTH .NOD> <INDEX ,SIDE-EFFECTS>>
+ <PUT .NOD ,SIDE-EFFECTS <>>)>
+ <PUT .NOD ,RESULT-TYPE <ANALYSIS-DISPATCHER .NOD .RTYP>>
+ <UPDATE-SIDE-EFFECTS .NOD .P>
+ <RESULT-TYPE .NOD>>
+
+<DEFINE UPDATE-SIDE-EFFECTS (NOD P "AUX" TEM TT)
+ #DECL ((NOD) NODE (TEM TT) <OR FALSE LIST>)
+ <COND
+ (<AND <N==? <NODE-TYPE .NOD> ,QUOTE-CODE>
+ <SET TEM <SIDE-EFFECTS .NOD>>
+ <REPEAT ()
+ <COND (<NOT <TYPE? .P NODE>> <RETURN <>>)>
+ <COND (<G=? <LENGTH .P> <CHTYPE <INDEX ,SIDE-EFFECTS> FIX>>
+ <RETURN T>)>
+ <SET P <PARENT .P>>>>
+ <PUT
+ .P
+ ,SIDE-EFFECTS
+ <COND (<EMPTY? .TEM> <SIDE-EFFECTS .P>)
+ (<EMPTY? <SET TT <SIDE-EFFECTS .P>>> .TEM)
+ (<AND <MEMQ ALL .TEM> <MEMQ ALL .TT>>
+ <COND (<G? <LENGTH .TEM> <LENGTH .TT>>
+ <SET TT
+ <MAPF ,LIST
+ <FUNCTION (IT)
+ <COND (<AND <N==? .IT ALL>
+ <NOT <MEMQ .IT .TEM>>> .IT)
+ (ELSE <MAPRET>)>>
+ .TT>>
+ <COND (<EMPTY? .TT> .TEM)
+ (ELSE
+ <PUTREST <REST .TT <- <LENGTH .TT> 1>> .TEM>
+ .TT)>)
+ (ELSE
+ <SET TT
+ <MAPF ,LIST
+ <FUNCTION (IT)
+ <COND (<AND <N==? .IT ALL>
+ <NOT <MEMQ .IT .TT>>> .IT)
+ (ELSE <MAPRET>)>>
+ .TEM>>
+ <COND (<EMPTY? .TEM> .TT)
+ (ELSE
+ <PUTREST <REST .TEM <- <LENGTH .TEM> 1>> .TT>
+ .TEM)>)>)
+ (<G? <LENGTH .TT> <LENGTH .TEM>> (!.TEM !.TT))
+ (ELSE (!.TT !.TEM))>>)>>
+
+<DEFINE ARGCHK (GIV REQ NAME NOD "AUX" (HI .REQ) (LO .REQ))
+ #DECL ((GIV) FIX (REQ HI LO) <OR <LIST FIX FIX> FIX> (NOD) NODE)
+ <COND (<TYPE? .REQ LIST> <SET HI <2 .REQ>> <SET LO <1 .REQ>>)>
+ <COND (<L? .GIV .LO>
+ <COMPILE-ERROR "Too many arguments to: " .NAME .NOD>)
+ (<G? .GIV .HI>
+ <COMPILE-ERROR "Too many arguments to: " .NAME .NOD>)>
+ T>
+
+<DEFINE EANA (NOD RTYP NAME)
+ #DECL ((NOD) NODE)
+ <COND (<ANA .NOD .RTYP>)
+ (ELSE <COMPILE-ERROR "Argument wrong type to: " .NAME .NOD>)>>
+
+" FUNC-ANA main entry to analysis phase. Analyzes bindings then body."
+
+<DEFINE FUNC-ANA ANA-ACT (N R
+ "AUX" (ANALY-OK
+ <COND (<ASSIGNED? ANALY-OK> .ANALY-OK)
+ (ELSE T)>) (OV .VERBOSE))
+ #DECL ((ANA-ACT) <SPECIAL ANY> (ANALY-OK) <SPECIAL ANY>)
+ <COND (.VERBOSE <PUTREST <SET VERBOSE .OV> ()>)>
+ <FUNC-AN1 .N .R>>
+
+<DEFINE FUNC-AN1 (FCN RTYP
+ "AUX" (VARTBL <SYMTAB .FCN>) (TMPS 0) (HTMPS 0)
+ (TRUTH ())
+ (UNTRUTH ())
+ (WHO ()) (WHON <>) (PRED <>) TEM (LIFE ())
+ (USE-COUNT 0) (BACKTRACK 0) NRTYP)
+ #DECL ((FCN) <SPECIAL NODE> (VARTBL) <SPECIAL SYMTAB>
+ (TMPS BACKTRACK USE-COUNT HTMPS) <SPECIAL FIX>
+ (LIFE TRUTH UNTRUTH) <SPECIAL LIST> (WHO PRED WHON) <SPECIAL ANY>)
+ <RESET-VARS .VARTBL>
+ <BIND-AN <BINDING-STRUCTURE .FCN>>
+ <COND (<NOT <SET NRTYP <TYPE-OK? .RTYP <INIT-DECL-TYPE .FCN>>>>
+ <COMPILE-ERROR "Function returns wrong type: "
+ <NODE-NAME .FCN>
+ ". Declared type is "
+ <INIT-DECL-TYPE .FCN>
+ ", required type is "
+ .RTYP>)>
+ <PROG ((ACT? <ACTIV? <BINDING-STRUCTURE .FCN> T>) (OV .VERBOSE))
+ <COND (.VERBOSE <PUTREST <SET VERBOSE .OV> ()>)>
+ <PUT .FCN ,AGND <>>
+ <PUT .FCN ,LIVE-VARS ()>
+ <SET LIFE ()>
+ <PUT .FCN ,ASSUM <BUILD-TYPE-LIST .VARTBL>>
+ <PUT .FCN ,ACCUM-TYPE <COND (.ACT? .RTYP) (ELSE NO-RETURN)>>
+ <SET TEM <SEQ-AN <KIDS .FCN> <INIT-DECL-TYPE .FCN>>>
+ <COND (.ACT? <SPEC-FLUSH> <PUT-FLUSH ALL>)>
+ <COND
+ (<OR <AND <OR <AGND .FCN> .ACT?>
+ <NOT <ASSUM-OK? <ASSUM .FCN>
+ <OR <AGND .FCN>
+ <BUILD-TYPE-LIST .VARTBL>>>>>
+ <AND <NOT .ACT?>
+ <SET ACT? <ACTIV? <BINDING-STRUCTURE .FCN> T>>
+ <ASSERT-TYPES <ASSUM .FCN>>>>
+ <AGAIN>)>>
+ <PUT .FCN ,ASSUM ()>
+ <PUT .FCN ,DEAD-VARS ()>
+ <COND (<NOT .TEM>
+ <COMPILE-ERROR "Returned value violates decl of: " .NRTYP>)>
+ <PUT .FCN ,RESULT-TYPE <TYPE-MERGE <ACCUM-TYPE .FCN> .TEM>>
+ <PUT <RSUBR-DECLS .FCN> 2 <TASTEFUL-DECL <RESULT-TYPE .FCN>>>
+ <RESULT-TYPE .FCN>>
+
+" BIND-AN analyze binding structure for PROGs, FUNCTIONs etc."
+
+<DEFINE BIND-AN (BNDS "AUX" COD)
+ #DECL ((BNDS) <LIST [REST SYMTAB]> (COD) FIX)
+ <REPEAT (SYM)
+ #DECL ((SYM) SYMTAB)
+ <COND (<EMPTY? .BNDS> <RETURN>)>
+ <PUT <SET SYM <1 .BNDS>> ,COMPOSIT-TYPE ANY>
+ <PUT .SYM ,CURRENT-TYPE <>>
+ <BIND-DISPATCH .SYM>
+ <SET BNDS <REST .BNDS>>>>
+
+" ENTROPY ignore call and return."
+
+<DEFINE ENTROPY (SYM) T>
+
+<DEFINE TUP-BAN (SYM)
+ #DECL ((SYM) SYMTAB)
+ <COND (<NOT .ANALY-OK>
+ <PUT .SYM ,COMPOSIT-TYPE <DECL-SYM .SYM>>
+ <PUT .SYM ,CURRENT-TYPE ANY>)
+ (<N==? <ISTYPE? <DECL-SYM .SYM>> TUPLE>
+ <PUT .SYM ,COMPOSIT-TYPE TUPLE>
+ <PUT .SYM ,CURRENT-TYPE TUPLE>)
+ (ELSE
+ <PUT .SYM ,CURRENT-TYPE <DECL-SYM .SYM>>
+ <PUT .SYM ,COMPOSIT-TYPE <DECL-SYM .SYM>>)>>
+
+" Analyze AUX and OPTIONAL intializations."
+
+<DEFINE NORM-BAN (SYM
+ "AUX" (VARTBL <NEXT-SYM .SYM>) TEM COD (N <INIT-SYM .SYM>))
+ #DECL ((VARTBL) <SPECIAL SYMTAB> (SYM) SYMTAB (COD) FIX (N) NODE)
+ <COND (<NOT <SET TEM <ANA .N <DECL-SYM .SYM>>>>
+ <COMPILE-ERROR "AUX/OPT init for: "
+ <NAME-SYM .SYM>
+ ". Init value of: "
+ .N
+ " whose type is "
+ <RESULT-TYPE .N>
+ " violates decl of "
+ <DECL-SYM .SYM>>)>
+ <COND (<AND .ANALY-OK
+ <OR <G? <SET COD <CODE-SYM .SYM>> ,ARGL-OPT>
+ <L? .COD ,ARGL-QIOPT>>>
+ <COND (<==? <NODE-TYPE .N> ,QUOTE-CODE>
+ <COND (<==? <NODE-NAME .N> <>> <SET TEM BOOL-FALSE>)
+ (<==? <NODE-NAME .N> T> <SET TEM BOOL-TRUE>)>)>
+ <PUT .SYM ,CURRENT-TYPE .TEM>
+ <PUT .SYM ,COMPOSIT-TYPE .TEM>)
+ (ELSE
+ <PUT .SYM ,COMPOSIT-TYPE <DECL-SYM .SYM>>
+ <PUT .SYM ,CURRENT-TYPE <DECL-SYM .SYM>>)>>
+
+" ARGS-BAN analyze ARGS decl (change to OPTIONAL in some cases)."
+
+<DEFINE ARGS-BAN (SYM)
+ #DECL ((SYM) SYMTAB)
+ <PUT .SYM ,INIT-SYM <NODE1 ,QUOTE-CODE () LIST () ()>>
+ <PUT .SYM ,CODE-SYM ,ARGL-IOPT>
+ <COND (.ANALY-OK <PUT .SYM ,COMPOSIT-TYPE LIST>)
+ (ELSE <PUT .SYM ,COMPOSIT-TYPE <DECL-SYM .SYM>>)>
+ <COND (.ANALY-OK
+ <PUT .SYM ,CURRENT-TYPE <TYPE-AND LIST <DECL-SYM .SYM>>>)
+ (<NOT .ANALY-OK> <PUT .SYM ,CURRENT-TYPE ANY>)>>
+
+<DEFINE NAUX-BAN (SYM)
+ #DECL ((SYM) SYMTAB)
+ <PUT .SYM
+ ,COMPOSIT-TYPE
+ <COND (.ANALY-OK NO-RETURN) (ELSE <DECL-SYM .SYM>)>>
+ <PUT .SYM ,CURRENT-TYPE <COND (.ANALY-OK NO-RETURN) (ELSE ANY)>>>
+
+"BIND-DISPATCH go to various binding analyzers analyzers."
+
+<DEFINE BIND-DISPATCH (SYM "AUX" (COD <CODE-SYM .SYM>))
+ <CASE ,==?
+ .COD
+ (,ARGL-ACT <ENTROPY .SYM>)
+ (,ARGL-IAUX <NORM-BAN .SYM>)
+ (,ARGL-AUX <NAUX-BAN .SYM>)
+ (,ARGL-TUPLE <TUP-BAN .SYM>)
+ (,ARGL-ARGS <ARGS-BAN .SYM>)
+ (,ARGL-QIOPT <NORM-BAN .SYM>)
+ (,ARGL-IOPT <NORM-BAN .SYM>)
+ (,ARGL-QOPT <ENTROPY .SYM>)
+ (,ARGL-OPT <ENTROPY .SYM>)
+ (,ARGL-CALL <ENTROPY .SYM>)
+ (,ARGL-BIND <ENTROPY .SYM>)
+ (,ARGL-QUOTE <ENTROPY .SYM>)
+ (,ARGL-ARG <ENTROPY .SYM>)>>
+
+" SEQ-AN analyze a sequence of NODES discarding values until the last."
+
+<DEFINE SEQ-AN (L FTYP "OPTIONAL" (DO-PRED <>) "AUX" (SOA <>) VAL)
+ #DECL ((L) <LIST [REST NODE]>)
+ <COND
+ (<EMPTY? .L> <COMPILE-LOSSAGE "Empty KIDS list in SEQ-AN">)
+ (ELSE
+ <SET VAL
+ <REPEAT (TT N X Y TMP (RES NO-RETURN) (SPCD <>) ENDIF-FLAG
+ (RET-OR-AGAIN <>))
+ #DECL ((X) NODE (Y) <LIST [REST NODE]> (RET-OR-AGAIN) <SPECIAL ANY>)
+ <SET N <1 .L>>
+ <SET ENDIF-FLAG <>>
+ <COND
+ (<OR <AND <EMPTY? <SET L <REST .L>>> <NOT <IFSYS-ENDIF? .N "ENDIF">>>
+ <AND <NOT <EMPTY? .L>>
+ <IFSYS-ENDIF? <1 .L> "ENDIF">
+ <SET ENDIF-FLAG T>>>
+ <COND (<AND .DO-PRED <EMPTY? .L>>
+ <SET TRUTH ()>
+ <SET UNTRUTH ()>
+ <PROG ((PRED <PARENT .N>)) #DECL ((PRED) <SPECIAL ANY>)
+ <SET TT <ANA .N .FTYP>>>)
+ (ELSE
+ <SET TT <ANA .N .FTYP>>)>
+ <COND (<AND .ENDIF-FLAG .SPCD>
+ <ASSERT-TYPES <ORUPC .VARTBL .SPCD>>
+ <SET SPCD <>>)>
+ <SET RES <TYPE-MERGE .TT .RES>>)
+ (<IFSYS-ENDIF? .N "IFSYS">
+ <SET TT <ANA .N ANY>>
+ <SET SPCD <BUILD-TYPE-LIST .VARTBL>>)
+ (ELSE
+ <SET TT <ANA .N ANY>>
+ <COND
+ (<OR <L? <LENGTH .N> <CHTYPE <INDEX ,SIDE-EFFECTS> FIX>>
+ <NOT <SIDE-EFFECTS .N>>>
+ <COND
+ (<NOT .RET-OR-AGAIN>
+ <COND
+ (<AND .VERBOSE <NOT <EMPTY? .L>>>
+ <ADDVMESS
+ <PARENT .N>
+ ("This object has no side-effects and its value is ignored"
+ .N)>)>)
+ (ELSE <PUTPROP .N DONT-FLUSH-ME T>)>)>)>
+ <COND (<NOT .TT> <SET SOA .RET-OR-AGAIN> <RETURN <>>)>
+ <COND
+ (<==? .TT NO-RETURN>
+ <COND (<AND .VERBOSE <NOT <EMPTY? .L>>>
+ <ADDVMESS <PARENT .N>
+ ("This object ends a sequence of forms"
+ .N
+ " because it never returns")>)>
+ <SET SOA .RET-OR-AGAIN>
+ <RETURN NO-RETURN>)>
+ <COND (<EMPTY? .L> <SET SOA .RET-OR-AGAIN> <RETURN .RES>)>>>
+ <COND (.SOA <SET RET-OR-AGAIN T>)>
+ .VAL)>>
+
+<DEFINE IFSYS-ENDIF? (N STR "AUX" Y NM)
+ #DECL ((N) NODE (Y) <LIST [REST NODE]>)
+ <AND <==? <NODE-TYPE .N> ,CALL-CODE>
+ <G? <LENGTH <SET Y <KIDS .N>>> 1>
+ <TYPE? <SET NM <NODE-NAME <1 .Y>>> ATOM>
+ <=? <SPNAME .NM> .STR>>>
+
+" ANALYZE ASSIGNED? usage."
+
+<DEFINE ASSIGNED?-ANA (NOD RTYP
+ "AUX" (TEM <KIDS .NOD>) TT T1 T2 (TY '<OR ATOM
+ FALSE>))
+ #DECL ((TT NOD) NODE (T1) SYMTAB (TEM) <LIST [REST NODE]>)
+ <COND
+ (<EMPTY? .TEM> <COMPILE-ERROR "No arguments ASSIGNED?: " .NOD>)
+ (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <EANA <SET TT <1 .TEM>> ATOM ASSIGNED?>
+ <COND (<AND <EMPTY? <REST .TEM>>
+ <==? <NODE-TYPE .TT> ,QUOTE-CODE>
+ <SET T2 <SRCH-SYM <NODE-NAME .TT>>>
+ <NOT <==? <CODE-SYM <SET T1 .T2>> -1>>>
+ <PUT .NOD ,NODE-TYPE ,ASSIGNED?-CODE>
+ <PUT .NOD ,NODE-NAME .T1>
+ <PUT .T1 ,ASS? T>
+ <PUT .T1 ,USED-AT-ALL T>
+ <PUT .T1 ,USAGE-SYM <+ <USAGE-SYM .T1> 1>>
+ <REVIVE .NOD .T1>
+ <SET TY
+ <COND (<==? <GET-CURRENT-TYPE .T1> NO-RETURN> BOOL-FALSE)
+ (ELSE BOOLEAN)>>)
+ (<==? <LENGTH .TEM> 2>
+ <EANA <2 .TEM> '<OR <PRIMTYPE FRAME> PROCESS> ASSIGNED?>)
+ (<EMPTY? <REST .TEM>>
+ <COND (<AND .VERBOSE <==? <NODE-TYPE .TT> ,QUOTE-CODE>>
+ <ADDVMESS .NOD
+ ("External reference to LVAL: "
+ <NODE-NAME .TT>)>)>
+ <PUT .NOD ,NODE-TYPE ,ASSIGNED?-CODE>
+ <SET TY BOOLEAN>)
+ (ELSE <COMPILE-ERROR "Too many args to ASSIGNED?: " .NOD>)>)>
+ <TYPE-OK? .TY .RTYP>>
+
+<COND (<GASSIGNED? ASSIGNED?-ANA>
+ <PUTPROP ,ASSIGNED? ANALYSIS ,ASSIGNED?-ANA>)>
+
+" ANALYZE LVAL usage. Become either direct reference or PUSHJ"
+
+<DEFINE LVAL-ANA (NOD RTYP
+ "AUX" TEM ITYP (TT <>) T1 T2 T3 (P <PARENT .NOD>) NT)
+ #DECL ((NOD) NODE (TEM) <LIST [REST NODE]> (T1) SYMTAB (WHO) LIST)
+ <COND (<EMPTY? <SET TEM <KIDS .NOD>>>
+ <COMPILE-ERROR "No arguments LVAL: " .NOD>)
+ (<SEGFLUSH .NOD .RTYP>)
+ (<AND <OR <AND <TYPE? <NODE-NAME .NOD> SYMTAB>
+ <SET TT <NODE-NAME .NOD>>>
+ <AND <EANA <1 .TEM> ATOM LVAL>
+ <EMPTY? <REST .TEM>>
+ <==? <NODE-TYPE <1 .TEM>> ,QUOTE-CODE>
+ <==? <RESULT-TYPE <1 .TEM>> ATOM>
+ <SET TT <SRCH-SYM <NODE-NAME <1 .TEM>>>>>>
+ <COND (<==? .WHON .P> <SET WHO ((<> .TT) !.WHO)>) (ELSE T)>
+ <PROG ()
+ <SET ITYP <GET-CURRENT-TYPE .TT>>
+ T>
+ <COND (<AND <==? .PRED .P>
+ <SET T2 <TYPE-OK? .ITYP FALSE>>
+ <SET T3 <TYPE-OK? .ITYP '<NOT FALSE>>>>
+ <SET TRUTH <ADD-TYPE-LIST .TT .T3 .TRUTH <>>>
+ <SET UNTRUTH <ADD-TYPE-LIST .TT .T2 .UNTRUTH <>>>)
+ (<AND <N==? .PRED .P>
+ <OR <NOT <TYPE? .P NODE>>
+ <AND <N==? <SET NT <NODE-TYPE .P>> ,SET-CODE>
+ <N==? .NT ,NOT-CODE>
+ <OR <N==? .NT ,SUBR-CODE>
+ <AND <N==? <NODE-SUBR .P> ,SET>
+ <N==? <NODE-SUBR .P> ,NOT>>>>>
+ <MEMQ .ITYP '[BOOL-TRUE BOOL-FALSE BOOLEAN]>>
+ <SET-CURRENT-TYPE .TT <SET ITYP <GET-DECL .ITYP>>>
+ T)
+ (ELSE T)>
+ <NOT <==? <CODE-SYM <SET T1 .TT>> -1>>>
+ <PUT .NOD ,NODE-TYPE ,LVAL-CODE>
+ <REVIVE .NOD .T1>
+ <PUT .T1 ,RET-AGAIN-ONLY <>>
+ <PUT .T1 ,USED-AT-ALL T>
+ <PUT .T1 ,USAGE-SYM <+ <USAGE-SYM .T1> 1>>
+ <PUT .NOD ,NODE-NAME .T1>
+ <SET ITYP <TYPE-OK? .ITYP .RTYP>>
+ <COND (.ITYP <SET-CURRENT-TYPE .T1 .ITYP>)>
+ .ITYP)
+ (<EMPTY? <REST .TEM>>
+ <COND (<AND .VERBOSE <==? <NODE-TYPE <1 .TEM>> ,QUOTE-CODE>>
+ <ADDVMESS .NOD
+ ("External variable being referenced: "
+ <NODE-NAME <1 .TEM>>)>)>
+ <PUT .NOD ,NODE-TYPE ,FLVAL-CODE>
+ <AND .TT <PUT .NOD ,NODE-NAME <SET T1 .TT>>>
+ <COND (.TT <TYPE-OK? <DECL-SYM .T1> .RTYP>) (ELSE .RTYP)>)
+ (<AND <==? <LENGTH .TEM> 2>
+ <EANA <2 .TEM> '<OR <PRIMTYPE FRAME> PROCESS> LVAL>>
+ ANY)
+ (ELSE <COMPILE-ERROR "Too many args to LVAL: " .NOD>)>>
+
+<COND (<GASSIGNED? LVAL-ANA> <PUTPROP ,LVAL ANALYSIS ,LVAL-ANA>)>
+
+" SET-ANA analyze uses of SET."
+
+<DEFINE SET-ANA (NOD RTYP
+ "AUX" (TEM <KIDS .NOD>) (LN <LENGTH .TEM>) T1 (T2 ATOM) T11
+ (NM <2 <CHTYPE <NODE-SUBR .NOD> MSUBR>>) (WHON .WHON)
+ (PRED .PRED) OTYP T3 XX N)
+ #DECL ((N NOD) NODE (TEM) <LIST [REST NODE]> (LN) FIX (T1) SYMTAB
+ (WHON PRED) <SPECIAL ANY> (WHO) LIST)
+ <PUT .NOD ,SIDE-EFFECTS (.NOD !<SIDE-EFFECTS .NOD>)>
+ <COND
+ (<SEGFLUSH .NOD .RTYP>)
+ (<OR <AND <==? .NM SET> <L? .LN 2>>
+ <AND <==? .NM UNASSIGN> <==? .LN 0>>>
+ <COMPILE-ERROR "Too few arguments to: " .NOD>)
+ (<AND <OR <AND <TYPE? <NODE-NAME .NOD> SYMTAB> <SET T11 <NODE-NAME .NOD>>>
+ <AND <EANA <1 .TEM> ATOM .NM>
+ <OR <AND <==? .NM SET> <==? .LN 2>>
+ <AND <==? .NM UNASSIGN> <==? .LN 1>>>
+ <==? <NODE-TYPE <1 .TEM>> ,QUOTE-CODE>
+ <SET T11 <SRCH-SYM <NODE-NAME <1 .TEM>>>>>>
+ <COND (<==? .WHON <PARENT .NOD>>
+ <SET WHON .NOD>
+ <SET WHO ((T .T11) !.WHO)>)
+ (ELSE T)>
+ <COND (<==? .PRED <PARENT .NOD>> <SET PRED .NOD>) (ELSE T)>
+ <SET T1 .T11>
+ <COND (<AND <==? .NM SET>
+ <NOT <SET T2 <ANA <SET N <2 .TEM>>
+ <DECL-SYM .T1>>>>>
+ <COMPILE-ERROR "Decl violation: " <NAME-SYM .T1> .NOD>)
+ (ELSE T)>>
+ <PUT .T1 ,PURE-SYM <>>
+ <SET XX <DECL-SYM .T1>>
+ <PUT .T1 ,USAGE-SYM <+ <USAGE-SYM .T1> 1>>
+ <SET OTYP <OR <CURRENT-TYPE .T1> ANY>>
+ <COND (<AND <==? <CODE-SYM .T1> -1> .VERBOSE>
+ <ADDVMESS .NOD ("External variable being SET (or UNASSIGNed): "
+ <NAME-SYM .T1>)>)>
+ <COND (<==? .NM SET> <SET T2 <OR <TYPE-AND .T2 .RTYP> .T2>>)>
+ <COND (<N==? .NM SET>)
+ (<SET OTYP <TYPESAME .OTYP .T2>> <PUT .NOD ,TYPE-INFO (.OTYP <>)>)
+ (ELSE <PUT .NOD ,TYPE-INFO (<> <>)>)>
+ <PUT .NOD
+ ,NODE-TYPE
+ <COND (<==? <CODE-SYM .T1> -1> ,FSET-CODE) (ELSE ,SET-CODE)>>
+ <PUT .NOD ,NODE-NAME .T1>
+ <MAKE-DEAD .NOD .T1>
+ <COND (<AND <==? .NM SET> <==? <NODE-TYPE .N> ,QUOTE-CODE>>
+ <COND (<==? <NODE-NAME .N> <>> <SET T2 BOOL-FALSE>)
+ (<==? <NODE-NAME .N> T> <SET T2 BOOL-TRUE>)>)>
+ <SET-CURRENT-TYPE .T1 <COND (<==? .NM SET> .T2)(ELSE NO-RETURN)>>
+ <PUT .T1 ,USED-AT-ALL T>
+ <COND (<==? .NM SET>
+ <COND (<AND <==? .PRED .NOD>
+ <SET OTYP <TYPE-OK? .T2 '<NOT FALSE>>>
+ <SET T3 <TYPE-OK? .T2 FALSE>>>
+ <SET TRUTH <ADD-TYPE-LIST .T1 .OTYP .TRUTH T>>
+ <SET UNTRUTH <ADD-TYPE-LIST .T1 .T3 .UNTRUTH T>>)>
+ <TYPE-OK? .T2 .RTYP>)
+ (ELSE
+ <TYPE-OK? .T2 .RTYP>)>)
+ (<AND <==? .NM SET> <L? .LN 4>>
+ <SET T11 <ANA <2 .TEM> ANY>>
+ <COND (<==? .LN 2>
+ <COND (<AND .VERBOSE <==? <NODE-TYPE <1 .TEM>> ,QUOTE-CODE>>
+ <ADDVMESS .NOD
+ ("External variable being SET: "
+ <NODE-NAME <1 .TEM>>)>)>
+ <PUT .NOD ,NODE-TYPE ,FSET-CODE>)
+ (ELSE <EANA <3 .TEM> '<OR <PRIMTYPE FRAME> PROCESS> SET>)>
+ <TYPE-OK? .T11 .RTYP>)
+ (<AND <==? .NM UNASSIGN> <L? .LN 3>>
+ <COND (<==? .LN 1>
+ <COND (<AND .VERBOSE <==? <NODE-TYPE <1 .TEM>> ,QUOTE-CODE>>
+ <ADDVMESS .NOD
+ ("External variable being UNASSIGNed: "
+ <NODE-NAME <1 .TEM>>)>)>
+ <PUT .NOD ,NODE-TYPE ,FSET-CODE>)
+ (ELSE <EANA <2 .TEM> '<OR <PRIMTYPE FRAME> PROCESS> SET>)>)
+ (ELSE <COMPILE-ERROR "Too many args to SET: " .NOD>)>>
+
+<DEFINE MULTI-SET-ANA (NOD RTYP
+ "AUX" (K <KIDS .NOD>) (LN 0) (WHON .WHON) (PRED .PRED)
+ (SEG? <>) (N <1 .K>) (L-OF-A <NODE-NAME .N>)
+ L-OF-SY TY TY1 TTY FTY)
+ #DECL ((N NOD) NODE (TEM) <LIST [REST NODE]> (LN) FIX (T1) SYMTAB
+ (WHON PRED) <SPECIAL ANY> (WHO) LIST (L-OF-A L-OF-SY) LIST)
+ <PUT .NOD ,SIDE-EFFECTS (.NOD !<SIDE-EFFECTS .NOD>)>
+ <SET L-OF-SY
+ <MAPR ,LIST
+ <FUNCTION (AL NL
+ "AUX" (ATM:<OR ADECL ATOM LIST SYMTAB> <1 .AL>) (N:NODE <1 .NL>)
+ (NT:FIX <NODE-TYPE .N>) SY)
+ <COND
+ (<OR <==? .NT ,SEGMENT-CODE> <==? .NT ,SEG-CODE>>
+ <MAPSTOP !<MULTI-SET-SEG .NOD .AL .NL>>)
+ (ELSE
+ <COND (<AND <EMPTY? <REST .AL>> <NOT <EMPTY? <REST .NL>>>>
+ <COMPILE-ERROR "Too many values for vars: " .NOD>)
+ (<AND <NOT <EMPTY? <REST .AL>>> <EMPTY? <REST .NL>>>
+ <COMPILE-ERROR "Too few values for vars: " .NOD>)>
+ <SET TY1 ANY>
+ <COND (<TYPE? .ATM ATOM>
+ <COND (<SET SY <SRCH-SYM .ATM>> <SET ATM .SY>)>)
+ (<TYPE? .ATM ADECL>
+ <COND (<SET SY <SRCH-SYM <1 .ATM>>>
+ <SET TY1 <2 .ATM>>
+ <SET ATM .SY>)
+ (ELSE
+ <SET TY1 <2 .ATM>>
+ <SET ATM <1 .ATM>>)>)
+ (<TYPE? .ATM LIST>
+ <SET TY1 <1 .ATM>>
+ <SET ATM <2 .ATM>>)>
+ <COND (<TYPE? .ATM SYMTAB>
+ <COND (<AND <==? .WHON <PARENT .NOD>>
+ <EMPTY? <REST .AL>>>
+ <SET WHON .NOD>
+ <SET WHO ((T .ATM) !.WHO)>)>
+ <COND (<AND <==? .PRED <PARENT .NOD>>
+ <EMPTY? <REST .AL>>>
+ <SET PRED .NOD>)>
+ <COND (<OR <NOT <SET TY <TYPE-OK? .TY1 <DECL-SYM .ATM>>>>
+ <NOT <SET TY <ANA .N .TY>>>>
+ <COMPILE-ERROR "Decl violation: "
+ <NAME-SYM .N>
+ .NOD>)>
+ <PUT .ATM ,PURE-SYM <>>
+ <PUT .ATM ,USAGE-SYM <+ <USAGE-SYM .ATM> 1>>
+ <COND (<==? <NODE-TYPE .N> ,QUOTE-CODE>
+ <COND (<==? <NODE-NAME .N> <>>
+ <SET TY BOOL-FALSE>)
+ (<==? <NODE-NAME .N> T>
+ <SET TY BOOL-TRUE>)>)>
+ <SET-CURRENT-TYPE .ATM .TY>
+ <PUT .ATM ,USED-AT-ALL T>
+ <COND (<AND <==? .PRED .NOD>
+ <SET TTY <TYPE-OK? .TY '<NOT FALSE>>>
+ <SET FTY <TYPE-OK? .TY FALSE>>>
+ <SET TRUTH <ADD-TYPE-LIST .ATM .TTY .TRUTH T>>
+ <SET UNTRUTH
+ <ADD-TYPE-LIST .ATM .FTY .UNTRUTH T>>)>)
+ (ELSE <SET TY <ANA .N .TY1>>)>
+ <COND (<AND .VERBOSE
+ <OR <AND <TYPE? .ATM SYMTAB>
+ <==? <CODE-SYM .ATM> -1>
+ <SET ATM <NAME-SYM .ATM>>>
+ <TYPE? .ATM ATOM>>>
+ <ADDVMESS .NOD ("External variable being SET: " .ATM)>)>
+ (.ATM .TY1))>>
+ .L-OF-A
+ <REST .K>>>
+ <PUT .NOD ,NODE-NAME .L-OF-SY>
+ <PUT .NOD ,NODE-TYPE ,MULTI-SET-CODE>
+ <TYPE-OK? <2 <NTH .L-OF-SY <LENGTH .L-OF-SY>>> .RTYP>>
+
+<DEFINE MULTI-SET-SEG (NOD:NODE AL:LIST NL:<LIST [REST NODE]>
+ "AUX" (MIN-LN:FIX 0) (MAX-LN:FIX 0)
+ (LN:FIX <LENGTH .AL>) (COMPOSIT-DECL NO-RETURN)
+ (COMPOSIT-TYPE NO-RETURN) L-OF-SY:LIST)
+ <SET L-OF-SY
+ <MAPF ,LIST
+ <FUNCTION (ATM:<OR ADECL ATOM LIST SYMTAB> "AUX" SY (TY ANY))
+ <COND (<TYPE? .ATM ATOM>
+ <COND (<SET SY <SRCH-SYM .ATM>> <SET ATM .SY>)>)
+ (<TYPE? .ATM ADECL>
+ <COND (<SET SY <SRCH-SYM <1 .ATM>>>
+ <SET TY <2 .ATM>>
+ <SET ATM .SY>)
+ (ELSE
+ <SET TY <2 .ATM>>
+ <SET ATM <1 .ATM>>)>)
+ (<TYPE? .ATM LIST>
+ <SET TY <1 .ATM>>
+ <SET ATM <2 .ATM>>)>
+ <COND (<TYPE? .ATM SYMTAB>
+ <COND (<NOT <SET TY <TYPE-AND <DECL-SYM .ATM> .TY>>>
+ <COMPILE-ERROR "ADECL and DECL mismatch: "
+ <NAME-SYM .ATM>
+ .NOD>)>
+ <SET COMPOSIT-DECL
+ <TYPE-MERGE .COMPOSIT-DECL .TY>>
+ <PUT .ATM ,PURE-SYM <>>
+ <PUT .ATM ,USAGE-SYM <+ <USAGE-SYM .ATM> 1>>
+ <PUT .ATM ,USED-AT-ALL T>)>
+ (.ATM .TY)>
+ .AL>>
+ <MAPF <>
+ <FUNCTION (N:NODE "AUX" (NT:FIX <NODE-TYPE .N>) TY ET)
+ <COND
+ (<OR <==? .NT ,SEG-CODE> <==? .NT ,SEGMENT-CODE>>
+ <SET TY <EANA <SET N <1 <KIDS .N>>> '<OR MULTI STRUCTURED> MULTI-SET>>
+ <COND (<N==? .COMPOSIT-DECL ANY>
+ <COND (<NOT <SET ET
+ <TYPE-OK? <GET-ELE-TYPE .TY ALL>
+ .COMPOSIT-DECL>>>
+ <COMPILE-ERROR "Decl violation: " .NOD>)>)
+ (ELSE <SET ET <GET-ELE-TYPE .TY ALL>>)>
+ <SET COMPOSIT-TYPE <TYPE-MERGE .ET .COMPOSIT-TYPE>>
+ <SET MAX-LN <MAX <+ .MAX-LN <MAXL .TY>> ,MAX-LENGTH>>
+ <SET MIN-LN <+ .MIN-LN <MINL .TY>>>)
+ (ELSE
+ <SET COMPOSIT-TYPE
+ <TYPE-MERGE <EANA .N .COMPOSIT-DECL MULTI-SET> .COMPOSIT-TYPE>>
+ <SET MAX-LN <MAX <+ .MAX-LN 1> ,MAX-LENGTH>>
+ <SET MIN-LN <+ .MIN-LN 1>>)>>
+ .NL>
+ <MAPF <>
+ <FUNCTION (SY)
+ <COND (<TYPE? <SET SY <1 .SY>> SYMTAB>
+ <SET-CURRENT-TYPE
+ .SY <TYPE-AND .COMPOSIT-TYPE <DECL-SYM .SY>>>)>>
+ .L-OF-SY>
+ <COND (<G? .MIN-LN .LN> <COMPILE-ERROR "Too many values: " .NOD>)
+ (<L? .MAX-LN .LN> <COMPILE-ERROR "Too few values: " .NOD>)>
+ .L-OF-SY>
+
+<COND (<GASSIGNED? SET-ANA>
+ <PUTPROP ,SET ANALYSIS ,SET-ANA>
+ <PUTPROP ,UNASSIGN ANALYSIS ,SET-ANA>)>
+
+<DEFINE MUNG-L-D-STATE (V)
+ #DECL ((V) <OR VECTOR SYMTAB>)
+ <REPEAT ()
+ <COND (<TYPE? .V VECTOR> <RETURN>)>
+ <PUT .V ,DEATH-LIST ()>
+ <SET V <NEXT-SYM .V>>>>
+
+<DEFINE MRESTORE-L-D-STATE (L1 L2 V)
+ <RESTORE-L-D-STATE .L1 .V>
+ <RESTORE-L-D-STATE .L2 .V T>>
+
+<DEFINE FREST-L-D-STATE (L)
+ #DECL ((L) LIST)
+ <MAPF <>
+ <FUNCTION (LL)
+ #DECL ((LL) <LIST SYMTAB <LIST [REST NODE]>>)
+ <COND (<NOT <2 <TYPE-INFO <1 <2 .LL>>>>>
+ <PUT <1 .LL> ,DEATH-LIST <2 .LL>>)>>
+ .L>>
+
+<DEFINE RESTORE-L-D-STATE (L V "OPTIONAL" (FLG <>))
+ #DECL ((L) <LIST [REST <LIST SYMTAB LIST>]> (V) <OR SYMTAB VECTOR>)
+ <COND (<NOT .FLG>
+ <REPEAT (DL)
+ #DECL ((DL) <LIST [REST NODE]>)
+ <COND (<TYPE? .V VECTOR> <RETURN>)>
+ <COND (<AND <NOT <EMPTY? <SET DL <DEATH-LIST .V>>>>
+ <NOT <2 <TYPE-INFO <1 .DL>>>>>
+ <PUT .V ,DEATH-LIST ()>)>
+ <SET V <NEXT-SYM .V>>>)>
+ <REPEAT (S DL)
+ #DECL ((DL) <LIST NODE> (S) SYMTAB)
+ <COND (<EMPTY? .L> <RETURN>)>
+ <SET S <1 <1 .L>>>
+ <AND .FLG
+ <REPEAT ()
+ <COND (<==? .S .V> <RETURN>) (<TYPE? .V VECTOR> <RETURN>)>
+ <PUT .V
+ ,DEATH-LIST
+ <MAPF ,LIST
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <COND (<==? <NODE-TYPE .N> ,SET-CODE>
+ <MAPRET>)
+ (ELSE .N)>>
+ <DEATH-LIST .V>>>
+ <SET V <NEXT-SYM .V>>>>
+ <COND (<NOT <2 <TYPE-INFO <1 <SET DL <2 <1 .L>>>>>>>
+ <PUT .S
+ ,DEATH-LIST
+ <COND (.FLG <LMERGE <DEATH-LIST .S> .DL>) (ELSE .DL)>>)>
+ <SET L <REST .L>>>>
+
+<DEFINE SAVE-L-D-STATE (V)
+ #DECL ((V) <OR VECTOR SYMTAB>)
+ <REPEAT ((L (())) (LP .L) DL)
+ #DECL ((L LP) LIST (DL) <LIST [REST NODE]>)
+ <COND (<TYPE? .V VECTOR> <RETURN <REST .L>>)>
+ <COND (<AND <NOT <EMPTY? <SET DL <DEATH-LIST .V>>>>
+ <NOT <2 <CHTYPE <TYPE-INFO <1 .DL>> LIST>>>>
+ <SET LP <REST <PUTREST .LP ((.V .DL))>>>)>
+ <SET V <NEXT-SYM .V>>>>
+
+<DEFINE MSAVE-L-D-STATE (L V)
+ #DECL ((V) <OR VECTOR SYMTAB> (L) LIST)
+ <REPEAT ((L (() !.L)) (LR .L) (LP <REST .L>) DL S TEM)
+ #DECL ((L LP LR TEM) LIST (S) SYMTAB (DL) <LIST [REST NODE]>)
+ <COND (<EMPTY? .LP>
+ <PUTREST .L <SAVE-L-D-STATE .V>>
+ <RETURN <REST .LR>>)
+ (<TYPE? .V VECTOR> <RETURN <REST .LR>>)
+ (<AND <NOT <EMPTY? <SET DL <DEATH-LIST .V>>>>
+ <NOT <2 <TYPE-INFO <1 .DL>>>>>
+ <COND (<==? <SET S <1 <1 .LP>>> .V>
+ <SET TEM <LMERGE <2 <1 .LP>> .DL>>
+ <COND (<EMPTY? .TEM>
+ <PUTREST .L <SET LP <REST .LP>>>)
+ (ELSE
+ <PUT <1 .LP> 2 .TEM>
+ <SET LP <REST <SET L .LP>>>)>)
+ (ELSE
+ <PUTREST .L <SET L ((.V .DL))>>
+ <PUTREST .L .LP>)>)
+ (<==? .V <1 <1 .LP>>> <SET LP <REST <SET L .LP>>>)>
+ <SET V <NEXT-SYM .V>>>>
+
+<DEFINE LMERGE (L1 L2)
+ #DECL ((L1 L2) <LIST [REST NODE]>)
+ <SET L1
+ <MAPF ,LIST
+ <FUNCTION (N)
+ <COND (<OR <2 <TYPE-INFO .N>>
+ <AND <==? <NODE-TYPE .N> ,SET-CODE>
+ <NOT <MEMQ .N .L2>>>>
+ <MAPRET>)>
+ .N>
+ .L1>>
+ <SET L2
+ <MAPF ,LIST
+ <FUNCTION (N)
+ <COND (<OR <2 <TYPE-INFO .N>>
+ <==? <NODE-TYPE .N> ,SET-CODE>
+ <MEMQ .N .L1>>
+ <MAPRET>)>
+ .N>
+ .L2>>
+ <COND (<EMPTY? .L1> .L2)
+ (ELSE <PUTREST <REST .L1 <- <LENGTH .L1> 1>> .L2> .L1)>>
+
+<DEFINE MAKE-DEAD (N SYM)
+ #DECL ((N) NODE (SYM) SYMTAB)
+ <PUT .SYM ,DEATH-LIST (.N)>>
+
+<DEFINE KILL-REM (L V)
+ #DECL ((L) <LIST [REST SYMTAB]> (V) <OR SYMTAB VECTOR>)
+ <REPEAT ((L1 ()))
+ #DECL ((L1) LIST)
+ <COND (<TYPE? .V VECTOR> <RETURN .L1>)>
+ <COND (<AND <NOT <SPEC-SYM .V>>
+ <N==? <CODE-SYM .V> -1>
+ <MEMQ .V .L>>
+ <SET L1 (.V !.L1)>)>
+ <SET V <NEXT-SYM .V>>>>
+
+<DEFINE SAVE-SURVIVORS (LS LI "OPTIONAL" (FLG <>))
+ #DECL ((LS) <LIST [REST <LIST SYMTAB LIST>]> (LI) <LIST [REST
+ SYMTAB]>)
+ <MAPF <>
+ <FUNCTION (LL)
+ <COND (<MEMQ <1 .LL> .LI>
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <PUT <TYPE-INFO .N> 2 T>>
+ <2 .LL>>)
+ (.FLG <PUT <1 .LL> ,DEATH-LIST <2 .LL>>)>>
+ .LS>>
+
+<DEFINE REVIVE (NOD SYM "AUX" (L <DEATH-LIST .SYM>))
+ #DECL ((L) <LIST [REST NODE]> (SYM) SYMTAB (NOD) NODE)
+ <COND (<AND <NOT <SPEC-SYM .SYM>> <N==? <CODE-SYM .SYM> -1>>
+ <COND (<EMPTY? .L> <SET LIFE (.SYM !.LIFE)>)
+ (ELSE
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <PUT <TYPE-INFO .N> 2 T>>
+ .L>)>
+ <PUT .SYM ,DEATH-LIST (.NOD)>
+ <PUT .NOD ,TYPE-INFO (<> <>)>)>>
+
+" Ananlyze a FORM that could really be an NTH."
+
+<DEFINE FORM-F-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) (OBJ <NODE-NAME .NOD>) TYP)
+ #DECL ((NOD) NODE (K) <LIST [REST NODE]>)
+ <COND (<==? <ISTYPE? <SET TYP <ANA <1 .K> APPLICABLE>>> FIX>
+ <PUT .NOD ,KIDS (<2 .K> <1 .K> !<REST .K 2>)>
+ <COND (<==? <LENGTH .K> 2>
+ <SET RTYP <NTH-REST-ANA .NOD .RTYP ,NTH-CODE .TYP>>)
+ (ELSE <SET RTYP <PUT-ANA .NOD .RTYP ,PUT-CODE>>)>
+ <PUT .NOD ,NODE-SUBR <NODE-TYPE .NOD>>
+ <PUT .NOD ,KIDS .K>
+ <PUT .NOD ,NODE-NAME .OBJ>
+ <PUT .NOD ,NODE-TYPE ,FORM-F-CODE>
+ .RTYP)
+ (ELSE
+ <SPECIALIZE <NODE-NAME .NOD>>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <PUT .NOD ,SIDE-EFFECTS (ALL)>
+ <TYPE-OK? <RESULT-TYPE .NOD> .RTYP>)>>
+
+" Further analyze a FORM."
+
+<DEFINE FORM-AN (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <APPLY <OR <GETPROP <NODE-SUBR .NOD> ANALYSIS>
+ <GETPROP <TYPE <NODE-SUBR .NOD>> TANALYSIS>
+ <FUNCTION (N R)
+ #DECL ((N) NODE)
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <PUT .N ,SIDE-EFFECTS (ALL)>
+ <TYPE-OK? <RESULT-TYPE .N> .R>>>
+ .NOD
+ .RTYP>>
+
+"Determine if an ATOM is mainfest."
+
+<DEFINE MANIFESTQ (ATM)
+ #DECL ((ATM) ATOM)
+ <AND <MANIFEST? .ATM> <GASSIGNED? .ATM> <NOT <TYPE? ,.ATM MSUBR>>>>
+
+" Search for a decl associated with a local value."
+
+<DEFINE SRCH-SYM (ATM "AUX" (TB .VARTBL))
+ #DECL ((ATM) ATOM (TB) <PRIMTYPE VECTOR>)
+ <REPEAT ()
+ <COND (<EMPTY? .TB> <RETURN <>>)>
+ <COND (<==? .ATM <NAME-SYM .TB>> <RETURN .TB>)>
+ <SET TB <NEXT-SYM .TB>>>>
+
+" Here to flush decls of specials for an external function call."
+
+<DEFINE SPEC-FLUSH () <FLUSHER <>>>
+
+" Here to flush decls when a PUT, PUTREST or external call happens."
+
+<DEFINE PUT-FLUSH (TYP) <FLUSHER .TYP>>
+
+<DEFINE FLUSHER (FLSFLG "AUX" (V .VARTBL))
+ #DECL ((SYM) SYMTAB (V) <OR SYMTAB VECTOR>)
+ <COND
+ (.ANALY-OK
+ <REPEAT (SYM TEM CT)
+ #DECL ((SYM) SYMTAB)
+ <COND
+ (<AND <SET CT <CURRENT-TYPE <SET SYM .V>>>
+ <OR <AND <SPEC-SYM .SYM> <NOT .FLSFLG>>
+ <AND .FLSFLG
+ <N==? .CT NO-RETURN>
+ <N==? .CT BOOL-FALSE>
+ <N==? .CT BOOLEAN>
+ <N==? .CT BOOL-TRUE>
+ <TYPE-OK? <CURRENT-TYPE .V> '<STRUCTURED ANY>>
+ <OR <==? .FLSFLG ALL>
+ <NOT <SET TEM <STRUCTYP <CURRENT-TYPE .V>>>>
+ <==? .TEM .FLSFLG>>>>>
+ <SET-CURRENT-TYPE
+ .SYM <FLUSH-FIX-TYPE .SYM <CURRENT-TYPE .SYM> .FLSFLG>>)>
+ <COND (<EMPTY? <SET V <NEXT-SYM .V>>> <RETURN>)>>)
+ (ELSE
+ <REPEAT (SYM)
+ #DECL ((SYM) SYMTAB)
+ <COND (<EMPTY? <SET V <NEXT-SYM .V>>> <RETURN>)>>)>>
+
+<DEFINE FLUSH-FIX-TYPE (SYM TY FLG "AUX" TEM)
+ #DECL ((SYM) SYMTAB)
+ <OR <AND .FLG
+ <SET TEM <TOP-TYPE <TYPE-OK? .TY STRUCTURED>>>
+ <TYPE-OK? <COND (<SET TY <TYPE-OK? .TY '<NOT STRUCTURED>>>
+ <TYPE-MERGE .TEM .TY>)
+ (ELSE .TEM)>
+ <DECL-SYM .SYM>>>
+ <DECL-SYM .SYM>>>
+
+" Punt forms with segments in them."
+
+<DEFINE SEGFLUSH (NOD RTYP)
+ #DECL ((NOD) NODE (L) <LIST [REST NODE]>)
+ <COND
+ (<REPEAT ((L <KIDS .NOD>))
+ <AND <EMPTY? .L> <RETURN <>>>
+ <AND <==? <NODE-TYPE <1 .L>> ,SEGMENT-CODE> <RETURN T>>
+ <SET L <REST .L>>>
+ <COND (.VERBOSE
+ <ADDVMESS .NOD ("Not open compiled due to SEGMENT.")>)>
+ <SUBR-C-AN .NOD .RTYP>)>>
+
+" Determine if the arg to STACKFORM is a SUBR."
+
+<DEFINE APPLTYP (NOD "AUX" (NT <NODE-TYPE .NOD>) ATM TT)
+ #DECL ((ATM) ATOM (NOD TT) NODE (NT) FIX)
+ <COND (<==? .NT ,GVAL-CODE>
+ <COND (<AND <==? <NODE-TYPE <SET TT <1 <KIDS .NOD>>>>
+ ,QUOTE-CODE>
+ <GASSIGNED? <SET ATM <NODE-NAME .TT>>>
+ <TYPE? ,.ATM MSUBR>>
+ <SUBR-TYPE ,.ATM>)
+ (ELSE ANY)>)
+ (ELSE ANY)>>
+
+" Return type returned by a SUBR."
+
+<DEFINE SUBR-TYPE (SUB "AUX" TMP)
+ #DECL ((SUB) MSUBR)
+ <SET TMP <2 <GET-TMP .SUB>>>
+ <COND (<TYPE? .TMP ATOM FORM> .TMP) (ELSE ANY)>>
+
+" Access the SUBR data base for return type."
+
+<DEFINE GET-TMP (SUB "AUX" (LS <MEMQ .SUB ,SUBRS>))
+ #DECL ((VALUE) <LIST ANY ANY>)
+ <COND (.LS <NTH ,TEMPLATES <LENGTH .LS>>) (ELSE '(ANY ANY))>>
+
+" GVAL analyzer."
+
+<DEFINE GVAL-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) (LN <LENGTH .K>) TEM TT TEM1)
+ #DECL ((NOD TEM) NODE (TT) <VECTOR VECTOR ATOM ANY> (LN) FIX)
+ <COND
+ (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <ARGCHK .LN 1 GVAL .NOD>
+ <PUT .NOD ,NODE-TYPE ,FGVAL-CODE>
+ <EANA <1 .K> ATOM GVAL>
+ <COND (<AND <==? <NODE-TYPE <SET TEM <1 .K>>> ,QUOTE-CODE>
+ <==? <RESULT-TYPE .TEM> ATOM>>
+ <PUT .NOD ,NODE-TYPE ,GVAL-CODE>
+ <COND (<MANIFEST? <SET TEM1 <NODE-NAME .TEM>>>
+ <PUT .NOD ,NODE-TYPE ,QUOTE-CODE>
+ <PUT .NOD ,NODE-NAME ,.TEM1>
+ <PUT .NOD ,KIDS ()>
+ <TYPE-OK? <GEN-DECL ,.TEM1> .RTYP>)
+ (<AND <GBOUND? .TEM1>
+ <COND (<GASSIGNED? GLOC>
+ <SET TEM1 <GET-DECL <GLOC .TEM1>>>)
+ (ELSE <SET TEM1 <GET-DECL <GBIND .TEM1>>>)>>
+ <TYPE-OK? .TEM1 .RTYP>)
+ (ELSE <TYPE-OK? ANY .RTYP>)>)
+ (ELSE <TYPE-OK? ANY .RTYP>)>)>>
+
+<COND (<GASSIGNED? GVAL-ANA> <PUTPROP ,GVAL ANALYSIS ,GVAL-ANA>)>
+
+<DEFINE GASSIGNED?-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) (LN <LENGTH .K>)
+ (NM <NODE-NAME .NOD>))
+ #DECL ((NOD) NODE (K) <LIST [REST NODE]> (LN) FIX)
+ <COND (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <ARGCHK .LN 1 .NM .NOD>
+ <PUT .NOD ,NODE-TYPE ,GASSIGNED?-CODE>
+ <EANA <1 .K> ATOM .NM>)>
+ <TYPE-OK? '<OR ATOM FALSE> .RTYP>>
+
+<COND (<GASSIGNED? GASSIGNED?-ANA>
+ <PUTPROP ,GASSIGNED? ANALYSIS ,GASSIGNED?-ANA>)>
+
+<COND (<AND <GASSIGNED? GBOUND?> <GASSIGNED? GASSIGNED?-ANA>>
+ <PUTPROP ,GBOUND? ANALYSIS ,GASSIGNED?-ANA>)>
+
+" Analyze SETG usage."
+
+<DEFINE SETG-ANA (NOD RTYP
+ "AUX" (K <KIDS .NOD>) (LN <LENGTH .K>) TEM TT T1 TTT)
+ #DECL ((NOD TEM) NODE (K) <LIST [REST NODE]> (LN) FIX (TT) VECTOR)
+ <COND
+ (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <ARGCHK .LN '(2 3) SETG .NOD>
+ <PUT .NOD ,NODE-TYPE ,FSETG-CODE>
+ <EANA <SET TEM <1 .K>> ATOM SETG>
+ <PUT .NOD ,SIDE-EFFECTS (.NOD !<SIDE-EFFECTS .NOD>)>
+ <COND (<==? <NODE-TYPE .TEM> ,QUOTE-CODE>
+ <COND (<MANIFEST? <SET TTT <NODE-NAME .TEM>>>
+ <COMPILE-WARNING "SETGing manifest GVAL? " .TTT .NOD>)>
+ <PUT .NOD ,NODE-TYPE ,SETG-CODE>
+ <COND (<AND <GBOUND? .TTT>
+ <COND (<GASSIGNED? GLOC>
+ <SET T1 <GET-DECL <GLOC .TTT>>>)
+ (ELSE <SET T1 <GET-DECL <GBIND .TTT>>>)>>
+ <COND (<NOT <ANA <2 .K> .T1>>
+ <COMPILE-ERROR "GLOBAL declaration violation"
+ .TTT
+ .NOD>)>
+ <SET TTT <TYPE-OK? .T1 .RTYP>>)
+ (ELSE
+ <SET TTT <ANA <2 .K> ANY>>
+ <SET TTT <TYPE-OK? .TTT .RTYP>>)>)
+ (ELSE <SET TTT <ANA <2 .K> ANY>> <SET TTT <TYPE-OK? .TTT .RTYP>>)>
+ <COND (<==? .LN 3> <EANA <3 .K> ANY SETG>)>
+ .TTT)>>
+
+<COND (<GASSIGNED? SETG-ANA> <PUTPROP ,SETG ANALYSIS ,SETG-ANA>)>
+
+<DEFINE BUILD-TYPE-LIST (V)
+ #DECL ((V) <OR VECTOR SYMTAB> (VALUE) LIST)
+ <COND (.ANALY-OK
+ <REPEAT ((L (())) (LP .L) TEM)
+ #DECL ((L LP) LIST)
+ <COND (<EMPTY? .V> <RETURN <REST .L>>)
+ (<N==? <CODE-SYM .V> -1>
+ <SET TEM <GET-CURRENT-TYPE .V>>
+ <SET LP <REST <PUTREST .LP ((.V .TEM))>>>)>
+ <SET V <NEXT-SYM .V>>>)
+ (ELSE ())>>
+
+<DEFINE BUILD-MODIFIED-TYPE-LIST (V NL)
+ #DECL ((V) <OR VECTOR SYMTAB> (NL VALUE) LIST)
+ <COND (.ANALY-OK
+ <REPEAT ((L (())) (LP .L) TEM)
+ #DECL ((L LP) LIST)
+ <COND (<EMPTY? .V> <RETURN <REST .L>>)
+ (<N==? <CODE-SYM .V> -1>
+ <SET TEM <GET-CURRENT-TYPE .V>>
+ <MAPF <>
+ <FUNCTION (LL) #DECL ((LL) !<LIST SYMTAB ANY>)
+ <COND (<==? <1 .LL> .V>
+ <SET TEM <2 .LL>>
+ <MAPLEAVE>)>>
+ .NL>
+ <SET LP <REST <PUTREST .LP ((.V .TEM))>>>)>
+ <SET V <NEXT-SYM .V>>>)
+ (ELSE ())>>
+
+<DEFINE RESET-VARS (V "OPTIONAL" (VL '[]) (FLG <>))
+ #DECL ((V VL) <OR SYMTAB VECTOR>)
+ <REPEAT ()
+ <COND (<==? .V .VL> <SET FLG T>)>
+ <COND (<EMPTY? .V> <RETURN>)
+ (<NOT .FLG>
+ <PUT .V ,CURRENT-TYPE <>>
+ <PUT .V ,COMPOSIT-TYPE ANY>)>
+ <PUT .V ,DEATH-LIST ()>
+ <SET V <NEXT-SYM .V>>>>
+
+<DEFINE GET-CURRENT-TYPE (SYM)
+ #DECL ((SYM) SYMTAB)
+ <COND (<AND .ANALY-OK <CURRENT-TYPE .SYM>>) (ELSE <DECL-SYM .SYM>)>>
+
+<DEFINE SET-CURRENT-TYPE (SYM ITYP "AUX" (OTYP <DECL-SYM .SYM>))
+ #DECL ((SYM) SYMTAB)
+ <COND (<AND .ANALY-OK <N==? <CODE-SYM .SYM> -1>>
+ <PUT .SYM ,CURRENT-TYPE <SET ITYP <TYPE-AND .ITYP .OTYP>>>
+ <PUT .SYM
+ ,COMPOSIT-TYPE
+ <TYPE-MERGE .ITYP <COMPOSIT-TYPE .SYM>>>)
+ (ELSE
+ <PUT .SYM ,CURRENT-TYPE <>>
+ <PUT .SYM ,COMPOSIT-TYPE .OTYP>)>>
+
+<DEFINE ORUPC (V L)
+ #DECL ((V) <OR VECTOR SYMTAB> (L) <LIST [REST !<LIST SYMTAB ANY>]>)
+ <COND
+ (.ANALY-OK
+ <REPEAT ((LL .L) LLL)
+ #DECL ((LLL) !<LIST SYMTAB <OR ATOM FORM SEGMENT>>
+ (LL) <LIST [REST !<LIST SYMTAB ANY>]>)
+ <COND (<TYPE? .V VECTOR> <RETURN>)>
+ <COND (<N==? <CODE-SYM .V> -1>
+ <COND (<==? <1 <SET LLL <1 .LL>>> .V>
+ <PUT .LLL 2 <TYPE-MERGE <2 .LLL> <GET-CURRENT-TYPE .V>>>)
+ (ELSE <ERROR BAD-ORUPC!-ERRORS>)>
+ <SET LL <REST .LL>>)>
+ <SET V <NEXT-SYM .V>>>)>
+ .L>
+
+<DEFINE ORUP (ONE:<LIST [REST !<LIST SYMTAB ANY>]>
+ TWO:<LIST [REST !<LIST SYMTAB ANY>]>)
+ <MAPF <>
+ <FUNCTION (A:!<LIST SYMTAB ANY> B:!<LIST SYMTAB ANY>)
+ <PUT .A 2 <TYPE-MERGE <2 .A> <2 .B>>>>
+ .ONE .TWO>
+ .ONE>
+
+<DEFINE ANDUP (ONE:<LIST [REST !<LIST SYMTAB ANY>]>
+ TWO:<LIST [REST !<LIST SYMTAB ANY>]>)
+ <MAPF <>
+ <FUNCTION (A:!<LIST SYMTAB ANY> B:!<LIST SYMTAB ANY>)
+ <PUT .A 2 <TYPE-AND <2 .A> <2 .B>>>>
+ .ONE .TWO>
+ .ONE>
+
+
+<DEFINE ASSERT-TYPES (L)
+ #DECL ((L) <LIST [REST !<LIST SYMTAB ANY>]>)
+ <MAPF <> <FUNCTION (LL) <SET-CURRENT-TYPE <1 .LL> <2 .LL>>> .L>>
+
+<DEFINE ADD-TYPE-LIST (SYM NDECL INF MUNG
+ "OPTIONAL" (NTH-REST ())
+ "AUX" (WIN <>) (OD <GET-CURRENT-TYPE .SYM>))
+ #DECL ((SYM) SYMTAB (INF) LIST (NTH-REST) <LIST [REST ATOM FIX]>
+ (NDECL) <OR ATOM FALSE FORM SEGMENT> (MUNG) <OR ATOM FALSE>)
+ <COND (.ANALY-OK
+ <SET NDECL <TYPE-NTH-REST .NDECL .NTH-REST>>
+ <MAPF <>
+ <FUNCTION (L)
+ #DECL ((L) <LIST SYMTAB ANY>)
+ <COND (<==? <1 .L> .SYM>
+ <SET NDECL
+ <COND (.MUNG <TYPE-AND .NDECL .OD>)
+ (ELSE <TYPE-AND .NDECL <2 .L>>)>>
+ <PUT .L 2 .NDECL>
+ <MAPLEAVE <SET WIN T>>)>>
+ .INF>
+ <COND (<NOT .WIN>
+ <SET NDECL <TYPE-AND .NDECL .OD>>
+ <SET INF ((.SYM .NDECL .MUNG) !.INF)>)>)>
+ .INF>
+
+<DEFINE TYPE-NTH-REST (NDECL NTH-REST)
+ #DECL ((NTH-REST) <LIST [REST ATOM FIX]>)
+ <REPEAT ((FIRST T) (NUM 0))
+ #DECL ((NUM) FIX)
+ <COND (<EMPTY? .NTH-REST> <RETURN .NDECL>)>
+ <COND (<==? <1 .NTH-REST> NTH>
+ <SET NDECL
+ <FORM STRUCTURED
+ !<COND (<0? <SET NUM
+ <+ .NUM <2 .NTH-REST> -1>>>
+ ())
+ (<1? .NUM> (ANY))
+ (ELSE ([.NUM ANY]))>
+ .NDECL>>
+ <SET NUM 0>
+ <SET FIRST <>>)
+ (.FIRST <SET NDECL <REST-DECL .NDECL <2 .NTH-REST>>>)
+ (ELSE <SET NUM <+ .NUM <2 .NTH-REST>>>)>
+ <SET NTH-REST <REST .NTH-REST 2>>>>
+
+" AND/OR analyzer. Called from AND-ANA and OR-ANA."
+
+<DEFINE BOOL-AN (NOD RTYP ORER
+ "AUX" (L <KIDS .NOD>) FTYP FTY
+ (RTY
+ <COND (<TYPE-OK? .RTYP FALSE> .RTYP)
+ (ELSE <FORM OR .RTYP FALSE>)>)
+ (FLG <==? .PRED <PARENT .NOD>>) (SINF ()) STR SUNT
+ (FIRST T) FNOK NFNOK PASS)
+ #DECL ((NOD) NODE (L) <LIST [REST NODE]> (ORER RTYP) ANY (FTYP) FORM
+ (STR SINF SUNT) LIST)
+ <PROG ((TRUTH ()) (UNTRUTH ()) (PRED .NOD) L-D)
+ #DECL ((TRUTH UNTRUTH) <SPECIAL LIST> (PRED) <SPECIAL ANY> (L-D) LIST)
+ <COND
+ (<EMPTY? .L> <SET FTYP <TYPE-OK? FALSE .RTYP>>)
+ (ELSE
+ <SET FTY
+ <MAPR ,TYPE-MERGE
+ <FUNCTION (N "AUX" (LAST <EMPTY? <REST .N>>) TY)
+ #DECL ((N) <LIST NODE>)
+ <COND (<AND .LAST <NOT .FLG>> <SET PRED <>>)>
+ <SET TY <ANA <1 .N> <COND (.LAST .RTYP) (.ORER .RTY) (ELSE ANY)>>>
+ <SET FNOK <OR <==? .TY NO-RETURN> <NOT <TYPE-OK? .TY FALSE>>>>
+ <SET NFNOK <==? FALSE <ISTYPE? .TY>>>
+ <SET PASS <COND (.ORER .NFNOK) (ELSE .FNOK)>>
+ <COND (<NOT .TY>
+ <SET TY ANY>
+ <COMPILE-WARNING "OR/AND clause returns wrong type: "
+ <1 .N>>)>
+ <COND
+ (<COND (.ORER .FNOK) (ELSE .NFNOK)>
+ <COND
+ (<AND .VERBOSE <NOT .LAST>>
+ <ADDVMESS .NOD
+ ("This object prematurely ends AND/OR: "
+ <1 .N>
+ !<COND (<==? .TY NO-RETURN> '(" it never returns "))
+ (ELSE (" its type is: " .TY))>)>)>
+ <SET LAST T>)>
+ <COND
+ (<AND <N==? .TY NO-RETURN> <OR <NOT .PASS> .LAST>>
+ <SET TRUTH <BUILD-MODIFIED-TYPE-LIST .VARTBL .TRUTH>>
+ <SET UNTRUTH <BUILD-MODIFIED-TYPE-LIST .VARTBL .UNTRUTH>>
+ <COND (.FIRST
+ <SET L-D <SAVE-L-D-STATE .VARTBL>>
+ <SET STR .TRUTH>
+ <SET SUNT .UNTRUTH>
+ <SET SINF <BUILD-MODIFIED-TYPE-LIST .VARTBL
+ <COND (.ORER .TRUTH)
+ (ELSE
+ .UNTRUTH)>>>)
+ (ELSE
+ <SET L-D <MSAVE-L-D-STATE .L-D .VARTBL>>
+ <COND (.ORER
+ <SET SUNT .UNTRUTH>
+ <SET STR <ORUP .STR .TRUTH>>
+ <SET SINF <ORUP .SINF .TRUTH>>)
+ (ELSE
+ <SET SUNT <ORUP .SUNT .UNTRUTH>>
+ <SET STR .TRUTH>
+ <SET SINF <ORUP .SINF .UNTRUTH>>)>)>
+ <SET FIRST <>>
+ <ASSERT-TYPES <COND (.ORER .SUNT) (ELSE .STR)>>)>
+ <SET TRUTH ()>
+ <SET UNTRUTH ()>
+ <OR .FIRST <RESTORE-L-D-STATE .L-D .VARTBL>>
+ <COND (<==? .TY NO-RETURN>
+ <COND (<NOT .LAST>
+ <COMPILE-WARNING "AND/OR clause is unreachable: "
+ <1 .N>>)>
+ <SET FLG <>>
+ <ASSERT-TYPES .SINF>
+ <MAPSTOP NO-RETURN>)
+ (.LAST <ASSERT-TYPES .SINF> <MAPSTOP .TY>)
+ (<AND .ORER .NFNOK> <MAPRET>)
+ (.ORER .TY)
+ (.FNOK <MAPRET>)
+ (ELSE FALSE)>>
+ .L>>
+ <COND (<AND .FNOK .ORER> <SET FTY <TYPE-OK? .FTY '<NOT FALSE>>>)>)>>
+ <COND (.FLG <SET TRUTH .STR> <SET UNTRUTH .SUNT>)>
+ .FTY>
+
+<DEFINE COPY-TYPE-LIST (L)
+ #DECL ((L) LIST)
+ <MAPF ,LIST
+ <FUNCTION (LL)
+ #DECL ((LL) <LIST ANY ANY ANY>)
+ (<1 .LL> <2 .LL> <3 .LL>)>
+ .L>>
+
+<DEFINE AND-ANA (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <PUT .NOD ,NODE-TYPE ,AND-CODE>
+ <BOOL-AN .NOD .RTYP <>>>
+
+<COND (<GASSIGNED? AND-ANA> <PUTPROP ,AND ANALYSIS ,AND-ANA>)>
+
+<DEFINE OR-ANA (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <PUT .NOD ,NODE-TYPE ,OR-CODE>
+ <BOOL-AN .NOD .RTYP T>>
+
+<COND (<GASSIGNED? OR-ANA> <PUTPROP ,OR ANALYSIS ,OR-ANA>)>
+
+" COND analyzer."
+
+<DEFINE CASE-ANA (N R) <COND-CASE .N .R T>>
+
+<DEFINE COND-ANA (N R) <COND-CASE .N .R <>>>
+
+<DEFINE COND-CASE (NOD RTYP CASE?
+ "AUX" (L <KIDS .NOD>) (FIRST T) (LAST <>) TT FNOK NFNOK STR
+ SUNT (FIRST1 T) PRAT (DFLG <>) TST-TYP SVWHO
+ (PRED-FLG <==? .PRED <PARENT .NOD>>))
+ #DECL ((NOD) NODE (L) <LIST [REST NODE]> (RTYP) ANY)
+ <PROG ((TRUTH ()) (UNTRUTH ()) (TINF1 ()) (TINF ())
+ L-D L-D1 (PRED .PRED))
+ #DECL ((TRUTH UNTRUTH) <SPECIAL LIST> (TINF1 TINF L-D L-D1) LIST
+ (PRED) <SPECIAL <OR FALSE NODE>>)
+ <COND
+ (<EMPTY? .L> <TYPE-OK? FALSE .RTYP>)
+ (ELSE
+ <COND (.CASE?
+ <SET PRAT <NODE-NAME <1 <KIDS <1 .L>>>>>
+ <PROG ((WHON .NOD) (WHO ()))
+ #DECL ((WHO) <SPECIAL LIST> (WHON) <SPECIAL NODE>)
+ <SET TST-TYP <EANA <2 .L> ANY CASE>>
+ <SET SVWHO .WHO>>
+ <SET L <REST .L 2>>)>
+ <SET TT
+ <MAPR ,TYPE-MERGE
+ <FUNCTION (BRN "AUX" (BR <1 .BRN>) (EC T) STR1 SUNT1)
+ #DECL ((BRN) <LIST NODE> (BR) NODE)
+ <COND (<N==? <NODE-TYPE .BR> ,QUOTE-CODE>
+ <PUT .BR ,SIDE-EFFECTS <>>)>
+ <SET PRED .BR>
+ <COND (<AND .CASE? <==? <NODE-TYPE .BR> ,QUOTE-CODE> <SET DFLG T>>
+ <MAPRET>)>
+ <COND (<NOT <PREDIC .BR>>
+ <COMPILE-ERROR "Empty COND clause: " .BR>)>
+ <SET TRUTH ()>
+ <SET UNTRUTH ()>
+ <SET LAST <EMPTY? <REST .BRN>>>
+ <SET TT
+ <COND (<NOT <EMPTY? <CLAUSES .BR>>> <SET EC <>> ANY)
+ (.LAST .RTYP)
+ (ELSE <TYPE-MERGE .RTYP FALSE>)>>
+ <SET TT
+ <COND (.CASE?
+ <SPEC-ANA <NODE-NAME <CHTYPE <PREDIC .BR> NODE>>
+ .PRAT
+ .TST-TYP
+ .TT
+ .DFLG
+ .BR
+ .SVWHO>)
+ (ELSE <ANA <PREDIC .BR> .TT>)>>
+ <SET DFLG <SET PRED <>>>
+ <SET FNOK <OR <==? .TT NO-RETURN> <NOT <TYPE-OK? .TT FALSE>>>>
+ <SET NFNOK <==? <ISTYPE? .TT> FALSE>>
+ <COND
+ (.VERBOSE
+ <COND
+ (.NFNOK
+ <ADDVMESS
+ .NOD
+ ("Cond predicate always FALSE: "
+ <PREDIC .BR>
+ !<COND (<EMPTY? <CLAUSES .BR>> ())
+ (ELSE (" and non-reachable code in clause."))>)>)>
+ <COND
+ (<AND .FNOK <NOT .LAST>>
+ <ADDVMESS
+ .NOD
+ ("Cond ended prematurely because predicate always true: "
+ <PREDIC .BR>
+ " type of value: "
+ .TT)>)>)>
+ <COND (<NOT <OR .FNOK <AND <NOT .LAST> .NFNOK>>>
+ <SET TRUTH <BUILD-MODIFIED-TYPE-LIST .VARTBL .TRUTH>>
+ <SET UNTRUTH <BUILD-MODIFIED-TYPE-LIST .VARTBL .UNTRUTH>>
+ <SET L-D <SAVE-L-D-STATE .VARTBL>>
+ <COND (.FIRST
+ <SET TINF .UNTRUTH>)
+ (ELSE
+ <SET TINF <ANDUP .TINF .UNTRUTH>>)>
+ <ASSERT-TYPES .TRUTH>
+ <SET FIRST <>>)>
+ <COND (.PRED-FLG
+ <SET STR1 .TRUTH>
+ <SET SUNT1 .UNTRUTH>
+ <SET TRUTH <SET UNTRUTH ()>>)>
+ <COND (<AND <NOT .NFNOK>
+ <OR .EC <SET TT <SEQ-AN <CLAUSES .BR>
+ .RTYP .PRED-FLG>>>>
+ <COND (<N==? .TT NO-RETURN>
+ <COND (.PRED-FLG
+ <SET TRUTH
+ <BUILD-MODIFIED-TYPE-LIST .VARTBL
+ .TRUTH>>
+ <SET UNTRUTH
+ <BUILD-MODIFIED-TYPE-LIST .VARTBL
+ .UNTRUTH>>
+ <COND (.FIRST1
+ <SET STR .TRUTH>
+ <SET SUNT <ORUP .SUNT1 .UNTRUTH>>)
+ (ELSE
+ <SET STR <ORUP .STR .TRUTH>>
+ <SET SUNT
+ <ORUP .SUNT
+ <ORUP .SUNT1 .UNTRUTH>>>)>)>
+ <COND (.FIRST1
+ <SET TINF1 <BUILD-TYPE-LIST .VARTBL>>
+ <SET L-D1 <SAVE-L-D-STATE .VARTBL>>)
+ (ELSE
+ <SET TINF1 <ORUPC .VARTBL .TINF1>>
+ <SET L-D1 <MSAVE-L-D-STATE .L-D1 .VARTBL>>)>
+ <SET FIRST1 <>>)>
+ <OR .FIRST <RESTORE-L-D-STATE .L-D .VARTBL>>
+ <COND (.LAST
+ <AND <NOT .FNOK> <SET TT <TYPE-MERGE .TT FALSE>>>)
+ (.EC <SET TT <TYPE-OK? .TT '<NOT FALSE>>>)>)
+ (.NFNOK <SET TT FALSE>)>
+ <UPDATE-SIDE-EFFECTS .BR .NOD>
+ <COND
+ (<AND <OR .LAST .FNOK> .TT>
+ <COND (.FNOK
+ <ASSERT-TYPES .TINF1>
+ <OR .FIRST1 <RESTORE-L-D-STATE .L-D1 .VARTBL>>)
+ (ELSE
+ <COND (.FIRST1
+ <ASSERT-TYPES .TINF>
+ <OR .FIRST <RESTORE-L-D-STATE .L-D .VARTBL>>)
+ (ELSE
+ <ASSERT-TYPES <ORUP .TINF .TINF1>>
+ <MRESTORE-L-D-STATE .L-D1 .L-D .VARTBL>)>)>
+ <MAPSTOP .TT>)
+ (.TT <ASSERT-TYPES .TINF> .TT)
+ (ELSE <ASSERT-TYPES .TINF> <MAPRET>)>>
+ .L>>)>>
+ <COND (.PRED-FLG
+ <SET TRUTH .STR>
+ <SET UNTRUTH .SUNT>)>
+ .TT>
+
+" PROG/REPEAT analyzer. Hacks bindings and sets up info for GO/RETURN/AGAIN
+ analyzers."
+
+<DEFINE PRG-REP-ANA (PPNOD RT
+ "AUX" (OV .VARTBL) (VARTBL <SYMTAB .PPNOD>) TT L-D
+ (OPN <AND <ASSIGNED? PNOD> .PNOD>) PNOD PRTYP)
+ #DECL ((PNOD) <SPECIAL NODE> (VARTBL) <SPECIAL SYMTAB> (OV) SYMTAB
+ (L-D) LIST (PPNOD) NODE)
+ <COND (<N==? <NODE-SUBR .PPNOD> ,BIND> <SET PNOD .PPNOD>)
+ (.OPN <SET PNOD .OPN>)>
+ <PROG ((TMPS 0) (HTMPS 0) (ACT? <ACTIV? <BINDING-STRUCTURE .PPNOD> T>))
+ #DECL ((TMPS HTMPS) <SPECIAL FIX>)
+ <BIND-AN <BINDING-STRUCTURE .PPNOD>>
+ <SET L-D <SAVE-L-D-STATE .VARTBL>>
+ <RESET-VARS .VARTBL .OV T>
+ <COND (<NOT <SET PRTYP <TYPE-OK? .RT <INIT-DECL-TYPE .PPNOD>>>>
+ <COMPILE-ERROR
+"Required type of PROG/REPEAT call violates its decl."
+ "Required type is "
+ .RT
+ " and value decl is "
+ <INIT-DECL-TYPE .PPNOD>>)>
+ <PUT .PPNOD ,RESULT-TYPE .PRTYP>
+ <PROG ((STMPS .TMPS) (SHTMPS .HTMPS) (LL .LIFE) (OV .VERBOSE))
+ #DECL ((STMPS SHTMPS) FIX (LL LIFE) LIST)
+ <COND (.VERBOSE <PUTREST <SET VERBOSE .OV> ()>)>
+ <MUNG-L-D-STATE .VARTBL>
+ <SET LIFE .LL>
+ <PUT .PPNOD ,AGND <>>
+ <PUT .PPNOD ,DEAD-VARS ()>
+ <PUT .PPNOD ,VSPCD ()>
+ <PUT .PPNOD ,LIVE-VARS ()>
+ <SET TMPS .STMPS>
+ <SET HTMPS .SHTMPS>
+ <PUT .PPNOD ,ASSUM <BUILD-TYPE-LIST .VARTBL>>
+ <PUT .PPNOD ,ACCUM-TYPE NO-RETURN>
+ <SET TT
+ <SEQ-AN <KIDS .PPNOD>
+ <COND (<N==? <NODE-SUBR .PPNOD> ,REPEAT> .PRTYP)
+ (ELSE ANY)>>>
+ <COND (.ACT? <SPEC-FLUSH> <PUT-FLUSH ALL>)>
+ <COND
+ (<OR .ACT? <==? <NODE-SUBR .PPNOD> ,REPEAT> <AGND .PPNOD>>
+ <COND
+ (<NOT <ASSUM-OK? <ASSUM .PPNOD>
+ <COND (<AND <N==? <NODE-SUBR .PPNOD> ,REPEAT>
+ <AGND .PPNOD>>
+ <AGND .PPNOD>)
+ (<AGND .PPNOD>
+ <ORUPC .VARTBL <CHTYPE <AGND .PPNOD> LIST>>)
+ (ELSE <BUILD-TYPE-LIST .VARTBL>)>>>
+ <AGAIN>)>)
+ (<AND <NOT .ACT?> <SET ACT? <ACTIV? <BINDING-STRUCTURE .PPNOD> T>>>
+ <ASSERT-TYPES <ASSUM .PPNOD>>
+ <AGAIN>)>>
+ <COND (<==? <NODE-SUBR .PPNOD> ,REPEAT>
+ <COND (<AGND .PPNOD>
+ <PUT .PPNOD
+ ,LIVE-VARS
+ <MSAVE-L-D-STATE <LIVE-VARS .PPNOD> .VARTBL>>)
+ (ELSE <PUT .PPNOD ,LIVE-VARS <SAVE-L-D-STATE .VARTBL>>)>)>
+ <SAVE-SURVIVORS .L-D .LIFE T>
+ <SAVE-SURVIVORS <LIVE-VARS .PPNOD> .LIFE>
+ <COND (<NOT .TT>
+ <COMPILE-ERROR "PROG/REPEAT returns incorrect type "
+ .PRTYP
+ .PPNOD>)>
+ <COND (<NOT <OR <==? .TT NO-RETURN> <==? <NODE-SUBR .PPNOD> ,REPEAT>>>
+ <PUT .PPNOD
+ ,DEAD-VARS
+ <MSAVE-L-D-STATE <DEAD-VARS .PPNOD> .VARTBL>>
+ <COND (<N==? <ACCUM-TYPE .PPNOD> NO-RETURN>
+ <ASSERT-TYPES <ORUPC .VARTBL <VSPCD .PPNOD>>>)>)
+ (<N==? <ACCUM-TYPE .PPNOD> NO-RETURN>
+ <ASSERT-TYPES <VSPCD .PPNOD>>)>
+ <FREST-L-D-STATE <DEAD-VARS .PPNOD>>
+ <SET LIFE <KILL-REM .LIFE .OV>>
+ <PUT .PPNOD
+ ,ACCUM-TYPE
+ <COND (.ACT? <PUT .PPNOD ,SIDE-EFFECTS (ALL)> .PRTYP)
+ (<==? <NODE-SUBR .PPNOD> ,REPEAT> <ACCUM-TYPE .PPNOD>)
+ (ELSE <TYPE-MERGE .TT <ACCUM-TYPE .PPNOD>>)>>>
+ <ACCUM-TYPE .PPNOD>>
+
+" Determine if assumptions made for this loop are still valid."
+
+<DEFINE ASSUM-OK? (AS TY "AUX" (OK? T))
+ #DECL ((TY AS) <LIST [REST <LIST SYMTAB ANY>]>)
+ <COND
+ (.ANALY-OK
+ <MAPF <>
+ <FUNCTION (L "AUX" (SYM <1 .L>) (TT <>))
+ #DECL ((L) <LIST SYMTAB <OR ATOM FORM SEGMENT>>)
+ <COND
+ (<N==? <2 .L> ANY>
+ <MAPF <>
+ <FUNCTION (LL)
+ <COND (<AND <SET TT <==? <1 .LL> .SYM>>
+ <N=? <2 .L> <2 .LL>>
+ <OR <==? <2 .L> NO-RETURN>
+ <TYPE-OK? <2 .LL> <NOTIFY <2 .L>>>>>
+ <COND (.OK?
+ <SET BACKTRACK <+ .BACKTRACK 1>>
+ <COND (,STATUS-LINE
+ <UPDATE-STATUS "Comp" <> "ANA"
+ .BACKTRACK>)>)>
+ <SET OK? <>>
+ <AND <GASSIGNED? DEBUGSW>
+ ,DEBUGSW
+ <PRIN1 <NAME-SYM .SYM>>
+ <PRINC " NOT OK current type: ">
+ <PRIN1 <2 .LL>>
+ <PRINC " assumed type: ">
+ <PRIN1 <2 .L>>
+ <CRLF>>)>
+ <AND .TT
+ <PUT .L 2 <TYPE-MERGE <2 .LL> <2 .L>>>
+ <MAPLEAVE>>>
+ .TY>)>>
+ .AS>
+ <COND (<NOT .OK?> <ASSERT-TYPES .AS>)>)>
+ .OK?>
+
+<DEFINE NOTIFY (D)
+ <COND (<AND <TYPE? .D FORM> <==? <LENGTH .D> 2> <==? <1 .D> NOT>>
+ <2 .D>)
+ (ELSE <FORM NOT .D>)>>
+
+" Analyze RETURN from a PROG/REPEAT. Check with PROGs final type."
+
+<DEFINE RETURN-ANA (NOD RTYP "AUX" (TT <KIDS .NOD>) N (LN <LENGTH .TT>) TEM)
+ #DECL ((NOD) NODE (TT) <LIST [REST NODE]> (LN) FIX (N) <OR NODE
+ FALSE>)
+ <SET RET-OR-AGAIN T>
+ <COND (<G? .LN 2> <COMPILE-ERROR "Too many args to RETURN." .NOD>)
+ (<OR <AND <==? .LN 2> <SET N <ACT-CHECK <2 .TT>>>>
+ <AND <L=? .LN 1> <SET N <PROGCHK RETURN .NOD>>>>
+ <SET N <CHTYPE .N NODE>>
+ <AND <0? .LN>
+ <PUT .NOD
+ ,KIDS
+ <SET TT (<NODE1 ,QUOTE-CODE .NOD ATOM T ()>)>>>
+ <SET TEM <EANA <1 .TT> <INIT-DECL-TYPE .N> RETURN>>
+ <COND (<==? <ACCUM-TYPE .N> NO-RETURN>
+ <PUT .N ,VSPCD <BUILD-TYPE-LIST <SYMTAB .N>>>
+ <PUT .N ,DEAD-VARS <SAVE-L-D-STATE .VARTBL>>)
+ (ELSE
+ <PUT .N ,VSPCD <ORUPC <SYMTAB .N> <VSPCD .N>>>
+ <PUT .N
+ ,DEAD-VARS
+ <MSAVE-L-D-STATE <DEAD-VARS .N> .VARTBL>>)>
+ <PUT .N ,ACCUM-TYPE <TYPE-MERGE .TEM <ACCUM-TYPE .N>>>
+ <PUT .NOD ,NODE-TYPE ,RETURN-CODE>
+ NO-RETURN)
+ (ELSE <SUBR-C-AN .NOD ANY>)>>
+
+<COND (<GASSIGNED? RETURN-ANA> <PUTPROP ,RETURN ANALYSIS ,RETURN-ANA>)>
+
+<DEFINE MULTI-RETURN-ANA (NOD RTYP
+ "AUX" (TT <KIDS .NOD>) N (LN <LENGTH .TT>) TEM
+ (SEG <>) (TYPS <FORM MULTI>)
+ (TP <CHTYPE .TYPS LIST>))
+ #DECL ((NOD) NODE (TT) <LIST [REST NODE]> (LN) FIX (N) <OR NODE
+ FALSE>)
+ <COND (<L? .LN 1> <COMPILE-ERROR "Too few args to MULTI-RETURN." .NOD>)
+ (ELSE
+ <COND (<AND <==? <NODE-TYPE <SET N <1 .TT>>> ,QUOTE-CODE>
+ <==? <NODE-NAME .N> <>>>
+ <SET N <PROGCHK MULTI-RETURN .N>>)
+ (<SET N <ACT-CHECK .N>>)
+ (ELSE <EANA <1 .TT> '<OR FRAME T$FRAME> MULTI-RETURN>)>
+ <MAPR <>
+ <FUNCTION (NP "AUX" (NN <1 .NP>) TY)
+ #DECL ((NN) NODE)
+ <COND (<==? <NODE-TYPE .NN> ,SEGMENT-CODE>
+ <SET TY
+ <EANA <1 <KIDS .NN>>
+ '<OR MULTI STRUCTURED>
+ MULTI-RETURN>>
+ <COND (<AND <N==? .TY ANY>
+ <N==? <SET TY
+ <GET-ELE-TYPE .TY ALL>>
+ ANY>>
+ <COND (<AND <NOT .SEG>
+ <EMPTY? <REST .NP>>>
+ <PUTREST .TP ([REST .TY])>)
+ (<AND <EMPTY? <REST .NP>>
+ <N==? .SEG ANY>>
+ <PUTREST .TP
+ ([REST
+ <TYPE-MERGE .SEG
+ .TY>])>)
+ (<N==? .SEG ANY>
+ <SET SEG
+ <TYPE-MERGE .SEG .TY>>)>)
+ (ELSE <SET SEG ANY>)>)
+ (ELSE
+ <SET TY <EANA .NN ANY MULTI-RETURN>>
+ <COND (<NOT .SEG>
+ <PUTREST .TP <SET TP (.TY)>>)>)>>
+ <REST .TT>>
+ <COND (<AND .N <==? <ACCUM-TYPE .N> NO-RETURN>>
+ <PUT .N ,VSPCD <BUILD-TYPE-LIST <SYMTAB .N>>>
+ <PUT .N ,DEAD-VARS <SAVE-L-D-STATE .VARTBL>>)
+ (.N
+ <PUT .N ,VSPCD <ORUPC <SYMTAB .N> <VSPCD .N>>>
+ <PUT .N
+ ,DEAD-VARS
+ <MSAVE-L-D-STATE <DEAD-VARS .N> .VARTBL>>)>
+ <COND (.N <PUT .N ,ACCUM-TYPE <TYPE-MERGE .TYPS
+ <ACCUM-TYPE .N>>>)>
+ <PUT .NOD ,NODE-TYPE ,MULTI-RETURN-CODE>
+ NO-RETURN)>>
+
+<COND (<AND <GASSIGNED? MULTI-RETURN> <GASSIGNED? MULTI-RETURN-ANA>>
+ <PUTPROP ,MULTI-RETURN ANALYSIS ,MULTI-RETURN-ANA>)>
+
+<DEFINE ACT-CHECK (N "OPT" (RETMNG T) "AUX" SYM RAO N1 (NT <NODE-TYPE .N>))
+ #DECL ((N N1) NODE (SYM) <OR SYMTAB FALSE> (RAO VALUE) <OR FALSE NODE>
+ (NT) FIX)
+ <COND (<OR <AND <==? .NT ,LVAL-CODE>
+ <TYPE? <NODE-NAME .N> SYMTAB>
+ <PURE-SYM <SET SYM <NODE-NAME .N>>>
+ <==? <CODE-SYM .SYM> 1>>
+ <AND <OR <==? .NT ,RSUBR-CODE> <==? .NT ,SUBR-CODE>>
+ <==? <NODE-SUBR .N> ,LVAL>
+ <==? <LENGTH <KIDS .N>> 1>
+ <==? <NODE-TYPE <SET N1 <1 <KIDS .N>>>> ,QUOTE-CODE>
+ <TYPE? <NODE-NAME .N1> ATOM>
+ <SET SYM <SRCH-SYM <NODE-NAME .N1>>>
+ <PURE-SYM .SYM>
+ <==? <CODE-SYM .SYM> 1>>>
+ <SET RAO <RET-AGAIN-ONLY <CHTYPE .SYM SYMTAB>>>
+ <EANA .N FRAME AGAIN-RETURN>
+ <COND (.RETMNG <PUT <CHTYPE .SYM SYMTAB> ,RET-AGAIN-ONLY .RAO>)>
+ .RAO)>>
+
+" AGAIN analyzer."
+
+<DEFINE AGAIN-ANA (NOD RTYP "AUX" (TEM <KIDS .NOD>) N)
+ #DECL ((NOD) NODE (TEM) <LIST [REST NODE]> (N) <OR FALSE NODE>)
+ <SET RET-OR-AGAIN T>
+ <COND (<OR <AND <EMPTY? .TEM> <SET N <PROGCHK AGAIN .NOD>>>
+ <AND <EMPTY? <REST .TEM>> <SET N <ACT-CHECK <1 .TEM>>>>>
+ <PUT .NOD ,NODE-TYPE ,AGAIN-CODE>
+ <SET N <CHTYPE .N NODE>>
+ <COND (<AGND .N>
+ <PUT .N
+ ,LIVE-VARS
+ <MSAVE-L-D-STATE <LIVE-VARS .N> .VARTBL>>)
+ (ELSE <PUT .N ,LIVE-VARS <SAVE-L-D-STATE .VARTBL>>)>
+ <PUT .N
+ ,AGND
+ <COND (<NOT <AGND .N>> <BUILD-TYPE-LIST <SYMTAB .N>>)
+ (ELSE <ORUPC <SYMTAB .N> <AGND .N>>)>>
+ NO-RETURN)
+ (<EMPTY? <REST .TEM>>
+ <COND (<NOT <ANA <1 .TEM> FRAME>>
+ <COMPILE-ERROR "Again not passed an activation" .NOD>)>
+ ANY)
+ (ELSE <COMPILE-ERROR "Too many arguments to AGAIN" .NOD>)>>
+
+<COND (<GASSIGNED? AGAIN-ANA> <PUTPROP ,AGAIN ANALYSIS ,AGAIN-ANA>)>
+
+" If not in PROG/REPEAT complain about NAME."
+
+<DEFINE PROGCHK (NAME NOD)
+ #DECL ((NOD) NODE)
+ <COND (<NOT <ASSIGNED? PNOD>>
+ <COMPILE-ERROR "Not in PROG/REPEAT " .NAME .NOD>)>
+ .PNOD>
+
+" Dispatch to special handlers for SUBRs. Or use standard."
+
+<DEFINE SUBR-ANA (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <APPLY <GETPROP <NODE-SUBR .NOD> ANALYSIS ',SUBR-C-AN> .NOD .RTYP>>
+
+" Hairy SUBR call analyzer. Also looks for internal calls."
+
+<DEFINE SUBR-C-AN (NOD RTYP
+ "AUX" (ARGS 0) (TYP ANY) (TMPL <GET-TMP <NODE-SUBR .NOD>>)
+ (NRGS1 <1 .TMPL>))
+ #DECL ((NOD) <SPECIAL NODE> (ARGS) <SPECIAL FIX> (TYP NRGS1) <SPECIAL ANY>
+ (TMPL) <SPECIAL LIST>)
+ <MAPF
+ <FUNCTION ("TUPLE" T
+ "AUX" NARGS TEM (NARGS1 .NRGS1) (N .NOD) (TPL .TMPL)
+ (RGS .ARGS))
+ #DECL ((T) TUPLE (ARGS RGS TL) FIX (TMPL TPL) <LIST ANY ANY>
+ (N NOD) NODE (NARGS) <LIST FIX FIX>)
+ <SET TYP <2 .TPL>>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <COND (<SEGS .N>
+ <COND (<TYPE? .TYP ATOM FORM>) (ELSE <SET TYP ANY>)>)
+ (ELSE
+ <COND (<TYPE? .NARGS1 FIX>
+ <ARGCHK .RGS .NARGS1 <NODE-NAME .N> .NOD>)
+ (<TYPE? .NARGS1 LIST>
+ <COND (<G? .RGS <2 <SET NARGS .NARGS1>>>
+ <COMPILE-ERROR "Too many arguments to "
+ <NODE-NAME .N>
+ .N>)>
+ <COND (<L? .RGS <1 .NARGS>>
+ <COMPILE-ERROR
+ "Too few arguments to "
+ <NODE-NAME .N>
+ .N>)>)>
+ <COND (<TYPE? .TYP ATOM FORM>)
+ (ELSE <SET TYP <APPLY .TYP !.T>>)>
+ <SET ARGS .RGS>)>>
+ <FUNCTION (N "AUX" TYP)
+ #DECL ((N NOD) NODE (ARGS) FIX (ARGACS) <PRIMTYPE LIST>)
+ <COND (<==? <NODE-TYPE .N> ,SEGMENT-CODE>
+ <EANA <1 <KIDS .N>> '<OR MULTI STRUCTURED> SEGMENT>
+ <PUT .NOD ,SEGS T>
+ ANY)
+ (ELSE <SET ARGS <+ .ARGS 1>> <SET TYP <ANA .N ANY>> .TYP)>>
+ <KIDS .NOD>>
+ <PUT .NOD ,SIDE-EFFECTS (ALL)>
+ <TYPE-OK? .TYP .RTYP>>
+
+<DEFINE SEGMENT-ANA (NOD RTYP)
+ <COMPILE-ERROR "Illegal segment (not in form or structure)" .NOD>>
+
+" Analyze VECTOR, UVECTOR and LIST builders."
+
+<DEFINE COPY-AN (NOD RTYP
+ "AUX" (ARGS 0) (RT <ISTYPE? <RESULT-TYPE .NOD>>)
+ (K <KIDS .NOD>) N (LWIN <==? .RT LIST>) NN COD)
+ #DECL ((NOD N) NODE (ARGS) FIX (K) <LIST [REST NODE]>)
+ <COND
+ (<NOT <EMPTY? .K>>
+ <REPEAT (DC STY PTY TEM TT (SG <>) (FRM <FORM .RT>)
+ (FRME <CHTYPE .FRM LIST>) (GOTDC <>))
+ #DECL ((FRM) FORM (FRME) <LIST ANY>)
+ <COND
+ (<EMPTY? .K>
+ <COND (<==? .RT LIST>
+ <RETURN <SET RT
+ <COND (<EMPTY? <REST .FRM>> <1 .FRM>)
+ (ELSE .FRM)>>>)>
+ <COND (.DC <PUTREST .FRME ([REST .DC])>)
+ (.STY <PUTREST .FRME ([REST .STY])>)
+ (.PTY <PUTREST .FRME ([REST <FORM PRIMTYPE .PTY>])>)>
+ <RETURN <SET RT .FRM>>)
+ (<OR <==? <SET COD <NODE-TYPE <SET N <1 .K>>>> ,SEGMENT-CODE>
+ <==? .COD ,SEG-CODE>>
+ <SET TEM <GET-ELE-TYPE <EANA <1 <KIDS .N>>
+ '<OR MULTI STRUCTURED> SEGMENT> ALL>>
+ <PUT .NOD ,SEGS T>
+ <COND (<NOT .SG> <SET GOTDC <>>)>
+ <SET SG T>
+ <COND (<AND .LWIN
+ <MEMQ <STRUCTYP <RESULT-TYPE <1 <KIDS .N>>>>
+ '[LIST VECTOR UVECTOR TUPLE]>>)
+ (ELSE <SET LWIN <>>)>)
+ (ELSE <SET ARGS <+ .ARGS 2>> <SET TEM <ANA .N ANY>>)>
+ <COND (<NOT .GOTDC>
+ <SET GOTDC T>
+ <SET PTY
+ <COND (<SET STY <ISTYPE? <SET DC .TEM>>> <MTYPR .STY>)>>)
+ (<OR <NOT .DC> <N==? .DC .TEM>>
+ <SET DC <>>
+ <COND (<OR <N==? <SET TT <ISTYPE? .TEM>> .STY> <NOT .STY>>
+ <SET STY <>>
+ <COND (<AND .PTY <==? .PTY <AND .TT <MTYPR .TT>>>>)
+ (ELSE <SET PTY <>>)>)>)>
+ <COND (<NOT .SG> <SET FRME <REST <PUTREST .FRME (.TEM)>>>)>
+ <SET K <REST .K>>>)>
+ <PUT .NOD ,RESULT-TYPE .RT>
+ <COND
+ (<AND <GASSIGNED? COPY-LIST-CODE> .LWIN>
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <COND (<==? <NODE-TYPE .N> ,SEGMENT-CODE>
+ <PUT .N ,NODE-TYPE ,SEG-CODE>)>>
+ <KIDS .NOD>>
+ <COND (<AND <==? <LENGTH <SET K <KIDS .NOD>>> 1>
+ <==? <NODE-TYPE <1 .K>> ,SEG-CODE>
+ <==? <STRUCTYP <RESULT-TYPE <SET NN <1 <KIDS <1 .K>>>>>>
+ LIST>>
+ <COND (<NOT <EMPTY? <PARENT .NOD>>>
+ <MAPR <>
+ <FUNCTION (L "AUX" (N <1 .L>))
+ #DECL ((N) NODE (L) <LIST [REST NODE]>)
+ <COND (<==? .NOD .N>
+ <PUT .L 1 .NN>
+ <MAPLEAVE>)>>
+ <KIDS <CHTYPE <PARENT .NOD> NODE>>>)>
+ <PUT .NN ,PARENT <CHTYPE <PARENT .NOD> NODE>>
+ <SET RT <RESULT-TYPE .NN>>)
+ (ELSE <PUT .NOD ,NODE-TYPE ,COPY-LIST-CODE>)>)
+ (ELSE
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <COND (<==? <NODE-TYPE .N> ,SEG-CODE>
+ <PUT .N ,NODE-TYPE ,SEGMENT-CODE>)>>
+ <KIDS .NOD>>
+ <PUT .NOD ,NODE-TYPE ,COPY-CODE>)>
+ <TYPE-OK? .RT .RTYP>>
+
+" Analyze quoted objects, for structures hack type specs."
+
+<DEFINE QUOTE-ANA (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <TYPE-OK? <GEN-DECL <NODE-NAME .NOD>> .RTYP>>
+
+<DEFINE QUOTE-ANA2 (NOD RTYP)
+ #DECL ((NOD) NODE)
+ <COND (<1? <LENGTH <KIDS .NOD>>>
+ <PUT .NOD ,NODE-TYPE ,QUOTE-CODE>
+ <PUT .NOD ,NODE-NAME <1 <KIDS .NOD>>>
+ <PUT .NOD ,KIDS ()>
+ <TYPE-OK? <RESULT-TYPE .NOD> .RTYP>)
+ (ELSE <COMPILE-ERROR "Empty QUOTE?">)>>
+
+<COND (<GASSIGNED? QUOTE-ANA2> <PUTPROP ,QUOTE ANALYSIS ,QUOTE-ANA2>)>
+
+" Analyze a call to an RSUBR."
+
+<DEFINE RSUBR-ANA (NOD RTYP
+ "AUX" (ARGS 0)
+ (DCL:<LIST [REST !<LIST ATOM ANY!>]> <TYPE-INFO .NOD>)
+ (SEGF <>) (MUST-EMPTY T) FRST (TUPF <>) (OPTF <>)
+ (K:<LIST [REST NODE]> <KIDS .NOD>)
+ (NM:ATOM <NODE-NAME .NOD>) (RT <>))
+ #DECL ((NOD) NODE (ARGS) FIX)
+ <MAPF <>
+ <FUNCTION (ARG "AUX" TY ET)
+ #DECL ((ARG NOD) NODE)
+ <COND (<NOT <EMPTY? .DCL>>
+ <COND (<==? <SET FRST <1 <SET RT <1 .DCL>>>> OPTIONAL>
+ <SET OPTF T>)
+ (<==? .FRST TUPLE> <SET TUPF T>)>
+ <SET RT <2 .RT>>
+ <SET DCL <REST .DCL>>)
+ (<NOT .TUPF> <SET OPTF <SET RT <>>>)>
+ <COND (<==? <NODE-TYPE .ARG> ,SEGMENT-CODE>
+ <SET SEGF T>
+ <SET ET
+ <GET-ELE-TYPE <SET TY <ANA <1 <KIDS .ARG>> ANY>> ALL>>
+ <COND (<COND (.TUPF <TYPE-OK? <GET-ELE-TYPE .RT ALL> .ET>)
+ (.RT <TYPE-OK? .RT .ET>)>)
+ (<AND <OR <NOT .RT> .TUPF .OPTF> <L=? <MINL .TY> 0>>
+ <SET MUST-EMPTY T>
+ <COMPILE-WARNING "Segment must be empty: " .NOD>)
+ (<NOT .RT> <COMPILE-ERROR "Too many arguments to: "
+ .NM .ARG>)
+ (ELSE
+ <COMPILE-ERROR "Argument wrong type to: "
+ .NM
+ .ARG>)>
+ <PUT .NOD ,SEGS T>)
+ (ELSE
+ <SET ARGS <+ .ARGS 1>>
+ <EANA .ARG
+ <COND (.TUPF <GET-ELE-TYPE .RT <COND (.SEGF ALL)
+ (ELSE .ARGS)>>)
+ (ELSE .RT)> .NM>)>>
+ .K>
+ <COND (<OR <==? .NM PRINC> <==? .NM PRINT> <==? .NM PRIN1>>
+ <RESULT-TYPE .NOD <TYPE-AND <RESULT-TYPE .NOD>
+ <RESULT-TYPE <1 .K>>>>)>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <PUT .NOD ,SIDE-EFFECTS (ALL)>
+ <TYPE-OK? <RESULT-TYPE .NOD> .RTYP>>
+
+" Analyze CHTYPE, in some cases do it at compile time."
+
+
+<DEFINE CHTYPE-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) NTN NT OBN OB TARG S1 S2
+ TDECL)
+ #DECL ((NOD OBN NTN) NODE (K) <LIST [REST NODE]> (NT) ATOM)
+ <COND
+ (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <ARGCHK <LENGTH .K> 2 CHTYPE .NOD>
+ <SET OB <ANA <SET OBN <1 .K>> ANY>>
+ <EANA <SET NTN <2 .K>> ATOM CHTYPE>
+ <COND
+ (<==? <NODE-TYPE .NTN> ,QUOTE-CODE>
+ <COND (<NOT <ISTYPE? <SET NT <NODE-NAME .NTN>>>>
+ <COMPILE-ERROR "Second arg to CHTYPE not a type " .NT .NOD>)>
+ <COND (<NOT <TYPE-OK? .OB <FORM PRIMTYPE <MTYPR .NT>>>>
+ <COMPILE-ERROR "Primtypes differ in CHTYPE" .OB .NT .NOD>)>
+ <COND (<==? <NODE-TYPE .OBN> ,QUOTE-CODE>
+ <PUT .NOD ,NODE-TYPE ,QUOTE-CODE>
+ <PUT .NOD ,KIDS ()>
+ <PUT .NOD ,NODE-NAME <CHTYPE <NODE-NAME .OBN> .NT>>)
+ (<TYPESAME .OB .NT>
+ <COMPILE-WARNING "Redundant CHTYPE" .NOD>
+ <PUT .NOD ,NODE-TYPE ,ID-CODE>)
+ (<SET TDECL <GET-DECL .NT>>
+ <SET TDECL <CHTYPE
+ (<FORM PRIMTYPE <TYPEPRIM .NT>> !<REST .TDECL>)
+ <TYPE .TDECL>>>
+ <COND (<NOT <TYPE-OK? .OB .TDECL>>
+ <COMPILE-ERROR "DECL violation in CHTYPE "
+ .NOD>)>
+ <PUT .NOD ,NODE-TYPE ,CHTYPE-CODE>)
+ (ELSE <PUT .NOD ,NODE-TYPE ,CHTYPE-CODE>)>
+ <PUT .NOD ,RESULT-TYPE .NT>
+ <TYPE-OK? .NT .RTYP>)
+ (<AND <==? <NODE-TYPE .NTN> ,RSUBR-CODE> <==? <NODE-NAME .NTN> TYPE>>
+ <COND
+ (<AND <SET S1 <PRIMITIVE-TYPE .OB>>
+ <SET S2
+ <PRIMITIVE-TYPE <SET TARG <RESULT-TYPE <1 <KIDS .NTN>>>>>>
+ <NOT <TYPE-OK? .S1 .S2>>>
+ <COMPILE-ERROR "Primtypes differ in CHTYPE" .OB .TARG .NOD>)
+ (ELSE
+ <PUT .NOD ,NODE-TYPE ,CHTYPE-CODE>
+ <PUT .NOD ,RESULT-TYPE .TARG>
+ <TYPE-OK? .TARG .RTYP>)>)
+ (ELSE
+ <COND (.VERBOSE <ADDVMESS .NOD ("Can't open compile CHTYPE.")>)>
+ <TYPE-OK? ANY .RTYP>)>)>>
+
+<COND (<GASSIGNED? CHTYPE-ANA> <PUTPROP ,CHTYPE ANALYSIS ,CHTYPE-ANA>)>
+
+" Analyze use of ASCII sometimes do at compile time."
+
+<DEFINE ASCII-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) ITM TYP TEM)
+ #DECL ((NOD ITM) NODE (K) <LIST [REST NODE]>)
+ <COND (<SEGFLUSH .NOD .RTYP>)
+ (ELSE
+ <ARGCHK <LENGTH .K> 1 ASCII .NOD>
+ <SET TYP <EANA <SET ITM <1 .K>> '<OR FIX CHARACTER> ASCII>>
+ <COND (<==? <NODE-TYPE .ITM> ,QUOTE-CODE>
+ <PUT .NOD ,NODE-TYPE ,QUOTE-CODE>
+ <PUT .NOD ,NODE-NAME <SET TEM <ASCII <NODE-NAME .ITM>>>>
+ <PUT .NOD ,RESULT-TYPE <TYPE .TEM>>
+ <PUT .NOD ,KIDS ()>)
+ (<==? <ISTYPE? .TYP> FIX>
+ <PUT .NOD ,NODE-TYPE ,CHTYPE-CODE>
+ <PUT .NOD ,RESULT-TYPE CHARACTER>)
+ (<==? .TYP CHARACTER>
+ <PUT .NOD ,NODE-TYPE ,CHTYPE-CODE>
+ <PUT .NOD ,RESULT-TYPE FIX>)
+ (ELSE <PUT .NOD ,RESULT-TYPE '<OR FIX CHARACTER>>)>
+ <TYPE-OK? <RESULT-TYPE .NOD> .RTYP>)>>
+
+<COND (<GASSIGNED? ASCII-ANA> <PUTPROP ,ASCII ANALYSIS ,ASCII-ANA>)>
+
+<DEFINE UNWIND-ANA (NOD RTYP "AUX" (K <KIDS .NOD>) ITYP)
+ #DECL ((NOD) NODE (K) <LIST [REST NODE]>)
+ <SET ITYP <EANA <1 .K> ANY UNWIND>>
+ <EANA <2 .K> ANY UNWIND>
+ <PUTPROP .FCN UNWIND T>
+ <TYPE-OK? .ITYP .RTYP>>
+
+" Analyze READ type SUBRS in two cases (print uncertain usage message maybe?)"
+
+<DEFINE READ-ANA (N R)
+ #DECL ((N) NODE)
+ <MAPF <>
+ <FUNCTION (NN "AUX" TY)
+ #DECL ((NN N) NODE)
+ <COND (<==? <NODE-TYPE .NN> ,EOF-CODE>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <SET TY <EANAQ <1 <KIDS .NN>> ANY <NODE-NAME .N> .N>>
+ <COND (<TYPE-OK? .TY '<OR FORM LIST VECTOR UVECTOR>>
+ <COMPILE-WARNING
+ "Uncertain use of " <NODE-NAME .N> .N>)
+ (ELSE <PUT .N ,NODE-TYPE ,READ-EOF2-CODE>)>)
+ (ELSE <EANA .NN ANY <NODE-NAME .N>>)>>
+ <KIDS .N>>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <TYPE-OK? ANY .R>>
+
+<DEFINE READ2-ANA (N R)
+ #DECL ((N) NODE)
+ <MAPF <>
+ <FUNCTION (NN)
+ #DECL ((NN N) NODE)
+ <COND (<==? <NODE-TYPE .NN> ,EOF-CODE>
+ <EANAQ <1 <KIDS .NN>> ANY <NODE-NAME .N> .N>)
+ (ELSE <EANA .NN ANY <NODE-NAME .N>>)>>
+ <KIDS .N>>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>
+ <TYPE-OK? ANY .R>>
+
+<DEFINE GET-ANA (N R "AUX" TY (K <KIDS .N>) (NAM <NODE-NAME .N>))
+ #DECL ((N) NODE (K) <LIST NODE NODE NODE>)
+ <EANA <1 .K> ANY .NAM>
+ <EANA <2 .K> ANY .NAM>
+ <SET TY <EANAQ <3 .K> ANY .NAM .N>>
+ <COND (<TYPE-OK? .TY '<OR LIST VECTOR UVECTOR FORM>>
+ <COMPILE-WARNING "Uncertain use of " .NAM .N>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>)
+ (ELSE <PUT .N ,NODE-TYPE ,GET2-CODE>)>
+ <TYPE-OK? ANY .R>>
+
+<DEFINE GET2-ANA (N R
+ "AUX" (K <KIDS .N>) (NAM <NODE-NAME .N>) (LN <LENGTH .K>))
+ #DECL ((N) NODE (K) <LIST NODE NODE [REST NODE]> (LN) FIX)
+ <EANA <1 .K> ANY .NAM>
+ <EANA <2 .K> ANY .NAM>
+ <COND (<==? .LN 3> <EANAQ <3 .K> ANY .NAM .N>)>
+ <TYPE-OK? ANY .R>>
+
+<DEFINE EANAQ (N R NAM INOD "AUX" SPCD)
+ #DECL ((N) NODE (SPCD) LIST)
+ <SET SPCD <BUILD-TYPE-LIST .VARTBL>>
+ <SET R <EANA .N .R .NAM>>
+ <ASSERT-TYPES <ORUPC .VARTBL .SPCD>>
+ .R>
+
+<DEFINE ACTIV? (BST NOACT)
+ #DECL ((BST) <LIST [REST SYMTAB]>)
+ <REPEAT ()
+ <AND <EMPTY? .BST> <RETURN <>>>
+ <AND <==? <CODE-SYM <1 .BST>> 1>
+ <OR <NOT .NOACT>
+ <NOT <RET-AGAIN-ONLY <1 .BST>>>
+ <SPEC-SYM <1 .BST>>>
+ <RETURN T>>
+ <SET BST <REST .BST>>>>
+
+<DEFINE SAME-DECL? (D1 D2) <OR <=? .D1 .D2> <NOT <TYPE-OK? .D2 <NOTIFY .D1>>>>>
+
+<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>>
+ <COMPILE-NOTE "Redeclared special " .SYM>
+ <PUT .T2 ,SPEC-SYM T>)>)>
+ <COND (<MEMQ <PRIMTYPE .OBJ> '[FORM LIST UVECTOR VECTOR]>
+ <MAPF <> ,SPECIALIZE .OBJ>)>>
+
+<DEFINE ADECL-ANA (NOD RTYP "AUX" (RT <NODE-NAME .NOD>) (N <1 <KIDS .NOD>>) TY)
+
+ <COND (<NOT <SET TY <TYPE-OK? .RT .RTYP>>>
+ <COMPILE-ERROR "ADECL asserts incompatible type."
+ "Required type is "
+ .RTYP
+ " ADECL type is "
+ .RT>)
+ (<NOT <SET RT <ANA .N .TY>>>
+ <COMPILE-ERROR "ADECL asserts incompatible type."
+ "Result type is "
+ <RESULT-TYPE .N>
+ " ADECL type is "
+ .TY>)>
+ <PUT .NOD ,RESULT-TYPE .RT>
+ .RT>
+
+<DEFINE CALL-ANA (N R "AUX" (K <KIDS .N>) INS TYP NN)
+ #DECL ((N INS) NODE (K) <LIST [REST NODE]> (NN) <OR FALSE NODE>)
+ <COND
+ (<EMPTY? .K> <COMPILE-ERROR "CALL has no instruction supplied" .N>)
+ (<AND <==? <NODE-TYPE <SET INS <1 .K>>> ,QUOTE-CODE>
+ <TYPE? <NODE-NAME .INS> ATOM>
+ <SET TYP <LEGAL-MIM-INS .INS>>>
+ <PUT .N ,SIDE-EFFECTS (.N !<SIDE-EFFECTS .N>)>
+ <COND (<==? <NODE-NAME .INS> `RTUPLE>
+ <EANA <2 .K> FIX RTUPLE>
+ <COND (<SET NN <ACT-CHECK <3 .K> <>>>
+ <COND (<==? <ACCUM-TYPE .NN> NO-RETURN>
+ <PUT .NN ,VSPCD <BUILD-TYPE-LIST <SYMTAB .NN>>>
+ <PUT .NN ,DEAD-VARS <SAVE-L-D-STATE .VARTBL>>)
+ (ELSE
+ <PUT .NN ,VSPCD <ORUPC <SYMTAB .NN> <VSPCD .NN>>>
+ <PUT .NN
+ ,DEAD-VARS
+ <MSAVE-L-D-STATE <DEAD-VARS .NN> .VARTBL>>)>
+ <PUT .NN ,ACCUM-TYPE <TYPE-MERGE TUPLE <ACCUM-TYPE .NN>>>)
+ (ELSE <EANA <3 .K> FRAME RTUPLE>)>)
+ (ELSE
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <COND (<==? <NODE-TYPE .N> ,SEGMENT-CODE>
+ <EANA <1 <KIDS .N>> '<OR MULTI STRUCTURED> CALL>)
+ (ELSE <EANA .N ANY CALL>)>>
+ <REST .K>>)>
+ <TYPE-OK? .R .TYP>)
+ (ELSE <COMPILE-ERROR "CALL with a non-instruction: " .N>)>>
+
+<DEFINE LEGAL-MIM-INS (N "AUX" (ATM <NODE-NAME .N>) MIMOP)
+ #DECL ((FCN N) NODE (ATM) ATOM)
+ <COND (<SET MIMOP <LOOKUP <SPNAME .ATM> ,MIM-OBL>>
+ <PUT .N ,NODE-NAME .MIMOP>
+ <COND (<=? <SPNAME .MIMOP> "ACTIVATION">
+ <PUT .FCN ,ACTIVATED T>)>
+ <COND (<GETPROP .MIMOP TYPE>) (ELSE ANY)>)>>
+
+<DEFINE APPLY-ANA (N R "AUX" (K <KIDS .N>))
+ #DECL ((N) NODE (K) <LIST [REST NODE]>)
+ <COND (<EMPTY? .K> <COMPILE-ERROR "APPLY has nothing to apply" .N>)
+ (ELSE
+ <PUT .N ,SIDE-EFFECTS (.N !<SIDE-EFFECTS .N>)>
+ <MAPF <>
+ <FUNCTION (N)
+ #DECL ((N) NODE)
+ <COND (<==? <NODE-TYPE .N> ,SEGMENT-CODE>
+ <EANA <1 <KIDS .N>>
+ '<OR MULTI STRUCTURED> CALL>)
+ (ELSE <EANA .N ANY CALL>)>>
+ .K>
+ <PUT .N ,NODE-TYPE ,APPLY-CODE>
+ <TYPE-OK? .R ANY>)>>
+
+<COND (<GASSIGNED? APPLY-ANA> <PUTPROP ,APPLY ANALYSIS ,APPLY-ANA>)>
+
+<DEFINE ANALYSIS-DISPATCHER (NOD RTYP)
+ <CASE ,==?
+ <NODE-TYPE .NOD>
+ (,QUOTE-CODE <QUOTE-ANA .NOD .RTYP>)
+ (,FUNCTION-CODE <FUNC-ANA .NOD .RTYP>)
+ (,SEGMENT-CODE <SEGMENT-ANA .NOD .RTYP>)
+ (,FORM-CODE <FORM-AN .NOD .RTYP>)
+ (,PROG-CODE <PRG-REP-ANA .NOD .RTYP>)
+ (,SUBR-CODE <SUBR-ANA .NOD .RTYP>)
+ (,COND-CODE <COND-ANA .NOD .RTYP>)
+ (,COPY-CODE <COPY-AN .NOD .RTYP>)
+ (,RSUBR-CODE <RSUBR-ANA .NOD .RTYP>)
+ (,ISTRUC-CODE <ISTRUC-ANA .NOD .RTYP>)
+ (,ISTRUC2-CODE <ISTRUC2-ANA .NOD .RTYP>)
+ (,READ-EOF-CODE <READ-ANA .NOD .RTYP>)
+ (,READ-EOF2-CODE <READ2-ANA .NOD .RTYP>)
+ (,GET-CODE <GET-ANA .NOD .RTYP>)
+ (,GET2-CODE <GET2-ANA .NOD .RTYP>)
+ (,MAP-CODE <MAPPER-AN .NOD .RTYP>)
+ (,MARGS-CODE <MARGS-ANA .NOD .RTYP>)
+ (,ARITH-CODE <ARITH-ANA .NOD .RTYP>)
+ (,TEST-CODE <ARITHP-ANA .NOD .RTYP>)
+ (,0-TST-CODE <ARITHP-ANA .NOD .RTYP>)
+ (,1?-CODE <ARITHP-ANA .NOD .RTYP>)
+ (,MIN-MAX-CODE <ARITH-ANA .NOD .RTYP>)
+ (,ABS-CODE <ABS-ANA .NOD .RTYP>)
+ (,FIX-CODE <FIX-ANA .NOD .RTYP>)
+ (,FLOAT-CODE <FLOAT-ANA .NOD .RTYP>)
+ (,MOD-CODE <MOD-ANA .NOD .RTYP>)
+ (,LNTH-CODE <LENGTH-ANA .NOD .RTYP>)
+ (,MT-CODE <EMPTY?-ANA .NOD .RTYP>)
+ (,NTH-CODE <NTH-ANA .NOD .RTYP>)
+ (,REST-CODE <REST-ANA .NOD .RTYP>)
+ (,PUT-CODE <PUT-ANA .NOD .RTYP>)
+ (,PUTR-CODE <PUTREST-ANA .NOD .RTYP>)
+ (,UNWIND-CODE <UNWIND-ANA .NOD .RTYP>)
+ (,FORM-F-CODE <FORM-F-ANA .NOD .RTYP>)
+ (,IRSUBR-CODE <IRSUBR-ANA .NOD .RTYP>)
+ (,ROT-CODE <ROT-ANA .NOD .RTYP>)
+ (,LSH-CODE <LSH-ANA .NOD .RTYP>)
+ (,BIT-TEST-CODE <BIT-TEST-ANA .NOD .RTYP>)
+ (,CASE-CODE <CASE-ANA .NOD .RTYP>)
+ (,COPY-LIST-CODE <COPY-AN .NOD .RTYP>)
+ (,ADECL-CODE <ADECL-ANA .NOD .RTYP>)
+ (,CALL-CODE <CALL-ANA .NOD .RTYP>)
+ (,APPLY-CODE <APPLY-ANA .NOD .RTYP>)
+ (,FGETBITS-CODE <FGETBITS-ANA .NOD .RTYP>)
+ (,FPUTBITS-CODE <FPUTBITS-ANA .NOD .RTYP>)
+ (,STACK-CODE <STACK-ANA .NOD .RTYP>)
+ (,BACK-CODE <BACK-ANA .NOD .RTYP>)
+ (,TOP-CODE <TOP-ANA .NOD .RTYP>)
+ (,CHANNEL-OP-CODE <CHANNEL-OP-ANA .NOD .RTYP>)
+ (,ATOM-PART-CODE <ATOM-PART-ANA .NOD .RTYP>)
+ (,OFFSET-PART-CODE <OFFSET-PART-ANA .NOD .RTYP>)
+ (,PUT-GET-DECL-CODE <PUT-GET-DECL-ANA .NOD .RTYP>)
+ (,SUBSTRUC-CODE <SUBSTRUC-ANA .NOD .RTYP>)
+ (,MULTI-SET-CODE <MULTI-SET-ANA .NOD .RTYP>)
+ DEFAULT
+ (<SUBR-ANA .NOD .RTYP>)>>
+
+<DEFINE SPEC-ANA (CONST PRED-NAME OTYPE RTYP DFLG NOD WHO "AUX" TEM PAT)
+ #DECL ((NOD) NODE)
+ <SET PAT
+ <COND (<TYPE? .CONST LIST>
+ <COND (<==? .PRED-NAME ==?> <GEN-DECL <1 .CONST>>)
+ (<==? .PRED-NAME TYPE?> <TYPE-MERGE !.CONST>)
+ (ELSE
+ <MAPF ,TYPE-MERGE
+ <FUNCTION (X) <FORM PRIMTYPE .X>>
+ .CONST>)>)
+ (ELSE
+ <COND (<==? .PRED-NAME ==?> <GEN-DECL .CONST>)
+ (<==? .PRED-NAME TYPE?> .CONST)
+ (ELSE <FORM PRIMTYPE .CONST>)>)>>
+ <COND
+ (.DFLG <PUT .NOD ,RESULT-TYPE <SET TEM <TYPE-OK? ATOM .RTYP>>> .TEM)
+ (ELSE
+ <COND (<AND <N==? .PRED-NAME ==?>
+ <N==? .OTYPE ANY>
+ <NOT <TYPE-OK? <FORM NOT .PAT> .OTYPE>>>
+ <SET TEM ATOM>)
+ (<TYPE-OK? .OTYPE .PAT> <SET TEM '<OR FALSE ATOM>>)
+ (ELSE <SET TEM FALSE>)>
+ <MAPF <>
+ <FUNCTION (L "AUX" (FLG <1 .L>) (SYM <2 .L>))
+ #DECL ((L) <LIST <OR ATOM FALSE> SYMTAB> (SYM) SYMTAB)
+ <SET TRUTH
+ <ADD-TYPE-LIST .SYM .PAT .TRUTH .FLG <REST .L 2>>>
+ <OR <==? .TEM ATOM>
+ <SET UNTRUTH
+ <ADD-TYPE-LIST .SYM
+ <FORM NOT .PAT>
+ .UNTRUTH
+ .FLG
+ <REST .L 2>>>>>
+ .WHO>
+ <PUT .NOD ,RESULT-TYPE <SET TEM <TYPE-OK? .TEM .RTYP>>>
+ .TEM)>>
+
+<DEFINE ISTRUC-ANA (N R "AUX" (K <KIDS .N>) FM NUM TY (NEL REST) SIZ)
+ #DECL ((N FM NUM) NODE)
+ <EANA <SET NUM <1 .K>> FIX <NODE-NAME .N>>
+ <SET TY
+ <EANA <SET FM <2 .K>>
+ <COND (<==? <NODE-NAME .FM> ISTRING> CHARACTER)
+ (<==? <NODE-NAME .FM> IBYTES> FIX)
+ (<==? <NODE-NAME .FM> UVECTOR> FIX)
+ (ELSE ANY)>
+ <NODE-NAME .N>>>
+ <COND (<TYPE-OK? .TY '<OR FORM LIST VECTOR UVECTOR LVAL GVAL>>
+ <COMPILE-WARNING "Explicit EVAL required: " <NODE-NAME .N> .N>
+ <SPEC-FLUSH>
+ <PUT-FLUSH ALL>)>
+ <COND (<==? <NODE-TYPE .NUM> ,QUOTE-CODE> <SET NEL <NODE-NAME .NUM>>)>
+ <COND (<TYPE-OK? .TY FORM> <SET TY ANY>)>
+ <TYPE-OK? <FORM <ISTYPE? <RESULT-TYPE .N>>
+ !<COND (<TYPE? .NEL FIX> ([.NEL .TY])) (ELSE ())>
+ !<COND (<==? .TY ANY> ()) (ELSE ([REST .TY]))>>
+ .R>>
+
+<DEFINE ISTRUC2-ANA (N R "AUX" (K <KIDS .N>) GD NUM TY (NEL REST) SIZ)
+ #DECL ((N NUM GD) NODE)
+ <EANA <SET NUM <1 .K>> FIX <NODE-NAME .N>>
+ <SET TY
+ <COND (<==? <NODE-NAME .N> ISTRING> CHARACTER)
+ (<OR <==? <NODE-NAME .N> IBYTES>
+ <==? <NODE-NAME .N> IUVECTOR>>
+ FIX)
+ (ELSE ANY)>>
+ <COND (<==? <LENGTH .K> 2>
+ <SET TY <EANA <SET GD <2 .K>> .TY <NODE-NAME .N>>>)>
+ <COND (<==? <NODE-TYPE .NUM> ,QUOTE-CODE> <SET NEL <NODE-NAME .NUM>>)>
+ <TYPE-OK? <COND (<AND <==? .NEL REST> <==? .TY ANY>>
+ <ISTYPE? <RESULT-TYPE .N>>)
+ (ELSE
+ <FORM <ISTYPE? <RESULT-TYPE .N>>
+ !<COND (<N==? .NEL REST> ([.NEL .TY]))
+ (ELSE ())>
+ !<COND (<==? .TY ANY> ())
+ (ELSE ([REST .TY]))>>)>
+ .R>>
+
+<DEFINE STACK-ANA (N R) #DECL ((N) NODE) <EANA <1 <KIDS .N>> .R STACK>>
+
+<DEFINE CHANNEL-OP-ANA (N R "AUX" (K <KIDS .N>) TY)
+ #DECL ((N) NODE (K) <LIST [REST NODE]>)
+ <COND (<SEGFLUSH .N .R>)
+ (ELSE
+ <PUT .N ,SIDE-EFFECTS (.N !<SIDE-EFFECTS .N>)>
+ <COND (<L? <LENGTH .K> 2> <ARGCHK <LENGTH .K> 2 CHANNEL-OP .N>)>
+ <SET TY <EANA <1 .K> CHANNEL CHANNEL-OP>>
+ <EANA <2 .K> ATOM CHANNEL-OP>
+ <MAPF <>
+ <FUNCTION (NN) #DECL ((NN) NODE) <ANA .NN ANY>>
+ <REST .K 2>>
+ <COND (<AND <TYPE? .TY FORM SEGMENT>
+ <==? <LENGTH .TY> 2>
+ <TYPE? <SET TY <2 .TY>> FORM>
+ <==? <LENGTH .TY> 2>
+ <==? <1 .TY> QUOTE>
+ <TYPE? <2 .TY> ATOM>>
+ <PUT .N ,NODE-TYPE ,CHANNEL-OP-CODE>
+ <PUT .N ,NODE-SUBR <2 .TY>>)>
+ <TYPE-OK? .R ANY>)>>
+
+<COND (<AND <GASSIGNED? CHANNEL-OP> <GASSIGNED? CHANNEL-OP-ANA>>
+ <PUTPROP ,CHANNEL-OP ANALYSIS ,CHANNEL-OP-ANA>)>
+
+
+<DEFINE P-SYMTAB (SY:SYMTAB)
+ <PRINC "#SY ">
+ <PRINC <NAME-SYM .SY>>
+ <PRINC " Decl: ">
+ <PRIN1 <DECL-SYM .SY>>
+ <PRINC " CType: ">
+ <PRIN1 <GET-CURRENT-TYPE .SY>>>
+
+<COND (<GASSIGNED? P-SYMTAB> <PRINTTYPE SYMTAB ,P-SYMTAB>)>
+
+<DEFINE P-NODE (NOD:NODE)
+ <PRINC "#NODE ">
+ <PRIN1 <NTH ,CODVEC <NODE-TYPE .NOD>>>
+ <PRINC " Name: ">
+ <PRIN1 <NODE-NAME .NOD>>
+ <PRINC " Type: ">
+ <PRIN1 <RESULT-TYPE .NOD>>>
+
+<COND (<GASSIGNED? P-NODE> <PRINTTYPE NODE ,P-NODE>)>
+
+<ENDPACKAGE>