| File: | src/scobind.c |
| Warning: | line 3539, column 26 Array access (via field 'uses') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /****************************************************************************** | |||
| 2 | * | |||
| 3 | * scobind.c: Deduce the scopes of identifiers. | |||
| 4 | * | |||
| 5 | * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org). | |||
| 6 | * | |||
| 7 | *****************************************************************************/ | |||
| 8 | ||||
| 9 | #include "abpretty.h" | |||
| 10 | #include "abuse.h" | |||
| 11 | #include "comsg.h" | |||
| 12 | #include "debug.h" | |||
| 13 | #include "doc.h" | |||
| 14 | #include "fint.h" | |||
| 15 | #include "format.h" | |||
| 16 | #include "lib.h" | |||
| 17 | #include "spesym.h" | |||
| 18 | #include "stab.h" | |||
| 19 | #include "store.h" | |||
| 20 | #include "strops.h" | |||
| 21 | #include "symcoinfo.h" | |||
| 22 | #include "table.h" | |||
| 23 | #include "tfcond.h" | |||
| 24 | #include "tposs.h" | |||
| 25 | #include "tqual.h" | |||
| 26 | #include "util.h" | |||
| 27 | ||||
| 28 | ||||
| 29 | #include "genstyle.h" | |||
| 30 | ||||
| 31 | Bool scoDebug = false((int) 0); | |||
| 32 | Bool scoStabDebug = false((int) 0); | |||
| 33 | Bool scoFluidDebug = false((int) 0); | |||
| 34 | Bool scoUndoDebug = false((int) 0); | |||
| 35 | ||||
| 36 | #define scoDEBUGif (!scoDebug) { } else afprintf DEBUG_IF(sco)if (!scoDebug) { } else afprintf | |||
| 37 | #define scoStabDEBUGif (!scoStabDebug) { } else afprintf DEBUG_IF(scoStab)if (!scoStabDebug) { } else afprintf | |||
| 38 | #define scoFluidDEBUGif (!scoFluidDebug) { } else afprintf DEBUG_IF(scoFluid)if (!scoFluidDebug) { } else afprintf | |||
| 39 | #define scoUndoDEBUGif (!scoUndoDebug) { } else afprintf DEBUG_IF(scoUndo)if (!scoUndoDebug) { } else afprintf | |||
| 40 | ||||
| 41 | /****************************************************************************** | |||
| 42 | * | |||
| 43 | * :: Identifier contexts | |||
| 44 | * | |||
| 45 | *****************************************************************************/ | |||
| 46 | ||||
| 47 | enum idContext { | |||
| 48 | SCO_Id_START, | |||
| 49 | SCO_Id_InType = SCO_Id_START, | |||
| 50 | SCO_Id_Label, | |||
| 51 | SCO_Id_Used, | |||
| 52 | SCO_Id_LIMIT | |||
| 53 | }; | |||
| 54 | ||||
| 55 | typedef Enum(idContext)enum idContext IdContext; | |||
| 56 | ||||
| 57 | static char *IdContextNames[] = { | |||
| 58 | "InType", | |||
| 59 | "Label", | |||
| 60 | "Used" | |||
| 61 | }; | |||
| 62 | ||||
| 63 | /****************************************************************************** | |||
| 64 | * | |||
| 65 | * :: Declaration contexts | |||
| 66 | * | |||
| 67 | *****************************************************************************/ | |||
| 68 | ||||
| 69 | enum declContext { | |||
| 70 | SCO_Sig_START, | |||
| 71 | SCO_Sig_Assign = SCO_Sig_START, | |||
| 72 | SCO_Sig_Builtin, | |||
| 73 | SCO_Sig_Declare, | |||
| 74 | SCO_Sig_Default, | |||
| 75 | SCO_Sig_Define, | |||
| 76 | SCO_Sig_DDefine, | |||
| 77 | SCO_Sig_Export, | |||
| 78 | SCO_Sig_Extend, | |||
| 79 | SCO_Sig_Fluid, | |||
| 80 | SCO_Sig_Foreign, | |||
| 81 | SCO_Sig_Free, | |||
| 82 | SCO_Sig_FreeRef, | |||
| 83 | SCO_Sig_ImplicitLocal, | |||
| 84 | SCO_Sig_Import, | |||
| 85 | SCO_Sig_Inline, | |||
| 86 | SCO_Sig_InType, | |||
| 87 | SCO_Sig_Local, | |||
| 88 | SCO_Sig_Loop, | |||
| 89 | SCO_Sig_Param, | |||
| 90 | SCO_Sig_Used, | |||
| 91 | SCO_Sig_Reference, | |||
| 92 | SCO_Sig_Value, | |||
| 93 | SCO_Sig_LIMIT | |||
| 94 | }; | |||
| 95 | ||||
| 96 | typedef Enum(declContext)enum declContext DeclContext; | |||
| 97 | ||||
| 98 | static char *DeclContextNames[] = { | |||
| 99 | "Assign", | |||
| 100 | "Builtin", | |||
| 101 | "Declare", | |||
| 102 | "Default", | |||
| 103 | "Define", | |||
| 104 | "DDefine", | |||
| 105 | "Export", | |||
| 106 | "Extend", | |||
| 107 | "Fluid", | |||
| 108 | "Foreign", | |||
| 109 | "Free", | |||
| 110 | "FreeReference", | |||
| 111 | "ImplicitLocal", | |||
| 112 | "Import", | |||
| 113 | "Inline", | |||
| 114 | "InType", | |||
| 115 | "Local", | |||
| 116 | "Loop", | |||
| 117 | "Param", | |||
| 118 | "Used", | |||
| 119 | "Referenced", | |||
| 120 | "Value" | |||
| 121 | }; | |||
| 122 | ||||
| 123 | /****************************************************************************** | |||
| 124 | * | |||
| 125 | * :: Declaration information | |||
| 126 | * | |||
| 127 | *****************************************************************************/ | |||
| 128 | ||||
| 129 | typedef AIntList DefnPos; | |||
| 130 | ||||
| 131 | DECLARE_LIST(DefnPos)typedef struct DefnPosListCons { DefnPos first; struct DefnPosListCons *rest; } *DefnPosList; struct DefnPos_listOpsStruct { DefnPosList (*Cons) (DefnPos, DefnPosList); DefnPosList (*Singleton) (DefnPos ); DefnPosList (*List) (int n, ...); DefnPosList (*Listv) (va_list argp); DefnPosList (*ListNull) (DefnPos, ...); Bool (*Equal) (DefnPosList, DefnPosList, Bool (*f) (DefnPos, DefnPos)); DefnPos (*Find) (DefnPosList, DefnPos, Bool(*eq)(DefnPos,DefnPos) , int *); DefnPos (*Match) (DefnPosList, void *, Bool(*match)(DefnPos , void *), int *); DefnPosList (*MatchAll) (DefnPosList, void *, Bool(*match)(DefnPos, void *)); DefnPosList (*FreeCons) ( DefnPosList); void (*Free) (DefnPosList); DefnPosList (*FreeTo ) (DefnPosList, DefnPosList); void (*FreeDeeply) (DefnPosList , void (*f)(DefnPos)); DefnPosList (*FreeDeeplyTo) (DefnPosList , DefnPosList, void (*f) (DefnPos) ); DefnPosList (*FreeIfSat ) (DefnPosList, void (*f)(DefnPos), Bool (*s)(DefnPos)); DefnPos (*Elt) (DefnPosList, Length); DefnPosList (*Drop) (DefnPosList , Length); DefnPosList (*LastCons) (DefnPosList); Length (*_Length ) (DefnPosList); Bool (*IsLength) (DefnPosList, Length); Bool (*IsShorter) (DefnPosList, Length); Bool (*IsLonger) (DefnPosList , Length); DefnPosList (*Copy) (DefnPosList); DefnPosList (*CopyTo ) (DefnPosList, DefnPosList); DefnPosList (*CopyDeeply) (DefnPosList , DefnPos (*)(DefnPos)); DefnPosList (*CopyDeeplyTo) (DefnPosList , DefnPosList, DefnPos (*)(DefnPos)); DefnPosList (*Map) (DefnPos (*f)(DefnPos), DefnPosList); DefnPosList (*NMap) (DefnPos (* f)(DefnPos), DefnPosList); DefnPosList (*Reverse) (DefnPosList ); DefnPosList (*NReverse) (DefnPosList); DefnPosList (*Concat ) (DefnPosList, DefnPosList); DefnPosList (*NConcat) (DefnPosList , DefnPosList); Bool (*Memq) (DefnPosList, DefnPos); Bool (*Member ) (DefnPosList, DefnPos, Bool(*eq)(DefnPos,DefnPos) ); Bool ( *ContainsAllq) (DefnPosList, DefnPosList); Bool (*ContainsAnyq ) (DefnPosList, DefnPosList); Bool (*ContainsAll) (DefnPosList , DefnPosList, Bool (*eq)(DefnPos, DefnPos)); Bool (*ContainsAny ) (DefnPosList, DefnPosList, Bool (*eq)(DefnPos, DefnPos)); int (*Posq) (DefnPosList, DefnPos); int (*Position) (DefnPosList , DefnPos, Bool(*eq)(DefnPos,DefnPos) ); DefnPosList (*NRemove ) (DefnPosList, DefnPos, Bool(*eq)(DefnPos,DefnPos) ); void ( *FillVector) (DefnPos *, DefnPosList); int (*Print) (FILE *, DefnPosList , int (*pr)(FILE *, DefnPos) ); int (*GPrint) (FILE *, DefnPosList , int (*pr)(FILE *, DefnPos), char *l,char *m,char *r); int ( *Format) (OStream, CString, DefnPosList); }; extern struct DefnPos_listOpsStruct const *DefnPos_listPointer; | |||
| 132 | CREATE_LIST(DefnPos)struct DefnPos_listOpsStruct const *DefnPos_listPointer = (struct DefnPos_listOpsStruct const *) &ptrlistOps; | |||
| 133 | ||||
| 134 | typedef struct decl_info { | |||
| 135 | UShort intStepNo; | |||
| 136 | AbSyn id; | |||
| 137 | AbSyn type; | |||
| 138 | DefnPosList defpos; | |||
| 139 | Doc doc; | |||
| 140 | AbSyn uses[SCO_Sig_LIMIT]; | |||
| 141 | } *DeclInfo; | |||
| 142 | ||||
| 143 | DECLARE_LIST(DeclInfo)typedef struct DeclInfoListCons { DeclInfo first; struct DeclInfoListCons *rest; } *DeclInfoList; struct DeclInfo_listOpsStruct { DeclInfoList (*Cons) (DeclInfo, DeclInfoList); DeclInfoList (*Singleton) ( DeclInfo); DeclInfoList (*List) (int n, ...); DeclInfoList (* Listv) (va_list argp); DeclInfoList (*ListNull) (DeclInfo, ... ); Bool (*Equal) (DeclInfoList, DeclInfoList, Bool (*f) (DeclInfo , DeclInfo)); DeclInfo (*Find) (DeclInfoList, DeclInfo, Bool( *eq)(DeclInfo,DeclInfo) , int *); DeclInfo (*Match) (DeclInfoList , void *, Bool(*match)(DeclInfo, void *), int *); DeclInfoList (*MatchAll) (DeclInfoList, void *, Bool(*match)(DeclInfo, void *)); DeclInfoList (*FreeCons) (DeclInfoList); void (*Free) ( DeclInfoList); DeclInfoList (*FreeTo) (DeclInfoList, DeclInfoList ); void (*FreeDeeply) (DeclInfoList, void (*f)(DeclInfo)); DeclInfoList (*FreeDeeplyTo) (DeclInfoList, DeclInfoList, void (*f) (DeclInfo ) ); DeclInfoList (*FreeIfSat) (DeclInfoList, void (*f)(DeclInfo ), Bool (*s)(DeclInfo)); DeclInfo (*Elt) (DeclInfoList, Length ); DeclInfoList (*Drop) (DeclInfoList, Length); DeclInfoList ( *LastCons) (DeclInfoList); Length (*_Length) (DeclInfoList); Bool (*IsLength) (DeclInfoList, Length); Bool (*IsShorter) (DeclInfoList , Length); Bool (*IsLonger) (DeclInfoList, Length); DeclInfoList (*Copy) (DeclInfoList); DeclInfoList (*CopyTo) (DeclInfoList , DeclInfoList); DeclInfoList (*CopyDeeply) (DeclInfoList, DeclInfo (*)(DeclInfo)); DeclInfoList (*CopyDeeplyTo) (DeclInfoList, DeclInfoList , DeclInfo (*)(DeclInfo)); DeclInfoList (*Map) (DeclInfo (*f) (DeclInfo), DeclInfoList); DeclInfoList (*NMap) (DeclInfo (*f )(DeclInfo), DeclInfoList); DeclInfoList (*Reverse) (DeclInfoList ); DeclInfoList (*NReverse) (DeclInfoList); DeclInfoList (*Concat ) (DeclInfoList, DeclInfoList); DeclInfoList (*NConcat) (DeclInfoList , DeclInfoList); Bool (*Memq) (DeclInfoList, DeclInfo); Bool ( *Member) (DeclInfoList, DeclInfo, Bool(*eq)(DeclInfo,DeclInfo ) ); Bool (*ContainsAllq) (DeclInfoList, DeclInfoList); Bool ( *ContainsAnyq) (DeclInfoList, DeclInfoList); Bool (*ContainsAll ) (DeclInfoList, DeclInfoList, Bool (*eq)(DeclInfo, DeclInfo) ); Bool (*ContainsAny) (DeclInfoList, DeclInfoList, Bool (*eq )(DeclInfo, DeclInfo)); int (*Posq) (DeclInfoList, DeclInfo); int (*Position) (DeclInfoList, DeclInfo, Bool(*eq)(DeclInfo, DeclInfo) ); DeclInfoList (*NRemove) (DeclInfoList, DeclInfo, Bool(*eq)(DeclInfo,DeclInfo) ); void (*FillVector) (DeclInfo *, DeclInfoList); int (*Print) (FILE *, DeclInfoList, int (* pr)(FILE *, DeclInfo) ); int (*GPrint) (FILE *, DeclInfoList, int (*pr)(FILE *, DeclInfo), char *l,char *m,char *r); int ( *Format) (OStream, CString, DeclInfoList); }; extern struct DeclInfo_listOpsStruct const *DeclInfo_listPointer; | |||
| 144 | CREATE_LIST(DeclInfo)struct DeclInfo_listOpsStruct const *DeclInfo_listPointer = ( struct DeclInfo_listOpsStruct const *) &ptrlistOps; | |||
| 145 | ||||
| 146 | /* A condition. We keep the stab information so its depth can be compared | |||
| 147 | * to the tform depth in tfFloat | |||
| 148 | */ | |||
| 149 | ||||
| 150 | typedef struct ScoCondition { | |||
| 151 | Stab stab; | |||
| 152 | AbSyn absyn; | |||
| 153 | Bool negate; | |||
| 154 | } *ScoCondition; | |||
| 155 | ||||
| 156 | DECLARE_LIST(ScoCondition)typedef struct ScoConditionListCons { ScoCondition first; struct ScoConditionListCons *rest; } *ScoConditionList; struct ScoCondition_listOpsStruct { ScoConditionList (*Cons) (ScoCondition, ScoConditionList); ScoConditionList (*Singleton) (ScoCondition); ScoConditionList (*List) (int n, ...); ScoConditionList (*Listv) (va_list argp ); ScoConditionList (*ListNull) (ScoCondition, ...); Bool (*Equal ) (ScoConditionList, ScoConditionList, Bool (*f) (ScoCondition , ScoCondition)); ScoCondition (*Find) (ScoConditionList, ScoCondition , Bool(*eq)(ScoCondition,ScoCondition) , int *); ScoCondition (*Match) (ScoConditionList, void *, Bool(*match)(ScoCondition , void *), int *); ScoConditionList (*MatchAll) (ScoConditionList , void *, Bool(*match)(ScoCondition, void *)); ScoConditionList (*FreeCons) (ScoConditionList); void (*Free) (ScoConditionList ); ScoConditionList (*FreeTo) (ScoConditionList, ScoConditionList ); void (*FreeDeeply) (ScoConditionList, void (*f)(ScoCondition )); ScoConditionList (*FreeDeeplyTo) (ScoConditionList, ScoConditionList , void (*f) (ScoCondition) ); ScoConditionList (*FreeIfSat) ( ScoConditionList, void (*f)(ScoCondition), Bool (*s)(ScoCondition )); ScoCondition (*Elt) (ScoConditionList, Length); ScoConditionList (*Drop) (ScoConditionList, Length); ScoConditionList (*LastCons ) (ScoConditionList); Length (*_Length) (ScoConditionList); Bool (*IsLength) (ScoConditionList, Length); Bool (*IsShorter) (ScoConditionList , Length); Bool (*IsLonger) (ScoConditionList, Length); ScoConditionList (*Copy) (ScoConditionList); ScoConditionList (*CopyTo) (ScoConditionList , ScoConditionList); ScoConditionList (*CopyDeeply) (ScoConditionList , ScoCondition (*)(ScoCondition)); ScoConditionList (*CopyDeeplyTo ) (ScoConditionList, ScoConditionList, ScoCondition (*)(ScoCondition )); ScoConditionList (*Map) (ScoCondition (*f)(ScoCondition), ScoConditionList); ScoConditionList (*NMap) (ScoCondition (* f)(ScoCondition), ScoConditionList); ScoConditionList (*Reverse ) (ScoConditionList); ScoConditionList (*NReverse) (ScoConditionList ); ScoConditionList (*Concat) (ScoConditionList, ScoConditionList ); ScoConditionList (*NConcat) (ScoConditionList, ScoConditionList ); Bool (*Memq) (ScoConditionList, ScoCondition); Bool (*Member ) (ScoConditionList, ScoCondition, Bool(*eq)(ScoCondition,ScoCondition ) ); Bool (*ContainsAllq) (ScoConditionList, ScoConditionList ); Bool (*ContainsAnyq) (ScoConditionList, ScoConditionList); Bool (*ContainsAll) (ScoConditionList, ScoConditionList, Bool (*eq)(ScoCondition, ScoCondition)); Bool (*ContainsAny) (ScoConditionList , ScoConditionList, Bool (*eq)(ScoCondition, ScoCondition)); int (*Posq) (ScoConditionList, ScoCondition); int (*Position) (ScoConditionList , ScoCondition, Bool(*eq)(ScoCondition,ScoCondition) ); ScoConditionList (*NRemove) (ScoConditionList, ScoCondition, Bool(*eq)(ScoCondition ,ScoCondition) ); void (*FillVector) (ScoCondition *, ScoConditionList ); int (*Print) (FILE *, ScoConditionList, int (*pr)(FILE *, ScoCondition ) ); int (*GPrint) (FILE *, ScoConditionList, int (*pr)(FILE * , ScoCondition), char *l,char *m,char *r); int (*Format) (OStream , CString, ScoConditionList); }; extern struct ScoCondition_listOpsStruct const *ScoCondition_listPointer; | |||
| 157 | CREATE_LIST(ScoCondition)struct ScoCondition_listOpsStruct const *ScoCondition_listPointer = (struct ScoCondition_listOpsStruct const *) &ptrlistOps; | |||
| 158 | ||||
| 159 | /****************************************************************************** | |||
| 160 | * | |||
| 161 | * :: Identifier information | |||
| 162 | * | |||
| 163 | *****************************************************************************/ | |||
| 164 | ||||
| 165 | typedef struct id_info { | |||
| 166 | BPack(Bool)UByte allFree; | |||
| 167 | BPack(Bool)UByte allLocal; | |||
| 168 | BPack(Bool)UByte allFluid; | |||
| 169 | ULong serialNo; | |||
| 170 | UShort intStepNo; | |||
| 171 | Symbol sym; | |||
| 172 | AbSyn uses[SCO_Id_LIMIT]; | |||
| 173 | DeclInfoList declInfoList; | |||
| 174 | AbSyn defaultType; | |||
| 175 | AbSyn exampleId; | |||
| 176 | AbSynList usePreDef; | |||
| 177 | } *IdInfo; | |||
| 178 | ||||
| 179 | DECLARE_LIST(IdInfo)typedef struct IdInfoListCons { IdInfo first; struct IdInfoListCons *rest; } *IdInfoList; struct IdInfo_listOpsStruct { IdInfoList (*Cons) (IdInfo, IdInfoList); IdInfoList (*Singleton) (IdInfo ); IdInfoList (*List) (int n, ...); IdInfoList (*Listv) (va_list argp); IdInfoList (*ListNull) (IdInfo, ...); Bool (*Equal) ( IdInfoList, IdInfoList, Bool (*f) (IdInfo, IdInfo)); IdInfo ( *Find) (IdInfoList, IdInfo, Bool(*eq)(IdInfo,IdInfo) , int *) ; IdInfo (*Match) (IdInfoList, void *, Bool(*match)(IdInfo, void *), int *); IdInfoList (*MatchAll) (IdInfoList, void *, Bool (*match)(IdInfo, void *)); IdInfoList (*FreeCons) (IdInfoList ); void (*Free) (IdInfoList); IdInfoList (*FreeTo) (IdInfoList , IdInfoList); void (*FreeDeeply) (IdInfoList, void (*f)(IdInfo )); IdInfoList (*FreeDeeplyTo) (IdInfoList, IdInfoList, void ( *f) (IdInfo) ); IdInfoList (*FreeIfSat) (IdInfoList, void (*f )(IdInfo), Bool (*s)(IdInfo)); IdInfo (*Elt) (IdInfoList, Length ); IdInfoList (*Drop) (IdInfoList, Length); IdInfoList (*LastCons ) (IdInfoList); Length (*_Length) (IdInfoList); Bool (*IsLength ) (IdInfoList, Length); Bool (*IsShorter) (IdInfoList, Length ); Bool (*IsLonger) (IdInfoList, Length); IdInfoList (*Copy) ( IdInfoList); IdInfoList (*CopyTo) (IdInfoList, IdInfoList); IdInfoList (*CopyDeeply) (IdInfoList, IdInfo (*)(IdInfo)); IdInfoList ( *CopyDeeplyTo) (IdInfoList, IdInfoList, IdInfo (*)(IdInfo)); IdInfoList (*Map) (IdInfo (*f)(IdInfo), IdInfoList); IdInfoList (*NMap) (IdInfo (*f)(IdInfo), IdInfoList); IdInfoList (*Reverse) (IdInfoList ); IdInfoList (*NReverse) (IdInfoList); IdInfoList (*Concat) ( IdInfoList, IdInfoList); IdInfoList (*NConcat) (IdInfoList, IdInfoList ); Bool (*Memq) (IdInfoList, IdInfo); Bool (*Member) (IdInfoList , IdInfo, Bool(*eq)(IdInfo,IdInfo) ); Bool (*ContainsAllq) (IdInfoList , IdInfoList); Bool (*ContainsAnyq) (IdInfoList, IdInfoList); Bool (*ContainsAll) (IdInfoList, IdInfoList, Bool (*eq)(IdInfo , IdInfo)); Bool (*ContainsAny) (IdInfoList, IdInfoList, Bool (*eq)(IdInfo, IdInfo)); int (*Posq) (IdInfoList, IdInfo); int (*Position) (IdInfoList, IdInfo, Bool(*eq)(IdInfo,IdInfo) ); IdInfoList (*NRemove) (IdInfoList, IdInfo, Bool(*eq)(IdInfo, IdInfo) ); void (*FillVector) (IdInfo *, IdInfoList); int (*Print ) (FILE *, IdInfoList, int (*pr)(FILE *, IdInfo) ); int (*GPrint ) (FILE *, IdInfoList, int (*pr)(FILE *, IdInfo), char *l,char *m,char *r); int (*Format) (OStream, CString, IdInfoList); } ; extern struct IdInfo_listOpsStruct const *IdInfo_listPointer; | |||
| 180 | CREATE_LIST(IdInfo)struct IdInfo_listOpsStruct const *IdInfo_listPointer = (struct IdInfo_listOpsStruct const *) &ptrlistOps; | |||
| 181 | ||||
| 182 | typedef struct lambda_info { | |||
| 183 | AbSyn lhs; | |||
| 184 | AbSyn rhs; | |||
| 185 | ScoConditionList scoCondList; | |||
| 186 | } *LambdaInfo; | |||
| 187 | ||||
| 188 | DECLARE_LIST(LambdaInfo)typedef struct LambdaInfoListCons { LambdaInfo first; struct LambdaInfoListCons *rest; } *LambdaInfoList; struct LambdaInfo_listOpsStruct { LambdaInfoList (*Cons) (LambdaInfo, LambdaInfoList); LambdaInfoList (*Singleton ) (LambdaInfo); LambdaInfoList (*List) (int n, ...); LambdaInfoList (*Listv) (va_list argp); LambdaInfoList (*ListNull) (LambdaInfo , ...); Bool (*Equal) (LambdaInfoList, LambdaInfoList, Bool ( *f) (LambdaInfo, LambdaInfo)); LambdaInfo (*Find) (LambdaInfoList , LambdaInfo, Bool(*eq)(LambdaInfo,LambdaInfo) , int *); LambdaInfo (*Match) (LambdaInfoList, void *, Bool(*match)(LambdaInfo, void *), int *); LambdaInfoList (*MatchAll) (LambdaInfoList, void *, Bool(*match)(LambdaInfo, void *)); LambdaInfoList (*FreeCons ) (LambdaInfoList); void (*Free) (LambdaInfoList); LambdaInfoList (*FreeTo) (LambdaInfoList, LambdaInfoList); void (*FreeDeeply ) (LambdaInfoList, void (*f)(LambdaInfo)); LambdaInfoList (*FreeDeeplyTo ) (LambdaInfoList, LambdaInfoList, void (*f) (LambdaInfo) ); LambdaInfoList (*FreeIfSat) (LambdaInfoList, void (*f)(LambdaInfo), Bool (* s)(LambdaInfo)); LambdaInfo (*Elt) (LambdaInfoList, Length); LambdaInfoList (*Drop) (LambdaInfoList, Length); LambdaInfoList (*LastCons) (LambdaInfoList); Length (*_Length) (LambdaInfoList); Bool ( *IsLength) (LambdaInfoList, Length); Bool (*IsShorter) (LambdaInfoList , Length); Bool (*IsLonger) (LambdaInfoList, Length); LambdaInfoList (*Copy) (LambdaInfoList); LambdaInfoList (*CopyTo) (LambdaInfoList , LambdaInfoList); LambdaInfoList (*CopyDeeply) (LambdaInfoList , LambdaInfo (*)(LambdaInfo)); LambdaInfoList (*CopyDeeplyTo) (LambdaInfoList, LambdaInfoList, LambdaInfo (*)(LambdaInfo)) ; LambdaInfoList (*Map) (LambdaInfo (*f)(LambdaInfo), LambdaInfoList ); LambdaInfoList (*NMap) (LambdaInfo (*f)(LambdaInfo), LambdaInfoList ); LambdaInfoList (*Reverse) (LambdaInfoList); LambdaInfoList (*NReverse) (LambdaInfoList); LambdaInfoList (*Concat) (LambdaInfoList , LambdaInfoList); LambdaInfoList (*NConcat) (LambdaInfoList, LambdaInfoList); Bool (*Memq) (LambdaInfoList, LambdaInfo); Bool (*Member) (LambdaInfoList, LambdaInfo, Bool(*eq)(LambdaInfo, LambdaInfo) ); Bool (*ContainsAllq) (LambdaInfoList, LambdaInfoList ); Bool (*ContainsAnyq) (LambdaInfoList, LambdaInfoList); Bool (*ContainsAll) (LambdaInfoList, LambdaInfoList, Bool (*eq)(LambdaInfo , LambdaInfo)); Bool (*ContainsAny) (LambdaInfoList, LambdaInfoList , Bool (*eq)(LambdaInfo, LambdaInfo)); int (*Posq) (LambdaInfoList , LambdaInfo); int (*Position) (LambdaInfoList, LambdaInfo, Bool (*eq)(LambdaInfo,LambdaInfo) ); LambdaInfoList (*NRemove) (LambdaInfoList , LambdaInfo, Bool(*eq)(LambdaInfo,LambdaInfo) ); void (*FillVector ) (LambdaInfo *, LambdaInfoList); int (*Print) (FILE *, LambdaInfoList , int (*pr)(FILE *, LambdaInfo) ); int (*GPrint) (FILE *, LambdaInfoList , int (*pr)(FILE *, LambdaInfo), char *l,char *m,char *r); int (*Format) (OStream, CString, LambdaInfoList); }; extern struct LambdaInfo_listOpsStruct const *LambdaInfo_listPointer; | |||
| 189 | CREATE_LIST(LambdaInfo)struct LambdaInfo_listOpsStruct const *LambdaInfo_listPointer = (struct LambdaInfo_listOpsStruct const *) &ptrlistOps; | |||
| 190 | ||||
| 191 | localstatic LambdaInfo lambdaInfoAlloc(AbSyn lhs, AbSyn rhs, ScoConditionList condition); | |||
| 192 | localstatic void lambdaInfoFree(LambdaInfo info); | |||
| 193 | ||||
| 194 | /****************************************************************************** | |||
| 195 | * | |||
| 196 | * :: Conditional Definitions | |||
| 197 | * | |||
| 198 | *****************************************************************************/ | |||
| 199 | ||||
| 200 | localstatic DefnPos defposTail (DefnPos pos); | |||
| 201 | localstatic Bool defposEqual (DefnPos a, DefnPos b); | |||
| 202 | localstatic Bool defposIsRoot (DefnPos pos); | |||
| 203 | localstatic void defposFree (DefnPos pos); | |||
| 204 | localstatic AbSynList defposToAbSyn(AIntList defnPos); | |||
| 205 | /* (ToDo: Rename above functions to defnposXXX) */ | |||
| 206 | ||||
| 207 | /****************************************************************************** | |||
| 208 | * | |||
| 209 | * :: Static variables | |||
| 210 | * | |||
| 211 | *****************************************************************************/ | |||
| 212 | ||||
| 213 | static Stab scoStab; | |||
| 214 | static Bool scoIsInType; | |||
| 215 | static Bool scoIsInAdd; | |||
| 216 | static Bool scoIsInExport; | |||
| 217 | static Bool scoIsInExtend; | |||
| 218 | static Bool scoIsInImport; | |||
| 219 | static AbSynList scoDefineList; | |||
| 220 | static LambdaInfoList scoLambdaList; | |||
| 221 | static IdInfoList scoIdInfoList; | |||
| 222 | static Bool scoUndoState; | |||
| 223 | static SymeList scoUndoSymes; | |||
| 224 | static TFormList scoUndoTForms; | |||
| 225 | static ScoConditionList scoCondList; | |||
| 226 | static int scoDefCounter; | |||
| 227 | ||||
| 228 | /****************************************************************************** | |||
| 229 | * | |||
| 230 | * :: Local operations | |||
| 231 | * | |||
| 232 | *****************************************************************************/ | |||
| 233 | ||||
| 234 | typedef void (*ScoBindFun) (AbSyn); | |||
| 235 | ||||
| 236 | localstatic void scobindValue (AbSyn); | |||
| 237 | localstatic void scobindContext (AbSyn); | |||
| 238 | localstatic void scobindType (AbSyn); | |||
| 239 | localstatic void scobindLevel (AbSyn, ScoBindFun, ULong); | |||
| 240 | ||||
| 241 | localstatic void scobindLambdaList (void); | |||
| 242 | localstatic void scobindPushDefine (AbSyn); | |||
| 243 | localstatic void scobindPopDefine (AbSyn); | |||
| 244 | localstatic void scobindSetStab (AbSyn, ULong); | |||
| 245 | localstatic void scobindStabHash (AbSyn, Stab); | |||
| 246 | ||||
| 247 | localstatic void scobindApply (AbSyn); | |||
| 248 | localstatic void scobindAssign (AbSyn); | |||
| 249 | localstatic void scobindBuiltin (AbSyn); | |||
| 250 | localstatic void scobindDeclare (AbSyn); | |||
| 251 | localstatic void scobindDefault (AbSyn); | |||
| 252 | localstatic void scobindDefine (AbSyn); | |||
| 253 | localstatic void scobindDDefine (AbSyn); | |||
| 254 | localstatic void scobindExport (AbSyn); | |||
| 255 | localstatic void scobindExtend (AbSyn); | |||
| 256 | localstatic void scobindFluid (AbSyn); | |||
| 257 | localstatic void scobindFor (AbSyn); | |||
| 258 | localstatic void scobindForeignImport (AbSyn); | |||
| 259 | localstatic void scobindForeignExport (AbSyn); | |||
| 260 | localstatic void scobindFree (AbSyn); | |||
| 261 | localstatic void scobindImport (AbSyn); | |||
| 262 | localstatic void scobindInline (AbSyn); | |||
| 263 | localstatic void scobindLocal (AbSyn); | |||
| 264 | localstatic void scobindReference (AbSyn); | |||
| 265 | localstatic void scobindParam (AbSyn); | |||
| 266 | localstatic void scobindTry (AbSyn); | |||
| 267 | localstatic void scobindIf (AbSyn); | |||
| 268 | localstatic void scobindAnd (AbSyn); | |||
| 269 | ||||
| 270 | localstatic void scobindApplySelf (AbSyn); | |||
| 271 | localstatic Bool scobindApplyNeedsSelf (AbSyn); | |||
| 272 | localstatic Bool scobindApplyNeedsScope (AbSyn); | |||
| 273 | localstatic Bool scobindApplyArgNeedsScope(AbSyn); | |||
| 274 | localstatic void scobindApplyScope (AbSyn); | |||
| 275 | localstatic void scobindApplyParam (AbSyn); | |||
| 276 | localstatic void scobindApplyComma (AbSyn); | |||
| 277 | localstatic void scobindApplyArg (AbSyn); | |||
| 278 | localstatic void scobindAssignDeclare (AbSyn); | |||
| 279 | localstatic void scobindAssignId (AbSyn, AbSyn); | |||
| 280 | localstatic void scobindBuiltinDeclare (AbSyn); | |||
| 281 | localstatic void scobindBuiltinId (AbSyn, AbSyn); | |||
| 282 | localstatic void scobindDefaultDeclare (AbSyn); | |||
| 283 | localstatic void scobindDefaultId (AbSyn, AbSyn); | |||
| 284 | localstatic void scobindDefineDeclare (AbSyn, AbSyn); | |||
| 285 | localstatic void scobindDefineId (AbSyn, AbSyn, AbSyn); | |||
| 286 | localstatic void scobindDefineRhs (AbSyn, AbSyn, DeclContext); | |||
| 287 | localstatic void scobindDDefineComma (AbSyn); | |||
| 288 | localstatic void scobindDDefineDeclare (AbSyn, AbSyn); | |||
| 289 | localstatic void scobindDDefineId (AbSyn, AbSyn, AbSyn); | |||
| 290 | localstatic void scobindExportTo (AbSyn, AbSyn); | |||
| 291 | localstatic void scobindExportFrom (AbSyn, AbSyn); | |||
| 292 | localstatic void scobindExportWhat (AbSyn); | |||
| 293 | localstatic void scobindExportDeclare (AbSyn, AbSyn); | |||
| 294 | localstatic void scobindExportId (AbSyn, AbSyn, AbSyn); | |||
| 295 | localstatic void scobindExtendDeclare (AbSyn, AbSyn); | |||
| 296 | localstatic void scobindExtendId (AbSyn, AbSyn, AbSyn); | |||
| 297 | localstatic Syme scobindGetExtend (AbSyn, AbSyn); | |||
| 298 | localstatic void scobindFluidComma (AbSyn); | |||
| 299 | localstatic void scobindFluidDeclare (AbSyn); | |||
| 300 | localstatic void scobindFluidId (AbSyn, AbSyn); | |||
| 301 | localstatic void scobindFor0 (AbSyn, Bool); | |||
| 302 | localstatic void scobindForDeclare (AbSyn, AbSyn); | |||
| 303 | localstatic void scobindForId (AbSyn, AbSyn); | |||
| 304 | localstatic void scobindForeignDeclare (AbSyn, ForeignOrigin); | |||
| 305 | localstatic void scobindForeignId (AbSyn, AbSyn, ForeignOrigin); | |||
| 306 | localstatic void scobindParamDefine (AbSyn, AbSyn); | |||
| 307 | localstatic void scobindParamDeclare (AbSyn, AbSyn); | |||
| 308 | localstatic void scobindParamId (AbSyn, AbSyn, AbSyn); | |||
| 309 | localstatic Bool scoIsNewCollect (AbSyn ab); | |||
| 310 | ||||
| 311 | localstatic TForm scobindTfSyntaxFrAbSyn(Stab stab, AbSyn ab); | |||
| 312 | ||||
| 313 | /* | |||
| 314 | * scobindDeclare | |||
| 315 | */ | |||
| 316 | localstatic DeclInfo scobindDeclareId (AbSyn, AbSyn, AbSyn, DeclContext); | |||
| 317 | localstatic TForm scobindDeclareTForm (Stab, AbSyn, AbSyn, AbSyn, DeclContext); | |||
| 318 | localstatic void scobindUniqifyDecl (AbSyn, AbSyn); | |||
| 319 | localstatic void scobindIntroduceId (AbSyn, AbSyn, DeclContext); | |||
| 320 | localstatic AbSyn scobindGuessType (AbSyn); | |||
| 321 | ||||
| 322 | /* | |||
| 323 | * scobindFree | |||
| 324 | * scobindLocal | |||
| 325 | */ | |||
| 326 | localstatic void scobindLOF (AbSyn, DeclContext); | |||
| 327 | localstatic void scobindLOFComma (AbSyn, AbSyn, DeclContext); | |||
| 328 | localstatic void scobindLOFDeclare (AbSyn, AbSyn, DeclContext); | |||
| 329 | localstatic void scobindLOFId (AbSyn, DeclContext); | |||
| 330 | localstatic void scobindLOFType (AbSyn, AbSyn, AbSyn, | |||
| 331 | DeclContext); | |||
| 332 | localstatic void scobindLOFDeclInfo (AbSyn, IdInfo, DeclInfo, | |||
| 333 | DeclContext); | |||
| 334 | ||||
| 335 | /* | |||
| 336 | * Properties of different lexical levels. | |||
| 337 | */ | |||
| 338 | #define scobindApplyFlags0 0 | |||
| 339 | #define scobindLambdaFlags0 0 | |||
| 340 | #define scobindAddFlags(1<<1) STAB_LEVEL_LARGE(1<<1) | |||
| 341 | #define scobindWithFlags(1<<1) STAB_LEVEL_LARGE(1<<1) | |||
| 342 | #define scobindWhereFlags(1<<3) STAB_LEVEL_WHERE(1<<3) | |||
| 343 | #define scobindRepeatFlags(1<<2) STAB_LEVEL_LOOP(1<<2) | |||
| 344 | #define scobindCollectFlags(1<<5) STAB_LEVEL_COLLECT(1<<5) | |||
| 345 | #define scobindGenerateFlags(1<<2) STAB_LEVEL_LOOP(1<<2) | |||
| 346 | #define scobindXGenerateFlags(1<<4) STAB_LEVEL_XGENERATE(1<<4) | |||
| 347 | ||||
| 348 | /* | |||
| 349 | * scobindIf (and conditions) | |||
| 350 | * | |||
| 351 | * FIXME: This really needs some cleanup | |||
| 352 | */ | |||
| 353 | localstatic void scobindIf (AbSyn); | |||
| 354 | localstatic void scoCondPush (Stab, AbSyn, Bool); | |||
| 355 | localstatic void scoCondPop (void); | |||
| 356 | localstatic ScoConditionList scoConditions (void); | |||
| 357 | localstatic DefnPos scoConditionToDefnPos(ScoConditionList); | |||
| 358 | localstatic TfCondElt scoCondListCondElt(); | |||
| 359 | ||||
| 360 | /* | |||
| 361 | * IdInfo | |||
| 362 | */ | |||
| 363 | localstatic IdInfo idInfoNew (Stab, AbSyn); | |||
| 364 | localstatic void idInfoFree (IdInfo); | |||
| 365 | localstatic Bool idInfoIsNew (IdInfo); | |||
| 366 | localstatic void scobindFreeIdInfo (Stab); | |||
| 367 | localstatic IdInfoList scobindSaveIdInfo (Stab); | |||
| 368 | localstatic void scobindRestoreIdInfo (Stab, IdInfoList, Bool); | |||
| 369 | localstatic IdInfo getIdInfoInAnyScope (Stab, AbSyn); | |||
| 370 | localstatic IdInfo getIdInfoInThisScope (Stab, Symbol); | |||
| 371 | localstatic void scobindSetIdUse (IdInfo, IdContext, AbSyn); | |||
| 372 | localstatic AbSyn scobindDefaultType (Stab, Symbol); | |||
| 373 | ||||
| 374 | #define idInfoCell(x)((IdInfoList) (symCoInfo(x)->phaseVal.generic)) \ | |||
| 375 | ((IdInfoList) (symCoInfo(x)->phaseVal.generic)) | |||
| 376 | ||||
| 377 | #define setIdInfoCell(x,y)(symCoInfo(x)->phaseVal.generic = (Pointer) (y)) \ | |||
| 378 | (symCoInfo(x)->phaseVal.generic = (Pointer) (y)) | |||
| 379 | ||||
| 380 | /* | |||
| 381 | * DeclInfo | |||
| 382 | */ | |||
| 383 | localstatic DeclInfo declInfoNew (AbSyn, AbSyn, DefnPos); | |||
| 384 | localstatic void declInfoFree (DeclInfo); | |||
| 385 | localstatic Bool declInfoIsNew (DeclInfo); | |||
| 386 | localstatic Bool declInfoUseIsNew (AbSyn); | |||
| 387 | localstatic Bool declInfoIsImplicitLocal (DeclInfo); | |||
| 388 | localstatic void scobindRestoreDeclInfo (IdInfo); | |||
| 389 | localstatic DeclInfo idInfoHasType (IdInfo, AbSyn); | |||
| 390 | localstatic DeclInfo idInfoAddType (IdInfo, AbSyn, AbSyn, AbSyn, ScoConditionList); | |||
| 391 | localstatic void scobindSetSigUse (DeclInfo, DeclContext, AbSyn); | |||
| 392 | localstatic Bool scobindCheckCondition (DeclInfo, ScoConditionList); | |||
| 393 | localstatic Bool scobindCheckDefnPos (DeclInfo, DefnPos); | |||
| 394 | ||||
| 395 | /* | |||
| 396 | * scobindAddMeaning | |||
| 397 | */ | |||
| 398 | localstatic void scobindAddMeaning (AbSyn, Symbol, Stab, | |||
| 399 | SymeTag, TForm, AInt); | |||
| 400 | localstatic Bool scobindNeedsMeaning (AbSyn, TForm); | |||
| 401 | localstatic void scobindSetMeaning (AbSyn, Syme); | |||
| 402 | localstatic Syme scobindDefMeaning (Stab, SymeTag, Symbol, | |||
| 403 | TForm, AInt); | |||
| 404 | /* | |||
| 405 | * scobindReconcile | |||
| 406 | */ | |||
| 407 | localstatic void scobindReconcile (Stab,AbSynTag); | |||
| 408 | localstatic void scobindReconcileId (Stab,AbSynTag,Symbol,IdInfo); | |||
| 409 | localstatic void scobindReconcileDecls (Stab,AbSynTag,Symbol,IdInfo); | |||
| 410 | localstatic void scobindReconcileDecl (Stab,AbSynTag,Symbol,IdInfo, | |||
| 411 | DeclInfo); | |||
| 412 | ||||
| 413 | /* | |||
| 414 | * scobindPrint | |||
| 415 | */ | |||
| 416 | extern void scobindPrint (Stab); | |||
| 417 | localstatic void scobindPrintStab (Stab); | |||
| 418 | localstatic void scobindPrintId (Symbol); | |||
| 419 | localstatic void scobindPrintIdInfo (IdInfo); | |||
| 420 | localstatic void scobindPrintDeclInfo (Length, DeclInfo); | |||
| 421 | ||||
| 422 | /* | |||
| 423 | * scobindUndo | |||
| 424 | */ | |||
| 425 | localstatic void scobindRestore (void); | |||
| 426 | localstatic void scobindSave (void); | |||
| 427 | localstatic void scobindUndo (void); | |||
| 428 | localstatic void scoUndoStab (Stab); | |||
| 429 | localstatic void scoUndoStabLevel (StabLevel); | |||
| 430 | localstatic Bool scoUndoStabEntry (StabEntry); | |||
| 431 | localstatic void scoUndoSyme (Syme); | |||
| 432 | localstatic void scoUndoTForm (TForm); | |||
| 433 | localstatic void scoUndoTFormUses (TFormUses); | |||
| 434 | localstatic Bool isNewSyme (Syme); | |||
| 435 | localstatic Bool isNewTForm (TForm); | |||
| 436 | localstatic Bool isNewTFormUses (TFormUses); | |||
| 437 | ||||
| 438 | ||||
| 439 | /*!! This needs to be cleaned up. */ | |||
| 440 | localstatic void markOuterInstanceOfFree (AbSyn, AbSyn, DeclContext); | |||
| 441 | ||||
| 442 | localstatic void checkOuterUseOfImplicitLocal (Stab, AbSyn, AbSyn); | |||
| 443 | localstatic void checkOuterUseOfLexicalConstant (Stab, AbSyn); | |||
| 444 | localstatic Bool scobindCheckOuterUseOfFluid (AbSyn, AbSyn); | |||
| 445 | ||||
| 446 | localstatic void scobindUsedType (Stab, AbSyn); | |||
| 447 | localstatic void scobindImportType (Stab, AbSyn); | |||
| 448 | ||||
| 449 | localstatic void scobindMatchWiths (AbSyn, AbSyn, DeclContext); | |||
| 450 | localstatic Bool scobindMatchParams (AbSyn, AbSyn); | |||
| 451 | localstatic Bool scobindMatchParam (AbSyn, AbSyn); | |||
| 452 | ||||
| 453 | localstatic void scobindAdd (AbSyn); | |||
| 454 | localstatic void scobindCollect (AbSyn); | |||
| 455 | localstatic void scobindHas (AbSyn); | |||
| 456 | localstatic void scobindId (AbSyn, IdContext); | |||
| 457 | localstatic void scobindLabel (AbSyn); | |||
| 458 | localstatic void scobindGenerate (AbSyn); | |||
| 459 | localstatic void scobindXGenerate (AbSyn); | |||
| 460 | localstatic void scobindLambda (AbSyn); | |||
| 461 | localstatic void scobindRepeat (AbSyn); | |||
| 462 | localstatic void scobindWhere (AbSyn); | |||
| 463 | localstatic void scobindWith (AbSyn); | |||
| 464 | ||||
| 465 | localstatic Bool scobindTFormMustBeUnique (AbSyn ab); | |||
| 466 | ||||
| 467 | #define abSetTFormCond(a,t)if (! ((a)->abHdr.seman ? (a)->abHdr.seman->tform : 0 )) abSetTForm((a), (t)) if (! abTForm(a)((a)->abHdr.seman ? (a)->abHdr.seman->tform : 0)) abSetTForm((a), (t)) | |||
| 468 | ||||
| 469 | #if 1 | |||
| 470 | #define scobindRetNeedsDefn(ab)((((ab)->abHdr.tag == (AB_Id)) && ((ab)->abId.sym )==(ssymCategory)) || ((ab)->abHdr.tag == (AB_With))) \ | |||
| 471 | (abIsTheId(ab, ssymCategory)(((ab)->abHdr.tag == (AB_Id)) && ((ab)->abId.sym )==(ssymCategory)) || abHasTag(ab, AB_With)((ab)->abHdr.tag == (AB_With))) | |||
| 472 | ||||
| 473 | #define scobindMapNeedsDefn(ab)((((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ab)-> abHdr.argc)-1) == 2) || ((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply.op))->abId.sym)==(ssymPackedArrow))) && (((ab)->abHdr.argc)-1) == 2)) && ((((((ab)->abApply .argv[1]))->abHdr.tag == (AB_Id)) && ((((ab)->abApply .argv[1]))->abId.sym)==(ssymCategory)) || ((((ab)->abApply .argv[1]))->abHdr.tag == (AB_With)))) \ | |||
| 474 | (abIsAnyMap(ab)(((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ab)-> abHdr.argc)-1) == 2) || ((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply.op))->abId.sym)==(ssymPackedArrow))) && (((ab)->abHdr.argc)-1) == 2)) && scobindRetNeedsDefn(abMapRet(ab))((((((ab)->abApply.argv[1]))->abHdr.tag == (AB_Id)) && ((((ab)->abApply.argv[1]))->abId.sym)==(ssymCategory)) || ((((ab)->abApply.argv[1]))->abHdr.tag == (AB_With)) )) | |||
| 475 | #else | |||
| 476 | localstatic Bool | |||
| 477 | scobindRetNeedsDefn(AbSyn ab)((((AbSyn ab)->abHdr.tag == (AB_Id)) && ((AbSyn ab )->abId.sym)==(ssymCategory)) || ((AbSyn ab)->abHdr.tag == (AB_With))) | |||
| 478 | { | |||
| 479 | if (abIsTheId(ab, ssymCategory)(((ab)->abHdr.tag == (AB_Id)) && ((ab)->abId.sym )==(ssymCategory)) || abHasTag(ab, AB_With)((ab)->abHdr.tag == (AB_With))) | |||
| 480 | return true1; | |||
| 481 | ||||
| 482 | return false((int) 0); | |||
| 483 | } | |||
| 484 | ||||
| 485 | localstatic Bool | |||
| 486 | scobindMapNeedsDefn(AbSyn ab)((((((AbSyn ab)->abHdr.tag == (AB_Apply)) && ((((( AbSyn ab)->abApply.op))->abHdr.tag == (AB_Id)) && ((((AbSyn ab)->abApply.op))->abId.sym)==(ssymArrow))) && (((AbSyn ab)->abHdr.argc)-1) == 2) || ((((AbSyn ab)->abHdr .tag == (AB_Apply)) && (((((AbSyn ab)->abApply.op) )->abHdr.tag == (AB_Id)) && ((((AbSyn ab)->abApply .op))->abId.sym)==(ssymPackedArrow))) && (((AbSyn ab )->abHdr.argc)-1) == 2)) && ((((((AbSyn ab)->abApply .argv[1]))->abHdr.tag == (AB_Id)) && ((((AbSyn ab) ->abApply.argv[1]))->abId.sym)==(ssymCategory)) || (((( AbSyn ab)->abApply.argv[1]))->abHdr.tag == (AB_With)))) | |||
| 487 | { | |||
| 488 | AbSyn ret; | |||
| 489 | if (!abIsAnyMap(ab)(((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ab)-> abHdr.argc)-1) == 2) || ((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply.op))->abId.sym)==(ssymPackedArrow))) && (((ab)->abHdr.argc)-1) == 2))) | |||
| 490 | return false((int) 0); | |||
| 491 | ret = abMapRet(ab)((ab)->abApply.argv[1]); | |||
| 492 | ||||
| 493 | if (abIsAnyMap(ret)(((((ret)->abHdr.tag == (AB_Apply)) && (((((ret)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ret)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ret)-> abHdr.argc)-1) == 2) || ((((ret)->abHdr.tag == (AB_Apply)) && (((((ret)->abApply.op))->abHdr.tag == (AB_Id )) && ((((ret)->abApply.op))->abId.sym)==(ssymPackedArrow ))) && (((ret)->abHdr.argc)-1) == 2))) | |||
| 494 | return scobindMapNeedsDefn(ret)((((((ret)->abHdr.tag == (AB_Apply)) && (((((ret)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ret)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ret)-> abHdr.argc)-1) == 2) || ((((ret)->abHdr.tag == (AB_Apply)) && (((((ret)->abApply.op))->abHdr.tag == (AB_Id )) && ((((ret)->abApply.op))->abId.sym)==(ssymPackedArrow ))) && (((ret)->abHdr.argc)-1) == 2)) && ( (((((ret)->abApply.argv[1]))->abHdr.tag == (AB_Id)) && ((((ret)->abApply.argv[1]))->abId.sym)==(ssymCategory) ) || ((((ret)->abApply.argv[1]))->abHdr.tag == (AB_With )))); | |||
| 495 | ||||
| 496 | return scobindRetNeedsDefn(ret)((((ret)->abHdr.tag == (AB_Id)) && ((ret)->abId .sym)==(ssymCategory)) || ((ret)->abHdr.tag == (AB_With))); | |||
| 497 | ||||
| 498 | } | |||
| 499 | ||||
| 500 | #endif | |||
| 501 | localstatic Bool | |||
| 502 | scobindTFormMustBeUnique(AbSyn ab) | |||
| 503 | { | |||
| 504 | if (abIsAnyMap(ab)(((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)-> abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)-> abApply.op))->abId.sym)==(ssymArrow))) && (((ab)-> abHdr.argc)-1) == 2) || ((((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply.op))->abId.sym)==(ssymPackedArrow))) && (((ab)->abHdr.argc)-1) == 2))) | |||
| 505 | return scobindTFormMustBeUnique(abMapRet(ab)((ab)->abApply.argv[1])); | |||
| 506 | ||||
| 507 | return abIsTheId(ab,ssymCategory)(((ab)->abHdr.tag == (AB_Id)) && ((ab)->abId.sym )==(ssymCategory)); | |||
| 508 | } | |||
| 509 | ||||
| 510 | ||||
| 511 | /****************************************************************************** | |||
| 512 | * | |||
| 513 | * :: scopeBind Top-level external entry points. | |||
| 514 | * | |||
| 515 | *****************************************************************************/ | |||
| 516 | ||||
| 517 | void | |||
| 518 | scobindInitFile(void) | |||
| 519 | { | |||
| 520 | scoIdInfoList = listNil(IdInfo)((IdInfoList) 0); | |||
| 521 | scoUndoState = false((int) 0); | |||
| 522 | scoDefCounter = 1; | |||
| 523 | } | |||
| 524 | ||||
| 525 | void | |||
| 526 | scobindFiniFile(void) | |||
| 527 | { | |||
| 528 | listFreeDeeply(IdInfo)(IdInfo_listPointer->FreeDeeply)(scoIdInfoList, idInfoFree); | |||
| 529 | scoIdInfoList = listNil(IdInfo)((IdInfoList) 0); | |||
| 530 | scoUndoState = false((int) 0); | |||
| 531 | } | |||
| 532 | ||||
| 533 | int | |||
| 534 | scobindMaxDef() | |||
| 535 | { | |||
| 536 | return scoDefCounter; | |||
| 537 | } | |||
| 538 | ||||
| 539 | void | |||
| 540 | scoSetUndoState(void) | |||
| 541 | { | |||
| 542 | scoUndoState = true1; | |||
| 543 | } | |||
| 544 | ||||
| 545 | void | |||
| 546 | scopeBind(Stab stab, AbSyn absyn) | |||
| 547 | { | |||
| 548 | scoStab = stab; | |||
| 549 | scoIsInType = false((int) 0); | |||
| 550 | scoIsInAdd = false((int) 0); | |||
| 551 | scoIsInExtend = false((int) 0); | |||
| 552 | scoIsInExport = false((int) 0); | |||
| 553 | scoIsInImport = false((int) 0); | |||
| 554 | scoDefineList = listNil(AbSyn)((AbSynList) 0); | |||
| 555 | scoLambdaList = listNil(LambdaInfo)((LambdaInfoList) 0); | |||
| 556 | ||||
| 557 | if (DEBUG(sco)scoDebug) { | |||
| 558 | fprintf(dbOut, "Top-level Scope Begin"); | |||
| 559 | findent += 2; | |||
| 560 | fnewline(dbOut); | |||
| 561 | } | |||
| 562 | ||||
| 563 | scobindRestore(); | |||
| 564 | ||||
| 565 | scobindValue(absyn); | |||
| 566 | scobindLambdaList(); | |||
| 567 | scobindReconcile(scoStab, AB_Add); | |||
| 568 | ||||
| 569 | scobindSave(); | |||
| 570 | ||||
| 571 | if (DEBUG(sco)scoDebug) { | |||
| 572 | findent -= 2; | |||
| 573 | fnewline(dbOut); | |||
| 574 | scobindPrint(scoStab); | |||
| 575 | if (DEBUG(scoStab)scoStabDebug) { | |||
| 576 | stabPrint(dbOut, scoStab); | |||
| 577 | } | |||
| 578 | fnewline(dbOut); | |||
| 579 | fprintf(dbOut, "Top-level Scope End\n\n"); | |||
| 580 | fnewline(dbOut); | |||
| 581 | } | |||
| 582 | } | |||
| 583 | ||||
| 584 | localstatic void | |||
| 585 | scobindRestore() | |||
| 586 | { | |||
| 587 | if (scoIdInfoList) { | |||
| 588 | scobindRestoreIdInfo(scoStab, scoIdInfoList, scoUndoState); | |||
| 589 | scoIdInfoList = listNil(IdInfo)((IdInfoList) 0); | |||
| 590 | ||||
| 591 | if (scoUndoState) scobindUndo(); | |||
| 592 | } | |||
| 593 | } | |||
| 594 | ||||
| 595 | localstatic void | |||
| 596 | scobindSave() | |||
| 597 | { | |||
| 598 | if (fintMode == FINT_LOOP2) | |||
| 599 | scoIdInfoList = scobindSaveIdInfo(scoStab); | |||
| 600 | else | |||
| 601 | scobindFreeIdInfo(scoStab); | |||
| 602 | } | |||
| 603 | ||||
| 604 | /****************************************************************************** | |||
| 605 | * | |||
| 606 | * :: scobindValue Top-level recursive entry point. | |||
| 607 | * | |||
| 608 | *****************************************************************************/ | |||
| 609 | ||||
| 610 | localstatic void | |||
| 611 | scobindValue(AbSyn absyn) | |||
| 612 | { | |||
| 613 | Bool isCoroutine; | |||
| 614 | ||||
| 615 | switch (abTag(absyn)((absyn)->abHdr.tag)) { | |||
| 616 | case AB_Nothing: | |||
| 617 | break; | |||
| 618 | ||||
| 619 | case AB_Assign: | |||
| 620 | case AB_Builtin: | |||
| 621 | case AB_Declare: | |||
| 622 | case AB_Default: | |||
| 623 | case AB_Define: | |||
| 624 | case AB_DDefine: | |||
| 625 | case AB_Export: | |||
| 626 | case AB_Extend: | |||
| 627 | case AB_Fluid: | |||
| 628 | case AB_For: | |||
| 629 | case AB_ForeignImport: | |||
| 630 | case AB_ForeignExport: | |||
| 631 | case AB_Free: | |||
| 632 | case AB_Import: | |||
| 633 | case AB_Inline: | |||
| 634 | case AB_Local: | |||
| 635 | scobindContext(absyn); | |||
| 636 | break; | |||
| 637 | ||||
| 638 | case AB_Add: | |||
| 639 | scobindLevel(absyn, scobindAdd, scobindAddFlags(1<<1)); | |||
| 640 | break; | |||
| 641 | ||||
| 642 | case AB_Apply: | |||
| 643 | scobindApply(absyn); | |||
| 644 | break; | |||
| 645 | ||||
| 646 | case AB_CoerceTo: | |||
| 647 | scobindValue(absyn->abCoerceTo.expr); | |||
| 648 | scobindUsedType(scoStab, absyn->abCoerceTo.type); | |||
| 649 | break; | |||
| 650 | ||||
| 651 | case AB_Collect: | |||
| 652 | if (gfGenTypeDefault() == GENTYPE_Coroutine || scoIsNewCollect(absyn)) { | |||
| 653 | scobindLevel(absyn, scobindCollect, scobindXGenerateFlags(1<<4)); | |||
| 654 | } | |||
| 655 | else { | |||
| 656 | scobindLevel(absyn, scobindCollect, scobindCollectFlags(1<<5)); | |||
| 657 | } | |||
| 658 | break; | |||
| 659 | ||||
| 660 | case AB_Generate: | |||
| 661 | isCoroutine = gfGenTypeGenerator(absyn) == GENTYPE_Coroutine; | |||
| 662 | if (isCoroutine) { | |||
| 663 | scobindLevel(absyn, scobindXGenerate, scobindXGenerateFlags(1<<4)); | |||
| 664 | } | |||
| 665 | else { | |||
| 666 | scobindLevel(absyn, scobindGenerate, scobindGenerateFlags(1<<2)); | |||
| 667 | } | |||
| 668 | break; | |||
| 669 | ||||
| 670 | case AB_Fix: | |||
| 671 | bugUnimpl("scoBind")bug("Unimplemented %s (line %d in file %s).", "scoBind", 671, "scobind.c"); | |||
| 672 | ||||
| 673 | case AB_Has: | |||
| 674 | scobindHas(absyn); | |||
| 675 | break; | |||
| 676 | ||||
| 677 | case AB_Hide: | |||
| 678 | scobindUsedType(scoStab, absyn->abHide.type); | |||
| 679 | abSetTFormCond(absyn, abTForm(absyn->abHide.type))if (! ((absyn)->abHdr.seman ? (absyn)->abHdr.seman-> tform : 0)) abSetTForm((absyn), (((absyn->abHide.type)-> abHdr.seman ? (absyn->abHide.type)->abHdr.seman->tform : 0))); | |||
| 680 | break; | |||
| 681 | ||||
| 682 | case AB_Id: | |||
| 683 | scobindId(absyn, SCO_Id_Used); | |||
| 684 | break; | |||
| 685 | ||||
| 686 | case AB_Label: | |||
| 687 | scobindLabel(absyn->abLabel.label); | |||
| 688 | scobindValue(absyn->abLabel.expr); | |||
| 689 | break; | |||
| 690 | ||||
| 691 | case AB_Lambda: | |||
| 692 | case AB_PLambda: | |||
| 693 | scobindLevel(absyn, scobindLambda, scobindLambdaFlags0); | |||
| 694 | break; | |||
| 695 | ||||
| 696 | case AB_PretendTo: | |||
| 697 | scobindValue(absyn->abPretendTo.expr); | |||
| 698 | scobindUsedType(scoStab, absyn->abPretendTo.type); | |||
| 699 | break; | |||
| 700 | ||||
| 701 | case AB_Qualify: | |||
| 702 | scobindValue(absyn->abQualify.what); | |||
| 703 | scobindUsedType(scoStab, absyn->abQualify.origin); | |||
| 704 | break; | |||
| 705 | ||||
| 706 | case AB_Reference: | |||
| 707 | scobindReference(absyn->abReference.body); | |||
| 708 | break; | |||
| 709 | ||||
| 710 | case AB_Repeat: | |||
| 711 | scobindLevel(absyn, scobindRepeat, scobindRepeatFlags(1<<2)); | |||
| 712 | break; | |||
| 713 | ||||
| 714 | case AB_RestrictTo: | |||
| 715 | scobindValue(absyn->abRestrictTo.expr); | |||
| 716 | scobindUsedType(scoStab, absyn->abRestrictTo.type); | |||
| 717 | break; | |||
| 718 | case AB_Where: | |||
| 719 | scobindLevel(absyn, scobindWhere, scobindWhereFlags(1<<3)); | |||
| 720 | break; | |||
| 721 | case AB_Try: | |||
| 722 | scobindTry(absyn); | |||
| 723 | break; | |||
| 724 | ||||
| 725 | case AB_With: | |||
| 726 | if (!abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab : 0)) /* check if already done */ | |||
| 727 | scobindLevel(absyn, scobindWith, scobindWithFlags(1<<1)); | |||
| 728 | break; | |||
| 729 | ||||
| 730 | case AB_If: | |||
| 731 | scobindIf(absyn); | |||
| 732 | break; | |||
| 733 | ||||
| 734 | case AB_And: | |||
| 735 | scobindAnd(absyn); | |||
| 736 | break; | |||
| 737 | ||||
| 738 | default: | |||
| 739 | if (!abIsLeaf(absyn)(((absyn)->abHdr.tag) < AB_NODE_START)) { | |||
| 740 | Length i, argc = abArgc(absyn)((absyn)->abHdr.argc); | |||
| 741 | AbSyn *argv = abArgv(absyn)((absyn)->abGen.data.argv); | |||
| 742 | ||||
| 743 | for (i = 0; i < argc; i += 1) | |||
| 744 | scobindValue(argv[i]); | |||
| 745 | } | |||
| 746 | break; | |||
| 747 | } | |||
| 748 | } | |||
| 749 | ||||
| 750 | /****************************************************************************** | |||
| 751 | * | |||
| 752 | * :: scobindContext Dispatch function for signature introducing contexts. | |||
| 753 | * | |||
| 754 | *****************************************************************************/ | |||
| 755 | ||||
| 756 | localstatic void | |||
| 757 | scobindContext(AbSyn absyn) | |||
| 758 | { | |||
| 759 | switch (abTag(absyn)((absyn)->abHdr.tag)) { | |||
| 760 | case AB_Assign: | |||
| 761 | scobindAssign(absyn); | |||
| 762 | break; | |||
| 763 | ||||
| 764 | case AB_Builtin: | |||
| 765 | scobindBuiltin(absyn); | |||
| 766 | break; | |||
| 767 | ||||
| 768 | case AB_Declare: | |||
| 769 | scobindDeclare(absyn); | |||
| 770 | break; | |||
| 771 | ||||
| 772 | case AB_Default: | |||
| 773 | scobindDefault(absyn); | |||
| 774 | break; | |||
| 775 | ||||
| 776 | case AB_Define: | |||
| 777 | scobindDefine(absyn); | |||
| 778 | break; | |||
| 779 | ||||
| 780 | case AB_DDefine: | |||
| 781 | scobindDDefine(absyn); | |||
| 782 | break; | |||
| 783 | ||||
| 784 | case AB_Export: | |||
| 785 | scobindExport(absyn); | |||
| 786 | break; | |||
| 787 | ||||
| 788 | case AB_Extend: | |||
| 789 | scobindExtend(absyn); | |||
| 790 | break; | |||
| 791 | ||||
| 792 | case AB_Fluid: | |||
| 793 | scobindFluid(absyn); | |||
| 794 | break; | |||
| 795 | ||||
| 796 | case AB_For: | |||
| 797 | scobindFor(absyn); | |||
| 798 | break; | |||
| 799 | ||||
| 800 | case AB_ForeignImport: | |||
| 801 | scobindForeignImport(absyn); | |||
| 802 | break; | |||
| 803 | ||||
| 804 | case AB_ForeignExport: | |||
| 805 | scobindForeignExport(absyn); | |||
| 806 | break; | |||
| 807 | ||||
| 808 | case AB_Free: | |||
| 809 | scobindFree(absyn); | |||
| 810 | break; | |||
| 811 | ||||
| 812 | case AB_Import: | |||
| 813 | scobindImport(absyn); | |||
| 814 | break; | |||
| 815 | ||||
| 816 | case AB_Inline: | |||
| 817 | scobindInline(absyn); | |||
| 818 | break; | |||
| 819 | ||||
| 820 | case AB_Local: | |||
| 821 | scobindLocal(absyn); | |||
| 822 | break; | |||
| 823 | ||||
| 824 | default: | |||
| 825 | bugBadCase(abTag(absyn))bug("Bad case %d (line %d in file %s).", (int) ((absyn)->abHdr .tag), 825, "scobind.c"); | |||
| 826 | break; | |||
| 827 | } | |||
| 828 | } | |||
| 829 | ||||
| 830 | /****************************************************************************** | |||
| 831 | * | |||
| 832 | * :: scobindType Top-level entry point for types. | |||
| 833 | * | |||
| 834 | *****************************************************************************/ | |||
| 835 | ||||
| 836 | localstatic void | |||
| 837 | scobindType(AbSyn type) | |||
| 838 | { | |||
| 839 | Bool save = scoIsInType; | |||
| 840 | ||||
| 841 | scoIsInType = true1; | |||
| 842 | scobindValue(type); | |||
| 843 | scoIsInType = save; | |||
| 844 | } | |||
| 845 | ||||
| 846 | /****************************************************************************** | |||
| 847 | * | |||
| 848 | * :: scobindLevel Apply 'fun' within a new scope level. | |||
| 849 | * | |||
| 850 | *****************************************************************************/ | |||
| 851 | ||||
| 852 | localstatic void | |||
| 853 | scobindLevel(AbSyn absyn, ScoBindFun fun, ULong flags) | |||
| 854 | { | |||
| 855 | LambdaInfoList savedLambdaList; | |||
| 856 | Bool saveInType = scoIsInType; | |||
| 857 | ||||
| 858 | ||||
| 859 | assert(absyn)do { if (!(absyn)) _do_assert(("absyn"),"scobind.c",859); } while (0); | |||
| 860 | ||||
| 861 | if (abIsNothing(absyn)((absyn)->abHdr.tag == (AB_Nothing))) | |||
| 862 | return; | |||
| 863 | ||||
| 864 | savedLambdaList = scoLambdaList; | |||
| 865 | ||||
| 866 | scoLambdaList = listNil(LambdaInfo)((LambdaInfoList) 0); | |||
| 867 | ||||
| 868 | /* | |||
| 869 | * If we start a new scope level then we are no longer in a | |||
| 870 | * type. This fixes bugs such as bug 988 where we used to give | |||
| 871 | * spurious errors about variables being used in constants. | |||
| 872 | * However, this hides some instances where a variable is used | |||
| 873 | * in a type. The simplest example of this is as follows: given | |||
| 874 | * a domain constructor Foo(X:SingleInteger), | |||
| 875 | * | |||
| 876 | * local myVar:SingleInteger := 42; | |||
| 877 | * import from Foo(X == myVar); | |||
| 878 | * | |||
| 879 | * We compute the type Foo(X) before giving X the value of myVar. | |||
| 880 | * This is probably one area where variables can be used in a | |||
| 881 | * type because the definition nails the value into a constant. | |||
| 882 | */ | |||
| 883 | scoIsInType = false((int) 0); | |||
| 884 | ||||
| 885 | scobindSetStab(absyn, flags); | |||
| 886 | scoStab = abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab : 0); | |||
| 887 | ||||
| 888 | if (DEBUG(sco)scoDebug) { | |||
| 889 | fprintf(dbOut, "%s Scope Begin (# %lu) (lambda: %ld lex: %ld)", | |||
| 890 | abInfo(abTag(absyn))abInfoTable[(((absyn)->abHdr.tag)) - AB_START].str, car(scoStab)((scoStab)->first)->serialNo, | |||
| 891 | car(scoStab)((scoStab)->first)->lambdaLevel, car(scoStab)((scoStab)->first)->lexicalLevel); | |||
| 892 | findent += 2; | |||
| 893 | fnewline(dbOut); | |||
| 894 | } | |||
| 895 | ||||
| 896 | fun(absyn); | |||
| 897 | scobindLambdaList(); | |||
| 898 | scobindReconcile(scoStab, abTag(absyn)((absyn)->abHdr.tag)); | |||
| 899 | ||||
| 900 | if (DEBUG(sco)scoDebug) { | |||
| 901 | scobindPrint(scoStab); | |||
| 902 | if (DEBUG(scoStab)scoStabDebug) { | |||
| 903 | stabPrintTo(dbOut, scoStab, -1); | |||
| 904 | } | |||
| 905 | findent -= 2; | |||
| 906 | fnewline(dbOut); | |||
| 907 | fprintf(dbOut, "%s Scope End (# %lu)", | |||
| 908 | abInfo(abTag(absyn))abInfoTable[(((absyn)->abHdr.tag)) - AB_START].str, car(scoStab)((scoStab)->first)->serialNo); | |||
| 909 | fnewline(dbOut); | |||
| 910 | } | |||
| 911 | ||||
| 912 | scobindFreeIdInfo(scoStab); | |||
| 913 | ||||
| 914 | scoStab = stabPopLevel(scoStab); | |||
| 915 | scoLambdaList = savedLambdaList; | |||
| 916 | scoIsInType = saveInType; | |||
| 917 | } | |||
| 918 | ||||
| 919 | localstatic void | |||
| 920 | scobindLambdaList(void) | |||
| 921 | { | |||
| 922 | ScoConditionList savedScoCondList = scoCondList; | |||
| 923 | ||||
| 924 | scoLambdaList = listNReverse(LambdaInfo)(LambdaInfo_listPointer->NReverse)(scoLambdaList); | |||
| 925 | while (scoLambdaList) { | |||
| 926 | LambdaInfo info = car(scoLambdaList)((scoLambdaList)->first); | |||
| 927 | AbSyn lhs = info->lhs; | |||
| 928 | AbSyn rhs = info->rhs; | |||
| 929 | ||||
| 930 | scoCondList = info->scoCondList; | |||
| 931 | scobindPushDefine(lhs); | |||
| 932 | scobindLevel(rhs, scobindLambda, scobindLambdaFlags0); | |||
| 933 | scobindPopDefine(lhs); | |||
| 934 | ||||
| 935 | lambdaInfoFree(info); | |||
| 936 | scoLambdaList = listFreeCons(LambdaInfo)(LambdaInfo_listPointer->FreeCons)(scoLambdaList); | |||
| 937 | } | |||
| 938 | ||||
| 939 | scoCondList = savedScoCondList; | |||
| 940 | } | |||
| 941 | ||||
| 942 | localstatic void | |||
| 943 | scobindPushDefine(AbSyn lhs) | |||
| 944 | { | |||
| 945 | if (!abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma))) | |||
| 946 | listPush(AbSyn, abDefineeId(lhs), scoDefineList)(scoDefineList = (AbSyn_listPointer->Cons)(abDefineeId(lhs ), scoDefineList)); | |||
| 947 | } | |||
| 948 | ||||
| 949 | localstatic void | |||
| 950 | scobindPopDefine(AbSyn lhs) | |||
| 951 | { | |||
| 952 | if (!abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma))) | |||
| 953 | scoDefineList = listFreeCons(AbSyn)(AbSyn_listPointer->FreeCons)(scoDefineList); | |||
| 954 | } | |||
| 955 | ||||
| 956 | localstatic void | |||
| 957 | scobindSetStab(AbSyn absyn, ULong flags) | |||
| 958 | { | |||
| 959 | Stab stab = stabPushLevel(scoStab, abPos(absyn)(spstackFirst((absyn)->abHdr.pos)), flags); | |||
| 960 | scobindStabHash(absyn, stab); | |||
| 961 | abSetStab(absyn, stab); | |||
| 962 | } | |||
| 963 | ||||
| 964 | localstatic Bool | |||
| 965 | scobindStabHashIsUsed(Stab stab, Hash h) | |||
| 966 | { | |||
| 967 | StabList l; | |||
| 968 | ||||
| 969 | if (car(stab)((stab)->first)->hash == h) | |||
| 970 | return true1; | |||
| 971 | ||||
| 972 | for (l = car(stab)((stab)->first)->children; l; l = cdr(l)((l)->rest)) | |||
| 973 | if (scobindStabHashIsUsed(car(l)((l)->first), h)) | |||
| 974 | return true1; | |||
| 975 | ||||
| 976 | return false((int) 0); | |||
| 977 | } | |||
| 978 | ||||
| 979 | localstatic void | |||
| 980 | scobindStabHash(AbSyn absyn, Stab stab0) | |||
| 981 | { | |||
| 982 | Hash h = abHashList(listCons(AbSyn)(AbSyn_listPointer->Cons)(absyn, scoDefineList)); | |||
| 983 | ||||
| 984 | if (h && !scobindStabHashIsUsed(stabFile(), h)) | |||
| 985 | car(stab0)((stab0)->first)->hash = h; | |||
| 986 | } | |||
| 987 | ||||
| 988 | /* | |||
| 989 | * scopeBind functions called through scobindLevel | |||
| 990 | */ | |||
| 991 | ||||
| 992 | localstatic void | |||
| 993 | scobindAdd(AbSyn absyn) | |||
| 994 | { | |||
| 995 | AbSyn base = absyn->abAdd.base; | |||
| 996 | AbSyn capsule = absyn->abAdd.capsule; | |||
| 997 | Bool save = scoIsInAdd; | |||
| 998 | ||||
| 999 | scoIsInAdd = true1; | |||
| 1000 | scobindValue(base); | |||
| 1001 | scobindValue(capsule); | |||
| 1002 | scoIsInAdd = save; | |||
| 1003 | ||||
| 1004 | stabDefLexVar(scoStab, ssymSelf, tfType); | |||
| 1005 | } | |||
| 1006 | ||||
| 1007 | localstatic void | |||
| 1008 | scobindLambda(AbSyn absyn) | |||
| 1009 | { | |||
| 1010 | TForm tf; | |||
| 1011 | AbSyn ret = absyn->abLambda.rtype; | |||
| 1012 | Bool save = scoIsInAdd; | |||
| 1013 | ||||
| 1014 | scobindParam(absyn->abLambda.param); | |||
| 1015 | if (ret && abIsNotNothing(ret)!((ret)->abHdr.tag == (AB_Nothing))) { | |||
| 1016 | AbSyn *retv = abArgvAs(AB_Comma, ret)(((ret)->abHdr.tag == (AB_Comma)) ? ((ret)->abGen.data. argv) : &(ret)); | |||
| 1017 | Length i, retc = abArgcAs(AB_Comma, ret)(((ret)->abHdr.tag == (AB_Comma)) ? ((ret)->abHdr.argc) : 1); | |||
| 1018 | ||||
| 1019 | scobindType(ret); | |||
| 1020 | ||||
| 1021 | /* Save the rhs on the return type if needed. */ | |||
| 1022 | if (scobindRetNeedsDefn(ret)((((ret)->abHdr.tag == (AB_Id)) && ((ret)->abId .sym)==(ssymCategory)) || ((ret)->abHdr.tag == (AB_With)))) | |||
| 1023 | tf = tfSyntaxDefine(scoStab,ret,absyn->abLambda.body); | |||
| 1024 | ||||
| 1025 | /* Import from each of the return types. */ | |||
| 1026 | for (i = 0; i < retc; i += 1) { | |||
| 1027 | AbSyn reti = retv[i]; | |||
| 1028 | ||||
| 1029 | tf = abTForm(ret)((ret)->abHdr.seman ? (ret)->abHdr.seman->tform : 0); | |||
| 1030 | if (tf == NULL((void*)0)) { | |||
| 1031 | tf = scobindTfSyntaxFrAbSyn(scoStab, reti); | |||
| 1032 | abSetTForm(reti, tf); | |||
| 1033 | } | |||
| 1034 | if (!abHasTag(reti, AB_Hide)((reti)->abHdr.tag == (AB_Hide))) | |||
| 1035 | stabImportTForm(scoStab, tf); | |||
| 1036 | } | |||
| 1037 | ||||
| 1038 | /* Make sure product types have a type form. */ | |||
| 1039 | if (abTForm(ret)((ret)->abHdr.seman ? (ret)->abHdr.seman->tform : 0) == NULL((void*)0)) | |||
| 1040 | abSetTForm(ret, scobindTfSyntaxFrAbSyn(scoStab, ret)); | |||
| 1041 | } | |||
| 1042 | #if RTYPE | |||
| 1043 | else | |||
| 1044 | comsgError(absyn, ALDOR_E_ChkMissingRetType95); | |||
| 1045 | #endif | |||
| 1046 | scoIsInAdd = false((int) 0); | |||
| 1047 | scobindValue(absyn->abLambda.body); | |||
| 1048 | scoIsInAdd = save; | |||
| 1049 | } | |||
| 1050 | ||||
| 1051 | localstatic void | |||
| 1052 | scobindCollect(AbSyn absyn) | |||
| 1053 | { | |||
| 1054 | int i, itc = abCollectIterc(absyn)(((absyn)->abHdr.argc)-1); | |||
| 1055 | ||||
| 1056 | for (i = 0; i < itc; i++) | |||
| 1057 | scobindValue(absyn->abCollect.iterv[i]); | |||
| 1058 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); | |||
| 1059 | scobindValue(absyn->abCollect.body); | |||
| 1060 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 1061 | } | |||
| 1062 | ||||
| 1063 | localstatic void | |||
| 1064 | scobindGenerate(AbSyn absyn) | |||
| 1065 | { | |||
| 1066 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); | |||
| 1067 | scobindValue(absyn->abGenerate.count); | |||
| 1068 | scobindValue(absyn->abGenerate.body); | |||
| 1069 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 1070 | } | |||
| 1071 | ||||
| 1072 | localstatic void | |||
| 1073 | scobindXGenerate(AbSyn absyn) | |||
| 1074 | { | |||
| 1075 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); | |||
| 1076 | scobindValue(absyn->abGenerate.count); | |||
| 1077 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 1078 | scobindValue(absyn->abGenerate.body); | |||
| 1079 | } | |||
| 1080 | ||||
| 1081 | ||||
| 1082 | localstatic void | |||
| 1083 | scobindRepeat(AbSyn absyn) | |||
| 1084 | { | |||
| 1085 | int i, itc = abRepeatIterc(absyn)(((absyn)->abHdr.argc)-1); | |||
| 1086 | ||||
| 1087 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); | |||
| 1088 | for (i = 0; i < itc; i++) | |||
| 1089 | scobindValue(absyn->abRepeat.iterv[i]); | |||
| 1090 | scobindValue(absyn->abRepeat.body); | |||
| 1091 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 1092 | } | |||
| 1093 | ||||
| 1094 | localstatic void | |||
| 1095 | scobindWhere(AbSyn absyn) | |||
| 1096 | { | |||
| 1097 | scobindValue(absyn->abWhere.context); | |||
| 1098 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); /* 'for' does unlock locally */ | |||
| 1099 | scobindValue(absyn->abWhere.expr); | |||
| 1100 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 1101 | } | |||
| 1102 | ||||
| 1103 | localstatic void | |||
| 1104 | scobindWith(AbSyn absyn) | |||
| 1105 | { | |||
| 1106 | AbSyn base = absyn->abWith.base; | |||
| 1107 | AbSyn within = absyn->abWith.within; | |||
| 1108 | TForm tfbase, tf; | |||
| 1109 | Syme syme; | |||
| 1110 | ||||
| 1111 | if (abIsNotNothing(base)!((base)->abHdr.tag == (AB_Nothing))) { | |||
| 1112 | tfbase = scobindTfSyntaxFrAbSyn(scoStab, base); | |||
| 1113 | stabCategoricallyImportTForm(scoStab, tfbase); | |||
| 1114 | } | |||
| 1115 | tf = stabMakeUsedTForm(cdr(scoStab)((scoStab)->rest), absyn, scoCondListCondElt()); | |||
| 1116 | syme = stabDefLexVar(scoStab, ssymSelf, tf); | |||
| 1117 | ||||
| 1118 | scobindValue(base); | |||
| 1119 | scobindExportWhat(within); | |||
| 1120 | } | |||
| 1121 | ||||
| 1122 | localstatic void | |||
| 1123 | scobindHas(AbSyn absyn) | |||
| 1124 | { | |||
| 1125 | AbSyn cat = absyn->abHas.property; | |||
| 1126 | AbSyn dom = absyn->abHas.expr; | |||
| 1127 | TForm tfdom, tfcat; | |||
| 1128 | ||||
| 1129 | scobindValue(cat); | |||
| 1130 | scobindValue(dom); | |||
| 1131 | ||||
| 1132 | tfcat = stabMakeUsedTForm(scoStab, cat, scoCondListCondElt()); | |||
| 1133 | tfdom = stabMakeUsedTForm(scoStab, dom, scoCondListCondElt()); | |||
| 1134 | ||||
| 1135 | stabAddTFormQuery(scoStab, tfdom, tfcat); | |||
| 1136 | } | |||
| 1137 | ||||
| 1138 | localstatic void | |||
| 1139 | scobindId(AbSyn id, IdContext context) | |||
| 1140 | { | |||
| 1141 | if (id) { | |||
| 1142 | IdInfo idInfo; | |||
| 1143 | Bool okayContext; | |||
| 1144 | ||||
| 1145 | assert(abHasTag(id, AB_Id))do { if (!(((id)->abHdr.tag == (AB_Id)))) _do_assert(("abHasTag(id, AB_Id)" ),"scobind.c",1145); } while (0); | |||
| 1146 | ||||
| 1147 | idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 1148 | scobindSetIdUse(idInfo, context, id); | |||
| 1149 | ||||
| 1150 | if (scoIsInType) | |||
| 1151 | scobindSetIdUse(idInfo, SCO_Id_InType, id); | |||
| 1152 | ||||
| 1153 | /* | |||
| 1154 | * Note use-before-definitions. We ought to be doing | |||
| 1155 | * this using data-flow _after_ type inference (so | |||
| 1156 | * that we can ignore lazy values such as domains). | |||
| 1157 | * Until then we have to exclude certain contexts. | |||
| 1158 | */ | |||
| 1159 | okayContext = scoIsInAdd || scoIsInExport || scoIsInImport || | |||
| 1160 | scoIsInExtend; | |||
| 1161 | if (!idInfo->declInfoList && !okayContext) { | |||
| 1162 | AbSynList uses = idInfo->usePreDef; | |||
| 1163 | idInfo->usePreDef = listCons(AbSyn)(AbSyn_listPointer->Cons)(id, uses); | |||
| 1164 | } | |||
| 1165 | } | |||
| 1166 | } | |||
| 1167 | ||||
| 1168 | localstatic void | |||
| 1169 | scobindLabel(AbSyn lab) | |||
| 1170 | { | |||
| 1171 | assert(lab)do { if (!(lab)) _do_assert(("lab"),"scobind.c",1171); } while (0); | |||
| 1172 | ||||
| 1173 | if (abIsNotNothing(lab)!((lab)->abHdr.tag == (AB_Nothing))) { | |||
| 1174 | IdInfo idInfo; | |||
| 1175 | assert(abHasTag(lab, AB_Id))do { if (!(((lab)->abHdr.tag == (AB_Id)))) _do_assert(("abHasTag(lab, AB_Id)" ),"scobind.c",1175); } while (0); | |||
| 1176 | ||||
| 1177 | idInfo = getIdInfoInAnyScope(scoStab, lab); | |||
| 1178 | scobindSetIdUse(idInfo, SCO_Id_Label, lab); | |||
| 1179 | stabAddLabel(scoStab, lab); | |||
| 1180 | } | |||
| 1181 | } | |||
| 1182 | ||||
| 1183 | /****************************************************************************** | |||
| 1184 | * | |||
| 1185 | * :: scobind utility functions. | |||
| 1186 | * | |||
| 1187 | *****************************************************************************/ | |||
| 1188 | ||||
| 1189 | /* | |||
| 1190 | * Try to match up symbol table of 'with' forms in abType with those in | |||
| 1191 | * abLamb. abType has already been analyzed. | |||
| 1192 | * | |||
| 1193 | * Future work: we need to be much better at detecting domains and | |||
| 1194 | * categories. We rely on finding a "with" for the type. This is | |||
| 1195 | * usually okay because abnorm tries hard to ensure that all domain | |||
| 1196 | * definitions get a "with" for their type. It fails when we have | |||
| 1197 | * non-obvious domain definitions such as: | |||
| 1198 | * | |||
| 1199 | * MyInteger:Ring == Integer; | |||
| 1200 | * | |||
| 1201 | * The problem is that we don't recognise Integer as being a domain | |||
| 1202 | * or Ring as being a category until after tinfer. By then it might | |||
| 1203 | * be too late. | |||
| 1204 | */ | |||
| 1205 | localstatic void | |||
| 1206 | scobindMatchWiths(AbSyn abType, AbSyn abLamb, DeclContext context) | |||
| 1207 | { | |||
| 1208 | AbSyn lparam = abLamb->abLambda.param, | |||
| 1209 | lrtype = abLamb->abLambda.rtype; | |||
| 1210 | ||||
| 1211 | if (abIsAnyMap(abType)(((((abType)->abHdr.tag == (AB_Apply)) && (((((abType )->abApply.op))->abHdr.tag == (AB_Id)) && ((((abType )->abApply.op))->abId.sym)==(ssymArrow))) && (( (abType)->abHdr.argc)-1) == 2) || ((((abType)->abHdr.tag == (AB_Apply)) && (((((abType)->abApply.op))-> abHdr.tag == (AB_Id)) && ((((abType)->abApply.op)) ->abId.sym)==(ssymPackedArrow))) && (((abType)-> abHdr.argc)-1) == 2)) && | |||
| 1212 | (context == SCO_Sig_Extend || | |||
| 1213 | context == SCO_Sig_DDefine || | |||
| 1214 | scobindRetNeedsDefn(lrtype)((((lrtype)->abHdr.tag == (AB_Id)) && ((lrtype)-> abId.sym)==(ssymCategory)) || ((lrtype)->abHdr.tag == (AB_With ))))) { | |||
| 1215 | AbSyn aparam = abArgv(abType)((abType)->abGen.data.argv)[1], | |||
| 1216 | artype = abArgv(abType)((abType)->abGen.data.argv)[2]; | |||
| 1217 | ||||
| 1218 | if (!abEqual(lrtype, artype)) | |||
| 1219 | return; | |||
| 1220 | if (abHasTag(aparam, AB_Comma)((aparam)->abHdr.tag == (AB_Comma)) && 1 == abArgc(aparam)((aparam)->abHdr.argc)) | |||
| 1221 | aparam = abArgv(aparam)((aparam)->abGen.data.argv)[0]; | |||
| 1222 | if (abHasTag(lparam, AB_Comma)((lparam)->abHdr.tag == (AB_Comma)) && 1 == abArgc(lparam)((lparam)->abHdr.argc)) | |||
| 1223 | lparam = abArgv(lparam)((lparam)->abGen.data.argv)[0]; | |||
| 1224 | ||||
| 1225 | if (scobindMatchParams(aparam, lparam)) { | |||
| 1226 | abTransferSemantics(aparam, lparam); | |||
| 1227 | abTransferSemantics(artype, lrtype); | |||
| 1228 | } | |||
| 1229 | } | |||
| 1230 | } | |||
| 1231 | ||||
| 1232 | /* | |||
| 1233 | * Do the map parameters from a type declaration match the | |||
| 1234 | * map parameters from the lambda definition? | |||
| 1235 | */ | |||
| 1236 | localstatic Bool | |||
| 1237 | scobindMatchParams(AbSyn aparam, AbSyn lparam) | |||
| 1238 | { | |||
| 1239 | AbSyn *parv = abArgvAs(AB_Comma, lparam)(((lparam)->abHdr.tag == (AB_Comma)) ? ((lparam)->abGen .data.argv) : &(lparam)); | |||
| 1240 | Length parc = abArgcAs(AB_Comma, lparam)(((lparam)->abHdr.tag == (AB_Comma)) ? ((lparam)->abHdr .argc) : 1); | |||
| 1241 | AbSyn *argv = abArgvAs(AB_Comma, aparam)(((aparam)->abHdr.tag == (AB_Comma)) ? ((aparam)->abGen .data.argv) : &(aparam)); | |||
| 1242 | Length i, argc = abArgcAs(AB_Comma, aparam)(((aparam)->abHdr.tag == (AB_Comma)) ? ((aparam)->abHdr .argc) : 1); | |||
| 1243 | ||||
| 1244 | Bool result = (parc == argc); | |||
| 1245 | ||||
| 1246 | for (i = 0; result && i < argc; i += 1) { | |||
| 1247 | AbSyn par = parv[i]; | |||
| 1248 | AbSyn arg = argv[i]; | |||
| 1249 | ||||
| 1250 | result &= scobindMatchParam(arg, par); | |||
| 1251 | } | |||
| 1252 | ||||
| 1253 | return result; | |||
| 1254 | } | |||
| 1255 | ||||
| 1256 | /* | |||
| 1257 | * Does a parameter from a map type declaration match the corresponding | |||
| 1258 | * parameter from the lambda definition? Accepts declaration, definition | |||
| 1259 | * and identifier nodes as arguments. | |||
| 1260 | */ | |||
| 1261 | localstatic Bool | |||
| 1262 | scobindMatchParam(AbSyn arg, AbSyn par) | |||
| 1263 | { | |||
| 1264 | AbSynTag aTag = abTag(arg)((arg)->abHdr.tag); | |||
| 1265 | AbSynTag pTag = abTag(par)((par)->abHdr.tag); | |||
| 1266 | const char *err = "parameter is not an identifier or a declaration"; | |||
| 1267 | ||||
| 1268 | /* Safety check */ | |||
| 1269 | assert(aTag == AB_Define || aTag == AB_Declare || aTag == AB_Id)do { if (!(aTag == AB_Define || aTag == AB_Declare || aTag == AB_Id)) _do_assert(("aTag == AB_Define || aTag == AB_Declare || aTag == AB_Id" ),"scobind.c",1269); } while (0); | |||
| 1270 | assert(pTag == AB_Define || pTag == AB_Declare || pTag == AB_Id)do { if (!(pTag == AB_Define || pTag == AB_Declare || pTag == AB_Id)) _do_assert(("pTag == AB_Define || pTag == AB_Declare || pTag == AB_Id" ),"scobind.c",1270); } while (0); | |||
| 1271 | ||||
| 1272 | /* Extract declarations from default value definitions */ | |||
| 1273 | if (aTag == AB_Define) | |||
| 1274 | return scobindMatchParam(arg->abDefine.lhs, par); | |||
| 1275 | if (pTag == AB_Define) | |||
| 1276 | return scobindMatchParam(arg, par->abDefine.lhs); | |||
| 1277 | ||||
| 1278 | /* | |||
| 1279 | * Argument and parameter are declarations or identifiers. | |||
| 1280 | * If only one is a declaration then ignore that declaration. | |||
| 1281 | * We could simply return abEqual(arg->abDeclare.id, par) or | |||
| 1282 | * abEqual(arg, par->abDeclare.id) but we play safe. | |||
| 1283 | */ | |||
| 1284 | if (aTag != pTag) { | |||
| 1285 | /* Which is the declaration node? */ | |||
| 1286 | if (aTag == AB_Declare) /* && (pTag == AB_Id) */ | |||
| 1287 | return scobindMatchParam(arg->abDeclare.id, par); | |||
| 1288 | if (pTag == AB_Declare) /* && (aTag == AB_Id) */ | |||
| 1289 | return scobindMatchParam(arg, par->abDeclare.id); | |||
| 1290 | ||||
| 1291 | /* Impossible */ | |||
| 1292 | comsgFatal(arg, ALDOR_F_Bug365, err); | |||
| 1293 | NotReached(return false){(void)bug("Not supposed to reach line %d in file: %s\n",1293 , "scobind.c");}; | |||
| 1294 | } | |||
| 1295 | ||||
| 1296 | /* Either two declarations or two identifiers */ | |||
| 1297 | if (aTag == AB_Id) /* && (pTag == AB_Id) */ | |||
| 1298 | return abEqual(arg, par); | |||
| 1299 | ||||
| 1300 | /* Must be two declarations */ | |||
| 1301 | if (aTag != AB_Declare) { | |||
| 1302 | comsgFatal(arg, ALDOR_F_Bug365, err); | |||
| 1303 | NotReached(return false){(void)bug("Not supposed to reach line %d in file: %s\n",1303 , "scobind.c");}; | |||
| 1304 | } | |||
| 1305 | ||||
| 1306 | /* Compare identifiers */ | |||
| 1307 | if (!abEqual(arg->abDeclare.id, par->abDeclare.id)) return false((int) 0); | |||
| 1308 | ||||
| 1309 | /* Identifiers match: check the types */ | |||
| 1310 | arg = arg->abDeclare.type; | |||
| 1311 | par = par->abDeclare.type; | |||
| 1312 | ||||
| 1313 | /* Identifiers match: compare types if possible */ | |||
| 1314 | if (abIsNothing(arg)((arg)->abHdr.tag == (AB_Nothing)) || abIsNothing(par)((par)->abHdr.tag == (AB_Nothing))) return true1; | |||
| 1315 | ||||
| 1316 | /* Types are present: must be equal */ | |||
| 1317 | return abEqual(arg, par); | |||
| 1318 | } | |||
| 1319 | ||||
| 1320 | localstatic void | |||
| 1321 | markOuterInstanceOfFree(AbSyn id, AbSyn type, DeclContext context) | |||
| 1322 | { | |||
| 1323 | Stab stab; | |||
| 1324 | Symbol sym = id->abId.sym; | |||
| 1325 | Bool diffType = false((int) 0); | |||
| 1326 | ||||
| 1327 | assert(type)do { if (!(type)) _do_assert(("type"),"scobind.c",1327); } while (0); | |||
| 1328 | ||||
| 1329 | for (stab = cdr(scoStab)((scoStab)->rest); stab; stab = cdr(stab)((stab)->rest)) { | |||
| 1330 | IdInfo idInfo = getIdInfoInThisScope(stab, sym); | |||
| 1331 | DeclInfo di; | |||
| 1332 | ||||
| 1333 | if (!idInfo) continue; | |||
| 1334 | ||||
| 1335 | if (idInfo->allFree || !idInfo->declInfoList) | |||
| 1336 | continue; | |||
| 1337 | ||||
| 1338 | if (abIsUnknown(type)((type)->abHdr.tag == (AB_Blank))) | |||
| 1339 | di = car(idInfo->declInfoList)((idInfo->declInfoList)->first); | |||
| 1340 | else if ((di = idInfoHasType(idInfo, type)) != NULL((void*)0)) | |||
| 1341 | ; | |||
| 1342 | else if ((di = idInfoHasType(idInfo, abUnknown)) != NULL((void*)0)) | |||
| 1343 | di->type = type; | |||
| 1344 | else | |||
| 1345 | diffType = true1; | |||
| 1346 | ||||
| 1347 | if (!di || di->uses[SCO_Sig_Free]) | |||
| 1348 | continue; | |||
| 1349 | ||||
| 1350 | scobindSetSigUse(di, context, id); | |||
| 1351 | return; | |||
| 1352 | } | |||
| 1353 | ||||
| 1354 | if (diffType) | |||
| 1355 | comsgError(id, ALDOR_E_ScoBadTypeFree116, symString(sym)((sym)->str)); | |||
| 1356 | else | |||
| 1357 | comsgError(id, ALDOR_E_ScoUnknownFree130, symString(sym)((sym)->str)); | |||
| 1358 | } | |||
| 1359 | ||||
| 1360 | localstatic void | |||
| 1361 | scobindImportType(Stab stab, AbSyn type) | |||
| 1362 | { | |||
| 1363 | if (abHasTag(type, AB_Hide)((type)->abHdr.tag == (AB_Hide))) { | |||
| 1364 | scobindUsedType(stab, type->abHide.type); | |||
| 1365 | abSetTFormCond(type, abTForm(type->abHide.type))if (! ((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0)) abSetTForm((type), (((type->abHide.type)->abHdr. seman ? (type->abHide.type)->abHdr.seman->tform : 0) )); | |||
| 1366 | } | |||
| 1367 | else { | |||
| 1368 | scobindType(type); | |||
| 1369 | abSetTFormCond(type,if (! ((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0)) abSetTForm((type), (stabImportTForm(stab, scobindTfSyntaxFrAbSyn (stab, type)))) | |||
| 1370 | stabImportTForm(stab, scobindTfSyntaxFrAbSyn(stab, type)))if (! ((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0)) abSetTForm((type), (stabImportTForm(stab, scobindTfSyntaxFrAbSyn (stab, type)))); | |||
| 1371 | } | |||
| 1372 | } | |||
| 1373 | ||||
| 1374 | localstatic void | |||
| 1375 | scobindUsedType(Stab stab, AbSyn type) | |||
| 1376 | { | |||
| 1377 | scobindType(type); | |||
| 1378 | stabMakeUsedTForm(stab, type, scoCondListCondElt()); | |||
| 1379 | } | |||
| 1380 | ||||
| 1381 | localstatic void | |||
| 1382 | checkOuterUseOfImplicitLocal(Stab stab, AbSyn id, AbSyn type) | |||
| 1383 | { | |||
| 1384 | /* | |||
| 1385 | * id is an implicit local. It is an error if it is local, free or a | |||
| 1386 | * parameter in an outer scope. If type != 0, the types must match | |||
| 1387 | * in an outer scope to generate the message. | |||
| 1388 | */ | |||
| 1389 | ||||
| 1390 | Symbol sym = id->abId.sym; | |||
| 1391 | ||||
| 1392 | for (stab = cdr(stab)((stab)->rest); stab; stab = cdr(stab)((stab)->rest)) { | |||
| 1393 | IdInfo idInfo = getIdInfoInThisScope(stab, sym); | |||
| 1394 | DeclInfoList dil; | |||
| 1395 | ||||
| 1396 | if (! idInfo) | |||
| 1397 | continue; | |||
| 1398 | ||||
| 1399 | for (dil = idInfo->declInfoList; dil; dil = cdr(dil)((dil)->rest)) { | |||
| 1400 | DeclInfo outerDeclInfo = car(dil)((dil)->first); | |||
| 1401 | ||||
| 1402 | if ((abIsUnknown(type)((type)->abHdr.tag == (AB_Blank)) || | |||
| 1403 | abIsUnknown(outerDeclInfo->type)((outerDeclInfo->type)->abHdr.tag == (AB_Blank)) || | |||
| 1404 | abEqualModDeclares(type, outerDeclInfo->type)) && | |||
| 1405 | (outerDeclInfo->uses[SCO_Sig_ImplicitLocal] || | |||
| 1406 | outerDeclInfo->uses[SCO_Sig_Local] || | |||
| 1407 | outerDeclInfo->uses[SCO_Sig_Free] || | |||
| 1408 | outerDeclInfo->uses[SCO_Sig_Param])) | |||
| 1409 | { | |||
| 1410 | comsgWarning(id, ALDOR_W_ScoBadLocal132, | |||
| 1411 | symString(sym)((sym)->str)); | |||
| 1412 | return; | |||
| 1413 | } | |||
| 1414 | } | |||
| 1415 | } | |||
| 1416 | } | |||
| 1417 | ||||
| 1418 | localstatic void | |||
| 1419 | checkOuterUseOfLexicalConstant(Stab stab, AbSyn id) | |||
| 1420 | { | |||
| 1421 | /* | |||
| 1422 | * id is an implicit or explicit lexical constant. It is illegal | |||
| 1423 | * to have a parameter or lexical variable in an outer scope with | |||
| 1424 | * the same name. | |||
| 1425 | */ | |||
| 1426 | ||||
| 1427 | Symbol sym = id->abId.sym; | |||
| 1428 | ||||
| 1429 | for (stab = cdr(stab)((stab)->rest); stab; stab = cdr(stab)((stab)->rest)) { | |||
| 1430 | IdInfo idInfo = getIdInfoInThisScope(stab, sym); | |||
| 1431 | DeclInfoList dil; | |||
| 1432 | ||||
| 1433 | if (! idInfo) | |||
| 1434 | continue; | |||
| 1435 | ||||
| 1436 | for (dil = idInfo->declInfoList; dil; dil = cdr(dil)((dil)->rest)) { | |||
| 1437 | DeclInfo odi = car(dil)((dil)->first); /* outer decl info */ | |||
| 1438 | ||||
| 1439 | if (odi->uses[SCO_Sig_Assign] || | |||
| 1440 | odi->uses[SCO_Sig_Param]) | |||
| 1441 | { | |||
| 1442 | comsgNError(id,ALDOR_E_ScoBadLexConst112); | |||
| 1443 | if (odi->uses[SCO_Sig_Assign]) | |||
| 1444 | comsgNote(odi->uses[SCO_Sig_Assign], | |||
| 1445 | ALDOR_N_Here3); | |||
| 1446 | else | |||
| 1447 | comsgNote(odi->uses[SCO_Sig_Param], | |||
| 1448 | ALDOR_N_Here3); | |||
| 1449 | return; | |||
| 1450 | } | |||
| 1451 | } | |||
| 1452 | } | |||
| 1453 | } | |||
| 1454 | ||||
| 1455 | localstatic Bool | |||
| 1456 | scobindCheckOuterUseOfFluid(AbSyn id, AbSyn type) | |||
| 1457 | { | |||
| 1458 | Stab stab = scoStab; | |||
| 1459 | Symbol sym = id->abId.sym; | |||
| 1460 | Bool foundOuter = false((int) 0); | |||
| 1461 | for (stab = cdr(stab)((stab)->rest); stab; stab = cdr(stab)((stab)->rest)) { | |||
| 1462 | IdInfo idInfo = getIdInfoInThisScope(stab, sym); | |||
| 1463 | if (idInfo) { | |||
| 1464 | DeclInfo declInfo; | |||
| 1465 | ||||
| 1466 | if (type) | |||
| 1467 | declInfo = idInfoHasType(idInfo, type); | |||
| 1468 | else | |||
| 1469 | declInfo = car(idInfo->declInfoList)((idInfo->declInfoList)->first); | |||
| 1470 | if (declInfo && !declInfo->uses[SCO_Sig_Fluid]) | |||
| 1471 | comsgError(id, ALDOR_E_ScoFluidShadow113); | |||
| 1472 | foundOuter = true1; | |||
| 1473 | } | |||
| 1474 | } | |||
| 1475 | return foundOuter; | |||
| 1476 | } | |||
| 1477 | ||||
| 1478 | /****************************************************************************** | |||
| 1479 | * | |||
| 1480 | * :: scobindApply | |||
| 1481 | * | |||
| 1482 | *****************************************************************************/ | |||
| 1483 | ||||
| 1484 | localstatic void | |||
| 1485 | scobindApply(AbSyn ab) | |||
| 1486 | { | |||
| 1487 | int i, argc = abArgc(ab)((ab)->abHdr.argc); | |||
| 1488 | AbSyn *argv = abArgv(ab)((ab)->abGen.data.argv); | |||
| 1489 | ||||
| 1490 | if (scobindApplyNeedsSelf(ab)) | |||
| 1491 | scobindApplySelf(ab); | |||
| 1492 | ||||
| 1493 | if (scobindApplyNeedsScope(ab)) | |||
| 1494 | scobindLevel(ab, scobindApplyScope, scobindApplyFlags0); | |||
| 1495 | ||||
| 1496 | else | |||
| 1497 | for (i = 0; i < argc; i += 1) | |||
| 1498 | scobindValue(argv[i]); | |||
| 1499 | } | |||
| 1500 | ||||
| 1501 | localstatic void | |||
| 1502 | scobindApplySelf(AbSyn ab) | |||
| 1503 | { | |||
| 1504 | TForm tf, tf0; | |||
| 1505 | Syme syme; | |||
| 1506 | SymeList self; | |||
| 1507 | ||||
| 1508 | tf = stabMakeUsedTForm(scoStab, ab, scoCondListCondElt()); | |||
| 1509 | ||||
| 1510 | /* We don't want this self visible. */ | |||
| 1511 | tf0 = abIsApplyOf(ab, ssymJoin)(((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply .op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply .op))->abId.sym)==(ssymJoin))) ? tf : tfType; | |||
| 1512 | syme = symeNewLexVar(ssymSelf, tf0, car(scoStab)((scoStab)->first)); | |||
| 1513 | self = listCons(Syme)(Syme_listPointer->Cons)(syme, listNil(Syme)((SymeList) 0)); | |||
| 1514 | tfSetSelf(tf, self)((tf)->self = (self)); | |||
| 1515 | } | |||
| 1516 | ||||
| 1517 | localstatic Bool | |||
| 1518 | scobindApplyNeedsSelf(AbSyn ab) | |||
| 1519 | { | |||
| 1520 | AbSyn op; | |||
| 1521 | Symbol sym; | |||
| 1522 | ||||
| 1523 | assert(abIsApply(ab))do { if (!(((ab)->abHdr.tag == (AB_Apply)))) _do_assert(("abIsApply(ab)" ),"scobind.c",1523); } while (0); | |||
| 1524 | op = abApplyOp(ab)((ab)->abApply.op); | |||
| 1525 | sym = abIsId(op)((op)->abHdr.tag == (AB_Id)) ? abIdSym(op)((op)->abId.sym) : NULL((void*)0); | |||
| 1526 | ||||
| 1527 | return sym == ssymJoin || | |||
| 1528 | sym == ssymRawRecord || | |||
| 1529 | sym == ssymRecord || | |||
| 1530 | sym == ssymUnion || | |||
| 1531 | sym == ssymTrailingArray; | |||
| 1532 | } | |||
| 1533 | ||||
| 1534 | localstatic Bool | |||
| 1535 | scobindApplyNeedsScope(AbSyn ab) | |||
| 1536 | { | |||
| 1537 | int i, argc = abArgc(ab)((ab)->abHdr.argc); | |||
| 1538 | AbSyn *argv = abArgv(ab)((ab)->abGen.data.argv); | |||
| 1539 | ||||
| 1540 | for (i = 0; i < argc; i++) | |||
| 1541 | if (scobindApplyArgNeedsScope(argv[i])) | |||
| 1542 | return true1; | |||
| 1543 | return false((int) 0); | |||
| 1544 | } | |||
| 1545 | ||||
| 1546 | localstatic Bool | |||
| 1547 | scobindApplyArgNeedsScope(AbSyn ab) | |||
| 1548 | { | |||
| 1549 | AbSyn *argv = abArgvAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abGen.data.argv ) : &(ab)); | |||
| 1550 | Length i, argc = abArgcAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abHdr.argc) : 1); | |||
| 1551 | ||||
| 1552 | for (i = 0; i < argc; i += 1) | |||
| 1553 | switch (abTag(argv[i])((argv[i])->abHdr.tag)) { | |||
| 1554 | case AB_Declare: | |||
| 1555 | case AB_Define: | |||
| 1556 | case AB_With: | |||
| 1557 | return true1; | |||
| 1558 | default: | |||
| 1559 | break; | |||
| 1560 | } | |||
| 1561 | ||||
| 1562 | return false((int) 0); | |||
| 1563 | } | |||
| 1564 | ||||
| 1565 | /****************************************************************************** | |||
| 1566 | * | |||
| 1567 | * :: scobindApplyScope | |||
| 1568 | * | |||
| 1569 | *****************************************************************************/ | |||
| 1570 | ||||
| 1571 | localstatic void | |||
| 1572 | scobindApplyScope(AbSyn absyn) | |||
| 1573 | { | |||
| 1574 | AbSyn *argv = abArgv(absyn)((absyn)->abGen.data.argv); | |||
| 1575 | Length i, argc = abArgc(absyn)((absyn)->abHdr.argc); | |||
| 1576 | ||||
| 1577 | for (i = 0; i < argc; i += 1) { | |||
| 1578 | AbSyn arg = argv[i]; | |||
| 1579 | if (abIsAnyMap(absyn)(((((absyn)->abHdr.tag == (AB_Apply)) && (((((absyn )->abApply.op))->abHdr.tag == (AB_Id)) && ((((absyn )->abApply.op))->abId.sym)==(ssymArrow))) && (( (absyn)->abHdr.argc)-1) == 2) || ((((absyn)->abHdr.tag == (AB_Apply)) && (((((absyn)->abApply.op))->abHdr .tag == (AB_Id)) && ((((absyn)->abApply.op))->abId .sym)==(ssymPackedArrow))) && (((absyn)->abHdr.argc )-1) == 2)) && i == 1) | |||
| 1580 | scobindApplyParam(arg); | |||
| 1581 | else if (abHasTag(arg, AB_Comma)((arg)->abHdr.tag == (AB_Comma))) | |||
| 1582 | scobindApplyComma(arg); | |||
| 1583 | else | |||
| 1584 | scobindApplyArg(arg); | |||
| 1585 | } | |||
| 1586 | } | |||
| 1587 | ||||
| 1588 | /* | |||
| 1589 | * Scobind the parameter list of a function declaration. This examines | |||
| 1590 | * the parameter list from left-to-right adding new declarations as they | |||
| 1591 | * are encountered. Unfortunately this means that dependent maps must be | |||
| 1592 | * defined in a specific order with earlier parameters being available | |||
| 1593 | * as arguments to the types of later parameters. | |||
| 1594 | * | |||
| 1595 | * Ideally parameter declarations ought to be considered simultaneously | |||
| 1596 | * so that a wider class of dependent maps are possible. This requires | |||
| 1597 | * extra work during code generation to ensure that all definitions take | |||
| 1598 | * place in the correct order. This might happen automatically. | |||
| 1599 | */ | |||
| 1600 | localstatic void | |||
| 1601 | scobindApplyParam(AbSyn params) | |||
| 1602 | { | |||
| 1603 | AbSyn *argv = abArgvAs(AB_Comma, params)(((params)->abHdr.tag == (AB_Comma)) ? ((params)->abGen .data.argv) : &(params)); | |||
| 1604 | Length i, argc = abArgcAs(AB_Comma, params)(((params)->abHdr.tag == (AB_Comma)) ? ((params)->abHdr .argc) : 1); | |||
| 1605 | ||||
| 1606 | for (i = 0; i < argc; i += 1) { | |||
| 1607 | AbSyn arg = argv[i]; | |||
| 1608 | if (abHasTag(arg, AB_Declare)((arg)->abHdr.tag == (AB_Declare)) || abHasTag(arg, AB_Define)((arg)->abHdr.tag == (AB_Define))) | |||
| 1609 | scobindParam(arg); | |||
| 1610 | else | |||
| 1611 | scobindApplyArg(arg); | |||
| 1612 | } | |||
| 1613 | } | |||
| 1614 | ||||
| 1615 | localstatic void | |||
| 1616 | scobindApplyComma(AbSyn ab) | |||
| 1617 | { | |||
| 1618 | AbSyn *argv = abArgvAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abGen.data.argv ) : &(ab)); | |||
| 1619 | Length i, argc = abArgcAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abHdr.argc) : 1); | |||
| 1620 | ||||
| 1621 | for (i = 0; i < argc; i += 1) | |||
| 1622 | scobindApplyArg(argv[i]); | |||
| 1623 | } | |||
| 1624 | ||||
| 1625 | localstatic void | |||
| 1626 | scobindApplyArg(AbSyn arg) | |||
| 1627 | { | |||
| 1628 | if (abHasTag(arg, AB_Assign)((arg)->abHdr.tag == (AB_Assign))) { | |||
| 1629 | Stab ostab = scoStab; | |||
| 1630 | scoStab = cdr(scoStab)((scoStab)->rest); | |||
| 1631 | scobindValue(arg); | |||
| 1632 | scoStab = ostab; | |||
| 1633 | } | |||
| 1634 | else if (abHasTag(arg, AB_With)((arg)->abHdr.tag == (AB_With))) { | |||
| 1635 | scobindValue(arg); | |||
| 1636 | abSetTFormCond(arg, scobindTfSyntaxFrAbSyn(scoStab, arg))if (! ((arg)->abHdr.seman ? (arg)->abHdr.seman->tform : 0)) abSetTForm((arg), (scobindTfSyntaxFrAbSyn(scoStab, arg ))); | |||
| 1637 | } | |||
| 1638 | else | |||
| 1639 | scobindValue(arg); | |||
| 1640 | } | |||
| 1641 | ||||
| 1642 | /****************************************************************************** | |||
| 1643 | * | |||
| 1644 | * :: scobindAssign | |||
| 1645 | * | |||
| 1646 | *****************************************************************************/ | |||
| 1647 | ||||
| 1648 | localstatic void | |||
| 1649 | scobindAssign(AbSyn ab) | |||
| 1650 | { | |||
| 1651 | AbSyn lhs = ab->abAssign.lhs; | |||
| 1652 | AbSyn rhs = ab->abAssign.rhs; | |||
| 1653 | AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data. argv) : &(lhs)); | |||
| 1654 | Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc) : 1); | |||
| 1655 | Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)); | |||
| 1656 | ||||
| 1657 | for (i = 0; i < argc; i += 1) { | |||
| 1658 | AbSyn arg = argv[i]; | |||
| 1659 | ||||
| 1660 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 1661 | case AB_Id: | |||
| 1662 | scobindIntroduceId(arg, (isComma ? NULL((void*)0) : rhs), | |||
| 1663 | SCO_Sig_Assign); | |||
| 1664 | break; | |||
| 1665 | ||||
| 1666 | case AB_Declare: | |||
| 1667 | scobindAssignDeclare(arg); | |||
| 1668 | break; | |||
| 1669 | ||||
| 1670 | case AB_Apply: | |||
| 1671 | scobindValue(arg); | |||
| 1672 | break; | |||
| 1673 | ||||
| 1674 | default: | |||
| 1675 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 1675, "scobind.c"); | |||
| 1676 | break; | |||
| 1677 | } | |||
| 1678 | } | |||
| 1679 | ||||
| 1680 | scobindValue(rhs); | |||
| 1681 | } | |||
| 1682 | ||||
| 1683 | localstatic void | |||
| 1684 | scobindAssignDeclare(AbSyn decl) | |||
| 1685 | { | |||
| 1686 | AbSyn name = decl->abDeclare.id; | |||
| 1687 | AbSyn type = decl->abDeclare.type; | |||
| 1688 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 1689 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 1690 | ||||
| 1691 | for (i = 0; i < argc; i += 1) | |||
| 1692 | scobindAssignId(argv[i], type); | |||
| 1693 | } | |||
| 1694 | ||||
| 1695 | localstatic void | |||
| 1696 | scobindAssignId(AbSyn id, AbSyn type) | |||
| 1697 | { | |||
| 1698 | DeclInfo declInfo; | |||
| 1699 | ||||
| 1700 | declInfo = scobindDeclareId(id, type, NULL((void*)0), SCO_Sig_Assign); | |||
| 1701 | scobindSetSigUse(declInfo, SCO_Sig_Assign, id); | |||
| 1702 | ||||
| 1703 | if (declInfo->uses[SCO_Sig_Free]) | |||
| 1704 | markOuterInstanceOfFree(id, type, SCO_Sig_Assign); | |||
| 1705 | ||||
| 1706 | if (declInfoIsImplicitLocal(declInfo)) | |||
| 1707 | scobindSetSigUse(declInfo, SCO_Sig_ImplicitLocal, id); | |||
| 1708 | } | |||
| 1709 | ||||
| 1710 | /****************************************************************************** | |||
| 1711 | * | |||
| 1712 | * :: scobindBuiltin | |||
| 1713 | * | |||
| 1714 | *****************************************************************************/ | |||
| 1715 | ||||
| 1716 | localstatic void | |||
| 1717 | scobindBuiltin(AbSyn ab) | |||
| 1718 | { | |||
| 1719 | AbSyn what = ab->abBuiltin.what; | |||
| 1720 | AbSyn *argv = abArgvAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abGen. data.argv) : &(what)); | |||
| 1721 | Length i, argc = abArgcAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abHdr. argc) : 1); | |||
| 1722 | Bool save = scoIsInImport; | |||
| 1723 | ||||
| 1724 | scoIsInImport = true1; | |||
| 1725 | for (i = 0; i < argc; i += 1) | |||
| 1726 | scobindBuiltinDeclare(argv[i]); | |||
| 1727 | scoIsInImport = save; | |||
| 1728 | } | |||
| 1729 | ||||
| 1730 | localstatic void | |||
| 1731 | scobindBuiltinDeclare(AbSyn decl) | |||
| 1732 | { | |||
| 1733 | AbSyn name = decl->abDeclare.id; | |||
| 1734 | AbSyn type = decl->abDeclare.type; | |||
| 1735 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 1736 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 1737 | ||||
| 1738 | for (i = 0; i < argc; i += 1) | |||
| 1739 | scobindBuiltinId(argv[i], type); | |||
| 1740 | } | |||
| 1741 | ||||
| 1742 | localstatic void | |||
| 1743 | scobindBuiltinId(AbSyn id, AbSyn type) | |||
| 1744 | { | |||
| 1745 | Symbol sym = id->abId.sym; | |||
| 1746 | AInt bv; | |||
| 1747 | DeclInfo declInfo; | |||
| 1748 | ||||
| 1749 | if (!symInfo(sym)((sym)->info) || !symCoInfo(sym)) | |||
| 1750 | symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align)); | |||
| 1751 | ||||
| 1752 | bv = foamBValIdTag(sym)((FoamBValTag) symCoInfo(sym)->foamTagVal); | |||
| 1753 | ||||
| 1754 | if (bv == FOAM_BVAL_LIMIT | |||
| 1755 | && sym != ssymArrNew | |||
| 1756 | && sym != ssymArrElt | |||
| 1757 | && sym != ssymArrSet | |||
| 1758 | && sym != ssymArrDispose | |||
| 1759 | && sym != ssymRecNew | |||
| 1760 | && sym != ssymRecElt | |||
| 1761 | && sym != ssymRecSet | |||
| 1762 | && sym != ssymRecDispose | |||
| 1763 | && sym != ssymBIntDispose) | |||
| 1764 | { | |||
| 1765 | comsgError(id, ALDOR_E_ScoNotBuiltin125); | |||
| 1766 | return; | |||
| 1767 | } | |||
| 1768 | ||||
| 1769 | declInfo = scobindDeclareId(id, type, NULL((void*)0), SCO_Sig_Builtin); | |||
| 1770 | scobindSetSigUse(declInfo, SCO_Sig_Builtin, id); | |||
| 1771 | scobindAddMeaning(id, sym, scoStab, SYME_Builtin, abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), bv); | |||
| 1772 | } | |||
| 1773 | ||||
| 1774 | /****************************************************************************** | |||
| 1775 | * | |||
| 1776 | * :: scobindDeclare | |||
| 1777 | * | |||
| 1778 | *****************************************************************************/ | |||
| 1779 | ||||
| 1780 | localstatic void | |||
| 1781 | scobindDeclare(AbSyn ab) | |||
| 1782 | { | |||
| 1783 | AbSyn id = ab->abDeclare.id; | |||
| 1784 | AbSyn type = ab->abDeclare.type; | |||
| 1785 | AbSyn *argv = abArgvAs(AB_Comma, id)(((id)->abHdr.tag == (AB_Comma)) ? ((id)->abGen.data.argv ) : &(id)); | |||
| 1786 | Length i, argc = abArgcAs(AB_Comma, id)(((id)->abHdr.tag == (AB_Comma)) ? ((id)->abHdr.argc) : 1); | |||
| 1787 | ||||
| 1788 | for (i = 0; i < argc; i += 1) | |||
| 1789 | scobindDeclareId(argv[i], type, NULL((void*)0), SCO_Sig_Declare); | |||
| 1790 | } | |||
| 1791 | ||||
| 1792 | localstatic DeclInfo | |||
| 1793 | scobindDeclareId(AbSyn id, AbSyn type, AbSyn val, DeclContext context) | |||
| 1794 | { | |||
| 1795 | Symbol sym = id->abId.sym; | |||
| 1796 | AbSyn dtype = scobindDefaultType(scoStab, sym); | |||
| 1797 | IdInfo info = getIdInfoInAnyScope(scoStab, id); | |||
| 1798 | DeclInfo di = idInfoAddType(info, id, type, val, scoConditions()); | |||
| 1799 | AbSyn oval = di->uses[SCO_Sig_Value]; | |||
| 1800 | TForm tform; | |||
| 1801 | ||||
| 1802 | assert(abIsNotNothing(type))do { if (!(!((type)->abHdr.tag == (AB_Nothing)))) _do_assert (("abIsNotNothing(type)"),"scobind.c",1802); } while (0); | |||
| 1803 | ||||
| 1804 | /* Check the type against any default type which was given. */ | |||
| 1805 | if (dtype && !abEqualModDeclares(type, dtype)) | |||
| 1806 | comsgWarning(id, ALDOR_W_ScoVarDefault136, symString(sym)((sym)->str)); | |||
| 1807 | ||||
| 1808 | /* Check the value against any previous value which was given (extends get a free pass). */ | |||
| 1809 | if (val && oval && !abEqual(val, oval) | |||
| 1810 | && context != SCO_Sig_Extend) { | |||
| 1811 | /*!! comsgError(id, ALDOR_E_ScoVal, symString(sym)); */ | |||
| 1812 | return di; | |||
| 1813 | } | |||
| 1814 | ||||
| 1815 | /* Mark the identifier as declared. */ | |||
| 1816 | scobindSetSigUse(di, SCO_Sig_Declare, id); | |||
| 1817 | if (val) scobindSetSigUse(di, SCO_Sig_Value, val); | |||
| 1818 | if (scoIsInType) scobindSetSigUse(di, SCO_Sig_InType, id); | |||
| 1819 | ||||
| 1820 | /* Construct the syntax type for the declaration. */ | |||
| 1821 | scobindType(type); | |||
| 1822 | tform = scobindDeclareTForm(scoStab, id, type, val, context); | |||
| 1823 | tform = stabAddTFormDeclaree(scoStab, tform, id); | |||
| 1824 | if (!abHasTag(type, AB_Hide)((type)->abHdr.tag == (AB_Hide))) { | |||
| 1825 | stabImportTForm(scoStab, tform); | |||
| 1826 | if (context == SCO_Sig_Param) | |||
| 1827 | stabParameterImportTForm(scoStab, tform); | |||
| 1828 | } | |||
| 1829 | ||||
| 1830 | abSetTForm(type, tform); | |||
| 1831 | return di; | |||
| 1832 | } | |||
| 1833 | ||||
| 1834 | localstatic TForm | |||
| 1835 | scobindDeclareTForm(Stab stab, AbSyn id, AbSyn type, AbSyn val, DeclContext context) | |||
| 1836 | { | |||
| 1837 | TForm tf; | |||
| 1838 | ||||
| 1839 | if (val == NULL((void*)0)) { | |||
| 1840 | if (abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 )) | |||
| 1841 | return abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ); | |||
| 1842 | else | |||
| 1843 | return scobindTfSyntaxFrAbSyn(stab, type); | |||
| 1844 | } | |||
| 1845 | else if (abIsAnyLambda(val)(((val)->abHdr.tag == (AB_Lambda)) || ((val)->abHdr.tag == (AB_PLambda))) && | |||
| 1846 | (context == SCO_Sig_Extend || | |||
| 1847 | context == SCO_Sig_DDefine || | |||
| 1848 | scobindMapNeedsDefn(type)((((((type)->abHdr.tag == (AB_Apply)) && (((((type )->abApply.op))->abHdr.tag == (AB_Id)) && ((((type )->abApply.op))->abId.sym)==(ssymArrow))) && (( (type)->abHdr.argc)-1) == 2) || ((((type)->abHdr.tag == (AB_Apply)) && (((((type)->abApply.op))->abHdr .tag == (AB_Id)) && ((((type)->abApply.op))->abId .sym)==(ssymPackedArrow))) && (((type)->abHdr.argc )-1) == 2)) && ((((((type)->abApply.argv[1]))-> abHdr.tag == (AB_Id)) && ((((type)->abApply.argv[1 ]))->abId.sym)==(ssymCategory)) || ((((type)->abApply.argv [1]))->abHdr.tag == (AB_With)))))) | |||
| 1849 | tf = tfSyntaxDefineMap(scoStab, type, val); | |||
| 1850 | ||||
| 1851 | else if (context == SCO_Sig_Extend || | |||
| 1852 | context == SCO_Sig_DDefine || | |||
| 1853 | (context == SCO_Sig_Define && abIsUnknown(type)((type)->abHdr.tag == (AB_Blank))) || | |||
| 1854 | scobindRetNeedsDefn(type)((((type)->abHdr.tag == (AB_Id)) && ((type)->abId .sym)==(ssymCategory)) || ((type)->abHdr.tag == (AB_With)) )) | |||
| 1855 | tf = tfSyntaxDefine(scoStab, type, val); | |||
| 1856 | else | |||
| 1857 | tf = scobindTfSyntaxFrAbSyn(stab, type); | |||
| 1858 | ||||
| 1859 | if (scobindTFormMustBeUnique(type)) { | |||
| 1860 | scobindUniqifyDecl(tfExpr(tf)tfToAbSyn(tf), id); | |||
| 1861 | } | |||
| 1862 | return tf; | |||
| 1863 | } | |||
| 1864 | ||||
| 1865 | localstatic void | |||
| 1866 | scobindUniqifyDecl(AbSyn decl, AbSyn id) | |||
| 1867 | { | |||
| 1868 | ||||
| 1869 | while (abIsAnyMap(decl)(((((decl)->abHdr.tag == (AB_Apply)) && (((((decl) ->abApply.op))->abHdr.tag == (AB_Id)) && ((((decl )->abApply.op))->abId.sym)==(ssymArrow))) && (( (decl)->abHdr.argc)-1) == 2) || ((((decl)->abHdr.tag == (AB_Apply)) && (((((decl)->abApply.op))->abHdr .tag == (AB_Id)) && ((((decl)->abApply.op))->abId .sym)==(ssymPackedArrow))) && (((decl)->abHdr.argc )-1) == 2))) | |||
| 1870 | decl = abMapRet(decl)((decl)->abApply.argv[1]); | |||
| 1871 | ||||
| 1872 | assert(abTag(id) == AB_Id)do { if (!(((id)->abHdr.tag) == AB_Id)) _do_assert(("abTag(id) == AB_Id" ),"scobind.c",1872); } while (0); | |||
| 1873 | assert(abTag(decl) == AB_Define)do { if (!(((decl)->abHdr.tag) == AB_Define)) _do_assert(( "abTag(decl) == AB_Define"),"scobind.c",1873); } while (0); | |||
| 1874 | assert(abTag(decl->abDefine.lhs) == AB_Declare)do { if (!(((decl->abDefine.lhs)->abHdr.tag) == AB_Declare )) _do_assert(("abTag(decl->abDefine.lhs) == AB_Declare"), "scobind.c",1874); } while (0); | |||
| 1875 | ||||
| 1876 | decl->abDefine.lhs->abDeclare.id = abNewLabel(sposNone,abNew(AB_Label, sposNone,2, id,abNew(AB_Nothing, sposNone,0 ) ) | |||
| 1877 | id,abNew(AB_Label, sposNone,2, id,abNew(AB_Nothing, sposNone,0 ) ) | |||
| 1878 | abNewNothing(sposNone))abNew(AB_Label, sposNone,2, id,abNew(AB_Nothing, sposNone,0 ) ); | |||
| 1879 | } | |||
| 1880 | ||||
| 1881 | localstatic void | |||
| 1882 | scobindIntroduceId(AbSyn id, AbSyn val, DeclContext context) | |||
| 1883 | { | |||
| 1884 | Symbol sym = id->abId.sym; | |||
| 1885 | AbSyn type; | |||
| 1886 | TForm tform; | |||
| 1887 | IdInfo idInfo; | |||
| 1888 | DeclInfo declInfo; | |||
| 1889 | ||||
| 1890 | /* Compute a type expression for the identifier. */ | |||
| 1891 | ||||
| 1892 | idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 1893 | ||||
| 1894 | /* Try the default type. */ | |||
| 1895 | type = scobindDefaultType(scoStab, sym); | |||
| 1896 | ||||
| 1897 | if (!type && val) | |||
| 1898 | /* Try to take the type from the syntax of the val. */ | |||
| 1899 | type = scobindGuessType(val); | |||
| 1900 | ||||
| 1901 | if (!type
| |||
| 1902 | /* Take the type from a previous declaration. */ | |||
| 1903 | type = car(idInfo->declInfoList)((idInfo->declInfoList)->first)->type; | |||
| 1904 | ||||
| 1905 | if (!type
| |||
| 1906 | /* Give up. (Although later we may infer the type from val.) */ | |||
| 1907 | type = abCopy(abUnknown); | |||
| 1908 | abSetTForm(type, tfUnknown); | |||
| 1909 | } | |||
| 1910 | ||||
| 1911 | if (context
| |||
| 1912 | declInfo = idInfoAddType(idInfo, id, type, val, scoConditions()); | |||
| 1913 | ||||
| 1914 | /* Construct the syntax type for the identifier. */ | |||
| 1915 | scobindType(type); | |||
| 1916 | tform = scobindDeclareTForm(scoStab, id, type, val, context); | |||
| 1917 | tform = stabAddTFormDeclaree(scoStab, tform, id); | |||
| 1918 | if (abIsUnknown(type)((type)->abHdr.tag == (AB_Blank))) abSetTForm(type, tform); | |||
| 1919 | if (!abHasTag(type, AB_Hide)((type)->abHdr.tag == (AB_Hide))) stabImportTForm(scoStab, tform); | |||
| 1920 | ||||
| 1921 | /* Determine if the identifier is free. */ | |||
| 1922 | ||||
| 1923 | if (idInfo->allFree
| |||
| 1924 | if (context == SCO_Sig_Define) { | |||
| 1925 | comsgNError(id, ALDOR_E_ScoFreeConst119, symString(sym)((sym)->str)); | |||
| 1926 | if (declInfo && declInfo->uses[SCO_Sig_Free]) | |||
| 1927 | comsgNote(declInfo->uses[SCO_Sig_Free], | |||
| 1928 | ALDOR_N_Here3); | |||
| 1929 | } | |||
| 1930 | else if (context == SCO_Sig_Assign) | |||
| 1931 | markOuterInstanceOfFree(id, type, context); | |||
| 1932 | } | |||
| 1933 | ||||
| 1934 | scobindSetSigUse(declInfo, context, id); | |||
| 1935 | if (val) scobindSetSigUse(declInfo, SCO_Sig_Value, val); | |||
| 1936 | ||||
| 1937 | if (context == SCO_Sig_Default) | |||
| 1938 | scobindSetSigUse(declInfo, SCO_Sig_Define, id); | |||
| 1939 | ||||
| 1940 | if (scoIsInType) | |||
| 1941 | scobindSetSigUse(declInfo, SCO_Sig_InType, id); | |||
| 1942 | ||||
| 1943 | if (context == SCO_Sig_Loop) | |||
| 1944 | scobindSetSigUse(declInfo, SCO_Sig_Assign, id); | |||
| 1945 | ||||
| 1946 | if (context != SCO_Sig_Define && declInfoIsImplicitLocal(declInfo)) | |||
| 1947 | scobindSetSigUse(declInfo, SCO_Sig_ImplicitLocal, id); | |||
| 1948 | } | |||
| 1949 | ||||
| 1950 | localstatic AbSyn | |||
| 1951 | scobindGuessType(AbSyn val) | |||
| 1952 | { | |||
| 1953 | AbSyn type, id, arg, ret; | |||
| 1954 | ||||
| 1955 | switch (abTag(val)((val)->abHdr.tag)) { | |||
| 1956 | case AB_PretendTo: | |||
| 1957 | type = val->abPretendTo.type; | |||
| 1958 | break; | |||
| 1959 | case AB_CoerceTo: | |||
| 1960 | type = val->abCoerceTo.type; | |||
| 1961 | break; | |||
| 1962 | case AB_RestrictTo: | |||
| 1963 | type = val->abRestrictTo.type; | |||
| 1964 | break; | |||
| 1965 | case AB_Lambda: | |||
| 1966 | id = abNewId(abPos(val), ssymArrow)abNew(AB_Id, (spstackFirst((val)->abHdr.pos)),1, ssymArrow ); | |||
| 1967 | arg = val->abLambda.param; | |||
| 1968 | ret = val->abLambda.rtype; | |||
| 1969 | type = abNewApply2(abPos(val), id, arg, ret)abNew(AB_Apply, (spstackFirst((val)->abHdr.pos)),3, id,arg ,ret); | |||
| 1970 | break; | |||
| 1971 | case AB_PLambda: | |||
| 1972 | id = abNewId(abPos(val), ssymPackedArrow)abNew(AB_Id, (spstackFirst((val)->abHdr.pos)),1, ssymPackedArrow ); | |||
| 1973 | arg = val->abPLambda.param; | |||
| 1974 | ret = val->abPLambda.rtype; | |||
| 1975 | type = abNewApply2(abPos(val), id, arg, ret)abNew(AB_Apply, (spstackFirst((val)->abHdr.pos)),3, id,arg ,ret); | |||
| 1976 | break; | |||
| 1977 | default: | |||
| 1978 | type = NULL((void*)0); | |||
| 1979 | break; | |||
| 1980 | } | |||
| 1981 | ||||
| 1982 | return type; | |||
| 1983 | } | |||
| 1984 | ||||
| 1985 | /****************************************************************************** | |||
| 1986 | * | |||
| 1987 | * :: scobindDefault | |||
| 1988 | * | |||
| 1989 | *****************************************************************************/ | |||
| 1990 | ||||
| 1991 | localstatic void | |||
| 1992 | scobindDefault(AbSyn ab) | |||
| 1993 | { | |||
| 1994 | AbSyn body = ab->abDefault.body; | |||
| 1995 | AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen. data.argv) : &(body)); | |||
| 1996 | Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr. argc) : 1); | |||
| 1997 | ||||
| 1998 | for (i = 0; i < argc; i += 1) { | |||
| 1999 | if (abHasTag(argv[i], AB_Declare)((argv[i])->abHdr.tag == (AB_Declare))) { | |||
| 2000 | scobindDefaultDeclare(argv[i]); | |||
| 2001 | /* argv[i] = abNewNothing(abPos(argv[i])); */ | |||
| 2002 | } | |||
| 2003 | else | |||
| 2004 | scobindValue(argv[i]); | |||
| 2005 | } | |||
| 2006 | /* ab->abDefault.body = body; */ | |||
| 2007 | } | |||
| 2008 | ||||
| 2009 | localstatic void | |||
| 2010 | scobindDefaultDeclare(AbSyn decl) | |||
| 2011 | { | |||
| 2012 | AbSyn name = decl->abDeclare.id; | |||
| 2013 | AbSyn type = decl->abDeclare.type; | |||
| 2014 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2015 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2016 | ||||
| 2017 | for (i = 0; i < argc; i += 1) | |||
| 2018 | scobindDefaultId(argv[i], type); | |||
| 2019 | } | |||
| 2020 | ||||
| 2021 | localstatic void | |||
| 2022 | scobindDefaultId(AbSyn id, AbSyn type) | |||
| 2023 | { | |||
| 2024 | IdInfo idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 2025 | scobindImportType(scoStab, type); | |||
| 2026 | idInfo->defaultType = abCopy(type); | |||
| 2027 | } | |||
| 2028 | ||||
| 2029 | /****************************************************************************** | |||
| 2030 | * | |||
| 2031 | * :: scobindDefine | |||
| 2032 | * | |||
| 2033 | *****************************************************************************/ | |||
| 2034 | ||||
| 2035 | localstatic void | |||
| 2036 | scobindDefine(AbSyn ab) | |||
| 2037 | { | |||
| 2038 | AbSyn lhs = ab->abDefine.lhs; | |||
| 2039 | AbSyn rhs = ab->abDefine.rhs; | |||
| 2040 | AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data. argv) : &(lhs)); | |||
| 2041 | Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc) : 1); | |||
| 2042 | Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)); | |||
| 2043 | Bool isKey = abUse(ab)((ab)->abHdr.use) == AB_Use_Value; | |||
| 2044 | AbSyn val = isComma ? NULL((void*)0) : rhs; | |||
| 2045 | DeclContext context = isKey ? SCO_Sig_Default : SCO_Sig_Define; | |||
| 2046 | ||||
| 2047 | scobindPushDefine(lhs); | |||
| 2048 | ||||
| 2049 | for (i = 0; i < argc; i += 1) { | |||
| 2050 | AbSyn arg = argv[i]; | |||
| 2051 | ||||
| 2052 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 2053 | case AB_Id: | |||
| 2054 | scobindIntroduceId(arg, val, context); | |||
| 2055 | break; | |||
| 2056 | ||||
| 2057 | case AB_Declare: | |||
| 2058 | scobindDefineDeclare(arg, val); | |||
| 2059 | break; | |||
| 2060 | ||||
| 2061 | default: | |||
| 2062 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 2062, "scobind.c"); | |||
| 2063 | break; | |||
| 2064 | } | |||
| 2065 | } | |||
| 2066 | ||||
| 2067 | scobindDefineRhs(lhs, rhs, context); | |||
| 2068 | scobindPopDefine(lhs); | |||
| 2069 | } | |||
| 2070 | ||||
| 2071 | localstatic void | |||
| 2072 | scobindDefineDeclare(AbSyn decl, AbSyn val) | |||
| 2073 | { | |||
| 2074 | AbSyn name = decl->abDeclare.id; | |||
| 2075 | AbSyn type = decl->abDeclare.type; | |||
| 2076 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2077 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2078 | ||||
| 2079 | for (i = 0; i < argc; i += 1) | |||
| 2080 | scobindDefineId(argv[i], type, val); | |||
| 2081 | } | |||
| 2082 | ||||
| 2083 | localstatic void | |||
| 2084 | scobindDefineId(AbSyn id, AbSyn type, AbSyn val) | |||
| 2085 | { | |||
| 2086 | DeclInfo declInfo; | |||
| 2087 | ||||
| 2088 | declInfo = scobindDeclareId(id, type, val, SCO_Sig_Define); | |||
| 2089 | scobindSetSigUse(declInfo, SCO_Sig_Define, id); | |||
| 2090 | ||||
| 2091 | abSetDefineIdx(id, scoDefCounter++); | |||
| 2092 | ||||
| 2093 | if (declInfo->uses[SCO_Sig_Free]) | |||
| 2094 | comsgError(id, ALDOR_E_ScoFreeConst119, symString(id->abId.sym)((id->abId.sym)->str)); | |||
| 2095 | } | |||
| 2096 | ||||
| 2097 | localstatic void | |||
| 2098 | scobindDefineRhs(AbSyn lhs, AbSyn rhs, DeclContext context) | |||
| 2099 | { | |||
| 2100 | if (abIsAnyLambda(rhs)(((rhs)->abHdr.tag == (AB_Lambda)) || ((rhs)->abHdr.tag == (AB_PLambda)))) { | |||
| 2101 | LambdaInfo info = lambdaInfoAlloc(lhs, rhs, | |||
| 2102 | scoCondList); | |||
| 2103 | scoLambdaList = listCons(LambdaInfo)(LambdaInfo_listPointer->Cons)(info, scoLambdaList); | |||
| 2104 | ||||
| 2105 | if (abHasTag(lhs, AB_Declare)((lhs)->abHdr.tag == (AB_Declare))) | |||
| 2106 | scobindMatchWiths(lhs->abDeclare.type, rhs, context); | |||
| 2107 | } | |||
| 2108 | else | |||
| 2109 | scobindValue(rhs); | |||
| 2110 | } | |||
| 2111 | ||||
| 2112 | /****************************************************************************** | |||
| 2113 | * | |||
| 2114 | * :: scobindDDefine | |||
| 2115 | * | |||
| 2116 | *****************************************************************************/ | |||
| 2117 | ||||
| 2118 | localstatic void | |||
| 2119 | scobindDDefine(AbSyn absyn) | |||
| 2120 | { | |||
| 2121 | AbSyn body = absyn->abDDefine.body; | |||
| 2122 | AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen. data.argv) : &(body)); | |||
| 2123 | Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr. argc) : 1); | |||
| 2124 | ||||
| 2125 | for (i = 0; i < argc; i += 1) | |||
| 2126 | scobindDDefineComma(argv[i]); | |||
| 2127 | } | |||
| 2128 | ||||
| 2129 | localstatic void | |||
| 2130 | scobindDDefineComma(AbSyn defn) | |||
| 2131 | { | |||
| 2132 | AbSyn lhs = defn->abDefine.lhs; | |||
| 2133 | AbSyn rhs = defn->abDefine.rhs; | |||
| 2134 | AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data. argv) : &(lhs)); | |||
| 2135 | Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc) : 1); | |||
| 2136 | Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)); | |||
| 2137 | ||||
| 2138 | scobindPushDefine(lhs); | |||
| 2139 | ||||
| 2140 | for (i = 0; i < argc; i += 1) { | |||
| 2141 | AbSyn arg = argv[i]; | |||
| 2142 | ||||
| 2143 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 2144 | case AB_Id: | |||
| 2145 | scobindIntroduceId(arg, (isComma ? NULL((void*)0) : rhs), | |||
| 2146 | SCO_Sig_DDefine); | |||
| 2147 | break; | |||
| 2148 | ||||
| 2149 | case AB_Declare: | |||
| 2150 | scobindDDefineDeclare(arg, rhs); | |||
| 2151 | break; | |||
| 2152 | ||||
| 2153 | default: | |||
| 2154 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 2154, "scobind.c"); | |||
| 2155 | break; | |||
| 2156 | } | |||
| 2157 | } | |||
| 2158 | ||||
| 2159 | scobindDefineRhs(lhs, rhs, SCO_Sig_DDefine); | |||
| 2160 | scobindPopDefine(lhs); | |||
| 2161 | } | |||
| 2162 | ||||
| 2163 | localstatic void | |||
| 2164 | scobindDDefineDeclare(AbSyn decl, AbSyn val) | |||
| 2165 | { | |||
| 2166 | AbSyn name = decl->abDeclare.id; | |||
| 2167 | AbSyn type = decl->abDeclare.type; | |||
| 2168 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2169 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2170 | ||||
| 2171 | for (i = 0; i < argc; i += 1) | |||
| 2172 | scobindDDefineId(argv[i], type, val); | |||
| 2173 | } | |||
| 2174 | ||||
| 2175 | localstatic void | |||
| 2176 | scobindDDefineId(AbSyn id, AbSyn type, AbSyn val) | |||
| 2177 | { | |||
| 2178 | DeclInfo declInfo; | |||
| 2179 | ||||
| 2180 | declInfo = scobindDeclareId(id, type, val, SCO_Sig_DDefine); | |||
| 2181 | scobindSetSigUse(declInfo, SCO_Sig_DDefine, id); | |||
| 2182 | ||||
| 2183 | if (declInfo->uses[SCO_Sig_Free]) | |||
| 2184 | comsgError(id, ALDOR_E_ScoFreeConst119, symString(id->abId.sym)((id->abId.sym)->str)); | |||
| 2185 | } | |||
| 2186 | ||||
| 2187 | /****************************************************************************** | |||
| 2188 | * | |||
| 2189 | * :: scobindExtend | |||
| 2190 | * | |||
| 2191 | *****************************************************************************/ | |||
| 2192 | ||||
| 2193 | localstatic void | |||
| 2194 | scobindExtend(AbSyn absyn) | |||
| 2195 | { | |||
| 2196 | AbSyn body = absyn->abExtend.body; | |||
| 2197 | AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen. data.argv) : &(body)); | |||
| 2198 | Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr. argc) : 1); | |||
| 2199 | ||||
| 2200 | for (i = 0; i < argc; i += 1) { | |||
| 2201 | if (abHasTag(argv[i], AB_Define)((argv[i])->abHdr.tag == (AB_Define))) { | |||
| 2202 | AbSyn lhs = argv[i]->abDefine.lhs; | |||
| 2203 | AbSyn rhs = argv[i]->abDefine.rhs; | |||
| 2204 | ||||
| 2205 | scobindExtendDeclare(lhs, rhs); | |||
| 2206 | scobindDefineRhs(lhs, rhs, SCO_Sig_Extend); | |||
| 2207 | } | |||
| 2208 | else | |||
| 2209 | scobindExtendDeclare(argv[i], NULL((void*)0)); | |||
| 2210 | } | |||
| 2211 | } | |||
| 2212 | ||||
| 2213 | localstatic void | |||
| 2214 | scobindExtendDeclare(AbSyn lhs, AbSyn rhs) | |||
| 2215 | { | |||
| 2216 | Bool save = scoIsInExtend; | |||
| 2217 | ||||
| 2218 | scoIsInExtend = true1; | |||
| 2219 | switch (abTag(lhs)((lhs)->abHdr.tag)) { | |||
| 2220 | case AB_Declare: | |||
| 2221 | scobindExtendId(lhs->abDeclare.id, lhs->abDeclare.type, rhs); | |||
| 2222 | break; | |||
| 2223 | ||||
| 2224 | case AB_Id: | |||
| 2225 | scobindExtendId(lhs, NULL((void*)0), rhs); | |||
| 2226 | break; | |||
| 2227 | ||||
| 2228 | default: | |||
| 2229 | bugBadCase(abTag(lhs))bug("Bad case %d (line %d in file %s).", (int) ((lhs)->abHdr .tag), 2229, "scobind.c"); | |||
| 2230 | break; | |||
| 2231 | } | |||
| 2232 | scoIsInExtend = save; | |||
| 2233 | } | |||
| 2234 | ||||
| 2235 | localstatic void | |||
| 2236 | scobindExtendId(AbSyn id, AbSyn type, AbSyn val) | |||
| 2237 | { | |||
| 2238 | Symbol sym = id->abId.sym; | |||
| 2239 | Doc doc = abComment(id)((id)->abHdr.seman ? (id)->abHdr.seman->comment : 0); | |||
| 2240 | DeclInfo declInfo; | |||
| 2241 | Syme syme, ext; | |||
| 2242 | ||||
| 2243 | if (doc == NULL((void*)0)) doc = docNone; | |||
| 2244 | ||||
| 2245 | /* Create the syme for the extendee. */ | |||
| 2246 | declInfo = scobindDeclareId(id, type, val, SCO_Sig_Extend); | |||
| 2247 | scobindSetSigUse(declInfo, SCO_Sig_Extend, id); | |||
| 2248 | syme = stabDefExtendee(scoStab, sym, abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), doc); | |||
| 2249 | abSetSyme(id, syme); | |||
| 2250 | ||||
| 2251 | /* Create the syme for the extension. */ | |||
| 2252 | ext = scobindGetExtend(id, type); | |||
| 2253 | if (ext == NULL((void*)0)) { | |||
| 2254 | TForm template = tfSyntaxExtend(scoStab, id, type); | |||
| 2255 | ext = symeNewExtend(sym, template, car(scoStab)((scoStab)->first)); | |||
| 2256 | car(scoStab)((scoStab)->first)->extendSymes = | |||
| 2257 | listCons(Syme)(Syme_listPointer->Cons)(ext, car(scoStab)((scoStab)->first)->extendSymes); | |||
| 2258 | } | |||
| 2259 | ||||
| 2260 | /* Associate the extendee with the extension. */ | |||
| 2261 | symeSetExtension(syme, ext)symeXSetExtension(syme, (AInt) ext); | |||
| 2262 | symeAddExtendee(ext, syme); | |||
| 2263 | stabAddTFormDeclaree(scoStab, symeType(ext), id); | |||
| 2264 | stabAddTFormExtendees(scoStab, symeType(ext), id); | |||
| 2265 | stabAddTFormExtension(scoStab, abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), id); | |||
| 2266 | } | |||
| 2267 | ||||
| 2268 | localstatic Syme | |||
| 2269 | scobindGetExtend(AbSyn id, AbSyn type) | |||
| 2270 | { | |||
| 2271 | Stab stab; | |||
| 2272 | Symbol sym = id->abId.sym; | |||
| 2273 | ||||
| 2274 | for (stab = scoStab; stab; stab = cdr(stab)((stab)->rest)) { | |||
| 2275 | IdInfo idInfo = getIdInfoInThisScope(stab, sym); | |||
| 2276 | DeclInfoList dil; | |||
| 2277 | ||||
| 2278 | dil = idInfo ? idInfo->declInfoList : listNil(DeclInfo)((DeclInfoList) 0); | |||
| 2279 | ||||
| 2280 | for (; dil; dil = cdr(dil)((dil)->rest)) { | |||
| 2281 | DeclInfo di = car(dil)((dil)->first); | |||
| 2282 | AbSyn abuse = di->uses[SCO_Sig_Extend]; | |||
| 2283 | Syme ext; | |||
| 2284 | ||||
| 2285 | ext = abuse ? symeExtension(abSyme(abuse)((abuse)->abHdr.seman ? (abuse)->abHdr.seman->syme : 0)) : NULL((void*)0); | |||
| 2286 | if (ext && tfCanExtend(abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), symeType(ext))) | |||
| 2287 | return ext; | |||
| 2288 | } | |||
| 2289 | } | |||
| 2290 | ||||
| 2291 | return NULL((void*)0); | |||
| 2292 | } | |||
| 2293 | ||||
| 2294 | /****************************************************************************** | |||
| 2295 | * | |||
| 2296 | * :: scobindExport | |||
| 2297 | * | |||
| 2298 | *****************************************************************************/ | |||
| 2299 | ||||
| 2300 | localstatic void | |||
| 2301 | scobindExport(AbSyn ab) | |||
| 2302 | { | |||
| 2303 | AbSyn what = ab->abExport.what; | |||
| 2304 | AbSyn from = ab->abExport.origin; | |||
| 2305 | AbSyn dest = ab->abExport.destination; | |||
| 2306 | Bool save = scoIsInExport; | |||
| 2307 | ||||
| 2308 | assert(abIsNothing(from) || abIsNothing(dest))do { if (!(((from)->abHdr.tag == (AB_Nothing)) || ((dest)-> abHdr.tag == (AB_Nothing)))) _do_assert(("abIsNothing(from) || abIsNothing(dest)" ),"scobind.c",2308); } while (0); | |||
| 2309 | ||||
| 2310 | scoIsInExport = true1; | |||
| 2311 | ||||
| 2312 | if (abIsNotNothing(dest)!((dest)->abHdr.tag == (AB_Nothing))) | |||
| 2313 | scobindExportTo(what, dest); | |||
| 2314 | ||||
| 2315 | else if (abIsNotNothing(from)!((from)->abHdr.tag == (AB_Nothing))) | |||
| 2316 | scobindExportFrom(what, from); | |||
| 2317 | ||||
| 2318 | else | |||
| 2319 | scobindExportWhat(what); | |||
| 2320 | ||||
| 2321 | scoIsInExport = save; | |||
| 2322 | } | |||
| 2323 | ||||
| 2324 | localstatic void | |||
| 2325 | scobindExportTo(AbSyn what, AbSyn dest) | |||
| 2326 | { | |||
| 2327 | scobindType(dest); | |||
| 2328 | abSetTFormCond(dest, scobindTfSyntaxFrAbSyn(scoStab, dest))if (! ((dest)->abHdr.seman ? (dest)->abHdr.seman->tform : 0)) abSetTForm((dest), (scobindTfSyntaxFrAbSyn(scoStab, dest ))); | |||
| 2329 | scobindLOF(what, SCO_Sig_Local); | |||
| 2330 | } | |||
| 2331 | ||||
| 2332 | localstatic void | |||
| 2333 | scobindExportFrom(AbSyn what, AbSyn origin) | |||
| 2334 | { | |||
| 2335 | TForm tf; | |||
| 2336 | ||||
| 2337 | scobindType(origin); | |||
| 2338 | scobindValue(what); | |||
| 2339 | ||||
| 2340 | tf = scobindTfSyntaxFrAbSyn(scoStab, origin); | |||
| 2341 | if (abIsNothing(what)((what)->abHdr.tag == (AB_Nothing))) | |||
| 2342 | tf = stabExportTForm(scoStab, tf); | |||
| 2343 | else | |||
| 2344 | tf = stabQualifiedExportTForm(scoStab, what, tf); | |||
| 2345 | ||||
| 2346 | abSetTFormCond(origin, tf)if (! ((origin)->abHdr.seman ? (origin)->abHdr.seman-> tform : 0)) abSetTForm((origin), (tf)); | |||
| 2347 | } | |||
| 2348 | ||||
| 2349 | localstatic void | |||
| 2350 | scobindExportWhat(AbSyn what) | |||
| 2351 | { | |||
| 2352 | Length i; | |||
| 2353 | ||||
| 2354 | switch (abTag(what)((what)->abHdr.tag)) { | |||
| 2355 | case AB_Nothing: | |||
| 2356 | break; | |||
| 2357 | ||||
| 2358 | case AB_Comma: | |||
| 2359 | case AB_Sequence: | |||
| 2360 | for (i = 0; i < abArgc(what)((what)->abHdr.argc); i += 1) | |||
| 2361 | scobindExportWhat(abArgv(what)((what)->abGen.data.argv)[i]); | |||
| 2362 | break; | |||
| 2363 | ||||
| 2364 | case AB_Define: { | |||
| 2365 | AbSyn lhs = what->abDefine.lhs; | |||
| 2366 | AbSyn rhs = what->abDefine.rhs; | |||
| 2367 | ||||
| 2368 | scobindExportDeclare(lhs, rhs); | |||
| 2369 | scobindDefineRhs(lhs, rhs, SCO_Sig_Export); | |||
| 2370 | break; | |||
| 2371 | } | |||
| 2372 | ||||
| 2373 | case AB_Declare: | |||
| 2374 | scobindExportDeclare(what, NULL((void*)0)); | |||
| 2375 | break; | |||
| 2376 | ||||
| 2377 | case AB_Default: | |||
| 2378 | /* 'default' statement within 'with' body */ | |||
| 2379 | ||||
| 2380 | scobindValue(what); | |||
| 2381 | break; | |||
| 2382 | ||||
| 2383 | case AB_If: | |||
| 2384 | /* 'if' statement within 'with' body */ | |||
| 2385 | ||||
| 2386 | scobindValue(what->abIf.test); | |||
| 2387 | scoCondPush(scoStab, what->abIf.test, false((int) 0)); | |||
| 2388 | scobindExportWhat(what->abIf.thenAlt); | |||
| 2389 | scoCondPop(); | |||
| 2390 | scoCondPush(scoStab, what->abIf.test, true1); | |||
| 2391 | scobindExportWhat(what->abIf.elseAlt); | |||
| 2392 | scoCondPop(); | |||
| 2393 | break; | |||
| 2394 | ||||
| 2395 | case AB_Import: | |||
| 2396 | /* 'import' within 'with' body */ | |||
| 2397 | ||||
| 2398 | scobindValue(what); | |||
| 2399 | break; | |||
| 2400 | ||||
| 2401 | default: | |||
| 2402 | scobindValue(what); | |||
| 2403 | break; | |||
| 2404 | } | |||
| 2405 | } | |||
| 2406 | ||||
| 2407 | localstatic void | |||
| 2408 | scobindExportDeclare(AbSyn decl, AbSyn val) | |||
| 2409 | { | |||
| 2410 | AbSyn name = decl->abDeclare.id; | |||
| 2411 | AbSyn type = decl->abDeclare.type; | |||
| 2412 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2413 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2414 | ||||
| 2415 | for (i = 0; i < argc; i += 1) | |||
| 2416 | scobindExportId(argv[i], type, val); | |||
| 2417 | } | |||
| 2418 | ||||
| 2419 | localstatic void | |||
| 2420 | scobindExportId(AbSyn id, AbSyn type, AbSyn val) | |||
| 2421 | { | |||
| 2422 | Symbol sym = id->abId.sym; | |||
| 2423 | Doc doc = abComment(id)((id)->abHdr.seman ? (id)->abHdr.seman->comment : 0); | |||
| 2424 | DeclInfo declInfo; | |||
| 2425 | ||||
| 2426 | if (doc == NULL((void*)0)) doc = docNone; | |||
| 2427 | ||||
| 2428 | declInfo = scobindDeclareId(id, type, val, SCO_Sig_Export); | |||
| 2429 | scobindSetSigUse(declInfo, SCO_Sig_Export, id); | |||
| 2430 | scobindAddMeaning(id, sym, scoStab, SYME_Export, abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), | |||
| 2431 | (AInt) doc); | |||
| 2432 | } | |||
| 2433 | ||||
| 2434 | /****************************************************************************** | |||
| 2435 | * | |||
| 2436 | * :: scobindForeignExport | |||
| 2437 | * | |||
| 2438 | *****************************************************************************/ | |||
| 2439 | ||||
| 2440 | localstatic void | |||
| 2441 | scobindForeignExport(AbSyn ab) | |||
| 2442 | { | |||
| 2443 | AbSyn dest = ab->abForeignExport.dest; | |||
| 2444 | AbSyn what = ab->abForeignExport.what; | |||
| 2445 | ForeignOrigin forg = forgFrAbSyn(dest->abApply.argv[0]); | |||
| 2446 | ||||
| 2447 | scoIsInExport = true1; | |||
| 2448 | ||||
| 2449 | if (forg->protocol == FOAM_Proto_Java) { | |||
| 2450 | scobindValue(what); | |||
| 2451 | } | |||
| 2452 | else { | |||
| 2453 | scobindLOF(what, SCO_Sig_Local); | |||
| 2454 | } | |||
| 2455 | ||||
| 2456 | ||||
| 2457 | scoIsInExport = false((int) 0); | |||
| 2458 | } | |||
| 2459 | ||||
| 2460 | /****************************************************************************** | |||
| 2461 | * | |||
| 2462 | * :: scobindFluid | |||
| 2463 | * | |||
| 2464 | *****************************************************************************/ | |||
| 2465 | ||||
| 2466 | localstatic void | |||
| 2467 | scobindFluid(AbSyn ab) | |||
| 2468 | { | |||
| 2469 | AbSyn body = ab->abFluid.argv[0]; | |||
| 2470 | AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen. data.argv) : &(body)); | |||
| 2471 | Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr. argc) : 1); | |||
| 2472 | ||||
| 2473 | for (i = 0; i < argc; i += 1) { | |||
| 2474 | if (abHasTag(argv[i], AB_Assign)((argv[i])->abHdr.tag == (AB_Assign))) { | |||
| 2475 | scobindAssign(argv[i]); | |||
| 2476 | scobindFluidComma(argv[i]->abAssign.lhs); | |||
| 2477 | } | |||
| 2478 | else | |||
| 2479 | scobindFluidComma(argv[i]); | |||
| 2480 | } | |||
| 2481 | } | |||
| 2482 | ||||
| 2483 | localstatic void | |||
| 2484 | scobindFluidComma(AbSyn lhs) | |||
| 2485 | { | |||
| 2486 | AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data. argv) : &(lhs)); | |||
| 2487 | Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc) : 1); | |||
| 2488 | ||||
| 2489 | for (i = 0; i < argc; i += 1) { | |||
| 2490 | AbSyn arg = argv[i]; | |||
| 2491 | ||||
| 2492 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 2493 | case AB_Id: | |||
| 2494 | scobindFluidId(arg, NULL((void*)0)); | |||
| 2495 | break; | |||
| 2496 | ||||
| 2497 | case AB_Declare: | |||
| 2498 | scobindFluidDeclare(arg); | |||
| 2499 | break; | |||
| 2500 | ||||
| 2501 | default: | |||
| 2502 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 2502, "scobind.c"); | |||
| 2503 | break; | |||
| 2504 | } | |||
| 2505 | } | |||
| 2506 | } | |||
| 2507 | ||||
| 2508 | localstatic void | |||
| 2509 | scobindFluidDeclare(AbSyn decl) | |||
| 2510 | { | |||
| 2511 | AbSyn name = decl->abDeclare.id; | |||
| 2512 | AbSyn type = decl->abDeclare.type; | |||
| 2513 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2514 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2515 | ||||
| 2516 | for (i = 0; i < argc; i += 1) | |||
| 2517 | scobindFluidId(argv[i], type); | |||
| 2518 | } | |||
| 2519 | ||||
| 2520 | localstatic void | |||
| 2521 | scobindFluidId(AbSyn id, AbSyn type) | |||
| 2522 | { | |||
| 2523 | IdInfo idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 2524 | ||||
| 2525 | if (type) { | |||
| 2526 | DeclInfo declInfo; | |||
| 2527 | declInfo = scobindDeclareId(id, type, NULL((void*)0), SCO_Sig_Fluid); | |||
| 2528 | scobindSetSigUse(declInfo, SCO_Sig_Fluid, id); | |||
| 2529 | } | |||
| 2530 | else { | |||
| 2531 | DeclInfoList dil; | |||
| 2532 | idInfo->allFluid = true1; | |||
| 2533 | for (dil = idInfo->declInfoList; dil; dil = cdr(dil)((dil)->rest)) | |||
| 2534 | scobindSetSigUse(car(dil)((dil)->first), SCO_Sig_Fluid, id); | |||
| 2535 | } | |||
| 2536 | } | |||
| 2537 | ||||
| 2538 | /****************************************************************************** | |||
| 2539 | * | |||
| 2540 | * :: scobindFor | |||
| 2541 | * | |||
| 2542 | *****************************************************************************/ | |||
| 2543 | ||||
| 2544 | localstatic void | |||
| 2545 | scobindFor(AbSyn ab) | |||
| 2546 | { | |||
| 2547 | AbSyn lhs = ab->abFor.lhs; | |||
| 2548 | AbSyn whole = ab->abFor.whole; | |||
| 2549 | AbSyn test = ab->abFor.test; | |||
| 2550 | Stab ostab = scoStab; | |||
| 2551 | Bool stabWasLocked = stabLevelIsLocked(scoStab)(((scoStab)->first)->isLocked); | |||
| 2552 | ||||
| 2553 | /* whole should be analyzed in the enclosing symbol table. */ | |||
| 2554 | scoStab = stabPopLevel(scoStab); | |||
| 2555 | scobindValue(whole); | |||
| 2556 | scoStab = ostab; | |||
| 2557 | ||||
| 2558 | if (stabWasLocked) | |||
| 2559 | stabUnlockLevel(scoStab)(((scoStab)->first)->isLocked = ((int) 0)); | |||
| 2560 | ||||
| 2561 | scobindFor0(lhs, true1); | |||
| 2562 | scobindValue(test); | |||
| 2563 | ||||
| 2564 | if (stabWasLocked) | |||
| 2565 | stabLockLevel(scoStab)(((scoStab)->first)->isLocked = 1); | |||
| 2566 | } | |||
| 2567 | ||||
| 2568 | localstatic void | |||
| 2569 | scobindFor0(AbSyn var, Bool check) | |||
| 2570 | { | |||
| 2571 | Length i; | |||
| 2572 | ||||
| 2573 | switch (abTag(var)((var)->abHdr.tag)) { | |||
| ||||
| 2574 | case AB_Comma: | |||
| 2575 | case AB_Sequence: | |||
| 2576 | for (i = 0; i < abArgc(var)((var)->abHdr.argc); i += 1) | |||
| 2577 | scobindFor0(abArgv(var)((var)->abGen.data.argv)[i], check); | |||
| 2578 | break; | |||
| 2579 | ||||
| 2580 | case AB_Free: | |||
| 2581 | scobindFree(var); | |||
| 2582 | scobindFor0(abArgv(var)((var)->abGen.data.argv)[0], false((int) 0)); | |||
| 2583 | break; | |||
| 2584 | ||||
| 2585 | case AB_Local: | |||
| 2586 | scobindLocal(var); | |||
| 2587 | scobindFor0(abArgv(var)((var)->abGen.data.argv)[0], false((int) 0)); | |||
| 2588 | break; | |||
| 2589 | ||||
| 2590 | case AB_Id: | |||
| 2591 | if (check) { | |||
| 2592 | scobindLOF(var, SCO_Sig_Local); | |||
| 2593 | checkOuterUseOfImplicitLocal(scoStab, var, abUnknown); | |||
| 2594 | } | |||
| 2595 | scobindIntroduceId(var, NULL((void*)0), SCO_Sig_Loop); | |||
| 2596 | break; | |||
| 2597 | ||||
| 2598 | case AB_Declare: | |||
| 2599 | if (check) { | |||
| 2600 | scobindLOF(var, SCO_Sig_Local); | |||
| 2601 | checkOuterUseOfImplicitLocal(scoStab, abDefineeId(var), | |||
| 2602 | var->abDeclare.type); | |||
| 2603 | } | |||
| 2604 | scobindForDeclare(var->abDeclare.id, var->abDeclare.type); | |||
| 2605 | break; | |||
| 2606 | ||||
| 2607 | default: | |||
| 2608 | bugBadCase(abTag(var))bug("Bad case %d (line %d in file %s).", (int) ((var)->abHdr .tag), 2608, "scobind.c"); | |||
| 2609 | break; | |||
| 2610 | } | |||
| 2611 | } | |||
| 2612 | ||||
| 2613 | localstatic void | |||
| 2614 | scobindForDeclare(AbSyn name, AbSyn type) | |||
| 2615 | { | |||
| 2616 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2617 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2618 | ||||
| 2619 | for (i = 0; i < argc; i += 1) | |||
| 2620 | scobindForId(argv[i], type); | |||
| 2621 | } | |||
| 2622 | ||||
| 2623 | localstatic void | |||
| 2624 | scobindForId(AbSyn id, AbSyn type) | |||
| 2625 | { | |||
| 2626 | DeclInfo declInfo; | |||
| 2627 | ||||
| 2628 | declInfo = scobindDeclareId(id, type, NULL((void*)0), SCO_Sig_Loop); | |||
| 2629 | scobindSetSigUse(declInfo, SCO_Sig_Loop, id); | |||
| 2630 | scobindSetSigUse(declInfo, SCO_Sig_Assign, id); | |||
| 2631 | ||||
| 2632 | if (declInfo->uses[SCO_Sig_Free]) | |||
| 2633 | markOuterInstanceOfFree(id, type, SCO_Sig_Assign); | |||
| 2634 | ||||
| 2635 | if (declInfoIsImplicitLocal(declInfo)) | |||
| 2636 | scobindSetSigUse(declInfo, SCO_Sig_ImplicitLocal, id); | |||
| 2637 | } | |||
| 2638 | ||||
| 2639 | /****************************************************************************** | |||
| 2640 | * | |||
| 2641 | * :: scobindForeignImport | |||
| 2642 | * | |||
| 2643 | *****************************************************************************/ | |||
| 2644 | ||||
| 2645 | localstatic void | |||
| 2646 | scobindForeignImport(AbSyn ab) | |||
| 2647 | { | |||
| 2648 | AbSyn origin = ab->abForeignImport.origin; | |||
| 2649 | AbSyn what = ab->abForeignImport.what; | |||
| 2650 | AbSyn *argv = abArgvAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abGen. data.argv) : &(what)); | |||
| 2651 | Length i, argc = abArgcAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abHdr. argc) : 1); | |||
| 2652 | ||||
| 2653 | if (abHasTag(what, AB_Id)((what)->abHdr.tag == (AB_Id)) || abHasTag(what, AB_With)((what)->abHdr.tag == (AB_With))) | |||
| 2654 | { | |||
| 2655 | TForm tf; | |||
| 2656 | AbSyn abTf; | |||
| 2657 | TFormUses tfu; | |||
| 2658 | ||||
| 2659 | /* Treat as a traditional import */ | |||
| 2660 | scobindType(origin); | |||
| 2661 | scobindValue(what); | |||
| 2662 | tf = scobindTfSyntaxFrAbSyn(scoStab, origin); | |||
| 2663 | tf = stabQualifiedImportTForm(scoStab, what, tf); | |||
| 2664 | abSetTFormCond(origin, tf)if (! ((origin)->abHdr.seman ? (origin)->abHdr.seman-> tform : 0)) abSetTForm((origin), (tf)); | |||
| 2665 | ||||
| 2666 | ||||
| 2667 | /* Find the use of this tform */ | |||
| 2668 | abTf = tfExpr(tf)tfToAbSyn(tf); | |||
| 2669 | tfu = stabFindTFormUses(scoStab, abTf); | |||
| 2670 | ||||
| 2671 | ||||
| 2672 | /* Mark as qualified foreign or builtin import */ | |||
| 2673 | if (abIsTheId(origin, ssymBuiltin)(((origin)->abHdr.tag == (AB_Id)) && ((origin)-> abId.sym)==(ssymBuiltin))) | |||
| 2674 | tqSetStatus(tfu->imports, TQUAL_Builtin); | |||
| 2675 | else | |||
| 2676 | tqSetStatus(tfu->imports, TQUAL_Foreign); | |||
| 2677 | } | |||
| 2678 | else | |||
| 2679 | { | |||
| 2680 | Bool save = scoIsInImport; | |||
| 2681 | scoIsInImport = true1; | |||
| 2682 | for (i = 0; i < argc; i += 1) | |||
| 2683 | { | |||
| 2684 | AbSyn arg = argv[i]; | |||
| 2685 | ||||
| 2686 | if (abHasTag(argv[i], AB_Declare)((argv[i])->abHdr.tag == (AB_Declare))) | |||
| 2687 | { | |||
| 2688 | ForeignOrigin forg; | |||
| 2689 | ||||
| 2690 | forg = forgFrAbSyn(origin); | |||
| 2691 | scobindForeignDeclare(arg, forg); | |||
| 2692 | } | |||
| 2693 | } | |||
| 2694 | scoIsInImport = save; | |||
| 2695 | } | |||
| 2696 | } | |||
| 2697 | ||||
| 2698 | localstatic void | |||
| 2699 | scobindForeignDeclare(AbSyn decl, ForeignOrigin forg) | |||
| 2700 | { | |||
| 2701 | AbSyn name = decl->abDeclare.id; | |||
| 2702 | AbSyn type = decl->abDeclare.type; | |||
| 2703 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2704 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2705 | ||||
| 2706 | for (i = 0; i < argc; i += 1) | |||
| 2707 | scobindForeignId(argv[i], type, forg); | |||
| 2708 | } | |||
| 2709 | ||||
| 2710 | localstatic void | |||
| 2711 | scobindForeignId(AbSyn id, AbSyn type, ForeignOrigin forg) | |||
| 2712 | { | |||
| 2713 | Symbol sym = id->abId.sym; | |||
| 2714 | DeclInfo declInfo; | |||
| 2715 | ||||
| 2716 | declInfo = scobindDeclareId(id, type, NULL((void*)0), SCO_Sig_Foreign); | |||
| 2717 | scobindSetSigUse(declInfo, SCO_Sig_Foreign, id); | |||
| 2718 | scobindAddMeaning(id, sym, scoStab,SYME_Foreign,abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), | |||
| 2719 | (AInt) forg); | |||
| 2720 | } | |||
| 2721 | ||||
| 2722 | /****************************************************************************** | |||
| 2723 | * | |||
| 2724 | * :: scobindImport | |||
| 2725 | * | |||
| 2726 | *****************************************************************************/ | |||
| 2727 | ||||
| 2728 | localstatic void | |||
| 2729 | scobindImport(AbSyn ab) | |||
| 2730 | { | |||
| 2731 | AbSyn what = ab->abImport.what; | |||
| 2732 | AbSyn from = ab->abImport.origin; | |||
| 2733 | TForm tf; | |||
| 2734 | Bool save = scoIsInImport; | |||
| 2735 | ||||
| 2736 | scobindType(from); | |||
| 2737 | ||||
| 2738 | scoIsInImport = true1; | |||
| 2739 | scobindValue(what); | |||
| 2740 | scoIsInImport = save; | |||
| 2741 | ||||
| 2742 | tf = scobindTfSyntaxFrAbSyn(scoStab, from); | |||
| 2743 | if (abIsNothing(what)((what)->abHdr.tag == (AB_Nothing))) | |||
| 2744 | tf = stabExplicitlyImportTForm(scoStab, tf); | |||
| 2745 | else | |||
| 2746 | tf = stabQualifiedImportTForm(scoStab, what, tf); | |||
| 2747 | ||||
| 2748 | abSetTFormCond(from, tf)if (! ((from)->abHdr.seman ? (from)->abHdr.seman->tform : 0)) abSetTForm((from), (tf)); | |||
| 2749 | } | |||
| 2750 | ||||
| 2751 | /****************************************************************************** | |||
| 2752 | * | |||
| 2753 | * :: scobindInline | |||
| 2754 | * | |||
| 2755 | *****************************************************************************/ | |||
| 2756 | ||||
| 2757 | localstatic void | |||
| 2758 | scobindInline(AbSyn ab) | |||
| 2759 | { | |||
| 2760 | AbSyn what = ab->abInline.what; | |||
| 2761 | AbSyn from = ab->abInline.origin; | |||
| 2762 | TForm tf; | |||
| 2763 | ||||
| 2764 | scobindType(from); | |||
| 2765 | scobindValue(what); | |||
| 2766 | ||||
| 2767 | tf = scobindTfSyntaxFrAbSyn(scoStab, from); | |||
| 2768 | if (abIsNothing(what)((what)->abHdr.tag == (AB_Nothing))) | |||
| 2769 | tf = stabInlineTForm(scoStab, tf); | |||
| 2770 | else | |||
| 2771 | tf = stabQualifiedInlineTForm(scoStab, what, tf); | |||
| 2772 | ||||
| 2773 | abSetTFormCond(from, tf)if (! ((from)->abHdr.seman ? (from)->abHdr.seman->tform : 0)) abSetTForm((from), (tf)); | |||
| 2774 | } | |||
| 2775 | ||||
| 2776 | /****************************************************************************** | |||
| 2777 | * | |||
| 2778 | * :: scobindParam | |||
| 2779 | * | |||
| 2780 | *****************************************************************************/ | |||
| 2781 | ||||
| 2782 | localstatic void | |||
| 2783 | scobindParam(AbSyn ab) | |||
| 2784 | { | |||
| 2785 | AbSyn *argv = abArgvAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abGen.data.argv ) : &(ab)); | |||
| 2786 | Length i, argc = abArgcAs(AB_Comma, ab)(((ab)->abHdr.tag == (AB_Comma)) ? ((ab)->abHdr.argc) : 1); | |||
| 2787 | ||||
| 2788 | for (i = 0; i < argc; i += 1) { | |||
| 2789 | if (abHasTag(argv[i], AB_Define)((argv[i])->abHdr.tag == (AB_Define))) { | |||
| 2790 | AbSyn lhs = argv[i]->abDefine.lhs; | |||
| 2791 | AbSyn rhs = argv[i]->abDefine.rhs; | |||
| 2792 | ||||
| 2793 | scobindParamDefine(lhs, rhs); | |||
| 2794 | scobindDefineRhs(lhs, rhs, SCO_Sig_Param); | |||
| 2795 | } | |||
| 2796 | else | |||
| 2797 | scobindParamDefine(argv[i], NULL((void*)0)); | |||
| 2798 | } | |||
| 2799 | } | |||
| 2800 | ||||
| 2801 | localstatic void | |||
| 2802 | scobindParamDefine(AbSyn lhs, AbSyn rhs) | |||
| 2803 | { | |||
| 2804 | switch (abTag(lhs)((lhs)->abHdr.tag)) { | |||
| 2805 | case AB_Declare: | |||
| 2806 | scobindParamDeclare(lhs, rhs); | |||
| 2807 | break; | |||
| 2808 | ||||
| 2809 | default: | |||
| 2810 | /*!! abcheck */ | |||
| 2811 | comsgError(lhs, ALDOR_E_ScoBadParameter115); | |||
| 2812 | break; | |||
| 2813 | } | |||
| 2814 | } | |||
| 2815 | ||||
| 2816 | localstatic void | |||
| 2817 | scobindParamDeclare(AbSyn decl, AbSyn val) | |||
| 2818 | { | |||
| 2819 | AbSyn name = decl->abDeclare.id; | |||
| 2820 | AbSyn type = decl->abDeclare.type; | |||
| 2821 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2822 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2823 | ||||
| 2824 | for (i = 0; i < argc; i += 1) { | |||
| 2825 | AbSyn id = argv[i]; | |||
| 2826 | ||||
| 2827 | /*!! This is almost certainly wrong. */ | |||
| 2828 | Symbol sym = id->abId.sym; | |||
| 2829 | AbSyn idType = type; | |||
| 2830 | if (abIsNothing(idType)((idType)->abHdr.tag == (AB_Nothing))) { | |||
| 2831 | idType = scobindDefaultType(scoStab, id->abId.sym); | |||
| 2832 | if (idType) decl->abDeclare.type = abCopy(idType); | |||
| 2833 | } | |||
| 2834 | if (!idType) { | |||
| 2835 | comsgError(id, ALDOR_E_ScoParmType128, symString(sym)((sym)->str)); | |||
| 2836 | continue; | |||
| 2837 | } | |||
| 2838 | ||||
| 2839 | scobindParamId(id, idType, val); | |||
| 2840 | } | |||
| 2841 | } | |||
| 2842 | ||||
| 2843 | localstatic void | |||
| 2844 | scobindParamId(AbSyn id, AbSyn type, AbSyn val) | |||
| 2845 | { | |||
| 2846 | Symbol sym = id->abId.sym; | |||
| 2847 | DeclInfo declInfo; | |||
| 2848 | ||||
| 2849 | declInfo = scobindDeclareId(id, type, val, SCO_Sig_Param); | |||
| 2850 | scobindSetSigUse(declInfo, SCO_Sig_Param, id); | |||
| 2851 | ||||
| 2852 | if (abSyme(id)((id)->abHdr.seman ? (id)->abHdr.seman->syme : 0)) | |||
| 2853 | stabAddMeaning(scoStab, abSyme(id)((id)->abHdr.seman ? (id)->abHdr.seman->syme : 0)); | |||
| 2854 | else | |||
| 2855 | scobindAddMeaning(id, sym, scoStab, SYME_Param, abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0 ), | |||
| 2856 | (AInt) NULL((void*)0)); | |||
| 2857 | } | |||
| 2858 | ||||
| 2859 | /****************************************************************************** | |||
| 2860 | * | |||
| 2861 | * :: scobindReference | |||
| 2862 | * | |||
| 2863 | *****************************************************************************/ | |||
| 2864 | ||||
| 2865 | localstatic void | |||
| 2866 | scobindReference(AbSyn ab) | |||
| 2867 | { | |||
| 2868 | /* We ought to continue down the tree */ | |||
| 2869 | scobindValue(ab); | |||
| 2870 | ||||
| 2871 | ||||
| 2872 | /* Ignore complicated things */ | |||
| 2873 | if (!abHasTag(ab, AB_Id)((ab)->abHdr.tag == (AB_Id))) | |||
| 2874 | return; | |||
| 2875 | ||||
| 2876 | /* Mark the thing being referenced */ | |||
| 2877 | scobindIntroduceId(ab, NULL((void*)0), SCO_Sig_Reference); | |||
| 2878 | } | |||
| 2879 | ||||
| 2880 | /****************************************************************************** | |||
| 2881 | * | |||
| 2882 | * :: scobindFree | |||
| 2883 | * :: scobindLocal | |||
| 2884 | * | |||
| 2885 | *****************************************************************************/ | |||
| 2886 | ||||
| 2887 | localstatic void | |||
| 2888 | scobindFree(AbSyn ab) | |||
| 2889 | { | |||
| 2890 | scobindLOF(ab->abFree.argv[0], SCO_Sig_Free); | |||
| 2891 | } | |||
| 2892 | ||||
| 2893 | localstatic void | |||
| 2894 | scobindLocal(AbSyn ab) | |||
| 2895 | { | |||
| 2896 | scobindLOF(ab->abLocal.argv[0], SCO_Sig_Local); | |||
| 2897 | } | |||
| 2898 | ||||
| 2899 | localstatic void | |||
| 2900 | scobindLOF(AbSyn body, DeclContext context) | |||
| 2901 | { | |||
| 2902 | AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen. data.argv) : &(body)); | |||
| 2903 | Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr. argc) : 1); | |||
| 2904 | ||||
| 2905 | for (i = 0; i < argc; i += 1) { | |||
| 2906 | AbSyn arg = argv[i]; | |||
| 2907 | ||||
| 2908 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 2909 | case AB_Id: | |||
| 2910 | case AB_Declare: | |||
| 2911 | case AB_Comma: | |||
| 2912 | scobindLOFComma(arg, NULL((void*)0), context); | |||
| 2913 | break; | |||
| 2914 | ||||
| 2915 | case AB_Assign: | |||
| 2916 | scobindLOFComma(arg->abAssign.lhs, NULL((void*)0), context); | |||
| 2917 | scobindAssign(arg); | |||
| 2918 | break; | |||
| 2919 | ||||
| 2920 | case AB_Define: | |||
| 2921 | scobindLOFComma(arg->abDefine.lhs, | |||
| 2922 | arg->abDefine.rhs, context); | |||
| 2923 | scobindDefine(arg); | |||
| 2924 | break; | |||
| 2925 | ||||
| 2926 | default: | |||
| 2927 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 2927, "scobind.c"); | |||
| 2928 | break; | |||
| 2929 | } | |||
| 2930 | } | |||
| 2931 | } | |||
| 2932 | ||||
| 2933 | localstatic void | |||
| 2934 | scobindLOFComma(AbSyn lhs, AbSyn rhs, DeclContext context) | |||
| 2935 | { | |||
| 2936 | AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data. argv) : &(lhs)); | |||
| 2937 | Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc) : 1); | |||
| 2938 | Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)); | |||
| 2939 | AbSyn val = isComma ? NULL((void*)0) : rhs; | |||
| 2940 | ||||
| 2941 | for (i = 0; i < argc; i += 1) { | |||
| 2942 | AbSyn arg = argv[i]; | |||
| 2943 | ||||
| 2944 | switch (abTag(arg)((arg)->abHdr.tag)) { | |||
| 2945 | case AB_Id: | |||
| 2946 | scobindLOFId(arg, context); | |||
| 2947 | break; | |||
| 2948 | ||||
| 2949 | case AB_Declare: | |||
| 2950 | scobindLOFDeclare(arg, val, context); | |||
| 2951 | break; | |||
| 2952 | ||||
| 2953 | default: | |||
| 2954 | bugBadCase(abTag(arg))bug("Bad case %d (line %d in file %s).", (int) ((arg)->abHdr .tag), 2954, "scobind.c"); | |||
| 2955 | break; | |||
| 2956 | } | |||
| 2957 | } | |||
| 2958 | } | |||
| 2959 | ||||
| 2960 | localstatic void | |||
| 2961 | scobindLOFDeclare(AbSyn decl, AbSyn rhs, DeclContext context) | |||
| 2962 | { | |||
| 2963 | AbSyn name = decl->abDeclare.id; | |||
| 2964 | AbSyn type = decl->abDeclare.type; | |||
| 2965 | AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data .argv) : &(name)); | |||
| 2966 | Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc ) : 1); | |||
| 2967 | Bool isComma = abHasTag(name, AB_Comma)((name)->abHdr.tag == (AB_Comma)); | |||
| 2968 | AbSyn val = isComma ? NULL((void*)0) : rhs; | |||
| 2969 | ||||
| 2970 | for (i = 0; i < argc; i += 1) | |||
| 2971 | scobindLOFType(argv[i], type, val, context); | |||
| 2972 | } | |||
| 2973 | ||||
| 2974 | localstatic void | |||
| 2975 | scobindLOFId(AbSyn id, DeclContext context) | |||
| 2976 | { | |||
| 2977 | IdInfo idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 2978 | DeclInfoList dil = idInfo->declInfoList; | |||
| 2979 | ||||
| 2980 | if (context == SCO_Sig_Local) | |||
| 2981 | idInfo->allLocal = true1; | |||
| 2982 | else | |||
| 2983 | idInfo->allFree = true1; | |||
| 2984 | ||||
| 2985 | if (!dil && context == SCO_Sig_Free) | |||
| 2986 | markOuterInstanceOfFree(id, abUnknown, SCO_Sig_FreeRef); | |||
| 2987 | ||||
| 2988 | for (; dil; dil = cdr(dil)((dil)->rest)) | |||
| 2989 | scobindLOFDeclInfo(id, idInfo, car(dil)((dil)->first), context); | |||
| 2990 | } | |||
| 2991 | ||||
| 2992 | localstatic void | |||
| 2993 | scobindLOFType(AbSyn id, AbSyn type, AbSyn val, DeclContext context) | |||
| 2994 | { | |||
| 2995 | IdInfo idInfo = getIdInfoInAnyScope(scoStab, id); | |||
| 2996 | DeclInfo declInfo; | |||
| 2997 | ||||
| 2998 | scobindDeclareId(id, type, val, context); | |||
| 2999 | declInfo = idInfoHasType(idInfo, type); | |||
| 3000 | ||||
| 3001 | if (declInfo) | |||
| 3002 | scobindLOFDeclInfo(id, idInfo, declInfo, context); | |||
| 3003 | else if (context == SCO_Sig_Free) | |||
| 3004 | markOuterInstanceOfFree(id, type, SCO_Sig_FreeRef); | |||
| 3005 | } | |||
| 3006 | ||||
| 3007 | localstatic void | |||
| 3008 | scobindLOFDeclInfo(AbSyn id, IdInfo idInfo, DeclInfo di, DeclContext context) | |||
| 3009 | { | |||
| 3010 | AbSyn abNote = NULL((void*)0); | |||
| 3011 | ||||
| 3012 | if (idInfo->uses[SCO_Id_Used]) | |||
| 3013 | abNote = idInfo->uses[SCO_Id_Used]; | |||
| 3014 | else if (di->uses[SCO_Sig_Used]) | |||
| 3015 | abNote = di->uses[SCO_Sig_Used]; | |||
| 3016 | else if (di->uses[SCO_Sig_Assign]) | |||
| 3017 | abNote = di->uses[SCO_Sig_Assign]; | |||
| 3018 | else if (di->uses[SCO_Sig_Define]) | |||
| 3019 | abNote = di->uses[SCO_Sig_Define]; | |||
| 3020 | ||||
| 3021 | if (abNote) { | |||
| 3022 | comsgNError(id, ALDOR_E_ScoLateFreeLocal120); | |||
| 3023 | comsgNote(abNote, ALDOR_N_Here3); | |||
| 3024 | } | |||
| 3025 | ||||
| 3026 | scobindSetSigUse(di, context, id); | |||
| 3027 | ||||
| 3028 | if (di->uses[SCO_Sig_Param]) | |||
| 3029 | comsgError(id, ALDOR_E_ScoParmLocFree126); | |||
| 3030 | ||||
| 3031 | if (di->uses[SCO_Sig_Free] && di->uses[SCO_Sig_Local]) | |||
| 3032 | comsgError(id, ALDOR_E_ScoFreeAndLoc118, symString(id->abId.sym)((id->abId.sym)->str)); | |||
| 3033 | ||||
| 3034 | if (context == SCO_Sig_Free) | |||
| 3035 | markOuterInstanceOfFree(id, di->type, SCO_Sig_FreeRef); | |||
| 3036 | } | |||
| 3037 | ||||
| 3038 | /****************************************************************************** | |||
| 3039 | * | |||
| 3040 | * :: scobindTry | |||
| 3041 | * | |||
| 3042 | *****************************************************************************/ | |||
| 3043 | ||||
| 3044 | localstatic void | |||
| 3045 | scobindTry(AbSyn ab) | |||
| 3046 | { | |||
| 3047 | AbSyn id = ab->abTry.id; | |||
| 3048 | ||||
| 3049 | if (!abIsNothing(id)((id)->abHdr.tag == (AB_Nothing))) { | |||
| 3050 | AbSyn with, base, within; | |||
| 3051 | base = abNewNothing(abPos(id))abNew(AB_Nothing, (spstackFirst((id)->abHdr.pos)),0 ); | |||
| 3052 | abPutUse(base, AB_Use_Type); | |||
| 3053 | within = abNewNothing(abPos(id))abNew(AB_Nothing, (spstackFirst((id)->abHdr.pos)),0 ); | |||
| 3054 | abPutUse(within, AB_Use_Declaration); | |||
| 3055 | with = abNewWith(abPos(id), base, within)abNew(AB_With, (spstackFirst((id)->abHdr.pos)),2, base,within ); | |||
| 3056 | ||||
| 3057 | id = abDefineeId(ab->abTry.id); | |||
| 3058 | scobindDeclareId(id, with, | |||
| 3059 | NULL((void*)0), SCO_Sig_Define); | |||
| 3060 | } | |||
| 3061 | scobindValue(ab->abTry.expr); | |||
| 3062 | scobindValue(ab->abTry.except); | |||
| 3063 | scobindValue(ab->abTry.always); | |||
| 3064 | } | |||
| 3065 | ||||
| 3066 | /****************************************************************************** | |||
| 3067 | * | |||
| 3068 | * :: scobindIf | |||
| 3069 | * | |||
| 3070 | *****************************************************************************/ | |||
| 3071 | ||||
| 3072 | localstatic void | |||
| 3073 | scobindIf(AbSyn ab) | |||
| 3074 | { | |||
| 3075 | AbSyn test = ab->abIf.test; | |||
| 3076 | scobindValue(test); | |||
| 3077 | scoCondPush(scoStab, test, false((int) 0)); | |||
| 3078 | scobindValue(ab->abIf.thenAlt); | |||
| 3079 | scoCondPop(); | |||
| 3080 | scoCondPush(scoStab, test, true1); | |||
| 3081 | scobindValue(ab->abIf.elseAlt); | |||
| 3082 | scoCondPop(); | |||
| 3083 | } | |||
| 3084 | ||||
| 3085 | localstatic void | |||
| 3086 | scobindAnd(AbSyn ab) | |||
| 3087 | { | |||
| 3088 | int i; | |||
| 3089 | for (i=0; i<abArgc(ab)((ab)->abHdr.argc); i++) { | |||
| 3090 | AbSyn cond = ab->abAnd.argv[i]; | |||
| 3091 | scobindValue(cond); | |||
| 3092 | scoCondPush(scoStab, cond, false((int) 0)); | |||
| 3093 | } | |||
| 3094 | for (i=0; i<abArgc(ab)((ab)->abHdr.argc); i++) { | |||
| 3095 | scoCondPop(); | |||
| 3096 | } | |||
| 3097 | } | |||
| 3098 | ||||
| 3099 | ||||
| 3100 | localstatic ScoCondition | |||
| 3101 | scoConditionNew(Stab stab, AbSyn absyn, Bool isNegated) | |||
| 3102 | { | |||
| 3103 | ScoCondition cond = (ScoCondition) stoAlloc(OB_Other0, sizeof(*cond)); | |||
| 3104 | cond->stab = stab; | |||
| 3105 | cond->absyn = absyn; | |||
| 3106 | cond->negate = isNegated; | |||
| 3107 | ||||
| 3108 | return cond; | |||
| 3109 | } | |||
| 3110 | ||||
| 3111 | localstatic void | |||
| 3112 | scoCondPush(Stab stab, AbSyn ab, Bool isNegated) | |||
| 3113 | { | |||
| 3114 | scoCondList = listCons(ScoCondition)(ScoCondition_listPointer->Cons)(scoConditionNew(stab, ab, isNegated), scoCondList); | |||
| 3115 | } | |||
| 3116 | ||||
| 3117 | localstatic void | |||
| 3118 | scoCondPop() | |||
| 3119 | { | |||
| 3120 | /* FIXME: Blatant memleak */ | |||
| 3121 | scoCondList = cdr(scoCondList)((scoCondList)->rest); | |||
| 3122 | } | |||
| 3123 | ||||
| 3124 | localstatic ScoConditionList | |||
| 3125 | scoConditions() | |||
| 3126 | { | |||
| 3127 | return scoCondList; | |||
| 3128 | } | |||
| 3129 | ||||
| 3130 | localstatic AInt | |||
| 3131 | defPosEltFromAbSyn(AbSyn ab, Bool isNegated) | |||
| 3132 | { | |||
| 3133 | return isNegated ? (((AInt) ab) | 1) : (AInt) ab; | |||
| 3134 | } | |||
| 3135 | ||||
| 3136 | localstatic DefnPos | |||
| 3137 | defposTail(DefnPos pos) | |||
| 3138 | { | |||
| 3139 | return cdr(pos)((pos)->rest); | |||
| 3140 | } | |||
| 3141 | ||||
| 3142 | localstatic Bool | |||
| 3143 | defposEqInner(AInt a, AInt b) | |||
| 3144 | { | |||
| 3145 | return a == b; | |||
| 3146 | } | |||
| 3147 | ||||
| 3148 | localstatic AbSynList | |||
| 3149 | defposToAbSyn(AIntList defnPos) | |||
| 3150 | { | |||
| 3151 | AbSynList list = listNil(AbSyn)((AbSynList) 0); | |||
| 3152 | while (defnPos != listNil(AInt)((AIntList) 0)) { | |||
| 3153 | AInt c = car(defnPos)((defnPos)->first); | |||
| 3154 | AbSyn elt = c & 1 ? abNewNot(sposNone, (AbSyn)(c & ~1))abNew(AB_Not, sposNone,1, (AbSyn)(c & ~1)): (AbSyn) c; | |||
| 3155 | list = listCons(AbSyn)(AbSyn_listPointer->Cons)(elt, list); | |||
| 3156 | defnPos = cdr(defnPos)((defnPos)->rest); | |||
| 3157 | } | |||
| 3158 | ||||
| 3159 | return listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(list); | |||
| 3160 | } | |||
| 3161 | ||||
| 3162 | localstatic Bool | |||
| 3163 | defposEqual(DefnPos a, DefnPos b) | |||
| 3164 | { | |||
| 3165 | Bool flg = listEqual(AInt)(AInt_listPointer->Equal)(a, b, defposEqInner); | |||
| 3166 | #if 0 | |||
| 3167 | afprintf(dbOut, "DefPosEqual: %pAbSynList %pAbSynList = %d\n", defposToAbSyn(a), defposToAbSyn(b), flg); | |||
| 3168 | #endif | |||
| 3169 | return flg; | |||
| 3170 | } | |||
| 3171 | ||||
| 3172 | localstatic Bool | |||
| 3173 | defposIsRoot(DefnPos pos) | |||
| 3174 | { | |||
| 3175 | return pos == listNil(AInt)((AIntList) 0); | |||
| 3176 | } | |||
| 3177 | ||||
| 3178 | localstatic void | |||
| 3179 | defposFree(DefnPos pos) | |||
| 3180 | { | |||
| 3181 | listFree(AInt)(AInt_listPointer->Free)(pos); | |||
| 3182 | } | |||
| 3183 | ||||
| 3184 | /****************************************************************************** | |||
| 3185 | * | |||
| 3186 | * :: scobindCollect | |||
| 3187 | * | |||
| 3188 | *****************************************************************************/ | |||
| 3189 | ||||
| 3190 | localstatic Bool scoCollectIsNewIter(AbSyn ab); | |||
| 3191 | ||||
| 3192 | localstatic Bool | |||
| 3193 | scoIsNewCollect(AbSyn absyn) | |||
| 3194 | { | |||
| 3195 | AbSyn *iterv = absyn->abCollect.iterv; | |||
| 3196 | Length i, iterc = abCollectIterc(absyn)(((absyn)->abHdr.argc)-1); | |||
| 3197 | int newIters = 0; | |||
| 3198 | ||||
| 3199 | for (i=0; i<iterc; i++) { | |||
| 3200 | if (scoCollectIsNewIter(iterv[i])) { | |||
| 3201 | newIters++; | |||
| 3202 | } | |||
| 3203 | } | |||
| 3204 | ||||
| 3205 | return iterc > 0 && newIters == iterc; | |||
| 3206 | } | |||
| 3207 | ||||
| 3208 | localstatic Bool | |||
| 3209 | scoCollectIsNewIter(AbSyn absyn) | |||
| 3210 | { | |||
| 3211 | if (abTag(absyn)((absyn)->abHdr.tag) == AB_For && abFlag_IsNewIter(absyn)(((absyn)->abHdr.flags) == AB_Flag_NewIter)) { | |||
| 3212 | return true1; | |||
| 3213 | } | |||
| 3214 | return false((int) 0); | |||
| 3215 | } | |||
| 3216 | ||||
| 3217 | ||||
| 3218 | /****************************************************************************** | |||
| 3219 | * | |||
| 3220 | * :: IdInfo | |||
| 3221 | * | |||
| 3222 | *****************************************************************************/ | |||
| 3223 | ||||
| 3224 | localstatic IdInfo | |||
| 3225 | idInfoNew(Stab stab, AbSyn id) | |||
| 3226 | { | |||
| 3227 | Symbol sym = id->abId.sym; | |||
| 3228 | IdInfo idInfo; | |||
| 3229 | IdInfoList iil; | |||
| 3230 | Length c; | |||
| 3231 | ||||
| 3232 | if (!symInfo(sym)((sym)->info) || !symCoInfo(sym)) | |||
| 3233 | symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align)); | |||
| 3234 | ||||
| 3235 | car(stab)((stab)->first)->idsInScope = listCons(Symbol)(Symbol_listPointer->Cons)(sym, car(stab)((stab)->first)->idsInScope); | |||
| 3236 | ||||
| 3237 | idInfo = (IdInfo) stoAlloc(OB_Other0, sizeof(*idInfo)); | |||
| 3238 | ||||
| 3239 | idInfo->allFree = false((int) 0); | |||
| 3240 | idInfo->allLocal = false((int) 0); | |||
| 3241 | idInfo->allFluid = false((int) 0); | |||
| 3242 | idInfo->serialNo = car(stab)((stab)->first)->serialNo; | |||
| 3243 | idInfo->intStepNo = intStepNo; | |||
| 3244 | idInfo->sym = sym; | |||
| 3245 | idInfo->declInfoList = listNil(DeclInfo)((DeclInfoList) 0); /* NULL; */ | |||
| 3246 | idInfo->defaultType = NULL((void*)0); | |||
| 3247 | idInfo->exampleId = id; | |||
| 3248 | idInfo->usePreDef = listNil(AbSyn)((AbSynList) 0); | |||
| 3249 | ||||
| 3250 | for (c = 0; c < SCO_Id_LIMIT; c += 1) | |||
| 3251 | idInfo->uses[c] = NULL((void*)0); | |||
| 3252 | ||||
| 3253 | /* | |||
| 3254 | * Insert the new id info so that the id info structures are sorted | |||
| 3255 | * from innermost to outermost. (Inner stabs have higher serialNo's.) | |||
| 3256 | */ | |||
| 3257 | ||||
| 3258 | iil = listCons(IdInfo)(IdInfo_listPointer->Cons)(idInfo, idInfoCell(sym)((IdInfoList) (symCoInfo(sym)->phaseVal.generic))); | |||
| 3259 | setIdInfoCell(sym, iil)(symCoInfo(sym)->phaseVal.generic = (Pointer) (iil)); | |||
| 3260 | ||||
| 3261 | while (cdr(iil)((iil)->rest) && idInfo->serialNo < car(cdr(iil))((((iil)->rest))->first)->serialNo) { | |||
| 3262 | car(iil)((iil)->first) = car(cdr(iil))((((iil)->rest))->first); | |||
| 3263 | iil = cdr(iil)((iil)->rest); | |||
| 3264 | } | |||
| 3265 | setcar(iil, idInfo)((iil)->first = (idInfo)); | |||
| 3266 | ||||
| 3267 | return idInfo; | |||
| 3268 | } | |||
| 3269 | ||||
| 3270 | localstatic void | |||
| 3271 | idInfoFree(IdInfo idInfo) | |||
| 3272 | { | |||
| 3273 | listFreeDeeply(DeclInfo)(DeclInfo_listPointer->FreeDeeply)(idInfo->declInfoList, declInfoFree); | |||
| 3274 | listFree(AbSyn)(AbSyn_listPointer->Free)(idInfo->usePreDef); | |||
| 3275 | stoFree(idInfo); | |||
| 3276 | } | |||
| 3277 | ||||
| 3278 | localstatic Bool | |||
| 3279 | idInfoIsNew(IdInfo idInfo) | |||
| 3280 | { | |||
| 3281 | return idInfo->intStepNo == intStepNo - 1; | |||
| 3282 | } | |||
| 3283 | ||||
| 3284 | localstatic void | |||
| 3285 | scobindFreeIdInfo(Stab stab) | |||
| 3286 | { | |||
| 3287 | SymbolList ids = car(stab)((stab)->first)->idsInScope; | |||
| 3288 | ||||
| 3289 | for (; ids; ids = listFreeCons(Symbol)(Symbol_listPointer->FreeCons)(ids)) { | |||
| 3290 | Symbol id = car(ids)((ids)->first); | |||
| 3291 | IdInfoList il = idInfoCell(id)((IdInfoList) (symCoInfo(id)->phaseVal.generic)); | |||
| 3292 | IdInfo info = car(il)((il)->first); | |||
| 3293 | ||||
| 3294 | idInfoFree(info); | |||
| 3295 | setIdInfoCell(id, listFreeCons(IdInfo)(il))(symCoInfo(id)->phaseVal.generic = (Pointer) ((IdInfo_listPointer ->FreeCons)(il))); | |||
| 3296 | } | |||
| 3297 | car(stab)((stab)->first)->idsInScope = ids; | |||
| 3298 | } | |||
| 3299 | ||||
| 3300 | localstatic IdInfoList | |||
| 3301 | scobindSaveIdInfo(Stab stab) | |||
| 3302 | { | |||
| 3303 | SymbolList ids = car(stab)((stab)->first)->idsInScope; | |||
| 3304 | IdInfoList iil = listNil(IdInfo)((IdInfoList) 0); | |||
| 3305 | ||||
| 3306 | for (; ids; ids = listFreeCons(Symbol)(Symbol_listPointer->FreeCons)(ids)) { | |||
| 3307 | Symbol id = car(ids)((ids)->first); | |||
| 3308 | IdInfoList il = idInfoCell(id)((IdInfoList) (symCoInfo(id)->phaseVal.generic)); | |||
| 3309 | IdInfo info = car(il)((il)->first); | |||
| 3310 | ||||
| 3311 | iil = listCons(IdInfo)(IdInfo_listPointer->Cons)(info, iil); | |||
| 3312 | setIdInfoCell(id, listFreeCons(IdInfo)(il))(symCoInfo(id)->phaseVal.generic = (Pointer) ((IdInfo_listPointer ->FreeCons)(il))); | |||
| 3313 | } | |||
| 3314 | car(stab)((stab)->first)->idsInScope = ids; | |||
| 3315 | ||||
| 3316 | return iil; | |||
| 3317 | } | |||
| 3318 | ||||
| 3319 | localstatic void | |||
| 3320 | scobindRestoreIdInfo(Stab stab, IdInfoList iil, Bool undo) | |||
| 3321 | { | |||
| 3322 | SymbolList ids = listNil(Symbol)((SymbolList) 0); | |||
| 3323 | ||||
| 3324 | for (; iil; iil = listFreeCons(IdInfo)(IdInfo_listPointer->FreeCons)(iil)) { | |||
| 3325 | IdInfo info = car(iil)((iil)->first); | |||
| 3326 | Symbol id = info->sym; | |||
| 3327 | IdInfoList il = idInfoCell(id)((IdInfoList) (symCoInfo(id)->phaseVal.generic)); | |||
| 3328 | ||||
| 3329 | if (undo && idInfoIsNew(info)) | |||
| 3330 | idInfoFree(info); | |||
| 3331 | else { | |||
| 3332 | ids = listCons(Symbol)(Symbol_listPointer->Cons)(id, ids); | |||
| 3333 | setIdInfoCell(id, listCons(IdInfo)(info, il))(symCoInfo(id)->phaseVal.generic = (Pointer) ((IdInfo_listPointer ->Cons)(info, il))); | |||
| 3334 | if (undo) scobindRestoreDeclInfo(info); | |||
| 3335 | } | |||
| 3336 | } | |||
| 3337 | car(stab)((stab)->first)->idsInScope = ids; | |||
| 3338 | } | |||
| 3339 | ||||
| 3340 | /* | |||
| 3341 | * Get the id info from the innermost level which can have it. | |||
| 3342 | * A lexical level can have info for an id if the id is already present, | |||
| 3343 | * or if the level is unlocked. | |||
| 3344 | */ | |||
| 3345 | localstatic IdInfo | |||
| 3346 | getIdInfoInAnyScope(Stab stab, AbSyn id) | |||
| 3347 | { | |||
| 3348 | Symbol sym = id->abId.sym; | |||
| 3349 | IdInfo info = NULL((void*)0); | |||
| 3350 | ||||
| 3351 | for (; stab && !info; stab = cdr(stab)((stab)->rest)) { | |||
| 3352 | info = getIdInfoInThisScope(stab, sym); | |||
| 3353 | if (!info && !stabLevelIsLocked(stab)(((stab)->first)->isLocked)) | |||
| 3354 | info = idInfoNew(stab, id); | |||
| 3355 | } | |||
| 3356 | ||||
| 3357 | assert(info)do { if (!(info)) _do_assert(("info"),"scobind.c",3357); } while (0); | |||
| 3358 | return info; | |||
| 3359 | } | |||
| 3360 | ||||
| 3361 | /* | |||
| 3362 | * Get the id info for sym if it exists in the given scope. | |||
| 3363 | * Return NULL if no id info exists for sym in the given scope. | |||
| 3364 | */ | |||
| 3365 | localstatic IdInfo | |||
| 3366 | getIdInfoInThisScope(Stab stab, Symbol sym) | |||
| 3367 | { | |||
| 3368 | ULong serialNo = car(stab)((stab)->first)->serialNo; | |||
| 3369 | IdInfoList info; | |||
| 3370 | ||||
| 3371 | if (!symInfo(sym)((sym)->info) || !symCoInfo(sym)) | |||
| 3372 | symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align)); | |||
| 3373 | ||||
| 3374 | for (info = idInfoCell(sym)((IdInfoList) (symCoInfo(sym)->phaseVal.generic)); info; info = cdr(info)((info)->rest)) { | |||
| 3375 | if (car(info)((info)->first)->serialNo == serialNo) | |||
| 3376 | return car(info)((info)->first); | |||
| 3377 | else if (car(info)((info)->first)->serialNo < serialNo) | |||
| 3378 | return NULL((void*)0); | |||
| 3379 | } | |||
| 3380 | return NULL((void*)0); | |||
| 3381 | } | |||
| 3382 | ||||
| 3383 | localstatic void | |||
| 3384 | scobindSetIdUse(IdInfo idInfo, IdContext context, AbSyn use) | |||
| 3385 | { | |||
| 3386 | idInfo->uses[context] = use; | |||
| 3387 | } | |||
| 3388 | ||||
| 3389 | localstatic AbSyn | |||
| 3390 | scobindDefaultType(Stab stab, Symbol sym) | |||
| 3391 | { | |||
| 3392 | AbSyn dtype = NULL((void*)0); | |||
| 3393 | ||||
| 3394 | for (; stab && !dtype; stab = cdr(stab)((stab)->rest)) { | |||
| 3395 | IdInfo info = getIdInfoInThisScope(stab, sym); | |||
| 3396 | dtype = info ? info->defaultType : NULL((void*)0); | |||
| 3397 | } | |||
| 3398 | ||||
| 3399 | return dtype; | |||
| 3400 | } | |||
| 3401 | ||||
| 3402 | /****************************************************************************** | |||
| 3403 | * | |||
| 3404 | * :: DeclInfo | |||
| 3405 | * | |||
| 3406 | *****************************************************************************/ | |||
| 3407 | ||||
| 3408 | localstatic DeclInfo | |||
| 3409 | declInfoNew(AbSyn id, AbSyn type, DefnPos cond) | |||
| 3410 | { | |||
| 3411 | DeclInfo di; | |||
| 3412 | Length c; | |||
| 3413 | ||||
| 3414 | di = (DeclInfo) stoAlloc(OB_Other0, sizeof(*di)); | |||
| 3415 | ||||
| 3416 | di->intStepNo = intStepNo; | |||
| 3417 | di->id = id; | |||
| 3418 | di->type = type; | |||
| 3419 | di->defpos = listSingleton(DefnPos)(DefnPos_listPointer->Singleton)(cond); | |||
| 3420 | di->doc = id ? abComment(id)((id)->abHdr.seman ? (id)->abHdr.seman->comment : 0) : docNone; | |||
| 3421 | ||||
| 3422 | for (c = 0; c < SCO_Sig_LIMIT; c += 1) | |||
| 3423 | di->uses[c] = NULL((void*)0); | |||
| 3424 | ||||
| 3425 | return di; | |||
| 3426 | } | |||
| 3427 | ||||
| 3428 | localstatic void | |||
| 3429 | declInfoFree(DeclInfo di) | |||
| 3430 | { | |||
| 3431 | stoFree(di); | |||
| 3432 | } | |||
| 3433 | ||||
| 3434 | localstatic Bool | |||
| 3435 | declInfoIsNew(DeclInfo di) | |||
| 3436 | { | |||
| 3437 | return di->intStepNo == intStepNo - 1; | |||
| 3438 | } | |||
| 3439 | ||||
| 3440 | localstatic Bool | |||
| 3441 | declInfoUseIsNew(AbSyn ab) | |||
| 3442 | { | |||
| 3443 | return ab && (!abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0) || isNewSyme(abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0))); | |||
| 3444 | } | |||
| 3445 | ||||
| 3446 | localstatic Bool | |||
| 3447 | declInfoIsImplicitLocal(DeclInfo di) | |||
| 3448 | { | |||
| 3449 | return !(di->uses[SCO_Sig_Local] || | |||
| 3450 | di->uses[SCO_Sig_Free] || | |||
| 3451 | di->uses[SCO_Sig_Param] || | |||
| 3452 | di->uses[SCO_Sig_Export]); | |||
| 3453 | } | |||
| 3454 | ||||
| 3455 | localstatic void | |||
| 3456 | scobindRestoreDeclInfo(IdInfo ido) | |||
| 3457 | { | |||
| 3458 | DeclInfoList dil = ido->declInfoList; | |||
| 3459 | dil = listFreeIfSat(DeclInfo)(DeclInfo_listPointer->FreeIfSat)(dil, declInfoFree, declInfoIsNew); | |||
| 3460 | ido->declInfoList = dil; | |||
| 3461 | ||||
| 3462 | for (; dil; dil = cdr(dil)((dil)->rest)) { | |||
| 3463 | DeclInfo di = car(dil)((dil)->first); | |||
| 3464 | Length i; | |||
| 3465 | for (i = SCO_Sig_START; i < SCO_Sig_LIMIT; i += 1) | |||
| 3466 | if (declInfoUseIsNew(di->uses[i])) | |||
| 3467 | di->uses[i] = NULL((void*)0); | |||
| 3468 | } | |||
| 3469 | } | |||
| 3470 | ||||
| 3471 | localstatic DeclInfo | |||
| 3472 | idInfoHasType(IdInfo ido, AbSyn type) | |||
| 3473 | { | |||
| 3474 | DeclInfoList dil; | |||
| 3475 | ||||
| 3476 | for (dil = ido->declInfoList; dil; dil = cdr(dil)((dil)->rest)) | |||
| 3477 | if (abEqualModDeclares(car(dil)((dil)->first)->type, type)) | |||
| 3478 | return car(dil)((dil)->first); | |||
| 3479 | return NULL((void*)0); | |||
| 3480 | } | |||
| 3481 | ||||
| 3482 | /* | |||
| 3483 | * Augment list of types and symbol documentation. | |||
| 3484 | */ | |||
| 3485 | localstatic DeclInfo | |||
| 3486 | idInfoAddType(IdInfo ido, AbSyn id, AbSyn type, AbSyn val, ScoConditionList cond) | |||
| 3487 | { | |||
| 3488 | DeclInfo di; | |||
| 3489 | ||||
| 3490 | /* If this id has been declared with this type, | |||
| 3491 | * use the old decl info. | |||
| 3492 | */ | |||
| 3493 | if ((di = idInfoHasType(ido, type)) != NULL((void*)0)) | |||
| 3494 | ; | |||
| 3495 | ||||
| 3496 | /* If this id has been declared with type Unknown, | |||
| 3497 | * substitute the new type in the old decl info. | |||
| 3498 | */ | |||
| 3499 | else if ((di = idInfoHasType(ido, abUnknown)) != NULL((void*)0) && | |||
| 3500 | (val == NULL((void*)0) || di->uses[SCO_Sig_Value] == NULL((void*)0))) | |||
| 3501 | di->type = type; | |||
| 3502 | ||||
| 3503 | /* Otherwise create a new decl info structure. */ | |||
| 3504 | else { | |||
| 3505 | di = declInfoNew(id, type, scoConditionToDefnPos(cond)); | |||
| 3506 | ||||
| 3507 | if (ido->allFree) | |||
| 3508 | scobindSetSigUse(di, SCO_Sig_Free, id); | |||
| 3509 | if (ido->allLocal) | |||
| 3510 | scobindSetSigUse(di, SCO_Sig_Local, id); | |||
| 3511 | ||||
| 3512 | ido->declInfoList = listCons(DeclInfo)(DeclInfo_listPointer->Cons)(di, ido->declInfoList); | |||
| 3513 | } | |||
| 3514 | ||||
| 3515 | return di; | |||
| 3516 | } | |||
| 3517 | ||||
| 3518 | localstatic void | |||
| 3519 | scobindSetSigUse(DeclInfo declInfo, DeclContext context, AbSyn use) | |||
| 3520 | { | |||
| 3521 | /* check for double definitions */ | |||
| 3522 | ||||
| 3523 | /*!! This shouldn't be here. */ | |||
| 3524 | if (context
| |||
| 3525 | if (fintMode == FINT_LOOP2 && | |||
| 3526 | fintYesOrNo("Redefine? (y/n): ")) { | |||
| 3527 | comsgFPrintf(stdoutstdout, ALDOR_M_FintRedefined246, | |||
| 3528 | use->abId.sym->str); | |||
| 3529 | } | |||
| 3530 | else if (!scobindCheckCondition(declInfo, scoCondList)) { | |||
| 3531 | comsgNError(use, ALDOR_E_ScoDupDefine117, | |||
| 3532 | symString(use->abId.sym)((use->abId.sym)->str)); | |||
| 3533 | comsgNote(declInfo->uses[context], ALDOR_N_Here3); | |||
| 3534 | } | |||
| 3535 | declInfo->defpos = listCons(DefnPos)(DefnPos_listPointer->Cons)(scoConditionToDefnPos(scoCondList), | |||
| 3536 | declInfo->defpos); | |||
| 3537 | } | |||
| 3538 | ||||
| 3539 | declInfo->uses[context] = use; | |||
| ||||
| 3540 | } | |||
| 3541 | ||||
| 3542 | localstatic TfCondElt scoConditionListToCondElt(ScoConditionList); | |||
| 3543 | localstatic AbSynList scoConditionToAbSyn(ScoConditionList); | |||
| 3544 | ||||
| 3545 | localstatic Bool | |||
| 3546 | scobindCheckCondition(DeclInfo declInfo, ScoConditionList conditionList) | |||
| 3547 | { | |||
| 3548 | DefnPos defnPos = scoConditionToDefnPos(conditionList); | |||
| 3549 | Bool check = scobindCheckDefnPos(declInfo, defnPos); | |||
| 3550 | scoDEBUGif (!scoDebug) { } else afprintf(dbOut, "scobindCheckCondition: %pAbSynList %d\n", | |||
| 3551 | scoConditionToAbSyn(conditionList), check); | |||
| 3552 | defposFree(defnPos); | |||
| 3553 | ||||
| 3554 | return check; | |||
| 3555 | } | |||
| 3556 | ||||
| 3557 | localstatic DefnPos | |||
| 3558 | scoConditionToDefnPos(ScoConditionList condition) | |||
| 3559 | { | |||
| 3560 | AIntList list = listNil(AInt)((AIntList) 0); | |||
| 3561 | while (condition != listNil(ScoCondition)((ScoConditionList) 0)) { | |||
| 3562 | ScoCondition conditionElt = car(condition)((condition)->first); | |||
| 3563 | AInt elt = defPosEltFromAbSyn(conditionElt->absyn, conditionElt->negate); | |||
| 3564 | list = listCons(AInt)(AInt_listPointer->Cons)(elt, list); | |||
| 3565 | condition = cdr(condition)((condition)->rest); | |||
| 3566 | } | |||
| 3567 | ||||
| 3568 | return listNReverse(AInt)(AInt_listPointer->NReverse)(list); | |||
| 3569 | } | |||
| 3570 | ||||
| 3571 | localstatic AbSynList | |||
| 3572 | scoConditionToAbSyn(ScoConditionList condition) | |||
| 3573 | { | |||
| 3574 | AbSynList list = listNil(AbSyn)((AbSynList) 0); | |||
| 3575 | while (condition != listNil(ScoCondition)((ScoConditionList) 0)) { | |||
| 3576 | ScoCondition conditionElt = car(condition)((condition)->first); | |||
| 3577 | AbSyn elt = conditionElt->negate | |||
| 3578 | ? abNewNot(sposNone, conditionElt->absyn)abNew(AB_Not, sposNone,1, conditionElt->absyn) | |||
| 3579 | : conditionElt->absyn; | |||
| 3580 | list = listCons(AbSyn)(AbSyn_listPointer->Cons)(elt, list); | |||
| 3581 | condition = cdr(condition)((condition)->rest); | |||
| 3582 | } | |||
| 3583 | ||||
| 3584 | return listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(list); | |||
| 3585 | } | |||
| 3586 | ||||
| 3587 | localstatic TfCondElt | |||
| 3588 | scoCondListCondElt() | |||
| 3589 | { | |||
| 3590 | return scoConditionListToCondElt(scoCondList); | |||
| 3591 | } | |||
| 3592 | ||||
| 3593 | localstatic TfCondElt | |||
| 3594 | scoConditionListToCondElt(ScoConditionList conditionList) | |||
| 3595 | { | |||
| 3596 | AbSynList list = listNil(AbSyn)((AbSynList) 0); | |||
| 3597 | ScoConditionList condition = conditionList; | |||
| 3598 | if (condition == listNil(ScoCondition)((ScoConditionList) 0)) | |||
| 3599 | return NULL((void*)0); | |||
| 3600 | ||||
| 3601 | while (condition != listNil(ScoCondition)((ScoConditionList) 0)) { | |||
| 3602 | ScoCondition conditionElt = car(condition)((condition)->first); | |||
| 3603 | AbSyn elt = conditionElt->negate | |||
| 3604 | ? abNewNot(sposNone, conditionElt->absyn)abNew(AB_Not, sposNone,1, conditionElt->absyn) | |||
| 3605 | : conditionElt->absyn; | |||
| 3606 | list = listCons(AbSyn)(AbSyn_listPointer->Cons)(elt, list); | |||
| 3607 | condition = cdr(condition)((condition)->rest); | |||
| 3608 | } | |||
| 3609 | ||||
| 3610 | list = listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(list); | |||
| 3611 | return tfCondEltNew(conditionList->first->stab, list); | |||
| 3612 | } | |||
| 3613 | ||||
| 3614 | ||||
| 3615 | /* | |||
| 3616 | * Returns true iff a definition is found with the same | |||
| 3617 | * conditionalisation as the current symbol. | |||
| 3618 | */ | |||
| 3619 | localstatic Bool | |||
| 3620 | scobindCheckDefnPos(DeclInfo declInfo, DefnPos posn) | |||
| 3621 | { | |||
| 3622 | DefnPosList lpos = declInfo->defpos; | |||
| 3623 | ||||
| 3624 | while (lpos) { | |||
| 3625 | if (defposEqual(car(lpos)((lpos)->first), posn)) | |||
| 3626 | return false((int) 0); | |||
| 3627 | lpos = cdr(lpos)((lpos)->rest); | |||
| 3628 | } | |||
| 3629 | ||||
| 3630 | if (defposIsRoot(posn)) return true1; | |||
| 3631 | ||||
| 3632 | return scobindCheckDefnPos(declInfo, defposTail(posn)); | |||
| 3633 | } | |||
| 3634 | ||||
| 3635 | AbSynList | |||
| 3636 | scobindDefnPosToList(DefnPosList defnPosList) | |||
| 3637 | { | |||
| 3638 | AbSynList conditionList = listNil(AbSyn)((AbSynList) 0); | |||
| 3639 | while (defnPosList != listNil(DefnPos)((DefnPosList) 0)) { | |||
| 3640 | AbSynList absynList = defposToAbSyn(car(defnPosList)((defnPosList)->first)); | |||
| 3641 | defnPosList = cdr(defnPosList)((defnPosList)->rest); | |||
| 3642 | ||||
| 3643 | if (absynList == listNil(AbSyn)((AbSynList) 0)) | |||
| 3644 | conditionList = listCons(AbSyn)(AbSyn_listPointer->Cons)(NULL((void*)0), conditionList); | |||
| 3645 | else { | |||
| 3646 | AbSyn absyn = (cdr(absynList)((absynList)->rest) == listNil(AbSyn)((AbSynList) 0)) | |||
| 3647 | ? car(absynList)((absynList)->first) : abNewAndAll(sposNone, absynList); | |||
| 3648 | conditionList = listCons(AbSyn)(AbSyn_listPointer->Cons)(absyn, conditionList); | |||
| 3649 | } | |||
| 3650 | } | |||
| 3651 | return listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(conditionList); | |||
| 3652 | } | |||
| 3653 | ||||
| 3654 | /****************************************************************************** | |||
| 3655 | * | |||
| 3656 | * :: scobindAddMeaning | |||
| 3657 | * | |||
| 3658 | *****************************************************************************/ | |||
| 3659 | ||||
| 3660 | localstatic void | |||
| 3661 | scobindAddMeaning(AbSyn ab, Symbol sym, Stab stab, SymeTag kind, | |||
| 3662 | TForm tf, AInt data) | |||
| 3663 | { | |||
| 3664 | if (scobindNeedsMeaning(ab, tf)) { | |||
| 3665 | Syme syme = scobindDefMeaning(stab,kind,sym,tf,data); | |||
| 3666 | scobindSetMeaning(ab, syme); | |||
| 3667 | symeSetSrcPos(syme, abPos(ab))(symeSetFieldVal = ((AInt) ((spstackFirst((ab)->abHdr.pos) ))), (((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme )->lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_SrcPos))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_SrcPos )] = (symeSetFieldVal)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo[SYFI_SrcPos].def) ? symeSetFieldVal : symeSetFieldFn (syme,SYFI_SrcPos,symeSetFieldVal)); | |||
| 3668 | } | |||
| 3669 | } | |||
| 3670 | ||||
| 3671 | localstatic Bool | |||
| 3672 | scobindNeedsMeaning(AbSyn ab, TForm tf) | |||
| 3673 | { | |||
| 3674 | return ab == NULL((void*)0) || abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0) == NULL((void*)0) || | |||
| 3675 | symeIsLazy(abSyme(ab))(((((((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0 ))->kind == SYME_Trigger ? libGetAllSymes((((ab)->abHdr .seman ? (ab)->abHdr.seman->syme : 0))->lib) : ((void *)0)), (((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0)))->bits) & (0x0001)) || symeType(abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0)) != tf; | |||
| 3676 | } | |||
| 3677 | ||||
| 3678 | localstatic void | |||
| 3679 | scobindSetMeaning(AbSyn ab, Syme syme) | |||
| 3680 | { | |||
| 3681 | if (ab) { | |||
| 3682 | if (abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0) == NULL((void*)0)) { | |||
| 3683 | String s = abPrettyClippedIn(tfExpr(symeType(syme))tfToAbSyn(symeType(syme)), | |||
| 3684 | 60, ABPP_NOINDENT(-1)); | |||
| 3685 | ||||
| 3686 | comsgRemark(ab, ALDOR_R_ScoMeaning137, | |||
| 3687 | comsgString(symeTagToDescrMsgId(symeKind(syme))(symeInfo[((((syme)->kind == SYME_Trigger ? libGetAllSymes ((syme)->lib) : ((void*)0)), (syme))->kind)].msgId)), | |||
| 3688 | symeString(syme)((((syme)->id))->str), s); | |||
| 3689 | strFree(s); | |||
| 3690 | } | |||
| 3691 | abSetSyme(ab, syme); | |||
| 3692 | } | |||
| 3693 | } | |||
| 3694 | ||||
| 3695 | localstatic Syme | |||
| 3696 | scobindDefMeaning(Stab stab, SymeTag kind, Symbol sym, TForm tf, AInt data) | |||
| 3697 | { | |||
| 3698 | Syme syme = NULL((void*)0); | |||
| 3699 | ||||
| 3700 | switch (kind) { | |||
| 3701 | case SYME_Param: | |||
| 3702 | syme = stabDefParam(stab, sym, tf); | |||
| 3703 | break; | |||
| 3704 | case SYME_LexVar: | |||
| 3705 | syme = stabDefLexVar(stab, sym, tf); | |||
| 3706 | break; | |||
| 3707 | case SYME_LexConst: | |||
| 3708 | syme = stabDefLexConst(stab, sym, tf); | |||
| 3709 | break; | |||
| 3710 | case SYME_Fluid: | |||
| 3711 | syme = stabDefFluid(stab, sym, tf); | |||
| 3712 | break; | |||
| 3713 | case SYME_Export: | |||
| 3714 | syme = stabDefExport(stab, sym, tf, (Doc) data); | |||
| 3715 | break; | |||
| 3716 | case SYME_Builtin: | |||
| 3717 | syme = stabDefBuiltin(stab, sym, tf, (FoamBValTag) data); | |||
| 3718 | break; | |||
| 3719 | case SYME_Foreign: | |||
| 3720 | syme = stabDefForeign(stab, sym, tf, (ForeignOrigin) data); | |||
| 3721 | break; | |||
| 3722 | default: | |||
| 3723 | bugBadCase(kind)bug("Bad case %d (line %d in file %s).", (int) kind, 3723, "scobind.c" ); | |||
| 3724 | break; | |||
| 3725 | } | |||
| 3726 | ||||
| 3727 | return syme; | |||
| 3728 | } | |||
| 3729 | ||||
| 3730 | /****************************************************************************** | |||
| 3731 | * | |||
| 3732 | * :: scobindReconcile | |||
| 3733 | * | |||
| 3734 | *****************************************************************************/ | |||
| 3735 | ||||
| 3736 | localstatic void | |||
| 3737 | scobindReconcile(Stab stab, AbSynTag context) | |||
| 3738 | { | |||
| 3739 | SymbolList ids = car(stab)((stab)->first)->idsInScope; | |||
| 3740 | ||||
| 3741 | for (; ids; ids = cdr(ids)((ids)->rest)) { | |||
| 3742 | Symbol id = car(ids)((ids)->first); | |||
| 3743 | IdInfoList il = idInfoCell(id)((IdInfoList) (symCoInfo(id)->phaseVal.generic)); | |||
| 3744 | IdInfo info = car(il)((il)->first); | |||
| 3745 | ||||
| 3746 | ||||
| 3747 | /* The standard checks */ | |||
| 3748 | scobindReconcileId(stab, context, id, info); | |||
| 3749 | } | |||
| 3750 | } | |||
| 3751 | ||||
| 3752 | localstatic void | |||
| 3753 | scobindReconcileId(Stab stab, AbSynTag context, Symbol sym, IdInfo idInfo) | |||
| 3754 | { | |||
| 3755 | AbSyn abuse; | |||
| 3756 | ||||
| 3757 | if (idInfo->declInfoList) | |||
| 3758 | scobindReconcileDecls(stab, context, sym, idInfo); | |||
| 3759 | ||||
| 3760 | /* Check for bad uses or non-uses of locals. */ | |||
| 3761 | else if (idInfo->allLocal) { | |||
| 3762 | AbSyn ab = idInfo->exampleId; | |||
| 3763 | String str = symString(sym)((sym)->str); | |||
| 3764 | ||||
| 3765 | if (idInfo->allFree) | |||
| 3766 | comsgError(ab, ALDOR_E_ScoFreeAndLoc118, str); | |||
| 3767 | else if ((abuse = idInfo->uses[SCO_Id_Used]) != NULL((void*)0)) | |||
| 3768 | comsgWarning(abuse, ALDOR_W_ScoBadUse134, str); | |||
| 3769 | else | |||
| 3770 | comsgWarning(ab, ALDOR_W_ScoLocalNoUse135, str); | |||
| 3771 | ||||
| 3772 | if (idInfo->allFluid) | |||
| 3773 | bug("local, free, fluid, wassa matta?"); | |||
| 3774 | } | |||
| 3775 | else { | |||
| 3776 | /* | |||
| 3777 | * The identifier is not defined in this scope | |||
| 3778 | * level and so it must either be defined in an | |||
| 3779 | * outer level or it has been imported. Create | |||
| 3780 | * new usage information in the level outside | |||
| 3781 | * this one to allow the symbol meaning to be | |||
| 3782 | * bound in that level, if appropriate. | |||
| 3783 | */ | |||
| 3784 | abuse = idInfo->uses[SCO_Id_InType]; | |||
| 3785 | if (abuse && stab != stabFile()) { | |||
| 3786 | idInfo = getIdInfoInAnyScope(cdr(stab)((stab)->rest), abuse); | |||
| 3787 | idInfo->uses[SCO_Id_InType] = abuse; | |||
| 3788 | } | |||
| 3789 | abuse = idInfo->uses[SCO_Id_Used]; | |||
| 3790 | if (abuse && stab != stabFile()) { | |||
| 3791 | idInfo = getIdInfoInAnyScope(cdr(stab)((stab)->rest), abuse); | |||
| 3792 | idInfo->uses[SCO_Id_Used] = abuse; | |||
| 3793 | } | |||
| 3794 | } | |||
| 3795 | } | |||
| 3796 | ||||
| 3797 | localstatic void | |||
| 3798 | scobindReconcileDecls(Stab stab, AbSynTag context, Symbol sym, IdInfo idInfo) | |||
| 3799 | { | |||
| 3800 | Bool lazy = false((int) 0); | |||
| 3801 | AbSynList earlyUse; | |||
| 3802 | DeclInfoList declInfoList; | |||
| 3803 | AbSyn isAssigned = NULL((void*)0), isDefined = NULL((void*)0), isReffed = NULL((void*)0); | |||
| 3804 | ||||
| 3805 | /* Reverse list so we see signatures in correct order. */ | |||
| 3806 | idInfo->declInfoList = listNReverse(DeclInfo)(DeclInfo_listPointer->NReverse)(idInfo->declInfoList); | |||
| 3807 | declInfoList = idInfo->declInfoList; | |||
| 3808 | ||||
| 3809 | for ( ; declInfoList; declInfoList = cdr(declInfoList)((declInfoList)->rest)) { | |||
| 3810 | DeclInfo declInfo = car(declInfoList)((declInfoList)->first); | |||
| 3811 | AbSyn abuse; | |||
| 3812 | ||||
| 3813 | abuse = declInfo->uses[SCO_Sig_Assign]; | |||
| 3814 | if (abuse) { | |||
| 3815 | if (isAssigned) { | |||
| 3816 | comsgNError(isAssigned, ALDOR_E_ScoVarOverload129); | |||
| 3817 | comsgNote(abuse, ALDOR_N_Here3); | |||
| 3818 | abState(declInfo->id)((declInfo->id)->abHdr.state) = AB_State_Error; | |||
| 3819 | } | |||
| 3820 | isAssigned = abuse; | |||
| 3821 | if (fintMode == FINT_LOOP2 && isDefined) | |||
| 3822 | abState(declInfo->id)((declInfo->id)->abHdr.state) = AB_State_Error; | |||
| 3823 | } | |||
| 3824 | ||||
| 3825 | abuse = declInfo->uses[SCO_Sig_Define]; | |||
| 3826 | if (abuse && !isDefined) { | |||
| 3827 | isDefined = abuse; | |||
| 3828 | if (fintMode == FINT_LOOP2 && isAssigned) | |||
| 3829 | abState(declInfo->id)((declInfo->id)->abHdr.state) = AB_State_Error; | |||
| 3830 | } | |||
| 3831 | ||||
| 3832 | abuse = declInfo->uses[SCO_Sig_Reference]; | |||
| 3833 | if (abuse) | |||
| 3834 | isReffed = abuse; | |||
| 3835 | ||||
| 3836 | ||||
| 3837 | /* Does it look like a lazy value? */ | |||
| 3838 | if (!lazy && abIsAnyMap(declInfo->type)(((((declInfo->type)->abHdr.tag == (AB_Apply)) && (((((declInfo->type)->abApply.op))->abHdr.tag == (AB_Id )) && ((((declInfo->type)->abApply.op))->abId .sym)==(ssymArrow))) && (((declInfo->type)->abHdr .argc)-1) == 2) || ((((declInfo->type)->abHdr.tag == (AB_Apply )) && (((((declInfo->type)->abApply.op))->abHdr .tag == (AB_Id)) && ((((declInfo->type)->abApply .op))->abId.sym)==(ssymPackedArrow))) && (((declInfo ->type)->abHdr.argc)-1) == 2))) | |||
| 3839 | lazy = true1; | |||
| 3840 | ||||
| 3841 | scobindReconcileDecl(stab, context, sym, idInfo, declInfo); | |||
| 3842 | } | |||
| 3843 | ||||
| 3844 | ||||
| 3845 | /* Ensure id is not assigned and defined. */ | |||
| 3846 | if (isAssigned && isDefined) { | |||
| 3847 | comsgNError(isAssigned, ALDOR_E_ScoAssAndDef109, symString(sym)((sym)->str)); | |||
| 3848 | comsgNote(isDefined, ALDOR_N_Here3); | |||
| 3849 | } | |||
| 3850 | ||||
| 3851 | ||||
| 3852 | /* Ensure id is not referenced and defined */ | |||
| 3853 | if (isReffed && isDefined) { | |||
| 3854 | comsgNError(isReffed, ALDOR_E_ScoAssAndRef110, symString(sym)((sym)->str)); | |||
| 3855 | comsgNote(isDefined, ALDOR_N_Here3); | |||
| 3856 | } | |||
| 3857 | ||||
| 3858 | ||||
| 3859 | /* Ensure id is not library or archive identifier and assigned */ | |||
| 3860 | /* or defined. */ | |||
| 3861 | if (isAssigned || isDefined) { | |||
| 3862 | AbSyn ab = isAssigned ? isAssigned : isDefined; | |||
| 3863 | if (stabGetLibrary(sym) || stabGetArchive(sym)) | |||
| 3864 | comsgError(ab, ALDOR_E_ScoLibrary121, symString(sym)((sym)->str)); | |||
| 3865 | } | |||
| 3866 | ||||
| 3867 | ||||
| 3868 | /* | |||
| 3869 | * Ensure that non-lazy constants aren't used before their | |||
| 3870 | * definition outside an `add'. We don't seem to need to | |||
| 3871 | * watch for domains and categories as they never seem to | |||
| 3872 | * generate use-before-definition errors. If we do, try | |||
| 3873 | * extending the range of cases in which `lazy' is true. | |||
| 3874 | */ | |||
| 3875 | earlyUse = idInfo->usePreDef; | |||
| 3876 | if (!lazy && isDefined && earlyUse) { | |||
| 3877 | /* | |||
| 3878 | * Display an error for each use-before-definition of | |||
| 3879 | * non-lazy constants used outside and `add' body. | |||
| 3880 | * We don't need to reverse `earlyUse' because the | |||
| 3881 | * comsg system sorts messages by line number. | |||
| 3882 | */ | |||
| 3883 | for (;earlyUse; earlyUse = cdr(earlyUse)((earlyUse)->rest)) { | |||
| 3884 | AbSyn id = car(earlyUse)((earlyUse)->first); | |||
| 3885 | comsgNError(id, ALDOR_E_ScoEarlyUse138, symString(sym)((sym)->str)); | |||
| 3886 | comsgNote(isDefined, ALDOR_N_Here3); | |||
| 3887 | } | |||
| 3888 | } | |||
| 3889 | } | |||
| 3890 | ||||
| 3891 | /* | |||
| 3892 | * This function processes the data for a given signature. | |||
| 3893 | */ | |||
| 3894 | localstatic void | |||
| 3895 | scobindReconcileDecl(Stab stab, AbSynTag context, Symbol sym, IdInfo idInfo, | |||
| 3896 | DeclInfo declInfo) | |||
| 3897 | { | |||
| 3898 | AbSyn assigned = declInfo->uses[SCO_Sig_Assign]; | |||
| 3899 | ||||
| 3900 | /* Error if name used in type is a variable. */ | |||
| 3901 | ||||
| 3902 | if ((idInfo->uses[SCO_Id_InType] || declInfo->uses[SCO_Sig_InType]) | |||
| 3903 | && assigned) | |||
| 3904 | { | |||
| 3905 | comsgError(assigned, ALDOR_E_ScoAssTypeId111, symString(sym)((sym)->str)); | |||
| 3906 | } | |||
| 3907 | ||||
| 3908 | /* | |||
| 3909 | * Error if a loop variable is assigned to. The initial creation | |||
| 3910 | * of the loop variable will be an assignment, but if the use is | |||
| 3911 | * not the same then there has been a later assignment. | |||
| 3912 | */ | |||
| 3913 | ||||
| 3914 | if (declInfo->uses[SCO_Sig_Loop] && | |||
| 3915 | declInfo->uses[SCO_Sig_Loop] != assigned) | |||
| 3916 | { | |||
| 3917 | comsgError(assigned, ALDOR_E_ScoBadLoopAss114); | |||
| 3918 | } | |||
| 3919 | ||||
| 3920 | /* Leave early if we don't require symbol meaning generation */ | |||
| 3921 | ||||
| 3922 | if (declInfo->uses[SCO_Sig_Builtin] && declInfo->uses[SCO_Sig_Foreign]) | |||
| 3923 | comsgError(declInfo->uses[SCO_Sig_Builtin], | |||
| 3924 | ALDOR_E_ScoSameSig127); | |||
| 3925 | ||||
| 3926 | if (declInfo->uses[SCO_Sig_Builtin] || declInfo->uses[SCO_Sig_Foreign]) | |||
| 3927 | { | |||
| 3928 | if (declInfo->uses[SCO_Sig_Free]) | |||
| 3929 | comsgError(declInfo->uses[SCO_Sig_Free],ALDOR_E_ScoNoFree122); | |||
| 3930 | if (declInfo->uses[SCO_Sig_Local]) | |||
| 3931 | comsgError(declInfo->uses[SCO_Sig_Local],ALDOR_E_ScoNoFree122); | |||
| 3932 | if (declInfo->uses[SCO_Sig_Param]) | |||
| 3933 | comsgError(declInfo->uses[SCO_Sig_Free],ALDOR_E_ScoNoParm123); | |||
| 3934 | if (assigned) | |||
| 3935 | comsgError(assigned, ALDOR_E_ScoNoSet124); | |||
| 3936 | if (declInfo->uses[SCO_Sig_Define]) | |||
| 3937 | comsgError(declInfo->uses[SCO_Sig_Define],ALDOR_E_ScoNoSet124); | |||
| 3938 | return; | |||
| 3939 | } | |||
| 3940 | ||||
| 3941 | if (declInfo->uses[SCO_Sig_Free] || declInfo->uses[SCO_Sig_Param]) | |||
| 3942 | return; | |||
| 3943 | ||||
| 3944 | /* Process explicit locals */ | |||
| 3945 | ||||
| 3946 | if (declInfo->uses[SCO_Sig_Local]) { | |||
| 3947 | TForm tf = scobindTfSyntaxFrAbSyn(stab, declInfo->type); | |||
| 3948 | ||||
| 3949 | if (declInfo->uses[SCO_Sig_Define]) { | |||
| 3950 | checkOuterUseOfLexicalConstant(stab, declInfo->id); | |||
| 3951 | scobindAddMeaning(declInfo->id,sym,stab,SYME_LexConst, | |||
| 3952 | tf, (AInt) NULL((void*)0)); | |||
| 3953 | return; | |||
| 3954 | } | |||
| 3955 | ||||
| 3956 | if (assigned) { | |||
| 3957 | scobindAddMeaning(declInfo->id,sym,stab,SYME_LexVar, | |||
| 3958 | tf, (AInt) NULL((void*)0)); | |||
| 3959 | return; | |||
| 3960 | } | |||
| 3961 | ||||
| 3962 | /* we seem to need to make the syme to keep tinfer happy */ | |||
| 3963 | ||||
| 3964 | scobindAddMeaning(declInfo->id,sym,stab,SYME_LexConst, | |||
| 3965 | tf, (AInt) NULL((void*)0)); | |||
| 3966 | ||||
| 3967 | /* check for use without assignment or definition */ | |||
| 3968 | ||||
| 3969 | if (idInfo->uses[SCO_Id_Used]) | |||
| 3970 | comsgWarning(idInfo->uses[SCO_Id_Used], | |||
| 3971 | ALDOR_W_ScoBadUse134, symString(sym)((sym)->str)); | |||
| 3972 | else if (declInfo->uses[SCO_Sig_Used]) | |||
| 3973 | comsgWarning(declInfo->uses[SCO_Sig_Used], | |||
| 3974 | ALDOR_W_ScoBadUse134, symString(sym)((sym)->str)); | |||
| 3975 | else if (! declInfo->uses[SCO_Sig_FreeRef]) | |||
| 3976 | comsgWarning(declInfo->uses[SCO_Sig_Local], | |||
| 3977 | ALDOR_W_ScoLocalNoUse135, symString(sym)((sym)->str)); | |||
| 3978 | return; | |||
| 3979 | } | |||
| 3980 | if (declInfo->uses[SCO_Sig_Fluid]) { | |||
| 3981 | TForm tf; | |||
| 3982 | if (abIsNothing(declInfo->type)((declInfo->type)->abHdr.tag == (AB_Nothing))) | |||
| 3983 | tf = tfUnknown; | |||
| 3984 | else | |||
| 3985 | tf = scobindTfSyntaxFrAbSyn(stab,declInfo->type); | |||
| 3986 | ||||
| 3987 | scoFluidDEBUGif (!scoFluidDebug) { } else afprintf(dbOut, "Adding fluid: %s", symString(sym)((sym)->str)); | |||
| 3988 | if (DEBUG(scoFluid)scoFluidDebug) { | |||
| 3989 | tfPrintDb(tf); | |||
| 3990 | } | |||
| 3991 | ||||
| 3992 | if (!scobindCheckOuterUseOfFluid(declInfo->id, declInfo->type)) { | |||
| 3993 | scoFluidDEBUGif (!scoFluidDebug) { } else afprintf(dbOut, " New\n"); | |||
| 3994 | scobindAddMeaning(declInfo->id, sym, stab, SYME_Fluid, | |||
| 3995 | tf, (AInt) NULL((void*)0)); | |||
| 3996 | } | |||
| 3997 | else | |||
| 3998 | scoFluidDEBUGif (!scoFluidDebug) { } else afprintf(dbOut, " See'd it before.\n"); | |||
| 3999 | return; | |||
| 4000 | } | |||
| 4001 | ||||
| 4002 | /* Signature without 'local' declaration. */ | |||
| 4003 | ||||
| 4004 | if (assigned) { | |||
| 4005 | TForm tf; | |||
| 4006 | ||||
| 4007 | if (context != AB_Apply) | |||
| 4008 | checkOuterUseOfImplicitLocal(stab, | |||
| 4009 | assigned, | |||
| 4010 | declInfo->type); | |||
| 4011 | ||||
| 4012 | tf = scobindTfSyntaxFrAbSyn(stab, declInfo->type); | |||
| 4013 | ||||
| 4014 | if (fintMode == FINT_LOOP2) { | |||
| 4015 | if (abSyme(declInfo->id)((declInfo->id)->abHdr.seman ? (declInfo->id)->abHdr .seman->syme : 0)) | |||
| 4016 | return; | |||
| 4017 | if (tfIsUnknown(tf)(((tf)->tag) == TF_Unknown) && stabGetLex(stab, sym)) | |||
| 4018 | return; | |||
| 4019 | } | |||
| 4020 | ||||
| 4021 | scobindAddMeaning(declInfo->id, sym, stab, SYME_LexVar, | |||
| 4022 | tf, (AInt) NULL((void*)0)); | |||
| 4023 | return; | |||
| 4024 | } | |||
| 4025 | ||||
| 4026 | if (declInfo->uses[SCO_Sig_Define]) { | |||
| 4027 | TForm tf = scobindTfSyntaxFrAbSyn(stab, declInfo->type); | |||
| 4028 | if (context == AB_Add || context == AB_With) { | |||
| 4029 | Syme syme; | |||
| 4030 | AbSynList defConditions; | |||
| 4031 | if (!abSyme(declInfo->id)((declInfo->id)->abHdr.seman ? (declInfo->id)->abHdr .seman->syme : 0)) | |||
| 4032 | scobindAddMeaning(declInfo->id, | |||
| 4033 | sym, stab, SYME_Export, | |||
| 4034 | tf, (AInt) declInfo->doc); | |||
| 4035 | assert(abSyme(declInfo->id))do { if (!(((declInfo->id)->abHdr.seman ? (declInfo-> id)->abHdr.seman->syme : 0))) _do_assert(("abSyme(declInfo->id)" ),"scobind.c",4035); } while (0); | |||
| 4036 | syme = abSyme(declInfo->id)((declInfo->id)->abHdr.seman ? (declInfo->id)->abHdr .seman->syme : 0); | |||
| 4037 | defConditions = scobindDefnPosToList(declInfo->defpos); | |||
| 4038 | symeSetDefinitionConditions(syme, defConditions)(symeSetFieldVal = ((AInt) (defConditions)), (((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0 )), (syme))->locmask) & (1 << (SYFI_DefinitionConditions ))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_DefinitionConditions )] = (symeSetFieldVal)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo[SYFI_DefinitionConditions].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_DefinitionConditions,symeSetFieldVal )); | |||
| 4039 | } | |||
| 4040 | else { | |||
| 4041 | checkOuterUseOfLexicalConstant(stab, declInfo->id); | |||
| 4042 | scobindAddMeaning(declInfo->id, sym, stab, | |||
| 4043 | SYME_LexConst, tf, (AInt) NULL((void*)0)); | |||
| 4044 | ||||
| 4045 | if (context != AB_Apply) | |||
| 4046 | checkOuterUseOfImplicitLocal(stab, | |||
| 4047 | declInfo->uses[SCO_Sig_Define], | |||
| 4048 | declInfo->type); | |||
| 4049 | ||||
| 4050 | scobindSetSigUse(declInfo, SCO_Sig_ImplicitLocal, | |||
| 4051 | declInfo->uses[SCO_Sig_Define]); | |||
| 4052 | } | |||
| 4053 | return; | |||
| 4054 | } | |||
| 4055 | ||||
| 4056 | if (abSyme(declInfo->id)((declInfo->id)->abHdr.seman ? (declInfo->id)->abHdr .seman->syme : 0)) | |||
| 4057 | return; | |||
| 4058 | ||||
| 4059 | /* make anything else into a lexical constant */ | |||
| 4060 | ||||
| 4061 | scobindAddMeaning(declInfo->id, sym, stab, SYME_LexConst, | |||
| 4062 | scobindTfSyntaxFrAbSyn(stab, declInfo->type), (AInt) NULL((void*)0)); | |||
| 4063 | } | |||
| 4064 | ||||
| 4065 | /****************************************************************************** | |||
| 4066 | * | |||
| 4067 | * :: scobindPrint | |||
| 4068 | * | |||
| 4069 | *****************************************************************************/ | |||
| 4070 | ||||
| 4071 | void | |||
| 4072 | scobindPrint(Stab stab) | |||
| 4073 | { | |||
| 4074 | scobindPrintStab(stab); | |||
| 4075 | } | |||
| 4076 | ||||
| 4077 | localstatic void | |||
| 4078 | scobindPrintStab(Stab stab) | |||
| 4079 | { | |||
| 4080 | SymbolList ids; | |||
| 4081 | ||||
| 4082 | for (ids = car(stab)((stab)->first)->idsInScope; ids; ids = cdr(ids)((ids)->rest)) { | |||
| 4083 | scobindPrintId(car(ids)((ids)->first)); | |||
| 4084 | if (cdr(ids)((ids)->rest)) fnewline(dbOut); | |||
| 4085 | } | |||
| 4086 | } | |||
| 4087 | ||||
| 4088 | localstatic void | |||
| 4089 | scobindPrintId(Symbol id) | |||
| 4090 | { | |||
| 4091 | IdInfoList il = idInfoCell(id)((IdInfoList) (symCoInfo(id)->phaseVal.generic)); | |||
| 4092 | IdInfo info = (il ? car(il)((il)->first) : NULL((void*)0)); | |||
| 4093 | DeclInfoList dil; | |||
| 4094 | Length i; | |||
| 4095 | ||||
| 4096 | if (!info) return; | |||
| 4097 | ||||
| 4098 | fprintf(dbOut, " %-14s: ", symString(id)((id)->str)); | |||
| 4099 | scobindPrintIdInfo(info); | |||
| 4100 | for (i = 1, dil = info->declInfoList; dil; i += 1, dil = cdr(dil)((dil)->rest)) | |||
| 4101 | scobindPrintDeclInfo(i, car(dil)((dil)->first)); | |||
| 4102 | } | |||
| 4103 | ||||
| 4104 | localstatic void | |||
| 4105 | scobindPrintIdInfo(IdInfo info) | |||
| 4106 | { | |||
| 4107 | Length c; | |||
| 4108 | ||||
| 4109 | if (info->allFree) | |||
| 4110 | fprintf(dbOut, "AllFree "); | |||
| 4111 | if (info->allLocal) | |||
| 4112 | fprintf(dbOut, "AllLocal "); | |||
| 4113 | if (info->allFluid) | |||
| 4114 | fprintf(dbOut, "AllFluid "); | |||
| 4115 | ||||
| 4116 | for (c = SCO_Id_START; c < SCO_Id_LIMIT; c += 1) | |||
| 4117 | if (info->uses[c]) | |||
| 4118 | fprintf(dbOut, "%s ", IdContextNames[c]); | |||
| 4119 | ||||
| 4120 | if (info->defaultType) { | |||
| 4121 | fprintf(dbOut, "Default ("); | |||
| 4122 | abPrettyPrintClippedIn(dbOut, info->defaultType, | |||
| 4123 | ABPP_UNCLIPPED(200000L), 1); | |||
| 4124 | fprintf(dbOut, ")"); | |||
| 4125 | } | |||
| 4126 | } | |||
| 4127 | ||||
| 4128 | localstatic void | |||
| 4129 | scobindPrintDeclInfo(Length i, DeclInfo declInfo) | |||
| 4130 | { | |||
| 4131 | Length c; | |||
| 4132 | ||||
| 4133 | fnewline(dbOut); | |||
| 4134 | fprintf(dbOut, " %-14s: [%d] ", " ", (int) i); | |||
| 4135 | ||||
| 4136 | if (declInfo->type) { | |||
| 4137 | fprintf(dbOut, "<"); | |||
| 4138 | abPrettyPrintClippedIn(dbOut, declInfo->type, | |||
| 4139 | ABPP_UNCLIPPED(200000L), 1); | |||
| 4140 | fprintf(dbOut, "> "); | |||
| 4141 | } | |||
| 4142 | ||||
| 4143 | for (c = SCO_Sig_START; c < SCO_Sig_LIMIT; c += 1) | |||
| 4144 | if (declInfo->uses[c]) | |||
| 4145 | fprintf(dbOut, "%s ", DeclContextNames[c]); | |||
| 4146 | } | |||
| 4147 | ||||
| 4148 | /****************************************************************************** | |||
| 4149 | * | |||
| 4150 | * :: scobindUndo | |||
| 4151 | * | |||
| 4152 | *****************************************************************************/ | |||
| 4153 | ||||
| 4154 | localstatic void | |||
| 4155 | scobindUndo() | |||
| 4156 | { | |||
| 4157 | scoUndoSymes = listNil(Syme)((SymeList) 0); | |||
| 4158 | scoUndoTForms = listNil(TForm)((TFormList) 0); | |||
| 4159 | ||||
| 4160 | scoUndoStab(scoStab); | |||
| 4161 | ||||
| 4162 | listFreeDeeply(Syme)(Syme_listPointer->FreeDeeply)(scoUndoSymes, symeFree); | |||
| 4163 | listFreeDeeply(TForm)(TForm_listPointer->FreeDeeply)(scoUndoTForms, tfFree); | |||
| 4164 | ||||
| 4165 | scoUndoState = false((int) 0); | |||
| 4166 | } | |||
| 4167 | ||||
| 4168 | localstatic void | |||
| 4169 | scoUndoStab(Stab stab) | |||
| 4170 | { | |||
| 4171 | StabLevel stabLev; | |||
| 4172 | StabList stabl; | |||
| 4173 | ||||
| 4174 | for (stabLev = car(stab)((stab)->first); stab; stab = cdr(stab)((stab)->rest)) { | |||
| 4175 | scoUndoStabLevel(stabLev); | |||
| 4176 | for (stabl = stabLev->children; stabl; stabl = cdr(stabl)((stabl)->rest)) | |||
| 4177 | scoUndoStab(car(stabl)((stabl)->first)); | |||
| 4178 | } | |||
| 4179 | } | |||
| 4180 | ||||
| 4181 | localstatic void | |||
| 4182 | scoUndoStabLevel(StabLevel stabLev) | |||
| 4183 | { | |||
| 4184 | tblRemoveIf(stabLev->tbl, (TblFreeEltFun) stoFree, | |||
| 4185 | (TblTestEltFun) scoUndoStabEntry); | |||
| 4186 | ||||
| 4187 | stabLev->boundSymes= listFreeIfSat(Syme)(Syme_listPointer->FreeIfSat) | |||
| 4188 | (stabLev->boundSymes, scoUndoSyme, isNewSyme); | |||
| 4189 | ||||
| 4190 | stabLev->tformsUsed.list = listFreeIfSat(TFormUses)(TFormUses_listPointer->FreeIfSat) | |||
| 4191 | (stabLev->tformsUsed.list, scoUndoTFormUses, isNewTFormUses); | |||
| 4192 | ||||
| 4193 | if (stabLev->tformsUsed.table) | |||
| 4194 | tblRemoveIf(stabLev->tformsUsed.table, | |||
| 4195 | (TblFreeEltFun) scoUndoTFormUses, | |||
| 4196 | (TblTestEltFun) isNewTFormUses); | |||
| 4197 | ||||
| 4198 | stabLev->tformsUnused = listFreeIfSat(TForm)(TForm_listPointer->FreeIfSat) | |||
| 4199 | (stabLev->tformsUnused, scoUndoTForm, isNewTForm); | |||
| 4200 | } | |||
| 4201 | ||||
| 4202 | localstatic Bool | |||
| 4203 | scoUndoStabEntry(StabEntry stent) | |||
| 4204 | { | |||
| 4205 | SymeList osymes, nsymes; | |||
| 4206 | Length oldLength; | |||
| 4207 | ||||
| 4208 | if (!stent) return false((int) 0); | |||
| 4209 | ||||
| 4210 | osymes = stent->symev[0]; | |||
| 4211 | oldLength = listLength(Syme)(Syme_listPointer->_Length)(osymes); | |||
| 4212 | ||||
| 4213 | nsymes = listFreeIfSat(Syme)(Syme_listPointer->FreeIfSat)(osymes, scoUndoSyme, isNewSyme); | |||
| 4214 | stent->symev[0] = nsymes; | |||
| 4215 | ||||
| 4216 | if (listLength(Syme)(Syme_listPointer->_Length)(nsymes) != oldLength) { | |||
| 4217 | tpossFree(stent->possv[0]); | |||
| 4218 | stent->possv[0] = NULL((void*)0); | |||
| 4219 | } | |||
| 4220 | ||||
| 4221 | return (nsymes == listNil(Syme)((SymeList) 0)); | |||
| 4222 | } | |||
| 4223 | ||||
| 4224 | localstatic void | |||
| 4225 | scoUndoSyme(Syme syme) | |||
| 4226 | { | |||
| 4227 | if (!listMemq(Syme)(Syme_listPointer->Memq)(scoUndoSymes, syme)) | |||
| 4228 | scoUndoSymes = listCons(Syme)(Syme_listPointer->Cons)(syme, scoUndoSymes); | |||
| 4229 | } | |||
| 4230 | ||||
| 4231 | localstatic void | |||
| 4232 | scoUndoTForm(TForm tf) | |||
| 4233 | { | |||
| 4234 | if (!listMemq(TForm)(TForm_listPointer->Memq)(scoUndoTForms, tf)) | |||
| 4235 | scoUndoTForms = listCons(TForm)(TForm_listPointer->Cons)(tf, scoUndoTForms); | |||
| 4236 | } | |||
| 4237 | ||||
| 4238 | localstatic void | |||
| 4239 | scoUndoTFormUses(TFormUses tfu) | |||
| 4240 | { | |||
| 4241 | scoUndoTForm(tfu->tf); | |||
| 4242 | /* stoFree(tfu); $$ USE tfUsesPool or intStepNo or refCounter */ | |||
| 4243 | } | |||
| 4244 | ||||
| 4245 | localstatic Bool | |||
| 4246 | isNewSyme(Syme syme) | |||
| 4247 | { | |||
| 4248 | return symeIntStepNo(syme)((UShort) (SYFI_IntStepNo < (8 * sizeof(int)) && ! (((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)-> lib) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_IntStepNo ))) ? (symeFieldInfo[SYFI_IntStepNo].def) : (((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0 )), (syme))->locmask) & (1 << (SYFI_IntStepNo))) ? ((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme )->lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_IntStepNo))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_IntStepNo )] : (symeFieldInfo[SYFI_IntStepNo].def)) : symeGetFieldFn(syme ,SYFI_IntStepNo))) == intStepNo - 1; | |||
| 4249 | } | |||
| 4250 | ||||
| 4251 | localstatic Bool | |||
| 4252 | isNewTForm(TForm tf) | |||
| 4253 | { | |||
| 4254 | return tf->intStepNo == intStepNo - 1; | |||
| 4255 | } | |||
| 4256 | ||||
| 4257 | localstatic Bool | |||
| 4258 | isNewTFormUses(TFormUses tfu) | |||
| 4259 | { | |||
| 4260 | return tfu->tf->intStepNo == intStepNo - 1; | |||
| 4261 | } | |||
| 4262 | ||||
| 4263 | ||||
| 4264 | /****************************************************************************** | |||
| 4265 | * | |||
| 4266 | * :: Setting conditions | |||
| 4267 | * | |||
| 4268 | *****************************************************************************/ | |||
| 4269 | ||||
| 4270 | localstatic void scobindTfConditions(Stab stab, TForm tf, TfCondElt conditions); | |||
| 4271 | ||||
| 4272 | localstatic TForm | |||
| 4273 | scobindTfSyntaxFrAbSyn(Stab stab, AbSyn ab) | |||
| 4274 | { | |||
| 4275 | TForm tf = tfSyntaxFrAbSyn(stab, ab); | |||
| 4276 | scobindTfConditions(stab, tf, scoCondListCondElt()); | |||
| 4277 | return tf; | |||
| 4278 | } | |||
| 4279 | ||||
| 4280 | localstatic void | |||
| 4281 | scobindTfConditions(Stab stab, TForm tf, TfCondElt conditions) | |||
| 4282 | { | |||
| 4283 | if (!tfIsPending(tf)(((tf)->state)==TF_State_Pending)) | |||
| 4284 | return; | |||
| 4285 | ||||
| 4286 | if (conditions == NULL((void*)0)) | |||
| 4287 | return; | |||
| 4288 | ||||
| 4289 | tfSyntaxConditions(stab, tf, conditions); | |||
| 4290 | } | |||
| 4291 | ||||
| 4292 | /****************************************************************************** | |||
| 4293 | * | |||
| 4294 | * :: LambdaInfo | |||
| 4295 | * | |||
| 4296 | *****************************************************************************/ | |||
| 4297 | ||||
| 4298 | localstatic LambdaInfo | |||
| 4299 | lambdaInfoAlloc(AbSyn lhs, AbSyn rhs, ScoConditionList condition) | |||
| 4300 | { | |||
| 4301 | LambdaInfo info = (LambdaInfo) stoAlloc(OB_Other0, sizeof(*info)); | |||
| 4302 | info->lhs = lhs; | |||
| 4303 | info->rhs = rhs; | |||
| 4304 | info->scoCondList = condition; | |||
| 4305 | ||||
| 4306 | return info; | |||
| 4307 | } | |||
| 4308 | ||||
| 4309 | localstatic void | |||
| 4310 | lambdaInfoFree(LambdaInfo info) | |||
| 4311 | { | |||
| 4312 | stoFree(info); | |||
| 4313 | } |