ctranslator.bmx 161 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699
  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 "parser.bmx"
  26. Type TCTranslator Extends TTranslator
  27. 'Field stringConstCount:Int
  28. Field prefix:String
  29. Field reserved_methods:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  30. Method New()
  31. _trans = Self
  32. End Method
  33. Method TransSPointer$( ty:TType, withVar:Int = False )
  34. Local p:String
  35. If ty
  36. If withVar And (ty._flags & TType.T_VAR) Then
  37. p:+ "*"
  38. End If
  39. If ty._flags & TType.T_PTR Then
  40. p:+ "*"
  41. Else If ty._flags & TType.T_PTRPTR Then
  42. p:+ "**"
  43. Else If ty._flags & TType.T_PTRPTRPTR Then
  44. p:+ "***"
  45. End If
  46. End If
  47. Return p
  48. End Method
  49. Method TransArrayType$( ty:TType)
  50. Local p:String = TransSPointer(ty)
  51. If TBoolType( ty ) Return "~q" + p + "i~q"
  52. If TByteType( ty ) Return "~q" + p + "b~q"
  53. If TShortType( ty ) Return "~q" + p + "s~q"
  54. If TIntType( ty ) Return "~q" + p + "i~q"
  55. If TUIntType( ty ) Return "~q" + p + "u~q"
  56. If TFloatType( ty ) Return "~q" + p + "f~q"
  57. If TDoubleType( ty ) Return "~q" + p + "d~q"
  58. If TLongType( ty ) Return "~q" + p + "l~q"
  59. If TULongType( ty ) Return "~q" + p + "y~q"
  60. If TSizeTType( ty ) Return "~q" + p + "z~q"
  61. If TWParamType( ty ) Return "~q" + p + "w~q"
  62. If TLParamType( ty ) Return "~q" + p + "x~q"
  63. If TStringType( ty ) Return "~q$~q"
  64. If TInt128Type( ty ) Return "~q" + p + "j~q"
  65. If TFloat128Type( ty ) Return "~q" + p + "k~q"
  66. If TDouble128Type( ty ) Return "~q" + p + "m~q"
  67. If TFloat64Type( ty ) Return "~q" + p + "h~q"
  68. If TArrayType( ty ) Then
  69. Local s:String = "["
  70. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  71. s:+ ","
  72. Next
  73. s:+ "]"
  74. s:+ TransArrayType(TArrayType( ty ).elemType)
  75. Return Enquote(s.Replace("~q", ""))
  76. End If
  77. If TObjectType( ty ) Then
  78. If TObjectType( ty ).classdecl.IsStruct()
  79. Return "~q" + p + "@" + TObjectType(ty).classDecl.ident + "~q"
  80. Else
  81. If Not TObjectType( ty ).classdecl.IsExtern()
  82. Return "~q:" + TObjectType(ty).classDecl.ident + "~q"
  83. Else
  84. If TObjectType( ty ).classdecl.IsInterface() Then
  85. Return "~q" + p + "*#" + TObjectType(ty).classDecl.ident + "~q"
  86. ' ElseIf TObjectType( ty ).classdecl.IsStruct()
  87. ' Return "~q" + p + "@" + TObjectType(ty).classDecl.ident + "~q"
  88. Else
  89. Return "~q" + p + "#" + TObjectType(ty).classDecl.ident + "~q"
  90. End If
  91. End If
  92. End If
  93. End If
  94. If TFunctionPtrType( ty ) Return "~q(~q"
  95. End Method
  96. Method TransDefDataType$( ty:TType)
  97. If TByteType( ty ) Return "~qb~q"
  98. If TShortType( ty ) Return "~qs~q"
  99. If TIntType( ty ) Return "~qi~q"
  100. If TUIntType( ty ) Return "~qu~q"
  101. If TFloatType( ty ) Return "~qf~q"
  102. If TDoubleType( ty ) Return "~qd~q"
  103. If TLongType( ty ) Return "~ql~q"
  104. If TULongType( ty ) Return "~qy~q"
  105. If TSizeTType( ty ) Return "~qz~q"
  106. If TStringType( ty ) Return "~q$~q"
  107. If TWParamType( ty ) Return "~qw~q"
  108. If TLParamType( ty ) Return "~qx~q"
  109. End Method
  110. Method TransDefDataConversion$(ty:TType)
  111. If TByteType( ty ) Return "bbConvertToInt"
  112. If TShortType( ty ) Return "bbConvertToInt"
  113. If TIntType( ty ) Return "bbConvertToInt"
  114. If TUIntType( ty ) Return "bbConvertToUInt"
  115. If TFloatType( ty ) Return "bbConvertToFloat"
  116. If TDoubleType( ty ) Return "bbConvertToDouble"
  117. If TLongType( ty ) Return "bbConvertToLong"
  118. If TULongType( ty ) Return "bbConvertToULong"
  119. If TSizeTType( ty ) Return "bbConvertToSizet"
  120. If TStringType( ty ) Return "bbConvertToString"
  121. End Method
  122. Method TransDefDataUnionType$(ty:TType)
  123. If TByteType( ty ) Return "b"
  124. If TShortType( ty ) Return "s"
  125. If TIntType( ty ) Return "i"
  126. If TUIntType( ty ) Return "u"
  127. If TFloatType( ty ) Return "f"
  128. If TDoubleType( ty ) Return "d"
  129. If TLongType( ty ) Return "l"
  130. If TULongType( ty ) Return "y"
  131. If TSizeTType( ty ) Return "z"
  132. If TWParamType( ty ) Return "w"
  133. If TLParamType( ty ) Return "x"
  134. If TStringType( ty ) Return "t"
  135. End Method
  136. Method TransDebugScopeType$(ty:TType)
  137. Local p:String = TransSPointer(ty)
  138. If TByteType( ty ) Return p + "b"
  139. If TShortType( ty ) Return p + "s"
  140. If TIntType( ty ) Return p + "i"
  141. If TUIntType( ty ) Return p + "u"
  142. If TFloatType( ty ) Return p + "f"
  143. If TDoubleType( ty ) Return p + "d"
  144. If TLongType( ty ) Return p + "l"
  145. If TULongType( ty ) Return p + "y"
  146. If TSizeTType( ty ) Return p + "t"
  147. If TWParamType( ty ) Return p + "W"
  148. If TLParamType( ty ) Return p + "X"
  149. If TInt128Type( ty ) Return p + "j"
  150. If TFloat128Type( ty ) Return p + "k"
  151. If TDouble128Type( ty ) Return p + "m"
  152. If TFloat64Type( ty ) Return p + "h"
  153. If TStringType( ty ) Return "$"
  154. If TArrayType( ty ) Then
  155. Local s:String = "["
  156. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  157. s:+ ","
  158. Next
  159. s:+ "]"
  160. Return s + TransDebugScopeType(TArrayType( ty ).elemType)
  161. End If
  162. If TObjectType( ty ) Then
  163. If TObjectType( ty ).classdecl.IsStruct() Then
  164. Return p + "@" + TObjectType(ty).classDecl.ident
  165. Else If Not TObjectType( ty ).classdecl.IsExtern()
  166. Return ":" + TObjectType( ty ).classDecl.ident
  167. Else
  168. If TObjectType( ty ).classdecl.IsInterface() Then
  169. Return p + "*#" + TObjectType(ty).classDecl.ident
  170. Else
  171. Return p + "#" + TObjectType(ty).classDecl.ident
  172. End If
  173. End If
  174. End If
  175. If TFunctionPtrType( ty ) Then
  176. Local func:TFuncDecl = TFunctionPtrType( ty ).func
  177. Local s:String = "("
  178. For Local i:Int = 0 Until func.argDecls.length
  179. If i Then
  180. s :+ ","
  181. End If
  182. s :+ TransDebugScopeType(func.argDecls[i].ty)
  183. Next
  184. Return s + ")" + TransDebugScopeType(func.retType)
  185. End If
  186. End Method
  187. Method TransType$( ty:TType, ident:String, fpReturnTypeFunctionArgs:String = Null, fpReturnTypeClassFunc:Int = False)
  188. Local p:String = TransSPointer(ty, True)
  189. If TVoidType( ty ) Or Not ty Then
  190. Return "void"
  191. End If
  192. If TBoolType( ty ) Return "BBINT" + p
  193. If TByteType( ty ) Return "BBBYTE" + p
  194. If TShortType( ty ) Return "BBSHORT" + p
  195. If TIntType( ty ) Return "BBINT" + p
  196. If TUIntType( ty ) Return "BBUINT" + p
  197. If TFloatType( ty ) Return "BBFLOAT" + p
  198. If TDoubleType( ty ) Return "BBDOUBLE" + p
  199. If TLongType( ty ) Return "BBLONG" + p
  200. If TULongType( ty ) Return "BBULONG" + p
  201. If TSizeTType( ty ) Return "BBSIZET" + p
  202. If TWParamType( ty ) Return "WPARAM" + p
  203. If TLParamType( ty ) Return "LPARAM" + p
  204. If TInt128Type( ty ) Return "BBINT128" + p
  205. If TFloat128Type( ty ) Return "BBFLOAT128" + p
  206. If TDouble128Type( ty ) Return "BBDOUBLE128" + p
  207. If TFloat64Type( ty ) Return "BBFLOAT64" + p
  208. If TStringType( ty ) Then
  209. If ty._flags & TType.T_CHAR_PTR Then
  210. Return "BBBYTE *"
  211. Else If ty._flags & TType.T_SHORT_PTR Then
  212. Return "BBSHORT *"
  213. End If
  214. Return "BBSTRING" + p
  215. End If
  216. If TArrayType( ty ) Return "BBARRAY" + p
  217. If TObjectType( ty ) Then
  218. Return TransObject(TObjectType(ty).classdecl) + p
  219. End If
  220. If TFunctionPtrType( ty ) Then
  221. TFunctionPtrType(ty).func.Semant
  222. Local retType:String = TransType(TFunctionPtrType(ty).func.retType, "")
  223. Local api:String
  224. If TFunctionPtrType(ty).func.attrs & DECL_API_WIN32 Then
  225. api = " __stdcall "
  226. End If
  227. Local args:String
  228. For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
  229. arg.Semant()
  230. If args Then
  231. args :+ ","
  232. End If
  233. args :+ TransType(arg.ty, "")
  234. Next
  235. Local ret:String = ""
  236. If fpReturnTypeFunctionArgs Then
  237. ret = Bra(fpReturnTypeFunctionArgs)
  238. End If
  239. If fpReturnTypeClassFunc Then
  240. ' typedef for function pointer return type
  241. Return ident + "x" + Bra(api + p +"* " + ident) + Bra(args)
  242. Else
  243. Return retType + Bra(api + p +"* " + ident + ret) + Bra(args)
  244. End If
  245. End If
  246. If TExternObjectType( ty ) Return "struct " + TExternObjectType( ty ).classDecl.munged + p
  247. InternalErr
  248. End Method
  249. Method TransIfcType$( ty:TType, isSuperStrict:Int = False )
  250. Local p:String = TransSPointer(ty)
  251. If ty And (ty._flags & TType.T_VAR) Then
  252. p :+ " Var"
  253. End If
  254. If Not ty Then
  255. If opt_issuperstrict Or isSuperStrict Then
  256. Return p
  257. Else
  258. Return "%" + p
  259. End If
  260. End If
  261. If TVoidType( ty ) Then
  262. Return p
  263. End If
  264. If TByteType( ty ) Return "@" + p
  265. If TShortType( ty ) Return "@@" + p
  266. If TIntType( ty ) Return "%" + p
  267. If TUIntType( ty ) Return "|" + p
  268. If TFloatType( ty ) Return "#" + p
  269. If TDoubleType( ty ) Return "!" + p
  270. If TLongType( ty ) Return "%%" + p
  271. If TULongType( ty ) Return "||" + p
  272. If TSizeTType( ty ) Return "%z" + p
  273. If TWParamType( ty ) Return "%w" + p
  274. If TLParamType( ty ) Return "%x" + p
  275. If TInt128Type( ty ) Return "%j" + p
  276. If TFloat128Type( ty ) Return "!k" + p
  277. If TDouble128Type( ty ) Return "!m" + p
  278. If TFloat64Type( ty ) Return "!h" + p
  279. If TStringType( ty ) Then
  280. If ty._flags & TType.T_CHAR_PTR Then
  281. Return "$z"
  282. Else If ty._flags & TType.T_SHORT_PTR Then
  283. Return "$w"
  284. End If
  285. Return "$" + p
  286. End If
  287. If TArrayType( ty ) Then
  288. Local s:String = TransIfcType(TArrayType( ty ).elemType) + "&["
  289. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  290. s:+ ","
  291. Next
  292. Return s + "]" + p
  293. End If
  294. If TObjectType( ty ) Then
  295. Local t:String = ":"
  296. If TObjectType(ty).classDecl.IsExtern() Then
  297. If TObjectType(ty).classDecl.IsInterface() Then
  298. t = "??"
  299. ElseIf TObjectType(ty).classDecl.IsStruct() Then
  300. t = "~~"
  301. Else
  302. t = "?"
  303. End If
  304. End If
  305. Local cdecl:TClassDecl = TObjectType(ty).classDecl
  306. ' find first type in hierarchy that isn't private
  307. While cdecl.IsPrivate() And cdecl.superClass <> Null
  308. cdecl = cdecl.superClass
  309. Wend
  310. Return t + cdecl.ident + p
  311. End If
  312. If TFunctionPtrType( ty ) Return TransIfcType(TFunctionPtrType(ty).func.retType, TFunctionPtrType(ty).func.ModuleScope().IsSuperStrict()) + TransIfcArgs(TFunctionPtrType(ty).func)
  313. If TExternObjectType( ty ) Return ":" + TExternObjectType(ty).classDecl.ident + p
  314. InternalErr
  315. End Method
  316. Method TransRefType$( ty:TType, ident:String )
  317. Return TransType( ty, ident )
  318. End Method
  319. Method TransValue$( ty:TType,value$ )
  320. If value
  321. If IsPointerType(ty, 0, TType.T_POINTER) Return value
  322. If TBoolType( ty ) Return "1"
  323. If TShortType( ty ) Return value
  324. If TIntType( ty ) Return value
  325. If TUIntType( ty ) Return value+"U"
  326. If TLongType( ty ) Return value+"LL"
  327. If TULongType( ty ) Return value+"ULL"
  328. If TSizeTType( ty ) Return value
  329. If TWParamType( ty ) Return value
  330. If TLParamType( ty ) Return value
  331. If TInt128Type( ty ) Return value
  332. If TFloatType( ty ) Then
  333. If value = "nan" Or value = "1.#IND0000" Then
  334. Return "bbPOSNANf"
  335. Else If value="-nan" Or value = "-1.#IND0000" Then
  336. Return "bbNEGNANf"
  337. Else If value = "inf" Or value = "1.#INF0000" Then
  338. Return "bbPOSINFf"
  339. Else If value = "-inf" Or value = "-1.#INF0000" Then
  340. Return "bbNEGINFf"
  341. Else
  342. If value.ToLower().Find("e")>=0 Then
  343. Return value
  344. End If
  345. If value.Find(".") < 0 Then
  346. value :+ ".0"
  347. End If
  348. Return value+"f"
  349. End If
  350. End If
  351. If TDoubleType( ty ) Or TFloat128Type(ty) Or TDouble128Type(ty) Or TFloat64Type(ty) Then
  352. If value = "nan" Or value = "1.#IND0000" Then
  353. Return "bbPOSNANd"
  354. Else If value="-nan" Or value = "-1.#IND0000" Then
  355. Return "bbNEGNANd"
  356. Else If value = "inf" Or value = "1.#INF0000" Then
  357. Return "bbPOSINFd"
  358. Else If value = "-inf" Or value = "-1.#INF0000" Then
  359. Return "bbNEGINFd"
  360. Else
  361. If value.ToLower().Find("e") >=0 Then
  362. Return value
  363. End If
  364. If value.Find(".") < 0 Then
  365. value :+ ".0"
  366. End If
  367. Return value
  368. End If
  369. End If
  370. If TStringType( ty ) Return TransStringConst(value )
  371. If TByteType( ty ) Return value
  372. Else
  373. If TBoolType( ty ) Return "0"
  374. If TIntrinsicType( ty) Then
  375. If IsPointerType(ty, 0, TType.T_POINTER) Then
  376. Return "0"
  377. Else
  378. Return "{}"
  379. End If
  380. End If
  381. If TNumericType( ty ) Return "0" ' numeric and pointers
  382. If TStringType( ty ) Return "&bbEmptyString"
  383. If TArrayType( ty ) Return "&bbEmptyArray"
  384. If TObjectType( ty ) Then
  385. If TObjectType( ty ).classDecl.IsExtern() Or TObjectType( ty ).classDecl.IsStruct() Then
  386. If TObjectType( ty ).classDecl.IsInterface() Or IsPointerType(ty) Or (Not TObjectType( ty ).classDecl.IsStruct()) Then
  387. Return "0"
  388. Else
  389. Return "{}"
  390. End If
  391. Else
  392. Return "&bbNullObject"
  393. End If
  394. End If
  395. If TFunctionPtrType( ty) Return "&brl_blitz_NullFunctionError" ' todo ??
  396. EndIf
  397. InternalErr
  398. End Method
  399. Method TransArgs$( args:TExpr[],decl:TFuncDecl, objParam:String = Null )
  400. 'If decl.ident="AddS" DebugStop
  401. Local t$
  402. If objParam And (decl.IsMethod() Or decl.isCtor()) And ((Not decl.IsExtern()) Or (decl.IsExtern() And TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct())) Then
  403. t:+ objParam
  404. End If
  405. For Local i:Int=0 Until decl.argDecls.Length
  406. Local ty:TType = TArgDecl(decl.argDecls[i].actual).ty
  407. If t t:+","
  408. If i < args.length
  409. Local arg:TExpr = args[i]
  410. If TNullExpr(arg) Then
  411. t :+ TransValue(ty, Null)
  412. Continue
  413. Else If TIndexExpr(arg) And (ty._flags & TType.T_VAR) Then
  414. t:+ "&"
  415. Else If TStringType(ty) And (ty._flags & TType.T_VAR) Then
  416. If TCastExpr(arg) And TStringType(TCastExpr(arg).expr.exprType) Then
  417. t:+ "&"
  418. End If
  419. Else If TArrayType(ty) And (ty._flags & TType.T_VAR) Then
  420. If TVarExpr(arg) And TArrayType(TVarExpr(arg).exprType) And Not (arg.exprType._flags & TType.T_VAR) Then
  421. t:+ "&"
  422. End If
  423. Else If TObjectType(ty) And (ty._flags & TType.T_VAR) Then
  424. If (TVarExpr(arg) Or TMemberVarExpr(arg)) And TObjectType(arg.exprType) And Not (arg.exprType._flags & TType.T_VAR) Then
  425. t:+ "&"
  426. End If
  427. Else If TFunctionPtrType(ty) Or IsPointerType(ty, TType.T_BYTE) Then
  428. If TFunctionPtrType(ty) And (ty._flags & TType.T_VAR) Then
  429. t:+ "&"
  430. End If
  431. If TInvokeExpr(arg) And Not TInvokeExpr(arg).decl.IsMethod() Then
  432. If IsPointerType(ty, TType.T_BYTE) Then
  433. t:+ TInvokeExpr(arg).Trans()
  434. Else
  435. ' need to test scopes to see if we need to use the current instance's function or not
  436. ' use the "actual", not the copy we made for the function pointer.
  437. Local fdecl:TFuncDecl = TFuncDecl(TInvokeExpr(arg).decl.actual)
  438. If Not fdecl.munged Then
  439. MungDecl fdecl
  440. TInvokeExpr(arg).decl.munged = fdecl.munged
  441. End If
  442. If TClassDecl(fdecl.scope) Then
  443. ' current scope is related to function scope?
  444. If _env.ClassScope() And _env.FuncScope() And _env.FuncScope().IsMethod() Then
  445. If _env.ClassScope().ExtendsClass(TClassDecl(fdecl.scope)) Then
  446. Local scope:TScopeDecl = _env.scope
  447. Local obj:String = Bra("struct " + scope.munged + "_obj*")
  448. Local class:String = "o->clas"
  449. t:+ class + "->f_" + fdecl.ident + MangleMethod(fdecl)
  450. Else
  451. t:+ fdecl.munged
  452. End If
  453. Else
  454. t:+ fdecl.munged
  455. End If
  456. Else
  457. t:+ fdecl.munged
  458. End If
  459. End If
  460. Continue
  461. End If
  462. ' some cases where we are passing a function pointer via a void* parameter.
  463. If TCastExpr(arg) And TInvokeExpr(TCastExpr(arg).expr) And Not TInvokeExpr(TCastExpr(arg).expr).invokedWithBraces Then
  464. If Not TInvokeExpr(TCastExpr(arg).expr).decl.munged Then
  465. t:+ TInvokeExpr(TCastExpr(arg).expr).decl.actual.munged
  466. Else
  467. t:+ TInvokeExpr(TCastExpr(arg).expr).decl.munged
  468. End If
  469. Continue
  470. End If
  471. ' Object -> Byte Ptr
  472. If IsPointerType(ty, TType.T_BYTE) And TObjectType(arg.exprType) Then
  473. t:+ Bra(Bra("(BBBYTE*)" + Bra(arg.Trans())) + "+" + Bra("sizeof(void*)"))
  474. Continue
  475. End If
  476. Else If IsNumericType(ty) Then
  477. If TObjectType(arg.exprType) 'And TObjectType(args[i].exprType).classDecl = TClassDecl.nullObjectClass Then
  478. err "NULL"
  479. t:+ "0"
  480. Continue
  481. End If
  482. End If
  483. If decl.argDecls[i].castTo Then
  484. t:+ Bra(decl.argDecls[i].castTo) + arg.Trans()
  485. Else
  486. Local tc:String = TransTemplateCast( ty,arg.exprType,arg.Trans() )
  487. ' *sigh*
  488. ' if var is going to var, remove any leading dereference character.
  489. ' rather hacky. Would be better to cast variable to varptr during semanting (well done if you can work out where!)
  490. If arg.exprType.EqualsType( ty.ActualType() ) And (ty._flags & TType.T_VAR) And (arg.exprType._flags & TType.T_VAR) Then
  491. If tc.startswith("*") Then
  492. tc = tc[1..]
  493. End If
  494. End If
  495. t:+ tc
  496. 't:+TransTemplateCast( ty,args[i].exprType,args[i].Trans() )
  497. End If
  498. Else
  499. decl.argDecls[i].Semant()
  500. ' default values
  501. Local init:TExpr = decl.argDecls[i].init
  502. If init Then
  503. If TConstExpr(init) Then
  504. If TObjectType(TConstExpr(init).exprType) Then
  505. t:+"NULLNULLNULL"
  506. ' And TNullDecl(TObjectType(TConstExpr(init).exprType).classDecl)) Or (TConstExpr(init).value = "bbNullObject") Then
  507. If TStringType(decl.argDecls[i].ty) Then
  508. t :+ "&bbEmptyString"
  509. Else If TArrayType(decl.argDecls[i].ty) Then
  510. t :+ "&bbEmptyArray"
  511. Else
  512. t :+ "&bbNullObject"
  513. End If
  514. Else
  515. t:+ decl.argDecls[i].init.Trans()
  516. End If
  517. Else If TFunctionPtrType(ty) Then
  518. If TInvokeExpr(init) Then
  519. t:+ TInvokeExpr(init).decl.munged
  520. End If
  521. Else
  522. t:+ decl.argDecls[i].init.Trans()
  523. End If
  524. End If
  525. End If
  526. Next
  527. Return Bra(t)
  528. End Method
  529. Method TransArgsTypes$( args:TExpr[],declArgTypes:TType[])
  530. Local t$
  531. For Local i:Int=0 Until args.Length
  532. If t t:+","
  533. t:+TransTemplateCast( declArgTypes[i],args[i].exprType,args[i].Trans() )
  534. Next
  535. Return Bra(t)
  536. End Method
  537. Method TransPtrCast$( ty:TType,src:TType,expr$,cast$ )
  538. If IsPointerType(ty, 0, TType.T_POINTER | TType.T_VARPTR | TType.T_VAR) Or TFunctionPtrType(ty) Then
  539. ' TODO : pointer stuff
  540. If TNullType(src) Return TransValue(ty, Null)
  541. Return expr
  542. End If
  543. 'If expr = "NULL" DebugStop
  544. ' If TIntType(ty) And TStringType(src) Then
  545. 'DebugStop
  546. ' Return "bbObjectDowncast" + Bra(expr + ",&" + TStringType(src).cDecl.munged)
  547. ' End If
  548. If TNullType(src)
  549. Return TransValue(ty, Null)
  550. End If
  551. If TStringType(ty) And TObjectType(src) Then
  552. If Not TStringType(ty).cDecl Then
  553. ty.Semant()
  554. End If
  555. 'If TNullDecl(TObjectType(src).classDecl) Then
  556. ' Return "&bbEmptyString"
  557. 'End If
  558. Return Bra("(BBString *)bbObjectDowncast" + Bra(expr + ",&" + TStringType(ty).cDecl.munged))
  559. End If
  560. 'If TArrayType(ty) And TObjectType(src) Then
  561. ' If TNullDecl(TObjectType(src).classDecl) Then
  562. ' Return "&bbEmptyArray"
  563. ' End If
  564. 'End If
  565. If TVarPtrType(src) And TNumericType(ty) Then
  566. Return "*" + expr
  567. End If
  568. If TIntType(ty) And TStringType(src) Then
  569. Return Bra(expr + " != &bbEmptyString")
  570. End If
  571. ' If TIntType(ty) And TObjectType(src) Then
  572. ' Return Bra(expr + " != &bbNullObject")
  573. ' End If
  574. If TObjectType(ty) And TStringType(src) Then
  575. Return expr
  576. End If
  577. If Not TObjectType(ty) Or Not TObjectType(src) Then
  578. DebugStop
  579. InternalErr
  580. End If
  581. Local t$=TransType(ty, "TODO: TransPtrCast")
  582. If src.GetClass().IsInterface() Or ty.GetClass().IsInterface() cast="dynamic"
  583. If src.GetClass().IsInterface() And Not ty.GetClass().IsInterface() Then
  584. Return cast+"_cast<"+TransType(ty, "TODO: TransPtrCast")+">"+Bra( expr )
  585. End If
  586. 'upcast?
  587. If src.GetClass().ExtendsClass( ty.GetClass() ) Return expr
  588. If TObjectType(ty) Then
  589. Return Bra(Bra(TransObject(TObjectType(ty).classDecl)) + "bbObjectDowncast" + Bra(expr + ",&" + TObjectType(ty).classDecl.munged))
  590. End If
  591. Return cast+"_cast<"+TransType(ty, "TODO: TransPtrCast")+">"+Bra( expr )
  592. End Method
  593. '***** Utility *****
  594. Method TransLocalDecl$( decl:TLocalDecl,init:TExpr, declare:Int = False )
  595. If Not declare And opt_debug Then
  596. Local ty:TType = decl.ty
  597. If Not TObjectType( ty ) Or (TObjectType( ty ) And Not TObjectType( ty ).classDecl.IsStruct()) Then
  598. If TIntrinsicType(ty) Then
  599. If Not TConstExpr(init) Then
  600. Return decl.munged+"="+init.Trans()
  601. End If
  602. Else
  603. Return decl.munged+"="+init.Trans()
  604. End If
  605. Else If TObjectType( ty ) And TObjectType( ty ).classDecl.IsStruct() Then
  606. If Not TConstExpr(init) Then
  607. Return decl.munged+"="+init.Trans()
  608. End If
  609. End If
  610. Else
  611. If TFunctionPtrType(decl.ty) Then
  612. If TInvokeExpr(init) And Not TInvokeExpr(init).invokedWithBraces Then
  613. Return TransType( decl.ty, decl.munged ) + " = " + TInvokeExpr(init).decl.munged
  614. Else
  615. Return TransType( decl.ty, decl.munged ) + "=" + init.Trans()
  616. End If
  617. Else
  618. Local ty:TType = decl.ty
  619. If TVoidType( ty ) Or Not ty Then
  620. ty = init.exprType
  621. End If
  622. If TObjectType(ty) Then
  623. If TObjectType(ty).classdecl.IsExtern() Then
  624. If TObjectType(ty).classdecl.IsInterface() Then
  625. Return TransType( ty, decl.munged )+" "+decl.munged+"="+init.Trans()
  626. Else
  627. Return TransType( ty, decl.munged )+" "+decl.munged+"="+init.Trans()
  628. End If
  629. Else
  630. If TObjectType(ty).classdecl.IsStruct() Then
  631. Return TransType( ty, decl.munged )+" "+decl.munged + "= " + init.Trans()
  632. Else
  633. Return TransType( ty, decl.munged )+" volatile "+decl.munged+"="+init.Trans()
  634. End If
  635. End If
  636. Else
  637. Return TransType( ty, decl.munged )+" "+decl.munged+"="+init.Trans()
  638. End If
  639. End If
  640. End If
  641. End Method
  642. Method TransLocalDeclNoInit$( decl:TVarDecl )
  643. If TFunctionPtrType(decl.ty) Then
  644. Return TransType( decl.ty, decl.munged ) + "=" + TransValue(decl.ty, "")
  645. Else
  646. If TObjectType(decl.ty) Then
  647. If TObjectType(decl.ty).classdecl.IsExtern() Then
  648. If Not TObjectType(decl.ty).classdecl.IsStruct() Then
  649. Return TransType( decl.ty, decl.munged )+" "+decl.munged+"=" + TransValue(decl.ty, "")
  650. Else
  651. Return TransType( decl.ty, decl.munged )+" "+decl.munged
  652. End If
  653. Else
  654. If Not TObjectType(decl.ty).classdecl.IsStruct() Then
  655. Return TransType( decl.ty, decl.munged )+" volatile "+decl.munged + "=" + TransValue(decl.ty, "")
  656. Else
  657. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
  658. End If
  659. End If
  660. Else
  661. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
  662. End If
  663. End If
  664. End Method
  665. Method TransGlobalDecl$( gdecl:TGlobalDecl )
  666. Local glob:String
  667. If Not gdecl.funcGlobal Then
  668. If Not (gdecl.attrs & DECL_INITONLY) Then
  669. glob :+"static " + TransType( gdecl.init.exprType, gdecl.munged )+" "
  670. End If
  671. glob :+ gdecl.munged+"="
  672. If (TNewObjectExpr(gdecl.init) Or TNewArrayExpr(gdecl.init)) And Not (gdecl.attrs & DECL_INITONLY) Then
  673. glob :+ "0;~n"
  674. glob :+ indent + "if (" + gdecl.munged + "==0) {~n"
  675. glob :+ indent + "~t" + gdecl.munged + "=" + gdecl.init.Trans() + ";~n"
  676. glob :+ indent + "}"
  677. Else If TArrayExpr(gdecl.init) And Not (gdecl.attrs & DECL_INITONLY) Then
  678. glob :+ "0;~n"
  679. Emit glob
  680. Emit "if (" + gdecl.munged + "==0) {"
  681. glob = gdecl.munged + "=" + gdecl.init.Trans() + ";"
  682. Emit glob
  683. Emit "}"
  684. glob = ""
  685. Else
  686. If gdecl.init Then
  687. If TFunctionPtrType(gdecl.ty) Then
  688. If TInvokeExpr(gdecl.init) And Not TInvokeExpr(gdecl.init).invokedWithBraces Then
  689. glob :+ TInvokeExpr(gdecl.init).decl.munged
  690. Else
  691. glob :+ gdecl.init.Trans()
  692. End If
  693. Else If Not TConstExpr(gdecl.init) And Not (gdecl.attrs & DECL_INITONLY) Then
  694. ' for non const, we need to add an initialiser
  695. glob :+ TransValue(gdecl.ty, "") + ";~n"
  696. glob :+ indent +"static int _" + gdecl.munged + "_inited = 0;~n"
  697. glob :+ indent + "if (!_" + gdecl.munged + "_inited) {~n"
  698. glob :+ indent + "~t_" + gdecl.munged + "_inited = 1;~n"
  699. glob :+ indent + "~t" + gdecl.munged + " = " + gdecl.init.Trans() + ";~n"
  700. glob :+ indent + "}"
  701. Else
  702. glob :+ gdecl.init.Trans()
  703. End If
  704. Else
  705. If TFunctionPtrType(gdecl.ty) Then
  706. glob :+ "&brl_blitz_NullFunctionError"
  707. Else
  708. glob :+ "0"
  709. End If
  710. End If
  711. End If
  712. Else
  713. glob :+ "static int _" + gdecl.munged + "_inited = 0;~n"
  714. glob :+ indent + "if (!_" + gdecl.munged + "_inited) {~n"
  715. glob :+ indent + "~t_" + gdecl.munged + "_inited = 1;~n"
  716. glob :+ indent + "~t" + gdecl.munged + " = "
  717. If gdecl.init Then
  718. glob :+ gdecl.init.Trans()
  719. Else
  720. glob :+ TransValue(gdecl.ty, "")
  721. End If
  722. glob :+ ";~n"
  723. glob :+ indent + "}"
  724. End If
  725. Return glob
  726. End Method
  727. Method CreateLocal2$( ty:TType, t$ )
  728. Local tmp:TLocalDecl=New TLocalDecl.Create( "", ty,Null, True )
  729. MungDecl tmp
  730. If TShortType(ty) Then
  731. Emit TransType(ty, "") + " " + tmp.munged + " = bbStringToWString" + Bra(t)+ ";"
  732. Else
  733. Emit TransType(ty, "") + " " + tmp.munged + " = bbStringToCString" + Bra(t)+ ";"
  734. End If
  735. customVarStack.Push(tmp.munged)
  736. Return tmp.munged
  737. End Method
  738. Method EmitPushErr()
  739. Emit "pushErr();"
  740. End Method
  741. Method EmitSetErr( info$ )
  742. Emit "errInfo=~q"+info.Replace( "\","/" )+"~q;"
  743. End Method
  744. Method EmitPopErr()
  745. Emit "popErr();"
  746. End Method
  747. '***** Declarations *****
  748. Method TransStatic$( decl:TDecl )
  749. If decl.IsExtern() Then
  750. If Not decl.munged
  751. Return decl.ident
  752. End If
  753. Return decl.munged
  754. Else If _env And decl.scope And decl.scope=_env.ClassScope()
  755. ' calling a class function from a method?
  756. If TFuncDecl(decl) And _env.ClassScope() And _env.FuncScope() And _env.FuncScope().IsMethod() And Not (decl.attrs & FUNC_PTR) Then
  757. Local scope:TScopeDecl = _env.ClassScope()
  758. Local obj:String = Bra("struct " + scope.munged + "_obj*")
  759. Local class:String = "o->clas"
  760. Return class + "->f_" + decl.ident + MangleMethod(TFuncDecl(decl))
  761. Else
  762. Return decl.munged
  763. End If
  764. Else If TClassDecl( decl.scope )
  765. 'Return decl.scope.munged+"::"+decl.munged
  766. Return decl.munged
  767. Else If TModuleDecl( decl.scope )
  768. Return decl.munged
  769. Else If TFuncDecl(decl.scope)
  770. Return decl.munged
  771. Else If TGlobalDecl(decl)
  772. Return decl.munged
  773. Else If TBlockDecl(decl.scope)
  774. Return decl.munged
  775. EndIf
  776. InternalErr
  777. End Method
  778. Method TransTemplateCast$( ty:TType,src:TType,expr$ )
  779. ' *sigh*
  780. ' if var is going to var, remove any leading dereference character.
  781. ' rather hacky. Would be better to cast variable to varptr during semanting (well done if you can work out where!)
  782. 'If src.EqualsType( ty.ActualType() ) And (ty._flags & TType.T_VAR) And (src._flags & TType.T_VAR) Then
  783. ' If expr.startswith("*") Then
  784. ' expr = expr[1..]
  785. ' End If
  786. 'End If
  787. If ty=src Return expr
  788. ty=ty.ActualType()
  789. 'src=src.ActualType()
  790. If src.EqualsType( ty ) Return expr
  791. Return TransPtrCast( ty,src,expr,"static" )
  792. End Method
  793. Method TransGlobal$( decl:TGlobalDecl )
  794. Return TransStatic( decl )
  795. End Method
  796. Method TransField$( decl:TFieldDecl,lhs:TExpr )
  797. If lhs Then
  798. Return TransFieldRef(decl, TransSubExpr( lhs ), lhs.exprType)
  799. Else
  800. Return TransFieldRef(decl, "o", Null)
  801. End If
  802. ' Local swiz$
  803. ' If TObjectType( decl.ty )
  804. ' If TObjectType( decl.ty ).classDecl.IsInterface() swiz=".p"
  805. ' EndIf
  806. ' If lhs Return TransSubExpr( lhs )+"->"+decl.munged+swiz
  807. ' Return decl.munged+swiz
  808. End Method
  809. Method TransFunc$( decl:TFuncDecl,args:TExpr[],lhs:TExpr, sup:Int = False, scope:TScopeDecl = Null )
  810. 'If decl.ident = "eventfilter" DebugStop
  811. ' for calling the super class method instead
  812. Local tSuper:String
  813. If sup Then
  814. tSuper = "->super"
  815. End If
  816. If Not decl.munged
  817. MungDecl decl
  818. End If
  819. 'If decl.IsMethod()
  820. If lhs And Not TSelfExpr(lhs) Then
  821. If TStringType(lhs.exprType) Then
  822. Return decl.munged + TransArgs(args, decl, TransSubExpr( lhs ))
  823. End If
  824. If TStmtExpr(lhs) Then
  825. lhs.Trans()
  826. lhs = TStmtExpr(lhs).expr
  827. End If
  828. If TVarExpr(lhs) Then
  829. Local cdecl:TClassDecl
  830. If TObjectType(TVarExpr(lhs).decl.ty) Then
  831. cdecl = TObjectType(TVarExpr(lhs).decl.ty).classDecl
  832. Else If TArrayType(TVarExpr(lhs).decl.ty) Then
  833. Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  834. End If
  835. If decl.attrs & FUNC_PTR Then
  836. 'Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  837. Return TransSubExpr( lhs ) + "->" + decl.munged+TransArgs( args,decl, Null)
  838. Else
  839. If decl.scope.IsExtern()
  840. If Not cdecl.IsStruct() Then
  841. 'Return decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  842. Return Bra(TransSubExpr( lhs )) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  843. End If
  844. Err "TODO extern types not allowed methods"
  845. Else
  846. If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  847. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + TransSubExpr( lhs ) + ", " + "&" + cdecl.munged + "_ifc)"))
  848. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  849. Else
  850. If cdecl.IsStruct() Then
  851. If Not isPointerType(lhs.exprType) Then
  852. Return "_" + decl.munged+TransArgs( args,decl, "&" + TransSubExpr( lhs ) )
  853. Else
  854. Return "_" + decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  855. End If
  856. Else
  857. Local class:String = Bra(TransSubExpr( lhs )) + "->clas" + tSuper
  858. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  859. End If
  860. End If
  861. End If
  862. End If
  863. Else If TNewObjectExpr(lhs) Then
  864. Local cdecl:TClassDecl = TNewObjectExpr(lhs).classDecl
  865. If cdecl.IsStruct() Then
  866. ' create a local variable of the inner invocation
  867. Local lvar:String = CreateLocal(lhs)
  868. Return "_" + decl.munged+TransArgs( args,decl, "&" + lvar )
  869. Else
  870. Local class:String = cdecl.munged
  871. Return class + "." + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  872. End If
  873. Else If TCastExpr(lhs) Then
  874. Local cdecl:TClassDecl = TObjectType(TCastExpr(lhs).ty).classDecl
  875. Local obj:String = Bra(TransObject(cdecl))
  876. If decl.attrs & FUNC_PTR Then
  877. Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  878. Else
  879. ' Null test
  880. If opt_debug Then
  881. EmitDebugNullObjectError(TransSubExpr( lhs ))
  882. End If
  883. If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  884. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + obj + TransSubExpr( lhs ) + ", " + "&" + cdecl.munged + "_ifc)"))
  885. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  886. Else
  887. Local class:String = Bra("(" + obj + TransSubExpr( lhs ) + ")->clas" + tSuper)
  888. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  889. End If
  890. End If
  891. Else If TMemberVarExpr(lhs) Then
  892. If TObjectType(TMemberVarExpr(lhs).decl.ty) Then
  893. Local cdecl:TClassDecl = TObjectType(TMemberVarExpr(lhs).decl.ty).classDecl
  894. Local obj:String = Bra(TransObject(cdecl))
  895. If decl.scope.IsExtern()
  896. If TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct() Then
  897. Return Bra(TransSubExpr( lhs )) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  898. Else
  899. Return decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  900. End If
  901. Else
  902. If cdecl.IsStruct() Then
  903. ' baaaaaaaaaaaaaaaaa
  904. If Not isPointerType(lhs.exprType) Then
  905. Return "_" + decl.munged+TransArgs( args,decl, "&" + TransSubExpr( lhs ) )
  906. Else
  907. Return "_" + decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  908. End If
  909. Else
  910. If decl.attrs & FUNC_PTR Then
  911. Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  912. Else
  913. ' Null test
  914. If opt_debug Then
  915. EmitDebugNullObjectError(TransSubExpr( lhs ))
  916. End If
  917. Local class:String = Bra("(" + obj + TransSubExpr( lhs ) + ")->clas" + tSuper)
  918. 'Local class:String = TransFuncClass(cdecl)
  919. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  920. End If
  921. End If
  922. End If
  923. Else If TArrayType(TMemberVarExpr(lhs).decl.ty) Then
  924. Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  925. End If
  926. Else If TInvokeExpr(lhs) Then
  927. ' create a local variable of the inner invocation
  928. Local lvar:String = CreateLocal(lhs)
  929. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  930. If Not isPointerType(lhs.exprType) Then
  931. Return "_" + decl.munged+TransArgs( args,decl, "&" + lvar )
  932. Else
  933. Return "_" + decl.munged+TransArgs( args,decl, lvar )
  934. End If
  935. Else
  936. ' Null test
  937. If opt_debug Then
  938. EmitDebugNullObjectError(lvar)
  939. End If
  940. Local obj:String = Bra(TransObject(decl.scope))
  941. Local class:String = Bra("(" + obj + lvar +")->clas" + tSuper)
  942. Return class + "->" + TransFuncPrefix(decl.scope, decl)+ FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  943. End If
  944. 'Local obj:String = Bra("struct " + decl.scope.munged + "_obj*")
  945. 'Local class:String = Bra("(" + obj + TransSubExpr( lhs ) +")->clas" + tSuper)
  946. 'Local class:String = Bra("&" + decl.scope.munged)
  947. 'Return class + "->" + TransFuncPrefix(decl.scope, decl.ident) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
  948. Else If TInvokeMemberExpr(lhs)
  949. ' create a local variable of the inner invocation
  950. Local lvar:String = CreateLocal(lhs)
  951. If decl.scope.IsExtern()
  952. If TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct() Then
  953. Return Bra(lvar) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, lvar ))
  954. End If
  955. Return "// TODO"
  956. Else
  957. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  958. If Not isPointerType(lhs.exprType) Then
  959. Return "_" + decl.munged+TransArgs( args,decl, "&" + lvar )
  960. Else
  961. Return "_" + decl.munged+TransArgs( args,decl, lvar )
  962. End If
  963. Else
  964. ' Null test
  965. If opt_debug Then
  966. EmitDebugNullObjectError(lvar)
  967. End If
  968. Local obj:String = lvar + "->clas" + tSuper
  969. Return obj + "->" + TransFuncPrefix(decl.scope, decl)+ FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  970. End If
  971. End If
  972. Else If TIndexExpr(lhs) Then
  973. Local loc:String = CreateLocal(lhs)
  974. Local obj:String = Bra(TransObject(decl.scope))
  975. ' Null test
  976. If opt_debug Then
  977. EmitDebugNullObjectError(loc)
  978. End If
  979. If decl.attrs & FUNC_PTR Then
  980. Return loc + "->" + decl.munged+TransArgs( args,decl, Null)
  981. Else
  982. If decl.scope.IsExtern()
  983. Local cdecl:TClassDecl = TClassDecl(decl.scope)
  984. If Not cdecl.IsStruct() Then
  985. Return Bra(loc) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, loc ))
  986. End If
  987. Err "TODO extern types not allowed methods"
  988. Else
  989. Local cdecl:TClassDecl = TClassDecl(decl.scope)
  990. If cdecl And (cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl)) Then
  991. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + obj + loc + ", " + "&" + cdecl.munged + "_ifc)"))
  992. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, loc )
  993. Else
  994. Local class:String = Bra(loc + "->clas" + tSuper)
  995. Return class + "->" + TransFuncPrefix(decl.scope, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, loc )
  996. End If
  997. End If
  998. End If
  999. Else
  1000. InternalErr
  1001. End If
  1002. 'Return TransSubExpr( lhs )+"->"+decl.munged+TransArgs( args,decl )
  1003. 'Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1004. End If
  1005. ' ((brl_standardio_TCStandardIO_obj*)o->clas)->md_Read(o, xxx, xxx)
  1006. If decl.IsMethod() Then
  1007. If Not (decl.attrs & FUNC_PTR) Then
  1008. Local class:String
  1009. If Not scope Then
  1010. scope = decl.scope
  1011. If TClassDecl(scope) And Not TClassDecl(scope).IsStruct() Then
  1012. Local obj:String = Bra(TransObject(scope))
  1013. class = "(" + obj + "o)->clas" + tSuper
  1014. ' Null test
  1015. If opt_debug Then
  1016. EmitDebugNullObjectError("o")
  1017. End If
  1018. End If
  1019. Else
  1020. class = Bra("&" + scope.munged) + tSuper
  1021. End If
  1022. 'Local obj:String = Bra("struct " + scope.munged + "_obj*")
  1023. 'Local class:String = Bra("(" + obj + "o)->clas" + tSuper)
  1024. 'Local class:String = Bra("&" + decl.scope.munged)
  1025. If TClassDecl(scope).IsStruct() Then
  1026. Return "_" + decl.munged+TransArgs( args,decl, "o" )
  1027. Else
  1028. Return class + "->" + TransFuncPrefix(scope, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, "o" )
  1029. End If
  1030. Else
  1031. ' Null test
  1032. If opt_debug Then
  1033. EmitDebugNullObjectError("o")
  1034. End If
  1035. Local obj:String = Bra(TransObject(decl.scope))
  1036. Return Bra(obj + "o") + "->" + decl.munged+TransArgs( args,decl )
  1037. End If
  1038. End If
  1039. Return TransStatic( decl )+TransArgs( args,decl )
  1040. End Method
  1041. Method TransObject:String(decl:TScopeDecl, this:Int = False)
  1042. If decl.ident = "Object"
  1043. Return "BBOBJECT"
  1044. Else
  1045. If TClassDecl(decl) And TClassDecl(decl).IsStruct() Then
  1046. Local t:String = "struct "
  1047. If decl.IsExtern() Then
  1048. t :+ decl.ident
  1049. Else
  1050. t :+ decl.munged
  1051. End If
  1052. If this Then
  1053. Return t + "*"
  1054. Else
  1055. Return t
  1056. End If
  1057. Else
  1058. If decl.IsExtern() Then
  1059. Return "struct " + decl.ident + "*"
  1060. Else
  1061. Return "struct " + decl.munged + "_obj*"
  1062. End If
  1063. End If
  1064. End If
  1065. End Method
  1066. Method TransFuncClass:String(decl:TClassDecl)
  1067. If decl.ident = "Object"
  1068. Return Bra("&bbObjectClass")
  1069. Else
  1070. Return Bra("&" + decl.munged)
  1071. End If
  1072. End Method
  1073. Method TransFuncPrefix:String(decl:TScopeDecl, fdecl:TFuncDecl)
  1074. Local ident:String = fdecl.ident
  1075. If Not decl Or decl.ident = "Object" Or equalsBuiltInFunc(fdecl.ClassScope(), fdecl)
  1076. Return ""
  1077. Else
  1078. If fdecl.IsMethod() Then
  1079. Return "m_"
  1080. Else
  1081. Return "f_"
  1082. End If
  1083. End If
  1084. End Method
  1085. Method TransSuperFunc$( decl:TFuncDecl,args:TExpr[], scope:TScopeDecl )
  1086. Return TransFunc(decl, args, Null, True, scope)
  1087. ' If decl.IsMethod()
  1088. ' Return decl.ClassScope().munged+".md_"+decl.ident+TransArgs( args,decl, "o" )
  1089. ' Else
  1090. ' Return decl.ClassScope().munged+".fn_"+decl.ident+TransArgs( args,decl)
  1091. ' End If
  1092. End Method
  1093. Method TransMinExpr:String(expr:TMinExpr)
  1094. Local s:String
  1095. If TDecimalType(expr.exprType) Then
  1096. s = "bbFloatMin"
  1097. Else If TLongType(expr.exprType) Then
  1098. s = "bbLongMin"
  1099. Else If TSizeTType(expr.exprType) Then
  1100. s = "bbSizetMin"
  1101. Else If TUIntType(expr.exprType) Then
  1102. s = "bbUIntMin"
  1103. Else If TULongType(expr.exprType) Then
  1104. s = "bbULongMin"
  1105. Else
  1106. s = "bbIntMin"
  1107. End If
  1108. Return s + Bra(expr.expr.trans() + "," + expr.expr2.Trans())
  1109. End Method
  1110. Method TransMaxExpr:String(expr:TMaxExpr)
  1111. Local s:String
  1112. If TDecimalType(expr.exprType) Then
  1113. s = "bbFloatMax"
  1114. Else If TLongType(expr.exprType) Then
  1115. s = "bbLongMax"
  1116. Else If TSizeTType(expr.exprType) Then
  1117. s = "bbSizetMax"
  1118. Else If TUIntType(expr.exprType) Then
  1119. s = "bbUIntMax"
  1120. Else If TULongType(expr.exprType) Then
  1121. s = "bbULongMax"
  1122. Else
  1123. s = "bbIntMax"
  1124. End If
  1125. Return s + Bra(expr.expr.trans() + "," + expr.expr2.Trans())
  1126. End Method
  1127. Method TransAscExpr:String(expr:TAscExpr)
  1128. Return "bbStringAsc" + Bra(expr.expr.Trans())
  1129. End Method
  1130. Method TransChrExpr:String(expr:TChrExpr)
  1131. Return "bbStringFromChar" + Bra(expr.expr.Trans())
  1132. End Method
  1133. Method TransSgnExpr:String(expr:TSgnExpr)
  1134. Local s:String
  1135. If TFloatType(expr.expr.exprType) Or TDoubleType(expr.expr.exprType)
  1136. 'decl.ident contains "sgn", same like "bbFloatSng"
  1137. s = "bbFloatSgn"
  1138. Else If TLongType(expr.expr.exprType) Then
  1139. s = "bbLongSgn"
  1140. Else If TSizeTType(expr.expr.exprType) Then
  1141. s = "bbSizetSgn"
  1142. Else If TUIntType(expr.expr.exprType) Then
  1143. s = "bbUIntSgn"
  1144. Else If TULongType(expr.expr.exprType) Then
  1145. s = "bbULongSgn"
  1146. Else
  1147. s = "bbIntSgn"
  1148. End If
  1149. Return s + Bra(expr.expr.Trans())
  1150. End Method
  1151. Method TransAbsExpr:String(expr:TAbsExpr)
  1152. Local s:String
  1153. If TDecimalType(expr.exprType) Then
  1154. s = "bbFloatAbs"
  1155. Else If TLongType(expr.exprType)
  1156. s = "bbLongAbs"
  1157. Else If TSizeTType(expr.exprType)
  1158. s = "bbSizetAbs"
  1159. Else If TUIntType(expr.exprType)
  1160. s = "bbUIntAbs"
  1161. Else If TULongType(expr.exprType)
  1162. s = "bbULongAbs"
  1163. Else
  1164. s = "bbIntAbs"
  1165. End If
  1166. Return s + Bra(expr.expr.Trans())
  1167. End Method
  1168. Method TransLenExpr:String(expr:TLenExpr)
  1169. 'constant strings do not have "->length", so we use the
  1170. 'precalculated value
  1171. If TConstExpr(expr.expr) Then
  1172. If TStringType(expr.expr.exprType) Then
  1173. Return TConstExpr(expr.expr).value.Length
  1174. End If
  1175. End If
  1176. If TStringType(expr.expr.exprType) Then
  1177. Return Bra(expr.expr.Trans()) + "->length"
  1178. Else If TArrayType(expr.expr.exprType) Then
  1179. Return Bra(expr.expr.Trans()) + "->scales[0]"
  1180. Else If TCastExpr(expr.expr) Then
  1181. If TArrayType(TCastExpr(expr.expr).expr.exprType) Then
  1182. Return Bra(TCastExpr(expr.expr).expr.Trans()) + "->scales[0]"
  1183. End If
  1184. 'other types just have a length of "1"
  1185. Else
  1186. Return "1"
  1187. End If
  1188. End Method
  1189. Method TransSizeOfExpr:String(expr:TSizeOfExpr)
  1190. Local cexpr:TConstExpr = TConstExpr(expr.expr)
  1191. If cexpr Then
  1192. If TNumericType(cexpr.exprType) Then
  1193. Return "sizeof" + Bra(TransType(cexpr.exprType, ""))
  1194. ' strings
  1195. Else If TStringType(cexpr.exprType) Then
  1196. ' length of const string * 2 bytes per char
  1197. Return Len(cexpr.value) * 2
  1198. End If
  1199. Else
  1200. If TNumericType(expr.expr.exprType) Then
  1201. ' remove Var-ness first, if any
  1202. Local t:TType = expr.expr.exprType.Copy()
  1203. If t._flags & TType.T_VAR Then
  1204. t._flags :~ TType.T_VAR
  1205. End If
  1206. Return "sizeof" + Bra(TransType(t, ""))
  1207. ' strings
  1208. Else If TStringType(expr.expr.exprType) Then
  1209. 'unicode chars each take 2 bytes
  1210. Return Bra(expr.expr.Trans()) + "->length * 2"
  1211. ' arrays
  1212. Else If TArrayType(expr.expr.exprType) Then
  1213. 'normal exprType is something like "int[]" that
  1214. 'is why it has to be checked against elemType
  1215. Local elemType:TType = TArrayType( expr.expr.exprType ).elemType
  1216. ' numerics - including numeric pointers
  1217. If TNumericType(elemType) Then
  1218. 'multiply element count * size of element type
  1219. Return Bra(expr.expr.Trans()) + "->scales[0] * sizeof" + Bra(TransType(elemType, ""))
  1220. ' everything else : string, array, object, function pointer - are all pointers
  1221. Else
  1222. 'arrays of objects are of size: elementCount * pointerSize
  1223. Return Bra(expr.expr.Trans()) + "->scales[0] * sizeof(void*)"
  1224. EndIf
  1225. ' objects
  1226. Else If TObjectType(expr.expr.exprType) Then
  1227. If TObjectType( expr.expr.exprType ).classDecl.ident = "Object" Then
  1228. Return "0"
  1229. Else
  1230. Local cdecl:TClassDecl = TObjectType( expr.expr.exprType ).classDecl
  1231. If cdecl.IsStruct() Then
  1232. If TIdentTypeExpr(expr.expr) Then
  1233. If cdecl.IsExtern() Then
  1234. Return "sizeof" + Bra("struct " + cdecl.ident)
  1235. Else
  1236. Return "sizeof" + Bra("struct " + cdecl.munged)
  1237. End If
  1238. Else
  1239. Return "sizeof" + Bra(expr.expr.Trans())
  1240. End If
  1241. Else
  1242. If TIdentTypeExpr(expr.expr) Then
  1243. Return Bra(Bra(TransFuncClass(cdecl)) + "->obj_size")
  1244. Else
  1245. Return Bra(Bra(expr.expr.Trans()) + "->clas->obj_size")
  1246. End If
  1247. End If
  1248. End If
  1249. End If
  1250. End If
  1251. InternalErr
  1252. End Method
  1253. '***** Expressions *****
  1254. Method TransConstExpr$( expr:TConstExpr )
  1255. If TStringType(expr.exprType) Then
  1256. Return TransStringConst(expr.value)
  1257. Else
  1258. Return TransValue( expr.exprType,expr.value )
  1259. End If
  1260. End Method
  1261. Field stringMap:TMap = New TMap
  1262. Method TransStringConst:String(value:String)
  1263. If value Then
  1264. _appInstance.mapStringConsts(value)
  1265. End If
  1266. Local sc:TStringConst = TStringConst(_app.stringConsts.ValueForKey(value))
  1267. Local s:String
  1268. If Not sc Then
  1269. s = "bbEmptyString"
  1270. Else
  1271. If Not sc.count Then
  1272. sc.count :+ 1
  1273. End If
  1274. s = sc.id
  1275. End If
  1276. Return "&" + s
  1277. End Method
  1278. Method TransNewObjectExpr$( expr:TNewObjectExpr )
  1279. Local t$
  1280. If Not expr.classDecl.IsStruct() And (Not expr.ctor.argDecls Or expr.ctor.argDecls.length = 0) Then
  1281. If expr.instanceExpr Then
  1282. t = "bbObjectNew(" + Bra(expr.instanceExpr.Trans()) + "->clas)"
  1283. Else
  1284. If ClassHasObjectField(expr.classDecl) Then
  1285. t = "bbObjectNew(&" + expr.classDecl.actual.munged + ")"
  1286. Else
  1287. t = "bbObjectAtomicNew(&" + expr.classDecl.actual.munged + ")"
  1288. End If
  1289. End If
  1290. Else
  1291. Local ctorMunged:String
  1292. If expr.classDecl = expr.ctor.scope Then
  1293. ctorMunged = expr.ctor.munged
  1294. Else
  1295. ctorMunged = expr.classDecl.actual.munged + "_" + expr.ctor.ident + MangleMethod(expr.ctor)
  1296. End If
  1297. If expr.instanceExpr Then
  1298. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, Bra(expr.instanceExpr.Trans()) + "->clas" )
  1299. Else
  1300. If ClassHasObjectField(expr.classDecl) Then
  1301. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, "&" + expr.classDecl.actual.munged )
  1302. Else
  1303. If expr.classDecl.IsStruct() Then
  1304. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor)
  1305. Else
  1306. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, "&" + expr.classDecl.actual.munged)
  1307. End If
  1308. End If
  1309. End If
  1310. End If
  1311. 'Local t$="(new "+expr.classDecl.actual.munged+")"
  1312. 'If expr.ctor t:+"->"+expr.ctor.actual.munged+TransArgs( expr.args,expr.ctor )
  1313. Return t
  1314. End Method
  1315. Method TransNewArrayExpr$( expr:TNewArrayExpr )
  1316. If expr.expr.length = 1 Then
  1317. If TObjectType(expr.ty) And TObjectType(expr.ty).classdecl.IsStruct() And Not IsPointerType(expr.ty) Then
  1318. Return "bbArrayNew1DStruct" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans() + ", sizeof" + Bra(TransObject(TObjectType(expr.ty).classdecl)))
  1319. Else
  1320. Return "bbArrayNew1D" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans())
  1321. End If
  1322. Else
  1323. ' multiple array
  1324. Local s:String
  1325. For Local i:Int = 0 Until expr.expr.length
  1326. If i Then
  1327. s:+ ", "
  1328. End If
  1329. s:+ expr.expr[i].Trans()
  1330. Next
  1331. Return "bbArrayNew" + Bra(TransArrayType(expr.ty) + ", " + expr.expr.length + ", " + s)
  1332. End If
  1333. End Method
  1334. Method TransSelfExpr$( expr:TSelfExpr )
  1335. Return "o"
  1336. End Method
  1337. Method TransIdentTypeExpr:String(expr:TIdentTypeExpr)
  1338. Return "struct " + expr.cdecl.munged + "_obj"
  1339. End Method
  1340. Method TransCastExpr$( expr:TCastExpr )
  1341. Local t$= expr.expr.Trans()
  1342. Local dst:TType=expr.exprType
  1343. Local src:TType=expr.expr.exprType
  1344. If TNumericType(src) And (src._flags & TType.T_VAR) Then
  1345. ' var number being cast to a varptr
  1346. If (dst._flags & TType.T_VARPTR) Then
  1347. Return "&" + Bra(t)
  1348. End If
  1349. End If
  1350. If (dst._flags & TType.T_VARPTR) Or (dst._flags & TType.T_VAR) Then
  1351. If Not TConstExpr(expr.expr) Then
  1352. If TInvokeExpr(expr.expr) Return t
  1353. If TByteType( src) Return Bra("&"+t)
  1354. If TShortType( src) Return Bra("&"+t)
  1355. If TFloatType( src) Return Bra("&"+t)
  1356. If TIntType( src) Return Bra("&"+t)
  1357. If TUIntType( src) Return Bra("&"+t)
  1358. If TLongType( src) Return Bra("&"+t)
  1359. If TULongType( src) Return Bra("&"+t)
  1360. If TSizeTType( src) Return Bra("&"+t)
  1361. If TDoubleType( src) Return Bra("&"+t)
  1362. If TInt128Type( src) Return Bra("&"+t)
  1363. If TFloat128Type( src) Return Bra("&"+t)
  1364. If TDouble128Type( src) Return Bra("&"+t)
  1365. If TFloat64Type( src) Return Bra("&"+t)
  1366. If TWParamType( src) Return Bra("&"+t)
  1367. If TLParamType( src) Return Bra("&"+t)
  1368. If TObjectType(src) Then
  1369. If TObjectType(src).classDecl.IsExtern() Or (dst._flags & TType.T_VARPTR) Then
  1370. Return Bra("&" + t)
  1371. Else
  1372. If TObjectType(dst) Then
  1373. Return Bra("&" + t)
  1374. Else
  1375. Return Bra(Bra("(BBBYTE*)" + Bra("&" + t)) + "+" + Bra("sizeof(void*)"))
  1376. End If
  1377. End If
  1378. End If
  1379. If TFunctionPtrType(src) Return Bra("&"+t)
  1380. 'If TPointerType( src) Return Bra("&"+t)
  1381. Else
  1382. Return Bra(TransValue(TConstExpr(expr.expr).ty, TConstExpr(expr.expr).value))
  1383. End If
  1384. Else If IsPointerType( dst, 0, TType.T_POINTER | TType.T_CHAR_PTR | TType.T_SHORT_PTR )
  1385. If TArrayType(src) Then
  1386. Return Bra(Bra(TransType(dst, "")) + "BBARRAYDATA(" + t + "," + t + "->dims)")
  1387. End If
  1388. 'If TByteType(src) And Not IsPointerType(src, TType.T_BYTE, TType.T_POINTER) Return Bra("&"+t)
  1389. If TStringType(src) Then
  1390. Local tmp:String
  1391. If IsPointerType( dst, 0, TType.T_SHORT_PTR ) Or IsPointerType( dst, TType.T_SHORT, TType.T_PTR ) Then
  1392. tmp = CreateLocal2(NewPointerType(TType.T_SHORT), t)
  1393. Else
  1394. tmp = CreateLocal2(NewPointerType(TType.T_BYTE), t)
  1395. End If
  1396. Return tmp
  1397. End If
  1398. If (TStringType(dst) And IsPointerType( dst, 0, TType.T_CHAR_PTR | TType.T_SHORT_PTR )) And TNullType(src) Then
  1399. Return "0"
  1400. End If
  1401. If TObjectType(src) Then
  1402. If TObjectType(src).classDecl.IsExtern() Or (src._flags & TType.T_VARPTR) Then
  1403. Return Bra(t)
  1404. Else
  1405. Return Bra(Bra("(BBBYTE*)" + t) + "+" + Bra("sizeof(void*)"))
  1406. End If
  1407. End If
  1408. Local p:String = TransSPointer(dst)
  1409. If TByteType( dst )
  1410. If IsPointerType(src, TType.T_BYTE, TType.T_POINTER & dst._flags) Return t
  1411. If TNumericType( src ) Return Bra("(BBBYTE" + p + ")"+t)
  1412. Else If TShortType( dst )
  1413. If IsPointerType(src, TType.T_SHORT, TType.T_POINTER & dst._flags) Return t
  1414. If TNumericType( src ) Return Bra("(BBSHORT" + p + ")"+t)
  1415. Else If TIntType( dst )
  1416. If IsPointerType(src, TType.T_INT, TType.T_POINTER & dst._flags) Return t
  1417. If TNumericType( src ) Return Bra("(BBINT" + p + ")"+t)
  1418. Else If TUIntType( dst )
  1419. If IsPointerType(src, TType.T_UINT, TType.T_POINTER & dst._flags) Return t
  1420. If TNumericType( src ) Return Bra("(BBUINT" + p + ")"+t)
  1421. Else If TFloatType( dst )
  1422. If IsPointerType(src, TType.T_FLOAT, TType.T_POINTER & dst._flags) Return t
  1423. If TNumericType( src ) Return Bra("(BBFLOAT" + p + ")"+t)
  1424. Else If TDoubleType( dst )
  1425. If IsPointerType(src, TType.T_DOUBLE, TType.T_POINTER & dst._flags) Return t
  1426. If TNumericType( src ) Return Bra("(BBDOUBLE" + p + ")"+t)
  1427. Else If TLongType( dst )
  1428. If IsPointerType(src, TType.T_LONG, TType.T_POINTER & dst._flags) Return t
  1429. If TNumericType( src ) Return Bra("(BBLONG" + p + ")"+t)
  1430. Else If TULongType( dst )
  1431. If IsPointerType(src, TType.T_ULONG, TType.T_POINTER & dst._flags) Return t
  1432. If TNumericType( src ) Return Bra("(BBULONG" + p + ")"+t)
  1433. Else If TSizeTType( dst )
  1434. If IsPointerType(src, TType.T_SIZET, TType.T_POINTER & dst._flags) Return t
  1435. If TNumericType( src ) Return Bra("(BBSIZET" + p + ")"+t)
  1436. Else If TWParamType( dst )
  1437. If IsPointerType(src, TType.T_WPARAM, TType.T_POINTER & dst._flags) Return t
  1438. If TNumericType( src ) Return Bra("(WPARAM" + p + ")"+t)
  1439. Else If TLParamType( dst )
  1440. If IsPointerType(src, TType.T_LPARAM, TType.T_POINTER & dst._flags) Return t
  1441. If TNumericType( src ) Return Bra("(LPARAM" + p + ")"+t)
  1442. Else If TInt128Type( dst )
  1443. If IsPointerType(src, TType.T_INT128, TType.T_POINTER & dst._flags) Return t
  1444. If TNumericType( src ) Return Bra("(BBINT128" + p + ")"+t)
  1445. Else If TFloat128Type( dst )
  1446. If IsPointerType(src, TType.T_FLOAT128, TType.T_POINTER & dst._flags) Return t
  1447. If TNumericType( src ) Return Bra("(BBFLOAT128" + p + ")"+t)
  1448. Else If TDouble128Type( dst )
  1449. If IsPointerType(src, TType.T_DOUBLE128, TType.T_POINTER & dst._flags) Return t
  1450. If TNumericType( src ) Return Bra("(BBDOUBLE128" + p + ")"+t)
  1451. Else If TFloat64Type( dst )
  1452. If IsPointerType(src, TType.T_FLOAT64, TType.T_POINTER & dst._flags) Return t
  1453. If TNumericType( src ) Return Bra("(BBFLOAT64" + p + ")"+t)
  1454. 'Else If TIntPtrPtrType( dst )
  1455. ' If TBytePtrType( src) Return Bra("(BBINT**)"+t)
  1456. ' If TShortPtrType( src ) Return Bra("(BBINT**)"+t)
  1457. ' If TIntPtrType( src ) Return Bra("(BBINT**)"+t)
  1458. ' If TFloatPtrType( src ) Return Bra("(BBINT**)"+t)
  1459. ' If TDoublePtrType( src ) Return Bra("(BBINT**)"+t)
  1460. ' If TLongPtrType( src ) Return Bra("(BBINT**)"+t)
  1461. ' If TNumericType( src ) Return Bra("(BBINT**)"+t)
  1462. End If
  1463. Else If TBoolType( dst )
  1464. If TFunctionPtrType(src) Return Bra(Bra( t+"!=0" ) + " && " + Bra( t+"!=&brl_blitz_NullFunctionError" ))
  1465. 'If TFunctionPtrType(src) Return Bra( t+"!=0" )
  1466. If IsPointerType( src, 0, TType.T_POINTER ) Return Bra( t )
  1467. If TBoolType( src ) Return t
  1468. If TByteType( src ) Return Bra( t+"!=0" )
  1469. If TShortType( src ) Return Bra( t+"!=0" )
  1470. If TIntType( src ) Return Bra( t+"!=0" )
  1471. If TUIntType( src ) Return Bra( t+"!=0" )
  1472. If TFloatType( src ) Return Bra( t+"!=0.0f" )
  1473. 'If TCastExpr(expr.expr) And (TArrayType( src ) Or TStringType( src ) Or TObjectType( src )) Then
  1474. ' Return Bra( t+"!= &bbNullObject" )
  1475. 'End If
  1476. If TLongType( src ) Return Bra( t+"!=0" )
  1477. If TULongType( src ) Return Bra( t+"!=0" )
  1478. If TSizeTType( src ) Return Bra( t+"!=0" )
  1479. If TWParamType( src ) Return Bra( t+"!=0" )
  1480. If TLParamType( src ) Return Bra( t+"!=0" )
  1481. If TDoubleType( src ) Return Bra( t+"!=0.0f" )
  1482. If TArrayType( src ) Return Bra( t+"!= &bbEmptyArray" )
  1483. If TStringType( src ) Return Bra( t+"!= &bbEmptyString" )
  1484. If TObjectType( src ) Then
  1485. If TObjectType(src).classDecl.IsExtern() Then
  1486. If Not TObjectType(src).classDecl.IsStruct() Then
  1487. Return Bra( t+"!=0" )
  1488. Else
  1489. Return Bra("1")
  1490. End If
  1491. Else
  1492. Return Bra( t+"!= &bbNullObject" )
  1493. End If
  1494. End If
  1495. Else If TIntType( dst )
  1496. If TBoolType( src ) Return Bra( t )
  1497. If TByteType( src) Return Bra("(BBINT)"+t)
  1498. If TShortType( src) Return Bra("(BBINT)"+t)
  1499. If TBoolType( src ) Return t
  1500. If TIntType( src ) Return t
  1501. If TUIntType( src ) Return Bra("(BBINT)"+t)
  1502. If TFloatType( src ) Return Bra("(BBINT)"+t)
  1503. If TDoubleType( src ) Return Bra("(BBINT)"+t)
  1504. If TLongType( src ) Return Bra("(BBINT)"+t)
  1505. If TULongType( src ) Return Bra("(BBINT)"+t)
  1506. If TSizeTType( src ) Return Bra("(BBINT)"+t)
  1507. If TWParamType( src ) Return Bra("(BBINT)"+t)
  1508. If TLParamType( src ) Return Bra("(BBINT)"+t)
  1509. If TStringType( src ) Return "bbStringToInt" + Bra(t)
  1510. 'If TIntVarPtrType( src ) Return Bra("*" + t)
  1511. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBINT)"+t)
  1512. 'If TPointerType( src ) Return Bra("(BBINT)"+t)
  1513. Else If TLongType( dst )
  1514. If TBoolType( src ) Return Bra( t )
  1515. If TByteType( src) Return Bra("(BBLONG)"+t)
  1516. If TShortType( src) Return Bra("(BBLONG)"+t)
  1517. If TIntType( src) Return Bra("(BBLONG)"+t)
  1518. If TUIntType( src) Return Bra("(BBLONG)"+t)
  1519. If TLongType( src ) Return t
  1520. If TULongType( src ) Return Bra("(BBLONG)"+t)
  1521. If TSizeTType( src ) Return Bra("(BBLONG)"+t)
  1522. If TWParamType( src ) Return Bra("(BBLONG)"+t)
  1523. If TLParamType( src ) Return Bra("(BBLONG)"+t)
  1524. If TFloatType( src ) Return Bra("(BBLONG)"+t)
  1525. If TDoubleType( src ) Return Bra("(BBLONG)"+t)
  1526. If TStringType( src ) Return "bbStringToLong" + Bra(t)
  1527. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBLONG)"+t)
  1528. If TFloat64Type( src ) Return Bra("(BBLONG)"+t)
  1529. 'If TPointerType( src ) Return Bra("(BBLONG)"+t)
  1530. Else If TSizeTType( dst )
  1531. If TBoolType( src ) Return Bra( t )
  1532. If TByteType( src) Return Bra("(BBSIZET)"+t)
  1533. If TShortType( src) Return Bra("(BBSIZET)"+t)
  1534. If TIntType( src) Return Bra("(BBSIZET)"+t)
  1535. If TUIntType( src) Return Bra("(BBSIZET)"+t)
  1536. If TLongType( src) Return Bra("(BBSIZET)"+t)
  1537. If TULongType( src) Return Bra("(BBSIZET)"+t)
  1538. If TSizeTType( src ) Return t
  1539. If TWParamType( src ) Return Bra("(BBSIZET)"+t)
  1540. If TLParamType( src ) Return Bra("(BBSIZET)"+t)
  1541. If TFloatType( src ) Return Bra("(BBSIZET)"+t)
  1542. If TDoubleType( src ) Return Bra("(BBSIZET)"+t)
  1543. If TStringType( src ) Return "bbStringToSizet" + Bra(t)
  1544. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBSIZET)"+t)
  1545. If TFloat64Type( src ) Return Bra("(BBSIZET)"+t)
  1546. 'If TPointerType( src ) Return Bra("(BBLONG)"+t)
  1547. Else If TFloatType( dst )
  1548. If TBoolType( src ) Return Bra( t )
  1549. If TByteType( src ) Return Bra("(BBFLOAT)"+t)
  1550. If TIntType( src ) Return Bra("(BBFLOAT)"+t)
  1551. If TUIntType( src ) Return Bra("(BBFLOAT)"+t)
  1552. If TShortType( src ) Return Bra("(BBFLOAT)"+t)
  1553. If TFloatType( src ) Return t
  1554. If TDoubleType( src ) Return Bra("(BBFLOAT)"+t)
  1555. If TLongType( src ) Return Bra("(BBFLOAT)"+t)
  1556. If TULongType( src ) Return Bra("(BBFLOAT)"+t)
  1557. If TSizeTType( src ) Return Bra("(BBFLOAT)"+t)
  1558. If TWParamType( src ) Return Bra("(BBFLOAT)"+t)
  1559. If TLParamType( src ) Return Bra("(BBFLOAT)"+t)
  1560. If TStringType( src ) Return "bbStringToFloat" + Bra(t)
  1561. 'If TFloatVarPtrType( src ) Return Bra("*" + t)
  1562. 'If TPointerType( src ) Return Bra("(BBFLOAT)"+t)
  1563. Else If TDoubleType( dst )
  1564. If TBoolType( src ) Return Bra( t )
  1565. If TByteType( src ) Return Bra("(BBDOUBLE)"+t)
  1566. If TIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1567. If TUIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1568. If TShortType( src ) Return Bra("(BBDOUBLE)"+t)
  1569. If TDoubleType( src ) Return t
  1570. If TFloatType( src ) Return Bra("(BBDOUBLE)"+t)
  1571. If TLongType( src ) Return Bra("(BBDOUBLE)"+t)
  1572. If TULongType( src ) Return Bra("(BBDOUBLE)"+t)
  1573. If TSizeTType( src ) Return Bra("(BBDOUBLE)"+t)
  1574. If TWParamType( src ) Return Bra("(BBDOUBLE)"+t)
  1575. If TLParamType( src ) Return Bra("(BBDOUBLE)"+t)
  1576. If TStringType( src ) Return "bbStringToDouble" + Bra(t)
  1577. 'If TDoubleVarPtrType( src ) Return Bra("*" + t)
  1578. 'If TPointerType( src ) Return Bra("(BBDOUBLE)"+t)
  1579. Else If TStringType( dst )
  1580. If IsPointerType(src, 0, TType.T_POINTER) Return "bbStringFromSizet"+Bra( t )
  1581. If TBoolType( src ) Return "bbStringFromInt"+Bra( t )
  1582. If TByteType( src ) Return "bbStringFromInt"+Bra( t )
  1583. If TShortType( src ) Return "bbStringFromInt"+Bra( t )
  1584. If TIntType( src ) Return "bbStringFromInt"+Bra( t )
  1585. If TUIntType( src ) Return "bbStringFromUInt"+Bra( t )
  1586. If TLongType( src ) Return "bbStringFromLong"+Bra( t )
  1587. If TULongType( src ) Return "bbStringFromULong"+Bra( t )
  1588. If TSizeTType( src ) Return "bbStringFromSizet"+Bra( t )
  1589. If TWParamType( src ) Return "bbStringFromWParam"+Bra( t )
  1590. If TLParamType( src ) Return "bbStringFromLParam"+Bra( t )
  1591. If TFloatType( src ) Return "bbStringFromFloat"+Bra( t )
  1592. If TDoubleType( src ) Return "bbStringFromDouble"+Bra( t )
  1593. If TStringType( src ) Then
  1594. If src._flags & TType.T_CHAR_PTR Then
  1595. Return "bbStringFromCString"+Bra( t )
  1596. End If
  1597. If src._flags & TType.T_SHORT_PTR Then
  1598. Return "bbStringFromWString"+Bra( t )
  1599. End If
  1600. If src._flags & TType.T_VAR Then
  1601. If TSliceExpr( expr.expr ) Then
  1602. Return "&" + Bra(t)
  1603. End If
  1604. Return t
  1605. End If
  1606. Return t
  1607. End If
  1608. 'If TStringVarPtrType( src ) Then
  1609. ' If TSliceExpr( expr.expr ) Then
  1610. ' Return t
  1611. ' End If
  1612. ' Return "*" + t
  1613. 'End If
  1614. 'If TStringCharPtrType( src ) Return "bbStringFromCString"+Bra( t )
  1615. 'Else If TStringVarPtrType( dst )
  1616. 'DebugStop
  1617. Else If TByteType( dst )
  1618. If TBoolType( src ) Return Bra( t )
  1619. If TByteType( src) Return t
  1620. If TShortType( src ) Return Bra("(BBBYTE)"+t)
  1621. If TIntType( src ) Return Bra("(BBBYTE)"+t)
  1622. If TUIntType( src ) Return Bra("(BBBYTE)"+t)
  1623. If TFloatType( src ) Return Bra("(BBBYTE)"+t)
  1624. If TDoubleType( src ) Return Bra("(BBBYTE)"+t)
  1625. If TLongType( src ) Return Bra("(BBBYTE)"+t)
  1626. If TULongType( src ) Return Bra("(BBBYTE)"+t)
  1627. If TSizeTType( src ) Return Bra("(BBBYTE)"+t)
  1628. If TWParamType( src ) Return Bra("(BBBYTE)"+t)
  1629. If TLParamType( src ) Return Bra("(BBBYTE)"+t)
  1630. If TStringType( src ) Return "bbStringToInt" + Bra(t)
  1631. 'If TByteVarPtrType( src ) Return Bra("*" + t)
  1632. Else If TShortType( dst )
  1633. If TBoolType( src ) Return Bra( t )
  1634. If TShortType( src) Return t
  1635. If TByteType( src) Return Bra("(BBSHORT)"+t)
  1636. If TIntType( src ) Return Bra("(BBSHORT)"+t)
  1637. If TUIntType( src ) Return Bra("(BBSHORT)"+t)
  1638. If TFloatType( src ) Return Bra("(BBSHORT)"+t)
  1639. If TDoubleType( src ) Return Bra("(BBSHORT)"+t)
  1640. If TLongType( src ) Return Bra("(BBSHORT)"+t)
  1641. If TULongType( src ) Return Bra("(BBSHORT)"+t)
  1642. If TSizeTType( src ) Return Bra("(BBSHORT)"+t)
  1643. If TWParamType( src ) Return Bra("(BBSHORT)"+t)
  1644. If TLParamType( src ) Return Bra("(BBSHORT)"+t)
  1645. If TStringType( src ) Return "bbStringToInt" + Bra(t)
  1646. 'If TShortVarPtrType( src ) Return Bra("*" + t)
  1647. Else If TUIntType( dst )
  1648. If TBoolType( src ) Return Bra( t )
  1649. If TShortType( src ) Return Bra("(BBUINT)"+t)
  1650. If TByteType( src) Return Bra("(BBUINT)"+t)
  1651. If TIntType( src ) Return Bra("(BBUINT)"+t)
  1652. If TUIntType( src) Return t
  1653. If TFloatType( src ) Return Bra("(BBUINT)"+t)
  1654. If TDoubleType( src ) Return Bra("(BBUINT)"+t)
  1655. If TLongType( src ) Return Bra("(BBUINT)"+t)
  1656. If TULongType( src ) Return Bra("(BBUINT)"+t)
  1657. If TSizeTType( src ) Return Bra("(BBUINT)"+t)
  1658. If TWParamType( src ) Return Bra("(BBUINT)"+t)
  1659. If TLParamType( src ) Return Bra("(BBUINT)"+t)
  1660. If TStringType( src ) Return "bbStringToUInt" + Bra(t)
  1661. Else If TULongType( dst )
  1662. If TBoolType( src ) Return Bra( t )
  1663. If TShortType( src ) Return Bra("(BBULONG)"+t)
  1664. If TByteType( src) Return Bra("(BBULONG)"+t)
  1665. If TIntType( src ) Return Bra("(BBULONG)"+t)
  1666. If TUIntType( src ) Return Bra("(BBULONG)"+t)
  1667. If TFloatType( src ) Return Bra("(BBULONG)"+t)
  1668. If TDoubleType( src ) Return Bra("(BBULONG)"+t)
  1669. If TLongType( src ) Return Bra("(BBULONG)"+t)
  1670. If TULongType( src) Return t
  1671. If TSizeTType( src ) Return Bra("(BBULONG)"+t)
  1672. If TWParamType( src ) Return Bra("(BBULONG)"+t)
  1673. If TLParamType( src ) Return Bra("(BBULONG)"+t)
  1674. If TStringType( src ) Return "bbStringToULong" + Bra(t)
  1675. If TFloat64Type( src ) Return Bra("(BBULONG)"+t)
  1676. Else If TFloat64Type( dst )
  1677. If TFloat64Type( src) Return t
  1678. If TLongType( src ) Return Bra("(BBFLOAT64)"+t)
  1679. If TULongType( src ) Return Bra("(BBFLOAT64)"+t)
  1680. If TSizeTType( src ) Return Bra("(BBFLOAT64)"+t)
  1681. Else If TInt128Type( dst )
  1682. If TInt128Type( src) Return t
  1683. If TFloat128Type( src ) Return Bra("(BBINT128)"+t)
  1684. If TDouble128Type( src ) Return Bra("(BBINT128)"+t)
  1685. Else If TFloat128Type( dst )
  1686. If TFloat128Type( src) Return t
  1687. If TInt128Type( src ) Return Bra("(BBFLOAT128)"+t)
  1688. If TDouble128Type( src ) Return Bra("(BBFLOAT128)"+t)
  1689. Else If TDouble128Type( dst )
  1690. If TDouble128Type( src) Return t
  1691. If TInt128Type( src ) Return Bra("(BBDOUBLE128)"+t)
  1692. If TFloat128Type( src ) Return Bra("(BBDOUBLE128)"+t)
  1693. Else If TWParamType( dst )
  1694. If TBoolType( src ) Return Bra( t )
  1695. If TByteType( src) Return Bra("(WPARAM)"+t)
  1696. If TShortType( src) Return Bra("(WPARAM)"+t)
  1697. If TIntType( src) Return Bra("(WPARAM)"+t)
  1698. If TUIntType( src) Return Bra("(WPARAM)"+t)
  1699. If TLongType( src) Return Bra("(WPARAM)"+t)
  1700. If TULongType( src) Return Bra("(WPARAM)"+t)
  1701. If TSizeTType( src ) Return Bra("(WPARAM)"+t)
  1702. If TWParamType( src ) Return t
  1703. If TLParamType( src ) Return Bra("(WPARAM)"+t)
  1704. If TFloatType( src ) Return Bra("(WPARAM)"+t)
  1705. If TDoubleType( src ) Return Bra("(WPARAM)"+t)
  1706. If TStringType( src ) Return "bbStringToWParam" + Bra(t)
  1707. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(WPARAM)"+t)
  1708. Else If TLParamType( dst )
  1709. If TBoolType( src ) Return Bra( t )
  1710. If TByteType( src) Return Bra("(LPARAM)"+t)
  1711. If TShortType( src) Return Bra("(LPARAM)"+t)
  1712. If TIntType( src) Return Bra("(LPARAM)"+t)
  1713. If TUIntType( src) Return Bra("(LPARAM)"+t)
  1714. If TLongType( src) Return Bra("(LPARAM)"+t)
  1715. If TULongType( src) Return Bra("(LPARAM)"+t)
  1716. If TSizeTType( src ) Return Bra("(LPARAM)"+t)
  1717. If TWParamType( src ) Return Bra("(LPARAM)"+t)
  1718. If TLParamType( src ) Return t
  1719. If TFloatType( src ) Return Bra("(LPARAM)"+t)
  1720. If TDoubleType( src ) Return Bra("(LPARAM)"+t)
  1721. If TStringType( src ) Return "bbStringToLParam" + Bra(t)
  1722. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(LPARAM)"+t)
  1723. Else If TArrayType( dst )
  1724. If TArrayType( src ) Then
  1725. If TObjectType( TArrayType( dst ).elemType ) And TObjectType( TArrayType( dst ).elemType ).classDecl.ident = "Object" Then
  1726. ' if we are casting to Object[], don't actually cast.
  1727. Return Bra(t)
  1728. Else
  1729. Return "bbArrayCastFromObject" + Bra(t + "," + TransArrayType(TArrayType( dst ).elemType))
  1730. End If
  1731. End If
  1732. If TObjectType( src) And (TObjectType( src ).classDecl.ident = "___Array" Or TObjectType( src ).classDecl.ident = "Object") Then
  1733. Return "bbArrayCastFromObject" + Bra(t + "," + TransArrayType(TArrayType( dst ).elemType))
  1734. End If
  1735. Else If TObjectType( dst )
  1736. 'If TArrayType( src ) Return Bra("(BBOBJECT)"+t)
  1737. 'If TStringType( src ) Return Bra("(BBOBJECT)"+t)
  1738. 'If TObjectType( src ) Return t
  1739. If Not TObjectType( dst ).classDecl.IsExtern() Then
  1740. If TNullType( src ) Return "&bbNullObject"
  1741. If TObjectType(dst).classDecl.IsInterface() Then
  1742. Return Bra(Bra(TransObject(TObjectType(dst).classDecl)) + "bbInterfaceDowncast" + Bra(t + ",&" + TObjectType(dst).classDecl.munged + "_ifc"))
  1743. Else
  1744. ' no need to downcast to BBObject, as all objects extend it...
  1745. If TObjectType( dst ).classDecl.ident = "Object" Then
  1746. Return t
  1747. Else
  1748. Return Bra(Bra(TransObject(TObjectType(dst).classDecl)) + "bbObjectDowncast" + Bra(t + ",&" + TObjectType(dst).classDecl.munged))
  1749. End If
  1750. End If
  1751. Else
  1752. If TObjectType( dst ).classDecl.IsInterface() Then
  1753. Return t
  1754. Else
  1755. Return "" ' TODO??
  1756. End If
  1757. End If
  1758. End If
  1759. Return TransPtrCast( dst,src,t,"dynamic" )
  1760. Err "C++ translator can't convert "+src.ToString()+" to "+dst.ToString()
  1761. End Method
  1762. Method TransUnaryExpr$( expr:TUnaryExpr )
  1763. Local pri:Int=ExprPri( expr )
  1764. Local t_expr$
  1765. If TVarExpr(expr.expr) Then
  1766. If TObjectType(TVarExpr(expr.expr).exprType) Then
  1767. t_expr = Bra( expr.expr.Trans() + "!= &bbNullObject")
  1768. Else If TStringType(TVarExpr(expr.expr).exprType) Then
  1769. t_expr = Bra( expr.expr.Trans() + "!= &bbEmptyString")
  1770. Else
  1771. t_expr = TransSubExpr( expr.expr,pri )
  1772. End If
  1773. Else
  1774. t_expr = TransSubExpr( expr.expr,pri )
  1775. End If
  1776. ' TransSubExpr( expr.expr,pri )
  1777. Return TransUnaryOp( expr.op )+t_expr
  1778. End Method
  1779. Method TransBinaryExpr$( expr:TBinaryExpr )
  1780. Local pri:Int=ExprPri( expr )
  1781. _inBinary :+ 1
  1782. Local t_lhs$=TransSubExpr( expr.lhs,pri )
  1783. ' If TVarPtrType(expr.lhs.exprType) Then
  1784. ' t_lhs = "*" + t_lhs
  1785. ' End If
  1786. Local t_rhs$=TransSubExpr( expr.rhs,pri-1 )
  1787. ' If TVarPtrType(expr.rhs.exprType) Then
  1788. ' t_rhs = "*" + t_rhs
  1789. ' End If
  1790. _inBinary :- 1
  1791. If expr.op = "+" Then
  1792. If TStringType(expr.exprType) Then
  1793. Return "bbStringConcat(" + t_lhs + "," + t_rhs + ")"
  1794. Else If TArrayType(expr.exprType) Then
  1795. Return "bbArrayConcat(" + TransArrayType(TArrayType(expr.lhs.exprType).elemType) + "," + t_lhs + "," + t_rhs + ")"
  1796. End If
  1797. End If
  1798. If expr.op = "^" Then
  1799. Return "pow" + Bra(t_lhs + ", " + t_rhs)
  1800. End If
  1801. If expr.op = "mod" Or expr.op = "%" Then
  1802. If TDecimalType(expr.lhs.exprType) Or TDecimalType(expr.rhs.exprType) Then
  1803. Return "fmod" + Bra(t_lhs + ", " + t_rhs)
  1804. End If
  1805. End If
  1806. If (expr.op = "shr" Or expr.op = "&" Or expr.op = "|") And TIntType(expr.exprType) Then
  1807. t_lhs = "(unsigned int)(" + t_lhs + ")"
  1808. End If
  1809. If TBinaryCompareExpr(expr) Then
  1810. If TStringType(TBinaryCompareExpr(expr).ty) Then
  1811. If t_lhs="&bbNullObject" Then
  1812. err "NULL"
  1813. t_lhs = "&bbEmptyString"
  1814. End If
  1815. If t_rhs="&bbNullObject" Then
  1816. err "NULL"
  1817. t_rhs = "&bbEmptyString"
  1818. End If
  1819. If t_lhs <> "&bbEmptyString" And t_rhs <> "&bbEmptyString" Then
  1820. Return "bbStringCompare" + Bra(t_lhs + ", " + t_rhs) + TransBinaryOp(expr.op, "") + "0"
  1821. End If
  1822. End If
  1823. If IsPointerType(TBinaryCompareExpr(expr).ty, 0, TType.T_POINTER) Then
  1824. If t_lhs="&bbNullObject" Then
  1825. t_lhs = "0"
  1826. End If
  1827. If t_rhs="&bbNullObject" Then
  1828. t_rhs = "0"
  1829. End If
  1830. End If
  1831. If TArrayType(TBinaryCompareExpr(expr).ty) Then
  1832. If t_lhs="&bbNullObject" Then
  1833. err "NULL"
  1834. t_lhs = "&bbEmptyArray"
  1835. End If
  1836. If t_rhs="&bbNullObject" Then
  1837. err "NULL"
  1838. t_rhs = "&bbEmptyArray"
  1839. End If
  1840. End If
  1841. End If
  1842. Return bra(t_lhs+TransBinaryOp( expr.op,t_rhs )+t_rhs)
  1843. End Method
  1844. Method TransIndexExpr$( expr:TIndexExpr )
  1845. Local t_expr$=TransSubExpr( expr.expr )
  1846. Local t_index$
  1847. If expr.index.length = 1 Then
  1848. If TArraySizeExpr(expr.index[0]) Then
  1849. Local sizes:TArraySizeExpr = TArraySizeExpr(expr.index[0])
  1850. sizes.Trans()
  1851. Local v:String = sizes.val.munged
  1852. Local i:Int = 0
  1853. For i = 0 Until sizes.index.length - 1
  1854. If i Then
  1855. t_index :+ " + "
  1856. End If
  1857. t_index :+ "(*(" + v
  1858. If i Then
  1859. t_index :+ "+" + i
  1860. End If
  1861. t_index :+ ")) * " + sizes.index[i].Trans()
  1862. Next
  1863. t_index :+ " + " + sizes.index[i].Trans()
  1864. ' (*(v+0)) * var1 + (*(v+1)) * var2 + var3
  1865. 'DebugStop
  1866. Else
  1867. t_index=expr.index[0].Trans()
  1868. End If
  1869. End If
  1870. If TStringType( expr.expr.exprType ) Then
  1871. Return Bra(t_expr) + "->buf[" + t_index + "]"
  1872. 'Return "(BBINT)"+t_expr+"["+t_index+"]"
  1873. End If
  1874. If TArrayType( expr.expr.exprType ) Then
  1875. If TFunctionPtrType(TArrayType( expr.expr.exprType ).elemType) Then
  1876. If opt_debug Then
  1877. Return Bra(Bra(TransType(TArrayType( expr.expr.exprType).elemType, "*")) + Bra("BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")")) + "[" + t_index + "]"
  1878. Else
  1879. Return Bra(Bra(TransType(TArrayType( expr.expr.exprType).elemType, "*")) + Bra("BBARRAYDATA(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims)")) + "[" + t_index + "]"
  1880. End If
  1881. Else
  1882. If opt_debug Then
  1883. Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")") + "[" + t_index + "]"
  1884. Else
  1885. Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATA(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims)") + "[" + t_index + "]"
  1886. End If
  1887. End If
  1888. End If
  1889. 'Local swiz$
  1890. 'If TObjectType( expr.exprType )And expr.exprType.GetClass().IsInterface() swiz=".p"
  1891. 'If ENV_CONFIG="debug" Return t_expr+".At("+t_index+")"+swiz
  1892. Return t_expr+"["+t_index+"]"
  1893. End Method
  1894. Method TransSliceExpr$( expr:TSliceExpr )
  1895. 'DebugStop
  1896. Local t_expr:String=TransSubExpr( expr.expr )
  1897. Local t_args$
  1898. If expr.from Then
  1899. t_args=expr.from.Trans()
  1900. Else
  1901. t_args = "0"
  1902. End If
  1903. If expr.term Then
  1904. t_args:+","+expr.term.Trans()
  1905. Else
  1906. If TArrayType(expr.exprType) Then
  1907. t_args :+ "," + Bra(t_expr) + "->scales[0]"
  1908. 'Else If TStringVarPtrType(expr.exprType) Then
  1909. ' t_args :+ ",(*" + t_expr + ")->length"
  1910. Else
  1911. t_args :+ "," + Bra(t_expr) + "->length"
  1912. End If
  1913. End If
  1914. If TArrayType(expr.exprType) Then
  1915. Return "bbArraySlice" + Bra(TransArrayType(TArrayType(expr.exprType).elemType) + "," + t_expr + "," + t_args)
  1916. 'Else If TStringVarPtrType(expr.exprType) Then
  1917. ' Return "bbStringSlice" + Bra("*" + t_expr + "," + t_args)
  1918. Else
  1919. Return "bbStringSlice" + Bra(t_expr + "," + t_args)
  1920. End If
  1921. 'Return t_expr+".Slice("+t_args+")"
  1922. End Method
  1923. Method TransArrayExpr$( expr:TArrayExpr )
  1924. Local elemType:TType=TArrayType( expr.exprType ).elemType
  1925. Local tmpData:TLocalDecl =New TLocalDecl.Create( "",TType.voidType,Null )
  1926. MungDecl tmpData
  1927. Local tmpArray:TLocalDecl =New TLocalDecl.Create( "",TType.voidType,Null )
  1928. MungDecl tmpArray
  1929. Local t$
  1930. Local count:Int
  1931. For Local elem:TExpr=EachIn expr.exprs
  1932. If t t:+","
  1933. t:+elem.Trans()
  1934. count :+ 1
  1935. Next
  1936. Local tt$
  1937. ' If Not _env tt="static "
  1938. If Not TFunctionPtrType(elemType) Then
  1939. tt :+ TransType( elemType, tmpData.munged ) + " "+tmpData.munged + "[]"
  1940. Else
  1941. tt :+ TransType( elemType, tmpData.munged + "[]" )
  1942. End If
  1943. Emit tt+"={"+t+"};"
  1944. Emit "BBARRAY " + tmpArray.munged + " = bbArrayFromData" + Bra(TransArrayType(elemType) + "," + count + "," + tmpData.munged ) + ";"
  1945. Return tmpArray.munged
  1946. 'Return "bbArrayFromData" + Bra(TransArrayType(elemType) + "," + count + "," + tmp.munged )
  1947. 'Return "Array<"+TransRefType( elemType, "MM" )+" >("+tmp.munged+","+expr.exprs.Length+")"
  1948. End Method
  1949. Method TransArraySizeExpr$ ( expr:TArraySizeExpr )
  1950. ' scales[0] is the total size of the array
  1951. ' we start from [1] because it is the size of the next full dimension.
  1952. ' in the case of a 2-dimensional array, [1] represents the length of a row.
  1953. Return Bra("(BBARRAY)" + expr.expr.Trans()) + "->scales + 1"
  1954. End Method
  1955. Method TransIntrinsicExpr$( decl:TDecl,expr:TExpr,args:TExpr[] )
  1956. Local texpr$,arg0$,arg1$,arg2$
  1957. If expr texpr=TransSubExpr( expr )
  1958. If args.Length>0 And args[0] arg0=args[0].Trans()
  1959. If args.Length>1 And args[1] arg1=args[1].Trans()
  1960. If args.Length>2 And args[2] arg2=args[2].Trans()
  1961. Local id$=decl.munged[1..]
  1962. Local id2$=id[..1].ToUpper()+id[1..]
  1963. Select id
  1964. '
  1965. 'global functions
  1966. Case "print" Return "Print"+Bra( arg0 )
  1967. Case "error" Return "Error"+Bra( arg0 )
  1968. '
  1969. 'string/array methods
  1970. Case "length" Return texpr+".Length()"
  1971. Case "resize" Return texpr+".Resize"+Bra( arg0 )
  1972. 'string methods
  1973. Case "compare" Return texpr+".Compare"+Bra( arg0 )
  1974. Case "find" Return texpr+".Find"+Bra( arg0+","+arg1 )
  1975. Case "findlast" Return texpr+".FindLast"+Bra( arg0 )
  1976. Case "findlast2" Return texpr+".FindLast"+Bra( arg0+","+arg1 )
  1977. Case "trim" Return texpr+".Trim()"
  1978. Case "join" Return texpr+".Join"+Bra( arg0 )
  1979. Case "split" Return texpr+".Split"+Bra( arg0 )
  1980. Case "replace" Return texpr+".Replace"+Bra( arg0+","+arg1 )
  1981. Case "tolower" Return texpr+".ToLower()"
  1982. Case "toupper" Return texpr+".ToUpper()"
  1983. Case "contains" Return texpr+".Contains"+Bra( arg0 )
  1984. Case "startswith" Return texpr+".StartsWith"+Bra( arg0 )
  1985. Case "endswith" Return texpr+".EndsWith"+Bra( arg0 )
  1986. 'string functions
  1987. Case "fromchar" Return "String"+Bra( "(Char)"+Bra(arg0)+",1" )
  1988. 'math methods
  1989. Case "sin","cos","tan" Return "(float)"+id+Bra( Bra(arg0)+"*D2R" )
  1990. Case "asin","acos","atan" Return "(float)"+Bra( id+Bra(arg0)+"*R2D" )
  1991. Case "atan2" Return "(float)"+Bra( id+Bra(arg0+","+arg1)+"*R2D" )
  1992. Case "sqrt","floor","ceil","log" Return "(float)"+id+Bra( arg0 )
  1993. Case "pow" Return "(float)"+id+Bra( arg0+","+arg1 )
  1994. '
  1995. End Select
  1996. InternalErr
  1997. End Method
  1998. '***** Statements *****
  1999. Method TransTryStmt$( stmt:TTryStmt )
  2000. Emit "do {"
  2001. EmitLocalDeclarations(stmt.block)
  2002. Emit "jmp_buf * buf = bbExEnter();"
  2003. Emit "switch(setjmp(*buf)) {"
  2004. Emit "case 0: {"
  2005. If opt_debug Then
  2006. Emit "bbOnDebugPushExState();"
  2007. End If
  2008. PushLoopTryStack(stmt)
  2009. tryStack.Push(stmt.block)
  2010. EmitBlock( stmt.block )
  2011. tryStack.Pop()
  2012. PopLoopTryStack
  2013. Emit "bbExLeave();"
  2014. If opt_debug Then
  2015. Emit "bbOnDebugPopExState();"
  2016. End If
  2017. Emit "}"
  2018. Emit "break;"
  2019. Emit "case 1:"
  2020. Emit "{"
  2021. If opt_debug Then
  2022. Emit "bbOnDebugPopExState();"
  2023. End If
  2024. Emit "BBOBJECT ex = bbExObject();"
  2025. Local s:String = ""
  2026. For Local c:TCatchStmt=EachIn stmt.catches
  2027. MungDecl c.init
  2028. If TStringType(c.init.ty) Then
  2029. Emit s + "if (bbObjectDowncast(ex,&bbStringClass) != &bbEmptyString) {"
  2030. Emit TransType( c.init.ty, c.init.munged )+" "+ c.init.munged + "=(BBSTRING)ex;"
  2031. Else If TArrayType(c.init.ty) Then
  2032. Emit s + "if (bbObjectDowncast(ex,&bbArrayClass) != &bbEmptyArray) {"
  2033. Emit TransType( c.init.ty, c.init.munged )+" "+ c.init.munged + "=(BBARRAY)ex;"
  2034. Else If TObjectType(c.init.ty) Then
  2035. Emit s + "if (bbObjectDowncast(ex,&"+TObjectType(c.init.ty).classDecl.munged+") != &bbNullObject) {"
  2036. Emit TransType( c.init.ty, c.init.munged )+" "+ c.init.munged + "=" + Bra(TransType( c.init.ty, c.init.munged )) + "ex;"
  2037. Else
  2038. Err "Not an object"
  2039. End If
  2040. EmitLocalDeclarations(c.block, c.init)
  2041. EmitBlock( c.block )
  2042. s = "} else "
  2043. Next
  2044. If s Then
  2045. Emit s + " {"
  2046. ' unhandled exception
  2047. Emit "bbExThrow(ex);"
  2048. Emit "}"
  2049. Else
  2050. ' unhandled exception
  2051. Emit "bbExThrow(ex);"
  2052. End If
  2053. Emit "}"
  2054. Emit "break;"
  2055. Emit "}"
  2056. Emit "} while(0);"
  2057. End Method
  2058. Method EmitTryStack()
  2059. For Local i:Int = 0 Until tryStack.Length()
  2060. Emit "bbExLeave();"
  2061. If opt_debug Then
  2062. Emit "bbOnDebugPopExState();"
  2063. End If
  2064. Next
  2065. End Method
  2066. Method EmitLocalScopeStack()
  2067. For Local i:Int = 0 Until localScope.Length()
  2068. Emit "// TODO"
  2069. Next
  2070. End Method
  2071. Method EmitDebugEnterScope(block:TBlockDecl)
  2072. Local count:Int
  2073. For Local decl:TDecl = EachIn block.Decls()
  2074. If TLocalDecl(decl) Then
  2075. count :+ 1
  2076. End If
  2077. If TConstDecl(decl) Then
  2078. count :+ 1
  2079. End If
  2080. If TGlobalDecl(decl) Then
  2081. count :+ 1
  2082. End If
  2083. Next
  2084. ' a method also includes "Self" reference back to parent Type
  2085. If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
  2086. count :+ 1
  2087. End If
  2088. If _app.mainFunc = block Then
  2089. For Local decl:TDecl = EachIn _app.mainModule.Decls()
  2090. If TConstDecl(decl) Then
  2091. count :+ 1
  2092. End If
  2093. If TGlobalDecl(decl) Then
  2094. count :+ 1
  2095. End If
  2096. Next
  2097. End If
  2098. If Not count Then
  2099. Emit "struct BBDebugScope __scope = {"
  2100. Else
  2101. Emit "struct BBDebugScope_" + count + " __scope = {"
  2102. _app.scopeDefs.Insert(String(count), "")
  2103. End If
  2104. If TFuncDecl(block) Then
  2105. Emit "BBDEBUGSCOPE_FUNCTION,"
  2106. If _app.mainFunc = block Then
  2107. ' use the filename as the base function name
  2108. Emit Enquote(StripExt(StripDir(_app.mainModule.filepath))) + ","
  2109. Else
  2110. Emit Enquote(TFuncDecl(block).ident) + ","
  2111. End If
  2112. Else
  2113. Emit "BBDEBUGSCOPE_LOCALBLOCK,"
  2114. Emit "0,"
  2115. End If
  2116. Emit "{"
  2117. If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
  2118. Emit "{"
  2119. Emit "BBDEBUGDECL_LOCAL,"
  2120. Emit "~qSelf~q,"
  2121. Emit Enquote(TransDebugScopeType(TClassDecl(block.scope).objectType)) + ","
  2122. Emit ".var_address=&o"
  2123. Emit "},"
  2124. End If
  2125. ' block consts and globals
  2126. ' consts
  2127. For Local cdecl:TConstDecl = EachIn block.Decls()
  2128. EmitConstDebugScope(cdecl)
  2129. Next
  2130. ' globals
  2131. For Local gdecl:TGlobalDecl = EachIn block.Decls()
  2132. EmitGlobalDebugScope(gdecl)
  2133. Next
  2134. ' iterate through decls and add as appropriate
  2135. For Local decl:TDecl = EachIn block.Decls()
  2136. Local ldecl:TLocalDecl = TLocalDecl(decl)
  2137. If ldecl Then
  2138. Emit "{"
  2139. If ldecl.ty._flags & TType.T_VAR Then
  2140. Emit "BBDEBUGDECL_VARPARAM,"
  2141. Else
  2142. Emit "BBDEBUGDECL_LOCAL,"
  2143. End If
  2144. Emit Enquote(ldecl.ident) + ","
  2145. Emit Enquote(TransDebugScopeType(ldecl.ty)) + ","
  2146. Emit ".var_address=&" + ldecl.munged
  2147. Emit "},"
  2148. Continue
  2149. End If
  2150. Next
  2151. ' add module consts and globals
  2152. If _app.mainFunc = block Then
  2153. ' consts
  2154. For Local cdecl:TConstDecl = EachIn _app.mainModule.Decls()
  2155. EmitConstDebugScope(cdecl)
  2156. Next
  2157. ' globals
  2158. For Local gdecl:TGlobalDecl = EachIn _app.mainModule.Decls()
  2159. EmitGlobalDebugScope(gdecl)
  2160. Next
  2161. End If
  2162. Emit "BBDEBUGDECL_END "
  2163. Emit "}"
  2164. Emit "};"
  2165. Emit "bbOnDebugEnterScope(&__scope);"
  2166. End Method
  2167. Method EmitDebugNullObjectError(variable:String)
  2168. ' FIXME : for now we don't generate this in a binary expression, because the test may not be required depending on context
  2169. If Not _inBinary Then
  2170. Emit "if (" + variable + " == &bbNullObject) brl_blitz_NullObjectError();"
  2171. End If
  2172. End Method
  2173. Method TransAssignStmt$( stmt:TAssignStmt )
  2174. If Not stmt.rhs Return stmt.lhs.Trans()
  2175. Local rhs$=stmt.rhs.Trans()
  2176. Local lhs$=stmt.lhs.TransVar()
  2177. Local s:String
  2178. If IsPointerType(stmt.lhs.exprType, TType.T_BYTE) And rhs = "&bbNullObject" Then
  2179. rhs = "0"
  2180. End If
  2181. If stmt.op = ":%" Then
  2182. If TDecimalType(stmt.lhs.exprType) Or TDecimalType(stmt.rhs.exprType) Then
  2183. Return lhs + "=fmod" + Bra(lhs + "," + rhs)
  2184. End If
  2185. End If
  2186. If TStringType(stmt.lhs.exprType) 'Or TStringVarPtrType(stmt.lhs.exprType) Then
  2187. ' s:+ "{"
  2188. ' s:+ "BBSTRING tmp=" + lhs + ";~n"
  2189. If stmt.op = ":+" Then
  2190. s :+ lhs+"=bbStringConcat("+lhs+","+rhs+")"
  2191. Else If rhs = "&bbNullObject" Then
  2192. s :+ lhs+TransAssignOp( stmt.op )+"&bbEmptyString"
  2193. Else
  2194. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2195. End If
  2196. ' s :+ ";~nBBRETAIN(" + lhs +")~n"
  2197. ' s :+ "BBRELEASE(tmp)~n"
  2198. ' s:+ "}"
  2199. Else If TVarPtrType(stmt.lhs.exprType) Then
  2200. If TCastExpr(stmt.rhs) And IsNumericType(TCastExpr(stmt.rhs).expr.exprType) Then
  2201. rhs = TCastExpr(stmt.rhs).expr.Trans()
  2202. End If
  2203. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2204. Else If TArrayType(stmt.lhs.exprType) Then
  2205. If stmt.op = ":+" Then
  2206. s :+ lhs+"=bbArrayConcat("+ TransArrayType(TArrayType(stmt.lhs.exprType).elemType) + "," + lhs+","+rhs+")"
  2207. Else If rhs = "&bbNullObject" Then
  2208. s :+ lhs+TransAssignOp( stmt.op )+"&bbEmptyArray"
  2209. Else
  2210. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2211. End If
  2212. Else If (TFunctionPtrType(stmt.lhs.exprType) <> Null Or IsPointerType(stmt.lhs.exprType, TType.T_BYTE)) And TInvokeExpr(stmt.rhs) And Not TInvokeExpr(stmt.rhs).invokedWithBraces Then
  2213. rhs = TInvokeExpr(stmt.rhs).decl.munged
  2214. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2215. Else
  2216. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2217. End If
  2218. If DEBUG Then
  2219. DebugObject(stmt.lhs.exprType, lhs, Null, True)
  2220. End If
  2221. Return s
  2222. End Method
  2223. Method TransThrowStmt:String( stmt:TThrowStmt )
  2224. Local s:String = "bbExThrow("
  2225. s:+ stmt.expr.Trans()
  2226. s :+ ")"
  2227. Return s
  2228. End Method
  2229. Method TransAssertStmt$( stmt:TAssertStmt )
  2230. If opt_debug Then
  2231. Emit "if (!" + Bra(stmt.expr.Trans()) + ") {"
  2232. Emit "brl_blitz_RuntimeError(" + stmt.elseExpr.Trans() + ");"
  2233. Emit "}"
  2234. End If
  2235. End Method
  2236. Method TransEndStmt$( stmt:TEndStmt )
  2237. Emit "bbEnd();"
  2238. End Method
  2239. Method TransReleaseStmt$( stmt:TReleaseStmt )
  2240. Emit "bbHandleRelease" + Bra(stmt.expr.Trans()) + ";"
  2241. End Method
  2242. Method TransRestoreDataStmt$( stmt:TRestoreDataStmt )
  2243. Emit "_defDataOffset = &_defData[" + TDataLabelExpr(stmt.expr).dataDef.label.index + "];"
  2244. End Method
  2245. Method TransReadDataStmt$( stmt:TReadDataStmt )
  2246. For Local expr:TExpr = EachIn stmt.args
  2247. ' buffer overflow test
  2248. If opt_debug Then
  2249. Emit "if (_defDataOffset - _defData >= " + TDefDataDecl.count + ") brl_blitz_OutOfDataError();"
  2250. End If
  2251. Emit expr.Trans() + " = " + TransDefDataConversion(expr.exprType) + Bra("_defDataOffset++") + ";"
  2252. Next
  2253. End Method
  2254. Method TransNativeStmt$( stmt:TNativeStmt)
  2255. Emit stmt.raw
  2256. End Method
  2257. Method TransFullName:String(decl:TDecl)
  2258. Local s:String
  2259. If decl.scope Then
  2260. s:+ TransFullName(decl.scope)
  2261. End If
  2262. If s Then
  2263. s :+ " : "
  2264. End If
  2265. If TModuleDecl(decl) Then
  2266. s:+ decl.ModuleScope().munged
  2267. Else
  2268. s :+ decl.ident
  2269. End If
  2270. If TFuncDecl(decl) Then
  2271. s:+ "()"
  2272. End If
  2273. Return s
  2274. End Method
  2275. Method ClassHasObjectField:Int(classDecl:TClassDecl)
  2276. If classDecl.superClass Then
  2277. If ClassHasObjectField(classDecl.superClass) Then
  2278. Return True
  2279. End If
  2280. End If
  2281. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2282. If Not decl.IsSemanted() Then
  2283. decl.Semant()
  2284. End If
  2285. If TStringType(decl.ty) Or TArrayType(decl.ty) Or (TObjectType(decl.ty) And Not TObjectType(decl.ty).classDecl.IsStruct()) Then
  2286. Return True
  2287. End If
  2288. Next
  2289. Return False
  2290. End Method
  2291. '***** Declarations *****
  2292. Rem
  2293. Method EmitFuncProto( decl:TFuncDecl )
  2294. PushMungScope
  2295. decl.Semant
  2296. MungDecl decl
  2297. 'Find decl we override
  2298. Local odecl:TFuncDecl=decl
  2299. While odecl.overrides
  2300. odecl=odecl.overrides
  2301. Wend
  2302. Local args$
  2303. For Local arg:TArgDecl=EachIn odecl.argDecls
  2304. If args args:+","
  2305. args:+TransType( arg.ty )
  2306. Next
  2307. Local t$=TransType( odecl.retType )+" "+decl.munged+Bra( args )
  2308. If decl.IsAbstract() t:+"=0"
  2309. Local q$
  2310. If decl.IsExtern() q:+"extern "
  2311. If decl.IsMethod() q:+"virtual "
  2312. If decl.IsStatic() And decl.ClassScope() q:+"static "
  2313. Emit q+t+";"
  2314. PopMungScope
  2315. End Method
  2316. End Rem
  2317. Method EmitBBClassFuncProto( decl:TFuncDecl)
  2318. 'PushMungScope
  2319. BeginLocalScope
  2320. 'DebugStop
  2321. ' decl.Semant
  2322. ' MungDecl decl
  2323. 'Find decl we override
  2324. Local odecl:TFuncDecl=decl
  2325. 'If odecl.overrides And Not odecl.returnTypeSubclassed Then Return
  2326. 'DebugLog decl.ident
  2327. ' While odecl.overrides
  2328. ' odecl=odecl.overrides
  2329. ' Wend
  2330. Local id$=decl.munged
  2331. Local pre:String
  2332. If decl.IsMethod() Then
  2333. id :+ "_m"
  2334. pre = "m_"
  2335. Else
  2336. id :+ "_f"
  2337. pre = "f_"
  2338. End If
  2339. Local bk:String = ";"
  2340. 'Local pre:String = "typedef "
  2341. 'If odecl.IsExtern() Then
  2342. ' pre = "extern "
  2343. 'End If
  2344. 'DebugLog "id = " + id
  2345. Emit id + " " + pre + FuncDeclMangleIdent(odecl) + ";"
  2346. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  2347. Rem
  2348. If Not TFunctionPtrType(odecl.retType) Then
  2349. If Not odecl.castTo Then
  2350. Emit pre + TransType( odecl.retType, "" )+" "+ Bra("*" + id)+Bra( args ) + bk
  2351. Else
  2352. If Not odecl.noCastGen Then
  2353. Emit pre + odecl.castTo +" "+Bra("*" + id)+Bra( args ) + bk
  2354. End If
  2355. End If
  2356. Else
  2357. If Not odecl.castTo Then
  2358. Emit pre + TransType( odecl.retType, id )+" "+Bra( args ) + bk
  2359. Else
  2360. If Not odecl.noCastGen Then
  2361. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  2362. End If
  2363. End If
  2364. End If
  2365. For Local t$=EachIn argCasts
  2366. Emit t
  2367. Next
  2368. ' End If
  2369. End Rem
  2370. 'PopMungScope
  2371. EndLocalScope
  2372. End Method
  2373. Method FuncDeclMangleIdent:String(fdecl:TFuncDecl)
  2374. If (Not fdecl.ClassScope()) Or (equalsBuiltInFunc(fdecl.classScope(), fdecl)) Then
  2375. Return fdecl.ident
  2376. End If
  2377. If Not fdecl.mangled Then
  2378. Local id:String = fdecl.ident
  2379. If fdecl.attrs & FUNC_OPERATOR Then
  2380. id = MungSymbol(id)
  2381. End If
  2382. fdecl.mangled = id + MangleMethod(fdecl)
  2383. End If
  2384. Return fdecl.mangled
  2385. ' If fdecl.olIndex Then
  2386. ' Return fdecl.ident + fdecl.olIndex
  2387. ' Else
  2388. ' Return fdecl.ident
  2389. ' End If
  2390. End Method
  2391. Method EmitClassFuncProto( decl:TFuncDecl, isStruct:Int = False)
  2392. 'PushMungScope
  2393. BeginLocalScope
  2394. decl.Semant
  2395. MungDecl decl
  2396. 'Find decl we override
  2397. Local odecl:TFuncDecl=decl
  2398. ' If odecl.overrides Then Return
  2399. While odecl.overrides
  2400. odecl=odecl.overrides
  2401. Wend
  2402. 'Generate 'args' string and arg casts
  2403. Local args$
  2404. ' pass object for method
  2405. If decl.IsMethod() Then
  2406. args :+ TransObject(decl.scope, True)
  2407. End If
  2408. Local argCasts:TStack =New TStack
  2409. For Local i:Int=0 Until decl.argDecls.Length
  2410. Local arg:TArgDecl=decl.argDecls[i]
  2411. Local oarg:TArgDecl=odecl.argDecls[i]
  2412. MungDecl arg
  2413. If args args:+","
  2414. If Not TFunctionPtrType(oarg.ty) Then
  2415. If Not odecl.castTo Then
  2416. args:+TransType( oarg.ty, arg.munged )
  2417. Else
  2418. args:+ oarg.castTo + " " + arg.munged
  2419. End If
  2420. Else
  2421. If Not odecl.castTo Then
  2422. args:+TransType( oarg.ty, arg.munged )
  2423. Else
  2424. args:+ oarg.castTo
  2425. End If
  2426. End If
  2427. If arg.ty.EqualsType( oarg.ty ) Continue
  2428. Local t$=arg.munged
  2429. arg.munged=""
  2430. MungDecl arg
  2431. argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
  2432. Next
  2433. Local id$=decl.munged
  2434. Local bk:String = ";"
  2435. Local pre:String = "typedef "
  2436. Local api:String
  2437. If decl.IsMethod() Then
  2438. id :+ "_m"
  2439. Else
  2440. id :+ "_f"
  2441. End If
  2442. If decl.attrs & DECL_API_WIN32 Then
  2443. api = " __stdcall "
  2444. End If
  2445. 'If odecl.IsExtern() Then
  2446. ' pre = "extern "
  2447. 'End If
  2448. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  2449. If Not TFunctionPtrType(decl.retType) Then
  2450. If Not odecl.castTo Then
  2451. If Not isStruct Then
  2452. If Not decl.overrides Or decl.returnTypeSubclassed Then
  2453. Emit pre + TransType( decl.retType, "" )+" "+ Bra(api + "*" + id)+Bra( args ) + bk
  2454. End If
  2455. End If
  2456. If decl.IsMethod() Then
  2457. Emit TransType(decl.retType, "") + " _" + decl.munged +Bra( args ) + bk
  2458. Else
  2459. Emit TransType(decl.retType, "") + api + " " + decl.munged +Bra( args ) + bk
  2460. End If
  2461. Else
  2462. If Not odecl.noCastGen Then
  2463. If Not isStruct Then
  2464. If Not decl.overrides Or decl.returnTypeSubclassed Then
  2465. Emit pre + odecl.castTo +" "+Bra(api + "*" + id)+Bra( args ) + bk
  2466. End If
  2467. End If
  2468. If decl.IsMethod() Then
  2469. Emit odecl.castTo + " _" + decl.munged +Bra( args ) + bk
  2470. Else
  2471. Emit odecl.castTo + " " + decl.munged +Bra( args ) + bk
  2472. End If
  2473. End If
  2474. End If
  2475. Else
  2476. If Not odecl.castTo Then
  2477. If Not args Then
  2478. ' for function pointer return type, we need to generate () regardless of whether there are
  2479. ' args or not.
  2480. args = " "
  2481. End If
  2482. ' emit function ptr typedef
  2483. Emit pre + TransType( decl.retType, id + "x") + bk
  2484. ' emit actual typedef (with return type of above typedef)
  2485. Emit pre + TransType( decl.retType, id, args, True ) + bk
  2486. Else
  2487. If Not odecl.noCastGen Then
  2488. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  2489. End If
  2490. End If
  2491. End If
  2492. For Local t$=EachIn argCasts
  2493. Emit t
  2494. Next
  2495. ' End If
  2496. 'PopMungScope
  2497. EndLocalScope
  2498. End Method
  2499. Method EmitFuncDecl( decl:TFuncDecl, proto:Int = False, classFunc:Int = False )
  2500. 'If Not proto And decl.IsAbstract() Return
  2501. Local tmpDebug:Int = opt_debug
  2502. If decl.isNoDebug() Then
  2503. opt_debug = False
  2504. End If
  2505. 'PushMungScope
  2506. BeginLocalScope
  2507. 'DebugStop
  2508. decl.Semant
  2509. MungDecl decl
  2510. ' emit nested functions
  2511. If Not proto Then
  2512. ' emit nested protos
  2513. For Local fdecl:TFuncDecl = EachIn decl._decls
  2514. EmitFuncDecl(fdecl, True, classFunc)
  2515. Next
  2516. ' emit nested bodies
  2517. For Local fdecl:TFuncDecl = EachIn decl._decls
  2518. EmitFuncDecl(fdecl, proto, classFunc)
  2519. Next
  2520. End If
  2521. 'Find decl we override
  2522. Local odecl:TFuncDecl=decl
  2523. While odecl.overrides
  2524. odecl=odecl.overrides
  2525. Wend
  2526. 'Generate 'args' string and arg casts
  2527. Local args$
  2528. ' pass object for method
  2529. If decl.IsMethod() Then
  2530. args :+ TransObject(decl.scope, True) + " o"
  2531. End If
  2532. Local argCasts:TStack =New TStack
  2533. For Local i:Int=0 Until decl.argDecls.Length
  2534. Local arg:TArgDecl=decl.argDecls[i]
  2535. Local oarg:TArgDecl=odecl.argDecls[i]
  2536. MungDecl arg, True
  2537. If args args:+","
  2538. If Not TFunctionPtrType(oarg.ty) Then
  2539. If Not odecl.castTo Then
  2540. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  2541. Else
  2542. args:+ oarg.castTo + " " + arg.munged
  2543. End If
  2544. Else
  2545. If Not odecl.castTo Then
  2546. args:+TransType( oarg.ty, arg.munged )
  2547. Else
  2548. args:+ oarg.castTo
  2549. End If
  2550. End If
  2551. If arg.ty.EqualsType( oarg.ty ) Continue
  2552. Local t$=arg.munged
  2553. arg.munged=""
  2554. MungDecl arg
  2555. argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
  2556. Next
  2557. Local id$=decl.munged
  2558. If classFunc Then
  2559. If decl.IsMethod() Then
  2560. id = "_" + id
  2561. End If
  2562. Else
  2563. If Not odecl.IsExtern() Then
  2564. id = id
  2565. End If
  2566. End If
  2567. Local bk:String = "{"
  2568. Local pre:String
  2569. Local api:String
  2570. If proto Then
  2571. If odecl.IsExtern() Then
  2572. pre = "extern "
  2573. If TFunctionPtrType(decl.retType) Then
  2574. pre = ""
  2575. End If
  2576. End If
  2577. bk = ";"
  2578. End If
  2579. If decl.attrs & DECL_API_WIN32 Then
  2580. api = " __stdcall "
  2581. End If
  2582. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  2583. If Not IsStandardFunc(decl.munged) Then
  2584. If Not TFunctionPtrType(odecl.retType) Then
  2585. If Not odecl.castTo Then
  2586. Emit pre + TransType( decl.retType, "" )+ api + " "+id+Bra( args ) + bk
  2587. Else
  2588. If Not odecl.noCastGen Then
  2589. Emit pre + odecl.castTo + api + " "+id+Bra( args ) + bk
  2590. End If
  2591. End If
  2592. Else
  2593. If Not odecl.castTo Then
  2594. If Not args Then
  2595. ' for function pointer return type, we need to generate () regardless of whether there are
  2596. ' args or not.
  2597. args = " "
  2598. End If
  2599. Emit pre + TransType( decl.retType, id, args )+ bk
  2600. Else
  2601. If Not odecl.noCastGen Then
  2602. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  2603. End If
  2604. End If
  2605. End If
  2606. For Local t$=EachIn argCasts
  2607. Emit t
  2608. Next
  2609. End If
  2610. If Not proto Then
  2611. If PROFILER Then
  2612. DebugPrint("", TransFullName(decl))
  2613. End If
  2614. If DEBUG Then
  2615. For Local i:Int=0 Until decl.argDecls.Length
  2616. Local arg:TArgDecl=decl.argDecls[i]
  2617. DebugObject(arg.ty, arg.munged, id)
  2618. Next
  2619. End If
  2620. If decl.IsAbstract() Then
  2621. ' TODO : remove following line when generation stablises.
  2622. Emit "printf(~qAbstract method called : " + decl.ident + "\n~q);fflush(stdout);"
  2623. Emit "brl_blitz_NullMethodError();"
  2624. Else
  2625. decl.Semant()
  2626. If opt_debug And decl.IsMethod() Then
  2627. EmitDebugNullObjectError("o")
  2628. End If
  2629. EmitLocalDeclarations(decl)
  2630. EmitBlock decl
  2631. End If
  2632. Emit "}"
  2633. End If
  2634. ' reset label ids
  2635. contLabelId = 0
  2636. exitLabelId = 0
  2637. EndLocalScope
  2638. 'PopMungScope
  2639. opt_debug = tmpDebug
  2640. End Method
  2641. Method EmitLocalDeclarations(decl:TScopeDecl, ignoreVar:TValDecl = Null)
  2642. If opt_debug Then
  2643. For Local ldecl:TLocalDecl = EachIn decl.Decls()
  2644. If ldecl <> ignoreVar Then
  2645. If Not TArgDecl(ldecl) And Not ldecl.generated Then
  2646. MungDecl ldecl
  2647. Local ty:TType = ldecl.ty
  2648. Local t:String = TransLocalDeclNoInit(ldecl)
  2649. ' If TObjectType( ty ) And TObjectType( ty ).classDecl.IsStruct() Then
  2650. ' t :+ "={}"
  2651. ' End If
  2652. Emit t + ";"
  2653. End If
  2654. End If
  2655. Next
  2656. End If
  2657. End Method
  2658. Method EmitClassFieldsProto(classDecl:TClassDecl)
  2659. If classDecl.superClass Then
  2660. EmitClassFieldsProto(classDecl.superClass)
  2661. End If
  2662. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2663. decl.Semant()
  2664. If Not TFunctionPtrType(decl.ty) Then
  2665. If classDecl.IsExtern() Then
  2666. Emit TransType(decl.ty, "") + " " + decl.ident + ";"
  2667. Else
  2668. Emit TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower() + ";"
  2669. End If
  2670. Else
  2671. If classDecl.IsExtern() Then
  2672. Emit TransType(decl.ty, decl.ident) + ";"
  2673. Else
  2674. Emit TransType(decl.ty, "_" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower()) + ";"
  2675. End If
  2676. End If
  2677. Next
  2678. End Method
  2679. Method EmitClassGlobalsProto(classDecl:TClassDecl)
  2680. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  2681. decl.Semant()
  2682. If TFunctionPtrType(decl.ty) Then
  2683. Emit TransRefType( decl.ty, decl.munged ) + ";"
  2684. Else
  2685. Emit "extern "+TransRefType( decl.ty, "" )+" "+ decl.munged+";"
  2686. End If
  2687. Next
  2688. End Method
  2689. Method BBClassClassFuncProtoBuildList( classDecl:TClassDecl, list:TList )
  2690. 'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  2691. If classDecl.superClass Then
  2692. BBClassClassFuncProtoBuildList(classDecl.superClass, list)
  2693. End If
  2694. For Local idecl:TClassDecl = EachIn classDecl.implmentsAll
  2695. BBClassClassFuncProtoBuildList(idecl, list)
  2696. Next
  2697. For Local decl:TDecl=EachIn classDecl.Decls()
  2698. Local fdecl:TFuncDecl =TFuncDecl( decl )
  2699. If fdecl
  2700. If Not fdecl.IsSemanted()
  2701. fdecl.Semant()
  2702. End If
  2703. If Not equalsBuiltInFunc(classDecl, fdecl) And Not equalsTorFunc(classDecl, fdecl) Then
  2704. Local ignore:Int
  2705. Local link:TLink=list._head._succ
  2706. While link<>list._head
  2707. Local ofdecl:TFuncDecl = TFuncDecl(link._value)
  2708. If fdecl.ident = ofdecl.ident And fdecl.EqualsArgs(ofdecl) Then
  2709. If fdecl.overrides Then
  2710. If fdecl.returnTypeSubclassed Then
  2711. link._value = fdecl
  2712. End If
  2713. ignore = True
  2714. Exit
  2715. End If
  2716. If TFuncDecl(link._value).IsMethod() Then
  2717. ignore = True
  2718. End If
  2719. EndIf
  2720. link = link._succ
  2721. Wend
  2722. If Not ignore Then
  2723. list.AddLast(fdecl)
  2724. End If
  2725. Continue
  2726. End If
  2727. EndIf
  2728. Next
  2729. End Method
  2730. Method EmitBBClassClassFuncProto( classDecl:TClassDecl )
  2731. Local list:TList = New TList
  2732. BBClassClassFuncProtoBuildList(classDecl, list)
  2733. For Local fdecl:TFuncDecl = EachIn list
  2734. EmitBBClassFuncProto( fdecl )
  2735. Next
  2736. End Method
  2737. Method EmitClassProto( classDecl:TClassDecl )
  2738. Local classid$=classDecl.munged
  2739. Local superid$
  2740. If classDecl.superClass Then
  2741. superid=classDecl.superClass.actual.munged
  2742. End If
  2743. 'Emit "void _" + classid + "_New" + Bra(TransObject(classdecl) + " o") + ";"
  2744. EmitClassDeclNewListProto(classDecl)
  2745. If classHierarchyHasFunction(classDecl, "Delete") Then
  2746. Emit "void _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + ";"
  2747. End If
  2748. If classHasFunction(classDecl, "ToString") Then
  2749. Emit "BBSTRING _" + classid + "_ToString" + Bra(TransObject(classdecl) + " o") + ";"
  2750. End If
  2751. If classHasFunction(classDecl, "Compare") Then
  2752. Emit "BBINT _" + classid + "_Compare(" + TransObject(classdecl) + " o, BBOBJECT otherObject);"
  2753. End If
  2754. If classHasFunction(classDecl, "SendMessage") Then
  2755. Emit "BBOBJECT _" + classid + "_SendMessage(" + TransObject(classdecl) + " o, BBOBJECT message, BBOBJECT source);"
  2756. End If
  2757. 'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  2758. classDecl.SemantParts()
  2759. 'Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls(Null, False)
  2760. For Local decl:TDecl=EachIn classDecl.Decls()
  2761. 'For Local fdecl:TFuncDecl = EachIn fdecls
  2762. Local fdecl:TFuncDecl =TFuncDecl( decl )
  2763. If fdecl
  2764. If Not equalsBuiltInFunc(classDecl, fdecl) And Not equalsTorFunc(classDecl, fdecl) Then
  2765. EmitClassFuncProto( fdecl )
  2766. Continue
  2767. End If
  2768. EndIf
  2769. Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  2770. If gdecl
  2771. MungDecl gdecl
  2772. ' Emit "static "+TransRefType( gdecl.ty )+" "+gdecl.munged+";"
  2773. Continue
  2774. EndIf
  2775. Next
  2776. Emit ""
  2777. ' emit the class structure
  2778. Emit "struct BBClass_" + classid + " {"
  2779. If classDecl.superClass.ident = "Object" Then
  2780. Emit "BBClass* super;"
  2781. Else
  2782. Emit "struct BBClass_" + classDecl.superClass.munged + "* super;"
  2783. End If
  2784. Emit "void (*free)( BBObject *o );"
  2785. Emit "BBDebugScope* debug_scope;"
  2786. Emit "unsigned int instance_size;"
  2787. Emit "void (*ctor)( BBOBJECT o );"
  2788. Emit "void (*dtor)( BBOBJECT o );"
  2789. Emit "BBSTRING (*ToString)( BBOBJECT x );"
  2790. Emit "int (*Compare)( BBOBJECT x,BBOBJECT y );"
  2791. Emit "BBOBJECT (*SendMessage)( BBOBJECT o,BBOBJECT m,BBOBJECT s );"
  2792. Emit "BBINTERFACETABLE itable;"
  2793. Emit "void* extra;"
  2794. Emit "unsigned int obj_size;"
  2795. EmitBBClassClassFuncProto(classDecl)
  2796. Emit "};~n"
  2797. If classDecl.IsInterface() Then
  2798. Emit "struct " + classid + "_methods {"
  2799. EmitBBClassClassFuncProto(classDecl)
  2800. Emit "};~n"
  2801. End If
  2802. Emit "struct " + classid + "_obj {"
  2803. Emit "struct BBClass_" + classid + "* clas;"
  2804. BeginLocalScope
  2805. EmitClassFieldsProto(classDecl)
  2806. EndLocalScope
  2807. Emit "};"
  2808. Emit "extern struct BBClass_" + classid + " " + classid + ";"
  2809. EmitClassGlobalsProto(classDecl);
  2810. ' fields
  2811. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2812. MungDecl decl
  2813. Next
  2814. End Method
  2815. Method EmitExternClassFuncProto( classDecl:TClassDecl )
  2816. If classDecl.superClass Then
  2817. EmitExternClassFuncProto(classDecl.superClass)
  2818. End If
  2819. For Local decl:TFuncDecl = EachIn classDecl.Decls()
  2820. decl.Semant()
  2821. ' code is written as a method, but emitted as a function pointer
  2822. ' with self as the first parameter
  2823. Local func:TFuncDecl = TFuncDecl(decl.Copy())
  2824. Local argDecl:TArgDecl = New TArgDecl.Create("This", classDecl.objectType, Null)
  2825. func.argDecls = [argDecl] + func.argDecls
  2826. func.Semant()
  2827. Local ty:TFunctionPtrType = New TFunctionPtrType
  2828. ty.func = func
  2829. Emit TransType(ty, decl.Ident) + ";"
  2830. Next
  2831. End Method
  2832. Method EmitExternClassTypeFuncProto( classDecl:TClassDecl )
  2833. Local doneCtorDtor:Int
  2834. Local iDecl:TClassDecl
  2835. For Local decl:TFuncDecl = EachIn classDecl.GetAllOriginalFuncDecls(Null, True)
  2836. decl.Semant()
  2837. ' first interface preceeds ctor/dtor
  2838. If Not doneCtorDtor
  2839. If Not iDecl And TClassDecl(decl.scope).IsInterface() Then
  2840. iDecl = TClassDecl(decl.scope)
  2841. End If
  2842. If iDecl
  2843. If iDecl <> TClassDecl(decl.scope) Then
  2844. ' a different interface
  2845. doneCtorDtor = True
  2846. Emit "void(*_ctor)();"
  2847. Emit "void(*_dtor)();"
  2848. End If
  2849. Else
  2850. doneCtorDtor = True
  2851. Emit "void(*_ctor)();"
  2852. Emit "void(*_dtor)();"
  2853. End If
  2854. End If
  2855. ' code is written as a method, but emitted as a function pointer
  2856. ' with self as the first parameter
  2857. Local func:TFuncDecl = TFuncDecl(decl.Copy())
  2858. Local argDecl:TArgDecl = New TArgDecl.Create("This", classDecl.objectType, Null)
  2859. func.argDecls = [argDecl] + func.argDecls
  2860. func.Semant()
  2861. Local ty:TFunctionPtrType = New TFunctionPtrType
  2862. ty.func = func
  2863. Emit TransType(ty, decl.Ident) + ";"
  2864. Next
  2865. End Method
  2866. Method EmitExternClassProto( classDecl:TClassDecl )
  2867. Emit "typedef struct " + classDecl.ident + " " + classDecl.ident + ";"
  2868. ' vtable
  2869. Emit "struct " + classDecl.ident + "Vtbl {"
  2870. ' methods
  2871. If classDecl.IsInterface() Then
  2872. EmitExternClassFuncProto(classDecl)
  2873. Else
  2874. EmitExternClassTypeFuncProto(classDecl)
  2875. End If
  2876. Emit "};"
  2877. Emit "struct " + classDecl.ident + " {"
  2878. Emit "struct " + classDecl.ident + "Vtbl* vtbl;"
  2879. Emit "};"
  2880. End Method
  2881. Field emittedStructs:TList = New TList
  2882. Method EmitStructClassProto( classDecl:TClassDecl )
  2883. If emittedStructs.Contains(classDecl) Return
  2884. emittedStructs.AddLast(classDecl)
  2885. ' emit any dependent structs first
  2886. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2887. decl.Semant()
  2888. If TObjectType(decl.ty) And TObjectType(decl.ty).classDecl.IsStruct() Then
  2889. If Not emittedStructs.Contains(TObjectType(decl.ty).classDecl) Then
  2890. EmitStructClassProto(TObjectType(decl.ty).classDecl)
  2891. End If
  2892. End If
  2893. Next
  2894. If classDecl.IsExtern()
  2895. Emit "struct " + classDecl.ident + " {"
  2896. Else
  2897. EmitClassDeclNewListProto( classDecl )
  2898. For Local fdecl:TFuncDecl=EachIn classDecl.Decls()
  2899. If fdecl.IdentLower() <> "new" Then
  2900. EmitClassFuncProto( fdecl, True )
  2901. End If
  2902. Next
  2903. Emit "struct " + classDecl.munged + " {"
  2904. End If
  2905. BeginLocalScope
  2906. EmitClassFieldsProto(classDecl)
  2907. EndLocalScope
  2908. Emit "};"
  2909. End Method
  2910. Method classHasFunction:Int(classDecl:TClassDecl, func:String)
  2911. Local f:String = func.ToLower()
  2912. For Local decl:TFuncDecl = EachIn classDecl.Decls()
  2913. If Not decl.IsSemanted() Then
  2914. decl.Semant
  2915. End If
  2916. If decl.IdentLower() = f And equalsBuiltInFunc(classDecl.superClass, decl) Then
  2917. Return True
  2918. End If
  2919. Next
  2920. Return False
  2921. End Method
  2922. Method classHierarchyHasFunction:Int(classDecl:TClassDecl, func:String)
  2923. If classHasFunction(classDecl, func) Return True
  2924. If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
  2925. Return classHierarchyHasFunction(classDecl.superClass, func)
  2926. End If
  2927. Return False
  2928. End Method
  2929. Method classidForFunction:String(classDecl:TClassDecl, func:String)
  2930. If classHasFunction(classDecl, func) Return classDecl.munged
  2931. If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
  2932. Return classidForFunction(classDecl.superClass, func)
  2933. End If
  2934. Return Null
  2935. End Method
  2936. Method EmitMark( id$,ty:TType,queue:Int )
  2937. If TObjectType( ty )
  2938. If id.EndsWith( ".p" )
  2939. If ty.GetClass().IsInterface() id=id[..-2] Else InternalErr
  2940. Else
  2941. If ty.GetClass().IsInterface() InternalErr
  2942. EndIf
  2943. If queue
  2944. Emit "gc_mark_q("+id+");"
  2945. Else
  2946. Emit "gc_mark("+id+");"
  2947. EndIf
  2948. Else If TArrayType( ty )
  2949. Emit "gc_mark("+id+");"
  2950. Return
  2951. EndIf
  2952. End Method
  2953. Method EmitClassConstsDebugScope(classDecl:TClassDecl)
  2954. For Local decl:TConstDecl = EachIn classDecl.Decls()
  2955. EmitConstDebugScope(decl)
  2956. Next
  2957. End Method
  2958. Method EmitConstDebugScope(decl:TConstDecl)
  2959. Emit "{"
  2960. Emit "BBDEBUGDECL_CONST,"
  2961. Emit Enquote(decl.ident) + ","
  2962. Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
  2963. _appInstance.mapStringConsts(decl.value)
  2964. Emit ".const_value=&" + TStringConst(_appInstance.stringConsts.ValueForKey(decl.value)).id
  2965. Emit "},"
  2966. End Method
  2967. Method EmitClassFieldsDebugScope(classDecl:TClassDecl)
  2968. ' Don't list superclass fields in our debug scope
  2969. 'If classDecl.superClass Then
  2970. ' EmitClassFieldsDebugScope(classDecl.superClass)
  2971. 'End If
  2972. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2973. Emit "{"
  2974. Emit "BBDEBUGDECL_FIELD,"
  2975. Emit Enquote(decl.ident) + ","
  2976. Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
  2977. Local offset:String = ".field_offset=offsetof"
  2978. If classDecl.IsStruct() Then
  2979. offset :+ Bra("struct " + classDecl.munged + "," + decl.munged)
  2980. Else
  2981. offset :+ Bra("struct " + classDecl.munged + "_obj," + decl.munged)
  2982. End If
  2983. ' If WORD_SIZE = 8 Then
  2984. ' Emit Bra("BBLONG") + offset
  2985. ' Else
  2986. Emit offset
  2987. ' End If
  2988. 'If Not TFunctionPtrType(decl.ty) Then
  2989. ' Emit TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.ident.ToLower() + ";"
  2990. 'Else
  2991. ' Emit TransType(decl.ty, "_" + classDecl.actual.munged.ToLower() + "_" + decl.ident.ToLower()) + ";"
  2992. 'End If
  2993. Emit "},"
  2994. 'offset:+ decl.ty.GetSize()
  2995. Next
  2996. 'Return offset
  2997. End Method
  2998. Method EmitClassStandardMethodDebugScope(ident:String, ty:String, munged:String)
  2999. Emit "{"
  3000. Emit "BBDEBUGDECL_TYPEMETHOD,"
  3001. Emit Enquote(ident) + ","
  3002. Emit Enquote(ty) + ","
  3003. Emit "&" + munged
  3004. Emit "},"
  3005. End Method
  3006. Method TransDebugMetaData:String(meta:String)
  3007. If meta Then
  3008. Return "{" + meta + "}"
  3009. End If
  3010. End Method
  3011. Method EmitBBClassFuncsDebugScope(decl:TFuncDecl)
  3012. Emit "{"
  3013. If decl.IsMethod() Then
  3014. Emit "BBDEBUGDECL_TYPEMETHOD,"
  3015. Else
  3016. Emit "BBDEBUGDECL_TYPEFUNCTION,"
  3017. End If
  3018. Emit Enquote(decl.ident) + ","
  3019. Local s:String = "("
  3020. For Local i:Int = 0 Until decl.argDecls.length
  3021. If i Then
  3022. s:+ ","
  3023. End If
  3024. s:+ TransDebugScopeType(decl.argDecls[i].ty)
  3025. Next
  3026. s:+ ")"
  3027. If decl.retType Then
  3028. s:+ TransDebugScopeType(decl.retType)
  3029. End If
  3030. s:+ TransDebugMetaData(decl.metadata.metadataString)
  3031. Emit Enquote(s) + ","
  3032. If decl.IsMethod() Or decl.IsCTor() Then
  3033. Emit "&_" + decl.munged
  3034. Else
  3035. Emit "&" + decl.munged
  3036. End If
  3037. Emit "},"
  3038. End Method
  3039. Method BBClassClassFuncsDebugScopeBuildList(classDecl:TClassDecl, list:TList)
  3040. 'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  3041. For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
  3042. Local fdecl:TFuncDecl =TFuncDecl( decl )
  3043. If fdecl
  3044. If Not fdecl.IsSemanted()
  3045. fdecl.Semant()
  3046. End If
  3047. If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
  3048. Continue
  3049. End If
  3050. If Not equalsBuiltInFunc(classDecl, fdecl) Then
  3051. Local ignore:Int
  3052. Local link:TLink=list._head._succ
  3053. While link<>list._head
  3054. If fdecl.ident = TFuncDecl(link._value).ident Then
  3055. If fdecl.overrides Then
  3056. link._value = fdecl
  3057. ignore = True
  3058. Exit
  3059. End If
  3060. EndIf
  3061. link = link._succ
  3062. Wend
  3063. If Not ignore Then
  3064. list.AddLast(fdecl)
  3065. End If
  3066. Continue
  3067. End If
  3068. EndIf
  3069. Next
  3070. End Method
  3071. Method EmitBBClassClassFuncsDebugScope(classDecl:TClassDecl)
  3072. Local list:TList = New TList
  3073. BBClassClassFuncsDebugScopeBuildList(classDecl, list)
  3074. For Local fdecl:TFuncDecl = EachIn list
  3075. EmitBBClassFuncsDebugScope( fdecl )
  3076. Next
  3077. End Method
  3078. Method EmitClassFuncsDebugScope(classDecl:TClassDecl)
  3079. If classDecl.IsExtern() Return
  3080. Local classid$=classDecl.munged
  3081. Local superid$
  3082. If classDecl.superClass Then
  3083. superid = classDecl.superClass.actual.munged
  3084. End If
  3085. Local ret:String = "()i"
  3086. If opt_issuperstrict Then
  3087. ret = "()"
  3088. End If
  3089. If Not classDecl.IsInterface() Then
  3090. EmitClassStandardMethodDebugScope("New", ret, "_" + classid + "_New")
  3091. End If
  3092. If classHasFunction(classDecl, "ToString") Then
  3093. EmitClassStandardMethodDebugScope("ToString", "()$", "_" + classidForFunction(classDecl, "ToString") + "_ToString")
  3094. 'Emit "_" + classid + "_ToString,"
  3095. End If
  3096. If classHasFunction(classDecl, "Compare") Then
  3097. EmitClassStandardMethodDebugScope("Compare", "(:Object)i", "_" + classidForFunction(classDecl, "Compare") + "_Compare")
  3098. 'Emit "_" + classid + "_ObjectCompare,"
  3099. End If
  3100. If classHasFunction(classDecl, "SendMessage") Then
  3101. EmitClassStandardMethodDebugScope("SendMessage", "(:Object, :Object):Object", "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage")
  3102. 'Emit "_" + classid + "_SendMessage,"
  3103. End If
  3104. EmitBBClassClassFuncsDebugScope(classDecl)
  3105. End Method
  3106. Method EmitClassGlobalDebugScope( classDecl:TClassDecl )
  3107. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  3108. EmitGlobalDebugScope(decl)
  3109. Next
  3110. End Method
  3111. Method EmitGlobalDebugScope( decl:TGlobalDecl )
  3112. Emit "{"
  3113. Emit "BBDEBUGDECL_GLOBAL,"
  3114. Emit Enquote(decl.ident) + ","
  3115. Emit Enquote(TransDebugScopeType(decl.ty)) + ","
  3116. Emit "&" + decl.munged
  3117. Emit "},"
  3118. End Method
  3119. Method CountBBClassClassFuncsDebugScope(classDecl:TClassDecl, count:Int Var)
  3120. For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
  3121. Local fdecl:TFuncDecl =TFuncDecl( decl )
  3122. If fdecl
  3123. If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
  3124. Continue
  3125. End If
  3126. If Not equalsBuiltInFunc(classDecl, fdecl) Then
  3127. count :+ 1
  3128. End If
  3129. End If
  3130. Next
  3131. End Method
  3132. Method CountClassConstsDebugScope(classDecl:TClassDecl, count:Int Var)
  3133. For Local decl:TConstDecl = EachIn classDecl.Decls()
  3134. count :+ 1
  3135. Next
  3136. End Method
  3137. Method CountClassFieldsDebugScope(classDecl:TClassDecl, count:Int Var)
  3138. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3139. count :+ 1
  3140. Next
  3141. End Method
  3142. Method DebugScopeDeclCount:Int(classDecl:TClassDecl)
  3143. Local count:Int = 2 ' "New" counts as first one
  3144. ' but we don't use "New" for interfaces...
  3145. If classDecl.IsInterface() Or (classDecl.IsExtern() And classDecl.IsStruct()) Then
  3146. count :- 1
  3147. End If
  3148. ' consts
  3149. CountClassConstsDebugScope(classDecl, count)
  3150. ' fields
  3151. CountClassFieldsDebugScope(classDecl, count)
  3152. ' standard methods
  3153. If classHasFunction(classDecl, "ToString") Then
  3154. count :+ 1
  3155. End If
  3156. If classHasFunction(classDecl, "Compare") Then
  3157. count :+ 1
  3158. End If
  3159. If classHasFunction(classDecl, "SendMessage") Then
  3160. count :+ 1
  3161. End If
  3162. ' methods and functions
  3163. CountBBClassClassFuncsDebugScope(classDecl, count)
  3164. ' class globals
  3165. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  3166. count :+ 1
  3167. Next
  3168. Return count
  3169. End Method
  3170. Method EmitClassDecl( classDecl:TClassDecl )
  3171. 'If classDecl.IsTemplateInst()
  3172. ' Return
  3173. 'EndIf
  3174. If classDecl.IsExtern() And Not classDecl.IsStruct() Then
  3175. Return
  3176. EndIf
  3177. Local classid$=classDecl.munged
  3178. Local superid$
  3179. If classDecl.superClass Then
  3180. superid = classDecl.superClass.actual.munged
  3181. End If
  3182. If Not classDecl.IsExtern() Then
  3183. ' process nested functions for new
  3184. Local decl:TFuncDecl = classDecl.FindFuncDecl("new",,,,,,SCOPE_CLASS_HEIRARCHY)
  3185. If decl And decl.scope = classDecl Then ' only our own New method, not any from superclasses
  3186. decl.Semant
  3187. ' emit nested protos
  3188. For Local fdecl:TFuncDecl = EachIn decl._decls
  3189. EmitFuncDecl(fdecl, True, False)
  3190. Next
  3191. ' emit nested bodies
  3192. For Local fdecl:TFuncDecl = EachIn decl._decls
  3193. EmitFuncDecl(fdecl, False, False)
  3194. Next
  3195. End If
  3196. EmitClassDeclNewList(classDecl)
  3197. ' process nested functions for delete
  3198. decl = classDecl.FindFuncDecl("delete",,,,,,SCOPE_CLASS_HEIRARCHY)
  3199. If decl Then
  3200. decl.Semant
  3201. ' emit nested protos
  3202. For Local fdecl:TFuncDecl = EachIn decl._decls
  3203. EmitFuncDecl(fdecl, True, False)
  3204. Next
  3205. ' emit nested bodies
  3206. For Local fdecl:TFuncDecl = EachIn decl._decls
  3207. EmitFuncDecl(fdecl, False, False)
  3208. Next
  3209. End If
  3210. If classHierarchyHasFunction(classDecl, "Delete") Then
  3211. EmitClassDeclDelete(classDecl)
  3212. End If
  3213. Rem
  3214. 'fields ctor
  3215. Emit classid+"::"+classid+"(){"
  3216. For Local decl:TDecl=EachIn classDecl.Semanted()
  3217. Local fdecl:TFieldDecl=TFieldDecl( decl )
  3218. If Not fdecl Continue
  3219. Emit TransField(fdecl,Null)+"="+fdecl.init.Trans()+";"
  3220. Next
  3221. Emit "}"
  3222. End Rem
  3223. Local reserved:String = ",New,Delete,".ToLower()
  3224. 'methods
  3225. For Local decl:TDecl=EachIn classDecl.Decls()
  3226. Local fdecl:TFuncDecl=TFuncDecl( decl )
  3227. If fdecl
  3228. If reserved.Find("," + fdecl.IdentLower() + ",") = -1 Then
  3229. EmitGDBDebug(fdecl)
  3230. EmitFuncDecl fdecl, , True
  3231. Continue
  3232. End If
  3233. EndIf
  3234. 'Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  3235. 'If gdecl
  3236. ' Emit TransRefType( gdecl.ty )+" "+classid+"::"+gdecl.munged+";"
  3237. ' Continue
  3238. ' EndIf
  3239. Next
  3240. Rem
  3241. 'gc_mark
  3242. Emit "void "+classid+"::mark(){"
  3243. If classDecl.superClass
  3244. Emit classDecl.superClass.actual.munged+"::mark();"
  3245. EndIf
  3246. For Local decl:TDecl=EachIn classDecl.Semanted()
  3247. Local fdecl:TFieldDecl=TFieldDecl( decl )
  3248. If fdecl EmitMark TransField(fdecl,Null),fdecl.ty,True
  3249. Next
  3250. Emit "}"
  3251. End Rem
  3252. For Local decl:TDecl=EachIn classDecl.Semanted()
  3253. Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  3254. If gdecl
  3255. If TFunctionPtrType(gdecl.ty) Then
  3256. Emit TransRefType( gdecl.ty, gdecl.munged ) + ";"
  3257. Else
  3258. Emit TransRefType( gdecl.ty, "" )+" "+gdecl.munged+";"
  3259. End If
  3260. Continue
  3261. EndIf
  3262. Next
  3263. reserved = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  3264. End If
  3265. 'Emit "struct _" + classid + "_DebugScope{"
  3266. 'Emit "int kind;"
  3267. 'Emit "const char *name;"
  3268. 'Emit "BBDebugDecl decls[" + DebugScopeDeclCount(classDecl) + "];"
  3269. 'Emit "};"
  3270. Local count:Int = DebugScopeDeclCount(classDecl)
  3271. ' debugscope
  3272. If count > 1 Then
  3273. _app.scopeDefs.Insert(String(count - 1), "")
  3274. Emit "struct BBDebugScope_" + (count - 1) + " " + classid + "_scope ={"
  3275. Else
  3276. Emit "struct BBDebugScope " + classid + "_scope ={"
  3277. End If
  3278. If classDecl.IsInterface() Then
  3279. Emit "BBDEBUGSCOPE_USERINTERFACE,"
  3280. Else If classDecl.IsStruct() Then
  3281. Emit "BBDEBUGSCOPE_USERSTRUCT,"
  3282. Else
  3283. Emit "BBDEBUGSCOPE_USERTYPE,"
  3284. End If
  3285. Emit EnQuote(classDecl.ident + TransDebugMetaData(classDecl.metadata.metadataString)) + ","
  3286. Emit "{"
  3287. ' debug const decls
  3288. EmitClassConstsDebugScope(classDecl)
  3289. ' debug field decls
  3290. EmitClassFieldsDebugScope(classDecl)
  3291. ' debug global decls
  3292. EmitClassGlobalDebugScope(classDecl)
  3293. ' debug func decls
  3294. EmitClassFuncsDebugScope(classDecl)
  3295. Emit "BBDEBUGDECL_END"
  3296. Emit "}"
  3297. Emit "};"
  3298. Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls()
  3299. Local implementedInterfaces:TMap = classDecl.GetInterfaces()
  3300. Local ifcCount:Int
  3301. If Not classDecl.IsStruct() Then
  3302. ' interface class implementation
  3303. If Not classDecl.IsInterface()
  3304. If Not implementedInterfaces.IsEmpty() Then
  3305. Emit "struct " + classid + "_vdef {"
  3306. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  3307. Emit "struct " + ifc.munged + "_methods interface_" + ifc.ident + ";"
  3308. ifcCount :+ 1
  3309. Next
  3310. Emit "};~n"
  3311. Emit "static struct BBInterfaceOffsets " + classid + "_ifc_offsets[] = {"
  3312. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  3313. Emit "{&" + ifc.munged + "_ifc, offsetof(struct " + classid + "_vdef, interface_" + ifc.ident + ")},"
  3314. Next
  3315. Emit "};~n"
  3316. Emit "struct " + classid + "_vdef " + classid + "_ifc_vtable = {"
  3317. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  3318. Emit ".interface_" + ifc.ident + "={"
  3319. For Local func:TFuncDecl = EachIn ifc.GetImplementedFuncs()
  3320. If func.IsMethod() Then
  3321. For Local f:TFuncDecl = EachIn fdecls
  3322. Mungdecl f
  3323. If f.ident = func.ident And func.EqualsFunc(f) Then
  3324. Emit "_" + f.munged + ","
  3325. Exit
  3326. End If
  3327. Next
  3328. End If
  3329. Next
  3330. Emit "},"
  3331. Next
  3332. Emit "};~n"
  3333. Emit "struct BBInterfaceTable " + classid + "_itable = {"
  3334. Emit classid + "_ifc_offsets,"
  3335. Emit "&" + classid + "_ifc_vtable,"
  3336. Emit ifcCount
  3337. Emit "};~n"
  3338. End If
  3339. End If
  3340. Emit "struct BBClass_" + classid + " " + classid + "={"
  3341. ' super class reference
  3342. Emit "&" + classDecl.superClass.munged + ","
  3343. Emit "bbObjectFree,"
  3344. ' debugscope
  3345. Emit "&" + classid + "_scope,"
  3346. ' object instance size
  3347. Emit "sizeof" + Bra("struct " + classid + "_obj") + ","
  3348. ' standard methods
  3349. Emit "_" + classid + "_New,"
  3350. If Not classHierarchyHasFunction(classDecl, "Delete") Then
  3351. Emit "bbObjectDtor,"
  3352. Else
  3353. Emit "_" + classid + "_Delete,"
  3354. End If
  3355. If classHierarchyHasFunction(classDecl, "ToString") Then
  3356. Emit "_" + classidForFunction(classDecl, "ToString") + "_ToString,"
  3357. Else
  3358. Emit "bbObjectToString,"
  3359. End If
  3360. If classHierarchyHasFunction(classDecl, "Compare") Then
  3361. Emit "_" + classidForFunction(classDecl, "Compare") + "_Compare,"
  3362. Else
  3363. Emit "bbObjectCompare,"
  3364. End If
  3365. If classHierarchyHasFunction(classDecl, "SendMessage") Then
  3366. Emit "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage,"
  3367. Else
  3368. Emit "bbObjectSendMessage,"
  3369. End If
  3370. 'Emit "public:"
  3371. 'fields
  3372. 'For Local decl:TDecl=EachIn classDecl.Semanted()
  3373. ' Local fdecl:TFieldDecl =TFieldDecl( decl )
  3374. ' If fdecl
  3375. ' Emit TransRefType( fdecl.ty )+" "+fdecl.munged+";"
  3376. ' Continue
  3377. ' EndIf
  3378. 'Next
  3379. 'fields ctor
  3380. 'Emit classid+"();"
  3381. 'methods
  3382. 'For Local decl:TDecl=EachIn classDecl.Semanted()
  3383. '
  3384. ' Local fdecl:TFuncDecl =TFuncDecl( decl )
  3385. ' If fdecl
  3386. ' EmitFuncProto fdecl
  3387. ' Continue
  3388. ' EndIf
  3389. '
  3390. ' Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  3391. ' If gdecl
  3392. ' Emit "static "+TransRefType( gdecl.ty )+" "+gdecl.munged+";"
  3393. ' Continue
  3394. ' EndIf
  3395. 'Next
  3396. 'gc mark
  3397. 'Emit "void mark();"
  3398. If classDecl.IsInterface() Or implementedInterfaces.IsEmpty() Then
  3399. ' itable
  3400. Emit "0,"
  3401. ' extra pointer
  3402. Emit "0,"
  3403. Else
  3404. Emit "&" + classid + "_itable,"
  3405. ' extra pointer
  3406. Emit "0,"
  3407. End If
  3408. ' obj_size
  3409. Emit TransObjectSize(classDecl)
  3410. ' methods/funcs
  3411. 'reserved = "New,Delete,ToString,ObjectCompare,SendMessage".ToLower()
  3412. 'For Local decl:TFuncDecl = EachIn classDecl.Decls()
  3413. For Local decl:TFuncDecl = EachIn fdecls
  3414. If Not equalsBuiltInFunc(classDecl, decl) And Not equalsTorFunc(classDecl, decl) Then
  3415. MungDecl decl
  3416. If decl.IsMethod() Then
  3417. Emit ",_" + decl.munged
  3418. Else
  3419. Emit "," + decl.munged
  3420. End If
  3421. End If
  3422. Next
  3423. Emit "};~n"
  3424. If classDecl.IsInterface() Then
  3425. Emit "const struct BBInterface " + classid + "_ifc = { &" + classid + ", (const char *) ~q" + classDecl.ident + "~q };"
  3426. Else
  3427. End If
  3428. End If
  3429. End Method
  3430. Method TransObjectSize:String(classDecl:TClassDecl)
  3431. Local t:String
  3432. Local fieldDecl:TFieldDecl
  3433. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3434. fieldDecl = decl
  3435. Next
  3436. If fieldDecl Then
  3437. t = "offsetof" + Bra("struct " + classDecl.munged + "_obj," + fieldDecl.munged) + " - sizeof(void*) + sizeof" + Bra(TransType(fieldDecl.ty, ""))
  3438. Else
  3439. t = "0"
  3440. End If
  3441. Return t
  3442. End Method
  3443. Method EmitClassDeclNew( classDecl:TClassDecl, fdecl:TFuncDecl )
  3444. Local classid$=classDecl.munged
  3445. Local superid$=classDecl.superClass.actual.munged
  3446. Local t:String = "void _"
  3447. If fdecl.argDecls.Length Then
  3448. If classDecl = fdecl.scope Then
  3449. t :+ fdecl.munged
  3450. Else
  3451. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  3452. End If
  3453. Else
  3454. t :+ classid + "_New"
  3455. End If
  3456. 'Find decl we override
  3457. Local odecl:TFuncDecl=fdecl
  3458. While odecl.overrides
  3459. odecl=odecl.overrides
  3460. Wend
  3461. Local args:String = TransObject(classdecl, True) + " o"
  3462. For Local i:Int=0 Until fdecl.argDecls.Length
  3463. Local arg:TArgDecl=fdecl.argDecls[i]
  3464. Local oarg:TArgDecl=odecl.argDecls[i]
  3465. MungDecl arg, True
  3466. If args args:+","
  3467. If Not TFunctionPtrType(oarg.ty) Then
  3468. If Not odecl.castTo Then
  3469. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  3470. Else
  3471. args:+ oarg.castTo + " " + arg.munged
  3472. End If
  3473. Else
  3474. If Not odecl.castTo Then
  3475. args:+TransType( oarg.ty, arg.munged )
  3476. Else
  3477. args:+ oarg.castTo
  3478. End If
  3479. End If
  3480. If arg.ty.EqualsType( oarg.ty ) Continue
  3481. Next
  3482. Emit t + Bra(args) + " {"
  3483. Local newDecl:TNewDecl = TNewDecl(fdecl)
  3484. If Not classDecl.IsStruct() Then
  3485. ' calling constructor?
  3486. If newDecl And newDecl.chainedCtor Then
  3487. mungdecl newDecl.chainedCtor.ctor
  3488. Emit "_" + newDecl.chainedCtor.ctor.ClassScope().munged + "_" + newDecl.chainedCtor.ctor.ident + MangleMethod(newDecl.chainedCtor.ctor) + TransArgs(newDecl.chainedCtor.args, newDecl.chainedCtor.ctor, "o") + ";"
  3489. Else
  3490. If classDecl.superClass.ident = "Object" Then
  3491. Emit "bbObjectCtor(o);"
  3492. Else
  3493. Emit "_" + superid + "_New(o);"
  3494. End If
  3495. End If
  3496. Emit "o->clas = (BBClass*)&" + classid + ";"
  3497. End If
  3498. ' only initialise fields if we are not chaining to a local (in our class) constructor.
  3499. ' this prevents fields being re-initialised through the call-chain.
  3500. If Not newDecl.chainedCtor Or (newDecl.chainedCtor And classDecl <> newDecl.chainedCtor.ctor.scope) Then
  3501. ' field initialisation
  3502. For Local decl:TFieldDecl=EachIn classDecl.Decls()
  3503. Local fld:String
  3504. ' ((int*)((char*)o + 5))[0] =
  3505. fld :+ TransFieldRef(decl, "o")
  3506. If decl.init Then
  3507. If TObjectType(decl.ty) And TObjectType(decl.ty).classdecl.IsExtern() And TObjectType(decl.ty).classdecl.IsStruct() Then
  3508. ' skip for uninitialised extern type
  3509. If Not isPointerType(decl.ty) And TConstExpr(decl.init) And Not TConstExpr(decl.init).value Then
  3510. Continue
  3511. End If
  3512. End If
  3513. ' initial value
  3514. If (TConstExpr(decl.init) And Not TConstExpr(decl.init).value) And TIntrinsicType(decl.ty) Then
  3515. fld :+ "= "
  3516. If TFloat64Type(decl.ty) Then
  3517. fld :+ "_mm_setzero_si64();"
  3518. Else If TFloat128Type(decl.ty) Then
  3519. fld :+ "_mm_setzero_ps();"
  3520. Else If TDouble128Type(decl.ty) Then
  3521. fld :+ "_mm_setzero_pd();"
  3522. Else If TInt128Type(decl.ty) Then
  3523. fld :+ "_mm_setzero_si128();"
  3524. End If
  3525. Else
  3526. If TObjectType(decl.ty) And TObjectType(decl.ty).classdecl.IsStruct() And Not isPointerType(decl.ty) And (TConstExpr(decl.init) And Not TConstExpr(decl.init).value) Then
  3527. fld = "memset(&" + fld + ", 0, sizeof" + Bra(TransType(decl.ty, "")) + ");"
  3528. Else
  3529. fld :+ "= " + decl.init.Trans() + ";"
  3530. End If
  3531. End If
  3532. Else
  3533. If TNumericType(decl.ty) Or TObjectType(decl.ty) Or IsPointerType(decl.ty, 0, TType.T_POINTER) Then
  3534. fld :+ "= 0;"
  3535. Else If TFunctionPtrType(decl.ty) Then
  3536. fld :+ "= &brl_blitz_NullFunctionError;"
  3537. Else If TStringType(decl.ty) Then
  3538. fld :+ "= &bbEmptyString;"
  3539. Else If TArrayType(decl.ty) Then
  3540. fld :+ "= &bbEmptyArray;"
  3541. End If
  3542. End If
  3543. Emit fld
  3544. Next
  3545. End If
  3546. 'Local decl:TFuncDecl = classDecl.FindFuncDecl("new",,,,,,SCOPE_CLASS_LOCAL)
  3547. If fdecl And (fdecl.scope = classDecl Or fdecl.argDecls.Length) Then ' only our own New method, not any from superclasses
  3548. fdecl.Semant
  3549. If fdecl.munged <> "bbObjectCtor" Then
  3550. EmitLocalDeclarations(fdecl)
  3551. EmitBlock fdecl
  3552. End If
  3553. End If
  3554. '
  3555. Emit "}"
  3556. End Method
  3557. Method EmitClassDeclNewList( classDecl:TClassDecl )
  3558. Local classid$=classDecl.munged
  3559. Local superid$=classDecl.superClass.actual.munged
  3560. Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", SCOPE_CLASS_LOCAL))
  3561. For Local fdecl:TFuncDecl = EachIn newDecls
  3562. EmitClassDeclNew(classDecl, fdecl)
  3563. ' generate "objectNew" function if required
  3564. If (fdecl.argDecls And fdecl.argDecls.length) Or classDecl.IsStruct() Then
  3565. EmitClassDeclNewInit(classDecl, fdecl)
  3566. End If
  3567. Next
  3568. End Method
  3569. Method EmitClassDeclNewListProto( classDecl:TClassDecl )
  3570. Local classid$=classDecl.munged
  3571. 'Local superid$=classDecl.superClass.actual.munged
  3572. Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", SCOPE_CLASS_LOCAL))
  3573. For Local fdecl:TFuncDecl = EachIn newDecls
  3574. EmitClassDeclNewProto(classDecl, fdecl)
  3575. ' generate "objectNew" function if required
  3576. If (fdecl.argDecls And fdecl.argDecls.length) Or classDecl.IsStruct() Then
  3577. EmitClassDeclObjectNewProto(classDecl, fdecl)
  3578. End If
  3579. Next
  3580. End Method
  3581. Method EmitClassDeclNewInit(classDecl:TClassDecl, fdecl:TFuncDecl)
  3582. Local funcMunged:String
  3583. If classDecl = fdecl.scope Then
  3584. funcMunged = fdecl.munged
  3585. Else
  3586. funcMunged = classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  3587. End If
  3588. Local t:String = TransObject(classdecl) + " _" + funcMunged + "_ObjectNew"
  3589. 'Find decl we override
  3590. Local odecl:TFuncDecl=fdecl
  3591. While odecl.overrides
  3592. odecl=odecl.overrides
  3593. Wend
  3594. Local args:String
  3595. If Not classDecl.IsStruct() Then
  3596. args = "BBClass * clas"
  3597. End If
  3598. For Local i:Int=0 Until fdecl.argDecls.Length
  3599. Local arg:TArgDecl=fdecl.argDecls[i]
  3600. Local oarg:TArgDecl=odecl.argDecls[i]
  3601. MungDecl arg, True
  3602. If args args:+","
  3603. If Not TFunctionPtrType(oarg.ty) Then
  3604. If Not odecl.castTo Then
  3605. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  3606. Else
  3607. args:+ oarg.castTo + " " + arg.munged
  3608. End If
  3609. Else
  3610. If Not odecl.castTo Then
  3611. args:+TransType( oarg.ty, arg.munged )
  3612. Else
  3613. args:+ oarg.castTo
  3614. End If
  3615. End If
  3616. If arg.ty.EqualsType( oarg.ty ) Continue
  3617. Next
  3618. Emit t + Bra(args) + " {"
  3619. t = TransObject(classdecl) + " o"
  3620. If classDecl.IsStruct() Then
  3621. Emit t + ";"
  3622. Else
  3623. t :+ " = "
  3624. If ClassHasObjectField(classDecl) Then
  3625. t :+ "bbObjectNewNC"
  3626. Else
  3627. t :+ "bbObjectAtomicNewNC"
  3628. End If
  3629. Emit t + "(clas);"
  3630. End If
  3631. t = "_" + funcMunged
  3632. If classDecl.IsStruct() Then
  3633. t :+ "(&o"
  3634. Else
  3635. t :+ "(o"
  3636. End If
  3637. For Local i:Int=0 Until fdecl.argDecls.Length
  3638. Local arg:TArgDecl=fdecl.argDecls[i]
  3639. t :+ ", " + arg.munged
  3640. Next
  3641. Emit t + ");"
  3642. Emit "return o;"
  3643. Emit "}"
  3644. End Method
  3645. Method EmitClassDeclNewProto( classDecl:TClassDecl, fdecl:TFuncDecl )
  3646. Local classid$=classDecl.munged
  3647. Local superid$
  3648. If classDecl.superClass Then
  3649. superid = classDecl.superClass.actual.munged
  3650. End If
  3651. Local t:String = "void _"
  3652. If fdecl.argDecls.Length Then
  3653. If classDecl = fdecl.scope Then
  3654. t :+ fdecl.munged
  3655. Else
  3656. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  3657. End If
  3658. Else
  3659. t :+ classid + "_New"
  3660. End If
  3661. 'Find decl we override
  3662. Local odecl:TFuncDecl=fdecl
  3663. While odecl.overrides
  3664. odecl=odecl.overrides
  3665. Wend
  3666. Local args:String = TransObject(classdecl, True) + " o"
  3667. For Local i:Int=0 Until fdecl.argDecls.Length
  3668. Local arg:TArgDecl=fdecl.argDecls[i]
  3669. Local oarg:TArgDecl=odecl.argDecls[i]
  3670. MungDecl arg, True
  3671. If args args:+","
  3672. If Not TFunctionPtrType(oarg.ty) Then
  3673. If Not odecl.castTo Then
  3674. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  3675. Else
  3676. args:+ oarg.castTo + " " + arg.munged
  3677. End If
  3678. Else
  3679. If Not odecl.castTo Then
  3680. args:+TransType( oarg.ty, arg.munged )
  3681. Else
  3682. args:+ oarg.castTo
  3683. End If
  3684. End If
  3685. If arg.ty.EqualsType( oarg.ty ) Continue
  3686. Next
  3687. Emit t + Bra(args) + ";"
  3688. End Method
  3689. Method EmitClassDeclObjectNewProto(classDecl:TClassDecl, fdecl:TFuncDecl)
  3690. Local t:String = TransObject(classdecl) + " _"
  3691. If classDecl = fdecl.scope Then
  3692. t :+ fdecl.munged
  3693. Else
  3694. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  3695. End If
  3696. t:+ "_ObjectNew"
  3697. 'Find decl we override
  3698. Local odecl:TFuncDecl=fdecl
  3699. While odecl.overrides
  3700. odecl=odecl.overrides
  3701. Wend
  3702. Local args:String
  3703. If Not classDecl.IsStruct() Then
  3704. args = "BBClass * clas"
  3705. End If
  3706. For Local i:Int=0 Until fdecl.argDecls.Length
  3707. Local arg:TArgDecl=fdecl.argDecls[i]
  3708. Local oarg:TArgDecl=odecl.argDecls[i]
  3709. MungDecl arg, True
  3710. If args args:+","
  3711. If Not TFunctionPtrType(oarg.ty) Then
  3712. If Not odecl.castTo Then
  3713. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  3714. Else
  3715. args:+ oarg.castTo + " " + arg.munged
  3716. End If
  3717. Else
  3718. If Not odecl.castTo Then
  3719. args:+TransType( oarg.ty, arg.munged )
  3720. Else
  3721. args:+ oarg.castTo
  3722. End If
  3723. End If
  3724. If arg.ty.EqualsType( oarg.ty ) Continue
  3725. Next
  3726. Emit t + Bra(args) + ";"
  3727. End Method
  3728. Method EmitClassDeclDelete( classDecl:TClassDecl )
  3729. Local classid$=classDecl.munged
  3730. Local superid$=classDecl.superClass.actual.munged
  3731. ' New
  3732. ' If opt_issuperstrict Then
  3733. Emit "void _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + " {"
  3734. ' Else
  3735. ' Emit "int _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + " {"
  3736. ' End If
  3737. Local decl:TFuncDecl = classDecl.FindFuncDecl("delete",,,,,,SCOPE_CLASS_HEIRARCHY)
  3738. If decl Then
  3739. decl.Semant
  3740. EmitLocalDeclarations(decl)
  3741. EmitBlock decl
  3742. End If
  3743. ' field cleanup
  3744. For Local decl:TFieldDecl=EachIn classDecl.Decls()
  3745. ' String
  3746. If TStringType(decl.declTy) Then
  3747. Emit "BBRELEASE(" + TransFieldRef(decl, "o") + ")"
  3748. End If
  3749. ' object
  3750. ' TODO
  3751. Next
  3752. ' finally, call super delete
  3753. EmitClassDeclDeleteDtor(classDecl)
  3754. '
  3755. Emit "}"
  3756. End Method
  3757. Method EmitClassDeclDeleteDtor( classDecl:TClassDecl )
  3758. Local superid$=classDecl.superClass.actual.munged
  3759. If classDecl.superClass.ident = "Object" Or Not classHierarchyHasFunction(classDecl.superClass, "Delete") Then
  3760. Emit "bbObjectDtor(o);"
  3761. Else
  3762. Emit "_" + superid + "_Delete(o);"
  3763. End If
  3764. End Method
  3765. Method TransFieldRef:String(decl:TFieldDecl, variable:String, exprType:TType = Null)
  3766. Local s:String = variable
  3767. 'DebugStop
  3768. Local ind:String = "->"
  3769. If decl.scope And TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  3770. If exprType And Not IsPointerType(exprType) And variable <> "o" Then
  3771. ind = "."
  3772. End If
  3773. End If
  3774. If variable.StartsWith("*") Then
  3775. variable = Bra(variable)
  3776. End If
  3777. ' Null test
  3778. If opt_debug
  3779. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  3780. '
  3781. Else
  3782. EmitDebugNullObjectError(variable)
  3783. End If
  3784. End If
  3785. ' array.length
  3786. If decl.scope And decl.scope.ident = "___Array" Then
  3787. If decl.ident = "length" Then
  3788. Return Bra(variable + "->scales[0]")
  3789. End If
  3790. If decl.ident = "numberOfDimensions" Then
  3791. Return Bra(variable + "->dims")
  3792. End If
  3793. If decl.ident = "sizeMinusHeader" Then
  3794. Return Bra(variable + "->size")
  3795. End If
  3796. If decl.ident = "elementTypeEncoding" Then
  3797. Return Bra(variable + "->type")
  3798. End If
  3799. End If
  3800. ' string methods
  3801. If decl.scope And decl.scope.ident = "String" Then
  3802. If decl.ident = "length" Then
  3803. 'If exprType._flags & TType.T_VAR Then
  3804. ' Return Bra("(*" + variable + ")->length")
  3805. 'Else
  3806. If variable.StartsWith("&_s") Then
  3807. Return Bra(variable[1..] + ".length")
  3808. Else
  3809. Return Bra(variable + "->length")
  3810. End If
  3811. 'End If
  3812. End If
  3813. End If
  3814. 'If TObjectType(exprType) And (exprType._flags & TType.T_VAR) Then
  3815. ' ' get the object from the pointer
  3816. ' variable = Bra("*" + variable)
  3817. 'End If
  3818. If IsNumericType(decl.ty) Then
  3819. s = variable + ind + decl.munged + " "
  3820. Else If TStringType(decl.ty) Then
  3821. s = variable + ind + decl.munged + " "
  3822. Else If TObjectType(decl.ty) Then
  3823. s = variable + ind + decl.munged + " "
  3824. Else If IsPointerType(decl.ty, 0, TType.T_POINTER) Then
  3825. s = variable + ind + decl.munged + " "
  3826. Else If TFunctionPtrType(decl.ty) Then
  3827. s = variable + ind + decl.munged + " "
  3828. Else If TArrayType(decl.ty) Then
  3829. s = variable + ind + decl.munged + " "
  3830. End If
  3831. Return s
  3832. End Method
  3833. ' " _" + classDecl.actual.munged + "_" + decl.ident.ToLower(
  3834. Method TransIfcArgs:String(funcDecl:TFuncDecl)
  3835. Local args:String
  3836. If Not funcDecl.IsSemanted() Then
  3837. funcDecl.Semant()
  3838. End If
  3839. For Local i:Int=0 Until funcDecl.argDecls.Length
  3840. Local arg:TArgDecl = funcDecl.argDecls[i]
  3841. If args args:+","
  3842. args:+ arg.ident + TransIfcType( arg.ty )
  3843. If arg.init Then
  3844. If TInvokeExpr(arg.init) Then
  3845. args:+ "=" + Enquote(TInvokeExpr(arg.init).decl.munged)
  3846. Else
  3847. args:+ "=" + TransIfcConstExpr(arg.init)
  3848. End If
  3849. End If
  3850. Next
  3851. Return Bra(args)
  3852. End Method
  3853. Method EmitIfcClassFuncDecl(funcDecl:TFuncDecl)
  3854. funcDecl.Semant
  3855. Local func:String
  3856. ' method / function
  3857. If funcDecl.IsMethod() Or funcDecl.IsCTor() Then
  3858. func :+ "-"
  3859. Else
  3860. func :+ "+"
  3861. End If
  3862. If funcDecl.attrs & FUNC_OPERATOR Then
  3863. func :+ BmxEnquote(funcDecl.ident)
  3864. Else
  3865. func :+ funcDecl.ident
  3866. End If
  3867. func :+ TransIfcType(funcDecl.retType, funcDecl.ModuleScope().IsSuperStrict())
  3868. ' function args
  3869. func :+ TransIfcArgs(funcDecl)
  3870. If funcDecl.attrs & DECL_FINAL Then
  3871. func :+ "F"
  3872. Else If funcDecl.attrs & DECL_ABSTRACT Then
  3873. func :+ "A"
  3874. End If
  3875. If funcDecl.attrs & FUNC_OPERATOR Then
  3876. func :+ "O"
  3877. End If
  3878. func :+ "="
  3879. func :+ Enquote(funcDecl.munged)
  3880. Emit func
  3881. End Method
  3882. Method EmitIfcFuncDecl(funcDecl:TFuncDecl)
  3883. Local func:String
  3884. func :+ funcDecl.ident
  3885. ' ensure the function has been semanted
  3886. funcDecl.Semant()
  3887. func :+ TransIfcType(funcDecl.retType, funcDecl.ModuleScope().IsSuperStrict())
  3888. ' function args
  3889. func :+ TransIfcArgs(funcDecl)
  3890. func :+ "="
  3891. func :+ Enquote(funcDecl.munged)
  3892. If funcDecl.castTo Then
  3893. func :+ ":" + funcDecl.castTo
  3894. func :+ " " + funcDecl.munged + "("
  3895. For Local i:Int = 0 Until funcDecl.argDecls.length
  3896. If i Then
  3897. func :+ ", "
  3898. End If
  3899. func :+ funcDecl.argDecls[i].castTo
  3900. Next
  3901. func :+ ")"
  3902. End If
  3903. Emit func
  3904. End Method
  3905. Method TransIfcConstExpr:String(expr:TExpr)
  3906. If Not expr.exprType Then
  3907. expr.Semant()
  3908. End If
  3909. If TStringType(expr.exprType) Then
  3910. Return "$" + EscapeChars(BmxEnquote(expr.Eval()))
  3911. EndIf
  3912. If TArrayType(expr.exprType) Then
  3913. Return Enquote("bbEmptyArray")
  3914. End If
  3915. If TFunctionPtrType(expr.exprType) Then
  3916. If TCastExpr(expr) Then
  3917. If TInvokeExpr(TCastExpr(expr).expr) Then
  3918. Return Enquote(TInvokeExpr(TCastExpr(expr).expr).decl.munged)
  3919. End If
  3920. If TNullExpr(TCastExpr(expr).expr) Then
  3921. Return Enquote("brl_blitz_NullFunctionError")
  3922. End If
  3923. End If
  3924. InternalErr
  3925. End If
  3926. If TObjectType(expr.exprType) Then
  3927. If TCastExpr(expr) Then
  3928. If TNullExpr(TCastExpr(expr).expr) Then
  3929. Return Enquote("bbNullObject")
  3930. End If
  3931. End If
  3932. End If
  3933. If IsPointerType(expr.exprType, 0, TType.T_POINTER) Then
  3934. If TCastExpr(expr) Then
  3935. If TNullExpr(TCastExpr(expr).expr) Then
  3936. Return "0"
  3937. End If
  3938. If TConstExpr(TCastExpr(expr).expr) Then
  3939. Return TConstExpr(TCastExpr(expr).expr).value
  3940. End If
  3941. End If
  3942. End If
  3943. If IsNumericType(expr.exprType) Then
  3944. Local s:String = expr.Eval()
  3945. If Not s Then
  3946. Return "0"
  3947. Else
  3948. If TDecimalType(expr.exprType) Then
  3949. Return s + TransIfcType(expr.exprType)
  3950. Else
  3951. Return s
  3952. End If
  3953. End If
  3954. EndIf
  3955. 'If TObjectType(expr.exprType) And TNullDecl(TObjectType(expr.exprType).classDecl) Then
  3956. ' Return Enquote("bbNullObject")
  3957. 'End If
  3958. End Method
  3959. Method EmitIfcConstDecl(constDecl:TConstDecl)
  3960. Local c:String
  3961. c = constDecl.ident + TransIfcType(constDecl.ty)
  3962. If TExpr(constDecl.init) Then
  3963. c:+ "=" + TransIfcConstExpr(TExpr(constDecl.init))
  3964. End If
  3965. Emit c
  3966. End Method
  3967. Method EmitIfcFieldDecl(fieldDecl:TFieldDecl)
  3968. Local f:String = "." + fieldDecl.ident + TransIfcType(fieldDecl.ty, fieldDecl.ModuleScope().IsSuperStrict())
  3969. f :+ "&"
  3970. Emit f
  3971. End Method
  3972. Method EmitIfcClassDecl(classDecl:TClassDecl)
  3973. Local head:String = classDecl.ident + "^"
  3974. If classDecl.superClass Then
  3975. head :+ classDecl.superClass.ident
  3976. Else
  3977. head :+ "Null"
  3978. End If
  3979. If classDecl.implments Then
  3980. head :+ "@"
  3981. For Local i:Int = 0 Until classDecl.implments.length
  3982. If i Then
  3983. head :+ ","
  3984. End If
  3985. head :+ classDecl.implments[i].ident
  3986. Next
  3987. End If
  3988. Emit head + "{", False
  3989. 'PushMungScope
  3990. BeginLocalScope
  3991. ' fields, globals and consts
  3992. ' For Local decl:TDecl=EachIn classDecl.Decls()
  3993. ' const
  3994. For Local cDecl:TConstDecl = EachIn classDecl.Decls()
  3995. cDecl.Semant()
  3996. EmitIfcConstDecl(cDecl)
  3997. Next
  3998. ' global
  3999. For Local gDecl:TGlobalDecl = EachIn classDecl.Decls()
  4000. gDecl.Semant()
  4001. EmitIfcGlobalDecl(gDecl)
  4002. Next
  4003. ' field
  4004. For Local fDecl:TFieldDecl = EachIn classDecl.Decls()
  4005. fDecl.Semant()
  4006. EmitIfcFieldDecl(fDecl)
  4007. Next
  4008. ' functions
  4009. If Not classDecl.IsExtern() Then
  4010. Emit "-New()=" + Enquote("_" + classDecl.munged + "_New")
  4011. If classHierarchyHasFunction(classDecl, "Delete") Then
  4012. Emit "-Delete()=" + Enquote("_" + classDecl.munged + "_Delete")
  4013. End If
  4014. For Local decl:TDecl=EachIn classDecl.Decls()
  4015. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4016. If fdecl
  4017. If Not equalsIfcBuiltInFunc(classDecl, fdecl) Then
  4018. EmitIfcClassFuncDecl fdecl
  4019. End If
  4020. Continue
  4021. EndIf
  4022. Next
  4023. Local flags:String
  4024. If classDecl.IsAbstract() Then
  4025. flags :+ "A"
  4026. End If
  4027. If classDecl.attrs & DECL_FINAL Then
  4028. flags :+ "F"
  4029. End If
  4030. If classDecl.attrs & CLASS_INTERFACE Then
  4031. flags :+ "I"
  4032. Else If classDecl.IsStruct() Then
  4033. flags :+ "S"
  4034. End If
  4035. Emit "}" + flags + "=" + Enquote(classDecl.munged), False
  4036. Else
  4037. For Local decl:TDecl=EachIn classDecl.Decls()
  4038. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4039. If fdecl
  4040. EmitIfcClassFuncDecl fdecl
  4041. Continue
  4042. EndIf
  4043. Next
  4044. Local flags:String = "E"
  4045. If classDecl.IsInterface() Then
  4046. flags :+ "I"
  4047. Else If classDecl.IsStruct() Then
  4048. flags :+ "S"
  4049. End If
  4050. If classDecl.attrs & DECL_API_WIN32 Then
  4051. flags :+ "W"
  4052. End If
  4053. Emit "}" + flags + "=0", False
  4054. End If
  4055. 'PopMungScope
  4056. EndLocalScope
  4057. End Method
  4058. Method EmitIfcGlobalDecl(globalDecl:TGlobalDecl)
  4059. globalDecl.Semant
  4060. Local g:String = globalDecl.ident
  4061. g:+ TransIfcType(globalDecl.ty, globalDecl.ModuleScope().IsSuperStrict())
  4062. g:+ "&"
  4063. g :+ "="
  4064. g :+ "mem:p("
  4065. If TFunctionPtrType(globalDecl.ty) Then
  4066. g :+ Enquote(TFunctionPtrType(globalDecl.ty).func.munged)
  4067. Else
  4068. g :+ Enquote(globalDecl.munged)
  4069. End If
  4070. g :+ ")"
  4071. Emit g
  4072. End Method
  4073. Method EmitModuleInclude(moduleDecl:TModuleDecl, included:TMap = Null)
  4074. If moduleDecl.filepath Then
  4075. ' a module import
  4076. If FileType(moduleDecl.filepath) = FILETYPE_DIR Or (opt_ismain And moduleDecl.ident = opt_modulename) Then
  4077. Local inc:String = ModuleHeaderFromIdent(moduleDecl.ident, True)
  4078. If Not included Or (included And Not included.Contains(inc)) Then
  4079. Emit "#include <" + inc + ">"
  4080. If included Then
  4081. included.Insert(inc, inc)
  4082. End If
  4083. End If
  4084. Else
  4085. ' a file import...
  4086. Local inc:String = FileHeaderFromFile(moduleDecl, False)
  4087. If Not included Or (included And Not included.Contains(inc)) Then
  4088. Emit "#include ~q" + inc + "~q"
  4089. If included Then
  4090. included.Insert(inc, inc)
  4091. End If
  4092. End If
  4093. End If
  4094. ' DebugLog moduleDecl.filepath
  4095. End If
  4096. End Method
  4097. Method EmitModuleInit(moduleDecl:TModuleDecl)
  4098. If moduleDecl.filepath Then
  4099. ' a module import
  4100. If FileType(moduleDecl.filepath) = FILETYPE_DIR Then
  4101. Emit MungModuleName(moduleDecl) + "();"
  4102. Else
  4103. ' maybe a file import...
  4104. Emit MungImportFromFile(moduleDecl) + "();"
  4105. End If
  4106. End If
  4107. End Method
  4108. Method EmitIncBinFile(ib:TIncbin)
  4109. If FileType(ib.path) = FILETYPE_FILE Then
  4110. Local ident:String = _appInstance.munged + "_ib_" + ib.id
  4111. Local buf:Byte[] = LoadByteArray(ib.path)
  4112. ib.length = buf.length
  4113. Emit "unsigned char " + ident + "[] = {"
  4114. Local s:String
  4115. Local hx:Short[2]
  4116. For Local i:Int = 0 Until buf.length
  4117. Local val:Int = buf[i]
  4118. For Local k:Int=1 To 0 Step -1
  4119. Local n:Int=(val&15)+48
  4120. If n>57 n:+39
  4121. hx[k]=n
  4122. val:Shr 4
  4123. Next
  4124. s :+ "0x" + String.FromShorts( hx,2 )
  4125. s :+ ","
  4126. If s.length > 80 Then
  4127. Emit s
  4128. s = ""
  4129. End If
  4130. Next
  4131. Emit s
  4132. Emit "};"
  4133. End If
  4134. End Method
  4135. Method TransHeader(app:TAppDecl)
  4136. SetOutput("head")
  4137. _app = app
  4138. prefix = app.GetPathPrefix()
  4139. ' TODO
  4140. If Not opt_apptype Then
  4141. app.mainFunc.munged="bb_localmain"
  4142. Else
  4143. app.mainFunc.munged="bb_main"
  4144. End If
  4145. ' track what's been included so far - avoid duplicates
  4146. Local included:TMap = New TMap
  4147. For Local decl:TModuleDecl=EachIn app.imported.Values()
  4148. For Local mdecl:TDecl=EachIn decl.imported.Values()
  4149. MungDecl mdecl
  4150. 'skip mdecls we are not interested in
  4151. If Not TModuleDecl(mdecl) Then Continue
  4152. If app.mainModule = mdecl Then Continue
  4153. If mdecl.ident = "brl.classes" Then Continue
  4154. If mdecl.ident = "brl.blitzkeywords" Then Continue
  4155. EmitModuleInclude(TModuleDecl(mdecl), included)
  4156. Next
  4157. Next
  4158. For Local header:String=EachIn app.headers
  4159. Emit "#include ~q../" + header + "~q"
  4160. Next
  4161. Emit "int " + app.munged + "();"
  4162. For Local decl:TDecl=EachIn app.Semanted()
  4163. If decl.declImported Continue
  4164. MungDecl decl
  4165. Local cdecl:TClassDecl=TClassDecl( decl )
  4166. If Not cdecl Continue
  4167. ' mung, but don't emit
  4168. ' Emit prefix + decl.munged+";"
  4169. 'PushMungScope
  4170. funcMungs = New TMap
  4171. BeginLocalScope
  4172. For Local decl:TDecl=EachIn cdecl.Semanted()
  4173. MungDecl decl
  4174. cdecl.SemantParts()
  4175. Next
  4176. EndLocalScope
  4177. 'PopMungScope
  4178. Next
  4179. ' forward declarations
  4180. For Local decl:TClassDecl=EachIn app.Semanted()
  4181. If decl.declImported Or (decl.IsExtern() And Not decl.IsStruct()) Continue
  4182. If Not decl.IsStruct()
  4183. Emit "struct " + decl.munged + "_obj;"
  4184. Else
  4185. Emit "struct " + decl.munged + ";"
  4186. End If
  4187. If decl.IsInterface() Then
  4188. Emit "extern const struct BBInterface " + decl.munged + "_ifc;"
  4189. End If
  4190. Next
  4191. 'prototypes/header! - structs first
  4192. For Local decl:TDecl=EachIn app.Semanted()
  4193. If decl.declImported Continue
  4194. Local cdecl:TClassDecl=TClassDecl( decl )
  4195. If cdecl
  4196. If cdecl.IsStruct() Then
  4197. EmitStructClassProto cdecl
  4198. End If
  4199. EndIf
  4200. Next
  4201. 'prototypes/header!
  4202. For Local decl:TDecl=EachIn app.Semanted()
  4203. If decl.declImported Continue
  4204. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  4205. If gdecl
  4206. MungDecl gdecl
  4207. If Not TFunctionPtrType(gdecl.ty) Then
  4208. If Not gdecl.IsPrivate() Then
  4209. Emit "extern "+TransRefType( gdecl.ty, "" )+" "+gdecl.munged+";" 'forward reference...
  4210. End If
  4211. Else
  4212. If Not TFunctionPtrType(gdecl.ty).func.noCastGen Then
  4213. ' generate function pointer refs if we haven't been told not to
  4214. ' If Not gdecl.IsExtern() Then
  4215. Emit TransRefType( gdecl.ty, gdecl.munged )+";" 'forward reference...
  4216. ' End If
  4217. End If
  4218. End If
  4219. Continue
  4220. EndIf
  4221. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4222. If fdecl' And Not fdecl.IsExtern()
  4223. ' don't include the main function - it's handled separately
  4224. If fdecl = app.mainFunc Then
  4225. Continue
  4226. End If
  4227. EmitGDBDebug(fdecl)
  4228. EmitFuncDecl( fdecl, True)
  4229. Continue
  4230. EndIf
  4231. Local cdecl:TClassDecl=TClassDecl( decl )
  4232. If cdecl
  4233. If Not cdecl.IsStruct() Then
  4234. If Not cdecl.IsExtern()
  4235. EmitClassProto cdecl
  4236. Else
  4237. EmitExternClassProto cdecl
  4238. End If
  4239. 'Else
  4240. ' EmitStructClassProto cdecl
  4241. End If
  4242. 'Continue
  4243. EndIf
  4244. Next
  4245. End Method
  4246. Method IncBinRequiresRebuild:Int(file:String, incbins:TList)
  4247. ' file doesn't exist?
  4248. If Not FileType(file) Then
  4249. Return True
  4250. End If
  4251. Local timestamp:Int = FileTime(file)
  4252. ' file exists... read header and compare names
  4253. ' read lines until "// ----"
  4254. ' TODO
  4255. Local files:TList = New TList
  4256. Local stream:TStream = ReadFile(file)
  4257. While True
  4258. Local s:String = ReadLine(stream)
  4259. If Not s.StartsWith("// ") Or s.StartsWith("// ----") Then
  4260. Exit
  4261. End If
  4262. Local ind:Int = s.Find("// FILE : ")
  4263. If ind = 0 Then
  4264. files.AddLast(s[10..].Replace("~q",""))
  4265. End If
  4266. Wend
  4267. stream.Close()
  4268. ' different number of files?
  4269. If files.Count() <> incbins.Count() Then
  4270. Return True
  4271. End If
  4272. ' different file names?
  4273. Local count:Int
  4274. For Local s:String = EachIn files
  4275. For Local ib:TIncbin = EachIn incbins
  4276. If s = ib.file Then
  4277. count :+ 1
  4278. Exit
  4279. End If
  4280. Next
  4281. Next
  4282. If count <> files.count() Then
  4283. Return True
  4284. End If
  4285. count = 0
  4286. For Local ib:TIncbin = EachIn incbins
  4287. For Local s:String = EachIn files
  4288. If s = ib.file Then
  4289. count :+ 1
  4290. Exit
  4291. End If
  4292. Next
  4293. Next
  4294. If count <> incbins.count() Then
  4295. Return True
  4296. End If
  4297. For Local ib:TIncbin = EachIn incbins
  4298. If timestamp < FileTime(ib.path) Then
  4299. Return True
  4300. End If
  4301. ' set the length, as we will need this later if we aren't loading the files now.
  4302. ib.length = FileSize(ib.path)
  4303. Next
  4304. Return False
  4305. End Method
  4306. Method TransIncBin(app:TAppDecl)
  4307. If app.incbins.Count() > 0 Then
  4308. SetOutput("incbin")
  4309. Local mung:String = FileMung(False)
  4310. Local name:String = StripAll(app.mainModule.filepath)
  4311. Local file:String = name + ".bmx" + mung + ".incbin.h"
  4312. Local filepath:String = OutputFilePath(opt_filepath, mung, "incbin.h")
  4313. If IncBinRequiresRebuild(filepath, app.incbins) Then
  4314. app.genIncBinHeader = True
  4315. For Local ib:TIncbin = EachIn app.incbins
  4316. Emit "// FILE : " + Enquote(ib.file)
  4317. Next
  4318. Emit "// ----"
  4319. For Local ib:TIncbin = EachIn app.incbins
  4320. EmitIncBinFile(ib)
  4321. Next
  4322. End If
  4323. SetOutput("pre_source")
  4324. Emit "#include ~q" + file + "~q"
  4325. End If
  4326. End Method
  4327. Method TransGlobalInit(decl:TGlobalDecl)
  4328. If TFunctionPtrType(decl.ty) Then
  4329. If TInvokeExpr(decl.init) And Not TInvokeExpr(decl.init).invokedWithBraces Then
  4330. Emit TransGlobal( decl )+"="+TInvokeExpr(decl.init).decl.munged + ";"
  4331. Else
  4332. Emit TransGlobal( decl )+"="+decl.init.Trans()+";"
  4333. End If
  4334. Else
  4335. If Not decl.funcGlobal Then
  4336. Emit TransGlobal( decl )+"="+decl.init.Trans()+";"
  4337. End If
  4338. End If
  4339. End Method
  4340. Method TransSource(app:TAppDecl)
  4341. SetOutput("pre_source")
  4342. ' include our header
  4343. EmitModuleInclude(app.mainModule)
  4344. ' incbins
  4345. TransIncBin(app)
  4346. SetOutput("source")
  4347. ' Private Global declarations
  4348. ' since we don't declare them in the header, they need to be near the top of the source
  4349. For Local decl:TDecl=EachIn app.Semanted()
  4350. If decl.declImported Continue
  4351. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  4352. If gdecl And gdecl.IsPrivate() Then
  4353. If Not TFunctionPtrType(gdecl.ty) Then
  4354. If TConstExpr(gdecl.init) Then
  4355. Emit TransRefType( gdecl.ty, "WW" )+" "+TransGlobalDecl(gdecl)+";"
  4356. gdecl.inited = True
  4357. Else
  4358. If Not gdecl.IsExtern() Then
  4359. Emit TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  4360. Else
  4361. ' delcare in source for any references to it locally in this module
  4362. Emit "extern "+TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  4363. End If
  4364. End If
  4365. Else
  4366. 'Emit TransRefType( gdecl.ty, gdecl.munged ) + ";"
  4367. End If
  4368. Continue
  4369. EndIf
  4370. Next
  4371. For Local gdecl:TGlobalDecl=EachIn app.SemantedGlobals
  4372. If gdecl And gdecl.funcGlobal Then
  4373. MungDecl gdecl
  4374. If Not TFunctionPtrType(gdecl.ty) Then
  4375. Emit "static " + TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  4376. Else
  4377. Emit "static " + TransRefType( gdecl.ty, gdecl.munged ) + ";"
  4378. End If
  4379. Continue
  4380. End If
  4381. Next
  4382. 'definitions!
  4383. For Local decl:TDecl=EachIn app.Semanted()
  4384. If decl.declImported Continue
  4385. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  4386. If gdecl
  4387. If Not TFunctionPtrType(gdecl.ty) And Not gdecl.IsPrivate() Then
  4388. If TConstExpr(gdecl.init) Then
  4389. Emit TransRefType( gdecl.ty, "WW" )+" "+TransGlobalDecl(gdecl)+";"
  4390. gdecl.inited = True
  4391. Else
  4392. If Not gdecl.IsExtern() Then
  4393. Emit TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+ "=" + TransValue(gdecl.ty, "") + ";"
  4394. End If
  4395. End If
  4396. Else
  4397. 'Emit TransRefType( gdecl.ty, gdecl.munged ) + ";"
  4398. End If
  4399. Continue
  4400. EndIf
  4401. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4402. If fdecl And Not fdecl.IsExtern()
  4403. ' don't include the main function - it's handled separately
  4404. If fdecl = app.mainFunc Then
  4405. Continue
  4406. End If
  4407. EmitGDBDebug(fdecl)
  4408. EmitFuncDecl fdecl
  4409. Continue
  4410. EndIf
  4411. Local cdecl:TClassDecl=TClassDecl( decl )
  4412. If cdecl
  4413. EmitGDBDebug(cdecl)
  4414. EmitClassDecl cdecl
  4415. Continue
  4416. EndIf
  4417. Next
  4418. Emit "static int " + app.munged + "_inited" + " = 0;"
  4419. Emit "int " + app.munged + "(){"
  4420. ' initialise stuff
  4421. Emit "if (!" + app.munged + "_inited) {"
  4422. Emit app.munged + "_inited = 1;"
  4423. ' register incbins
  4424. For Local ib:TIncbin = EachIn app.incbins
  4425. Emit "bbIncbinAdd(&" + TStringConst(app.stringConsts.ValueForKey(ib.file)).id + ",&" + app.munged + "_ib_" + ib.id + "," + ib.length + ");"
  4426. Next
  4427. Local importOnce:TMap = New TMap
  4428. ' call any imported mod inits
  4429. For Local decl:TModuleDecl=EachIn app.imported.Values()
  4430. For Local mdecl:TDecl=EachIn decl.imported.Values()
  4431. If TModuleDecl(mdecl) And app.mainModule <> mdecl And mdecl.ident <> "brl.classes" And mdecl.ident <> "brl.blitzkeywords" Then
  4432. If Not importOnce.Contains(mdecl.ident) Then
  4433. EmitModuleInit(TModuleDecl(mdecl))
  4434. importOnce.Insert(mdecl.ident, "")
  4435. End If
  4436. End If
  4437. Next
  4438. Next
  4439. ' register types
  4440. For Local decl:TDecl=EachIn app.Semanted()
  4441. If decl.declImported Continue
  4442. Local cdecl:TClassDecl=TClassDecl( decl )
  4443. If cdecl And Not cdecl.IsExtern()
  4444. If Not cdecl.IsInterface() Then
  4445. If Not cdecl.IsStruct() Then
  4446. Emit "bbObjectRegisterType(&" + cdecl.munged + ");"
  4447. Else
  4448. Emit "bbObjectRegisterStruct(&" + cdecl.munged + "_scope);"
  4449. End If
  4450. Else
  4451. Emit "bbObjectRegisterInterface(&" + cdecl.munged + "_ifc);"
  4452. End If
  4453. EndIf
  4454. Next
  4455. '
  4456. ' defdata init
  4457. If Not app.dataDefs.IsEmpty() Then
  4458. Emit "_defDataOffset = &_defData;"
  4459. End If
  4460. ' initialise globals
  4461. For Local decl:TGlobalDecl=EachIn app.semantedGlobals
  4462. If decl.declImported Continue
  4463. decl.Semant
  4464. ' TODO : what about OnDebugStop etc, who have no init ?
  4465. If decl.init And Not (decl.attrs & DECL_INITONLY) Then
  4466. If decl.scope And TClassDecl(decl.scope) Then
  4467. ' class global inits need to be generated in the correct order.
  4468. ' only generate global inits if the parent class hasn't already been processed,
  4469. ' otherwise, we will skip this global as it should already have been generated.
  4470. If Not TClassDecl(decl.scope).globInit Then
  4471. TClassDecl(decl.scope).globInit = True
  4472. For Local gdecl:TGlobalDecl = EachIn decl.scope._decls
  4473. If gdecl.declImported Continue
  4474. gdecl.Semant
  4475. If gdecl.init And Not (gdecl.attrs & DECL_INITONLY) Then
  4476. TransGlobalInit(gdecl)
  4477. End If
  4478. Next
  4479. End If
  4480. Else
  4481. TransGlobalInit(decl)
  4482. End If
  4483. End If
  4484. Next
  4485. ' now do the local main stuff
  4486. app.mainFunc.Semant()
  4487. EmitLocalDeclarations(app.mainFunc)
  4488. EmitBlock app.mainFunc
  4489. Emit "}"
  4490. Emit "return 0;"
  4491. Emit "}"
  4492. ' redirect string generation to the top of the source
  4493. SetOutput("pre_source")
  4494. ' strings
  4495. For Local s:String = EachIn app.stringConsts.Keys()
  4496. If s Then
  4497. Local key:TStringConst = TStringConst(app.stringConsts.ValueForKey(s))
  4498. If key.count > 0 Then
  4499. Emit "static BBString " + key.id + "={"
  4500. Emit "&bbStringClass,"
  4501. 'Emit "2147483647,"
  4502. Emit s.length + ","
  4503. Local t:String = "{"
  4504. For Local i:Int = 0 Until s.length
  4505. If i Then
  4506. t:+ ","
  4507. End If
  4508. t:+ s[i]
  4509. If i And Not (i Mod 16) Then
  4510. Emit t
  4511. t = ""
  4512. End If
  4513. Next
  4514. Emit t + "}"
  4515. Emit "};"
  4516. End If
  4517. End If
  4518. Next
  4519. ' defdata
  4520. EmitDefDataArray(app)
  4521. ' scope defs
  4522. If Not app.scopedefs.IsEmpty() Then
  4523. For Local val:String = EachIn app.scopedefs.Keys()
  4524. Local i:Int = val.ToInt()
  4525. Emit "struct BBDebugScope_" + i + "{int kind; const char *name; BBDebugDecl decls[" + (i + 1) + "]; };"
  4526. Next
  4527. End If
  4528. End Method
  4529. Method EmitDefDataArray(app:TAppDecl)
  4530. If Not app.dataDefs.IsEmpty() Then
  4531. '
  4532. Emit "static struct bbDataDef * _defDataOffset;"
  4533. Emit "static struct bbDataDef _defData[" + TDefDataDecl.count + "]={"
  4534. For Local decl:TDefDataDecl = EachIn app.dataDefs
  4535. EmitDefData(decl)
  4536. Next
  4537. Emit "};"
  4538. End If
  4539. End Method
  4540. Method EmitDefData(decl:TDefDataDecl)
  4541. For Local i:Int = 0 Until decl.data.length
  4542. Local expr:TExpr = decl.data[i]
  4543. Emit "{"
  4544. Emit TransDefDataType(expr.exprType) + ","
  4545. Emit "{"
  4546. Emit "." + TransDefDataUnionType(expr.exprType) + " = " + expr.Trans()
  4547. Emit "}"
  4548. Emit "},"
  4549. Next
  4550. End Method
  4551. Method EmitIfcImports(impMod:TModuleDecl, processed:TMap)
  4552. For Local decl:TDecl=EachIn impMod.imported.Values()
  4553. Local mdecl:TModuleDecl=TModuleDecl( decl )
  4554. If mdecl And mdecl.ident <> "brl.classes" And mdecl.ident <> "brl.blitzkeywords" Then
  4555. If mdecl.filepath.EndsWith(".bmx")
  4556. If _appInstance.mainModule<>mdecl
  4557. EmitIfcImports(mdecl, processed)
  4558. For Local s:String = EachIn mdecl.fileImports
  4559. If Not processed.Contains("XX" + s + "XX") Then
  4560. Emit "import " + BmxEnquote(s)
  4561. processed.Insert("XX" + s + "XX", "")
  4562. End If
  4563. Next
  4564. End If
  4565. Else
  4566. If Not processed.Contains(mdecl.ident)
  4567. Emit "import " + mdecl.ident
  4568. processed.Insert(mdecl.ident, "")
  4569. End If
  4570. End If
  4571. End If
  4572. Next
  4573. End Method
  4574. Method EmitIfcStructImports(impMod:TModuleDecl, processed:TMap)
  4575. For Local decl:TDecl=EachIn impMod.imported.Values()
  4576. Local mdecl:TModuleDecl=TModuleDecl( decl )
  4577. If mdecl Then
  4578. If mdecl.filepath.EndsWith(".bmx") And _appInstance.mainModule<>mdecl And Not processed.Contains(mdecl)
  4579. EmitIfcStructImports(mdecl, processed)
  4580. processed.Insert(mdecl, mdecl)
  4581. For Local decl:TDecl=EachIn mdecl._decls
  4582. decl.Semant
  4583. ' consts
  4584. Local cdecl:TConstDecl=TConstDecl( decl )
  4585. If cdecl
  4586. EmitIfcConstDecl(cdecl)
  4587. Continue
  4588. End If
  4589. ' classes
  4590. Local tdecl:TClassDecl=TClassDecl( decl )
  4591. If tdecl
  4592. EmitIfcClassDecl(tdecl)
  4593. Continue
  4594. EndIf
  4595. ' functions
  4596. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4597. If fdecl And fdecl <> _appInstance.mainFunc Then
  4598. EmitIfcFuncDecl(fdecl)
  4599. Continue
  4600. End If
  4601. ' globals
  4602. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  4603. If gdecl
  4604. EmitIfcGlobalDecl(gdecl)
  4605. Continue
  4606. End If
  4607. Next
  4608. End If
  4609. End If
  4610. Next
  4611. End Method
  4612. Method FileHeaderFromFile:String(mdecl:TModuleDecl, includePath:Int = False)
  4613. Local name:String = StripAll(mdecl.filepath)
  4614. Local dir:String = ExtractDir(mdecl.filePath)
  4615. Local file:String = name + ".bmx" + FileMung(opt_apptype And (Not mdecl.declImported)) + ".h"
  4616. If mdecl.relPath Then
  4617. Local dir:String = ExtractDir(mdecl.relPath)
  4618. If dir Then
  4619. file = "../" + dir + "/.bmx/" + file
  4620. End If
  4621. End If
  4622. Return file
  4623. End Method
  4624. Method MungImportFromFile:String(mdecl:TModuleDecl)
  4625. Local result:String
  4626. If opt_buildtype <> BUILDTYPE_MODULE Then
  4627. Local dir:String = ExtractDir(mdecl.filepath).ToLower()
  4628. dir = dir[dir.findLast("/") + 1..]
  4629. If dir.EndsWith(".mod") Then
  4630. dir = dir.Replace(".mod", "")
  4631. End If
  4632. Local file:String = StripDir(mdecl.filepath).ToLower()
  4633. result = "_bb_" + dir + "_" + StripExt(file)
  4634. Else
  4635. result = "_bb_" + mdecl.ident
  4636. End If
  4637. 'return with all non-allowed chars (like "-" or " ") removed
  4638. Return TStringHelper.Sanitize(result)
  4639. End Method
  4640. Method TransInterface(app:TAppDecl)
  4641. SetOutput("interface")
  4642. If app.mainModule.IsSuperStrict() Then
  4643. Emit "superstrict"
  4644. End If
  4645. ' module info
  4646. For Local info:String = EachIn app.mainModule.modInfo
  4647. Emit "ModuleInfo " + BmxEnquote(info)
  4648. Next
  4649. Local processed:TMap = New TMap
  4650. ' module imports
  4651. For Local decl:TDecl=EachIn app.mainModule.imported.Values()
  4652. Local mdecl:TModuleDecl=TModuleDecl( decl )
  4653. If mdecl Then
  4654. If mdecl.IsActualModule() Then
  4655. Emit "import " + mdecl.ident
  4656. processed.Insert(mdecl.ident, "")
  4657. Else If Not opt_ismain And mdecl.filepath.EndsWith(".bmx") And app.mainModule<>mdecl
  4658. Local file:String = StripDir(mdecl.filepath)
  4659. If mdecl.relPath Then
  4660. Local dir:String = ExtractDir(mdecl.relPath)
  4661. If dir Then
  4662. file = dir + "/" + file
  4663. End If
  4664. End If
  4665. If Not processed.Contains(file) Then
  4666. Emit "import " + Enquote(file)
  4667. processed.Insert(file, "")
  4668. End If
  4669. End If
  4670. End If
  4671. Next
  4672. ' module imports from other files?
  4673. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain Then
  4674. EmitIfcImports(app.mainModule, processed)
  4675. End If
  4676. ' other imports
  4677. For Local s:String = EachIn app.fileImports
  4678. Emit "import " + BmxEnquote(s)
  4679. Next
  4680. processed = New TMap
  4681. ' imported module structure (consts, classes, functions, etc)
  4682. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain Then
  4683. EmitIfcStructImports(app.mainModule, processed)
  4684. End If
  4685. ' consts
  4686. For Local decl:TDecl=EachIn app.Semanted()
  4687. If decl.IsPrivate() Continue
  4688. Local cdecl:TConstDecl=TConstDecl( decl )
  4689. If cdecl And Not cdecl.declImported
  4690. EmitIfcConstDecl(cdecl)
  4691. End If
  4692. Next
  4693. ' classes
  4694. For Local decl:TDecl=EachIn app.Semanted()
  4695. If decl.IsPrivate() Continue
  4696. Local cdecl:TClassDecl=TClassDecl( decl )
  4697. If cdecl And Not cdecl.declImported
  4698. EmitIfcClassDecl(cdecl)
  4699. EndIf
  4700. Next
  4701. ' functions
  4702. For Local decl:TDecl=EachIn app.Semanted()
  4703. If decl.IsPrivate() Continue
  4704. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4705. If fdecl And fdecl <> app.mainFunc And Not fdecl.declImported Then
  4706. EmitIfcFuncDecl(fdecl)
  4707. End If
  4708. Next
  4709. ' globals
  4710. For Local decl:TDecl=EachIn app.Semanted()
  4711. If decl.IsPrivate() Continue
  4712. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  4713. If gdecl And Not gdecl.declImported
  4714. EmitIfcGlobalDecl(gdecl)
  4715. End If
  4716. Next
  4717. End Method
  4718. Method TransApp( app:TAppDecl )
  4719. If app.mainModule.IsSuperStrict()
  4720. opt_issuperstrict = True
  4721. End If
  4722. TransHeader(app)
  4723. TransSource(app)
  4724. TransInterface(app)
  4725. End Method
  4726. End Type