ctranslator.bmx 167 KB

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