2
0

FoxCSharpParser.Mod 144 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789
  1. MODULE FoxCSharpParser;
  2. (* module originating from Alexey Gokhberg's ActiveCells# Parser *)
  3. IMPORT Strings, StringPool, Diagnostics, D := Debugging, Basic := FoxBasic, FoxScanner,
  4. Scanner := FoxCSharpScanner, SyntaxTree := FoxSyntaxTree, Global := FoxGlobal,
  5. KernelLog (* DEBUG *);
  6. CONST
  7. Trace = FALSE;
  8. (* modifiers *)
  9. Public = 0;
  10. Internal = 1;
  11. LynxCase = FoxScanner.Lowercase;
  12. invalidPosition = -1;
  13. TYPE
  14. LocalIdentEntry = OBJECT
  15. VAR
  16. next: LocalIdentEntry;
  17. level: LONGINT;
  18. name: SyntaxTree.Identifier;
  19. local: SyntaxTree.Identifier;
  20. END LocalIdentEntry;
  21. LocalIdentTable = OBJECT
  22. VAR
  23. head: LocalIdentEntry;
  24. level: LONGINT;
  25. suffix: LONGINT;
  26. PROCEDURE & Init;
  27. BEGIN
  28. Reset;
  29. END Init;
  30. PROCEDURE Reset;
  31. BEGIN
  32. head := NIL;
  33. level := 0;
  34. suffix := 0;
  35. END Reset;
  36. PROCEDURE OpenScope;
  37. BEGIN
  38. INC(level);
  39. END OpenScope;
  40. PROCEDURE CloseScope;
  41. VAR p: LocalIdentEntry;
  42. BEGIN
  43. p := head;
  44. WHILE (p # NIL) & (p.level = level) DO
  45. p := p.next;
  46. END;
  47. head := p;
  48. DEC(level);
  49. END CloseScope;
  50. PROCEDURE Enter(name: SyntaxTree.Identifier): SyntaxTree.Identifier;
  51. VAR p, q: LocalIdentEntry;
  52. local: SyntaxTree.Identifier;
  53. str: Scanner.IdentifierString;
  54. BEGIN
  55. IF level = 0 THEN
  56. RETURN name;
  57. END;
  58. p := head;
  59. q := NIL;
  60. WHILE (q = NIL) & (p # NIL) & (p.level = level) DO
  61. IF p.name = name THEN
  62. q := p;
  63. END;
  64. p := p.next;
  65. END;
  66. IF q # NIL THEN
  67. RETURN q.local;
  68. END;
  69. Basic.GetString(name, str);
  70. Strings.AppendChar(str, "@");
  71. INC(suffix);
  72. Basic.AppendNumber(str, suffix);
  73. local := Basic.MakeString(str);
  74. NEW(q);
  75. q.level := level;
  76. q.name := name;
  77. q.local := local;
  78. q.next := head;
  79. head := q;
  80. RETURN local;
  81. END Enter;
  82. PROCEDURE Find(name: SyntaxTree.Identifier): SyntaxTree.Identifier;
  83. VAR p: LocalIdentEntry;
  84. BEGIN
  85. p := head;
  86. WHILE (p # NIL) & (p.name # name) DO
  87. p := p.next;
  88. END;
  89. IF p # NIL THEN
  90. RETURN p.local;
  91. END;
  92. RETURN name;
  93. END Find;
  94. END LocalIdentTable;
  95. Parser* = OBJECT
  96. VAR
  97. scanner: Scanner.Scanner;
  98. symbol-: Scanner.Symbol;
  99. diagnostics: Diagnostics.Diagnostics;
  100. currentScope: SyntaxTree.Scope;
  101. recentCommentItem: ANY;
  102. recentLine: LONGINT;
  103. recentComment: SyntaxTree.Comment;
  104. moduleScope: SyntaxTree.ModuleScope;
  105. error-: BOOLEAN;
  106. activeCellsSupport: BOOLEAN;
  107. initStatements: SyntaxTree.StatementSequence;
  108. initOuter: SyntaxTree.Statement;
  109. delegateModifiers: SyntaxTree.Modifier;
  110. lynxChar: SyntaxTree.Identifier;
  111. lynxSbyte: SyntaxTree.Identifier;
  112. lynxShort: SyntaxTree.Identifier;
  113. lynxInt: SyntaxTree.Identifier;
  114. lynxLong: SyntaxTree.Identifier;
  115. lynxFloat: SyntaxTree.Identifier;
  116. lynxDouble: SyntaxTree.Identifier;
  117. lynxBool: SyntaxTree.Identifier;
  118. lynxObject: SyntaxTree.Identifier;
  119. lynxString: SyntaxTree.Identifier;
  120. lynxNewobj: SyntaxTree.Identifier;
  121. lynxNewarr: SyntaxTree.Identifier;
  122. lynxAsop: SyntaxTree.Identifier;
  123. lynxUnop: SyntaxTree.Identifier;
  124. lynxBinop: SyntaxTree.Identifier;
  125. lynxSend: SyntaxTree.Identifier;
  126. lynxReceive: SyntaxTree.Identifier;
  127. lynxRecvnb: SyntaxTree.Identifier;
  128. lynxConnect: SyntaxTree.Identifier;
  129. lynxDelegate: SyntaxTree.Identifier;
  130. lynxNewsel: SyntaxTree.Identifier;
  131. lynxAddsel: SyntaxTree.Identifier;
  132. lynxSelect: SyntaxTree.Identifier;
  133. lynxSelidx: SyntaxTree.Identifier;
  134. lynxType: SyntaxTree.Identifier;
  135. identMain: SyntaxTree.Identifier;
  136. localIdentTable: LocalIdentTable;
  137. indent: LONGINT; (* for debugging purposes only *)
  138. (** constructor, init parser with scanner providing input and with diagnostics for error output *)
  139. PROCEDURE & Init*(scanner: Scanner.Scanner; diagnostics: Diagnostics.Diagnostics);
  140. BEGIN
  141. SELF.scanner := scanner;
  142. SELF.diagnostics := diagnostics;
  143. error := ~scanner.GetNextSymbol(symbol);
  144. recentCommentItem := NIL;
  145. recentComment := NIL;
  146. initStatements := NIL;
  147. initOuter := NIL;
  148. InitDelegateModifiers;
  149. InitSystemNames;
  150. StringPool.GetIndex("lynx@type", lynxType);
  151. StringPool.GetIndex("main", identMain);
  152. NEW(localIdentTable);
  153. (* debugging *)
  154. indent := 0;
  155. activeCellsSupport := FALSE;
  156. END Init;
  157. PROCEDURE InitDelegateModifiers;
  158. VAR name: SyntaxTree.Identifier;
  159. BEGIN
  160. StringPool.GetIndex("DELEGATE", name);
  161. delegateModifiers := SyntaxTree.NewModifier(invalidPosition, name, NIL);
  162. END InitDelegateModifiers;
  163. (*
  164. NOTE: Fox semantical analysis has been extended in order to recognize
  165. and properly support the following names of system procedures.
  166. Lynx version of FoxGlobal provides the respective bindings.
  167. *)
  168. PROCEDURE InitSystemNames;
  169. BEGIN
  170. StringPool.GetIndex(Global.LynxChar, lynxChar);
  171. StringPool.GetIndex(Global.LynxSbyte, lynxSbyte);
  172. StringPool.GetIndex(Global.LynxShort, lynxShort);
  173. StringPool.GetIndex(Global.LynxInt, lynxInt);
  174. StringPool.GetIndex(Global.LynxLong, lynxLong);
  175. StringPool.GetIndex(Global.LynxFloat, lynxFloat);
  176. StringPool.GetIndex(Global.LynxDouble, lynxDouble);
  177. StringPool.GetIndex(Global.LynxBool, lynxBool);
  178. StringPool.GetIndex(Global.LynxObject, lynxObject);
  179. StringPool.GetIndex(Global.LynxString, lynxString);
  180. StringPool.GetIndex(Global.LynxNewobj, lynxNewobj);
  181. StringPool.GetIndex(Global.LynxNewarr, lynxNewarr);
  182. StringPool.GetIndex(Global.LynxAsop, lynxAsop);
  183. StringPool.GetIndex(Global.LynxUnop, lynxUnop);
  184. StringPool.GetIndex(Global.LynxBinop, lynxBinop);
  185. StringPool.GetIndex(Global.LynxSend, lynxSend);
  186. StringPool.GetIndex(Global.LynxReceive, lynxReceive);
  187. StringPool.GetIndex(Global.LynxRecvnb, lynxRecvnb);
  188. StringPool.GetIndex(Global.LynxConnect, lynxConnect);
  189. StringPool.GetIndex(Global.LynxDelegate, lynxDelegate);
  190. StringPool.GetIndex(Global.LynxNewsel, lynxNewsel);
  191. StringPool.GetIndex(Global.LynxAddsel, lynxAddsel);
  192. StringPool.GetIndex(Global.LynxSelect, lynxSelect);
  193. StringPool.GetIndex(Global.LynxSelidx, lynxSelidx);
  194. END InitSystemNames;
  195. PROCEDURE ActiveCellsSupport*;
  196. BEGIN
  197. activeCellsSupport := TRUE
  198. END ActiveCellsSupport;
  199. PROCEDURE S(CONST s: ARRAY OF CHAR); (* for debugging purposes only *)
  200. VAR i: LONGINT;
  201. BEGIN
  202. D.Ln;
  203. INC(indent);
  204. D.Int(indent, 1);
  205. FOR i := 1 TO indent DO
  206. D.Str(" ");
  207. END;
  208. D.Str("start: ");
  209. D.Str(s);
  210. D.Str(" at pos ");
  211. D.Int(symbol.start, 1);
  212. END S;
  213. PROCEDURE E(CONST s: ARRAY OF CHAR); (* for debugging purposes only *)
  214. VAR i: LONGINT;
  215. BEGIN
  216. D.Ln;
  217. D.Int(indent, 1);
  218. FOR i := 1 TO indent DO
  219. D.Str(" ");
  220. END;
  221. D.Str("end : ");
  222. D.Str(s);
  223. D.Str(" at pos ");
  224. D.Int(symbol.start, 1);
  225. END E;
  226. PROCEDURE EE(CONST s, t: ARRAY OF CHAR); (* for debugging purposes only *)
  227. VAR i: LONGINT;
  228. BEGIN
  229. D.Ln;
  230. D.Int(indent, 1);
  231. FOR i := 1 TO indent DO
  232. D.Str(" ");
  233. END;
  234. D.Str("end : ");
  235. D.Str(s);
  236. D.Str(" (");
  237. D.Str(t);
  238. D.Str(") at pos ");
  239. END EE;
  240. (** output error message and / or given code *)
  241. PROCEDURE Error(position: LONGINT; code: LONGINT; CONST message: ARRAY OF CHAR);
  242. VAR errorMessage: ARRAY 256 OF CHAR;
  243. BEGIN
  244. IF diagnostics # NIL THEN
  245. Basic.GetErrorMessage(code,message,errorMessage);
  246. diagnostics.Error(scanner.source^, position, code, errorMessage);
  247. END;
  248. error := TRUE;
  249. (* @@@ *)
  250. HALT(100);
  251. END Error;
  252. (** helper procedures interfacing to the scanner **)
  253. (** Get next symbol from scanner and store it in object-local variable 'symbol' *)
  254. PROCEDURE NextSymbol;
  255. VAR comment: SyntaxTree.Comment;
  256. BEGIN
  257. error := ~scanner.GetNextSymbol(symbol) OR error;
  258. WHILE ~error & (symbol.token = Scanner.Comment) DO
  259. comment := SyntaxTree.NewComment(symbol.start, currentScope, symbol.string^, symbol.stringLength);
  260. moduleScope.AddComment(comment);
  261. IF recentComment = NIL THEN
  262. recentComment := comment;
  263. IF symbol.line = recentLine THEN
  264. IF recentCommentItem # NIL THEN
  265. IF (recentCommentItem IS SyntaxTree.Symbol) THEN
  266. IF recentCommentItem(SyntaxTree.Symbol).comment = NIL THEN
  267. recentCommentItem(SyntaxTree.Symbol).SetComment(comment)
  268. END;
  269. ELSIF (recentCommentItem IS SyntaxTree.Statement) THEN
  270. IF recentCommentItem(SyntaxTree.Statement).comment = NIL THEN
  271. recentCommentItem(SyntaxTree.Statement).SetComment(comment)
  272. END;
  273. ELSIF (recentCommentItem IS SyntaxTree.IfPart) THEN
  274. IF recentCommentItem(SyntaxTree.IfPart).comment = NIL THEN
  275. recentCommentItem(SyntaxTree.IfPart).SetComment(comment)
  276. END;
  277. ELSIF (recentCommentItem IS SyntaxTree.CasePart) THEN
  278. IF recentCommentItem(SyntaxTree.CasePart).comment = NIL THEN
  279. recentCommentItem(SyntaxTree.CasePart).SetComment(comment)
  280. END;
  281. (* LYNX+
  282. ELSIF (recentCommentItem IS SyntaxTree.WithPart) THEN
  283. IF recentCommentItem(SyntaxTree.WithPart).comment = NIL THEN
  284. recentCommentItem(SyntaxTree.WithPart).SetComment(comment)
  285. END;
  286. -LYNX *)
  287. END;
  288. comment.SetItem(recentCommentItem, TRUE);
  289. recentComment := NIL;
  290. recentCommentItem := NIL
  291. END;
  292. END;
  293. END;
  294. error := ~scanner.GetNextSymbol(symbol);
  295. END;
  296. END NextSymbol;
  297. (** Check if current symbol equals sym. If yes then return true, return false otherwise *)
  298. PROCEDURE Peek(token: Scanner.Token): BOOLEAN;
  299. VAR comment: SyntaxTree.Comment;
  300. BEGIN
  301. WHILE ~error & (symbol.token = Scanner.Comment) DO
  302. comment := SyntaxTree.NewComment(symbol.start, currentScope, symbol.string^, symbol.stringLength);
  303. moduleScope.AddComment(comment);
  304. IF recentComment = NIL THEN
  305. recentComment := comment;
  306. END;
  307. error := ~scanner.GetNextSymbol(symbol);
  308. END;
  309. RETURN symbol.token = token
  310. END Peek;
  311. (** Check if the current symbol equals sym. If yes then read next symbol, report error otherwise. Returns success value *)
  312. PROCEDURE Mandatory(token: Scanner.Token): BOOLEAN;
  313. BEGIN
  314. (* @@@ *)
  315. (*
  316. KernelLog.String("Mandatory: want ");
  317. KernelLog.Int(token, 1);
  318. KernelLog.String(" have ");
  319. KernelLog.Int(symbol.token, 1);
  320. KernelLog.Ln();
  321. *)
  322. (* because of NextSymbol! *)
  323. ASSERT(token # Scanner.Identifier);
  324. ASSERT(token # Scanner.IntegerLiteral);
  325. ASSERT(token # Scanner.RealLiteral);
  326. ASSERT(token # Scanner.CharacterLiteral);
  327. ASSERT(token # Scanner.StringLiteral);
  328. IF ~Peek(token) THEN
  329. Error(symbol.start, token, "");
  330. RETURN FALSE
  331. ELSE
  332. NextSymbol;
  333. RETURN TRUE
  334. END
  335. END Mandatory;
  336. (** Check if the current symbol equals sym. If yes then read next symbol, report error otherwise *)
  337. PROCEDURE Check(token: Scanner.Token);
  338. VAR b: BOOLEAN;
  339. BEGIN
  340. b := Mandatory(token);
  341. END Check;
  342. (** Check if current symbol is an identifier. If yes then copy identifier to name and get next symbol,
  343. report error otherwise and set name to empty name. Returns success value *)
  344. PROCEDURE MandatoryIdentifier(VAR name: SyntaxTree.Identifier): BOOLEAN;
  345. BEGIN
  346. IF Peek(Scanner.Identifier) THEN
  347. name := symbol.identifier;
  348. NextSymbol;
  349. RETURN TRUE
  350. ELSE
  351. Error(symbol.start, Scanner.Identifier, "");
  352. name := SyntaxTree.invalidIdentifier;
  353. RETURN FALSE
  354. END
  355. END MandatoryIdentifier;
  356. (** Expect an identifier (using MandatoryIdentifier) and return identifier object **)
  357. PROCEDURE Identifier(VAR position: LONGINT): SyntaxTree.Identifier;
  358. VAR name: SyntaxTree.Identifier;
  359. identifier: SyntaxTree.Identifier;
  360. BEGIN
  361. position := symbol.start;
  362. IF MandatoryIdentifier(name) THEN
  363. identifier := name;
  364. ELSE
  365. identifier := SyntaxTree.invalidIdentifier;
  366. END;
  367. RETURN identifier
  368. END Identifier;
  369. (** Check if current symbol equals sym. If yes then get next symbol, return false otherwise *)
  370. PROCEDURE Optional(token: Scanner.Token): BOOLEAN;
  371. BEGIN
  372. (* do not use for Identifier or literal if the result is needed ! *)
  373. IF Peek(token) THEN
  374. NextSymbol;
  375. RETURN TRUE
  376. ELSE
  377. RETURN FALSE
  378. END
  379. END Optional;
  380. (* ignore one ore more symbols of type token *)
  381. PROCEDURE Ignore(token: Scanner.Token);
  382. BEGIN
  383. WHILE Optional(token) DO
  384. (* void *)
  385. END;
  386. END Ignore;
  387. (** Handling comments **)
  388. PROCEDURE SetNextInComment(c: SyntaxTree.Comment; this: ANY);
  389. BEGIN
  390. WHILE c # NIL DO
  391. c.SetItem(this, FALSE);
  392. c := c.nextComment
  393. END;
  394. END SetNextInComment;
  395. PROCEDURE CommentSymbol(symbol: SyntaxTree.Symbol);
  396. BEGIN
  397. IF (recentComment # NIL) (* & (recentComment.nextSymbol = NIL) *) THEN
  398. symbol.SetComment(recentComment);
  399. SetNextInComment(recentComment, symbol);
  400. recentComment := NIL
  401. END;
  402. recentLine := scanner.line;
  403. recentCommentItem := symbol;
  404. END CommentSymbol;
  405. (** Mapping tokens to AST operators **)
  406. (*
  407. Mapping table for all punctuation tokens
  408. Lynx Fox
  409. ------------------------------------------------------------
  410. Exclamation* = 1; (* ! *) Not
  411. ExclamationEqual* = 2; (* != *) Unequal
  412. Percent* = 3; (* % *) lynx@binop (rem)
  413. PercentEqual* = 4; (* %= *) lynx@asop (rem)
  414. And* = 5; (* & *) lynx@binop (and)
  415. AndEqual* = 6; (* &= *) lynx@asop (and)
  416. AndAnd* = 7; (* && *) And
  417. LeftParenthesis* = 8; (* ( *) N/A
  418. RightParenthesis* = 9; (* ) *) N/A
  419. Times* = 10; (* * *) Times
  420. TimesEqual* = 11; (* *= *) lynx@asop (mul)
  421. Plus* = 12; (* + *) Plus
  422. PlusEqual* = 13; (* += *) lynx@asop (add)
  423. PlusPlus* = 14; (* ++ *) lynx@asop (add)
  424. Comma* = 15; (* , *) N/A
  425. Minus* = 16; (* - *) Minus
  426. MinusEqual* = 17; (* -= *) lynx@asop (sub)
  427. MinusMinus* = 18; (* -- *) lynx@asop (sub)
  428. Period* = 19; (* . *) N/A
  429. Slash* = 20; (* / *) lynx@binop (div)
  430. SlashEqual* = 21; (* /= *) lynx@asop (div)
  431. Colon* = 22; (* : *) N/A
  432. Semicolon* = 23; (* ; *) N/A
  433. Less* = 24; (* < *) Less
  434. LessEqual* = 25; (* <= *) LessEqual
  435. LeftShift* = 26; (* << *) lynx@binop (shl)
  436. LeftShiftEqual* = 27; (* <<= *) lynx@asop (shl)
  437. Equal* = 28; (* = *) N/A
  438. EqualEqual* = 29; (* == *) Equal
  439. Greater* = 30; (* > *) Greater
  440. GreaterEqual* = 31; (* >= *) GreaterEqual
  441. RightShift* = 32; (* >> *) lynx@binop (shr)
  442. RightShiftEqual* = 33; (* >>= *) lynx@asop (shr)
  443. LeftBracket* = 34; (* [ *) N/A
  444. RightBracket* = 35; (* ] *) N/A
  445. Arrow* = 36; (* ^ *) lynx@binop (xor)
  446. ArrowEqual* = 37; (* ^= *) lynx@asop (xor)
  447. LeftBrace* = 38; (* { *) N/A
  448. Bar* = 39; (* | *) lynx@binop (or)
  449. BarEqual* = 40; (* |= *) lynx@asop (or)
  450. BarBar* = 41; (* || *) Or
  451. RightBrace* = 42; (* } *) N/A
  452. Tilde* = 43; (* ~ *) lynx@unop (not)
  453. *)
  454. PROCEDURE MapOperator(token: Scanner.Token): LONGINT;
  455. VAR operator: LONGINT;
  456. BEGIN
  457. CASE token OF
  458. Scanner.Exclamation:
  459. operator := FoxScanner.Not;
  460. | Scanner.ExclamationEqual:
  461. operator := FoxScanner.Unequal;
  462. | Scanner.Percent, Scanner.PercentEqual:
  463. operator := 256 + Global.LynxOpRem;
  464. | Scanner.And, Scanner.AndEqual:
  465. operator := 256 + Global.LynxOpAnd;
  466. | Scanner.AndAnd:
  467. operator := FoxScanner.And;
  468. | Scanner.Times:
  469. operator := FoxScanner.Times;
  470. | Scanner.TimesEqual:
  471. operator := 256 + Global.LynxOpMul;
  472. | Scanner.Plus:
  473. operator := FoxScanner.Plus;
  474. | Scanner.PlusEqual, Scanner.PlusPlus:
  475. operator := 256 + Global.LynxOpAdd;
  476. | Scanner.Minus:
  477. operator := FoxScanner.Minus;
  478. | Scanner.MinusEqual, Scanner.MinusMinus:
  479. operator := 256 + Global.LynxOpSub;
  480. | Scanner.Slash, Scanner.SlashEqual:
  481. operator := 256 + Global.LynxOpDiv;
  482. | Scanner.Less:
  483. operator := FoxScanner.Less;
  484. | Scanner.LessEqual:
  485. operator := FoxScanner.LessEqual;
  486. | Scanner.LeftShift, Scanner.LeftShiftEqual:
  487. operator := 256 + Global.LynxOpShl;
  488. | Scanner.EqualEqual:
  489. operator := FoxScanner.Equal;
  490. | Scanner.Greater:
  491. operator := FoxScanner.Greater;
  492. | Scanner.GreaterEqual:
  493. operator := FoxScanner.GreaterEqual;
  494. | Scanner.RightShift, Scanner.RightShiftEqual:
  495. operator := 256 + Global.LynxOpShr;
  496. | Scanner.Arrow, Scanner.ArrowEqual:
  497. operator := 256 + Global.LynxOpXor;
  498. | Scanner.Bar, Scanner.BarEqual:
  499. operator := 256 + Global.LynxOpOr;
  500. | Scanner.BarBar:
  501. operator := FoxScanner.Or;
  502. | Scanner.Tilde:
  503. operator := 256 + Global.LynxOpNot;
  504. END;
  505. RETURN operator;
  506. END MapOperator;
  507. PROCEDURE NewUnaryExpression(
  508. position: LONGINT;
  509. operand: SyntaxTree.Expression;
  510. operator: LONGINT): SyntaxTree.Expression;
  511. VAR expressionList: SyntaxTree.ExpressionList;
  512. expression: SyntaxTree.Expression;
  513. designator: SyntaxTree.Designator;
  514. BEGIN
  515. operator := MapOperator(operator);
  516. IF operator < 256 THEN
  517. expression := SyntaxTree.NewUnaryExpression(position, operand, operator);
  518. ELSE
  519. expressionList := SyntaxTree.NewExpressionList();
  520. expression := SyntaxTree.NewIntegerValue(position, operator-256);
  521. expressionList.AddExpression(expression);
  522. expressionList.AddExpression(operand);
  523. designator := SyntaxTree.NewIdentifierDesignator(position, lynxUnop);
  524. expression := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  525. END;
  526. RETURN expression;
  527. END NewUnaryExpression;
  528. PROCEDURE NewBinaryExpression(
  529. position: LONGINT;
  530. left, right: SyntaxTree.Expression;
  531. operator: LONGINT): SyntaxTree.Expression;
  532. VAR expressionList: SyntaxTree.ExpressionList;
  533. expression: SyntaxTree.Expression;
  534. designator: SyntaxTree.Designator;
  535. BEGIN
  536. operator := MapOperator(operator);
  537. IF operator < 256 THEN
  538. expression := SyntaxTree.NewBinaryExpression(position, left, right, operator);
  539. ELSE
  540. expressionList := SyntaxTree.NewExpressionList();
  541. expression := SyntaxTree.NewIntegerValue(position, operator-256);
  542. expressionList.AddExpression(expression);
  543. expressionList.AddExpression(left);
  544. expressionList.AddExpression(right);
  545. designator := SyntaxTree.NewIdentifierDesignator(position, lynxBinop);
  546. expression := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  547. END;
  548. RETURN expression;
  549. END NewBinaryExpression;
  550. PROCEDURE NewTypeExpression(position: LONGINT): SyntaxTree.Expression;
  551. BEGIN
  552. RETURN SyntaxTree.NewIdentifierDesignator(position, lynxType);
  553. END NewTypeExpression;
  554. PROCEDURE NewReceiveExpression(
  555. position: LONGINT; left, right: SyntaxTree.Expression): SyntaxTree.Expression;
  556. VAR expressionList: SyntaxTree.ExpressionList;
  557. expression: SyntaxTree.Expression;
  558. designator: SyntaxTree.Designator;
  559. BEGIN
  560. expressionList := SyntaxTree.NewExpressionList();
  561. expressionList.AddExpression(left);
  562. expressionList.AddExpression(right);
  563. designator := SyntaxTree.NewIdentifierDesignator(position, lynxRecvnb);
  564. expression := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  565. RETURN expression;
  566. END NewReceiveExpression;
  567. PROCEDURE MapNumberType(numberType: LONGINT): LONGINT;
  568. BEGIN
  569. CASE numberType OF
  570. Scanner.IntNumber:
  571. numberType := FoxScanner.Longint;
  572. | Scanner.LongNumber:
  573. numberType := FoxScanner.Hugeint;
  574. | Scanner.FloatNumber:
  575. numberType := FoxScanner.Real;
  576. | Scanner.DoubleNumber:
  577. numberType := FoxScanner.Longreal;
  578. END;
  579. RETURN numberType;
  580. END MapNumberType;
  581. (*
  582. ACHTUNG: Initializers of members of modules, classes, structs,
  583. cells, and cellnets are collected in a special statement
  584. block. This block is inserted as the first statement in
  585. the corresponding constructors.
  586. TODO: This feature is not yet implemented. Initializers are
  587. collected but not inserted in constructors. Implement what is missing.
  588. *)
  589. (* create a statement block to collect initializers *)
  590. PROCEDURE EnterInit;
  591. VAR block: SyntaxTree.StatementBlock;
  592. BEGIN
  593. block := SyntaxTree.NewStatementBlock(invalidPosition, NIL);
  594. initOuter := block;
  595. initStatements := SyntaxTree.NewStatementSequence();
  596. block.SetStatementSequence(initStatements);
  597. END EnterInit;
  598. (** Parsing according to the EBNF **)
  599. (**
  600. type-name:
  601. identifier
  602. module-name '.' identifier
  603. **)
  604. PROCEDURE QualifiedIdentifier(): SyntaxTree.QualifiedIdentifier;
  605. VAR prefix, suffix: SyntaxTree.Identifier;
  606. qualifiedIdentifier: SyntaxTree.QualifiedIdentifier;
  607. position0, position1: LONGINT;
  608. BEGIN
  609. IF Trace THEN
  610. S("QualifiedIdentifier")
  611. END;
  612. prefix := Identifier(position0);
  613. IF prefix # SyntaxTree.invalidIdentifier THEN
  614. IF ~Optional(Scanner.Period) THEN
  615. suffix := prefix;
  616. prefix := SyntaxTree.invalidIdentifier; (* empty *)
  617. ELSE
  618. suffix := Identifier(position1);
  619. END;
  620. qualifiedIdentifier := SyntaxTree.NewQualifiedIdentifier(position0, prefix, suffix);
  621. ELSE
  622. qualifiedIdentifier := SyntaxTree.invalidQualifiedIdentifier;
  623. END;
  624. IF Trace THEN
  625. E("QualifiedIdentifier")
  626. END;
  627. RETURN qualifiedIdentifier
  628. END QualifiedIdentifier;
  629. (**
  630. expression-list:
  631. expression
  632. expression-list ',' expression
  633. **)
  634. PROCEDURE ExpressionList(expressionList: SyntaxTree.ExpressionList);
  635. VAR expression: SyntaxTree.Expression;
  636. BEGIN
  637. IF Trace THEN
  638. S("ExpressionList")
  639. END;
  640. REPEAT
  641. expression := Expression();
  642. expressionList.AddExpression(expression);
  643. UNTIL ~Optional(Scanner.Comma);
  644. IF Trace THEN
  645. E("ExpressionList")
  646. END;
  647. END ExpressionList;
  648. (**
  649. argument-list:
  650. argument
  651. argument-list ',' argument
  652. argument:
  653. expression
  654. 'ref' variable-reference
  655. variable-reference:
  656. expression
  657. **)
  658. PROCEDURE ArgumentList(expressionList: SyntaxTree.ExpressionList);
  659. VAR expression: SyntaxTree.Expression;
  660. modifier: LONGINT;
  661. BEGIN
  662. IF Trace THEN
  663. S("ArgumentList")
  664. END;
  665. REPEAT
  666. IF Optional(Scanner.Ref) THEN
  667. modifier := Scanner.Ref;
  668. ELSE
  669. modifier := -1;
  670. END;
  671. (*
  672. ACHTUNG: Modifiers cannot be validated without AST modifications,
  673. therefore 'modifier' value is not used in this release.
  674. *)
  675. expression := Expression();
  676. expressionList.AddExpression(expression);
  677. UNTIL ~Optional(Scanner.Comma);
  678. IF Trace THEN
  679. E("ArgumentList")
  680. END;
  681. END ArgumentList;
  682. (**
  683. primary-expression:
  684. array-creation-expression
  685. primary-no-array-creation-expression
  686. primary-no-array-creation-expression:
  687. literal
  688. simple-name
  689. parenthesized-expression
  690. member-access
  691. invocation-expression
  692. element-access
  693. this-access
  694. base-access
  695. object-creation-expression
  696. delegate-creation-expression
  697. receive-expression
  698. literal:
  699. boolean-literal
  700. integer-literal
  701. real-literal
  702. character-literal
  703. string-literal
  704. null-literal
  705. boolean-literal:
  706. 'true'
  707. 'false'
  708. null-literal:
  709. 'null'
  710. simple-name:
  711. identifier
  712. parenthesized-expression:
  713. '(' expression ')'
  714. member-access:
  715. primary-expression '.' identifier
  716. invocation-expression:
  717. primary-expression '(' [argument-list] ')'
  718. element-access:
  719. primary-no-array-creation-expression '[' expression-list ']'
  720. this-access:
  721. 'this'
  722. base-access:
  723. 'base' '.' identifier
  724. object-creation-expression:
  725. 'new' non-array-type '(' [argument-list] ')'
  726. array-creation-expression:
  727. 'new' non-array-type '[' expression-list ']' [rank-specifiers]
  728. delegate-creation-expression:
  729. 'new' delegate-type '(' expression ')'
  730. receive-expression:
  731. primary-expression '??' primary-expression
  732. **)
  733. PROCEDURE Accessors(expression: SyntaxTree.Expression; arrayCreation: BOOLEAN): SyntaxTree.Expression;
  734. VAR identifier: SyntaxTree.Identifier;
  735. expressionList: SyntaxTree.ExpressionList;
  736. position: LONGINT;
  737. BEGIN
  738. LOOP
  739. position := symbol.start;
  740. IF Optional(Scanner.Period) THEN
  741. identifier := Identifier(position);
  742. expression := SyntaxTree.NewSelectorDesignator(position, expression(SyntaxTree.Designator), identifier);
  743. ELSIF Optional(Scanner.LeftParenthesis) THEN
  744. expressionList := SyntaxTree.NewExpressionList();
  745. IF ~Optional(Scanner.RightParenthesis) THEN
  746. ArgumentList(expressionList);
  747. Check(Scanner.RightParenthesis);
  748. END;
  749. expression := SyntaxTree.NewParameterDesignator(position, expression(SyntaxTree.Designator), expressionList);
  750. ELSIF (~arrayCreation) & Optional(Scanner.LeftBracket) THEN
  751. expressionList := SyntaxTree.NewExpressionList();
  752. ExpressionList(expressionList);
  753. Check(Scanner.RightBracket);
  754. (* ACHTUNG: 27-09-2012
  755. expression := SyntaxTree.NewArrowDesignator(position, expression);
  756. *)
  757. expression := SyntaxTree.NewBracketDesignator(position, expression(SyntaxTree.Designator), expressionList);
  758. ELSE
  759. EXIT;
  760. END;
  761. END;
  762. RETURN expression;
  763. END Accessors;
  764. PROCEDURE PrimaryExpression(): SyntaxTree.Expression;
  765. VAR expression: SyntaxTree.Expression;
  766. designator: SyntaxTree.Designator;
  767. realValue: SyntaxTree.RealValue;
  768. identifier: SyntaxTree.Identifier;
  769. type: SyntaxTree.Type;
  770. typeExpression: SyntaxTree.Expression;
  771. expressionList: SyntaxTree.ExpressionList;
  772. position: LONGINT;
  773. arrayCreation: BOOLEAN;
  774. arrayType: SyntaxTree.ArrayType;
  775. pointerType: SyntaxTree.PointerType;
  776. rightExpression: SyntaxTree.Expression;
  777. i, n: LONGINT;
  778. BEGIN
  779. IF Trace THEN
  780. S("PrimaryExpression")
  781. END;
  782. position := symbol.start;
  783. arrayCreation := FALSE;
  784. IF Peek(Scanner.True) THEN
  785. expression := SyntaxTree.NewBooleanValue(position, TRUE);
  786. expression.End(symbol.end);
  787. NextSymbol;
  788. ELSIF Peek(Scanner.False) THEN
  789. expression := SyntaxTree.NewBooleanValue(position, FALSE);
  790. expression.End(symbol.end);
  791. NextSymbol;
  792. ELSIF Peek(Scanner.IntegerLiteral) THEN
  793. IF symbol.numberType = Scanner.IntNumber THEN
  794. expression := SyntaxTree.NewIntegerValue(position, symbol.integer);
  795. expression.End(symbol.end);
  796. ELSIF symbol.numberType = Scanner.LongNumber THEN
  797. expression := SyntaxTree.NewIntegerValue(position, symbol.hugeint);
  798. expression.End(symbol.end);
  799. ELSE
  800. HALT(100);
  801. END;
  802. NextSymbol;
  803. ELSIF Peek(Scanner.RealLiteral) THEN
  804. realValue := SyntaxTree.NewRealValue(position, symbol.real);
  805. realValue.SetSubtype(MapNumberType(symbol.numberType));
  806. expression := realValue;
  807. expression.End(symbol.end);
  808. NextSymbol;
  809. ELSIF Peek(Scanner.CharacterLiteral) THEN
  810. expression := SyntaxTree.NewCharacterValue(position, symbol.character);
  811. expression.End(symbol.end);
  812. NextSymbol;
  813. ELSIF Peek(Scanner.StringLiteral) THEN
  814. (*
  815. TODO: Revise this: may need a string constructor wrapper ...
  816. ... and symbol.stringLength may be important too
  817. *)
  818. expression := SyntaxTree.NewStringValue(position, symbol.string);
  819. expression.End(symbol.end);
  820. NextSymbol;
  821. ELSIF Peek(Scanner.Identifier) THEN
  822. identifier := Identifier(position);
  823. identifier := localIdentTable.Find(identifier);
  824. expression := SyntaxTree.NewIdentifierDesignator(position, identifier);
  825. ELSIF Peek(Scanner.Null) THEN
  826. expression := SyntaxTree.NewNilValue(position);
  827. expression.End(symbol.end);
  828. NextSymbol;
  829. ELSIF Optional(Scanner.LeftParenthesis) THEN
  830. expression := Expression();
  831. Check(Scanner.RightParenthesis);
  832. ELSIF Optional(Scanner.This) THEN
  833. expression := SyntaxTree.NewSelfDesignator(position);
  834. ELSIF Optional(Scanner.Base) THEN
  835. Check(Scanner.Period);
  836. position := symbol.start;
  837. identifier := Identifier(position);
  838. expression := SyntaxTree.NewIdentifierDesignator(position, identifier);
  839. expression := SyntaxTree.NewArrowDesignator(position, expression(SyntaxTree.Designator));
  840. ELSIF Optional(Scanner.New) THEN
  841. type := NonArrayType();
  842. expressionList := SyntaxTree.NewExpressionList();
  843. typeExpression := NewTypeExpression(position);
  844. expressionList.AddExpression(typeExpression);
  845. IF Optional(Scanner.LeftBracket) THEN
  846. arrayCreation := TRUE;
  847. ExpressionList(expressionList);
  848. Check(Scanner.RightBracket);
  849. WHILE Optional(Scanner.LeftBracket) DO
  850. type := RankSpecifier(type);
  851. Check(Scanner.RightBracket);
  852. END;
  853. n := expressionList.Length() - 1;
  854. FOR i := 1 TO n DO
  855. arrayType := SyntaxTree.NewArrayType(position, currentScope, SyntaxTree.Open);
  856. arrayType.SetArrayBase(type);
  857. type := arrayType;
  858. END;
  859. pointerType := SyntaxTree.NewPointerType(position, currentScope);
  860. pointerType.SetPointerBase(type);
  861. type := pointerType;
  862. END;
  863. typeExpression.SetType(type);
  864. IF ~arrayCreation THEN
  865. Check(Scanner.LeftParenthesis);
  866. IF ~Optional(Scanner.RightParenthesis) THEN
  867. ArgumentList(expressionList);
  868. Check(Scanner.RightParenthesis);
  869. END;
  870. designator := SyntaxTree.NewIdentifierDesignator(position, lynxNewobj);
  871. expression := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  872. ELSE
  873. designator := SyntaxTree.NewIdentifierDesignator(position, lynxNewarr);
  874. expression := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  875. END;
  876. ELSE
  877. Error(symbol.start, Diagnostics.Invalid, "Invalid primary expression");
  878. NextSymbol;
  879. expression := SyntaxTree.invalidExpression;
  880. END;
  881. expression := Accessors(expression, arrayCreation);
  882. position := symbol.start;
  883. IF Optional(Scanner.QuestionQuestion) THEN
  884. rightExpression := PrimaryExpression();
  885. expression := NewReceiveExpression(position, expression, rightExpression);
  886. END;
  887. IF Trace THEN
  888. E("PrimaryExpression")
  889. END;
  890. RETURN expression;
  891. END PrimaryExpression;
  892. (**
  893. unary-expression:
  894. primary-expression
  895. '+' unary-expression
  896. '-' unary-expression
  897. '!' unary-expression
  898. '~' unary-expression
  899. cast-expression
  900. **)
  901. PROCEDURE UnaryExpression(): SyntaxTree.Expression;
  902. VAR expression: SyntaxTree.Expression;
  903. operator: LONGINT;
  904. position: LONGINT;
  905. BEGIN
  906. IF Trace THEN
  907. S("UnaryExpression")
  908. END;
  909. position := symbol.start;
  910. IF Peek(Scanner.Plus) OR Peek(Scanner.Minus) OR
  911. Peek(Scanner.Exclamation) OR Peek(Scanner.Tilde) THEN
  912. operator := symbol.token;
  913. NextSymbol;
  914. expression := UnaryExpression();
  915. expression := NewUnaryExpression(position, expression, operator);
  916. ELSE
  917. (* TODO: Implement cast-expression *)
  918. expression := PrimaryExpression();
  919. END;
  920. IF Trace THEN
  921. E("UnaryExpression")
  922. END;
  923. RETURN expression;
  924. END UnaryExpression;
  925. (**
  926. multiplicative-expression:
  927. unary-expression
  928. multiplicative-expression '*' unary-expression
  929. multiplicative-expression '/' unary-expression
  930. multiplicative-expression '%' unary-expression
  931. **)
  932. PROCEDURE MultiplicativeExpression(): SyntaxTree.Expression;
  933. VAR expression, rightExpression: SyntaxTree.Expression;
  934. operator: LONGINT;
  935. position: LONGINT;
  936. BEGIN
  937. IF Trace THEN
  938. S("MultiplicativeExpression")
  939. END;
  940. position := symbol.start;
  941. expression := UnaryExpression();
  942. WHILE Peek(Scanner.Times) OR Peek(Scanner.Slash) OR Peek(Scanner.Percent) DO
  943. operator := symbol.token;
  944. NextSymbol;
  945. rightExpression := UnaryExpression();
  946. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  947. END;
  948. IF Trace THEN
  949. E("MultiplicativeExpression")
  950. END;
  951. RETURN expression;
  952. END MultiplicativeExpression;
  953. (**
  954. additive-expression:
  955. multiplicative-expression
  956. additive-expression '+' multiplicative-expression
  957. additive-expression '–' multiplicative-expression
  958. **)
  959. PROCEDURE AdditiveExpression(): SyntaxTree.Expression;
  960. VAR expression, rightExpression: SyntaxTree.Expression;
  961. operator: LONGINT;
  962. position: LONGINT;
  963. BEGIN
  964. IF Trace THEN
  965. S("AdditiveExpression")
  966. END;
  967. position := symbol.start;
  968. expression := MultiplicativeExpression();
  969. WHILE Peek(Scanner.Plus) OR Peek(Scanner.Minus) DO
  970. operator := symbol.token;
  971. NextSymbol;
  972. rightExpression := MultiplicativeExpression();
  973. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  974. END;
  975. IF Trace THEN
  976. E("AdditiveExpression")
  977. END;
  978. RETURN expression;
  979. END AdditiveExpression;
  980. (**
  981. shift-expression:
  982. additive-expression
  983. shift-expression '<<' additive-expression
  984. shift-expression '>>' additive-expression
  985. **)
  986. PROCEDURE ShiftExpression(): SyntaxTree.Expression;
  987. VAR expression, rightExpression: SyntaxTree.Expression;
  988. operator: LONGINT;
  989. position: LONGINT;
  990. BEGIN
  991. IF Trace THEN
  992. S("ShiftExpression")
  993. END;
  994. position := symbol.start;
  995. expression := AdditiveExpression();
  996. WHILE Peek(Scanner.LeftShift) OR Peek(Scanner.RightShift) DO
  997. operator := symbol.token;
  998. NextSymbol;
  999. rightExpression := AdditiveExpression();
  1000. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1001. END;
  1002. IF Trace THEN
  1003. E("ShiftExpression")
  1004. END;
  1005. RETURN expression;
  1006. END ShiftExpression;
  1007. (**
  1008. relational-expression:
  1009. shift-expression
  1010. relational-expression '<' shift-expression
  1011. relational-expression '>' shift-expression
  1012. relational-expression '<=' shift-expression
  1013. relational-expression '>=' shift-expression
  1014. relational-expression 'is' type-name
  1015. relational-expression 'as' type-name
  1016. **)
  1017. PROCEDURE RelationalExpression(): SyntaxTree.Expression;
  1018. VAR expression, rightExpression: SyntaxTree.Expression;
  1019. operator: LONGINT;
  1020. position: LONGINT;
  1021. BEGIN
  1022. IF Trace THEN
  1023. S("RelationalExpression")
  1024. END;
  1025. position := symbol.start;
  1026. expression := ShiftExpression();
  1027. WHILE Peek(Scanner.Less) OR Peek(Scanner.Greater) OR
  1028. Peek(Scanner.LessEqual) OR Peek(Scanner.GreaterEqual) OR
  1029. Peek(Scanner.Is) OR Peek(Scanner.As) DO
  1030. operator := symbol.token;
  1031. NextSymbol;
  1032. rightExpression := ShiftExpression();
  1033. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1034. END;
  1035. IF Trace THEN
  1036. E("RelationalExpression")
  1037. END;
  1038. RETURN expression;
  1039. END RelationalExpression;
  1040. (**
  1041. equality-expression:
  1042. relational-expression
  1043. equality-expression '==' relational-expression
  1044. equality-expression '!=' relational-expression
  1045. **)
  1046. PROCEDURE EqualityExpression(): SyntaxTree.Expression;
  1047. VAR expression, rightExpression: SyntaxTree.Expression;
  1048. operator: LONGINT;
  1049. position: LONGINT;
  1050. BEGIN
  1051. IF Trace THEN
  1052. S("EqualityExpression")
  1053. END;
  1054. position := symbol.start;
  1055. expression := RelationalExpression();
  1056. WHILE Peek(Scanner.EqualEqual) OR Peek(Scanner.ExclamationEqual) DO
  1057. operator := symbol.token;
  1058. NextSymbol;
  1059. rightExpression := RelationalExpression();
  1060. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1061. END;
  1062. IF Trace THEN
  1063. E("EqualityExpression")
  1064. END;
  1065. RETURN expression;
  1066. END EqualityExpression;
  1067. (**
  1068. and-expression:
  1069. equality-expression
  1070. and-expression '&' equality-expression
  1071. **)
  1072. PROCEDURE AndExpression(): SyntaxTree.Expression;
  1073. VAR expression, rightExpression: SyntaxTree.Expression;
  1074. operator: LONGINT;
  1075. position: LONGINT;
  1076. BEGIN
  1077. IF Trace THEN
  1078. S("AndExpression")
  1079. END;
  1080. position := symbol.start;
  1081. expression := EqualityExpression();
  1082. WHILE Peek(Scanner.And) DO
  1083. operator := symbol.token;
  1084. NextSymbol;
  1085. rightExpression := EqualityExpression();
  1086. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1087. END;
  1088. IF Trace THEN
  1089. E("AndExpression")
  1090. END;
  1091. RETURN expression;
  1092. END AndExpression;
  1093. (**
  1094. exclusive-or-expression:
  1095. and-expression
  1096. exclusive-or-expression '^' and-expression
  1097. **)
  1098. PROCEDURE ExclusiveOrExpression(): SyntaxTree.Expression;
  1099. VAR expression, rightExpression: SyntaxTree.Expression;
  1100. operator: LONGINT;
  1101. position: LONGINT;
  1102. BEGIN
  1103. IF Trace THEN
  1104. S("ExclusiveOrExpression")
  1105. END;
  1106. position := symbol.start;
  1107. expression := AndExpression();
  1108. WHILE Peek(Scanner.Arrow) DO
  1109. operator := symbol.token;
  1110. NextSymbol;
  1111. rightExpression := AndExpression();
  1112. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1113. END;
  1114. IF Trace THEN
  1115. E("ExclusiveOrExpression")
  1116. END;
  1117. RETURN expression;
  1118. END ExclusiveOrExpression;
  1119. (**
  1120. inclusive-or-expression:
  1121. exclusive-or-expression
  1122. inclusive-or-expression '|' exclusive-or-expression
  1123. **)
  1124. PROCEDURE InclusiveOrExpression(): SyntaxTree.Expression;
  1125. VAR expression, rightExpression: SyntaxTree.Expression;
  1126. operator: LONGINT;
  1127. position: LONGINT;
  1128. BEGIN
  1129. IF Trace THEN
  1130. S("InclusiveOrExpression")
  1131. END;
  1132. position := symbol.start;
  1133. expression := ExclusiveOrExpression();
  1134. WHILE Peek(Scanner.Bar) DO
  1135. operator := symbol.token;
  1136. NextSymbol;
  1137. rightExpression := ExclusiveOrExpression();
  1138. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1139. END;
  1140. IF Trace THEN
  1141. E("InclusiveOrExpression")
  1142. END;
  1143. RETURN expression;
  1144. END InclusiveOrExpression;
  1145. (**
  1146. conditional-and-expression:
  1147. inclusive-or-expression
  1148. conditional-and-expression '&&' inclusive-or-expression
  1149. **)
  1150. PROCEDURE ConditionalAndExpression(): SyntaxTree.Expression;
  1151. VAR expression, rightExpression: SyntaxTree.Expression;
  1152. operator: LONGINT;
  1153. position: LONGINT;
  1154. BEGIN
  1155. IF Trace THEN
  1156. S("ConditionalAndExpression")
  1157. END;
  1158. position := symbol.start;
  1159. expression := InclusiveOrExpression();
  1160. WHILE Peek(Scanner.AndAnd) DO
  1161. operator := symbol.token;
  1162. NextSymbol;
  1163. rightExpression := InclusiveOrExpression();
  1164. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1165. END;
  1166. IF Trace THEN
  1167. E("ConditionalAndExpression")
  1168. END;
  1169. RETURN expression;
  1170. END ConditionalAndExpression;
  1171. (**
  1172. conditional-or-expression:
  1173. conditional-and-expression
  1174. conditional-or-expression '||' conditional-and-expression
  1175. **)
  1176. PROCEDURE ConditionalOrExpression(): SyntaxTree.Expression;
  1177. VAR expression, rightExpression: SyntaxTree.Expression;
  1178. operator: LONGINT;
  1179. position: LONGINT;
  1180. BEGIN
  1181. IF Trace THEN
  1182. S("ConditionalOrExpression")
  1183. END;
  1184. position := symbol.start;
  1185. expression := ConditionalAndExpression();
  1186. WHILE Peek(Scanner.BarBar) DO
  1187. operator := symbol.token;
  1188. NextSymbol;
  1189. rightExpression := ConditionalAndExpression();
  1190. expression := NewBinaryExpression(position, expression, rightExpression, operator);
  1191. END;
  1192. IF Trace THEN
  1193. E("ConditionalOrExpression")
  1194. END;
  1195. RETURN expression;
  1196. END ConditionalOrExpression;
  1197. (**
  1198. expression:
  1199. conditional-expression
  1200. conditional-expression:
  1201. conditional-or-expression
  1202. **)
  1203. PROCEDURE Expression(): SyntaxTree.Expression;
  1204. VAR expression: SyntaxTree.Expression;
  1205. BEGIN
  1206. IF Trace THEN
  1207. S("Expression")
  1208. END;
  1209. expression := ConditionalOrExpression();
  1210. IF Trace THEN
  1211. E("Expression")
  1212. END;
  1213. RETURN expression;
  1214. END Expression;
  1215. (**
  1216. local-variable-declaration:
  1217. type local-variable-declarators
  1218. **)
  1219. PROCEDURE LocalVariableDeclaration(
  1220. statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement; type: SyntaxTree.Type);
  1221. VAR previousStatements: SyntaxTree.StatementSequence;
  1222. previousOuter: SyntaxTree.Statement;
  1223. BEGIN
  1224. IF Trace THEN
  1225. S("LocalVariableDeclaration")
  1226. END;
  1227. previousStatements := initStatements;
  1228. previousOuter := initOuter;
  1229. initStatements := statements;
  1230. initOuter := outer;
  1231. IF type = NIL THEN
  1232. type := Type();
  1233. END;
  1234. REPEAT
  1235. VariableDeclarator(currentScope, {}, type, SyntaxTree.invalidIdentifier, invalidPosition);
  1236. UNTIL ~Optional(Scanner.Comma);
  1237. initStatements := previousStatements;
  1238. initOuter := previousOuter;
  1239. IF Trace THEN
  1240. E("LocalVariableDeclaration")
  1241. END;
  1242. END LocalVariableDeclaration;
  1243. (**
  1244. local-constant-declaration:
  1245. 'const' type constant-declarators
  1246. **)
  1247. PROCEDURE LocalConstantDeclaration(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1248. VAR type: SyntaxTree.Type;
  1249. BEGIN
  1250. (* ACHTUNG: Parameters 'statements' and 'outer' are not used *)
  1251. IF Trace THEN
  1252. S("LocalConstantDeclaration")
  1253. END;
  1254. type := Type();
  1255. REPEAT
  1256. ConstantDeclarator(currentScope, {}, type);
  1257. UNTIL ~Optional(Scanner.Comma);
  1258. IF Trace THEN
  1259. E("LocalConstantDeclaration")
  1260. END;
  1261. END LocalConstantDeclaration;
  1262. (**
  1263. block:
  1264. '{' [statement-list] '}'
  1265. **)
  1266. PROCEDURE Block(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1267. VAR block: SyntaxTree.StatementBlock;
  1268. BEGIN
  1269. IF Trace THEN
  1270. S("Block")
  1271. END;
  1272. Check(Scanner.LeftBrace);
  1273. block := SyntaxTree.NewStatementBlock(symbol.end, outer);
  1274. (* CommentStatement(block); *)
  1275. IF ~Optional(Scanner.RightBrace) THEN
  1276. localIdentTable.OpenScope;
  1277. block.SetStatementSequence(StatementList(block));
  1278. localIdentTable.CloseScope;
  1279. Check(Scanner.RightBrace);
  1280. END;
  1281. statements.AddStatement(block);
  1282. IF Trace THEN
  1283. E("Block")
  1284. END;
  1285. END Block;
  1286. (**
  1287. expression-statement:
  1288. statement-expression ';'
  1289. statement-expression:
  1290. invocation-expression
  1291. assignment
  1292. post-increment-expression
  1293. post-decrement-expression
  1294. send-expression
  1295. receive-expression
  1296. connect-expression
  1297. delegate-expression
  1298. assignment:
  1299. primary-expression assignment-operator expression
  1300. assignment-operator: one of
  1301. '=' '+=' '-=' '*=' '/=' '%=' '&=' '|=' '^=' '<<=' '>>='
  1302. post-increment-expression:
  1303. primary-expression '++'
  1304. post-decrement-expression:
  1305. primary-expression '--'
  1306. send-expression:
  1307. primary-expression '!' expression-list
  1308. receive-expression:
  1309. primary-expression '?' expression-list
  1310. connect-expression:
  1311. primary-expression '>>' primary-expression
  1312. delegate-expression:
  1313. primary-expression '<=' primary-expression
  1314. **)
  1315. PROCEDURE NewAsopStatement(
  1316. position: LONGINT;
  1317. operator: LONGINT;
  1318. left: SyntaxTree.Designator;
  1319. right: SyntaxTree.Expression;
  1320. outer: SyntaxTree.Statement): SyntaxTree.Statement;
  1321. VAR expressionList: SyntaxTree.ExpressionList;
  1322. expression: SyntaxTree.Expression;
  1323. designator: SyntaxTree.Designator;
  1324. BEGIN
  1325. operator := MapOperator(operator);
  1326. ASSERT(operator >= 256);
  1327. expressionList := SyntaxTree.NewExpressionList();
  1328. expression := SyntaxTree.NewIntegerValue(position, operator-256);
  1329. expressionList.AddExpression(expression);
  1330. expressionList.AddExpression(left);
  1331. expressionList.AddExpression(right);
  1332. designator := SyntaxTree.NewIdentifierDesignator(position, lynxAsop);
  1333. designator := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  1334. RETURN SyntaxTree.NewProcedureCallStatement(designator.position, designator, outer);
  1335. END NewAsopStatement;
  1336. (* ACHTUNG: LYNX 15-MAY-2013 *)
  1337. PROCEDURE PatchPortReference(expression: SyntaxTree.Expression): SyntaxTree.Expression;
  1338. VAR result: SyntaxTree.Expression;
  1339. parameterDesignator: SyntaxTree.ParameterDesignator;
  1340. parameters: SyntaxTree.ExpressionList;
  1341. p0: SyntaxTree.Expression;
  1342. identifierDesignator: SyntaxTree.IdentifierDesignator;
  1343. bracketDesignator: SyntaxTree.BracketDesignator;
  1344. left, left2: SyntaxTree.Expression;
  1345. BEGIN
  1346. IF ~(expression IS SyntaxTree.ParameterDesignator) THEN
  1347. result := expression;
  1348. ELSE
  1349. parameterDesignator := expression(SyntaxTree.ParameterDesignator);
  1350. parameters := parameterDesignator.parameters;
  1351. IF parameters.Length() # 1 THEN
  1352. result := expression;
  1353. ELSE
  1354. p0 := parameters.GetExpression(0);
  1355. IF p0 IS SyntaxTree.IdentifierDesignator THEN
  1356. (* C(P) -> C.P *)
  1357. left := parameterDesignator.left;
  1358. identifierDesignator := p0(SyntaxTree.IdentifierDesignator);
  1359. result :=
  1360. SyntaxTree.NewSelectorDesignator(
  1361. expression.position, left(SyntaxTree.Designator), identifierDesignator.identifier);
  1362. ELSIF p0 IS SyntaxTree.BracketDesignator THEN
  1363. bracketDesignator := p0(SyntaxTree.BracketDesignator);
  1364. left2 := bracketDesignator.left;
  1365. IF left2 IS SyntaxTree.IdentifierDesignator THEN
  1366. (* C(P[I]) -> C.P[I] *)
  1367. left := parameterDesignator.left;
  1368. identifierDesignator := left2(SyntaxTree.IdentifierDesignator);
  1369. result :=
  1370. SyntaxTree.NewBracketDesignator(
  1371. expression.position,
  1372. SyntaxTree.NewSelectorDesignator(
  1373. expression.position,
  1374. left(SyntaxTree.Designator),
  1375. identifierDesignator.identifier),
  1376. bracketDesignator.parameters);
  1377. ELSE
  1378. result := expression;
  1379. END;
  1380. ELSE
  1381. result := expression;
  1382. END;
  1383. END;
  1384. END;
  1385. RETURN result;
  1386. END PatchPortReference;
  1387. PROCEDURE NewPortStatement(
  1388. position: LONGINT;
  1389. name: SyntaxTree.Identifier;
  1390. left: SyntaxTree.Designator;
  1391. right: SyntaxTree.Expression;
  1392. outer: SyntaxTree.Statement): SyntaxTree.Statement;
  1393. VAR expressionList: SyntaxTree.ExpressionList;
  1394. designator: SyntaxTree.Designator;
  1395. BEGIN
  1396. expressionList := SyntaxTree.NewExpressionList();
  1397. expressionList.AddExpression(left);
  1398. expressionList.AddExpression(right);
  1399. designator := SyntaxTree.NewIdentifierDesignator(position, name);
  1400. designator := SyntaxTree.NewParameterDesignator(position, designator, expressionList);
  1401. RETURN SyntaxTree.NewProcedureCallStatement(designator.position, designator, outer);
  1402. END NewPortStatement;
  1403. PROCEDURE StatementExpression(
  1404. statements: SyntaxTree.StatementSequence;
  1405. outer: SyntaxTree.Statement;
  1406. expression: SyntaxTree.Expression): BOOLEAN;
  1407. VAR designator: SyntaxTree.Designator;
  1408. expressionList: SyntaxTree.ExpressionList;
  1409. statement: SyntaxTree.Statement;
  1410. operator: LONGINT;
  1411. position: LONGINT;
  1412. length, i: LONGINT;
  1413. temp: SyntaxTree.Expression;
  1414. BEGIN
  1415. IF Trace THEN
  1416. S("StatementExpression")
  1417. END;
  1418. (* ACHTUNG: Only expressions of type SyntaxTree.Designator are supported
  1419. in place of primary-expression in the above productions. This is
  1420. required for compatibility with Fox back-end *)
  1421. statement := NIL;
  1422. position := symbol.start;
  1423. IF expression = NIL THEN
  1424. expression := PrimaryExpression();
  1425. END;
  1426. IF ~(expression IS SyntaxTree.Designator) THEN
  1427. Error(position, Diagnostics.Invalid, "Invalid expression statement");
  1428. ELSE
  1429. designator := expression(SyntaxTree.Designator);
  1430. position := symbol.start;
  1431. IF Optional(Scanner.Equal) THEN
  1432. expression := Expression();
  1433. statement := SyntaxTree.NewAssignment(position, designator, expression, outer);
  1434. ELSIF Peek(Scanner.PlusEqual) OR Peek(Scanner.MinusEqual) OR
  1435. Peek(Scanner.TimesEqual) OR Peek(Scanner.SlashEqual) OR
  1436. Peek(Scanner.PercentEqual) OR Peek(Scanner.AndEqual) OR
  1437. Peek(Scanner.BarEqual) OR Peek(Scanner.ArrowEqual) OR
  1438. Peek(Scanner.LeftShiftEqual) OR Peek(Scanner.RightShiftEqual) THEN
  1439. operator := symbol.token;
  1440. NextSymbol;
  1441. (* lynx@asop(operator, designator, expression) *)
  1442. expression := Expression();
  1443. statement := NewAsopStatement(position, operator, designator, expression, outer);
  1444. ELSIF Optional(Scanner.PlusPlus) THEN
  1445. (* lynx@asop(PlusEqual, designator, 1) *)
  1446. operator := Scanner.PlusPlus;
  1447. expression := SyntaxTree.NewIntegerValue(position, 1);
  1448. statement := NewAsopStatement(position, operator, designator, expression, outer);
  1449. ELSIF Optional(Scanner.MinusMinus) THEN
  1450. (* lynx@asop(MinusEqual, designator, 1) *)
  1451. operator := Scanner.MinusMinus;
  1452. expression := SyntaxTree.NewIntegerValue(position, 1);
  1453. statement := NewAsopStatement(position, operator, designator, expression, outer);
  1454. (* ACHTUNG: LYNX 15-MAY-2013
  1455. ELSIF Optional(Scanner.Exclamation) THEN
  1456. (* lynx@send(designator, expression) *)
  1457. expression := Expression();
  1458. statement := NewPortStatement(position, lynxSend, designator, expression, outer);
  1459. ELSIF Optional(Scanner.Question) THEN
  1460. (* lynx@receive(designator, expression) *)
  1461. expression := Expression();
  1462. statement := NewPortStatement(position, lynxReceive, designator, expression, outer);
  1463. *)
  1464. ELSIF Optional(Scanner.Exclamation) THEN
  1465. (* lynx@send(designator, expression) *)
  1466. expressionList := SyntaxTree.NewExpressionList();
  1467. ExpressionList(expressionList);
  1468. length := expressionList.Length();
  1469. FOR i := 0 TO length - 1 DO
  1470. expression := expressionList.GetExpression(i);
  1471. statement := NewPortStatement(position, lynxSend, designator, expression, outer);
  1472. IF i < length - 1 THEN
  1473. statements.AddStatement(statement);
  1474. END;
  1475. END;
  1476. ELSIF Optional(Scanner.Question) THEN
  1477. (* lynx@receive(designator, expression) *)
  1478. expressionList := SyntaxTree.NewExpressionList();
  1479. ExpressionList(expressionList);
  1480. length := expressionList.Length();
  1481. FOR i := 0 TO length - 1 DO
  1482. expression := expressionList.GetExpression(i);
  1483. statement := NewPortStatement(position, lynxReceive, designator, expression, outer);
  1484. IF i < length - 1 THEN
  1485. statements.AddStatement(statement);
  1486. END;
  1487. END;
  1488. (* ACHTUNG: LYNX 15-MAY-2013
  1489. ELSIF Optional(Scanner.RightShift) THEN
  1490. (* lynx@connect(designator, expression) *)
  1491. expression := PrimaryExpression();
  1492. statement := NewPortStatement(position, lynxConnect, designator, expression, outer);
  1493. ELSIF Optional(Scanner.LessEqual) THEN
  1494. (* lynx@delegate(designator, expression) *)
  1495. expression := PrimaryExpression();
  1496. statement := NewPortStatement(position, lynxDelegate, designator, expression, outer);
  1497. *)
  1498. ELSIF Optional(Scanner.RightShift) THEN
  1499. (* lynx@connect(designator, expression) *)
  1500. expression := PrimaryExpression();
  1501. temp := PatchPortReference(designator);
  1502. designator := temp(SyntaxTree.Designator);
  1503. expression := PatchPortReference(expression);
  1504. statement := NewPortStatement(position, lynxConnect, designator, expression, outer);
  1505. ELSIF Optional(Scanner.LessEqual) THEN
  1506. (* lynx@delegate(designator, expression) *)
  1507. expression := PrimaryExpression();
  1508. temp := PatchPortReference(designator);
  1509. designator := temp(SyntaxTree.Designator);
  1510. expression := PatchPortReference(expression);
  1511. statement := NewPortStatement(position, lynxDelegate, designator, expression, outer);
  1512. ELSIF designator IS SyntaxTree.ParameterDesignator THEN
  1513. statement := SyntaxTree.NewProcedureCallStatement(designator.position, designator, outer);
  1514. ELSE
  1515. Error(position, Diagnostics.Invalid, "Invalid expression statement");
  1516. END;
  1517. END;
  1518. IF statement # NIL THEN
  1519. (* CommentStatement(statement); *)
  1520. statements.AddStatement(statement);
  1521. END;
  1522. IF Trace THEN
  1523. E("StatementExpression")
  1524. END;
  1525. RETURN statement # NIL;
  1526. END StatementExpression;
  1527. PROCEDURE ExpressionStatement(
  1528. statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement): BOOLEAN;
  1529. VAR b: BOOLEAN;
  1530. BEGIN
  1531. IF Trace THEN
  1532. S("ExpressionStatement")
  1533. END;
  1534. b := StatementExpression(statements, outer, NIL);
  1535. Check(Scanner.Semicolon);
  1536. IF Trace THEN
  1537. E("ExpressionStatement")
  1538. END;
  1539. RETURN b;
  1540. END ExpressionStatement;
  1541. (**
  1542. if-statement:
  1543. 'if' '(' boolean-expression ')' embedded-statement
  1544. 'if' '(' boolean-expression ')' embedded-statement 'else' embedded-statement
  1545. **)
  1546. PROCEDURE IfStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1547. VAR expression: SyntaxTree.Expression;
  1548. ifStatement: SyntaxTree.IfStatement;
  1549. elsePart: SyntaxTree.IfPart;
  1550. statementSequence: SyntaxTree.StatementSequence;
  1551. b: BOOLEAN;
  1552. BEGIN
  1553. IF Trace THEN
  1554. S("IfStatement")
  1555. END;
  1556. Check(Scanner.If);
  1557. ifStatement := SyntaxTree.NewIfStatement(symbol.start, outer);
  1558. (* CommentStatement(ifStatement); *)
  1559. Check(Scanner.LeftParenthesis);
  1560. expression := Expression();
  1561. Check(Scanner.RightParenthesis);
  1562. ifStatement.ifPart.SetCondition(expression);
  1563. statementSequence := SyntaxTree.NewStatementSequence();
  1564. b := EmbeddedStatement(statementSequence, ifStatement);
  1565. ifStatement.ifPart.SetStatements(statementSequence);
  1566. IF Optional(Scanner.Else) THEN
  1567. statementSequence := SyntaxTree.NewStatementSequence();
  1568. b := EmbeddedStatement(statementSequence, ifStatement);
  1569. ifStatement.SetElsePart(statementSequence);
  1570. END;
  1571. statements.AddStatement(ifStatement);
  1572. IF Trace THEN
  1573. E("IfStatement")
  1574. END;
  1575. END IfStatement;
  1576. (**
  1577. switch-statement:
  1578. 'switch' '(' expression ')' switch-block
  1579. switch-block:
  1580. '{' [switch-sections] '}'
  1581. switch-sections:
  1582. switch-section
  1583. switch-sections switch-section
  1584. switch-section:
  1585. switch-labels statement-list
  1586. switch-labels:
  1587. switch-label
  1588. switch-labels switch-label
  1589. switch-label:
  1590. 'case' constant-expression ':'
  1591. 'default' ':'
  1592. **)
  1593. PROCEDURE SwitchSection(caseStatement: SyntaxTree.CaseStatement; VAR haveDefault: BOOLEAN);
  1594. VAR casePart: SyntaxTree.CasePart;
  1595. statements: SyntaxTree.StatementSequence;
  1596. last: SyntaxTree.Statement;
  1597. element: SyntaxTree.Expression;
  1598. defaultSection: BOOLEAN;
  1599. length, position: LONGINT;
  1600. BEGIN
  1601. IF Trace THEN
  1602. S("SwitchSection")
  1603. END;
  1604. casePart := SyntaxTree.NewCasePart();
  1605. defaultSection := FALSE;
  1606. WHILE Peek(Scanner.Case) OR Peek(Scanner.Default) DO
  1607. (* CommentCasePart(casePart); *)
  1608. IF Optional(Scanner.Case) THEN
  1609. element := Expression();
  1610. Check(Scanner.Colon);
  1611. casePart.elements.AddExpression(element);
  1612. ELSE
  1613. position := symbol.start;
  1614. Check(Scanner.Default);
  1615. Check(Scanner.Colon);
  1616. IF haveDefault THEN
  1617. Error(position, Diagnostics.Invalid, "Duplicate default label");
  1618. ELSE
  1619. defaultSection := TRUE;
  1620. haveDefault := TRUE;
  1621. END;
  1622. END;
  1623. END;
  1624. statements := StatementList(caseStatement);
  1625. length := statements.Length();
  1626. IF length = 0 THEN
  1627. Error(symbol.start, Diagnostics.Invalid, "Fall through in switch section");
  1628. ELSE
  1629. last := statements.GetStatement(length-1);
  1630. IF last IS SyntaxTree.ExitStatement THEN
  1631. statements.RemoveStatement(last);
  1632. ELSIF ~(last IS SyntaxTree.ReturnStatement) THEN
  1633. Error(symbol.start, Diagnostics.Invalid, "Fall through in switch section");
  1634. END;
  1635. END;
  1636. IF ~defaultSection THEN
  1637. casePart.SetStatements(statements);
  1638. caseStatement.AddCasePart(casePart);
  1639. ELSE
  1640. (* ignore case labels, if any *)
  1641. (* ACHTUNG: these labels will not be checked for duplicates *)
  1642. caseStatement.SetElsePart(statements);
  1643. END;
  1644. IF Trace THEN
  1645. E("SwitchSection")
  1646. END;
  1647. END SwitchSection;
  1648. PROCEDURE SwitchStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1649. VAR expression: SyntaxTree.Expression;
  1650. caseStatement: SyntaxTree.CaseStatement;
  1651. haveDefault: BOOLEAN;
  1652. BEGIN
  1653. IF Trace THEN
  1654. S("SwitchStatement")
  1655. END;
  1656. Check(Scanner.Switch);
  1657. caseStatement := SyntaxTree.NewCaseStatement(symbol.start, outer);
  1658. (* CommentStatement(caseStatement); *)
  1659. Check(Scanner.LeftParenthesis);
  1660. expression := Expression();
  1661. Check(Scanner.RightParenthesis);
  1662. caseStatement.SetVariable(expression);
  1663. Check(Scanner.LeftBrace);
  1664. haveDefault := FALSE;
  1665. WHILE Peek(Scanner.Case) OR Peek(Scanner.Default) DO
  1666. SwitchSection(caseStatement, haveDefault);
  1667. END;
  1668. Check(Scanner.RightBrace);
  1669. statements.AddStatement(caseStatement);
  1670. IF Trace THEN
  1671. E("SwitchStatement")
  1672. END;
  1673. END SwitchStatement;
  1674. (**
  1675. select-statement:
  1676. 'select' select-block
  1677. select-block:
  1678. '{' select-sections '}'
  1679. select-sections:
  1680. select-section
  1681. select-sections select-section
  1682. select-section:
  1683. select-label statement-list
  1684. select-label:
  1685. 'case' [select-replicator] primary-expression '?' primary-expression ':'
  1686. select-replicator:
  1687. '(' integral-type simple-name 'in' expression ':' expression ')'
  1688. **)
  1689. (**
  1690. Fox mapping schema:
  1691. // LYNX
  1692. select {
  1693. case c ? x:
  1694. S1;
  1695. case (int i in m : n) d[i] ? y:
  1696. S2;
  1697. }
  1698. // Fox
  1699. lynx@newsel;
  1700. lynx@addsel(0, 0, c);
  1701. FOR i := m TO n DO
  1702. lynx@addsel(1, i, d[i])
  1703. END;
  1704. CASE lynx@select() OF
  1705. 0:
  1706. c ? x;
  1707. S1;
  1708. | 1:
  1709. i := lynx@selidx();
  1710. d[i] ? y;
  1711. S2;
  1712. END;
  1713. **)
  1714. PROCEDURE NewLynxNewsel(
  1715. position: LONGINT; outer: SyntaxTree.Statement): SyntaxTree.Statement;
  1716. VAR parameters: SyntaxTree.ExpressionList;
  1717. designator: SyntaxTree.Designator;
  1718. BEGIN
  1719. parameters := SyntaxTree.NewExpressionList();
  1720. designator := SyntaxTree.NewIdentifierDesignator(position, lynxNewsel);
  1721. designator := SyntaxTree.NewParameterDesignator(position, designator, parameters);
  1722. RETURN SyntaxTree.NewProcedureCallStatement(position, designator, outer);
  1723. END NewLynxNewsel;
  1724. PROCEDURE NewLynxAddsel(
  1725. position: LONGINT;
  1726. index: LONGINT;
  1727. variable: SyntaxTree.Identifier;
  1728. channel: SyntaxTree.Expression;
  1729. outer: SyntaxTree.Statement): SyntaxTree.Statement;
  1730. VAR parameters: SyntaxTree.ExpressionList;
  1731. designator: SyntaxTree.Designator;
  1732. BEGIN
  1733. parameters := SyntaxTree.NewExpressionList();
  1734. parameters.AddExpression(SyntaxTree.NewIntegerValue(position, index));
  1735. IF variable # SyntaxTree.invalidIdentifier THEN
  1736. parameters.AddExpression(
  1737. SyntaxTree.NewIdentifierDesignator(position, variable));
  1738. ELSE
  1739. parameters.AddExpression(SyntaxTree.NewIntegerValue(position, 0));
  1740. END;
  1741. parameters.AddExpression(channel);
  1742. designator := SyntaxTree.NewIdentifierDesignator(position, lynxAddsel);
  1743. designator := SyntaxTree.NewParameterDesignator(position, designator, parameters);
  1744. RETURN SyntaxTree.NewProcedureCallStatement(position, designator, outer);
  1745. END NewLynxAddsel;
  1746. PROCEDURE NewLynxSelect(position: LONGINT): SyntaxTree.Expression;
  1747. VAR left: SyntaxTree.Designator;
  1748. parameters: SyntaxTree.ExpressionList;
  1749. BEGIN
  1750. left := SyntaxTree.NewIdentifierDesignator(position, lynxSelect);
  1751. parameters := SyntaxTree.NewExpressionList();
  1752. RETURN SyntaxTree.NewParameterDesignator(position, left, parameters);
  1753. END NewLynxSelect;
  1754. PROCEDURE NewLynxSelidx(
  1755. position: LONGINT;
  1756. variable: SyntaxTree.Identifier;
  1757. outer: SyntaxTree.Statement): SyntaxTree.Statement;
  1758. VAR left: SyntaxTree.Designator;
  1759. parameters: SyntaxTree.ExpressionList;
  1760. right: SyntaxTree.Expression;
  1761. BEGIN
  1762. left := SyntaxTree.NewIdentifierDesignator(position, lynxSelidx);
  1763. parameters := SyntaxTree.NewExpressionList();
  1764. right := SyntaxTree.NewParameterDesignator(position, left, parameters);
  1765. left := SyntaxTree.NewIdentifierDesignator(position, variable);
  1766. RETURN SyntaxTree.NewAssignment(position, left, right, outer);
  1767. END NewLynxSelidx;
  1768. PROCEDURE SelectSection(
  1769. statements: SyntaxTree.StatementSequence;
  1770. caseStatement: SyntaxTree.CaseStatement;
  1771. index: LONGINT;
  1772. outer: SyntaxTree.Statement);
  1773. VAR typename, varname: SyntaxTree.Identifier;
  1774. type: SyntaxTree.Type;
  1775. variable: SyntaxTree.Variable;
  1776. position: LONGINT;
  1777. from, to: SyntaxTree.Expression;
  1778. channel, target: SyntaxTree.Expression;
  1779. statement: SyntaxTree.Statement;
  1780. forStatement: SyntaxTree.ForStatement;
  1781. forBody: SyntaxTree.StatementSequence;
  1782. designator: SyntaxTree.Designator;
  1783. casePart: SyntaxTree.CasePart;
  1784. caseBody: SyntaxTree.StatementSequence;
  1785. length: LONGINT;
  1786. last: SyntaxTree.Statement;
  1787. BEGIN
  1788. IF Trace THEN
  1789. S("SelectSection")
  1790. END;
  1791. position := symbol.start;
  1792. Check(Scanner.Case);
  1793. localIdentTable.OpenScope;
  1794. IF Optional(Scanner.LeftParenthesis) THEN
  1795. IF Optional(Scanner.Sbyte) THEN
  1796. typename := lynxSbyte;
  1797. ELSIF Optional(Scanner.Short) THEN
  1798. typename := lynxShort;
  1799. ELSIF Optional(Scanner.Int) THEN
  1800. typename := lynxInt;
  1801. ELSIF Optional(Scanner.Long) THEN
  1802. typename := lynxLong;
  1803. ELSE
  1804. Error(position, Diagnostics.Invalid, "Missing integral type specifier");
  1805. typename := lynxInt;
  1806. END;
  1807. type :=
  1808. SyntaxTree.NewQualifiedType(
  1809. position,
  1810. currentScope,
  1811. SyntaxTree.NewQualifiedIdentifier(
  1812. position, SyntaxTree.invalidIdentifier, typename));
  1813. varname := Identifier(position);
  1814. varname := localIdentTable.Enter(varname);
  1815. variable := SyntaxTree.NewVariable(position, varname);
  1816. CommentSymbol(variable);
  1817. variable.SetType(type);
  1818. currentScope.AddVariable(variable);
  1819. Check(Scanner.In);
  1820. from := Expression();
  1821. Check(Scanner.Colon);
  1822. to := Expression();
  1823. Check(Scanner.RightParenthesis);
  1824. ELSE
  1825. varname := SyntaxTree.invalidIdentifier;
  1826. END;
  1827. channel := PrimaryExpression();
  1828. Check(Scanner.Question);
  1829. target := PrimaryExpression();
  1830. Check(Scanner.Colon);
  1831. (* prolog *)
  1832. IF varname = SyntaxTree.invalidIdentifier THEN
  1833. statement := NewLynxAddsel(position, index, varname, channel, outer);
  1834. statements.AddStatement(statement);
  1835. ELSE
  1836. forStatement := SyntaxTree.NewForStatement(symbol.start, outer);
  1837. designator := SyntaxTree.NewIdentifierDesignator(position, varname);
  1838. forStatement.SetVariable(designator);
  1839. forStatement.SetFrom(from);
  1840. forStatement.SetTo(to);
  1841. forBody := SyntaxTree.NewStatementSequence();
  1842. statement :=
  1843. NewLynxAddsel(position, index, varname, channel, forStatement);
  1844. forBody.AddStatement(statement);
  1845. forStatement.SetStatements(forBody);
  1846. statements.AddStatement(forStatement);
  1847. END;
  1848. (* case part *)
  1849. casePart := SyntaxTree.NewCasePart();
  1850. casePart.elements.AddExpression(SyntaxTree.NewIntegerValue(position, index));
  1851. (* same logic as for switch: *)
  1852. caseBody := StatementList(caseStatement);
  1853. length := caseBody.Length();
  1854. IF length = 0 THEN
  1855. Error(symbol.start, Diagnostics.Invalid, "Fall through in switch section");
  1856. ELSE
  1857. last := caseBody.GetStatement(length-1);
  1858. IF last IS SyntaxTree.ExitStatement THEN
  1859. caseBody.RemoveStatement(last);
  1860. ELSIF ~(last IS SyntaxTree.ReturnStatement) THEN
  1861. Error(symbol.start, Diagnostics.Invalid, "Fall through in switch section");
  1862. END;
  1863. END;
  1864. statement := NewPortStatement(position, lynxReceive, channel(SyntaxTree.Designator), target, caseStatement);
  1865. caseBody.PrependStatement(statement);
  1866. IF varname # SyntaxTree.invalidIdentifier THEN
  1867. statement := NewLynxSelidx(position, varname, caseStatement);
  1868. caseBody.PrependStatement(statement);
  1869. END;
  1870. casePart.SetStatements(caseBody);
  1871. caseStatement.AddCasePart(casePart);
  1872. localIdentTable.CloseScope;
  1873. IF Trace THEN
  1874. E("SelectSection")
  1875. END;
  1876. END SelectSection;
  1877. PROCEDURE SelectStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1878. VAR statement: SyntaxTree.Statement;
  1879. caseStatement: SyntaxTree.CaseStatement;
  1880. expression: SyntaxTree.Expression;
  1881. index: LONGINT;
  1882. position: LONGINT;
  1883. BEGIN
  1884. IF Trace THEN
  1885. S("SelectStatement")
  1886. END;
  1887. position := symbol.start;
  1888. Check(Scanner.Select);
  1889. statement := NewLynxNewsel(position, outer);
  1890. statements.AddStatement(statement);
  1891. caseStatement := SyntaxTree.NewCaseStatement(position, outer);
  1892. expression := NewLynxSelect(position);
  1893. caseStatement.SetVariable(expression);
  1894. Check(Scanner.LeftBrace);
  1895. index := 0;
  1896. WHILE Peek(Scanner.Case) DO
  1897. SelectSection(statements, caseStatement, index, outer);
  1898. INC(index);
  1899. END;
  1900. position := symbol.start;
  1901. Check(Scanner.RightBrace);
  1902. IF index = 0 THEN
  1903. Error(position, Diagnostics.Invalid, "Empty select statement");
  1904. END;
  1905. statements.AddStatement(caseStatement);
  1906. IF Trace THEN
  1907. E("SelectStatement")
  1908. END;
  1909. END SelectStatement;
  1910. (**
  1911. while-statement:
  1912. 'while' '(' boolean-expression ')' embedded-statement
  1913. **)
  1914. PROCEDURE WhileStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1915. VAR expression: SyntaxTree.Expression;
  1916. whileStatement: SyntaxTree.WhileStatement;
  1917. statementSequence: SyntaxTree.StatementSequence;
  1918. b: BOOLEAN;
  1919. BEGIN
  1920. IF Trace THEN
  1921. S("WhileStatement")
  1922. END;
  1923. Check(Scanner.While);
  1924. whileStatement := SyntaxTree.NewWhileStatement(symbol.start, outer);
  1925. (* CommentStatement(whileStatement); *)
  1926. Check(Scanner.LeftParenthesis);
  1927. expression := Expression();
  1928. Check(Scanner.RightParenthesis);
  1929. whileStatement.SetCondition(expression);
  1930. statementSequence := SyntaxTree.NewStatementSequence();
  1931. b := EmbeddedStatement(statementSequence, whileStatement);
  1932. whileStatement.SetStatements(statementSequence);
  1933. statements.AddStatement(whileStatement);
  1934. IF Trace THEN
  1935. E("WhileStatement")
  1936. END;
  1937. END WhileStatement;
  1938. (**
  1939. do-statement:
  1940. 'do' embedded-statement 'while' '(' boolean-expression ')' ';'
  1941. **)
  1942. PROCEDURE DoStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1943. VAR expression: SyntaxTree.Expression;
  1944. repeatStatement: SyntaxTree.RepeatStatement;
  1945. statementSequence: SyntaxTree.StatementSequence;
  1946. position: LONGINT;
  1947. b: BOOLEAN;
  1948. BEGIN
  1949. IF Trace THEN
  1950. S("DoStatement")
  1951. END;
  1952. Check(Scanner.Do);
  1953. repeatStatement := SyntaxTree.NewRepeatStatement(symbol.start, outer);
  1954. (* CommentStatement(repeatStatement); *)
  1955. statementSequence := SyntaxTree.NewStatementSequence();
  1956. b := EmbeddedStatement(statementSequence, repeatStatement);
  1957. repeatStatement.SetStatements(statementSequence);
  1958. Check(Scanner.While);
  1959. Check(Scanner.LeftParenthesis);
  1960. position := symbol.start;
  1961. expression := Expression();
  1962. Check(Scanner.RightParenthesis);
  1963. expression := NewUnaryExpression(position, expression, Scanner.Exclamation);
  1964. repeatStatement.SetCondition(expression);
  1965. statements.AddStatement(repeatStatement);
  1966. IF Trace THEN
  1967. E("DoStatement")
  1968. END;
  1969. END DoStatement;
  1970. (**
  1971. statement-expression-list:
  1972. statement-expression
  1973. statement-expression-list ',' statement-expression
  1974. **)
  1975. PROCEDURE StatementExpressionList(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1976. VAR b: BOOLEAN;
  1977. BEGIN
  1978. IF Trace THEN
  1979. S("StatementExpressionList")
  1980. END;
  1981. REPEAT
  1982. b := StatementExpression(statements, outer, NIL);
  1983. UNTIL ~Optional(Scanner.Comma);
  1984. IF Trace THEN
  1985. E("StatementExpressionList")
  1986. END;
  1987. END StatementExpressionList;
  1988. (**
  1989. for-initializer:
  1990. local-variable-declaration
  1991. statement-expression-list
  1992. **)
  1993. PROCEDURE ForInitializer(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  1994. VAR isDeclaration: BOOLEAN;
  1995. b: BOOLEAN;
  1996. BEGIN
  1997. IF Trace THEN
  1998. S("ForInitializer")
  1999. END;
  2000. IF Peek(Scanner.Bool) OR Peek(Scanner.Sbyte) OR
  2001. Peek(Scanner.Short) OR Peek(Scanner.Int) OR
  2002. Peek(Scanner.Long) OR Peek(Scanner.Char) OR
  2003. Peek(Scanner.Float) OR Peek(Scanner.Double) OR
  2004. Peek(Scanner.Object) OR Peek(Scanner.String) THEN
  2005. LocalVariableDeclaration(statements, outer, NIL);
  2006. ELSIF Peek(Scanner.Identifier) THEN
  2007. (* either local-variable-declaration or statement expression *)
  2008. b := ExpressionOrDeclaration(statements, outer, isDeclaration);
  2009. IF ~isDeclaration & Optional(Scanner.Comma) THEN
  2010. StatementExpressionList(statements, outer);
  2011. END;
  2012. ELSE
  2013. StatementExpressionList(statements, outer);
  2014. END;
  2015. IF Trace THEN
  2016. E("ForInitializer")
  2017. END;
  2018. END ForInitializer;
  2019. (**
  2020. for-iterator:
  2021. statement-expression-list
  2022. **)
  2023. PROCEDURE ForIterator(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  2024. BEGIN
  2025. IF Trace THEN
  2026. S("ForIterator")
  2027. END;
  2028. StatementExpressionList(statements, outer);
  2029. IF Trace THEN
  2030. E("ForIterator")
  2031. END;
  2032. END ForIterator;
  2033. (**
  2034. for-statement:
  2035. 'for' '(' [for-initializer] ';' [for-condition] ';' [for-iterator] ')' embedded-statement
  2036. for-condition:
  2037. boolean-expression
  2038. **)
  2039. PROCEDURE ForStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  2040. VAR expression: SyntaxTree.Expression;
  2041. whileStatement: SyntaxTree.WhileStatement;
  2042. statementSequence: SyntaxTree.StatementSequence;
  2043. iterator: SyntaxTree.StatementSequence;
  2044. position0, position1: LONGINT;
  2045. i: LONGINT;
  2046. b: BOOLEAN;
  2047. BEGIN
  2048. IF Trace THEN
  2049. S("ForStatement")
  2050. END;
  2051. Check(Scanner.For);
  2052. localIdentTable.OpenScope;
  2053. whileStatement := SyntaxTree.NewWhileStatement(symbol.start, outer);
  2054. (* CommentStatement(whileStatement); *)
  2055. Check(Scanner.LeftParenthesis);
  2056. IF ~Optional(Scanner.Semicolon) THEN
  2057. ForInitializer(statements, outer);
  2058. Check(Scanner.Semicolon);
  2059. END;
  2060. position0 := symbol.start;
  2061. position1 := symbol.end;
  2062. IF ~Optional(Scanner.Semicolon) THEN
  2063. expression := Expression();
  2064. Check(Scanner.Semicolon);
  2065. ELSE
  2066. expression := SyntaxTree.NewBooleanValue(position0, TRUE);
  2067. expression.End(position1);
  2068. END;
  2069. IF ~Optional(Scanner.RightParenthesis) THEN
  2070. iterator := SyntaxTree.NewStatementSequence();
  2071. ForIterator(iterator, whileStatement);
  2072. Check(Scanner.RightParenthesis);
  2073. ELSE
  2074. iterator := NIL;
  2075. END;
  2076. whileStatement.SetCondition(expression);
  2077. statementSequence := SyntaxTree.NewStatementSequence();
  2078. b := EmbeddedStatement(statementSequence, whileStatement);
  2079. IF iterator # NIL THEN
  2080. FOR i := 0 TO iterator.Length() - 1 DO
  2081. statementSequence.AddStatement(iterator.GetStatement(i));
  2082. END;
  2083. END;
  2084. whileStatement.SetStatements(statementSequence);
  2085. statements.AddStatement(whileStatement);
  2086. localIdentTable.CloseScope;
  2087. IF Trace THEN
  2088. E("ForStatement")
  2089. END;
  2090. END ForStatement;
  2091. (**
  2092. return-statement:
  2093. 'return' [expression] ';'
  2094. **)
  2095. PROCEDURE ReturnStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  2096. VAR returnStatement: SyntaxTree.ReturnStatement;
  2097. expression: SyntaxTree.Expression;
  2098. BEGIN
  2099. IF Trace THEN
  2100. S("ReturnStatement")
  2101. END;
  2102. Check(Scanner.Return);
  2103. returnStatement := SyntaxTree.NewReturnStatement(symbol.start, outer);
  2104. (* CommentStatement(returnStatement); *)
  2105. IF ~Optional(Scanner.Semicolon) THEN
  2106. expression := Expression();
  2107. returnStatement.SetReturnValue(expression);
  2108. Check(Scanner.Semicolon);
  2109. END;
  2110. statements.AddStatement(returnStatement);
  2111. IF Trace THEN
  2112. E("ReturnStatement")
  2113. END;
  2114. END ReturnStatement;
  2115. (**
  2116. break-statement:
  2117. 'break' ';'
  2118. **)
  2119. PROCEDURE BreakStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement);
  2120. VAR statement: SyntaxTree.Statement;
  2121. BEGIN
  2122. IF Trace THEN
  2123. S("BreakStatement")
  2124. END;
  2125. Check(Scanner.Break);
  2126. statement := SyntaxTree.NewExitStatement(symbol.start, outer);
  2127. (* CommentStatement(statement); *)
  2128. statements.AddStatement(statement);
  2129. Check(Scanner.Semicolon);
  2130. IF Trace THEN
  2131. E("BreakStatement")
  2132. END;
  2133. END BreakStatement;
  2134. (**
  2135. embedded-statement:
  2136. block
  2137. empty-statement
  2138. expression-statement
  2139. selection-statement
  2140. iteration-statement
  2141. jump-statement
  2142. empty-statement:
  2143. ';'
  2144. selection-statement:
  2145. if-statement
  2146. switch-statement
  2147. select-statement
  2148. iteration-statement:
  2149. while-statement
  2150. do-statement
  2151. for-statement
  2152. jump-statement:
  2153. break-statement
  2154. return-statement
  2155. **)
  2156. PROCEDURE EmbeddedStatement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement): BOOLEAN;
  2157. VAR result: BOOLEAN;
  2158. BEGIN
  2159. IF Trace THEN
  2160. S("EmbeddedStatement")
  2161. END;
  2162. IF Optional(Scanner.Semicolon) THEN
  2163. result := FALSE;
  2164. ELSIF Peek(Scanner.LeftBrace) THEN
  2165. Block(statements, outer);
  2166. result := TRUE;
  2167. ELSIF Peek(Scanner.If) THEN
  2168. IfStatement(statements, outer);
  2169. result := TRUE;
  2170. ELSIF Peek(Scanner.Switch) THEN
  2171. SwitchStatement(statements, outer);
  2172. result := TRUE;
  2173. ELSIF Peek(Scanner.Select) THEN
  2174. SelectStatement(statements, outer);
  2175. result := TRUE;
  2176. ELSIF Peek(Scanner.While) THEN
  2177. WhileStatement(statements, outer);
  2178. result := TRUE;
  2179. ELSIF Peek(Scanner.Do) THEN
  2180. DoStatement(statements, outer);
  2181. result := TRUE;
  2182. ELSIF Peek(Scanner.For) THEN
  2183. ForStatement(statements, outer);
  2184. result := TRUE;
  2185. ELSIF Peek(Scanner.Break) THEN
  2186. BreakStatement(statements, outer);
  2187. result := TRUE;
  2188. ELSIF Peek(Scanner.Return) THEN
  2189. ReturnStatement(statements, outer);
  2190. result := TRUE;
  2191. ELSE
  2192. result := ExpressionStatement(statements, outer);
  2193. END;
  2194. IF Trace THEN
  2195. E("EmbeddedStatement")
  2196. END;
  2197. RETURN result;
  2198. END EmbeddedStatement;
  2199. (**
  2200. statement:
  2201. declaration-statement
  2202. embedded-statement
  2203. declaration-statement:
  2204. local-variable-declaration ';'
  2205. local-constant-declaration ';'
  2206. **)
  2207. PROCEDURE ExpressionOrDeclaration(
  2208. statements: SyntaxTree.StatementSequence;
  2209. outer: SyntaxTree.Statement;
  2210. VAR isDeclaration: BOOLEAN): BOOLEAN;
  2211. VAR result: BOOLEAN;
  2212. name0, name1: SyntaxTree.Identifier;
  2213. position0, position1, position2: LONGINT;
  2214. leftBracket: BOOLEAN;
  2215. qualifiedIdentifier: SyntaxTree.QualifiedIdentifier;
  2216. type: SyntaxTree.Type;
  2217. expression: SyntaxTree.Expression;
  2218. expressionList: SyntaxTree.ExpressionList;
  2219. BEGIN
  2220. name0 := Identifier(position0);
  2221. IF Optional(Scanner.Period) THEN
  2222. name1 := Identifier(position1);
  2223. ELSE
  2224. name1 := SyntaxTree.invalidIdentifier;
  2225. END;
  2226. isDeclaration := FALSE;
  2227. leftBracket := FALSE;
  2228. position2 := symbol.start;
  2229. IF Peek(Scanner.Identifier) THEN
  2230. isDeclaration := TRUE;
  2231. ELSIF Optional(Scanner.LeftBracket) THEN
  2232. leftBracket := TRUE;
  2233. IF Peek(Scanner.RightBracket) OR Peek(Scanner.Comma) THEN
  2234. isDeclaration := TRUE;
  2235. END;
  2236. END;
  2237. IF isDeclaration THEN
  2238. (* local-variable-declaration *)
  2239. IF name1 = SyntaxTree.invalidIdentifier THEN
  2240. name1 := name0;
  2241. name0 := SyntaxTree.invalidIdentifier;
  2242. END;
  2243. qualifiedIdentifier := SyntaxTree.NewQualifiedIdentifier(position0, name0, name1);
  2244. type := SyntaxTree.NewQualifiedType(
  2245. qualifiedIdentifier.position, currentScope, qualifiedIdentifier);
  2246. IF leftBracket THEN
  2247. type := RankSpecifier(type);
  2248. Check(Scanner.RightBracket);
  2249. END;
  2250. WHILE Optional(Scanner.LeftBracket) DO
  2251. type := RankSpecifier(type);
  2252. Check(Scanner.RightBracket);
  2253. END;
  2254. LocalVariableDeclaration(statements, outer, type);
  2255. ELSE
  2256. (* expression-statement *)
  2257. name0 := localIdentTable.Find(name0);
  2258. expression := SyntaxTree.NewIdentifierDesignator(position0, name0);
  2259. IF name1 # SyntaxTree.invalidIdentifier THEN
  2260. expression := SyntaxTree.NewSelectorDesignator(position1, expression(SyntaxTree.Designator), name1);
  2261. END;
  2262. IF leftBracket THEN
  2263. expressionList := SyntaxTree.NewExpressionList();
  2264. ExpressionList(expressionList);
  2265. Check(Scanner.RightBracket);
  2266. expression := SyntaxTree.NewBracketDesignator(position2, expression(SyntaxTree.Designator), expressionList);
  2267. END;
  2268. expression := Accessors(expression, FALSE);
  2269. result := StatementExpression(statements, outer, expression);
  2270. END;
  2271. RETURN result;
  2272. END ExpressionOrDeclaration;
  2273. PROCEDURE Statement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement): BOOLEAN;
  2274. VAR result: BOOLEAN;
  2275. isDeclaration: BOOLEAN;
  2276. BEGIN
  2277. IF Trace THEN
  2278. S("Statement")
  2279. END;
  2280. IF Peek(Scanner.Const) THEN
  2281. LocalConstantDeclaration(statements, outer);
  2282. Check(Scanner.Semicolon);
  2283. result := TRUE;
  2284. ELSIF Peek(Scanner.Bool) OR Peek(Scanner.Sbyte) OR
  2285. Peek(Scanner.Short) OR Peek(Scanner.Int) OR
  2286. Peek(Scanner.Long) OR Peek(Scanner.Char) OR
  2287. Peek(Scanner.Float) OR Peek(Scanner.Double) OR
  2288. Peek(Scanner.Object) OR Peek(Scanner.String) THEN
  2289. LocalVariableDeclaration(statements, outer, NIL);
  2290. Check(Scanner.Semicolon);
  2291. result := TRUE;
  2292. ELSIF Peek(Scanner.Identifier) THEN
  2293. (* either local-variable-declaration or statement expression *)
  2294. result := ExpressionOrDeclaration(statements, outer, isDeclaration);
  2295. Check(Scanner.Semicolon);
  2296. ELSE
  2297. result := EmbeddedStatement(statements, outer);
  2298. END;
  2299. IF Trace THEN
  2300. E("Statement")
  2301. END;
  2302. RETURN result;
  2303. END Statement;
  2304. (**
  2305. statement-list:
  2306. statement
  2307. statement-list statement
  2308. **)
  2309. PROCEDURE StatementList(outer: SyntaxTree.Statement): SyntaxTree.StatementSequence;
  2310. VAR statements: SyntaxTree.StatementSequence;
  2311. b: BOOLEAN;
  2312. BEGIN
  2313. IF Trace THEN
  2314. S("StatementList")
  2315. END;
  2316. statements := SyntaxTree.NewStatementSequence();
  2317. REPEAT
  2318. b := Statement(statements, outer);
  2319. UNTIL Peek(Scanner.RightBrace) OR Peek(Scanner.Case) OR Peek(Scanner.Default) ;
  2320. IF Trace THEN
  2321. E("StatementList")
  2322. END;
  2323. RETURN statements;
  2324. END StatementList;
  2325. (**
  2326. block:
  2327. '{' [statement-list] '}'
  2328. **)
  2329. PROCEDURE Body(scope: SyntaxTree.ProcedureScope): SyntaxTree.Body;
  2330. VAR body: SyntaxTree.Body;
  2331. previousScope: SyntaxTree.Scope;
  2332. BEGIN
  2333. IF Trace THEN
  2334. S("Body")
  2335. END;
  2336. previousScope := currentScope;
  2337. currentScope := scope;
  2338. Check(Scanner.LeftBrace);
  2339. body := SyntaxTree.NewBody(symbol.start, scope);
  2340. IF ~Optional(Scanner.RightBrace) THEN
  2341. body.SetStatementSequence(StatementList(body));
  2342. Check(Scanner.RightBrace);
  2343. END;
  2344. currentScope := previousScope;
  2345. IF Trace THEN
  2346. E("Body")
  2347. END;
  2348. RETURN body;
  2349. END Body;
  2350. (**
  2351. type:
  2352. value-type
  2353. reference-type
  2354. port-type
  2355. value-type:
  2356. struct-type
  2357. struct-type:
  2358. type-name
  2359. simple-type
  2360. simple-type:
  2361. numeric-type
  2362. 'bool'
  2363. numeric-type:
  2364. integral-type
  2365. floating-point-type
  2366. integral-type:
  2367. 'sbyte'
  2368. 'short'
  2369. 'int'
  2370. 'long'
  2371. 'char'
  2372. floating-point-type:
  2373. 'float'
  2374. 'double'
  2375. reference-type:
  2376. class-type
  2377. array-type
  2378. delegate-type
  2379. class-type:
  2380. type-name
  2381. 'object'
  2382. 'string'
  2383. array-type:
  2384. non-array-type rank-specifiers
  2385. non-array-type:
  2386. value-type
  2387. class-type
  2388. delegate-type
  2389. rank-specifiers:
  2390. rank-specifier
  2391. rank-specifiers rank-specifier
  2392. rank-specifier:
  2393. '[' [dim-separators] ']'
  2394. dim-separators:
  2395. ','
  2396. dim-separators ','
  2397. delegate-type:
  2398. type-name
  2399. **)
  2400. PROCEDURE RankSpecifier(type: SyntaxTree.Type): SyntaxTree.Type;
  2401. VAR position: LONGINT;
  2402. arrayType: SyntaxTree.ArrayType;
  2403. pointerType: SyntaxTree.PointerType;
  2404. BEGIN
  2405. IF Trace THEN
  2406. S("RankSpecifier")
  2407. END;
  2408. position := symbol.start;
  2409. REPEAT
  2410. arrayType := SyntaxTree.NewArrayType(position, currentScope, SyntaxTree.Open);
  2411. arrayType.SetArrayBase(type);
  2412. type := arrayType;
  2413. UNTIL ~Optional(Scanner.Comma);
  2414. pointerType := SyntaxTree.NewPointerType(position, currentScope);
  2415. pointerType.SetPointerBase(type);
  2416. type := pointerType;
  2417. IF Trace THEN
  2418. E("RankSpecifier")
  2419. END;
  2420. RETURN type;
  2421. END RankSpecifier;
  2422. PROCEDURE NonArrayType(): SyntaxTree.Type;
  2423. VAR type: SyntaxTree.Type;
  2424. position: LONGINT;
  2425. name: SyntaxTree.Identifier;
  2426. direction: LONGINT;
  2427. qualifiedIdentifier: SyntaxTree.QualifiedIdentifier;
  2428. BEGIN
  2429. IF Trace THEN
  2430. S("NonArrayType")
  2431. END;
  2432. position := symbol.start;
  2433. name := SyntaxTree.invalidIdentifier;
  2434. direction := -1;
  2435. IF Optional(Scanner.Bool) THEN
  2436. name := lynxBool;
  2437. ELSIF Optional(Scanner.Sbyte) THEN
  2438. name := lynxSbyte;
  2439. ELSIF Optional(Scanner.Short) THEN
  2440. name := lynxShort;
  2441. ELSIF Optional(Scanner.Int) THEN
  2442. name := lynxInt;
  2443. ELSIF Optional(Scanner.Long) THEN
  2444. name := lynxLong;
  2445. ELSIF Optional(Scanner.Char) THEN
  2446. name := lynxChar;
  2447. ELSIF Optional(Scanner.Float) THEN
  2448. name := lynxFloat;
  2449. ELSIF Optional(Scanner.Double) THEN
  2450. name := lynxDouble;
  2451. ELSIF Optional(Scanner.Object) THEN
  2452. name := lynxObject;
  2453. ELSIF Optional(Scanner.String) THEN
  2454. name := lynxString;
  2455. ELSIF Optional(Scanner.In) THEN
  2456. direction := SyntaxTree.InPort;
  2457. ELSIF Optional(Scanner.Out) THEN
  2458. direction := SyntaxTree.OutPort;
  2459. END;
  2460. IF direction >= 0 THEN
  2461. type := SyntaxTree.NewPortType(position, direction, NIL, currentScope);
  2462. ELSE
  2463. IF name # SyntaxTree.invalidIdentifier THEN
  2464. qualifiedIdentifier :=
  2465. SyntaxTree.NewQualifiedIdentifier(
  2466. position, SyntaxTree.invalidIdentifier, name);
  2467. ELSE
  2468. qualifiedIdentifier := QualifiedIdentifier();
  2469. END;
  2470. type := SyntaxTree.NewQualifiedType(
  2471. qualifiedIdentifier.position, currentScope, qualifiedIdentifier);
  2472. END;
  2473. IF Trace THEN
  2474. E("NonArrayType")
  2475. END;
  2476. RETURN type;
  2477. END NonArrayType;
  2478. PROCEDURE Type(): SyntaxTree.Type;
  2479. VAR type: SyntaxTree.Type;
  2480. BEGIN
  2481. IF Trace THEN
  2482. S("Type")
  2483. END;
  2484. type := NonArrayType();
  2485. WHILE Optional(Scanner.LeftBracket) DO
  2486. type := RankSpecifier(type);
  2487. Check(Scanner.RightBracket);
  2488. END;
  2489. IF Trace THEN
  2490. E("Type")
  2491. END;
  2492. RETURN type;
  2493. END Type;
  2494. (**
  2495. attributes:
  2496. '[' attribute-list ']'
  2497. attribute-list:
  2498. attribute
  2499. attribute-list ',' attribute
  2500. attribute:
  2501. attribute-name [attribute-argument]
  2502. attribute-name:
  2503. identifier
  2504. attribute-argument:
  2505. '(' attribute-argument-expression ')'
  2506. attribute-argument-expression:
  2507. expression
  2508. **)
  2509. PROCEDURE AppendModifier(VAR list: SyntaxTree.Modifier; modifier: SyntaxTree.Modifier);
  2510. VAR this, next: SyntaxTree.Modifier;
  2511. BEGIN
  2512. IF list = NIL THEN
  2513. list := modifier
  2514. ELSE
  2515. this := list;
  2516. next := list.nextModifier;
  2517. WHILE next # NIL DO
  2518. this := next;
  2519. next := this.nextModifier;
  2520. END;
  2521. this.SetNext(modifier);
  2522. END;
  2523. END AppendModifier;
  2524. PROCEDURE Attributes(): SyntaxTree.Modifier;
  2525. VAR identifier: SyntaxTree.Identifier;
  2526. modifier, list: SyntaxTree.Modifier;
  2527. position: LONGINT;
  2528. expression: SyntaxTree.Expression;
  2529. BEGIN
  2530. IF Trace THEN
  2531. S("Attributes")
  2532. END;
  2533. (* left bracket already consumed *)
  2534. list := NIL;
  2535. REPEAT
  2536. position := symbol.start;
  2537. identifier := Identifier(position);
  2538. IF Optional(Scanner.LeftParenthesis) THEN
  2539. expression := Expression();
  2540. Check(Scanner.RightParenthesis);
  2541. ELSE
  2542. expression := NIL;
  2543. END;
  2544. modifier := SyntaxTree.NewModifier(position, identifier, expression);
  2545. AppendModifier(list, modifier);
  2546. UNTIL ~Optional(Scanner.Comma);
  2547. Check(Scanner.RightBracket);
  2548. IF Trace THEN
  2549. E("Attributes")
  2550. END;
  2551. RETURN list;
  2552. END Attributes;
  2553. (**
  2554. constant-modifiers:
  2555. constant-modifier
  2556. constant-modifiers constant-modifier
  2557. constant-modifier:
  2558. 'public'
  2559. field-modifiers:
  2560. field-modifier
  2561. field-modifiers field-modifier
  2562. field-modifier:
  2563. 'public'
  2564. 'internal'
  2565. method-modifiers:
  2566. method-modifier
  2567. method-modifiers method-modifier
  2568. method-modifier:
  2569. 'public'
  2570. constructor-modifiers:
  2571. constructor-modifier
  2572. constructor-modifiers constructor-modifier
  2573. constructor-modifier:
  2574. public
  2575. class-modifiers:
  2576. class-modifier
  2577. class-modifiers class-modifier
  2578. class-modifier:
  2579. 'public'
  2580. struct-modifiers:
  2581. struct-modifier
  2582. struct-modifiers struct-modifier
  2583. struct-modifier:
  2584. 'public'
  2585. delegate-modifiers:
  2586. delegate-modifier
  2587. delegate-modifiers delegate-modifier
  2588. delegate-modifier:
  2589. 'public'
  2590. **)
  2591. PROCEDURE Modifiers(VAR modifiers: SET);
  2592. BEGIN
  2593. modifiers := {};
  2594. LOOP
  2595. IF Optional(Scanner.Public) THEN
  2596. INCL(modifiers, Public);
  2597. ELSIF Optional(Scanner.Internal) THEN
  2598. INCL(modifiers, Internal);
  2599. ELSE
  2600. EXIT;
  2601. END;
  2602. END;
  2603. END Modifiers;
  2604. PROCEDURE IdentifierAccess(modifiers: SET; allowedReadOnly: BOOLEAN): SET;
  2605. VAR access: SET;
  2606. BEGIN
  2607. IF modifiers * {Public, Internal} = {Public, Internal} THEN
  2608. Error(symbol.start, Diagnostics.Invalid, "conflicting modifiers");
  2609. END;
  2610. IF Public IN modifiers THEN
  2611. access := SyntaxTree.Public + SyntaxTree.Protected + SyntaxTree.Internal;
  2612. ELSIF Internal IN modifiers THEN
  2613. IF ~allowedReadOnly THEN
  2614. Error(symbol.start, Diagnostics.Invalid, "may not be defined internal")
  2615. ELSE
  2616. access := SyntaxTree.ReadOnly + {SyntaxTree.InternalWrite};
  2617. END;
  2618. ELSE
  2619. access := SyntaxTree.Internal;
  2620. END;
  2621. RETURN access;
  2622. END IdentifierAccess;
  2623. (**
  2624. constant-declaration:
  2625. [constant-modifiers] 'const' type constant-declarators ';'
  2626. constant-declarators:
  2627. constant-declarator
  2628. constant-declarators ',' constant-declarator
  2629. constant-declarator:
  2630. identifier '=' constant-expression
  2631. **)
  2632. PROCEDURE ConstantDeclarator(
  2633. parentScope: SyntaxTree.Scope;
  2634. modifiers: SET;
  2635. type: SyntaxTree.Type);
  2636. VAR name: SyntaxTree.Identifier;
  2637. position: LONGINT;
  2638. constant: SyntaxTree.Constant;
  2639. expression: SyntaxTree.Expression;
  2640. access: SET;
  2641. BEGIN
  2642. IF Trace THEN
  2643. S("ConstantDeclarator")
  2644. END;
  2645. name := Identifier(position);
  2646. name := localIdentTable.Enter(name);
  2647. access := IdentifierAccess(modifiers, FALSE);
  2648. constant := SyntaxTree.NewConstant(position, name);
  2649. CommentSymbol(constant);
  2650. constant.SetAccess(access);
  2651. (* ACHTUNG: Make sure that Fox semantic checker will respect a type set at this stage: *)
  2652. constant.SetType(type);
  2653. Check(Scanner.Equal);
  2654. expression := Expression();
  2655. constant.SetValue(expression);
  2656. parentScope.AddConstant(constant);
  2657. IF Trace THEN
  2658. E("ConstantDeclarator")
  2659. END;
  2660. END ConstantDeclarator;
  2661. PROCEDURE ConstantDeclaration(parentScope: SyntaxTree.Scope; modifiers: SET);
  2662. VAR type: SyntaxTree.Type;
  2663. BEGIN
  2664. IF Trace THEN
  2665. S("ConstantDeclaration")
  2666. END;
  2667. type := Type();
  2668. REPEAT
  2669. ConstantDeclarator(parentScope, modifiers, type);
  2670. UNTIL ~Optional(Scanner.Comma);
  2671. Check(Scanner.Semicolon);
  2672. IF Trace THEN
  2673. E("ConstantDeclaration")
  2674. END;
  2675. END ConstantDeclaration;
  2676. (**
  2677. field-declaration:
  2678. [field-modifiers] type variable-declarators ';'
  2679. field-modifiers:
  2680. field-modifier
  2681. field-modifiers field-modifier
  2682. variable-declarators:
  2683. variable-declarator
  2684. variable-declarators ',' variable-declarator
  2685. variable-declarator:
  2686. identifier
  2687. identifier '=' variable-initializer
  2688. variable-initializer:
  2689. expression
  2690. // array-initializer
  2691. **)
  2692. PROCEDURE VariableDeclarator(
  2693. parentScope: SyntaxTree.Scope;
  2694. modifiers: SET;
  2695. type: SyntaxTree.Type;
  2696. name: SyntaxTree.Identifier;
  2697. position: LONGINT);
  2698. VAR variable: SyntaxTree.Variable;
  2699. expression: SyntaxTree.Expression;
  2700. designator: SyntaxTree.Designator;
  2701. statement: SyntaxTree.Statement;
  2702. start: LONGINT;
  2703. access: SET;
  2704. BEGIN
  2705. IF Trace THEN
  2706. S("VariableDeclarator")
  2707. END;
  2708. IF name = SyntaxTree.invalidIdentifier THEN
  2709. name := Identifier(position);
  2710. END;
  2711. name := localIdentTable.Enter(name);
  2712. access := IdentifierAccess(modifiers, TRUE);
  2713. variable := SyntaxTree.NewVariable(position, name);
  2714. CommentSymbol(variable);
  2715. variable.SetAccess(access);
  2716. variable.SetType(type);
  2717. parentScope.AddVariable(variable);
  2718. start := symbol.start;
  2719. (* 'initOuter' is set to NIL in contexts where initialization is not yet implemented *)
  2720. IF (initOuter # NIL) & Optional(Scanner.Equal) THEN
  2721. (* ACHTUNG: array-initializer form is not supported *)
  2722. designator := SyntaxTree.NewIdentifierDesignator(position, name);
  2723. expression := Expression();
  2724. statement := SyntaxTree.NewAssignment(start, designator, expression, initOuter);
  2725. initStatements.AddStatement(statement);
  2726. END;
  2727. IF Trace THEN
  2728. E("VariableDeclarator")
  2729. END;
  2730. END VariableDeclarator;
  2731. PROCEDURE FieldDeclaration(
  2732. parentScope: SyntaxTree.Scope;
  2733. modifiers: SET;
  2734. type: SyntaxTree.Type;
  2735. name: SyntaxTree.Identifier;
  2736. position: LONGINT);
  2737. BEGIN
  2738. IF Trace THEN
  2739. S("FieldDeclaration")
  2740. END;
  2741. REPEAT
  2742. VariableDeclarator(parentScope, modifiers, type, name, position);
  2743. name := SyntaxTree.invalidIdentifier;
  2744. position := invalidPosition;
  2745. UNTIL ~Optional(Scanner.Comma);
  2746. Check(Scanner.Semicolon);
  2747. IF Trace THEN
  2748. E("FieldDeclaration")
  2749. END;
  2750. END FieldDeclaration;
  2751. (**
  2752. formal-parameter-list:
  2753. fixed-parameters
  2754. fixed-parameters:
  2755. fixed-parameter
  2756. fixed-parameters ',' fixed-parameter
  2757. fixed-parameter:
  2758. [parameter-modifier] type identifier
  2759. parameter-modifier:
  2760. 'ref'
  2761. **)
  2762. PROCEDURE FixedParameter(procedureType: SyntaxTree.ProcedureType; parentScope: SyntaxTree.Scope);
  2763. VAR type: SyntaxTree.Type;
  2764. name: SyntaxTree.Identifier;
  2765. parameter: SyntaxTree.Parameter;
  2766. kind, position: LONGINT;
  2767. BEGIN
  2768. IF Trace THEN
  2769. S("FixedParameter")
  2770. END;
  2771. IF Optional(Scanner.Ref) THEN
  2772. kind := SyntaxTree.VarParameter;
  2773. ELSE
  2774. kind := SyntaxTree.ValueParameter;
  2775. END;
  2776. type := Type();
  2777. name := Identifier(position);
  2778. parameter := SyntaxTree.NewParameter(position, procedureType, name, kind);
  2779. procedureType.AddParameter(parameter);
  2780. parameter.SetType(type);
  2781. IF Trace THEN
  2782. E("FixedParameter")
  2783. END;
  2784. END FixedParameter;
  2785. PROCEDURE FormalParameterList(
  2786. procedureType: SyntaxTree.ProcedureType;
  2787. parentScope: SyntaxTree.Scope;
  2788. returnType: SyntaxTree.Type);
  2789. BEGIN
  2790. IF Trace THEN
  2791. S("FormalParameterList")
  2792. END;
  2793. Check(Scanner.LeftParenthesis);
  2794. IF ~Optional(Scanner.RightParenthesis) THEN
  2795. REPEAT
  2796. FixedParameter(procedureType, parentScope);
  2797. UNTIL ~Optional(Scanner.Comma);
  2798. Check(Scanner.RightParenthesis);
  2799. END;
  2800. IF returnType # NIL THEN
  2801. procedureType.SetReturnType(returnType);
  2802. END;
  2803. IF Trace THEN
  2804. E("FormalParameterList")
  2805. END;
  2806. END FormalParameterList;
  2807. (**
  2808. constructor-initializer:
  2809. ':' 'base' '(' [argument-list] ')'
  2810. **)
  2811. PROCEDURE ConstructorInitializer(scope: SyntaxTree.ProcedureScope);
  2812. BEGIN
  2813. IF Trace THEN
  2814. S("ConstructorInitializer")
  2815. END;
  2816. (* TODO *)
  2817. IF Trace THEN
  2818. E("ConstructorInitializer")
  2819. END;
  2820. END ConstructorInitializer;
  2821. (**
  2822. method-declaration:
  2823. method-header method-body
  2824. method-header:
  2825. [method-modifiers] return-type member-name '(' [formal-parameter-list] ')'
  2826. return-type:
  2827. type
  2828. 'void'
  2829. member-name:
  2830. identifier
  2831. method-body:
  2832. block
  2833. constructor-declaration:
  2834. [constructor-modifiers] constructor-declarator constructor-body
  2835. constructor-declarator:
  2836. identifier ( [formal-parameter-list] ) [constructor-initializer]
  2837. constructor-body:
  2838. block
  2839. **)
  2840. PROCEDURE ProcedureDeclaration(
  2841. parentScope: SyntaxTree.Scope;
  2842. modifiers: SET;
  2843. type: SyntaxTree.Type;
  2844. name: SyntaxTree.Identifier;
  2845. position: LONGINT;
  2846. isConstructor: BOOLEAN);
  2847. VAR procedure: SyntaxTree.Procedure;
  2848. procedureType: SyntaxTree.ProcedureType;
  2849. procedureScope: SyntaxTree.ProcedureScope;
  2850. previousScope: SyntaxTree.Scope;
  2851. access: SET;
  2852. body: SyntaxTree.Body;
  2853. BEGIN
  2854. procedureType := SyntaxTree.NewProcedureType(position, parentScope);
  2855. access := IdentifierAccess(modifiers, FALSE);
  2856. procedureScope := SyntaxTree.NewProcedureScope(parentScope);
  2857. procedure := SyntaxTree.NewProcedure(position, name, procedureScope);
  2858. procedure.SetConstructor(isConstructor);
  2859. CommentSymbol(procedure);
  2860. procedure.SetAccess(access);
  2861. procedure.SetType(procedureType);
  2862. FormalParameterList(procedureType, procedureScope, type);
  2863. IF isConstructor & Optional(Scanner.Colon) THEN
  2864. (* TODO: Connect initializer to the body *)
  2865. ConstructorInitializer(procedureScope);
  2866. END;
  2867. previousScope := currentScope;
  2868. currentScope := procedureScope;
  2869. body := Body(procedureScope);
  2870. currentScope := previousScope;
  2871. procedureScope.SetBody(body);
  2872. parentScope.AddProcedure(procedure);
  2873. END ProcedureDeclaration;
  2874. PROCEDURE MethodDeclaration(
  2875. parentScope: SyntaxTree.Scope;
  2876. modifiers: SET;
  2877. type: SyntaxTree.Type;
  2878. name: SyntaxTree.Identifier;
  2879. position: LONGINT);
  2880. BEGIN
  2881. IF Trace THEN
  2882. S("MethodDeclaration")
  2883. END;
  2884. localIdentTable.Reset;
  2885. IF (name = identMain) &
  2886. (parentScope IS SyntaxTree.CellScope) &
  2887. ~parentScope(SyntaxTree.CellScope).ownerCell.isCellNet THEN
  2888. (* bodies of cells are represented as main() functions *)
  2889. BodyDeclaration(parentScope, modifiers, type, name, position);
  2890. ELSE
  2891. ProcedureDeclaration(parentScope, modifiers, type, name, position, FALSE);
  2892. END;
  2893. IF Trace THEN
  2894. E("MethodDeclaration")
  2895. END;
  2896. END MethodDeclaration;
  2897. PROCEDURE ConstructorDeclaration(
  2898. parentScope: SyntaxTree.Scope;
  2899. modifiers: SET;
  2900. name: SyntaxTree.Identifier;
  2901. position: LONGINT);
  2902. BEGIN
  2903. IF Trace THEN
  2904. S("ConstructorDeclaration")
  2905. END;
  2906. localIdentTable.Reset;
  2907. IF (parentScope IS SyntaxTree.ModuleScope) OR
  2908. ((parentScope IS SyntaxTree.CellScope) &
  2909. parentScope(SyntaxTree.CellScope).ownerCell.isCellNet) THEN
  2910. (* bodies of modules and cellnets are represented as constructors *)
  2911. BodyDeclaration(parentScope, modifiers, NIL, name, position);
  2912. ELSE
  2913. ProcedureDeclaration(parentScope, modifiers, NIL, name, position, TRUE);
  2914. END;
  2915. IF Trace THEN
  2916. E("ConstructorDeclaration")
  2917. END;
  2918. END ConstructorDeclaration;
  2919. PROCEDURE BodyDeclaration(
  2920. parentScope: SyntaxTree.Scope;
  2921. modifiers: SET;
  2922. type: SyntaxTree.Type;
  2923. name: SyntaxTree.Identifier;
  2924. position: LONGINT);
  2925. VAR procedureScope: SyntaxTree.ProcedureScope;
  2926. procedureType: SyntaxTree.ProcedureType;
  2927. procedure: SyntaxTree.Procedure;
  2928. BEGIN
  2929. procedureScope := SyntaxTree.NewProcedureScope(parentScope);
  2930. IF parentScope IS SyntaxTree.ModuleScope THEN
  2931. procedure := SyntaxTree.NewProcedure(position, Global.ModuleBodyName, procedureScope);
  2932. procedure.SetAccess(SyntaxTree.Hidden);
  2933. ELSE
  2934. procedure := SyntaxTree.NewProcedure(position, Global.RecordBodyName, procedureScope);
  2935. procedure.SetAccess(SyntaxTree.Public+SyntaxTree.Protected+SyntaxTree.Internal);
  2936. END;
  2937. parentScope.AddProcedure(procedure);
  2938. procedureType := SyntaxTree.NewProcedureType(position, parentScope);
  2939. FormalParameterList(procedureType, procedureScope, type);
  2940. IF procedureType.numberParameters # 0 THEN
  2941. Error(position, Diagnostics.Invalid, "constructor/main has parameters");
  2942. ELSIF procedureType.returnType # NIL THEN
  2943. Error(position, Diagnostics.Invalid, "constructor/main returns value");
  2944. END;
  2945. procedure.SetType(procedureType);
  2946. procedure.SetBodyProcedure(TRUE);
  2947. procedureScope.SetBody(Body(procedureScope));
  2948. IF parentScope IS SyntaxTree.ModuleScope THEN
  2949. parentScope(SyntaxTree.ModuleScope).SetBodyProcedure(procedure);
  2950. ELSE
  2951. parentScope(SyntaxTree.CellScope).SetBodyProcedure(procedure);
  2952. END;
  2953. END BodyDeclaration;
  2954. (**
  2955. class-declaration:
  2956. [class-modifiers] 'class' identifier [class-base] class-body [';']
  2957. class-base:
  2958. ':' class-type
  2959. class-body:
  2960. '{' [class-member-declarations] '}'
  2961. class-member-declarations:
  2962. class-member-declaration
  2963. class-member-declarations class-member-declaration
  2964. class-member-declaration:
  2965. constant-declaration
  2966. field-declaration
  2967. method-declaration
  2968. constructor-declaration
  2969. type-declaration
  2970. type-declaration:
  2971. class-declaration
  2972. struct-declaration
  2973. delegate-declaration
  2974. cell-declaration
  2975. cellnet-declaration
  2976. **)
  2977. PROCEDURE MemberDeclaration(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  2978. VAR attributes: SyntaxTree.Modifier;
  2979. modifiers: SET;
  2980. type: SyntaxTree.Type;
  2981. name: SyntaxTree.Identifier;
  2982. position: LONGINT;
  2983. BEGIN
  2984. IF Optional(Scanner.LeftBracket) THEN
  2985. attributes := Attributes();
  2986. ELSE
  2987. attributes := NIL;
  2988. END;
  2989. Modifiers(modifiers);
  2990. IF Optional(Scanner.Const) THEN
  2991. ConstantDeclaration(parentScope, modifiers);
  2992. ELSIF Optional(Scanner.Class) THEN
  2993. ClassDeclaration(parentScope, modifiers);
  2994. ELSIF Optional(Scanner.Struct) THEN
  2995. StructDeclaration(parentScope, modifiers);
  2996. ELSIF Optional(Scanner.Delegate) THEN
  2997. DelegateDeclaration(parentScope, modifiers);
  2998. ELSIF Optional(Scanner.Cell) THEN
  2999. CellDeclaration(parentScope, modifiers, attributes, FALSE);
  3000. ELSIF Optional(Scanner.Cellnet) THEN
  3001. CellDeclaration(parentScope, modifiers, attributes, TRUE);
  3002. ELSIF Peek(Scanner.Identifier) & (symbol.identifier = parentName) THEN
  3003. name := Identifier(position);
  3004. ConstructorDeclaration(parentScope, modifiers, name, position);
  3005. ELSIF Optional(Scanner.Void) THEN
  3006. name := Identifier(position);
  3007. MethodDeclaration(parentScope, modifiers, NIL, name, position);
  3008. ELSE
  3009. type := Type();
  3010. name := Identifier(position);
  3011. IF Peek(Scanner.LeftParenthesis) THEN
  3012. MethodDeclaration(parentScope, modifiers, type, name, position);
  3013. ELSE
  3014. FieldDeclaration(parentScope, modifiers, type, name, position);
  3015. END;
  3016. END;
  3017. END MemberDeclaration;
  3018. PROCEDURE ClassMemberDeclaration(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3019. BEGIN
  3020. IF Trace THEN
  3021. S("ClassMemberDeclaration")
  3022. END;
  3023. MemberDeclaration(parentScope, parentName);
  3024. IF Trace THEN
  3025. E("ClassMemberDeclaration")
  3026. END;
  3027. END ClassMemberDeclaration;
  3028. PROCEDURE ClassMemberDeclarations(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3029. VAR previousScope: SyntaxTree.Scope;
  3030. BEGIN
  3031. IF Trace THEN
  3032. S("ClassMemberDeclarations")
  3033. END;
  3034. previousScope := currentScope;
  3035. currentScope := parentScope;
  3036. WHILE ~Peek(Scanner.RightBrace) DO
  3037. ClassMemberDeclaration(parentScope, parentName);
  3038. END;
  3039. currentScope := previousScope;
  3040. IF Trace THEN
  3041. E("ClassMemberDeclarations")
  3042. END;
  3043. END ClassMemberDeclarations;
  3044. PROCEDURE ClassDeclaration(parentScope: SyntaxTree.Scope; modifiers: SET);
  3045. VAR name: SyntaxTree.Identifier;
  3046. position: LONGINT;
  3047. typeDeclaration: SyntaxTree.TypeDeclaration;
  3048. access: SET;
  3049. objectType: SyntaxTree.RecordType;
  3050. pointerType: SyntaxTree.PointerType;
  3051. recordScope: SyntaxTree.RecordScope;
  3052. qualifiedIdentifier: SyntaxTree.QualifiedIdentifier;
  3053. baseType: SyntaxTree.Type;
  3054. previousStatements: SyntaxTree.StatementSequence;
  3055. previousOuter: SyntaxTree.Statement;
  3056. b: BOOLEAN;
  3057. BEGIN
  3058. IF Trace THEN
  3059. S("ClassDeclaration")
  3060. END;
  3061. previousStatements := initStatements;
  3062. previousOuter := initOuter;
  3063. (* TODO: Implement initialization of fields *)
  3064. initStatements := NIL;
  3065. initOuter := NIL;
  3066. EnterInit;
  3067. (* symbol 'class' already consumed *)
  3068. name := Identifier(position);
  3069. access := IdentifierAccess(modifiers, FALSE);
  3070. typeDeclaration := SyntaxTree.NewTypeDeclaration(position, name);
  3071. CommentSymbol(typeDeclaration);
  3072. recordScope := SyntaxTree.NewRecordScope(parentScope);
  3073. pointerType := SyntaxTree.NewPointerType(position, parentScope);
  3074. objectType := SyntaxTree.NewRecordType(position, parentScope, recordScope);
  3075. objectType.IsObject(TRUE);
  3076. objectType.SetPointerType(pointerType);
  3077. pointerType.SetPointerBase(objectType);
  3078. IF Optional(Scanner.Colon) THEN
  3079. qualifiedIdentifier := QualifiedIdentifier();
  3080. baseType := SyntaxTree.NewQualifiedType(
  3081. qualifiedIdentifier.position, parentScope, qualifiedIdentifier);
  3082. objectType.SetBaseType(baseType);
  3083. END;
  3084. Check(Scanner.LeftBrace);
  3085. ClassMemberDeclarations(recordScope, name);
  3086. Check(Scanner.RightBrace);
  3087. b := Optional(Scanner.Semicolon);
  3088. pointerType.SetTypeDeclaration(typeDeclaration);
  3089. typeDeclaration.SetDeclaredType(pointerType);
  3090. typeDeclaration.SetAccess(access);
  3091. parentScope.AddTypeDeclaration(typeDeclaration);
  3092. initStatements := previousStatements;
  3093. initOuter := previousOuter;
  3094. IF Trace THEN
  3095. E("ClassDeclaration")
  3096. END;
  3097. END ClassDeclaration;
  3098. (**
  3099. struct-declaration:
  3100. [struct-modifiers] 'struct' identifier struct-body [';']
  3101. struct-body:
  3102. '{' [struct-member-declarations] '}'
  3103. struct-member-declarations:
  3104. struct-member-declaration
  3105. struct-member-declarations struct-member-declaration
  3106. struct-member-declaration:
  3107. constant-declaration
  3108. field-declaration
  3109. method-declaration
  3110. constructor-declaration
  3111. type-declaration
  3112. **)
  3113. PROCEDURE StructMemberDeclaration(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3114. BEGIN
  3115. IF Trace THEN
  3116. S("StructMemberDeclaration")
  3117. END;
  3118. MemberDeclaration(parentScope, parentName);
  3119. IF Trace THEN
  3120. E("StructMemberDeclaration")
  3121. END;
  3122. END StructMemberDeclaration;
  3123. PROCEDURE StructMemberDeclarations(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3124. VAR previousScope: SyntaxTree.Scope;
  3125. BEGIN
  3126. IF Trace THEN
  3127. S("StructMemberDeclarations")
  3128. END;
  3129. previousScope := currentScope;
  3130. currentScope := parentScope;
  3131. WHILE ~Peek(Scanner.RightBrace) DO
  3132. StructMemberDeclaration(parentScope, parentName);
  3133. END;
  3134. currentScope := previousScope;
  3135. IF Trace THEN
  3136. E("StructMemberDeclarations")
  3137. END;
  3138. END StructMemberDeclarations;
  3139. PROCEDURE StructDeclaration(parentScope: SyntaxTree.Scope; modifiers: SET);
  3140. VAR name: SyntaxTree.Identifier;
  3141. position: LONGINT;
  3142. typeDeclaration: SyntaxTree.TypeDeclaration;
  3143. access: SET;
  3144. recordType: SyntaxTree.RecordType;
  3145. recordScope: SyntaxTree.RecordScope;
  3146. previousStatements: SyntaxTree.StatementSequence;
  3147. previousOuter: SyntaxTree.Statement;
  3148. b: BOOLEAN;
  3149. BEGIN
  3150. IF Trace THEN
  3151. S("StructDeclaration")
  3152. END;
  3153. previousStatements := initStatements;
  3154. previousOuter := initOuter;
  3155. (* TODO: Implement initialization of fields *)
  3156. initStatements := NIL;
  3157. initOuter := NIL;
  3158. (* symbol 'struct' already consumed *)
  3159. name := Identifier(position);
  3160. access := IdentifierAccess(modifiers, FALSE);
  3161. typeDeclaration := SyntaxTree.NewTypeDeclaration(position, name);
  3162. CommentSymbol(typeDeclaration);
  3163. recordScope := SyntaxTree.NewRecordScope(parentScope);
  3164. recordType := SyntaxTree.NewRecordType(position, parentScope, recordScope);
  3165. Check(Scanner.LeftBrace);
  3166. StructMemberDeclarations(recordScope, name);
  3167. Check(Scanner.RightBrace);
  3168. b := Optional(Scanner.Semicolon);
  3169. recordType.SetTypeDeclaration(typeDeclaration);
  3170. typeDeclaration.SetDeclaredType(recordType);
  3171. typeDeclaration.SetAccess(access);
  3172. parentScope.AddTypeDeclaration(typeDeclaration);
  3173. initStatements := previousStatements;
  3174. initOuter := previousOuter;
  3175. IF Trace THEN
  3176. E("StructDeclaration")
  3177. END;
  3178. END StructDeclaration;
  3179. (**
  3180. delegate-declaration:
  3181. [delegate-modifiers] 'delegate' return-type identifier '(' [formal-parameter-list] ')' ';'
  3182. **)
  3183. PROCEDURE DelegateDeclaration(parentScope: SyntaxTree.Scope; modifiers: SET);
  3184. VAR returnType: SyntaxTree.Type;
  3185. name: SyntaxTree.Identifier;
  3186. position: LONGINT;
  3187. typeDeclaration: SyntaxTree.TypeDeclaration;
  3188. access: SET;
  3189. procedureType: SyntaxTree.ProcedureType;
  3190. BEGIN
  3191. IF Trace THEN
  3192. S("DelegateDeclaration")
  3193. END;
  3194. (* symbol 'delegate' already consumed *)
  3195. IF Optional(Scanner.Void) THEN
  3196. returnType := NIL;
  3197. ELSE
  3198. returnType := Type();
  3199. END;
  3200. name := Identifier(position);
  3201. access := IdentifierAccess(modifiers, FALSE);
  3202. typeDeclaration := SyntaxTree.NewTypeDeclaration(position, name);
  3203. CommentSymbol(typeDeclaration);
  3204. procedureType := SyntaxTree.NewProcedureType(position, parentScope);
  3205. procedureType.SetModifiers(delegateModifiers);
  3206. (* ACHTUNG: Should we create a fictionary parentScope for parameters? *)
  3207. FormalParameterList(procedureType, parentScope, returnType);
  3208. procedureType.SetTypeDeclaration(typeDeclaration);
  3209. typeDeclaration.SetDeclaredType(procedureType);
  3210. typeDeclaration.SetAccess(access);
  3211. parentScope.AddTypeDeclaration(typeDeclaration);
  3212. IF Trace THEN
  3213. E("DelegateDeclaration")
  3214. END;
  3215. END DelegateDeclaration;
  3216. (**
  3217. port-list:
  3218. port-declaration
  3219. port-list ',' port-declaration
  3220. port-declaration:
  3221. port-type ['[' constant-expression ']'] identifier
  3222. port-type:
  3223. 'in'
  3224. 'out'
  3225. **)
  3226. PROCEDURE PortDeclaration(cell: SyntaxTree.CellType; parentScope: SyntaxTree.Scope);
  3227. VAR position: LONGINT;
  3228. direction: LONGINT;
  3229. type: SyntaxTree.Type;
  3230. arrayType: SyntaxTree.ArrayType;
  3231. expression: SyntaxTree.Expression;
  3232. name: SyntaxTree.Identifier;
  3233. parameter: SyntaxTree.Parameter;
  3234. BEGIN
  3235. IF Trace THEN
  3236. S("PortDeclaration")
  3237. END;
  3238. position := symbol.start;
  3239. IF Optional(Scanner.In) THEN
  3240. direction := SyntaxTree.InPort;
  3241. ELSIF Optional(Scanner.Out) THEN
  3242. direction := SyntaxTree.OutPort;
  3243. ELSE
  3244. Error(position, Diagnostics.Invalid, "invalid direction, expected in or out");
  3245. END;
  3246. type := SyntaxTree.NewPortType(position, direction, NIL, parentScope);
  3247. IF Optional(Scanner.LeftBracket) THEN
  3248. expression := Expression();
  3249. arrayType := SyntaxTree.NewArrayType(position, parentScope, SyntaxTree.Static);
  3250. arrayType.SetArrayBase(type);
  3251. arrayType.SetLength(expression);
  3252. type := arrayType;
  3253. Check(Scanner.RightBracket);
  3254. END;
  3255. name := Identifier(position);
  3256. parameter := SyntaxTree.NewParameter(position, cell, name, SyntaxTree.ValueParameter);
  3257. cell.AddParameter(parameter);
  3258. parameter.SetType(type);
  3259. IF Trace THEN
  3260. E("PortDeclaration")
  3261. END;
  3262. END PortDeclaration;
  3263. PROCEDURE PortList(cell: SyntaxTree.CellType; parentScope: SyntaxTree.Scope);
  3264. BEGIN
  3265. IF Trace THEN
  3266. S("PortList")
  3267. END;
  3268. Check(Scanner.LeftParenthesis);
  3269. IF ~Optional(Scanner.RightParenthesis) THEN
  3270. REPEAT
  3271. PortDeclaration(cell, parentScope);
  3272. UNTIL ~Optional(Scanner.Comma);
  3273. Check(Scanner.RightParenthesis);
  3274. END;
  3275. IF Trace THEN
  3276. E("PortList")
  3277. END;
  3278. END PortList;
  3279. (**
  3280. cell-declaration:
  3281. [cell-modifiers] 'cell' identifier ['(' [cell-parameter-list] ')'] cell-body [';']
  3282. cell-body:
  3283. '{' [cell-member-declarations] '}'
  3284. cell-member-declarations:
  3285. cell-member-declaration
  3286. cell-member-declarations cell-member-declaration
  3287. cell-member-declaration:
  3288. constant-declaration
  3289. field-declaration
  3290. method-declaration
  3291. constructor-declaration
  3292. type-declaration
  3293. cellnet-declaration:
  3294. [cell-modifiers] 'cellnet' identifier ['(' [cell-parameter-list] ')'] cell-body [';']
  3295. **)
  3296. PROCEDURE CellMemberDeclaration(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3297. BEGIN
  3298. IF Trace THEN
  3299. S("CellMemberDeclaration")
  3300. END;
  3301. MemberDeclaration(parentScope, parentName);
  3302. IF Trace THEN
  3303. E("CellMemberDeclaration")
  3304. END;
  3305. END CellMemberDeclaration;
  3306. PROCEDURE CellMemberDeclarations(parentScope: SyntaxTree.Scope; parentName: SyntaxTree.Identifier);
  3307. VAR previousScope: SyntaxTree.Scope;
  3308. BEGIN
  3309. IF Trace THEN
  3310. S("CellMemberDeclarations")
  3311. END;
  3312. previousScope := currentScope;
  3313. currentScope := parentScope;
  3314. WHILE ~Peek(Scanner.RightBrace) DO
  3315. CellMemberDeclaration(parentScope, parentName);
  3316. END;
  3317. currentScope := previousScope;
  3318. IF Trace THEN
  3319. E("CellMemberDeclarations")
  3320. END;
  3321. END CellMemberDeclarations;
  3322. PROCEDURE CellDeclaration(
  3323. parentScope: SyntaxTree.Scope;
  3324. modifiers: SET;
  3325. attributes: SyntaxTree.Modifier;
  3326. isCellNet: BOOLEAN);
  3327. VAR name: SyntaxTree.Identifier;
  3328. position: LONGINT;
  3329. access: SET;
  3330. typeDeclaration: SyntaxTree.TypeDeclaration;
  3331. cellScope: SyntaxTree.CellScope;
  3332. cellType: SyntaxTree.CellType;
  3333. previousStatements: SyntaxTree.StatementSequence;
  3334. previousOuter: SyntaxTree.Statement;
  3335. b: BOOLEAN;
  3336. BEGIN
  3337. IF Trace THEN
  3338. S("CellDeclaration")
  3339. END;
  3340. previousStatements := initStatements;
  3341. previousOuter := initOuter;
  3342. (* TODO: Implement initialization of fields *)
  3343. initStatements := NIL;
  3344. initOuter := NIL;
  3345. (* symbol 'cell' already consumed *)
  3346. name := Identifier(position);
  3347. access := IdentifierAccess(modifiers, FALSE);
  3348. typeDeclaration := SyntaxTree.NewTypeDeclaration(position, name);
  3349. CommentSymbol(typeDeclaration);
  3350. cellScope := SyntaxTree.NewCellScope(parentScope);
  3351. cellType := SyntaxTree.NewCellType(position, parentScope, cellScope);
  3352. cellType.IsCellNet(isCellNet);
  3353. cellScope.SetOwnerCell(cellType);
  3354. IF attributes # NIL THEN
  3355. cellType.SetModifiers(attributes);
  3356. END;
  3357. IF Peek(Scanner.LeftParenthesis) THEN
  3358. PortList(cellType, cellScope);
  3359. END;
  3360. EnterInit;
  3361. Check(Scanner.LeftBrace);
  3362. CellMemberDeclarations(cellScope, name);
  3363. Check(Scanner.RightBrace);
  3364. b := Optional(Scanner.Semicolon);
  3365. cellType.SetTypeDeclaration(typeDeclaration);
  3366. typeDeclaration.SetDeclaredType(cellType);
  3367. typeDeclaration.SetAccess(access);
  3368. parentScope.AddTypeDeclaration(typeDeclaration);
  3369. initStatements := previousStatements;
  3370. initOuter := previousOuter;
  3371. IF Trace THEN
  3372. E("CellDeclaration")
  3373. END;
  3374. END CellDeclaration;
  3375. (**
  3376. import-directives:
  3377. import-directive
  3378. import-directives import-directive
  3379. import-directive:
  3380. import-alias-directive
  3381. import-module-directive
  3382. import-alias-directive:
  3383. 'import' identifier '=' module-name ';'
  3384. import-module-directive:
  3385. 'import' module-name ';'
  3386. module-name:
  3387. identifier
  3388. **)
  3389. PROCEDURE ImportDirective(moduleScope: SyntaxTree.ModuleScope);
  3390. VAR alias, name, context: SyntaxTree.Identifier;
  3391. import: SyntaxTree.Import;
  3392. position, idPosition: LONGINT;
  3393. BEGIN
  3394. IF Trace THEN
  3395. S("ImportDirective")
  3396. END;
  3397. (* import symbol already consumed *)
  3398. position := symbol.start;
  3399. alias := Identifier(idPosition);
  3400. IF alias # SyntaxTree.invalidIdentifier THEN
  3401. IF Optional(Scanner.Equal) THEN
  3402. name := Identifier(idPosition);
  3403. ELSE
  3404. name := alias;
  3405. END;
  3406. import := SyntaxTree.NewImport(position, alias, name, TRUE);
  3407. CommentSymbol(import);
  3408. moduleScope.AddImport(import);
  3409. END;
  3410. Check(Scanner.Semicolon);
  3411. IF Trace THEN
  3412. E("ImportDirective");
  3413. END;
  3414. END ImportDirective;
  3415. PROCEDURE ImportDirectives(moduleScope: SyntaxTree.ModuleScope);
  3416. BEGIN
  3417. IF Trace THEN
  3418. S("ImportDirectives")
  3419. END;
  3420. WHILE Optional(Scanner.Import) DO
  3421. ImportDirective(moduleScope);
  3422. END;
  3423. IF Trace THEN
  3424. E("ImportDirectives");
  3425. END;
  3426. END ImportDirectives;
  3427. (**
  3428. compilation-unit:
  3429. 'module' identifier '{' [import-directives] [class-member-declarations] '}' [';']
  3430. 'cellnet' identifier '{' [import-directives] [class-member-declarations] '}' [';']
  3431. **)
  3432. PROCEDURE Module*(): SyntaxTree.Module;
  3433. VAR moduleName, context: SyntaxTree.Identifier;
  3434. module: SyntaxTree.Module;
  3435. position: LONGINT;
  3436. isCellNet: BOOLEAN;
  3437. scannerDiagnostics: Diagnostics.Diagnostics;
  3438. b: BOOLEAN;
  3439. BEGIN
  3440. IF Trace THEN
  3441. S("Module")
  3442. END;
  3443. position := symbol.start;
  3444. (* needed to feed in comment already before module starts: *)
  3445. moduleScope := SyntaxTree.NewModuleScope();
  3446. currentScope := moduleScope;
  3447. isCellNet := Optional(Scanner.Cellnet);
  3448. IF isCellNet OR Mandatory(Scanner.Module) THEN
  3449. moduleName := Identifier(position);
  3450. module := SyntaxTree.NewModule(scanner.source^, position, moduleName, moduleScope, LynxCase);
  3451. IF isCellNet THEN
  3452. module.SetCellNet(TRUE);
  3453. END;
  3454. module.SetType(SyntaxTree.moduleType);
  3455. CommentSymbol(module);
  3456. Check(Scanner.LeftBrace);
  3457. IF Peek(Scanner.Import) THEN
  3458. ImportDirectives(moduleScope)
  3459. END;
  3460. EnterInit;
  3461. ClassMemberDeclarations(moduleScope, moduleName);
  3462. Check(Scanner.RightBrace);
  3463. b := Optional(Scanner.Semicolon);
  3464. IF ~error & ~scanner.error THEN
  3465. (* read ahead to read comments *)
  3466. scannerDiagnostics := NIL;
  3467. scanner.ResetErrorDiagnostics(scannerDiagnostics);
  3468. NextSymbol;
  3469. scanner.ResetErrorDiagnostics(scannerDiagnostics);
  3470. (* do not use Check for not reading after end of module *)
  3471. SetNextInComment(recentComment, module);
  3472. module.SetClosingComment(recentComment);
  3473. recentComment := NIL;
  3474. END;
  3475. END;
  3476. IF Trace THEN
  3477. E("Module")
  3478. END;
  3479. RETURN module
  3480. END Module;
  3481. END Parser; (* Parser *)
  3482. (** parser retrieval **)
  3483. PROCEDURE NewParser*(scanner: Scanner.Scanner; diagnostics: Diagnostics.Diagnostics): Parser;
  3484. VAR parser: Parser;
  3485. BEGIN
  3486. NEW(parser, scanner, diagnostics);
  3487. RETURN parser;
  3488. END NewParser;
  3489. END FoxCSharpParser.