FoxFingerPrinter.Mod 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388
  1. MODULE FoxFingerPrinter; (** AUTHOR "fof"; PURPOSE "FingerPrinting"; *)
  2. (* literature for the fingerprinting: Dissertation Crelier *)
  3. IMPORT SyntaxTree := FoxSyntaxTree, Basic := FoxBasic, SYSTEM, Global := FoxGlobal,Scanner := FoxScanner,
  4. D := Debugging, Streams;
  5. (** FingerPrinting
  6. FP(TypeDeclaration) = 0 <*> fpModeType -> Name -> Visibility <*> FP(Type).
  7. FP(ConstantDeclaration) = 0 <*> fpModeConstant -> Name -> Visibility <*> FP(Type) -> Basic -> Value.
  8. FP(VariableDeclaration) = 0 <*> fpModePar -> Name -> Visibility <*> FP(Type).
  9. FP(ProcedureDeclaration) = 0 <*> fpModeInlineProcedure -> Name -> Visibility <*> FP(Type) -> Code.
  10. | 0 <*> fpModeExportedProcedure -> Name -> Visibility <*> FP(Type)
  11. Name(fp,name) = fp <*> name[0] <*> ... <*> name[n].
  12. Visibility(fp,vis) = fp <*> fpExtern | fp <*> fpExternR | fp <*> fpOther <*> vis.
  13. Value(fp) = fp <*> fpTrue | fp <*> fpFalse | fp <*> integer | fp <*> intlow <*> inthigh | fp -> Name
  14. FP(Type) = FP(BasicType) | FP(RecordType) | FP(PointerType)
  15. | FP(ArrayType) | FP(MathArrayType) | FP(ProcedurType)
  16. FP(BasicType) = fpTypeChar8 | fpTypeChar16 | fpTypeChar32
  17. | fpTypeShortint | fpTypeInteger | fpTypeLongint | fpTypeHugeint
  18. | fpTypeReal | fpTypeLongreal
  19. | fpTypeSet | fpTypePointer |fpTypeString
  20. | fpTypeByte | fpTypeAll | fpTypeSame | fpTypeRange | fpTypeBoolean.
  21. PublicFP(BasicType) = FP(basicType).
  22. PrivateFP(BasicType) = sizeof(basicType).
  23. FP(RecordType) = fpTypeComposite <*> fptypeRecord
  24. [ -> Name(moduleName) -> Name(typeName)] [<*> FP(baseType)]
  25. PublicFP(RecordType) = FP(recordType) [<*> PublicFP(baseType)] {<*> FP(method) <*> methodNumber }
  26. {<*> PublicFP(fieldType) <*> offset(field) <*> FP(field)} <*> flags.
  27. PrivateFP(RecordType) = FP(recordType) [<*> PrivateFP(baseType)] {<*> FP(method) <*> methodNumber }
  28. {<*> PrivateFP(fieldType) <*> offset(field) <*> FP(field)}
  29. FP(Method) = 0 <*> fpModeMethod -> Name(methodName) -> Signature(method).
  30. FP(Field) = 0 <*> fpModeField -> Name(fieldName) -> Visibility [<*> fpUntraced] <*> FP(type).
  31. FP(PointerType) = fpTypePointer <*> fpTypeBasic -> Name <*> FP(baseType).
  32. PublicFP(PointerType) = 0.
  33. PrivateFP(PointerType) = 0.
  34. FP(ArrayType) = fpTypeComposite <*> (fpTypeOpenArray | fpTypeStaticArray)
  35. -> Name <*> FP(baseType) [<*> length].
  36. PublicFP(ArrayType) = FP(arrayType).
  37. PrivateFP(ArrayType) = FP(arrayType).
  38. FP(MathArrayType) = fpTypeComposite <*> (fpTypeOpenArray | fpTypeStaticArray)
  39. -> Name <*> FP(baseType) [<*> length].
  40. PublicFP(MathArrayType) = FP(arrayType).
  41. PrivateFP(MathArrayType) = FP(arrayType).
  42. FP(ProcedureType) = fpTypeProcedure <*> fpTypeBasic [<*> fpDelegate]-> Name.
  43. PublicFP(ProcedureType) = FP(arrayType) -> Signature(procedureType)
  44. PrivateFP(ProcedureType) = FP(arrayType)-> Signature(procedureType).
  45. Signature(f) = f <*> FP(returnType)
  46. { <*> (fpModeVarParameter | fpModeConstParameter | fpModePar)
  47. <*> FP(parameterType) [-> Name(parameterName)] }
  48. **)
  49. CONST
  50. (*FingerPrints/Obj Modes*)
  51. fpModeVar=1;
  52. fpModePar=1;
  53. fpModeVarPar=2;
  54. fpModeConstPar=fpModeVarPar; (*! for compatibility, must be changed *)
  55. fpModeConst=3;
  56. fpModeField=4;
  57. fpModeType=5;
  58. fpModeExportedProcedure=7;
  59. fpModeInlineProcedure=9;
  60. fpModeMethod=13;
  61. (*FingerPrints/Type Forms*)
  62. fpTypeByte = 1;
  63. fpTypeBoolean=2;
  64. fpTypeChar8=3;
  65. fpTypeShortint=4;
  66. fpTypeInteger=5;
  67. fpTypeLongint=6;
  68. fpTypeReal=7;
  69. fpTypeLongreal=8;
  70. fpTypeSet=9;
  71. fpTypeString=10;
  72. fpTypeNone = 12;
  73. fpTypePointer=13;
  74. fpTypeProcedure=14;
  75. fpTypeComposite=15;
  76. fpTypeHugeint=16;
  77. fpTypeChar16 = 17;
  78. fpTypeChar32 = 18;
  79. fpTypeAll = 19;
  80. fpTypeSame = 20;
  81. fpTypeRange = 21;
  82. fpTypeEnum = 22;
  83. fpTypePort = 23;
  84. fpTypeChannel = 23;
  85. fpTypeComplex = 24;
  86. fpTypeLongcomplex = 25;
  87. fpTypeModule=26;
  88. fpTypeSize=27;
  89. fpTypeAddress=28;
  90. fpTypeBasic=1;
  91. fpTypeStaticArray=2;
  92. fpTypeDynamicArray=4;
  93. fpTypeOpenArray=5;
  94. fpTypeRecord=6;
  95. fpIntern=0;
  96. fpExtern=1;
  97. fpExternR=2;
  98. fpOther =3;
  99. fpFalse=0;
  100. fpTrue=1;
  101. fpHasBody = 1;
  102. fpProtected =4;
  103. fpActive = 5;
  104. fpDelegate = 5;
  105. fpSystemType = 6;
  106. fpUntraced = 4;
  107. Trace=FALSE;
  108. TYPE
  109. FingerPrint = SyntaxTree.FingerPrint;
  110. FingerPrinter*= OBJECT (SyntaxTree.Visitor)
  111. VAR
  112. fp-: LONGINT; (* temporary fingerprint for values etc. *)
  113. fingerprint: FingerPrint;
  114. deep: BOOLEAN; (* public / private field of FP needed ? *)
  115. traceLevel: LONGINT;
  116. level: LONGINT;
  117. PROCEDURE & InitFingerPrinter*();
  118. BEGIN fp:= 0; deep := FALSE; traceLevel := 0;
  119. END InitFingerPrinter;
  120. (** types *)
  121. (*
  122. FP(BasicType) = | fpTypeByte | fpTypeAll | fpTypeSame | fpTypeRange | fpTypeBoolean.
  123. | fpTypeSet | fpTypePointer
  124. PublicFP(BasicType) = FP(basicType).
  125. PrivateFP(BasicType) = sizeof(basicType).
  126. *)
  127. PROCEDURE VisitBasicType*(x: SyntaxTree.BasicType);
  128. BEGIN
  129. END VisitBasicType;
  130. PROCEDURE SetTypeFingerprint(x: SyntaxTree.Type; fp: LONGINT);
  131. VAR fingerprint: FingerPrint;
  132. BEGIN
  133. fingerprint := x.fingerprint;
  134. IF ~fingerprint.shallowAvailable THEN
  135. fingerprint.shallow := fp;
  136. fingerprint.public := fp;
  137. fingerprint.private := fp;
  138. fingerprint.shallowAvailable := TRUE;
  139. fingerprint.deepAvailable := TRUE; (* no distinction between deep and shallow fp necessary *)
  140. x.SetFingerPrint(fingerprint);
  141. END;
  142. SELF.fingerprint := fingerprint;
  143. END SetTypeFingerprint;
  144. PROCEDURE VisitRangeType*(x: SyntaxTree.RangeType);
  145. VAR fingerprint: FingerPrint;
  146. BEGIN
  147. SetTypeFingerprint(x,fpTypeRange);
  148. END VisitRangeType;
  149. PROCEDURE VisitBooleanType*(x: SyntaxTree.BooleanType);
  150. BEGIN
  151. SetTypeFingerprint(x,fpTypeBoolean);
  152. END VisitBooleanType;
  153. PROCEDURE VisitByteType*(x: SyntaxTree.ByteType);
  154. BEGIN
  155. SetTypeFingerprint(x,fpTypeByte)
  156. END VisitByteType;
  157. PROCEDURE VisitSetType*(x: SyntaxTree.SetType);
  158. BEGIN
  159. SetTypeFingerprint(x,fpTypeSet)
  160. END VisitSetType;
  161. PROCEDURE VisitNilType*(x: SyntaxTree.NilType);
  162. BEGIN
  163. SetTypeFingerprint(x,fpTypePointer)
  164. END VisitNilType;
  165. PROCEDURE VisitAnyType*(x: SyntaxTree.AnyType);
  166. BEGIN
  167. SetTypeFingerprint(x,fpTypePointer)
  168. END VisitAnyType;
  169. PROCEDURE VisitAddressType*(x: SyntaxTree.AddressType);
  170. BEGIN
  171. SetTypeFingerprint(x,fpTypeAddress)
  172. END VisitAddressType;
  173. PROCEDURE VisitSizeType*(x: SyntaxTree.SizeType);
  174. BEGIN
  175. SetTypeFingerprint(x, fpTypeSize);
  176. END VisitSizeType;
  177. PROCEDURE VisitObjectType*(x: SyntaxTree.ObjectType);
  178. BEGIN
  179. SetTypeFingerprint(x,fpTypePointer)
  180. END VisitObjectType;
  181. (*
  182. FP(BasicType) = fpTypeChar8 | fpTypeChar16 | fpTypeChar32
  183. PublicFP(BasicType) = FP(basicType).
  184. PrivateFP(BasicType) = sizeof(basicType).
  185. *)
  186. PROCEDURE VisitCharacterType*(x: SyntaxTree.CharacterType);
  187. BEGIN
  188. IF x.sizeInBits = 8 THEN SetTypeFingerprint(x,fpTypeChar8)
  189. ELSIF x.sizeInBits = 16 THEN SetTypeFingerprint(x,fpTypeChar16)
  190. ELSIF x.sizeInBits =32 THEN SetTypeFingerprint(x,fpTypeChar32)
  191. ELSE HALT(100)
  192. END;
  193. END VisitCharacterType;
  194. (*
  195. FP(BasicType) = fpTypeShortint | fpTypeInteger | fpTypeLongint | fpTypeLongint
  196. PublicFP(BasicType) = FP(basicType).
  197. PrivateFP(BasicType) = sizeof(basicType).
  198. *)
  199. PROCEDURE VisitIntegerType*(x: SyntaxTree.IntegerType);
  200. BEGIN
  201. IF x.sizeInBits=8 THEN SetTypeFingerprint(x,fpTypeShortint)
  202. ELSIF x.sizeInBits = 16 THEN SetTypeFingerprint(x,fpTypeInteger)
  203. ELSIF x.sizeInBits = 32 THEN SetTypeFingerprint(x,fpTypeLongint)
  204. ELSIF x.sizeInBits = 64 THEN SetTypeFingerprint(x,fpTypeHugeint)
  205. ELSE HALT(100)
  206. END;
  207. END VisitIntegerType;
  208. (*
  209. FP(BasicType) = fpTypeReal | fpTypeLongreal
  210. PublicFP(BasicType) = FP(basicType).
  211. PrivateFP(BasicType) = sizeof(basicType).
  212. *)
  213. PROCEDURE VisitFloatType*(x: SyntaxTree.FloatType);
  214. BEGIN
  215. IF x.sizeInBits = 32 THEN SetTypeFingerprint(x,fpTypeReal)
  216. ELSIF x.sizeInBits = 64 THEN SetTypeFingerprint(x,fpTypeLongreal)
  217. ELSE HALT(100)
  218. END;
  219. END VisitFloatType;
  220. PROCEDURE VisitComplexType*(x: SyntaxTree.ComplexType);
  221. BEGIN
  222. ASSERT(x.componentType # NIL);
  223. IF x.componentType.sizeInBits = 32 THEN SetTypeFingerprint(x,fpTypeComplex)
  224. ELSIF x.componentType.sizeInBits = 64 THEN SetTypeFingerprint(x,fpTypeLongcomplex)
  225. ELSE HALT(100)
  226. END
  227. END VisitComplexType;
  228. (*
  229. FP(BasicType) = fpStringType
  230. PublicFP(BasicType) = FP(basicType).
  231. PrivateFP(BasicType) = sizeof(basicType).
  232. *)
  233. PROCEDURE VisitStringType*(x: SyntaxTree.StringType);
  234. BEGIN
  235. SetTypeFingerprint(x,fpTypeString);
  236. END VisitStringType;
  237. (**
  238. fp enumeration type
  239. **)
  240. PROCEDURE VisitEnumerationType*(x: SyntaxTree.EnumerationType);
  241. VAR fingerprint: FingerPrint; enumerator: SyntaxTree.Constant; fp: LONGINT;
  242. BEGIN
  243. fingerprint := x.fingerprint;
  244. IF ~fingerprint.shallowAvailable THEN
  245. fp := fpTypeEnum;
  246. IF x.enumerationBase # NIL THEN
  247. FPType(fp,x.enumerationBase);
  248. END;
  249. enumerator := x.enumerationScope.firstConstant;
  250. WHILE enumerator # NIL DO
  251. IF enumerator.access * SyntaxTree.Public # {} THEN
  252. FPName(fp,enumerator.name);
  253. END;
  254. FPValue(fp,enumerator.value);
  255. enumerator := enumerator.nextConstant;
  256. END;
  257. fingerprint.shallow := fp;
  258. fingerprint.public := fingerprint.shallow;
  259. fingerprint.private := fingerprint.shallow;
  260. fingerprint.shallowAvailable := TRUE;
  261. fingerprint.deepAvailable := TRUE; (* no distinction between deep and shallow fp necessary *)
  262. x.SetFingerPrint(fingerprint);
  263. END;
  264. SELF.fingerprint := fingerprint
  265. (*! must be implemented
  266. IF x.enumerationBase # NIL THEN
  267. baseType := ResolveType(x.enumerationBase);
  268. resolved := baseType.resolved;
  269. enumerationBase := resolved(SyntaxTree.EnumerationType);
  270. baseScope := enumerationBase.enumerationScope;
  271. x.SetBaseValue(enumerationBase.baseValue + baseScope.numberEnumerators);
  272. END;
  273. CheckEnumerationScope(x.enumerationScope);
  274. x.SetState(SyntaxTree.Resolved);
  275. END;
  276. resolvedType := ResolvedType(x);
  277. *)
  278. END VisitEnumerationType;
  279. PROCEDURE VisitQualifiedType*(x: SyntaxTree.QualifiedType);
  280. BEGIN
  281. VType(x.resolved);
  282. END VisitQualifiedType;
  283. (*
  284. FP(ArrayType) = fpTypeComposite <*> (fpTypeOpenArray | fpTypeStaticArray)
  285. -> Name <*> FP(baseType) [<*> length].
  286. PublicFP(ArrayType) = FP(arrayType).
  287. PrivateFP(ArrayType) = FP(arrayType).
  288. *)
  289. PROCEDURE VisitArrayType*(x: SyntaxTree.ArrayType);
  290. VAR fingerprint: FingerPrint; deep: BOOLEAN; fp: LONGINT;
  291. BEGIN
  292. IF Trace THEN TraceEnter("ArrayType") END;
  293. fingerprint := x.fingerprint;
  294. deep := SELF.deep;
  295. IF ~fingerprint.shallowAvailable THEN
  296. fingerprint.shallowAvailable := TRUE; (* the fingerprinting may return to itself => avoid circles *)
  297. SELF.deep := FALSE;
  298. fp := 0;
  299. FPNumber(fp,fpTypeComposite);
  300. IF x.form = SyntaxTree.Open THEN FPNumber(fp,fpTypeOpenArray)
  301. ELSIF x.form = SyntaxTree.Static THEN FPNumber(fp,fpTypeStaticArray)
  302. ELSIF x.form = SyntaxTree.SemiDynamic THEN FPNumber(fp, fpTypeDynamicArray);
  303. ELSE HALT(200)
  304. END;
  305. TypeName(fp,x);
  306. fingerprint.shallow := fp;
  307. x.SetFingerPrint(fingerprint);
  308. FPType(fp,x.arrayBase.resolved);
  309. IF x.form = SyntaxTree.Static THEN FPNumber(fp,x.staticLength) END;
  310. fingerprint.shallow := fp;
  311. fingerprint.public := fingerprint.shallow;
  312. fingerprint.private := fingerprint.shallow;
  313. x.SetFingerPrint(fingerprint);
  314. SELF.deep := deep;
  315. END;
  316. IF deep & ~fingerprint.deepAvailable THEN
  317. fingerprint.private := fingerprint.shallow;
  318. fingerprint.public := fingerprint.shallow;
  319. fingerprint.deepAvailable := TRUE; (* to avoid circles during base finger printing *)
  320. x.SetFingerPrint(fingerprint);
  321. VType(x.arrayBase); (* make sure that base pointer is also deeply fped *)
  322. END;
  323. IF Trace THEN TraceExit("ArrayType",fingerprint) END;
  324. SELF.fingerprint := fingerprint;
  325. END VisitArrayType;
  326. (*
  327. FP(MathArrayType) = fpTypeComposite <*> (fpTypeOpenArray | fpTypeStaticArray)
  328. -> Name <*> FP(baseType) [<*> length].
  329. PublicFP(MathArrayType) = FP(arrayType).
  330. PrivateFP(MathArrayType) = FP(arrayType).
  331. *)
  332. PROCEDURE VisitMathArrayType*(x: SyntaxTree.MathArrayType);
  333. VAR fingerprint: FingerPrint; deep: BOOLEAN; fp: LONGINT;
  334. BEGIN
  335. fingerprint := x.fingerprint;
  336. deep := SELF.deep;
  337. IF Trace THEN TraceEnter("MathArrayType") END;
  338. IF ~fingerprint.shallowAvailable THEN
  339. fingerprint.shallowAvailable := TRUE; (* the fingerprinting may return to itself => avoid circles *)
  340. SELF.deep := FALSE;
  341. fp := 0;
  342. FPNumber(fp,fpTypeComposite);
  343. IF x.form = SyntaxTree.Open THEN FPNumber(fp,fpTypeOpenArray)
  344. ELSIF x.form = SyntaxTree.Static THEN FPNumber(fp,fpTypeStaticArray)
  345. ELSIF x.form = SyntaxTree.Tensor THEN (* do nothing *)
  346. ELSE HALT(200)
  347. END;
  348. TypeName(fp,x);
  349. IF x.arrayBase # NIL THEN
  350. FPType(fp,x.arrayBase.resolved);
  351. END;
  352. IF x.form = SyntaxTree.Static THEN FPNumber(fp,x.staticLength) END;
  353. fingerprint.shallow := fp;
  354. fingerprint.public := fingerprint.shallow;
  355. fingerprint.private := fingerprint.shallow;
  356. fingerprint.shallowAvailable := TRUE;
  357. x.SetFingerPrint(fingerprint);
  358. SELF.deep := deep;
  359. END;
  360. IF deep & ~fingerprint.deepAvailable THEN
  361. VType(x.arrayBase);
  362. fingerprint.private := fingerprint.shallow;
  363. fingerprint.public := fingerprint.shallow;
  364. fingerprint.deepAvailable := TRUE;
  365. x.SetFingerPrint(fingerprint);
  366. END;
  367. IF Trace THEN TraceExit("MathArrayType",fingerprint) END;
  368. SELF.fingerprint := fingerprint;
  369. END VisitMathArrayType;
  370. (*
  371. fp = fp [ -> Name(moduleName) -> Name(typeName) ]
  372. *)
  373. PROCEDURE TypeName(VAR fp: LONGINT; x:SyntaxTree.Type);
  374. VAR typeDeclaration: SyntaxTree.TypeDeclaration;
  375. BEGIN
  376. IF (x.scope # NIL) THEN
  377. (* only executed for imported types, reason:
  378. modification of a type name would result in modified fingerprint leading to modified fingerprints of using structures such as
  379. in the following example:
  380. TYPE A=ARRAY 32 OF CHAR;
  381. PROCEDURE P*(a:A);
  382. ...
  383. END P;
  384. IF name of A was changed, P would get a new fingerprint.
  385. Better: fingerprint of P only depends in type of A but not on its declared name.
  386. *)
  387. IF Trace THEN
  388. TraceIndent;
  389. D.Str("TypeName ");
  390. D.Str0(x.scope.ownerModule.name);
  391. END;
  392. typeDeclaration := x.typeDeclaration;
  393. IF(typeDeclaration # NIL) & (typeDeclaration.access # SyntaxTree.Hidden) THEN
  394. FPName(fp,x.scope.ownerModule.name);
  395. IF (typeDeclaration.declaredType.resolved # x) THEN
  396. (* in record type: pointer to type declaration of a pointer *)
  397. typeDeclaration := NIL
  398. END;
  399. IF (typeDeclaration # NIL) & (typeDeclaration.scope # NIL)THEN
  400. FPName(fp,typeDeclaration.name);
  401. IF Trace THEN
  402. D.Str(".");
  403. D.Str0(typeDeclaration.name);
  404. END;
  405. ELSIF (typeDeclaration # NIL) & (typeDeclaration.scope = NIL) THEN
  406. D.Str("typedeclaration without scope: "); D.Str0(x.typeDeclaration.name); D.Int(x.typeDeclaration.position.start,5); D.Ln;
  407. D.Update;
  408. ELSE
  409. FPNumber(fp,0);
  410. END;
  411. ELSE
  412. FPNumber(fp, 0);
  413. END;
  414. IF Trace THEN
  415. D.Str(", fp = "); D.Hex(fp,-8); D.Ln;
  416. END
  417. END
  418. END TypeName;
  419. (*
  420. FP(PointerType) = fpTypePointer <*> fpTypeBasic -> Name <*> FP(baseType).
  421. PublicFP(PointerType) = 0.
  422. PrivateFP(PointerType) = 0.
  423. *)
  424. PROCEDURE VisitPointerType*(x: SyntaxTree.PointerType);
  425. VAR fingerprint,typeFP: FingerPrint; fp: LONGINT; deep: BOOLEAN;
  426. BEGIN
  427. IF Trace THEN TraceEnter("PointerType"); END;
  428. fingerprint := x.fingerprint;
  429. deep := SELF.deep;
  430. IF ~fingerprint.shallowAvailable THEN
  431. IF Trace THEN TraceIndent; D.Str("PointerType shallow");D.Ln; END;
  432. SELF.deep := FALSE;
  433. fp := 0;
  434. FPNumber(fp, fpTypePointer); FPNumber(fp, fpTypeBasic);
  435. TypeName(fp,x);
  436. FPType(fp,x.pointerBase);
  437. fingerprint.shallow := fp;
  438. fingerprint.private := fp;
  439. fingerprint.public := fp;
  440. fingerprint.shallowAvailable := TRUE;
  441. fingerprint.deepAvailable := TRUE;
  442. (*
  443. deep fingerprinting leads to cycles -> must be done on record type directly, if a deep FP is needed
  444. IF deep & ~fingerprint.deepAvailable THEN
  445. IF Trace THEN TraceIndent; D.Str("PointerType:deep");D.Ln; END;
  446. x.pointerBase.Accept(SELF);
  447. fingerprint.deepAvailable := TRUE;
  448. END;
  449. *)
  450. x.SetFingerPrint(fingerprint);
  451. SELF.deep := deep;
  452. END;
  453. IF Trace THEN TraceExit("PointerType",fingerprint) END;
  454. SELF.fingerprint := fingerprint;
  455. END VisitPointerType;
  456. (*
  457. FP(PortType) = fpTypePort <*> fpTypeBasic -> Name <*> FP(baseType).
  458. PublicFP(PortType) = 0.
  459. PrivateFP(PortType) = 0.
  460. *)
  461. PROCEDURE VisitPortType*(x: SyntaxTree.PortType);
  462. VAR fingerprint: FingerPrint; fp: LONGINT; deep: BOOLEAN;
  463. BEGIN
  464. IF Trace THEN TraceEnter("PortType"); END;
  465. fingerprint := x.fingerprint;
  466. deep := SELF.deep;
  467. IF ~fingerprint.shallowAvailable THEN
  468. IF Trace THEN TraceIndent; D.Str("PortType shallow");D.Ln; END;
  469. SELF.deep := FALSE;
  470. fp := 0;
  471. FPNumber(fp, fpTypePort); FPNumber(fp, fpTypeBasic);
  472. TypeName(fp,x);
  473. FPNumber(fp,x.sizeInBits);
  474. fingerprint.shallow := fp;
  475. fingerprint.private := fp;
  476. fingerprint.public := fp;
  477. fingerprint.shallowAvailable := TRUE;
  478. fingerprint.deepAvailable := TRUE;
  479. SELF.deep := deep;
  480. END;
  481. IF Trace THEN TraceExit("PortType",fingerprint) END;
  482. SELF.fingerprint := fingerprint;
  483. END VisitPortType;
  484. (*
  485. FP(Method) = 0 <*> fpModeMethod -> Name(methodName) -> Signature(method).
  486. *)
  487. PROCEDURE FPrintMethod(VAR private,public: LONGINT; procedure,body: SyntaxTree.Procedure);
  488. VAR fingerprint: FingerPrint; fp: LONGINT; name: ARRAY 256 OF CHAR;
  489. BEGIN
  490. IF Trace THEN TraceEnter("Method");
  491. D.Address(SYSTEM.VAL(ADDRESS,procedure));
  492. procedure.GetName(name);
  493. TraceIndent; D.Str("name = "); D.Str(name); D.Ln;
  494. END;
  495. ASSERT(deep);
  496. fingerprint := procedure.fingerprint;
  497. IF ~fingerprint.shallowAvailable THEN
  498. fp := 0;
  499. FPNumber(fp,fpModeMethod);
  500. Global.GetSymbolName(procedure,name);
  501. FPString(fp,name);
  502. FPSignature(fp,procedure.type(SyntaxTree.ProcedureType),procedure IS SyntaxTree.Operator );
  503. fingerprint.shallow := fp;
  504. fingerprint.public := fingerprint.shallow;
  505. fingerprint.private := fingerprint.shallow;
  506. fingerprint.shallowAvailable := TRUE;
  507. procedure.SetFingerPrint(fingerprint)
  508. ELSE
  509. fp := fingerprint.shallow;
  510. END;
  511. IF procedure.access * SyntaxTree.Public # {} THEN (* visible method or visible supermethod *)
  512. IF Trace THEN D.String("fp before method number"); D.Hex(fp,-8); D.Ln END;
  513. FPNumber(fp,procedure.methodNumber);
  514. IF Trace THEN D.String("fp after method number"); D.Hex(fp,-8); D.Ln END;
  515. IF procedure # body THEN
  516. FPNumber(private,fp); FPNumber(public,fp);
  517. END;
  518. END;
  519. IF Trace THEN
  520. TraceIndent; D.Str("Method, fp = "); D.Hex(private,-8); D.Str(" "); D.Hex(public,-8); D.Ln;
  521. TraceExit("Method",fingerprint)
  522. END;
  523. END FPrintMethod;
  524. PROCEDURE VisitCellType*(x: SyntaxTree.CellType);
  525. VAR fingerprint: FingerPrint; fp:LONGINT; name: SyntaxTree.String;
  526. BEGIN
  527. fingerprint := x.fingerprint;
  528. deep := SELF.deep;
  529. IF ~fingerprint.shallowAvailable THEN
  530. fp := 0;
  531. TypeName(fp,x);
  532. fingerprint.shallow := fp;
  533. fingerprint.public := fp;
  534. fingerprint.private := fp;
  535. fingerprint.deepAvailable := TRUE;
  536. fingerprint.shallowAvailable := TRUE;
  537. x.SetFingerPrint(fingerprint);
  538. END;
  539. SELF.fingerprint := fingerprint
  540. END VisitCellType;
  541. (*
  542. FP(RecordType) = fpTypeComposite <*> fptypeRecord
  543. [ -> Name(moduleName) -> Name(typeName)] [<*> FP(baseType)]
  544. PublicFP(RecordType) = FP(recordType) [<*> PublicFP(baseType)] {<*> FP(method) <*> methodNumber }
  545. {<*> PublicFP(fieldType) <*> offset(field) <*> FP(field)} <*> flags.
  546. PrivateFP(RecordType) = FP(recordType) [<*> PrivateFP(baseType)] {<*> FP(method) <*> methodNumber }
  547. {<*> PrivateFP(fieldType) <*> offset(field) <*> FP(field)}
  548. *)
  549. PROCEDURE VisitRecordType*(x: SyntaxTree.RecordType);
  550. VAR scope: SyntaxTree.RecordScope; fp: LONGINT; variable: SyntaxTree.Variable;
  551. fingerprint,variableFingerPrint,variableTypeFingerPrint,baseFingerPrint: FingerPrint;flags: SET;
  552. symbol: SyntaxTree.Symbol; procedure: SyntaxTree.Procedure; baseType: SyntaxTree.Type;
  553. body: SyntaxTree.Body; name: ARRAY 256 OF CHAR;
  554. deep: BOOLEAN;
  555. (* for dealing with cycles the private and public fingerprint are computed here
  556. while FP is computed completely during call of Type0 *)
  557. BEGIN
  558. fingerprint := x.fingerprint;
  559. deep := SELF.deep;
  560. IF Trace THEN TraceEnter("Record"); END;
  561. IF ~fingerprint.shallowAvailable THEN
  562. IF Trace THEN TraceIndent; D.Str("RecordType Enter Shallow "); D.Ln; END;
  563. SELF.deep := FALSE;
  564. fp := 0;
  565. FPNumber(fp, fpTypeComposite); FPNumber(fp, fpTypeRecord);
  566. TypeName(fp,x);
  567. IF Trace THEN TraceIndent; D.Str("RecordType Name ");D.Hex(fp,-8); D.Ln; END;
  568. IF (x.baseType # NIL) THEN
  569. baseType := x.GetBaseRecord();
  570. FPType(fp,baseType);
  571. END;
  572. SELF.deep := TRUE;
  573. (* methods, sorted *)
  574. scope := x.recordScope;
  575. symbol := scope.firstSymbol;
  576. WHILE symbol # NIL DO (* number and names of procedures -- method table ! *)
  577. IF symbol IS SyntaxTree.Procedure THEN
  578. procedure := symbol(SyntaxTree.Procedure);
  579. FPNumber(fp,fpModeMethod);
  580. Global.GetSymbolName(procedure,name);
  581. FPString(fp,name);
  582. IF Trace THEN TraceIndent; D.Str("RecordType Method "); TraceFP(fingerprint); D.Ln; END;
  583. END;
  584. symbol := symbol.nextSymbol
  585. END;
  586. fingerprint.shallow := fp;
  587. fingerprint.public := fingerprint.shallow;
  588. fingerprint.private := fingerprint.shallow;
  589. fingerprint.shallowAvailable := TRUE;
  590. x.SetFingerPrint(fingerprint);
  591. SELF.deep := deep;
  592. IF Trace THEN TraceIndent; D.Str("RecordType Shallow Done "); TraceFP(fingerprint); D.Ln; END;
  593. END;
  594. IF deep & ~fingerprint.deepAvailable THEN
  595. IF Trace THEN TraceIndent; D.Str("RecordType Enter Deep "); D.Ln; END;
  596. fingerprint.private := fingerprint.shallow;
  597. fingerprint.public := fingerprint.shallow;
  598. (*! finger printing for interfaces omitted *)
  599. IF Trace THEN TraceIndent; D.Str("RecordType before basetype"); TraceFP(fingerprint); D.Ln; END;
  600. (* now compute base record finger prints *)
  601. baseType := x.GetBaseRecord();
  602. IF (baseType # NIL) THEN
  603. IF baseType IS SyntaxTree.PointerType THEN baseType := baseType(SyntaxTree.PointerType).pointerBase.resolved END;
  604. baseFingerPrint := TypeFP(baseType); (* deep finger print *)
  605. FPNumber(fingerprint.private,baseFingerPrint.private);
  606. FPNumber(fingerprint.public,baseFingerPrint.public);
  607. END;
  608. scope := x.recordScope;
  609. IF Trace THEN TraceIndent; D.Str("RecordType before methods"); TraceFP(fingerprint); D.Ln; END;
  610. (* methods, sorted *)
  611. symbol := scope.firstSymbol;
  612. WHILE symbol # NIL DO
  613. IF symbol IS SyntaxTree.Procedure THEN
  614. procedure := symbol(SyntaxTree.Procedure);
  615. FPrintMethod(fingerprint.private, fingerprint.public, procedure, scope.bodyProcedure);
  616. IF Trace THEN TraceIndent; D.Str("RecordType Method "); TraceFP(fingerprint); D.Ln; END;
  617. END;
  618. symbol := symbol.nextSymbol
  619. END;
  620. IF Trace THEN TraceIndent; D.Str("RecordType after methods"); TraceFP(fingerprint); D.Ln; END;
  621. variable := scope.firstVariable;
  622. WHILE variable # NIL DO
  623. variableFingerPrint := variable.fingerprint;
  624. IF variable.access * SyntaxTree.Public # {} THEN
  625. (* variable fp = & fpModeField & Name & Visibility [& fpUntraced] & Type *)
  626. fp := 0;
  627. FPNumber(fp,fpModeField);
  628. FPName(fp,variable.name);
  629. FPVisibility(fp,variable.access);
  630. IF variable.untraced THEN FPNumber(fp,fpUntraced) END;
  631. variableTypeFingerPrint := TypeFP(variable.type); (* deep finger print *)
  632. FPNumber(fp,variableTypeFingerPrint.shallow);
  633. variableFingerPrint.shallow := fp;
  634. FPNumber(fingerprint.private,variableTypeFingerPrint.private);
  635. FPNumber(fingerprint.private,SHORT(variable.offsetInBits DIV 8));
  636. FPNumber(fingerprint.private,fp);
  637. FPNumber(fingerprint.public,variableTypeFingerPrint.public);
  638. FPNumber(fingerprint.public,SHORT(variable.offsetInBits DIV 8));
  639. FPNumber(fingerprint.public,fp);
  640. IF Trace THEN TraceIndent; D.Str("RecordType Field "); D.Str0(variable.name); D.Str(" "); TraceFP(fingerprint); D.Ln; END;
  641. ELSE
  642. fp := 0;
  643. IF variable.untraced THEN FPNumber(fp,fpUntraced) END;
  644. FPNumber(fingerprint.private,fp);
  645. IF Trace THEN TraceIndent; D.Str("RecordType InvisibleField "); TraceFP(fingerprint); D.Ln; END;
  646. END;
  647. variable := variable.nextVariable;
  648. END;
  649. FPNumber(fingerprint.private, SHORT(x.sizeInBits DIV 8));
  650. FPNumber(fingerprint.public, SHORT(x.sizeInBits DIV 8));
  651. flags := {};
  652. IF x.recordScope.bodyProcedure # NIL THEN
  653. body := x.recordScope.bodyProcedure.procedureScope.body;
  654. INCL(flags, fpHasBody);
  655. IF body # NIL THEN
  656. IF body.isActive THEN INCL(flags,fpActive) END;
  657. IF body.isExclusive THEN INCL(flags,fpProtected) END;
  658. END;
  659. IF Trace THEN TraceIndent; D.Str("RecordType Body "); TraceFP(fingerprint); D.Ln; END;
  660. END;
  661. IF x.IsProtected() THEN INCL(flags,fpProtected) END;
  662. FPSet(fingerprint.public, flags);
  663. IF Trace THEN TraceIndent; D.Str("RecordType Exit Deep "); TraceFP(fingerprint); D.Ln; END;
  664. (*
  665. ASSERT(fingerprint.private # 0,100);
  666. ASSERT(fingerprint.public # 0,101);
  667. *)
  668. fingerprint.deepAvailable := TRUE;
  669. x.SetFingerPrint(fingerprint);
  670. END;
  671. SELF.fingerprint := fingerprint;
  672. IF Trace THEN TraceExit("Record",fingerprint); END;
  673. END VisitRecordType;
  674. (*
  675. FP(ProcedureType) = fpTypeProcedure <*> fpTypeBasic [<*> fpDelegate]-> Name.
  676. PublicFP(ProcedureType) = FP(arrayType) -> Signature(procedureType)
  677. PrivateFP(ProcedureType) = FP(arrayType)-> Signature(procedureType).
  678. *)
  679. PROCEDURE VisitProcedureType*(x: SyntaxTree.ProcedureType);
  680. VAR fingerprint: FingerPrint; deep: BOOLEAN; fp: LONGINT;
  681. BEGIN
  682. IF Trace THEN TraceEnter("ProcedureType") END;
  683. fingerprint := x.fingerprint;
  684. deep := SELF.deep;
  685. IF ~fingerprint.shallowAvailable THEN
  686. fingerprint.shallowAvailable := TRUE; (*! to avoid circles, this is not fully clean - for paco *)
  687. fp := 0;
  688. FPNumber(fp,fpTypeProcedure);
  689. FPNumber(fp,fpTypeBasic);
  690. IF x.isDelegate THEN FPNumber(fp,fpDelegate) END;
  691. x.SetFingerPrint(fingerprint);
  692. TypeName(fp,x);
  693. fingerprint.public := fp; fingerprint.private := fp;
  694. fingerprint.shallow := fp;
  695. FPSignature(fp,x,FALSE);
  696. fingerprint.public := fp; fingerprint.private := fp;
  697. fingerprint.shallow := fp;
  698. fingerprint.deepAvailable := TRUE;
  699. x.SetFingerPrint(fingerprint);
  700. END;
  701. (*
  702. IF ~fingerprint.deepAvailable THEN
  703. SELF.deep := FALSE;
  704. FPSignature(fp,x,FALSE);
  705. SELF.deep := deep;
  706. fingerprint.public := fp; fingerprint.private := fp;
  707. fingerprint.shallow := fp;
  708. fingerprint.deepAvailable := TRUE;
  709. END;
  710. *)
  711. IF Trace THEN TraceExit("ProcedureType",fingerprint) END;
  712. SELF.fingerprint := fingerprint;
  713. END VisitProcedureType;
  714. (** values - used in constant symbols - effects in fingerprint modification of (object) global variable fp *)
  715. (* fp = fp & (fpTrue | fpFalse) *)
  716. PROCEDURE VisitBooleanValue*(x: SyntaxTree.BooleanValue);
  717. BEGIN IF x.value THEN FPNumber(SELF.fp,fpTrue) ELSE FPNumber(SELF.fp,fpFalse) END
  718. END VisitBooleanValue;
  719. (* fp = fp & (HugeInt | Number) *)
  720. PROCEDURE VisitIntegerValue*(x: SyntaxTree.IntegerValue);
  721. BEGIN FPHugeInt(SELF.fp,x.value)
  722. END VisitIntegerValue;
  723. (* fp = fp & (HugeInt | Number) *)
  724. PROCEDURE VisitEnumerationValue*(x: SyntaxTree.EnumerationValue);
  725. BEGIN FPHugeInt(SELF.fp,x.value)
  726. END VisitEnumerationValue;
  727. (* fp = fp & ORD(char) *)
  728. PROCEDURE VisitCharacterValue*(x: SyntaxTree.CharacterValue);
  729. BEGIN FPNumber(SELF.fp,ORD(x.value)) END VisitCharacterValue;
  730. (* fp = fp & Set *)
  731. PROCEDURE VisitSetValue*(x: SyntaxTree.SetValue);
  732. BEGIN FPHugeInt(SELF.fp,SYSTEM.VAL(HUGEINT,x.value)) END VisitSetValue;
  733. PROCEDURE VisitMathArrayExpression*(x: SyntaxTree.MathArrayExpression);
  734. VAR element: SyntaxTree.Expression; i: LONGINT;
  735. BEGIN
  736. FOR i := 0 TO x.elements.Length()-1 DO
  737. element := x.elements.GetExpression(i);
  738. FPValue(fp, element);
  739. END;
  740. END VisitMathArrayExpression;
  741. (* fp = fp {& Value} *)
  742. PROCEDURE VisitMathArrayValue*(x: SyntaxTree.MathArrayValue);
  743. BEGIN
  744. VisitMathArrayExpression(x.array); (* do not call FPValue here, recursion possible because x.array.resolved = x *)
  745. END VisitMathArrayValue;
  746. (* fp = fp & (Real | LongReal) *)
  747. PROCEDURE VisitRealValue*(x: SyntaxTree.RealValue);
  748. BEGIN
  749. IF x.type.sizeInBits=32 THEN FPReal(SELF.fp,SHORT(x.value))
  750. ELSE FPLongReal(SELF.fp,x.value)
  751. END;
  752. END VisitRealValue;
  753. PROCEDURE VisitComplexValue*(x: SyntaxTree.ComplexValue);
  754. BEGIN
  755. FPLongReal(SELF.fp,x.realValue);
  756. FPLongReal(SELF.fp,x.imagValue);
  757. END VisitComplexValue;
  758. PROCEDURE VisitNilValue*(x: SyntaxTree.NilValue);
  759. BEGIN IF x.type.sizeInBits = 64 THEN FPHugeInt(SELF.fp, 0) ELSE FPNumber(SELF.fp, 0) END;
  760. END VisitNilValue;
  761. (* fp = fp & String *)
  762. PROCEDURE VisitStringValue*(x: SyntaxTree.StringValue);
  763. BEGIN FPString(SELF.fp,x.value^) END VisitStringValue;
  764. (* fp = fp & FP(x) *)
  765. PROCEDURE FPValue(VAR fp: LONGINT; x: SyntaxTree.Expression);
  766. BEGIN
  767. SELF.fp := fp;
  768. IF x.resolved # NIL THEN
  769. x.resolved.Accept(SELF);
  770. ELSE
  771. x.Accept(SELF)
  772. END;
  773. fp := SELF.fp
  774. END FPValue;
  775. PROCEDURE FPType(VAR fp: LONGINT; t: SyntaxTree.Type);
  776. BEGIN
  777. INC(level); ASSERT(level <= 100);
  778. IF t = NIL THEN FPNumber(fp,fpTypeNone);
  779. ELSE VType(t); FPNumber(fp,SELF.fingerprint.shallow);
  780. END;
  781. DEC(level);
  782. END FPType;
  783. (* Signature(f) = f <*> FP(returnType)
  784. { <*> (fpModeVarParameter | fpModeConstParameter | fpModePar)
  785. <*> FP(parameterType) [-> Name(parameterName)] }
  786. *)
  787. PROCEDURE FPSignature(VAR fp: LONGINT; t: SyntaxTree.ProcedureType; isOperator: BOOLEAN);
  788. VAR par,self: SyntaxTree.Parameter; deep: BOOLEAN;
  789. (* fp = fp & (fpModeVarPar | fpModeConstPar | fpModePar) [ & Name ] *)
  790. PROCEDURE FPPar(VAR fp: LONGINT; par: SyntaxTree.Parameter);
  791. VAR deep: BOOLEAN;
  792. BEGIN
  793. IF par.kind = SyntaxTree.VarParameter THEN FPNumber(fp, fpModeVarPar)
  794. ELSIF par.kind = SyntaxTree.ConstParameter THEN
  795. IF (par.type.resolved IS SyntaxTree.ArrayType) OR (par.type.resolved IS SyntaxTree.RecordType) THEN (*! compatiblity with paco *)
  796. FPNumber(fp,fpModeVarPar)
  797. ELSE
  798. FPNumber(fp,fpModePar)
  799. END;
  800. ELSE FPNumber(fp, fpModePar) END;
  801. deep := SELF.deep;
  802. SELF.deep := FALSE;
  803. FPType(fp,par.type);
  804. SELF.deep := deep;
  805. IF isOperator & ~(par.type.resolved IS SyntaxTree.BasicType) & (par.type.resolved.typeDeclaration # NIL) THEN
  806. FPName(fp,par.type.resolved.typeDeclaration.name);
  807. (* D.Str("fp "); D.Str0(par.type.resolved.typeDeclaration.name.name); D.Ln;*)
  808. ELSIF isOperator & (par.type.resolved IS SyntaxTree.BasicType) THEN
  809. FPName(fp,par.type.resolved(SyntaxTree.BasicType).name);
  810. (* D.Str("fpb "); D.Str0(par.type.resolved(SyntaxTree.BasicType).name.name);*)
  811. END;
  812. END FPPar;
  813. BEGIN
  814. IF Trace THEN
  815. TraceIndent; D.Str("FPSignature enter "); D.Hex(fp,-8); D.Ln;
  816. END;
  817. deep := SELF.deep;
  818. SELF.deep := FALSE;
  819. FPType(fp,t.returnType);
  820. SELF.deep := deep;
  821. IF Trace THEN
  822. TraceIndent; D.Str("FPSignature after return type "); D.Hex(fp,-8); D.Ln;
  823. END;
  824. IF IsOberonProcedure(t) THEN
  825. self := t.firstParameter;
  826. WHILE (self # NIL) & (self.name#Global.SelfParameterName) DO
  827. self := self.nextParameter;
  828. END;
  829. IF self # NIL THEN FPPar(fp,self) END; (* self parameter *)
  830. (*
  831. IF t.selfParameter # NIL THEN FPPar(fp,t.selfParameter) END; (* self parameter *)
  832. self := NIL;
  833. *)
  834. IF Trace THEN
  835. TraceIndent; D.Str("FPSignature after self "); D.Hex(fp,-8); D.Ln;
  836. END;
  837. par := t.firstParameter;
  838. WHILE (par#self) DO (*! done as in PACO *)
  839. FPPar(fp, par);
  840. IF Trace THEN
  841. TraceIndent; D.Str("FPSignature par "); D.Hex(fp,-8); D.Ln;
  842. END;
  843. par:=par.nextParameter;
  844. END;
  845. IF Trace THEN
  846. TraceIndent; D.Str("FPSignature exit "); D.Hex(fp,-8); D.Ln;
  847. END;
  848. ELSE
  849. par := t.lastParameter;
  850. WHILE (par#NIL) DO (*! done as in PACO *)
  851. FPPar(fp, par);
  852. IF Trace THEN
  853. TraceIndent; D.Str("FPSignature par "); D.Hex(fp,-8); D.Ln;
  854. END;
  855. par:=par.prevParameter;
  856. END;
  857. END;
  858. END FPSignature;
  859. (** symbols *)
  860. (*
  861. FP(TypeDeclaration) = 0 <*> fpModeType -> Name -> Visibility <*> FP(Type).
  862. *)
  863. PROCEDURE VisitTypeDeclaration*(x: SyntaxTree.TypeDeclaration);
  864. VAR fp: LONGINT;
  865. fingerprint: FingerPrint; deep: BOOLEAN;
  866. typeFP: FingerPrint;
  867. BEGIN
  868. fingerprint := x.fingerprint;
  869. IF ~fingerprint.shallowAvailable THEN
  870. IF Trace THEN TraceEnter("TypeDeclaration") END;
  871. deep := SELF.deep;
  872. SELF.deep := FALSE;
  873. fp := 0;
  874. FPNumber(fp, fpModeType);
  875. FPName(fp,x.name);
  876. IF Trace THEN TraceIndent; D.String("access="); D.Set(x.access); D.Ln; END;
  877. FPVisibility(fp, x.access);
  878. VType(x.declaredType);
  879. FPNumber(fp, SELF.fingerprint.shallow);
  880. fingerprint.shallow := fp;
  881. fingerprint.public := fp;
  882. fingerprint.private := fp;
  883. fingerprint.shallowAvailable := TRUE;
  884. x.SetFingerPrint(fingerprint);
  885. SELF.deep := deep;
  886. IF Trace THEN TraceExit("TypeDeclaration",fingerprint) END;
  887. END;
  888. IF deep & ~fingerprint.deepAvailable THEN
  889. fingerprint := x.fingerprint;
  890. typeFP := TypeFP(x.declaredType);
  891. IF x.declaredType.resolved IS SyntaxTree.PointerType THEN
  892. typeFP := TypeFP(x.declaredType.resolved(SyntaxTree.PointerType).pointerBase);
  893. END;
  894. FPNumber(fingerprint.public, typeFP.public);
  895. FPNumber(fingerprint.private, typeFP.private);
  896. fingerprint.deepAvailable := TRUE;
  897. x.SetFingerPrint(fingerprint);
  898. END;
  899. SELF.fingerprint := fingerprint
  900. END VisitTypeDeclaration;
  901. (*
  902. FP(ConstantDeclaration) = 0 <*> fpModeConstant -> Name -> Visibility <*> FP(Type) -> Basic -> Value.
  903. *)
  904. PROCEDURE VisitConstant*(x: SyntaxTree.Constant);
  905. VAR access: SET;
  906. fingerprint: FingerPrint;
  907. fp: LONGINT;
  908. deep: BOOLEAN;
  909. BEGIN
  910. fingerprint := x.fingerprint;
  911. IF ~fingerprint.shallowAvailable THEN
  912. deep := SELF.deep;
  913. SELF.deep := FALSE;
  914. fp := 0;
  915. FPNumber(fp, fpModeConst);
  916. FPName(fp,x.name);
  917. (* for compatibility with old compiler: *)
  918. access := x.access; IF SyntaxTree.PublicRead IN access THEN INCL(access,SyntaxTree.PublicWrite) END;
  919. FPVisibility(fp, access);
  920. FPType(fp, x.type);
  921. FPNumber(fp, fpTypeBasic);
  922. FPValue(fp, x.value);
  923. fingerprint.shallow := fp;
  924. fingerprint.public := fingerprint.shallow;
  925. fingerprint.private := fingerprint.shallow;
  926. fingerprint.shallowAvailable := TRUE;
  927. x.SetFingerPrint(fingerprint);
  928. SELF.deep := deep;
  929. END;
  930. SELF.fingerprint := fingerprint
  931. END VisitConstant;
  932. (*
  933. FP(VariableDeclaration) = 0 <*> fpModePar -> Name -> Visibility <*> FP(Type).
  934. *)
  935. PROCEDURE VisitVariable*(x: SyntaxTree.Variable);
  936. VAR fingerprint: FingerPrint; deep: BOOLEAN; name: SyntaxTree.IdentifierString;
  937. BEGIN
  938. fingerprint := x.fingerprint;
  939. IF ~fingerprint.shallowAvailable THEN
  940. deep := SELF.deep;
  941. SELF.deep := FALSE;
  942. fp := 0;
  943. FPNumber(fp,fpModeVar);
  944. Global.GetSymbolName(x,name);
  945. FPString(fp,name);
  946. FPVisibility(fp,x.access);
  947. VType(x.type);
  948. FPNumber(fp,SELF.fingerprint.shallow);
  949. fingerprint.shallow := fp;
  950. fingerprint.public := fingerprint.shallow;
  951. fingerprint.private := fingerprint.shallow;
  952. fingerprint.shallowAvailable := TRUE;
  953. x.SetFingerPrint(fingerprint);
  954. SELF.deep := deep;
  955. END;
  956. SELF.fingerprint := fingerprint
  957. END VisitVariable;
  958. PROCEDURE VisitProperty*(x: SyntaxTree.Property);
  959. BEGIN
  960. VisitVariable(x);
  961. END VisitProperty;
  962. (*
  963. FP(ParameterDeclaration) = 0 <*> fpModePar -> Name -> Visibility <*> FP(Type).
  964. *)
  965. PROCEDURE VisitParameter*(x: SyntaxTree.Parameter);
  966. VAR fingerprint: FingerPrint; deep: BOOLEAN; name: SyntaxTree.IdentifierString;
  967. BEGIN
  968. fingerprint := x.fingerprint;
  969. IF ~fingerprint.shallowAvailable THEN
  970. deep := SELF.deep;
  971. SELF.deep := FALSE;
  972. fp := 0;
  973. FPNumber(fp,fpModePar);
  974. Global.GetSymbolName(x,name);
  975. FPString(fp,name);
  976. FPVisibility(fp,x.access);
  977. VType(x.type);
  978. FPNumber(fp,SELF.fingerprint.shallow);
  979. fingerprint.shallow := fp;
  980. fingerprint.public := fingerprint.shallow;
  981. fingerprint.private := fingerprint.shallow;
  982. fingerprint.shallowAvailable := TRUE;
  983. x.SetFingerPrint(fingerprint);
  984. SELF.deep := deep;
  985. END;
  986. SELF.fingerprint := fingerprint
  987. END VisitParameter;
  988. (*
  989. FP(ProcedureDeclaration) = 0 <*> fpModeInlineProcedure -> Name -> Visibility <*> FP(Type) -> Code.
  990. | 0 <*> fpModeExportedProcedure -> Name -> Visibility <*> FP(Type)
  991. *)
  992. PROCEDURE VisitProcedure*(x: SyntaxTree.Procedure);
  993. VAR fp: LONGINT; access: SET; fingerprint: FingerPrint; deep: BOOLEAN; code: SyntaxTree.Code; i: LONGINT;
  994. size,value: LONGINT; name: ARRAY 256 OF CHAR;
  995. BEGIN
  996. IF x.scope IS SyntaxTree.RecordScope THEN (* method *)
  997. FPrintMethod(fp,fp,x,NIL);
  998. fingerprint := x.fingerprint;
  999. ELSE
  1000. fingerprint := x.fingerprint;
  1001. IF ~fingerprint.shallowAvailable THEN
  1002. deep := SELF.deep;
  1003. SELF.deep := FALSE;
  1004. (* for compatibility with old compiler: *)
  1005. access := x.access; IF SyntaxTree.PublicRead IN access THEN INCL(access,SyntaxTree.PublicWrite) END;
  1006. fp := 0;
  1007. IF x.isInline THEN
  1008. FPNumber(fp, fpModeInlineProcedure);
  1009. FPName(fp,x.name);
  1010. FPVisibility(fp, access);
  1011. FPSignature(fp,x.type(SyntaxTree.ProcedureType),x IS SyntaxTree.Operator);
  1012. IF (x.procedureScope.body # NIL) & (x.procedureScope.body.code # NIL) THEN
  1013. code := x.procedureScope.body.code;
  1014. IF code.inlineCode = NIL THEN
  1015. size := 0
  1016. ELSE
  1017. size := code.inlineCode.GetSize() DIV 8;
  1018. END;
  1019. FPNumber(fp,size);
  1020. FOR i := 0 TO size-1 DO
  1021. value := code.inlineCode.GetBits(i*8,8);
  1022. FPNumber(fp,value);
  1023. END;
  1024. END;
  1025. ELSE
  1026. FPNumber(fp, fpModeExportedProcedure);
  1027. Global.GetSymbolName(x,name);
  1028. FPString(fp,name);
  1029. FPVisibility(fp, access);
  1030. FPSignature(fp,x.type(SyntaxTree.ProcedureType),x IS SyntaxTree.Operator);
  1031. END;
  1032. fingerprint.shallow := fp;
  1033. fingerprint.public := fingerprint.shallow;
  1034. fingerprint.private := fingerprint.shallow;
  1035. fingerprint.shallowAvailable := TRUE;
  1036. x.SetFingerPrint(fingerprint);
  1037. SELF.deep := deep;
  1038. END;
  1039. END;
  1040. SELF.fingerprint := fingerprint
  1041. END VisitProcedure;
  1042. (* cf. Procedure *)
  1043. PROCEDURE VisitOperator*(x: SyntaxTree.Operator);
  1044. BEGIN
  1045. VisitProcedure(x) (* same finger print as a procedure *)
  1046. END VisitOperator;
  1047. PROCEDURE VisitModule*(x: SyntaxTree.Module);
  1048. VAR fingerprint, symbolFingerPrint: FingerPrint; deep: BOOLEAN; fp: LONGINT; symbol: SyntaxTree.Symbol; scope: SyntaxTree.ModuleScope;
  1049. BEGIN
  1050. fingerprint := x.fingerprint;
  1051. deep := SELF.deep;
  1052. IF Trace THEN TraceEnter("Record"); END;
  1053. IF ~fingerprint.shallowAvailable THEN
  1054. IF Trace THEN TraceIndent; D.Str("Module Enter Shallow "); D.Ln; END;
  1055. SELF.deep := FALSE;
  1056. fp := 0;
  1057. FPNumber(fp, fpTypeModule);
  1058. FPName(fp,x.name);
  1059. IF Trace THEN TraceIndent; D.Str("Module Name ");D.Hex(fp,-8); D.Ln; END;
  1060. fingerprint.shallow := fp;
  1061. fingerprint.public := fingerprint.shallow;
  1062. fingerprint.private := fingerprint.shallow;
  1063. fingerprint.shallowAvailable := TRUE;
  1064. x.SetFingerPrint(fingerprint);
  1065. SELF.deep := deep;
  1066. IF Trace THEN TraceIndent; D.Str("Module Shallow Done "); TraceFP(fingerprint); D.Ln; END;
  1067. END;
  1068. IF deep & ~fingerprint.deepAvailable THEN
  1069. IF Trace THEN TraceIndent; D.Str("Module Enter Deep "); D.Ln; END;
  1070. fingerprint.private := fingerprint.shallow;
  1071. fingerprint.public := fingerprint.shallow;
  1072. scope := x.moduleScope;
  1073. IF Trace THEN TraceIndent; D.Str("RecordType before methods"); TraceFP(fingerprint); D.Ln; END;
  1074. symbol := scope.firstSymbol;
  1075. WHILE symbol # NIL DO
  1076. IF symbol.access * SyntaxTree.Public # {} THEN
  1077. symbolFingerPrint := SymbolFP(symbol);
  1078. FPNumber(fingerprint.private,symbolFingerPrint.shallow);
  1079. FPNumber(fingerprint.public,symbolFingerPrint.shallow);
  1080. END;
  1081. symbol := symbol.nextSymbol;
  1082. END;
  1083. IF Trace THEN TraceIndent; D.Str("Module Exit Deep "); TraceFP(fingerprint); D.Ln; END;
  1084. (*
  1085. ASSERT(fingerprint.private # 0,100);
  1086. ASSERT(fingerprint.public # 0,101);
  1087. *)
  1088. fingerprint.deepAvailable := TRUE;
  1089. x.SetFingerPrint(fingerprint);
  1090. END;
  1091. SELF.fingerprint := fingerprint;
  1092. IF Trace THEN TraceExit("Record",fingerprint); END;
  1093. END VisitModule;
  1094. PROCEDURE VisitSymbol*(x: SyntaxTree.Symbol);
  1095. BEGIN
  1096. fingerprint.shallow := 0;
  1097. fingerprint.public := fingerprint.shallow;
  1098. fingerprint.private := fingerprint.shallow;
  1099. fingerprint.shallowAvailable := TRUE;
  1100. x.SetFingerPrint(fingerprint);
  1101. END VisitSymbol;
  1102. PROCEDURE TraceIndent;
  1103. VAR i: LONGINT;
  1104. BEGIN
  1105. FOR i := 1 TO traceLevel DO D.Str(" "); END;
  1106. END TraceIndent;
  1107. PROCEDURE TraceEnter(CONST name: ARRAY OF CHAR);
  1108. BEGIN
  1109. INC(traceLevel); TraceIndent;
  1110. D.Str("Enter ");
  1111. D.Str(name);
  1112. D.Ln;
  1113. END TraceEnter;
  1114. PROCEDURE TraceExit(CONST name: ARRAY OF CHAR; fingerprint: FingerPrint);
  1115. BEGIN
  1116. TraceIndent; DEC(traceLevel);
  1117. D.Str("Exit "); D.Str(name); D.Str(" "); TraceFP(fingerprint); D.Ln;
  1118. END TraceExit;
  1119. PROCEDURE TraceFP(fingerprint: FingerPrint);
  1120. BEGIN
  1121. D.Hex(fingerprint.shallow,-8); D.Str(" "); D.Hex(fingerprint.private,-8);
  1122. D.Str(" "); D.Hex(fingerprint.public,-8);
  1123. END TraceFP;
  1124. (* returns the finger print (object) of a type *)
  1125. PROCEDURE TypeFP*(this: SyntaxTree.Type): FingerPrint;
  1126. VAR deep: BOOLEAN;
  1127. BEGIN
  1128. IF Trace THEN TraceEnter("TypeFP"); END;
  1129. deep := SELF.deep;
  1130. SELF.deep := TRUE;
  1131. VType(this);
  1132. SELF.deep := deep;
  1133. ASSERT(fingerprint.deepAvailable,101);
  1134. ASSERT(fingerprint.shallow #0,102);
  1135. IF Trace THEN TraceExit("TypeFP",fingerprint); D.Ln;
  1136. D.Ln; END;
  1137. RETURN fingerprint
  1138. END TypeFP;
  1139. (* returns the finger print (object) of a symbol *)
  1140. PROCEDURE SymbolFP*(this: SyntaxTree.Symbol): FingerPrint;
  1141. VAR deep: BOOLEAN;
  1142. BEGIN
  1143. deep := SELF.deep;
  1144. SELF.deep := TRUE;
  1145. IF Trace THEN TraceEnter("SymbolFP");
  1146. TraceIndent;
  1147. D.Str("name: ");
  1148. D.Str0(this.name); D.Ln;
  1149. END;
  1150. this.Accept(SELF);
  1151. SELF.deep := deep;
  1152. IF Trace THEN TraceExit("SymbolFP",fingerprint); D.Ln; END;
  1153. RETURN fingerprint
  1154. END SymbolFP;
  1155. END FingerPrinter;
  1156. (** ---------- FingerPrinting primitives -------------- *)
  1157. PROCEDURE IsOberonProcedure(type: SyntaxTree.ProcedureType): BOOLEAN;
  1158. BEGIN
  1159. RETURN type.callingConvention = SyntaxTree.OberonCallingConvention
  1160. END IsOberonProcedure;
  1161. (* fp = fp <*> val *)
  1162. PROCEDURE FPNumber*(VAR fp: LONGINT; val: LONGINT);
  1163. BEGIN
  1164. fp:=SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ROT(fp, 7)) / SYSTEM.VAL(SET, val))
  1165. END FPNumber;
  1166. (* fp = fp <*> set *)
  1167. PROCEDURE FPSet*(VAR fp: LONGINT; set: SET);
  1168. BEGIN FPNumber(fp, SYSTEM.VAL(LONGINT, set))
  1169. END FPSet;
  1170. (* fp = fp <*> real *)
  1171. PROCEDURE FPReal*(VAR fp: LONGINT; real: REAL);
  1172. BEGIN FPNumber(fp, SYSTEM.VAL(LONGINT, real))
  1173. END FPReal;
  1174. (* fp = fp <*> low <*> high *)
  1175. PROCEDURE FPLongReal*(VAR fp: LONGINT; lr: LONGREAL);
  1176. VAR l, h: LONGINT;
  1177. BEGIN
  1178. SYSTEM.GET(ADDRESSOF(lr)+4, l); SYSTEM.GET(ADDRESSOF(lr), h);
  1179. FPNumber(fp, l); FPNumber(fp, h);
  1180. END FPLongReal;
  1181. (* fp = fp <*> low <*> high *)
  1182. PROCEDURE FPHugeInt*(VAR fp: LONGINT; huge: HUGEINT);
  1183. VAR l, h: LONGINT;
  1184. BEGIN
  1185. SYSTEM.GET(ADDRESSOF(huge)+4, l); SYSTEM.GET(ADDRESSOF(huge), h);
  1186. FPNumber(fp, l); FPNumber(fp, h);
  1187. END FPHugeInt;
  1188. (* fp = fp -> String *)
  1189. PROCEDURE FPName*(VAR fp: LONGINT; x: SyntaxTree.Identifier);
  1190. VAR name: Scanner.IdentifierString;
  1191. BEGIN
  1192. Basic.GetString(x,name);
  1193. FPString(fp,name);
  1194. END FPName;
  1195. (* fp = fp {<*> str[i]} *)
  1196. PROCEDURE FPString*(VAR fp: LONGINT; CONST str: ARRAY OF CHAR);
  1197. VAR i: INTEGER; ch: CHAR;
  1198. BEGIN i:=0; REPEAT ch:=str[i]; FPNumber(fp, ORD(ch)); INC(i) UNTIL ch=0X
  1199. END FPString;
  1200. (* fp = fp <*> (fpExtern | fpExternR | fpIntern | fpOther + vis) *)
  1201. PROCEDURE FPVisibility*(VAR fp: LONGINT; vis: SET);
  1202. BEGIN
  1203. IF SyntaxTree.PublicWrite IN vis THEN FPNumber(fp, fpExtern)
  1204. ELSIF SyntaxTree.PublicRead IN vis THEN FPNumber(fp, fpExternR)
  1205. ELSIF SyntaxTree.Internal * vis #{} THEN FPNumber(fp, fpIntern)
  1206. ELSE
  1207. FPNumber(fp, fpOther + SYSTEM.VAL(LONGINT, vis))
  1208. END
  1209. END FPVisibility;
  1210. PROCEDURE DumpFingerPrint*(w: Streams.Writer; fp: FingerPrint);
  1211. BEGIN
  1212. w.String("fingerprint: ");
  1213. w.String("shallow = "); w.Hex(fp.shallow,8);
  1214. w.String(", private = "); w.Hex(fp.private,8);
  1215. w.String(", public = "); w.Hex(fp.public,8);
  1216. w.Ln;
  1217. END DumpFingerPrint;
  1218. END FoxFingerPrinter.