FoxFingerPrinter.Mod 43 KB

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