parser.bmx 107 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199
  1. ' Copyright (c) 2013-2016 Bruce A Henderson
  2. '
  3. ' Based on the public domain Monkey "trans" by Mark Sibly
  4. '
  5. ' This software is provided 'as-is', without any express or implied
  6. ' warranty. In no event will the authors be held liable for any damages
  7. ' arising from the use of this software.
  8. '
  9. ' Permission is granted to anyone to use this software for any purpose,
  10. ' including commercial applications, and to alter it and redistribute it
  11. ' freely, subject to the following restrictions:
  12. '
  13. ' 1. The origin of this software must not be misrepresented; you must not
  14. ' claim that you wrote the original software. If you use this software
  15. ' in a product, an acknowledgment in the product documentation would be
  16. ' appreciated but is not required.
  17. '
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. '
  21. ' 3. This notice may not be removed or altered from any source
  22. ' distribution.
  23. '
  24. SuperStrict
  25. Import BRL.MaxUtil
  26. Import "toker.bmx"
  27. Import "iparser.bmx"
  28. Global FILE_EXT$="bmx"
  29. Type TForEachinStmt Extends TLoopStmt
  30. Field varid$
  31. Field varty:TType
  32. Field varlocal:Int
  33. Field expr:TExpr
  34. Field block:TBlockDecl
  35. Field varExpr:TExpr
  36. Field stmts:TList=New TList
  37. Method Create:TForEachinStmt( varid$,varty:TType,varlocal:Int,expr:TExpr,block:TBlockDecl,loopLabel:TLoopLabelDecl,varExpr:TExpr )
  38. Self.varid=varid
  39. Self.varty=varty
  40. Self.varlocal=varlocal
  41. Self.expr=expr
  42. Self.block=block
  43. Self.loopLabel=loopLabel
  44. Self.varExpr = varExpr
  45. Return Self
  46. End Method
  47. Method OnCopy:TStmt( scope:TScopeDecl )
  48. Return New TForEachinStmt.Create( varid,varty,varlocal,expr.Copy(),block.CopyBlock( scope ),TLoopLabelDecl(loopLabel.Copy()), varExpr.Copy() )
  49. End Method
  50. Method OnSemant()
  51. expr=expr.Semant()
  52. If TArrayType( expr.exprType ) Or TStringType( expr.exprType )
  53. Local exprTmp:TLocalDecl=New TLocalDecl.Create( "",Null,expr,,True )
  54. Local indexTmp:TLocalDecl=New TLocalDecl.Create( "",Null,New TConstExpr.Create( New TUIntType,"0" ),,True )
  55. Local lenExpr:TExpr=New TIdentExpr.Create( "Length",New TVarExpr.Create( exprTmp ) )
  56. Local cmpExpr:TExpr=New TBinaryCompareExpr.Create( "<",New TVarExpr.Create( indexTmp ),lenExpr )
  57. Local indexExpr:TExpr=New TIndexExpr.Create( New TVarExpr.Create( exprTmp ),[New TVarExpr.Create( indexTmp )] )
  58. Local addExpr:TExpr=New TBinaryMathExpr.Create( "+",New TVarExpr.Create( indexTmp ),New TConstExpr.Create( New TIntType,"1" ) )
  59. Local cont:TContinueStmt
  60. If varlocal
  61. ' array of object ?
  62. If TArrayType( expr.exprType ) And TObjectType(TArrayType( expr.exprType ).elemType) And (Not TObjectType(TArrayType( expr.exprType ).elemType).classdecl.IsExtern() ..
  63. Or (TObjectType(TArrayType( expr.exprType ).elemType).classdecl.IsExtern() ..
  64. And IsPointerType(TArrayType( expr.exprType ).elemType))) Then
  65. Local cExpr:TExpr
  66. If TIdentType(varty) And TIdentType(varty).ident = "Object" Then
  67. cExpr = indexExpr
  68. Else
  69. cExpr = New TCastExpr.Create( varty, indexExpr,CAST_EXPLICIT )
  70. End If
  71. ' local variable
  72. Local varTmp:TLocalDecl=New TLocalDecl.Create( varid,varty,cExpr )
  73. ' local var as expression
  74. Local expr:TExpr=New TVarExpr.Create( varTmp )
  75. ' var = Null
  76. expr=New TBinaryCompareExpr.Create( "=",expr, New TNullExpr.Create(TType.nullObjectType))
  77. ' then continue
  78. Local thenBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  79. Local elseBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  80. cont = New TContinueStmt
  81. thenBlock.AddStmt cont
  82. block.stmts.AddFirst New TIfStmt.Create( expr,thenBlock,elseBlock )
  83. block.stmts.AddFirst New TAssignStmt.Create( "=",New TVarExpr.Create( indexTmp ),addExpr )
  84. block.stmts.AddFirst New TDeclStmt.Create( varTmp )
  85. Else
  86. Local varTmp:TLocalDecl=New TLocalDecl.Create( varid,varty,indexExpr )
  87. block.stmts.AddFirst New TAssignStmt.Create( "=",New TVarExpr.Create( indexTmp ),addExpr, True )
  88. block.stmts.AddFirst New TDeclStmt.Create( varTmp, True )
  89. End If
  90. Else
  91. If TArrayType( expr.exprType ) And TObjectType(TArrayType( expr.exprType ).elemType) Then
  92. ' var = Null
  93. If Not varty Then
  94. varExpr = varExpr.Semant()
  95. varty = varExpr.exprType
  96. 'Local decl:TValDecl = block.scope.FindValDecl(varid.ToLower())
  97. 'If decl Then
  98. ' decl.Semant()
  99. '
  100. ' varty = decl.ty.Copy()
  101. 'End If
  102. End If
  103. ' expr=New TBinaryCompareExpr.Create( "=",New TIdentExpr.Create( varid ), New TNullExpr.Create(TType.nullObjectType))
  104. expr=New TBinaryCompareExpr.Create( "=",varExpr, New TNullExpr.Create(TType.nullObjectType))
  105. ' then continue
  106. Local thenBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  107. Local elseBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  108. cont = New TContinueStmt
  109. thenBlock.AddStmt cont
  110. block.stmts.AddFirst New TIfStmt.Create( expr,thenBlock,elseBlock )
  111. 'block.stmts.AddFirst New TDeclStmt.Create( varTmp )
  112. block.stmts.AddFirst New TAssignStmt.Create( "=",New TVarExpr.Create( indexTmp ),addExpr, True )
  113. ' block.stmts.AddFirst New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),New TCastExpr.Create( varty, indexExpr,CAST_EXPLICIT ), True )
  114. block.stmts.AddFirst New TAssignStmt.Create( "=",varExpr,New TCastExpr.Create( varty, indexExpr,CAST_EXPLICIT ), True )
  115. Else
  116. block.stmts.AddFirst New TAssignStmt.Create( "=",New TVarExpr.Create( indexTmp ),addExpr, True )
  117. ' block.stmts.AddFirst New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),indexExpr, True )
  118. block.stmts.AddFirst New TAssignStmt.Create( "=",varExpr,indexExpr, True )
  119. End If
  120. EndIf
  121. Local whileStmt:TWhileStmt=New TWhileStmt.Create( cmpExpr,block,Null, True )
  122. block=New TBlockDecl.Create( block.scope, True )
  123. block.AddStmt New TDeclStmt.Create( exprTmp, True )
  124. block.AddStmt New TDeclStmt.Create( indexTmp, True )
  125. block.AddStmt whileStmt
  126. If cont Then
  127. cont.loop = whileStmt
  128. End If
  129. Else If TObjectType( expr.exprType )
  130. Local tmpDecl:TDeclStmt
  131. If TInvokeExpr(expr) Or TInvokeMemberExpr(expr) Then
  132. Local tmpVar:TLocalDecl=New TLocalDecl.Create( "",expr.exprType,expr,,True )
  133. tmpVar.Semant()
  134. tmpDecl = New TDeclStmt.Create( tmpVar, True )
  135. expr = New TVarExpr.Create( tmpVar )
  136. End If
  137. Local enumerInit:TExpr=New TFuncCallExpr.Create( New TIdentExpr.Create( "ObjectEnumerator",expr ) )
  138. Local enumerTmp:TLocalDecl=New TLocalDecl.Create( "",Null,enumerInit,,True )
  139. Local hasNextExpr:TExpr=New TFuncCallExpr.Create( New TIdentExpr.Create( "HasNext",New TVarExpr.Create( enumerTmp ) ) )
  140. Local nextObjExpr:TExpr=New TFuncCallExpr.Create( New TIdentExpr.Create( "NextObject",New TVarExpr.Create( enumerTmp ) ) )
  141. Local cont:TContinueStmt
  142. If varlocal
  143. ' Local varTmp:TLocalDecl=New TLocalDecl.Create( varid,varty,nextObjExpr )
  144. ' block.stmts.AddFirst New TDeclStmt.Create( varTmp )
  145. Local cExpr:TExpr
  146. If TIdentType(varty) And TIdentType(varty).ident = "Object" Then
  147. cExpr = nextObjExpr
  148. Else
  149. cExpr = New TCastExpr.Create( varty, nextObjExpr,CAST_EXPLICIT )
  150. End If
  151. ' local variable
  152. Local varTmp:TLocalDecl=New TLocalDecl.Create( varid,varty,cExpr)
  153. ' local var as expression
  154. Local expr:TExpr=New TVarExpr.Create( varTmp )
  155. ' var = Null
  156. expr=New TBinaryCompareExpr.Create( "=",expr, New TNullExpr.Create(TType.nullObjectType))
  157. ' then continue
  158. Local thenBlock:TBlockDecl=New TBlockDecl.Create( block.scope, True )
  159. Local elseBlock:TBlockDecl=New TBlockDecl.Create( block.scope, True )
  160. cont = New TContinueStmt.Create(Null, True)
  161. thenBlock.AddStmt cont
  162. block.stmts.AddFirst New TIfStmt.Create( expr,thenBlock,elseBlock, True )
  163. block.stmts.AddFirst New TDeclStmt.Create( varTmp, True )
  164. Else
  165. If Not varty Then
  166. varExpr = varExpr.Semant()
  167. varty = varExpr.exprType
  168. End If
  169. ' If Not varty Then
  170. ' Local decl:TValDecl = block.scope.FindValDecl(varid.ToLower())
  171. '
  172. ' If decl Then
  173. ' decl.Semant()
  174. '
  175. ' varty = decl.ty.Copy()
  176. ' End If
  177. ' End If
  178. ' var = Null
  179. ' Local expr:TExpr=New TBinaryCompareExpr.Create( "=",New TIdentExpr.Create( varid ), New TNullExpr.Create(TType.nullObjectType))
  180. Local expr:TExpr=New TBinaryCompareExpr.Create( "=",varExpr, New TNullExpr.Create(TType.nullObjectType))
  181. ' then continue
  182. Local thenBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  183. Local elseBlock:TBlockDecl=New TBlockDecl.Create( block.scope )
  184. cont = New TContinueStmt
  185. thenBlock.AddStmt cont
  186. block.stmts.AddFirst New TIfStmt.Create( expr,thenBlock,elseBlock )
  187. 'block.stmts.AddFirst New TDeclStmt.Create( varTmp )
  188. ' block.stmts.AddFirst New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),New TCastExpr.Create( varty, nextObjExpr,CAST_EXPLICIT ))
  189. block.stmts.AddFirst New TAssignStmt.Create( "=",varExpr,New TCastExpr.Create( varty, nextObjExpr,CAST_EXPLICIT ))
  190. EndIf
  191. Local whileStmt:TWhileStmt=New TWhileStmt.Create( hasNextExpr,block,Null, True )
  192. block=New TBlockDecl.Create( block.scope, True )
  193. If tmpDecl Then
  194. block.AddStmt tmpDecl
  195. End If
  196. block.AddStmt New TDeclStmt.Create( enumerTmp, True )
  197. block.AddStmt whileStmt
  198. If cont Then
  199. cont.loop = whileStmt
  200. End If
  201. Else
  202. InternalErr
  203. EndIf
  204. block.Semant
  205. End Method
  206. Method Trans$()
  207. _trans.EmitBlock block
  208. End Method
  209. End Type
  210. Type TIncbin
  211. Field file:String
  212. Field path:String
  213. Field id:Int
  214. Field length:Int
  215. Global count:Int
  216. Method Create:TIncbin(file:String, source:String)
  217. count :+ 1
  218. Self.file = file
  219. ' find the file
  220. If Not FileType(file) Then
  221. ' maybe relative to source
  222. Local dir:String = ExtractDir(source) + "/" + file
  223. If FileType(dir) = FILETYPE_FILE Then
  224. path = RealPath(dir)
  225. Else
  226. Return Null
  227. End If
  228. Else
  229. path = RealPath(file)
  230. End If
  231. id = count
  232. Return Self
  233. End Method
  234. End Type
  235. '***** Parser *****
  236. Type TParser
  237. Field _toker:TToker
  238. Field _toke:String
  239. Field _tokeType:Int
  240. 'Ronny: _tokerStack is unused
  241. 'Field _tokerStack:TList=New TList'<TToker>
  242. Field _block:TBlockDecl
  243. Field _blockStack:TList=New TList'<TBlockDecl>
  244. Field _errStack:TStringList=New TStringList
  245. Field _app:TAppDecl
  246. Field _module:TModuleDecl
  247. Field _externCasts:TMap = New TMap
  248. Method SetErr(toker:TToker = Null)
  249. Local t:TToker = _toker
  250. If toker Then
  251. t = toker
  252. End If
  253. If t.Path()
  254. _errInfo=FormatError(t.Path(),t.Line(),0)
  255. EndIf
  256. End Method
  257. Method DoErr(error:String, toker:TToker = Null)
  258. SetErr(toker)
  259. Err error
  260. End Method
  261. Method PushBlock( block:TBlockDecl )
  262. If _block <> Null Then
  263. _blockStack.AddLast _block
  264. End If
  265. _errStack.AddLast _errInfo
  266. _block=block
  267. End Method
  268. Method PopBlock()
  269. _block=TBlockDecl(_blockStack.RemoveLast())
  270. _errInfo=String(_errStack.RemoveLast())
  271. End Method
  272. Method RealPath$( path$ )
  273. Local popDir$=CurrentDir()
  274. ChangeDir ExtractDir( _toker.Path() )
  275. path=BRL.FileSystem.RealPath( path )
  276. ChangeDir popDir
  277. Return path
  278. End Method
  279. Method ActualPath:String(path:String)
  280. Local dir:String = ExtractDir(path)
  281. Local origFile:String = StripDir(path)
  282. Local lowerFile:String = origFile.ToLower()
  283. Local actualDir:String = ExtractDir(RealPath(path))
  284. Local files:String[] = LoadDir(actualDir)
  285. For Local file:String = EachIn files
  286. If file.ToLower() = lowerFile Then
  287. If file <> origFile Then
  288. ' we could raise as a warning instead, but an error encourages the user to fix their code ;-)
  289. Err "Actual file '" + file + "' differs in case with import '" + origFile + "'"
  290. ' what we might do were we to warn instead...
  291. If dir Then
  292. Return dir + "/" + file
  293. Else
  294. Return file
  295. End If
  296. End If
  297. Exit
  298. End If
  299. Next
  300. Return path
  301. End Method
  302. Method NextToke$()
  303. Local toke$=_toke
  304. Repeat
  305. _toke=_toker.NextToke()
  306. _tokeType=_toker.TokeType()
  307. Until _tokeType<>TOKE_SPACE
  308. If _tokeType=TOKE_KEYWORD _toke=_toker._tokeLower
  309. If toke="," SkipEols
  310. Return _toke
  311. End Method
  312. Method NextTokeToker$(toker:TToker)
  313. ' Local toke$=toker._toke
  314. Repeat
  315. toker.NextToke()
  316. Until toker.tokeType()<>TOKE_SPACE
  317. Return toker._toke
  318. End Method
  319. Method DescribeToke:String( toke:String )
  320. Select toke
  321. Case "~n"
  322. Return "end-of-line"
  323. End Select
  324. Return toke
  325. End Method
  326. Method CParse:Int( toke$ )
  327. If _toke.ToLower()<>toke
  328. Return False
  329. EndIf
  330. NextToke
  331. Return True
  332. End Method
  333. Method CParseToker:Int( toker:TToker, toke$ )
  334. If toker._toke.ToLower()<>toke
  335. Return False
  336. EndIf
  337. NextTokeToker(toker)
  338. Return True
  339. End Method
  340. Method Parse( toke$ )
  341. If Not CParse( toke )
  342. DoErr "Syntax error - expecting '"+toke+"'."
  343. EndIf
  344. End Method
  345. Method ParseToker( toker:TToker, toke$ )
  346. If Not CParseToker( toker, toke )
  347. DoErr "Syntax error - expecting '"+toke+"'.", toker
  348. EndIf
  349. End Method
  350. Method AtEos:Int()
  351. Return _toke="" Or _toke=";" Or _toke="~n" Or _toke="else"
  352. End Method
  353. Method SkipEols()
  354. While CParse( "~n" ) Or CParse(";")
  355. Wend
  356. SetErr
  357. End Method
  358. Method SkipEolsToker(toker:TToker)
  359. While CParseToker( toker, "~n" )
  360. Wend
  361. SetErr
  362. End Method
  363. Method ParseStringLit$()
  364. If _tokeType<>TOKE_STRINGLIT Err "Expecting string literal."
  365. Local str$=BmxUnquote( _toke )
  366. NextToke
  367. Return str
  368. End Method
  369. Method ParseIdent$()
  370. Select _toke
  371. Case "@" NextToke
  372. Case "string","object", "self"
  373. Default
  374. If _tokeType<>TOKE_IDENT Err "Syntax error - expecting identifier."
  375. End Select
  376. Local id$=_toke
  377. NextToke
  378. Return id
  379. End Method
  380. Method ParseIdentType:TIdentType()
  381. Local id$=ParseIdent()
  382. 'DebugLog "ParseIdentType : " + id
  383. If CParse( "." ) id:+"."+ParseIdent()
  384. If CParse( "." ) id:+"."+ParseIdent()
  385. Local args:TIdentType[]
  386. If CParse( "<" )
  387. Local nargs:Int
  388. Repeat
  389. Local arg:TIdentType=ParseIdentType()
  390. If args.Length=nargs args=args+ New TIdentType[10]
  391. args[nargs]=arg
  392. nargs:+1
  393. Until Not CParse(",")
  394. args=args[..nargs]
  395. Parse ">"
  396. EndIf
  397. Return New TIdentType.Create( id,args )
  398. End Method
  399. Method CParseIdentType:TIdentType( inner:Int=False )
  400. If _tokeType<>TOKE_IDENT Return Null
  401. Local id$=ParseIdent()
  402. While CParse( "." )
  403. If _tokeType<>TOKE_IDENT Return Null
  404. id:+"."+ParseIdent()
  405. Wend
  406. If Not CParse( "<" )
  407. If inner Return New TIdentType.Create( id,Null )
  408. Return Null
  409. EndIf
  410. Local args:TType[]
  411. Local nargs:Int
  412. Repeat
  413. Local arg:TType=CParsePrimitiveType()
  414. If Not arg
  415. arg=CParseIdentType( True )
  416. If Not arg Return Null
  417. EndIf
  418. While IsArrayDef()
  419. arg = ParseArrayType(arg)
  420. Wend
  421. ' While CParse( "[]" )
  422. ' arg=arg.ArrayOf()
  423. ' Wend
  424. args = args + [arg]
  425. nargs :+ 1
  426. Until Not CParse(",")
  427. If Not CParse( ">" ) Return Null
  428. Return New TIdentType.Create( id,args )
  429. End Method
  430. Method CParsePrimitiveType:TType()
  431. If CParse( "string" ) Return TType.stringType
  432. If CParse( "object" ) Return New TIdentType.Create( "brl.classes.object" )
  433. Local ty:TType
  434. If CParse( "short" )
  435. ty = New TShortType
  436. Else If CParse( "byte" )
  437. ty = New TByteType
  438. Else If CParse( "int" )
  439. ty = New TIntType
  440. Else If CParse( "uint" )
  441. ty = New TUIntType
  442. Else If CParse( "float" )
  443. ty = New TFloatType
  444. Else If CParse( "long" )
  445. ty = New TLongType
  446. Else If CParse( "ulong" )
  447. ty = New TULongType
  448. Else If CParse( "double" )
  449. ty = New TDoubleType
  450. Else If CParse( "size_t" )
  451. ty = New TSizeTType
  452. Else If CParse( "int128" ) Then
  453. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  454. ty = New TInt128Type
  455. Else If CParse( "float128" ) Then
  456. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  457. ty = New TFloat128Type
  458. Else If CParse( "double128" ) Then
  459. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  460. ty = New TDouble128Type
  461. Else If CParse( "float64" ) Then
  462. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  463. ty = New TFloat64Type
  464. Else If CParse( "wparam" ) Then
  465. If opt_platform <> "win32" Err "WParam types only available on Win32"
  466. ty = New TWParamType
  467. Else If CParse( "lparam" ) Then
  468. If opt_platform <> "win32" Err "LParam types only available on Win32"
  469. ty = New TLParamType
  470. End If
  471. While CParse("ptr")
  472. ty = TType.MapToPointerType(ty)
  473. Wend
  474. Return ty
  475. End Method
  476. Method CParsePrimitiveNumberType:TType()
  477. If CParse( "short" ) Return New TShortType
  478. If CParse( "byte" ) Return New TByteType
  479. If CParse( "int" ) Return New TIntType
  480. If CParse( "uint" ) Return New TUIntType
  481. If CParse( "float" ) Return New TFloatType
  482. If CParse( "long" ) Return New TLongType
  483. If CParse( "ulong" ) Return New TULongType
  484. If CParse( "double" ) Return New TDoubleType
  485. If CParse( "size_t" ) Return New TSizeTType
  486. If CParse( "int128" ) Then
  487. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  488. Return New TInt128Type
  489. End If
  490. If CParse( "float128" ) Then
  491. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  492. Return New TFloat128Type
  493. End If
  494. If CParse( "double128" ) Then
  495. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  496. Return New TDouble128Type
  497. End If
  498. If CParse( "float64" ) Then
  499. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  500. Return New TFloat64Type
  501. End If
  502. If CParse( "wparam" ) Then
  503. If opt_platform <> "win32" Err "WParam types only available on Win32"
  504. Return New TWParamType
  505. End If
  506. If CParse( "lparam" ) Then
  507. If opt_platform <> "win32" Err "LParam types only available on Win32"
  508. Return New TLParamType
  509. End If
  510. End Method
  511. Method ParseNewType:TType()
  512. If CParse( "void" ) Return New TVoidType
  513. If CParse( "short" ) Return New TShortType
  514. If CParse( "byte" ) Return New TByteType
  515. If CParse( "int" ) Return New TIntType
  516. If CParse( "uint" ) Return New TUIntType
  517. If CParse( "float" ) Return New TFloatType
  518. If CParse( "string" ) Return TType.stringType
  519. If CParse( "object" ) Return New TIdentType.Create( "brl.classes.object" )
  520. If CParse( "long" ) Return New TLongType
  521. If CParse( "ulong" ) Return New TULongType
  522. If CParse( "double" ) Return New TDoubleType
  523. If CParse( "size_t" ) Return New TSizeTType
  524. If CParse( "int128" ) Then
  525. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  526. Return New TInt128Type
  527. End If
  528. If CParse( "float128" ) Then
  529. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  530. Return New TFloat128Type
  531. End If
  532. If CParse( "double128" ) Then
  533. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  534. Return New TDouble128Type
  535. End If
  536. If CParse( "float64" ) Then
  537. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  538. Return New TFloat64Type
  539. End If
  540. If CParse( "wparam" ) Then
  541. If opt_platform <> "win32" Err "WParam types only available on Win32"
  542. Return New TWParamType
  543. End If
  544. If CParse( "lparam" ) Then
  545. If opt_platform <> "win32" Err "LParam types only available on Win32"
  546. Return New TLParamType
  547. End If
  548. Return ParseIdentType()
  549. End Method
  550. Method ParseType:TType()
  551. Local ty:TType=CParsePrimitiveType()
  552. If ty Return ty
  553. Return ParseIdentType()
  554. End Method
  555. Method ParseConstNumberType:TType()
  556. Local ty:TType
  557. Select _toke
  558. Case "@"
  559. NextToke
  560. ty=New TByteType
  561. While CParse("ptr")
  562. ty = TType.MapToPointerType(ty)
  563. Wend
  564. Case "@@"
  565. NextToke
  566. ty=New TShortType
  567. While CParse("ptr")
  568. ty = TType.MapToPointerType(ty)
  569. Wend
  570. Case "%"
  571. NextToke
  572. ty=New TIntType
  573. While CParse("ptr")
  574. ty = TType.MapToPointerType(ty)
  575. Wend
  576. Case "#"
  577. NextToke
  578. ty=New TFloatType
  579. While CParse("ptr")
  580. ty = TType.MapToPointerType(ty)
  581. Wend
  582. Case "$"
  583. NextToke
  584. ty=New TStringType
  585. Case "!"
  586. NextToke
  587. ty=New TDoubleType
  588. While CParse("ptr")
  589. ty = TType.MapToPointerType(ty)
  590. Wend
  591. Case "%%"
  592. NextToke
  593. ty=New TLongType
  594. While CParse("ptr")
  595. ty = TType.MapToPointerType(ty)
  596. Wend
  597. Case ":"
  598. NextToke
  599. ty=CParsePrimitiveNumberType()
  600. If Not ty Then
  601. If CParse("string") Then
  602. ty=New TStringType
  603. Else
  604. ty = ParseIdentType()
  605. End If
  606. Else
  607. While CParse("ptr")
  608. ty = TType.MapToPointerType(ty)
  609. Wend
  610. End If
  611. End Select
  612. While IsArrayDef()
  613. ty = ParseArrayType(ty)
  614. Wend
  615. 'While CParse( "[]" )
  616. ' ty=New TArrayType.Create( ty )
  617. 'Wend
  618. Return ty
  619. End Method
  620. Method ParseDeclType:TType()
  621. Local ty:TType
  622. Select _toke
  623. Case "@"
  624. NextToke
  625. ty=New TByteType
  626. While CParse("ptr")
  627. ty = TType.MapToPointerType(ty)
  628. Wend
  629. Case "@@"
  630. NextToke
  631. ty=New TShortType
  632. While CParse("ptr")
  633. ty = TType.MapToPointerType(ty)
  634. Wend
  635. Case "%"
  636. NextToke
  637. ty=New TIntType
  638. While CParse("ptr")
  639. ty = TType.MapToPointerType(ty)
  640. Wend
  641. Case "%%"
  642. NextToke
  643. ty=New TLongType
  644. While CParse("ptr")
  645. ty = TType.MapToPointerType(ty)
  646. Wend
  647. Case "#"
  648. NextToke
  649. ty=New TFloatType
  650. If CParse("ptr") Then
  651. ty = TType.MapToPointerType(ty)
  652. End If
  653. Case "$"
  654. NextToke
  655. ty=New TStringType
  656. If CParse("z") Then
  657. ty._flags :| TType.T_CHAR_PTR
  658. Else If CParse("w") Then
  659. ty._flags :| TType.T_SHORT_PTR
  660. End If
  661. Case "!"
  662. NextToke
  663. ty=New TDoubleType
  664. While CParse("ptr")
  665. ty = TType.MapToPointerType(ty)
  666. Wend
  667. Case ":"
  668. NextToke
  669. ty=ParseType()
  670. If CParse("ptr") Then
  671. ' FIXME #200
  672. 'If TStringType(ty) = Null And (TObjectType(ty) = Null Or (TObjectType(ty) <> Null And TObjectType(ty).classDecl.IsExtern())) And TArrayType(ty) = Null Then
  673. ty = TType.MapToPointerType(ty)
  674. While CParse("ptr")
  675. ty = TType.MapToPointerType(ty)
  676. Wend
  677. 'Else
  678. ' ty = Null
  679. 'End If
  680. If Not ty DoErr "Invalid Pointer type."
  681. End If
  682. Case "("
  683. ' for Strict code, void will be converted to Int during semanting.
  684. ty=New TVoidType
  685. Default
  686. If _module.IsSuperStrict() Err "Illegal type expression."
  687. ty=New TIntType
  688. While CParse("ptr")
  689. ty = TType.MapToPointerType(ty)
  690. Wend
  691. End Select
  692. ' array ?
  693. While IsArrayDef()
  694. ty = ParseArrayType(ty)
  695. Wend
  696. Return ty
  697. End Method
  698. Method ParseArrayExpr:TArrayExpr()
  699. Parse "["
  700. Local args:TExpr[],nargs:Int
  701. Repeat
  702. Local arg:TExpr=ParseExpr()
  703. If args.Length=nargs args=args + New TExpr[10]
  704. args[nargs]=arg
  705. nargs:+1
  706. Until Not CParse(",")
  707. args=args[..nargs]
  708. Parse "]"
  709. Return New TArrayExpr.Create( args )
  710. End Method
  711. ' replaces While CParse( "[]" ) sections, with support for multi-dimension arrays
  712. Method ParseArrayType:TType(ty:TType)
  713. While True
  714. Local dims:Int = 1
  715. If CParse("[]") Then
  716. ty=New TArrayType.Create( ty )
  717. Exit
  718. End If
  719. If Not CParse("[") Then
  720. Exit
  721. End If
  722. While CParse( ",")
  723. dims :+ 1
  724. Wend
  725. Parse "]"
  726. ty=New TArrayType.Create( ty, dims )
  727. Exit
  728. Wend
  729. Return ty
  730. End Method
  731. Method IsArrayDef:Int()
  732. Local isDef:Int = True
  733. Local toker:TToker=New TToker.Copy(_toker)
  734. While True
  735. 'Local dims:Int = 1
  736. If CParseToker(toker, "[]") Then
  737. Exit
  738. End If
  739. If Not CParseToker(toker, "[") Then
  740. isDef = False
  741. Exit
  742. End If
  743. While CParseToker(toker, ",")
  744. 'dims :+ 1
  745. Wend
  746. If Not CParseToker(toker, "]") Then
  747. isDef = False
  748. Exit
  749. End If
  750. Exit
  751. Wend
  752. Return isDef
  753. End Method
  754. Method ParseArgs:TExpr[]( stmt:Int )
  755. Local args:TExpr[]
  756. If stmt
  757. If AtEos() Return args
  758. Else
  759. If _toke<>"(" Return args
  760. EndIf
  761. Local nargs:Int,eat:Int
  762. If _toke="("
  763. If stmt
  764. Local toker:TToker=New TToker.Copy(_toker),bra:Int=1
  765. Repeat
  766. toker.NextToke
  767. toker.SkipSpace
  768. Select toker.Toke().ToLower()
  769. Case "","else"
  770. Err "Parenthesis mismatch error."
  771. Case "(","["
  772. bra:+1
  773. Case "]",")"
  774. bra:-1
  775. If bra Continue
  776. toker.NextToke
  777. toker.SkipSpace
  778. Select toker.Toke().ToLower()
  779. Case ".","(","[","",";","~n","else"
  780. eat=True
  781. End Select
  782. Exit
  783. Case ","
  784. If bra<>1 Continue
  785. eat=True
  786. Exit
  787. End Select
  788. Forever
  789. Else
  790. eat=True
  791. EndIf
  792. If eat And NextToke()=")"
  793. NextToke
  794. Return args
  795. EndIf
  796. EndIf
  797. Repeat
  798. Local arg:TExpr
  799. If _toke And _toke<>"," arg=ParseExpr()
  800. If args.Length=nargs args=args + New TExpr[10]
  801. args[nargs]=arg
  802. nargs:+1
  803. Until Not CParse(",")
  804. args=args[..nargs]
  805. If eat Parse ")"
  806. Return args
  807. End Method
  808. Method ParsePrimaryExpr:TExpr( stmt:Int )
  809. Local expr:TExpr
  810. Select _toke.ToLower()
  811. Case "("
  812. NextToke
  813. expr=ParseExpr()
  814. Parse ")"
  815. Case "["
  816. expr=ParseArrayExpr()
  817. Case "[]"
  818. NextToke
  819. expr=New TConstExpr.Create( TType.emptyArrayType,"" )
  820. Case "."
  821. expr=New TScopeExpr.Create( _module )
  822. Case "new"
  823. NextToke
  824. If _toke = "(" Then
  825. ' call constructor
  826. expr=New TNewExpr.Create( ParseArgs(stmt) )
  827. Else
  828. Local ty:TType=ParseType()
  829. While CParse("ptr")
  830. ty = TType.MapToPointerType(ty)
  831. Wend
  832. If _toke = "[" Or _toke = "[]" Then
  833. Local depth:Int = 0
  834. Local ln:TExpr[]
  835. Local tmpTy:TType = ty.Copy()
  836. Repeat
  837. Local dims:Int = 1
  838. If CParse("[]") Then
  839. tmpTy=New TArrayType.Create( tmpTy )
  840. depth :+ 1
  841. Continue
  842. End If
  843. ' looking for an array with expression
  844. If Not ln Then
  845. Parse "["
  846. Else
  847. If Not CParse("[") Then
  848. Exit
  849. Else
  850. Err "Unexpected '[' after array size declaration"
  851. End If
  852. End If
  853. Repeat
  854. If CParse(",") Then
  855. dims :+ 1
  856. Continue
  857. End If
  858. If CParse("]") Exit
  859. ln = ln + [ParseExpr()]
  860. If CParse("]") Exit
  861. Parse(",")
  862. dims :+ 1
  863. Forever
  864. If Not ln Then
  865. tmpTy=New TArrayType.Create( tmpTy, dims )
  866. End If
  867. Forever
  868. If ln Then
  869. ty = tmpTy
  870. End If
  871. ' Repeat
  872. 'If CParse( "[" )
  873. ' Repeat
  874. ' ln = ln + [ParseExpr()]
  875. ' If CParse("]") Exit
  876. ' Parse ","
  877. ' Forever
  878. 'Parse "]"
  879. ' ty = ParseArrayType(ty)
  880. ' Forever
  881. 'While CParse( "[]" )
  882. ' ty=New TArrayType.Create( ty)
  883. 'Wend
  884. expr=New TNewArrayExpr.Create( ty,ln )
  885. Else
  886. expr=New TNewObjectExpr.Create( ty,ParseArgs( stmt ) )
  887. EndIf
  888. End If
  889. Case "null"
  890. NextToke
  891. expr = New TNullExpr.Create(TType.nullObjectType)
  892. 'expr=New TConstExpr.Create( TType.nullObjectType,"" )
  893. Case "true"
  894. NextToke
  895. expr=New TConstExpr.Create( New TIntType,"1" )
  896. Case "false"
  897. NextToke
  898. expr=New TConstExpr.Create( New TIntType,"" )
  899. Case "int","long","float","double","object","short","byte","size_t","uint","ulong","int128","float64","float128","double128","lparam","wparam"
  900. Local id$=_toke
  901. Local ty:TType=ParseType()
  902. If TIntType(ty) And id.ToLower() <> "int" Then
  903. Select id.ToLower()
  904. Case "byte"
  905. ty = New TByteType
  906. Case "short"
  907. ty = New TShortType
  908. Case "uint"
  909. ty = New TUIntType
  910. Case "long"
  911. ty = New TLongType
  912. Case "ulong"
  913. ty = New TULongType
  914. Case "float"
  915. ty = New TFloatType
  916. Case "double"
  917. ty = New TDoubleType
  918. Case "size_t"
  919. ty = New TSizeTType
  920. Case "int128"
  921. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  922. ty = New TInt128Type
  923. Case "float128"
  924. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  925. ty = New TFloat128Type
  926. Case "double128"
  927. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  928. ty = New TDouble128Type
  929. Case "float64"
  930. If opt_arch <> "x64" Err "Intrinsic types only available on x64"
  931. ty = New TFloat64Type
  932. Case "wparam"
  933. If opt_platform <> "win32" Err "WParam types only available on Win32"
  934. ty = New TWParamType
  935. Case "lparam"
  936. If opt_platform <> "win32" Err "LParam types only available on Win32"
  937. ty = New TLParamType
  938. End Select
  939. End If
  940. While CParse("ptr")
  941. ty = TType.MapToPointerType(ty)
  942. Wend
  943. ' array
  944. ty = ParseArrayType(ty)
  945. 'While CParse( "[]" )
  946. ' ty=New TArrayType.Create( ty)
  947. 'Wend
  948. ' optional brackets
  949. If CParse( "(" )
  950. expr=ParseExpr()
  951. Parse ")"
  952. expr=New TCastExpr.Create( ty,expr,CAST_EXPLICIT )
  953. Else
  954. expr=ParseExpr()
  955. If TBinaryExpr(expr) Then
  956. ' cast lhs and apply to rhs
  957. Local cexpr:TCastExpr=New TCastExpr.Create( ty,TBinaryExpr(expr).lhs,CAST_EXPLICIT )
  958. TBinaryExpr(expr).lhs = cexpr
  959. Else
  960. expr=New TCastExpr.Create( ty,expr,CAST_EXPLICIT )
  961. End If
  962. EndIf
  963. Case "sizeof"
  964. NextToke
  965. Local ty:TType = ParseConstNumberType()
  966. If ty Then
  967. If Not TIntType(ty) Then
  968. Err "Return type for 'SizeOf' must be Int"
  969. End If
  970. End If
  971. ' optional brackets
  972. If CParse( "(" )
  973. expr=ParseExpr()
  974. Parse ")"
  975. expr=New TSizeOfExpr.Create( expr )
  976. Else
  977. expr=ParseExpr()
  978. expr=New TSizeOfExpr.Create( expr )
  979. EndIf
  980. Case "len"
  981. NextToke
  982. Local ty:TType = ParseConstNumberType()
  983. If ty Then
  984. If Not TIntType(ty) Then
  985. Err "Return type for 'Len' must be Int"
  986. End If
  987. End If
  988. ' optional brackets
  989. If CParse( "(" )
  990. expr=ParseExpr()
  991. Parse ")"
  992. expr=New TLenExpr.Create( expr )
  993. Else
  994. expr=ParseExpr()
  995. expr=New TLenExpr.Create( expr )
  996. EndIf
  997. Case "abs"
  998. NextToke
  999. ' optional brackets
  1000. If CParse( "(" )
  1001. expr=ParseExpr()
  1002. Parse ")"
  1003. expr=New TAbsExpr.Create( expr )
  1004. Else
  1005. expr=ParseExpr()
  1006. expr=New TAbsExpr.Create( expr )
  1007. EndIf
  1008. Case "min"
  1009. NextToke
  1010. ' optional brackets
  1011. Local b:Int = CParse( "(" )
  1012. expr=ParseExpr()
  1013. Parse ","
  1014. Local expr2:TExpr=ParseExpr()
  1015. If b Then
  1016. Parse ")"
  1017. End If
  1018. expr=New TMinExpr.Create( expr, expr2 )
  1019. Case "max"
  1020. NextToke
  1021. ' optional brackets
  1022. Local b:Int = CParse( "(" )
  1023. expr=ParseExpr()
  1024. Parse ","
  1025. Local expr2:TExpr=ParseExpr()
  1026. If b Then
  1027. Parse ")"
  1028. End If
  1029. expr=New TMaxExpr.Create( expr, expr2 )
  1030. Case "asc"
  1031. NextToke
  1032. Local ty:TType = ParseConstNumberType()
  1033. If ty Then
  1034. If Not TIntType(ty) Then
  1035. Err "Return type for 'Asc' must be Int"
  1036. End If
  1037. End If
  1038. ' optional brackets
  1039. If CParse( "(" )
  1040. expr=ParseExpr()
  1041. Parse ")"
  1042. expr=New TAscExpr.Create( expr )
  1043. Else
  1044. expr=ParseExpr()
  1045. expr=New TAscExpr.Create( expr )
  1046. EndIf
  1047. Case "chr"
  1048. NextToke
  1049. Local ty:TType = ParseConstNumberType()
  1050. If ty Then
  1051. If Not TStringType(ty) Then
  1052. Err "Return type for 'Chr' must be String"
  1053. End If
  1054. End If
  1055. ' optional brackets
  1056. If CParse( "(" )
  1057. expr=ParseExpr()
  1058. Parse ")"
  1059. expr=New TChrExpr.Create( expr )
  1060. Else
  1061. expr=ParseExpr()
  1062. expr=New TChrExpr.Create( expr )
  1063. EndIf
  1064. Case "sgn"
  1065. NextToke
  1066. ' optional brackets
  1067. If CParse( "(" )
  1068. expr=ParseExpr()
  1069. Parse ")"
  1070. expr=New TSgnExpr.Create( expr )
  1071. Else
  1072. expr=ParseExpr()
  1073. expr=New TSgnExpr.Create( expr )
  1074. EndIf
  1075. Case "string"
  1076. Local id$=_toke
  1077. Local ty:TType=ParseType()
  1078. If CParse("ptr") Then
  1079. ty = TType.MapToPointerType(ty)
  1080. End If
  1081. ' string array
  1082. ty = ParseArrayType(ty)
  1083. 'While CParse( "[]" )
  1084. ' ty=New TArrayType.Create( ty)
  1085. 'Wend
  1086. If CParse( "(" )
  1087. expr=ParseExpr()
  1088. Parse ")"
  1089. expr=New TCastExpr.Create( ty,expr,CAST_EXPLICIT )
  1090. Else
  1091. expr=New TIdentExpr.Create( id )
  1092. EndIf
  1093. Case "varptr"
  1094. NextToke
  1095. expr=ParseExpr()
  1096. expr=New TCastExpr.Create( New TVarPtrType, expr, CAST_EXPLICIT )
  1097. Case "pi"
  1098. NextToke
  1099. expr=New TConstExpr.Create( New TDoubleType, Pi )
  1100. Case "self"
  1101. NextToke
  1102. expr=New TSelfExpr
  1103. Case "super"
  1104. NextToke
  1105. Parse "."
  1106. If _toke="new"
  1107. Err "Call to super class constructor must be first statement in a constructor."
  1108. EndIf
  1109. Local id$=ParseIdent()
  1110. ' eat any type stuff
  1111. ParseConstNumberType()
  1112. expr=New TInvokeSuperExpr.Create( id,ParseArgs( stmt ) )
  1113. Default
  1114. Select _tokeType
  1115. Case TOKE_IDENT
  1116. Local tok:TToker=New TToker.Copy( _toker )
  1117. Local ty:TType=CParseIdentType()
  1118. If ty
  1119. expr=New TIdentTypeExpr.Create( ty )
  1120. Else
  1121. _toker=tok
  1122. _toke=_toker.Toke()
  1123. _tokeType=_toker.TokeType()
  1124. expr=New TIdentExpr.Create( ParseIdent() )
  1125. ty = ParseConstNumberType()
  1126. If TArrayType(ty) Then
  1127. If Not TArrayType(ty).elemType Then
  1128. TArrayType(ty).elemType = New TIdentType.Create(TIdentExpr(expr).ident)
  1129. expr=New TIdentTypeExpr.Create( ty )
  1130. End If
  1131. End If
  1132. EndIf
  1133. 'expr=New TIdentExpr.Create( ParseIdent() )
  1134. Case TOKE_INTLIT
  1135. expr=New TConstExpr.Create( New TIntType,_toke )
  1136. NextToke
  1137. Local ty:TType = ParseConstNumberType()
  1138. If ty Then
  1139. TConstExpr(expr).UpdateType(ty)
  1140. End If
  1141. Case TOKE_LONGLIT
  1142. expr=New TConstExpr.Create( New TLongType,_toke )
  1143. NextToke
  1144. Local ty:TType = ParseConstNumberType()
  1145. If ty Then
  1146. TConstExpr(expr).UpdateType(ty)
  1147. End If
  1148. Case TOKE_FLOATLIT
  1149. expr=New TConstExpr.Create( New TFloatType,_toke )
  1150. NextToke
  1151. Local ty:TType = ParseConstNumberType()
  1152. If ty Then
  1153. TConstExpr(expr).ty = ty
  1154. End If
  1155. Case TOKE_STRINGLIT
  1156. expr=New TConstExpr.Create( TType.stringType,BmxUnquote( _toke ) )
  1157. _app.mapStringConsts(BmxUnquote( _toke ))
  1158. NextToke
  1159. Default
  1160. Err "Expecting expression but encountered '"+_toke+"'"
  1161. End Select
  1162. End Select
  1163. Repeat
  1164. Select _toke
  1165. Case "."
  1166. NextToke
  1167. expr=New TIdentExpr.Create( ParseIdent(),expr )
  1168. ParseConstNumberType()
  1169. 'DebugLog expr.ToString()
  1170. Case "("
  1171. If expr = Null Then
  1172. NextToke
  1173. expr=ParseExpr()
  1174. Parse ")"
  1175. Else
  1176. expr=New TFuncCallExpr.Create( expr,ParseArgs( stmt ) )
  1177. End If
  1178. Case "["
  1179. NextToke
  1180. If CParse( ".." )
  1181. If _toke="]"
  1182. expr=New TSliceExpr.Create( expr,Null,Null )
  1183. Else
  1184. expr=New TSliceExpr.Create( expr,Null,ParseExpr() )
  1185. EndIf
  1186. Parse "]"
  1187. Else
  1188. Local from:TExpr=ParseExpr()
  1189. If CParse( ".." )
  1190. If _toke="]"
  1191. expr=New TSliceExpr.Create( expr,from,Null )
  1192. Else
  1193. expr=New TSliceExpr.Create( expr,from,ParseExpr() )
  1194. EndIf
  1195. Parse "]"
  1196. Else
  1197. Local ind:TExpr[] = [from]
  1198. Repeat
  1199. If CParse("]") Then
  1200. Exit
  1201. End If
  1202. Parse ","
  1203. ind = ind + [ParseExpr()]
  1204. Forever
  1205. expr=New TIndexExpr.Create( expr,ind )
  1206. EndIf
  1207. EndIf
  1208. Default
  1209. Return expr
  1210. End Select
  1211. Forever
  1212. End Method
  1213. Method ParseUnaryExpr:TExpr()
  1214. SkipEols
  1215. Local op$=_toke
  1216. Select op
  1217. Case "+","-","~~","not"
  1218. NextToke
  1219. Local expr:TExpr=ParseUnaryExpr()
  1220. Return New TUnaryExpr.Create( op,expr )
  1221. End Select
  1222. Return ParsePrimaryExpr( False )
  1223. End Method
  1224. Method ParsePowExpr:TExpr()
  1225. Local expr:TExpr=ParseUnaryExpr()
  1226. Repeat
  1227. Local op$=_toke
  1228. Select op
  1229. Case "^"
  1230. NextToke
  1231. Local rhs:TExpr=ParseUnaryExpr()
  1232. expr=New TBinaryMathExpr.Create( op,expr,rhs )
  1233. Default
  1234. Return expr
  1235. End Select
  1236. Forever
  1237. End Method
  1238. Method ParseMulDivExpr:TExpr()
  1239. Local expr:TExpr=ParsePowExpr()
  1240. Repeat
  1241. Local op$=_toke
  1242. Select op
  1243. Case "*","/","mod","shl","shr", "sar"
  1244. NextToke
  1245. Local rhs:TExpr=ParsePowExpr()
  1246. expr=New TBinaryMathExpr.Create( op,expr,rhs )
  1247. Default
  1248. Return expr
  1249. End Select
  1250. Forever
  1251. End Method
  1252. Method ParseAddSubExpr:TExpr()
  1253. Local expr:TExpr=ParseMulDivExpr()
  1254. Repeat
  1255. Local op$=_toke
  1256. Select op
  1257. Case "+","-"
  1258. NextToke
  1259. Local rhs:TExpr=ParseMulDivExpr()
  1260. expr=New TBinaryMathExpr.Create( op,expr,rhs )
  1261. Default
  1262. Return expr
  1263. End Select
  1264. Forever
  1265. End Method
  1266. Method ParseBitandExpr:TExpr()
  1267. Local expr:TExpr=ParseAddSubExpr()
  1268. Repeat
  1269. Local op$=_toke
  1270. Select op
  1271. Case "&","~~"
  1272. NextToke
  1273. Local rhs:TExpr=ParseAddSubExpr()
  1274. expr=New TBinaryMathExpr.Create( op,expr,rhs )
  1275. Default
  1276. Return expr
  1277. End Select
  1278. Forever
  1279. End Method
  1280. Method ParseBitorExpr:TExpr()
  1281. Local expr:TExpr=ParseBitandExpr()
  1282. Repeat
  1283. Local op$=_toke
  1284. Select op
  1285. Case "|"
  1286. NextToke
  1287. Local rhs:TExpr=ParseBitandExpr()
  1288. expr=New TBinaryMathExpr.Create( op,expr,rhs )
  1289. Default
  1290. Return expr
  1291. End Select
  1292. Forever
  1293. End Method
  1294. Method ParseCompareExpr:TExpr()
  1295. Local expr:TExpr=ParseBitorExpr()
  1296. Repeat
  1297. Local op$=_toke
  1298. Select op
  1299. Case "=","<",">","<=","=<",">=","=>","<>"
  1300. NextToke
  1301. ' <= or =>
  1302. If (op=">" And (_toke="=")) Or (op="=" And (_toke=">"))
  1303. op:+_toke
  1304. NextToke
  1305. ' <> or <= or =<
  1306. Else If (op="<" And _toke=">") Or (op="<" And _toke="=") Or (op="=" And _toke="<")
  1307. op:+_toke
  1308. NextToke
  1309. EndIf
  1310. Local rhs:TExpr=ParseBitorExpr()
  1311. expr=New TBinaryCompareExpr.Create( op,expr,rhs )
  1312. Default
  1313. Return expr
  1314. End Select
  1315. Forever
  1316. End Method
  1317. Method ParseAndExpr:TExpr()
  1318. Local expr:TExpr=ParseCompareExpr()
  1319. Repeat
  1320. Local op$=_toke
  1321. If op="and"
  1322. NextToke
  1323. Local rhs:TExpr=ParseCompareExpr()
  1324. expr=New TBinaryLogicExpr.Create( op,expr,rhs )
  1325. Else
  1326. Return expr
  1327. EndIf
  1328. Forever
  1329. End Method
  1330. Method ParseOrExpr:TExpr()
  1331. Local expr:TExpr=ParseAndExpr()
  1332. Repeat
  1333. Local op$=_toke
  1334. If op="or"
  1335. NextToke
  1336. Local rhs:TExpr=ParseAndExpr()
  1337. expr=New TBinaryLogicExpr.Create( op,expr,rhs )
  1338. Else
  1339. Return expr
  1340. EndIf
  1341. Forever
  1342. End Method
  1343. Method ParseExpr:TExpr()
  1344. Return ParseOrExpr()
  1345. End Method
  1346. Rem
  1347. unused atm
  1348. Method ReadTillNextToken:string(amount:int=1)
  1349. 'copy current toker and move one token forward
  1350. local tok:TToker = New TToker.Copy(_toker)
  1351. local result:string = _toker._toke
  1352. for local i:int = 0 until amount
  1353. NextTokeToker(tok)
  1354. result :+ " "+ tok._toke
  1355. Next
  1356. return _toker._toke+" "+tok._toke
  1357. End Method
  1358. End Rem
  1359. Method ParseIfStmt( term$, elseIfEndIfReadAheadCheck:Int = False )
  1360. Local tok:TToker
  1361. 'rules:
  1362. '- the command "end" cannot be used as condition
  1363. '- "endif" or "end if" is not allowed in singleline-ifs
  1364. 'if current toke is "if", move on to the next toke
  1365. CParse "if"
  1366. 'read in the expression/condition following after "if"
  1367. Local expr:TExpr=ParseExpr()
  1368. 'if current toke is "then", move to next, else stay at this
  1369. 'position -> makes "then" usage voluntary
  1370. CParse "then"
  1371. 'create empty blocks for then/else
  1372. Local thenBlock:TBlockDecl=New TBlockDecl.Create( _block )
  1373. Local elseBlock:TBlockDecl=New TBlockDecl.Create( _block )
  1374. 'define if the current if is a "singleline if"
  1375. '"singleline ifs" are not allowed to contain "endif" "end if"
  1376. Local singleLineIf:Int = True
  1377. 'to know if it is a multiline or singleline if we have to check
  1378. 'for certain situations
  1379. Select _toke
  1380. Case "~n"
  1381. 'if a <- newline
  1382. ' print "a"
  1383. 'endif
  1384. singleLineIf = False
  1385. Case "if"
  1386. 'another "if" means the outer one is a singleline if!
  1387. singleLineIf = True
  1388. Case "else"
  1389. 'if ReadTillNextToken().toLower() = "else if"
  1390. ' print "IF: found if X then Y else if ..."
  1391. 'else
  1392. ' print "IF: found if X then Y else ..."
  1393. 'endif
  1394. 'also read "else if"
  1395. singleLineIf = True
  1396. Case "elseif"
  1397. singleLineIf = True
  1398. End Select
  1399. 'set thenBlock as the active block
  1400. PushBlock( thenBlock )
  1401. 'now check each toke until we reach our desired term
  1402. 'for singleline-if this is "~n", for multiline-if this is
  1403. '"endif" or "end if"
  1404. If singleLineIf
  1405. term = "~n"
  1406. Else
  1407. term = "end" 'endif, end if
  1408. EndIf
  1409. 'only read until reaching the limit - or no valid toke was returned
  1410. While _toke <> term
  1411. Local currentToke:String = _toke
  1412. Select currentToke
  1413. 'file end before endif/end/elseif
  1414. Case ""
  1415. Err("Expecting expression but encountered end-of-file")
  1416. '"endif" / "end if"
  1417. Case "endif", "end"
  1418. NextToke()
  1419. If singleLineIf Then
  1420. 'check for "end"-command ("if a=1 end")
  1421. If currentToke = "end" And (currentToke + _toke) <> "endif" Then
  1422. ParseEndStmt(False)
  1423. 'found "end if"
  1424. Else
  1425. Err "'End If' without matching 'If'"
  1426. Exit
  1427. EndIf
  1428. EndIf
  1429. 'If currentToke = "endif" or (currentToke + _toke)="endif"
  1430. ' 'do something if "endif/end if" happens ?
  1431. 'Endif
  1432. 'finish this if-statement
  1433. Exit
  1434. '"else" and "elseif" / "else if"
  1435. Case "else","elseif"
  1436. ' print "parsing "+currentToke
  1437. If _block = elseBlock
  1438. Err("If statement can only have one 'else' block.")
  1439. EndIf
  1440. 'switch from thenBlock to elseBlock
  1441. PopBlock()
  1442. PushBlock(elseBlock)
  1443. 'move to next token, might contain "if" for "else if"
  1444. 'doing it this way avoids to parse "elseif if" as
  1445. 'else-statement
  1446. NextToke()
  1447. If currentToke = "elseif" Or (currentToke + _toke)="elseif"
  1448. 'create a new if-statement and exit current handling
  1449. ParseIfStmt(term, True)
  1450. Exit
  1451. EndIf
  1452. Default
  1453. 'parse the current and next tokens
  1454. ParseStmt()
  1455. currentToke = _toke
  1456. 'handle the end-function and "end if"
  1457. Select currentToke
  1458. Case "end"
  1459. 'check next toke too
  1460. NextToke()
  1461. 'found end-function
  1462. If currentToke = "end" And (currentToke + _toke)<>"endif"
  1463. ' print " parsing end .... handling"
  1464. ParseEndStmt(False)
  1465. 'found "end if"
  1466. Else
  1467. If CParse("if") Then
  1468. If singleLineIf Then
  1469. Err "'End If' without matching 'If'"
  1470. End If
  1471. Exit
  1472. End If
  1473. 'NextToke()
  1474. EndIf
  1475. End Select
  1476. End Select
  1477. Wend
  1478. 'change block
  1479. PopBlock()
  1480. 'create a if-then[-else]-statement
  1481. Local stmt:TIfStmt=New TIfStmt.Create( expr,thenBlock,elseBlock )
  1482. _block.AddStmt stmt
  1483. End Method
  1484. Method ParseWhileStmt(loopLabel:TLoopLabelDecl = Null)
  1485. Parse "while"
  1486. Local expr:TExpr=ParseExpr()
  1487. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1488. PushBlock block
  1489. While Not CParse( "wend" ) And Not CParse( "endwhile" )
  1490. ' If CParse( "end" )
  1491. ' CParse "while"
  1492. ' Exit
  1493. ' EndIf
  1494. ParseStmt
  1495. ' to handle "end" statement
  1496. If _toke = "end" Then
  1497. NextToke
  1498. If _toke = "while" Then
  1499. NextToke
  1500. Exit
  1501. Else
  1502. ParseEndStmt(False)
  1503. End If
  1504. End If
  1505. Wend
  1506. PopBlock
  1507. Local stmt:TWhileStmt=New TWhileStmt.Create( expr,block,loopLabel )
  1508. _block.AddStmt stmt
  1509. End Method
  1510. Method ParseRepeatStmt(loopLabel:TLoopLabelDecl = Null)
  1511. Parse "repeat"
  1512. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1513. PushBlock block
  1514. While _toke<>"until" And _toke<>"forever"
  1515. ParseStmt
  1516. Wend
  1517. PopBlock
  1518. SetErr
  1519. Local expr:TExpr
  1520. If CParse( "until" )
  1521. expr=ParseExpr()
  1522. Else
  1523. Parse "forever"
  1524. expr=New TConstExpr.Create( New TBoolType,"" )
  1525. EndIf
  1526. Local stmt:TRepeatStmt=New TRepeatStmt.Create( block,expr,loopLabel )
  1527. _block.AddStmt stmt
  1528. End Method
  1529. Method ParseForStmt(loopLabel:TLoopLabelDecl = Null)
  1530. Parse "for"
  1531. Local varid$,varty:TType,varlocal:Int
  1532. Local varExpr:TExpr
  1533. If CParse( "local" )
  1534. varlocal=True
  1535. varid=ParseIdent()
  1536. 'If Not CParse( ":=" )
  1537. varty=ParseDeclType()
  1538. If varty._flags & (TType.T_CHAR_PTR | TType.T_SHORT_PTR) Then
  1539. DoErr "Illegal variable type"
  1540. End If
  1541. If _toke = "(" Then
  1542. Local fdecl:TFuncDecl = ParseFuncDecl("", FUNC_PTR | DECL_ARG)
  1543. If Not varty Then
  1544. varty = New TFunctionPtrType
  1545. TFunctionPtrType(varty).func = fdecl
  1546. Else
  1547. fdecl.retType = varty
  1548. varty = New TFunctionPtrType
  1549. TFunctionPtrType(varty).func = fdecl
  1550. End If
  1551. TFunctionPtrType(varty).func.ident = varid
  1552. ' function pointer array ?
  1553. While IsArrayDef()
  1554. varty = ParseArrayType(varty)
  1555. Wend
  1556. End If
  1557. Parse( "=" )
  1558. 'EndIf
  1559. Else
  1560. varlocal=False
  1561. varExpr=ParsePrimaryExpr( False )
  1562. 'varExpr = New TIdentExpr.Create( ParseIdent(),varExpr )
  1563. 'ParseConstNumberType()
  1564. ' varid=ParseIdent()
  1565. 'While Cparse(".")
  1566. 'NextToke
  1567. ' varExpr = New TIdentExpr.Create( ParseIdent(),varExpr )
  1568. ' ParseConstNumberType()
  1569. 'Wend
  1570. ' eat any type stuff
  1571. ' ParseConstNumberType()
  1572. Parse "="
  1573. EndIf
  1574. If CParse( "eachin" )
  1575. Local expr:TExpr=ParseExpr()
  1576. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1577. PushBlock block
  1578. While Not CParse( "next" )
  1579. 'If CParse( "end" )
  1580. ' CParse "for"
  1581. ' Exit
  1582. 'EndIf
  1583. ParseStmt
  1584. Wend
  1585. PopBlock
  1586. Local stmt:TForEachinStmt=New TForEachinStmt.Create( varid,varty,varlocal,expr,block,loopLabel, varExpr )
  1587. _block.AddStmt stmt
  1588. Return
  1589. EndIf
  1590. Local from:TExpr=ParseExpr()
  1591. Local op$
  1592. If CParse( "to" )
  1593. op="<="
  1594. Else If CParse( "until" )
  1595. op="<"
  1596. Else
  1597. Err "Expecting 'To' or 'Until'."
  1598. EndIf
  1599. Local term:TExpr=ParseExpr()
  1600. Local stp:TExpr
  1601. If CParse( "step" )
  1602. stp=ParseExpr()
  1603. Else
  1604. stp=New TConstExpr.Create( New TIntType,"1" )
  1605. EndIf
  1606. Local init:TStmt,expr:TExpr,incr:TStmt
  1607. If varlocal
  1608. Local indexVar:TLocalDecl=New TLocalDecl.Create( varid,varty,New TCastExpr.Create( varty,from,1 ),0 )
  1609. init=New TDeclStmt.Create( indexVar )
  1610. expr=New TBinaryCompareExpr.Create( op,New TVarExpr.Create( indexVar ),New TCastExpr.Create( varty,term,1 ) )
  1611. incr=New TAssignStmt.Create( "=",New TVarExpr.Create( indexVar ),New TBinaryMathExpr.Create( "+",New TVarExpr.Create( indexVar ),New TCastExpr.Create( varty,stp,1 ) ) )
  1612. Else
  1613. ' varty is NULL here for the casts. We will back-populate it later.
  1614. ' init=New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),from )
  1615. ' expr=New TBinaryCompareExpr.Create( op,New TIdentExpr.Create( varid ),New TCastExpr.Create( varty,term,1 ) )
  1616. ' incr=New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),New TBinaryMathExpr.Create( "+",New TIdentExpr.Create( varid ),New TCastExpr.Create( varty,stp,1 ) ) )
  1617. init=New TAssignStmt.Create( "=",varExpr,from )
  1618. expr=New TBinaryCompareExpr.Create( op,varExpr,New TCastExpr.Create( varty,term,1 ) )
  1619. incr=New TAssignStmt.Create( "=",varExpr,New TBinaryMathExpr.Create( "+",varExpr,New TCastExpr.Create( varty,stp,1 ) ) )
  1620. EndIf
  1621. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1622. PushBlock block
  1623. While Not CParse( "next" )
  1624. 'If CParse( "end" )
  1625. ' CParse "for"
  1626. ' Exit
  1627. 'EndIf
  1628. ParseStmt
  1629. Wend
  1630. PopBlock
  1631. NextToke
  1632. Local stmt:TForStmt=New TForStmt.Create( init,expr,incr,block,loopLabel )
  1633. _block.AddStmt stmt
  1634. End Method
  1635. Method ParseDefDataStmt(label:TLoopLabelDecl = Null)
  1636. Parse "defdata"
  1637. If AtEos() Then
  1638. Err "Expecting expression but encountered " + DescribeToke(_toke)
  1639. End If
  1640. Local args:TExpr[]
  1641. Local nargs:Int
  1642. Repeat
  1643. Local arg:TExpr
  1644. If _toke And _toke<>"," arg=ParseExpr()
  1645. If args.Length=nargs args=args + New TExpr[10]
  1646. args[nargs]=arg
  1647. nargs:+1
  1648. Until Not CParse(",")
  1649. args=args[..nargs]
  1650. Local dataLabel:TDataLabelDecl
  1651. If label Then
  1652. dataLabel = New TDataLabelDecl.Create(label.ident, label.attrs)
  1653. End If
  1654. Local decl:TDefDataDecl = New TDefDataDecl.Create(args, dataLabel)
  1655. _app.dataDefs.AddLast(decl)
  1656. End Method
  1657. Method ParseReadDataStmt()
  1658. Parse "readdata"
  1659. Local args:TExpr[]
  1660. Local nargs:Int
  1661. If Not AtEos() Then
  1662. Repeat
  1663. Local arg:TExpr
  1664. If _toke And _toke<>"," arg=ParseExpr()
  1665. If args.Length=nargs args=args + New TExpr[10]
  1666. args[nargs]=arg
  1667. nargs:+1
  1668. Until Not CParse(",")
  1669. args=args[..nargs]
  1670. End If
  1671. _block.AddStmt New TReadDataStmt.Create( args )
  1672. End Method
  1673. Method ParseRestoreDataStmt()
  1674. Parse "restoredata"
  1675. Local expr:TExpr = ParseExpr()
  1676. _block.AddStmt New TRestoreDataStmt.Create( expr )
  1677. End Method
  1678. Method ParseReturnStmt()
  1679. Parse "return"
  1680. Local expr:TExpr
  1681. If Not AtEos() expr=ParseExpr()
  1682. _block.AddStmt New TReturnStmt.Create( expr )
  1683. End Method
  1684. Method ParseExitStmt()
  1685. Parse "exit"
  1686. Local expr:TExpr
  1687. If Not AtEos() expr=ParseExpr()
  1688. _block.AddStmt New TBreakStmt.Create(expr)
  1689. End Method
  1690. Method ParseContinueStmt()
  1691. Parse "continue"
  1692. Local expr:TExpr
  1693. If Not AtEos() expr=ParseExpr()
  1694. _block.AddStmt New TContinueStmt.Create(expr)
  1695. End Method
  1696. Method ParseTryStmt()
  1697. Parse "try"
  1698. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1699. Local catches:TList=New TList
  1700. PushBlock block
  1701. While _toke<>"end" And _toke<>"endtry"
  1702. If CParse( "catch" )
  1703. Local id:String=ParseIdent()
  1704. Local ty:TType
  1705. If Not CParse(":") Then
  1706. Parse "$"
  1707. ty= TType.stringType
  1708. Else
  1709. ty=ParseType()
  1710. End If
  1711. Local init:TLocalDecl=New TLocalDecl.Create( id,ty,Null,0 )
  1712. Local block:TBlockDecl=New TBlockDecl.Create( _block )
  1713. catches.AddLast(New TCatchStmt.Create( init,block ))
  1714. PopBlock
  1715. PushBlock block
  1716. Else
  1717. ParseStmt
  1718. If _toke = "end" Then
  1719. NextToke
  1720. If _toke = "try" Then
  1721. ' we are done with the try statement
  1722. Exit
  1723. Else
  1724. ParseEndStmt(False)
  1725. End If
  1726. End If
  1727. End If
  1728. Wend
  1729. PopBlock
  1730. If Not CParse("endtry") Then
  1731. ' TODO : handle case of no catch - perhaps throw the exception again.
  1732. 'If Not catches.Length() Err "Try block must have at least one catch block"
  1733. NextToke
  1734. CParse "try"
  1735. End If
  1736. _block.AddStmt New TTryStmt.Create( block,TCatchStmt[](catches.ToArray()) )
  1737. End Method
  1738. Method ParseThrowStmt()
  1739. Parse "throw"
  1740. Local expr:TExpr = ParseExpr()
  1741. _block.AddStmt New TThrowStmt.Create( expr )
  1742. End Method
  1743. Method ParseReleaseStmt()
  1744. Parse "release"
  1745. Local expr:TExpr = ParseExpr()
  1746. _block.AddStmt New TReleaseStmt.Create( expr )
  1747. End Method
  1748. Method ParseAssertStmt()
  1749. Parse "assert"
  1750. Local expr:TExpr = ParseExpr()
  1751. Local elseExpr:TExpr
  1752. If _toke = "," Or _toke = "else" Then
  1753. NextToke
  1754. elseExpr = ParseExpr()
  1755. End If
  1756. _block.AddStmt New TAssertStmt.Create( expr, elseExpr )
  1757. End Method
  1758. Method ParseEndStmt(eatEnd:Int = True)
  1759. If eatEnd Then
  1760. Parse "end"
  1761. End If
  1762. _block.AddStmt New TEndStmt.Create( )
  1763. End Method
  1764. Method ParseSelectStmt()
  1765. Parse "select"
  1766. Local block:TBlockDecl=_block
  1767. Local tmpVar:TLocalDecl=New TLocalDecl.Create( "",Null,ParseExpr(),,True )
  1768. block.AddStmt New TDeclStmt.Create( tmpVar )
  1769. While _toke<>"end" And _toke<>"default" And _toke<>"endselect"
  1770. SetErr
  1771. Select _toke
  1772. Case "~n"
  1773. NextToke
  1774. Case "case"
  1775. NextToke
  1776. Local comp:TExpr
  1777. Repeat
  1778. Local expr:TExpr=New TVarExpr.Create( tmpVar )
  1779. expr=New TBinaryCompareExpr.Create( "=",expr,ParseExpr() )
  1780. If comp
  1781. comp=New TBinaryLogicExpr.Create( "or",comp,expr )
  1782. Else
  1783. comp=expr
  1784. EndIf
  1785. Until Not CParse(",")
  1786. Local thenBlock:TBlockDecl=New TBlockDecl.Create( _block )
  1787. Local elseBlock:TBlockDecl=New TBlockDecl.Create( _block )
  1788. Local ifstmt:TIfStmt=New TIfStmt.Create( comp,thenBlock,elseBlock )
  1789. block.AddStmt ifstmt
  1790. block=ifstmt.thenBlock
  1791. PushBlock block
  1792. Local fin:Int = False
  1793. While _toke<>"case" And _toke<>"default" And _toke<>"end" And _toke<>"endselect"
  1794. ParseStmt
  1795. If _toke = "end" Then
  1796. NextToke
  1797. If _toke = "select" Then
  1798. ' we are done with the select statement, full exit
  1799. fin = True
  1800. Exit
  1801. Else
  1802. ParseEndStmt(False)
  1803. End If
  1804. End If
  1805. Wend
  1806. PopBlock
  1807. block=elseBlock
  1808. If fin Exit
  1809. Default
  1810. Err "Syntax error - expecting 'Case', 'Default' or 'End'."
  1811. End Select
  1812. Wend
  1813. If _toke="default"
  1814. NextToke
  1815. PushBlock block
  1816. While _toke<>"end" And _toke<>"endselect"
  1817. SetErr
  1818. Select _toke
  1819. Case "case"
  1820. Err "Case can not appear after default."
  1821. Case "default"
  1822. Err "Select statement can have only one default block."
  1823. End Select
  1824. ParseStmt
  1825. If _toke = "end" Then
  1826. NextToke
  1827. If _toke = "select" Then
  1828. Exit
  1829. Else
  1830. ParseEndStmt(False)
  1831. End If
  1832. End If
  1833. Wend
  1834. PopBlock
  1835. EndIf
  1836. SetErr
  1837. If Not CParse("endselect") Then
  1838. If Not CParse("select")
  1839. Parse "end"
  1840. Parse "select"
  1841. End If
  1842. End If
  1843. End Method
  1844. Method ParseExternBlock(mdecl:TModuleDecl, attrs:Int)
  1845. NextToke
  1846. If _tokeType=TOKE_STRINGLIT
  1847. Local api:String = ParseStringLit().ToLower()
  1848. If api = "win32" Then
  1849. attrs:| DECL_API_WIN32
  1850. End If
  1851. End If
  1852. attrs = attrs | DECL_EXTERN
  1853. If CParse( "private" ) attrs=attrs|DECL_PRIVATE
  1854. While _toke<>"endextern"
  1855. If CParse( "end" )
  1856. Parse "extern"
  1857. Exit
  1858. EndIf
  1859. SetErr
  1860. Select _toke
  1861. Case "~n"
  1862. NextToke
  1863. Case "const","global"
  1864. mdecl.InsertDecls ParseDecls( _toke,attrs )
  1865. Case "struct"
  1866. mdecl.InsertDecl ParseClassDecl( _toke,attrs | CLASS_STRUCT )
  1867. Case "type"
  1868. mdecl.InsertDecl ParseClassDecl( _toke,attrs )
  1869. Case "function"
  1870. mdecl.InsertDecl ParseFuncDecl( _toke,attrs )
  1871. Case "interface"
  1872. mdecl.InsertDecl ParseClassDecl( _toke,attrs | CLASS_INTERFACE )
  1873. Default
  1874. If _toke <> "end" And _toke <> "endextern" Then
  1875. Err "Expecting expression but encountered '"+_toke+"'"
  1876. End If
  1877. End Select
  1878. Wend
  1879. If _toke="endextern" Then
  1880. NextToke
  1881. End If
  1882. End Method
  1883. Method ParseStmt()
  1884. SetErr
  1885. Select _toke
  1886. Case ";","~n"
  1887. NextToke
  1888. Case "const","local","global"
  1889. ParseDeclStmts
  1890. ' nested function - needs to get added to the "module"
  1891. Case "function"
  1892. _block.InsertDecl ParseFuncDecl( _toke,FUNC_NESTED)
  1893. Case "return"
  1894. ParseReturnStmt()
  1895. Case "exit"
  1896. ParseExitStmt()
  1897. Case "continue"
  1898. ParseContinueStmt()
  1899. Case "if"
  1900. ParseIfStmt( "" )
  1901. Case "while"
  1902. ParseWhileStmt()
  1903. Case "repeat"
  1904. ParseRepeatStmt()
  1905. Case "for"
  1906. ParseForStmt()
  1907. Case "select"
  1908. ParseSelectStmt()
  1909. Case "assert"
  1910. ParseAssertStmt()
  1911. Case "try"
  1912. ParseTryStmt()
  1913. Case "throw"
  1914. ParseThrowStmt()
  1915. Case "end"
  1916. ParseEndStmt()
  1917. Case "extern"
  1918. ParseExternBlock(_module, 0)
  1919. Case "#"
  1920. Local decl:TLoopLabelDecl = ParseLoopLabelDecl()
  1921. NextToke
  1922. While _toke
  1923. SetErr
  1924. Select _toke.ToLower()
  1925. Case "~n"
  1926. NextToke
  1927. Case "while"
  1928. ParseWhileStmt(decl)
  1929. Exit
  1930. Case "repeat"
  1931. ParseRepeatStmt(decl)
  1932. Exit
  1933. Case "for"
  1934. ParseForStmt(decl)
  1935. Exit
  1936. Case "defdata"
  1937. ParseDefDataStmt(decl)
  1938. Exit
  1939. Default
  1940. Err "Labels must appear before a loop or DefData statement"
  1941. End Select
  1942. Wend
  1943. Case "release"
  1944. ParseReleaseStmt()
  1945. Case "defdata"
  1946. ParseDefDataStmt()
  1947. Case "readdata"
  1948. ParseReadDataStmt()
  1949. Case "restoredata"
  1950. ParseRestoreDataStmt()
  1951. Default
  1952. If _toke.StartsWith("'!") Then
  1953. If _tokeType = TOKE_NATIVE Then
  1954. ParseNativeStmt()
  1955. End If
  1956. Else
  1957. Local expr:TExpr=ParsePrimaryExpr( True )
  1958. Select _toke.ToLower()
  1959. '"=","*=","/=","+=","-=","&=","|=","~~=","Mod","Shl","Shr"
  1960. Case "=",":*",":/",":+",":-",":&",":|",":~~","mod","shl","shr", ":shl", ":shr", "sar", ":sar", ":mod"
  1961. ' remap symbols...
  1962. 'For Local i:Int = 0 Until TToker._symbols.length
  1963. ' Local sym$= TToker._symbols[i]
  1964. ' If _toke.ToLower() = sym
  1965. ' _toke = TToker._symbols_map[i]
  1966. ' Exit
  1967. ' EndIf
  1968. 'Next
  1969. If TIdentExpr( expr ) Or TIndexExpr( expr )
  1970. Local op$=_toke.ToLower()
  1971. NextToke
  1972. ' If Not op.EndsWith( "=" ) And Not op.StartsWith("=")
  1973. ' Parse "="
  1974. ' op:+"="
  1975. ' EndIf
  1976. _block.AddStmt New TAssignStmt.Create( op,expr,ParseExpr() )
  1977. Else
  1978. Err "Assignment operator '"+_toke+"' cannot be used this way."
  1979. EndIf
  1980. Return
  1981. End Select
  1982. If TIdentExpr( expr )
  1983. expr=New TFuncCallExpr.Create( expr,ParseArgs( True ) )
  1984. Else If TFuncCallExpr( expr) Or TInvokeSuperExpr( expr ) Or TNewObjectExpr( expr ) Or TNewExpr(expr)
  1985. Else If TIndexExpr(expr)
  1986. expr = New TFuncCallExpr.Create( expr, ParseArgs( True ) )
  1987. Else
  1988. Err "Expression cannot be used as a statement."
  1989. EndIf
  1990. _block.AddStmt New TExprStmt.Create( expr )
  1991. End If
  1992. End Select
  1993. End Method
  1994. Method ParseDecl:TDecl( toke$,attrs:Int )
  1995. SetErr
  1996. Local id$=ParseIdent()
  1997. Local ty:TType
  1998. Local init:TExpr
  1999. If attrs & DECL_EXTERN
  2000. ty=ParseDeclType()
  2001. ' If CParse("(") Then
  2002. If _toke = "(" Then
  2003. ' function pointer?
  2004. Local decl:TFuncDecl = ParseFuncDecl("", attrs | FUNC_PTR)
  2005. If Not ty Then
  2006. ty = New TFunctionPtrType
  2007. TFunctionPtrType(ty).func = decl
  2008. Else
  2009. decl.retType = ty
  2010. ty = New TFunctionPtrType
  2011. TFunctionPtrType(ty).func = decl
  2012. End If
  2013. TFunctionPtrType(ty).func.ident = id
  2014. Else If toke = "const" Then
  2015. If CParse("=") Then
  2016. init=ParseExpr()
  2017. End If
  2018. End If
  2019. Else If CParse( ":=" )
  2020. init=ParseExpr()
  2021. Else
  2022. ty=ParseDeclType()
  2023. If CParse( "=" )
  2024. init=ParseExpr()
  2025. Else If CParse( "[" )
  2026. Local ln:TExpr[]
  2027. Repeat
  2028. If CParse(",") Then
  2029. ln = ln + [New TNullExpr]
  2030. Continue
  2031. End If
  2032. If CParse("]") Exit
  2033. ln = ln + [ParseExpr()]
  2034. If CParse("]") Exit
  2035. Parse(",")
  2036. Forever
  2037. 'Parse "]"
  2038. ty = ParseArrayType(ty)
  2039. 'While CParse( "[]" )
  2040. ' ty=New TArrayType.Create(ty)
  2041. 'Wend
  2042. init=New TNewArrayExpr.Create( ty,ln)
  2043. ty=New TArrayType.Create( ty, ln.length )
  2044. Else If _toke = "(" Then
  2045. ' function pointer?
  2046. Local fdecl:TFuncDecl = ParseFuncDecl("", FUNC_PTR)
  2047. If toke = "field" Then
  2048. fdecl.attrs :| FUNC_METHOD
  2049. End If
  2050. If Not ty Then
  2051. ty = New TFunctionPtrType
  2052. TFunctionPtrType(ty).func = fdecl
  2053. Else
  2054. fdecl.retType = ty
  2055. ty = New TFunctionPtrType
  2056. TFunctionPtrType(ty).func = fdecl
  2057. End If
  2058. TFunctionPtrType(ty).func.ident = ""
  2059. ' an initialised array of function pointers?
  2060. If Not IsArrayDef() And CParse( "[" )
  2061. Local ln:TExpr[]
  2062. Repeat
  2063. If CParse(",") Then
  2064. ln = ln + [New TNullExpr]
  2065. Continue
  2066. End If
  2067. If CParse("]") Exit
  2068. ln = ln + [ParseExpr()]
  2069. If CParse("]") Exit
  2070. Parse(",")
  2071. Forever
  2072. 'Parse "]"
  2073. ty = ParseArrayType(ty)
  2074. 'While CParse( "[]" )
  2075. ' ty=New TArrayType.Create(ty)
  2076. 'Wend
  2077. init=New TNewArrayExpr.Create( ty,ln)
  2078. ty=New TArrayType.Create( ty, ln.length )
  2079. Else
  2080. While IsArrayDef()
  2081. ty = ParseArrayType(ty)
  2082. Wend
  2083. ' check for function pointer init
  2084. If CParse("=") Then
  2085. init=ParseExpr()
  2086. Else
  2087. init=New TConstExpr.Create( ty,"" )
  2088. End If
  2089. End If
  2090. Else If toke<>"const"
  2091. init=New TConstExpr.Create( ty,"" )
  2092. Else
  2093. Err "Constants must be initialized."
  2094. EndIf
  2095. EndIf
  2096. Local decl:TValDecl
  2097. Select toke
  2098. Case "global" decl=New TGlobalDecl.Create( id,ty,init,attrs )
  2099. Case "field" decl=New TFieldDecl.Create( id,ty,init,attrs )
  2100. Case "const" decl=New TConstDecl.Create( id,ty,init,attrs )
  2101. Case "local" decl=New TLocalDecl.Create( id,ty,init,attrs )
  2102. End Select
  2103. If decl.IsExtern()
  2104. 'DebugStop
  2105. If CParse( "=" )
  2106. decl.munged=ParseStringLit()
  2107. Else
  2108. decl.munged=decl.ident
  2109. EndIf
  2110. If TFunctionPtrType(ty) Then
  2111. TFunctionPtrType(ty).func.munged = decl.munged
  2112. Local cdets:TCastDets = TCastDets(_externCasts.ValueForKey(TFunctionPtrType(ty).func.munged))
  2113. If cdets Then
  2114. TFunctionPtrType(ty).func.castTo = cdets.retType
  2115. If cdets.noGen Then
  2116. TFunctionPtrType(ty).func.noCastGen = True
  2117. End If
  2118. For Local i:Int = 0 Until cdets.args.length
  2119. If i < TFunctionPtrType(ty).func.argDecls.length Then
  2120. TFunctionPtrType(ty).func.argDecls[i].castTo = cdets.args[i]
  2121. End If
  2122. Next
  2123. End If
  2124. End If
  2125. EndIf
  2126. 'meta data for variables
  2127. If CParse( "{" ) Then
  2128. 'print "meta for variable: "+id+ " -> "+ParseMetaData()
  2129. decl.metadata = ParseMetaData()
  2130. EndIf
  2131. Return decl
  2132. End Method
  2133. Method ParseDecls:TList( toke$,attrs:Int )
  2134. If toke Parse toke
  2135. Local decls:TList=New TList'<Decl>
  2136. Repeat
  2137. Local decl:TDecl=ParseDecl( toke,attrs )
  2138. decls.AddLast decl
  2139. If Not CParse(",") Return decls
  2140. Forever
  2141. End Method
  2142. Method ParseDeclStmts()
  2143. Local toke$=_toke
  2144. NextToke
  2145. Repeat
  2146. Local decl:TDecl=ParseDecl( toke,0 )
  2147. _block.AddStmt New TDeclStmt.Create( decl )
  2148. ' reset the decl scope, adding decl to the block decl list.
  2149. ' this improves scope visibilty - for decls such as embedded functions
  2150. If TConstDecl(decl) Or TGlobalDecl(decl) Then
  2151. decl.scope = Null
  2152. _block.InsertDecl(decl)
  2153. If TGlobalDecl(decl) Then
  2154. TGlobalDecl(decl).funcGlobal = True
  2155. End If
  2156. End If
  2157. Until Not CParse(",")
  2158. End Method
  2159. Method ParseLoopLabelDecl:TLoopLabelDecl()
  2160. NextToke
  2161. Local id:String = ParseIdent()
  2162. Return New TLoopLabelDecl.Create(id, 0)
  2163. End Method
  2164. 'handle end-of-line "dot dot return"-line connector
  2165. '-> skips EOL tokens
  2166. Method HandleDotsLineConnector(eatToke:Int = False)
  2167. Local tok:TToker = New TToker.Copy(_toker)
  2168. Local t:String = tok.NextToke()
  2169. Local count:Int = tok.SkipSpace()
  2170. For Local i:Int = 0 Until count
  2171. NextToke
  2172. Next
  2173. t = tok._toke
  2174. If t = "~r" Then
  2175. t = tok.NextToke()
  2176. If t = "~n" Then
  2177. NextToke
  2178. NextToke
  2179. Else
  2180. NextToke
  2181. End If
  2182. Else
  2183. If t = "~n" Then
  2184. NextToke
  2185. End If
  2186. End If
  2187. If eatToke And Not count Then
  2188. NextToke
  2189. End If
  2190. End Method
  2191. 'should return a specific "metadata object" ?
  2192. ' metadata is in the form : {key key=value key="value"}
  2193. Method ParseMetaData:TMetadata()
  2194. Local meta:TMetadata = New TMetadata
  2195. SkipEols
  2196. Repeat
  2197. If meta.metadataString Then
  2198. meta.metadataString :+ " "
  2199. End If
  2200. Select _tokeType
  2201. Case TOKE_INTLIT
  2202. Err "Expecting '}' but encountered integer literal"
  2203. Case TOKE_FLOATLIT
  2204. Err "Expecting '}' but encountered floating point literal"
  2205. Case TOKE_STRINGLIT
  2206. Err "Expecting '}' but encountered string literal"
  2207. Case TOKE_SYMBOL
  2208. Err "Expecting '}' but encountered " + _toke
  2209. End Select
  2210. 'append current token to metaDataString
  2211. Local key:String = _toke
  2212. meta.metadataString :+ key
  2213. 'read next token
  2214. NextToke()
  2215. Local value:String
  2216. ' got a value
  2217. If CParse("=") Then
  2218. If _tokeType = TOKE_IDENT Then
  2219. Err "Meta data must be literal constant"
  2220. End If
  2221. value = _toke
  2222. meta.metadataString :+ "=" + value
  2223. 'read next token
  2224. NextToke()
  2225. Else
  2226. value = "1"
  2227. meta.metadataString :+ "=1"
  2228. End If
  2229. meta.InsertMeta(key.ToLower(), value)
  2230. 'reached end of meta data declaration
  2231. If _toke="}" Then Exit
  2232. Forever
  2233. 'continue to next token
  2234. NextToke()
  2235. 'parse this into something
  2236. Return meta
  2237. End Method
  2238. Method ParseFuncDecl:TFuncDecl( toke$,attrs:Int, returnType:TType = Null )
  2239. SetErr
  2240. If toke Parse toke
  2241. Local id$
  2242. Local ty:TType
  2243. Local meth:Int = attrs & FUNC_METHOD
  2244. Local meta:TMetadata
  2245. Local noMangle:Int
  2246. If Not returnType Then
  2247. If attrs & FUNC_METHOD
  2248. If _toke="new"
  2249. If attrs & DECL_EXTERN
  2250. Err "Extern classes cannot have constructors"
  2251. EndIf
  2252. id="New"
  2253. NextToke
  2254. attrs:|FUNC_CTOR
  2255. attrs:&~FUNC_METHOD
  2256. Else If _toke="operator" Then
  2257. attrs:|FUNC_OPERATOR
  2258. NextToke
  2259. Local t:String = _toke.ToLower()
  2260. NextToke
  2261. Select t
  2262. Case "*","/","+","-","&","|","~~"
  2263. id = t
  2264. Case ":*",":/",":+",":-",":&",":|",":~~"
  2265. id = t
  2266. Case "<",">"',"="',"<=",">=","=","<>"
  2267. If CParse("=") Then
  2268. t :+ "="
  2269. Else If t = "<" And CParse(">") Then
  2270. t :+ ">"
  2271. End If
  2272. id = t
  2273. Case "="
  2274. id = t
  2275. Case "mod", "shl", "shr"
  2276. id = t
  2277. Case ":mod", ":shl", ":shr"
  2278. id = t
  2279. Default
  2280. DoErr "Operator must be one of: * / + - & | ~~ :* :/ :+ :- :& :| :~~ < > <= >= = <> mod shl shr :mod :shl :shr"
  2281. End Select
  2282. ty=ParseDeclType()
  2283. Else
  2284. id=ParseIdent()
  2285. ty=ParseDeclType()
  2286. If ty._flags & (TType.T_CHAR_PTR | TType.T_SHORT_PTR) Then
  2287. DoErr "Illegal function return type"
  2288. End If
  2289. ' Delete() return type should always be Void
  2290. If id.ToLower() = "delete" Then
  2291. attrs:|FUNC_DTOR
  2292. If TIntType(ty) Then
  2293. ty = New TVoidType
  2294. End If
  2295. End If
  2296. EndIf
  2297. Else
  2298. If Not (attrs & FUNC_PTR) Then
  2299. id=ParseIdent()
  2300. ty=ParseDeclType()
  2301. ' can only return "$z" and "$w" from an extern function.
  2302. If ty._flags & (TType.T_CHAR_PTR | TType.T_SHORT_PTR) And Not (attrs & DECL_EXTERN) Then
  2303. DoErr "Illegal function return type"
  2304. End If
  2305. End If
  2306. EndIf
  2307. End If
  2308. Local args:TArgDecl[]
  2309. Parse "("
  2310. SkipEols
  2311. If _toke<>")"
  2312. Local nargs:Int
  2313. Repeat
  2314. Local argId$=ParseIdent()
  2315. Local ty:TType=ParseDeclType()
  2316. Local init:TExpr
  2317. ' function pointer ?
  2318. If _toke = "(" Then
  2319. Local fdecl:TFuncDecl = ParseFuncDecl("", FUNC_PTR | DECL_ARG)
  2320. If Not ty Then
  2321. ty = New TFunctionPtrType
  2322. TFunctionPtrType(ty).func = fdecl
  2323. Else
  2324. fdecl.retType = ty
  2325. ty = New TFunctionPtrType
  2326. TFunctionPtrType(ty).func = fdecl
  2327. End If
  2328. TFunctionPtrType(ty).func.ident = argId
  2329. ' function pointer array ?
  2330. While IsArrayDef()
  2331. ty = ParseArrayType(ty)
  2332. Wend
  2333. End If
  2334. ' var argument?
  2335. If CParse("var") Then
  2336. ty = TType.MapToVarType(ty)
  2337. Else If CParse( "=" )
  2338. init=ParseExpr()
  2339. End If
  2340. Local arg:TArgDecl=New TArgDecl.Create( argId,ty,init )
  2341. If args.Length=nargs args=args + New TArgDecl[10]
  2342. args[nargs]=arg
  2343. nargs:+1
  2344. If _toke=")" Exit
  2345. Parse ","
  2346. Forever
  2347. args=args[..nargs]
  2348. EndIf
  2349. Parse ")"
  2350. If returnType Then
  2351. Return New TFuncDecl.CreateF(Null,returnType,args,attrs)
  2352. End If
  2353. Local fdecl:TFuncDecl
  2354. ' wait.. so everything until now was a function pointer return type, and we still have to process the function declaration...
  2355. If _toke = "(" Then
  2356. Local retTy:TType = New TFunctionPtrType
  2357. TFunctionPtrType(retTy).func = New TFuncDecl.CreateF("",ty,args,attrs )
  2358. TFunctionPtrType(retTy).func.attrs :| FUNC_PTR
  2359. fdecl = ParseFuncDecl("", attrs, retTy)
  2360. ty = retTy
  2361. End If
  2362. Repeat
  2363. If CParse( "final" )
  2364. attrs:|DECL_FINAL
  2365. Else If CParse( "abstract" )
  2366. attrs:|DECL_ABSTRACT
  2367. Else If CParse( "property" )
  2368. If attrs & FUNC_METHOD
  2369. attrs:|FUNC_PROPERTY
  2370. Else
  2371. Err "Only methods can be properties."
  2372. EndIf
  2373. Else If CParse( "nodebug" )
  2374. ' TODO : NoDebug
  2375. attrs :| DECL_NODEBUG
  2376. Else If CParse( "{" ) 'meta data
  2377. ' TODO : do something with the metadata
  2378. 'meta data for functions/methods
  2379. 'print "meta for func/meth: "+id+ " -> "+ParseMetaData()
  2380. meta = ParseMetaData()
  2381. If meta.HasMeta("nomangle") Then
  2382. If attrs & FUNC_METHOD Then
  2383. Err "Only functions can specify NoMangle"
  2384. Else
  2385. noMangle = True
  2386. End If
  2387. End If
  2388. Else If _tokeType=TOKE_STRINGLIT
  2389. ' "win32", etc
  2390. ' TODO ? something with this??
  2391. Local api:String = ParseStringLit().ToLower()
  2392. If api = "win32" Then
  2393. attrs :| DECL_API_WIN32
  2394. End If
  2395. Else
  2396. Exit
  2397. EndIf
  2398. Forever
  2399. Local funcDecl:TFuncDecl
  2400. If attrs & FUNC_CTOR Then
  2401. funcDecl=New TNewDecl.CreateF( id,ty,args,attrs )
  2402. Else
  2403. If fdecl Then
  2404. funcDecl = fdecl
  2405. funcDecl.ident = id
  2406. Else
  2407. funcDecl=New TFuncDecl.CreateF( id,ty,args,attrs )
  2408. End If
  2409. funcDecl.noMangle = noMangle
  2410. End If
  2411. If meta Then
  2412. funcDecl.metadata = meta
  2413. End If
  2414. If funcDecl.IsExtern() Or (attrs & FUNC_PTR)
  2415. funcDecl.munged=funcDecl.ident
  2416. ' a normal function pointer definition *probably* can't be defined with a munged name?
  2417. ' If there is an equals here, one can assume it is for an initialisation...
  2418. 'If (Not (attrs & FUNC_PTR)) Or (attrs & FUNC_PTR And Not (attrs & DECL_ARG)) Then
  2419. If Not (attrs & FUNC_PTR) Then
  2420. If CParse( "=" )
  2421. funcDecl.munged=ParseStringLit()
  2422. End If
  2423. 'Array $resize hack!
  2424. 'If funcDecl.munged="$resize"
  2425. ' funcDecl.retTypeExpr=TType.emptyArrayType
  2426. 'EndIf
  2427. EndIf
  2428. If funcDecl.munged Then
  2429. ' look up extern cast list
  2430. Local cdets:TCastDets = TCastDets(_externCasts.ValueForKey(funcDecl.munged))
  2431. If cdets Then
  2432. funcDecl.castTo = cdets.retType
  2433. If cdets.noGen Then
  2434. funcDecl.noCastGen = True
  2435. End If
  2436. For Local i:Int = 0 Until cdets.args.length
  2437. If i < funcDecl.argDecls.length Then
  2438. funcDecl.argDecls[i].castTo = cdets.args[i]
  2439. End If
  2440. Next
  2441. End If
  2442. End If
  2443. Return funcDecl
  2444. EndIf
  2445. If funcDecl.IsAbstract() Return funcDecl
  2446. 'Ok, only first statement of a constructor can call super constructor - not pretty, should be in semant.
  2447. If attrs & FUNC_CTOR
  2448. SkipEols
  2449. If CParse( "super" )
  2450. Parse "."
  2451. If _toke="new"
  2452. Local id$="New"
  2453. NextToke
  2454. 'funcDecl.superCtor=New TInvokeSuperExpr.Create( id,ParseArgs( True ) )
  2455. 'funcDecl.AddStmt New TExprStmt.Create( funcDecl.superCtor )
  2456. funcDecl.AddStmt New TExprStmt.Create( New TNewExpr.Create(ParseArgs(True), True))
  2457. Else
  2458. Local id$=ParseIdent()
  2459. funcDecl.AddStmt New TExprStmt.Create( New TInvokeSuperExpr.Create( id,ParseArgs( True ) ) )
  2460. EndIf
  2461. Else
  2462. 'Invoke super default ctor
  2463. 'funcDecl.superCtor=New InvokeSuperExpr( "new",[] )
  2464. 'funcDecl.AddStmt New TExprStmt( funcDecl.superCtor )
  2465. EndIf
  2466. EndIf
  2467. PushBlock funcDecl
  2468. While (Not meth And _toke.ToLower()<>"endfunction") Or (meth And _toke.ToLower()<>"endmethod")
  2469. If CParse( "end" )
  2470. If (Not meth And CParse("function")) Or (meth And CParse("method"))
  2471. Exit
  2472. End If
  2473. ' handle "end" statement
  2474. ParseEndStmt(False)
  2475. EndIf
  2476. ParseStmt
  2477. Wend
  2478. PopBlock
  2479. NextToke
  2480. 'If toke CParse toke
  2481. Return funcDecl
  2482. End Method
  2483. Method ParseClassDecl:TClassDecl( toke$,attrs:Int )
  2484. SetErr
  2485. If toke Parse toke
  2486. Local id$=ParseIdent()
  2487. Local args:TStack = New TStack
  2488. Local superTy:TIdentType
  2489. Local imps:TIdentType[]
  2490. Local meta:TMetadata
  2491. 'If (attrs & CLASS_INTERFACE) And (attrs & DECL_EXTERN)
  2492. ' Err "Interfaces cannot be extern."
  2493. 'EndIf
  2494. If CParse( "<" )
  2495. If attrs & DECL_EXTERN
  2496. Err "Extern classes cannot be generic."
  2497. EndIf
  2498. 'If attrs & CLASS_INTERFACE
  2499. ' Err "Interfaces cannot be generic."
  2500. 'EndIf
  2501. 'If attrs & CLASS_TEMPLATEARG
  2502. ' Err "Class parameters cannot be generic."
  2503. 'EndIf
  2504. Local nargs:Int
  2505. Repeat
  2506. 'Local decl:TClassDecl=ParseClassDecl( "",CLASS_TEMPLATEARG )
  2507. 'If args.Length=nargs args=args + New TClassDecl[10]
  2508. 'args[nargs]=decl
  2509. 'nargs:+1
  2510. args.Push ParseIdent()
  2511. Until Not CParse(",")
  2512. 'args=args[..nargs]
  2513. Parse ">"
  2514. EndIf
  2515. If CParse( "extends" )
  2516. 'If attrs & CLASS_TEMPLATEARG
  2517. ' Err "Extends cannot be used with class parameters."
  2518. 'EndIf
  2519. ' If CParse( "null" )
  2520. '
  2521. If attrs & CLASS_STRUCT
  2522. Err "Structs cannot be extended"
  2523. EndIf
  2524. '
  2525. ' If Not (attrs & DECL_EXTERN)
  2526. ' Err "Only extern objects can extend null."
  2527. ' EndIf
  2528. '
  2529. ' superTy=Null
  2530. '
  2531. ' Else
  2532. If attrs & CLASS_INTERFACE And Not (attrs & DECL_EXTERN)
  2533. Local nimps:Int
  2534. Repeat
  2535. If imps.Length=nimps imps=imps + New TIdentType[10]
  2536. imps[nimps]=ParseIdentType()
  2537. nimps:+1
  2538. Until Not CParse(",")
  2539. imps=imps[..nimps]
  2540. superTy=New TIdentType.Create( "brl.classes.object" )
  2541. Else
  2542. superTy=ParseIdentType()
  2543. EndIf
  2544. Else
  2545. If Not (attrs & DECL_EXTERN) Then
  2546. superTy=New TIdentType.Create( "brl.classes.object" )
  2547. End If
  2548. EndIf
  2549. If CParse( "implements" )
  2550. If attrs & CLASS_STRUCT
  2551. Err "Implements cannot be used with Structs"
  2552. EndIf
  2553. 'If attrs & DECL_EXTERN
  2554. ' Err "Implements cannot be used with external classes."
  2555. 'EndIf
  2556. If attrs & CLASS_INTERFACE
  2557. Err "Implements cannot be used with interfaces."
  2558. EndIf
  2559. 'If attrs & CLASS_TEMPLATEARG
  2560. ' Err "Implements cannot be used with class parameters."
  2561. 'EndIf
  2562. Local nimps:Int
  2563. Repeat
  2564. If imps.Length=nimps imps=imps + New TIdentType[10]
  2565. imps[nimps]=ParseIdentType()
  2566. nimps:+1
  2567. Until Not CParse(",")
  2568. imps=imps[..nimps]
  2569. EndIf
  2570. Repeat
  2571. If CParse( "final" )
  2572. If attrs & CLASS_INTERFACE
  2573. Err "Final cannot be used with interfaces."
  2574. End If
  2575. If attrs & CLASS_STRUCT
  2576. Err "Final cannot be used with structs."
  2577. End If
  2578. If attrs & DECL_FINAL
  2579. Err "Duplicate type attribute."
  2580. End If
  2581. If attrs & DECL_ABSTRACT
  2582. Err "Classes cannot be both final and abstract."
  2583. End If
  2584. attrs:|DECL_FINAL
  2585. Else If CParse( "abstract" )
  2586. If attrs & CLASS_INTERFACE
  2587. Err "Abstract cannot be used with interfaces."
  2588. EndIf
  2589. If attrs & CLASS_STRUCT
  2590. Err "Abstract cannot be used with structs."
  2591. EndIf
  2592. If attrs & DECL_ABSTRACT
  2593. Err "Duplicate type attribute."
  2594. End If
  2595. If attrs & DECL_FINAL
  2596. Err "Types cannot be both final and abstract."
  2597. End If
  2598. attrs:|DECL_ABSTRACT
  2599. Else
  2600. Exit
  2601. EndIf
  2602. Forever
  2603. 'check for metadata
  2604. If CParse( "{" )
  2605. If attrs & CLASS_STRUCT
  2606. Err "Structs cannot store metadata."
  2607. EndIf
  2608. meta = ParseMetaData()
  2609. End If
  2610. Local classDecl:TClassDecl=New TClassDecl.Create( id,String[](args.ToArray()),superTy,imps,attrs )
  2611. If meta Then
  2612. classDecl.metadata = meta
  2613. End If
  2614. If classDecl.IsExtern()
  2615. classDecl.munged=classDecl.ident
  2616. If CParse( "=" ) classDecl.munged=ParseStringLit()
  2617. EndIf
  2618. 'If classDecl.IsTemplateArg() Return classDecl
  2619. Local decl_attrs:Int=(attrs & DECL_EXTERN) | (attrs & DECL_NODEBUG) | (attrs & DECL_API_WIN32)
  2620. Local method_attrs:Int=decl_attrs|FUNC_METHOD | (attrs & DECL_NODEBUG)
  2621. If attrs & CLASS_INTERFACE method_attrs:|DECL_ABSTRACT
  2622. Repeat
  2623. SkipEols
  2624. Select _toke
  2625. Case "end"
  2626. NextToke
  2627. Exit
  2628. Case "endtype"
  2629. If attrs & CLASS_INTERFACE Then
  2630. Err "Syntax error - expecting End Interface, not 'EndType'"
  2631. End If
  2632. If attrs & CLASS_STRUCT Then
  2633. Err "Syntax error - expecting End Struct, not 'EndType'"
  2634. End If
  2635. toke = Null
  2636. NextToke
  2637. Exit
  2638. Case "endstruct"
  2639. If attrs & CLASS_INTERFACE Then
  2640. Err "Syntax error - expecting End Interface, not 'EndStruct'"
  2641. End If
  2642. If Not (attrs & CLASS_STRUCT) Then
  2643. Err "Syntax error - expecting End Type, not 'EndStruct'"
  2644. End If
  2645. toke = Null
  2646. NextToke
  2647. Exit
  2648. Case "endinterface"
  2649. If Not (attrs & CLASS_INTERFACE) And Not (attrs & CLASS_STRUCT) Then
  2650. Err "Syntax error - expecting End Type, not 'EndInterface'"
  2651. End If
  2652. If Not (attrs & CLASS_INTERFACE) And (attrs & CLASS_STRUCT) Then
  2653. Err "Syntax error - expecting End Struct, not 'EndInterface'"
  2654. End If
  2655. toke = Null
  2656. NextToke
  2657. Exit
  2658. Case "private"
  2659. NextToke
  2660. decl_attrs=decl_attrs | DECL_PRIVATE
  2661. Case "public"
  2662. NextToke
  2663. decl_attrs=decl_attrs & ~DECL_PRIVATE
  2664. Case "const","global","field"
  2665. If attrs & DECL_EXTERN Then
  2666. If (attrs & CLASS_INTERFACE) Then
  2667. Err "Extern Interfaces can only contain methods."
  2668. End If
  2669. If Not (attrs & CLASS_STRUCT) Then
  2670. Err "Extern Types can only contain methods."
  2671. End If
  2672. End If
  2673. If (attrs & CLASS_INTERFACE) And _toke<>"const"
  2674. Err "Interfaces can only contain constants and methods."
  2675. EndIf
  2676. If (attrs & CLASS_STRUCT) And _toke<>"field"
  2677. Err "Structs can only contain fields."
  2678. EndIf
  2679. classDecl.InsertDecls ParseDecls( _toke,decl_attrs )
  2680. Case "method"
  2681. If (attrs & CLASS_STRUCT) And (attrs & DECL_EXTERN) Then
  2682. Err "Structs can only contain fields."
  2683. EndIf
  2684. Local decl:TFuncDecl=ParseFuncDecl( _toke,method_attrs )
  2685. If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
  2686. classDecl.InsertDecl decl
  2687. Case "function"
  2688. If (attrs & CLASS_INTERFACE)
  2689. Err "Interfaces can only contain constants and methods."
  2690. EndIf
  2691. If attrs & CLASS_STRUCT Then
  2692. If (attrs & DECL_EXTERN) Then
  2693. Err "Structs can only contain fields."
  2694. Else
  2695. Err "Structs can only contain fields and methods."
  2696. End If
  2697. EndIf
  2698. If attrs & DECL_EXTERN Then
  2699. Err "Extern Types can only contain methods."
  2700. End If
  2701. Local decl:TFuncDecl=ParseFuncDecl( _toke,decl_attrs )
  2702. classDecl.InsertDecl decl
  2703. Default
  2704. Err "Syntax error - expecting class member declaration, not '" + _toke + "'"
  2705. End Select
  2706. Forever
  2707. If toke Parse toke
  2708. Return classDecl
  2709. End Method
  2710. Method ParseNativeStmt()
  2711. If Not _toke.StartsWith("'!") Then
  2712. Err "Syntax error - expecting !'"
  2713. End If
  2714. Local raw:String = _toke[2..]
  2715. _block.AddStmt New TNativeStmt.Create( raw )
  2716. NextToke
  2717. End Method
  2718. Method ParseModuleDecl:String( toke$,attrs:Int )
  2719. NextToke
  2720. ' namespace . module
  2721. Return ParseModPath().ToLower()
  2722. End Method
  2723. Method ParseModPath$()
  2724. Local path$=ParseIdent()
  2725. While CParse( "." )
  2726. path:+"."+ParseIdent()
  2727. Wend
  2728. Return path
  2729. End Method
  2730. Method ExtractModIdent$( modpath$ )
  2731. Local i:Int=modpath.FindLast( "." )
  2732. If i<>-1 Return modpath[i+1..]
  2733. Return modpath
  2734. End Method
  2735. Method ImportFile( filepath$ )
  2736. If filepath.Endswith(".bmx") Then
  2737. filepath = ActualPath(filepath)
  2738. Local origPath:String = RealPath(filepath)
  2739. Local path:String = OutputFilePath(origPath, FileMung(), "i")
  2740. If FileType( path )<>FILETYPE_FILE
  2741. Err "File '"+ path +"' not found."
  2742. EndIf
  2743. If _module.imported.Contains( path ) Return
  2744. Local modpath:String
  2745. If opt_buildtype = BUILDTYPE_MODULE Then
  2746. Local dir:String = ExtractDir(origPath).ToLower()
  2747. dir = dir[dir.findLast("/") + 1..]
  2748. If dir.EndsWith(".mod") Then
  2749. dir = ""
  2750. Else
  2751. dir :+ "_"
  2752. End If
  2753. Local file:String = StripDir(origPath).ToLower()
  2754. modpath = opt_modulename + "_" + dir + StripExt(file)
  2755. Else
  2756. modpath = StripExt(filepath)
  2757. End If
  2758. 'sanitize the path, remove non-allowed chars
  2759. modpath = TStringHelper.Sanitize(modpath.ToLower())
  2760. ' try to import interface
  2761. Local par:TIParser = New TIParser
  2762. If par.ParseModuleImport(_module, modpath, origPath, path, , , filepath, True) Return
  2763. Else If filepath.startswith("-") Then
  2764. If Not _app.fileimports.Contains(filepath) Then
  2765. _app.fileimports.AddLast filepath
  2766. End If
  2767. Else
  2768. If filepath.EndsWith(".h") Or filepath.EndsWith(".hpp") Or filepath.EndsWith(".hxx") Then
  2769. If filepath.Find("*") = -1 Then
  2770. _app.headers.AddLast filepath
  2771. End If
  2772. Else
  2773. Local path:String = ActualPath(RealPath(filepath))
  2774. If FileType( path )<>FILETYPE_FILE
  2775. Err "File '"+ path +"' not found."
  2776. End If
  2777. End If
  2778. End If
  2779. End Method
  2780. Method ImportAllModules(attrs:Int)
  2781. ' get all brl and pub modules
  2782. Local mods:TList = EnumModules("brl")
  2783. mods = EnumModules("pub", mods)
  2784. For Local m:String = EachIn mods
  2785. ImportModule(m, attrs)
  2786. Next
  2787. End Method
  2788. Method ImportModule( modpath$,attrs:Int )
  2789. SetErr
  2790. modpath = modpath.ToLower()
  2791. Local basepath:String = ModulePath(modpath.ToLower())
  2792. If _module.imported.Contains( basepath ) Return
  2793. ' try to import interface
  2794. Local par:TIParser = New TIParser
  2795. If par.ParseModuleImport(_module, modpath, basepath, , , attrs) Return
  2796. 'DebugStop
  2797. 'Local mdecl:TDecl=_app.imported.ValueForKey( basepath )
  2798. 'If Not mdecl
  2799. ' mdecl=ParseModule( filepath,_app )
  2800. 'EndIf
  2801. '_module.imported.Insert mdecl.filepath,mdecl
  2802. 'If Not (attrs & DECL_PRIVATE) _module.pubImported.Insert mdecl.filepath,mdecl
  2803. '_module.InsertDecl New AliasDecl( mdecl.ident,mdecl,attrs )
  2804. 'End Rem
  2805. End Method
  2806. Method ValidateModIdent( id$ )
  2807. If id.Length
  2808. If IsAlpha( id[0] ) Or id[0]="_"[0]
  2809. Local err:Int
  2810. For Local i:Int=1 Until id.Length
  2811. If IsAlpha( id[i] ) Or IsDigit( id[i] ) Or id[i]="_"[0] Continue
  2812. err=1
  2813. Exit
  2814. Next
  2815. If Not err Return
  2816. EndIf
  2817. EndIf
  2818. Err "Invalid module identifier '"+id+"'."
  2819. End Method
  2820. Method MungAppDecl(app:TAppDecl)
  2821. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain Then
  2822. app.munged = MungModuleName(opt_modulename)
  2823. Else If opt_buildtype = BUILDTYPE_MODULE Then
  2824. Local dir:String = ExtractDir(opt_filepath).ToLower()
  2825. dir = dir[dir.findLast("/") + 1..]
  2826. If dir.EndsWith(".mod") Then
  2827. dir = ""
  2828. Else
  2829. dir :+ "_"
  2830. End If
  2831. app.munged = "_bb_" + opt_modulename + "_" + dir + StripExt(StripDir(opt_filepath).ToLower())
  2832. Else
  2833. ' main application file?
  2834. If opt_apptype Then
  2835. app.munged = "_bb_main"
  2836. Else
  2837. Local dir:String = ExtractDir(opt_filepath).ToLower()
  2838. dir = dir[dir.findLast("/") + 1..]
  2839. If dir.EndsWith(".mod") Then
  2840. dir = dir.Replace(".mod", "")
  2841. End If
  2842. Local file:String = StripDir(opt_filepath).ToLower()
  2843. app.munged = "_bb_" + dir + "_" + StripExt(file)
  2844. End If
  2845. End If
  2846. 'sanitize, remove non-allowed chars
  2847. app.munged = TStringHelper.Sanitize(app.munged)
  2848. End Method
  2849. ' load external cast defs
  2850. Method LoadExternCasts(path:String)
  2851. For Local externs:Int = 0 Until 3
  2852. Local ePath:String
  2853. ' we will iterate through all possibilities as there may be different sets
  2854. ' of explicit casts/no gen funcs for each.
  2855. Select externs
  2856. Case 0
  2857. ' eg. file.win32.x86.x
  2858. ePath = StripExt(path) + "." + opt_platform + "." + opt_arch + ".x"
  2859. Case 1
  2860. ' eg. file.win32.x
  2861. ePath = StripExt(path) + "." + opt_platform + ".x"
  2862. Case 2
  2863. ' eg. file.x
  2864. ePath = StripExt(path) + ".x"
  2865. End Select
  2866. If FileType(ePath) = FILETYPE_FILE Then
  2867. Local toker:TToker=New TToker.Create( ePath,LoadText( ePath ) )
  2868. toker.NextToke
  2869. While True
  2870. SkipEolsToker(toker)
  2871. If toker._tokeType = TOKE_EOF Exit
  2872. Local rt$=toker._toke
  2873. If CParseToker(toker, "unsigned") Then
  2874. rt :+ " " + toker._toke
  2875. End If
  2876. NextTokeToker(toker)
  2877. If CParseToker(toker,"*") Then
  2878. rt:+ "*"
  2879. If CParseToker(toker,"*") Then
  2880. rt:+ "*"
  2881. End If
  2882. End If
  2883. Local dets:TCastDets = New TCastDets
  2884. If CParseToker(toker, "__stdcall") Then
  2885. dets.api = "__stdcall"
  2886. End If
  2887. ' fname
  2888. Local fn$=toker._toke
  2889. NextTokeToker(toker)
  2890. dets.name = fn
  2891. dets.retType = rt
  2892. _externCasts.Insert(fn, dets)
  2893. ' args
  2894. ParseToker(toker, "(")
  2895. If CParseToker(toker, ")") Then
  2896. ' don't generate header extern
  2897. If CParseToker(toker, "!") Then
  2898. dets.noGen = True
  2899. End If
  2900. Continue
  2901. End If
  2902. Local i:Int = 0
  2903. Repeat
  2904. Local at$=toker._toke
  2905. If CParseToker(toker, "const") Then
  2906. at :+ " " + toker._toke
  2907. End If
  2908. If CParseToker(toker, "unsigned") Then
  2909. at :+ " " + toker._toke
  2910. End If
  2911. If CParseToker(toker, "struct") Then
  2912. at :+ " " + toker._toke
  2913. End If
  2914. NextTokeToker(toker)
  2915. If CParseToker(toker, "*") Then
  2916. at:+ "*"
  2917. If CParseToker(toker, "*") Then
  2918. at:+ "*"
  2919. End If
  2920. End If
  2921. ' function pointer
  2922. If CParseToker(toker, "(") Then
  2923. ParseToker(toker, "*")
  2924. ParseToker(toker, ")")
  2925. at :+ "(*)"
  2926. ParseToker(toker, "(")
  2927. at :+ "("
  2928. While Not CParseToker(toker, ")")
  2929. NextTokeToker(toker)
  2930. at :+ toker._toke
  2931. Wend
  2932. at :+ ")"
  2933. End If
  2934. dets.args :+ [at]
  2935. If toker._toke=")" Exit
  2936. ParseToker(toker, ",")
  2937. i:+ 1
  2938. Forever
  2939. NextTokeToker(toker)
  2940. ' don't generate header extern
  2941. If CParseToker(toker, "!") Then
  2942. dets.noGen = True
  2943. End If
  2944. Wend
  2945. End If
  2946. Next
  2947. End Method
  2948. Method ParseCurrentFile:Int(path:String, attrs:Int)
  2949. LoadExternCasts(path)
  2950. While _toke
  2951. SetErr
  2952. Select _toke.toLower()
  2953. Case "~n"
  2954. NextToke
  2955. Case "public"
  2956. NextToke
  2957. attrs=attrs & ~DECL_PRIVATE
  2958. Case "private"
  2959. NextToke
  2960. attrs=attrs | DECL_PRIVATE
  2961. Case "extern"
  2962. ParseExternBlock(_module, attrs)
  2963. Case "const"
  2964. _module.InsertDecls ParseDecls( _toke,attrs )
  2965. Case "global"
  2966. Local list:TList = ParseDecls( _toke,attrs )
  2967. _module.InsertDecls list
  2968. For Local gdecl:TGlobalDecl = EachIn list
  2969. gdecl.attrs :| DECL_INITONLY
  2970. _block.AddStmt New TDeclStmt.Create( gdecl )
  2971. Next
  2972. Case "struct"
  2973. _module.InsertDecl ParseClassDecl( _toke,attrs | CLASS_STRUCT )
  2974. Case "type"
  2975. _module.InsertDecl ParseClassDecl( _toke,attrs )
  2976. Case "interface"
  2977. _module.InsertDecl ParseClassDecl( _toke,attrs|CLASS_INTERFACE|DECL_ABSTRACT )
  2978. Case "function"
  2979. _module.InsertDecl ParseFuncDecl( _toke,attrs )
  2980. Case "incbin"
  2981. NextToke
  2982. Local s:String = ParseStringLit()
  2983. _app.mapStringConsts(s)
  2984. Local ib:TIncBin = New TIncbin.Create(s, path)
  2985. If Not ib Then
  2986. DoErr "Incbin file '"+ s +"' not found."
  2987. End If
  2988. _app.incbins.AddLast(ib)
  2989. Case "include"
  2990. 'include command is NOT just a pattern to replace with
  2991. 'content. BlitzMax parses each included file before the
  2992. 'content gets appended to the source (right before
  2993. 'semanting or analyzing content)
  2994. NextToke
  2995. Local includeFile:String = ParseStringLit()
  2996. 'convert the URI of the to include file as it might be
  2997. 'a relative one
  2998. includeFile = RealPath(includeFile)
  2999. 'instead of merging the data of multiple parsers, the
  3000. 'same parser is used for all included files - but each
  3001. 'of them uses an individual toker
  3002. If FileType( includeFile )<>FILETYPE_FILE
  3003. DoErr "File '"+ includeFile +"' not found."
  3004. EndIf
  3005. 'instead of "LoadText" "PreProcess" is used to include
  3006. 'handling of conditionals and comments
  3007. Try
  3008. Local includeSource:String = PreProcess(includeFile)
  3009. Local includeToker:TToker = New TToker.Create(includeFile, includeSource)
  3010. 'backup old vars
  3011. Local oldToker:TToker = Self._toker
  3012. 'assign temporary vars
  3013. Self._toker = includeToker
  3014. 'parse the include file
  3015. parseCurrentFile(includeFile, attrs)
  3016. 'restore backup vars
  3017. Self._toker = oldToker
  3018. Catch e:TStreamException
  3019. DoErr "Failed to include file '" + includeFile + "' : '" + e.ToString() + "'"
  3020. End Try
  3021. 'move on to next toke (after include "xyz.bmx")
  3022. NextToke
  3023. Default
  3024. ParseStmt
  3025. 'Err "Syntax error - expecting declaration."
  3026. End Select
  3027. Wend
  3028. Return attrs
  3029. End Method
  3030. Method ParseMain()
  3031. SkipEols
  3032. Local mattrs:Int
  3033. 'If CParse( "strict" ) mattrs:|MODULE_STRICT
  3034. 'If CParse( "superstrict" ) mattrs:|MODULE_SUPERSTRICT
  3035. Local path$=_toker.Path()
  3036. Local ident$=StripAll( path )
  3037. Local munged$ '="bb_"+ident+"_"
  3038. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain
  3039. ValidateModIdent ident
  3040. Else If opt_buildtype = BUILDTYPE_MODULE Then
  3041. Local dir:String = ExtractDir(opt_filepath).ToLower()
  3042. dir = dir[dir.findLast("/") + 1..]
  3043. If dir.EndsWith(".mod") Then
  3044. dir = ""
  3045. Else
  3046. dir :+ "_"
  3047. End If
  3048. munged = opt_modulename + "_" + dir + ident
  3049. 'sanitize, remove non-allowed chars
  3050. munged = TStringHelper.Sanitize(munged.ToLower())
  3051. End If
  3052. If opt_ismain Then 'And opt_modulename <> "brl.blitz" Then
  3053. ident = opt_modulename
  3054. End If
  3055. If opt_buildtype = BUILDTYPE_APP Then
  3056. ident = "m_" + ident
  3057. End If
  3058. _module=New TModuleDecl.Create( ident,munged,path,mattrs )
  3059. _module.AddImport path,_module
  3060. _app.InsertModule _module
  3061. ' mung the app decl
  3062. MungAppDecl(_app)
  3063. If opt_buildtype = BUILDTYPE_MODULE And opt_modulename = "brl.blitz" Then
  3064. ' import Object and String definitions
  3065. Local par:TIParser = New TIParser
  3066. par.ParseModuleImport(_module, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "/blitz_classes.i")
  3067. ' set up built-in keywords
  3068. par = New TIParser
  3069. par.ParseModuleImport(_module, "brl.blitzkeywords", "", "", MakeKeywords())
  3070. End If
  3071. ' don't import ourself
  3072. If opt_modulename <> "brl.blitz" Then
  3073. Local par:TIParser = New TIParser
  3074. par.ParseModuleImport(_module, "brl.blitz", modulepath("brl.blitz"), , , MODULE_ACTUALMOD)
  3075. End If
  3076. Local mainFunc:TFuncDecl = New TFuncDecl.CreateF("__LocalMain", New TIntType,Null,0)
  3077. '_app.InsertDecl mainFunc
  3078. _module.insertDecl(mainFunc)
  3079. 'Local mainBlock:TBlockDecl = New TBlockDecl.Create( _block )
  3080. ' import all brl and pub modules if we haven't specified one
  3081. If opt_buildtype <> BUILDTYPE_MODULE And Not opt_framework Then
  3082. ImportAllModules MODULE_ACTUALMOD
  3083. Else
  3084. If opt_framework Then
  3085. Local par:TIParser = New TIParser
  3086. par.ParseModuleImport(_module, opt_framework, modulepath(opt_framework), , , MODULE_ACTUALMOD)
  3087. End If
  3088. End If
  3089. Local attrs:Int
  3090. 'Parse header - imports etc.
  3091. While _toke
  3092. SetErr
  3093. Select _toke.ToLower()
  3094. Case "~n"
  3095. NextToke
  3096. Case "public"
  3097. NextToke
  3098. attrs=attrs & ~DECL_PRIVATE
  3099. Case "private"
  3100. NextToke
  3101. attrs=attrs | DECL_PRIVATE
  3102. Case "import"
  3103. NextToke
  3104. If _tokeType=TOKE_STRINGLIT
  3105. ' TODO
  3106. 'ImportFile ReplaceEnvTags( ParseStringLit() )
  3107. ImportFile ParseStringLit()
  3108. Else
  3109. ImportModule ParseModPath(),attrs | MODULE_ACTUALMOD
  3110. EndIf
  3111. Case "framework"
  3112. NextToke
  3113. ImportModule ParseModPath(),attrs
  3114. Case "alias"
  3115. NextToke
  3116. Repeat
  3117. Local ident$=ParseIdent()
  3118. Parse "="
  3119. Local decl:Object
  3120. Local scope:TScopeDecl=_module
  3121. _env=_module 'naughty! Shouldn't be doing GetDecl in parser...
  3122. Repeat
  3123. Local id$=ParseIdent()
  3124. decl=scope.FindDecl( id )
  3125. If Not decl Err "Identifier '"+id+"' not found."
  3126. If Not CParse( "." ) Exit
  3127. scope=TScopeDecl( decl )
  3128. If Not scope Or TFuncDecl( scope ) Err "Invalid scope '"+id+"'."
  3129. Forever
  3130. _env=Null '/naughty
  3131. _module.InsertDecl New TAliasDecl.Create( ident,decl,attrs )
  3132. Until Not CParse(",")
  3133. Case "module"
  3134. Local m:String = ParseModuleDecl(_toke, attrs)
  3135. If m.ToLower() <> opt_modulename Then
  3136. Err "Module does not match commandline module"
  3137. End If
  3138. 'sanitize, remove non-allowed chars
  3139. _module.munged = TStringHelper.Sanitize(m)
  3140. Case "nodebug"
  3141. mainFunc.attrs :| DECL_NODEBUG
  3142. attrs :| DECL_NODEBUG
  3143. NextToke
  3144. Case "strict"
  3145. If _module.attrs & (MODULE_STRICT | MODULE_SUPERSTRICT) Then
  3146. Err "Strict or SuperStrict already specified"
  3147. End If
  3148. _module.attrs :| MODULE_STRICT
  3149. nextToke
  3150. Case "superstrict"
  3151. If _module.attrs & (MODULE_STRICT | MODULE_SUPERSTRICT) Then
  3152. Err "Strict or SuperStrict already specified"
  3153. End If
  3154. _module.attrs :| MODULE_SUPERSTRICT
  3155. opt_issuperstrict = True
  3156. nextToke
  3157. Case "moduleinfo"
  3158. NextToke
  3159. Local info:String = ParseStringLit()
  3160. _module.modInfo.AddLast(info)
  3161. Default
  3162. Exit
  3163. End Select
  3164. Wend
  3165. ' app code
  3166. PushBlock(mainFunc)
  3167. 'Parse main app
  3168. attrs = ParseCurrentFile(path, attrs)
  3169. PopBlock
  3170. End Method
  3171. Method ParseModule()
  3172. End Method
  3173. Method Create:TParser( toker:TToker,app:TAppDecl )
  3174. _toke="~n"
  3175. _toker=toker
  3176. _app=app
  3177. SetErr
  3178. NextToke
  3179. Return Self
  3180. End Method
  3181. End Type
  3182. Function Eval$( toker:TToker,_type:TType )
  3183. Local src$
  3184. While toker.Toke() And toker.Toke()<>"'" And toker.Toke()<>"~n" And toker.Toke()<>"~r"
  3185. src:+toker.Toke()
  3186. toker.NextToke()
  3187. Wend
  3188. Local t:String=EvalS( src,_type )
  3189. Return t
  3190. End Function
  3191. Function PreProcessNextToke$(toker:TToker)
  3192. Repeat
  3193. toker.NextToke()
  3194. Until toker.tokeType()<>TOKE_SPACE Or toker.Toke().Endswith("~n")
  3195. Return toker._toke
  3196. End Function
  3197. Function PreProcess$( path$ )
  3198. Local ifnest:Int,con:Int=1,line:Int,source:TStringList=New TStringList
  3199. Local toker:TToker=New TToker.Create( path,LoadText( path ), True )
  3200. PreProcessNextToke(toker)
  3201. Repeat
  3202. If line
  3203. source.AddLast "~n"
  3204. While toker.Toke() And Not toker.Toke().Endswith("~n") And toker.TokeType()<>TOKE_LINECOMMENT
  3205. PreProcessNextToke(toker)
  3206. Wend
  3207. If Not toker.Toke() Exit
  3208. PreProcessNextToke(toker)
  3209. EndIf
  3210. line :+ 1
  3211. ' catch up with any skipped lines
  3212. While line < toker._line - 1
  3213. line:+1
  3214. source.AddLast "~n"
  3215. Wend
  3216. If toker.TokeType()=TOKE_SPACE And Not toker.Toke().Endswith("~n") PreProcessNextToke(toker)
  3217. If toker.Toke()<>"?"
  3218. If con
  3219. Local textline$
  3220. While toker.Toke() And toker.Toke()<>"~n" And toker.TokeType()<>TOKE_LINECOMMENT
  3221. Local toke$=toker.Toke()
  3222. textline:+toke
  3223. toker.NextToke()
  3224. Wend
  3225. If textline Then
  3226. source.AddLast textline
  3227. EndIf
  3228. EndIf
  3229. Continue
  3230. EndIf
  3231. Local stm$= PreProcessNextToke(toker).ToLower()
  3232. 'toker.NextToke()
  3233. Local isNot:Int = False
  3234. If stm = "not" Then
  3235. If toker.TokeType()=TOKE_SPACE PreProcessNextToke(toker)
  3236. stm = toker.Toke().ToLower()
  3237. isNot = True
  3238. End If
  3239. 'If stm="end" Or stm="else"
  3240. ' If toker.TokeType()=TOKE_SPACE toker.NextToke()
  3241. ' If toker.Toke().ToLower()="if"
  3242. ' toker.NextToke()
  3243. ' stm:+"if"
  3244. ' EndIf
  3245. 'EndIf
  3246. Rem
  3247. Debug True if program is being compiled in debug mode.
  3248. Threaded True if program is being compiled in threaded mode.
  3249. Win32 True if program is being compiled for the Windows operating system.
  3250. MacOS True if program is being compiled for the MacOS operating system.
  3251. Linux True if program is being compiled for the Linux operating system.
  3252. X86 True if program is being compiled for the Intel CPU.
  3253. PPC True if program is being compiled for the PowerPC CPU.
  3254. MacOSX86 True if program is being compiled for an Intel Mac.
  3255. MacOSPPC True if program is being compiled for a PowerPC Mac.
  3256. BigEndian True if program is being compiled for a big endian CPU.
  3257. LittleEndian
  3258. End Rem
  3259. Select stm
  3260. Case "~r", "~n"
  3261. 'ifnest = 0
  3262. con = 1
  3263. Default
  3264. ' test for EOF
  3265. If Not toker.Toke() Exit
  3266. con = 0
  3267. Try
  3268. If Eval( toker,New TIntType ) = "1" con = 1
  3269. Catch error:String
  3270. con = 0
  3271. End Try
  3272. Rem
  3273. Case "macos", "macosx86", "x86", "littleendian", "bigendian"
  3274. con = 1
  3275. ' If con=ifnest
  3276. ' If Eval( toker,TType.intType ) con:+1
  3277. ' EndIf
  3278. '
  3279. ifnest = 1
  3280. ' Case "rem"
  3281. '
  3282. ' ifnest:+1
  3283. Case "threaded", "win32", "linux", "ppc", "win32x86", "linuxx86", "macosppc"
  3284. If isNot Then
  3285. con = 1
  3286. Else
  3287. con = 0
  3288. End If
  3289. ifnest = 1
  3290. Case "else","elseif"
  3291. If Not ifnest Err "#Else without #If"
  3292. If con=ifnest
  3293. con=-con
  3294. Else If con=ifnest-1
  3295. If stm="elseif"
  3296. If Eval( toker,TType.intType ) con:+1
  3297. Else
  3298. con:+1
  3299. EndIf
  3300. EndIf
  3301. Case "end","endif"
  3302. If Not ifnest Err "#End without #If"
  3303. ifnest:-1
  3304. If con<0 con=-con
  3305. If ifnest<con con=ifnest
  3306. ' Case "print"
  3307. ' If con=ifnest
  3308. ' TODO
  3309. 'Print ReplaceEnvTags( Eval( toker,TType.stringType ) )
  3310. ' EndIf
  3311. ' Case "error"
  3312. ' If con=ifnest
  3313. ' TODO
  3314. 'Err ReplaceEnvTags( Eval( toker,TType.stringType ) )
  3315. ' EndIf
  3316. Default
  3317. Err "Unrecognized preprocessor directive '"+stm+"'."
  3318. End Rem
  3319. End Select
  3320. Forever
  3321. Return source.Join( "" )
  3322. End Function
  3323. Function ParseModule:TModuleDecl( path$,app:TAppDecl )
  3324. 'Local source$=PreProcess( path )
  3325. Local source:String = LoadText(path)
  3326. Local toker:TToker=New TToker.Create( path,source )
  3327. Local parser:TParser=New TParser.Create( toker,app )
  3328. parser.ParseMain
  3329. Return parser._module
  3330. End Function
  3331. '***** PUBLIC API ******
  3332. Function ParseApp:TAppDecl( path$ )
  3333. Local app:TAppDecl=New TAppDecl
  3334. _appInstance = app
  3335. Local source$=PreProcess( path )
  3336. 'Local source:String = LoadString(path)
  3337. Local toker:TToker=New TToker.Create( path,source )
  3338. Local parser:TParser=New TParser.Create( toker,app )
  3339. parser.ParseMain
  3340. Return app
  3341. End Function
  3342. Function MungModuleName:String(ident:Object)
  3343. Local mung:String
  3344. If String(ident) Then
  3345. Local id:String = String(ident)
  3346. mung = "__bb_" + id + "_" + id[id.Find(".") + 1..]
  3347. Else
  3348. Local mdecl:TModuleDecl = TModuleDecl(ident)
  3349. If mdecl Then
  3350. Local id:String = mdecl.ident
  3351. Local dir:String = ExtractDir(mdecl.filepath).ToLower()
  3352. dir = dir[dir.findLast("/") + 1..]
  3353. If dir.EndsWith(".mod") Then
  3354. dir = ""
  3355. Else
  3356. dir :+ "_"
  3357. End If
  3358. mung = "__bb_" + id + "_" + dir + id[id.Find(".") + 1..]
  3359. End If
  3360. End If
  3361. 'return sanitized, remove non-allowed chars
  3362. Return TStringHelper.Sanitize(mung)
  3363. End Function
  3364. Function EvalS$( source$,ty:TType )
  3365. Local env:TScopeDecl=New TScopeDecl
  3366. Rem
  3367. Debug True if program is being compiled in debug mode.
  3368. Threaded True if program is being compiled in threaded mode.
  3369. Win32 True if program is being compiled for the Windows operating system.
  3370. MacOS True if program is being compiled for the MacOS operating system.
  3371. Linux True if program is being compiled for the Linux operating system.
  3372. X86 True if program is being compiled for the Intel CPU.
  3373. PPC True if program is being compiled for the PowerPC CPU.
  3374. MacOSX86 True if program is being compiled for an Intel Mac.
  3375. MacOSPPC True if program is being compiled for a PowerPC Mac.
  3376. BigEndian True if program is being compiled for a big endian CPU.
  3377. LittleEndian
  3378. End Rem
  3379. ' debug/release
  3380. env.InsertDecl New TConstDecl.Create( "debug",New TIntType,New TConstExpr.Create( New TIntType,opt_debug ),0 )
  3381. 'env.InsertDecl New TConstDecl.Create( "release",TType.intType,New TConstExpr.Create( TType.intType,opt_release ),0 )
  3382. ' threaded
  3383. env.InsertDecl New TConstDecl.Create( "threaded",New TIntType,New TConstExpr.Create( New TIntType,opt_threaded ),0 )
  3384. ' macos
  3385. env.InsertDecl New TConstDecl.Create( "macos",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="macos" Or opt_platform="osx" Or opt_platform="ios"),0 )
  3386. env.InsertDecl New TConstDecl.Create( "macosx86",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx" Or opt_platform="ios") And opt_arch="x86"),0 )
  3387. env.InsertDecl New TConstDecl.Create( "macosppc",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx") And opt_arch="ppc"),0 )
  3388. env.InsertDecl New TConstDecl.Create( "macosx64",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx" Or opt_platform="ios") And opt_arch="x64"),0 )
  3389. ' osx
  3390. env.InsertDecl New TConstDecl.Create( "osx",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="macos" Or opt_platform="osx" ),0 )
  3391. env.InsertDecl New TConstDecl.Create( "osxx86",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx") And opt_arch="x86"),0 )
  3392. env.InsertDecl New TConstDecl.Create( "osxppc",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx") And opt_arch="ppc"),0 )
  3393. env.InsertDecl New TConstDecl.Create( "osxx64",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="macos" Or opt_platform="osx") And opt_arch="x64"),0 )
  3394. ' ios
  3395. env.InsertDecl New TConstDecl.Create( "ios",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="ios" ),0 )
  3396. env.InsertDecl New TConstDecl.Create( "iosx86",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="ios" And opt_arch="x86"),0 )
  3397. env.InsertDecl New TConstDecl.Create( "iosx64",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="ios" And opt_arch="x64"),0 )
  3398. env.InsertDecl New TConstDecl.Create( "iosarmv7",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="ios" And opt_arch="armv7"),0 )
  3399. env.InsertDecl New TConstDecl.Create( "iosarm64",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="ios" And opt_arch="arm64"),0 )
  3400. ' windows
  3401. env.InsertDecl New TConstDecl.Create( "win32",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="win32" ),0 )
  3402. env.InsertDecl New TConstDecl.Create( "win32x86",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="win32" And opt_arch="x86"),0 )
  3403. env.InsertDecl New TConstDecl.Create( "win32x64",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="win64" And opt_arch="x64") Or (opt_platform="win32" And opt_arch="x64")),0 )
  3404. env.InsertDecl New TConstDecl.Create( "win64",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="win64" And opt_arch="x64") Or (opt_platform="win32" And opt_arch="x64")),0 )
  3405. ' linux
  3406. env.InsertDecl New TConstDecl.Create( "linux",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="linux" Or opt_platform="android" Or opt_platform="raspberrypi")),0 )
  3407. env.InsertDecl New TConstDecl.Create( "linuxx86",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="linux" Or opt_platform="android") And opt_arch="x86"),0 )
  3408. env.InsertDecl New TConstDecl.Create( "linuxx64",New TIntType,New TConstExpr.Create( New TIntType,(opt_platform="linux" Or opt_platform="android") And opt_arch="x64"),0 )
  3409. env.InsertDecl New TConstDecl.Create( "linuxarm",New TIntType,New TConstExpr.Create( New TIntType, ((opt_platform="android" Or opt_platform="linux") And (opt_arch="arm" Or opt_arch="armeabi" Or opt_arch="armeabiv7a" Or opt_arch="arm64v8a")) Or (opt_platform="raspberrypi" And opt_arch="arm")),0 )
  3410. ' android
  3411. env.InsertDecl New TConstDecl.Create( "android",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" ),0 )
  3412. env.InsertDecl New TConstDecl.Create( "androidx86",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And opt_arch="x86"),0 )
  3413. env.InsertDecl New TConstDecl.Create( "androidx64",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And opt_arch="x64"),0 )
  3414. env.InsertDecl New TConstDecl.Create( "androidarm",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And (opt_arch="arm" Or opt_arch="armeabi" Or opt_arch="armeabiv7a" Or opt_arch="arm64v8a") ),0 )
  3415. env.InsertDecl New TConstDecl.Create( "androidarmeabi",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And opt_arch="armeabi"),0 )
  3416. env.InsertDecl New TConstDecl.Create( "androidarmeabiv7a",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And opt_arch="armeabiv7a"),0 )
  3417. env.InsertDecl New TConstDecl.Create( "androidarm64v8a",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="android" And opt_arch="arm64v8a"),0 )
  3418. ' raspberrypi - ARM only
  3419. env.InsertDecl New TConstDecl.Create( "raspberrypi",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="raspberrypi" And opt_arch="arm"),0 )
  3420. env.InsertDecl New TConstDecl.Create( "raspberrypiARM",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="raspberrypi" And opt_arch="arm"),0 )
  3421. ' emscripten
  3422. env.InsertDecl New TConstDecl.Create( "emscripten",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="emscripten" ),0 )
  3423. env.InsertDecl New TConstDecl.Create( "emscriptenjs",New TIntType,New TConstExpr.Create( New TIntType,opt_platform="emscripten" And opt_arch="js"),0 )
  3424. ' arch
  3425. env.InsertDecl New TConstDecl.Create( "ppc",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="ppc" ),0 )
  3426. env.InsertDecl New TConstDecl.Create( "x86",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="x86" ),0 )
  3427. env.InsertDecl New TConstDecl.Create( "x64",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="x64" ),0 )
  3428. env.InsertDecl New TConstDecl.Create( "arm",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="arm" Or opt_arch="armeabi" Or opt_arch="armeabiv7a" Or opt_arch="arm64v8a" ),0 )
  3429. env.InsertDecl New TConstDecl.Create( "armeabi",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="armeabi" ),0 )
  3430. env.InsertDecl New TConstDecl.Create( "armeabiv7a",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="armeabiv7a" ),0 )
  3431. env.InsertDecl New TConstDecl.Create( "arm64v8a",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="arm64v8a" ),0 )
  3432. env.InsertDecl New TConstDecl.Create( "js",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="js" ),0 )
  3433. env.InsertDecl New TConstDecl.Create( "armv7",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="armv7" ),0 )
  3434. env.InsertDecl New TConstDecl.Create( "arm64",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="arm64" ),0 )
  3435. env.InsertDecl New TConstDecl.Create( "ptr32",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="x86" Or opt_arch="ppc" Or opt_arch="armv7" Or opt_arch="arm" Or opt_arch="armeabi" Or opt_arch="armeabiv7a" ),0 )
  3436. env.InsertDecl New TConstDecl.Create( "ptr64",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="x64" Or opt_arch="arm64" Or opt_arch="arm64v8a" ),0 )
  3437. ' endian
  3438. env.InsertDecl New TConstDecl.Create( "bigendian",New TIntType,New TConstExpr.Create( New TIntType,opt_arch="ppc" ),0 )
  3439. env.InsertDecl New TConstDecl.Create( "littleendian",New TIntType,New TConstExpr.Create( New TIntType,opt_arch<>"ppc" ),0 )
  3440. ' opengles target platform
  3441. env.InsertDecl New TConstDecl.Create( "opengles",New TIntType,New TConstExpr.Create( New TIntType, opt_platform="android" Or opt_platform="raspberrypi" Or opt_platform="emscripten" Or opt_platform="ios" Or (opt_platform="linux" And opt_arch="arm") ),0 )
  3442. ' musl - linux only
  3443. env.InsertDecl New TConstDecl.Create( "musl",New TIntType,New TConstExpr.Create( New TIntType,(opt_musl And (opt_platform="linux" Or opt_platform="android" Or opt_platform="raspberrypi"))),0 )
  3444. ' new compiler
  3445. env.InsertDecl New TConstDecl.Create( "bmxng",New TIntType,New TConstExpr.Create( New TIntType, True ),0 )
  3446. ' env.InsertDecl New TConstDecl.Create( "LANG",TType.stringType,New TConstExpr.Create( TType.stringType,ENV_LANG ),0 )
  3447. ' env.InsertDecl New TConstDecl.Create( "TARGET",TType.stringType,New TConstExpr.Create( TType.stringType,ENV_TARGET ),0 )
  3448. ' env.InsertDecl New TConstDecl.Create( "CONFIG",TType.stringType,New TConstExpr.Create( TType.stringType,ENV_CONFIG ),0 )
  3449. PushEnv env
  3450. Local toker:TToker=New TToker.Create( "",source )
  3451. Local parser:TParser=New TParser.Create( toker,Null )
  3452. Local expr:TExpr=parser.ParseExpr()
  3453. expr=expr.Semant()
  3454. If ty expr=expr.Cast( ty )
  3455. Local val$=expr.Eval()
  3456. PopEnv
  3457. Return val
  3458. End Function
  3459. Type TCastDets
  3460. Field name:String
  3461. Field retType:String
  3462. Field noGen:Int
  3463. Field args:String[0]
  3464. Field api:String
  3465. End Type