FoxGlobal.Mod 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693
  1. MODULE FoxGlobal; (** AUTHOR "fof & fn"; PURPOSE "Oberon Compiler Globally Defined Symbols"; *)
  2. (* (c) fof ETH Zürich, 2008 *)
  3. IMPORT
  4. SyntaxTree := FoxSyntaxTree, Basic := FoxBasic, Scanner := FoxScanner, Strings, Dates, D:= Debugging;
  5. CONST
  6. (* system flag names *)
  7. StringWinAPI* = "WINAPI";
  8. StringC* = "C";
  9. StringMovable*="MOVABLE";
  10. StringUntraced* = "UNTRACED";
  11. StringDelegate* = "DELEGATE";
  12. StringInterrupt*= "INTERRUPT";
  13. StringPcOffset* = "PCOFFSET";
  14. StringEntry* = "INITIAL";
  15. StringExit*= "FINAL";
  16. StringNoPAF*="NOPAF";
  17. StringFixed*="FIXED";
  18. StringFictive*="FICTIVE";
  19. StringAligned*="ALIGNED";
  20. StringAlignStack*="ALIGNSTACK";
  21. StringFinal*="FINAL";
  22. StringAbstract*="ABSTRACT";
  23. StringRegister*= "REGISTER";
  24. StringNoReturn*="NORETURN";
  25. StringUnsafe*="UNSAFE";
  26. StringPlain*="PLAIN";
  27. StringDisposable*="DISPOSABLE";
  28. StringUnchecked*="UNCHECKED";
  29. StringUncooperative*="UNCOOPERATIVE";
  30. (* block modifier flag names *)
  31. StringExclusive* = "EXCLUSIVE";
  32. StringActive* = "ACTIVE";
  33. StringPriority* = "PRIORITY";
  34. StringSafe* = "SAFE";
  35. StringRealtime* = "REALTIME";
  36. StringDynamic* = "DYNAMIC";
  37. StringInstructionWidth*="InstructionWidth";
  38. StringDataMemorySize*= "DataMemorySize";
  39. StringCodeMemorySize*= "CodeMemorySize";
  40. StringChannelWidth*= "ChannelWidth";
  41. StringChannelDepth*= "ChannelDepth";
  42. StringChannelModule*= "Channels";
  43. StringSystemModule* = "SYSTEM";
  44. StringsystemModule* = "system";
  45. StringBaseMem*= "BaseMem";
  46. StringBaseDiv*= "BaseDiv";
  47. StringVector*="Vector";
  48. StringFloatingPoint*="FloatingPoint";
  49. StringNoMul*="NoMul";
  50. StringNonBlockingIO*="HasNonBlockingIO";
  51. StringFrequencyDivider*="FrequencyDivider";
  52. StringEngine*="Engine";
  53. StringTRM*="TRM";
  54. StringTRMS*="TRMS";
  55. (* traps *)
  56. WithTrap* = 1;
  57. CaseTrap* = 2;
  58. ReturnTrap* = 3;
  59. TypeEqualTrap* = 5;
  60. TypeCheckTrap* = 6;
  61. IndexCheckTrap* = 7;
  62. AssertTrap* = 8;
  63. ArraySizeTrap* = 9;
  64. ArrayFormTrap*=10; (* fof: indicates that array cannot be (re-)allocated since shape, type or size does not match *)
  65. NoReturnTrap*=16;
  66. (** builtin procedures **)
  67. (* FoxProgTools.Enum -e -i
  68. (* global proper procedures *)
  69. Assert Copy Dec Excl Halt Inc Incl New Dispose GetProcedure Connect Delegate
  70. Read Write Reshape Wait
  71. (* global functions *)
  72. Abs Cap Chr Chr32 Entier EntierH Incr Len Long Max Min Odd Ord Ord32 Short Size
  73. Sum Dim Cas First Last Step Re Im Ash Lsh Rot
  74. (* system proper procedures *)
  75. systemGet systemPut systemMove systemNew systemRef
  76. systemTypeCode systemHalt
  77. systemPut8 systemPut16 systemPut32 systemPut64 systemTrace
  78. systemSetStackPointer systemSetFramePointer systemSetActivity
  79. (* system functions *)
  80. systemAdr systemSize systemBit systemGet64 systemGet32 systemGet16 systemGet8
  81. systemVal systemMsk
  82. systemGetStackPointer systemGetFramePointer systemGetActivity
  83. (* for active cells *)
  84. Send Receive
  85. (* for backend specific extensions *)
  86. systemSpecial
  87. (* compatibility with Oberon07 -- other mappings: LSL -> LSH, FLOOR -> Entier, Pack und Unpk currently unsupported *)
  88. Asr Ror Flt
  89. Conversion
  90. DotTimesPlus AtMulDec AtMulInc DecMul IncMul
  91. endFox
  92. ~
  93. *)
  94. (* global proper procedures *)
  95. Assert*= Scanner.EndOfText+1; Copy*= Assert+1; Dec*= Copy+1; Excl*= Dec+1; Halt*= Excl+1; Inc*= Halt+1; Incl*= Inc+1; New*= Incl+1; Dispose*= New+1; GetProcedure*= Dispose+1; Connect*= GetProcedure+1; Delegate*= Connect+1; Read*= Delegate+1; Write*= Read+1; Reshape*= Write+1; Wait*= Reshape+1;
  96. (* global functions *)
  97. Abs*= Wait+1; Cap*= Abs+1; Chr*= Cap+1; Chr32*= Chr+1; Entier*= Chr32+1; EntierH*= Entier+1; Incr*= EntierH+1; Len*= Incr+1; Long*= Len+1; Max*= Long+1; Min*= Max+1; Odd*= Min+1; Ord*= Odd+1; Ord32*= Ord+1; Short*= Ord32+1; Size*= Short+1; Sum*= Size+1; Dim*= Sum+1; Cas*= Dim+1; First*= Cas+1; Last*= First+1; Step*= Last+1; Re*= Step+1; Im*= Re+1; Ash*= Im+1; Lsh*= Ash+1; Rot*= Lsh+1;
  98. All* = Rot+1;
  99. (* system proper procedures *)
  100. systemGet*= All+1; systemPut*= systemGet+1; systemMove*= systemPut+1; systemNew*= systemMove+1; systemRef*= systemNew+1; systemTypeCode*= systemRef+1; systemHalt*= systemTypeCode+1; systemPut8*= systemHalt+1; systemPut16*= systemPut8+1; systemPut32*= systemPut16+1; systemPut64*= systemPut32+1; systemTrace*= systemPut64+1; systemSetStackPointer*= systemTrace+1; systemSetFramePointer*= systemSetStackPointer+1; systemSetActivity*= systemSetFramePointer+1;
  101. (* system functions *)
  102. systemAdr*= systemSetActivity+1; systemSize*= systemAdr+1; systemBit*= systemSize+1; systemGet64*= systemBit+1; systemGet32*= systemGet64+1; systemGet16*= systemGet32+1; systemGet8*= systemGet16+1; systemVal*= systemGet8+1; systemMsk*= systemVal+1; systemGetStackPointer*= systemMsk+1; systemGetFramePointer*= systemGetStackPointer+1; systemGetActivity*= systemGetFramePointer+1;
  103. (* for active cells *)
  104. Send*= systemGetActivity+1; Receive*= Send+1;
  105. (* for backend specific extensions *)
  106. systemSpecial*= Receive+1;
  107. (* compatibility with Oberon07 -- other mappings: LSL -> LSH, FLOOR -> Entier, Pack und Unpk currently unsupported *)
  108. Asr*= systemSpecial+1; Ror*= Asr+1; Flt*= Ror+1; Conversion*= Flt+1; DotTimesPlus*= Conversion+1; AtMulDec*= DotTimesPlus+1; AtMulInc*= AtMulDec+1; DecMul*= AtMulInc+1; IncMul*= DecMul+1; endFox*= IncMul+1;
  109. VectorCapability* = 0;
  110. FloatingPointCapability*= 1;
  111. EngineCapability*= 2;
  112. TRMSCapability*= 3;
  113. NoMulCapability*=4;
  114. NonBlockingIOCapability*=5;
  115. CONST
  116. (* LYNX extensions *)
  117. (* different naming schema to satisfy FoxScanner when parsing imports *)
  118. LynxChar* = "@lynx_char";
  119. LynxSbyte* = "@lynx_sbyte";
  120. LynxShort* = "@lynx_short";
  121. LynxInt* = "@lynx_int";
  122. LynxLong* = "@lynx_long";
  123. LynxFloat* = "@lynx_float";
  124. LynxDouble* = "@lynx_double";
  125. LynxBool* = "@lynx_bool";
  126. LynxObject* = "@lynx_object";
  127. LynxString* = "@lynx_string";
  128. LynxNewobj* = "lynx@newobj";
  129. LynxNewarr* = "lynx@newarr";
  130. LynxAsop* = "lynx@asop";
  131. LynxUnop* = "lynx@unop";
  132. LynxBinop* = "lynx@binop";
  133. LynxSend* = "lynx@send";
  134. LynxReceive* = "lynx@receive";
  135. LynxRecvnb* = "lynx@recvnb";
  136. LynxConnect* = "lynx@connect";
  137. LynxDelegate* = "lynx@delegate";
  138. LynxNewsel* = "lynx@newsel";
  139. LynxAddsel* = "lynx@addsel";
  140. LynxSelect* = "lynx@select";
  141. LynxSelidx* = "lynx@selidx";
  142. LynxOpAdd* = 1;
  143. LynxOpSub* = 2;
  144. LynxOpMul* = 3;
  145. LynxOpDiv* = 4;
  146. LynxOpRem* = 5;
  147. LynxOpAnd* = 6;
  148. LynxOpOr* = 7;
  149. LynxOpXor* = 8;
  150. LynxOpShl* = 9;
  151. LynxOpShr* = 10;
  152. LynxOpNot* = 11;
  153. SymLynxNewobj* = endFox;
  154. SymLynxNewarr* = endFox + 1;
  155. SymLynxAsop* = endFox + 2;
  156. SymLynxUnop* = endFox + 3;
  157. SymLynxBinop* = endFox + 4;
  158. SymLynxRecvnb* = endFox + 5;
  159. SymLynxNewsel* = endFox + 6;
  160. SymLynxAddsel* = endFox + 7;
  161. SymLynxSelect* = endFox + 8;
  162. SymLynxSelidx* = endFox + 9;
  163. end = endFox + 10;
  164. VAR
  165. (* names *)
  166. SelfParameterName-,ReturnParameterName-,SystemName-,systemName-,PointerReturnName-, ResultName-,
  167. A2Name-,OberonName-,ArrayBaseName-,RecordBodyName-,ModuleBodyName-,
  168. NameWinAPI-,NameC-,NameMovable-,NameUntraced-,NameDelegate-,NameInterrupt-, NamePcOffset-, NameNoPAF-,NameEntry-, NameExit-, NameFixed-,NameFictive-, NameAligned-,NameStackAligned-,
  169. NameExclusive-,NameActive-,NamePriority-,NameSafe-,NameRealtime-, NameDynamic-, NameDataMemorySize-, NameCodeMemorySize-
  170. , NameChannelWidth-, NameChannelDepth-, NameChannelModule-, NameVector-, NameFloatingPoint-, NameNoMul-,NameNonBlockingIO-, NameTRM-, NameTRMS-, NameEngine-, NameFinal-, NameAbstract-,
  171. NameFrequencyDivider-, NameRegister-,NameNoReturn-,NamePlain-,NameUnsafe-,NameDisposable-,NameUnchecked-,NameUncooperative-: SyntaxTree.Identifier;
  172. identifiers: ARRAY 2 OF ARRAY end OF SyntaxTree.Identifier;
  173. (* some handy type variables for backend / checker implementers *)
  174. Boolean8-, Boolean32-: SyntaxTree.BooleanType;
  175. Integer8-, Integer16-, Integer32-, Integer64-: SyntaxTree.IntegerType;
  176. Unsigned8-, Unsigned16-, Unsigned32-, Unsigned64-: SyntaxTree.IntegerType;
  177. Character8-, Character16-, Character32-: SyntaxTree.CharacterType;
  178. Float32-, Float64-: SyntaxTree.FloatType;
  179. Complex64-, Complex128-: SyntaxTree.ComplexType;
  180. Byte8: SyntaxTree.ByteType;
  181. Byte32: SyntaxTree.ByteType;
  182. TYPE
  183. Alignment* = RECORD
  184. min, max: LONGINT; (* alignments in bits *)
  185. END;
  186. PassInRegisterProc = PROCEDURE {DELEGATE} (type: SyntaxTree.Type): BOOLEAN;
  187. System*= OBJECT
  188. VAR
  189. (* system and global scopes and modules (lowercase and uppercase each) *)
  190. systemScope-, globalScope-: ARRAY 2 OF SyntaxTree.ModuleScope;
  191. systemModule-,globalModule-: ARRAY 2 OF SyntaxTree.Module;
  192. activeCellsCapabilities-: SyntaxTree.Symbol; (* list of supported capabilities, filled by ActiveCells specification *)
  193. (* addressing granularity in code and data memory *)
  194. codeUnit-: LONGINT;
  195. dataUnit-: LONGINT;
  196. (* alignment (variables, record entries) *)
  197. (* alignment (parameters & stack frames) *)
  198. variableAlignment-, parameterAlignment-: Alignment;
  199. (* offset of first parameter *)
  200. offsetFirstParameter-: LONGINT;
  201. (* to determine if a builtin-procedure can be operator-overloaded *)
  202. operatorDefined-: ARRAY end OF BOOLEAN;
  203. (* type sizes defined by backend *)
  204. addressSize-: LONGINT;
  205. (* system type mapping, in a later version only the global (unisgned) types should be used
  206. the following two types are only there for compatibility with the system as is
  207. problematic are mainly the conversions between (signed) Oberon types and (unsigned) addressType.
  208. A good concept has to be derived.
  209. *)
  210. addressType-, sizeType-, shortintType-, integerType-, longintType-, hugeintType-, wordType-, longWordType-, characterType-, characterType8-, characterType16-, characterType32-, setType-, booleanType-, anyType-,byteType-,
  211. realType-, longrealType-, complexType-, longcomplexType-, objectType-, nilType-, rangeType-: SyntaxTree.Type;
  212. CanPassInRegister-: PassInRegisterProc;
  213. cellsAreObjects-: BOOLEAN;
  214. PROCEDURE &InitSystem*(codeUnit, dataUnit: LONGINT; addressSize, minVarAlign, maxVarAlign, minParAlign, maxParAlign, offsetFirstPar: LONGINT; cooperative: BOOLEAN);
  215. VAR i: LONGINT;
  216. BEGIN
  217. ASSERT(dataUnit > 0);
  218. ASSERT(minVarAlign > 0);
  219. ASSERT(maxVarAlign > 0);
  220. ASSERT(minParAlign > 0);
  221. ASSERT(maxParAlign > 0);
  222. SELF.dataUnit := dataUnit;
  223. SELF.codeUnit := codeUnit;
  224. SELF.addressSize := addressSize;
  225. SELF.variableAlignment.min := minVarAlign;
  226. SELF.variableAlignment.max := maxVarAlign;
  227. SELF.parameterAlignment.min := minParAlign;
  228. SELF.parameterAlignment.max := maxParAlign;
  229. SELF.offsetFirstParameter := offsetFirstPar;
  230. IF cooperative THEN INC(SELF.offsetFirstParameter,addressSize) END;
  231. activeCellsCapabilities := NIL;
  232. BuildScopes(SELF);
  233. FOR i := 0 TO LEN(operatorDefined)-1 DO
  234. operatorDefined[i] := FALSE;
  235. END;
  236. CanPassInRegister :=NIL;
  237. cellsAreObjects := FALSE;
  238. END InitSystem;
  239. PROCEDURE SetCellsAreObjects*(c: BOOLEAN);
  240. BEGIN
  241. cellsAreObjects := c;
  242. END SetCellsAreObjects;
  243. PROCEDURE SetRegisterPassCallback*(canPassInRegister: PassInRegisterProc);
  244. BEGIN
  245. CanPassInRegister := canPassInRegister;
  246. END SetRegisterPassCallback;
  247. PROCEDURE AddCapability*(name: SyntaxTree.Identifier);
  248. VAR symbol: SyntaxTree.Symbol;
  249. BEGIN
  250. symbol := SyntaxTree.NewSymbol(name);
  251. symbol.SetNext(activeCellsCapabilities);
  252. activeCellsCapabilities := symbol
  253. END AddCapability;
  254. PROCEDURE GenerateRecordOffsets*(x: SyntaxTree.RecordType): BOOLEAN; (* normally done in checker but the binary symbol file format makes this necessary *)
  255. VAR baseType: SyntaxTree.RecordType; offset,size: LONGINT; alignment, thisAlignment: LONGINT; variable: SyntaxTree.Variable;
  256. BEGIN
  257. baseType :=x.GetBaseRecord();
  258. IF (baseType # NIL) & (baseType.sizeInBits < 0) THEN
  259. IF~ GenerateRecordOffsets(baseType) THEN RETURN FALSE END;
  260. END;
  261. IF baseType # NIL THEN
  262. offset := baseType.sizeInBits;
  263. alignment := baseType.alignmentInBits;
  264. ELSE
  265. offset := 0; alignment := x.alignmentInBits;
  266. IF alignment <= 0 THEN alignment := dataUnit END;
  267. END;
  268. variable := x.recordScope.firstVariable;
  269. WHILE (variable # NIL) DO
  270. IF ~variable.fictive THEN
  271. size := SizeOf(variable.type.resolved);
  272. IF size < 0 THEN RETURN FALSE END;
  273. IF variable.alignment > 0 THEN
  274. thisAlignment := variable.alignment*dataUnit;
  275. ELSE
  276. thisAlignment := AlignmentOf(SELF.variableAlignment, variable.type.resolved);
  277. END;
  278. Basic.Align(offset, thisAlignment);
  279. IF thisAlignment > alignment THEN alignment := thisAlignment END;
  280. variable.SetOffset(offset);
  281. INC(offset,size);
  282. END;
  283. variable := variable.nextVariable;
  284. END;
  285. x.SetAlignmentInBits(alignment);
  286. Basic.Align(offset, alignment); (* strictly speaking not necessary, but with the old object file format otherwise problems with the GC show up *)
  287. x.SetSize(offset);
  288. RETURN TRUE
  289. END GenerateRecordOffsets;
  290. PROCEDURE GenerateCellOffsets(x: SyntaxTree.CellType): BOOLEAN;
  291. VAR baseType: SyntaxTree.Type; offset,size: LONGINT; alignment, thisAlignment: LONGINT; variable: SyntaxTree.Variable;
  292. BEGIN
  293. baseType := x.baseType;
  294. IF (baseType # NIL) THEN
  295. baseType := baseType.resolved;
  296. IF baseType IS SyntaxTree.PointerType THEN
  297. baseType := baseType(SyntaxTree.PointerType).pointerBase.resolved
  298. END;
  299. IF (baseType IS SyntaxTree.CellType) THEN
  300. IF~ GenerateCellOffsets(baseType(SyntaxTree.CellType)) THEN RETURN FALSE END;
  301. ELSE ASSERT (baseType IS SyntaxTree.RecordType);
  302. IF~GenerateRecordOffsets(baseType(SyntaxTree.RecordType)) THEN RETURN FALSE END;
  303. END;
  304. END;
  305. IF baseType # NIL THEN
  306. offset := baseType.sizeInBits;
  307. alignment := baseType.alignmentInBits;
  308. ELSE
  309. offset := 0; alignment := x.alignmentInBits;
  310. IF alignment <= 0 THEN alignment := dataUnit END;
  311. END;
  312. variable := x.cellScope.firstVariable;
  313. WHILE (variable # NIL) DO
  314. IF ~variable.fictive THEN
  315. size := SizeOf(variable.type.resolved);
  316. IF size < 0 THEN RETURN FALSE END;
  317. IF variable.alignment > 0 THEN
  318. thisAlignment := variable.alignment*dataUnit;
  319. ELSE
  320. thisAlignment := AlignmentOf(SELF.variableAlignment, variable.type.resolved);
  321. END;
  322. Basic.Align(offset, thisAlignment);
  323. IF thisAlignment > alignment THEN alignment := thisAlignment END;
  324. variable.SetOffset(offset);
  325. INC(offset,size);
  326. END;
  327. variable := variable.nextVariable;
  328. END;
  329. x.SetAlignmentInBits(alignment);
  330. Basic.Align(offset, alignment); (* strictly speaking not necessary, but with the old object file format otherwise problems with the GC show up *)
  331. x.SetSize(offset);
  332. RETURN TRUE
  333. END GenerateCellOffsets;
  334. PROCEDURE GenerateVariableOffsets*(scope: SyntaxTree.Scope): BOOLEAN;
  335. VAR variable: SyntaxTree.Variable; offset,size: LONGINT; alignment: LONGINT; parameterOffset :LONGINT;
  336. BEGIN
  337. IF scope IS SyntaxTree.RecordScope THEN (* increasing indices *)
  338. RETURN GenerateRecordOffsets(scope(SyntaxTree.RecordScope).ownerRecord)
  339. ELSIF scope IS SyntaxTree.CellScope THEN
  340. RETURN GenerateCellOffsets(scope(SyntaxTree.CellScope).ownerCell);
  341. ELSE (* module scope or procedure scope: decreasing indices *)
  342. ASSERT((scope IS SyntaxTree.ModuleScope) OR (scope IS SyntaxTree.ProcedureScope));
  343. offset := 0;
  344. IF scope IS SyntaxTree.ProcedureScope THEN
  345. parameterOffset := scope(SyntaxTree.ProcedureScope).ownerProcedure.type(SyntaxTree.ProcedureType).parameterOffset
  346. ELSE
  347. parameterOffset := 0
  348. END;
  349. variable := scope.firstVariable;
  350. WHILE (variable # NIL) DO
  351. IF (variable.externalName = NIL) & ~variable.fictive THEN
  352. size := SizeOf(variable.type.resolved);
  353. IF size < 0 THEN RETURN FALSE END;
  354. DEC(offset,size);
  355. IF variable.alignment > 0 THEN
  356. Basic.Align(offset, -variable.alignment*dataUnit);
  357. ELSE
  358. alignment := AlignmentOf(SELF.variableAlignment,variable.type.resolved);
  359. Basic.Align(offset,-alignment);
  360. END;
  361. variable.SetOffset(offset);
  362. END;
  363. variable := variable.nextVariable;
  364. END;
  365. END;
  366. RETURN TRUE
  367. END GenerateVariableOffsets;
  368. PROCEDURE GenerateParameterOffsets*(procedure : SyntaxTree.Procedure; nestedProcedure: BOOLEAN): BOOLEAN;
  369. VAR offset,size: LONGINT;parameter: SyntaxTree.Parameter; procedureType: SyntaxTree.ProcedureType;
  370. BEGIN
  371. procedureType := procedure.type(SyntaxTree.ProcedureType);
  372. IF (procedure.isInline) THEN
  373. offset := 0
  374. ELSE
  375. offset := SELF.offsetFirstParameter;
  376. END;
  377. IF nestedProcedure THEN
  378. INC(offset,addressSize); (* parameter offset of static link *) (*! check alternative: add hidden parameter *)
  379. END;
  380. IF procedureType.callingConvention = SyntaxTree.OberonCallingConvention THEN
  381. parameter := procedureType.lastParameter;
  382. WHILE (parameter # NIL) DO
  383. Basic.Align(offset,addressSize);
  384. parameter.SetOffset(offset);
  385. size := SizeOfParameter(parameter);
  386. IF size < 0 THEN RETURN FALSE END;
  387. INC(offset,SizeOfParameter(parameter));
  388. parameter := parameter.prevParameter;
  389. END;
  390. parameter := procedureType.returnParameter;
  391. IF parameter # NIL THEN
  392. Basic.Align(offset,addressSize);
  393. parameter.SetOffset(offset);
  394. size := SizeOfParameter(parameter);
  395. IF size < 0 THEN RETURN FALSE END;
  396. INC(offset,SizeOfParameter(parameter));
  397. END;
  398. ELSE
  399. parameter := procedureType.firstParameter;
  400. WHILE (parameter # NIL) DO
  401. Basic.Align(offset,addressSize);
  402. parameter.SetOffset(offset);
  403. size := SizeOfParameter(parameter);
  404. IF size < 0 THEN RETURN FALSE END;
  405. INC(offset,size);
  406. parameter := parameter.nextParameter;
  407. END;
  408. END;
  409. IF (procedureType.isDelegate) THEN
  410. INC(offset,addressSize); (* parameter offset of delegate *)
  411. END;
  412. procedureType.SetParameterOffset(offset);
  413. RETURN TRUE
  414. END GenerateParameterOffsets;
  415. PROCEDURE SizeOf*(type: SyntaxTree.Type): LONGINT;
  416. VAR size: LONGINT; base: SyntaxTree.Type;
  417. BEGIN
  418. IF type = NIL THEN RETURN -1 END;
  419. type := type.resolved;
  420. IF type IS SyntaxTree.BasicType THEN
  421. size := type.sizeInBits
  422. ELSIF type IS SyntaxTree.PointerType THEN
  423. size := addressSize
  424. ELSIF type IS SyntaxTree.ProcedureType THEN
  425. IF type(SyntaxTree.ProcedureType).isDelegate THEN
  426. size := 2*addressSize
  427. ELSE
  428. size := addressSize
  429. END;
  430. ELSIF type IS SyntaxTree.RecordType THEN
  431. (* do not treat a record type like a pointer even if the Pointer field is set, this leads to problems in object files
  432. rather make sure that each reference type is a POINTER TO at least behind the secenes!
  433. *)
  434. IF ~(SyntaxTree.Resolved IN type.state) THEN
  435. size := -1
  436. ELSE
  437. size :=type.sizeInBits;
  438. IF size < 0 THEN
  439. IF GenerateRecordOffsets(type(SyntaxTree.RecordType)) THEN
  440. size :=type.sizeInBits;
  441. ELSE
  442. size := -1
  443. END;
  444. END;
  445. END;
  446. ELSIF type IS SyntaxTree.ArrayType THEN
  447. IF ~(SyntaxTree.Resolved IN type.state) THEN
  448. size := -1
  449. ELSIF type.sizeInBits >= 0 THEN
  450. size := type.sizeInBits
  451. ELSIF type(SyntaxTree.ArrayType).form = SyntaxTree.Static THEN
  452. size := AlignedSizeOf(type(SyntaxTree.ArrayType).arrayBase.resolved)*type(SyntaxTree.ArrayType).staticLength;
  453. type.SetSize(size);
  454. ELSE
  455. size := 0; base := type;
  456. WHILE(base IS SyntaxTree.ArrayType) DO
  457. base := base(SyntaxTree.ArrayType).arrayBase.resolved;
  458. INC(size); (* length field *)
  459. END;
  460. size := size*addressSize+addressSize;
  461. type.SetSize(size)
  462. END;
  463. ELSIF type IS SyntaxTree.MathArrayType THEN
  464. IF ~(SyntaxTree.Resolved IN type.state) THEN
  465. size := -1
  466. ELSIF type(SyntaxTree.MathArrayType).form = SyntaxTree.Static THEN
  467. size := SizeOf(type(SyntaxTree.MathArrayType).arrayBase.resolved)*type(SyntaxTree.MathArrayType).staticLength
  468. ELSIF type(SyntaxTree.MathArrayType).form = SyntaxTree.Tensor THEN
  469. size := addressSize (* pointer to geometry descriptor *)
  470. ELSE
  471. size := 0;
  472. WHILE(type # NIL) & (type IS SyntaxTree.MathArrayType) DO
  473. type := type(SyntaxTree.MathArrayType).arrayBase;
  474. IF type # NIL THEN type := type.resolved END;
  475. INC(size);
  476. END;
  477. size := size*2*addressSize (* length and increments *) +5*addressSize (* data ptr, adr ptr, flags, dim and elementsize *);
  478. END;
  479. ELSIF type IS SyntaxTree.StringType THEN
  480. ASSERT(SyntaxTree.Resolved IN type.state);
  481. size := type(SyntaxTree.StringType).length * SizeOf(type(SyntaxTree.StringType).baseType);
  482. ELSIF type IS SyntaxTree.EnumerationType THEN
  483. size := addressSize
  484. ELSIF type = SyntaxTree.invalidType THEN size := 0
  485. ELSIF type IS SyntaxTree.QualifiedType THEN
  486. HALT(101); (* hint that unresolved type has been taken for type size computation *)
  487. ELSIF type IS SyntaxTree.PortType THEN
  488. size := addressSize
  489. ELSIF type IS SyntaxTree.CellType THEN
  490. size := addressSize;
  491. ELSIF type IS SyntaxTree.RangeType THEN
  492. size := 3 * SizeOf(longintType);
  493. ELSE
  494. HALT(100)
  495. END;
  496. RETURN size
  497. END SizeOf;
  498. PROCEDURE SizeOfParameter*(par: SyntaxTree.Parameter):LONGINT;
  499. BEGIN
  500. IF (par.type.resolved IS SyntaxTree.ArrayType) OR (par.type.resolved IS SyntaxTree.MathArrayType) THEN
  501. IF (par.type.resolved IS SyntaxTree.ArrayType) & (par.type.resolved(SyntaxTree.ArrayType).form = SyntaxTree.Static) &
  502. (par.kind IN {SyntaxTree.ConstParameter,SyntaxTree.VarParameter})
  503. OR
  504. (par.type.resolved IS SyntaxTree.MathArrayType) & (par.type.resolved(SyntaxTree.MathArrayType).form = SyntaxTree.Static) &
  505. (par.kind IN {SyntaxTree.ConstParameter,SyntaxTree.VarParameter})
  506. OR (par.type.resolved IS SyntaxTree.MathArrayType) & (par.kind = SyntaxTree.VarParameter)
  507. THEN
  508. RETURN addressSize
  509. ELSIF IsOberonProcedure(par.ownerType) THEN
  510. RETURN SizeOf(par.type);
  511. ELSE RETURN addressSize
  512. END
  513. ELSIF par.type.resolved IS SyntaxTree.RangeType THEN
  514. IF par.kind = SyntaxTree.VarParameter THEN
  515. RETURN addressSize
  516. ELSE
  517. RETURN SizeOf(rangeType) (* array range components are materialized on stack for both value and const parameters *)
  518. END
  519. ELSIF par.type.resolved IS SyntaxTree.RecordType THEN
  520. IF (par.kind IN {SyntaxTree.ConstParameter,SyntaxTree.VarParameter}) THEN
  521. IF IsOberonProcedure(par.ownerType) THEN
  522. RETURN 2*addressSize
  523. ELSE
  524. RETURN addressSize
  525. END
  526. ELSE
  527. RETURN SizeOf(par.type);
  528. END;
  529. ELSIF par.kind = SyntaxTree.VarParameter THEN
  530. RETURN addressSize
  531. ELSIF par.kind = SyntaxTree.ConstParameter THEN
  532. RETURN SizeOf(par.type)
  533. ELSE
  534. RETURN SizeOf(par.type);
  535. END;
  536. END SizeOfParameter;
  537. PROCEDURE AlignmentOf*(CONST alignment: Alignment;type: SyntaxTree.Type): LONGINT;
  538. VAR result: LONGINT;
  539. BEGIN
  540. type := type.resolved;
  541. IF type IS SyntaxTree.RecordType THEN
  542. IF type.alignmentInBits <= 0 THEN
  543. IF GenerateRecordOffsets(type(SyntaxTree.RecordType)) THEN
  544. result := type.alignmentInBits
  545. END
  546. ELSE
  547. result := type.alignmentInBits
  548. END;
  549. ELSIF type IS SyntaxTree.ArrayType THEN
  550. IF type.alignmentInBits <= 0 THEN
  551. IF type(SyntaxTree.ArrayType).form = SyntaxTree.Static THEN
  552. result := AlignmentOf(alignment,type(SyntaxTree.ArrayType).arrayBase.resolved);
  553. ELSE
  554. result := alignment.max
  555. END;
  556. type.SetAlignmentInBits(result)
  557. ELSE
  558. result := type.alignmentInBits
  559. END;
  560. ELSIF type IS SyntaxTree.StringType THEN
  561. result := SizeOf(type(SyntaxTree.StringType).baseType);
  562. ELSE
  563. result := SizeOf(type);
  564. IF result > alignment.max THEN result := alignment.max END;
  565. IF result < alignment.min THEN result := alignment.min END;
  566. END;
  567. ASSERT(result # 0);
  568. RETURN result
  569. END AlignmentOf;
  570. PROCEDURE AlignedSizeOf*(type: SyntaxTree.Type): LONGINT;
  571. VAR size: LONGINT;
  572. BEGIN
  573. size := SizeOf(type);
  574. Basic.Align(size, AlignmentOf(variableAlignment, type));
  575. RETURN size
  576. END AlignedSizeOf;
  577. (* LYNX+ *)
  578. PROCEDURE IsLynx*(): BOOLEAN;
  579. BEGIN
  580. RETURN TRUE;
  581. END IsLynx;
  582. (* -LYNX *)
  583. END System;
  584. PROCEDURE BuildScopes(system: System);
  585. VAR i: LONGINT;
  586. BEGIN
  587. FOR i := 0 TO end-1 DO
  588. system.operatorDefined[i] := FALSE
  589. END;
  590. system.globalScope[Scanner.Uppercase] := SyntaxTree.NewModuleScope();
  591. system.globalScope[Scanner.Lowercase] := SyntaxTree.NewModuleScope();
  592. system.globalModule[Scanner.Uppercase] := SyntaxTree.NewModule("",-1,SyntaxTree.NewIdentifier("@GLOBAL"),system.globalScope[Scanner.Uppercase],Scanner.Uppercase);
  593. system.globalModule[Scanner.Lowercase] := SyntaxTree.NewModule("",-1,SyntaxTree.NewIdentifier("@global"),system.globalScope[Scanner.Lowercase],Scanner.Lowercase);
  594. system.systemScope[Scanner.Uppercase] := SyntaxTree.NewModuleScope();
  595. system.systemScope[Scanner.Lowercase] := SyntaxTree.NewModuleScope();
  596. system.systemModule[Scanner.Uppercase] := SyntaxTree.NewModule("",-1,SystemName,system.systemScope[Scanner.Uppercase],Scanner.Uppercase);
  597. system.systemModule[Scanner.Lowercase] := SyntaxTree.NewModule("",-1,systemName,system.systemScope[Scanner.Lowercase],Scanner.Lowercase);
  598. END BuildScopes;
  599. PROCEDURE SetDefaultDeclarations*(system: System; minBits: LONGINT);
  600. VAR now: Dates.DateTime; date, time: ARRAY 20 OF CHAR;
  601. BEGIN
  602. (* types *)
  603. system.longintType := SyntaxTree.NewIntegerType(32, TRUE);
  604. system.hugeintType := SyntaxTree.NewIntegerType(64, TRUE);
  605. system.wordType := SyntaxTree.NewIntegerType(MIN(system.addressSize,32),TRUE);
  606. system.longWordType := SyntaxTree.NewIntegerType(system.addressSize,TRUE);
  607. system.realType := SyntaxTree.NewFloatType(32);
  608. system.longrealType := SyntaxTree.NewFloatType(64);
  609. (*
  610. system.longintType := Integer32;
  611. system.hugeintType := Integer64;
  612. system.realType := Float32;
  613. system.longrealType := Float64;
  614. *)
  615. IF minBits = 32 THEN
  616. system.shortintType := SyntaxTree.NewIntegerType(32, TRUE);
  617. system.integerType := SyntaxTree.NewIntegerType(32, TRUE);
  618. system.booleanType := SyntaxTree.NewBooleanType(32);
  619. system.byteType := SyntaxTree.NewByteType(32);
  620. system.characterType := SyntaxTree.NewCharacterType(32);
  621. system.characterType8 := SyntaxTree.NewCharacterType(32);
  622. system.characterType16 := SyntaxTree.NewCharacterType(32);
  623. system.characterType32 := SyntaxTree.NewCharacterType(32);
  624. (*
  625. system.shortintType := Integer32;
  626. system.integerType := Integer32;
  627. system.booleanType := Boolean32;
  628. system.byteType := Byte32;
  629. system.characterType := Character32;
  630. *)
  631. ELSE
  632. ASSERT(minBits = 8); (* nothing else is currently implemented *)
  633. system.shortintType := SyntaxTree.NewIntegerType(8, TRUE);
  634. system.integerType := SyntaxTree.NewIntegerType(16, TRUE);
  635. system.booleanType := SyntaxTree.NewBooleanType(8);
  636. system.byteType := SyntaxTree.NewByteType(8);
  637. system.characterType := SyntaxTree.NewCharacterType(8);;
  638. system.characterType8 := SyntaxTree.NewCharacterType(8);;
  639. system.characterType16 := SyntaxTree.NewCharacterType(16);;
  640. system.characterType32 := SyntaxTree.NewCharacterType(32);;
  641. (*
  642. system.shortintType := Integer8;
  643. system.integerType := Integer16;
  644. system.booleanType := Boolean8;
  645. system.byteType := Byte8;
  646. system.characterType := Character8;
  647. *)
  648. END;
  649. system.anyType := SyntaxTree.NewAnyType(system.addressSize);
  650. system.objectType := SyntaxTree.NewObjectType(system.addressSize);
  651. system.nilType := SyntaxTree.NewNilType(system.addressSize);
  652. system.addressType := SyntaxTree.NewAddressType(system.addressSize);
  653. system.sizeType := SyntaxTree.NewSizeType(system.addressSize);
  654. system.rangeType := SyntaxTree.NewRangeType(3 * system.SizeOf(system.longintType));
  655. system.complexType := Complex64;
  656. system.longcomplexType := Complex128;
  657. system.setType := SyntaxTree.NewSetType(system.addressSize);
  658. (* type declarations *)
  659. DeclareType(system.byteType,"BYTE",system.systemScope);
  660. DeclareType(system.addressType,"ADDRESS",system.globalScope);
  661. DeclareType(system.sizeType,"SIZE",system.globalScope);
  662. (*DeclareType(Same,"SAME",system.systemScope);*)
  663. (* system builtin procedures *)
  664. NewBuiltin(systemGet,"GET",system.systemScope,TRUE);
  665. NewBuiltin(systemPut,"PUT",system.systemScope,TRUE);
  666. NewBuiltin(systemPut64,"PUT64",system.systemScope,TRUE);
  667. NewBuiltin(systemPut32,"PUT32",system.systemScope,TRUE);
  668. NewBuiltin(systemPut16,"PUT16",system.systemScope,TRUE);
  669. NewBuiltin(systemPut8,"PUT8",system.systemScope,TRUE);
  670. NewBuiltin(systemGet64,"GET64",system.systemScope,TRUE);
  671. NewBuiltin(systemGet32,"GET32",system.systemScope,TRUE);
  672. NewBuiltin(systemGet16,"GET16",system.systemScope,TRUE);
  673. NewBuiltin(systemGet8,"GET8",system.systemScope,TRUE);
  674. NewBuiltin(systemVal,"VAL",system.systemScope,TRUE);
  675. NewBuiltin(systemMove,"MOVE",system.systemScope,TRUE);
  676. NewBuiltin(systemRef,"REF",system.systemScope,FALSE);
  677. NewBuiltin(systemNew,"NEW",system.systemScope,FALSE);
  678. NewBuiltin(systemTypeCode,"TYPECODE",system.systemScope,TRUE);
  679. NewBuiltin(systemHalt,"HALT",system.systemScope,TRUE);
  680. NewBuiltin(systemSize,"SIZE",system.systemScope,TRUE);
  681. NewBuiltin(systemAdr,"ADR",system.systemScope,TRUE);
  682. NewBuiltin(systemMsk,"MSK",system.systemScope,TRUE);
  683. NewBuiltin(systemBit,"BIT",system.systemScope,TRUE);
  684. now := Dates.Now ();
  685. Strings.FormatDateTime ("hh:nn:ss", now, time);
  686. Strings.FormatDateTime ("mmm dd yyyy", now, date);
  687. NewStringConstantCamelCase("Time", Strings.NewString (time), system.characterType, system.systemScope);
  688. NewStringConstantCamelCase("Date", Strings.NewString (date), system.characterType, system.systemScope);
  689. NewBuiltinCamelCase(systemGetStackPointer,"GetStackPointer",system.systemScope,TRUE);
  690. NewBuiltinCamelCase(systemSetStackPointer,"SetStackPointer",system.systemScope,TRUE);
  691. NewBuiltinCamelCase(systemGetFramePointer,"GetFramePointer",system.systemScope,TRUE);
  692. NewBuiltinCamelCase(systemSetFramePointer,"SetFramePointer",system.systemScope,TRUE);
  693. NewBuiltinCamelCase(systemGetActivity,"GetActivity",system.systemScope,TRUE);
  694. NewBuiltinCamelCase(systemSetActivity,"SetActivity",system.systemScope,TRUE);
  695. (* Set up system types *)
  696. DeclareType(system.characterType,"CHAR",system.globalScope);
  697. DeclareType(system.characterType8,"CHAR8",system.globalScope);
  698. DeclareType(system.characterType16,"CHAR16",system.globalScope);
  699. DeclareType(system.characterType32,"CHAR32",system.globalScope);
  700. DeclareType(system.rangeType,"RANGE",system.globalScope);
  701. DeclareType(system.shortintType,"SHORTINT",system.globalScope);
  702. DeclareType(system.integerType,"INTEGER",system.globalScope);
  703. DeclareType(system.longintType,"LONGINT",system.globalScope);
  704. DeclareType(system.hugeintType,"HUGEINT",system.globalScope);
  705. DeclareType(system.wordType,"WORD",system.globalScope);
  706. DeclareType(system.longWordType,"LONGWORD",system.globalScope);
  707. DeclareType(Integer8, "SIGNED8", system.globalScope);
  708. DeclareType(Integer16, "SIGNED16", system.globalScope);
  709. DeclareType(Integer32, "SIGNED32", system.globalScope);
  710. DeclareType(Integer64, "SIGNED64", system.globalScope);
  711. DeclareType(Unsigned8, "UNSIGNED8", system.globalScope);
  712. DeclareType(Unsigned16, "UNSIGNED16", system.globalScope);
  713. DeclareType(Unsigned32, "UNSIGNED32", system.globalScope);
  714. DeclareType(Unsigned64, "UNSIGNED64", system.globalScope);
  715. DeclareType(system.realType,"REAL",system.globalScope);
  716. DeclareType(system.longrealType,"LONGREAL",system.globalScope);
  717. DeclareType(system.complexType,"COMPLEX",system.globalScope);
  718. DeclareType(system.longcomplexType,"LONGCOMPLEX",system.globalScope);
  719. DeclareType(system.booleanType,"BOOLEAN",system.globalScope);
  720. DeclareType(system.setType,"SET",system.globalScope);
  721. DeclareType(system.anyType,"ANY",system.globalScope);
  722. DeclareType(system.objectType,"OBJECT",system.globalScope);
  723. (* global functions *)
  724. NewBuiltin(Abs,"ABS",system.globalScope,TRUE);
  725. NewBuiltin(Ash,"ASH",system.globalScope,TRUE);
  726. NewBuiltin(Asr,"ASR",system.globalScope,TRUE);
  727. NewBuiltin(Cap,"CAP",system.globalScope,TRUE);
  728. NewBuiltin(Chr,"CHR",system.globalScope,TRUE);
  729. NewBuiltin(Chr32,"CHR32",system.globalScope,TRUE);
  730. NewBuiltin(Entier,"ENTIER",system.globalScope,TRUE);
  731. NewBuiltin(Entier,"FLOOR",system.globalScope,TRUE);
  732. NewBuiltin(EntierH,"ENTIERH",system.globalScope,TRUE);
  733. NewBuiltin(Len,"LEN",system.globalScope,TRUE);
  734. NewBuiltin(Long,"LONG",system.globalScope,TRUE);
  735. NewBuiltin(Max,"MAX",system.globalScope,TRUE);
  736. NewBuiltin(Min,"MIN",system.globalScope,TRUE);
  737. NewBuiltin(Odd,"ODD",system.globalScope,TRUE);
  738. NewBuiltin(Ord,"ORD",system.globalScope,TRUE);
  739. NewBuiltin(Ord32,"ORD32",system.globalScope,TRUE);
  740. NewBuiltin(Lsh,"LSH",system.globalScope,TRUE);
  741. NewBuiltin(Lsh,"LSL",system.globalScope,TRUE);
  742. NewBuiltin(Rot,"ROT",system.globalScope,TRUE);
  743. NewBuiltin(Ror,"ROR",system.globalScope,TRUE);
  744. NewBuiltin(Incr,"INCR",system.globalScope,TRUE);
  745. NewBuiltin(Short,"SHORT",system.globalScope,TRUE);
  746. NewBuiltin(Sum,"SUM",system.globalScope,TRUE);
  747. NewBuiltin(Dim,"DIM",system.globalScope,TRUE);
  748. NewBuiltin(Cas,"CAS",system.globalScope,TRUE);
  749. NewBuiltin(First,"FIRST",system.globalScope,TRUE);
  750. NewBuiltin(Last,"LAST",system.globalScope,TRUE);
  751. NewBuiltin(Step,"STEP",system.globalScope,TRUE);
  752. NewBuiltin(Re,"RE",system.globalScope,TRUE);
  753. NewBuiltin(Im,"IM",system.globalScope,TRUE);
  754. NewBuiltin(systemAdr,"ADDRESSOF",system.globalScope,TRUE);
  755. NewBuiltin(systemSize,"SIZEOF",system.globalScope,TRUE);
  756. (* global proper procedures *)
  757. NewBuiltin(Assert,"ASSERT",system.globalScope,TRUE);
  758. NewBuiltin(Copy,"COPY",system.globalScope,TRUE);
  759. NewBuiltin(Dec,"DEC",system.globalScope,TRUE);
  760. NewBuiltin(Excl,"EXCL",system.globalScope,TRUE);
  761. NewBuiltin(Halt,"HALT",system.globalScope,TRUE);
  762. NewBuiltin(Inc,"INC",system.globalScope,TRUE);
  763. NewBuiltin(Incl,"INCL",system.globalScope,TRUE);
  764. NewBuiltin(New,"NEW",system.globalScope,FALSE);
  765. NewBuiltin(Dispose,"DISPOSE",system.globalScope, FALSE);
  766. NewBuiltin(GetProcedure,"GETPROCEDURE",system.globalScope,TRUE);
  767. NewBuiltin(systemTrace,"TRACE",system.globalScope,TRUE);
  768. NewBuiltin(Reshape,"RESHAPE",system.globalScope,TRUE);
  769. NewBuiltin(All,"ALL",system.globalScope,TRUE);
  770. NewBuiltin(Wait,"WAIT",system.globalScope,FALSE);
  771. NewBuiltin(Connect,"CONNECT",system.globalScope,FALSE);
  772. NewBuiltin(Receive,"RECEIVE",system.globalScope,FALSE);
  773. NewBuiltin(Send,"SEND",system.globalScope,FALSE);
  774. NewBuiltin(Delegate,"DELEGATE",system.globalScope,FALSE);
  775. (*!
  776. (* Following is LYNX version: *)
  777. IF minBits = 8 THEN
  778. system.characterType := Character16;
  779. END;
  780. (* LYNX builtin types *)
  781. DeclareLynxType(system.characterType, LynxChar, system.globalScope);
  782. DeclareLynxType(system.shortintType, LynxSbyte, system.globalScope);
  783. DeclareLynxType(system.integerType, LynxShort, system.globalScope);
  784. DeclareLynxType(system.longintType, LynxInt, system.globalScope);
  785. DeclareLynxType(system.hugeintType, LynxLong, system.globalScope);
  786. DeclareLynxType(system.realType, LynxFloat, system.globalScope);
  787. DeclareLynxType(system.longrealType, LynxDouble, system.globalScope);
  788. DeclareLynxType(system.booleanType, LynxBool, system.globalScope);
  789. (* TODO: object, string *)
  790. (* LYNX global functions *)
  791. NewBuiltin(SymLynxNewobj, LynxNewobj, system.globalScope, TRUE);
  792. NewBuiltin(SymLynxNewarr, LynxNewarr, system.globalScope, TRUE);
  793. NewBuiltin(SymLynxAsop, LynxAsop, system.globalScope, TRUE);
  794. NewBuiltin(SymLynxUnop, LynxUnop, system.globalScope, TRUE);
  795. NewBuiltin(SymLynxBinop, LynxBinop, system.globalScope, TRUE);
  796. NewBuiltin(SymLynxRecvnb, LynxRecvnb, system.globalScope, TRUE);
  797. (*
  798. LynxCompiler will register builtins for send/receive/connect/delegate
  799. under "lynx@*" names but with their original Fox numeric identifiers,
  800. so that no modifications will be required in the semantic checker and
  801. intermediate backend.
  802. *)
  803. NewBuiltin(SymLynxNewsel, LynxNewsel, system.globalScope, TRUE);
  804. NewBuiltin(SymLynxAddsel, LynxAddsel, system.globalScope, TRUE);
  805. NewBuiltin(SymLynxSelect, LynxSelect, system.globalScope, TRUE);
  806. NewBuiltin(SymLynxSelidx, LynxSelidx, system.globalScope, TRUE);
  807. *)
  808. END SetDefaultDeclarations;
  809. PROCEDURE OperatorDefined*(system: System; op: LONGINT; defined: BOOLEAN);
  810. BEGIN
  811. system.operatorDefined[op] := defined;
  812. END OperatorDefined;
  813. PROCEDURE SetDefaultOperators*(system: System);
  814. VAR i: LONGINT;
  815. BEGIN
  816. FOR i := Scanner.Equal TO Scanner.Not DO
  817. OperatorDefined(system,i,TRUE);
  818. END;
  819. OperatorDefined(system, Conversion, TRUE);
  820. OperatorDefined(system, DotTimesPlus, TRUE);
  821. OperatorDefined(system, AtMulDec, TRUE);
  822. OperatorDefined(system, AtMulInc, TRUE);
  823. OperatorDefined(system, DecMul, TRUE);
  824. OperatorDefined(system, IncMul, TRUE);
  825. OperatorDefined(system,Scanner.Transpose,TRUE);
  826. OperatorDefined(system,Scanner.Becomes,TRUE);
  827. OperatorDefined(system,Dec,TRUE);
  828. OperatorDefined(system,Excl,TRUE);
  829. OperatorDefined(system,Inc,TRUE);
  830. OperatorDefined(system,Incl,TRUE);
  831. OperatorDefined(system,Abs,TRUE);
  832. OperatorDefined(system,Ash,TRUE);
  833. OperatorDefined(system,Cap,TRUE);
  834. OperatorDefined(system,Chr,TRUE);
  835. OperatorDefined(system,Entier,TRUE);
  836. OperatorDefined(system,EntierH,TRUE);
  837. OperatorDefined(system,Len,TRUE);
  838. OperatorDefined(system,Long,TRUE);
  839. OperatorDefined(system,Max,TRUE);
  840. OperatorDefined(system,Min,TRUE);
  841. OperatorDefined(system,Odd,TRUE);
  842. OperatorDefined(system,Short,TRUE);
  843. OperatorDefined(system,Sum,TRUE);
  844. OperatorDefined(system,Dim,TRUE);
  845. OperatorDefined(system,Scanner.Address, TRUE);
  846. OperatorDefined(system,Scanner.Size, TRUE);
  847. OperatorDefined(system,Scanner.Alias, TRUE);
  848. OperatorDefined(system,All,TRUE);
  849. OperatorDefined(system, Scanner.Questionmarks, TRUE);
  850. OperatorDefined(system, Scanner.GreaterGreater, TRUE);
  851. OperatorDefined(system, Scanner.LessLess, TRUE);
  852. END SetDefaultOperators;
  853. PROCEDURE DefaultSystem*(): System;
  854. VAR system: System;
  855. BEGIN
  856. NEW(system,8,8,32, 8,32,32,32,64,FALSE);
  857. SetDefaultDeclarations(system,8);
  858. SetDefaultOperators(system);
  859. RETURN system
  860. END DefaultSystem;
  861. PROCEDURE IsOberonProcedure*(type: SyntaxTree.Type): BOOLEAN;
  862. BEGIN
  863. RETURN (type IS SyntaxTree.ProcedureType) & (type(SyntaxTree.ProcedureType).callingConvention = SyntaxTree.OberonCallingConvention)
  864. END IsOberonProcedure;
  865. PROCEDURE AlignedSizeOf*(system: System; CONST alignment: Alignment; type: SyntaxTree.Type):LONGINT;
  866. VAR value: LONGINT;
  867. BEGIN
  868. value := SHORT(system.SizeOf(type));
  869. INC(value, (-value) MOD system.AlignmentOf(alignment, type));
  870. RETURN value;
  871. END AlignedSizeOf;
  872. (* returns if a module is the system module *)
  873. PROCEDURE IsSystemModule*(module: SyntaxTree.Module): BOOLEAN;
  874. BEGIN RETURN (module.name=systemName) OR (module.name=SystemName)
  875. END IsSystemModule;
  876. (** Various factories *)
  877. PROCEDURE DeclareType0(type: SyntaxTree.Type; CONST name: ARRAY OF CHAR; in: SyntaxTree.Scope);
  878. VAR basic: SyntaxTree.TypeDeclaration; duplicate: BOOLEAN;
  879. BEGIN
  880. basic := SyntaxTree.NewTypeDeclaration(-1,SyntaxTree.NewIdentifier(name));
  881. basic.SetDeclaredType(type);
  882. basic.SetState(SyntaxTree.Resolved);
  883. basic.SetAccess(SyntaxTree.ReadOnly);
  884. in.AddTypeDeclaration(basic);
  885. in.EnterSymbol(basic,duplicate);
  886. ASSERT(~duplicate);
  887. END DeclareType0;
  888. (** External interface backends can use to add their types etc. to the global scope *)
  889. PROCEDURE DeclareType*(type: SyntaxTree.Type; CONST name: ARRAY OF CHAR; CONST scope: ARRAY OF SyntaxTree.ModuleScope);
  890. VAR nameL,nameU: Scanner.IdentifierString;
  891. BEGIN
  892. Basic.Lowercase(name,nameL);
  893. Basic.Uppercase(name,nameU);
  894. DeclareType0(type,nameU,scope[Scanner.Uppercase]);
  895. DeclareType0(type,nameL,scope[Scanner.Lowercase]);
  896. END DeclareType;
  897. (* LYNX+ *)
  898. PROCEDURE DeclareLynxType*(
  899. type: SyntaxTree.Type; CONST name: ARRAY OF CHAR; CONST scope: ARRAY OF SyntaxTree.ModuleScope);
  900. BEGIN
  901. DeclareType0(type, name, scope[Scanner.Uppercase]);
  902. DeclareType0(type, name, scope[Scanner.Lowercase]);
  903. END DeclareLynxType;
  904. (* -LYNX *)
  905. PROCEDURE NewConstant0(CONST name: ARRAY OF CHAR; int: LONGINT; type: SyntaxTree.Type; in: SyntaxTree.Scope);
  906. VAR constant: SyntaxTree.Constant; value: SyntaxTree.IntegerValue;duplicate: BOOLEAN;
  907. BEGIN
  908. value := SyntaxTree.NewIntegerValue(-1,int);
  909. value.SetType(type);
  910. constant := SyntaxTree.NewConstant(-1,SyntaxTree.NewIdentifier(name));
  911. constant.SetValue(value);
  912. constant.SetType(value.type);
  913. constant.SetAccess(SyntaxTree.ReadOnly);
  914. constant.SetState(SyntaxTree.Resolved);
  915. in.AddConstant(constant);
  916. in.EnterSymbol(constant,duplicate);
  917. ASSERT(~duplicate);
  918. END NewConstant0;
  919. PROCEDURE NewConstant*(CONST name: ARRAY OF CHAR; int: LONGINT; type: SyntaxTree.Type; CONST scope: ARRAY OF SyntaxTree.ModuleScope);
  920. VAR nameL,nameU: Scanner.IdentifierString;
  921. BEGIN
  922. Basic.Lowercase(name,nameL);
  923. Basic.Uppercase(name,nameU);
  924. NewConstant0(nameU,int,type,scope[Scanner.Uppercase]);
  925. NewConstant0(nameL,int,type,scope[Scanner.Lowercase]);
  926. END NewConstant;
  927. PROCEDURE NewStringConstant0(CONST name: ARRAY OF CHAR; string: SyntaxTree.String; baseType: SyntaxTree.Type; in: SyntaxTree.Scope);
  928. VAR constant: SyntaxTree.Constant; value: SyntaxTree.StringValue;duplicate: BOOLEAN;
  929. BEGIN
  930. value := SyntaxTree.NewStringValue(-1,string);
  931. value.SetType(SyntaxTree.NewStringType(-1,baseType,value.length));
  932. constant := SyntaxTree.NewConstant(-1,SyntaxTree.NewIdentifier(name));
  933. constant.SetValue(value);
  934. constant.SetType(value.type);
  935. constant.SetAccess(SyntaxTree.ReadOnly);
  936. constant.SetState(SyntaxTree.Resolved);
  937. in.AddConstant(constant);
  938. in.EnterSymbol(constant,duplicate);
  939. ASSERT(~duplicate);
  940. END NewStringConstant0;
  941. PROCEDURE NewStringConstant*(CONST name: ARRAY OF CHAR; string: SyntaxTree.String; type: SyntaxTree.Type; CONST scope: ARRAY OF SyntaxTree.ModuleScope);
  942. VAR nameL,nameU: Scanner.IdentifierString;
  943. BEGIN
  944. Basic.Lowercase(name,nameL);
  945. Basic.Uppercase(name,nameU);
  946. NewStringConstant0(nameU,string,type,scope[Scanner.Uppercase]);
  947. NewStringConstant0(nameL,string,type,scope[Scanner.Lowercase]);
  948. END NewStringConstant;
  949. PROCEDURE NewStringConstantCamelCase*(CONST name: ARRAY OF CHAR; string: SyntaxTree.String; type: SyntaxTree.Type; CONST scope: ARRAY OF SyntaxTree.ModuleScope);
  950. BEGIN
  951. NewStringConstant0(name,string,type,scope[Scanner.Uppercase]);
  952. NewStringConstant0(name,string,type,scope[Scanner.Lowercase]);
  953. END NewStringConstantCamelCase;
  954. PROCEDURE NewBuiltin0( id: LONGINT; CONST name: ARRAY OF CHAR; in: SyntaxTree.ModuleScope; realtime: BOOLEAN);
  955. VAR basic: SyntaxTree.Builtin; duplicate: BOOLEAN; type: SyntaxTree.ProcedureType;
  956. BEGIN
  957. basic := SyntaxTree.NewBuiltin(-1,SyntaxTree.NewIdentifier(name),id);
  958. basic.SetAccess(SyntaxTree.ReadOnly);
  959. type := SyntaxTree.NewProcedureType(-1,in);
  960. type.SetRealtime(realtime);
  961. type.SetReturnType(SyntaxTree.invalidType); (* make incompatible to any procedure *)
  962. basic.SetType(type);
  963. basic.SetState(SyntaxTree.Resolved);
  964. in.EnterSymbol(basic,duplicate);
  965. in.AddBuiltin(basic);
  966. ASSERT(~duplicate);
  967. END NewBuiltin0;
  968. PROCEDURE NewBuiltin*(id: LONGINT; CONST name: ARRAY OF CHAR; CONST scope: ARRAY OF SyntaxTree.ModuleScope; realtime: BOOLEAN);
  969. VAR nameL,nameU: Scanner.IdentifierString;
  970. BEGIN
  971. Basic.Lowercase(name,nameL);
  972. Basic.Uppercase(name,nameU);
  973. NewBuiltin0(id,nameU,scope[Scanner.Uppercase],realtime);
  974. NewBuiltin0(id,nameL,scope[Scanner.Lowercase],realtime);
  975. END NewBuiltin;
  976. PROCEDURE NewBuiltinCamelCase*(id: LONGINT; CONST name: ARRAY OF CHAR; CONST scope: ARRAY OF SyntaxTree.ModuleScope; realtime: BOOLEAN);
  977. BEGIN
  978. NewBuiltin0(id,name,scope[Scanner.Uppercase],realtime);
  979. NewBuiltin0(id,name,scope[Scanner.Lowercase],realtime);
  980. END NewBuiltinCamelCase;
  981. PROCEDURE NewCustomBuiltin0(CONST name: ARRAY OF CHAR; scope: SyntaxTree.ModuleScope; subType: SHORTINT; procedureType: SyntaxTree.ProcedureType);
  982. VAR
  983. isDuplicate: BOOLEAN;
  984. customBuiltin: SyntaxTree.CustomBuiltin;
  985. BEGIN
  986. customBuiltin := SyntaxTree.NewCustomBuiltin(-1, SyntaxTree.NewIdentifier(name), systemSpecial, subType);
  987. customBuiltin.SetAccess(SyntaxTree.ReadOnly); (* TODO: this might be changed *)
  988. procedureType.SetRealtime(TRUE);
  989. customBuiltin.SetType(procedureType); (* TODO: make incompatible to any procedure *)
  990. customBuiltin.SetState(SyntaxTree.Resolved);
  991. scope.EnterSymbol(customBuiltin, isDuplicate);
  992. scope.AddBuiltin(customBuiltin);
  993. ASSERT(~isDuplicate)
  994. END NewCustomBuiltin0;
  995. PROCEDURE NewCustomBuiltin*(CONST name: ARRAY OF CHAR; CONST scope: ARRAY OF SyntaxTree.ModuleScope; subType: SHORTINT; procedureType: SyntaxTree.ProcedureType);
  996. VAR
  997. nameL, nameU: Scanner.IdentifierString;
  998. BEGIN
  999. Basic.Lowercase(name, nameL);
  1000. Basic.Uppercase(name, nameU);
  1001. NewCustomBuiltin0(nameU, scope[Scanner.Uppercase], subType, procedureType);
  1002. NewCustomBuiltin0(nameL, scope[Scanner.Lowercase], subType, procedureType)
  1003. END NewCustomBuiltin;
  1004. PROCEDURE ModuleFileName*(moduleName,context: SyntaxTree.Identifier; VAR fileName: ARRAY OF CHAR);
  1005. VAR prefix,name: Scanner.IdentifierString;
  1006. BEGIN
  1007. Basic.GetString(moduleName,name);
  1008. IF (context = SyntaxTree.invalidIdentifier) OR (context = A2Name) THEN
  1009. COPY(name,fileName);
  1010. ELSE
  1011. ASSERT(context=OberonName);
  1012. Basic.GetString(context,prefix);
  1013. Basic.Concat(fileName,prefix,".",name);
  1014. END;
  1015. END ModuleFileName;
  1016. PROCEDURE ContextFromName*(CONST fileName: ARRAY OF CHAR; VAR module,context: SyntaxTree.Identifier);
  1017. VAR moduleName, contextName: Scanner.IdentifierString; i,j: LONGINT;
  1018. BEGIN
  1019. i := 0; j := 0;
  1020. WHILE (fileName[i] # 0X) & (fileName[i] # ".") DO
  1021. moduleName[i] := fileName[i];
  1022. INC(i);
  1023. END;
  1024. moduleName[i] := 0X;
  1025. IF fileName[i] # 0X THEN
  1026. COPY(moduleName, contextName);
  1027. INC(i);
  1028. WHILE(fileName[i] # 0X) DO
  1029. moduleName[j] := fileName[i];
  1030. INC(i); INC(j);
  1031. END;
  1032. moduleName[j] := 0X;
  1033. ELSE
  1034. contextName := "A2";
  1035. END;
  1036. module := SyntaxTree.NewIdentifier(moduleName);
  1037. context := SyntaxTree.NewIdentifier(contextName);
  1038. END ContextFromName;
  1039. PROCEDURE GetModuleName*(module: SyntaxTree.Module; VAR name: ARRAY OF CHAR);
  1040. VAR n: SyntaxTree.IdentifierString;
  1041. BEGIN
  1042. name := "";
  1043. IF module.context # SyntaxTree.invalidIdentifier THEN
  1044. Basic.GetString(module.context,n);
  1045. IF n# "A2" THEN Strings.Append(name,n);Strings.Append(name,".") END;
  1046. END;
  1047. module.GetName(n);
  1048. Strings.Append(name,n);
  1049. END GetModuleName;
  1050. PROCEDURE GetModuleSegmentedName*(module: SyntaxTree.Module; VAR name: Basic.SegmentedName);
  1051. BEGIN
  1052. Basic.InitSegmentedName(name);
  1053. IF (module.context # SyntaxTree.invalidIdentifier) & (module.context # A2Name) THEN
  1054. name[0] := module.context;
  1055. name[1] := module.name;
  1056. name[2] := -1;
  1057. ELSE
  1058. name[0] :=module.name;
  1059. name[1] := -1;
  1060. END;
  1061. END GetModuleSegmentedName;
  1062. PROCEDURE FindSymbol*(CONST name: Basic.SegmentedName; scope: SyntaxTree.Scope): SyntaxTree.Symbol;
  1063. VAR s: LONGINT; symbol : SyntaxTree.Symbol;
  1064. PROCEDURE GetSymbolScope;
  1065. VAR type: SyntaxTree.Type;
  1066. BEGIN
  1067. IF symbol IS SyntaxTree.Module THEN
  1068. scope := symbol(SyntaxTree.Module).moduleScope
  1069. ELSIF symbol IS SyntaxTree.Import THEN
  1070. scope := symbol(SyntaxTree.Import).module.moduleScope;
  1071. ELSIF symbol IS SyntaxTree.Procedure THEN
  1072. scope := symbol(SyntaxTree.Procedure).procedureScope
  1073. ELSIF symbol IS SyntaxTree.TypeDeclaration THEN
  1074. type := symbol(SyntaxTree.TypeDeclaration).declaredType.resolved;
  1075. IF type IS SyntaxTree.RecordType THEN
  1076. scope := type(SyntaxTree.RecordType).recordScope
  1077. END;
  1078. ELSE
  1079. scope := NIL
  1080. END
  1081. END GetSymbolScope;
  1082. PROCEDURE FindSymbol(name: SyntaxTree.Identifier): SyntaxTree.Symbol;
  1083. VAR symbols: SyntaxTree.Symbol;
  1084. BEGIN
  1085. IF scope = scope.ownerModule.moduleScope THEN
  1086. symbol := scope.ownerModule.moduleScope.ImportByModuleName(name, scope.ownerModule.context);
  1087. IF symbol = NIL THEN
  1088. symbol := scope.FindSymbol(name)
  1089. END;
  1090. ELSE
  1091. symbol := scope.FindSymbol(name)
  1092. END;
  1093. RETURN symbol
  1094. END FindSymbol;
  1095. BEGIN
  1096. s := 0;
  1097. IF name[0] = scope.ownerModule.name THEN
  1098. INC(s)
  1099. END;
  1100. scope := scope.ownerModule.moduleScope; (* expect fully qualified (segmented) name *)
  1101. REPEAT
  1102. IF scope = NIL THEN RETURN NIL END;
  1103. symbol := FindSymbol(name[s]);
  1104. IF symbol = NIL THEN RETURN NIL
  1105. ELSE
  1106. GetSymbolScope
  1107. END;
  1108. INC(s);
  1109. UNTIL (s = LEN(name)) OR (name[s] < 0);
  1110. RETURN symbol;
  1111. END FindSymbol;
  1112. PROCEDURE GetSymbolNameInScope*(symbol: SyntaxTree.Symbol; inScope: SyntaxTree.Scope; VAR name: ARRAY OF CHAR);
  1113. VAR n: SyntaxTree.IdentifierString; td: SyntaxTree.TypeDeclaration;
  1114. PROCEDURE Scope(scope: SyntaxTree.Scope);
  1115. BEGIN
  1116. IF scope = NIL THEN (* do nothing, locally declared temporary symbol *)
  1117. ELSIF scope = inScope THEN (* do not traverse further *)
  1118. ELSIF scope IS SyntaxTree.ModuleScope THEN
  1119. GetModuleName(scope.ownerModule, name);
  1120. Strings.Append(name,".");
  1121. ELSIF scope IS SyntaxTree.RecordScope THEN
  1122. Scope(scope.outerScope);
  1123. td := scope(SyntaxTree.RecordScope).ownerRecord.typeDeclaration;
  1124. IF td = NIL THEN
  1125. td := scope(SyntaxTree.RecordScope).ownerRecord.pointerType.typeDeclaration;
  1126. END;
  1127. td.GetName(n);
  1128. Strings.Append(name,n); Strings.Append(name,".")
  1129. ELSIF scope IS SyntaxTree.ProcedureScope THEN
  1130. Scope(scope.outerScope);
  1131. scope(SyntaxTree.ProcedureScope).ownerProcedure.GetName(n);
  1132. Strings.Append(name,n); Strings.Append(name,".")
  1133. ELSIF scope IS SyntaxTree.CellScope THEN
  1134. Scope(scope.outerScope);
  1135. td := scope(SyntaxTree.CellScope).ownerCell.typeDeclaration;
  1136. td.GetName(n);
  1137. Strings.Append(name,n); Strings.Append(name,".")
  1138. END;
  1139. END Scope;
  1140. BEGIN
  1141. name := "";
  1142. Scope(symbol.scope);
  1143. symbol.GetName(n);
  1144. IF symbol IS SyntaxTree.Operator THEN (*! append some more bits to make discrimintation possible *)
  1145. END;
  1146. Strings.Append(name,n);
  1147. END GetSymbolNameInScope;
  1148. PROCEDURE GetSymbolName*(symbol: SyntaxTree.Symbol; VAR name: ARRAY OF CHAR);
  1149. BEGIN GetSymbolNameInScope(symbol,NIL,name)
  1150. END GetSymbolName;
  1151. PROCEDURE GetSymbolSegmentedNameInScope*(symbol: SyntaxTree.Symbol; inScope: SyntaxTree.Scope; VAR pooledName: Basic.SegmentedName);
  1152. VAR n: SyntaxTree.String; td: SyntaxTree.TypeDeclaration; i: LONGINT;
  1153. PROCEDURE Scope(scope: SyntaxTree.Scope);
  1154. BEGIN
  1155. IF scope = NIL THEN (* do nothing, locally declared temporary symbol *)
  1156. ELSIF scope = inScope THEN (* do not traverse further *)
  1157. ELSIF scope IS SyntaxTree.ModuleScope THEN
  1158. IF scope(SyntaxTree.ModuleScope).ownerModule.context # A2Name THEN
  1159. Basic.SuffixSegmentedName(pooledName, scope(SyntaxTree.ModuleScope).ownerModule.context);
  1160. END;
  1161. Basic.SuffixSegmentedName(pooledName,scope.ownerModule.name);
  1162. ELSIF scope IS SyntaxTree.RecordScope THEN
  1163. Scope(scope.outerScope);
  1164. td := scope(SyntaxTree.RecordScope).ownerRecord.typeDeclaration;
  1165. IF td = NIL THEN
  1166. td := scope(SyntaxTree.RecordScope).ownerRecord.pointerType.typeDeclaration;
  1167. END;
  1168. Basic.SuffixSegmentedName(pooledName,td.name);
  1169. ELSIF scope IS SyntaxTree.ProcedureScope THEN
  1170. Scope(scope.outerScope);
  1171. Basic.SuffixSegmentedName(pooledName,scope(SyntaxTree.ProcedureScope).ownerProcedure.name);
  1172. ELSIF scope IS SyntaxTree.CellScope THEN
  1173. Scope(scope.outerScope);
  1174. td := scope(SyntaxTree.CellScope).ownerCell.typeDeclaration;
  1175. Basic.SuffixSegmentedName(pooledName, td.name);
  1176. END;
  1177. END Scope;
  1178. BEGIN
  1179. FOR i := 0 TO LEN(pooledName)-1 DO pooledName[i] := -1 END;
  1180. Scope(symbol.scope);
  1181. Basic.SuffixSegmentedName(pooledName, symbol.name);
  1182. END GetSymbolSegmentedNameInScope;
  1183. PROCEDURE GetSymbolSegmentedName*(symbol: SyntaxTree.Symbol; VAR pooledName: Basic.SegmentedName);
  1184. BEGIN
  1185. GetSymbolSegmentedNameInScope(symbol,NIL,pooledName);
  1186. END GetSymbolSegmentedName;
  1187. PROCEDURE Level*(t: SyntaxTree.Type): LONGINT;
  1188. VAR level: LONGINT;
  1189. BEGIN
  1190. IF t IS SyntaxTree.IntegerType THEN
  1191. CASE t.sizeInBits OF
  1192. 8: level := 0;
  1193. |16: level := 1;
  1194. |32: level := 2;
  1195. |64: level := 3;
  1196. END;
  1197. ELSIF t IS SyntaxTree.FloatType THEN
  1198. CASE t.sizeInBits OF
  1199. 32: level := 4;
  1200. |64: level := 5;
  1201. END
  1202. ELSE HALT(100)
  1203. END;
  1204. RETURN level
  1205. END Level;
  1206. PROCEDURE ConvertSigned*(this: HUGEINT; bits: LONGINT): HUGEINT;
  1207. BEGIN
  1208. bits := 64-bits;
  1209. RETURN ASH (ASH (this, bits), -bits);
  1210. END ConvertSigned;
  1211. PROCEDURE ConvertUnsigned*(this: HUGEINT; bits: LONGINT): HUGEINT;
  1212. BEGIN
  1213. bits := 64-bits;
  1214. RETURN LSH (LSH (this, bits), -bits);
  1215. END ConvertUnsigned;
  1216. PROCEDURE MaxInteger*(system: System; type: SyntaxTree.BasicType): HUGEINT;
  1217. BEGIN
  1218. RETURN ASH (HUGEINT(1), system.SizeOf (type) - 1) - 1;
  1219. END MaxInteger;
  1220. PROCEDURE MinInteger*(system: System; type: SyntaxTree.BasicType): HUGEINT;
  1221. BEGIN
  1222. RETURN -ASH (HUGEINT(1), system.SizeOf (type) - 1);
  1223. END MinInteger;
  1224. (*! make architecture independent ! *)
  1225. PROCEDURE MaxFloat*(system: System; type: SyntaxTree.FloatType): LONGREAL;
  1226. BEGIN
  1227. IF system.SizeOf(type) = 32 THEN RETURN MAX(REAL) ELSE RETURN MAX(LONGREAL) END;
  1228. END MaxFloat;
  1229. PROCEDURE MinFloat*(system: System; type: SyntaxTree.FloatType): LONGREAL;
  1230. BEGIN
  1231. IF system.SizeOf(type) = 32 THEN RETURN MIN(REAL) ELSE RETURN MIN(LONGREAL) END;
  1232. END MinFloat;
  1233. PROCEDURE IsUnsignedInteger*(this: HUGEINT; sizeInBits: LONGINT): BOOLEAN;
  1234. VAR m: HUGEINT;
  1235. BEGIN
  1236. m := ASH(HUGEINT(1),sizeInBits);
  1237. RETURN (this >= 0) & (this < m)
  1238. END IsUnsignedInteger;
  1239. PROCEDURE IsSignedInteger*(this: HUGEINT; sizeInBits: LONGINT): BOOLEAN;
  1240. VAR m: HUGEINT;
  1241. BEGIN
  1242. m := ASH(HUGEINT(1),sizeInBits-1);
  1243. RETURN (this < m) & (-this <= m)
  1244. END IsSignedInteger;
  1245. PROCEDURE GetSignedIntegerType*(system: System; this: HUGEINT): SyntaxTree.IntegerType;
  1246. (* code snippets for unsigned
  1247. ELSE
  1248. m := Runtime.AslH(1,system.SizeOf(type));
  1249. RETURN (this >= 0) & (this < m)
  1250. END;
  1251. PROCEDURE Bits(x: HUGEINT): BOOLEAN;
  1252. BEGIN
  1253. WHILE x > 0 DO INC(bits); x := x DIV 2 END;
  1254. END Bits;
  1255. IF a = MIN(HUGEINT) THEN (* -a does not work on lowest possible number, ~a+1 would overflow *)
  1256. RETURN Integer[64]
  1257. ELSIF a < 0 THEN
  1258. RETURN Integer[Bits(-a-1)+1]
  1259. ELSE
  1260. RETURN Unisgned[Bits(a)]
  1261. END;
  1262. *)
  1263. BEGIN
  1264. IF IsSignedInteger(this,8) THEN RETURN Integer8
  1265. ELSIF IsSignedInteger(this, 16) THEN RETURN Integer16
  1266. ELSIF IsSignedInteger(this, 32) THEN RETURN Integer32
  1267. ELSE RETURN Integer64
  1268. END;
  1269. END GetSignedIntegerType;
  1270. PROCEDURE GetIntegerType*(system: System; this: HUGEINT): SyntaxTree.IntegerType;
  1271. BEGIN
  1272. IF IsSignedInteger(this,8) THEN RETURN Integer8
  1273. (* system.SizeOf(...) = 8 : detect special backends with no sizes smaller than 32 *)
  1274. ELSIF (system.SizeOf(Unsigned8) = 8) & IsUnsignedInteger(this,8) THEN RETURN Unsigned8
  1275. ELSIF IsSignedInteger(this, 16) THEN RETURN Integer16
  1276. ELSIF (system.SizeOf(Unsigned16) = 16) & IsUnsignedInteger(this,16) THEN RETURN Unsigned16
  1277. ELSIF IsSignedInteger(this, 32) THEN RETURN Integer32
  1278. ELSIF IsUnsignedInteger(this,32) THEN RETURN Unsigned32
  1279. ELSE RETURN Integer64
  1280. END;
  1281. END GetIntegerType;
  1282. PROCEDURE NewIntegerValue*(system: System; position: LONGINT; hugeint: HUGEINT): SyntaxTree.Value;
  1283. VAR value: SyntaxTree.IntegerValue;
  1284. BEGIN
  1285. value := SyntaxTree.NewIntegerValue(position,hugeint);
  1286. value.SetType(GetIntegerType(system,hugeint));
  1287. RETURN value
  1288. END NewIntegerValue;
  1289. PROCEDURE NewBooleanValue*(system: System; position: LONGINT; b: BOOLEAN): SyntaxTree.Value;
  1290. VAR value: SyntaxTree.BooleanValue;
  1291. BEGIN
  1292. value := SyntaxTree.NewBooleanValue(position,b);
  1293. value.SetType(system.booleanType);
  1294. RETURN value
  1295. END NewBooleanValue;
  1296. PROCEDURE NewSetValue*(system: System; position: LONGINT; s: SET): SyntaxTree.Value;
  1297. VAR value: SyntaxTree.SetValue;
  1298. BEGIN
  1299. value := SyntaxTree.NewSetValue(position,s);
  1300. value.SetType(system.setType);
  1301. RETURN value
  1302. END NewSetValue;
  1303. PROCEDURE NewCharacterValue*(system: System; position: LONGINT; c: CHAR): SyntaxTree.Value;
  1304. VAR value: SyntaxTree.CharacterValue;
  1305. BEGIN
  1306. value := SyntaxTree.NewCharacterValue(position,c);
  1307. value.SetType(system.characterType);
  1308. RETURN value
  1309. END NewCharacterValue;
  1310. PROCEDURE NewNilValue*(system: System; position: LONGINT): SyntaxTree.Value;
  1311. VAR value: SyntaxTree.NilValue;
  1312. BEGIN
  1313. value := SyntaxTree.NewNilValue(position);
  1314. value.SetType(system.anyType);
  1315. RETURN value
  1316. END NewNilValue;
  1317. (* distance for assignment to <- from *)
  1318. PROCEDURE BasicTypeDistance*(system: System; from, to: SyntaxTree.BasicType): LONGINT;
  1319. VAR fromSize, toSize, distance: LONGINT;
  1320. BEGIN
  1321. fromSize := system.SizeOf(from); toSize := system.SizeOf(to);
  1322. distance := -1;
  1323. IF (from IS SyntaxTree.IntegerType) & (to IS SyntaxTree.IntegerType) & (toSize >= fromSize) THEN
  1324. IF from(SyntaxTree.IntegerType).signed # to(SyntaxTree.IntegerType).signed THEN
  1325. IF (toSize=fromSize) & to(SyntaxTree.IntegerType).signed THEN
  1326. distance := MIN(LONGINT)
  1327. ELSE
  1328. INC(distance,2);
  1329. END;
  1330. END;
  1331. WHILE toSize >= fromSize DO
  1332. toSize := toSize DIV 2; INC(distance);
  1333. END;
  1334. ELSIF (from IS SyntaxTree.CharacterType) & (to IS SyntaxTree.CharacterType) & (toSize >= fromSize) OR
  1335. (from IS SyntaxTree.FloatType) & (to IS SyntaxTree.FloatType) & (toSize >= fromSize)
  1336. THEN
  1337. WHILE toSize >= fromSize DO
  1338. toSize := toSize DIV 2; INC(distance);
  1339. END;
  1340. ELSIF (from IS SyntaxTree.IntegerType) & (to IS SyntaxTree.FloatType) THEN
  1341. IF toSize = 64 THEN distance := 1 ELSE distance := 0 END;
  1342. toSize := 64;
  1343. WHILE toSize >= fromSize DO
  1344. toSize := toSize DIV 2; INC(distance);
  1345. END;
  1346. ELSIF (from IS SyntaxTree.RangeType) & (to IS SyntaxTree.RangeType) THEN
  1347. distance := 0;
  1348. ELSIF (from IS SyntaxTree.BooleanType) & (to IS SyntaxTree.BooleanType) THEN
  1349. distance := 0;
  1350. END;
  1351. IF distance < 0 THEN distance := MAX(LONGINT) END;
  1352. RETURN distance
  1353. END BasicTypeDistance;
  1354. PROCEDURE GetIdentifier*(symbol: LONGINT; case: LONGINT): SyntaxTree.Identifier;
  1355. BEGIN
  1356. IF (symbol >= 0) & (symbol < LEN(identifiers,1)) THEN
  1357. RETURN identifiers[case,symbol]
  1358. ELSE
  1359. RETURN SyntaxTree.invalidIdentifier
  1360. END;
  1361. END GetIdentifier;
  1362. PROCEDURE GetSymbol*(case: LONGINT; id: SyntaxTree.Identifier): LONGINT;
  1363. VAR i: LONGINT;
  1364. BEGIN
  1365. (*! quick and dirty implementation, optimize ! *)
  1366. FOR i := 0 TO LEN(identifiers,1)-1 DO
  1367. IF id=identifiers[case,i] THEN RETURN i END;
  1368. END;
  1369. RETURN -1
  1370. END GetSymbol;
  1371. PROCEDURE InitIdentifiers;
  1372. VAR i: LONGINT;
  1373. PROCEDURE NewKeywordIdentifier(op: LONGINT);
  1374. VAR id: Scanner.IdentifierType;
  1375. BEGIN
  1376. Scanner.GetKeyword(Scanner.Uppercase,op,id);
  1377. identifiers[Scanner.Uppercase,op] := id;
  1378. Scanner.GetKeyword(Scanner.Lowercase,op,id);
  1379. identifiers[Scanner.Lowercase,op] := id;
  1380. END NewKeywordIdentifier;
  1381. PROCEDURE NewBuiltinIdentifier(op: LONGINT; CONST name: ARRAY OF CHAR);
  1382. VAR nameL,nameU: Scanner.IdentifierString;
  1383. BEGIN
  1384. ASSERT(op < LEN(identifiers[0]));
  1385. Basic.Lowercase(name,nameL);
  1386. Basic.Uppercase(name,nameU);
  1387. identifiers[Scanner.Lowercase,op] := SyntaxTree.NewIdentifier(nameL);
  1388. identifiers[Scanner.Uppercase,op] := SyntaxTree.NewIdentifier(nameU);
  1389. END NewBuiltinIdentifier;
  1390. BEGIN
  1391. FOR i := 0 TO LEN(identifiers,1)-1 DO
  1392. identifiers[Scanner.Uppercase,i] := SyntaxTree.invalidIdentifier; identifiers[Scanner.Lowercase,i] := SyntaxTree.invalidIdentifier;
  1393. END;
  1394. FOR i := 0 TO Scanner.EndOfText-1 DO
  1395. NewKeywordIdentifier(i);
  1396. END;
  1397. NewBuiltinIdentifier(Abs,"ABS");
  1398. NewBuiltinIdentifier(Ash,"ASH");
  1399. NewBuiltinIdentifier(Asr,"ASR");
  1400. NewBuiltinIdentifier(Cap,"CAP");
  1401. NewBuiltinIdentifier(Chr,"CHR");
  1402. NewBuiltinIdentifier(Chr32,"CHR32");
  1403. NewBuiltinIdentifier(Entier,"ENTIER");
  1404. NewBuiltinIdentifier(EntierH,"ENTIERH");
  1405. NewBuiltinIdentifier(Len,"LEN");
  1406. NewBuiltinIdentifier(Long,"LONG");
  1407. NewBuiltinIdentifier(Lsh,"LSH");
  1408. NewBuiltinIdentifier(Max,"MAX");
  1409. NewBuiltinIdentifier(Min,"MIN");
  1410. NewBuiltinIdentifier(Odd,"ODD");
  1411. NewBuiltinIdentifier(Ord,"ORD");
  1412. NewBuiltinIdentifier(Ord32,"ORD32");
  1413. NewBuiltinIdentifier(Ror,"ROR");
  1414. NewBuiltinIdentifier(Rot,"ROT");
  1415. NewBuiltinIdentifier(Short,"SHORT");
  1416. NewBuiltinIdentifier(Sum,"SUM");
  1417. NewBuiltinIdentifier(Dim,"DIM");
  1418. NewBuiltinIdentifier(Cas,"CAS");
  1419. NewBuiltinIdentifier(Dec,"DEC");
  1420. NewBuiltinIdentifier(Excl,"EXCL");
  1421. NewBuiltinIdentifier(Inc,"INC");
  1422. NewBuiltinIdentifier(Incl,"INCL");
  1423. NewBuiltinIdentifier(All,"ALL");
  1424. (* TODO: check if ok. The operators defined in FoxArrayBase require the following identifiers *)
  1425. (* TODO: ".*+" should preferably be added as a new token in the scanner *)
  1426. identifiers[Scanner.Lowercase, Scanner.Becomes] := SyntaxTree.NewIdentifier(":=");
  1427. identifiers[Scanner.Uppercase, Scanner.Becomes] := SyntaxTree.NewIdentifier(":=");
  1428. identifiers[Scanner.Lowercase, Scanner.Transpose] := SyntaxTree.NewIdentifier("`");
  1429. identifiers[Scanner.Uppercase, Scanner.Transpose] := SyntaxTree.NewIdentifier("`");
  1430. identifiers[Scanner.Lowercase, DotTimesPlus] := SyntaxTree.NewIdentifier(".*+");
  1431. identifiers[Scanner.Uppercase, DotTimesPlus] := SyntaxTree.NewIdentifier(".*+");
  1432. identifiers[Scanner.Lowercase, AtMulDec] := SyntaxTree.NewIdentifier("@MulDec");
  1433. identifiers[Scanner.Uppercase, AtMulDec] := SyntaxTree.NewIdentifier("@MulDec");
  1434. identifiers[Scanner.Lowercase, AtMulInc] := SyntaxTree.NewIdentifier("@MulInc");
  1435. identifiers[Scanner.Uppercase, AtMulInc] := SyntaxTree.NewIdentifier("@MulInc");
  1436. identifiers[Scanner.Lowercase, DecMul] := SyntaxTree.NewIdentifier("DecMul");
  1437. identifiers[Scanner.Uppercase, DecMul] := SyntaxTree.NewIdentifier("DecMul");
  1438. identifiers[Scanner.Lowercase, IncMul] := SyntaxTree.NewIdentifier("IncMul");
  1439. identifiers[Scanner.Uppercase, IncMul] := SyntaxTree.NewIdentifier("IncMul");
  1440. identifiers[Scanner.Lowercase,Conversion] := SyntaxTree.NewIdentifier("@Convert");
  1441. identifiers[Scanner.Uppercase,Conversion] := SyntaxTree.NewIdentifier("@Convert");
  1442. END InitIdentifiers;
  1443. (** initialize the global namespace *)
  1444. PROCEDURE Init;
  1445. BEGIN
  1446. InitIdentifiers;
  1447. (* names are not arbitrary, do not change unless you know what you do (compatibilty with paco!) *)
  1448. SystemName := SyntaxTree.NewIdentifier("SYSTEM");
  1449. systemName := SyntaxTree.NewIdentifier("system");
  1450. SelfParameterName := SyntaxTree.NewIdentifier("@Self");
  1451. ReturnParameterName := SyntaxTree.NewIdentifier("@ReturnParameter");
  1452. PointerReturnName := SyntaxTree.NewIdentifier("@PtrReturnType");
  1453. ResultName := SyntaxTree.NewIdentifier("RESULT");
  1454. A2Name := SyntaxTree.NewIdentifier("A2");
  1455. OberonName := SyntaxTree.NewIdentifier("Oberon");
  1456. ArrayBaseName := SyntaxTree.NewIdentifier("FoxArrayBase");
  1457. RecordBodyName := SyntaxTree.NewIdentifier("@Body");
  1458. ModuleBodyName := SyntaxTree.NewIdentifier("@Body");
  1459. NameWinAPI := SyntaxTree.NewIdentifier(StringWinAPI);
  1460. NameC := SyntaxTree.NewIdentifier(StringC);
  1461. NameMovable := SyntaxTree.NewIdentifier(StringMovable);
  1462. NameUntraced := SyntaxTree.NewIdentifier(StringUntraced);
  1463. NameDelegate := SyntaxTree.NewIdentifier(StringDelegate);
  1464. NameInterrupt := SyntaxTree.NewIdentifier(StringInterrupt);
  1465. NamePcOffset := SyntaxTree.NewIdentifier(StringPcOffset);
  1466. NameNoPAF := SyntaxTree.NewIdentifier(StringNoPAF);
  1467. NameEntry := SyntaxTree.NewIdentifier(StringEntry);
  1468. NameExit := SyntaxTree.NewIdentifier(StringExit);
  1469. NameFixed := SyntaxTree.NewIdentifier(StringFixed);
  1470. NameFictive := SyntaxTree.NewIdentifier(StringFictive);
  1471. NameAligned := SyntaxTree.NewIdentifier(StringAligned);
  1472. NameStackAligned := SyntaxTree.NewIdentifier(StringAlignStack);
  1473. NameExclusive := SyntaxTree.NewIdentifier(StringExclusive);
  1474. NameActive := SyntaxTree.NewIdentifier(StringActive);
  1475. NamePriority := SyntaxTree.NewIdentifier(StringPriority);
  1476. NameSafe := SyntaxTree.NewIdentifier(StringSafe);
  1477. NameRealtime := SyntaxTree.NewIdentifier(StringRealtime);
  1478. NameDynamic := SyntaxTree.NewIdentifier(StringDynamic);
  1479. NameDataMemorySize := SyntaxTree.NewIdentifier(StringDataMemorySize);
  1480. NameCodeMemorySize := SyntaxTree.NewIdentifier(StringCodeMemorySize);
  1481. NameChannelWidth := SyntaxTree.NewIdentifier(StringChannelWidth);
  1482. NameChannelDepth := SyntaxTree.NewIdentifier(StringChannelDepth);
  1483. NameChannelModule := SyntaxTree.NewIdentifier(StringChannelModule);
  1484. NameVector := SyntaxTree.NewIdentifier(StringVector);
  1485. NameFloatingPoint := SyntaxTree.NewIdentifier(StringFloatingPoint);
  1486. NameNoMul:= SyntaxTree.NewIdentifier(StringNoMul);
  1487. NameNonBlockingIO:=SyntaxTree.NewIdentifier(StringNonBlockingIO);
  1488. NameTRM := SyntaxTree.NewIdentifier(StringTRM);
  1489. NameTRMS := SyntaxTree.NewIdentifier(StringTRMS);
  1490. NameEngine := SyntaxTree.NewIdentifier(StringEngine);
  1491. NameFinal := SyntaxTree.NewIdentifier(StringFinal);
  1492. NameAbstract := SyntaxTree.NewIdentifier(StringAbstract);
  1493. NameFrequencyDivider := SyntaxTree.NewIdentifier(StringFrequencyDivider);
  1494. NameRegister := SyntaxTree.NewIdentifier(StringRegister);
  1495. NameNoReturn := SyntaxTree.NewIdentifier(StringNoReturn);
  1496. NamePlain := SyntaxTree.NewIdentifier(StringPlain);
  1497. NameUnsafe := SyntaxTree.NewIdentifier(StringUnsafe);
  1498. NameDisposable := SyntaxTree.NewIdentifier(StringDisposable);
  1499. NameUnchecked := SyntaxTree.NewIdentifier(StringUnchecked);
  1500. NameUncooperative := SyntaxTree.NewIdentifier(StringUncooperative);
  1501. (* types *)
  1502. Boolean8 := SyntaxTree.NewBooleanType(8);
  1503. Boolean32 := SyntaxTree.NewBooleanType(32);
  1504. Integer8 := SyntaxTree.NewIntegerType(8, TRUE);
  1505. Integer16 := SyntaxTree.NewIntegerType(16, TRUE);
  1506. Integer32 := SyntaxTree.NewIntegerType(32, TRUE);
  1507. Integer64 := SyntaxTree.NewIntegerType(64, TRUE);
  1508. Unsigned8 := SyntaxTree.NewIntegerType(8, FALSE);
  1509. Unsigned16 := SyntaxTree.NewIntegerType(16, FALSE);
  1510. Unsigned32 := SyntaxTree.NewIntegerType(32, FALSE);
  1511. Unsigned64 := SyntaxTree.NewIntegerType(64, FALSE);
  1512. Float32 := SyntaxTree.NewFloatType(32);
  1513. Float64 := SyntaxTree.NewFloatType(64);
  1514. Complex64 := SyntaxTree.NewComplexType(Float32);
  1515. Complex128 := SyntaxTree.NewComplexType(Float64);
  1516. Byte8 := SyntaxTree.NewByteType(8);
  1517. Byte32 := SyntaxTree.NewByteType(32);
  1518. Character8 := SyntaxTree.NewCharacterType(8);
  1519. Character16 := SyntaxTree.NewCharacterType(16);
  1520. Character32 := SyntaxTree.NewCharacterType(32);
  1521. END Init;
  1522. BEGIN
  1523. Init;
  1524. END FoxGlobal.