ctranslator.bmx 205 KB

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