ctranslator.bmx 204 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197
  1. ' Copyright (c) 2013-2023 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 TLongIntType( ty ) Return "~q" + p + "v~q"
  61. If TULongIntType( ty ) Return "~q" + p + "e~q"
  62. If TSizeTType( ty ) Return "~q" + p + "z~q"
  63. If TWParamType( ty ) Return "~q" + p + "w~q"
  64. If TLParamType( ty ) Return "~q" + p + "x~q"
  65. If TStringType( ty ) Return "~q$~q"
  66. If TInt128Type( ty ) Return "~q" + p + "j~q"
  67. If TFloat128Type( ty ) Return "~q" + p + "k~q"
  68. If TDouble128Type( ty ) Return "~q" + p + "m~q"
  69. If TFloat64Type( ty ) Return "~q" + p + "h~q"
  70. If TArrayType( ty ) Then
  71. Local s:String = "["
  72. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  73. s:+ ","
  74. Next
  75. s:+ "]"
  76. s:+ TransArrayType(TArrayType( ty ).elemType)
  77. Return Enquote(s.Replace("~q", ""))
  78. End If
  79. If TObjectType( ty ) Then
  80. If TObjectType( ty ).classdecl.IsStruct()
  81. Return "~q" + p + "@" + TObjectType(ty).classDecl.ident + "~q"
  82. Else
  83. If Not TObjectType( ty ).classdecl.IsExtern()
  84. Return "~q:" + TObjectType(ty).classDecl.ident + "~q"
  85. Else
  86. If TObjectType( ty ).classdecl.IsInterface() Then
  87. Return "~q" + p + "*#" + TObjectType(ty).classDecl.ident + "~q"
  88. ' ElseIf TObjectType( ty ).classdecl.IsStruct()
  89. ' Return "~q" + p + "@" + TObjectType(ty).classDecl.ident + "~q"
  90. Else
  91. Return "~q" + p + "#" + TObjectType(ty).classDecl.ident + "~q"
  92. End If
  93. End If
  94. End If
  95. End If
  96. If TFunctionPtrType( ty ) Return "~q(~q"
  97. If TEnumType( ty ) Return "~q/" + TEnumType(ty).decl.ident + "~q"
  98. End Method
  99. Method TransDefDataType$( ty:TType)
  100. If TByteType( ty ) Return "~qb~q"
  101. If TShortType( ty ) Return "~qs~q"
  102. If TIntType( ty ) Return "~qi~q"
  103. If TUIntType( ty ) Return "~qu~q"
  104. If TFloatType( ty ) Return "~qf~q"
  105. If TDoubleType( ty ) Return "~qd~q"
  106. If TLongType( ty ) Return "~ql~q"
  107. If TULongType( ty ) Return "~qy~q"
  108. If TSizeTType( ty ) Return "~qz~q"
  109. If TLongIntType( ty ) Return "~qv~q"
  110. If TULongIntType( ty ) Return "~qe~q"
  111. If TStringType( ty ) Return "~q$~q"
  112. If TWParamType( ty ) Return "~qw~q"
  113. If TLParamType( ty ) Return "~qx~q"
  114. End Method
  115. Method TransDefDataConversion$(ty:TType)
  116. If TByteType( ty ) Return "bbConvertToInt"
  117. If TShortType( ty ) Return "bbConvertToInt"
  118. If TIntType( ty ) Return "bbConvertToInt"
  119. If TUIntType( ty ) Return "bbConvertToUInt"
  120. If TFloatType( ty ) Return "bbConvertToFloat"
  121. If TDoubleType( ty ) Return "bbConvertToDouble"
  122. If TLongType( ty ) Return "bbConvertToLong"
  123. If TULongType( ty ) Return "bbConvertToULong"
  124. If TSizeTType( ty ) Return "bbConvertToSizet"
  125. If TLongIntType( ty ) Return "bbConvertToLongInt"
  126. If TULongIntType( ty ) Return "bbConvertToULongInt"
  127. If TStringType( ty ) Return "bbConvertToString"
  128. End Method
  129. Method TransDefDataUnionType$(ty:TType)
  130. If TByteType( ty ) Return "b"
  131. If TShortType( ty ) Return "s"
  132. If TIntType( ty ) Return "i"
  133. If TUIntType( ty ) Return "u"
  134. If TFloatType( ty ) Return "f"
  135. If TDoubleType( ty ) Return "d"
  136. If TLongType( ty ) Return "l"
  137. If TULongType( ty ) Return "y"
  138. If TSizeTType( ty ) Return "z"
  139. If TLongIntType( ty ) Return "v"
  140. If TULongIntType( ty ) Return "e"
  141. If TWParamType( ty ) Return "w"
  142. If TLParamType( ty ) Return "x"
  143. If TStringType( ty ) Return "t"
  144. End Method
  145. Method TransDebugScopeType$(ty:TType)
  146. Local p:String = TransSPointer(ty)
  147. If TByteType( ty ) Return p + "b"
  148. If TShortType( ty ) Return p + "s"
  149. If TIntType( ty ) Return p + "i"
  150. If TUIntType( ty ) Return p + "u"
  151. If TFloatType( ty ) Return p + "f"
  152. If TDoubleType( ty ) Return p + "d"
  153. If TLongType( ty ) Return p + "l"
  154. If TULongType( ty ) Return p + "y"
  155. If TSizeTType( ty ) Return p + "t"
  156. If TLongIntType( ty ) Return p + "v"
  157. If TULongIntType( ty ) Return p + "e"
  158. If TWParamType( ty ) Return p + "W"
  159. If TLParamType( ty ) Return p + "X"
  160. If TInt128Type( ty ) Return p + "j"
  161. If TFloat128Type( ty ) Return p + "k"
  162. If TDouble128Type( ty ) Return p + "m"
  163. If TFloat64Type( ty ) Return p + "h"
  164. If TStringType( ty ) Return "$"
  165. If TArrayType( ty ) Then
  166. Local s:String = "["
  167. If TArrayType( ty ).isStatic Then
  168. s :+ TArrayType( ty ).length
  169. Else
  170. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  171. s:+ ","
  172. Next
  173. End If
  174. s:+ "]"
  175. Return s + TransDebugScopeType(TArrayType( ty ).elemType)
  176. End If
  177. If TObjectType( ty ) Then
  178. If TObjectType( ty ).classdecl.IsStruct() Then
  179. Return p + "@" + TObjectType(ty).classDecl.ident
  180. Else If Not TObjectType( ty ).classdecl.IsExtern()
  181. Return ":" + TObjectType( ty ).classDecl.ident
  182. Else
  183. If TObjectType( ty ).classdecl.IsInterface() Then
  184. Return p + "*#" + TObjectType(ty).classDecl.ident
  185. Else
  186. Return p + "#" + TObjectType(ty).classDecl.ident
  187. End If
  188. End If
  189. End If
  190. If TFunctionPtrType( ty ) Then
  191. Local func:TFuncDecl = TFunctionPtrType( ty ).func
  192. Local s:String = "("
  193. For Local i:Int = 0 Until func.argDecls.length
  194. If i Then
  195. s :+ ","
  196. End If
  197. s :+ TransDebugScopeType(func.argDecls[i].ty)
  198. Next
  199. Return s + ")" + TransDebugScopeType(func.retType)
  200. End If
  201. If TEnumType( ty ) Then
  202. Return "/" + TEnumType( ty ).decl.ident
  203. End If
  204. End Method
  205. Method TransType$( ty:TType, ident:String, fpReturnTypeFunctionArgs:String = Null, fpReturnTypeClassFunc:Int = False)
  206. Local p:String = TransSPointer(ty, True)
  207. If TVoidType( ty ) Or Not ty Then
  208. Return "void"
  209. End If
  210. If TBoolType( ty ) Return "BBINT" + p
  211. If TByteType( ty ) Return "BBBYTE" + p
  212. If TShortType( ty ) Return "BBSHORT" + p
  213. If TIntType( ty ) Return "BBINT" + p
  214. If TUIntType( ty ) Return "BBUINT" + p
  215. If TFloatType( ty ) Return "BBFLOAT" + p
  216. If TDoubleType( ty ) Return "BBDOUBLE" + p
  217. If TLongType( ty ) Return "BBLONG" + p
  218. If TULongType( ty ) Return "BBULONG" + p
  219. If TSizeTType( ty ) Return "BBSIZET" + p
  220. If TLongIntType( ty ) Return "BBLONGINT" + p
  221. If TULongIntType( ty ) Return "BBULONGINT" + p
  222. If TWParamType( ty ) Return "WPARAM" + p
  223. If TLParamType( ty ) Return "LPARAM" + p
  224. If TInt128Type( ty ) Return "BBINT128" + p
  225. If TFloat128Type( ty ) Return "BBFLOAT128" + p
  226. If TDouble128Type( ty ) Return "BBDOUBLE128" + p
  227. If TFloat64Type( ty ) Return "BBFLOAT64" + p
  228. If TStringType( ty ) Then
  229. If ty._flags & TType.T_CHAR_PTR Then
  230. Return "BBBYTE *"
  231. Else If ty._flags & TType.T_SHORT_PTR Then
  232. Return "BBSHORT *"
  233. End If
  234. Return "BBSTRING" + p
  235. End If
  236. If TArrayType( ty ) Then
  237. If TArrayType( ty ).isStatic Then
  238. Return TransType(TArrayType( ty ).elemType, ident)
  239. Else
  240. Return "BBARRAY" + p
  241. End If
  242. End If
  243. If TObjectType( ty ) Then
  244. Return TransObject(TObjectType(ty).classdecl) + p
  245. End If
  246. If TFunctionPtrType( ty ) Then
  247. TFunctionPtrType(ty).func.Semant
  248. Local api:String
  249. If TFunctionPtrType(ty).func.attrs & DECL_API_STDCALL Then
  250. api = " __stdcall "
  251. End If
  252. Local args:String
  253. For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
  254. arg.Semant()
  255. If args Then
  256. args :+ ","
  257. End If
  258. args :+ TransType(arg.ty, "")
  259. Next
  260. Local ret:String = ""
  261. If fpReturnTypeFunctionArgs Then
  262. ret = Bra(fpReturnTypeFunctionArgs)
  263. End If
  264. If fpReturnTypeClassFunc Then
  265. ' typedef for function pointer return type
  266. Return ident + "x" + Bra(api + p +"* " + ident) + Bra(args)
  267. Else
  268. ' if a function F returns another function (let's call it G),
  269. ' then C syntax requires the declaration of F to be nested into that of the type of G
  270. ' e.g. "Function F:RetG(ArgG)(ArgF)" in BlitzMax becomes "RetG(* F(ArgF) )(ArgG)" in C
  271. ' solution: use "* F(ArgF)" as an ident to generate a declaration for G
  272. ' the result will be the declaration for F
  273. Local callable:String = Bra(api + p +"* " + ident + ret)
  274. If TFunctionPtrType(TFunctionPtrType(ty).func.retType) Then
  275. If Not args Then args = " " ' make sure the parentheses aren't ommited even if the parameter list is empty
  276. Return TransType(TFunctionPtrType(ty).func.retType, callable, args)
  277. Else
  278. Local retTypeStr:String = TransType(TFunctionPtrType(ty).func.retType, "")
  279. Return retTypeStr + callable + Bra(args)
  280. End If
  281. End If
  282. End If
  283. If TExternObjectType( ty ) Return "struct " + TExternObjectType( ty ).classDecl.munged + p
  284. If TEnumType( ty ) Return TransType( TEnumType( ty ).decl.ty, ident ) + p
  285. InternalErr "TCTranslator.TransType"
  286. End Method
  287. Method TransIfcType$( ty:TType, isSuperStrict:Int = False )
  288. Local p:String = TransSPointer(ty)
  289. If ty And (ty._flags & TType.T_VAR) Then
  290. p :+ " Var"
  291. End If
  292. If Not ty Then
  293. If opt_issuperstrict Or isSuperStrict Then
  294. Return p
  295. Else
  296. Return "%" + p
  297. End If
  298. End If
  299. If TVoidType( ty ) Then
  300. Return p
  301. End If
  302. If TByteType( ty ) Return "@" + p
  303. If TShortType( ty ) Return "@@" + p
  304. If TIntType( ty ) Return "%" + p
  305. If TUIntType( ty ) Return "|" + p
  306. If TFloatType( ty ) Return "#" + p
  307. If TDoubleType( ty ) Return "!" + p
  308. If TLongType( ty ) Return "%%" + p
  309. If TULongType( ty ) Return "||" + p
  310. If TSizeTType( ty ) Return "%z" + p
  311. If TLongIntType( ty ) Return "%v" + p
  312. If TULongIntType( ty ) Return "%e" + p
  313. If TWParamType( ty ) Return "%w" + p
  314. If TLParamType( ty ) Return "%x" + p
  315. If TInt128Type( ty ) Return "%j" + p
  316. If TFloat128Type( ty ) Return "!k" + p
  317. If TDouble128Type( ty ) Return "!m" + p
  318. If TFloat64Type( ty ) Return "!h" + p
  319. If TStringType( ty ) Then
  320. If ty._flags & TType.T_CHAR_PTR Then
  321. Return "$z"
  322. Else If ty._flags & TType.T_SHORT_PTR Then
  323. Return "$w"
  324. End If
  325. Return "$" + p
  326. End If
  327. If TArrayType( ty ) Then
  328. Local s:String = TransIfcType(TArrayType( ty ).elemType) + "&["
  329. If TArrayType( ty ).isStatic Then
  330. s :+ TArrayType( ty ).length
  331. Else
  332. For Local i:Int = 0 Until TArrayType( ty ).dims - 1
  333. s:+ ","
  334. Next
  335. End If
  336. Return s + "]" + p
  337. End If
  338. If TObjectType( ty ) Then
  339. Local t:String = ":"
  340. If TObjectType(ty).classDecl.IsExtern() Then
  341. If TObjectType(ty).classDecl.IsInterface() Then
  342. t = "??"
  343. ElseIf TObjectType(ty).classDecl.IsStruct() Then
  344. t = "~~"
  345. Else
  346. t = "?"
  347. End If
  348. End If
  349. Local cdecl:TClassDecl = TObjectType(ty).classDecl
  350. ' find first type in hierarchy that isn't private
  351. While cdecl.IsPrivate() And cdecl.superClass <> Null
  352. cdecl = cdecl.superClass
  353. Wend
  354. Local args:String
  355. If cdecl.instArgs And cdecl.instArgs.length Then
  356. args = "<"
  357. For Local i:Int = 0 Until cdecl.instArgs.length
  358. If i Then
  359. args :+ ","
  360. End If
  361. args :+ cdecl.instArgs[i].ToString()
  362. Next
  363. args :+ ">"
  364. End If
  365. Return t + cdecl.ident + args + p
  366. End If
  367. If TFunctionPtrType( ty ) Then
  368. Local t:String = TransIfcType(TFunctionPtrType(ty).func.retType, TFunctionPtrType(ty).func.ModuleScope().IsSuperStrict()) + TransIfcArgs(TFunctionPtrType(ty).func)
  369. If TFunctionPtrType( ty ).func.attrs & DECL_API_STDCALL Then
  370. t :+ "W"
  371. End If
  372. Return t
  373. End If
  374. If TExternObjectType( ty ) Return ":" + TExternObjectType(ty).classDecl.ident + p
  375. If TEnumType( ty ) Then
  376. Return "/" + TEnumType( ty ).decl.ident + p
  377. End If
  378. InternalErr "TCTranslator.TransIfcType"
  379. End Method
  380. Method TransRefType$( ty:TType, ident:String )
  381. Return TransType( ty, ident )
  382. End Method
  383. Method TransValue$( ty:TType,value$, isStructInit:Int = False )
  384. If value
  385. If IsPointerType(ty, 0, TType.T_POINTER) Return value
  386. If TBoolType( ty ) Return "1"
  387. If TShortType( ty ) Return value
  388. If TIntType( ty ) Return value
  389. If TUIntType( ty ) Return value+"U"
  390. If TLongType( ty ) Return value+"LL"
  391. If TULongType( ty ) Return value+"ULL"
  392. If TSizeTType( ty ) Return value
  393. If TLongIntType( ty ) Return value
  394. If TULongIntType( ty ) Return value
  395. If TWParamType( ty ) Return value
  396. If TLParamType( ty ) Return value
  397. If TInt128Type( ty ) Return value
  398. If TFloatType( ty ) Then
  399. If value = "nan" Or value.StartsWith("1.#IND0000") Then
  400. Return "bbPOSNANf"
  401. Else If value="-nan" Or value.StartsWith("-1.#IND0000") Then
  402. Return "bbNEGNANf"
  403. Else If value = "inf" Or value.StartsWith("1.#INF0000") Then
  404. Return "bbPOSINFf"
  405. Else If value = "-inf" Or value.StartsWith("-1.#INF0000") Then
  406. Return "bbNEGINFf"
  407. Else
  408. If value.ToLower().Find("e")>=0 Then
  409. Return value
  410. End If
  411. If value.Find(".") < 0 Then
  412. value :+ ".0"
  413. End If
  414. Return value+"f"
  415. End If
  416. End If
  417. If TDoubleType( ty ) Or TFloat128Type(ty) Or TDouble128Type(ty) Or TFloat64Type(ty) Then
  418. If value = "nan" Or value.StartsWith("1.#IND0000") Then
  419. Return "bbPOSNANd"
  420. Else If value="-nan" Or value.StartsWith("-1.#IND0000") Then
  421. Return "bbNEGNANd"
  422. Else If value = "inf" Or value.StartsWith("1.#INF0000") Then
  423. Return "bbPOSINFd"
  424. Else If value = "-inf" Or value.StartsWith("-1.#INF0000") Then
  425. Return "bbNEGINFd"
  426. Else
  427. If value.ToLower().Find("e") >=0 Then
  428. Return value
  429. End If
  430. If value.Find(".") < 0 Then
  431. value :+ ".0"
  432. End If
  433. Return value
  434. End If
  435. End If
  436. If TStringType( ty ) Return TransStringConst(value )
  437. If TByteType( ty ) Return value
  438. If TEnumType( ty ) Return value
  439. Else
  440. If TBoolType( ty ) Return "0"
  441. If TIntrinsicType( ty) Then
  442. If IsPointerType(ty, 0, TType.T_POINTER) Then
  443. Return "0"
  444. Else
  445. Return "{}"
  446. End If
  447. End If
  448. If TNumericType( ty ) Return "0" ' numeric and pointers
  449. If TStringType( ty ) Then
  450. If isStructInit Then
  451. Return "&bbEmptyString"
  452. Else
  453. Return Bra("&bbEmptyString")
  454. End If
  455. End If
  456. If TArrayType( ty ) Then
  457. If isStructInit Then
  458. If TArrayType( ty ).isStatic Then
  459. Local t:String = "{"
  460. For Local i:Int = 0 Until Int(TArrayType( ty ).length)
  461. If i Then
  462. t :+ ","
  463. End If
  464. t :+ TransValue(TArrayType( ty ).elemType, "", True)
  465. Next
  466. Return t + "}"
  467. Else
  468. Return "&bbEmptyArray"
  469. End If
  470. Else
  471. Return Bra("&bbEmptyArray")
  472. End If
  473. End If
  474. If TObjectType( ty ) Then
  475. If TObjectType( ty ).classDecl.IsExtern() Or TObjectType( ty ).classDecl.IsStruct() Then
  476. If TObjectType( ty ).classDecl.IsInterface() Or IsPointerType(ty,0,TType.T_POINTER) Or (Not TObjectType( ty ).classDecl.IsStruct()) Then
  477. Return "0"
  478. Else
  479. If TObjectType( ty ).classDecl.IsStruct() Then
  480. Local t:String
  481. If Not isStructInit Then
  482. t = "((" + TransType(ty, "") + "){"
  483. Else
  484. t = "{"
  485. End If
  486. Local fields:Int
  487. For Local f:TFieldDecl = EachIn TObjectType( ty ).classDecl.Decls()
  488. If fields Then
  489. t :+ ","
  490. End If
  491. fields = True
  492. t :+ TransValue(f.ty, "", True)
  493. Next
  494. If Not isStructInit Then
  495. t :+ "})"
  496. Else
  497. t :+ "}"
  498. End If
  499. Return t
  500. Else
  501. Return "{}"
  502. End If
  503. End If
  504. Else
  505. If isStructInit Then
  506. Return "&bbNullObject"
  507. Else
  508. Return Bra(Bra(TransType(ty, "*")) + "&bbNullObject")
  509. End If
  510. End If
  511. End If
  512. If TFunctionPtrType( ty) Return "(&brl_blitz_NullFunctionError)" ' todo ??
  513. If TEnumType( ty ) Then
  514. If TEnumType( ty ).decl.isFlags Then
  515. Return "0"
  516. Else
  517. Return TEnumType( ty ).decl.values[0].Value()
  518. End If
  519. End If
  520. EndIf
  521. InternalErr "TCTranslator.TransValue"
  522. End Method
  523. Method TransArgs$( args:TExpr[],decl:TFuncDecl, objParam:String = Null )
  524. 'If decl.ident="AddS" DebugStop
  525. Local t$
  526. 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
  527. ' object cast to match param type
  528. If TClassDecl(decl.scope) Then
  529. t :+ Bra(TransObject(TClassDecl(decl.scope).GetLatestFuncDecl(decl).scope, TClassDecl(decl.scope).IsStruct()))
  530. End If
  531. t:+ objParam
  532. End If
  533. For Local i:Int=0 Until decl.argDecls.Length
  534. Local argDecl:TArgDecl = decl.argDecls[i]
  535. Local ty:TType = TArgDecl(argDecl.actual).ty
  536. If t t:+","
  537. If i < args.length
  538. Local arg:TExpr = args[i]
  539. ' object cast to match param type
  540. If TObjectType(ty) And Not TObjectType(ty).classDecl.IsStruct() Then
  541. Local fdecl:TFuncDecl = decl
  542. If TClassDecl(decl.scope) Then
  543. fdecl = TClassDecl(decl.scope).GetOriginalFuncDecl(decl)
  544. End If
  545. t :+ Bra(TransObject(TObjectType(TArgDecl(fdecl.argDecls[i].actual).ty).classDecl))
  546. End If
  547. Local varRef:String
  548. If TNullExpr(arg) Then
  549. t :+ TransValue(ty, Null)
  550. Continue
  551. Else If TIndexExpr(arg) And (ty._flags & TType.T_VAR)Then
  552. varRef = "&"
  553. Else If TStringType(ty) And (ty._flags & TType.T_VAR) Then
  554. If TCastExpr(arg) And TStringType(TCastExpr(arg).expr.exprType) Then
  555. varRef = "&"
  556. End If
  557. Else If TArrayType(ty) And (ty._flags & TType.T_VAR) Then
  558. If (TVarExpr(arg) And TArrayType(TVarExpr(arg).exprType) Or (TMemberVarExpr(arg) And TArrayType(TMemberVarExpr(arg).exprType))) And Not (arg.exprType._flags & TType.T_VAR) Then
  559. varRef = "&"
  560. End If
  561. Else If TObjectType(ty) And (ty._flags & TType.T_VAR) Then
  562. If (TVarExpr(arg) Or TMemberVarExpr(arg)) And TObjectType(arg.exprType) And Not (arg.exprType._flags & TType.T_VAR) Then
  563. varRef = "&"
  564. End If
  565. Else If TFunctionPtrType(ty) Or IsPointerType(ty, TType.T_BYTE) Then
  566. If TFunctionPtrType(ty) And (ty._flags & TType.T_VAR) Then
  567. varRef = "&"
  568. End If
  569. If TInvokeExpr(arg) And Not TInvokeExpr(arg).decl.IsMethod() Then
  570. t :+ varRef
  571. If IsPointerType(ty, TType.T_BYTE) Then
  572. t:+ TInvokeExpr(arg).Trans()
  573. Else
  574. ' need to test scopes to see if we need to use the current instance's function or not
  575. ' use the "actual", not the copy we made for the function pointer.
  576. Local fdecl:TFuncDecl = TFuncDecl(TInvokeExpr(arg).decl.actual)
  577. If Not fdecl.munged Then
  578. MungDecl fdecl
  579. TInvokeExpr(arg).decl.munged = fdecl.munged
  580. End If
  581. If TClassDecl(fdecl.scope) Then
  582. ' current scope is related to function scope?
  583. If _env.ClassScope() And _env.FuncScope() And _env.FuncScope().IsMethod() Then
  584. If _env.ClassScope().ExtendsClass(TClassDecl(fdecl.scope)) Then
  585. Local scope:TScopeDecl = _env.scope
  586. Local obj:String = Bra("struct " + scope.munged + "_obj*")
  587. Local class:String = "o->clas"
  588. t:+ class + "->f_" + fdecl.ident + MangleMethod(fdecl)
  589. Else
  590. t:+ fdecl.munged
  591. End If
  592. Else
  593. t:+ fdecl.munged
  594. End If
  595. Else
  596. t:+ fdecl.munged
  597. End If
  598. End If
  599. Continue
  600. End If
  601. ' some cases where we are passing a function pointer via a void* parameter.
  602. If TCastExpr(arg) And TInvokeExpr(TCastExpr(arg).expr) And Not TInvokeExpr(TCastExpr(arg).expr).invokedWithBraces Then
  603. t:+ varRef
  604. If Not TInvokeExpr(TCastExpr(arg).expr).decl.munged Then
  605. t:+ TInvokeExpr(TCastExpr(arg).expr).decl.actual.munged
  606. Else
  607. t:+ TInvokeExpr(TCastExpr(arg).expr).decl.munged
  608. End If
  609. Continue
  610. End If
  611. ' Object -> Byte Ptr
  612. If IsPointerType(ty, TType.T_BYTE) And TObjectType(arg.exprType) Then
  613. t:+ varRef + Bra("bbObjectToFieldOffset" + Bra("(BBObject*)" + arg.Trans()))
  614. Continue
  615. End If
  616. Else If IsNumericType(ty) Then
  617. If TObjectType(arg.exprType) 'And TObjectType(args[i].exprType).classDecl = TClassDecl.nullObjectClass Then
  618. err "NULL"
  619. t:+ "0"
  620. Continue
  621. End If
  622. Else If TEnumType(ty) And (ty._flags & TType.T_VAR) Then
  623. If (TVarExpr(arg) Or TMemberVarExpr(arg)) And TEnumType(arg.exprType) And Not (arg.exprType._flags & TType.T_VAR) Then
  624. varRef = "&"
  625. End If
  626. End If
  627. If argDecl.castTo Then
  628. If argDecl.castTo.Find("*") >= 0 Then
  629. t:+ Bra(argDecl.castTo) + varRef + arg.Trans()
  630. Else
  631. t:+ varRef + Bra(argDecl.castTo) + arg.Trans()
  632. End If
  633. Else
  634. t :+ varRef
  635. Local tc:String = TransTemplateCast( ty,arg.exprType,arg.Trans() )
  636. ' *sigh*
  637. ' if var is going to var, remove any leading dereference character.
  638. ' rather hacky. Would be better to cast variable to varptr during semanting (well done if you can work out where!)
  639. If arg.exprType.EqualsType( ty.ActualType() ) And (ty._flags & TType.T_VAR) And ( (arg.exprType._flags & TType.T_VAR) Or (TSelfExpr(arg) And TObjectType(arg.exprType) And TObjectType(arg.exprType).classdecl.IsStruct())) Then
  640. If tc.startswith("*") Then
  641. tc = tc[1..]
  642. End If
  643. End If
  644. t:+ tc
  645. 't:+TransTemplateCast( ty,args[i].exprType,args[i].Trans() )
  646. End If
  647. Else
  648. argDecl.Semant()
  649. ' default values
  650. Local init:TExpr = argDecl.init
  651. If init Then
  652. If TConstExpr(init) Then
  653. If TObjectType(TConstExpr(init).exprType) Then
  654. t:+"NULLNULLNULL"
  655. ' And TNullDecl(TObjectType(TConstExpr(init).exprType).classDecl)) Or (TConstExpr(init).value = "bbNullObject") Then
  656. If TStringType(argDecl.ty) Then
  657. t :+ "&bbEmptyString"
  658. Else If TArrayType(argDecl.ty) Then
  659. t :+ "&bbEmptyArray"
  660. Else
  661. t :+ "&bbNullObject"
  662. End If
  663. Else
  664. t:+ argDecl.init.Trans()
  665. End If
  666. Else If TFunctionPtrType(ty) Then
  667. If TInvokeExpr(init) Then
  668. t:+ TInvokeExpr(init).decl.munged
  669. End If
  670. Else
  671. t:+ argDecl.init.Trans()
  672. End If
  673. End If
  674. End If
  675. Next
  676. Return Bra(t)
  677. End Method
  678. Method TransArgsTypes$( args:TExpr[],declArgTypes:TType[])
  679. Local t$
  680. For Local i:Int=0 Until args.Length
  681. If t t:+","
  682. t:+TransTemplateCast( declArgTypes[i],args[i].exprType,args[i].Trans() )
  683. Next
  684. Return Bra(t)
  685. End Method
  686. Method TransPtrCast$( ty:TType,src:TType,expr$,cast$ )
  687. If IsPointerType(ty, 0, TType.T_POINTER | TType.T_VARPTR | TType.T_VAR) Or TFunctionPtrType(ty) Then
  688. ' TODO : pointer stuff
  689. If TNullType(src) Return TransValue(ty, Null)
  690. Return expr
  691. End If
  692. 'If expr = "NULL" DebugStop
  693. ' If TIntType(ty) And TStringType(src) Then
  694. 'DebugStop
  695. ' Return "bbObjectDowncast" + Bra(expr + ",&" + TStringType(src).cDecl.munged)
  696. ' End If
  697. If TNullType(src)
  698. Return TransValue(ty, Null)
  699. End If
  700. If TStringType(ty) And TObjectType(src) Then
  701. If Not TStringType(ty).cDecl Then
  702. ty.Semant()
  703. End If
  704. 'If TNullDecl(TObjectType(src).classDecl) Then
  705. ' Return "&bbEmptyString"
  706. 'End If
  707. Return Bra("(BBString *)bbObjectStringcast" + Bra("(BBOBJECT)" + expr ))
  708. End If
  709. 'If TArrayType(ty) And TObjectType(src) Then
  710. ' If TNullDecl(TObjectType(src).classDecl) Then
  711. ' Return "&bbEmptyArray"
  712. ' End If
  713. 'End If
  714. If TVarPtrType(src) And TNumericType(ty) Then
  715. Return "*" + expr
  716. End If
  717. If TIntType(ty) And TStringType(src) Then
  718. Return Bra(expr + " != &bbEmptyString")
  719. End If
  720. ' If TIntType(ty) And TObjectType(src) Then
  721. ' Return Bra(expr + " != &bbNullObject")
  722. ' End If
  723. If TObjectType(ty) And TStringType(src) Then
  724. Return expr
  725. End If
  726. If Not TObjectType(ty) Or Not TObjectType(src) Then
  727. InternalErr "TCTranslator.TransPtrCast"
  728. End If
  729. Local t$=TransType(ty, "TODO: TransPtrCast")
  730. If src.GetClass().IsInterface() Or ty.GetClass().IsInterface() cast="dynamic"
  731. If src.GetClass().IsInterface() And Not ty.GetClass().IsInterface() Then
  732. Return cast+"_cast<"+TransType(ty, "TODO: TransPtrCast")+">"+Bra( expr )
  733. End If
  734. 'upcast?
  735. If src.GetClass().ExtendsClass( ty.GetClass() ) Return expr
  736. If TObjectType(ty) Then
  737. Return Bra(Bra(TransObject(TObjectType(ty).classDecl)) + "bbObjectDowncast" + Bra("(BBOBJECT)" + expr + ",(BBClass*)&" + TObjectType(ty).classDecl.munged))
  738. End If
  739. Return cast+"_cast<"+TransType(ty, "TODO: TransPtrCast")+">"+Bra( expr )
  740. End Method
  741. '***** Utility *****
  742. Method TransLocalDecl$( decl:TLocalDecl,init:TExpr, declare:Int = False, outputInit:Int = True )
  743. Local initTrans:String
  744. If outputInit Then
  745. Local cast:String
  746. If TObjectType(decl.ty) And Not TObjectType(decl.ty).classDecl.IsStruct() Then
  747. cast = Bra(TransType(decl.ty, ""))
  748. End If
  749. If TInvokeExpr(init) And Not TInvokeExpr(init).invokedWithBraces Then
  750. initTrans = "=" + cast + TInvokeExpr(init).decl.munged
  751. Else
  752. If Not TArrayType(decl.ty) Or Not TArrayType(decl.ty).isStatic Then
  753. initTrans = "=" + cast + init.Trans()
  754. Else
  755. initTrans = "[" + TArrayType(decl.ty).length + "]=" + TransValue(decl.ty, Null, True)
  756. End If
  757. End If
  758. End If
  759. Local volTrans:String = " "
  760. If decl.volatile Then
  761. volTrans = " volatile "
  762. End If
  763. If Not declare And opt_debug Then
  764. Local ty:TType = decl.ty
  765. If Not TObjectType( ty ) Or (TObjectType( ty ) And Not TObjectType( ty ).classDecl.IsStruct()) Then
  766. If TIntrinsicType(ty) Then
  767. If Not TConstExpr(init) Then
  768. Return decl.munged + initTrans
  769. End If
  770. Else If Not TArrayType(ty) Or Not TArrayType(ty).isStatic Then
  771. Return decl.munged + initTrans
  772. End If
  773. Else If TObjectType( ty ) And TObjectType( ty ).classDecl.IsStruct() Then
  774. If Not TConstExpr(init) Then
  775. Return decl.munged + initTrans
  776. End If
  777. End If
  778. Else
  779. If TFunctionPtrType(decl.ty) Then
  780. If TInvokeExpr(init) And Not TInvokeExpr(init).invokedWithBraces Then
  781. Return TransType( decl.ty, decl.munged ) + " = " + TInvokeExpr(init).decl.munged
  782. Else
  783. Return TransType( decl.ty, decl.munged ) + initTrans
  784. End If
  785. Else
  786. Local ty:TType = decl.ty
  787. If TVoidType( ty ) Or Not ty Then
  788. ty = init.exprType
  789. End If
  790. If TObjectType(ty) Then
  791. If TObjectType(ty).classdecl.IsExtern() Then
  792. If TObjectType(ty).classdecl.IsInterface() Then
  793. Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
  794. Else
  795. Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
  796. End If
  797. Else
  798. If TObjectType(ty).classdecl.IsStruct() Then
  799. Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
  800. Else
  801. 'If decl.volatile Then
  802. Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
  803. 'Else
  804. ' Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
  805. 'End If
  806. End If
  807. End If
  808. Else
  809. Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
  810. End If
  811. End If
  812. End If
  813. End Method
  814. Method TransLocalDeclNoInit$( decl:TVarDecl )
  815. If TFunctionPtrType(decl.ty) Then
  816. Return TransType( decl.ty, decl.munged ) + "=" + TransValue(decl.ty, "")
  817. Else
  818. If TObjectType(decl.ty) Then
  819. If TObjectType(decl.ty).classdecl.IsExtern() Then
  820. If Not TObjectType(decl.ty).classdecl.IsStruct() Then
  821. Return TransType( decl.ty, decl.munged )+" "+decl.munged+"=" + TransValue(decl.ty, "")
  822. Else
  823. Return TransType( decl.ty, decl.munged )+" "+decl.munged
  824. End If
  825. Else
  826. If Not TObjectType(decl.ty).classdecl.IsStruct() Then
  827. Local cast:String = Bra(TransObject(TObjectType(decl.ty).classDecl))
  828. If TLocalDecl(decl) And TLocalDecl(decl).volatile Then
  829. Return TransType( decl.ty, decl.munged )+" volatile "+decl.munged + "=" + cast + TransValue(decl.ty, "")
  830. Else
  831. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + cast + TransValue(decl.ty, "")
  832. End If
  833. Else
  834. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
  835. End If
  836. End If
  837. Else
  838. If TLocalDecl(decl) And TLocalDecl(decl).volatile Then
  839. Return TransType( decl.ty, decl.munged )+" volatile "+decl.munged + "=" + TransValue(decl.ty, "")
  840. Else
  841. If TArrayType(decl.ty) And TArrayType(decl.ty).isStatic Then
  842. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "[" + TArrayType(decl.ty).length + "]"
  843. Else
  844. Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
  845. End If
  846. End If
  847. End If
  848. End If
  849. End Method
  850. Method TransGlobalDecl$( gdecl:TGlobalDecl )
  851. Local glob:String
  852. If Not gdecl.funcGlobal Then
  853. If Not (gdecl.attrs & DECL_INITONLY) Then
  854. glob :+"static " + TransThreadedGlobal(gdecl) + TransType( gdecl.init.exprType, gdecl.munged )+" "
  855. End If
  856. glob :+ gdecl.munged+"="
  857. If (TNewObjectExpr(gdecl.init) Or TNewArrayExpr(gdecl.init)) And Not (gdecl.attrs & DECL_INITONLY) Then
  858. glob :+ "0;~n"
  859. glob :+ indent + "if (" + gdecl.munged + "==0) {~n"
  860. glob :+ indent + "~t" + gdecl.munged + "=" + gdecl.init.Trans() + ";~n"
  861. glob :+ indent + "}"
  862. Else If TArrayExpr(gdecl.init) And Not (gdecl.attrs & DECL_INITONLY) Then
  863. glob :+ "0;~n"
  864. Emit glob
  865. Emit "if (" + gdecl.munged + "==0) {"
  866. glob = gdecl.munged + "=" + gdecl.init.Trans() + ";"
  867. Emit glob
  868. Emit "}"
  869. glob = ""
  870. Else
  871. If gdecl.init Then
  872. If TFunctionPtrType(gdecl.ty) Then
  873. If TInvokeExpr(gdecl.init) And Not TInvokeExpr(gdecl.init).invokedWithBraces Then
  874. glob :+ TInvokeExpr(gdecl.init).decl.munged
  875. Else
  876. glob :+ gdecl.init.Trans()
  877. End If
  878. Else If Not TConstExpr(gdecl.init) And Not (gdecl.attrs & DECL_INITONLY) Then
  879. ' for non const, we need to add an initialiser
  880. glob :+ TransValue(gdecl.ty, "") + ";~n"
  881. glob :+ indent +"static " + TransThreadedGlobal(gdecl) + " int _" + gdecl.munged + "_inited = 0;~n"
  882. glob :+ indent + "if (!_" + gdecl.munged + "_inited) {~n"
  883. glob :+ indent + "~t_" + gdecl.munged + "_inited = 1;~n"
  884. glob :+ indent + "~t" + gdecl.munged + " = " + gdecl.init.Trans() + ";~n"
  885. glob :+ indent + "}"
  886. Else
  887. If TObjectType(gdecl.ty) Then
  888. glob :+ Bra(TransObject(TObjectType(gdecl.ty).classDecl))
  889. End If
  890. glob :+ gdecl.init.Trans()
  891. End If
  892. Else
  893. If TFunctionPtrType(gdecl.ty) Then
  894. glob :+ "&brl_blitz_NullFunctionError"
  895. Else
  896. glob :+ "0"
  897. End If
  898. End If
  899. End If
  900. Else
  901. glob :+ "static " + TransThreadedGlobal(gdecl) + " int _" + gdecl.munged + "_inited = 0;~n"
  902. glob :+ indent + "if (!_" + gdecl.munged + "_inited) {~n"
  903. glob :+ indent + "~t_" + gdecl.munged + "_inited = 1;~n"
  904. glob :+ indent + "~t" + gdecl.munged + " = "
  905. If gdecl.init Then
  906. glob :+ gdecl.init.Trans()
  907. Else
  908. glob :+ TransValue(gdecl.ty, "")
  909. End If
  910. glob :+ ";~n"
  911. glob :+ indent + "}"
  912. End If
  913. Return glob
  914. End Method
  915. Method TransExportDef:String(decl:TFuncDecl, withApi:Int = True)
  916. Local t:String = decl.munged
  917. If withApi And decl.attrs & DECL_API_STDCALL Then
  918. t :+ "@"
  919. Local size:Int
  920. For Local arg:TArgDecl = EachIn decl.argDecls
  921. size :+ arg.ty.GetSize()
  922. Next
  923. t :+ size
  924. End If
  925. Return t
  926. End Method
  927. Method CreateLocal2$( ty:TType, t$ )
  928. Local tmp:TLocalDecl=New TLocalDecl.Create( "", ty,Null, True )
  929. MungDecl tmp
  930. If TShortType(ty) Then
  931. Emit TransType(ty, "") + " " + tmp.munged + " = bbStringToWString" + Bra(t)+ ";"
  932. Else
  933. Emit TransType(ty, "") + " " + tmp.munged + " = (BBBYTE*)bbStringToCString" + Bra(t)+ ";"
  934. End If
  935. customVarStack.Push(tmp.munged)
  936. Return tmp.munged
  937. End Method
  938. Method EmitPushErr()
  939. Emit "pushErr();"
  940. End Method
  941. Method EmitSetErr( info$ )
  942. Emit "errInfo=~q"+info.Replace( "\","/" )+"~q;"
  943. End Method
  944. Method EmitPopErr()
  945. Emit "popErr();"
  946. End Method
  947. '***** Declarations *****
  948. Method TransStatic$( decl:TDecl )
  949. If decl.IsExtern() Then
  950. If Not decl.munged
  951. Return decl.ident
  952. End If
  953. Return decl.munged
  954. Else If _env And decl.scope And decl.scope=_env.ClassScope()
  955. ' calling a class function from a method?
  956. If TFuncDecl(decl) And _env.ClassScope() And _env.FuncScope() And _env.FuncScope().IsMethod() And Not (decl.attrs & FUNC_PTR) And Not _env.ClassScope().IsStruct() Then
  957. Local scope:TScopeDecl = _env.ClassScope()
  958. Local obj:String = Bra("struct " + scope.munged + "_obj*")
  959. Local class:String = "o->clas"
  960. Return class + "->f_" + decl.ident + MangleMethod(TFuncDecl(decl))
  961. Else
  962. Return decl.munged
  963. End If
  964. Else If TClassDecl( decl.scope )
  965. 'Return decl.scope.munged+"::"+decl.munged
  966. Return decl.munged
  967. Else If TModuleDecl( decl.scope )
  968. Return decl.munged
  969. Else If TFuncDecl(decl.scope)
  970. Return decl.munged
  971. Else If TGlobalDecl(decl)
  972. Return decl.munged
  973. Else If TBlockDecl(decl.scope)
  974. Return decl.munged
  975. Else If TEnumDecl(decl.scope)
  976. Select decl.ident
  977. Case "Values"
  978. Return "bbEnumValues"
  979. Default
  980. Return decl.munged
  981. End Select
  982. EndIf
  983. InternalErr "TCTranslator.TransStatic"
  984. End Method
  985. Method TransThreadedGlobal:String( decl:TDecl )
  986. If decl.attrs & DECL_THREADED Then
  987. Return "BBThreadLocal "
  988. Else
  989. Return ""
  990. End If
  991. End Method
  992. Method TransTemplateCast$( ty:TType,src:TType,expr$ )
  993. ' *sigh*
  994. ' if var is going to var, remove any leading dereference character.
  995. ' rather hacky. Would be better to cast variable to varptr during semanting (well done if you can work out where!)
  996. 'If src.EqualsType( ty.ActualType() ) And (ty._flags & TType.T_VAR) And (src._flags & TType.T_VAR) Then
  997. ' If expr.startswith("*") Then
  998. ' expr = expr[1..]
  999. ' End If
  1000. 'End If
  1001. If ty=src Return expr
  1002. ty=ty.ActualType()
  1003. 'src=src.ActualType()
  1004. If src.EqualsType( ty ) Return expr
  1005. Return TransPtrCast( ty,src,expr,"static" )
  1006. End Method
  1007. Method TransGlobal$( decl:TGlobalDecl )
  1008. Return TransStatic( decl )
  1009. End Method
  1010. Method TransField$( decl:TFieldDecl,lhs:TExpr )
  1011. If lhs Then
  1012. Return TransFieldRef(decl, TransSubExpr( lhs ), lhs.exprType)
  1013. Else
  1014. Return TransFieldRef(decl, "o", Null)
  1015. End If
  1016. ' Local swiz$
  1017. ' If TObjectType( decl.ty )
  1018. ' If TObjectType( decl.ty ).classDecl.IsInterface() swiz=".p"
  1019. ' EndIf
  1020. ' If lhs Return TransSubExpr( lhs )+"->"+decl.munged+swiz
  1021. ' Return decl.munged+swiz
  1022. End Method
  1023. Method TransFunc$( decl:TFuncDecl,args:TExpr[],lhs:TExpr, sup:Int = False, scope:TScopeDecl = Null )
  1024. ' for calling the super class method instead
  1025. Local tSuper:String
  1026. If sup Then
  1027. tSuper = "->super"
  1028. End If
  1029. If Not decl.munged
  1030. MungDecl decl
  1031. End If
  1032. 'If decl.IsMethod()
  1033. If lhs And Not TSelfExpr(lhs) Then
  1034. If TStringType(lhs.exprType) Then
  1035. Return decl.munged + TransArgs(args, decl, TransSubExpr( lhs ))
  1036. End If
  1037. If TStmtExpr(lhs) Then
  1038. lhs.Trans()
  1039. lhs = TStmtExpr(lhs).expr
  1040. End If
  1041. If TVarExpr(lhs) Then
  1042. Local cdecl:TClassDecl
  1043. If TObjectType(TVarExpr(lhs).decl.ty) Then
  1044. cdecl = TObjectType(TVarExpr(lhs).decl.ty).classDecl
  1045. Else If TArrayType(TVarExpr(lhs).decl.ty) Then
  1046. Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1047. End If
  1048. If decl.attrs & FUNC_PTR Then
  1049. 'Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  1050. Local op:String
  1051. If cdecl.IsStruct() Then op = "." Else op = "->"
  1052. Return TransSubExpr( lhs ) + op + decl.munged+TransArgs( args,decl, Null)
  1053. Else
  1054. 'Local lvar:String = CreateLocal(lhs, False)
  1055. 'Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1056. If decl.scope.IsExtern()
  1057. If Not cdecl.IsStruct() Then
  1058. 'Return decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  1059. Return Bra(TransSubExpr( lhs )) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  1060. 'Return Bra(lvarInit) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, lvar ))
  1061. End If
  1062. Err "TODO extern types not allowed methods"
  1063. Else
  1064. If cdecl And cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  1065. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface((BBObject*)" + TransSubExpr( lhs ) + ", " + "(BBInterface*)&" + cdecl.munged + "_ifc)"))
  1066. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  1067. ' Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + lvarInit + ", " + "&" + cdecl.munged + "_ifc)"))
  1068. ' Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1069. Else
  1070. If cdecl And cdecl.IsStruct() Then
  1071. Local pref:String
  1072. If decl.IsMethod() Then
  1073. pref = "_"
  1074. End If
  1075. If Not isPointerType(lhs.exprType) Then
  1076. Return pref + decl.munged+TransArgs( args,decl, "&" + TransSubExpr( lhs ) )
  1077. Else
  1078. Return pref + decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1079. End If
  1080. Else
  1081. If cdecl Then
  1082. Local obj:String = TransSubExpr( lhs )
  1083. Local preObj:String = obj
  1084. If opt_debug Then
  1085. preObj = TransDebugNullObjectError(obj, cdecl)
  1086. End If
  1087. Local class:String = Bra(preObj) + "->clas" + tSuper
  1088. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, obj )
  1089. Else
  1090. If TEnumDecl(decl.scope) Then
  1091. ' since we already have the ordinal, we can simply output that
  1092. If decl.ident = "Ordinal" Then
  1093. Return Bra(TransSubExpr( lhs ))
  1094. Else
  1095. Return decl.munged + Bra(TransSubExpr( lhs ))
  1096. End If
  1097. End If
  1098. End If
  1099. ' Local class:String = Bra(lvarInit) + "->clas" + tSuper
  1100. ' Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1101. End If
  1102. End If
  1103. End If
  1104. End If
  1105. Else If TNewObjectExpr(lhs) Then
  1106. Local cdecl:TClassDecl = TNewObjectExpr(lhs).classDecl
  1107. If cdecl.IsStruct() Then
  1108. ' create a local variable of the inner invocation
  1109. Local lvar:String = CreateLocal(lhs)
  1110. Local t:String
  1111. If decl.IsMethod() Then
  1112. t = "_"
  1113. End If
  1114. Return t + decl.munged+TransArgs( args,decl, "&" + lvar )
  1115. Else
  1116. If decl.IsMethod() Then
  1117. Local class:String = cdecl.munged
  1118. Return class + "." + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, TransSubExpr( lhs ) )
  1119. Else
  1120. Local class:String = Bra(Bra("struct " + cdecl.munged + "_obj*") + Bra(TransSubExpr( lhs ))) + "->clas" + tSuper
  1121. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl )
  1122. End If
  1123. End If
  1124. Else If TCastExpr(lhs) Then
  1125. Local ty:TType = TCastExpr(lhs).ty
  1126. If TObjectType(ty) Then
  1127. ' create a local variable of the inner invocation
  1128. Local lvar:String = CreateLocal(lhs, False, False)
  1129. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1130. Local cdecl:TClassDecl = TObjectType(ty).classDecl
  1131. Local obj:String = Bra(TransObject(cdecl))
  1132. If decl.attrs & FUNC_PTR Then
  1133. Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  1134. Else
  1135. ' Null test
  1136. If opt_debug Then
  1137. lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
  1138. End If
  1139. If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  1140. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface((BBObject*)" + obj + lvarInit + ", " + "(BBInterface*)&" + cdecl.munged + "_ifc)"))
  1141. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1142. Else
  1143. Local class:String = Bra("(" + obj + lvarInit + ")->clas" + tSuper)
  1144. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1145. End If
  1146. End If
  1147. Else If TEnumType(ty) Then
  1148. If TEnumDecl(decl.scope) Then
  1149. ' since we already have the ordinal, we can simply output that
  1150. If decl.ident = "Ordinal" Then
  1151. Return Bra(TransSubExpr( lhs ))
  1152. Else
  1153. Return decl.munged + Bra(TransSubExpr( lhs ))
  1154. End If
  1155. End If
  1156. End If
  1157. Else If TMemberVarExpr(lhs) Then
  1158. If TObjectType(TMemberVarExpr(lhs).decl.ty) Then
  1159. Local cdecl:TClassDecl = TObjectType(TMemberVarExpr(lhs).decl.ty).classDecl
  1160. Local obj:String = Bra(TransObject(cdecl))
  1161. If decl.scope.IsExtern()
  1162. If TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct() Then
  1163. Local lvar:String = CreateLocal(lhs, False, False)
  1164. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1165. Return Bra(lvarInit) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, lvar ))
  1166. Else
  1167. Return decl.munged + Bra(TransArgs( args,decl, TransSubExpr( lhs ) ))
  1168. End If
  1169. Else
  1170. If cdecl.IsStruct() Then
  1171. Local pref:String
  1172. If decl.IsMethod() Then
  1173. pref = "_"
  1174. End If
  1175. If Not isPointerType(lhs.exprType) Then
  1176. Return pref + decl.munged+TransArgs( args,decl, "&" + TransSubExpr( lhs ) )
  1177. Else
  1178. Return pref + decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1179. End If
  1180. Else
  1181. If decl.attrs & FUNC_PTR Then
  1182. Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
  1183. Else
  1184. Local lvar:String = CreateLocal(lhs, False, False)
  1185. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1186. ' Null test
  1187. If opt_debug Then
  1188. lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
  1189. End If
  1190. If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  1191. Local obj:String = Bra(TransObject(cdecl))
  1192. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface((BBObject*)" + obj + lvarInit + ", " + "(BBInterface*)&" + cdecl.munged + "_ifc)"))
  1193. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1194. Else
  1195. Local class:String = Bra("(" + obj + lvarInit + ")->clas" + tSuper)
  1196. Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1197. End If
  1198. End If
  1199. End If
  1200. End If
  1201. Else If TArrayType(TMemberVarExpr(lhs).decl.ty) Then
  1202. Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1203. End If
  1204. Else If TInvokeExpr(lhs) Then
  1205. If TEnumType(lhs.exprType) Then
  1206. If decl.ident = "Ordinal" Then
  1207. Return Bra(TransSubExpr( lhs ))
  1208. Else
  1209. Return decl.munged + Bra(TransSubExpr( lhs ))
  1210. End If
  1211. End If
  1212. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  1213. ' create a local variable of the inner invocation
  1214. Local lvar:String = CreateLocal(lhs, True)
  1215. Local pref:String
  1216. If decl.IsMethod() Then
  1217. pref = "_"
  1218. End If
  1219. If Not isPointerType(lhs.exprType) Then
  1220. Return pref + decl.munged+TransArgs( args,decl, "&" + lvar )
  1221. Else
  1222. Return pref + decl.munged+TransArgs( args,decl, lvar)
  1223. End If
  1224. Else
  1225. ' create a local variable of the inner invocation
  1226. Local lvar:String = CreateLocal(lhs, False, False)
  1227. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1228. ' Null test
  1229. If opt_debug Then
  1230. Local cdecl:TClassDecl = TClassDecl(decl.scope)
  1231. lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
  1232. End If
  1233. Local obj:String = Bra(TransObject(decl.scope))
  1234. Local class:String = Bra("(" + obj + lvarInit +")->clas" + tSuper)
  1235. Return class + "->" + TransFuncPrefix(decl.scope, decl)+ FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1236. End If
  1237. 'Local obj:String = Bra("struct " + decl.scope.munged + "_obj*")
  1238. 'Local class:String = Bra("(" + obj + TransSubExpr( lhs ) +")->clas" + tSuper)
  1239. 'Local class:String = Bra("&" + decl.scope.munged)
  1240. 'Return class + "->" + TransFuncPrefix(decl.scope, decl.ident) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
  1241. Else If TInvokeMemberExpr(lhs)
  1242. If TEnumType(lhs.exprType) Then
  1243. If decl.ident = "Ordinal" Then
  1244. Return Bra(TransSubExpr( lhs ))
  1245. Else
  1246. Return decl.munged + Bra(TransSubExpr( lhs ))
  1247. End If
  1248. End If
  1249. ' create a local variable of the inner invocation
  1250. Local lvar:String
  1251. Local lvarInit:String
  1252. If Not decl.scope.IsExtern() And TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  1253. lvar = CreateLocal(lhs, True)
  1254. Else
  1255. lvar = CreateLocal(lhs, False, False)
  1256. lvarInit = Bra(lvar + " = " + lhs.Trans())
  1257. End If
  1258. If decl.scope.IsExtern()
  1259. If TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct() Then
  1260. Return Bra(lvarInit) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, lvar ))
  1261. End If
  1262. Return "// TODO"
  1263. Else
  1264. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  1265. If Not isPointerType(lhs.exprType) Then
  1266. Return "_" + decl.munged+TransArgs( args,decl, "&" + lvar )
  1267. Else
  1268. Return "_" + decl.munged+TransArgs( args,decl, lvar )
  1269. End If
  1270. Else
  1271. Local cdecl:TClassDecl = TClassDecl(decl.scope)
  1272. ' Null test
  1273. If opt_debug Then
  1274. lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
  1275. End If
  1276. If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
  1277. Local obj:String = Bra(TransObject(cdecl))
  1278. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface((BBObject*)" + obj + lvarInit + ", " + "(BBInterface*)&" + cdecl.munged + "_ifc)"))
  1279. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1280. Else
  1281. Local obj:String = lvarInit + "->clas" + tSuper
  1282. Return obj + "->" + TransFuncPrefix(decl.scope, decl)+ FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1283. End If
  1284. End If
  1285. End If
  1286. Else If TIndexExpr(lhs) Then
  1287. If TEnumType(lhs.exprType) Then
  1288. If decl.ident = "Ordinal" Then
  1289. Return Bra(TransSubExpr( lhs ))
  1290. Else
  1291. Return decl.munged + Bra(TransSubExpr( lhs ))
  1292. End If
  1293. End If
  1294. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  1295. Local lvar:String = CreateLocal(lhs, True, False)
  1296. Local pref:String
  1297. If decl.IsMethod() Then
  1298. pref = "_"
  1299. End If
  1300. If Not isPointerType(lhs.exprType) Then
  1301. Return pref + decl.munged+TransArgs( args,decl, "&" + lvar )
  1302. Else
  1303. Return pref + decl.munged+TransArgs( args,decl, lvar )
  1304. End If
  1305. Else
  1306. Local lvar:String = CreateLocal(lhs, False, False)
  1307. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1308. ' Local loc:String = CreateLocal(lhs)
  1309. Local obj:String = Bra(TransObject(decl.scope))
  1310. Local cdecl:TClassDecl = TClassDecl(decl.scope)
  1311. ' Null test
  1312. If opt_debug Then
  1313. lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
  1314. End If
  1315. If decl.attrs & FUNC_PTR Then
  1316. Local op:String
  1317. If cdecl.IsStruct() Then op = "." Else op = "->"
  1318. Return lhs.Trans() + op + decl.munged+TransArgs( args,decl, Null)
  1319. Else
  1320. If decl.scope.IsExtern()
  1321. 'Local cdecl:TClassDecl = TClassDecl(decl.scope)
  1322. If Not cdecl.IsStruct() Then
  1323. Return Bra(lvarInit) + "->vtbl->" + decl.munged + Bra(TransArgs( args,decl, lvar ))
  1324. End If
  1325. Err "TODO extern types not allowed methods"
  1326. Else
  1327. 'Local cdecl:TClassDecl = TClassDecl(decl.scope)
  1328. If cdecl And (cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl)) Then
  1329. Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface((BBObject*)" + obj + lvarInit + ", " + "(BBInterface*)&" + cdecl.munged + "_ifc)"))
  1330. Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1331. Else
  1332. Local class:String = Bra(lvarInit + "->clas" + tSuper)
  1333. Return class + "->" + TransFuncPrefix(decl.scope, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1334. End If
  1335. End If
  1336. End If
  1337. End If
  1338. Else If TEnumType(lhs.exprType) Then
  1339. If decl.ident = "Ordinal" Then
  1340. Return Bra(TransSubExpr( lhs ))
  1341. Else
  1342. Return decl.munged + Bra(TransSubExpr( lhs ))
  1343. End If
  1344. Else If TInvokeSuperExpr(lhs) Then
  1345. Local lvar:String = CreateLocal(lhs, False, False)
  1346. Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
  1347. Local class:String = Bra(lvarInit + "->clas" + tSuper)
  1348. Return class + "->" + TransFuncPrefix(decl.scope, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
  1349. Else
  1350. InternalErr "TCTranslator.TransFunc"
  1351. End If
  1352. 'Return TransSubExpr( lhs )+"->"+decl.munged+TransArgs( args,decl )
  1353. 'Return decl.munged+TransArgs( args,decl, TransSubExpr( lhs ) )
  1354. End If
  1355. ' ((brl_standardio_TCStandardIO_obj*)o->clas)->md_Read(o, xxx, xxx)
  1356. If decl.IsMethod() Or decl.IsField() Then
  1357. If Not (decl.attrs & FUNC_PTR) Then
  1358. Local class:String
  1359. If Not scope Then
  1360. scope = decl.scope
  1361. If TClassDecl(scope) And Not TClassDecl(scope).IsStruct() Then
  1362. Local obj:String = Bra(TransObject(scope))
  1363. class = "(" + obj + "o)->clas" + tSuper
  1364. ' Null test
  1365. If opt_debug Then
  1366. Emit TransDebugNullObjectError("o", TClassDecl(scope)) + ";"
  1367. End If
  1368. End If
  1369. Else
  1370. class = Bra("&" + scope.munged) + tSuper
  1371. End If
  1372. 'Local obj:String = Bra("struct " + scope.munged + "_obj*")
  1373. 'Local class:String = Bra("(" + obj + "o)->clas" + tSuper)
  1374. 'Local class:String = Bra("&" + decl.scope.munged)
  1375. If TEnumDecl(scope) Then
  1376. ' since we already have the ordinal, we can simply output that
  1377. If decl.ident = "Ordinal" Then
  1378. Return Bra(TransSubExpr( lhs ))
  1379. Else
  1380. Return decl.munged + Bra(TransSubExpr( lhs ))
  1381. End If
  1382. Else If TClassDecl(scope) Then
  1383. If TClassDecl(scope).IsStruct() Then
  1384. Return "_" + decl.munged+TransArgs( args,decl, "o" )
  1385. Else
  1386. Return class + "->" + TransFuncPrefix(scope, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, "o" )
  1387. End If
  1388. End If
  1389. InternalErr "TCTranslator.TransFunc.2"
  1390. Else
  1391. ' Null test
  1392. If opt_debug Then
  1393. Emit TransDebugNullObjectError("o", TClassDecl(decl.scope)) + ";"
  1394. End If
  1395. Local obj:String
  1396. If TClassDecl(scope) And Not TClassDecl(scope).IsStruct() Then
  1397. obj = Bra(TransObject(decl.scope))
  1398. End If
  1399. Return Bra(obj + "o") + "->" + decl.munged+TransArgs( args,decl )
  1400. End If
  1401. End If
  1402. ' for want of a better place to put it...
  1403. ' It may be possible to have the generate via the TransStatic call below, but we'd need to inject a custom arg somewhere else then
  1404. If TEnumDecl(decl.scope) And decl.ident = "Values" Then
  1405. Return "bbEnumValues" + Bra(decl.scope.munged + "_BBEnum_impl")
  1406. End If
  1407. Return TransStatic( decl )+TransArgs( args,decl )
  1408. End Method
  1409. Method TransObject:String(decl:TScopeDecl, this:Int = False)
  1410. If decl.ident = "Object"
  1411. Return "BBOBJECT"
  1412. Else If decl.ident = "String" Then
  1413. Return "BBSTRING"
  1414. Else
  1415. If TClassDecl(decl) And TClassDecl(decl).IsStruct() Then
  1416. Local t:String = "struct "
  1417. If decl.IsExtern() Then
  1418. t :+ decl.ident
  1419. Else
  1420. t :+ decl.munged
  1421. End If
  1422. If this Then
  1423. Return t + "*"
  1424. Else
  1425. Return t
  1426. End If
  1427. Else
  1428. If decl.IsExtern() Then
  1429. Return "struct " + decl.ident + "*"
  1430. Else
  1431. Return "struct " + decl.munged + "_obj*"
  1432. End If
  1433. End If
  1434. End If
  1435. End Method
  1436. Method TransFuncClass:String(decl:TClassDecl)
  1437. If decl.ident = "Object"
  1438. Return Bra("&bbObjectClass")
  1439. Else
  1440. Return Bra("&" + decl.munged)
  1441. End If
  1442. End Method
  1443. Method TransFuncPrefix:String(decl:TScopeDecl, fdecl:TFuncDecl)
  1444. Local ident:String = fdecl.ident
  1445. If Not decl Or decl.ident = "Object" Or equalsBuiltInFunc(fdecl.ClassScope(), fdecl)
  1446. Return ""
  1447. Else
  1448. If fdecl.IsMethod() Then
  1449. Return "m_"
  1450. Else
  1451. Return "f_"
  1452. End If
  1453. End If
  1454. End Method
  1455. Method TransSuperFunc$( decl:TFuncDecl,args:TExpr[], scope:TScopeDecl )
  1456. Return TransFunc(decl, args, Null, True, scope)
  1457. ' If decl.IsMethod()
  1458. ' Return decl.ClassScope().munged+".md_"+decl.ident+TransArgs( args,decl, "o" )
  1459. ' Else
  1460. ' Return decl.ClassScope().munged+".fn_"+decl.ident+TransArgs( args,decl)
  1461. ' End If
  1462. End Method
  1463. Method TransAscExpr:String(expr:TAscExpr)
  1464. Return "bbStringAsc" + Bra(expr.expr.Trans())
  1465. End Method
  1466. Method TransChrExpr:String(expr:TChrExpr)
  1467. Return "bbStringFromChar" + Bra(expr.expr.Trans())
  1468. End Method
  1469. Method TransLenExpr:String(expr:TLenExpr)
  1470. 'constant strings do not have "->length", so we use the
  1471. 'precalculated value
  1472. If TConstExpr(expr.expr) Then
  1473. If TStringType(expr.expr.exprType) Then
  1474. Return TConstExpr(expr.expr).value.Length
  1475. End If
  1476. End If
  1477. If TStringType(expr.expr.exprType) Then
  1478. Return Bra(expr.expr.Trans()) + "->length"
  1479. Else If TArrayType(expr.expr.exprType) Then
  1480. Return Bra(expr.expr.Trans()) + "->scales[0]"
  1481. Else If TCastExpr(expr.expr) Then
  1482. If TArrayType(TCastExpr(expr.expr).expr.exprType) Then
  1483. Return Bra(TCastExpr(expr.expr).expr.Trans()) + "->scales[0]"
  1484. End If
  1485. 'other types just have a length of "1"
  1486. Else
  1487. Return "1"
  1488. End If
  1489. End Method
  1490. Method TransSizeOfExpr:String(expr:TSizeOfExpr)
  1491. Local cexpr:TConstExpr = TConstExpr(expr.expr)
  1492. If cexpr Then
  1493. If TNumericType(cexpr.exprType) Then
  1494. Return "sizeof" + Bra(TransType(cexpr.exprType, ""))
  1495. ' strings
  1496. Else If TStringType(cexpr.exprType) Then
  1497. ' length of const string * 2 bytes per char
  1498. Return Len(cexpr.value) * 2
  1499. End If
  1500. Else
  1501. If TNumericType(expr.expr.exprType) Then
  1502. ' remove Var-ness first, if any
  1503. Local t:TType = expr.expr.exprType.Copy()
  1504. If t._flags & TType.T_VAR Then
  1505. t._flags :~ TType.T_VAR
  1506. End If
  1507. Return "sizeof" + Bra(TransType(t, ""))
  1508. ' strings
  1509. Else If TStringType(expr.expr.exprType) Then
  1510. 'unicode chars each take 2 bytes
  1511. Return Bra(expr.expr.Trans()) + "->length * 2"
  1512. ' arrays
  1513. Else If TArrayType(expr.expr.exprType) Then
  1514. 'normal exprType is something like "int[]" that
  1515. 'is why it has to be checked against elemType
  1516. Local elemType:TType = TArrayType( expr.expr.exprType ).elemType
  1517. ' numerics - including numeric pointers
  1518. If TNumericType(elemType) Then
  1519. 'multiply element count * size of element type
  1520. Return Bra(expr.expr.Trans()) + "->scales[0] * sizeof" + Bra(TransType(elemType, ""))
  1521. ' everything else : string, array, object, function pointer - are all pointers
  1522. Else
  1523. 'arrays of objects are of size: elementCount * pointerSize
  1524. Return Bra(expr.expr.Trans()) + "->scales[0] * sizeof(void*)"
  1525. EndIf
  1526. ' objects
  1527. Else If TObjectType(expr.expr.exprType) Then
  1528. If TObjectType( expr.expr.exprType ).classDecl.ident = "Object" Then
  1529. Return "0"
  1530. Else
  1531. Local cdecl:TClassDecl = TObjectType( expr.expr.exprType ).classDecl
  1532. If cdecl.IsStruct() Then
  1533. If TIdentTypeExpr(expr.expr) Then
  1534. If cdecl.IsExtern() Then
  1535. Return "sizeof" + Bra("struct " + cdecl.ident)
  1536. Else
  1537. Return "sizeof" + Bra("struct " + cdecl.munged)
  1538. End If
  1539. Else
  1540. Return "sizeof" + Bra(expr.expr.Trans())
  1541. End If
  1542. Else
  1543. If TIdentTypeExpr(expr.expr) Then
  1544. Return Bra(Bra(TransFuncClass(cdecl)) + "->obj_size")
  1545. Else
  1546. Return Bra(Bra(expr.expr.Trans()) + "->clas->obj_size")
  1547. End If
  1548. End If
  1549. End If
  1550. End If
  1551. End If
  1552. InternalErr "TCTranslator.TransSizeOfExpr"
  1553. End Method
  1554. Method TransStackAllocExpr:String(expr:TStackAllocExpr)
  1555. Return "bbStackAlloc" + Bra(expr.expr.Trans())
  1556. End Method
  1557. Method TransFieldOffsetExpr:String(expr:TFieldOffsetExpr)
  1558. Local t:String = "offsetof("
  1559. Local cdecl:TClassDecl = TIdentTypeExpr(expr.typeExpr).cdecl
  1560. t :+ "struct " + cdecl.munged
  1561. If Not cdecl.IsStruct() Then
  1562. t :+ "_obj"
  1563. End If
  1564. Return t + ", " + TVarExpr(expr.fieldExpr).decl.munged + ")"
  1565. End Method
  1566. '***** Expressions *****
  1567. Method TransConstExpr$( expr:TConstExpr )
  1568. If TStringType(expr.exprType) Then
  1569. Return TransStringConst(expr.value)
  1570. Else
  1571. Return TransValue( expr.exprType,expr.value )
  1572. End If
  1573. End Method
  1574. Method TransStringConst:String(value:String)
  1575. If value Then
  1576. _appInstance.mapStringConsts(value)
  1577. End If
  1578. Local sc:TStringConst = TStringConst(_app.stringConsts.ValueForKey(value))
  1579. Local s:String
  1580. If Not sc Then
  1581. s = "bbEmptyString"
  1582. Else
  1583. sc.used :+ 1
  1584. s = sc.id
  1585. End If
  1586. Return Bra("(BBString*)&" + s)
  1587. End Method
  1588. Method StringConstId:String(value:String)
  1589. Local sc:TStringConst = TStringConst(_app.stringConsts.ValueForKey(value))
  1590. If sc Then
  1591. sc.used :+ 1
  1592. Return sc.id
  1593. End If
  1594. InternalErr "Missing const for string : " + value
  1595. End Method
  1596. Method TransNewObjectExpr$( expr:TNewObjectExpr )
  1597. Local t$
  1598. If Not expr.classDecl.IsStruct() And (Not expr.ctor.argDecls Or expr.ctor.argDecls.length = 0) Then
  1599. If expr.instanceExpr Then
  1600. t = "bbObjectNew(" + Bra(expr.instanceExpr.Trans()) + "->clas)"
  1601. Else
  1602. If ClassHasObjectField(expr.classDecl) Then
  1603. t = Bra(TransObject(TScopeDecl(expr.classDecl.actual))) + "bbObjectNew((BBClass *)&" + expr.classDecl.actual.munged + ")"
  1604. Else
  1605. t = Bra(TransObject(TScopeDecl(expr.classDecl.actual))) + "bbObjectAtomicNew((BBClass *)&" + expr.classDecl.actual.munged + ")"
  1606. End If
  1607. End If
  1608. Else
  1609. Local ctorMunged:String
  1610. If expr.classDecl = expr.ctor.scope Then
  1611. ctorMunged = expr.ctor.munged
  1612. Else
  1613. ctorMunged = expr.classDecl.actual.munged + "_" + expr.ctor.ident + MangleMethod(expr.ctor)
  1614. End If
  1615. If expr.instanceExpr Then
  1616. If expr.classDecl.IsStruct() Then
  1617. t = ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor)
  1618. Else
  1619. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, Bra(expr.instanceExpr.Trans()) + "->clas" )
  1620. End If
  1621. Else
  1622. If ClassHasObjectField(expr.classDecl) And Not expr.classDecl.IsStruct() Then
  1623. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, "&" + expr.classDecl.actual.munged )
  1624. Else
  1625. If expr.classDecl.IsStruct() Then
  1626. t = ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor)
  1627. Else
  1628. t = "_" + ctorMunged + "_ObjectNew" + TransArgs( expr.args,expr.ctor, "&" + expr.classDecl.actual.munged)
  1629. End If
  1630. End If
  1631. End If
  1632. End If
  1633. 'Local t$="(new "+expr.classDecl.actual.munged+")"
  1634. 'If expr.ctor t:+"->"+expr.ctor.actual.munged+TransArgs( expr.args,expr.ctor )
  1635. Return t
  1636. End Method
  1637. Method TransNewArrayExpr$( expr:TNewArrayExpr )
  1638. If expr.expr.length = 1 Then
  1639. If TObjectType(expr.ty) And TObjectType(expr.ty).classdecl.IsStruct() And Not IsPointerType(expr.ty) Then
  1640. Return "bbArrayNew1DStruct" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans() + ", sizeof" + ..
  1641. Bra(TransObject(TObjectType(expr.ty).classdecl)) + ", _" + TObjectType(expr.ty).classdecl.munged + "_New")
  1642. Else
  1643. Return "bbArrayNew1D" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans())
  1644. End If
  1645. Else
  1646. ' multiple array
  1647. Local s:String
  1648. For Local i:Int = 0 Until expr.expr.length
  1649. If i Then
  1650. s:+ ", "
  1651. End If
  1652. s:+ expr.expr[i].Trans()
  1653. Next
  1654. If TObjectType(expr.ty) And TObjectType(expr.ty).classdecl.IsStruct() And Not IsPointerType(expr.ty) Then
  1655. Return "bbArrayNewStruct" + Bra(TransArrayType(expr.ty) + ", sizeof" + Bra(TransObject(TObjectType(expr.ty).classdecl)) + ..
  1656. ", _" + TObjectType(expr.ty).classdecl.munged + "_New, " + expr.expr.length + ", " + s)
  1657. Else
  1658. Return "bbArrayNew" + Bra(TransArrayType(expr.ty) + ", " + expr.expr.length + ", " + s)
  1659. End If
  1660. End If
  1661. End Method
  1662. Method TransSelfExpr$( expr:TSelfExpr )
  1663. If (TObjectType(expr.exprType) And TObjectType(expr.exprType).classDecl.IsStruct()) Or ..
  1664. (TClassType(expr.exprType) And TClassType(expr.exprType).classDecl.IsStruct()) Then
  1665. Return "*o"
  1666. End If
  1667. Return "o"
  1668. End Method
  1669. Method TransIdentTypeExpr:String(expr:TIdentTypeExpr)
  1670. Return "struct " + expr.cdecl.munged + "_obj"
  1671. End Method
  1672. Method TransCastExpr$( expr:TCastExpr )
  1673. Local t$= expr.expr.Trans()
  1674. Local dst:TType=expr.ty
  1675. Local src:TType=expr.expr.exprType
  1676. If TNumericType(src) And (src._flags & TType.T_VAR) Then
  1677. ' var number being cast to a varptr
  1678. If (dst._flags & TType.T_VARPTR) Then
  1679. Return "&" + Bra(t)
  1680. End If
  1681. End If
  1682. If (dst._flags & TType.T_VARPTR) Or (dst._flags & TType.T_VAR) Then
  1683. If Not TConstExpr(expr.expr) Then
  1684. If TInvokeExpr(expr.expr) Return t
  1685. If TByteType( src) Return Bra("&"+t)
  1686. If TShortType( src) Return Bra("&"+t)
  1687. If TFloatType( src) Return Bra("&"+t)
  1688. If TIntType( src) Return Bra("&"+t)
  1689. If TUIntType( src) Return Bra("&"+t)
  1690. If TLongType( src) Return Bra("&"+t)
  1691. If TULongType( src) Return Bra("&"+t)
  1692. If TSizeTType( src) Return Bra("&"+t)
  1693. If TLongIntType( src) Return Bra("&"+t)
  1694. If TULongIntType( src) Return Bra("&"+t)
  1695. If TDoubleType( src) Return Bra("&"+t)
  1696. If TInt128Type( src) Return Bra("&"+t)
  1697. If TFloat128Type( src) Return Bra("&"+t)
  1698. If TDouble128Type( src) Return Bra("&"+t)
  1699. If TFloat64Type( src) Return Bra("&"+t)
  1700. If TWParamType( src) Return Bra("&"+t)
  1701. If TLParamType( src) Return Bra("&"+t)
  1702. If TObjectType(src) Then
  1703. If TObjectType(src).classDecl.IsExtern() Or (dst._flags & TType.T_VARPTR) Then
  1704. Return Bra("&" + t)
  1705. Else
  1706. If TObjectType(dst) Then
  1707. Return Bra("&" + t)
  1708. Else
  1709. Return Bra("bbObjectToFieldOffset" + Bra("(BBObject*)" + "&" + t))
  1710. End If
  1711. End If
  1712. End If
  1713. If TFunctionPtrType(src) Return Bra("&"+t)
  1714. 'If TPointerType( src) Return Bra("&"+t)
  1715. Else
  1716. Return Bra(TransValue(TConstExpr(expr.expr).ty, TConstExpr(expr.expr).value))
  1717. End If
  1718. Else If IsPointerType( dst, 0, TType.T_POINTER | TType.T_CHAR_PTR | TType.T_SHORT_PTR )
  1719. If TArrayType(src) Then
  1720. If TArrayType(src).isStatic Then
  1721. Return Bra("&" + Bra(t))
  1722. Else
  1723. Return Bra(Bra(TransType(dst, "")) + "BBARRAYDATA(" + t + ",1)")
  1724. End If
  1725. End If
  1726. 'If TByteType(src) And Not IsPointerType(src, TType.T_BYTE, TType.T_POINTER) Return Bra("&"+t)
  1727. If TStringType(src) Then
  1728. Local tmp:String
  1729. If IsPointerType( dst, 0, TType.T_SHORT_PTR ) Or IsPointerType( dst, TType.T_SHORT, TType.T_PTR ) Then
  1730. tmp = CreateLocal2(NewPointerType(TType.T_SHORT), t)
  1731. Else
  1732. tmp = CreateLocal2(NewPointerType(TType.T_BYTE), t)
  1733. End If
  1734. Return tmp
  1735. End If
  1736. If (TStringType(dst) And IsPointerType( dst, 0, TType.T_CHAR_PTR | TType.T_SHORT_PTR )) And TNullType(src) Then
  1737. Return "0"
  1738. End If
  1739. If TObjectType(src) Then
  1740. If TObjectType(src).classDecl.IsExtern() Or (src._flags & TType.T_VARPTR) Then
  1741. Return Bra(t)
  1742. Else
  1743. If Not TObjectType(src).classDecl.IsStruct() Then
  1744. Return Bra("bbObjectToFieldOffset" + Bra("(BBObject*)" + t))
  1745. Else
  1746. Return Bra("(BBBYTE*)" + t)
  1747. End If
  1748. End If
  1749. End If
  1750. Local p:String = TransSPointer(dst)
  1751. If TByteType( dst )
  1752. If IsPointerType(src, TType.T_BYTE, TType.T_POINTER & dst._flags) Return t
  1753. If TNumericType( src ) Return Bra("(BBBYTE" + p + ")"+t)
  1754. Else If TShortType( dst )
  1755. If IsPointerType(src, TType.T_SHORT, TType.T_POINTER & dst._flags) Return t
  1756. If TNumericType( src ) Return Bra("(BBSHORT" + p + ")"+t)
  1757. Else If TIntType( dst )
  1758. If IsPointerType(src, TType.T_INT, TType.T_POINTER & dst._flags) Return t
  1759. If TNumericType( src ) Return Bra("(BBINT" + p + ")"+t)
  1760. Else If TUIntType( dst )
  1761. If IsPointerType(src, TType.T_UINT, TType.T_POINTER & dst._flags) Return t
  1762. If TNumericType( src ) Return Bra("(BBUINT" + p + ")"+t)
  1763. Else If TFloatType( dst )
  1764. If IsPointerType(src, TType.T_FLOAT, TType.T_POINTER & dst._flags) Return t
  1765. If TNumericType( src ) Return Bra("(BBFLOAT" + p + ")"+t)
  1766. Else If TDoubleType( dst )
  1767. If IsPointerType(src, TType.T_DOUBLE, TType.T_POINTER & dst._flags) Return t
  1768. If TNumericType( src ) Return Bra("(BBDOUBLE" + p + ")"+t)
  1769. Else If TLongType( dst )
  1770. If IsPointerType(src, TType.T_LONG, TType.T_POINTER & dst._flags) Return t
  1771. If TNumericType( src ) Return Bra("(BBLONG" + p + ")"+t)
  1772. Else If TULongType( dst )
  1773. If IsPointerType(src, TType.T_ULONG, TType.T_POINTER & dst._flags) Return t
  1774. If TNumericType( src ) Return Bra("(BBULONG" + p + ")"+t)
  1775. Else If TSizeTType( dst )
  1776. If IsPointerType(src, TType.T_SIZET, TType.T_POINTER & dst._flags) Return t
  1777. If TNumericType( src ) Return Bra("(BBSIZET" + p + ")"+t)
  1778. Else If TLongIntType( dst )
  1779. If IsPointerType(src, TType.T_LONGINT, TType.T_POINTER & dst._flags) Return t
  1780. If TNumericType( src ) Return Bra("(BBLONGINT" + p + ")"+t)
  1781. Else If TULongIntType( dst )
  1782. If IsPointerType(src, TType.T_ULONGINT, TType.T_POINTER & dst._flags) Return t
  1783. If TNumericType( src ) Return Bra("(BBULONGINT" + p + ")"+t)
  1784. Else If TWParamType( dst )
  1785. If IsPointerType(src, TType.T_WPARAM, TType.T_POINTER & dst._flags) Return t
  1786. If TNumericType( src ) Return Bra("(WPARAM" + p + ")"+t)
  1787. Else If TLParamType( dst )
  1788. If IsPointerType(src, TType.T_LPARAM, TType.T_POINTER & dst._flags) Return t
  1789. If TNumericType( src ) Return Bra("(LPARAM" + p + ")"+t)
  1790. Else If TInt128Type( dst )
  1791. If IsPointerType(src, TType.T_INT128, TType.T_POINTER & dst._flags) Return t
  1792. If TNumericType( src ) Return Bra("(BBINT128" + p + ")"+t)
  1793. Else If TFloat128Type( dst )
  1794. If IsPointerType(src, TType.T_FLOAT128, TType.T_POINTER & dst._flags) Return t
  1795. If TNumericType( src ) Return Bra("(BBFLOAT128" + p + ")"+t)
  1796. Else If TDouble128Type( dst )
  1797. If IsPointerType(src, TType.T_DOUBLE128, TType.T_POINTER & dst._flags) Return t
  1798. If TNumericType( src ) Return Bra("(BBDOUBLE128" + p + ")"+t)
  1799. Else If TFloat64Type( dst )
  1800. If IsPointerType(src, TType.T_FLOAT64, TType.T_POINTER & dst._flags) Return t
  1801. If TNumericType( src ) Return Bra("(BBFLOAT64" + p + ")"+t)
  1802. 'Else If TIntPtrPtrType( dst )
  1803. ' If TBytePtrType( src) Return Bra("(BBINT**)"+t)
  1804. ' If TShortPtrType( src ) Return Bra("(BBINT**)"+t)
  1805. ' If TIntPtrType( src ) Return Bra("(BBINT**)"+t)
  1806. ' If TFloatPtrType( src ) Return Bra("(BBINT**)"+t)
  1807. ' If TDoublePtrType( src ) Return Bra("(BBINT**)"+t)
  1808. ' If TLongPtrType( src ) Return Bra("(BBINT**)"+t)
  1809. ' If TNumericType( src ) Return Bra("(BBINT**)"+t)
  1810. End If
  1811. Else If TBoolType( dst )
  1812. If TFunctionPtrType(src) Return Bra(Bra( t+"!=0" ) + " && " + Bra( t+"!=&brl_blitz_NullFunctionError" ))
  1813. 'If TFunctionPtrType(src) Return Bra( t+"!=0" )
  1814. If IsPointerType( src, 0, TType.T_POINTER ) Return Bra( t )
  1815. If TBoolType( src ) Return t
  1816. If TByteType( src ) Return Bra( t+"!=0" )
  1817. If TShortType( src ) Return Bra( t+"!=0" )
  1818. If TIntType( src ) Return Bra( t+"!=0" )
  1819. If TUIntType( src ) Return Bra( t+"!=0" )
  1820. If TFloatType( src ) Return Bra( t+"!=0.0f" )
  1821. 'If TCastExpr(expr.expr) And (TArrayType( src ) Or TStringType( src ) Or TObjectType( src )) Then
  1822. ' Return Bra( t+"!= &bbNullObject" )
  1823. 'End If
  1824. If TLongType( src ) Return Bra( t+"!=0" )
  1825. If TULongType( src ) Return Bra( t+"!=0" )
  1826. If TSizeTType( src ) Return Bra( t+"!=0" )
  1827. If TLongIntType( src ) Return Bra( t+"!=0" )
  1828. If TULongIntType( src ) Return Bra( t+"!=0" )
  1829. If TWParamType( src ) Return Bra( t+"!=0" )
  1830. If TLParamType( src ) Return Bra( t+"!=0" )
  1831. If TDoubleType( src ) Return Bra( t+"!=0.0f" )
  1832. If TArrayType( src ) Return Bra( t+"!= &bbEmptyArray" )
  1833. If TStringType( src ) Return Bra( t+"!= &bbEmptyString" )
  1834. If TObjectType( src ) Then
  1835. If TObjectType(src).classDecl.IsExtern() Then
  1836. If Not TObjectType(src).classDecl.IsStruct() Then
  1837. Return Bra( t+"!=0" )
  1838. Else
  1839. Return Bra("1")
  1840. End If
  1841. Else
  1842. If Not TObjectType(src).classDecl.IsStruct() Then
  1843. Return Bra( Bra(Bra("BBObject*") + t )+"!= &bbNullObject" )
  1844. Else
  1845. Return Bra("1")
  1846. End If
  1847. End If
  1848. End If
  1849. If TEnumType( src ) Return Bra( t+"!=0" )
  1850. Else If TIntType( dst )
  1851. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBINT)"+t)
  1852. If TBoolType( src ) Return Bra( t )
  1853. If TByteType( src) Return Bra("(BBINT)"+t)
  1854. If TShortType( src) Return Bra("(BBINT)"+t)
  1855. If TBoolType( src ) Return t
  1856. If TIntType( src ) Return t
  1857. If TUIntType( src ) Return Bra("(BBINT)"+t)
  1858. If TFloatType( src ) Return Bra("(BBINT)"+t)
  1859. If TDoubleType( src ) Return Bra("(BBINT)"+t)
  1860. If TLongType( src ) Return Bra("(BBINT)"+t)
  1861. If TULongType( src ) Return Bra("(BBINT)"+t)
  1862. If TSizeTType( src ) Return Bra("(BBINT)"+t)
  1863. If TLongIntType( src ) Return Bra("(BBINT)"+t)
  1864. If TULongIntType( src ) Return Bra("(BBINT)"+t)
  1865. If TWParamType( src ) Return Bra("(BBINT)"+t)
  1866. If TLParamType( src ) Return Bra("(BBINT)"+t)
  1867. If TStringType( src ) Return "bbStringToInt" + Bra(t)
  1868. If TEnumType( src) Return Bra("(BBINT)"+t)
  1869. 'If TIntVarPtrType( src ) Return Bra("*" + t)
  1870. 'If TPointerType( src ) Return Bra("(BBINT)"+t)
  1871. Else If TLongType( dst )
  1872. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBLONG)"+t)
  1873. If TBoolType( src ) Return Bra( t )
  1874. If TByteType( src) Return Bra("(BBLONG)"+t)
  1875. If TShortType( src) Return Bra("(BBLONG)"+t)
  1876. If TIntType( src) Return Bra("(BBLONG)"+t)
  1877. If TUIntType( src) Return Bra("(BBLONG)"+t)
  1878. If TLongType( src ) Return t
  1879. If TULongType( src ) Return Bra("(BBLONG)"+t)
  1880. If TSizeTType( src ) Return Bra("(BBLONG)"+t)
  1881. If TLongIntType( src ) Return Bra("(BBLONG)"+t)
  1882. If TULongIntType( src ) Return Bra("(BBLONG)"+t)
  1883. If TWParamType( src ) Return Bra("(BBLONG)"+t)
  1884. If TLParamType( src ) Return Bra("(BBLONG)"+t)
  1885. If TFloatType( src ) Return Bra("(BBLONG)"+t)
  1886. If TDoubleType( src ) Return Bra("(BBLONG)"+t)
  1887. If TStringType( src ) Return "bbStringToLong" + Bra(t)
  1888. If TFloat64Type( src ) Return Bra("(BBLONG)"+t)
  1889. If TEnumType( src) Return Bra("(BBLONG)"+t)
  1890. 'If TPointerType( src ) Return Bra("(BBLONG)"+t)
  1891. Else If TSizeTType( dst )
  1892. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBSIZET)"+t)
  1893. If TBoolType( src ) Return Bra( t )
  1894. If TByteType( src) Return Bra("(BBSIZET)"+t)
  1895. If TShortType( src) Return Bra("(BBSIZET)"+t)
  1896. If TIntType( src) Return Bra("(BBSIZET)"+t)
  1897. If TUIntType( src) Return Bra("(BBSIZET)"+t)
  1898. If TLongType( src) Return Bra("(BBSIZET)"+t)
  1899. If TULongType( src) Return Bra("(BBSIZET)"+t)
  1900. If TSizeTType( src ) Return t
  1901. If TLongIntType( src) Return Bra("(BBSIZET)"+t)
  1902. If TULongIntType( src) Return Bra("(BBSIZET)"+t)
  1903. If TWParamType( src ) Return Bra("(BBSIZET)"+t)
  1904. If TLParamType( src ) Return Bra("(BBSIZET)"+t)
  1905. If TFloatType( src ) Return Bra("(BBSIZET)"+t)
  1906. If TDoubleType( src ) Return Bra("(BBSIZET)"+t)
  1907. If TStringType( src ) Return "bbStringToSizet" + Bra(t)
  1908. If TFloat64Type( src ) Return Bra("(BBSIZET)"+t)
  1909. If TEnumType( src) Return Bra("(BBSIZET)"+t)
  1910. 'If TPointerType( src ) Return Bra("(BBLONG)"+t)
  1911. Else If TLongIntType( dst )
  1912. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBLONGINT)"+t)
  1913. If TBoolType( src ) Return Bra( t )
  1914. If TByteType( src) Return Bra("(BBLONGINT)"+t)
  1915. If TShortType( src) Return Bra("(BBLONGINT)"+t)
  1916. If TIntType( src) Return Bra("(BBLONGINT)"+t)
  1917. If TUIntType( src) Return Bra("(BBLONGINT)"+t)
  1918. If TLongType( src ) Return Bra("(BBLONGINT)"+t)
  1919. If TULongType( src ) Return Bra("(BBLONGINT)"+t)
  1920. If TSizeTType( src ) Return Bra("(BBLONGINT)"+t)
  1921. If TLongIntType( src ) Return t
  1922. If TULongIntType( src ) Return Bra("(BBLONGINT)"+t)
  1923. If TWParamType( src ) Return Bra("(BBLONGINT)"+t)
  1924. If TLParamType( src ) Return Bra("(BBLONGINT)"+t)
  1925. If TFloatType( src ) Return Bra("(BBLONGINT)"+t)
  1926. If TDoubleType( src ) Return Bra("(BBLONGINT)"+t)
  1927. If TStringType( src ) Return "bbStringToLongInt" + Bra(t)
  1928. If TFloat64Type( src ) Return Bra("(BBLONGINT)"+t)
  1929. If TEnumType( src) Return Bra("(BBLONGINT)"+t)
  1930. 'If TPointerType( src ) Return Bra("(BBLONGINT)"+t)
  1931. Else If TULongIntType( dst )
  1932. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBULONGINT)"+t)
  1933. If TBoolType( src ) Return Bra( t )
  1934. If TByteType( src) Return Bra("(BBULONGINT)"+t)
  1935. If TShortType( src) Return Bra("(BBULONGINT)"+t)
  1936. If TIntType( src) Return Bra("(BBULONGINT)"+t)
  1937. If TUIntType( src) Return Bra("(BBULONGINT)"+t)
  1938. If TLongType( src ) Return Bra("(BBULONGINT)"+t)
  1939. If TULongType( src ) Return Bra("(BBULONGINT)"+t)
  1940. If TSizeTType( src ) Return Bra("(BBULONGINT)"+t)
  1941. If TLongIntType( src ) Return Bra("(BBULONGINT)"+t)
  1942. If TULongIntType( src ) Return t
  1943. If TWParamType( src ) Return Bra("(BBULONGINT)"+t)
  1944. If TLParamType( src ) Return Bra("(BBULONGINT)"+t)
  1945. If TFloatType( src ) Return Bra("(BBULONGINT)"+t)
  1946. If TDoubleType( src ) Return Bra("(BBULONGINT)"+t)
  1947. If TStringType( src ) Return "bbStringToULongInt" + Bra(t)
  1948. If TFloat64Type( src ) Return Bra("(BBULONGINT)"+t)
  1949. If TEnumType( src) Return Bra("(BBULONGINT)"+t)
  1950. 'If TPointerType( src ) Return Bra("(BBULONGINT)"+t)
  1951. Else If TFloatType( dst )
  1952. If TBoolType( src ) Return Bra( t )
  1953. If TByteType( src ) Return Bra("(BBFLOAT)"+t)
  1954. If TIntType( src ) Return Bra("(BBFLOAT)"+t)
  1955. If TUIntType( src ) Return Bra("(BBFLOAT)"+t)
  1956. If TShortType( src ) Return Bra("(BBFLOAT)"+t)
  1957. If TFloatType( src ) Return t
  1958. If TDoubleType( src ) Return Bra("(BBFLOAT)"+t)
  1959. If TLongType( src ) Return Bra("(BBFLOAT)"+t)
  1960. If TULongType( src ) Return Bra("(BBFLOAT)"+t)
  1961. If TSizeTType( src ) Return Bra("(BBFLOAT)"+t)
  1962. If TLongIntType( src ) Return Bra("(BBFLOAT)"+t)
  1963. If TULongIntType( src ) Return Bra("(BBFLOAT)"+t)
  1964. If TWParamType( src ) Return Bra("(BBFLOAT)"+t)
  1965. If TLParamType( src ) Return Bra("(BBFLOAT)"+t)
  1966. If TStringType( src ) Return "bbStringToFloat" + Bra(t)
  1967. 'If TFloatVarPtrType( src ) Return Bra("*" + t)
  1968. 'If TPointerType( src ) Return Bra("(BBFLOAT)"+t)
  1969. Else If TDoubleType( dst )
  1970. If TBoolType( src ) Return Bra( t )
  1971. If TByteType( src ) Return Bra("(BBDOUBLE)"+t)
  1972. If TIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1973. If TUIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1974. If TShortType( src ) Return Bra("(BBDOUBLE)"+t)
  1975. If TDoubleType( src ) Return t
  1976. If TFloatType( src ) Return Bra("(BBDOUBLE)"+t)
  1977. If TLongType( src ) Return Bra("(BBDOUBLE)"+t)
  1978. If TULongType( src ) Return Bra("(BBDOUBLE)"+t)
  1979. If TSizeTType( src ) Return Bra("(BBDOUBLE)"+t)
  1980. If TLongIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1981. If TULongIntType( src ) Return Bra("(BBDOUBLE)"+t)
  1982. If TWParamType( src ) Return Bra("(BBDOUBLE)"+t)
  1983. If TLParamType( src ) Return Bra("(BBDOUBLE)"+t)
  1984. If TStringType( src ) Return "bbStringToDouble" + Bra(t)
  1985. 'If TDoubleVarPtrType( src ) Return Bra("*" + t)
  1986. 'If TPointerType( src ) Return Bra("(BBDOUBLE)"+t)
  1987. Else If TStringType( dst )
  1988. If IsPointerType(src, 0, TType.T_POINTER) Return "bbStringFromSizet"+Bra( t )
  1989. If TBoolType( src ) Return "bbStringFromInt"+Bra( t )
  1990. If TByteType( src ) Return "bbStringFromInt"+Bra( t )
  1991. If TShortType( src ) Return "bbStringFromInt"+Bra( t )
  1992. If TIntType( src ) Return "bbStringFromInt"+Bra( t )
  1993. If TUIntType( src ) Return "bbStringFromUInt"+Bra( t )
  1994. If TLongType( src ) Return "bbStringFromLong"+Bra( t )
  1995. If TULongType( src ) Return "bbStringFromULong"+Bra( t )
  1996. If TSizeTType( src ) Return "bbStringFromSizet"+Bra( t )
  1997. If TLongIntType( src ) Return "bbStringFromLongInt"+Bra( t )
  1998. If TULongIntType( src ) Return "bbStringFromULongInt"+Bra( t )
  1999. If TWParamType( src ) Return "bbStringFromWParam"+Bra( t )
  2000. If TLParamType( src ) Return "bbStringFromLParam"+Bra( t )
  2001. If TFloatType( src ) Return "bbStringFromFloat"+Bra( t )
  2002. If TDoubleType( src ) Return "bbStringFromDouble"+Bra( t )
  2003. If TStringType( src ) Then
  2004. If src._flags & TType.T_CHAR_PTR Then
  2005. Return "bbStringFromCString"+Bra( t )
  2006. End If
  2007. If src._flags & TType.T_SHORT_PTR Then
  2008. Return "bbStringFromWString"+Bra( t )
  2009. End If
  2010. If src._flags & TType.T_VAR Then
  2011. If TSliceExpr( expr.expr ) Then
  2012. Return "&" + Bra(t)
  2013. End If
  2014. Return t
  2015. End If
  2016. Return t
  2017. End If
  2018. If TEnumType( src ) Then
  2019. Local ty:TType = TEnumType( src ).decl.ty
  2020. If TByteType( ty ) Return "bbStringFromInt"+Bra( t )
  2021. If TShortType( ty ) Return "bbStringFromInt"+Bra( t )
  2022. If TIntType( ty ) Return "bbStringFromInt"+Bra( t )
  2023. If TUIntType( ty ) Return "bbStringFromUInt"+Bra( t )
  2024. If TLongType( ty ) Return "bbStringFromLong"+Bra( t )
  2025. If TULongType( ty ) Return "bbStringFromULong"+Bra( t )
  2026. If TSizeTType( ty ) Return "bbStringFromSizet"+Bra( t )
  2027. If TLongIntType( ty ) Return "bbStringFromLongInt"+Bra( t )
  2028. If TULongIntType( ty ) Return "bbStringFromULongInt"+Bra( t )
  2029. End If
  2030. 'If TStringVarPtrType( src ) Then
  2031. ' If TSliceExpr( expr.expr ) Then
  2032. ' Return t
  2033. ' End If
  2034. ' Return "*" + t
  2035. 'End If
  2036. 'If TStringCharPtrType( src ) Return "bbStringFromCString"+Bra( t )
  2037. 'Else If TStringVarPtrType( dst )
  2038. 'DebugStop
  2039. Else If TByteType( dst )
  2040. If TBoolType( src ) Return Bra( t )
  2041. If TByteType( src) Return t
  2042. If TShortType( src ) Return Bra("(BBBYTE)"+t)
  2043. If TIntType( src ) Return Bra("(BBBYTE)"+t)
  2044. If TUIntType( src ) Return Bra("(BBBYTE)"+t)
  2045. If TFloatType( src ) Return Bra("(BBBYTE)"+t)
  2046. If TDoubleType( src ) Return Bra("(BBBYTE)"+t)
  2047. If TLongType( src ) Return Bra("(BBBYTE)"+t)
  2048. If TULongType( src ) Return Bra("(BBBYTE)"+t)
  2049. If TSizeTType( src ) Return Bra("(BBBYTE)"+t)
  2050. If TLongIntType( src ) Return Bra("(BBBYTE)"+t)
  2051. If TULongIntType( src ) Return Bra("(BBBYTE)"+t)
  2052. If TWParamType( src ) Return Bra("(BBBYTE)"+t)
  2053. If TLParamType( src ) Return Bra("(BBBYTE)"+t)
  2054. If TStringType( src ) Return Bra("(BBBYTE)bbStringToInt" + Bra(t))
  2055. If TEnumType( src) Return Bra("(BBYTE)"+t)
  2056. 'If TByteVarPtrType( src ) Return Bra("*" + t)
  2057. Else If TShortType( dst )
  2058. If TBoolType( src ) Return Bra( t )
  2059. If TShortType( src) Return t
  2060. If TByteType( src) Return Bra("(BBSHORT)"+t)
  2061. If TIntType( src ) Return Bra("(BBSHORT)"+t)
  2062. If TUIntType( src ) Return Bra("(BBSHORT)"+t)
  2063. If TFloatType( src ) Return Bra("(BBSHORT)"+t)
  2064. If TDoubleType( src ) Return Bra("(BBSHORT)"+t)
  2065. If TLongType( src ) Return Bra("(BBSHORT)"+t)
  2066. If TULongType( src ) Return Bra("(BBSHORT)"+t)
  2067. If TSizeTType( src ) Return Bra("(BBSHORT)"+t)
  2068. If TLongIntType( src ) Return Bra("(BBSHORT)"+t)
  2069. If TULongIntType( src ) Return Bra("(BBSHORT)"+t)
  2070. If TWParamType( src ) Return Bra("(BBSHORT)"+t)
  2071. If TLParamType( src ) Return Bra("(BBSHORT)"+t)
  2072. If TStringType( src ) Return Bra("(BBSHORT)bbStringToInt" + Bra(t))
  2073. If TEnumType( src) Return Bra("(BBSHORT)"+t)
  2074. 'If TShortVarPtrType( src ) Return Bra("*" + t)
  2075. Else If TUIntType( dst )
  2076. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBUINT)"+t)
  2077. If TBoolType( src ) Return Bra( t )
  2078. If TShortType( src ) Return Bra("(BBUINT)"+t)
  2079. If TByteType( src) Return Bra("(BBUINT)"+t)
  2080. If TIntType( src ) Return Bra("(BBUINT)"+t)
  2081. If TUIntType( src) Return t
  2082. If TFloatType( src ) Return Bra("(BBUINT)"+t)
  2083. If TDoubleType( src ) Return Bra("(BBUINT)"+t)
  2084. If TLongType( src ) Return Bra("(BBUINT)"+t)
  2085. If TULongType( src ) Return Bra("(BBUINT)"+t)
  2086. If TSizeTType( src ) Return Bra("(BBUINT)"+t)
  2087. If TLongIntType( src ) Return Bra("(BBUINT)"+t)
  2088. If TULongIntType( src ) Return Bra("(BBUINT)"+t)
  2089. If TWParamType( src ) Return Bra("(BBUINT)"+t)
  2090. If TLParamType( src ) Return Bra("(BBUINT)"+t)
  2091. If TStringType( src ) Return "bbStringToUInt" + Bra(t)
  2092. If TEnumType( src) Return Bra("(BBUINT)"+t)
  2093. Else If TULongType( dst )
  2094. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(BBULONG)"+t)
  2095. If TBoolType( src ) Return Bra( t )
  2096. If TShortType( src ) Return Bra("(BBULONG)"+t)
  2097. If TByteType( src) Return Bra("(BBULONG)"+t)
  2098. If TIntType( src ) Return Bra("(BBULONG)"+t)
  2099. If TUIntType( src ) Return Bra("(BBULONG)"+t)
  2100. If TFloatType( src ) Return Bra("(BBULONG)"+t)
  2101. If TDoubleType( src ) Return Bra("(BBULONG)"+t)
  2102. If TLongType( src ) Return Bra("(BBULONG)"+t)
  2103. If TULongType( src) Return t
  2104. If TSizeTType( src ) Return Bra("(BBULONG)"+t)
  2105. If TLongIntType( src ) Return Bra("(BBULONG)"+t)
  2106. If TULongIntType( src ) Return Bra("(BBULONG)"+t)
  2107. If TWParamType( src ) Return Bra("(BBULONG)"+t)
  2108. If TLParamType( src ) Return Bra("(BBULONG)"+t)
  2109. If TStringType( src ) Return "bbStringToULong" + Bra(t)
  2110. If TFloat64Type( src ) Return Bra("(BBULONG)"+t)
  2111. If TEnumType( src) Return Bra("(BBULONG)"+t)
  2112. Else If TFloat64Type( dst )
  2113. If TFloat64Type( src) Return t
  2114. If TLongType( src ) Return Bra("(BBFLOAT64)"+t)
  2115. If TULongType( src ) Return Bra("(BBFLOAT64)"+t)
  2116. If TSizeTType( src ) Return Bra("(BBFLOAT64)"+t)
  2117. Else If TInt128Type( dst )
  2118. If TInt128Type( src) Return t
  2119. If TFloat128Type( src ) Return Bra("(BBINT128)"+t)
  2120. If TDouble128Type( src ) Return Bra("(BBINT128)"+t)
  2121. Else If TFloat128Type( dst )
  2122. If TFloat128Type( src) Return t
  2123. If TInt128Type( src ) Return Bra("(BBFLOAT128)"+t)
  2124. If TDouble128Type( src ) Return Bra("(BBFLOAT128)"+t)
  2125. Else If TDouble128Type( dst )
  2126. If TDouble128Type( src) Return t
  2127. If TInt128Type( src ) Return Bra("(BBDOUBLE128)"+t)
  2128. If TFloat128Type( src ) Return Bra("(BBDOUBLE128)"+t)
  2129. Else If TWParamType( dst )
  2130. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(WPARAM)"+t)
  2131. If TBoolType( src ) Return Bra( t )
  2132. If TByteType( src) Return Bra("(WPARAM)"+t)
  2133. If TShortType( src) Return Bra("(WPARAM)"+t)
  2134. If TIntType( src) Return Bra("(WPARAM)"+t)
  2135. If TUIntType( src) Return Bra("(WPARAM)"+t)
  2136. If TLongType( src) Return Bra("(WPARAM)"+t)
  2137. If TULongType( src) Return Bra("(WPARAM)"+t)
  2138. If TSizeTType( src ) Return Bra("(WPARAM)"+t)
  2139. If TLongIntType( src) Return Bra("(WPARAM)"+t)
  2140. If TULongIntType( src) Return Bra("(WPARAM)"+t)
  2141. If TWParamType( src ) Return t
  2142. If TLParamType( src ) Return Bra("(WPARAM)"+t)
  2143. If TFloatType( src ) Return Bra("(WPARAM)"+t)
  2144. If TDoubleType( src ) Return Bra("(WPARAM)"+t)
  2145. If TStringType( src ) Return "bbStringToWParam" + Bra(t)
  2146. Else If TLParamType( dst )
  2147. If IsPointerType(src,0,TType.T_POINTER) Return Bra("(LPARAM)"+t)
  2148. If TBoolType( src ) Return Bra( t )
  2149. If TByteType( src) Return Bra("(LPARAM)"+t)
  2150. If TShortType( src) Return Bra("(LPARAM)"+t)
  2151. If TIntType( src) Return Bra("(LPARAM)"+t)
  2152. If TUIntType( src) Return Bra("(LPARAM)"+t)
  2153. If TLongType( src) Return Bra("(LPARAM)"+t)
  2154. If TULongType( src) Return Bra("(LPARAM)"+t)
  2155. If TSizeTType( src ) Return Bra("(LPARAM)"+t)
  2156. If TLongIntType( src) Return Bra("(LPARAM)"+t)
  2157. If TULongIntType( src) Return Bra("(LPARAM)"+t)
  2158. If TWParamType( src ) Return Bra("(LPARAM)"+t)
  2159. If TLParamType( src ) Return t
  2160. If TFloatType( src ) Return Bra("(LPARAM)"+t)
  2161. If TDoubleType( src ) Return Bra("(LPARAM)"+t)
  2162. If TStringType( src ) Return "bbStringToLParam" + Bra(t)
  2163. Else If TArrayType( dst )
  2164. If TArrayType( src ) Then
  2165. If TObjectType( TArrayType( dst ).elemType ) And TObjectType( TArrayType( dst ).elemType ).classDecl.ident = "Object" Then
  2166. ' if we are casting to Object[], don't actually cast.
  2167. Return Bra(t)
  2168. Else
  2169. Return "bbArrayCastFromObject" + Bra(t + "," + TransArrayType(TArrayType( dst ).elemType))
  2170. End If
  2171. End If
  2172. If TObjectType( src) And (TObjectType( src ).classDecl.ident = "___Array" Or TObjectType( src ).classDecl.ident = "Object") Then
  2173. Return "bbArrayCastFromObject" + Bra(t + "," + TransArrayType(TArrayType( dst ).elemType))
  2174. End If
  2175. Else If TObjectType( dst )
  2176. 'If TArrayType( src ) Return Bra("(BBOBJECT)"+t)
  2177. 'If TStringType( src ) Return Bra("(BBOBJECT)"+t)
  2178. 'If TObjectType( src ) Return t
  2179. If Not TObjectType( dst ).classDecl.IsExtern() Then
  2180. If TObjectType( dst ).classDecl.IsStruct() Then
  2181. Return TransValue(dst, Null)
  2182. End If
  2183. If TNullType( src ) Return "&bbNullObject"
  2184. If TObjectType(dst).classDecl.IsInterface() Then
  2185. Return Bra(Bra(TransObject(TObjectType(dst).classDecl)) + "bbInterfaceDowncast" + Bra("(BBObject*)" +t + ",(BBInterface*)&" + TObjectType(dst).classDecl.munged + "_ifc"))
  2186. Else
  2187. ' no need to downcast to BBObject, as all objects extend it...
  2188. If TObjectType( dst ).classDecl.ident = "Object" Then
  2189. Return t
  2190. Else
  2191. Return Bra(Bra(TransObject(TObjectType(dst).classDecl)) + "bbObjectDowncast" + Bra("(BBOBJECT)" + t + ",(BBClass*)&" + TObjectType(dst).classDecl.munged))
  2192. End If
  2193. End If
  2194. Else
  2195. If TObjectType( dst ).classDecl.IsInterface() Then
  2196. Return t
  2197. Else
  2198. Return "" ' TODO??
  2199. End If
  2200. End If
  2201. Else If TEnumType( dst )
  2202. If TEnumType( src) Return t
  2203. If TIntegralType(src) Then
  2204. If opt_debug Then
  2205. Return "bbEnumCast_" + TransDebugScopeType(TEnumType(dst).decl.ty) + Bra(TEnumType(dst).decl.munged + "_BBEnum_impl," + t)
  2206. Else
  2207. ' no checking in release mode.
  2208. Return t
  2209. End If
  2210. End If
  2211. End If
  2212. Return TransPtrCast( dst,src,t,"dynamic" )
  2213. Err "C++ translator can't convert "+src.ToString()+" to "+dst.ToString()
  2214. End Method
  2215. Method TransUnaryExpr$( expr:TUnaryExpr )
  2216. Local pri:Int=ExprPri( expr )
  2217. Local t_expr$
  2218. If TVarExpr(expr.expr) Then
  2219. If TObjectType(TVarExpr(expr.expr).exprType) Then
  2220. If TObjectType(TVarExpr(expr.expr).exprType).classDecl.IsStruct() Then
  2221. t_expr = Bra( "1" )
  2222. Else
  2223. t_expr = Bra( expr.expr.Trans() + "!= &bbNullObject")
  2224. End If
  2225. Else If TStringType(TVarExpr(expr.expr).exprType) Then
  2226. t_expr = Bra( expr.expr.Trans() + "!= &bbEmptyString")
  2227. Else If expr.op = "~~" And TEnumType(expr.exprType) Then
  2228. Return Bra("bbEnum" + TEnumType(expr.exprType).decl.munged +"_Mask & ~~" + Bra(TransSubExpr( expr.expr,pri )))
  2229. Else
  2230. t_expr = TransSubExpr( expr.expr,pri )
  2231. End If
  2232. Else
  2233. If expr.op = "~~" And TEnumType(expr.exprType) Then
  2234. Return Bra("bbEnum" + TEnumType(expr.exprType).decl.munged +"_Mask & ~~" + Bra(TransSubExpr( expr.expr,pri )))
  2235. Else
  2236. t_expr = TransSubExpr( expr.expr,pri )
  2237. End If
  2238. End If
  2239. Return TransUnaryOp( expr.op )+t_expr
  2240. End Method
  2241. Method TransBinaryExpr$( expr:TBinaryExpr )
  2242. Local pri:Int=ExprPri( expr )
  2243. Local t_lhs$=TransSubExpr( expr.lhs,pri )
  2244. ' If TVarPtrType(expr.lhs.exprType) Then
  2245. ' t_lhs = "*" + t_lhs
  2246. ' End If
  2247. Local t_rhs$=TransSubExpr( expr.rhs,pri-1 )
  2248. ' If TVarPtrType(expr.rhs.exprType) Then
  2249. ' t_rhs = "*" + t_rhs
  2250. ' End If
  2251. If expr.op = "+" Then
  2252. If TStringType(expr.exprType) Then
  2253. Return "bbStringConcat(" + t_lhs + "," + t_rhs + ")"
  2254. Else If TArrayType(expr.exprType) Then
  2255. Return "bbArrayConcat(" + TransArrayType(TArrayType(expr.lhs.exprType).elemType) + "," + t_lhs + "," + t_rhs + ")"
  2256. End If
  2257. End If
  2258. If expr.op = "^" Then
  2259. If TIntegralType(expr.exprType) Then
  2260. Return "bbLongPow" + Bra(t_lhs + ", " + t_rhs)
  2261. Else
  2262. Return "bbFloatPow" + Bra(t_lhs + ", " + t_rhs)
  2263. End If
  2264. End If
  2265. If expr.op = "mod" Or expr.op = "%" Then
  2266. If TDecimalType(expr.lhs.exprType) Or TDecimalType(expr.rhs.exprType) Then
  2267. Return "bbFloatMod" + Bra(t_lhs + ", " + t_rhs)
  2268. End If
  2269. End If
  2270. If (expr.op = "shr" Or expr.op = "&" Or expr.op = "|") Then
  2271. If TIntType(expr.exprType) Then
  2272. t_lhs = "(unsigned int)(" + t_lhs + ")"
  2273. t_rhs = "(unsigned int)(" + t_rhs + ")"
  2274. Else If TLongType(expr.exprType) Then
  2275. t_lhs = "(unsigned long long)(" + t_lhs + ")"
  2276. t_rhs = "(unsigned long long)(" + t_rhs + ")"
  2277. Else If TLongIntType(expr.exprType) Then
  2278. t_lhs = "(unsigned long)(" + t_lhs + ")"
  2279. t_rhs = "(unsigned long)(" + t_rhs + ")"
  2280. End If
  2281. End If
  2282. If TBinaryCompareExpr(expr) Then
  2283. If TStringType(TBinaryCompareExpr(expr).ty) Then
  2284. If t_lhs="&bbNullObject" Then
  2285. err "NULL"
  2286. t_lhs = "&bbEmptyString"
  2287. End If
  2288. If t_rhs="&bbNullObject" Then
  2289. err "NULL"
  2290. t_rhs = "&bbEmptyString"
  2291. End If
  2292. If t_lhs <> "&bbEmptyString" And t_rhs <> "&bbEmptyString" Then
  2293. If expr.op = "=" Or expr.op = "<>" Then
  2294. Return "bbStringEquals" + Bra(t_lhs + ", " + t_rhs) + TransBinaryOp(expr.op, "") + "1"
  2295. Else
  2296. Return "bbStringCompare" + Bra(t_lhs + ", " + t_rhs) + TransBinaryOp(expr.op, "") + "0"
  2297. End If
  2298. End If
  2299. Else If IsPointerType(TBinaryCompareExpr(expr).ty, 0, TType.T_POINTER) Then
  2300. If t_lhs="&bbNullObject" Then
  2301. t_lhs = "0"
  2302. End If
  2303. If t_rhs="&bbNullObject" Then
  2304. t_rhs = "0"
  2305. End If
  2306. Else If TArrayType(TBinaryCompareExpr(expr).ty) Then
  2307. If t_lhs="&bbNullObject" Then
  2308. err "NULL"
  2309. t_lhs = "&bbEmptyArray"
  2310. End If
  2311. If t_rhs="&bbNullObject" Then
  2312. err "NULL"
  2313. t_rhs = "&bbEmptyArray"
  2314. End If
  2315. Else If TObjectType(TBinaryCompareExpr(expr).ty) Then
  2316. Local bcExpr:TBinaryCompareExpr = TBinaryCompareExpr(expr)
  2317. If bcExpr.lhs.exprType.ExtendsType(bcExpr.rhs.exprType) Then
  2318. If t_rhs="&bbNullObject" Then
  2319. t_lhs = Bra("(BBOBJECT)" + t_lhs)
  2320. Else
  2321. t_lhs = Bra(Bra(TransType(bcExpr.rhs.exprType, "*")) + t_lhs)
  2322. End If
  2323. Else If bcExpr.rhs.exprType.ExtendsType(bcExpr.lhs.exprType)
  2324. If t_lhs="&bbNullObject" Then
  2325. t_rhs = Bra("(BBOBJECT)" + t_rhs)
  2326. Else
  2327. t_rhs = Bra(Bra(TransType(bcExpr.lhs.exprType, "*")) + t_rhs)
  2328. End If
  2329. End If
  2330. If t_rhs="&bbNullObject" And TObjectType(bcExpr.lhs.exprType) And TObjectType(bcExpr.lhs.exprType).classDecl.ident = "Object" Then
  2331. If bcExpr.op = "=" Or bcExpr.op = "<>" Then
  2332. Local t:String = t_lhs
  2333. 'If Not TVarExpr(bcExpr.lhs) Then
  2334. ' t = CreateLocal(bcExpr.lhs)
  2335. 'End If
  2336. If bcExpr.op = "="
  2337. Return Bra(t + "==" + t_rhs )
  2338. Else
  2339. Return Bra(t + "!=" + t_rhs )
  2340. End If
  2341. End If
  2342. End If
  2343. If t_lhs="&bbNullObject" And TObjectType(bcExpr.rhs.exprType) And TObjectType(bcExpr.rhs.exprType).classDecl.ident = "Object" Then
  2344. If bcExpr.op = "=" Or bcExpr.op = "<>" Then
  2345. Local t:String = t_rhs
  2346. 'If Not TVarExpr(bcExpr.rhs) Then
  2347. ' t = CreateLocal(bcExpr.rhs)
  2348. 'End If
  2349. If bcExpr.op = "="
  2350. Return Bra(t + "==" + t_lhs )
  2351. Else
  2352. Return Bra(t + "!=" + t_lhs )
  2353. End If
  2354. End If
  2355. End If
  2356. End If
  2357. End If
  2358. Return bra(t_lhs+TransBinaryOp( expr.op,t_rhs )+t_rhs)
  2359. End Method
  2360. Method TransIndexExpr$( expr:TIndexExpr )
  2361. Local t_expr$=TransSubExpr( expr.expr )
  2362. Local t_index$
  2363. If expr.index.length = 1 Then
  2364. If TArraySizeExpr(expr.index[0]) Then
  2365. Local sizes:TArraySizeExpr = TArraySizeExpr(expr.index[0])
  2366. sizes.Trans()
  2367. Local v:String = sizes.val.munged
  2368. Local i:Int = 0
  2369. For i = 0 Until sizes.index.length - 1
  2370. If i Then
  2371. t_index :+ " + "
  2372. End If
  2373. t_index :+ "(*(" + v
  2374. If i Then
  2375. t_index :+ "+" + i
  2376. End If
  2377. t_index :+ ")) * " + sizes.index[i].Trans()
  2378. Next
  2379. t_index :+ " + " + sizes.index[i].Trans()
  2380. ' (*(v+0)) * var1 + (*(v+1)) * var2 + var3
  2381. 'DebugStop
  2382. Else
  2383. t_index=expr.index[0].Trans()
  2384. End If
  2385. End If
  2386. If TStringType( expr.expr.exprType ) Then
  2387. Return Bra(t_expr) + "->buf[" + t_index + "]"
  2388. 'Return "(BBINT)"+t_expr+"["+t_index+"]"
  2389. End If
  2390. If TArrayType( expr.expr.exprType ) Then
  2391. If TFunctionPtrType(TArrayType( expr.expr.exprType ).elemType) Then
  2392. If opt_debug Then
  2393. Return Bra(Bra(TransType(TArrayType( expr.expr.exprType).elemType, "*")) + Bra("BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")")) + "[" + t_index + "]"
  2394. Else
  2395. Return Bra(Bra(TransType(TArrayType( expr.expr.exprType).elemType, "*")) + Bra("BBARRAYDATA(" + t_expr + ",1)")) + "[" + t_index + "]"
  2396. End If
  2397. Else
  2398. If TArrayType( expr.expr.exprType ).isStatic Then
  2399. Return t_expr + "[" + t_index + "]"
  2400. Else
  2401. If opt_debug Then
  2402. Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")") + "[" + t_index + "]"
  2403. Else
  2404. Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATA(" + t_expr + ",1)") + "[" + t_index + "]"
  2405. End If
  2406. End If
  2407. End If
  2408. End If
  2409. 'Local swiz$
  2410. 'If TObjectType( expr.exprType )And expr.exprType.GetClass().IsInterface() swiz=".p"
  2411. 'If ENV_CONFIG="debug" Return t_expr+".At("+t_index+")"+swiz
  2412. Return t_expr+"["+t_index+"]"
  2413. End Method
  2414. Method TransSliceExpr$( expr:TSliceExpr )
  2415. 'DebugStop
  2416. Local t_expr:String=TransSubExpr( expr.expr )
  2417. Local t_args$
  2418. If expr.from Then
  2419. t_args=expr.from.Trans()
  2420. Else
  2421. t_args = "0"
  2422. End If
  2423. If expr.term Then
  2424. t_args:+","+expr.term.Trans()
  2425. Else
  2426. If TArrayType(expr.exprType) Then
  2427. t_args :+ "," + Bra(t_expr) + "->scales[0]"
  2428. 'Else If TStringVarPtrType(expr.exprType) Then
  2429. ' t_args :+ ",(*" + t_expr + ")->length"
  2430. Else
  2431. t_args :+ "," + Bra(t_expr) + "->length"
  2432. End If
  2433. End If
  2434. If TArrayType(expr.exprType) Then
  2435. Local ty:TType = TArrayType(expr.exprType).elemType
  2436. If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
  2437. Return "bbArraySliceStruct" + Bra(TransArrayType(ty) + "," + t_expr + "," + t_args + ", sizeof" + ..
  2438. Bra(TransObject(TObjectType(ty).classdecl)) + ", _" + TObjectType(ty).classdecl.munged + "_New")
  2439. Else
  2440. Return "bbArraySlice" + Bra(TransArrayType(ty) + "," + t_expr + "," + t_args)
  2441. End If
  2442. 'Else If TStringVarPtrType(expr.exprType) Then
  2443. ' Return "bbStringSlice" + Bra("*" + t_expr + "," + t_args)
  2444. Else
  2445. Return "bbStringSlice" + Bra(t_expr + "," + t_args)
  2446. End If
  2447. 'Return t_expr+".Slice("+t_args+")"
  2448. End Method
  2449. Method TransArrayExpr$( expr:TArrayExpr )
  2450. Local elemType:TType=TArrayType( expr.exprType ).elemType
  2451. Local tmpData:TLocalDecl =New TLocalDecl.Create( "",TType.voidType,Null )
  2452. MungDecl tmpData
  2453. Local tmpArray:TLocalDecl =New TLocalDecl.Create( "",TType.voidType,Null )
  2454. MungDecl tmpArray
  2455. Local t$
  2456. Local count:Int
  2457. For Local elem:TExpr=EachIn expr.exprs
  2458. If t t:+","
  2459. t:+elem.Trans()
  2460. count :+ 1
  2461. Next
  2462. Local tt$
  2463. ' If Not _env tt="static "
  2464. If Not TFunctionPtrType(elemType) Then
  2465. tt :+ TransType( elemType, tmpData.munged ) + " "+tmpData.munged + "[]"
  2466. Else
  2467. tt :+ TransType( elemType, tmpData.munged + "[]" )
  2468. End If
  2469. Emit tt+"={"+t+"};"
  2470. If TObjectType(elemType) And TObjectType(elemType).classdecl.IsStruct() And Not IsPointerType(elemType) Then
  2471. Emit "BBARRAY " + tmpArray.munged + " = bbArrayFromDataStruct" + Bra(TransArrayType(elemType) + "," + count + "," + tmpData.munged + ", sizeof" + Bra(TransObject(TObjectType(elemType).classdecl))) + ";"
  2472. Else If TEnumType(elemType)
  2473. Emit "BBARRAY " + tmpArray.munged + " = bbArrayFromDataSize" + Bra(TransArrayType(elemType) + "," + count + "," + tmpData.munged + "," + TEnumType(elemType).decl.ty.GetSize() ) + ";"
  2474. Else
  2475. Emit "BBARRAY " + tmpArray.munged + " = bbArrayFromData" + Bra(TransArrayType(elemType) + "," + count + "," + tmpData.munged ) + ";"
  2476. End If
  2477. Return tmpArray.munged
  2478. 'Return "bbArrayFromData" + Bra(TransArrayType(elemType) + "," + count + "," + tmp.munged )
  2479. 'Return "Array<"+TransRefType( elemType, "MM" )+" >("+tmp.munged+","+expr.exprs.Length+")"
  2480. End Method
  2481. Method TransArraySizeExpr$ ( expr:TArraySizeExpr )
  2482. ' scales[0] is the total size of the array
  2483. ' we start from [1] because it is the size of the next full dimension.
  2484. ' in the case of a 2-dimensional array, [1] represents the length of a row.
  2485. Return Bra("(BBARRAY)" + expr.expr.Trans()) + "->scales + 1"
  2486. End Method
  2487. Method TransIntrinsicExpr$( decl:TDecl,expr:TExpr,args:TExpr[] )
  2488. Local texpr$,arg0$,arg1$,arg2$
  2489. If expr texpr=TransSubExpr( expr )
  2490. If args.Length>0 And args[0] arg0=args[0].Trans()
  2491. If args.Length>1 And args[1] arg1=args[1].Trans()
  2492. If args.Length>2 And args[2] arg2=args[2].Trans()
  2493. Local id$=decl.munged[1..]
  2494. Local id2$=id[..1].ToUpper()+id[1..]
  2495. Select id
  2496. '
  2497. 'global functions
  2498. Case "print" Return "Print"+Bra( arg0 )
  2499. Case "error" Return "Error"+Bra( arg0 )
  2500. '
  2501. 'string/array methods
  2502. Case "length" Return texpr+".Length()"
  2503. Case "resize" Return texpr+".Resize"+Bra( arg0 )
  2504. 'string methods
  2505. Case "compare" Return texpr+".Compare"+Bra( arg0 )
  2506. Case "find" Return texpr+".Find"+Bra( arg0+","+arg1 )
  2507. Case "findlast" Return texpr+".FindLast"+Bra( arg0 )
  2508. Case "findlast2" Return texpr+".FindLast"+Bra( arg0+","+arg1 )
  2509. Case "trim" Return texpr+".Trim()"
  2510. Case "join" Return texpr+".Join"+Bra( arg0 )
  2511. Case "split" Return texpr+".Split"+Bra( arg0 )
  2512. Case "replace" Return texpr+".Replace"+Bra( arg0+","+arg1 )
  2513. Case "tolower" Return texpr+".ToLower()"
  2514. Case "toupper" Return texpr+".ToUpper()"
  2515. Case "contains" Return texpr+".Contains"+Bra( arg0 )
  2516. Case "startswith" Return texpr+".StartsWith"+Bra( arg0 )
  2517. Case "endswith" Return texpr+".EndsWith"+Bra( arg0 )
  2518. 'string functions
  2519. Case "fromchar" Return "String"+Bra( "(Char)"+Bra(arg0)+",1" )
  2520. 'math methods
  2521. Case "sin","cos","tan" Return "(float)"+id+Bra( Bra(arg0)+"*D2R" )
  2522. Case "asin","acos","atan" Return "(float)"+Bra( id+Bra(arg0)+"*R2D" )
  2523. Case "atan2" Return "(float)"+Bra( id+Bra(arg0+","+arg1)+"*R2D" )
  2524. Case "sqrt","floor","ceil","log" Return "(float)"+id+Bra( arg0 )
  2525. Case "pow" Return "(float)bbFloatPow"+Bra( arg0+","+arg1 )
  2526. '
  2527. End Select
  2528. InternalErr "TCTranslator.TransIntrinsicExpr"
  2529. End Method
  2530. '***** Statements *****
  2531. Method TransTryStmt$(tryStmt:TTryStmt)
  2532. Emit "{"
  2533. If tryStmt.finallyStmt Then MungDecl tryStmt.finallyStmt.finallyLabel
  2534. MungDecl tryStmt.rethrowLabel
  2535. MungDecl tryStmt.endTryLabel
  2536. Emit "BBOBJECT ex;"
  2537. If tryStmt.finallyStmt Then
  2538. ' for a nested Try construct, only declare this label once, because leaving such a construct
  2539. ' via Return, Exit Or Continue requires a jump to multiple Finally blocks in direct succession
  2540. ' and the "inner" declarations of retptr wouldn't be visible to the "outer" Finally blocks
  2541. Local alreadyDeclared:Int = False
  2542. For Local t:TTryStmt = EachIn tryStack
  2543. If t.finallyStmt Then alreadyDeclared = True; Exit
  2544. Next
  2545. If Not alreadyDeclared Then
  2546. Emit "void* retptr = &&" + tryStmt.rethrowLabel.munged + ";"
  2547. Else
  2548. Emit "retptr = &&" + tryStmt.rethrowLabel.munged + ";"
  2549. End If
  2550. End If
  2551. Emit "bbExTry {"
  2552. ' Try block:
  2553. Emit "case 0: {"
  2554. EmitLocalDeclarations tryStmt.block
  2555. If opt_debug Then Emit "bbOnDebugPushExState();"
  2556. PushLoopTryStack tryStmt
  2557. tryStack.Push tryStmt
  2558. EmitBlock tryStmt.block
  2559. tryStack.Pop
  2560. PopLoopTryStack
  2561. Emit "bbExLeave();"
  2562. If opt_debug Then Emit "bbOnDebugPopExState();"
  2563. ' run the Finally block if control reaches the end of the Try block
  2564. If tryStmt.finallyStmt Then EmitFinallyJmp tryStmt.finallyStmt, tryStmt.endTryLabel
  2565. Emit "}"
  2566. Emit "break;"
  2567. ' Catch blocks:
  2568. If tryStmt.catches Then
  2569. Emit "case 1: {"
  2570. If opt_debug Then Emit "bbOnDebugPopExState();"
  2571. If tryStmt.finallyStmt Then
  2572. If opt_debug Then Emit "bbOnDebugPushExState();"
  2573. Emit "ex = bbExCatchAndReenter();"
  2574. Else
  2575. Emit "ex = bbExCatch();"
  2576. End If
  2577. Local s:String = ""
  2578. For Local catchStmt:TCatchStmt = EachIn tryStmt.catches
  2579. MungDecl catchStmt.init
  2580. If TStringType(catchStmt.init.ty) Then
  2581. Emit s + "if (bbObjectStringcast((BBOBJECT)ex) != (BBOBJECT)&bbEmptyString) {"
  2582. Emit TransType(catchStmt.init.ty, catchStmt.init.munged) + " " + catchStmt.init.munged + "=(BBSTRING)ex;"
  2583. Else If TArrayType(catchStmt.init.ty) Then
  2584. Emit s + "if (bbObjectArraycast((BBOBJECT)ex) != &bbEmptyArray) {"
  2585. Emit TransType(catchStmt.init.ty, catchStmt.init.munged) + " " + catchStmt.init.munged + "=(BBARRAY)ex;"
  2586. Else If TObjectType(catchStmt.init.ty) Then
  2587. If TObjectType(catchStmt.init.ty).classDecl.IsInterface() Then
  2588. Emit s + "if (bbInterfaceDowncast((BBObject*)ex,(BBInterface*)&" + TObjectType(catchStmt.init.ty).classDecl.munged + "_ifc) != &bbNullObject) {"
  2589. Else
  2590. Emit s + "if (bbObjectDowncast((BBOBJECT)ex,(BBClass*)&" + TObjectType(catchStmt.init.ty).classDecl.munged + ") != &bbNullObject) {"
  2591. End If
  2592. Emit TransType(catchStmt.init.ty, catchStmt.init.munged) + " " + catchStmt.init.munged + "=" + Bra(TransType(catchStmt.init.ty, catchStmt.init.munged)) + "ex;"
  2593. Else
  2594. Err "Not an object"
  2595. End If
  2596. EmitLocalDeclarations catchStmt.block, catchStmt.init
  2597. If tryStmt.finallyStmt Then
  2598. PushLoopTryStack tryStmt
  2599. tryStack.Push tryStmt
  2600. EmitBlock catchStmt.block
  2601. tryStack.Pop
  2602. PopLoopTryStack
  2603. Else
  2604. EmitBlock catchStmt.block
  2605. End If
  2606. s = "} else "
  2607. Next
  2608. If tryStmt.finallyStmt Then
  2609. Emit s + "{"
  2610. ' run the Finally block if an exception was thrown from the Try block but not handled by any of the Catch blocks
  2611. Emit "bbExLeave();"
  2612. If opt_debug Then Emit "bbOnDebugPopExState();"
  2613. EmitFinallyJmp tryStmt.finallyStmt, tryStmt.rethrowLabel
  2614. Emit "}"
  2615. ' run the Finally block if an exception was thrown from the Try block and handled by one of the Catch blocks
  2616. Emit "bbExLeave();"
  2617. If opt_debug Then Emit "bbOnDebugPopExState();"
  2618. EmitFinallyJmp tryStmt.finallyStmt, tryStmt.endTryLabel
  2619. Else
  2620. Emit s + "{"
  2621. Emit "goto " + tryStmt.rethrowLabel.munged + ";"
  2622. Emit "}"
  2623. Emit "goto " + tryStmt.endTryLabel.munged + ";"
  2624. End If
  2625. Emit "}"
  2626. Emit "break;"
  2627. Else ' no catch blocks exist
  2628. Emit "case 1:"
  2629. 'If opt_debug Then Emit "bbOnDebugPopExState();"
  2630. End If
  2631. If tryStmt.finallyStmt Then
  2632. ' run the Finally block if an exception was thrown from a Catch block
  2633. Emit "case 2: {"
  2634. If opt_debug Then Emit "bbOnDebugPopExState();"
  2635. Emit "ex = bbExCatch();"
  2636. Emit "retptr = &&" + tryStmt.rethrowLabel.munged + ";"
  2637. Emit TransLabel(tryStmt.finallyStmt.finallyLabel)
  2638. EmitFinallyStmt tryStmt.finallyStmt
  2639. Emit "goto *retptr;"
  2640. Emit TransLabel(tryStmt.rethrowLabel)
  2641. Emit "bbExThrow(ex);"
  2642. Emit "}"
  2643. Emit "break;"
  2644. Else
  2645. Emit TransLabel(tryStmt.rethrowLabel)
  2646. Emit "bbExThrow(ex);"
  2647. End If
  2648. Emit "}"
  2649. Emit "}"
  2650. Emit TransLabel(tryStmt.endTryLabel)
  2651. End Method
  2652. Method EmitFinallyJmp(stmt:TFinallyStmt, returnLabel:TLoopLabelDecl)
  2653. Emit "retptr = &&" + returnLabel.munged + ";"
  2654. Emit "goto " + stmt.finallyLabel.munged + ";"
  2655. End Method
  2656. Method EmitFinallyStmt(f:TFinallyStmt)
  2657. Emit "{"
  2658. EmitLocalDeclarations f.block
  2659. EmitBlock f.block
  2660. Emit "}"
  2661. End Method
  2662. Method EmitDebugEnterScope(block:TBlockDecl)
  2663. Local scopeIndex:Int
  2664. Local count:Int
  2665. For Local decl:TDecl = EachIn block.Decls()
  2666. If TLocalDecl(decl) Then
  2667. count :+ 1
  2668. End If
  2669. If TGlobalDecl(decl) Then
  2670. count :+ 1
  2671. End If
  2672. Next
  2673. ' a method also includes "Self" reference back to parent Type
  2674. If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
  2675. count :+ 1
  2676. End If
  2677. If Not count Then
  2678. Emit "struct BBDebugScope __scope = {"
  2679. Else
  2680. Emit "struct BBDebugScope_" + count + " __scope = {"
  2681. _app.scopeDefs.Insert(String(count), "")
  2682. End If
  2683. If TFuncDecl(block) Then
  2684. Emit "BBDEBUGSCOPE_FUNCTION,"
  2685. If _app.mainFunc = block Then
  2686. ' use the filename as the base function name
  2687. Emit Enquote(StripExt(StripDir(_app.mainModule.filepath))) + ","
  2688. Else
  2689. Emit Enquote(TFuncDecl(block).ident) + ","
  2690. End If
  2691. Else
  2692. Emit "BBDEBUGSCOPE_LOCALBLOCK,"
  2693. Emit "0,"
  2694. End If
  2695. Emit "{"
  2696. If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
  2697. Emit "{"
  2698. Emit "BBDEBUGDECL_LOCAL,"
  2699. Emit "~qSelf~q,"
  2700. Emit Enquote(TransDebugScopeType(TClassDecl(block.scope).objectType)) + ","
  2701. Local prefix:String = "&"
  2702. If block.ClassScope().IsStruct() Then
  2703. prefix = ""
  2704. End If
  2705. Emit ".var_address=" + prefix + "o"
  2706. Emit "},"
  2707. scopeIndex:+ 1
  2708. End If
  2709. ' block globals
  2710. For Local gdecl:TGlobalDecl = EachIn block.Decls()
  2711. EmitGlobalDebugScope(gdecl, scopeIndex)
  2712. Next
  2713. ' iterate through decls and add as appropriate
  2714. For Local decl:TDecl = EachIn block.Decls()
  2715. Local ldecl:TLocalDecl = TLocalDecl(decl)
  2716. If ldecl Then
  2717. Emit "{"
  2718. If ldecl.ty._flags & TType.T_VAR Then
  2719. Emit "BBDEBUGDECL_VARPARAM,"
  2720. Else
  2721. Emit "BBDEBUGDECL_LOCAL,"
  2722. End If
  2723. Emit Enquote(ldecl.ident) + ","
  2724. Emit Enquote(TransDebugScopeType(ldecl.ty)) + ","
  2725. Emit ".var_address=&" + ldecl.munged
  2726. Emit "},"
  2727. Continue
  2728. End If
  2729. Next
  2730. Emit "{"
  2731. Emit "BBDEBUGDECL_END"
  2732. Emit "}"
  2733. Emit "}"
  2734. Emit "};"
  2735. ' threaded global
  2736. For Local gdecl:TGlobalDecl = EachIn block.Decls()
  2737. If gdecl.IsThreaded() Then
  2738. Emit "__scope.decls[" + gdecl.scopeIndex + "].var_address = &" + gdecl.munged + ";"
  2739. End If
  2740. Next
  2741. Emit "bbOnDebugEnterScope((BBDebugScope *)&__scope);"
  2742. End Method
  2743. Method EmitClassThreadedGlobalDebugInit(classDecl:TClassDecl)
  2744. Local classid:String = classDecl.munged
  2745. ' classid + "_scope
  2746. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  2747. If decl.IsThreaded() Then
  2748. Emit classid + "_scope.decls[" + decl.scopeIndex + "].var_address = &" + decl.munged + ";"
  2749. End If
  2750. Next
  2751. End Method
  2752. Method TransDebugNullObjectError:String(variable:String, cdecl:TClassDecl)
  2753. If cdecl.IsStruct() Or cdecl.ident = "String" Or cdecl.ident = "___Array" Then
  2754. 'Return cdecl.munged + "NullObjectTest(" + variable + ")"
  2755. Return variable
  2756. Else
  2757. Return Bra(Bra(TransObject(cdecl)) + "bbNullObjectTest((BBObject*)" + variable + ")")
  2758. End If
  2759. End Method
  2760. Method TransAssignStmt$( stmt:TAssignStmt )
  2761. If Not stmt.rhs Return stmt.lhs.Trans()
  2762. Local rhs$=stmt.rhs.Trans()
  2763. Local lhs$=stmt.lhs.TransVar()
  2764. Local s:String
  2765. Local cast:String
  2766. If TObjectType(stmt.lhs.exprType) And (Not TObjectType(stmt.lhs.exprType).classdecl.IsStruct() Or IsPointerType(stmt.lhs.exprType)) Then
  2767. If Not IsNumericType(stmt.rhs.exprType) Then
  2768. cast = Bra(TransType(stmt.lhs.exprType, ""))
  2769. End If
  2770. End If
  2771. If IsPointerType(stmt.lhs.exprType, TType.T_BYTE) And rhs = "&bbNullObject" Then
  2772. rhs = "0"
  2773. End If
  2774. If stmt.op = ":%" Then
  2775. If TDecimalType(stmt.lhs.exprType) Or TDecimalType(stmt.rhs.exprType) Then
  2776. Return lhs + "=bbFloatMod" + Bra(lhs + "," + rhs)
  2777. End If
  2778. End If
  2779. If TStringType(stmt.lhs.exprType) 'Or TStringVarPtrType(stmt.lhs.exprType) Then
  2780. ' s:+ "{"
  2781. ' s:+ "BBSTRING tmp=" + lhs + ";~n"
  2782. If stmt.op = ":+" Then
  2783. s :+ lhs+"=bbStringConcat("+lhs+","+rhs+")"
  2784. Else If rhs = "&bbNullObject" Then
  2785. s :+ lhs+TransAssignOp( stmt.op )+"&bbEmptyString"
  2786. Else
  2787. s :+ lhs+TransAssignOp( stmt.op )+rhs
  2788. End If
  2789. ' s :+ ";~nBBRETAIN(" + lhs +")~n"
  2790. ' s :+ "BBRELEASE(tmp)~n"
  2791. ' s:+ "}"
  2792. Else If TVarPtrType(stmt.lhs.exprType) Then
  2793. If TCastExpr(stmt.rhs) And IsNumericType(TCastExpr(stmt.rhs).expr.exprType) Then
  2794. rhs = TCastExpr(stmt.rhs).expr.Trans()
  2795. End If
  2796. s :+ lhs+TransAssignOp( stmt.op )+cast+rhs
  2797. Else If TArrayType(stmt.lhs.exprType) Then
  2798. If stmt.op = ":+" Then
  2799. s :+ lhs+"=bbArrayConcat("+ TransArrayType(TArrayType(stmt.lhs.exprType).elemType) + "," + lhs+","+rhs+")"
  2800. Else If rhs = "&bbNullObject" Then
  2801. s :+ lhs+TransAssignOp( stmt.op )+"&bbEmptyArray"
  2802. Else
  2803. s :+ lhs+TransAssignOp( stmt.op )+cast+rhs
  2804. End If
  2805. 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
  2806. rhs = TInvokeExpr(stmt.rhs).decl.munged
  2807. s :+ lhs+TransAssignOp( stmt.op )+cast+rhs
  2808. Else If TObjectType(stmt.lhs.exprType) And TObjectType(stmt.lhs.exprType).classDecl.IsStruct() And rhs = "&bbNullObject" Then
  2809. s :+ lhs+TransAssignOp( stmt.op )+cast+"{}"
  2810. Else
  2811. s :+ lhs+TransAssignOp( stmt.op )+cast+rhs
  2812. End If
  2813. If DEBUG Then
  2814. DebugObject(stmt.lhs.exprType, lhs, Null, True)
  2815. End If
  2816. Return s
  2817. End Method
  2818. Method TransThrowStmt:String( stmt:TThrowStmt )
  2819. Local s:String = "bbExThrow((BBObject *)"
  2820. s:+ stmt.expr.Trans()
  2821. s :+ ")"
  2822. Return s
  2823. End Method
  2824. Method TransAssertStmt$( stmt:TAssertStmt )
  2825. If opt_debug Then
  2826. Emit "if (!" + Bra(stmt.expr.Trans()) + ") {"
  2827. Emit "brl_blitz_RuntimeError(" + stmt.elseExpr.Trans() + ");"
  2828. Emit "}"
  2829. End If
  2830. End Method
  2831. Method TransEndStmt$( stmt:TEndStmt )
  2832. Emit "bbEnd();"
  2833. End Method
  2834. Method TransReleaseStmt$( stmt:TReleaseStmt )
  2835. Emit "bbHandleRelease" + Bra(stmt.expr.Trans()) + ";"
  2836. End Method
  2837. Method TransRestoreDataStmt$( stmt:TRestoreDataStmt )
  2838. Emit "_defDataOffset = &_defData[" + TDataLabelExpr(stmt.label).dataDef.label.index + "];"
  2839. End Method
  2840. Method TransReadDataStmt$( stmt:TReadDataStmt )
  2841. For Local expr:TExpr = EachIn stmt.args
  2842. ' buffer overflow test
  2843. If opt_debug Then
  2844. Emit "if (_defDataOffset - _defData >= " + TDefDataDecl.count + ") brl_blitz_OutOfDataError();"
  2845. End If
  2846. Emit expr.Trans() + " = " + TransDefDataConversion(expr.exprType) + Bra("_defDataOffset++") + ";"
  2847. Next
  2848. End Method
  2849. Method TransNativeStmt$( stmt:TNativeStmt)
  2850. Emit stmt.raw
  2851. End Method
  2852. Method TransFullName:String(decl:TDecl)
  2853. Local s:String
  2854. If decl.scope Then
  2855. s:+ TransFullName(decl.scope)
  2856. End If
  2857. If s Then
  2858. s :+ " : "
  2859. End If
  2860. If TModuleDecl(decl) Then
  2861. s:+ decl.ModuleScope().munged
  2862. Else
  2863. s :+ decl.ident
  2864. End If
  2865. If TFuncDecl(decl) Then
  2866. s:+ "()"
  2867. End If
  2868. Return s
  2869. End Method
  2870. Method ClassHasObjectField:Int(classDecl:TClassDecl, checked:TMap = Null)
  2871. If Not checked Then
  2872. checked = New TMap
  2873. End If
  2874. If checked.Contains(classDecl) Then
  2875. Return False
  2876. End If
  2877. checked.Insert(classDecl, "")
  2878. If classDecl.superClass Then
  2879. If ClassHasObjectField(classDecl.superClass, checked) Then
  2880. Return True
  2881. End If
  2882. End If
  2883. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  2884. If Not decl.IsSemanted() Then
  2885. decl.Semant()
  2886. End If
  2887. If IsManagedType(decl.ty, checked) Then
  2888. Return True
  2889. End If
  2890. Next
  2891. Return False
  2892. End Method
  2893. Method IsManagedType:Int(ty:TType, checked:TMap = Null)
  2894. If IsPointerType(ty) Then
  2895. Return False
  2896. End If
  2897. If TStringType(ty) Or (TArrayType(ty) And Not TArrayType(ty).isStatic) Or (TObjectType(ty) And Not TObjectType(ty).classDecl.IsStruct()) Then
  2898. Return True
  2899. End If
  2900. If TArrayType(ty) And TArrayType(ty).isStatic Then
  2901. Return IsManagedType(TArrayType(ty).elemType)
  2902. End If
  2903. If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
  2904. If ClassHasObjectField(TObjectType(ty).classDecl, checked) Then
  2905. Return True
  2906. End If
  2907. End If
  2908. Return False
  2909. End Method
  2910. '***** Declarations *****
  2911. Rem
  2912. Method EmitFuncProto( decl:TFuncDecl )
  2913. PushMungScope
  2914. decl.Semant
  2915. MungDecl decl
  2916. 'Find decl we override
  2917. Local odecl:TFuncDecl=decl
  2918. While odecl.overrides
  2919. odecl=odecl.overrides
  2920. Wend
  2921. Local args$
  2922. For Local arg:TArgDecl=EachIn odecl.argDecls
  2923. If args args:+","
  2924. args:+TransType( arg.ty )
  2925. Next
  2926. Local t$=TransType( odecl.retType )+" "+decl.munged+Bra( args )
  2927. If decl.IsAbstract() t:+"=0"
  2928. Local q$
  2929. If decl.IsExtern() q:+"extern "
  2930. If decl.IsMethod() q:+"virtual "
  2931. If decl.IsStatic() And decl.ClassScope() q:+"static "
  2932. Emit q+t+";"
  2933. PopMungScope
  2934. End Method
  2935. End Rem
  2936. Method EmitBBClassFuncProto( decl:TFuncDecl)
  2937. 'PushMungScope
  2938. BeginLocalScope
  2939. 'DebugStop
  2940. ' decl.Semant
  2941. ' MungDecl decl
  2942. 'Find decl we override
  2943. Local odecl:TFuncDecl=decl
  2944. 'If odecl.overrides And Not odecl.returnTypeSubclassed Then Return
  2945. 'DebugLog decl.ident
  2946. ' While odecl.overrides
  2947. ' odecl=odecl.overrides
  2948. ' Wend
  2949. Local id$=decl.munged
  2950. Local pre:String
  2951. If decl.IsMethod() Then
  2952. id :+ "_m"
  2953. pre = "m_"
  2954. Else
  2955. id :+ "_f"
  2956. pre = "f_"
  2957. End If
  2958. Local bk:String = ";"
  2959. 'Local pre:String = "typedef "
  2960. 'If odecl.IsExtern() Then
  2961. ' pre = "extern "
  2962. 'End If
  2963. 'DebugLog "id = " + id
  2964. Emit id + " " + pre + FuncDeclMangleIdent(odecl) + ";"
  2965. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  2966. Rem
  2967. If Not TFunctionPtrType(odecl.retType) Then
  2968. If Not odecl.castTo Then
  2969. Emit pre + TransType( odecl.retType, "" )+" "+ Bra("*" + id)+Bra( args ) + bk
  2970. Else
  2971. If Not odecl.noCastGen Then
  2972. Emit pre + odecl.castTo +" "+Bra("*" + id)+Bra( args ) + bk
  2973. End If
  2974. End If
  2975. Else
  2976. If Not odecl.castTo Then
  2977. Emit pre + TransType( odecl.retType, id )+" "+Bra( args ) + bk
  2978. Else
  2979. If Not odecl.noCastGen Then
  2980. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  2981. End If
  2982. End If
  2983. End If
  2984. For Local t$=EachIn argCasts
  2985. Emit t
  2986. Next
  2987. ' End If
  2988. End Rem
  2989. 'PopMungScope
  2990. EndLocalScope
  2991. End Method
  2992. Method FuncDeclMangleIdent:String(fdecl:TFuncDecl)
  2993. If (Not fdecl.ClassScope()) Or (equalsBuiltInFunc(fdecl.classScope(), fdecl)) Then
  2994. Return fdecl.ident
  2995. End If
  2996. If Not fdecl.mangled Then
  2997. Local id:String = fdecl.ident
  2998. If fdecl.attrs & FUNC_OPERATOR Then
  2999. id = MungSymbol(id)
  3000. End If
  3001. fdecl.mangled = id + MangleMethod(fdecl)
  3002. End If
  3003. Return fdecl.mangled
  3004. ' If fdecl.olIndex Then
  3005. ' Return fdecl.ident + fdecl.olIndex
  3006. ' Else
  3007. ' Return fdecl.ident
  3008. ' End If
  3009. End Method
  3010. Method EmitClassFuncProto( decl:TFuncDecl, isStruct:Int = False, emitFuncProtos:Int = True)
  3011. 'PushMungScope
  3012. BeginLocalScope
  3013. decl.Semant
  3014. MungDecl decl
  3015. 'Find decl we override
  3016. Local odecl:TFuncDecl=decl
  3017. ' If odecl.overrides Then Return
  3018. While odecl.overrides
  3019. odecl=odecl.overrides
  3020. Wend
  3021. 'Generate 'args' string and arg casts
  3022. Local args$
  3023. ' pass object for method
  3024. If decl.IsMethod() Then
  3025. args :+ TransObject(decl.scope, True)
  3026. End If
  3027. Local argCasts:TStack =New TStack
  3028. For Local i:Int=0 Until decl.argDecls.Length
  3029. Local arg:TArgDecl=decl.argDecls[i]
  3030. Local oarg:TArgDecl=odecl.argDecls[i]
  3031. MungDecl arg
  3032. If args args:+","
  3033. If Not TFunctionPtrType(oarg.ty) Then
  3034. If Not odecl.castTo Then
  3035. args:+TransType( oarg.ty, arg.munged )
  3036. If TArrayType(oarg.ty) And TArrayType(oarg.ty).isStatic Then
  3037. args :+ "[" + TArrayType(oarg.ty).length + "]"
  3038. End If
  3039. Else
  3040. args:+ oarg.castTo + " " + arg.munged
  3041. End If
  3042. Else
  3043. If Not odecl.castTo Then
  3044. args:+TransType( oarg.ty, arg.munged )
  3045. Else
  3046. args:+ oarg.castTo
  3047. End If
  3048. End If
  3049. If arg.ty.EqualsType( oarg.ty ) Continue
  3050. Local t$=arg.munged
  3051. arg.munged=""
  3052. MungDecl arg
  3053. argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
  3054. Next
  3055. Local id$=decl.munged
  3056. Local bk:String = ";"
  3057. Local pre:String = "typedef "
  3058. Local api:String
  3059. If decl.IsMethod() Then
  3060. id :+ "_m"
  3061. Else
  3062. id :+ "_f"
  3063. End If
  3064. If decl.attrs & DECL_API_STDCALL Then
  3065. api = " __stdcall "
  3066. End If
  3067. 'If odecl.IsExtern() Then
  3068. ' pre = "extern "
  3069. 'End If
  3070. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  3071. 'If emitFuncProtos
  3072. If Not TFunctionPtrType(decl.retType) Then
  3073. If Not odecl.castTo Then
  3074. If Not isStruct Then
  3075. Emit pre + TransType( decl.retType, "" )+" "+ Bra(api + "*" + id)+Bra( args ) + bk
  3076. End If
  3077. If emitFuncProtos
  3078. If decl.IsMethod() Then
  3079. Emit TransType(decl.retType, "") + " _" + decl.munged +Bra( args ) + bk
  3080. Else
  3081. Emit TransType(decl.retType, "") + api + " " + decl.munged +Bra( args ) + bk
  3082. End If
  3083. End If
  3084. Else
  3085. If Not odecl.noCastGen Then
  3086. If Not isStruct Then
  3087. If Not decl.overrides Or decl.returnTypeSubclassed Then
  3088. Emit pre + odecl.castTo +" "+Bra(api + "*" + id)+Bra( args ) + bk
  3089. End If
  3090. End If
  3091. If emitFuncProtos
  3092. If decl.IsMethod() Then
  3093. Emit odecl.castTo + " _" + decl.munged +Bra( args ) + bk
  3094. Else
  3095. Emit odecl.castTo + " " + decl.munged +Bra( args ) + bk
  3096. End If
  3097. End If
  3098. End If
  3099. End If
  3100. Else
  3101. If Not odecl.castTo Then
  3102. If Not args Then
  3103. ' for function pointer return type, we need to generate () regardless of whether there are
  3104. ' args or not.
  3105. args = " "
  3106. End If
  3107. ' emit function ptr typedef
  3108. Emit pre + TransType( decl.retType, id + "x") + bk
  3109. ' emit actual typedef (with return type of above typedef)
  3110. Emit pre + TransType( decl.retType, id, args, True ) + bk
  3111. Else
  3112. If Not odecl.noCastGen Then
  3113. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  3114. End If
  3115. End If
  3116. End If
  3117. For Local t$=EachIn argCasts
  3118. Emit t
  3119. Next
  3120. 'End If
  3121. 'PopMungScope
  3122. EndLocalScope
  3123. End Method
  3124. Method EmitFuncDecl( decl:TFuncDecl, proto:Int = False, classFunc:Int = False )
  3125. 'If Not proto And decl.IsAbstract() Return
  3126. Local tmpDebug:Int = opt_debug
  3127. If decl.isNoDebug() Then
  3128. opt_debug = False
  3129. End If
  3130. BeginLocalScope
  3131. decl.Semant
  3132. MungDecl decl
  3133. ' export defs?
  3134. If opt_apptype And opt_def And decl.attrs & DECL_EXPORT Then
  3135. If Not _appInstance.exportDefs.Contains(decl) Then
  3136. _appInstance.exportDefs.AddLast(decl)
  3137. End If
  3138. End If
  3139. ' emit nested functions/classes
  3140. If Not proto Then
  3141. ' emit nested classes
  3142. For Local cdecl:TClassDecl = EachIn decl._decls
  3143. MungDecl cdecl
  3144. EmitClassProto(cdecl, False)
  3145. EmitClassDecl(cdecl)
  3146. Next
  3147. ' emit nested protos
  3148. For Local fdecl:TFuncDecl = EachIn decl._decls
  3149. EmitFuncDecl(fdecl, True, classFunc)
  3150. Next
  3151. ' emit nested bodies
  3152. For Local fdecl:TFuncDecl = EachIn decl._decls
  3153. EmitFuncDecl(fdecl, proto, classFunc)
  3154. Next
  3155. End If
  3156. 'Find decl we override
  3157. Local odecl:TFuncDecl=decl
  3158. While odecl.overrides
  3159. odecl=odecl.overrides
  3160. Wend
  3161. 'Generate 'args' string and arg casts
  3162. Local args$
  3163. ' pass object for method
  3164. If decl.IsMethod() Then
  3165. args :+ TransObject(decl.scope, True) + " o"
  3166. End If
  3167. Local argCasts:TStack =New TStack
  3168. For Local i:Int=0 Until decl.argDecls.Length
  3169. Local arg:TArgDecl=decl.argDecls[i]
  3170. Local oarg:TArgDecl=odecl.argDecls[i]
  3171. MungDecl arg, True
  3172. If args args:+","
  3173. If Not TFunctionPtrType(oarg.ty) Then
  3174. If Not odecl.castTo Then
  3175. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  3176. If TArrayType(oarg.ty) And TArrayType(oarg.ty).isStatic Then
  3177. args :+ "[" + TArrayType(oarg.ty).length + "]"
  3178. End If
  3179. Else
  3180. args:+ oarg.castTo + " " + arg.munged
  3181. End If
  3182. Else
  3183. If Not odecl.castTo Then
  3184. args:+TransType( oarg.ty, arg.munged )
  3185. Else
  3186. args:+ oarg.castTo
  3187. End If
  3188. End If
  3189. If arg.ty.EqualsType( oarg.ty ) Continue
  3190. Local t$=arg.munged
  3191. arg.munged=""
  3192. MungDecl arg
  3193. argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
  3194. Next
  3195. Local id$=decl.munged
  3196. If classFunc Then
  3197. If decl.IsMethod() Then
  3198. id = "_" + id
  3199. End If
  3200. Else
  3201. If Not odecl.IsExtern() Then
  3202. id = id
  3203. End If
  3204. End If
  3205. Local iterations:Int = 1
  3206. If decl.attrs & DECL_INLINE Then
  3207. iterations = 2
  3208. End If
  3209. Local origProto:Int = proto
  3210. For Local i:Int = 0 Until iterations
  3211. proto = origProto
  3212. Local bk:String = "{"
  3213. Local pre:String
  3214. Local api:String
  3215. If proto Then
  3216. If odecl.IsExtern() Then
  3217. pre = "extern "
  3218. If TFunctionPtrType(decl.retType) Then
  3219. pre = ""
  3220. End If
  3221. End If
  3222. If decl.attrs & DECL_INLINE And i = 0 Then
  3223. pre = "inline "
  3224. Else
  3225. bk = ";"
  3226. End If
  3227. Else If decl.attrs & DECL_INLINE And i = 0 Then
  3228. pre = "extern "
  3229. bk = ";"
  3230. End If
  3231. If decl.attrs & DECL_INLINE Then
  3232. Select i
  3233. Case 0
  3234. pre = "#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L~n" + pre
  3235. Case 1
  3236. pre = "#else~n" + pre
  3237. End Select
  3238. End If
  3239. If decl.attrs & DECL_API_STDCALL Then
  3240. api = " __stdcall "
  3241. End If
  3242. ' If Not proto Or (proto And Not odecl.IsExtern()) Then
  3243. If Not IsStandardFunc(decl.munged) Then
  3244. If Not TFunctionPtrType(odecl.retType) Then
  3245. If Not odecl.castTo Then
  3246. Emit pre + TransType( decl.retType, "" )+ api + " "+id+Bra( args ) + bk
  3247. Else
  3248. If Not odecl.noCastGen Then
  3249. Emit pre + odecl.castTo + api + " "+id+Bra( args ) + bk
  3250. End If
  3251. End If
  3252. Else
  3253. If Not odecl.castTo Then
  3254. If Not args Then
  3255. ' for function pointer return type, we need to generate () regardless of whether there are
  3256. ' args or not.
  3257. args = " "
  3258. End If
  3259. Emit pre + TransType( decl.retType, id, args )+ bk
  3260. Else
  3261. If Not odecl.noCastGen Then
  3262. Emit pre + odecl.castTo +" "+Bra( args ) + bk
  3263. End If
  3264. End If
  3265. End If
  3266. For Local t$=EachIn argCasts
  3267. Emit t
  3268. Next
  3269. End If
  3270. If decl.attrs & DECL_INLINE And i = 0 Then
  3271. proto = Not proto
  3272. End If
  3273. If Not proto Then
  3274. If opt_coverage Then
  3275. EmitCoverageFunction(decl)
  3276. End If
  3277. If PROFILER Then
  3278. Select decl.ident
  3279. Case "WritePixel", "PixelPtr", "CopyPixels", "ConvertPixels", "ConvertPixelsToStdFormat", "ConvertPixelsFromStdFormat"
  3280. Case "OnDebugEnterScope", "OnDebugEnterStm", "GetDbgState", "OnDebugLeaveScope", "OnDebugPopExState", "OnDebugPushExState"
  3281. Default
  3282. DebugPrint("", TransFullName(decl))
  3283. End Select
  3284. End If
  3285. If DEBUG Then
  3286. For Local i:Int=0 Until decl.argDecls.Length
  3287. Local arg:TArgDecl=decl.argDecls[i]
  3288. DebugObject(arg.ty, arg.munged, id)
  3289. Next
  3290. End If
  3291. If decl.IsAbstract() Then
  3292. Emit "brl_blitz_NullMethodError();"
  3293. If Not TVoidType( decl.retType ) Then
  3294. Local ret:TReturnStmt = New TReturnStmt.Create(New TConstExpr.Create( decl.retType,"" ).Semant())
  3295. ret.fRetType = decl.retType
  3296. Emit ret.Trans() + ";"
  3297. unreachable = False
  3298. End If
  3299. Else
  3300. decl.Semant()
  3301. If opt_debug And decl.IsMethod() And Not TClassDecl(decl.scope).IsStruct() Then
  3302. Emit TransDebugNullObjectError("o", TClassDecl(decl.scope)) + ";"
  3303. End If
  3304. EmitLocalDeclarations(decl)
  3305. EmitBlock decl
  3306. End If
  3307. Emit "}"
  3308. End If
  3309. Next
  3310. If decl.attrs & DECL_INLINE Then
  3311. Emit "#endif"
  3312. End If
  3313. ' reset label ids
  3314. contLabelId = 0
  3315. exitLabelId = 0
  3316. EndLocalScope
  3317. 'PopMungScope
  3318. opt_debug = tmpDebug
  3319. End Method
  3320. Method EmitLocalDeclarations(decl:TScopeDecl, ignoreVar:TValDecl = Null)
  3321. If opt_debug Then
  3322. For Local ldecl:TLocalDecl = EachIn decl.Decls()
  3323. If ldecl <> ignoreVar Then
  3324. If Not TArgDecl(ldecl) And Not ldecl.generated Then
  3325. MungDecl ldecl
  3326. Local ty:TType = ldecl.ty
  3327. Local t:String = TransLocalDeclNoInit(ldecl)
  3328. ' If TObjectType( ty ) And TObjectType( ty ).classDecl.IsStruct() Then
  3329. ' t :+ "={}"
  3330. ' End If
  3331. Emit t + ";"
  3332. End If
  3333. End If
  3334. Next
  3335. End If
  3336. End Method
  3337. Method EmitClassFieldsProto(classDecl:TClassDecl)
  3338. If classDecl.superClass Then
  3339. EmitClassFieldsProto(classDecl.superClass)
  3340. End If
  3341. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3342. decl.Semant()
  3343. If Not TFunctionPtrType(decl.ty) Then
  3344. If classDecl.IsExtern() Then
  3345. Emit TransType(decl.ty, "") + " " + decl.ident + ";"
  3346. Else
  3347. Local t:String = TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower()
  3348. If TArrayType(decl.ty) And TArrayType(decl.ty).isStatic Then
  3349. t :+ "[" + TArrayType(decl.ty).length + "]"
  3350. End If
  3351. Emit t + ";"
  3352. End If
  3353. Else
  3354. If classDecl.IsExtern() Then
  3355. Emit TransType(decl.ty, decl.ident) + ";"
  3356. Else
  3357. Emit TransType(decl.ty, "_" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower()) + ";"
  3358. End If
  3359. End If
  3360. Next
  3361. End Method
  3362. Method EmitClassGlobalsProto(classDecl:TClassDecl)
  3363. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  3364. decl.Semant()
  3365. If TFunctionPtrType(decl.ty) Then
  3366. Emit "extern " + TransThreadedGlobal(decl) + TransRefType( decl.ty, decl.munged ) + ";"
  3367. Else
  3368. Emit "extern " + TransThreadedGlobal(decl) +TransRefType( decl.ty, "" )+" "+ decl.munged+";"
  3369. End If
  3370. Next
  3371. End Method
  3372. Method BBClassClassFuncProtoBuildList( classDecl:TClassDecl, list:TList )
  3373. Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls()
  3374. For Local decl:TFuncDecl=EachIn fdecls
  3375. If Not decl.IsSemanted()
  3376. decl.Semant()
  3377. End If
  3378. If Not equalsBuiltInFunc(classDecl, decl) And Not equalsTorFunc(classDecl, decl) Then
  3379. Local fdecl:TFuncDecl = classDecl.GetLatestFuncDecl(decl)
  3380. list.AddLast(fdecl)
  3381. End If
  3382. Next
  3383. End Method
  3384. Method EmitBBClassClassFuncProto( classDecl:TClassDecl )
  3385. Local list:TList = New TList
  3386. BBClassClassFuncProtoBuildList(classDecl, list)
  3387. For Local fdecl:TFuncDecl = EachIn list
  3388. EmitBBClassFuncProto( fdecl )
  3389. Next
  3390. End Method
  3391. Method EmitClassProto( classDecl:TClassDecl, emitFuncProtos:Int = True )
  3392. If classDecl.args Then
  3393. Return
  3394. End If
  3395. Local classid$=classDecl.munged
  3396. Local superid$
  3397. If classDecl.superClass Then
  3398. superid=classDecl.superClass.actual.munged
  3399. End If
  3400. 'Emit "void _" + classid + "_New" + Bra(TransObject(classdecl) + " o") + ";"
  3401. If emitFuncProtos Then
  3402. EmitClassDeclNewListProto(classDecl)
  3403. If classHierarchyHasFunction(classDecl, "Delete") Then
  3404. Emit "void _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + ";"
  3405. End If
  3406. If classHasFunction(classDecl, "ToString") Then
  3407. Emit "BBSTRING _" + classid + "_ToString" + Bra(TransObject(classdecl) + " o") + ";"
  3408. End If
  3409. If classHasFunction(classDecl, "Compare") Then
  3410. Emit "BBINT _" + classid + "_Compare(" + TransObject(classdecl) + " o, BBOBJECT otherObject);"
  3411. End If
  3412. If classHasFunction(classDecl, "SendMessage") Then
  3413. Emit "BBOBJECT _" + classid + "_SendMessage(" + TransObject(classdecl) + " o, BBOBJECT message, BBOBJECT source);"
  3414. End If
  3415. End If
  3416. 'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  3417. classDecl.SemantParts()
  3418. 'Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls(Null, False)
  3419. For Local decl:TDecl=EachIn classDecl.Decls()
  3420. 'For Local fdecl:TFuncDecl = EachIn fdecls
  3421. Local fdecl:TFuncDecl =TFuncDecl( decl )
  3422. If fdecl
  3423. If Not equalsBuiltInFunc(classDecl, fdecl) And Not equalsTorFunc(classDecl, fdecl) Then
  3424. EmitClassFuncProto( fdecl, , emitFuncProtos )
  3425. Continue
  3426. End If
  3427. EndIf
  3428. Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  3429. If gdecl
  3430. MungDecl gdecl
  3431. ' Emit "static "+TransRefType( gdecl.ty )+" "+gdecl.munged+";"
  3432. Continue
  3433. EndIf
  3434. Next
  3435. Emit ""
  3436. ' emit the class structure
  3437. Emit "struct BBClass_" + classid + " {"
  3438. If classDecl.superClass.ident = "Object" Then
  3439. Emit "BBClass* super;"
  3440. Else
  3441. Emit "struct BBClass_" + classDecl.superClass.munged + "* super;"
  3442. End If
  3443. Emit "void (*free)( BBObject *o );"
  3444. Emit "BBDebugScope* debug_scope;"
  3445. Emit "unsigned int instance_size;"
  3446. Emit "void (*ctor)( BBOBJECT o );"
  3447. Emit "void (*dtor)( BBOBJECT o );"
  3448. Emit "BBSTRING (*ToString)( BBOBJECT x );"
  3449. Emit "int (*Compare)( BBOBJECT x,BBOBJECT y );"
  3450. Emit "BBOBJECT (*SendMessage)( BBOBJECT o,BBOBJECT m,BBOBJECT s );"
  3451. Emit "BBINTERFACETABLE itable;"
  3452. Emit "void* extra;"
  3453. Emit "unsigned int obj_size;"
  3454. Emit "unsigned int instance_count;"
  3455. Emit "unsigned int fields_offset;"
  3456. EmitBBClassClassFuncProto(classDecl)
  3457. Emit "};~n"
  3458. If classDecl.IsInterface() Then
  3459. Emit "struct " + classid + "_methods {"
  3460. EmitBBClassClassFuncProto(classDecl)
  3461. Emit "};~n"
  3462. End If
  3463. Emit "struct " + classid + "_obj {"
  3464. Emit "struct BBClass_" + classid + "* clas;"
  3465. BeginLocalScope
  3466. EmitClassFieldsProto(classDecl)
  3467. EndLocalScope
  3468. Emit "};"
  3469. Emit "extern struct BBClass_" + classid + " " + classid + ";"
  3470. EmitClassGlobalsProto(classDecl);
  3471. ' fields
  3472. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3473. MungDecl decl
  3474. Next
  3475. End Method
  3476. Method EmitExternClassFuncProto( classDecl:TClassDecl )
  3477. If classDecl.superClass Then
  3478. EmitExternClassFuncProto(classDecl.superClass)
  3479. End If
  3480. For Local decl:TFuncDecl = EachIn classDecl.Decls()
  3481. decl.Semant()
  3482. ' code is written as a method, but emitted as a function pointer
  3483. ' with self as the first parameter
  3484. Local func:TFuncDecl = TFuncDecl(decl.Copy())
  3485. Local argDecl:TArgDecl = New TArgDecl.Create("This", classDecl.objectType, Null)
  3486. func.argDecls = [argDecl] + func.argDecls
  3487. func.Semant()
  3488. Local ty:TFunctionPtrType = New TFunctionPtrType
  3489. ty.func = func
  3490. Emit TransType(ty, decl.Ident) + ";"
  3491. Next
  3492. End Method
  3493. Method EmitExternClassTypeFuncProto( classDecl:TClassDecl )
  3494. Local doneCtorDtor:Int
  3495. Local iDecl:TClassDecl
  3496. For Local decl:TFuncDecl = EachIn classDecl.GetAllOriginalFuncDecls(Null, True)
  3497. decl.Semant()
  3498. ' first interface preceeds ctor/dtor
  3499. If Not doneCtorDtor
  3500. If Not iDecl And TClassDecl(decl.scope).IsInterface() Then
  3501. iDecl = TClassDecl(decl.scope)
  3502. End If
  3503. If iDecl
  3504. If iDecl <> TClassDecl(decl.scope) Then
  3505. ' a different interface
  3506. doneCtorDtor = True
  3507. Emit "void(*_ctor)();"
  3508. Emit "void(*_dtor)();"
  3509. End If
  3510. Else
  3511. doneCtorDtor = True
  3512. Emit "void(*_ctor)();"
  3513. Emit "void(*_dtor)();"
  3514. End If
  3515. End If
  3516. ' code is written as a method, but emitted as a function pointer
  3517. ' with self as the first parameter
  3518. Local func:TFuncDecl = TFuncDecl(decl.Copy())
  3519. Local argDecl:TArgDecl = New TArgDecl.Create("This", classDecl.objectType, Null)
  3520. func.argDecls = [argDecl] + func.argDecls
  3521. func.Semant()
  3522. Local ty:TFunctionPtrType = New TFunctionPtrType
  3523. ty.func = func
  3524. Emit TransType(ty, decl.Ident) + ";"
  3525. Next
  3526. End Method
  3527. Method EmitExternClassProtoTypedef( classDecl:TClassDecl )
  3528. Emit "typedef struct " + classDecl.ident + " " + classDecl.ident + ";"
  3529. End Method
  3530. Method EmitExternClassProto( classDecl:TClassDecl )
  3531. ' vtable
  3532. Emit "struct " + classDecl.ident + "Vtbl {"
  3533. ' methods
  3534. If classDecl.IsInterface() Then
  3535. EmitExternClassFuncProto(classDecl)
  3536. Else
  3537. EmitExternClassTypeFuncProto(classDecl)
  3538. End If
  3539. Emit "};"
  3540. Emit "struct " + classDecl.ident + " {"
  3541. Emit "struct " + classDecl.ident + "Vtbl* vtbl;"
  3542. Emit "};"
  3543. End Method
  3544. Field emittedStructs:TList = New TList
  3545. Method EmitStructClassProto( classDecl:TClassDecl )
  3546. If classDecl.declImported Return
  3547. If emittedStructs.Contains(classDecl) Return
  3548. emittedStructs.AddLast(classDecl)
  3549. ' emit any dependent structs first
  3550. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3551. decl.Semant()
  3552. If TObjectType(decl.ty) And TObjectType(decl.ty).classDecl.IsStruct() Then
  3553. If Not emittedStructs.Contains(TObjectType(decl.ty).classDecl) Then
  3554. EmitStructClassProto(TObjectType(decl.ty).classDecl)
  3555. End If
  3556. End If
  3557. Next
  3558. If classDecl.IsExtern()
  3559. Emit "struct " + classDecl.ident + " {"
  3560. Else
  3561. EmitClassDeclNewListProto( classDecl )
  3562. For Local fdecl:TFuncDecl=EachIn classDecl.Decls()
  3563. If fdecl.IdentLower() <> "new" Then
  3564. EmitClassFuncProto( fdecl, True )
  3565. End If
  3566. Next
  3567. Emit "struct " + classDecl.munged + " {"
  3568. End If
  3569. BeginLocalScope
  3570. EmitClassFieldsProto(classDecl)
  3571. EndLocalScope
  3572. Emit "};"
  3573. EmitClassGlobalsProto(classDecl);
  3574. End Method
  3575. Method classHasFunction:Int(classDecl:TClassDecl, func:String)
  3576. Local f:String = func.ToLower()
  3577. For Local decl:TFuncDecl = EachIn classDecl.Decls()
  3578. If Not decl.IsSemanted() Then
  3579. decl.Semant
  3580. End If
  3581. If decl.IdentLower() = f And equalsBuiltInFunc(classDecl.superClass, decl) Then
  3582. Return True
  3583. End If
  3584. Next
  3585. Return False
  3586. End Method
  3587. Method classHierarchyHasFunction:Int(classDecl:TClassDecl, func:String)
  3588. If classHasFunction(classDecl, func) Return True
  3589. If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
  3590. Return classHierarchyHasFunction(classDecl.superClass, func)
  3591. End If
  3592. Return False
  3593. End Method
  3594. Method classidForFunction:String(classDecl:TClassDecl, func:String)
  3595. If classHasFunction(classDecl, func) Return classDecl.munged
  3596. If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
  3597. Return classidForFunction(classDecl.superClass, func)
  3598. End If
  3599. Return Null
  3600. End Method
  3601. Method EmitMark( id$,ty:TType,queue:Int )
  3602. If TObjectType( ty )
  3603. If id.EndsWith( ".p" )
  3604. If ty.GetClass().IsInterface() id=id[..-2] Else InternalErr "TCTranslator.EmitMark"
  3605. Else
  3606. If ty.GetClass().IsInterface() InternalErr "TCTranslator.EmitMark"
  3607. EndIf
  3608. If queue
  3609. Emit "gc_mark_q("+id+");"
  3610. Else
  3611. Emit "gc_mark("+id+");"
  3612. EndIf
  3613. Else If TArrayType( ty )
  3614. Emit "gc_mark("+id+");"
  3615. Return
  3616. EndIf
  3617. End Method
  3618. Method EmitClassConstsDebugScope(classDecl:TClassDecl, scopeIndex:Int Var)
  3619. For Local decl:TConstDecl = EachIn classDecl.Decls()
  3620. EmitConstDebugScope(decl)
  3621. scopeIndex :+ 1
  3622. Next
  3623. End Method
  3624. Method EmitConstDebugScope(decl:TConstDecl)
  3625. Emit "{"
  3626. Emit "BBDEBUGDECL_CONST,"
  3627. Emit Enquote(decl.ident) + ","
  3628. Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
  3629. _appInstance.mapStringConsts(decl.value)
  3630. Emit ".const_value=(BBString*)&" + StringConstId(decl.value)
  3631. Emit "},"
  3632. End Method
  3633. Method EmitClassFieldsDebugScope(classDecl:TClassDecl, scopeIndex:Int Var)
  3634. ' Don't list superclass fields in our debug scope
  3635. 'If classDecl.superClass Then
  3636. ' EmitClassFieldsDebugScope(classDecl.superClass)
  3637. 'End If
  3638. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3639. Emit "{"
  3640. Emit "BBDEBUGDECL_FIELD,"
  3641. Emit Enquote(decl.ident) + ","
  3642. Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
  3643. Local offset:String = ".field_offset=offsetof"
  3644. If classDecl.IsStruct() Then
  3645. offset :+ Bra("struct " + classDecl.munged + "," + decl.munged)
  3646. Else
  3647. offset :+ Bra("struct " + classDecl.munged + "_obj," + decl.munged)
  3648. End If
  3649. ' If WORD_SIZE = 8 Then
  3650. ' Emit Bra("BBLONG") + offset
  3651. ' Else
  3652. Emit offset
  3653. ' End If
  3654. 'If Not TFunctionPtrType(decl.ty) Then
  3655. ' Emit TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.ident.ToLower() + ";"
  3656. 'Else
  3657. ' Emit TransType(decl.ty, "_" + classDecl.actual.munged.ToLower() + "_" + decl.ident.ToLower()) + ";"
  3658. 'End If
  3659. Emit "},"
  3660. scopeIndex :+ 1
  3661. 'offset:+ decl.ty.GetSize()
  3662. Next
  3663. 'Return offset
  3664. End Method
  3665. Method EmitClassStandardMethodDebugScope(ident:String, ty:String, munged:String)
  3666. Emit "{"
  3667. Emit "BBDEBUGDECL_TYPEMETHOD,"
  3668. Emit Enquote(ident) + ","
  3669. Emit Enquote(ty) + ","
  3670. Emit ".func_ptr=(BBFuncPtr)&" + munged
  3671. Emit "},"
  3672. End Method
  3673. Method TransDebugMetaData:String(meta:String)
  3674. If meta Then
  3675. Return "{" + meta + "}"
  3676. End If
  3677. End Method
  3678. Method EmitBBClassFuncsDebugScope(decl:TFuncDecl)
  3679. Emit "{"
  3680. If decl.IsMethod() Then
  3681. Emit "BBDEBUGDECL_TYPEMETHOD,"
  3682. Else
  3683. Emit "BBDEBUGDECL_TYPEFUNCTION,"
  3684. End If
  3685. Emit Enquote(decl.ident) + ","
  3686. Local s:String = "("
  3687. For Local i:Int = 0 Until decl.argDecls.length
  3688. If i Then
  3689. s:+ ","
  3690. End If
  3691. s:+ TransDebugScopeType(decl.argDecls[i].ty)
  3692. Next
  3693. s:+ ")"
  3694. If decl.retType Then
  3695. s:+ TransDebugScopeType(decl.retType)
  3696. End If
  3697. s:+ TransDebugMetaData(decl.metadata.metadataString)
  3698. Emit Enquote(s) + ","
  3699. If decl.IsMethod() Or decl.IsCTor() Then
  3700. Emit ".func_ptr=(BBFuncPtr)&_" + decl.munged
  3701. Else
  3702. Emit ".func_ptr=(BBFuncPtr)&" + decl.munged
  3703. End If
  3704. Emit "},"
  3705. End Method
  3706. Method BBClassClassFuncsDebugScopeBuildList(classDecl:TClassDecl, list:TList)
  3707. 'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  3708. For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
  3709. Local fdecl:TFuncDecl =TFuncDecl( decl )
  3710. If fdecl
  3711. If Not fdecl.IsSemanted()
  3712. fdecl.Semant()
  3713. End If
  3714. If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
  3715. Continue
  3716. End If
  3717. If Not equalsBuiltInFunc(classDecl, fdecl) Then
  3718. Local ignore:Int
  3719. Local link:TLink=list._head._succ
  3720. While link<>list._head
  3721. Local ofdecl:TFuncDecl = TFuncDecl(link._value)
  3722. If fdecl.ident = ofdecl.ident And fdecl.EqualsArgs(ofdecl) And fdecl.scope <> ofdecl.scope Then
  3723. If fdecl.overrides Then
  3724. link._value = fdecl
  3725. ignore = True
  3726. Exit
  3727. End If
  3728. EndIf
  3729. link = link._succ
  3730. Wend
  3731. If Not ignore Then
  3732. list.AddLast(fdecl)
  3733. End If
  3734. Continue
  3735. End If
  3736. EndIf
  3737. Next
  3738. End Method
  3739. Method EmitBBClassClassFuncsDebugScope(classDecl:TClassDecl)
  3740. Local list:TList = New TList
  3741. BBClassClassFuncsDebugScopeBuildList(classDecl, list)
  3742. For Local fdecl:TFuncDecl = EachIn list
  3743. EmitBBClassFuncsDebugScope( fdecl )
  3744. Next
  3745. End Method
  3746. Method EmitClassFuncsDebugScope(classDecl:TClassDecl)
  3747. If classDecl.IsExtern() Return
  3748. Local classid$=classDecl.munged
  3749. Local superid$
  3750. If classDecl.superClass Then
  3751. superid = classDecl.superClass.actual.munged
  3752. End If
  3753. Local ret:String = "()i"
  3754. If opt_issuperstrict Then
  3755. ret = "()"
  3756. End If
  3757. If Not classDecl.IsInterface() Then
  3758. EmitClassStandardMethodDebugScope("New", ret, "_" + classid + "_New")
  3759. End If
  3760. If classHasFunction(classDecl, "ToString") Then
  3761. EmitClassStandardMethodDebugScope("ToString", "()$", "_" + classidForFunction(classDecl, "ToString") + "_ToString")
  3762. 'Emit "_" + classid + "_ToString,"
  3763. End If
  3764. If classHasFunction(classDecl, "Compare") Then
  3765. EmitClassStandardMethodDebugScope("Compare", "(:Object)i", "_" + classidForFunction(classDecl, "Compare") + "_Compare")
  3766. 'Emit "_" + classid + "_ObjectCompare,"
  3767. End If
  3768. If classHasFunction(classDecl, "SendMessage") Then
  3769. EmitClassStandardMethodDebugScope("SendMessage", "(:Object, :Object):Object", "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage")
  3770. 'Emit "_" + classid + "_SendMessage,"
  3771. End If
  3772. EmitBBClassClassFuncsDebugScope(classDecl)
  3773. End Method
  3774. Method EmitClassGlobalDebugScope( classDecl:TClassDecl, scopeIndex:Int Var )
  3775. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  3776. EmitGlobalDebugScope(decl, scopeIndex)
  3777. scopeIndex :+ 1
  3778. Next
  3779. End Method
  3780. Method EmitGlobalDebugScope( decl:TGlobalDecl, scopeIndex:Int )
  3781. Emit "{"
  3782. Emit "BBDEBUGDECL_GLOBAL,"
  3783. Emit Enquote(decl.ident) + ","
  3784. Emit Enquote(TransDebugScopeType(decl.ty)) + ","
  3785. If decl.IsThreaded() Then
  3786. Emit ".var_address=0"
  3787. decl.scopeIndex = scopeIndex
  3788. Else
  3789. Emit ".var_address=(void*)&" + decl.munged
  3790. End If
  3791. Emit "},"
  3792. End Method
  3793. Method CountBBClassClassFuncsDebugScope(classDecl:TClassDecl, count:Int Var)
  3794. For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
  3795. Local fdecl:TFuncDecl =TFuncDecl( decl )
  3796. If fdecl
  3797. If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
  3798. Continue
  3799. End If
  3800. If Not equalsBuiltInFunc(classDecl, fdecl) Then
  3801. count :+ 1
  3802. End If
  3803. End If
  3804. Next
  3805. End Method
  3806. Method CountClassConstsDebugScope(classDecl:TClassDecl, count:Int Var)
  3807. For Local decl:TConstDecl = EachIn classDecl.Decls()
  3808. count :+ 1
  3809. Next
  3810. End Method
  3811. Method CountClassFieldsDebugScope(classDecl:TClassDecl, count:Int Var)
  3812. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  3813. count :+ 1
  3814. Next
  3815. End Method
  3816. Method DebugScopeDeclCount:Int(classDecl:TClassDecl)
  3817. Local count:Int = 2 ' "New" counts as first one
  3818. ' but we don't use "New" for interfaces...
  3819. If classDecl.IsInterface() Or (classDecl.IsExtern() And classDecl.IsStruct()) Then
  3820. count :- 1
  3821. End If
  3822. ' consts
  3823. CountClassConstsDebugScope(classDecl, count)
  3824. ' fields
  3825. CountClassFieldsDebugScope(classDecl, count)
  3826. ' standard methods
  3827. If classHasFunction(classDecl, "ToString") Then
  3828. count :+ 1
  3829. End If
  3830. If classHasFunction(classDecl, "Compare") Then
  3831. count :+ 1
  3832. End If
  3833. If classHasFunction(classDecl, "SendMessage") Then
  3834. count :+ 1
  3835. End If
  3836. ' methods and functions
  3837. CountBBClassClassFuncsDebugScope(classDecl, count)
  3838. ' class globals
  3839. For Local decl:TGlobalDecl = EachIn classDecl.Decls()
  3840. count :+ 1
  3841. Next
  3842. Return count
  3843. End Method
  3844. Method EmitClassDecl( classDecl:TClassDecl )
  3845. If classDecl.args Then
  3846. Return
  3847. End If
  3848. PushEnv classDecl
  3849. 'If classDecl.IsTemplateInst()
  3850. ' Return
  3851. 'EndIf
  3852. If classDecl.IsExtern() And Not classDecl.IsStruct() Then
  3853. Return
  3854. EndIf
  3855. Local classid$=classDecl.munged
  3856. Local superid$
  3857. If classDecl.superClass Then
  3858. superid = classDecl.superClass.actual.munged
  3859. End If
  3860. If Not classDecl.IsExtern() Then
  3861. ' process nested classes
  3862. For Local cdecl:TClassDecl = EachIn classDecl._decls
  3863. MungDecl cdecl
  3864. EmitClassProto(cdecl, False)
  3865. EmitClassDecl(cdecl)
  3866. Next
  3867. ' process nested functions for new
  3868. Local decl:TFuncDecl
  3869. Try
  3870. decl = classDecl.FindFuncDecl("new",,,,,True,SCOPE_CLASS_HEIRARCHY)
  3871. Catch e:String
  3872. End Try
  3873. If decl And decl.scope = classDecl Then ' only our own New method, not any from superclasses
  3874. decl.Semant
  3875. ' emit nested protos
  3876. For Local fdecl:TFuncDecl = EachIn decl._decls
  3877. EmitFuncDecl(fdecl, True, False)
  3878. Next
  3879. ' emit nested bodies
  3880. For Local fdecl:TFuncDecl = EachIn decl._decls
  3881. EmitFuncDecl(fdecl, False, False)
  3882. Next
  3883. End If
  3884. EmitClassDeclNewList(classDecl)
  3885. If Not (classDecl.attrs & CLASS_STRUCT) Then
  3886. ' process nested functions for delete
  3887. decl = classDecl.FindFuncDecl("delete",,,,,,SCOPE_CLASS_HEIRARCHY)
  3888. If decl Then
  3889. decl.Semant
  3890. ' emit nested protos
  3891. For Local fdecl:TFuncDecl = EachIn decl._decls
  3892. EmitFuncDecl(fdecl, True, False)
  3893. Next
  3894. ' emit nested bodies
  3895. For Local fdecl:TFuncDecl = EachIn decl._decls
  3896. EmitFuncDecl(fdecl, False, False)
  3897. Next
  3898. End If
  3899. If classHierarchyHasFunction(classDecl, "Delete") Then
  3900. EmitClassDeclDelete(classDecl)
  3901. End If
  3902. End If
  3903. Rem
  3904. 'fields ctor
  3905. Emit classid+"::"+classid+"(){"
  3906. For Local decl:TDecl=EachIn classDecl.Semanted()
  3907. Local fdecl:TFieldDecl=TFieldDecl( decl )
  3908. If Not fdecl Continue
  3909. Emit TransField(fdecl,Null)+"="+fdecl.init.Trans()+";"
  3910. Next
  3911. Emit "}"
  3912. End Rem
  3913. Local reserved:String = ",New,Delete,".ToLower()
  3914. 'methods
  3915. For Local decl:TDecl=EachIn classDecl.Decls()
  3916. Local fdecl:TFuncDecl=TFuncDecl( decl )
  3917. If fdecl
  3918. If reserved.Find("," + fdecl.IdentLower() + ",") = -1 Then
  3919. EmitGDBDebug(fdecl)
  3920. EmitFuncDecl fdecl, , True
  3921. Continue
  3922. End If
  3923. EndIf
  3924. 'Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  3925. 'If gdecl
  3926. ' Emit TransRefType( gdecl.ty )+" "+classid+"::"+gdecl.munged+";"
  3927. ' Continue
  3928. ' EndIf
  3929. Next
  3930. Rem
  3931. 'gc_mark
  3932. Emit "void "+classid+"::mark(){"
  3933. If classDecl.superClass
  3934. Emit classDecl.superClass.actual.munged+"::mark();"
  3935. EndIf
  3936. For Local decl:TDecl=EachIn classDecl.Semanted()
  3937. Local fdecl:TFieldDecl=TFieldDecl( decl )
  3938. If fdecl EmitMark TransField(fdecl,Null),fdecl.ty,True
  3939. Next
  3940. Emit "}"
  3941. End Rem
  3942. For Local decl:TDecl=EachIn classDecl.Semanted()
  3943. Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  3944. If gdecl
  3945. If TFunctionPtrType(gdecl.ty) Then
  3946. Emit TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, gdecl.munged ) + ";"
  3947. Else
  3948. Emit TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, "" )+" "+ gdecl.munged+";"
  3949. End If
  3950. Continue
  3951. EndIf
  3952. Next
  3953. reserved = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
  3954. End If
  3955. 'Emit "struct _" + classid + "_DebugScope{"
  3956. 'Emit "int kind;"
  3957. 'Emit "const char *name;"
  3958. 'Emit "BBDebugDecl decls[" + DebugScopeDeclCount(classDecl) + "];"
  3959. 'Emit "};"
  3960. Local count:Int = DebugScopeDeclCount(classDecl)
  3961. ' debugscope
  3962. If count > 1 Then
  3963. _app.scopeDefs.Insert(String(count - 1), "")
  3964. Emit "struct BBDebugScope_" + (count - 1) + " " + classid + "_scope ={"
  3965. Else
  3966. Emit "struct BBDebugScope " + classid + "_scope ={"
  3967. End If
  3968. If classDecl.IsInterface() Then
  3969. Emit "BBDEBUGSCOPE_USERINTERFACE,"
  3970. Else If classDecl.IsStruct() Then
  3971. Emit "BBDEBUGSCOPE_USERSTRUCT,"
  3972. Else
  3973. Emit "BBDEBUGSCOPE_USERTYPE,"
  3974. End If
  3975. Emit EnQuote(classDecl.ident + TransDebugMetaData(classDecl.metadata.metadataString)) + ","
  3976. Emit "{"
  3977. Local scopeIndex:Int
  3978. ' debug const decls
  3979. EmitClassConstsDebugScope(classDecl, scopeIndex)
  3980. ' debug field decls
  3981. EmitClassFieldsDebugScope(classDecl, scopeIndex)
  3982. ' debug global decls
  3983. EmitClassGlobalDebugScope(classDecl, scopeIndex)
  3984. ' debug func decls
  3985. EmitClassFuncsDebugScope(classDecl)
  3986. Emit "{"
  3987. Emit "BBDEBUGDECL_END"
  3988. Emit "}"
  3989. Emit "}"
  3990. Emit "};"
  3991. Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls()
  3992. Local implementedInterfaces:TMap = classDecl.GetInterfaces()
  3993. Local ifcCount:Int
  3994. If Not classDecl.IsStruct() Then
  3995. ' interface class implementation
  3996. If Not classDecl.IsInterface()
  3997. If Not implementedInterfaces.IsEmpty() Then
  3998. Emit "struct " + classid + "_vdef {"
  3999. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  4000. Emit "struct " + ifc.munged + "_methods interface_" + ifc.ident + ";"
  4001. ifcCount :+ 1
  4002. Next
  4003. Emit "};~n"
  4004. Emit "static struct BBInterfaceOffsets " + classid + "_ifc_offsets[] = {"
  4005. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  4006. Emit "{&" + ifc.munged + "_ifc, offsetof(struct " + classid + "_vdef, interface_" + ifc.ident + ")},"
  4007. Next
  4008. Emit "};~n"
  4009. Emit "struct " + classid + "_vdef " + classid + "_ifc_vtable = {"
  4010. For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
  4011. Emit ".interface_" + ifc.ident + "={"
  4012. Local dups:TMap = New TMap
  4013. For Local func:TFuncDecl = EachIn ifc.GetImplementedFuncs()
  4014. If func.IsMethod() Then
  4015. For Local f:TFuncDecl = EachIn fdecls
  4016. Mungdecl f
  4017. If f.ident = func.ident And f.EqualsFunc(func) Then
  4018. Local id:String = f.ident + "_"
  4019. For Local arg:TArgDecl = EachIn f.argDecls
  4020. id :+ TransMangleType(arg.ty)
  4021. Next
  4022. If Not dups.ValueForKey(id) Then
  4023. Emit "_" + f.munged + ","
  4024. dups.Insert(id, "")
  4025. End If
  4026. Exit
  4027. End If
  4028. Next
  4029. End If
  4030. Next
  4031. Emit "},"
  4032. Next
  4033. Emit "};~n"
  4034. Emit "struct BBInterfaceTable " + classid + "_itable = {"
  4035. Emit classid + "_ifc_offsets,"
  4036. Emit "&" + classid + "_ifc_vtable,"
  4037. Emit ifcCount
  4038. Emit "};~n"
  4039. End If
  4040. End If
  4041. Emit "struct BBClass_" + classid + " " + classid + "={"
  4042. ' super class reference
  4043. Emit "&" + classDecl.superClass.munged + ","
  4044. Emit "bbObjectFree,"
  4045. ' debugscope
  4046. Emit "(BBDebugScope*)&" + classid + "_scope,"
  4047. ' object instance size
  4048. Emit "sizeof" + Bra("struct " + classid + "_obj") + ","
  4049. ' standard methods
  4050. Emit "(void (*)(BBOBJECT))_" + classid + "_New,"
  4051. If Not classHierarchyHasFunction(classDecl, "Delete") Then
  4052. Emit "bbObjectDtor,"
  4053. Else
  4054. Emit "(void (*)(BBOBJECT))_" + classid + "_Delete,"
  4055. End If
  4056. If classHierarchyHasFunction(classDecl, "ToString") Then
  4057. Emit "(BBSTRING (*)(BBOBJECT))_" + classidForFunction(classDecl, "ToString") + "_ToString,"
  4058. Else
  4059. Emit "bbObjectToString,"
  4060. End If
  4061. If classHierarchyHasFunction(classDecl, "Compare") Then
  4062. Emit "(int (*)(BBOBJECT, BBOBJECT))_" + classidForFunction(classDecl, "Compare") + "_Compare,"
  4063. Else
  4064. Emit "bbObjectCompare,"
  4065. End If
  4066. If classHierarchyHasFunction(classDecl, "SendMessage") Then
  4067. Emit "(BBOBJECT (*)(BBOBJECT, BBOBJECT, BBOBJECT))_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage,"
  4068. Else
  4069. Emit "bbObjectSendMessage,"
  4070. End If
  4071. 'Emit "public:"
  4072. 'fields
  4073. 'For Local decl:TDecl=EachIn classDecl.Semanted()
  4074. ' Local fdecl:TFieldDecl =TFieldDecl( decl )
  4075. ' If fdecl
  4076. ' Emit TransRefType( fdecl.ty )+" "+fdecl.munged+";"
  4077. ' Continue
  4078. ' EndIf
  4079. 'Next
  4080. 'fields ctor
  4081. 'Emit classid+"();"
  4082. 'methods
  4083. 'For Local decl:TDecl=EachIn classDecl.Semanted()
  4084. '
  4085. ' Local fdecl:TFuncDecl =TFuncDecl( decl )
  4086. ' If fdecl
  4087. ' EmitFuncProto fdecl
  4088. ' Continue
  4089. ' EndIf
  4090. '
  4091. ' Local gdecl:TGlobalDecl =TGlobalDecl( decl )
  4092. ' If gdecl
  4093. ' Emit "static "+TransRefType( gdecl.ty )+" "+gdecl.munged+";"
  4094. ' Continue
  4095. ' EndIf
  4096. 'Next
  4097. 'gc mark
  4098. 'Emit "void mark();"
  4099. If classDecl.IsInterface() Or implementedInterfaces.IsEmpty() Then
  4100. ' itable
  4101. Emit "0,"
  4102. ' extra pointer
  4103. Emit "0,"
  4104. Else
  4105. Emit "&" + classid + "_itable,"
  4106. ' extra pointer
  4107. Emit "0,"
  4108. End If
  4109. ' obj_size
  4110. Emit TransObjectSize(classDecl)
  4111. ' instance_count
  4112. Emit ",0"
  4113. ' fields_offset
  4114. Emit TransFirstFieldOffset(classDecl)
  4115. ' methods/funcs
  4116. 'reserved = "New,Delete,ToString,ObjectCompare,SendMessage".ToLower()
  4117. 'For Local decl:TFuncDecl = EachIn classDecl.Decls()
  4118. For Local decl:TFuncDecl = EachIn fdecls
  4119. If Not equalsBuiltInFunc(classDecl, decl) And Not equalsTorFunc(classDecl, decl) Then
  4120. Local fdecl:TFuncDecl = classDecl.GetLatestFuncDecl(decl)
  4121. MungDecl decl
  4122. Local t:String = ","
  4123. If fdecl <> decl Then
  4124. MungDecl fdecl
  4125. If decl.IsMethod() Then
  4126. t :+ Bra(fdecl.munged + "_m")
  4127. Else
  4128. t :+ Bra(fdecl.munged + "_f")
  4129. End If
  4130. End If
  4131. If decl.IsMethod() Then
  4132. t:+ "_"
  4133. End If
  4134. t :+ decl.munged
  4135. Emit t
  4136. End If
  4137. Next
  4138. Emit "};~n"
  4139. If classDecl.IsInterface() Then
  4140. Emit "const struct BBInterface " + classid + "_ifc = { (BBClass *)&" + classid + ", (const char *) ~q" + classDecl.ident + "~q };"
  4141. Else
  4142. End If
  4143. End If
  4144. PopEnv
  4145. End Method
  4146. Method EmitEnumDecl(decl:TEnumDecl)
  4147. Local id:String = decl.munged
  4148. Emit "struct BBEnum" + decl.munged + "{"
  4149. Emit "const char * name;"
  4150. Emit "char * type;"
  4151. Emit "char * atype;"
  4152. Emit "int flags;"
  4153. Emit "int length;"
  4154. Emit "void * values;"
  4155. Emit "BBString * names[" + decl.values.length + "];"
  4156. Emit "};"
  4157. If decl.isFlags Then
  4158. Local s:String
  4159. For Local value:TEnumValueDecl = EachIn decl.values
  4160. If s Then
  4161. s :+ "|"
  4162. End If
  4163. s :+ value.Value()
  4164. Next
  4165. Emit "const " + TransType(decl.ty, "") + " bbEnum" + decl.munged +"_Mask = " + s + ";"
  4166. End If
  4167. Local count:Int
  4168. For Local value:TEnumValueDecl = EachIn decl.values
  4169. count :+ 1
  4170. Next
  4171. ' debugscope
  4172. If count > 0 Then
  4173. _app.scopeDefs.Insert(String(count), "")
  4174. Emit "struct BBDebugScope_" + count + " " + id + "_scope ={"
  4175. Else
  4176. Emit "struct BBDebugScope " + id + "_scope ={"
  4177. End If
  4178. Emit "BBDEBUGSCOPE_USERENUM,"
  4179. Emit EnQuote(decl.ident) + ","
  4180. Emit "{"
  4181. Local ty:TEnumType = New TEnumType.Create(decl)
  4182. For Local value:TEnumValueDecl = EachIn decl.values
  4183. Emit "{"
  4184. Emit "BBDEBUGDECL_GLOBAL,"
  4185. Emit Enquote(value.ident) + ","
  4186. Emit Enquote(TransDebugScopeType(ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
  4187. _appInstance.mapStringConsts(value.ident)
  4188. _appInstance.mapStringConsts(value.Value())
  4189. Emit ".const_value=(BBString*)&" + StringConstId(value.Value())
  4190. Emit "},"
  4191. Next
  4192. Emit "{"
  4193. Emit "BBDEBUGDECL_END"
  4194. Emit "}"
  4195. Emit "}"
  4196. Emit "};"
  4197. Local t:String
  4198. Local n:String
  4199. For Local v:TEnumValueDecl = EachIn decl.values
  4200. If t Then
  4201. t :+ ","
  4202. n :+ ","
  4203. End If
  4204. t :+ v.Value()
  4205. n :+ "(BBString*)&" + StringConstId(v.ident)
  4206. Next
  4207. Emit TransType(decl.ty, "") + " " + decl.munged + "_values[" + decl.values.length + "] = {" + t + "};"
  4208. Emit "struct BBEnum" + decl.munged + " " + decl.munged + "_BBEnum = {"
  4209. Emit EnQuote(decl.ident) + ","
  4210. Emit TransArrayType(decl.ty) + ","
  4211. Emit TransArrayType(New TEnumType.Create(decl)) + ","
  4212. Emit decl.isFlags + ","
  4213. Emit decl.values.length + ","
  4214. Emit "&" + decl.munged + "_values,"
  4215. Emit "{" + n + "}"
  4216. Emit "};"
  4217. Emit "BBEnum * " + decl.munged + "_BBEnum_impl;"
  4218. For Local fdecl:TFuncDecl = EachIn decl.FuncDecls()
  4219. MungDecl fdecl
  4220. Select fdecl.ident
  4221. Case "ToString"
  4222. Emit "BBSTRING " + fdecl.munged + Bra(TransType(decl.ty, "") + " ordinal") + " {"
  4223. Emit "return bbEnumToString_" + TransDebugScopeType(decl.ty) + Bra(decl.munged + "_BBEnum_impl, ordinal") + ";"
  4224. Emit "}"
  4225. Case "TryConvert"
  4226. Emit "BBINT " + fdecl.munged + Bra(TransType(decl.ty, "") + " ordinalValue, " + TransType(decl.ty, "") + " * ordinalResult") + " {"
  4227. Emit "return bbEnumTryConvert_" + TransDebugScopeType(decl.ty) + Bra(decl.munged + "_BBEnum_impl, ordinalValue, ordinalResult") + ";"
  4228. Emit "}"
  4229. End Select
  4230. Next
  4231. End Method
  4232. Method EmitEnumProto(decl:TEnumDecl)
  4233. Emit "extern BBEnum* " + decl.munged + "_BBEnum_impl;"
  4234. For Local fdecl:TFuncDecl = EachIn decl.FuncDecls()
  4235. MungDecl fdecl
  4236. Select fdecl.ident
  4237. Case "ToString"
  4238. Emit "BBSTRING " + fdecl.munged + Bra(TransType(decl.ty, "")) + ";"
  4239. Case "TryConvert"
  4240. Emit "BBINT " + fdecl.munged + Bra(TransType(decl.ty, "") + " ordinalValue, " + TransType(decl.ty, "") + " * ordinalResult") + ";"
  4241. Case "Ordinal"
  4242. ' nothing to generate
  4243. End Select
  4244. Next
  4245. Emit "extern const " + TransType(decl.ty, "") + " bbEnum" + decl.munged +"_Mask;"
  4246. End Method
  4247. Method TransObjectSize:String(classDecl:TClassDecl)
  4248. Local t:String
  4249. Local firstDecl:TFieldDecl
  4250. Local lastDecl:TFieldDecl
  4251. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  4252. If Not firstDecl Then
  4253. firstDecl = decl
  4254. End If
  4255. lastDecl = decl
  4256. Next
  4257. If firstDecl Then
  4258. If firstDecl <> lastDecl Then
  4259. t = "offsetof" + Bra("struct " + classDecl.munged + "_obj," + lastDecl.munged) + " - offsetof" + Bra("struct " + classDecl.munged + "_obj," + firstDecl.munged) + " + sizeof" + Bra(TransType(lastDecl.ty, ""))
  4260. Else
  4261. t = "sizeof" + Bra(TransType(lastDecl.ty, ""))
  4262. End If
  4263. Else
  4264. t = "0"
  4265. End If
  4266. Return t
  4267. End Method
  4268. Method TransFirstFieldOffset:String(classDecl:TClassDecl)
  4269. Local t:String
  4270. Local fieldDecl:TFieldDecl
  4271. For Local decl:TFieldDecl = EachIn classDecl.Decls()
  4272. fieldDecl = decl
  4273. Exit
  4274. Next
  4275. If fieldDecl Then
  4276. t = ",offsetof" + Bra("struct " + classDecl.munged + "_obj," + fieldDecl.munged)
  4277. Else
  4278. t = ",sizeof(void*)"
  4279. End If
  4280. Return t
  4281. End Method
  4282. Method EmitClassDeclNew( classDecl:TClassDecl, fdecl:TFuncDecl )
  4283. Local classid$=classDecl.munged
  4284. Local superid$
  4285. If classDecl.superClass Then
  4286. superid = classDecl.superClass.actual.munged
  4287. End If
  4288. Local t:String = "void _"
  4289. If fdecl.argDecls.Length Then
  4290. If classDecl = fdecl.scope Then
  4291. t :+ fdecl.munged
  4292. Else
  4293. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  4294. End If
  4295. Else
  4296. t :+ classid + "_New"
  4297. End If
  4298. 'Find decl we override
  4299. Local odecl:TFuncDecl=fdecl
  4300. If odecl.overrides And odecl.generated Then
  4301. fdecl = odecl.overrides
  4302. Else
  4303. While odecl.overrides
  4304. odecl=odecl.overrides
  4305. Wend
  4306. End If
  4307. Local args:String = TransObject(classdecl, True) + " o"
  4308. For Local i:Int=0 Until fdecl.argDecls.Length
  4309. Local arg:TArgDecl=fdecl.argDecls[i]
  4310. Local oarg:TArgDecl=odecl.argDecls[i]
  4311. MungDecl arg, True
  4312. If args args:+","
  4313. If Not TFunctionPtrType(oarg.ty) Then
  4314. If Not odecl.castTo Then
  4315. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  4316. Else
  4317. args:+ oarg.castTo + " " + arg.munged
  4318. End If
  4319. Else
  4320. If Not odecl.castTo Then
  4321. args:+TransType( oarg.ty, arg.munged )
  4322. Else
  4323. args:+ oarg.castTo
  4324. End If
  4325. End If
  4326. If arg.ty.EqualsType( oarg.ty ) Continue
  4327. Next
  4328. Emit t + Bra(args) + " {"
  4329. Local newDecl:TNewDecl = TNewDecl(fdecl)
  4330. If Not classDecl.IsStruct() Then
  4331. ' calling constructor?
  4332. If newDecl And newDecl.chainedCtor Then
  4333. mungdecl newDecl.chainedCtor.ctor
  4334. Emit "_" + newDecl.chainedCtor.ctor.ClassScope().munged + "_" + newDecl.chainedCtor.ctor.ident + MangleMethod(newDecl.chainedCtor.ctor) + TransArgs(newDecl.chainedCtor.args, newDecl.chainedCtor.ctor, "o") + ";"
  4335. Else
  4336. If classDecl.superClass.ident = "Object" Then
  4337. Emit "bbObjectCtor((BBOBJECT)o);"
  4338. Else
  4339. If fdecl And fdecl.scope <> classDecl And fdecl.argDecls.Length Then
  4340. t = "o"
  4341. For Local i:Int=0 Until fdecl.argDecls.Length
  4342. Local arg:TArgDecl=fdecl.argDecls[i]
  4343. t :+ ", " + arg.munged
  4344. Next
  4345. Emit "_" + newDecl.ClassScope().munged + "_" + newDecl.ident + MangleMethod(newDecl) + Bra(t) + ";"
  4346. Else
  4347. Emit "_" + superid + "_New((" + TransObject(classDecl.superClass) + ")o);"
  4348. End If
  4349. End If
  4350. End If
  4351. Emit "o->clas = &" + classid + ";" ' TODO
  4352. End If
  4353. ' only initialise fields if we are not chaining to a local (in our class) constructor.
  4354. ' this prevents fields being re-initialised through the call-chain.
  4355. If Not newDecl.chainedCtor Or (newDecl.chainedCtor And classDecl <> newDecl.chainedCtor.ctor.scope) Then
  4356. ' field initialisation
  4357. For Local decl:TFieldDecl=EachIn classDecl.Decls()
  4358. Local doEmit:Int = True
  4359. If Not decl.IsSemanted() Then
  4360. decl.Semant()
  4361. End If
  4362. Local fld:String
  4363. ' ((int*)((char*)o + 5))[0] =
  4364. fld :+ TransFieldRef(decl, "o")
  4365. If decl.init Then
  4366. If TObjectType(decl.ty) And TObjectType(decl.ty).classdecl.IsExtern() And TObjectType(decl.ty).classdecl.IsStruct() Then
  4367. ' skip for uninitialised extern type
  4368. If Not isPointerType(decl.ty) And TConstExpr(decl.init) And Not TConstExpr(decl.init).value Then
  4369. Continue
  4370. End If
  4371. End If
  4372. ' initial value
  4373. If (TConstExpr(decl.init) And Not TConstExpr(decl.init).value) And TIntrinsicType(decl.ty) Then
  4374. fld :+ "= "
  4375. If TFloat64Type(decl.ty) Then
  4376. fld :+ "_mm_setzero_si64();"
  4377. Else If TFloat128Type(decl.ty) Then
  4378. fld :+ "_mm_setzero_ps();"
  4379. Else If TDouble128Type(decl.ty) Then
  4380. fld :+ "_mm_setzero_pd();"
  4381. Else If TInt128Type(decl.ty) Then
  4382. fld :+ "_mm_setzero_si128();"
  4383. End If
  4384. Else
  4385. 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
  4386. fld = "memset(&" + fld + ", 0, sizeof" + Bra(TransType(decl.ty, "")) + ");"
  4387. Else If TInvokeExpr(decl.init) And Not TInvokeExpr(decl.init).invokedWithBraces Then
  4388. fld :+ "= " + TInvokeExpr(decl.init).decl.munged + ";"
  4389. Else If TObjectType(decl.ty) Then
  4390. fld :+ "= "
  4391. If Not TObjectType(decl.ty).classDecl.IsStruct() Then
  4392. fld :+ Bra(TransObject(TObjectType(decl.ty).classDecl))
  4393. End If
  4394. fld :+ decl.init.Trans() + ";"
  4395. Else If TArrayType(decl.ty) And TArrayType(decl.ty).isStatic Then
  4396. Local idx:String = "i" + fdecl.NextIdx()
  4397. fld = "int " + idx + ";for(" + idx + "=0;" + idx + "<" + TArrayType(decl.ty).length + ";" + idx + "++) " + TransFieldRef(decl, "o") + "[" + idx + "]=" + TransValue(TArrayType(decl.ty).elemType,Null,False) + ";"
  4398. Else
  4399. fld :+ "= " + decl.init.Trans() + ";"
  4400. End If
  4401. End If
  4402. Else
  4403. If TNumericType(decl.ty) Or IsPointerType(decl.ty, 0, TType.T_POINTER) Then
  4404. doEmit = False
  4405. Else If TObjectType(decl.ty) Then
  4406. If TObjectType(decl.ty).classDecl.IsStruct() Then
  4407. fld :+ "= " + TObjectType(decl.ty).classDecl.munged + "_New_ObjectNew();"
  4408. Else
  4409. fld :+ "= &bbNullObject;"
  4410. End If
  4411. Else If TFunctionPtrType(decl.ty) Then
  4412. fld :+ "= &brl_blitz_NullFunctionError;"
  4413. Else If TStringType(decl.ty) Then
  4414. fld :+ "= &bbEmptyString;"
  4415. Else If TArrayType(decl.ty) Then
  4416. If TArrayType(decl.ty).isStatic Then
  4417. Local idx:String = "i" + fdecl.NextIdx()
  4418. fld = "int " + idx + ";for(" + idx + "=0;" + idx + "<" + TArrayType(decl.ty).length + ";" + idx + "++) " + TransFieldRef(decl, "o") + "[" + idx + "]=" + TransValue(TArrayType(decl.ty).elemType,Null,False) + ";"
  4419. Else
  4420. fld :+ "= &bbEmptyArray;"
  4421. End If
  4422. Else If TEnumType(decl.ty) Then
  4423. fld :+ "= " + TEnumType(decl.ty).decl.values[0].Value() + ";"
  4424. End If
  4425. End If
  4426. If doEmit Then
  4427. Emit fld
  4428. End If
  4429. Next
  4430. End If
  4431. 'Local decl:TFuncDecl = classDecl.FindFuncDecl("new",,,,,,SCOPE_CLASS_LOCAL)
  4432. If fdecl And (fdecl.scope = classDecl) Then ' only our own New method, not any from superclasses
  4433. fdecl.Semant
  4434. If fdecl.munged <> "bbObjectCtor" Then
  4435. EmitLocalDeclarations(fdecl)
  4436. EmitBlock fdecl
  4437. End If
  4438. End If
  4439. '
  4440. Emit "}"
  4441. End Method
  4442. Method EmitClassDeclNewList( classDecl:TClassDecl )
  4443. Local classid$=classDecl.munged
  4444. Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", True,,,True))
  4445. For Local fdecl:TFuncDecl = EachIn newDecls
  4446. MungDecl fdecl
  4447. If fdecl.scope <> classDecl Then
  4448. fdecl.Clear()
  4449. EmitClassDeclNew(classDecl, fdecl)
  4450. Else
  4451. EmitClassDeclNew(classDecl, fdecl)
  4452. End If
  4453. ' generate "objectNew" function if required
  4454. If (fdecl.argDecls And fdecl.argDecls.length) Or classDecl.IsStruct() Then
  4455. EmitClassDeclNewInit(classDecl, fdecl)
  4456. End If
  4457. Next
  4458. End Method
  4459. Method EmitClassDeclNewListProto( classDecl:TClassDecl )
  4460. Local classid$=classDecl.munged
  4461. 'Local superid$=classDecl.superClass.actual.munged
  4462. Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", True,,,True))
  4463. For Local fdecl:TFuncDecl = EachIn newDecls
  4464. EmitClassDeclNewProto(classDecl, fdecl)
  4465. ' generate "objectNew" function if required
  4466. If (fdecl.argDecls And fdecl.argDecls.length) Or classDecl.IsStruct() Then
  4467. EmitClassDeclObjectNewProto(classDecl, fdecl)
  4468. End If
  4469. Next
  4470. End Method
  4471. Method EmitClassDeclNewInit(classDecl:TClassDecl, fdecl:TFuncDecl)
  4472. Local funcMunged:String
  4473. If classDecl = fdecl.scope Then
  4474. funcMunged = fdecl.munged
  4475. Else
  4476. funcMunged = classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  4477. End If
  4478. Local t:String = TransObject(classdecl) + " "
  4479. If Not classDecl.IsStruct() Then
  4480. t :+ "_"
  4481. End If
  4482. t :+ funcMunged + "_ObjectNew"
  4483. 'Find decl we override
  4484. Local odecl:TFuncDecl=fdecl
  4485. While odecl.overrides
  4486. odecl=odecl.overrides
  4487. Wend
  4488. Local args:String
  4489. If Not classDecl.IsStruct() Then
  4490. args = "BBClass * clas"
  4491. End If
  4492. For Local i:Int=0 Until fdecl.argDecls.Length
  4493. Local arg:TArgDecl=fdecl.argDecls[i]
  4494. Local oarg:TArgDecl=odecl.argDecls[i]
  4495. MungDecl arg, True
  4496. If args args:+","
  4497. If Not TFunctionPtrType(oarg.ty) Then
  4498. If Not odecl.castTo Then
  4499. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  4500. Else
  4501. args:+ oarg.castTo + " " + arg.munged
  4502. End If
  4503. Else
  4504. If Not odecl.castTo Then
  4505. args:+TransType( oarg.ty, arg.munged )
  4506. Else
  4507. args:+ oarg.castTo
  4508. End If
  4509. End If
  4510. If arg.ty.EqualsType( oarg.ty ) Continue
  4511. Next
  4512. Emit t + Bra(args) + " {"
  4513. t = TransObject(classdecl) + " o"
  4514. If classDecl.IsStruct() Then
  4515. t :+ " = {"
  4516. Local fields:Int
  4517. For Local f:TFieldDecl = EachIn classDecl.Decls()
  4518. If fields Then
  4519. t :+ ","
  4520. End If
  4521. fields = True
  4522. t :+ TransValue(f.ty, "", True)
  4523. Next
  4524. Emit t + "};"
  4525. Else
  4526. t :+ " = " + Bra(TransObject(classdecl))
  4527. If ClassHasObjectField(classDecl) Then
  4528. t :+ "bbObjectNewNC"
  4529. Else
  4530. t :+ "bbObjectAtomicNewNC"
  4531. End If
  4532. Emit t + "(clas);"
  4533. End If
  4534. t = "_" + funcMunged
  4535. If classDecl.IsStruct() Then
  4536. t :+ "(&o"
  4537. Else
  4538. t :+ "(o"
  4539. End If
  4540. For Local i:Int=0 Until fdecl.argDecls.Length
  4541. Local arg:TArgDecl=fdecl.argDecls[i]
  4542. t :+ ", " + arg.munged
  4543. Next
  4544. Emit t + ");"
  4545. Emit "return o;"
  4546. Emit "}"
  4547. End Method
  4548. Method EmitClassDeclNewProto( classDecl:TClassDecl, fdecl:TFuncDecl )
  4549. Local classid$=classDecl.munged
  4550. Local superid$
  4551. If classDecl.superClass Then
  4552. superid = classDecl.superClass.actual.munged
  4553. End If
  4554. Local t:String = "void _"
  4555. If fdecl.argDecls.Length Then
  4556. If classDecl = fdecl.scope Then
  4557. If Not fdecl.munged Then
  4558. MungDecl fdecl
  4559. End If
  4560. t :+ fdecl.munged
  4561. Else
  4562. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  4563. End If
  4564. Else
  4565. t :+ classid + "_New"
  4566. End If
  4567. 'Find decl we override
  4568. Local odecl:TFuncDecl=fdecl
  4569. While odecl.overrides
  4570. odecl=odecl.overrides
  4571. Wend
  4572. Local args:String = TransObject(classdecl, True) + " o"
  4573. For Local i:Int=0 Until fdecl.argDecls.Length
  4574. Local arg:TArgDecl=fdecl.argDecls[i]
  4575. Local oarg:TArgDecl=odecl.argDecls[i]
  4576. MungDecl arg, True
  4577. If args args:+","
  4578. If Not TFunctionPtrType(oarg.ty) Then
  4579. If Not odecl.castTo Then
  4580. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  4581. Else
  4582. args:+ oarg.castTo + " " + arg.munged
  4583. End If
  4584. Else
  4585. If Not odecl.castTo Then
  4586. args:+TransType( oarg.ty, arg.munged )
  4587. Else
  4588. args:+ oarg.castTo
  4589. End If
  4590. End If
  4591. If arg.ty.EqualsType( oarg.ty ) Continue
  4592. Next
  4593. Emit t + Bra(args) + ";"
  4594. End Method
  4595. Method EmitClassDeclObjectNewProto(classDecl:TClassDecl, fdecl:TFuncDecl)
  4596. Local t:String = TransObject(classdecl) + " "
  4597. If Not classDecl.IsStruct() Then
  4598. t :+ "_"
  4599. End If
  4600. If classDecl = fdecl.scope Then
  4601. t :+ fdecl.munged
  4602. Else
  4603. t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
  4604. End If
  4605. t:+ "_ObjectNew"
  4606. 'Find decl we override
  4607. Local odecl:TFuncDecl=fdecl
  4608. While odecl.overrides
  4609. odecl=odecl.overrides
  4610. Wend
  4611. Local args:String
  4612. If Not classDecl.IsStruct() Then
  4613. args = "BBClass * clas"
  4614. End If
  4615. For Local i:Int=0 Until fdecl.argDecls.Length
  4616. Local arg:TArgDecl=fdecl.argDecls[i]
  4617. Local oarg:TArgDecl=odecl.argDecls[i]
  4618. MungDecl arg, True
  4619. If args args:+","
  4620. If Not TFunctionPtrType(oarg.ty) Then
  4621. If Not odecl.castTo Then
  4622. args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
  4623. Else
  4624. args:+ oarg.castTo + " " + arg.munged
  4625. End If
  4626. Else
  4627. If Not odecl.castTo Then
  4628. args:+TransType( oarg.ty, arg.munged )
  4629. Else
  4630. args:+ oarg.castTo
  4631. End If
  4632. End If
  4633. If arg.ty.EqualsType( oarg.ty ) Continue
  4634. Next
  4635. Emit t + Bra(args) + ";"
  4636. End Method
  4637. Method EmitClassDeclDelete( classDecl:TClassDecl )
  4638. Local classid$=classDecl.munged
  4639. Local superid$=classDecl.superClass.actual.munged
  4640. ' New
  4641. ' If opt_issuperstrict Then
  4642. Emit "void _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + " {"
  4643. ' Else
  4644. ' Emit "int _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + " {"
  4645. ' End If
  4646. Local decl:TFuncDecl = classDecl.FindFuncDecl("delete",,,,,,SCOPE_CLASS_HEIRARCHY)
  4647. If decl And decl.ClassScope() = classDecl Then
  4648. decl.Semant
  4649. EmitLocalDeclarations(decl)
  4650. EmitBlock decl
  4651. End If
  4652. ' field cleanup
  4653. For Local decl:TFieldDecl=EachIn classDecl.Decls()
  4654. ' String
  4655. If TStringType(decl.declTy) Then
  4656. Emit "BBRELEASE(" + TransFieldRef(decl, "o") + ")"
  4657. End If
  4658. ' object
  4659. ' TODO
  4660. Next
  4661. ' finally, call super delete
  4662. EmitClassDeclDeleteDtor(classDecl)
  4663. '
  4664. Emit "}"
  4665. End Method
  4666. Method EmitClassDeclDeleteDtor( classDecl:TClassDecl )
  4667. Local superid$=classDecl.superClass.actual.munged
  4668. If classDecl.superClass.ident = "Object" Or Not classHierarchyHasFunction(classDecl.superClass, "Delete") Then
  4669. Emit "bbObjectDtor((BBOBJECT)o);"
  4670. Else
  4671. Emit "_" + superid + "_Delete((" + TransObject(TScopeDecl(classDecl.superClass.actual)) + ")o);"
  4672. End If
  4673. End Method
  4674. Method TransFieldRef:String(decl:TFieldDecl, variable:String, exprType:TType = Null)
  4675. Local s:String = variable
  4676. Local ind:String = "->"
  4677. If decl.scope And TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  4678. Local exprIsStruct:Int = Not exprType Or (TObjectType(exprType) And TObjectType(exprType).classDecl.attrs & CLASS_STRUCT)
  4679. If (exprIsStruct Or (exprType And Not IsPointerType(exprType))) And variable <> "o" Then
  4680. If Not exprIsStruct Or (exprType And Not IsPointerType(exprType)) Then
  4681. ind = "."
  4682. End If
  4683. End If
  4684. End If
  4685. If variable.StartsWith("*") Then
  4686. variable = Bra(variable)
  4687. End If
  4688. ' Null test
  4689. If opt_debug
  4690. If TClassDecl(decl.scope) And TClassDecl(decl.scope).IsStruct() Then
  4691. '
  4692. Else
  4693. variable = TransDebugNullObjectError(variable, TClassDecl(decl.scope))
  4694. End If
  4695. End If
  4696. ' array.length
  4697. If decl.scope And decl.scope.ident = "___Array" Then
  4698. If decl.ident = "length" Then
  4699. If TArrayType(exprType) And TArrayType(exprType).isStatic Then
  4700. Return TArrayType(exprType).length
  4701. Else
  4702. Return Bra(variable + "->scales[0]")
  4703. End If
  4704. End If
  4705. If decl.ident = "numberOfDimensions" Then
  4706. Return Bra(variable + "->dims")
  4707. End If
  4708. If decl.ident = "sizeMinusHeader" Then
  4709. Return Bra(variable + "->size")
  4710. End If
  4711. If decl.ident = "elementTypeEncoding" Then
  4712. Return Bra(variable + "->type")
  4713. End If
  4714. End If
  4715. ' string methods
  4716. If decl.scope And decl.scope.ident = "String" Then
  4717. If decl.ident = "length" Then
  4718. 'If exprType._flags & TType.T_VAR Then
  4719. ' Return Bra("(*" + variable + ")->length")
  4720. 'Else
  4721. If variable.StartsWith("&_s") Then
  4722. Return Bra(variable[1..] + ".length")
  4723. Else
  4724. Return Bra(variable + "->length")
  4725. End If
  4726. 'End If
  4727. End If
  4728. End If
  4729. 'If TObjectType(exprType) And (exprType._flags & TType.T_VAR) Then
  4730. ' ' get the object from the pointer
  4731. ' variable = Bra("*" + variable)
  4732. 'End If
  4733. If IsNumericType(decl.ty) Then
  4734. s = variable + ind + decl.munged + " "
  4735. Else If TStringType(decl.ty) Then
  4736. s = variable + ind + decl.munged + " "
  4737. Else If TObjectType(decl.ty) Then
  4738. s = variable + ind + decl.munged + " "
  4739. Else If IsPointerType(decl.ty, 0, TType.T_POINTER) Then
  4740. s = variable + ind + decl.munged + " "
  4741. Else If TFunctionPtrType(decl.ty) Then
  4742. s = variable + ind + decl.munged + " "
  4743. Else If TArrayType(decl.ty) Then
  4744. s = variable + ind + decl.munged + " "
  4745. Else If TEnumType(decl.ty) Then
  4746. s = variable + ind + decl.munged + " "
  4747. End If
  4748. Return s
  4749. End Method
  4750. ' " _" + classDecl.actual.munged + "_" + decl.ident.ToLower(
  4751. Method TransIfcArgs:String(funcDecl:TFuncDecl)
  4752. Local args:String
  4753. If Not funcDecl.IsSemanted() Then
  4754. funcDecl.Semant()
  4755. End If
  4756. For Local i:Int=0 Until funcDecl.argDecls.Length
  4757. Local arg:TArgDecl = funcDecl.argDecls[i]
  4758. If args args:+","
  4759. args:+ arg.ident + TransIfcType( arg.ty )
  4760. If arg.init Then
  4761. If TInvokeExpr(arg.init) Then
  4762. args:+ "=" + Enquote(TInvokeExpr(arg.init).decl.munged)
  4763. Else
  4764. args:+ "=" + TransIfcConstExpr(arg.init)
  4765. End If
  4766. End If
  4767. Next
  4768. Return Bra(args)
  4769. End Method
  4770. Method EmitIfcClassFuncDecl(funcDecl:TFuncDecl)
  4771. funcDecl.Semant
  4772. Local func:String
  4773. ' method / function
  4774. If funcDecl.IsMethod() Or funcDecl.IsCTor() Then
  4775. func :+ "-"
  4776. Else
  4777. func :+ "+"
  4778. End If
  4779. If funcDecl.attrs & FUNC_OPERATOR Then
  4780. func :+ BmxEnquote(funcDecl.ident)
  4781. Else
  4782. func :+ funcDecl.ident
  4783. End If
  4784. If Not TNewDecl(funcDecl) Then
  4785. func :+ TransIfcType(funcDecl.retType, funcDecl.ModuleScope().IsSuperStrict())
  4786. End If
  4787. ' function args
  4788. func :+ TransIfcArgs(funcDecl)
  4789. If funcDecl.attrs & DECL_FINAL Then
  4790. func :+ "F"
  4791. Else If funcDecl.attrs & DECL_ABSTRACT Then
  4792. func :+ "A"
  4793. End If
  4794. If funcDecl.attrs & FUNC_OPERATOR Then
  4795. func :+ "O"
  4796. End If
  4797. If funcDecl.attrs & DECL_PRIVATE Then
  4798. func :+ "P"
  4799. Else If funcDecl.attrs & DECL_PROTECTED Then
  4800. func :+ "R"
  4801. End If
  4802. If funcDecl.attrs & DECL_API_STDCALL Then
  4803. func :+ "W"
  4804. End If
  4805. If funcDecl.attrs & DECL_EXPORT Then
  4806. func :+ "E"
  4807. End If
  4808. func :+ "="
  4809. func :+ Enquote(funcDecl.munged)
  4810. Emit func
  4811. End Method
  4812. Method EmitIfcFuncDecl(funcDecl:TFuncDecl)
  4813. Local func:String
  4814. func :+ funcDecl.ident
  4815. ' ensure the function has been semanted
  4816. funcDecl.Semant()
  4817. func :+ TransIfcType(funcDecl.retType, funcDecl.ModuleScope().IsSuperStrict())
  4818. ' function args
  4819. func :+ TransIfcArgs(funcDecl)
  4820. If funcDecl.attrs & DECL_API_STDCALL Then
  4821. func :+ "W"
  4822. End If
  4823. func :+ "="
  4824. func :+ Enquote(funcDecl.munged)
  4825. If funcDecl.castTo Then
  4826. func :+ ":" + funcDecl.castTo
  4827. func :+ " " + funcDecl.munged + "("
  4828. For Local i:Int = 0 Until funcDecl.argDecls.length
  4829. If i Then
  4830. func :+ ", "
  4831. End If
  4832. func :+ funcDecl.argDecls[i].castTo
  4833. Next
  4834. func :+ ")"
  4835. End If
  4836. Emit func
  4837. End Method
  4838. Method TransIfcConstExpr:String(expr:TExpr)
  4839. If Not expr.exprType Then
  4840. expr.Semant()
  4841. End If
  4842. If TStringType(expr.exprType) Then
  4843. Return "$" + EscapeChars(BmxEnquote(expr.Eval()))
  4844. EndIf
  4845. If TArrayType(expr.exprType) Then
  4846. Return Enquote("bbEmptyArray")
  4847. End If
  4848. If TFunctionPtrType(expr.exprType) Then
  4849. If TCastExpr(expr) Then
  4850. If TInvokeExpr(TCastExpr(expr).expr) Then
  4851. Return Enquote(TInvokeExpr(TCastExpr(expr).expr).decl.munged)
  4852. End If
  4853. If TNullExpr(TCastExpr(expr).expr) Then
  4854. Return Enquote("brl_blitz_NullFunctionError")
  4855. End If
  4856. End If
  4857. InternalErr "TCTranslator.TransIfcConstExpr"
  4858. End If
  4859. If TObjectType(expr.exprType) Then
  4860. If TCastExpr(expr) Then
  4861. If TNullExpr(TCastExpr(expr).expr) Then
  4862. Return Enquote("bbNullObject")
  4863. End If
  4864. End If
  4865. End If
  4866. If IsPointerType(expr.exprType, 0, TType.T_POINTER) Then
  4867. If TCastExpr(expr) Then
  4868. If TNullExpr(TCastExpr(expr).expr) Then
  4869. Return "0"
  4870. End If
  4871. If TConstExpr(TCastExpr(expr).expr) Then
  4872. Return TConstExpr(TCastExpr(expr).expr).value
  4873. End If
  4874. End If
  4875. End If
  4876. If IsNumericType(expr.exprType) Then
  4877. Local s:String = expr.Eval()
  4878. If Not s Then
  4879. Return "0"
  4880. Else
  4881. If TDecimalType(expr.exprType) Then
  4882. If s.StartsWith("1.#INF0000") Or s = "1e1000" Then
  4883. s = "inf"
  4884. Else If s.StartsWith("-1.#INF0000") Then
  4885. s = "-inf"
  4886. Else If s.StartsWith("-1.#IND0000") Then
  4887. s = "nan"
  4888. End If
  4889. Return s + TransIfcType(expr.exprType)
  4890. Else
  4891. Return s
  4892. End If
  4893. End If
  4894. EndIf
  4895. If TEnumType(expr.exprType) Then
  4896. If TCastExpr(expr) And TNullExpr(TCastExpr(expr).expr) Then
  4897. Return TransValue(expr.exprType, Null)
  4898. Else
  4899. Return Expr.Eval()
  4900. End If
  4901. End If
  4902. 'If TObjectType(expr.exprType) And TNullDecl(TObjectType(expr.exprType).classDecl) Then
  4903. ' Return Enquote("bbNullObject")
  4904. 'End If
  4905. End Method
  4906. Method EmitIfcConstDecl(constDecl:TConstDecl)
  4907. Local c:String
  4908. c = constDecl.ident + TransIfcType(constDecl.ty)
  4909. If TExpr(constDecl.init) Then
  4910. c:+ "=" + TransIfcConstExpr(TExpr(constDecl.init))
  4911. End If
  4912. Emit c
  4913. End Method
  4914. Method EmitIfcFieldDecl(fieldDecl:TFieldDecl)
  4915. Local f:String
  4916. If fieldDecl.IsReadOnly() Then
  4917. f :+ "@"
  4918. End If
  4919. If fieldDecl.IsStatic() Then
  4920. f :+ "~~"
  4921. End If
  4922. If Not f Then
  4923. f :+ "."
  4924. End If
  4925. f :+ fieldDecl.ident + TransIfcType(fieldDecl.ty, fieldDecl.ModuleScope().IsSuperStrict())
  4926. f :+ "&"
  4927. If fieldDecl.IsPrivate() Then
  4928. f :+ "`"
  4929. Else If fieldDecl.IsProtected() Then
  4930. f :+ "``"
  4931. End If
  4932. Emit f
  4933. End Method
  4934. Method EmitIfcClassDecl(classDecl:TClassDecl)
  4935. Local head:String = classDecl.ident + "^"
  4936. If classDecl.superClass Then
  4937. head :+ classDecl.superClass.ident
  4938. Else
  4939. head :+ "Null"
  4940. End If
  4941. If classDecl.implments Then
  4942. head :+ "@"
  4943. For Local i:Int = 0 Until classDecl.implments.length
  4944. If i Then
  4945. head :+ ","
  4946. End If
  4947. head :+ classDecl.implments[i].ident
  4948. Next
  4949. End If
  4950. Emit head + "{", False
  4951. 'PushMungScope
  4952. BeginLocalScope
  4953. If Not classDecl.templateSource Then
  4954. ' const
  4955. For Local cDecl:TConstDecl = EachIn classDecl.Decls()
  4956. cDecl.Semant()
  4957. EmitIfcConstDecl(cDecl)
  4958. Next
  4959. ' global
  4960. For Local gDecl:TGlobalDecl = EachIn classDecl.Decls()
  4961. gDecl.Semant()
  4962. EmitIfcGlobalDecl(gDecl)
  4963. Next
  4964. ' field
  4965. For Local fDecl:TFieldDecl = EachIn classDecl.Decls()
  4966. fDecl.Semant()
  4967. EmitIfcFieldDecl(fDecl)
  4968. Next
  4969. End If
  4970. ' functions
  4971. If Not classDecl.IsExtern() Then
  4972. If Not classDecl.templateSource Then
  4973. If Not (classDecl.attrs & CLASS_INTERFACE) And Not classDecl.IsStruct() And Not classHierarchyHasFunction(classDecl, "New") Then
  4974. Emit "-New()=" + Enquote("_" + classDecl.munged + "_New")
  4975. End If
  4976. If classHierarchyHasFunction(classDecl, "Delete") Then
  4977. Emit "-Delete()=" + Enquote("_" + classDecl.munged + "_Delete")
  4978. End If
  4979. For Local decl:TDecl=EachIn classDecl.Decls()
  4980. Local fdecl:TFuncDecl=TFuncDecl( decl )
  4981. If fdecl
  4982. If Not equalsIfcBuiltInFunc(classDecl, fdecl) Then
  4983. EmitIfcClassFuncDecl fdecl
  4984. End If
  4985. Continue
  4986. EndIf
  4987. Next
  4988. End If
  4989. Local flags:String
  4990. If classDecl.IsAbstract() Then
  4991. flags :+ "A"
  4992. End If
  4993. If classDecl.attrs & DECL_FINAL Then
  4994. flags :+ "F"
  4995. End If
  4996. If classDecl.attrs & CLASS_INTERFACE Then
  4997. flags :+ "I"
  4998. Else If classDecl.IsStruct() Then
  4999. flags :+ "S"
  5000. End If
  5001. If classDecl.IsPrivate() Then
  5002. flags :+ "P"
  5003. End If
  5004. If classDecl.templateSource Then
  5005. flags :+ "G"
  5006. End If
  5007. Local t:String = "}" + flags + "="
  5008. If classDecl.templateSource Then
  5009. t :+ Enquote(classDecl.scope.munged)
  5010. t :+ ",<"
  5011. Local s:String
  5012. If classDecl.instArgs Then
  5013. For Local ty:TType = EachIn classDecl.instArgs
  5014. If s Then
  5015. s :+ ","
  5016. End If
  5017. s :+ ty.ToString()
  5018. Next
  5019. Else
  5020. s = "?"
  5021. End If
  5022. t :+ s + ">" + classDecl.templateSource.ToString()
  5023. Else
  5024. t :+ Enquote(classDecl.munged)
  5025. End If
  5026. Emit t, False
  5027. Else
  5028. For Local decl:TDecl=EachIn classDecl.Decls()
  5029. Local fdecl:TFuncDecl=TFuncDecl( decl )
  5030. If fdecl
  5031. EmitIfcClassFuncDecl fdecl
  5032. Continue
  5033. EndIf
  5034. Next
  5035. Local flags:String = "E"
  5036. If classDecl.IsInterface() Then
  5037. flags :+ "I"
  5038. Else If classDecl.IsStruct() Then
  5039. flags :+ "S"
  5040. End If
  5041. If classDecl.attrs & DECL_API_STDCALL Then
  5042. flags :+ "W"
  5043. End If
  5044. Emit "}" + flags + "=0", False
  5045. End If
  5046. 'PopMungScope
  5047. EndLocalScope
  5048. End Method
  5049. Method EmitIfcGlobalDecl(globalDecl:TGlobalDecl)
  5050. globalDecl.Semant
  5051. Local g:String = globalDecl.ident
  5052. g:+ TransIfcType(globalDecl.ty, globalDecl.ModuleScope().IsSuperStrict())
  5053. g:+ "&"
  5054. If globalDecl.IsPrivate() Then
  5055. g :+ "`"
  5056. Else If globalDecl.IsProtected() Then
  5057. g :+ "``"
  5058. End If
  5059. g :+ "="
  5060. g :+ "mem:p("
  5061. If TFunctionPtrType(globalDecl.ty) Then
  5062. g :+ Enquote(TFunctionPtrType(globalDecl.ty).func.munged)
  5063. Else
  5064. g :+ Enquote(globalDecl.munged)
  5065. End If
  5066. g :+ ")"
  5067. Emit g
  5068. End Method
  5069. Method EmitIfcEnumDecl(enumdecl:TEnumDecl)
  5070. enumDecl.Semant
  5071. Local e:String = enumDecl.ident + "\" + TransIfcType(enumDecl.ty)
  5072. Emit e + "{", False
  5073. For Local val:TEnumValueDecl = EachIn enumDecl.values
  5074. Emit val.ident + "=" + val.Value()
  5075. Next
  5076. Local flags:String
  5077. If enumDecl.isFlags Then
  5078. flags = "F"
  5079. End If
  5080. Emit "}" + flags + "=" + Enquote(enumDecl.munged), False
  5081. End Method
  5082. Method EmitModuleInclude(moduleDecl:TModuleDecl, included:TMap = Null)
  5083. If moduleDecl.filepath Then
  5084. ' a module import
  5085. If FileType(moduleDecl.filepath) = FILETYPE_DIR Or (opt_ismain And moduleDecl.ident = opt_modulename) Then
  5086. Local inc:String = ModuleHeaderFromIdent(moduleDecl.ident, True)
  5087. If Not included Or (included And Not included.Contains(inc)) Then
  5088. Emit "#include <" + inc + ">"
  5089. If included Then
  5090. included.Insert(inc, inc)
  5091. End If
  5092. End If
  5093. Else
  5094. ' a file import...
  5095. Local inc:String = FileHeaderFromFile(moduleDecl, False)
  5096. If Not included Or (included And Not included.Contains(inc)) Then
  5097. Emit "#include ~q" + inc + "~q"
  5098. If included Then
  5099. included.Insert(inc, inc)
  5100. End If
  5101. End If
  5102. End If
  5103. ' DebugLog moduleDecl.filepath
  5104. End If
  5105. End Method
  5106. Method EmitModuleInit(moduleDecl:TModuleDecl)
  5107. If moduleDecl.filepath Then
  5108. ' a module import
  5109. If FileType(moduleDecl.filepath) = FILETYPE_DIR Then
  5110. Emit MungModuleName(moduleDecl) + "();"
  5111. Else
  5112. ' maybe a file import...
  5113. Emit MungImportFromFile(moduleDecl) + "();"
  5114. End If
  5115. End If
  5116. End Method
  5117. Method EmitIncBinFile(ib:TIncbin)
  5118. If FileType(ib.path) = FILETYPE_FILE Then
  5119. If Not opt_legacy_incbin Then
  5120. Local ident:String = _appInstance.munged + "_" + ib.id
  5121. Emit "INCBIN(" + ident + ", ~q" + ib.path + "~q);"
  5122. Else
  5123. Local ident:String = _appInstance.munged + "_ib_" + ib.id
  5124. Local buf:Byte[] = LoadByteArray(ib.path)
  5125. ib.length = buf.length
  5126. Emit "unsigned char " + ident + "[] = {"
  5127. Local sb:TStringBuffer = New TStringBuffer
  5128. Local hx:Short[2]
  5129. Local LINES:Int
  5130. Local count:Int
  5131. For Local i:Int = 0 Until buf.length
  5132. Local val:Int = buf[i]
  5133. For Local k:Int=1 To 0 Step -1
  5134. Local n:Int=(val&15)+48
  5135. If n>57 n:+39
  5136. hx[k]=n
  5137. val:Shr 4
  5138. Next
  5139. sb.Append("0x").AppendShorts( hx,2 )
  5140. sb.Append(",")
  5141. count :+ 5
  5142. If count > 80 Then
  5143. sb.Append("~n")
  5144. count = 0
  5145. LINES :+ 1
  5146. End If
  5147. If LINES > 100 Then
  5148. Emit sb.ToString()
  5149. sb.SetLength(0)
  5150. LINES = 0
  5151. End If
  5152. Next
  5153. Emit sb.ToString()
  5154. Emit "};"
  5155. End If
  5156. End If
  5157. End Method
  5158. Method TransHeader(app:TAppDecl)
  5159. SetOutput("head")
  5160. _app = app
  5161. prefix = app.GetPathPrefix()
  5162. ' TODO
  5163. If Not opt_apptype Then
  5164. app.mainFunc.munged="bb_localmain"
  5165. Else
  5166. app.mainFunc.munged="bb_main"
  5167. End If
  5168. ' track what's been included so far - avoid duplicates
  5169. Local included:TMap = New TMap
  5170. For Local decl:TModuleDecl=EachIn app.imported.Values()
  5171. For Local mdecl:TDecl=EachIn decl.imported.Values()
  5172. MungDecl mdecl
  5173. 'skip mdecls we are not interested in
  5174. If Not TModuleDecl(mdecl) Then Continue
  5175. If app.mainModule = mdecl Then Continue
  5176. If mdecl.ident = "brl.classes" Then Continue
  5177. If mdecl.ident = "brl.blitzkeywords" Then Continue
  5178. EmitModuleInclude(TModuleDecl(mdecl), included)
  5179. Next
  5180. Next
  5181. For Local header:String=EachIn app.headers
  5182. Emit "#include ~q../" + header + "~q"
  5183. Next
  5184. Emit "int " + app.munged + "();"
  5185. For Local decl:TDecl=EachIn app.Semanted()
  5186. If decl.declImported And decl.munged Continue
  5187. MungDecl decl
  5188. Local cdecl:TClassDecl=TClassDecl( decl )
  5189. If Not cdecl Continue
  5190. ' mung, but don't emit
  5191. ' Emit prefix + decl.munged+";"
  5192. 'PushMungScope
  5193. funcMungs = New TMap
  5194. BeginLocalScope
  5195. For Local decl:TDecl=EachIn cdecl.Semanted()
  5196. MungDecl decl
  5197. cdecl.SemantParts()
  5198. Next
  5199. EndLocalScope
  5200. 'PopMungScope
  5201. Next
  5202. ' forward declarations
  5203. For Local decl:TClassDecl=EachIn app.Semanted()
  5204. If decl.declImported Or (decl.IsExtern() And Not decl.IsStruct()) Continue
  5205. If Not decl.IsStruct()
  5206. Emit "struct " + decl.munged + "_obj;"
  5207. Else
  5208. Emit "struct " + decl.munged + ";"
  5209. End If
  5210. If decl.IsInterface() Then
  5211. Emit "extern const struct BBInterface " + decl.munged + "_ifc;"
  5212. End If
  5213. Next
  5214. 'prototypes/header! - structs first
  5215. For Local decl:TDecl=EachIn app.Semanted()
  5216. If decl.declImported Continue
  5217. Local cdecl:TClassDecl=TClassDecl( decl )
  5218. If cdecl
  5219. If cdecl.IsStruct() Then
  5220. EmitStructClassProto cdecl
  5221. End If
  5222. EndIf
  5223. Next
  5224. ' prototypes/header - typedefs
  5225. For Local cdecl:TClassDecl=EachIn app.Semanted()
  5226. If cdecl.declImported Continue
  5227. If Not cdecl.IsStruct() And cdecl.IsExtern() Then
  5228. EmitExternClassProtoTypedef(cdecl)
  5229. End If
  5230. Next
  5231. 'prototypes/header!
  5232. For Local decl:TDecl=EachIn app.Semanted()
  5233. If decl.declImported Continue
  5234. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  5235. If gdecl
  5236. MungDecl gdecl
  5237. If Not gdecl.IsPrivate() Then
  5238. If Not TFunctionPtrType(gdecl.ty) Then
  5239. Emit "extern "+TransThreadedGlobal(gdecl)+TransRefType( gdecl.ty, "" )+" "+gdecl.munged+";" 'forward reference...
  5240. Else
  5241. If Not TFunctionPtrType(gdecl.ty).func.noCastGen Then
  5242. ' generate function pointer refs if we haven't been told not to
  5243. ' If Not gdecl.IsExtern() Then
  5244. Emit "extern " + TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, gdecl.munged )+";" 'forward reference...
  5245. ' End If
  5246. End If
  5247. End If
  5248. End If
  5249. Continue
  5250. EndIf
  5251. Local fdecl:TFuncDecl=TFuncDecl( decl )
  5252. If fdecl' And Not fdecl.IsExtern()
  5253. ' don't include the main function - it's handled separately
  5254. If fdecl = app.mainFunc Then
  5255. Continue
  5256. End If
  5257. EmitGDBDebug(fdecl)
  5258. EmitFuncDecl( fdecl, True)
  5259. Continue
  5260. EndIf
  5261. Local cdecl:TClassDecl=TClassDecl( decl )
  5262. If cdecl
  5263. If Not cdecl.IsStruct() Then
  5264. If Not cdecl.IsExtern()
  5265. EmitClassProto cdecl
  5266. Else
  5267. EmitExternClassProto cdecl
  5268. End If
  5269. 'Else
  5270. ' EmitStructClassProto cdecl
  5271. End If
  5272. 'Continue
  5273. EndIf
  5274. Local edecl:TEnumDecl = TEnumDecl( decl )
  5275. If edecl Then
  5276. EmitEnumProto edecl
  5277. Continue
  5278. End If
  5279. Next
  5280. End Method
  5281. Method IncBinRequiresRebuild:Int(file:String, incbins:TList)
  5282. ' file doesn't exist?
  5283. If Not FileType(file) Then
  5284. Return True
  5285. End If
  5286. Local timestamp:Int = FileTime(file)
  5287. ' file exists... read header and compare names
  5288. ' read lines until "// ----"
  5289. ' TODO
  5290. Local files:TList = New TList
  5291. Local hashes:TMap = New TMap
  5292. Local stream:TStream = ReadFile(file)
  5293. While True
  5294. Local s:String = ReadLine(stream)
  5295. If Not s.StartsWith("// ") Or s.StartsWith("// ----") Then
  5296. Exit
  5297. End If
  5298. Local ind:Int = s.Find("// FILE : ")
  5299. If ind = 0 Then
  5300. Local line:String = s[10..]
  5301. Local parts:String[] = line.Split("~t")
  5302. If parts.length = 1 Then
  5303. Return True
  5304. End If
  5305. Local filename:String = parts[0].Replace("~q","")
  5306. Local fileHash:String = parts[1]
  5307. files.AddLast(filename)
  5308. hashes.Insert(filename, fileHash)
  5309. End If
  5310. Wend
  5311. stream.Close()
  5312. ' different number of files?
  5313. If files.Count() <> incbins.Count() Then
  5314. Return True
  5315. End If
  5316. ' different file names?
  5317. Local count:Int
  5318. For Local s:String = EachIn files
  5319. For Local ib:TIncbin = EachIn incbins
  5320. If s = ib.file Then
  5321. count :+ 1
  5322. Exit
  5323. End If
  5324. Next
  5325. Next
  5326. If count <> files.count() Then
  5327. Return True
  5328. End If
  5329. count = 0
  5330. For Local ib:TIncbin = EachIn incbins
  5331. For Local s:String = EachIn files
  5332. If s = ib.file Then
  5333. count :+ 1
  5334. Exit
  5335. End If
  5336. Next
  5337. Next
  5338. If count <> incbins.count() Then
  5339. Return True
  5340. End If
  5341. For Local ib:TIncbin = EachIn incbins
  5342. If timestamp < FileTime(ib.path) Then
  5343. Return True
  5344. End If
  5345. Local fileHash:String = String(hashes.ValueForKey(ib.file))
  5346. If Not fileHash Then
  5347. Return True
  5348. End If
  5349. If fileHash <> CalculateFileHash(ib.path) Then
  5350. Return True
  5351. End If
  5352. ' set the length, as we will need this later if we aren't loading the files now.
  5353. ib.length = FileSize(ib.path)
  5354. Next
  5355. Return False
  5356. End Method
  5357. Method TransIncBin(app:TAppDecl)
  5358. If app.incbins.Count() > 0 Then
  5359. SetOutput("incbin")
  5360. Local mung:String = FileMung(False)
  5361. Local name:String = StripAll(app.mainModule.filepath)
  5362. Local file:String
  5363. If opt_legacy_incbin Then
  5364. file = "incbin.c"
  5365. Else
  5366. file = "incbin2.c"
  5367. End If
  5368. Local filepath:String = OutputFilePath(opt_filepath, mung, file)
  5369. If IncBinRequiresRebuild(filepath, app.incbins) Then
  5370. If Not opt_legacy_incbin Then
  5371. Emit "#define INCBIN_PREFIX _ib"
  5372. Emit "#define INCBIN_STYLE INCBIN_STYLE_SNAKE"
  5373. Emit "#include ~qbrl.mod/blitz.mod/incbin/incbin.h~q"
  5374. End If
  5375. app.genIncBinHeader = True
  5376. For Local ib:TIncbin = EachIn app.incbins
  5377. Local fileHash:String = CalculateFileHash(ib.path)
  5378. Emit "// FILE : " + Enquote(ib.file) + "~t" + fileHash
  5379. Next
  5380. Emit "// ----"
  5381. For Local ib:TIncbin = EachIn app.incbins
  5382. EmitIncBinFile(ib)
  5383. Next
  5384. End If
  5385. SetOutput("pre_source")
  5386. End If
  5387. End Method
  5388. Method TransGlobalInit(decl:TGlobalDecl)
  5389. If TFunctionPtrType(decl.ty) Then
  5390. If TInvokeExpr(decl.init) And Not TInvokeExpr(decl.init).invokedWithBraces Then
  5391. Emit TransGlobal( decl )+"="+TInvokeExpr(decl.init).decl.munged + ";"
  5392. Else
  5393. Emit TransGlobal( decl )+"="+decl.init.Trans()+";"
  5394. End If
  5395. Else
  5396. If Not decl.funcGlobal Then
  5397. If TObjectType(decl.ty) And Not TObjectType(decl.ty).classDecl.IsStruct() Then
  5398. Emit TransGlobal( decl )+"="+Bra(TransObject(TObjectType(decl.ty).classDecl))+decl.init.Trans()+";"
  5399. Else
  5400. Emit TransGlobal( decl )+"="+decl.init.Trans()+";"
  5401. End If
  5402. End If
  5403. End If
  5404. End Method
  5405. Method TransSource(app:TAppDecl)
  5406. SetOutput("pre_source")
  5407. ' include our header
  5408. EmitModuleInclude(app.mainModule)
  5409. ' incbins
  5410. TransIncBin(app)
  5411. SetOutput("source")
  5412. ' nested type forward declarations
  5413. For Local decl:TClassDecl=EachIn app.Semanted()
  5414. For Local cdecl:TClassDecl = EachIn decl._decls
  5415. MungDecl decl
  5416. MungDecl cdecl
  5417. If cdecl.declImported Or (cdecl.IsExtern() And Not cdecl.IsStruct()) Continue
  5418. If Not cdecl.IsStruct()
  5419. Emit "struct " + cdecl.munged + "_obj;"
  5420. Else
  5421. Emit "struct " + cdecl.munged + ";"
  5422. End If
  5423. If cdecl.IsInterface() Then
  5424. Emit "extern const struct BBInterface " + cdecl.munged + "_ifc;"
  5425. End If
  5426. Next
  5427. Next
  5428. ' Private Global declarations
  5429. ' since we don't declare them in the header, they need to be near the top of the source
  5430. For Local decl:TDecl=EachIn app.Semanted()
  5431. If decl.declImported Continue
  5432. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  5433. If gdecl And gdecl.IsPrivate() Then
  5434. If Not TFunctionPtrType(gdecl.ty) Then
  5435. If TConstExpr(gdecl.init) Then
  5436. Emit TransRefType( gdecl.ty, "WW" )+" "+TransGlobalDecl(gdecl)+";"
  5437. gdecl.inited = True
  5438. Else
  5439. If Not gdecl.IsExtern() Then
  5440. Emit TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  5441. Else
  5442. ' delcare in source for any references to it locally in this module
  5443. Emit "extern "+ TransThreadedGlobal(gdecl) +TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  5444. End If
  5445. End If
  5446. Else
  5447. If Not gdecl.IsExtern() Then
  5448. Emit TransRefType( gdecl.ty, gdecl.munged ) + ";"
  5449. EndIf
  5450. End If
  5451. Continue
  5452. EndIf
  5453. Next
  5454. For Local gdecl:TGlobalDecl=EachIn app.SemantedGlobals
  5455. If gdecl And gdecl.funcGlobal Then
  5456. MungDecl gdecl
  5457. If Not TFunctionPtrType(gdecl.ty) Then
  5458. Emit "static " + TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+";"
  5459. Else
  5460. Emit "static " + TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, gdecl.munged ) + ";"
  5461. End If
  5462. Continue
  5463. End If
  5464. Next
  5465. 'definitions!
  5466. For Local decl:TDecl=EachIn app.Semanted()
  5467. If decl.declImported Continue
  5468. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  5469. If gdecl
  5470. If gdecl.IsPrivate() Continue
  5471. If Not TFunctionPtrType(gdecl.ty) And Not gdecl.IsPrivate() Then
  5472. If TConstExpr(gdecl.init) Then
  5473. Emit TransThreadedGlobal(gdecl) + TransRefType( gdecl.ty, "WW" )+" "+TransGlobalDecl(gdecl)+";"
  5474. gdecl.inited = True
  5475. Else
  5476. If Not gdecl.IsExtern() Then
  5477. If TObjectType(gdecl.ty) Then
  5478. Emit TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+ "=" + Bra(TransObject(TObjectType(gdecl.ty).classDecl)) + TransValue(gdecl.ty, "") + ";"
  5479. Else
  5480. Emit TransRefType( gdecl.ty, "WW" )+" "+gdecl.munged+ "=" + TransValue(gdecl.ty, "") + ";"
  5481. End If
  5482. End If
  5483. End If
  5484. Else
  5485. If TFunctionPtrType(gdecl.ty) And Not gdecl.IsExtern() Then
  5486. Emit TransRefType( gdecl.ty, gdecl.munged ) + ";"
  5487. End If
  5488. End If
  5489. Continue
  5490. EndIf
  5491. Local fdecl:TFuncDecl=TFuncDecl( decl )
  5492. If fdecl And Not fdecl.IsExtern()
  5493. ' don't include the main function - it's handled separately
  5494. If fdecl = app.mainFunc Then
  5495. Continue
  5496. End If
  5497. EmitGDBDebug(fdecl)
  5498. EmitFuncDecl fdecl
  5499. Continue
  5500. EndIf
  5501. Local cdecl:TClassDecl=TClassDecl( decl )
  5502. If cdecl
  5503. EmitGDBDebug(cdecl)
  5504. EmitClassDecl cdecl
  5505. Continue
  5506. EndIf
  5507. Local edecl:TEnumDecl = TEnumDecl( decl )
  5508. If edecl Then
  5509. EmitEnumDecl edecl
  5510. Continue
  5511. End If
  5512. Next
  5513. ' emit nested functions/classes for localmain
  5514. ' emit nested protos
  5515. For Local fdecl:TFuncDecl = EachIn app.mainFunc._decls
  5516. EmitFuncDecl(fdecl, True)
  5517. Next
  5518. ' emit nested bodies
  5519. For Local fdecl:TFuncDecl = EachIn app.mainFunc._decls
  5520. EmitFuncDecl(fdecl, False)
  5521. Next
  5522. ' incbin decls
  5523. For Local ib:TIncbin = EachIn app.incbins
  5524. If opt_legacy_incbin Then
  5525. Emit "extern unsigned char * " + app.munged + "_ib_" + ib.id + ";"
  5526. Else
  5527. Emit "extern const unsigned char * " + ib.GeneratedDataName(app) + ";"
  5528. Emit "extern const unsigned int " + ib.GeneratedSizeName(app) + ";"
  5529. End If
  5530. Next
  5531. ' coverage
  5532. Local covCount:Int
  5533. If opt_coverage Then
  5534. Local id:Int
  5535. For Local file:String = EachIn coverageFileInfo.Keys()
  5536. Local covFile:TCoverageLineInfo = TCoverageLineInfo(coverageFileInfo.ValueForKey(file))
  5537. Local t:String
  5538. Emit "static int coverage_lines_" + id + "[] = {"
  5539. For Local i:Int = 0 Until covFile.lines.Length
  5540. If i And i Mod 40 = 0 Then
  5541. If i Then
  5542. t :+ ","
  5543. End If
  5544. Emit t
  5545. t = ""
  5546. Else
  5547. If i Then
  5548. t :+ ","
  5549. End If
  5550. End If
  5551. t :+ covFile.lines[i]
  5552. Next
  5553. If t Then
  5554. Emit t
  5555. End If
  5556. Emit "};"
  5557. Emit "static BBCoverageFunctionInfo coverage_funcs_" + id + "[] = {"
  5558. Local covFuncFile:TCoverageFunctionLineInfo = TCoverageFunctionLineInfo(coverageFunctionFileInfo.ValueForKey(file))
  5559. For Local i:Int = 0 Until covFuncFile.funcs.Length
  5560. Emit "{ " + Enquote(covFuncFile.funcs[i].name) + ", " + covFuncFile.funcs[i].line + " },"
  5561. Next
  5562. Emit "};"
  5563. id :+ 1
  5564. Next
  5565. covCount = id
  5566. If id Then
  5567. id = 0
  5568. Emit "static BBCoverageFileInfo coverage_files[] = {"
  5569. For Local file:String = EachIn coverageFileInfo.Keys()
  5570. Local covFile:TCoverageLineInfo = TCoverageLineInfo(coverageFileInfo.ValueForKey(file))
  5571. Emit "{"
  5572. Emit Enquote(file) + ","
  5573. Emit "coverage_lines_" + id + ","
  5574. Emit "sizeof(coverage_lines_" + id + ") / sizeof(coverage_lines_" + id + "[0]),"
  5575. Emit "NULL,"
  5576. Emit "coverage_funcs_" + id + ","
  5577. Emit "sizeof(coverage_funcs_" + id + ") / sizeof(coverage_funcs_" + id + "[0]),"
  5578. Emit "NULL,"
  5579. Emit "},"
  5580. id :+ 1
  5581. Next
  5582. Emit "{ NULL, NULL, 0, NULL, NULL, 0, NULL }"
  5583. Emit "};"
  5584. End If
  5585. End If
  5586. Emit "static int " + app.munged + "_inited" + " = 0;"
  5587. Emit "int " + app.munged + "(){"
  5588. ' initialise stuff
  5589. Emit "if (!" + app.munged + "_inited) {"
  5590. Emit app.munged + "_inited = 1;"
  5591. ' add global roots
  5592. Local first:TGlobalDecl
  5593. Local last:TGlobalDecl
  5594. For Local decl:TGlobalDecl=EachIn app.semantedGlobals
  5595. If decl.declImported Continue
  5596. decl.Semant
  5597. If Not first Then
  5598. first = decl
  5599. End If
  5600. last = decl
  5601. Next
  5602. If first Then
  5603. Emit "GC_add_roots(&" + first.munged + ", &" + last.munged + " + 1);"
  5604. End If
  5605. ' threaded global scope assignments
  5606. For Local decl:TDecl=EachIn app.Semanted()
  5607. If decl.declImported Continue
  5608. Local cdecl:TClassDecl=TClassDecl( decl )
  5609. If cdecl
  5610. EmitClassThreadedGlobalDebugInit(cdecl)
  5611. End If
  5612. Next
  5613. ' register incbins
  5614. For Local ib:TIncbin = EachIn app.incbins
  5615. If opt_legacy_incbin Then
  5616. Emit "bbIncbinAdd((BBString*)&" + StringConstId(ib.file) + ",&" + app.munged + "_ib_" + ib.id + "," + ib.length + ");"
  5617. Else
  5618. Emit "bbIncbinAdd((BBString*)&" + StringConstId(ib.file) + ",&" + ib.GeneratedDataName(app) + "," + ib.GeneratedSizeName(app) + ");"
  5619. End If
  5620. Next
  5621. Local importOnce:TMap = New TMap
  5622. ' call any imported mod inits
  5623. For Local decl:TModuleDecl=EachIn app.imported.Values()
  5624. For Local mdecl:TDecl=EachIn decl.imported.Values()
  5625. If TModuleDecl(mdecl) And app.mainModule <> mdecl And mdecl.ident <> "brl.classes" And mdecl.ident <> "brl.blitzkeywords" Then
  5626. If Not importOnce.Contains(mdecl.ident) Then
  5627. EmitModuleInit(TModuleDecl(mdecl))
  5628. importOnce.Insert(mdecl.ident, "")
  5629. End If
  5630. End If
  5631. Next
  5632. Next
  5633. ' initialise enums
  5634. For Local decl:TEnumDecl = EachIn app.Semanted()
  5635. If decl.declImported Continue
  5636. Emit decl.munged + "_BBEnum_impl = (BBEnum *)&" + decl.munged + "_BBEnum;"
  5637. Next
  5638. ' initialise coverage
  5639. If opt_coverage And covCount Then
  5640. Emit "bbCoverageRegisterFile(coverage_files);"
  5641. End If
  5642. ' register types
  5643. For Local decl:TDecl=EachIn app.Semanted()
  5644. If decl.declImported Continue
  5645. Local cdecl:TClassDecl=TClassDecl( decl )
  5646. If cdecl And Not cdecl.IsExtern() And Not cdecl.args
  5647. If Not cdecl.IsInterface() Then
  5648. If Not cdecl.IsStruct() Then
  5649. Emit "bbObjectRegisterType((BBCLASS)&" + cdecl.munged + ");"
  5650. Else
  5651. Emit "bbObjectRegisterStruct((BBDebugScope *)&" + cdecl.munged + "_scope);"
  5652. End If
  5653. Else
  5654. Emit "bbObjectRegisterInterface((BBInterface *)&" + cdecl.munged + "_ifc);"
  5655. End If
  5656. Continue
  5657. EndIf
  5658. Local edecl:TEnumDecl = TEnumDecl( decl )
  5659. If edecl Then
  5660. Emit "bbEnumRegister((BBEnum *)" + decl.munged + "_BBEnum_impl, (BBDebugScope *)&" + edecl.munged + "_scope);"
  5661. End If
  5662. Next
  5663. '
  5664. ' register files
  5665. If opt_debug Then
  5666. For Local Hash:String = EachIn fileRegister.Keys()
  5667. Local file:String = String(fileRegister.ValueForKey(Hash))
  5668. Emit "bbRegisterSource(" + Hash + ", ~q" + file + "~q);"
  5669. Next
  5670. End If
  5671. ' defdata init
  5672. If Not app.dataDefs.IsEmpty() Then
  5673. Emit "_defDataOffset = &_defData;"
  5674. End If
  5675. ' initialise globals
  5676. For Local decl:TGlobalDecl=EachIn app.semantedGlobals
  5677. If decl.declImported Continue
  5678. decl.Semant
  5679. If decl.scope And TClassDecl(decl.scope) And Not TClassDecl(decl.scope).IsStruct() Then
  5680. Emit TransGlobal( decl )+"="+TransValue(decl.ty, Null)+";"
  5681. End If
  5682. Next
  5683. ' initialise globals
  5684. For Local decl:TGlobalDecl=EachIn app.semantedGlobals
  5685. If decl.declImported Continue
  5686. 'decl.Semant
  5687. ' TODO : what about OnDebugStop etc, who have no init ?
  5688. If decl.init And Not (decl.attrs & DECL_INITONLY) Then
  5689. If decl.scope And TClassDecl(decl.scope) Then
  5690. ' class global inits need to be generated in the correct order.
  5691. ' only generate global inits if the parent class hasn't already been processed,
  5692. ' otherwise, we will skip this global as it should already have been generated.
  5693. If Not TClassDecl(decl.scope).globInit Then
  5694. TClassDecl(decl.scope).globInit = True
  5695. For Local gdecl:TGlobalDecl = EachIn decl.scope._decls
  5696. If gdecl.declImported Continue
  5697. gdecl.Semant
  5698. If gdecl.init And Not (gdecl.attrs & DECL_INITONLY) Then
  5699. TransGlobalInit(gdecl)
  5700. End If
  5701. Next
  5702. End If
  5703. Else
  5704. TransGlobalInit(decl)
  5705. End If
  5706. End If
  5707. Next
  5708. ' now do the local main stuff
  5709. app.mainFunc.Semant()
  5710. EmitLocalDeclarations(app.mainFunc)
  5711. EmitBlock app.mainFunc
  5712. Emit "}"
  5713. Emit "return 0;"
  5714. Emit "}"
  5715. ' redirect string generation to the def data section of the source
  5716. SetOutput("def_data")
  5717. ' defdata
  5718. EmitDefDataArray(app)
  5719. ' redirect string generation to the top of the source
  5720. SetOutput("pre_source")
  5721. ' strings
  5722. ' generate sized structs
  5723. Local sizes:TIntMap = New TIntMap
  5724. For Local s:String = EachIn app.stringConsts.Keys()
  5725. If s Then
  5726. Local key:TStringConst = TStringConst(app.stringConsts.ValueForKey(s))
  5727. If key.used > 0 Then
  5728. If Not sizes.Contains(s.length) Then
  5729. Emit "struct BBString_" + s.length + "{BBClass_String* clas;BBULONG hash;int length;BBChar buf[" + s.length + "];};"
  5730. sizes.Insert(s.length, "")
  5731. End If
  5732. End If
  5733. End If
  5734. Next
  5735. For Local s:String = EachIn app.stringConsts.Keys()
  5736. If s Then
  5737. Local key:TStringConst = TStringConst(app.stringConsts.ValueForKey(s))
  5738. If key.used > 0 Then
  5739. Emit "static struct BBString_" + s.length + " " + key.id + "={"
  5740. Emit "&bbStringClass,"
  5741. Emit bmx_gen_hash(s) + ","
  5742. Emit s.length + ","
  5743. Local t:String = "{"
  5744. For Local i:Int = 0 Until s.length
  5745. If i Then
  5746. t:+ ","
  5747. End If
  5748. t:+ s[i]
  5749. If i And Not (i Mod 16) Then
  5750. Emit t
  5751. t = ""
  5752. End If
  5753. Next
  5754. Emit t + "}"
  5755. Emit "};"
  5756. End If
  5757. End If
  5758. Next
  5759. ' scope defs
  5760. If Not app.scopedefs.IsEmpty() Then
  5761. For Local val:String = EachIn app.scopedefs.Keys()
  5762. Local i:Int = val.ToInt()
  5763. Emit "struct BBDebugScope_" + i + "{int kind; const char *name; BBDebugDecl decls[" + (i + 1) + "]; };"
  5764. Next
  5765. End If
  5766. End Method
  5767. Method EmitDefDataArray(app:TAppDecl)
  5768. If Not app.dataDefs.IsEmpty() Then
  5769. '
  5770. Emit "static struct bbDataDef * _defDataOffset;"
  5771. Emit "static struct bbDataDef _defData[" + TDefDataDecl.count + "]={"
  5772. For Local decl:TDefDataDecl = EachIn app.dataDefs
  5773. EmitDefData(decl)
  5774. Next
  5775. Emit "};"
  5776. End If
  5777. End Method
  5778. Method EmitDefData(decl:TDefDataDecl)
  5779. For Local i:Int = 0 Until decl.data.length
  5780. Local expr:TExpr = decl.data[i]
  5781. Emit "{"
  5782. Emit TransDefDataType(expr.exprType) + ","
  5783. Emit "{"
  5784. Emit "." + TransDefDataUnionType(expr.exprType) + " = " + expr.Trans()
  5785. Emit "}"
  5786. Emit "},"
  5787. Next
  5788. End Method
  5789. Method EmitIfcImports(impMod:TModuleDecl, processed:TMap)
  5790. For Local decl:TDecl=EachIn impMod.imported.Values()
  5791. Local mdecl:TModuleDecl=TModuleDecl( decl )
  5792. If mdecl And mdecl.ident <> "brl.classes" And mdecl.ident <> "brl.blitzkeywords" Then
  5793. If mdecl.filepath.EndsWith(".bmx")
  5794. If _appInstance.mainModule<>mdecl
  5795. EmitIfcImports(mdecl, processed)
  5796. For Local s:String = EachIn mdecl.fileImports
  5797. If Not processed.Contains("XX" + s + "XX") Then
  5798. Emit "import " + BmxEnquote(s)
  5799. processed.Insert("XX" + s + "XX", "")
  5800. End If
  5801. Next
  5802. End If
  5803. Else
  5804. If Not processed.Contains(mdecl.ident)
  5805. Emit "import " + mdecl.ident
  5806. processed.Insert(mdecl.ident, "")
  5807. End If
  5808. End If
  5809. End If
  5810. Next
  5811. End Method
  5812. Method EmitIfcStructImports(impMod:TModuleDecl, processed:TMap)
  5813. For Local decl:TDecl=EachIn impMod.imported.Values()
  5814. Local mdecl:TModuleDecl=TModuleDecl( decl )
  5815. If mdecl Then
  5816. If mdecl.filepath.EndsWith(".bmx") And _appInstance.mainModule<>mdecl And Not processed.Contains(mdecl)
  5817. EmitIfcStructImports(mdecl, processed)
  5818. processed.Insert(mdecl, mdecl)
  5819. For Local decl:TDecl=EachIn mdecl._decls
  5820. decl.Semant
  5821. ' consts
  5822. Local cdecl:TConstDecl=TConstDecl( decl )
  5823. If cdecl
  5824. EmitIfcConstDecl(cdecl)
  5825. Continue
  5826. End If
  5827. ' classes
  5828. Local tdecl:TClassDecl=TClassDecl( decl )
  5829. If tdecl
  5830. EmitIfcClassDecl(tdecl)
  5831. Continue
  5832. EndIf
  5833. ' functions
  5834. Local fdecl:TFuncDecl=TFuncDecl( decl )
  5835. If fdecl And fdecl <> _appInstance.mainFunc Then
  5836. EmitIfcFuncDecl(fdecl)
  5837. Continue
  5838. End If
  5839. ' globals
  5840. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  5841. If gdecl
  5842. EmitIfcGlobalDecl(gdecl)
  5843. Continue
  5844. End If
  5845. ' enums
  5846. Local edecl:TEnumDecl=TEnumDecl( decl )
  5847. If edecl
  5848. EmitIfcEnumDecl(edecl)
  5849. Continue
  5850. EndIf
  5851. Next
  5852. End If
  5853. End If
  5854. Next
  5855. End Method
  5856. Method FileHeaderFromFile:String(mdecl:TModuleDecl, includePath:Int = False)
  5857. Local name:String = StripAll(mdecl.filepath)
  5858. Local dir:String = ExtractDir(mdecl.filePath)
  5859. Local file:String = name + ".bmx" + FileMung(opt_apptype And (Not mdecl.declImported)) + ".h"
  5860. If mdecl.relPath Then
  5861. Local dir:String = ExtractDir(mdecl.relPath)
  5862. If dir Then
  5863. file = "../" + dir + "/.bmx/" + file
  5864. End If
  5865. End If
  5866. Return file
  5867. End Method
  5868. Method MungImportFromFile:String(mdecl:TModuleDecl)
  5869. Local result:String
  5870. If opt_buildtype <> BUILDTYPE_MODULE Then
  5871. Local dir:String = ExtractDir(mdecl.filepath).ToLower()
  5872. dir = dir[dir.findLast("/") + 1..]
  5873. If dir.EndsWith(".mod") Then
  5874. dir = dir.Replace(".mod", "")
  5875. End If
  5876. Local file:String = StripDir(mdecl.filepath).ToLower()
  5877. result = "_bb_" + dir + "_" + StripExt(file)
  5878. Else
  5879. result = "_bb_" + mdecl.ident
  5880. End If
  5881. 'return with all non-allowed chars (like "-" or " ") removed
  5882. Return TStringHelper.Sanitize(result)
  5883. End Method
  5884. Method TransInterface(app:TAppDecl)
  5885. SetOutput("interface")
  5886. If app.mainModule.IsSuperStrict() Then
  5887. Emit "superstrict"
  5888. End If
  5889. ' module info
  5890. For Local info:String = EachIn app.mainModule.modInfo
  5891. Emit "ModuleInfo " + BmxEnquote(info)
  5892. Next
  5893. Local processed:TMap = New TMap
  5894. ' module imports
  5895. For Local decl:TDecl=EachIn app.mainModule.imported.Values()
  5896. Local mdecl:TModuleDecl=TModuleDecl( decl )
  5897. If mdecl Then
  5898. If mdecl.IsActualModule() Then
  5899. Emit "import " + mdecl.ident
  5900. processed.Insert(mdecl.ident, "")
  5901. Else If Not opt_ismain And mdecl.filepath.EndsWith(".bmx") And app.mainModule<>mdecl
  5902. Local file:String = StripDir(mdecl.filepath)
  5903. If mdecl.relPath Then
  5904. Local dir:String = ExtractDir(mdecl.relPath)
  5905. If dir Then
  5906. file = dir + "/" + file
  5907. End If
  5908. End If
  5909. If Not processed.Contains(file) Then
  5910. Emit "import " + Enquote(file)
  5911. processed.Insert(file, "")
  5912. End If
  5913. End If
  5914. End If
  5915. Next
  5916. ' module imports from other files?
  5917. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain Then
  5918. EmitIfcImports(app.mainModule, processed)
  5919. End If
  5920. ' other imports
  5921. For Local s:String = EachIn app.fileImports
  5922. Emit "import " + BmxEnquote(s)
  5923. Next
  5924. processed = New TMap
  5925. ' imported module structure (consts, classes, functions, etc)
  5926. If opt_buildtype = BUILDTYPE_MODULE And opt_ismain Then
  5927. EmitIfcStructImports(app.mainModule, processed)
  5928. End If
  5929. ' consts
  5930. For Local decl:TDecl=EachIn app.Semanted()
  5931. If decl.IsPrivate() Continue
  5932. Local cdecl:TConstDecl=TConstDecl( decl )
  5933. If cdecl And Not cdecl.declImported
  5934. EmitIfcConstDecl(cdecl)
  5935. End If
  5936. Next
  5937. ' classes
  5938. For Local decl:TDecl=EachIn app.Semanted()
  5939. Local cdecl:TClassDecl=TClassDecl( decl )
  5940. If cdecl And cdecl.IsPrivate() And (Not cdecl.IsStruct() Or (cdecl.IsStruct() And Not cdecl.exposed)) Then
  5941. Continue
  5942. End If
  5943. If cdecl And Not cdecl.declImported
  5944. EmitIfcClassDecl(cdecl)
  5945. EndIf
  5946. Next
  5947. ' functions
  5948. For Local decl:TDecl=EachIn app.Semanted()
  5949. If decl.IsPrivate() Continue
  5950. Local fdecl:TFuncDecl=TFuncDecl( decl )
  5951. If fdecl And fdecl <> app.mainFunc And Not fdecl.declImported Then
  5952. EmitIfcFuncDecl(fdecl)
  5953. End If
  5954. Next
  5955. ' globals
  5956. For Local decl:TDecl=EachIn app.Semanted()
  5957. If decl.IsPrivate() Continue
  5958. Local gdecl:TGlobalDecl=TGlobalDecl( decl )
  5959. If gdecl And Not gdecl.declImported
  5960. EmitIfcGlobalDecl(gdecl)
  5961. End If
  5962. Next
  5963. ' enums
  5964. For Local decl:TDecl=EachIn app.Semanted()
  5965. If decl.IsPrivate() Continue
  5966. Local edecl:TEnumDecl=TEnumDecl( decl )
  5967. If edecl And Not edecl.declImported
  5968. EmitIfcEnumDecl(edecl)
  5969. End If
  5970. Next
  5971. End Method
  5972. Method TransDef(app:TAppDecl)
  5973. SetOutput("def")
  5974. Emit "LIBRARY " + StripExt(StripDir(opt_filepath))
  5975. Emit "EXPORTS"
  5976. For Local decl:TFuncDecl=EachIn app.exportDefs
  5977. Emit "~t" + TransExportDef(decl, opt_arch = "x86")
  5978. Next
  5979. Emit "~n"
  5980. End Method
  5981. Method TransApp( app:TAppDecl )
  5982. If app.mainModule.IsSuperStrict()
  5983. opt_issuperstrict = True
  5984. End If
  5985. TransHeader(app)
  5986. TransSource(app)
  5987. TransInterface(app)
  5988. If opt_makelib Then
  5989. If opt_def And opt_apptype Then
  5990. TransDef(app)
  5991. End If
  5992. End If
  5993. End Method
  5994. End Type