FoxCSharpParser.Mod 144 KB

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