ctranslator.bmx 184 KB

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