PCOM.Mod 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912
  1. (* Paco, Copyright 2000 - 2002, Patrik Reali, ETH Zurich *)
  2. MODULE PCOM; (** AUTHOR "prk"; PURPOSE "Parallel Compiler: symbol file plug-in"; *)
  3. (*
  4. PaCo, OM Symbol File Generator
  5. Warning: the SF tags must still be fine-tuned
  6. - remove SFcproc and fill hole
  7. - is SFtypSptr used?
  8. This file doesn't match exactly the OM-Format from mf/tk!
  9. SymFile = {modname} 0X
  10. [SFConst {Structure name val}]
  11. [SFvar {[SFreadonly] Structure name}]
  12. [SFxproc {Structure name ParList}]
  13. (* [SFlproc {Structure name ParList}] *)
  14. [SFoperator {Structure name ParList}]
  15. [SFcproc {Structure name ParList code}]
  16. [SFalias {Structure name}]
  17. [SFtyp {Structure}]
  18. SFEnd.
  19. ParList = {[SFvar] Structure name} SFEnd.
  20. Structure = Basic | UserStr | oldstr | modno (name | 0X oldimpstrn).
  21. Basic = SFtypBool .. SFtypNilTyp.
  22. UserStr = [SFinvisible][SFsysflag flag] UserStr2.
  23. UserStr2 = (SFtypOpenArr | SFtypDynArr) Structure name
  24. | SFtypArray Structure name sizen
  25. | SFtypPointer Structure name
  26. | SFtypProcTyp Structure name ParList
  27. | SFtypRecord Structure name prion flagsn RecStr
  28. RecDef = {[SFreadonly] Structure name}[SFtproc {Structure name ParList}] SFend.
  29. name object name written with 0X compression (last char incremented by 80X)
  30. initializers start with "&"
  31. record bodies @Body
  32. records invisible fields and methods are exported with name ""
  33. prio: any LONGINT
  34. flags: SET
  35. bit 0 Protectable
  36. bit 2 Active
  37. bit 3 Safe
  38. oldstr internal structure numbering ]-oo, 0] (!!! OM ]-oo, -1] !!!)
  39. on first export of an UserStr, a refnr is assigned, used then for
  40. further exports
  41. oldimpstr external structure numbering [0, +oo[
  42. on first re-export of a structure, a refnr is assigned and then used
  43. for all the succesive exports
  44. Every imported module has an own re-export numbering.
  45. 1, 2, 4: Size of the value
  46. n: compressed number (WriteNum/ReadNum)
  47. *)
  48. IMPORT
  49. SYSTEM, Modules, StringPool, PCM, PCS, PCT, PCBT, PCLIR;
  50. CONST
  51. Trace = FALSE;
  52. TraceCalls = FALSE; (*exported procedures*)
  53. TraceImport = FALSE;
  54. StrictChecks = TRUE; (*some more sanity checks*)
  55. TraceFPName = "D1";
  56. TraceFP = TRUE;
  57. ImportedModuleFlag = {};
  58. (*
  59. ImportedModuleFlag = {PCT.Overloading};
  60. *)
  61. (*
  62. ProgTools.Enumerate 01
  63. SFtypBool SFtypChar8 SFtypInt8 SFtypInt16 SFtypInt32 SFtypInt64
  64. SFtypFloat32 SFtypFloat64 SFtypSet SFtypString SFtypNoTyp SFtypNilTyp
  65. SFtypByte SFtypSptr
  66. SFmod1
  67. ~
  68. ProgTools.Enum 01
  69. SFtypBool SFtypChar8 SFtypChar16 SFtypChar32 SFtypInt8 SFtypInt16 SFtypInt32 SFtypInt64
  70. SFtypFloat32 SFtypFloat64
  71. SFtypSet SFtypString SFtypNoTyp SFtypNilTyp
  72. SFtypByte SFtypSptr
  73. SFmod1
  74. ~
  75. *)
  76. (* Symbol File Tags *)
  77. UndefTag = -1;
  78. (*
  79. SFtypBool=01H; SFtypChar8=02H; SFtypInt8=03H; SFtypInt16=04H; SFtypInt32=05H; SFtypInt64=06H;
  80. SFtypFloat32=07H; SFtypFloat64=08H; SFtypSet=09H; SFtypString=0AH; SFtypNoTyp=0BH; SFtypNilTyp=0CH;
  81. SFtypByte=0DH; SFtypSptr=0EH;
  82. SFmod1=0FH;
  83. *)
  84. SFtypBool = 1; SFtypChar8 = 2; SFtypChar16 = 3; SFtypChar32 = 4;
  85. SFtypInt8 = 5; SFtypInt16 = 6; SFtypInt32 = 7; SFtypInt64 = 8;
  86. SFtypFloat32 = 9; SFtypFloat64 = 10; SFtypSet = 11; SFtypString = 12;
  87. SFtypNoTyp = 13; SFtypNilTyp = 14; SFtypByte = 15; SFtypSptr = 16;
  88. SFmod1 = 17;
  89. SFlastStruct = SFtypSptr;
  90. SFmodOther=2DH;
  91. SFtypOpenArr=2EH; SFtypDynArr=2FH; SFtypArray=30H; SFtypPointer=31H; SFtypRecord=32H; SFtypProcTyp=33H;
  92. SFsysflag=34H; SFinvisible=35H; SFreadonly=36H; SFobjflag = 37H; (* fof: very (!) bad idea to have same number for two type flags *)
  93. SFconst=37H; SFvar=38H;
  94. SFlproc=39H; SFxproc=3AH; SFoperator=3BH; SFtproc=3CH; SFcproc = SFtproc;
  95. SFalias=3DH; SFtyp=3EH;
  96. SFend= 3FH;
  97. (** fof >> *)
  98. SFtypOpenEnhArr = 40H; SFtypDynEnhArr = 41H; SFtypTensor=42H; SFtypStaticEnhArray = 43H; (*fof*)
  99. (** << fof *)
  100. (* workaround: handle inlined operators *)
  101. InlineMarker = 0ABH;
  102. SFdelegate = 5;
  103. (*Fingerprints/Obj Modes*)
  104. FPMvar=1; FPMpar=1; FPMvarpar=2; FPMconst=3; FPMfield=4; FPMtype=5; FPMxproc=7; FPMcproc=9;
  105. FPMmethod=13;
  106. FPMinit=14;
  107. (*Fingerprints/Type Forms*)
  108. FPFbyte = 1;
  109. FPFbool=2; FPFchar8=3; FPFint8typ=4; FPFint16typ=5; FPFint32typ=6; FPFfloat32typ=7; FPFfloat64typ=8;
  110. FPFsettyp=9; FPFstringtyp=10;
  111. FPFnotyp = 12;
  112. FPFpointer=13; FPFproc=14; FPFcomp=15;
  113. FPFint64typ=16;
  114. FPFchar16typ = 17;
  115. FPFchar32typ = 18;
  116. FPFbasic=1; FPFstaticarr=2; FPFdynarr=4; FPFopenarr=5; FPFrecord=6;
  117. FPintern=0; FPextern=1; FPexternR=2; FPothervis =3;
  118. FPfalse=0; FPtrue=1;
  119. FPhasBody = 2H; FPprotected = 10H; FPactive = 20H;
  120. FPdelegate = 5; FPsystemType = 6;
  121. empty = -1; (*empty string index*)
  122. readonly = PCT.Internal + {PCT.PublicR};
  123. TYPE
  124. ReadStringProc = PROCEDURE (VAR R: PCM.SymReader; VAR string: ARRAY OF CHAR);
  125. StringBuf = ARRAY 256 OF CHAR;
  126. ImportList = POINTER TO ARRAY OF StringPool.Index;
  127. Symbol* = OBJECT (PCM.Attribute) (*attributes for PCT.Symbol*)
  128. VAR
  129. fp*: LONGINT; (*fingerprint*)
  130. sibling: PCT.Symbol;
  131. END Symbol;
  132. Struct* = OBJECT (PCM.Attribute) (*attributes for PCT.Struct*)
  133. VAR
  134. fp*, pbfp*, pvfp*: LONGINT; (*fingerprint*)
  135. fpdone* {UNTRACED} : PCT.Module; (*module relative to which the fp has been computed*)
  136. strref*: LONGINT; (*import: index for struct array*)
  137. tag: LONGINT; (*tag->export/import number*)
  138. uref*: LONGINT;
  139. mod*: PCT.Module; (*defining module*)
  140. PROCEDURE & Init*(mod: PCT.Module);
  141. BEGIN fpdone := NIL; tag := UndefTag; fp := 0; pbfp := 0; pbfp := 0;
  142. IF mod # NIL THEN SELF.mod := mod.scope.owner END (* canonical representation *)
  143. END Init;
  144. END Struct;
  145. StructArray = POINTER TO ARRAY OF PCT.Struct;
  146. Module* = OBJECT (PCM.Attribute) (*attributes for PCT.Module*)
  147. VAR
  148. nofimp: LONGINT; import: PCT.ModuleArray; (*import: list of all modules imported by SELF, [0..nofimp[*)
  149. nofstr: LONGINT; struct: StructArray; (*import: list of own structures, [0..nofstr[ *)
  150. nofreimp: LONGINT; reimp: StructArray; (*import of main: list of structs used by main, [0..nofreimp[*)
  151. expnumber: LONGINT; (*export of main: this module reference [1..oo[ ; OM uses mode for this*)
  152. changed: BOOLEAN; (*self-import: imported obj doesn't exist anymore*)
  153. PROCEDURE & Init*;
  154. BEGIN
  155. changed:=FALSE;
  156. nofimp:=0; nofstr:=0; nofreimp:=0; expnumber:=0;
  157. NEW(struct, 32);
  158. END Init;
  159. END Module;
  160. VAR
  161. predefStruct: ARRAY SFlastStruct+1 OF PCT.Struct;
  162. (*
  163. FPvis: ARRAY 5 OF SHORTINT;
  164. *)
  165. FParray: ARRAY 6 OF SHORTINT;
  166. altSelf: PCS.Name; (*predefined strings*)
  167. Ninterfaces, NpatchPointer0: LONGINT;
  168. (** ========== Symbol Table Checker ============== *)
  169. (** ---------- Fingerprinting -------------- *)
  170. PROCEDURE FPrint(VAR fp: LONGINT; val: LONGINT);
  171. BEGIN fp:=SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ROT(fp, 7)) / SYSTEM.VAL(SET, val))
  172. END FPrint;
  173. PROCEDURE FPrintSet(VAR fp: LONGINT; set: SET);
  174. BEGIN FPrint(fp, SYSTEM.VAL(LONGINT, set))
  175. END FPrintSet;
  176. PROCEDURE FPrintReal(VAR fp: LONGINT; real: REAL);
  177. BEGIN FPrint(fp, SYSTEM.VAL(LONGINT, real))
  178. END FPrintReal;
  179. PROCEDURE FPrintLReal(VAR fp: LONGINT; lr: LONGREAL);
  180. VAR l, h: LONGINT;
  181. BEGIN
  182. SYSTEM.GET(ADDRESSOF(lr)+4, l); SYSTEM.GET(ADDRESSOF(lr), h);
  183. FPrint(fp, l); FPrint(fp, h);
  184. END FPrintLReal;
  185. PROCEDURE FPrintName*(VAR fp: LONGINT; name: ARRAY OF CHAR);
  186. VAR i: INTEGER; ch: CHAR;
  187. BEGIN i:=0; REPEAT ch:=name[i]; FPrint(fp, ORD(ch)); INC(i) UNTIL ch=0X
  188. END FPrintName;
  189. PROCEDURE FPrintVis(VAR fp: LONGINT; vis: SET);
  190. BEGIN
  191. IF vis = PCT.Public THEN FPrint(fp, FPextern)
  192. ELSIF vis = readonly THEN FPrint(fp, FPexternR)
  193. ELSIF vis = PCT.Internal THEN FPrint(fp, FPintern)
  194. ELSE
  195. FPrint(fp, FPothervis + SYSTEM.VAL(LONGINT, vis))
  196. (*
  197. HALT(99)
  198. *)
  199. END
  200. END FPrintVis;
  201. PROCEDURE FPrintSign(VAR fp: LONGINT; par: PCT.Parameter; self: PCT.Parameter; ret: PCT.Struct; current: PCT.Module;
  202. isOperator: BOOLEAN);
  203. PROCEDURE FPrintPar(VAR fp: LONGINT; par: PCT.Parameter; current: PCT.Module);
  204. VAR str: StringBuf;
  205. BEGIN
  206. IF par.ref THEN FPrint(fp, FPMvarpar) ELSE FPrint(fp, FPMpar) END;
  207. IF par.type # NIL THEN FPrintTyp0(par.type, current); FPrint(fp, par.type.sym(Struct).fp) END;
  208. IF isOperator & (par.type # NIL) & (par.type.owner # NIL) THEN
  209. StringPool.GetString(par.type.owner.name, str);
  210. FPrintName(fp, str);
  211. END;
  212. END FPrintPar;
  213. BEGIN
  214. FPrintTyp0(ret, current); FPrint(fp, ret.sym(Struct).fp);
  215. IF self # NIL THEN FPrintPar(fp, self, current) END;
  216. WHILE (par#self) DO
  217. FPrintPar(fp, par, current);
  218. par:=par.nextPar
  219. END;
  220. END FPrintSign;
  221. PROCEDURE FPrintMeth(VAR pbfp, pvfp: LONGINT; mth, init, body: PCT.Method; current: PCT.Module);
  222. VAR fp: LONGINT; oAttr: Symbol; str: StringBuf;
  223. BEGIN
  224. IF (mth.vis # PCT.Internal) THEN
  225. IF mth.sym=NIL THEN NEW(oAttr); mth.sym:=oAttr ELSE oAttr := mth.sym(Symbol) END;
  226. fp:=0;
  227. FPrint(fp, FPMmethod);
  228. StringPool.GetString(mth.name, str); FPrintName(fp, str);
  229. FPrintSign(fp, mth.scope.firstPar, mth.self, mth.type, current, FALSE);
  230. (*
  231. IF mth = init THEN FPrint(fp, -1) END;
  232. *)
  233. oAttr.fp:=fp; (* mfix *)
  234. FPrint(fp, mth.adr(PCBT.Method).mthNo);
  235. IF mth # body THEN
  236. FPrint(pbfp, fp); FPrint(pvfp, fp)
  237. END
  238. END
  239. END FPrintMeth;
  240. PROCEDURE FPrintRecord(typ: PCT.Record; current: PCT.Module);
  241. VAR p: PCT.Symbol; fld: PCT.Variable; adr, i, flags, fp, pbfp, pvfp: LONGINT; tAttr: Struct; oAttr: Symbol;
  242. scope: PCT.RecScope; intf: PCT.Interface;
  243. name: ARRAY 32 OF CHAR; dump: BOOLEAN;
  244. str: StringBuf;
  245. BEGIN
  246. IF TraceFP THEN
  247. PCT.GetTypeName(typ, name); dump := name = TraceFPName
  248. END;
  249. tAttr := typ.sym(Struct);
  250. pvfp := tAttr.fp; pbfp := tAttr.fp;
  251. IF TraceFP & dump THEN
  252. PCM.LogWLn; PCM.LogWStr("FPRec, Base "); PCM.LogWHex(pvfp)
  253. END;
  254. scope := typ.scope;
  255. IF typ.intf # NIL THEN
  256. FOR i := 0 TO LEN(typ.intf)-1 DO
  257. intf := typ.intf[i];
  258. FPrintTyp(intf, current);
  259. tAttr := intf.sym(Struct);
  260. FPrint(pvfp, tAttr.pvfp);
  261. FPrint(pbfp, tAttr.pbfp);
  262. END
  263. END;
  264. IF typ.brec#NIL THEN
  265. tAttr := typ.brec.sym(Struct);
  266. FPrint(pvfp, tAttr.pvfp);
  267. FPrint(pbfp, tAttr.pbfp);
  268. END;
  269. IF TraceFP & dump THEN
  270. PCM.LogWLn; PCM.LogWStr("FPRec, Init "); PCM.LogWHex(pvfp); PCM.LogWStr(" "); PCM.LogWHex(pbfp)
  271. END;
  272. p := scope.sorted;
  273. WHILE p # NIL DO
  274. IF p IS PCT.Method THEN
  275. WITH p: PCT.Method DO
  276. FPrintMeth(pbfp, pvfp, p, scope.initproc, scope.body, current);
  277. IF TraceFP & dump THEN
  278. PCM.LogWLn; PCM.LogWStr("FPRec, Mth "); PCM.LogWHex(pvfp); PCM.LogWStr(" "); PCM.LogWHex(pbfp);
  279. PCM.LogWStr(" "); PCM.LogWStr0(p.name);
  280. PCM.LogWStr(" ");
  281. PCM.LogWNum(p.adr(PCBT.Method).mthNo);
  282. PCM.LogWStr(" ");
  283. IF p = scope.body THEN PCM.LogWStr("B") END;
  284. IF p = scope.initproc THEN PCM.LogWStr("&") END
  285. END
  286. END
  287. END;
  288. p := p.sorted
  289. END;
  290. fld := scope.firstVar;
  291. WHILE fld#NIL DO
  292. FPrintTyp(fld.type, current);
  293. tAttr := fld.type.sym(Struct);
  294. IF fld.vis#PCT.Internal THEN fp:=0; FPrint(fp, FPMfield);
  295. StringPool.GetString(fld.name, str); FPrintName(fp, str); FPrintVis(fp, fld.vis);
  296. IF PCM.Untraced IN fld.flags THEN FPrint(fp, PCM.Untraced) END;
  297. FPrint(fp, tAttr.fp);
  298. IF fld.sym = NIL THEN NEW(oAttr); fld.sym := oAttr ELSE oAttr := fld.sym(Symbol) END;
  299. oAttr.fp:=fp;
  300. adr := fld.adr(PCBT.Variable).offset;
  301. FPrint(pbfp, tAttr.pbfp); FPrint(pbfp, adr);
  302. FPrint(pvfp, tAttr.pvfp); FPrint(pvfp, adr);
  303. FPrint(pvfp, fp); FPrint(pbfp, fp);
  304. ELSE
  305. fp := 0;
  306. IF PCM.Untraced IN fld.flags THEN FPrint(fp, PCM.Untraced) END;
  307. FPrint(pvfp, fp) (* seems an error to me, I would use FPrint(pvfp, tAttr.fp) *)
  308. END;
  309. IF TraceFP & dump THEN
  310. PCM.LogWLn; PCM.LogWStr("FPRec, Fld "); PCM.LogWHex(pvfp); PCM.LogWStr(" "); PCM.LogWHex(pbfp);
  311. PCM.LogWStr(" "); PCM.LogWStr0(fld.name);
  312. PCM.LogWStr(" "); PCM.LogWNum(adr);
  313. END;
  314. fld := fld.nextVar
  315. END;
  316. IF ~(PCT.exclusive IN typ.mode) & (typ.brec # NIL) & (PCT.exclusive IN typ.brec.mode)THEN
  317. INCL(typ.mode, PCT.exclusive)
  318. END;
  319. flags := 0;
  320. IF scope.body # NIL THEN INC(flags, FPhasBody) END;
  321. IF PCT.active IN typ.mode THEN INC(flags, FPactive) END;
  322. IF PCT.exclusive IN typ.mode THEN INC(flags, FPprotected) END;
  323. FPrint(pbfp, flags);
  324. IF TraceFP & dump THEN
  325. PCM.LogWLn; PCM.LogWStr("FPRec, Flg "); PCM.LogWHex(pvfp); PCM.LogWStr(" "); PCM.LogWHex(pbfp); PCM.LogWHex(flags)
  326. END;
  327. tAttr := typ.sym(Struct); tAttr.pbfp := pbfp; tAttr.pvfp := pvfp; (* replace typ.pbfp with pbfp and typ.pvfp with pvfp *)
  328. END FPrintRecord;
  329. PROCEDURE FPrintTyp0(typ: PCT.Struct; current: PCT.Module);
  330. (* calculate fingerprint without looking at record fields, private and public fingerprints *)
  331. VAR fp, i: LONGINT; mode: SHORTINT; rec: PCT.Record; intf: PCT.Interface; tAttr: Struct; base: PCT.Struct;
  332. name: ARRAY 32 OF CHAR; dump: BOOLEAN; str: StringBuf;
  333. PROCEDURE Name; (*has side effects on the local variables!!!*)
  334. (* VAR str: StringBuf; *)
  335. BEGIN
  336. IF (tAttr.mod # NIL) & (tAttr.mod.scope # current.scope) THEN (*imported*)
  337. StringPool.GetString(tAttr.mod.name, str);
  338. FPrintName(fp, str);
  339. IF typ.owner#NIL THEN StringPool.GetString(typ.owner.name, str); FPrintName(fp, str) ELSE FPrint(fp, 0) END
  340. END;
  341. IF dump THEN
  342. PCM.LogWLn; PCM.LogWStr("FPTyp0, Name "); PCM.LogWHex(fp);
  343. PCM.LogWStr(" "); PCM.LogWStr0(current.name);
  344. PCM.LogWStr(" "); PCM.LogWStr0(tAttr.mod.name);
  345. PCM.LogWStr(" "); PCM.LogWStr(str);
  346. END
  347. END Name;
  348. BEGIN
  349. ASSERT(typ#NIL);
  350. IF ~(typ IS PCT.Basic) & (typ # PCT.String) & (typ # PCT.NilType) & (typ # PCT.NoType) THEN
  351. IF TraceFP THEN
  352. PCT.GetTypeName(typ, name);
  353. dump := name = TraceFPName
  354. END;
  355. IF typ.sym=NIL THEN NEW(tAttr, current); typ.sym:=tAttr
  356. (*
  357. ;PCM.LogWLn; PCM.LogWStr(" struc0 ");
  358. IF typ.owner # NIL THEN PCM.LogWStr0(typ.owner.name) END
  359. *)
  360. ELSE tAttr:=typ.sym(Struct) END;
  361. IF tAttr.fpdone # current THEN tAttr.fpdone := NIL END; (* reset fpdone: fp can be changed without changing it calling through FPSign! *)
  362. fp:=0;
  363. IF typ IS PCT.Pointer THEN
  364. FPrint(fp, FPFpointer); FPrint(fp, FPFbasic); ASSERT(typ.flags = {});
  365. Name;
  366. tAttr.fp:=fp; base := typ(PCT.Pointer).base;
  367. FPrintTyp0(base, current); FPrint(tAttr.fp, base.sym(Struct).fp);
  368. ELSIF typ IS PCT.Record THEN
  369. FPrint(fp, FPFcomp); FPrint(fp, FPFrecord);
  370. IF PCT.SystemType IN typ.flags THEN FPrint(fp, FPsystemType) END;
  371. rec := typ(PCT.Record);
  372. Name;
  373. tAttr.fp:=fp;
  374. IF rec.intf # NIL THEN
  375. FOR i := 0 TO LEN(rec.intf)-1 DO
  376. intf := rec.intf[i];
  377. FPrintTyp0(intf, current);
  378. FPrint(tAttr.fp, intf.sym(Struct).fp)
  379. END
  380. END;
  381. IF rec.brec # NIL THEN FPrintTyp0(rec.brec, current); FPrint(tAttr.fp, rec.brec.sym(Struct).fp) END;
  382. IF dump & (rec.brec # NIL) THEN PCM.LogWLn; PCM.LogWStr("FPTyp0, has base ") END
  383. ELSIF typ IS PCT.Array THEN
  384. WITH typ: PCT.Array DO
  385. mode := typ.mode;
  386. FPrint(fp, FPFcomp); FPrint(fp, FParray[mode]); ASSERT(typ.flags = {});
  387. Name; tAttr.fp:=fp;
  388. IF mode IN {PCT.static, PCT.open} THEN
  389. FPrintTyp0(typ.base, current);
  390. FPrint(tAttr.fp, typ.base.sym(Struct).fp);
  391. IF mode=PCT.static THEN FPrint(tAttr.fp, typ.len) END
  392. END;
  393. tAttr.pbfp:=tAttr.fp; tAttr.pvfp:=tAttr.fp
  394. END
  395. (** fof >> *)
  396. ELSIF typ IS PCT.EnhArray THEN (*fof*)
  397. WITH typ: PCT.EnhArray DO
  398. mode := typ.mode;
  399. FPrint( fp, FPFcomp ); FPrint( fp, FParray[mode] ); (*ASSERT(typ.flags = {});*)
  400. Name; tAttr.fp := fp;
  401. IF mode IN {PCT.static, PCT.open} THEN
  402. FPrintTyp0( typ.base, current ); FPrint( tAttr.fp, typ.base.sym( Struct ).fp );
  403. IF mode = PCT.static THEN FPrint( tAttr.fp, typ.len ) END
  404. END;
  405. tAttr.pbfp := tAttr.fp; tAttr.pvfp := tAttr.fp
  406. END
  407. ELSIF typ IS PCT.Tensor THEN
  408. WITH typ: PCT.Tensor DO
  409. FPrint( fp, FPFcomp );
  410. Name; tAttr.fp := fp;
  411. FPrintTyp0( typ.base, current ); FPrint( tAttr.fp, typ.base.sym( Struct ).fp );
  412. tAttr.pbfp := tAttr.fp; tAttr.pvfp := tAttr.fp
  413. END;
  414. (** << fof *)
  415. ELSIF typ IS PCT.Delegate THEN
  416. WITH typ: PCT.Delegate DO
  417. FPrint(fp, FPFproc); FPrint(fp, FPFbasic);
  418. IF ~(PCT.StaticMethodsOnly IN typ.flags) THEN FPrint(fp, FPdelegate) END;
  419. Name; tAttr.fp:=fp;
  420. FPrintSign(tAttr.fp, typ.scope.firstPar, NIL, typ.return, current, FALSE);
  421. tAttr.pbfp:=tAttr.fp; tAttr.pvfp:=tAttr.fp
  422. END
  423. END;
  424. IF dump THEN
  425. PCM.LogWLn; PCM.LogWStr("FPTyp0, End "); PCM.LogWHex(tAttr.fp)
  426. END
  427. END
  428. END FPrintTyp0;
  429. PROCEDURE FPrintTyp*(typ: PCT.Struct; current: PCT.Module);
  430. (* fpdone 0: not done yet >0: done for module fpdone-1 =-1: built in type *)
  431. VAR tAttr: Struct; name: ARRAY 32 OF CHAR;
  432. BEGIN
  433. current := current.scope.owner; (* canonical representation *)
  434. IF typ.sym=NIL THEN NEW(tAttr, current); typ.sym:=tAttr
  435. (*
  436. ;PCM.LogWLn; PCM.LogWStr(" struct ");
  437. IF typ.owner # NIL THEN PCM.LogWStr0(typ.owner.name) END
  438. *)
  439. ELSE tAttr:=typ.sym(Struct) END;
  440. IF ~(typ IS PCT.Basic) & (tAttr.fpdone # current) THEN
  441. IF TraceCalls THEN
  442. PCT.GetTypeName(typ, name);
  443. PCM.LogWLn; PCM.LogWStr("->FPrintTyp "); PCM.LogWStr(name);
  444. END;
  445. FPrintTyp0(typ, current);
  446. IF ~(typ IS PCT.Record) THEN tAttr.fpdone := current END;
  447. IF typ IS PCT.Pointer THEN FPrintTyp(typ(PCT.Pointer).base, current)
  448. ELSIF typ IS PCT.Array THEN FPrintTyp(typ(PCT.Array).base, current)
  449. (** fof >> *)
  450. ELSIF typ IS PCT.EnhArray THEN
  451. FPrintTyp( typ( PCT.EnhArray ).base, current ) (*fof*)
  452. ELSIF typ IS PCT.Tensor THEN
  453. FPrintTyp( typ( PCT.Tensor ).base, current ) (*fof*)
  454. (** << fof *)
  455. ELSIF typ IS PCT.Record THEN
  456. WITH typ: PCT.Record DO
  457. FPrintTyp(typ.btyp, current);
  458. IF (typ.brec # NIL) & (typ.brec.sym(Struct).fpdone # current) THEN
  459. PCT.GetTypeName(typ, name);
  460. (*
  461. PCM.LogWLn; PCM.LogWStr(" FPTyp, warning "); PCM.LogWStr(name);
  462. *)
  463. FPrintTyp(typ.brec, current)
  464. END;
  465. FPrintRecord(typ, current)
  466. END
  467. END;
  468. tAttr.fpdone:=current;
  469. IF TraceCalls THEN
  470. PCM.LogWLn; PCM.LogWStr("<-FPrintTyp "); PCM.LogWStr(name);
  471. END;
  472. IF TraceFP THEN
  473. PCT.GetTypeName(typ, name);
  474. IF name = TraceFPName THEN
  475. PCM.LogWLn; PCM.LogWStr("FPTyp "); PCM.LogWHex(tAttr.fp);
  476. PCM.LogWStr(" ");
  477. PCM.LogWHex(tAttr.pvfp);
  478. PCM.LogWStr(" ");
  479. PCM.LogWHex(tAttr.pbfp);
  480. END
  481. END
  482. END;
  483. END FPrintTyp;
  484. (** fof >> *)
  485. PROCEDURE FPrintConstEnhArray( VAR fp: LONGINT; val: PCT.Value );
  486. BEGIN
  487. IF val.vis # PCT.Internal THEN PCM.Error( -1, -1, "const arrays not fingerprinted yet" )
  488. END; (* otherwise a change does not change the module *)
  489. END FPrintConstEnhArray;
  490. (** << fof *)
  491. PROCEDURE FPrintObj*(obj: PCT.Symbol; current: PCT.Module);
  492. VAR fp, len, pos: LONGINT; con: PCT.Const; oAttr: Symbol; c: PCLIR.AsmBlock; str: StringBuf;
  493. BEGIN
  494. current := current.scope.owner; (* canonical representation *)
  495. (*PCM.LogWLn; PCM.LogWStr("FPrintObj "); PCM.LogWStr(obj.name);*)
  496. StringPool.GetString(obj.name, str);
  497. IF TraceCalls THEN
  498. PCM.LogWLn; PCM.LogWStr("->FPrintObj "); PCM.LogWStr(str);
  499. END;
  500. fp:=0;
  501. IF obj.sym=NIL THEN NEW(oAttr); obj.sym:=oAttr ELSE oAttr:=obj.sym(Symbol) END;
  502. IF obj IS PCT.Value THEN
  503. FPrint(fp, FPMconst); FPrintName(fp, str); FPrintVis(fp, obj.vis);
  504. IF obj.type.sym # NIL THEN (** fof 070731*)
  505. FPrint(fp, obj.type.sym(Struct).fp);
  506. END; (** fof 070731 *)
  507. FPrint(fp, FPFbasic);
  508. con:=obj(PCT.Value).const;
  509. IF con.type=PCT.Bool THEN
  510. IF con.bool THEN FPrint(fp, FPtrue) ELSE FPrint(fp, FPfalse) END
  511. ELSIF con.type=PCT.Char8 THEN FPrint(fp, con.int)
  512. ELSIF con.type=PCT.Int64 THEN FPrintLReal(fp, SYSTEM.VAL(LONGREAL, con.long))
  513. ELSIF PCT.IsCardinalType(con.type) THEN FPrint(fp, con.int)
  514. ELSIF con.type=PCT.Set THEN FPrintSet(fp, con.set)
  515. ELSIF con.type=PCT.Float32 THEN FPrintReal(fp, SHORT(con.real))
  516. ELSIF con.type=PCT.Float64 THEN FPrintLReal(fp, con.real)
  517. ELSIF con.type=PCT.String THEN FPrintName(fp, con.str^)
  518. (** fof >> *)
  519. ELSIF con.type IS PCT.EnhArray THEN
  520. FPrintConstEnhArray( fp, obj( PCT.Value ) );
  521. (** << fof *)
  522. ELSE
  523. HALT(99)
  524. END
  525. ELSIF obj IS PCT.GlobalVar THEN
  526. FPrint(fp, FPMvar); FPrintName(fp, str); FPrintVis(fp, obj.vis);
  527. FPrintTyp(obj.type, current); FPrint(fp, obj.type.sym(Struct).fp);
  528. ELSIF (obj IS PCT.Proc)&(obj.vis=PCT.Public) THEN
  529. WITH obj: PCT.Proc DO
  530. IF PCT.Inline IN obj.flags THEN
  531. FPrint(fp, FPMcproc); FPrintName(fp, str); FPrintVis(fp, obj.vis);
  532. FPrintSign(fp, obj.scope.firstPar, NIL, obj.type, current, PCT.Operator IN obj.flags);
  533. c := obj.scope.code(PCLIR.AsmInline).code;
  534. WHILE c # NIL DO
  535. len := c.len; pos := 0;
  536. FPrint(fp, len);
  537. WHILE pos < len DO FPrint(fp, ORD(c.code[pos])); INC(pos) END;
  538. c := c.next
  539. END;
  540. ELSE
  541. FPrint(fp, FPMxproc);
  542. FPrintName(fp, str); FPrintVis(fp, obj.vis);
  543. FPrintSign(fp, obj.scope.firstPar, NIL, obj.type, current, PCT.Operator IN obj.flags)
  544. END
  545. END
  546. ELSIF obj IS PCT.Type THEN
  547. FPrint(fp, FPMtype);
  548. FPrintName(fp, str);
  549. FPrintVis(fp, obj.vis);
  550. FPrintTyp(obj.type, current); FPrint(fp, obj.type.sym(Struct).fp);
  551. END;
  552. oAttr.fp:=fp;
  553. IF TraceCalls THEN
  554. PCM.LogWLn; PCM.LogWStr("<-FPrintObj "); PCM.LogWStr(str);
  555. END
  556. END FPrintObj;
  557. (* ========== Symbol File Saver ============== *)
  558. PROCEDURE Export*(VAR r: PCM.Rider; M: PCT.Module; new, extend, skipImport: BOOLEAN; VAR msg: ARRAY OF CHAR);
  559. VAR name: StringBuf;
  560. oldM: PCT.Module; nofstruct: LONGINT;
  561. newsym, changed, extended: BOOLEAN; MAttr: Module;
  562. impList: ImportList;
  563. PROCEDURE TypeChanged(new, old: PCT.Struct): BOOLEAN;
  564. VAR newstr, oldstr: Struct;
  565. BEGIN
  566. IF (new IS PCT.Record) THEN (* if type composition different -> fp different! *)
  567. newstr := new.sym(Struct); oldstr := old.sym(Struct);
  568. RETURN (newstr.pbfp # oldstr.pbfp) OR (newstr.pvfp # oldstr.pvfp)
  569. ELSIF (new IS PCT.Pointer) THEN
  570. RETURN TypeChanged(new(PCT.Pointer).base, old(PCT.Pointer).base)
  571. ELSIF (new IS PCT.Array) THEN
  572. RETURN TypeChanged(new(PCT.Array).base, old(PCT.Array).base)
  573. (** fof >> *)
  574. ELSIF (new IS PCT.EnhArray) THEN (*fof*)
  575. RETURN TypeChanged( new( PCT.EnhArray ).base, old( PCT.EnhArray ).base )
  576. ELSIF (new IS PCT.Tensor) THEN
  577. RETURN TypeChanged( new( PCT.Tensor ).base, old( PCT.Tensor ).base )
  578. (** << fof *)
  579. END;
  580. RETURN FALSE
  581. END TypeChanged;
  582. PROCEDURE CompareSymbol(new: PCT.Symbol; e, s: BOOLEAN);
  583. VAR old: PCT.Symbol; newsym: Symbol;
  584. BEGIN
  585. IF Trace THEN PCM.LogWLn; PCM.LogWStr("PCOM.Compare "); PCM.LogWStr0(new.name) END;
  586. FPrintObj(new, M); (*always compute the fp, will be used by other compiler components*)
  587. newsym := new.sym(Symbol); old := newsym.sibling;
  588. IF old # NIL THEN (* an old version exists .... *)
  589. FPrintObj(old, M);
  590. (* operators are not checked for changes *)
  591. IF ~(PCT.Operator IN new.flags) THEN
  592. IF (old.sym(Symbol).fp # newsym.fp) OR
  593. ((new IS PCT.Type) OR (new.type IS PCT.Record) & (new.type.owner = NIL)) & TypeChanged(new.type, old.type) THEN
  594. changed:=TRUE; PCM.ErrorN(402, PCM.InvalidPosition, new.name)
  595. END
  596. END
  597. ELSIF new.vis # PCT.Internal THEN (*new export*)
  598. extended:=TRUE; PCM.ErrorN(403, PCM.InvalidPosition, new.name)
  599. END
  600. END CompareSymbol;
  601. PROCEDURE OutParList(p: PCT.Parameter);
  602. (* export procedure parameters. Methods: self is already exported *)
  603. BEGIN
  604. WHILE (p # NIL) & (p.name # PCT.SelfName) DO
  605. IF PCT.WinAPIParam IN p.flags THEN (* ejz *)
  606. PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.WinAPIParam)
  607. ELSIF PCT.CParam IN p.flags THEN (* fof for Linux *)
  608. PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.CParam)
  609. END;
  610. IF p.ref THEN PCM.SymWNum(r, SFvar); END;
  611. (** fof >> *)
  612. IF PCM.ReadOnly IN p.flags THEN (* fof *)
  613. PCM.SymWNum(r, SFreadonly);
  614. END;
  615. (** << fof *)
  616. OutObj(p);
  617. p := p.nextPar
  618. END;
  619. PCM.SymWNum(r,SFend)
  620. END OutParList;
  621. PROCEDURE OutConst(c: PCT.Const);
  622. VAR type: PCT.Struct;
  623. BEGIN
  624. type := c.type;
  625. IF type = PCT.Char8 THEN PCM.SymWNum(r, c.int)
  626. ELSIF type = PCT.Int64 THEN PCM.SymWLReal(r, SYSTEM.VAL(LONGREAL, c.long))
  627. ELSIF PCT.IsCardinalType(type) THEN PCM.SymWNum(r, c.int)
  628. ELSIF type = PCT.Float32 THEN PCM.SymWReal(r, SHORT(c.real))
  629. ELSIF type = PCT.Float64 THEN PCM.SymWLReal(r, c.real)
  630. ELSIF type = PCT.String THEN PCM.SymWString(r, c.str^)
  631. ELSIF type = PCT.Bool THEN PCM.SymWNum(r, SYSTEM.VAL(SHORTINT, c.bool))
  632. ELSIF type = PCT.Set THEN PCM.SymWNum(r, SYSTEM.VAL(LONGINT, c.set))
  633. (** fof >> *)
  634. ELSIF type IS PCT.EnhArray THEN
  635. PCM.Error( 200, -1, "const arrays cannot be exported yet" );
  636. (** << fof *)
  637. ELSE HALT(99)
  638. END
  639. END OutConst;
  640. PROCEDURE OutImpMod(name: ARRAY OF CHAR; mAttr: Module);
  641. VAR m: Module; index: StringPool.Index;
  642. BEGIN
  643. IF mAttr.expnumber = 0 THEN (*first export from this module*)
  644. (* PCM.SymWMod(r, name); (*real name, not alias*) *)
  645. StringPool.GetIndex(name, index);
  646. AddImport(impList, index);
  647. (*
  648. m := mAttr.main.sym(Module);
  649. ASSERT(mAttr.main = M);
  650. *)
  651. m := M.sym(Module);
  652. INC(m.expnumber);
  653. mAttr.expnumber := m.expnumber; mAttr.nofreimp := 0
  654. END
  655. END OutImpMod;
  656. PROCEDURE OutRecord(rec: PCT.Record);
  657. VAR scope: PCT.RecScope; str: StringBuf; fld: PCT.Variable; mth: PCT.Method; first: BOOLEAN;
  658. BEGIN
  659. scope := rec.scope;
  660. PCM.SymWSet(r, rec.mode);
  661. PCM.SymW(r, CHR(rec.prio));
  662. fld := scope.firstVar;
  663. WHILE fld # NIL DO (*fields*)
  664. IF PCM.Untraced IN fld.flags THEN PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.Untraced) END;
  665. IF fld.vis=readonly THEN PCM.SymWNum(r, SFreadonly) END;
  666. OutStruct(fld.type);
  667. IF fld.vis=PCT.Internal THEN PCM.SymWString(r, "") ELSE StringPool.GetString(fld.name, str); PCM.SymWString(r, str) END;
  668. fld := fld.nextVar
  669. END;
  670. mth := scope.firstMeth; first := TRUE;
  671. WHILE mth # NIL DO (*methods*)
  672. IF ~(PCT.copy IN mth.flags) THEN
  673. IF first THEN PCM.SymWNum(r, SFtproc); first := FALSE END;
  674. IF PCT.RealtimeProc IN mth.flags THEN PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.RealtimeProc) END; (* ug *)
  675. OutStruct(mth.type);
  676. IF mth.vis = PCT.Internal THEN PCM.SymWString(r, "") END;
  677. IF mth = scope.initproc THEN PCM.SymW(r, "&") END;
  678. StringPool.GetString(mth.name, str); PCM.SymWString(r, str);
  679. IF mth.self.ref THEN PCM.SymWNum(r, SFvar) END;
  680. OutStruct(mth.self.type);
  681. PCM.SymWString(r, PCT.SelfNameStr);
  682. OutParList(mth.scope.firstPar);
  683. (* Indlined methods: only meant for Indexer *)
  684. IF (PCT.Inline IN mth.flags) & (PCT.Indexer IN mth.flags) THEN
  685. PCM.SymWNum(r, InlineMarker);
  686. OutInline(mth.scope.code);
  687. END;
  688. END;
  689. mth := mth.nextMeth
  690. END;
  691. PCM.SymWNum(r, SFend)
  692. END OutRecord;
  693. PROCEDURE OutStruct(typ: PCT.Struct);
  694. VAR tAttr: Struct; mAttr: Module; name: StringBuf; ptyp: PCT.Delegate;
  695. i: LONGINT; mname, tname: ARRAY 64 OF CHAR;
  696. BEGIN
  697. IF typ.sym=NIL THEN NEW(tAttr, M); typ.sym:=tAttr
  698. (*
  699. ;PCM.LogWLn; PCM.LogWStr(" outstr ");
  700. IF typ.owner # NIL THEN PCM.LogWStr0(typ.owner.name) END
  701. *)
  702. ELSE tAttr := typ.sym(Struct) END;
  703. ASSERT((tAttr.mod = NIL) OR (tAttr.mod = tAttr.mod.scope.owner), 500);
  704. ASSERT(M = M.scope.owner, 501);
  705. IF (tAttr.mod # NIL) & (tAttr.mod # M) THEN (*imported, reexport*)
  706. mAttr := tAttr.mod.sym(Module);
  707. IF StrictChecks THEN
  708. i := 0;
  709. WHILE (M.imports[i].sym # mAttr) DO INC(i) END; (*check if in imports -> initialized*)
  710. StringPool.GetString(M.imports[i].name, mname);
  711. PCT.GetTypeName(typ, tname);
  712. i := 0;
  713. WHILE (mAttr.struct[i] # typ) DO INC(i) END; (*check typ in struct -> initialized*)
  714. END;
  715. StringPool.GetString(tAttr.mod.name, name); OutImpMod(name, mAttr);
  716. IF mAttr.expnumber > (SFmodOther - SFmod1) THEN PCM.SymWNum(r, SFmodOther); PCM.SymWNum(r, mAttr.expnumber-1)
  717. (*
  718. ;Out.Ln; Out.String("has more than "); Out.Int(SFmodOther - SFmod1, 0); Out.String("imports ");
  719. *)
  720. ELSE PCM.SymWNum(r, SFmod1+mAttr.expnumber-1) END;
  721. (*
  722. IF mAttr.expnumber > 31 THEN PCM.SymWNum(r, SFmodOther); PCM.SymWNum(r, mAttr.expnumber-1)
  723. ELSE PCM.SymWNum(r, SFmod1+mAttr.expnumber-1) END;
  724. *)
  725. IF tAttr.tag = UndefTag THEN
  726. StringPool.GetString(typ.owner.name, name);
  727. PCM.SymWString(r, name); tAttr.tag := mAttr.nofreimp; INC(mAttr.nofreimp)
  728. ELSE
  729. PCM.SymW(r, 0X); PCM.SymWNum(r, tAttr.tag)
  730. END
  731. ELSIF typ IS PCT.Basic THEN PCM.SymWNum(r, tAttr.tag)
  732. ELSIF (typ=PCT.String)OR(typ=PCT.NilType)OR(typ=PCT.NoType) THEN PCM.SymWNum(r, tAttr.tag)
  733. ELSIF tAttr.tag # UndefTag THEN PCM.SymWNum(r, -tAttr.tag)
  734. ELSE tAttr.tag := nofstruct; INC(nofstruct);
  735. IF (typ.owner # NIL) & (typ.owner.vis = PCT.Internal) THEN PCM.SymWNum(r, SFinvisible)
  736. ELSIF (typ IS PCT.Record) & (typ.owner = NIL) THEN PCM.SymWNum(r, SFinvisible) (*inconsistency in symfile*)
  737. END;
  738. name:="";
  739. IF typ.owner#NIL THEN StringPool.GetString(typ.owner.name, name) END;
  740. IF typ IS PCT.Delegate THEN
  741. ptyp := typ(PCT.Delegate);
  742. IF ~(PCT.StaticMethodsOnly IN ptyp.flags) THEN PCM.SymWNum(r, SFsysflag); PCM.SymWNum(r, SFdelegate) END;
  743. PCM.SymWNum(r, SFtypProcTyp); OutStruct(ptyp.return); PCM.SymWString(r, name);
  744. PCM.SymWSet(r, ptyp.flags * {PCT.WinAPIParam, PCT.CParam, PCT.RealtimeProcType});
  745. OutParList(ptyp.scope.firstPar)
  746. ELSIF typ IS PCT.Record THEN
  747. WITH typ: PCT.Record DO
  748. ASSERT((typ.btyp=PCT.NoType) OR (typ.btyp IS PCT.Record) OR (typ.btyp IS PCT.Pointer));
  749. PCM.SymWNum(r, SFtypRecord);
  750. IF typ.intf # NIL THEN
  751. IF (LEN(typ.intf) > 0) & ~(PCM.ExportDefinitions IN PCM.codeOptions) THEN PCM.LogWLn; PCM.LogWStr("Warning: exports definitions, but flag not set") END;
  752. FOR i := 0 TO LEN(typ.intf)-1 DO OutStruct(typ.intf[i]) END
  753. END;
  754. OutStruct(typ.btyp);
  755. PCM.SymWString(r, name);
  756. PCM.SymWNum(r, 0); (* realtime flags ignored in PACO *)
  757. OutRecord(typ)
  758. END
  759. ELSIF typ IS PCT.Array THEN
  760. WITH typ: PCT.Array DO
  761. ASSERT(typ.mode IN {PCT.open, PCT.static});
  762. IF typ.mode=PCT.open THEN
  763. PCM.SymWNum(r, SFtypOpenArr)
  764. ELSIF typ.mode=PCT.static THEN
  765. PCM.SymWNum(r, SFtypArray)
  766. ELSE HALT(99)
  767. END;
  768. OutStruct(typ.base); PCM.SymWString(r, name);
  769. PCM.SymWNum(r, 0); (* realtime flags ignored in PACO *)
  770. IF typ.mode=PCT.static THEN PCM.SymWNum(r, typ.len) END
  771. END
  772. (** fof >> *)
  773. ELSIF typ IS PCT.EnhArray THEN (*fof*)
  774. WITH typ: PCT.EnhArray DO
  775. ASSERT ( typ.mode IN {PCT.open, PCT.static} );
  776. IF typ.mode = PCT.open THEN PCM.SymWNum( r, SFtypOpenEnhArr )
  777. ELSIF typ.mode = PCT.static THEN PCM.SymWNum( r, SFtypStaticEnhArray )
  778. ELSE HALT( 99 )
  779. END;
  780. OutStruct( typ.base );
  781. PCM.SymWString( r, name );
  782. IF typ.mode = PCT.static THEN PCM.SymWNum( r, typ.len ) END
  783. END
  784. ELSIF typ IS PCT.Tensor THEN
  785. WITH typ: PCT.Tensor DO
  786. PCM.SymWNum( r, SFtypTensor );
  787. OutStruct( typ.base ); PCM.SymWString( r, name );
  788. END;
  789. (** << fof *)
  790. ELSIF typ IS PCT.Pointer THEN
  791. PCM.SymWNum(r, SFtypPointer); OutStruct(typ(PCT.Pointer).base);
  792. PCM.SymWString(r, name);
  793. PCM.SymWNum(r, 0); (* realtime flags ignored in PACO *)
  794. END
  795. END
  796. END OutStruct;
  797. PROCEDURE OutObj(o: PCT.Symbol);
  798. VAR str: StringBuf;
  799. BEGIN
  800. IF PCM.Untraced IN o.flags THEN PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.Untraced) END;
  801. IF o.vis = readonly THEN PCM.SymWNum(r, SFreadonly) END;
  802. OutStruct(o.type); StringPool.GetString(o.name, str); PCM.SymWString(r, str)
  803. END OutObj;
  804. PROCEDURE OutInline(i: PCM.Attribute);
  805. VAR p: PCLIR.AsmBlock; len, pos, cnt: LONGINT;
  806. BEGIN
  807. WITH i: PCLIR.AsmInline DO
  808. ASSERT(i.fixup = NIL);
  809. p := i.code; len := 0;
  810. WHILE p # NIL DO INC(len, p.len); p := p.next END;
  811. p := i.code; pos := 0; cnt := 0;
  812. IF len = 0 THEN
  813. PCM.SymW(r, 0X)
  814. ELSE
  815. WHILE pos < len DO
  816. IF cnt = 0 THEN
  817. cnt := 255;
  818. IF len < 255 THEN cnt := len END;
  819. PCM.SymW(r, CHR(cnt))
  820. END;
  821. IF pos >= p.len THEN DEC(len, pos); p := p.next; pos := 0 END;
  822. PCM.SymW(r, p.code[pos]);
  823. INC(pos); DEC(cnt)
  824. END
  825. END;
  826. PCM.SymW(r, 0X)
  827. END;
  828. END OutInline;
  829. PROCEDURE OutModule(m: PCT.Module);
  830. VAR first: BOOLEAN; i, j: LONGINT; str: StringBuf;
  831. mm: Module; scope: PCT.ProcScope;
  832. v: PCT.Variable; p: PCT.Proc; t: PCT.Type; c: PCT.Value; p1, p2, pTmp, t1: PCT.Symbol;
  833. BEGIN
  834. ASSERT(m.scope.state >= PCT.procdeclared);
  835. nofstruct := 0;
  836. PCM.SymWNum(r, 0); (*end of imports*)
  837. IF Trace THEN PCM.LogWLn; PCM.LogWStr("OM.OutModule/const") END;
  838. IF m.imports # NIL THEN (* reset module and structures counters before exporting *)
  839. i := 0;
  840. WHILE (i < LEN(m.imports)) & (m.imports[i] # NIL) DO
  841. IF m.imports[i].sym # NIL THEN
  842. mm := m.imports[i].sym(Module);
  843. mm.expnumber := 0;
  844. mm.nofreimp := 0;
  845. FOR j := 0 TO mm.nofstr-1 DO
  846. mm.struct[j].sym(Struct).tag := UndefTag
  847. END
  848. ELSE
  849. PCM.LogWLn; PCM.LogWStr(" no sym: "); PCM.LogWStr0(m.imports[i].name)
  850. END;
  851. INC(i)
  852. END;
  853. END;
  854. IF PCM.error THEN RETURN END; (*symfile is changed*)
  855. IF {PCT.Overloading} * m.flags # {} THEN
  856. PCM.SymWNum(r, SFsysflag); PCM.SymWNum(r, SYSTEM.VAL(LONGINT, m.flags * {PCT.Overloading}))
  857. END;
  858. p1 := NIL; p2 := NIL; t1 := NIL;
  859. c := m.scope.firstValue; first := TRUE;
  860. WHILE c # NIL DO
  861. IF ~newsym THEN CompareSymbol(c, extend, new) ELSIF c.vis # PCT.Internal THEN FPrintObj(c, M) END;
  862. IF c.vis # PCT.Internal THEN
  863. IF first THEN PCM.SymWNum(r, SFconst); first := FALSE END;
  864. OutObj(c); OutConst(c.const)
  865. END;
  866. c := c.nextVal
  867. END;
  868. v := m.scope.firstVar; first := TRUE;
  869. WHILE v # NIL DO
  870. IF ~newsym THEN CompareSymbol(v, extend, new) ELSIF v.vis # PCT.Internal THEN FPrintObj(v, M) END;
  871. IF v.vis # PCT.Internal THEN
  872. IF first THEN PCM.SymWNum(r, SFvar); first := FALSE END;
  873. OutObj(v)
  874. END;
  875. v := v.nextVar
  876. END;
  877. (* ug: hidden variables are not written to the symbol file, scope.firstHiddenVar is not traversed. *)
  878. p := m.scope.firstProc; first := TRUE;
  879. WHILE p # NIL DO
  880. IF ~newsym THEN CompareSymbol(p, extend, new) ELSIF p.vis # PCT.Internal THEN FPrintObj(p, M) END;
  881. IF (p.vis # PCT.Internal) THEN
  882. IF ~(PCT.Inline IN p.flags) & ~(PCT.Operator IN p.flags) THEN
  883. IF first THEN PCM.SymWNum(r, SFxproc); first := FALSE END;
  884. IF PCT.RealtimeProc IN p.flags THEN PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.RealtimeProc) END; (* ug *)
  885. OutStruct(p.type); StringPool.GetString(p.name, str); PCM.SymWString(r, str); OutParList(p.scope.firstPar)
  886. ELSE
  887. p.dlink := p1; p1 := p
  888. END
  889. END;
  890. p := p.nextProc
  891. END;
  892. (*
  893. IF p1 # NIL THEN
  894. PCM.SymWNum(r, SFcproc);
  895. REPEAT
  896. OutStruct(p1.type); StringPool.GetString(p1.name, str); PCM.SymWString(r, str);
  897. scope := p1(PCT.Proc).scope; OutParList(scope.firstPar); OutInline(scope.code);
  898. p1 := p1.dlink
  899. UNTIL p1 = NIL
  900. END;
  901. *)
  902. first := TRUE;
  903. IF p1 # NIL THEN
  904. REPEAT
  905. pTmp := p1.dlink;
  906. IF (PCT.Operator IN p1.flags) THEN
  907. IF first THEN PCM.SymWNum(r, SFoperator); first := FALSE END;
  908. OutStruct(p1.type); StringPool.GetString(p1.name, str); PCM.SymWString(r, str);
  909. scope := p1(PCT.Proc).scope; OutParList(scope.firstPar);
  910. IF PCT.Inline IN p1.flags THEN PCM.SymWNum(r, InlineMarker); OutInline(scope.code) END;
  911. ELSE
  912. p1.dlink := p2; p2 := p1;
  913. END;
  914. p1 := pTmp;
  915. UNTIL p1 = NIL;
  916. END;
  917. IF p2 # NIL THEN
  918. PCM.SymWNum(r, SFcproc);
  919. REPEAT
  920. IF PCT.RealtimeProc IN p2.flags THEN PCM.SymWNum(r, SFobjflag); PCM.SymWNum(r, PCM.RealtimeProc) END; (* ug *)
  921. OutStruct(p2.type); StringPool.GetString(p2.name, str); PCM.SymWString(r, str);
  922. scope := p2(PCT.Proc).scope; OutParList(scope.firstPar); OutInline(scope.code);
  923. p2 := p2.dlink;
  924. UNTIL p2 = NIL;
  925. END;
  926. t := m.scope.firstType; first := TRUE;
  927. WHILE t # NIL DO
  928. IF ~newsym THEN CompareSymbol(t, extend, new) ELSIF t.vis # PCT.Internal THEN FPrintObj(t, M) END;
  929. IF t.vis # PCT.Internal THEN
  930. IF t # t.type.owner THEN (*alias*)
  931. IF first THEN PCM.SymWNum(r, SFalias); first := FALSE END;
  932. OutObj(t)
  933. ELSE
  934. t.dlink := t1; t1 := t
  935. END
  936. END;
  937. t := t.nextType
  938. END;
  939. first := TRUE;
  940. WHILE t1 # NIL DO
  941. IF (t1.type.sym=NIL) OR (t1.type.sym(Struct).tag=UndefTag) THEN (*not exported yet*)
  942. IF first THEN PCM.SymWNum(r, SFtyp); first := FALSE END;
  943. OutStruct(t1.type)
  944. END;
  945. t1 := t1.dlink
  946. END;
  947. (* write names of directly imported modules to symbol file *)
  948. IF m.directImps # NIL THEN
  949. FOR i := 0 TO LEN(m.directImps^) - 1 DO
  950. IF m.directImps[i] # NIL THEN
  951. AddImport(impList, m.directImps[i].name);
  952. END;
  953. END;
  954. END;
  955. (* add import list *)
  956. IF impList # NIL THEN
  957. i := 0;
  958. WHILE (i < LEN(impList^)-1) & (impList[i] # -1) DO
  959. StringPool.GetString(impList[i], str);
  960. PCM.SymWMod(r, str);
  961. INC(i);
  962. END
  963. END;
  964. IF Trace THEN PCM.LogWLn; PCM.LogWStr("OM.OutModule/end") END;
  965. PCM.SymWNum(r, SFend);
  966. END OutModule;
  967. BEGIN
  968. ASSERT(M#NIL);
  969. COPY("", msg);
  970. IF PCM.error THEN RETURN END;
  971. StringPool.GetString(M.name, name);
  972. newsym := FALSE;
  973. changed := FALSE;
  974. oldM := NIL;
  975. IF ~skipImport THEN
  976. Import(M, oldM, M.name); (* import self, to check for changes *)
  977. END;
  978. IF oldM # NIL THEN
  979. changed := M.sym(Module).changed
  980. ELSE
  981. IF M.sym = NIL THEN NEW(MAttr); M.sym := MAttr; MAttr := NIL END;
  982. newsym := TRUE
  983. END;
  984. (*export*)
  985. ASSERT(M.flags - ImportedModuleFlag = {}); (*export overrides only if allowed*)
  986. OutModule(M);
  987. IF PCM.error THEN RETURN END;
  988. PCM.CloseSym(r); (*commit file*)
  989. IF changed OR extended THEN
  990. IF changed THEN
  991. IF newsym OR new THEN COPY(" new symbol file", msg) ELSE PCM.Error(155, PCM.InvalidPosition, "") END
  992. ELSIF extended THEN
  993. IF extend OR new THEN COPY(" extended symbol file", msg) ELSE PCM.Error(155, PCM.InvalidPosition, "") END
  994. END
  995. END
  996. END Export;
  997. (* ========== Symbol File Loader ============== *)
  998. (** Double structure size, copy elements into new structure *)
  999. PROCEDURE ExtendStructArray*(VAR a: StructArray);
  1000. VAR b: StructArray; i: LONGINT;
  1001. BEGIN
  1002. IF a=NIL THEN NEW(a, 16)
  1003. ELSE
  1004. NEW(b, 2*LEN(a));
  1005. FOR i := 0 TO LEN(a)-1 DO b[i] := a[i] END;
  1006. a := b
  1007. END
  1008. END ExtendStructArray;
  1009. PROCEDURE AddImport(VAR list: ImportList; idx: StringPool.Index);
  1010. VAR
  1011. i: LONGINT;
  1012. newList: ImportList;
  1013. BEGIN
  1014. IF list = NIL THEN
  1015. NEW(list, 16);
  1016. FOR i := 0 TO LEN(list^)-1 DO
  1017. list[i] := -1;
  1018. END;
  1019. END;
  1020. i := 0;
  1021. WHILE (i < LEN(list^)) & (list[i] # -1) & (list[i] # idx) DO INC(i) END;
  1022. IF i >= LEN(list^) THEN
  1023. (* double list and append module index *)
  1024. NEW(newList, 2*LEN(list^));
  1025. FOR i := 0 TO LEN(list^)-1 DO newList[i] := list[i]; END;
  1026. FOR i := LEN(list^) TO LEN(newList^)-1 DO newList[i] := -1 END;
  1027. newList[LEN(list^)] := idx;
  1028. list := newList;
  1029. ELSIF list[i] = -1 THEN
  1030. (* append module index to list *)
  1031. list[i] := idx;
  1032. ELSE
  1033. (* do nothing, module already in list *)
  1034. END;
  1035. END AddImport;
  1036. (* ReadString - Read a 0X compressed string *)
  1037. PROCEDURE ReadString(VAR R: PCM.SymReader; VAR string: ARRAY OF CHAR);
  1038. VAR i: INTEGER; ch: CHAR;
  1039. BEGIN i := 0;
  1040. LOOP R.Char(ch);
  1041. IF ch = 0X THEN string[i] := 0X; RETURN
  1042. ELSIF ch < 7FX THEN string[i]:=ch; INC(i)
  1043. ELSIF ch > 7FX THEN string[i] := CHR(ORD(ch)-80H); string[i+1] := 0X; RETURN
  1044. ELSE (* ch = 7FX *) EXIT END
  1045. END;
  1046. LOOP R.Char(ch);
  1047. IF ch = 0X THEN string[i]:=0X; RETURN
  1048. ELSE string[i]:=ch; INC(i) END
  1049. END;
  1050. END ReadString;
  1051. PROCEDURE ReadStringNoZeroCompress(VAR R: PCM.SymReader; VAR string: ARRAY OF CHAR);
  1052. VAR i: INTEGER; ch: CHAR;
  1053. BEGIN
  1054. i := 0;
  1055. REPEAT
  1056. R.Char(ch);
  1057. string[i] := ch; INC(i);
  1058. UNTIL ch = 0X;
  1059. END ReadStringNoZeroCompress;
  1060. PROCEDURE ReadStrIndex(VAR r: PCM.SymReader; readString: ReadStringProc; VAR s: PCS.Name);
  1061. VAR name: ARRAY 256 OF CHAR;
  1062. BEGIN
  1063. (* ReadString(r, name); *)
  1064. readString(r, name);
  1065. IF name = "" THEN
  1066. s := empty
  1067. ELSE
  1068. StringPool.GetIndex(name, s)
  1069. END
  1070. END ReadStrIndex;
  1071. PROCEDURE ImportComplete(m: PCT.Module);
  1072. VAR attr: Module; i: LONGINT;
  1073. PROCEDURE RecordComplete(r: PCT.Record);
  1074. BEGIN
  1075. IF r.brec # NIL THEN RecordComplete(r.brec) END;
  1076. PCT.ChangeState(r.scope, PCT.complete, -1)
  1077. END RecordComplete;
  1078. BEGIN
  1079. PCT.ChangeState(m.scope, PCT.complete, -1);
  1080. attr := m.sym(Module);
  1081. FOR i := 0 TO attr.nofstr-1 DO
  1082. IF attr.struct[i] IS PCT.Record THEN
  1083. RecordComplete(attr.struct[i](PCT.Record))
  1084. END
  1085. END
  1086. END ImportComplete;
  1087. (** Import - Symbol Table Loader Plugin *)
  1088. PROCEDURE Import*(self: PCT.Module; VAR M: PCT.Module; modname: StringPool.Index);
  1089. VAR
  1090. res: WORD; tag, i: LONGINT; name: PCS.Name; str: PCT.Struct; vis: SET; R: PCM.SymReader;
  1091. proc: PCT.Proc;
  1092. scope: PCT.ModScope;
  1093. pscope: PCT.ProcScope;
  1094. selfimport, zeroCompress: BOOLEAN;
  1095. ver: CHAR;
  1096. MAttr: Module;
  1097. flag, flags: SET;
  1098. type: PCT.Type;
  1099. string: ARRAY 256 OF CHAR;
  1100. readString: ReadStringProc;
  1101. importError: BOOLEAN;
  1102. PROCEDURE Assert(cond: BOOLEAN);
  1103. BEGIN
  1104. IF ~cond THEN importError := TRUE END;
  1105. END Assert;
  1106. PROCEDURE EqualNames(s1, s2: PCT.Struct): BOOLEAN;
  1107. VAR res: BOOLEAN;
  1108. BEGIN
  1109. ASSERT(s1 # NIL); ASSERT(s2 # NIL);
  1110. IF (s1 IS PCT.Array) & (s2 IS PCT.Array) THEN
  1111. res := EqualNames(s1(PCT.Array).base, s2(PCT.Array).base);
  1112. (** fof >> *)
  1113. ELSIF (s1 IS PCT.EnhArray) & (s2 IS PCT.EnhArray) THEN (*fof*)
  1114. res := EqualNames( s1( PCT.EnhArray ).base, s2( PCT.EnhArray ).base );
  1115. ELSIF (s1 IS PCT.Tensor) & (s2 IS PCT.Tensor) THEN (*fof*)
  1116. res := EqualNames( s1( PCT.Tensor ).base, s2( PCT.Tensor ).base );
  1117. (** << fof *)
  1118. ELSIF ~(s1 IS PCT.Array) & ~(s2 IS PCT.Array) & ~(s1 IS PCT.EnhArray) & ~(s2 IS PCT.EnhArray) &~(s1 IS PCT.Tensor) & ~(s2 IS PCT.Tensor) (* fof*) THEN
  1119. IF (s1.owner # NIL) & (s2.owner # NIL) THEN
  1120. res := (s1.owner.name = s2.owner.name);
  1121. ELSE
  1122. res := FALSE;
  1123. END;
  1124. ELSE
  1125. res := FALSE;
  1126. END;
  1127. RETURN res;
  1128. END EqualNames;
  1129. PROCEDURE Insert(scope: PCT.Scope; obj: PCT.Symbol);
  1130. VAR old: PCT.Symbol; OAttr: Symbol;
  1131. p: PCT.Symbol;
  1132. paramProc, paramObj: PCT.Parameter;
  1133. j: LONGINT;
  1134. BEGIN
  1135. ASSERT(selfimport);
  1136. old:=PCT.Find(scope, scope, obj.name, PCT.procdeclared, FALSE);
  1137. (*
  1138. not the correct operator is found: type name is used to search, but not name of module,
  1139. where type is definded (not in symbol file)
  1140. changes in operator signatures are not recognized, only adding and removing of operators
  1141. *)
  1142. IF (old # NIL) & (PCT.Operator IN obj.flags) THEN
  1143. p := old;
  1144. old := NIL;
  1145. WHILE (p # NIL) & (p.name = obj.name) DO
  1146. paramProc := p(PCT.Proc).scope.firstPar;
  1147. paramObj := obj(PCT.Proc).scope.firstPar;
  1148. (* check for equal parameters (only the type names are compared!) *)
  1149. j := 0;
  1150. WHILE (j < p(PCT.Proc).scope.parCount) &
  1151. (p(PCT.Proc).scope.parCount = obj(PCT.Proc).scope.parCount) &
  1152. (p(PCT.Proc).vis = obj(PCT.Proc).vis) &
  1153. (paramProc.ref = paramObj.ref) & EqualNames(paramProc.type, paramObj.type) DO
  1154. paramProc := paramProc.nextPar;
  1155. paramObj := paramObj.nextPar;
  1156. INC(j)
  1157. END;
  1158. IF (j = p(PCT.Proc).scope.parCount) & (p(PCT.Proc).sym = NIL) THEN
  1159. old := p;
  1160. p := NIL
  1161. ELSE
  1162. p := p.sorted
  1163. END
  1164. END
  1165. END;
  1166. IF old=NIL THEN
  1167. PCM.ErrorN(401, PCM.InvalidPosition, obj.name); MAttr.changed:=TRUE
  1168. ELSIF old.vis#obj.vis THEN
  1169. PCM.ErrorN(401, PCM.InvalidPosition, obj.name); MAttr.changed:=TRUE
  1170. ELSE
  1171. ASSERT(old.sym=NIL);
  1172. NEW(OAttr); old.sym:=OAttr; OAttr.sibling:=obj
  1173. END
  1174. END Insert;
  1175. PROCEDURE GetImports;
  1176. VAR name: StringPool.Index; M: PCT.Module;
  1177. BEGIN
  1178. ReadStrIndex(R, readString, name);
  1179. WHILE name # empty DO
  1180. IF (MAttr.import = NIL) OR (MAttr.nofimp = LEN(MAttr.import)) THEN PCT.ExtendModArray(MAttr.import) END;
  1181. PCT.Import(self, M, name);
  1182. IF M = NIL THEN
  1183. PCM.ErrorN(0, 0, name)
  1184. ELSE
  1185. MAttr.import[MAttr.nofimp]:=M;
  1186. IF M.scope.state = 0 THEN (*fresh import*)
  1187. ImportComplete(M)
  1188. END;
  1189. INC(MAttr.nofimp); ReadStrIndex(R, readString, name)
  1190. END
  1191. END
  1192. END GetImports;
  1193. PROCEDURE InConst(): PCT.Const;
  1194. VAR i: LONGINT; r: REAL; lr: LONGREAL; str: PCS.String; set: SET; c: PCT.Const;
  1195. BEGIN
  1196. CASE tag OF
  1197. | SFtypBool: R.RawNum(i);
  1198. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / Bool / "); PCM.LogWNum(i) END;
  1199. IF i = 0 THEN c := PCT.False ELSE c := PCT.True END
  1200. | SFtypChar8: R.RawNum(i);
  1201. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / Char / "); PCM.LogWNum(i) END;
  1202. c := PCT.NewIntConst(i, PCT.Char8)
  1203. | SFtypInt8: R.RawNum(i);
  1204. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / SInt / "); PCM.LogWNum(i) END;
  1205. c := PCT.NewIntConst(i, PCT.Int8)
  1206. | SFtypInt16: R.RawNum(i);
  1207. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / Int / "); PCM.LogWNum(i) END;
  1208. c := PCT.NewIntConst(i, PCT.Int16)
  1209. | SFtypInt32: R.RawNum(i);
  1210. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / LInt / "); PCM.LogWNum(i) END;
  1211. c := PCT.NewIntConst(i, PCT.Int32)
  1212. | SFtypInt64: R.RawLReal(lr);
  1213. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / HInt / ") END;
  1214. c := PCT.NewInt64Const(SYSTEM.VAL(HUGEINT, lr))
  1215. | SFtypSet: R.RawNum(SYSTEM.VAL(LONGINT, set));
  1216. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / Set / "); PCM.LogWHex(SYSTEM.VAL(LONGINT, set)) END;
  1217. c := PCT.NewSetConst(set)
  1218. | SFtypFloat32: R.RawReal(r);
  1219. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / Real / ") END;
  1220. RETURN PCT.NewFloatConst(r, PCT.Float32)
  1221. | SFtypFloat64: R.RawLReal(lr);
  1222. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / LongReal / ") END;
  1223. c := PCT.NewFloatConst(lr, PCT.Float64)
  1224. | SFtypString: readString(R, str);
  1225. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("InConst / String / "); PCM.LogWStr(str) END;
  1226. c := PCT.NewStringConst(str)
  1227. | SFtypNilTyp:
  1228. END;
  1229. RETURN c
  1230. END InConst;
  1231. PROCEDURE InParList(upper: PCT.Scope): PCT.ProcScope;
  1232. VAR s: PCT.ProcScope; svar, var: BOOLEAN; name: PCS.Name; styp, str: PCT.Struct; f: LONGINT; flags: SET; (* ejz *)
  1233. BEGIN
  1234. styp := NIL;
  1235. NEW(s); PCT.InitScope(s, upper, {}, TRUE); PCT.SetOwner(s);
  1236. R.RawNum(tag);
  1237. WHILE tag#SFend DO
  1238. flags := {}; (* ejz *)
  1239. IF tag = SFobjflag THEN
  1240. R.RawNum(f); R.RawNum(tag);
  1241. IF f = PCM.CParam THEN (* fof for Linux *)
  1242. INCL(flags, PCT.CParam)
  1243. ELSIF f = PCM.WinAPIParam THEN
  1244. INCL(flags,PCT.WinAPIParam)
  1245. ELSE HALT(100)
  1246. END;
  1247. END;
  1248. IF tag=SFvar THEN
  1249. var:=TRUE; R.RawNum(tag);
  1250. ELSE var:=FALSE
  1251. END;
  1252. (** fof >> *)
  1253. IF tag = SFreadonly THEN (* var const *)
  1254. INCL(flags,PCM.ReadOnly); R.RawNum(tag);
  1255. END;
  1256. (** << fof *)
  1257. InStruct(str); ReadStrIndex(R, readString, name);
  1258. IF (name = PCT.SelfName) OR (name = altSelf) THEN (*move SELF to the end of the list / method only*)
  1259. styp := str; svar := var
  1260. ELSE
  1261. s.CreatePar(PCT.Public, var, name, flags, str, 0 (* fof *), res); (* ASSERT(res = PCT.Ok) *) (* ejz *)
  1262. Assert(res = PCT.Ok);
  1263. END;
  1264. R.RawNum(tag)
  1265. END;
  1266. IF styp # NIL THEN
  1267. s.CreatePar(PCT.Public, svar, PCT.SelfName, {}, styp, 0 (* fof *), res); (* ASSERT(res = PCT.Ok) *)
  1268. Assert(res = PCT.Ok);
  1269. END;
  1270. RETURN s
  1271. END InParList;
  1272. PROCEDURE InRecord(rec: PCT.Record; btyp: PCT.Struct; intf: PCT.Interfaces);
  1273. VAR mode, vis: SET; typ: PCT.Struct; name: PCS.Name;
  1274. mscope: PCT.ProcScope; s: PCT.RecScope; flags: SET; ch: CHAR;
  1275. BEGIN
  1276. NEW(s);
  1277. PCT.SetOwner(s);
  1278. PCT.InitScope(s, scope, {}, TRUE);
  1279. R.RawNum(SYSTEM.VAL(LONGINT, mode));
  1280. PCT.InitRecord(rec, btyp, intf, s, PCT.interface IN mode, TRUE, TRUE, res); (* ASSERT(res = PCT.Ok); *)
  1281. Assert(res = PCT.Ok);
  1282. rec.mode := mode;
  1283. R.Char(ch); rec.prio := ORD(ch);
  1284. IF TraceImport THEN
  1285. PCM.LogWLn; PCM.LogWStr("Rec / Mode / "); PCM.LogWHex(SYSTEM.VAL(LONGINT, rec.mode));
  1286. PCM.LogWLn; PCM.LogWStr("Rec / Prio / "); PCM.LogWNum(rec.prio)
  1287. END;
  1288. R.RawNum(tag);
  1289. WHILE (tag < SFtproc) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO (*read fields*)
  1290. InObj(name, vis, flags, typ);
  1291. IF name = empty THEN vis := PCT.Internal; name := PCT.Anonymous END;
  1292. s.CreateVar(name, vis, flags, typ, 0, (* fof *)NIL, res);
  1293. (* ASSERT(res = PCT.Ok); *)
  1294. Assert(res = PCT.Ok);
  1295. R.RawNum(tag);
  1296. END;
  1297. IF tag=SFtproc THEN
  1298. R.RawNum(tag);
  1299. WHILE tag#SFend DO
  1300. InObj(name, vis, flags, typ);
  1301. IF name = empty THEN vis := PCT.Internal; ReadStrIndex(R, readString, name) END;
  1302. mscope := InParList(s);
  1303. s.CreateProc(name, vis, flags, mscope, typ, 0, (* fof *) res); (* ASSERT(res = PCT.Ok); *)
  1304. Assert(res = PCT.Ok);
  1305. (* This identifies a inlined Indexer *)
  1306. R.RawNum(tag);
  1307. IF tag = InlineMarker THEN
  1308. INCL(flag, PCT.Inline);
  1309. INCL(flag, PCT.Indexer);
  1310. INCL(flag, PCT.Operator);
  1311. mscope.code := InCProc();
  1312. R.RawNum(tag)
  1313. END;
  1314. PCT.ChangeState(mscope, PCT.structdeclared, PCM.InvalidPosition);
  1315. END
  1316. END;
  1317. IF ~selfimport THEN PCT.AddRecord(M.scope, rec) END;
  1318. END InRecord;
  1319. PROCEDURE InStruct(VAR typ: PCT.Struct);
  1320. VAR i, len, strref, typtag, typadr: LONGINT; vis: SET; name: PCS.Name; btyp: PCT.Struct;
  1321. arr: PCT.Array; type: PCT.Type; mod: PCT.Module; typname: PCS.Name; proc: PCT.Delegate; r, rec: PCT.Record;
  1322. ptr: PCT.Pointer;
  1323. modAttr: Module; tAttr: Struct;
  1324. sysflag: LONGINT; sf: SET;
  1325. intf: ARRAY 32 OF PCT.Interface; c: CHAR;
  1326. earr: PCT.EnhArray; tensor: PCT.Tensor; readonly: LONGINT; (*fof*)
  1327. flags: LONGINT;
  1328. (*!!! when loading the user structures, no fix is used, but dummy elements !!!*)
  1329. BEGIN
  1330. IF tag <= 0 THEN (*oldstruct*)
  1331. ASSERT(MAttr.struct[-tag]#NIL);
  1332. (*IF MAttr.struct[-tag] = NIL THEN PCDebug.ToDo(PCM.NotImplemented); RETURN unknownType END;*)
  1333. typ := MAttr.struct[-tag];
  1334. IF TraceImport THEN
  1335. PCM.LogWLn; PCM.LogWStr("InStruct / OldStr "); PCM.LogWNum(-tag)
  1336. END
  1337. ELSIF tag <= SFlastStruct THEN (*BasicStructure*) typ := predefStruct[tag]
  1338. ;IF TraceImport THEN
  1339. PCM.LogWLn; PCM.LogWStr("InStruct / Basic ");
  1340. IF typ.owner # NIL THEN PCM.LogWStr0(typ.owner.name) ELSE PCM.LogWNum(tag) END
  1341. END
  1342. ELSIF tag <= SFmodOther THEN (*modno ( structname | 0X oldimpstruct)*)
  1343. IF tag = SFmodOther THEN R.RawNum(tag) ELSE tag := tag-SFmod1 END; (*tag = [0 .. +oo[ *)
  1344. mod := MAttr.import[tag]; ReadStrIndex(R, readString, typname);
  1345. modAttr := mod.sym(Module);
  1346. IF typname # empty THEN (*first import of struct*)
  1347. i := 0;
  1348. WHILE (i<modAttr.nofstr) & ((modAttr.struct[i].owner=NIL) OR (modAttr.struct[i].owner.name # typname)) DO INC(i) END;
  1349. IF i<modAttr.nofstr THEN typ := modAttr.struct[i] ELSE typ := PCT.UndefType END;
  1350. IF (modAttr.reimp = NIL) OR (modAttr.nofreimp = LEN(modAttr.reimp)) THEN ExtendStructArray(modAttr.reimp) END;
  1351. modAttr.reimp[modAttr.nofreimp] := typ; INC(modAttr.nofreimp);
  1352. IF TraceImport THEN
  1353. PCM.LogWLn; PCM.LogWStr("InStruct / Imported "); PCM.LogWStr0(mod.name);
  1354. PCM.LogWStr("."); PCM.LogWStr0(typname);
  1355. END
  1356. ELSE
  1357. R.RawNum(typadr); typ := modAttr.reimp[typadr];
  1358. IF TraceImport THEN
  1359. PCM.LogWLn; PCM.LogWStr("InStruct / Re-Imported "); PCM.LogWStr0(mod.name);
  1360. PCM.LogWStr("."); PCM.LogWStr0(typ.owner.name);
  1361. END
  1362. END
  1363. ELSE (*UserStructure*)
  1364. strref := MAttr.nofstr; INC(MAttr.nofstr);
  1365. IF MAttr.nofstr >= LEN(MAttr.struct) THEN ExtendStructArray(MAttr.struct) END;
  1366. vis := PCT.Public; sysflag := 0;
  1367. IF tag = SFinvisible THEN vis := PCT.Internal; R.RawNum(tag) END;
  1368. IF tag = SFsysflag THEN R.RawNum(sysflag); R.RawNum(tag) END;
  1369. typtag := tag; R.RawNum(tag);
  1370. (*first create the structure, to be used in recursive structs*)
  1371. CASE typtag OF
  1372. | SFtypOpenArr, SFtypArray:
  1373. NEW(arr); typ := arr
  1374. (** fof >> *)
  1375. | SFtypOpenEnhArr, SFtypStaticEnhArray:
  1376. NEW( earr ); typ := earr
  1377. | SFtypTensor:
  1378. NEW(tensor); typ := tensor;
  1379. (** << fof *)
  1380. | SFtypPointer:
  1381. NEW(ptr); typ := ptr
  1382. | SFtypRecord:
  1383. NEW(rec); typ := rec;
  1384. IF (strref > 0) & (MAttr.struct[strref-1] IS PCT.Pointer) THEN
  1385. ptr := MAttr.struct[strref-1](PCT.Pointer);
  1386. IF ptr.base = NIL THEN
  1387. INC(NpatchPointer0);
  1388. PCT.InitPointer(ptr, rec, res); (* ASSERT(res = PCT.Ok) *)
  1389. Assert(res = PCT.Ok);
  1390. END;
  1391. END;
  1392. | SFtypProcTyp:
  1393. NEW(proc); typ := proc
  1394. END;
  1395. (* ASSERT((sysflag = 0) OR (sysflag = SFdelegate)); *)
  1396. MAttr.struct[strref] := typ;
  1397. NEW(tAttr, M); typ.sym:=tAttr; tAttr.strref := strref;
  1398. (*
  1399. IF ~selfimport THEN tAttr.mod:=M END; (*only for imported structures: where from*)
  1400. *)
  1401. InStruct(btyp);
  1402. (* now load the struct, late fixes*)
  1403. CASE typtag OF
  1404. | SFtypOpenArr:
  1405. PCT.InitOpenArray(arr, btyp, res); (* ASSERT(res = PCT.Ok); *)
  1406. Assert(res = PCT.Ok);
  1407. ReadStrIndex(R, readString, name);
  1408. R.RawNum(flags); (* realtime flags , ignored in PACO *)
  1409. IF TraceImport THEN
  1410. PCM.LogWLn; PCM.LogWStr("InStruct / User / OpenArr ");
  1411. IF name # empty THEN PCM.LogWStr0(name) END
  1412. END
  1413. (** fof >> *)
  1414. | SFtypOpenEnhArr:
  1415. PCT.InitOpenEnhArray( earr, btyp, {PCT.open}, res ); (* ASSERT(res = PCT.Ok); *)
  1416. Assert( res = PCT.Ok );
  1417. ReadStrIndex( R, readString, name );
  1418. IF TraceImport THEN
  1419. PCM.LogWLn; PCM.LogWStr( "InStruct / User / OpenEnhArr " );
  1420. IF name # empty THEN PCM.LogWStr0( name ) END
  1421. END
  1422. | SFtypTensor:
  1423. PCT.InitTensor(tensor,btyp,res);
  1424. Assert( res = PCT.Ok );
  1425. ReadStrIndex( R, readString, name );
  1426. | SFtypStaticEnhArray: (*fof*)
  1427. ReadStrIndex( R, readString, name ); R.RawNum( len );
  1428. PCT.InitStaticEnhArray( earr, len, btyp, {PCT.static}, res ); (* ASSERT(res = PCT.Ok); *)
  1429. Assert( res = PCT.Ok );
  1430. IF TraceImport THEN
  1431. PCM.LogWLn; PCM.LogWStr( "InStruct / User / Array " ); PCM.LogWNum( len );
  1432. IF name # empty THEN PCM.LogWStr0( name ) END
  1433. END
  1434. (** << fof *)
  1435. | SFtypArray:
  1436. ReadStrIndex(R, readString, name);
  1437. R.RawNum(flags); (* realtime flags , ignored in PACO *)
  1438. R.RawNum(len);
  1439. PCT.InitStaticArray(arr, len, btyp, res); (* ASSERT(res = PCT.Ok); *)
  1440. Assert(res = PCT.Ok);
  1441. IF TraceImport THEN
  1442. PCM.LogWLn; PCM.LogWStr("InStruct / User / Array ");
  1443. PCM.LogWNum(len);
  1444. IF name # empty THEN PCM.LogWStr0(name) END
  1445. END
  1446. | SFtypPointer:
  1447. IF ptr.base # NIL THEN
  1448. ASSERT(ptr.base = btyp)
  1449. ELSE
  1450. PCT.InitPointer(ptr, btyp, res); (* ASSERT(res = PCT.Ok) *)
  1451. Assert(res = PCT.Ok);
  1452. END;
  1453. ReadStrIndex(R, readString, name);
  1454. R.RawNum(flags); (* realtime flags , ignored in PACO *)
  1455. IF TraceImport THEN
  1456. PCM.LogWLn; PCM.LogWStr("InStruct / User / Pointer ");
  1457. IF name # empty THEN PCM.LogWStr0(name) END
  1458. END
  1459. | SFtypRecord:
  1460. LOOP
  1461. IF btyp IS PCT.Pointer THEN
  1462. WITH btyp: PCT.Pointer DO
  1463. r := btyp.baseR;
  1464. IF PCT.interface IN r.mode THEN
  1465. INC(Ninterfaces);
  1466. intf[i] := btyp; INC(i)
  1467. ELSE
  1468. EXIT
  1469. END
  1470. END
  1471. ELSE
  1472. EXIT
  1473. END;
  1474. R.RawNum(tag);
  1475. InStruct(btyp)
  1476. END;
  1477. ReadStrIndex(R, readString, name);
  1478. R.RawNum(flags); (* realtime flags , ignored in PACO *)
  1479. InRecord(rec, btyp, intf);
  1480. IF TraceImport THEN
  1481. PCM.LogWLn; PCM.LogWStr("InStruct / User / Record ");
  1482. IF name # empty THEN PCM.LogWStr0(name) END
  1483. END
  1484. | SFtypProcTyp:
  1485. ReadStrIndex(R, readString, name);
  1486. R.RawNum(SYSTEM.VAL(LONGINT, sf));
  1487. IF sysflag # SFdelegate THEN INCL (sf, PCT.StaticMethodsOnly) END;
  1488. PCT.InitDelegate(proc, btyp, InParList(scope), sf, res); (* ASSERT(res = PCT.Ok); *)
  1489. Assert(res = PCT.Ok);
  1490. PCT.ChangeState(proc.scope, PCT.structdeclared, -1);
  1491. IF TraceImport THEN
  1492. PCM.LogWLn; PCM.LogWStr("InStruct / User / Proc ");
  1493. IF name # empty THEN PCM.LogWStr0(name) END
  1494. END
  1495. END;
  1496. IF name # empty THEN
  1497. IF ~selfimport THEN
  1498. scope.CreateType(name, vis, typ, 0(*fof*), res); (* ASSERT(res = PCT.Ok) *)
  1499. Assert(res = PCT.Ok);
  1500. ELSE
  1501. NEW(type); PCT.InitType(type, name, vis, typ); Insert(scope, type)
  1502. END
  1503. END
  1504. END
  1505. END InStruct;
  1506. PROCEDURE InCProc(): PCLIR.AsmInline;
  1507. VAR inline: PCLIR.AsmInline; p: PCLIR.AsmBlock; ch: CHAR; pos, len: LONGINT;
  1508. BEGIN
  1509. NEW(inline); R.Char(ch);
  1510. REPEAT
  1511. IF p = NIL THEN NEW(p); inline.code := p ELSE NEW(p.next); p := p.next END;
  1512. len := ORD(ch); p.len := len; pos := 0;
  1513. WHILE pos < len DO R.Char(p.code[pos]); INC(pos) END;
  1514. R.Char(ch)
  1515. UNTIL ch = 0X;
  1516. RETURN inline
  1517. END InCProc;
  1518. PROCEDURE InObj(VAR idx: PCS.Name; VAR vis: SET; VAR flag: SET; VAR typ: PCT.Struct);
  1519. VAR f: LONGINT; name: ARRAY 32 OF CHAR;
  1520. BEGIN
  1521. flag := {}; vis:=PCT.Public;
  1522. IF tag=SFobjflag THEN
  1523. R.RawNum(f); R.RawNum(tag);
  1524. IF f = PCM.Untraced THEN flag := {f}
  1525. ELSIF f = PCM.RealtimeProc THEN flag := {PCT.RealtimeProc} (* ug *)
  1526. ELSE PCM.LogWLn; PCM.LogWStr("PCOM.InObj: unknown objflag");
  1527. END
  1528. END;
  1529. IF tag=SFreadonly THEN R.RawNum(tag); vis := readonly END;
  1530. InStruct(typ); readString(R, name);
  1531. IF name = "" THEN
  1532. idx := empty
  1533. ELSIF name[0] = "&" THEN
  1534. flag := {PCT.Constructor};
  1535. i := 0; REPEAT name[i] := name[i+1]; INC(i) UNTIL name[i] = 0X;
  1536. StringPool.GetIndex(name, idx)
  1537. ELSE
  1538. StringPool.GetIndex(name, idx)
  1539. END;
  1540. IF TraceImport THEN
  1541. PCM.LogWLn; PCM.LogWStr("InObj: "); PCM.LogWStr(name)
  1542. END
  1543. END InObj;
  1544. BEGIN
  1545. IF Trace THEN PCM.LogWLn; PCM.LogWStr("OM.Import") END;
  1546. i := 0;
  1547. M:=NIL;
  1548. selfimport:=FALSE;
  1549. StringPool.GetString(modname, string);
  1550. IF ~PCM.OpenSymFile(string, R, ver, zeroCompress) THEN
  1551. RETURN
  1552. END;
  1553. IF zeroCompress THEN
  1554. readString := ReadString;
  1555. ELSE
  1556. readString := ReadStringNoZeroCompress;
  1557. END;
  1558. IF (self # NIL) & (self.sym = NIL) THEN (*first import, create symfile related structures*)
  1559. NEW(MAttr); self.sym:=MAttr;
  1560. END;
  1561. IF (self # NIL) & (self.name = modname) THEN
  1562. selfimport:=TRUE;
  1563. M := self;
  1564. MAttr:=M.sym(Module); MAttr.nofreimp:=0; scope:=M.scope;
  1565. ELSE
  1566. NEW(scope); PCT.SetOwner(scope);
  1567. M := PCT.NewModule(modname, TRUE, {}, scope);
  1568. NEW(MAttr); M.sym:=MAttr
  1569. END;
  1570. IF ~selfimport & (self # NIL) THEN self.AddImport(M) END;
  1571. IF (ver = PCM.FileVersion) OR (ver=PCM.FileVersionOC) THEN
  1572. R.RawSet(flags);
  1573. ELSE
  1574. PCM.Error(151, PCM.InvalidPosition, ""); M := NIL; RETURN
  1575. END;
  1576. GetImports;
  1577. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("Import "); PCM.LogWStr(string) END;
  1578. FOR i := 0 TO MAttr.nofimp-1 DO
  1579. ASSERT(MAttr.import # NIL, 500);
  1580. ASSERT(MAttr.import[i] # NIL, 501);
  1581. ASSERT(MAttr.import[i].sym # NIL, 502);
  1582. MAttr.import[i].sym(Module).nofreimp := 0
  1583. END; (*reset reimports*)
  1584. R.RawNum(tag);
  1585. flag := {};
  1586. IF tag = SFsysflag THEN
  1587. R.RawNum(SYSTEM.VAL(LONGINT, flag)); R.RawNum(tag);
  1588. END;
  1589. IF ~selfimport THEN PCT.InitScope(scope, NIL, flag, TRUE) END;
  1590. IF tag=SFconst THEN R.RawNum(tag);
  1591. WHILE (tag < SFvar) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1592. InObj(name, vis, flag, str);
  1593. IF ~selfimport THEN
  1594. scope.CreateValue(name, vis, InConst(), 0, (* fof *) res);
  1595. Assert(res = PCT.Ok);
  1596. (* ASSERT(res = PCT.Ok) *)
  1597. ELSE
  1598. Insert(scope, PCT.NewValue(name, vis, InConst()))
  1599. END;
  1600. R.RawNum(tag)
  1601. END
  1602. END;
  1603. IF Trace THEN PCM.LogWLn; PCM.LogWStr("OM.Import var....") END;
  1604. IF tag=SFvar THEN R.RawNum(tag);
  1605. WHILE (tag < SFxproc) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1606. InObj(name, vis, flag, str);
  1607. IF ~selfimport THEN
  1608. scope.CreateVar(name, vis, flag, str, 0, (* fof *) NIL, res);
  1609. Assert(res = PCT.Ok);
  1610. (* ASSERT(res = PCT.Ok)) *)
  1611. ELSE
  1612. Insert(scope, PCT.NewGlobalVar(vis, name, flag, str, res));
  1613. Assert(res = PCT.Ok);
  1614. (* ASSERT(res = PCT.Ok) *)
  1615. END;
  1616. R.RawNum(tag)
  1617. END
  1618. END;
  1619. IF Trace THEN PCM.LogWLn; PCM.LogWStr("OM.Import xproc....") END;
  1620. IF tag=SFxproc THEN R.RawNum(tag);
  1621. WHILE (tag < (*SFcproc*) SFoperator) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1622. InObj(name, vis, flag, str); pscope := InParList(scope);
  1623. IF ~selfimport THEN
  1624. scope.CreateProc(name, vis, flag, pscope, str, 0, (* fof *) res);
  1625. Assert(res = PCT.Ok);
  1626. (* ASSERT(res = PCT.Ok) *)
  1627. ELSE
  1628. proc := PCT.NewProc(vis, name, flag, pscope, str, res);
  1629. Assert(res = PCT.Ok);
  1630. (* ASSERT(res = PCT.Ok); *)
  1631. Insert(scope, proc);
  1632. END;
  1633. PCT.ChangeState(pscope, PCT.structdeclared, -1); R.RawNum(tag)
  1634. END
  1635. END;
  1636. IF tag=SFoperator THEN R.RawNum(tag);
  1637. WHILE (tag < SFcproc) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1638. InObj(name, vis, flag, str); pscope := InParList(scope);
  1639. INCL(flag, PCT.Operator);
  1640. R.RawNum(tag);
  1641. IF tag = InlineMarker THEN
  1642. INCL(flag, PCT.Inline);
  1643. pscope.code := InCProc();
  1644. R.RawNum(tag);
  1645. END;
  1646. IF ~selfimport THEN
  1647. scope.CreateProc(name, vis, flag, pscope, str, 0, (* fof *)res);
  1648. Assert(res = PCT.Ok);
  1649. (* ASSERT(res = PCT.Ok); *)
  1650. ELSE
  1651. proc := PCT.NewProc(vis, name, flag, pscope, str, res);
  1652. Assert(res = PCT.Ok);
  1653. (* ASSERT(res = PCT.Ok); *)
  1654. Insert(scope, proc);
  1655. END;
  1656. PCT.ChangeState(pscope, PCT.structdeclared, -1);
  1657. (* R.RawNum(tag) *)
  1658. END
  1659. END;
  1660. IF tag = SFcproc THEN R.RawNum(tag);
  1661. WHILE (tag < SFalias) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1662. InObj(name, vis, flag, str); pscope := InParList(scope);
  1663. INCL(flag, PCT.Inline);
  1664. IF ~selfimport THEN
  1665. scope.CreateProc(name, vis, flag, pscope, str, 0, (* fof *) res);
  1666. Assert(res = PCT.Ok);
  1667. (* ASSERT(res = PCT.Ok) *)
  1668. ELSE
  1669. Insert(scope, PCT.NewProc(vis, name, flag, pscope, str, res));
  1670. Assert(res = PCT.Ok);
  1671. (* ASSERT(res = PCT.Ok) *)
  1672. END;
  1673. pscope.code := InCProc();
  1674. PCT.ChangeState(pscope, PCT.structdeclared, -1); R.RawNum(tag)
  1675. END
  1676. END;
  1677. IF tag=SFalias THEN R.RawNum(tag);
  1678. WHILE (tag < SFtyp) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO
  1679. InStruct(str); ReadStrIndex(R, readString, name);
  1680. IF ~selfimport THEN
  1681. scope.CreateType(name, PCT.Public, str, 0, (* fof *)res);
  1682. Assert(res = PCT.Ok);
  1683. (* ASSERT(res = PCT.Ok) *)
  1684. ELSE
  1685. NEW(type); PCT.InitType(type, name, PCT.Public, str); Insert(scope, type)
  1686. END;
  1687. R.RawNum(tag)
  1688. END
  1689. END;
  1690. IF tag=SFtyp THEN R.RawNum(tag);
  1691. WHILE (tag < SFend) OR ((SFtypOpenEnhArr <= tag) & (tag <= SFtypStaticEnhArray)) (* fof *) DO InStruct(str); R.RawNum(tag) END
  1692. END;
  1693. IF importError THEN
  1694. M := NIL
  1695. ELSE
  1696. ImportComplete(M)
  1697. END
  1698. END Import;
  1699. (* ========== Initialisation ============ *)
  1700. PROCEDURE Cleanup;
  1701. BEGIN PCT.RemoveImporter(Import)
  1702. END Cleanup;
  1703. PROCEDURE InitBasic(t: PCT.Struct; tag, fp: LONGINT);
  1704. VAR sAttr: Struct;
  1705. BEGIN
  1706. NEW(sAttr, NIL); sAttr.tag := tag; t.sym := sAttr; sAttr.fp:=fp; sAttr.pbfp := fp;
  1707. IF t.size # NIL THEN sAttr.pvfp := t.size(PCBT.Size).size ELSE sAttr.pvfp := tag END;
  1708. predefStruct[tag] := t;
  1709. END InitBasic;
  1710. PROCEDURE Init;
  1711. BEGIN
  1712. (*Built-In types*)
  1713. InitBasic(PCT.NoType, SFtypNoTyp, FPFnotyp); PCT.NoType.sym(Struct).pvfp := SFtypNoTyp;
  1714. InitBasic(PCT.Bool, SFtypBool, FPFbool);
  1715. InitBasic(PCT.Char8, SFtypChar8, FPFchar8);
  1716. InitBasic(PCT.Char16, SFtypChar16, FPFchar16typ);
  1717. InitBasic(PCT.Char32, SFtypChar32, FPFchar32typ);
  1718. InitBasic(PCT.Int8, SFtypInt8, FPFint8typ);
  1719. InitBasic(PCT.Int16, SFtypInt16, FPFint16typ);
  1720. InitBasic(PCT.Int32, SFtypInt32, FPFint32typ);
  1721. InitBasic(PCT.Int64, SFtypInt64, FPFint64typ);
  1722. InitBasic(PCT.Float32, SFtypFloat32, FPFfloat32typ);
  1723. InitBasic(PCT.Float64, SFtypFloat64, FPFfloat64typ);
  1724. InitBasic(PCT.Set, SFtypSet, FPFsettyp);
  1725. InitBasic(PCT.String, SFtypString, FPFstringtyp); PCT.String.sym(Struct).pvfp := SFtypString;
  1726. (*InitBasic(PCT.PtrTyp, 0);*)
  1727. (*not initialized: NilTyp, UndefTyp (have special pvfp)*)
  1728. (*Built-In types, system*)
  1729. InitBasic(PCT.Ptr, SFtypSptr, FPFpointer);
  1730. InitBasic(PCT.Byte, SFtypByte, FPFbyte);
  1731. FParray[PCT.open]:=FPFopenarr; FParray[PCT.static]:=FPFstaticarr;
  1732. PCT.AddImporter(Import);
  1733. END Init;
  1734. PROCEDURE CreateString(VAR idx: StringPool.Index; str: ARRAY OF CHAR); (*to insert string constants*)
  1735. BEGIN StringPool.GetIndex(str, idx)
  1736. END CreateString;
  1737. BEGIN
  1738. Modules.InstallTermHandler(Cleanup);
  1739. Init;
  1740. IF Trace THEN PCM.LogWLn; PCM.LogWStr("PCOM.Trace on") END;
  1741. IF TraceImport THEN PCM.LogWLn; PCM.LogWStr("PCOM.TraceImport on") END;
  1742. CreateString(altSelf, "@SELF")
  1743. END PCOM.
  1744. (*
  1745. 15.11.06 ug Procedure Export with additional parameter skipImport that suppresses the import of the old symbol file
  1746. 11.06.02 prk emit modified symbol file message to main log (not kernel log)
  1747. 22.02.02 prk unicode support
  1748. 08.02.02 prk use Aos instead of Oberon modules
  1749. 05.02.02 prk PCT.Find cleanup
  1750. 22.01.02 prk ToDo list moved to PCDebug
  1751. 18.01.02 prk AosFS used instead of Files
  1752. 22.11.01 prk improved flag handling
  1753. 19.11.01 prk definitions
  1754. 17.11.01 prk more flexible type handling of integer constants
  1755. 16.11.01 prk constant folding of reals done with maximal precision
  1756. 14.11.01 prk include sysflag in fingerprint
  1757. 29.08.01 prk PCT functions: return "res" instead of taking "pos"
  1758. 27.08.01 prk scope.unsorted list removed; use var, proc, const and type lists instead
  1759. 17.08.01 prk overloading
  1760. 09.08.01 prk Symbol Table Loader Plugin
  1761. 11.07.01 prk support for fields and methods with same name in scope
  1762. 06.07.01 prk mark object explicitly
  1763. 05.07.01 prk import interface redesigned
  1764. 04.07.01 prk scope flags added, remove imported
  1765. 02.07.01 prk access flags, new design
  1766. 27.06.01 prk StringPool cleaned up
  1767. 27.06.01 prk ProcScope.CreatePar added
  1768. 15.06.01 prk support for duplicate scope entries
  1769. 13.06.01 prk export of empty inlines fixed
  1770. 06.06.01 prk use string pool for object names
  1771. 08.05.01 prk PCT interface cleanup. Use InitX instead of New*, allows type extension
  1772. 26.04.01 prk separation of RECORD and OBJECT in the parser
  1773. 02.04.01 prk ExtendModArray, ExtendStructArray exported
  1774. 30.03.01 prk object file version changed to 01X
  1775. 25.03.01 prk limited HUGEINT implementation (as abstract type)
  1776. 22.02.01 prk self reference for methods: use pointer-based self if possible (i.e. if object is dynamic and method
  1777. definitions in super-class is not record-based).
  1778. *)