FoxFingerPrinter.Mod 43 KB

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