mojoshader_compiler.c 236 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296
  1. /**
  2. * MojoShader; generate shader programs from bytecode of compiled
  3. * Direct3D shaders.
  4. *
  5. * Please see the file LICENSE.txt in the source's root directory.
  6. *
  7. * This file written by Ryan C. Gordon.
  8. */
  9. // !!! FIXME: this needs to be split into separate source files:
  10. // !!! FIXME: parse, AST, IR, etc. The problem is we need to deal with the
  11. // !!! FIXME: "Context" struct being passed around everywhere.
  12. #define __MOJOSHADER_INTERNAL__ 1
  13. #include "mojoshader_internal.h"
  14. #if DEBUG_COMPILER_PARSER
  15. #define LEMON_SUPPORT_TRACING 1
  16. #endif
  17. // !!! FIXME: I'd like to lose this. It's really inefficient. Just keep a
  18. // !!! FIXME: (tail) on these list structures instead?
  19. #define REVERSE_LINKED_LIST(typ, head) { \
  20. if ((head) && (head->next)) { \
  21. typ *tmp = NULL; \
  22. typ *tmp1 = NULL; \
  23. while (head != NULL) { \
  24. tmp = head; \
  25. head = head->next; \
  26. tmp->next = tmp1; \
  27. tmp1 = tmp; \
  28. } \
  29. head = tmp; \
  30. } \
  31. }
  32. static inline int operator_is_unary(const MOJOSHADER_astNodeType op)
  33. {
  34. return ( (op > MOJOSHADER_AST_OP_START_RANGE_UNARY) &&
  35. (op < MOJOSHADER_AST_OP_END_RANGE_UNARY) );
  36. } // operator_is_unary
  37. static inline int operator_is_binary(const MOJOSHADER_astNodeType op)
  38. {
  39. return ( (op > MOJOSHADER_AST_OP_START_RANGE_BINARY) &&
  40. (op < MOJOSHADER_AST_OP_END_RANGE_BINARY) );
  41. } // operator_is_binary
  42. static inline int operator_is_ternary(const MOJOSHADER_astNodeType op)
  43. {
  44. return ( (op > MOJOSHADER_AST_OP_START_RANGE_TERNARY) &&
  45. (op < MOJOSHADER_AST_OP_END_RANGE_TERNARY) );
  46. } // operator_is_ternary
  47. typedef union TokenData
  48. {
  49. int64 i64;
  50. double dbl;
  51. const char *string;
  52. const MOJOSHADER_astDataType *datatype;
  53. } TokenData;
  54. // This tracks data types and variables, and notes when they enter/leave scope.
  55. typedef struct SymbolScope
  56. {
  57. const char *symbol;
  58. const MOJOSHADER_astDataType *datatype;
  59. int index; // unique positive value within a function, negative if global.
  60. int referenced; // non-zero if something looked for this symbol (so we know it's used).
  61. struct SymbolScope *next;
  62. } SymbolScope;
  63. typedef struct SymbolMap
  64. {
  65. HashTable *hash;
  66. SymbolScope *scope;
  67. } SymbolMap;
  68. typedef struct LoopLabels
  69. {
  70. int start; // loop's start label during IR build.
  71. int end; // loop's end label during IR build.
  72. struct LoopLabels *prev;
  73. } LoopLabels;
  74. // Compile state, passed around all over the place.
  75. typedef struct Context
  76. {
  77. int isfail;
  78. int out_of_memory;
  79. MOJOSHADER_malloc malloc;
  80. MOJOSHADER_free free;
  81. void *malloc_data;
  82. ErrorList *errors;
  83. ErrorList *warnings;
  84. StringCache *strcache;
  85. const char *sourcefile; // current source file that we're parsing.
  86. unsigned int sourceline; // current line in sourcefile that we're parsing.
  87. SymbolMap usertypes;
  88. SymbolMap variables;
  89. MOJOSHADER_astNode *ast; // Abstract Syntax Tree
  90. const char *source_profile;
  91. int is_func_scope; // non-zero if semantic analysis is in function scope.
  92. int loop_count;
  93. int switch_count;
  94. int var_index; // next variable index for current function.
  95. int global_var_index; // next variable index for global scope.
  96. int user_func_index; // next function index for user-defined functions.
  97. int intrinsic_func_index; // next function index for intrinsic functions.
  98. MOJOSHADER_irStatement **ir; // intermediate representation.
  99. int ir_label_count; // next unused IR label index.
  100. int ir_temp_count; // next unused IR temporary value index.
  101. int ir_end; // current function's end label during IR build.
  102. int ir_ret; // temp that holds current function's retval during IR build.
  103. LoopLabels *ir_loop; // nested loop boundary labels during IR build.
  104. // Cache intrinsic types for fast lookup and consistent pointer values.
  105. MOJOSHADER_astDataType dt_none;
  106. MOJOSHADER_astDataType dt_bool;
  107. MOJOSHADER_astDataType dt_int;
  108. MOJOSHADER_astDataType dt_uint;
  109. MOJOSHADER_astDataType dt_float;
  110. MOJOSHADER_astDataType dt_float_snorm;
  111. MOJOSHADER_astDataType dt_float_unorm;
  112. MOJOSHADER_astDataType dt_half;
  113. MOJOSHADER_astDataType dt_double;
  114. MOJOSHADER_astDataType dt_string;
  115. MOJOSHADER_astDataType dt_sampler1d;
  116. MOJOSHADER_astDataType dt_sampler2d;
  117. MOJOSHADER_astDataType dt_sampler3d;
  118. MOJOSHADER_astDataType dt_samplercube;
  119. MOJOSHADER_astDataType dt_samplerstate;
  120. MOJOSHADER_astDataType dt_samplercompstate;
  121. MOJOSHADER_astDataType dt_buf_bool;
  122. MOJOSHADER_astDataType dt_buf_int;
  123. MOJOSHADER_astDataType dt_buf_uint;
  124. MOJOSHADER_astDataType dt_buf_half;
  125. MOJOSHADER_astDataType dt_buf_float;
  126. MOJOSHADER_astDataType dt_buf_double;
  127. MOJOSHADER_astDataType dt_buf_float_snorm;
  128. MOJOSHADER_astDataType dt_buf_float_unorm;
  129. Buffer *garbage; // this is sort of hacky.
  130. } Context;
  131. // !!! FIXME: cut and paste between every damned source file follows...
  132. // !!! FIXME: We need to make some sort of ContextBase that applies to all
  133. // !!! FIXME: files and move this stuff to mojoshader_common.c ...
  134. // Convenience functions for allocators...
  135. static inline void out_of_memory(Context *ctx)
  136. {
  137. ctx->isfail = ctx->out_of_memory = 1;
  138. } // out_of_memory
  139. static inline void *Malloc(Context *ctx, const size_t len)
  140. {
  141. void *retval = ctx->malloc((int) len, ctx->malloc_data);
  142. if (retval == NULL)
  143. out_of_memory(ctx);
  144. return retval;
  145. } // Malloc
  146. static inline char *StrDup(Context *ctx, const char *str)
  147. {
  148. char *retval = (char *) Malloc(ctx, strlen(str) + 1);
  149. if (retval != NULL)
  150. strcpy(retval, str);
  151. return retval;
  152. } // StrDup
  153. static inline void Free(Context *ctx, void *ptr)
  154. {
  155. ctx->free(ptr, ctx->malloc_data);
  156. } // Free
  157. static void *MallocBridge(int bytes, void *data)
  158. {
  159. return Malloc((Context *) data, (size_t) bytes);
  160. } // MallocBridge
  161. static void FreeBridge(void *ptr, void *data)
  162. {
  163. Free((Context *) data, ptr);
  164. } // FreeBridge
  165. static void failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
  166. static void failf(Context *ctx, const char *fmt, ...)
  167. {
  168. ctx->isfail = 1;
  169. if (ctx->out_of_memory)
  170. return;
  171. va_list ap;
  172. va_start(ap, fmt);
  173. errorlist_add_va(ctx->errors, ctx->sourcefile, ctx->sourceline, fmt, ap);
  174. va_end(ap);
  175. } // failf
  176. static inline void fail(Context *ctx, const char *reason)
  177. {
  178. failf(ctx, "%s", reason);
  179. } // fail
  180. static void warnf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
  181. static void warnf(Context *ctx, const char *fmt, ...)
  182. {
  183. if (ctx->out_of_memory)
  184. return;
  185. va_list ap;
  186. va_start(ap, fmt);
  187. errorlist_add_va(ctx->warnings, ctx->sourcefile, ctx->sourceline, fmt, ap);
  188. va_end(ap);
  189. } // warnf
  190. static inline void warn(Context *ctx, const char *reason)
  191. {
  192. warnf(ctx, "%s", reason);
  193. } // warn
  194. static inline int isfail(const Context *ctx)
  195. {
  196. return ctx->isfail;
  197. } // isfail
  198. static void symbolmap_nuke(const void *k, const void *v, void *d) {/*no-op*/}
  199. static int create_symbolmap(Context *ctx, SymbolMap *map)
  200. {
  201. // !!! FIXME: should compare string pointer, with string in cache.
  202. map->scope = NULL;
  203. map->hash = hash_create(ctx, hash_hash_string, hash_keymatch_string,
  204. symbolmap_nuke, 1, MallocBridge, FreeBridge, ctx);
  205. return (map->hash != NULL);
  206. } // create_symbolmap
  207. static int datatypes_match(const MOJOSHADER_astDataType *a,
  208. const MOJOSHADER_astDataType *b)
  209. {
  210. int i;
  211. if (a == b)
  212. return 1;
  213. else if (a->type != b->type)
  214. return 0;
  215. switch (a->type)
  216. {
  217. case MOJOSHADER_AST_DATATYPE_STRUCT:
  218. if (a->structure.member_count != b->structure.member_count)
  219. return 0;
  220. for (i = 0; i < a->structure.member_count; i++)
  221. {
  222. if (!datatypes_match(a->structure.members[i].datatype,
  223. b->structure.members[i].datatype))
  224. return 0;
  225. // stringcache'd, pointer compare is safe.
  226. else if (a->structure.members[i].identifier !=
  227. b->structure.members[i].identifier)
  228. return 0;
  229. } // for
  230. return 1;
  231. case MOJOSHADER_AST_DATATYPE_ARRAY:
  232. if (a->array.elements != b->array.elements)
  233. return 0;
  234. else if (!datatypes_match(a->array.base, b->array.base))
  235. return 0;
  236. return 1;
  237. case MOJOSHADER_AST_DATATYPE_VECTOR:
  238. if (a->vector.elements != b->vector.elements)
  239. return 0;
  240. else if (!datatypes_match(a->vector.base, b->vector.base))
  241. return 0;
  242. return 1;
  243. case MOJOSHADER_AST_DATATYPE_MATRIX:
  244. if (a->matrix.rows != b->matrix.rows)
  245. return 0;
  246. else if (a->matrix.columns != b->matrix.columns)
  247. return 0;
  248. else if (!datatypes_match(a->matrix.base, b->matrix.base))
  249. return 0;
  250. return 1;
  251. case MOJOSHADER_AST_DATATYPE_BUFFER:
  252. return datatypes_match(a->buffer.base, b->buffer.base);
  253. case MOJOSHADER_AST_DATATYPE_FUNCTION:
  254. if (a->function.num_params != b->function.num_params)
  255. return 0;
  256. else if (a->function.intrinsic != b->function.intrinsic)
  257. return 0;
  258. else if (!datatypes_match(a->function.retval, b->function.retval))
  259. return 0;
  260. for (i = 0; i < a->function.num_params; i++)
  261. {
  262. if (!datatypes_match(a->function.params[i], b->function.params[i]))
  263. return 0;
  264. } // for
  265. return 1;
  266. case MOJOSHADER_AST_DATATYPE_USER:
  267. return 0; // pointers must match, this clearly didn't.
  268. default:
  269. assert(0 && "unexpected case");
  270. return 0;
  271. } // switch
  272. return 0;
  273. } // datatypes_match
  274. static void push_symbol(Context *ctx, SymbolMap *map, const char *sym,
  275. const MOJOSHADER_astDataType *dt, const int index,
  276. const int check_dupes)
  277. {
  278. if (ctx->out_of_memory)
  279. return;
  280. // Decide if this symbol is defined, and if it's in the current scope.
  281. SymbolScope *item = NULL;
  282. const void *value = NULL;
  283. if ((check_dupes) && (sym != NULL) && (hash_find(map->hash, sym, &value)))
  284. {
  285. // check the current scope for a dupe.
  286. // !!! FIXME: note current scope's starting index, see if found
  287. // !!! FIXME: item is < index (and thus, a previous scope).
  288. item = map->scope;
  289. while ((item) && (item->symbol))
  290. {
  291. if ( ((const void *) item) == value )
  292. {
  293. failf(ctx, "Symbol '%s' already defined", sym);
  294. return;
  295. } // if
  296. item = item->next;
  297. } // while
  298. } // if
  299. // Add the symbol to our map and scope stack.
  300. item = (SymbolScope *) Malloc(ctx, sizeof (SymbolScope));
  301. if (item == NULL)
  302. return;
  303. if (sym != NULL) // sym can be NULL if we're pushing a new scope.
  304. {
  305. if (hash_insert(map->hash, sym, item) == -1)
  306. {
  307. Free(ctx, item);
  308. return;
  309. } // if
  310. } // if
  311. item->symbol = sym; // cached strings, don't copy.
  312. item->index = index;
  313. item->datatype = dt;
  314. item->referenced = 0;
  315. item->next = map->scope;
  316. map->scope = item;
  317. } // push_symbol
  318. static void push_usertype(Context *ctx, const char *sym, const MOJOSHADER_astDataType *dt)
  319. {
  320. if (sym != NULL)
  321. {
  322. MOJOSHADER_astDataType *userdt;
  323. userdt = (MOJOSHADER_astDataType *) Malloc(ctx, sizeof (*userdt));
  324. if (userdt != NULL)
  325. {
  326. // !!! FIXME: this is hacky.
  327. if (!buffer_append(ctx->garbage, &userdt, sizeof (userdt)))
  328. {
  329. Free(ctx, userdt);
  330. return;
  331. } // if
  332. userdt->type = MOJOSHADER_AST_DATATYPE_USER;
  333. userdt->user.details = dt;
  334. userdt->user.name = sym;
  335. dt = userdt;
  336. } // if
  337. } // if
  338. push_symbol(ctx, &ctx->usertypes, sym, dt, 0, 1);
  339. } // push_usertype
  340. static inline void push_variable(Context *ctx, const char *sym, const MOJOSHADER_astDataType *dt)
  341. {
  342. int idx = 0;
  343. if (sym != NULL)
  344. {
  345. // leave space for individual member indexes. The IR will need this.
  346. int additional = 0;
  347. if (dt->type == MOJOSHADER_AST_DATATYPE_STRUCT)
  348. additional = dt->structure.member_count;
  349. if (ctx->is_func_scope)
  350. {
  351. idx = ++ctx->var_index; // these are positive.
  352. ctx->var_index += additional;
  353. } // if
  354. else
  355. {
  356. idx = --ctx->global_var_index; // these are negative.
  357. ctx->global_var_index -= additional;
  358. } // else
  359. } // if
  360. push_symbol(ctx, &ctx->variables, sym, dt, idx, 1);
  361. } // push_variable
  362. static int push_function(Context *ctx, const char *sym,
  363. const MOJOSHADER_astDataType *dt,
  364. const int just_declare)
  365. {
  366. // we don't have any reason to support nested functions at the moment,
  367. // so this would be a bug.
  368. assert(!ctx->is_func_scope);
  369. assert(dt->type == MOJOSHADER_AST_DATATYPE_FUNCTION);
  370. // Functions are always global, so no need to search scopes.
  371. // Functions overload, though, so we have to continue iterating to
  372. // see if it matches anything.
  373. const void *value = NULL;
  374. void *iter = NULL;
  375. while (hash_iter(ctx->variables.hash, sym, &value, &iter))
  376. {
  377. // !!! FIXME: this breaks if you predeclare a function.
  378. // !!! FIXME: (a declare AFTER defining works, though.)
  379. // there's already something called this.
  380. SymbolScope *item = (SymbolScope *) value;
  381. if (datatypes_match(dt, item->datatype))
  382. {
  383. if (!just_declare)
  384. failf(ctx, "Function '%s' already defined.", sym);
  385. return item->index;
  386. } // if
  387. } // while
  388. int idx = 0;
  389. if ((sym != NULL) && (dt != NULL))
  390. {
  391. if (!dt->function.intrinsic)
  392. idx = ++ctx->user_func_index; // these are positive.
  393. else
  394. idx = --ctx->intrinsic_func_index; // these are negative.
  395. } // if
  396. // push_symbol() doesn't check dupes, because we just did.
  397. push_symbol(ctx, &ctx->variables, sym, dt, idx, 0);
  398. return idx;
  399. } // push_function
  400. static inline void push_scope(Context *ctx)
  401. {
  402. push_usertype(ctx, NULL, NULL);
  403. push_variable(ctx, NULL, NULL);
  404. } // push_scope
  405. static void pop_symbol(Context *ctx, SymbolMap *map)
  406. {
  407. SymbolScope *item = map->scope;
  408. if (!item)
  409. return;
  410. if (item->symbol)
  411. hash_remove(map->hash, item->symbol);
  412. map->scope = item->next;
  413. Free(ctx, item);
  414. } // pop_symbol
  415. static void pop_symbol_scope(Context *ctx, SymbolMap *map)
  416. {
  417. while ((map->scope) && (map->scope->symbol))
  418. pop_symbol(ctx, map);
  419. assert(map->scope != NULL);
  420. assert(map->scope->symbol == NULL);
  421. pop_symbol(ctx, map);
  422. } // pop_symbol_scope
  423. static inline void pop_scope(Context *ctx)
  424. {
  425. pop_symbol_scope(ctx, &ctx->usertypes);
  426. pop_symbol_scope(ctx, &ctx->variables);
  427. } // push_scope
  428. static const MOJOSHADER_astDataType *find_symbol(Context *ctx, SymbolMap *map, const char *sym, int *_index)
  429. {
  430. const void *_item = NULL;
  431. hash_find(map->hash, sym, &_item);
  432. SymbolScope *item = (SymbolScope *) _item;
  433. if (item != NULL)
  434. {
  435. item->referenced++;
  436. if (_index != NULL)
  437. *_index = item->index;
  438. } // if
  439. return item ? item->datatype : NULL;
  440. } // find_symbol
  441. static inline const MOJOSHADER_astDataType *find_usertype(Context *ctx, const char *sym)
  442. {
  443. return find_symbol(ctx, &ctx->usertypes, sym, NULL);
  444. } // find_usertype
  445. static inline const MOJOSHADER_astDataType *find_variable(Context *ctx, const char *sym, int *_index)
  446. {
  447. return find_symbol(ctx, &ctx->variables, sym, _index);
  448. } // find_variable
  449. static void destroy_symbolmap(Context *ctx, SymbolMap *map)
  450. {
  451. while (map->scope)
  452. pop_symbol(ctx, map);
  453. hash_destroy(map->hash);
  454. } // destroy_symbolmap
  455. static const MOJOSHADER_astDataType *new_datatype_vector(Context *ctx,
  456. const MOJOSHADER_astDataType *dt,
  457. const int columns)
  458. {
  459. MOJOSHADER_astDataType *retval;
  460. retval = (MOJOSHADER_astDataType *) Malloc(ctx, sizeof (*retval));
  461. if (retval == NULL)
  462. return NULL;
  463. // !!! FIXME: this is hacky.
  464. // !!! FIXME: I'd like to cache these anyhow and reuse types.
  465. if (!buffer_append(ctx->garbage, &retval, sizeof (retval)))
  466. {
  467. Free(ctx, retval);
  468. return NULL;
  469. } // if
  470. if ((columns < 1) || (columns > 4))
  471. fail(ctx, "Vector must have between 1 and 4 elements");
  472. retval->type = MOJOSHADER_AST_DATATYPE_VECTOR;
  473. retval->vector.base = dt;
  474. retval->vector.elements = columns;
  475. return retval;
  476. } // new_datatype_vector
  477. static const MOJOSHADER_astDataType *new_datatype_matrix(Context *ctx,
  478. const MOJOSHADER_astDataType *dt,
  479. const int rows, const int columns)
  480. {
  481. MOJOSHADER_astDataType *retval;
  482. // !!! FIXME: allocate enough for a matrix, but we need to cleanup things that copy without checking for subsize.
  483. retval = (MOJOSHADER_astDataType *) Malloc(ctx, sizeof (*retval));
  484. if (retval == NULL)
  485. return NULL;
  486. // !!! FIXME: this is hacky.
  487. // !!! FIXME: I'd like to cache these anyhow and reuse types.
  488. if (!buffer_append(ctx->garbage, &retval, sizeof (retval)))
  489. {
  490. Free(ctx, retval);
  491. return NULL;
  492. } // if
  493. if ((rows < 1) || (rows > 4))
  494. fail(ctx, "Matrix must have between 1 and 4 rows");
  495. if ((columns < 1) || (columns > 4))
  496. fail(ctx, "Matrix must have between 1 and 4 columns");
  497. retval->type = MOJOSHADER_AST_DATATYPE_MATRIX;
  498. retval->matrix.base = dt;
  499. retval->matrix.rows = rows;
  500. retval->matrix.columns = columns;
  501. return retval;
  502. } // new_datatype_matrix
  503. // !!! FIXME: move this to mojoshader_ast.c
  504. // !!! FIXME: new_* and delete_* should take an allocator, not a context.
  505. // These functions are mostly for construction and cleanup of nodes in the
  506. // parse tree. Mostly this is simple allocation and initialization, so we
  507. // can do as little in the lemon code as possible, and then sort it all out
  508. // afterwards.
  509. #define NEW_AST_NODE(retval, cls, typ) \
  510. cls *retval = (cls *) Malloc(ctx, sizeof (cls)); \
  511. do { \
  512. if (retval == NULL) { return NULL; } \
  513. retval->ast.type = typ; \
  514. retval->ast.filename = ctx->sourcefile; \
  515. retval->ast.line = ctx->sourceline; \
  516. } while (0)
  517. #define DELETE_AST_NODE(cls) do { \
  518. if (!cls) return; \
  519. } while (0)
  520. static void delete_compilation_unit(Context*, MOJOSHADER_astCompilationUnit*);
  521. static void delete_statement(Context *ctx, MOJOSHADER_astStatement *stmt);
  522. static MOJOSHADER_astExpression *new_identifier_expr(Context *ctx,
  523. const char *string)
  524. {
  525. NEW_AST_NODE(retval, MOJOSHADER_astExpressionIdentifier,
  526. MOJOSHADER_AST_OP_IDENTIFIER);
  527. retval->datatype = NULL;
  528. retval->identifier = string; // cached; don't copy string.
  529. retval->index = 0;
  530. return (MOJOSHADER_astExpression *) retval;
  531. } // new_identifier_expr
  532. static MOJOSHADER_astExpression *new_callfunc_expr(Context *ctx,
  533. const char *identifier,
  534. MOJOSHADER_astArguments *args)
  535. {
  536. NEW_AST_NODE(retval, MOJOSHADER_astExpressionCallFunction,
  537. MOJOSHADER_AST_OP_CALLFUNC);
  538. MOJOSHADER_astExpression *expr = new_identifier_expr(ctx, identifier);
  539. retval->datatype = NULL;
  540. retval->identifier = (MOJOSHADER_astExpressionIdentifier *) expr;
  541. retval->args = args;
  542. return (MOJOSHADER_astExpression *) retval;
  543. } // new_callfunc_expr
  544. static MOJOSHADER_astExpression *new_constructor_expr(Context *ctx,
  545. const MOJOSHADER_astDataType *dt,
  546. MOJOSHADER_astArguments *args)
  547. {
  548. NEW_AST_NODE(retval, MOJOSHADER_astExpressionConstructor,
  549. MOJOSHADER_AST_OP_CONSTRUCTOR);
  550. retval->datatype = dt;
  551. retval->args = args;
  552. return (MOJOSHADER_astExpression *) retval;
  553. } // new_constructor_expr
  554. static MOJOSHADER_astExpression *new_cast_expr(Context *ctx,
  555. const MOJOSHADER_astDataType *dt,
  556. MOJOSHADER_astExpression *operand)
  557. {
  558. NEW_AST_NODE(retval, MOJOSHADER_astExpressionCast, MOJOSHADER_AST_OP_CAST);
  559. retval->datatype = dt;
  560. retval->operand = operand;
  561. return (MOJOSHADER_astExpression *) retval;
  562. } // new_cast_expr
  563. static MOJOSHADER_astExpression *new_unary_expr(Context *ctx,
  564. const MOJOSHADER_astNodeType op,
  565. MOJOSHADER_astExpression *operand)
  566. {
  567. NEW_AST_NODE(retval, MOJOSHADER_astExpressionUnary, op);
  568. assert(operator_is_unary(op));
  569. retval->datatype = NULL;
  570. retval->operand = operand;
  571. return (MOJOSHADER_astExpression *) retval;
  572. } // new_unary_expr
  573. static MOJOSHADER_astExpression *new_binary_expr(Context *ctx,
  574. const MOJOSHADER_astNodeType op,
  575. MOJOSHADER_astExpression *left,
  576. MOJOSHADER_astExpression *right)
  577. {
  578. NEW_AST_NODE(retval, MOJOSHADER_astExpressionBinary, op);
  579. assert(operator_is_binary(op));
  580. retval->datatype = NULL;
  581. retval->left = left;
  582. retval->right = right;
  583. return (MOJOSHADER_astExpression *) retval;
  584. } // new_binary_expr
  585. static MOJOSHADER_astExpression *new_ternary_expr(Context *ctx,
  586. const MOJOSHADER_astNodeType op,
  587. MOJOSHADER_astExpression *left,
  588. MOJOSHADER_astExpression *center,
  589. MOJOSHADER_astExpression *right)
  590. {
  591. NEW_AST_NODE(retval, MOJOSHADER_astExpressionTernary, op);
  592. assert(operator_is_ternary(op));
  593. assert(op == MOJOSHADER_AST_OP_CONDITIONAL);
  594. retval->datatype = &ctx->dt_bool;
  595. retval->left = left;
  596. retval->center = center;
  597. retval->right = right;
  598. return (MOJOSHADER_astExpression *) retval;
  599. } // new_ternary_expr
  600. static MOJOSHADER_astExpression *new_deref_struct_expr(Context *ctx,
  601. MOJOSHADER_astExpression *identifier,
  602. const char *member)
  603. {
  604. NEW_AST_NODE(retval, MOJOSHADER_astExpressionDerefStruct,
  605. MOJOSHADER_AST_OP_DEREF_STRUCT);
  606. retval->datatype = NULL;
  607. retval->identifier = identifier;
  608. retval->member = member; // cached; don't copy string.
  609. retval->isswizzle = 0; // may change during semantic analysis.
  610. retval->member_index = 0; // set during semantic analysis.
  611. return (MOJOSHADER_astExpression *) retval;
  612. } // new_deref_struct_expr
  613. static MOJOSHADER_astExpression *new_literal_int_expr(Context *ctx,
  614. const int value)
  615. {
  616. NEW_AST_NODE(retval, MOJOSHADER_astExpressionIntLiteral,
  617. MOJOSHADER_AST_OP_INT_LITERAL);
  618. retval->datatype = &ctx->dt_int;
  619. retval->value = value;
  620. return (MOJOSHADER_astExpression *) retval;
  621. } // new_literal_int_expr
  622. static MOJOSHADER_astExpression *new_literal_float_expr(Context *ctx,
  623. const double dbl)
  624. {
  625. NEW_AST_NODE(retval, MOJOSHADER_astExpressionFloatLiteral,
  626. MOJOSHADER_AST_OP_FLOAT_LITERAL);
  627. retval->datatype = &ctx->dt_float;
  628. retval->value = dbl;
  629. return (MOJOSHADER_astExpression *) retval;
  630. } // new_literal_float_expr
  631. static MOJOSHADER_astExpression *new_literal_string_expr(Context *ctx,
  632. const char *string)
  633. {
  634. NEW_AST_NODE(retval, MOJOSHADER_astExpressionStringLiteral,
  635. MOJOSHADER_AST_OP_STRING_LITERAL);
  636. retval->datatype = &ctx->dt_string;
  637. retval->string = string; // cached; don't copy string.
  638. return (MOJOSHADER_astExpression *) retval;
  639. } // new_literal_string_expr
  640. static MOJOSHADER_astExpression *new_literal_boolean_expr(Context *ctx,
  641. const int value)
  642. {
  643. NEW_AST_NODE(retval, MOJOSHADER_astExpressionBooleanLiteral,
  644. MOJOSHADER_AST_OP_BOOLEAN_LITERAL);
  645. retval->datatype = &ctx->dt_bool;
  646. retval->value = value;
  647. return (MOJOSHADER_astExpression *) retval;
  648. } // new_literal_boolean_expr
  649. static void delete_arguments(Context *ctx, MOJOSHADER_astArguments *args);
  650. static void delete_expr(Context *ctx, MOJOSHADER_astExpression *_expr)
  651. {
  652. MOJOSHADER_astNode *expr = (MOJOSHADER_astNode *) _expr;
  653. DELETE_AST_NODE(expr);
  654. if (expr->ast.type == MOJOSHADER_AST_OP_CAST)
  655. delete_expr(ctx, expr->cast.operand);
  656. else if (expr->ast.type == MOJOSHADER_AST_OP_CONSTRUCTOR)
  657. delete_arguments(ctx, expr->constructor.args);
  658. else if (expr->ast.type == MOJOSHADER_AST_OP_DEREF_STRUCT)
  659. delete_expr(ctx, expr->derefstruct.identifier);
  660. else if (operator_is_unary(expr->ast.type))
  661. delete_expr(ctx, expr->unary.operand);
  662. else if (operator_is_binary(expr->ast.type))
  663. {
  664. delete_expr(ctx, expr->binary.left);
  665. delete_expr(ctx, expr->binary.right);
  666. } // else if
  667. else if (operator_is_ternary(expr->ast.type))
  668. {
  669. delete_expr(ctx, expr->ternary.left);
  670. delete_expr(ctx, expr->ternary.center);
  671. delete_expr(ctx, expr->ternary.right);
  672. } // else if
  673. else if (expr->ast.type == MOJOSHADER_AST_OP_CALLFUNC)
  674. {
  675. delete_expr(ctx, (MOJOSHADER_astExpression*)expr->callfunc.identifier);
  676. delete_arguments(ctx, expr->callfunc.args);
  677. } // else if
  678. // rest of operators don't have extra data to free.
  679. Free(ctx, expr);
  680. } // delete_expr
  681. static MOJOSHADER_astArguments *new_argument(Context *ctx,
  682. MOJOSHADER_astExpression *arg)
  683. {
  684. NEW_AST_NODE(retval, MOJOSHADER_astArguments, MOJOSHADER_AST_ARGUMENTS);
  685. retval->argument = arg;
  686. retval->next = NULL;
  687. return retval;
  688. } // new_argument
  689. static void delete_arguments(Context *ctx, MOJOSHADER_astArguments *args)
  690. {
  691. DELETE_AST_NODE(args);
  692. delete_arguments(ctx, args->next);
  693. delete_expr(ctx, args->argument);
  694. Free(ctx, args);
  695. } // delete_arguments
  696. static MOJOSHADER_astFunctionParameters *new_function_param(Context *ctx,
  697. const MOJOSHADER_astInputModifier inputmod,
  698. const MOJOSHADER_astDataType *dt,
  699. const char *identifier, const char *semantic,
  700. const MOJOSHADER_astInterpolationModifier interpmod,
  701. MOJOSHADER_astExpression *initializer)
  702. {
  703. NEW_AST_NODE(retval, MOJOSHADER_astFunctionParameters,
  704. MOJOSHADER_AST_FUNCTION_PARAMS);
  705. retval->datatype = dt;
  706. retval->input_modifier = inputmod;
  707. retval->identifier = identifier;
  708. retval->semantic = semantic;
  709. retval->interpolation_modifier = interpmod;
  710. retval->initializer = initializer;
  711. retval->next = NULL;
  712. return retval;
  713. } // new_function_param
  714. static void delete_function_params(Context *ctx,
  715. MOJOSHADER_astFunctionParameters *params)
  716. {
  717. DELETE_AST_NODE(params);
  718. delete_function_params(ctx, params->next);
  719. delete_expr(ctx, params->initializer);
  720. Free(ctx, params);
  721. } // delete_function_params
  722. static MOJOSHADER_astFunctionSignature *new_function_signature(Context *ctx,
  723. const MOJOSHADER_astDataType *dt,
  724. const char *identifier,
  725. MOJOSHADER_astFunctionParameters *params)
  726. {
  727. NEW_AST_NODE(retval, MOJOSHADER_astFunctionSignature,
  728. MOJOSHADER_AST_FUNCTION_SIGNATURE);
  729. retval->datatype = dt;
  730. retval->identifier = identifier;
  731. retval->params = params;
  732. retval->storage_class = MOJOSHADER_AST_FNSTORECLS_NONE;
  733. retval->semantic = NULL;
  734. return retval;
  735. } // new_function_signature
  736. static void delete_function_signature(Context *ctx,
  737. MOJOSHADER_astFunctionSignature *sig)
  738. {
  739. DELETE_AST_NODE(sig);
  740. delete_function_params(ctx, sig->params);
  741. Free(ctx, sig);
  742. } // delete_function_signature
  743. static MOJOSHADER_astCompilationUnit *new_function(Context *ctx,
  744. MOJOSHADER_astFunctionSignature *declaration,
  745. MOJOSHADER_astStatement *definition)
  746. {
  747. NEW_AST_NODE(retval, MOJOSHADER_astCompilationUnitFunction,
  748. MOJOSHADER_AST_COMPUNIT_FUNCTION);
  749. retval->next = NULL;
  750. retval->declaration = declaration;
  751. retval->definition = definition;
  752. retval->index = 0;
  753. return (MOJOSHADER_astCompilationUnit *) retval;
  754. } // new_function
  755. static void delete_function(Context *ctx,
  756. MOJOSHADER_astCompilationUnitFunction *unitfn)
  757. {
  758. DELETE_AST_NODE(unitfn);
  759. delete_compilation_unit(ctx, unitfn->next);
  760. delete_function_signature(ctx, unitfn->declaration);
  761. delete_statement(ctx, unitfn->definition);
  762. Free(ctx, unitfn);
  763. } // delete_function
  764. static MOJOSHADER_astScalarOrArray *new_scalar_or_array(Context *ctx,
  765. const char *ident, const int isvec,
  766. MOJOSHADER_astExpression *dim)
  767. {
  768. NEW_AST_NODE(retval, MOJOSHADER_astScalarOrArray,
  769. MOJOSHADER_AST_SCALAR_OR_ARRAY);
  770. retval->identifier = ident;
  771. retval->isarray = isvec;
  772. retval->dimension = dim;
  773. return retval;
  774. } // new_scalar_or_array
  775. static void delete_scalar_or_array(Context *ctx,MOJOSHADER_astScalarOrArray *s)
  776. {
  777. DELETE_AST_NODE(s);
  778. delete_expr(ctx, s->dimension);
  779. Free(ctx, s);
  780. } // delete_scalar_or_array
  781. static MOJOSHADER_astTypedef *new_typedef(Context *ctx, const int isconst,
  782. const MOJOSHADER_astDataType *dt,
  783. MOJOSHADER_astScalarOrArray *soa)
  784. {
  785. // we correct this datatype to the final version during semantic analysis.
  786. NEW_AST_NODE(retval, MOJOSHADER_astTypedef, MOJOSHADER_AST_TYPEDEF);
  787. retval->datatype = dt;
  788. retval->isconst = isconst;
  789. retval->details = soa;
  790. return retval;
  791. } // new_typedef
  792. static void delete_typedef(Context *ctx, MOJOSHADER_astTypedef *td)
  793. {
  794. DELETE_AST_NODE(td);
  795. delete_scalar_or_array(ctx, td->details);
  796. Free(ctx, td);
  797. } // delete_typedef
  798. static MOJOSHADER_astPackOffset *new_pack_offset(Context *ctx,
  799. const char *a, const char *b)
  800. {
  801. NEW_AST_NODE(retval, MOJOSHADER_astPackOffset, MOJOSHADER_AST_PACK_OFFSET);
  802. retval->ident1 = a;
  803. retval->ident2 = b;
  804. return retval;
  805. } // new_pack_offset
  806. static void delete_pack_offset(Context *ctx, MOJOSHADER_astPackOffset *o)
  807. {
  808. DELETE_AST_NODE(o);
  809. Free(ctx, o);
  810. } // delete_pack_offset
  811. static MOJOSHADER_astVariableLowLevel *new_variable_lowlevel(Context *ctx,
  812. MOJOSHADER_astPackOffset *po,
  813. const char *reg)
  814. {
  815. NEW_AST_NODE(retval, MOJOSHADER_astVariableLowLevel,
  816. MOJOSHADER_AST_VARIABLE_LOWLEVEL);
  817. retval->packoffset = po;
  818. retval->register_name = reg;
  819. return retval;
  820. } // new_variable_lowlevel
  821. static void delete_variable_lowlevel(Context *ctx,
  822. MOJOSHADER_astVariableLowLevel *vll)
  823. {
  824. DELETE_AST_NODE(vll);
  825. delete_pack_offset(ctx, vll->packoffset);
  826. Free(ctx, vll);
  827. } // delete_variable_lowlevel
  828. static MOJOSHADER_astAnnotations *new_annotation(Context *ctx,
  829. const MOJOSHADER_astDataType *dt,
  830. MOJOSHADER_astExpression *initializer)
  831. {
  832. NEW_AST_NODE(retval, MOJOSHADER_astAnnotations, MOJOSHADER_AST_ANNOTATION);
  833. retval->datatype = dt;
  834. retval->initializer = initializer;
  835. retval->next = NULL;
  836. return retval;
  837. } // new_annotation
  838. static void delete_annotation(Context *ctx, MOJOSHADER_astAnnotations *annos)
  839. {
  840. DELETE_AST_NODE(annos);
  841. delete_annotation(ctx, annos->next);
  842. delete_expr(ctx, annos->initializer);
  843. Free(ctx, annos);
  844. } // delete_annotation
  845. static MOJOSHADER_astVariableDeclaration *new_variable_declaration(
  846. Context *ctx, MOJOSHADER_astScalarOrArray *soa,
  847. const char *semantic,
  848. MOJOSHADER_astAnnotations *annotations,
  849. MOJOSHADER_astExpression *init,
  850. MOJOSHADER_astVariableLowLevel *vll)
  851. {
  852. NEW_AST_NODE(retval, MOJOSHADER_astVariableDeclaration,
  853. MOJOSHADER_AST_VARIABLE_DECLARATION);
  854. retval->datatype = NULL;
  855. retval->attributes = 0;
  856. retval->anonymous_datatype = NULL;
  857. retval->details = soa;
  858. retval->semantic = semantic;
  859. retval->annotations = annotations;
  860. retval->initializer = init;
  861. retval->lowlevel = vll;
  862. retval->next = NULL;
  863. return retval;
  864. } // new_variable_declaration
  865. static void delete_variable_declaration(Context *ctx,
  866. MOJOSHADER_astVariableDeclaration *dcl)
  867. {
  868. DELETE_AST_NODE(dcl);
  869. delete_variable_declaration(ctx, dcl->next);
  870. delete_scalar_or_array(ctx, dcl->details);
  871. delete_annotation(ctx, dcl->annotations);
  872. delete_expr(ctx, dcl->initializer);
  873. delete_variable_lowlevel(ctx, dcl->lowlevel);
  874. Free(ctx, dcl);
  875. } // delete_variable_declaration
  876. static MOJOSHADER_astCompilationUnit *new_global_variable(Context *ctx,
  877. MOJOSHADER_astVariableDeclaration *decl)
  878. {
  879. NEW_AST_NODE(retval, MOJOSHADER_astCompilationUnitVariable,
  880. MOJOSHADER_AST_COMPUNIT_VARIABLE);
  881. retval->next = NULL;
  882. retval->declaration = decl;
  883. return (MOJOSHADER_astCompilationUnit *) retval;
  884. } // new_global_variable
  885. static void delete_global_variable(Context *ctx,
  886. MOJOSHADER_astCompilationUnitVariable *var)
  887. {
  888. DELETE_AST_NODE(var);
  889. delete_compilation_unit(ctx, var->next);
  890. delete_variable_declaration(ctx, var->declaration);
  891. Free(ctx, var);
  892. } // delete_global_variable
  893. static MOJOSHADER_astCompilationUnit *new_global_typedef(Context *ctx,
  894. MOJOSHADER_astTypedef *td)
  895. {
  896. NEW_AST_NODE(retval, MOJOSHADER_astCompilationUnitTypedef,
  897. MOJOSHADER_AST_COMPUNIT_TYPEDEF);
  898. retval->next = NULL;
  899. retval->type_info = td;
  900. return (MOJOSHADER_astCompilationUnit *) retval;
  901. } // new_global_typedef
  902. static void delete_global_typedef(Context *ctx,
  903. MOJOSHADER_astCompilationUnitTypedef *unit)
  904. {
  905. DELETE_AST_NODE(unit);
  906. delete_compilation_unit(ctx, unit->next);
  907. delete_typedef(ctx, unit->type_info);
  908. Free(ctx, unit);
  909. } // delete_global_typedef
  910. static MOJOSHADER_astStructMembers *new_struct_member(Context *ctx,
  911. MOJOSHADER_astScalarOrArray *soa,
  912. const char *semantic)
  913. {
  914. NEW_AST_NODE(retval, MOJOSHADER_astStructMembers,
  915. MOJOSHADER_AST_STRUCT_MEMBER);
  916. retval->datatype = NULL;
  917. retval->semantic = semantic;
  918. retval->details = soa;
  919. retval->interpolation_mod = MOJOSHADER_AST_INTERPMOD_NONE;
  920. retval->next = NULL;
  921. return retval;
  922. } // new_struct_member
  923. static void delete_struct_member(Context *ctx,
  924. MOJOSHADER_astStructMembers *member)
  925. {
  926. DELETE_AST_NODE(member);
  927. delete_struct_member(ctx, member->next);
  928. delete_scalar_or_array(ctx, member->details);
  929. Free(ctx, member);
  930. } // delete_struct_member
  931. static MOJOSHADER_astStructDeclaration *new_struct_declaration(Context *ctx,
  932. const char *name,
  933. MOJOSHADER_astStructMembers *members)
  934. {
  935. NEW_AST_NODE(retval, MOJOSHADER_astStructDeclaration,
  936. MOJOSHADER_AST_STRUCT_DECLARATION);
  937. retval->datatype = NULL;
  938. retval->name = name;
  939. retval->members = members;
  940. return retval;
  941. } // new_struct_declaration
  942. static void delete_struct_declaration(Context *ctx,
  943. MOJOSHADER_astStructDeclaration *decl)
  944. {
  945. DELETE_AST_NODE(decl);
  946. delete_struct_member(ctx, decl->members);
  947. Free(ctx, decl);
  948. } // delete_struct_declaration
  949. static MOJOSHADER_astCompilationUnit *new_global_struct(Context *ctx,
  950. MOJOSHADER_astStructDeclaration *sd)
  951. {
  952. NEW_AST_NODE(retval, MOJOSHADER_astCompilationUnitStruct,
  953. MOJOSHADER_AST_COMPUNIT_STRUCT);
  954. retval->next = NULL;
  955. retval->struct_info = sd;
  956. return (MOJOSHADER_astCompilationUnit *) retval;
  957. } // new_global_struct
  958. static void delete_global_struct(Context *ctx,
  959. MOJOSHADER_astCompilationUnitStruct *unit)
  960. {
  961. DELETE_AST_NODE(unit);
  962. delete_compilation_unit(ctx, unit->next);
  963. delete_struct_declaration(ctx, unit->struct_info);
  964. Free(ctx, unit);
  965. } // delete_global_struct
  966. static void delete_compilation_unit(Context *ctx,
  967. MOJOSHADER_astCompilationUnit *unit)
  968. {
  969. if (!unit) return;
  970. // it's important to not recurse too deeply here, since you may have
  971. // thousands of items in this linked list (each line of a massive
  972. // function, for example). To avoid this, we iterate the list here,
  973. // deleting all children and making them think they have no reason
  974. // to recurse in their own delete methods.
  975. // Please note that everyone should _try_ to delete their "next" member,
  976. // just in case, but hopefully this cleaned it out.
  977. MOJOSHADER_astCompilationUnit *i = unit->next;
  978. unit->next = NULL;
  979. while (i)
  980. {
  981. MOJOSHADER_astCompilationUnit *next = i->next;
  982. i->next = NULL;
  983. delete_compilation_unit(ctx, i);
  984. i = next;
  985. } // while
  986. switch (unit->ast.type)
  987. {
  988. #define DELETE_UNIT(typ, cls, fn) \
  989. case MOJOSHADER_AST_COMPUNIT_##typ: delete_##fn(ctx, (cls *) unit); break;
  990. DELETE_UNIT(FUNCTION, MOJOSHADER_astCompilationUnitFunction, function);
  991. DELETE_UNIT(TYPEDEF, MOJOSHADER_astCompilationUnitTypedef, global_typedef);
  992. DELETE_UNIT(VARIABLE, MOJOSHADER_astCompilationUnitVariable, global_variable);
  993. DELETE_UNIT(STRUCT, MOJOSHADER_astCompilationUnitStruct, global_struct);
  994. #undef DELETE_UNIT
  995. default: assert(0 && "missing cleanup code"); break;
  996. } // switch
  997. // don't free (unit) here, the class-specific functions do it.
  998. } // delete_compilation_unit
  999. static MOJOSHADER_astStatement *new_typedef_statement(Context *ctx,
  1000. MOJOSHADER_astTypedef *td)
  1001. {
  1002. NEW_AST_NODE(retval, MOJOSHADER_astTypedefStatement,
  1003. MOJOSHADER_AST_STATEMENT_TYPEDEF);
  1004. retval->next = NULL;
  1005. retval->type_info = td;
  1006. return (MOJOSHADER_astStatement *) retval;
  1007. } // new_typedef_statement
  1008. static void delete_typedef_statement(Context *ctx,
  1009. MOJOSHADER_astTypedefStatement *stmt)
  1010. {
  1011. DELETE_AST_NODE(stmt);
  1012. delete_statement(ctx, stmt->next);
  1013. delete_typedef(ctx, stmt->type_info);
  1014. Free(ctx, stmt);
  1015. } // delete_typedef_statement
  1016. static MOJOSHADER_astStatement *new_return_statement(Context *ctx,
  1017. MOJOSHADER_astExpression *expr)
  1018. {
  1019. NEW_AST_NODE(retval, MOJOSHADER_astReturnStatement,
  1020. MOJOSHADER_AST_STATEMENT_RETURN);
  1021. retval->next = NULL;
  1022. retval->expr = expr;
  1023. return (MOJOSHADER_astStatement *) retval;
  1024. } // new_return_statement
  1025. static void delete_return_statement(Context *ctx,
  1026. MOJOSHADER_astReturnStatement *stmt)
  1027. {
  1028. DELETE_AST_NODE(stmt);
  1029. delete_statement(ctx, stmt->next);
  1030. delete_expr(ctx, stmt->expr);
  1031. Free(ctx, stmt);
  1032. } // delete_return_statement
  1033. static MOJOSHADER_astStatement *new_block_statement(Context *ctx,
  1034. MOJOSHADER_astStatement *stmts)
  1035. {
  1036. NEW_AST_NODE(retval, MOJOSHADER_astBlockStatement,
  1037. MOJOSHADER_AST_STATEMENT_BLOCK);
  1038. retval->next = NULL;
  1039. retval->statements = stmts;
  1040. return (MOJOSHADER_astStatement *) retval;
  1041. } // new_block_statement
  1042. static void delete_block_statement(Context *ctx,
  1043. MOJOSHADER_astBlockStatement *stmt)
  1044. {
  1045. DELETE_AST_NODE(stmt);
  1046. delete_statement(ctx, stmt->statements);
  1047. delete_statement(ctx, stmt->next);
  1048. Free(ctx, stmt);
  1049. } // delete_statement_block
  1050. static MOJOSHADER_astStatement *new_for_statement(Context *ctx,
  1051. MOJOSHADER_astVariableDeclaration *decl,
  1052. MOJOSHADER_astExpression *initializer,
  1053. MOJOSHADER_astExpression *looptest,
  1054. MOJOSHADER_astExpression *counter,
  1055. MOJOSHADER_astStatement *statement)
  1056. {
  1057. NEW_AST_NODE(retval, MOJOSHADER_astForStatement,
  1058. MOJOSHADER_AST_STATEMENT_FOR);
  1059. retval->next = NULL;
  1060. retval->unroll = -1;
  1061. retval->var_decl = decl;
  1062. retval->initializer = initializer;
  1063. retval->looptest = looptest;
  1064. retval->counter = counter;
  1065. retval->statement = statement;
  1066. return (MOJOSHADER_astStatement *) retval;
  1067. } // new_for_statement
  1068. static void delete_for_statement(Context *ctx,MOJOSHADER_astForStatement *stmt)
  1069. {
  1070. DELETE_AST_NODE(stmt);
  1071. delete_statement(ctx, stmt->next);
  1072. delete_variable_declaration(ctx, stmt->var_decl);
  1073. delete_expr(ctx, stmt->initializer);
  1074. delete_expr(ctx, stmt->looptest);
  1075. delete_expr(ctx, stmt->counter);
  1076. delete_statement(ctx, stmt->statement);
  1077. Free(ctx, stmt);
  1078. } // delete_for_statement
  1079. static MOJOSHADER_astStatement *new_do_statement(Context *ctx,
  1080. const int unroll,
  1081. MOJOSHADER_astStatement *stmt,
  1082. MOJOSHADER_astExpression *expr)
  1083. {
  1084. NEW_AST_NODE(retval,MOJOSHADER_astDoStatement,MOJOSHADER_AST_STATEMENT_DO);
  1085. retval->next = NULL;
  1086. retval->unroll = unroll;
  1087. retval->expr = expr;
  1088. retval->statement = stmt;
  1089. return (MOJOSHADER_astStatement *) retval;
  1090. } // new_do_statement
  1091. static void delete_do_statement(Context *ctx, MOJOSHADER_astDoStatement *stmt)
  1092. {
  1093. DELETE_AST_NODE(stmt);
  1094. delete_statement(ctx, stmt->next);
  1095. delete_statement(ctx, stmt->statement);
  1096. delete_expr(ctx, stmt->expr);
  1097. Free(ctx, stmt);
  1098. } // delete_do_statement
  1099. static MOJOSHADER_astStatement *new_while_statement(Context *ctx,
  1100. const int unroll,
  1101. MOJOSHADER_astExpression *expr,
  1102. MOJOSHADER_astStatement *stmt)
  1103. {
  1104. NEW_AST_NODE(retval, MOJOSHADER_astWhileStatement,
  1105. MOJOSHADER_AST_STATEMENT_WHILE);
  1106. retval->next = NULL;
  1107. retval->unroll = unroll;
  1108. retval->expr = expr;
  1109. retval->statement = stmt;
  1110. return (MOJOSHADER_astStatement *) retval;
  1111. } // new_while_statement
  1112. static void delete_while_statement(Context *ctx,
  1113. MOJOSHADER_astWhileStatement *stmt)
  1114. {
  1115. DELETE_AST_NODE(stmt);
  1116. delete_statement(ctx, stmt->next);
  1117. delete_statement(ctx, stmt->statement);
  1118. delete_expr(ctx, stmt->expr);
  1119. Free(ctx, stmt);
  1120. } // delete_while_statement
  1121. static MOJOSHADER_astStatement *new_if_statement(Context *ctx,
  1122. const int attr,
  1123. MOJOSHADER_astExpression *expr,
  1124. MOJOSHADER_astStatement *stmt,
  1125. MOJOSHADER_astStatement *elsestmt)
  1126. {
  1127. NEW_AST_NODE(retval,MOJOSHADER_astIfStatement,MOJOSHADER_AST_STATEMENT_IF);
  1128. retval->next = NULL;
  1129. retval->attributes = attr;
  1130. retval->expr = expr;
  1131. retval->statement = stmt;
  1132. retval->else_statement = elsestmt;
  1133. return (MOJOSHADER_astStatement *) retval;
  1134. } // new_if_statement
  1135. static void delete_if_statement(Context *ctx, MOJOSHADER_astIfStatement *stmt)
  1136. {
  1137. DELETE_AST_NODE(stmt);
  1138. delete_statement(ctx, stmt->next);
  1139. delete_expr(ctx, stmt->expr);
  1140. delete_statement(ctx, stmt->statement);
  1141. delete_statement(ctx, stmt->else_statement);
  1142. Free(ctx, stmt);
  1143. } // delete_if_statement
  1144. static MOJOSHADER_astSwitchCases *new_switch_case(Context *ctx,
  1145. MOJOSHADER_astExpression *expr,
  1146. MOJOSHADER_astStatement *stmt)
  1147. {
  1148. NEW_AST_NODE(retval, MOJOSHADER_astSwitchCases, MOJOSHADER_AST_SWITCH_CASE);
  1149. retval->expr = expr;
  1150. retval->statement = stmt;
  1151. retval->next = NULL;
  1152. return retval;
  1153. } // new_switch_case
  1154. static void delete_switch_case(Context *ctx, MOJOSHADER_astSwitchCases *sc)
  1155. {
  1156. DELETE_AST_NODE(sc);
  1157. delete_switch_case(ctx, sc->next);
  1158. delete_expr(ctx, sc->expr);
  1159. delete_statement(ctx, sc->statement);
  1160. Free(ctx, sc);
  1161. } // delete_switch_case
  1162. static MOJOSHADER_astStatement *new_empty_statement(Context *ctx)
  1163. {
  1164. NEW_AST_NODE(retval, MOJOSHADER_astEmptyStatement,
  1165. MOJOSHADER_AST_STATEMENT_EMPTY);
  1166. retval->next = NULL;
  1167. return (MOJOSHADER_astStatement *) retval;
  1168. } // new_empty_statement
  1169. static void delete_empty_statement(Context *ctx,
  1170. MOJOSHADER_astEmptyStatement *stmt)
  1171. {
  1172. DELETE_AST_NODE(stmt);
  1173. delete_statement(ctx, stmt->next);
  1174. Free(ctx, stmt);
  1175. } // delete_empty_statement
  1176. static MOJOSHADER_astStatement *new_break_statement(Context *ctx)
  1177. {
  1178. NEW_AST_NODE(retval, MOJOSHADER_astBreakStatement,
  1179. MOJOSHADER_AST_STATEMENT_BREAK);
  1180. retval->next = NULL;
  1181. return (MOJOSHADER_astStatement *) retval;
  1182. } // new_break_statement
  1183. static void delete_break_statement(Context *ctx,
  1184. MOJOSHADER_astBreakStatement *stmt)
  1185. {
  1186. DELETE_AST_NODE(stmt);
  1187. delete_statement(ctx, stmt->next);
  1188. Free(ctx, stmt);
  1189. } // delete_break_statement
  1190. static MOJOSHADER_astStatement *new_continue_statement(Context *ctx)
  1191. {
  1192. NEW_AST_NODE(retval, MOJOSHADER_astContinueStatement,
  1193. MOJOSHADER_AST_STATEMENT_CONTINUE);
  1194. retval->next = NULL;
  1195. return (MOJOSHADER_astStatement *) retval;
  1196. } // new_continue_statement
  1197. static void delete_continue_statement(Context *ctx,
  1198. MOJOSHADER_astContinueStatement *stmt)
  1199. {
  1200. DELETE_AST_NODE(stmt);
  1201. delete_statement(ctx, stmt->next);
  1202. Free(ctx, stmt);
  1203. } // delete_continue_statement
  1204. static MOJOSHADER_astStatement *new_discard_statement(Context *ctx)
  1205. {
  1206. NEW_AST_NODE(retval, MOJOSHADER_astDiscardStatement,
  1207. MOJOSHADER_AST_STATEMENT_DISCARD);
  1208. retval->next = NULL;
  1209. return (MOJOSHADER_astStatement *) retval;
  1210. } // new_discard_statement
  1211. static void delete_discard_statement(Context *ctx,
  1212. MOJOSHADER_astDiscardStatement *stmt)
  1213. {
  1214. DELETE_AST_NODE(stmt);
  1215. delete_statement(ctx, stmt->next);
  1216. Free(ctx, stmt);
  1217. } // delete_discard_statement
  1218. static MOJOSHADER_astStatement *new_expr_statement(Context *ctx,
  1219. MOJOSHADER_astExpression *expr)
  1220. {
  1221. NEW_AST_NODE(retval, MOJOSHADER_astExpressionStatement,
  1222. MOJOSHADER_AST_STATEMENT_EXPRESSION);
  1223. retval->next = NULL;
  1224. retval->expr = expr;
  1225. return (MOJOSHADER_astStatement *) retval;
  1226. } // new_expr_statement
  1227. static void delete_expr_statement(Context *ctx,
  1228. MOJOSHADER_astExpressionStatement *stmt)
  1229. {
  1230. DELETE_AST_NODE(stmt);
  1231. delete_statement(ctx, stmt->next);
  1232. delete_expr(ctx, stmt->expr);
  1233. Free(ctx, stmt);
  1234. } // delete_expr_statement
  1235. static MOJOSHADER_astStatement *new_switch_statement(Context *ctx,
  1236. const int attr,
  1237. MOJOSHADER_astExpression *expr,
  1238. MOJOSHADER_astSwitchCases *cases)
  1239. {
  1240. NEW_AST_NODE(retval, MOJOSHADER_astSwitchStatement,
  1241. MOJOSHADER_AST_STATEMENT_SWITCH);
  1242. retval->next = NULL;
  1243. retval->attributes = attr;
  1244. retval->expr = expr;
  1245. retval->cases = cases;
  1246. return (MOJOSHADER_astStatement *) retval;
  1247. } // new_switch_statement
  1248. static void delete_switch_statement(Context *ctx,
  1249. MOJOSHADER_astSwitchStatement *stmt)
  1250. {
  1251. DELETE_AST_NODE(stmt);
  1252. delete_expr(ctx, stmt->expr);
  1253. delete_switch_case(ctx, stmt->cases);
  1254. Free(ctx, stmt);
  1255. } // delete_switch_statement
  1256. static MOJOSHADER_astStatement *new_struct_statement(Context *ctx,
  1257. MOJOSHADER_astStructDeclaration *sd)
  1258. {
  1259. NEW_AST_NODE(retval, MOJOSHADER_astStructStatement,
  1260. MOJOSHADER_AST_STATEMENT_STRUCT);
  1261. retval->next = NULL;
  1262. retval->struct_info = sd;
  1263. return (MOJOSHADER_astStatement *) retval;
  1264. } // new_struct_statement
  1265. static void delete_struct_statement(Context *ctx,
  1266. MOJOSHADER_astStructStatement *stmt)
  1267. {
  1268. DELETE_AST_NODE(stmt);
  1269. delete_statement(ctx, stmt->next);
  1270. delete_struct_declaration(ctx, stmt->struct_info);
  1271. Free(ctx, stmt);
  1272. } // delete_struct_statement
  1273. static MOJOSHADER_astStatement *new_vardecl_statement(Context *ctx,
  1274. MOJOSHADER_astVariableDeclaration *vd)
  1275. {
  1276. NEW_AST_NODE(retval, MOJOSHADER_astVarDeclStatement,
  1277. MOJOSHADER_AST_STATEMENT_VARDECL);
  1278. retval->next = NULL;
  1279. retval->declaration = vd;
  1280. return (MOJOSHADER_astStatement *) retval;
  1281. } // new_vardecl_statement
  1282. static void delete_vardecl_statement(Context *ctx,
  1283. MOJOSHADER_astVarDeclStatement *stmt)
  1284. {
  1285. DELETE_AST_NODE(stmt);
  1286. delete_statement(ctx, stmt->next);
  1287. delete_variable_declaration(ctx, stmt->declaration);
  1288. Free(ctx, stmt);
  1289. } // delete_vardecl_statement
  1290. static void delete_statement(Context *ctx, MOJOSHADER_astStatement *stmt)
  1291. {
  1292. if (!stmt) return;
  1293. // it's important to not recurse too deeply here, since you may have
  1294. // thousands of items in this linked list (each line of a massive
  1295. // function, for example). To avoid this, we iterate the list here,
  1296. // deleting all children and making them think they have no reason
  1297. // to recurse in their own delete methods.
  1298. // Please note that everyone should _try_ to delete their "next" member,
  1299. // just in case, but hopefully this cleaned it out.
  1300. MOJOSHADER_astStatement *i = stmt->next;
  1301. stmt->next = NULL;
  1302. while (i)
  1303. {
  1304. MOJOSHADER_astStatement *next = i->next;
  1305. i->next = NULL;
  1306. delete_statement(ctx, i);
  1307. i = next;
  1308. } // while
  1309. switch (stmt->ast.type)
  1310. {
  1311. #define DELETE_STATEMENT(typ, cls, fn) \
  1312. case MOJOSHADER_AST_STATEMENT_##typ: \
  1313. delete_##fn##_statement(ctx, (cls *) stmt); break;
  1314. DELETE_STATEMENT(BLOCK, MOJOSHADER_astBlockStatement, block);
  1315. DELETE_STATEMENT(EMPTY, MOJOSHADER_astEmptyStatement, empty);
  1316. DELETE_STATEMENT(IF, MOJOSHADER_astIfStatement, if);
  1317. DELETE_STATEMENT(SWITCH, MOJOSHADER_astSwitchStatement, switch);
  1318. DELETE_STATEMENT(EXPRESSION, MOJOSHADER_astExpressionStatement, expr);
  1319. DELETE_STATEMENT(FOR, MOJOSHADER_astForStatement, for);
  1320. DELETE_STATEMENT(DO, MOJOSHADER_astDoStatement, do);
  1321. DELETE_STATEMENT(WHILE, MOJOSHADER_astWhileStatement, while);
  1322. DELETE_STATEMENT(RETURN, MOJOSHADER_astReturnStatement, return);
  1323. DELETE_STATEMENT(BREAK, MOJOSHADER_astBreakStatement, break);
  1324. DELETE_STATEMENT(CONTINUE, MOJOSHADER_astContinueStatement, continue);
  1325. DELETE_STATEMENT(DISCARD, MOJOSHADER_astDiscardStatement, discard);
  1326. DELETE_STATEMENT(TYPEDEF, MOJOSHADER_astTypedefStatement, typedef);
  1327. DELETE_STATEMENT(STRUCT, MOJOSHADER_astStructStatement, struct);
  1328. DELETE_STATEMENT(VARDECL, MOJOSHADER_astVarDeclStatement, vardecl);
  1329. #undef DELETE_STATEMENT
  1330. default: assert(0 && "missing cleanup code"); break;
  1331. } // switch
  1332. // don't free (stmt) here, the class-specific functions do it.
  1333. } // delete_statement
  1334. static const MOJOSHADER_astDataType *get_usertype(const Context *ctx,
  1335. const char *token)
  1336. {
  1337. const void *value; // search all scopes.
  1338. if (!hash_find(ctx->usertypes.hash, token, &value))
  1339. return NULL;
  1340. return value ? ((SymbolScope *) value)->datatype : NULL;
  1341. } // get_usertype
  1342. // This is where the actual parsing happens. It's Lemon-generated!
  1343. #define __MOJOSHADER_HLSL_COMPILER__ 1
  1344. #include "mojoshader_parser_hlsl.h"
  1345. #if 0
  1346. static int expr_is_constant(MOJOSHADER_astExpression *expr)
  1347. {
  1348. const MOJOSHADER_astNodeType op = expr->ast.type;
  1349. if (operator_is_unary(op))
  1350. return expr_is_constant(expr->unary.operand);
  1351. else if (operator_is_binary(op))
  1352. {
  1353. return ( expr_is_constant(expr->binary.left) &&
  1354. expr_is_constant(expr->binary.right) );
  1355. } // else if
  1356. else if (operator_is_ternary(op))
  1357. {
  1358. return ( expr_is_constant(expr->ternary.left) &&
  1359. expr_is_constant(expr->ternary.center) &&
  1360. expr_is_constant(expr->ternary.right) );
  1361. } // else if
  1362. return ( (op == MOJOSHADER_AST_OP_INT_LITERAL) ||
  1363. (op == MOJOSHADER_AST_OP_FLOAT_LITERAL) ||
  1364. (op == MOJOSHADER_AST_OP_STRING_LITERAL) ||
  1365. (op == MOJOSHADER_AST_OP_BOOLEAN_LITERAL) );
  1366. } // expr_is_constant
  1367. #endif
  1368. typedef struct AstCalcData
  1369. {
  1370. int isflt;
  1371. union
  1372. {
  1373. double f;
  1374. int64 i;
  1375. } value;
  1376. } AstCalcData;
  1377. // returns 0 if this expression is non-constant, 1 if it is.
  1378. // calculation results land in (data).
  1379. static int calc_ast_const_expr(Context *ctx, void *_expr, AstCalcData *data)
  1380. {
  1381. const MOJOSHADER_astNode *expr = (MOJOSHADER_astNode *) _expr;
  1382. const MOJOSHADER_astNodeType op = expr->ast.type;
  1383. ctx->sourcefile = expr->ast.filename;
  1384. ctx->sourceline = expr->ast.line;
  1385. if (operator_is_unary(op))
  1386. {
  1387. if (!calc_ast_const_expr(ctx, expr->unary.operand, data))
  1388. return 0;
  1389. if (data->isflt)
  1390. {
  1391. switch (op)
  1392. {
  1393. case MOJOSHADER_AST_OP_NEGATE:
  1394. data->value.f = -data->value.f;
  1395. return 1;
  1396. case MOJOSHADER_AST_OP_NOT:
  1397. data->value.f = !data->value.f;
  1398. return 1;
  1399. case MOJOSHADER_AST_OP_COMPLEMENT:
  1400. fail(ctx, "integer operation on floating point value");
  1401. return 0;
  1402. case MOJOSHADER_AST_OP_CAST:
  1403. // !!! FIXME: this should work, but it's complicated.
  1404. assert(0 && "write me");
  1405. return 0;
  1406. default: break;
  1407. } // switch
  1408. } // if
  1409. else // integer version
  1410. {
  1411. switch (op)
  1412. {
  1413. case MOJOSHADER_AST_OP_NEGATE:
  1414. data->value.i = -data->value.i;
  1415. return 1;
  1416. case MOJOSHADER_AST_OP_NOT:
  1417. data->value.i = !data->value.i;
  1418. return 1;
  1419. case MOJOSHADER_AST_OP_COMPLEMENT:
  1420. data->value.i = ~data->value.i;
  1421. return 1;
  1422. case MOJOSHADER_AST_OP_CAST:
  1423. // !!! FIXME: this should work, but it's complicated.
  1424. assert(0 && "write me");
  1425. return 0;
  1426. default: break;
  1427. } // switch
  1428. } // else
  1429. assert(0 && "unhandled operation?");
  1430. return 0;
  1431. } // if
  1432. else if (operator_is_binary(op))
  1433. {
  1434. AstCalcData subdata2;
  1435. if ( (!calc_ast_const_expr(ctx, expr->binary.left, data)) ||
  1436. (!calc_ast_const_expr(ctx, expr->binary.right, &subdata2)) )
  1437. return 0;
  1438. // upgrade to float if either operand is float.
  1439. if ((data->isflt) || (subdata2.isflt))
  1440. {
  1441. if (!data->isflt) data->value.f = (double) data->value.i;
  1442. if (!subdata2.isflt) subdata2.value.f = (double) subdata2.value.i;
  1443. data->isflt = subdata2.isflt = 1;
  1444. } // if
  1445. switch (op)
  1446. {
  1447. // gcc doesn't handle commas here, either (fails to parse!).
  1448. case MOJOSHADER_AST_OP_COMMA:
  1449. case MOJOSHADER_AST_OP_ASSIGN:
  1450. case MOJOSHADER_AST_OP_MULASSIGN:
  1451. case MOJOSHADER_AST_OP_DIVASSIGN:
  1452. case MOJOSHADER_AST_OP_MODASSIGN:
  1453. case MOJOSHADER_AST_OP_ADDASSIGN:
  1454. case MOJOSHADER_AST_OP_SUBASSIGN:
  1455. case MOJOSHADER_AST_OP_LSHIFTASSIGN:
  1456. case MOJOSHADER_AST_OP_RSHIFTASSIGN:
  1457. case MOJOSHADER_AST_OP_ANDASSIGN:
  1458. case MOJOSHADER_AST_OP_XORASSIGN:
  1459. case MOJOSHADER_AST_OP_ORASSIGN:
  1460. return 0; // assignment is non-constant.
  1461. default: break;
  1462. } // switch
  1463. if (data->isflt)
  1464. {
  1465. switch (op)
  1466. {
  1467. case MOJOSHADER_AST_OP_MULTIPLY:
  1468. data->value.f *= subdata2.value.f;
  1469. return 1;
  1470. case MOJOSHADER_AST_OP_DIVIDE:
  1471. data->value.f /= subdata2.value.f;
  1472. return 1;
  1473. case MOJOSHADER_AST_OP_ADD:
  1474. data->value.f += subdata2.value.f;
  1475. return 1;
  1476. case MOJOSHADER_AST_OP_SUBTRACT:
  1477. data->value.f -= subdata2.value.f;
  1478. return 1;
  1479. case MOJOSHADER_AST_OP_LESSTHAN:
  1480. data->isflt = 0;
  1481. data->value.i = data->value.f < subdata2.value.f;
  1482. return 1;
  1483. case MOJOSHADER_AST_OP_GREATERTHAN:
  1484. data->isflt = 0;
  1485. data->value.i = data->value.f > subdata2.value.f;
  1486. return 1;
  1487. case MOJOSHADER_AST_OP_LESSTHANOREQUAL:
  1488. data->isflt = 0;
  1489. data->value.i = data->value.f <= subdata2.value.f;
  1490. return 1;
  1491. case MOJOSHADER_AST_OP_GREATERTHANOREQUAL:
  1492. data->isflt = 0;
  1493. data->value.i = data->value.f >= subdata2.value.f;
  1494. return 1;
  1495. case MOJOSHADER_AST_OP_EQUAL:
  1496. data->isflt = 0;
  1497. data->value.i = data->value.f == subdata2.value.f;
  1498. return 1;
  1499. case MOJOSHADER_AST_OP_NOTEQUAL:
  1500. data->isflt = 0;
  1501. data->value.i = data->value.f != subdata2.value.f;
  1502. return 1;
  1503. case MOJOSHADER_AST_OP_LOGICALAND:
  1504. data->isflt = 0;
  1505. data->value.i = data->value.f && subdata2.value.f;
  1506. return 1;
  1507. case MOJOSHADER_AST_OP_LOGICALOR:
  1508. data->isflt = 0;
  1509. data->value.i = data->value.f || subdata2.value.f;
  1510. return 1;
  1511. case MOJOSHADER_AST_OP_LSHIFT:
  1512. case MOJOSHADER_AST_OP_RSHIFT:
  1513. case MOJOSHADER_AST_OP_MODULO:
  1514. case MOJOSHADER_AST_OP_BINARYAND:
  1515. case MOJOSHADER_AST_OP_BINARYXOR:
  1516. case MOJOSHADER_AST_OP_BINARYOR:
  1517. fail(ctx, "integer operation on floating point value");
  1518. return 0;
  1519. default: break;
  1520. } // switch
  1521. } // if
  1522. else // integer version.
  1523. {
  1524. switch (op)
  1525. {
  1526. case MOJOSHADER_AST_OP_MULTIPLY:
  1527. data->value.i *= subdata2.value.i;
  1528. return 1;
  1529. case MOJOSHADER_AST_OP_DIVIDE:
  1530. data->value.i /= subdata2.value.i;
  1531. return 1;
  1532. case MOJOSHADER_AST_OP_ADD:
  1533. data->value.i += subdata2.value.i;
  1534. return 1;
  1535. case MOJOSHADER_AST_OP_SUBTRACT:
  1536. data->value.i -= subdata2.value.i;
  1537. return 1;
  1538. case MOJOSHADER_AST_OP_LESSTHAN:
  1539. data->value.i = data->value.i < subdata2.value.i;
  1540. return 1;
  1541. case MOJOSHADER_AST_OP_GREATERTHAN:
  1542. data->value.i = data->value.i > subdata2.value.i;
  1543. return 1;
  1544. case MOJOSHADER_AST_OP_LESSTHANOREQUAL:
  1545. data->value.i = data->value.i <= subdata2.value.i;
  1546. return 1;
  1547. case MOJOSHADER_AST_OP_GREATERTHANOREQUAL:
  1548. data->value.i = data->value.i >= subdata2.value.i;
  1549. return 1;
  1550. case MOJOSHADER_AST_OP_EQUAL:
  1551. data->value.i = data->value.i == subdata2.value.i;
  1552. return 1;
  1553. case MOJOSHADER_AST_OP_NOTEQUAL:
  1554. data->value.i = data->value.i != subdata2.value.i;
  1555. return 1;
  1556. case MOJOSHADER_AST_OP_LOGICALAND:
  1557. data->value.i = data->value.i && subdata2.value.i;
  1558. return 1;
  1559. case MOJOSHADER_AST_OP_LOGICALOR:
  1560. data->value.i = data->value.i || subdata2.value.i;
  1561. return 1;
  1562. case MOJOSHADER_AST_OP_LSHIFT:
  1563. data->value.i = data->value.i << subdata2.value.i;
  1564. return 1;
  1565. case MOJOSHADER_AST_OP_RSHIFT:
  1566. data->value.i = data->value.i >> subdata2.value.i;
  1567. return 1;
  1568. case MOJOSHADER_AST_OP_MODULO:
  1569. data->value.i = data->value.i % subdata2.value.i;
  1570. return 1;
  1571. case MOJOSHADER_AST_OP_BINARYAND:
  1572. data->value.i = data->value.i & subdata2.value.i;
  1573. return 1;
  1574. case MOJOSHADER_AST_OP_BINARYXOR:
  1575. data->value.i = data->value.i ^ subdata2.value.i;
  1576. return 1;
  1577. case MOJOSHADER_AST_OP_BINARYOR:
  1578. data->value.i = data->value.i | subdata2.value.i;
  1579. return 1;
  1580. default: break;
  1581. } // switch
  1582. } // else
  1583. assert(0 && "unhandled operation?");
  1584. return 0;
  1585. } // else if
  1586. else if (operator_is_ternary(op))
  1587. {
  1588. AstCalcData subdata2;
  1589. AstCalcData subdata3;
  1590. assert(op == MOJOSHADER_AST_OP_CONDITIONAL); // only one we have.
  1591. if ( (!calc_ast_const_expr(ctx, expr->ternary.left, data)) ||
  1592. (!calc_ast_const_expr(ctx, expr->ternary.center, &subdata2)) ||
  1593. (!calc_ast_const_expr(ctx, expr->ternary.right, &subdata3)) )
  1594. return 0;
  1595. // first operand should be bool (for the one ternary operator we have).
  1596. if (data->isflt)
  1597. {
  1598. data->isflt = 0;
  1599. data->value.i = (int64) subdata3.value.f;
  1600. } // if
  1601. // upgrade to float if either operand is float.
  1602. if ((subdata2.isflt) || (subdata3.isflt))
  1603. {
  1604. if (!subdata2.isflt) subdata2.value.f = (double) subdata2.value.i;
  1605. if (!subdata3.isflt) subdata3.value.f = (double) subdata3.value.i;
  1606. subdata2.isflt = subdata3.isflt = 1;
  1607. } // if
  1608. data->isflt = subdata2.isflt;
  1609. if (data->isflt)
  1610. data->value.f = data->value.i ? subdata2.value.f : subdata3.value.f;
  1611. else
  1612. data->value.i = data->value.i ? subdata2.value.i : subdata3.value.i;
  1613. return 1;
  1614. } // else if
  1615. else // not an operator? See if this is a literal value.
  1616. {
  1617. switch (op)
  1618. {
  1619. case MOJOSHADER_AST_OP_INT_LITERAL:
  1620. data->isflt = 0;
  1621. data->value.i = expr->intliteral.value;
  1622. return 1;
  1623. case MOJOSHADER_AST_OP_FLOAT_LITERAL:
  1624. data->isflt = 1;
  1625. data->value.f = expr->floatliteral.value;
  1626. return 1;
  1627. case MOJOSHADER_AST_OP_BOOLEAN_LITERAL:
  1628. data->isflt = 0;
  1629. data->value.i = expr->boolliteral.value ? 1 : 0;
  1630. return 1;
  1631. default: break;
  1632. } // switch
  1633. } // switch
  1634. return 0; // not constant, or unhandled.
  1635. } // calc_ast_const_expr
  1636. static const MOJOSHADER_astDataType *reduce_datatype(Context *ctx, const MOJOSHADER_astDataType *dt)
  1637. {
  1638. const MOJOSHADER_astDataType *retval = dt;
  1639. while (retval && retval->type == MOJOSHADER_AST_DATATYPE_USER)
  1640. {
  1641. // !!! FIXME: Ugh, const removal.
  1642. MOJOSHADER_astDataTypeUser *user = (MOJOSHADER_astDataTypeUser *) &retval->user;
  1643. if (user->details->type == MOJOSHADER_AST_DATATYPE_NONE)
  1644. {
  1645. // Take this opportunity to fix up some usertype stubs that were
  1646. // left over from the parse phase. You HAVE to catch these in the
  1647. // right scope, so be aggressive about calling reduce_datatype()
  1648. // as soon as things come into view!
  1649. user->details = get_usertype(ctx, user->name);
  1650. assert(user->details != NULL);
  1651. } // if
  1652. retval = user->details;
  1653. } // while
  1654. return retval;
  1655. } // reduce_datatype
  1656. static inline const MOJOSHADER_astDataType *sanitize_datatype(Context *ctx, const MOJOSHADER_astDataType *dt)
  1657. {
  1658. reduce_datatype(ctx, dt);
  1659. return dt;
  1660. } // sanitize_datatype
  1661. static const MOJOSHADER_astDataType *build_function_datatype(Context *ctx,
  1662. const MOJOSHADER_astDataType *rettype,
  1663. const int paramcount,
  1664. const MOJOSHADER_astDataType **params,
  1665. const int intrinsic)
  1666. {
  1667. if ( ((paramcount > 0) && (params == NULL)) ||
  1668. ((paramcount == 0) && (params != NULL)) )
  1669. return NULL;
  1670. // !!! FIXME: this is hacky.
  1671. const MOJOSHADER_astDataType **dtparams;
  1672. void *ptr = Malloc(ctx, sizeof (*params) * paramcount);
  1673. if (ptr == NULL)
  1674. return NULL;
  1675. if (!buffer_append(ctx->garbage, &ptr, sizeof (ptr)))
  1676. {
  1677. Free(ctx, ptr);
  1678. return NULL;
  1679. } // if
  1680. dtparams = (const MOJOSHADER_astDataType **) ptr;
  1681. memcpy(dtparams, params, sizeof (*params) * paramcount);
  1682. ptr = Malloc(ctx, sizeof (MOJOSHADER_astDataType));
  1683. if (ptr == NULL)
  1684. return NULL;
  1685. if (!buffer_append(ctx->garbage, &ptr, sizeof (ptr)))
  1686. {
  1687. Free(ctx, ptr);
  1688. return NULL;
  1689. } // if
  1690. MOJOSHADER_astDataType *dt = (MOJOSHADER_astDataType *) ptr;
  1691. dt->type = MOJOSHADER_AST_DATATYPE_FUNCTION;
  1692. dt->function.retval = rettype;
  1693. dt->function.params = dtparams;
  1694. dt->function.num_params = paramcount;
  1695. dt->function.intrinsic = intrinsic;
  1696. return dt;
  1697. } // build_function_datatype
  1698. static const MOJOSHADER_astDataType *build_datatype(Context *ctx,
  1699. const int isconst,
  1700. const MOJOSHADER_astDataType *dt,
  1701. MOJOSHADER_astScalarOrArray *soa)
  1702. {
  1703. MOJOSHADER_astDataType *retval = NULL;
  1704. assert( (soa->isarray && soa->dimension) ||
  1705. (!soa->isarray && !soa->dimension) );
  1706. sanitize_datatype(ctx, dt);
  1707. // see if we can just reuse the exist datatype.
  1708. if (!soa->isarray)
  1709. {
  1710. const int c1 = (dt->type & MOJOSHADER_AST_DATATYPE_CONST) != 0;
  1711. const int c2 = (isconst != 0);
  1712. if (c1 == c2)
  1713. return dt; // reuse existing datatype!
  1714. } // if
  1715. retval = (MOJOSHADER_astDataType *) Malloc(ctx, sizeof (*retval));
  1716. if (retval == NULL)
  1717. return NULL;
  1718. // !!! FIXME: this is hacky.
  1719. if (!buffer_append(ctx->garbage, &retval, sizeof (retval)))
  1720. {
  1721. Free(ctx, retval);
  1722. return NULL;
  1723. } // if
  1724. if (!soa->isarray)
  1725. {
  1726. assert(soa->dimension == NULL);
  1727. memcpy(retval, dt, sizeof (MOJOSHADER_astDataType));
  1728. if (isconst)
  1729. retval->type = (MOJOSHADER_astDataTypeType)((unsigned)retval->type | MOJOSHADER_AST_DATATYPE_CONST);
  1730. else
  1731. retval->type = (MOJOSHADER_astDataTypeType)((unsigned)retval->type & ~MOJOSHADER_AST_DATATYPE_CONST);
  1732. return retval;
  1733. } // if
  1734. retval->type = MOJOSHADER_AST_DATATYPE_ARRAY;
  1735. retval->array.base = dt;
  1736. if (soa->dimension == NULL)
  1737. {
  1738. retval->array.elements = -1;
  1739. return retval;
  1740. } // if
  1741. // Run the expression to verify it's constant and produces a positive int.
  1742. AstCalcData data;
  1743. data.isflt = 0;
  1744. data.value.i = 0;
  1745. retval->array.elements = 16; // sane default for failure.
  1746. const int ok = calc_ast_const_expr(ctx, soa->dimension, &data);
  1747. // reset error position.
  1748. ctx->sourcefile = soa->ast.filename;
  1749. ctx->sourceline = soa->ast.line;
  1750. if (!ok)
  1751. fail(ctx, "array dimensions not constant");
  1752. else if (data.isflt)
  1753. fail(ctx, "array dimensions not integer");
  1754. else if (data.value.i < 0)
  1755. fail(ctx, "array dimensions negative");
  1756. else
  1757. retval->array.elements = data.value.i;
  1758. return retval;
  1759. } // build_datatype
  1760. static void require_numeric_datatype(Context *ctx,
  1761. const MOJOSHADER_astDataType *datatype)
  1762. {
  1763. datatype = reduce_datatype(ctx, datatype);
  1764. if (datatype->type == MOJOSHADER_AST_DATATYPE_VECTOR)
  1765. datatype = reduce_datatype(ctx, datatype->vector.base);
  1766. else if (datatype->type == MOJOSHADER_AST_DATATYPE_MATRIX)
  1767. datatype = reduce_datatype(ctx, datatype->matrix.base);
  1768. switch (datatype->type)
  1769. {
  1770. case MOJOSHADER_AST_DATATYPE_BOOL:
  1771. case MOJOSHADER_AST_DATATYPE_INT:
  1772. case MOJOSHADER_AST_DATATYPE_UINT:
  1773. case MOJOSHADER_AST_DATATYPE_HALF:
  1774. case MOJOSHADER_AST_DATATYPE_FLOAT:
  1775. case MOJOSHADER_AST_DATATYPE_DOUBLE:
  1776. return;
  1777. default: break;
  1778. } // switch
  1779. fail(ctx, "Expected numeric type"); // !!! FIXME: fmt.
  1780. // !!! FIXME: replace AST node with an AST_OP_INT_LITERAL zero, keep going.
  1781. } // require_numeric_datatype
  1782. static void require_integer_datatype(Context *ctx,
  1783. const MOJOSHADER_astDataType *datatype)
  1784. {
  1785. datatype = reduce_datatype(ctx, datatype);
  1786. switch (datatype->type)
  1787. {
  1788. case MOJOSHADER_AST_DATATYPE_INT:
  1789. case MOJOSHADER_AST_DATATYPE_UINT:
  1790. return;
  1791. default: break;
  1792. } // switch
  1793. fail(ctx, "Expected integer type"); // !!! FIXME: fmt.
  1794. // !!! FIXME: replace AST node with an AST_OP_INT_LITERAL zero, keep going.
  1795. } // require_integer_datatype
  1796. static void require_boolean_datatype(Context *ctx,
  1797. const MOJOSHADER_astDataType *datatype)
  1798. {
  1799. datatype = reduce_datatype(ctx, datatype);
  1800. switch (datatype->type)
  1801. {
  1802. case MOJOSHADER_AST_DATATYPE_BOOL:
  1803. case MOJOSHADER_AST_DATATYPE_INT:
  1804. case MOJOSHADER_AST_DATATYPE_UINT:
  1805. return;
  1806. default: break;
  1807. } // switch
  1808. fail(ctx, "Expected boolean type"); // !!! FIXME: fmt.
  1809. // !!! FIXME: replace AST node with an AST_OP_BOOLEAN_LITERAL false, keep going.
  1810. } // require_numeric_datatype
  1811. static void require_array_datatype(Context *ctx,
  1812. const MOJOSHADER_astDataType *datatype)
  1813. {
  1814. datatype = reduce_datatype(ctx, datatype);
  1815. if (datatype->type == MOJOSHADER_AST_DATATYPE_ARRAY)
  1816. return;
  1817. fail(ctx, "expected array");
  1818. // !!! FIXME: delete array dereference for further processing.
  1819. } // require_array_datatype
  1820. static void require_struct_datatype(Context *ctx,
  1821. const MOJOSHADER_astDataType *datatype)
  1822. {
  1823. datatype = reduce_datatype(ctx, datatype);
  1824. if (datatype->type == MOJOSHADER_AST_DATATYPE_STRUCT)
  1825. return;
  1826. fail(ctx, "expected struct");
  1827. // !!! FIXME: delete struct dereference for further processing.
  1828. } // require_struct_datatype
  1829. static int require_function_datatype(Context *ctx,
  1830. const MOJOSHADER_astDataType *datatype)
  1831. {
  1832. datatype = reduce_datatype(ctx, datatype);
  1833. if ((!datatype) || (datatype->type != MOJOSHADER_AST_DATATYPE_FUNCTION))
  1834. {
  1835. fail(ctx, "expected function");
  1836. return 0;
  1837. } // if
  1838. return 1;
  1839. } // require_function_datatype
  1840. // Extract the individual element type from an array datatype.
  1841. static const MOJOSHADER_astDataType *array_element_datatype(Context *ctx,
  1842. const MOJOSHADER_astDataType *datatype)
  1843. {
  1844. datatype = reduce_datatype(ctx, datatype);
  1845. assert(datatype->type == MOJOSHADER_AST_DATATYPE_ARRAY);
  1846. return datatype->array.base;
  1847. } // array_element_datatype
  1848. // This tests two datatypes to see if they are compatible, and adds cast
  1849. // operator nodes to the AST if the program was relying on implicit
  1850. // casts between then. Will fail() if the datatypes can't be coerced
  1851. // with a cast at all. (left) can be NULL to say that its datatype is
  1852. // set in stone (an lvalue, for example). No other NULLs are allowed.
  1853. // Returns final datatype used once implicit casting is complete.
  1854. // The datatypes must be pointers from the string cache.
  1855. static const MOJOSHADER_astDataType *add_type_coercion(Context *ctx,
  1856. MOJOSHADER_astExpression **left,
  1857. const MOJOSHADER_astDataType *_ldatatype,
  1858. MOJOSHADER_astExpression **right,
  1859. const MOJOSHADER_astDataType *_rdatatype)
  1860. {
  1861. // !!! FIXME: this whole function is probably naive at best.
  1862. const MOJOSHADER_astDataType *ldatatype = reduce_datatype(ctx, _ldatatype);
  1863. const MOJOSHADER_astDataType *rdatatype = reduce_datatype(ctx, _rdatatype);
  1864. if (ldatatype == rdatatype)
  1865. return ldatatype; // they already match, so we're done.
  1866. struct {
  1867. const MOJOSHADER_astDataTypeType type;
  1868. const int bits;
  1869. const int is_unsigned;
  1870. const int floating;
  1871. } typeinf[] = {
  1872. { MOJOSHADER_AST_DATATYPE_BOOL, 1, 1, 0 },
  1873. { MOJOSHADER_AST_DATATYPE_HALF, 16, 0, 1 },
  1874. { MOJOSHADER_AST_DATATYPE_INT, 32, 0, 0 },
  1875. { MOJOSHADER_AST_DATATYPE_UINT, 32, 1, 0 },
  1876. { MOJOSHADER_AST_DATATYPE_FLOAT, 32, 0, 1 },
  1877. { MOJOSHADER_AST_DATATYPE_DOUBLE, 64, 0, 1 },
  1878. };
  1879. int lvector = 0;
  1880. int lmatrix = 0;
  1881. int l = STATICARRAYLEN(typeinf);
  1882. if (ldatatype != NULL)
  1883. {
  1884. MOJOSHADER_astDataTypeType type = ldatatype->type;
  1885. if (type == MOJOSHADER_AST_DATATYPE_VECTOR)
  1886. {
  1887. lvector = 1;
  1888. type = ldatatype->vector.base->type;
  1889. } // if
  1890. else if (type == MOJOSHADER_AST_DATATYPE_MATRIX)
  1891. {
  1892. lmatrix = 1;
  1893. type = ldatatype->matrix.base->type;
  1894. } // if
  1895. for (l = 0; l < STATICARRAYLEN(typeinf); l++)
  1896. {
  1897. if (typeinf[l].type == type)
  1898. break;
  1899. } // for
  1900. } // if
  1901. int rvector = 0;
  1902. int rmatrix = 0;
  1903. int r = STATICARRAYLEN(typeinf);
  1904. if (rdatatype != NULL)
  1905. {
  1906. MOJOSHADER_astDataTypeType type = rdatatype->type;
  1907. if (type == MOJOSHADER_AST_DATATYPE_VECTOR)
  1908. {
  1909. rvector = 1;
  1910. type = rdatatype->vector.base->type;
  1911. } // if
  1912. else if (type == MOJOSHADER_AST_DATATYPE_MATRIX)
  1913. {
  1914. rmatrix = 1;
  1915. type = rdatatype->matrix.base->type;
  1916. } // if
  1917. for (r = 0; r < STATICARRAYLEN(typeinf); r++)
  1918. {
  1919. if (typeinf[r].type == type)
  1920. break;
  1921. } // for
  1922. } // if
  1923. enum { CHOOSE_NEITHER, CHOOSE_LEFT, CHOOSE_RIGHT } choice = CHOOSE_NEITHER;
  1924. if ((l < STATICARRAYLEN(typeinf)) && (r < STATICARRAYLEN(typeinf)))
  1925. {
  1926. if (left == NULL)
  1927. choice = CHOOSE_LEFT; // we need to force to the lvalue.
  1928. else if (lmatrix && !rmatrix)
  1929. choice = CHOOSE_LEFT;
  1930. else if (!lmatrix && rmatrix)
  1931. choice = CHOOSE_RIGHT;
  1932. else if (lvector && !rvector)
  1933. choice = CHOOSE_LEFT;
  1934. else if (!lvector && rvector)
  1935. choice = CHOOSE_RIGHT;
  1936. else if (typeinf[l].bits > typeinf[r].bits)
  1937. choice = CHOOSE_LEFT;
  1938. else if (typeinf[l].bits < typeinf[r].bits)
  1939. choice = CHOOSE_RIGHT;
  1940. else if (typeinf[l].floating && !typeinf[r].floating)
  1941. choice = CHOOSE_LEFT;
  1942. else if (!typeinf[l].floating && typeinf[r].floating)
  1943. choice = CHOOSE_RIGHT;
  1944. else if (typeinf[l].is_unsigned && !typeinf[r].is_unsigned)
  1945. choice = CHOOSE_LEFT;
  1946. else if (!typeinf[l].is_unsigned && typeinf[r].is_unsigned)
  1947. choice = CHOOSE_RIGHT;
  1948. } // if
  1949. if (choice == CHOOSE_LEFT)
  1950. {
  1951. *right = new_cast_expr(ctx, _ldatatype, *right);
  1952. return _ldatatype;
  1953. } // if
  1954. else if (choice == CHOOSE_RIGHT)
  1955. {
  1956. *left = new_cast_expr(ctx, _rdatatype, *left);
  1957. return _rdatatype;
  1958. } // else if
  1959. assert(choice == CHOOSE_NEITHER);
  1960. fail(ctx, "incompatible data types");
  1961. // Ditch original (*right), force a literal value that matches
  1962. // ldatatype, so further processing is normalized.
  1963. // !!! FIXME: force (right) to match (left).
  1964. delete_expr(ctx, *right);
  1965. *right = new_cast_expr(ctx, _ldatatype, new_literal_int_expr(ctx, 0));
  1966. return ldatatype;
  1967. } // add_type_coercion
  1968. static int is_swizzle_str(const char *str, const int veclen)
  1969. {
  1970. int i;
  1971. int is_xyzw = 0;
  1972. int is_rgba = 0;
  1973. assert(*str != '\0'); // can this actually happen?
  1974. for (i = 0; i < veclen; i++, str++)
  1975. {
  1976. const char ch = *str;
  1977. if (ch == '\0')
  1978. break;
  1979. else if ((ch == 'x') || (ch == 'y') || (ch == 'z') || (ch == 'w'))
  1980. is_xyzw = 1;
  1981. else if ((ch == 'r') || (ch == 'g') || (ch == 'b') || (ch == 'a'))
  1982. is_rgba = 1;
  1983. } // for
  1984. if (*str != '\0') // must be end of string here.
  1985. return 0; // not a swizzle.
  1986. return ((is_rgba + is_xyzw) == 1); // can only be one or the other.
  1987. } // is_swizzle_str
  1988. static int datatype_size(const MOJOSHADER_astDataType *dt)
  1989. {
  1990. switch (dt->type)
  1991. {
  1992. case MOJOSHADER_AST_DATATYPE_BOOL: return 1;
  1993. case MOJOSHADER_AST_DATATYPE_INT: return 4;
  1994. case MOJOSHADER_AST_DATATYPE_UINT: return 4;
  1995. case MOJOSHADER_AST_DATATYPE_FLOAT: return 4;
  1996. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM: return 4;
  1997. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM: return 4;
  1998. case MOJOSHADER_AST_DATATYPE_HALF: return 2;
  1999. case MOJOSHADER_AST_DATATYPE_DOUBLE: return 8;
  2000. return 1;
  2001. default:
  2002. assert(0 && "Maybe should have used reduce_datatype()?");
  2003. return 0;
  2004. } // switch
  2005. } // datatype_size
  2006. static inline int is_scalar_datatype(const MOJOSHADER_astDataType *dt)
  2007. {
  2008. switch (dt->type)
  2009. {
  2010. case MOJOSHADER_AST_DATATYPE_BOOL:
  2011. case MOJOSHADER_AST_DATATYPE_INT:
  2012. case MOJOSHADER_AST_DATATYPE_UINT:
  2013. case MOJOSHADER_AST_DATATYPE_FLOAT:
  2014. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM:
  2015. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM:
  2016. case MOJOSHADER_AST_DATATYPE_HALF:
  2017. case MOJOSHADER_AST_DATATYPE_DOUBLE:
  2018. return 1;
  2019. default:
  2020. return 0;
  2021. } // switch
  2022. } // is_scalar_datatype
  2023. static inline int is_float_datatype(const MOJOSHADER_astDataType *dt)
  2024. {
  2025. switch (dt->type)
  2026. {
  2027. case MOJOSHADER_AST_DATATYPE_FLOAT: return 1;
  2028. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM: return 1;
  2029. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM: return 1;
  2030. default: return 0;
  2031. } // switch
  2032. } // is_float_datatype
  2033. static int datatype_elems(Context *ctx, const MOJOSHADER_astDataType *dt)
  2034. {
  2035. dt = reduce_datatype(ctx, dt);
  2036. switch (dt->type)
  2037. {
  2038. case MOJOSHADER_AST_DATATYPE_VECTOR:
  2039. return dt->vector.elements;
  2040. case MOJOSHADER_AST_DATATYPE_MATRIX:
  2041. return dt->matrix.rows * dt->matrix.columns;
  2042. default:
  2043. return 1;
  2044. } // switch
  2045. } // datatype_elems
  2046. static const MOJOSHADER_astDataType *datatype_base(Context *ctx, const MOJOSHADER_astDataType *dt)
  2047. {
  2048. dt = reduce_datatype(ctx, dt);
  2049. if (dt == NULL)
  2050. return dt;
  2051. switch (dt->type)
  2052. {
  2053. case MOJOSHADER_AST_DATATYPE_VECTOR:
  2054. dt = dt->vector.base;
  2055. break;
  2056. case MOJOSHADER_AST_DATATYPE_MATRIX:
  2057. dt = dt->matrix.base;
  2058. break;
  2059. case MOJOSHADER_AST_DATATYPE_BUFFER:
  2060. dt = dt->buffer.base;
  2061. break;
  2062. case MOJOSHADER_AST_DATATYPE_ARRAY:
  2063. dt = dt->array.base;
  2064. break;
  2065. default: break;
  2066. } // switch
  2067. return dt;
  2068. } // datatype_base
  2069. typedef enum
  2070. {
  2071. DT_MATCH_INCOMPATIBLE, // flatly incompatible
  2072. DT_MATCH_COMPATIBLE_DOWNCAST, // would have to lose precision
  2073. DT_MATCH_COMPATIBLE_UPCAST, // would have to gain precision
  2074. DT_MATCH_COMPATIBLE, // can cast to without serious change.
  2075. DT_MATCH_PERFECT // identical datatype.
  2076. } DatatypeMatch;
  2077. static DatatypeMatch compatible_arg_datatype(Context *ctx,
  2078. const MOJOSHADER_astDataType *arg,
  2079. const MOJOSHADER_astDataType *param)
  2080. {
  2081. // The matching rules for HLSL function overloading, as far as I can
  2082. // tell from experimenting with Microsoft's compiler, seem to be this:
  2083. //
  2084. // - All parameters of a function must match what the caller specified
  2085. // after possible type promotion via the following rules.
  2086. // - If the number of arguments and the number of parameters don't match,
  2087. // that overload is immediately rejected.
  2088. // - Each overloaded function is given a score that is the sum of the
  2089. // "worth" of each parameter vs the caller's arguments
  2090. // (see DatatypeMatch). The higher the score, the more favorable this
  2091. // function overload would be.
  2092. // - If there is a tie for highest score between two or more function
  2093. // overloads, we declare that function call to be ambiguous and fail().
  2094. // - Scalars can be promoted to vectors to make a parameter match.
  2095. // - Scalars can promote to other scalars (short to int, etc).
  2096. // - Datatypes can downcast, but should generate a warning.
  2097. // (calling void fn(float x); as fn((double)1.0) should warn).
  2098. // - Vectors may NOT be extend (a float2 can't implicity extend to a
  2099. // float4).
  2100. // - Vectors with the same elements can promote (a half2 can become
  2101. // a float2). Downcasting between vectors with the same number of
  2102. // elements is allowed.
  2103. // - A perfect match of all params will be favored over any functions
  2104. // that only match if type promotion is applied (given a perfect match
  2105. // of all parameters, we'll stop looking for other matches).
  2106. if (datatypes_match(arg, param))
  2107. return DT_MATCH_PERFECT; // that was easy.
  2108. arg = reduce_datatype(ctx, arg);
  2109. param = reduce_datatype(ctx, param);
  2110. int do_base_test = 0;
  2111. if (is_scalar_datatype(arg))
  2112. do_base_test = 1; // we let these all go through for now.
  2113. else if (arg->type == param->type)
  2114. {
  2115. if (arg->type == MOJOSHADER_AST_DATATYPE_VECTOR)
  2116. do_base_test = (arg->vector.elements == param->vector.elements);
  2117. else if (arg->type == MOJOSHADER_AST_DATATYPE_MATRIX)
  2118. {
  2119. do_base_test =
  2120. ((arg->matrix.rows == param->matrix.rows) &&
  2121. (arg->matrix.columns == param->matrix.columns));
  2122. } // if
  2123. } // if
  2124. if (do_base_test)
  2125. {
  2126. arg = datatype_base(ctx, arg);
  2127. param = datatype_base(ctx, param);
  2128. const int argsize = datatype_size(arg);
  2129. const int paramsize = datatype_size(param);
  2130. const int argfloat = is_float_datatype(arg);
  2131. const int paramfloat = is_float_datatype(param);
  2132. if (argfloat && !paramfloat)
  2133. return DT_MATCH_COMPATIBLE_DOWNCAST; // always loss of precision.
  2134. else if (argfloat && !paramfloat)
  2135. {
  2136. if (argsize < paramsize)
  2137. return DT_MATCH_COMPATIBLE_UPCAST;
  2138. else
  2139. return DT_MATCH_COMPATIBLE_DOWNCAST; // loss of precision.
  2140. } // else if
  2141. else if (argsize == paramsize)
  2142. return DT_MATCH_COMPATIBLE;
  2143. else if (argsize < paramsize)
  2144. return DT_MATCH_COMPATIBLE_UPCAST;
  2145. else /* if (argsize > paramsize) */
  2146. return DT_MATCH_COMPATIBLE_DOWNCAST;
  2147. } // if
  2148. return DT_MATCH_INCOMPATIBLE;
  2149. } // compatible_arg_datatype
  2150. static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast);
  2151. // !!! FIXME: this function sucks.
  2152. static const MOJOSHADER_astDataType *match_func_to_call(Context *ctx,
  2153. MOJOSHADER_astExpressionCallFunction *ast)
  2154. {
  2155. SymbolScope *best = NULL; // best choice we find.
  2156. int best_score = 0;
  2157. MOJOSHADER_astExpressionIdentifier *ident = ast->identifier;
  2158. const char *sym = ident->identifier;
  2159. const void *value = NULL;
  2160. void *iter = NULL;
  2161. int argcount = 0;
  2162. MOJOSHADER_astArguments *args = ast->args;
  2163. while (args != NULL)
  2164. {
  2165. argcount++;
  2166. type_check_ast(ctx, args->argument);
  2167. args = args->next;
  2168. } // while;
  2169. // we do some tapdancing to handle function overloading here.
  2170. int match = 0;
  2171. while (hash_iter(ctx->variables.hash, sym, &value, &iter))
  2172. {
  2173. SymbolScope *item = (SymbolScope *) value;
  2174. const MOJOSHADER_astDataType *dt = item->datatype;
  2175. dt = reduce_datatype(ctx, dt);
  2176. // there's a locally-scoped symbol with this name? It takes precedence.
  2177. if (dt->type != MOJOSHADER_AST_DATATYPE_FUNCTION)
  2178. return dt;
  2179. const MOJOSHADER_astDataTypeFunction *dtfn = (MOJOSHADER_astDataTypeFunction *) dt;
  2180. const int perfect = argcount * ((int) DT_MATCH_PERFECT);
  2181. int score = 0;
  2182. if (argcount == dtfn->num_params) // !!! FIXME: default args.
  2183. {
  2184. args = ast->args;
  2185. int i;
  2186. for (i = 0; i < argcount; i++)
  2187. {
  2188. assert(args != NULL);
  2189. dt = args->argument->datatype;
  2190. args = args->next;
  2191. const DatatypeMatch compatible = compatible_arg_datatype(ctx, dt, dtfn->params[i]);
  2192. if (compatible == DT_MATCH_INCOMPATIBLE)
  2193. {
  2194. args = NULL;
  2195. score = 0;
  2196. break;
  2197. } // if
  2198. score += (int) compatible;
  2199. } // for
  2200. if (args != NULL)
  2201. score = 0; // too many arguments supplied. No match.
  2202. } // else
  2203. if (score == 0) // incompatible.
  2204. continue;
  2205. else if (score == perfect) // perfection! stop looking!
  2206. {
  2207. match = 1; // ignore all other compatible matches.
  2208. best = item;
  2209. break;
  2210. } // if
  2211. else if (score >= best_score) // compatible, but not perfect, match.
  2212. {
  2213. if (score == best_score)
  2214. {
  2215. match++;
  2216. // !!! FIXME: list each possible function in a fail(),
  2217. // !!! FIXME: but you can't actually fail() here, since
  2218. // !!! FIXME: this may cease to be ambiguous if we get
  2219. // !!! FIXME: a better match on a later overload.
  2220. } // if
  2221. else if (score > best_score)
  2222. {
  2223. match = 1; // reset the ambiguousness count.
  2224. best = item;
  2225. best_score = score;
  2226. } // if
  2227. } // else if
  2228. } // while
  2229. if (match > 1)
  2230. {
  2231. assert(best != NULL);
  2232. failf(ctx, "Ambiguous function call to '%s'", sym);
  2233. } // if
  2234. if (best == NULL)
  2235. {
  2236. assert(match == 0);
  2237. assert(best_score == 0);
  2238. // !!! FIXME: ident->datatype = ?
  2239. failf(ctx, "No matching function named '%s'", sym);
  2240. } // if
  2241. else
  2242. {
  2243. ident->datatype = reduce_datatype(ctx, best->datatype);
  2244. ident->index = best->index;
  2245. } // else
  2246. return ident->datatype;
  2247. } // match_func_to_call
  2248. static const MOJOSHADER_astDataType *vectype_from_base(Context *ctx,
  2249. const MOJOSHADER_astDataType *base,
  2250. const int len)
  2251. {
  2252. assert(len > 0);
  2253. assert(len <= 4);
  2254. if (len == 1) // return "float" and not "float1"
  2255. return base;
  2256. const char *typestr = NULL;
  2257. switch (base->type)
  2258. {
  2259. case MOJOSHADER_AST_DATATYPE_BOOL: typestr = "bool"; break;
  2260. case MOJOSHADER_AST_DATATYPE_INT: typestr = "int"; break;
  2261. case MOJOSHADER_AST_DATATYPE_UINT: typestr = "uint"; break;
  2262. case MOJOSHADER_AST_DATATYPE_HALF: typestr = "half"; break;
  2263. case MOJOSHADER_AST_DATATYPE_FLOAT: typestr = "float"; break;
  2264. case MOJOSHADER_AST_DATATYPE_DOUBLE: typestr = "double"; break;
  2265. default: assert(0 && "This shouldn't happen"); break;
  2266. } // switch
  2267. char buf[32];
  2268. snprintf(buf, sizeof (buf), "%s%d", typestr, len);
  2269. const MOJOSHADER_astDataType *datatype = get_usertype(ctx, buf);
  2270. assert(datatype != NULL);
  2271. return datatype;
  2272. } // vectype_from_base
  2273. // Go through the AST and make sure all datatypes check out okay. For datatypes
  2274. // that are compatible but are relying on an implicit cast, we add explicit
  2275. // casts to the AST here, so further processing doesn't have to worry about
  2276. // type coercion.
  2277. // For things that are incompatible, we generate errors and
  2278. // then replace them with reasonable defaults so further processing can
  2279. // continue (but code generation will be skipped due to errors).
  2280. // This means further processing can assume the AST is sane and not have to
  2281. // spend effort verifying it again.
  2282. // This stage will also set every AST node's datatype field, if it is
  2283. // meaningful to do so. This will allow conversion to IR to know what
  2284. // type/size a given node is.
  2285. static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)
  2286. {
  2287. MOJOSHADER_astNode *ast = (MOJOSHADER_astNode *) _ast;
  2288. const MOJOSHADER_astDataType *datatype = NULL;
  2289. const MOJOSHADER_astDataType *datatype2 = NULL;
  2290. const MOJOSHADER_astDataType *datatype3 = NULL;
  2291. if ((!ast) || (ctx->out_of_memory))
  2292. return NULL;
  2293. // upkeep so we report correct error locations...
  2294. ctx->sourcefile = ast->ast.filename;
  2295. ctx->sourceline = ast->ast.line;
  2296. switch (ast->ast.type)
  2297. {
  2298. case MOJOSHADER_AST_OP_POSTINCREMENT:
  2299. case MOJOSHADER_AST_OP_POSTDECREMENT:
  2300. case MOJOSHADER_AST_OP_PREINCREMENT:
  2301. case MOJOSHADER_AST_OP_PREDECREMENT:
  2302. case MOJOSHADER_AST_OP_COMPLEMENT:
  2303. case MOJOSHADER_AST_OP_NEGATE:
  2304. // !!! FIXME: must be lvalue.
  2305. // !!! FIXME: bools must type-promote to ...int?
  2306. // !!! FIXME: complement must not be float (...right?)
  2307. datatype = type_check_ast(ctx, ast->unary.operand);
  2308. require_numeric_datatype(ctx, datatype);
  2309. ast->unary.datatype = datatype;
  2310. return datatype;
  2311. case MOJOSHADER_AST_OP_NOT:
  2312. datatype = type_check_ast(ctx, ast->unary.operand);
  2313. require_boolean_datatype(ctx, datatype);
  2314. // !!! FIXME: coerce to bool here.
  2315. ast->unary.datatype = &ctx->dt_bool;
  2316. return datatype;
  2317. case MOJOSHADER_AST_OP_DEREF_ARRAY:
  2318. datatype = type_check_ast(ctx, ast->binary.left);
  2319. datatype2 = type_check_ast(ctx, ast->binary.right);
  2320. require_integer_datatype(ctx, datatype2);
  2321. add_type_coercion(ctx, NULL, &ctx->dt_int, &ast->binary.right, datatype2);
  2322. datatype = reduce_datatype(ctx, datatype);
  2323. if (datatype->type == MOJOSHADER_AST_DATATYPE_VECTOR)
  2324. {
  2325. // !!! FIXME: if constant int, fail if not 0 >= value <= vecsize.
  2326. ast->binary.datatype = datatype->vector.base;
  2327. } // if
  2328. else if (datatype->type == MOJOSHADER_AST_DATATYPE_MATRIX)
  2329. {
  2330. // !!! FIXME: if constant int, fail if not 0 >= value <= rowsize (colsize?).
  2331. ast->binary.datatype = vectype_from_base(ctx, datatype->matrix.base, datatype->matrix.columns); // !!! FIXME: rows?
  2332. }
  2333. else
  2334. {
  2335. require_array_datatype(ctx, datatype);
  2336. ast->binary.datatype = array_element_datatype(ctx, datatype);
  2337. } // else
  2338. return ast->binary.datatype;
  2339. case MOJOSHADER_AST_OP_DEREF_STRUCT:
  2340. {
  2341. const char *member = ast->derefstruct.member;
  2342. datatype = type_check_ast(ctx, ast->derefstruct.identifier);
  2343. const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, datatype);
  2344. // Is this a swizzle and not a struct deref?
  2345. if (reduced->type == MOJOSHADER_AST_DATATYPE_VECTOR)
  2346. {
  2347. const int veclen = reduced->vector.elements;
  2348. ast->derefstruct.isswizzle = 1;
  2349. if (!is_swizzle_str(member, veclen))
  2350. {
  2351. fail(ctx, "invalid swizzle on vector");
  2352. // force this to be sane for further processing.
  2353. const char *sane_swiz = stringcache(ctx->strcache, "xyzw");
  2354. member = ast->derefstruct.member = sane_swiz;
  2355. } // if
  2356. const int swizlen = (int) strlen(member);
  2357. if (swizlen != veclen)
  2358. datatype = vectype_from_base(ctx, reduced->vector.base, swizlen);
  2359. ast->derefstruct.datatype = datatype;
  2360. return ast->derefstruct.datatype;
  2361. } // if
  2362. // maybe this is an actual struct?
  2363. // !!! FIXME: replace with an int or something if not.
  2364. require_struct_datatype(ctx, reduced);
  2365. // map member to datatype
  2366. assert(ast->derefstruct.datatype == NULL);
  2367. const MOJOSHADER_astDataTypeStructMember *mbrs = reduced->structure.members;
  2368. int i;
  2369. for (i = 0; i < reduced->structure.member_count; i++)
  2370. {
  2371. if (strcmp(mbrs[i].identifier, member) == 0)
  2372. {
  2373. ast->derefstruct.datatype = mbrs[i].datatype;
  2374. ast->derefstruct.member_index = i;
  2375. break;
  2376. } // if
  2377. } // for
  2378. if (ast->derefstruct.datatype == NULL)
  2379. {
  2380. // !!! FIXME: replace with an int or something.
  2381. failf(ctx, "Struct has no member named '%s'", member);
  2382. } // if
  2383. return ast->derefstruct.datatype;
  2384. } // case
  2385. case MOJOSHADER_AST_OP_COMMA:
  2386. // evaluate and throw away left, return right.
  2387. type_check_ast(ctx, ast->binary.left);
  2388. ast->binary.datatype = type_check_ast(ctx, ast->binary.right);
  2389. return ast->binary.datatype;
  2390. case MOJOSHADER_AST_OP_MULTIPLY:
  2391. case MOJOSHADER_AST_OP_DIVIDE:
  2392. case MOJOSHADER_AST_OP_ADD:
  2393. case MOJOSHADER_AST_OP_SUBTRACT:
  2394. datatype = type_check_ast(ctx, ast->binary.left);
  2395. datatype2 = type_check_ast(ctx, ast->binary.right);
  2396. require_numeric_datatype(ctx, datatype);
  2397. require_numeric_datatype(ctx, datatype2);
  2398. ast->binary.datatype = add_type_coercion(ctx, &ast->binary.left,
  2399. datatype, &ast->binary.right, datatype2);
  2400. return ast->binary.datatype;
  2401. case MOJOSHADER_AST_OP_LSHIFT:
  2402. case MOJOSHADER_AST_OP_RSHIFT:
  2403. case MOJOSHADER_AST_OP_MODULO:
  2404. datatype = type_check_ast(ctx, ast->binary.left);
  2405. datatype2 = type_check_ast(ctx, ast->binary.right);
  2406. require_integer_datatype(ctx, datatype);
  2407. require_integer_datatype(ctx, datatype2);
  2408. ast->binary.datatype = add_type_coercion(ctx, &ast->binary.left,
  2409. datatype, &ast->binary.right, datatype2);
  2410. return ast->binary.datatype;
  2411. case MOJOSHADER_AST_OP_LESSTHAN:
  2412. case MOJOSHADER_AST_OP_GREATERTHAN:
  2413. case MOJOSHADER_AST_OP_LESSTHANOREQUAL:
  2414. case MOJOSHADER_AST_OP_GREATERTHANOREQUAL:
  2415. case MOJOSHADER_AST_OP_NOTEQUAL:
  2416. case MOJOSHADER_AST_OP_EQUAL:
  2417. datatype = type_check_ast(ctx, ast->binary.left);
  2418. datatype2 = type_check_ast(ctx, ast->binary.right);
  2419. add_type_coercion(ctx, &ast->binary.left, datatype,
  2420. &ast->binary.right, datatype2);
  2421. ast->binary.datatype = &ctx->dt_bool;
  2422. return ast->binary.datatype;
  2423. case MOJOSHADER_AST_OP_BINARYAND:
  2424. case MOJOSHADER_AST_OP_BINARYXOR:
  2425. case MOJOSHADER_AST_OP_BINARYOR:
  2426. datatype = type_check_ast(ctx, ast->binary.left);
  2427. datatype2 = type_check_ast(ctx, ast->binary.right);
  2428. require_integer_datatype(ctx, datatype);
  2429. require_integer_datatype(ctx, datatype2);
  2430. ast->binary.datatype = add_type_coercion(ctx, &ast->binary.left,
  2431. datatype, &ast->binary.right, datatype2);
  2432. return ast->binary.datatype;
  2433. case MOJOSHADER_AST_OP_LOGICALAND:
  2434. case MOJOSHADER_AST_OP_LOGICALOR:
  2435. datatype = type_check_ast(ctx, ast->binary.left);
  2436. datatype2 = type_check_ast(ctx, ast->binary.right);
  2437. require_boolean_datatype(ctx, datatype);
  2438. require_boolean_datatype(ctx, datatype2);
  2439. // !!! FIXME: coerce each to bool here, separately.
  2440. add_type_coercion(ctx, &ast->binary.left, datatype,
  2441. &ast->binary.right, datatype2);
  2442. ast->binary.datatype = &ctx->dt_bool;
  2443. case MOJOSHADER_AST_OP_ASSIGN:
  2444. case MOJOSHADER_AST_OP_MULASSIGN:
  2445. case MOJOSHADER_AST_OP_DIVASSIGN:
  2446. case MOJOSHADER_AST_OP_MODASSIGN:
  2447. case MOJOSHADER_AST_OP_ADDASSIGN:
  2448. case MOJOSHADER_AST_OP_SUBASSIGN:
  2449. case MOJOSHADER_AST_OP_LSHIFTASSIGN:
  2450. case MOJOSHADER_AST_OP_RSHIFTASSIGN:
  2451. case MOJOSHADER_AST_OP_ANDASSIGN:
  2452. case MOJOSHADER_AST_OP_XORASSIGN:
  2453. case MOJOSHADER_AST_OP_ORASSIGN:
  2454. // !!! FIXME: verify binary.left is an lvalue, or fail()!
  2455. datatype = type_check_ast(ctx, ast->binary.left);
  2456. datatype2 = type_check_ast(ctx, ast->binary.right);
  2457. ast->binary.datatype = add_type_coercion(ctx, NULL, datatype,
  2458. &ast->binary.right, datatype2);
  2459. return ast->binary.datatype;
  2460. case MOJOSHADER_AST_OP_CONDITIONAL:
  2461. datatype = type_check_ast(ctx, ast->ternary.left);
  2462. datatype2 = type_check_ast(ctx, ast->ternary.center);
  2463. datatype3 = type_check_ast(ctx, ast->ternary.right);
  2464. require_numeric_datatype(ctx, datatype);
  2465. ast->ternary.datatype = add_type_coercion(ctx, &ast->ternary.center,
  2466. datatype2, &ast->ternary.right, datatype3);
  2467. return ast->ternary.datatype;
  2468. case MOJOSHADER_AST_OP_IDENTIFIER:
  2469. datatype = find_variable(ctx, ast->identifier.identifier, &ast->identifier.index);
  2470. if (datatype == NULL)
  2471. {
  2472. fail(ctx, "Unknown identifier");
  2473. // !!! FIXME: replace with a sane default, move on.
  2474. datatype = &ctx->dt_int;
  2475. } // if
  2476. ast->identifier.datatype = datatype;
  2477. return ast->identifier.datatype;
  2478. case MOJOSHADER_AST_OP_INT_LITERAL:
  2479. case MOJOSHADER_AST_OP_FLOAT_LITERAL:
  2480. case MOJOSHADER_AST_OP_STRING_LITERAL:
  2481. case MOJOSHADER_AST_OP_BOOLEAN_LITERAL:
  2482. assert(ast->expression.datatype != NULL);
  2483. return ast->expression.datatype; // already set up during parsing.
  2484. case MOJOSHADER_AST_ARGUMENTS:
  2485. assert(0 && "Should be done by MOJOSHADER_AST_OP_CALLFUNC/CONSTRUCTOR");
  2486. return NULL;
  2487. case MOJOSHADER_AST_OP_CALLFUNC:
  2488. {
  2489. datatype = match_func_to_call(ctx, &ast->callfunc);
  2490. const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, datatype);
  2491. // !!! FIXME: replace AST node with an int if this isn't a func.
  2492. if (!require_function_datatype(ctx, reduced))
  2493. {
  2494. ast->callfunc.datatype = &ctx->dt_int;
  2495. return ast->callfunc.datatype;
  2496. } // if
  2497. MOJOSHADER_astArguments *arg = ast->callfunc.args;
  2498. int i;
  2499. for (i = 0; i < reduced->function.num_params; i++)
  2500. {
  2501. if (arg == NULL) // !!! FIXME: check for default parameters, fill them in.
  2502. {
  2503. fail(ctx, "Too few arguments");
  2504. // !!! FIXME: replace AST here.
  2505. break;
  2506. } // if
  2507. datatype2 = arg->argument->datatype; // already type-checked.
  2508. add_type_coercion(ctx, NULL, reduced->function.params[i],
  2509. &arg->argument, datatype2);
  2510. arg = arg->next;
  2511. } // for
  2512. assert(arg == NULL); // shouldn't have chosen func if too many args.
  2513. ast->callfunc.datatype = reduced->function.retval;
  2514. return ast->callfunc.datatype;
  2515. } // case
  2516. case MOJOSHADER_AST_OP_CONSTRUCTOR:
  2517. {
  2518. const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, ast->constructor.datatype);
  2519. const MOJOSHADER_astDataType *base_dt = reduced;
  2520. int num_params = 1;
  2521. assert(reduced != NULL);
  2522. switch (reduced->type)
  2523. {
  2524. case MOJOSHADER_AST_DATATYPE_VECTOR:
  2525. num_params = reduced->vector.elements;
  2526. base_dt = reduced->vector.base;
  2527. break;
  2528. case MOJOSHADER_AST_DATATYPE_MATRIX:
  2529. num_params = reduced->matrix.rows * reduced->matrix.columns;
  2530. base_dt = reduced->matrix.base;
  2531. break;
  2532. case MOJOSHADER_AST_DATATYPE_BOOL:
  2533. case MOJOSHADER_AST_DATATYPE_INT:
  2534. case MOJOSHADER_AST_DATATYPE_UINT:
  2535. case MOJOSHADER_AST_DATATYPE_FLOAT:
  2536. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM:
  2537. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM:
  2538. case MOJOSHADER_AST_DATATYPE_HALF:
  2539. case MOJOSHADER_AST_DATATYPE_DOUBLE:
  2540. case MOJOSHADER_AST_DATATYPE_STRING:
  2541. num_params = 1;
  2542. break;
  2543. // !!! FIXME: can you construct a MOJOSHADER_AST_DATATYPE_STRUCT?
  2544. // !!! FIXME: can you construct a MOJOSHADER_AST_DATATYPE_ARRAY?
  2545. // !!! FIXME: can you construct a MOJOSHADER_AST_DATATYPE_BUFFER?
  2546. default:
  2547. fail(ctx, "Invalid type for constructor");
  2548. delete_arguments(ctx, ast->constructor.args);
  2549. ast->constructor.args = new_argument(ctx, new_literal_int_expr(ctx, 0));
  2550. ast->constructor.datatype = &ctx->dt_int;
  2551. return ast->constructor.datatype;
  2552. } // switch
  2553. assert(num_params > 0);
  2554. MOJOSHADER_astArguments *arg = ast->constructor.args;
  2555. MOJOSHADER_astArguments *prev = NULL;
  2556. int i;
  2557. for (i = 0; i < num_params; i++)
  2558. {
  2559. if (arg == NULL) // !!! FIXME: check for default parameters.
  2560. {
  2561. fail(ctx, "Too few arguments");
  2562. // !!! FIXME: replace AST here.
  2563. break;
  2564. } // if
  2565. datatype2 = type_check_ast(ctx, arg->argument);
  2566. // "float4(float3(1,2,3),4)" is legal, so we need to see if
  2567. // we're a vector, and jump that number of parameters instead
  2568. // of doing type coercion.
  2569. reduced = reduce_datatype(ctx, datatype2);
  2570. if (reduced->type == MOJOSHADER_AST_DATATYPE_VECTOR)
  2571. {
  2572. // make sure things like float4(half3(1,2,3),1) convert that half3 to float3.
  2573. const int count = reduced->vector.elements;
  2574. datatype3 = vectype_from_base(ctx, base_dt, count);
  2575. add_type_coercion(ctx, NULL, datatype3, &arg->argument, datatype2);
  2576. i += count - 1;
  2577. } // else
  2578. else
  2579. {
  2580. add_type_coercion(ctx, NULL, base_dt, &arg->argument, datatype2);
  2581. } // else
  2582. prev = arg;
  2583. arg = arg->next;
  2584. } // for
  2585. if (arg != NULL)
  2586. {
  2587. fail(ctx, "Too many arguments");
  2588. // Process extra arguments then chop them out.
  2589. MOJOSHADER_astArguments *argi;
  2590. for (argi = arg; argi != NULL; argi = argi->next)
  2591. type_check_ast(ctx, argi->argument);
  2592. if (prev != NULL)
  2593. prev->next = NULL;
  2594. delete_arguments(ctx, arg);
  2595. } // if
  2596. return ast->constructor.datatype;
  2597. } // case
  2598. case MOJOSHADER_AST_OP_CAST:
  2599. datatype = sanitize_datatype(ctx, ast->cast.datatype);
  2600. datatype2 = type_check_ast(ctx, ast->cast.operand);
  2601. // you still need type coercion, since you could do a wrong cast,
  2602. // like "int x = (short) mychar;"
  2603. add_type_coercion(ctx, NULL, datatype, &ast->cast.operand, datatype2);
  2604. return datatype;
  2605. case MOJOSHADER_AST_STATEMENT_BREAK:
  2606. if ((ctx->loop_count == 0) && (ctx->switch_count == 0))
  2607. fail(ctx, "Break outside loop or switch");
  2608. // !!! FIXME: warn if unreachable statements follow?
  2609. type_check_ast(ctx, ast->stmt.next);
  2610. return NULL;
  2611. case MOJOSHADER_AST_STATEMENT_CONTINUE:
  2612. if (ctx->loop_count == 0)
  2613. fail(ctx, "Continue outside loop");
  2614. // !!! FIXME: warn if unreachable statements follow?
  2615. type_check_ast(ctx, ast->stmt.next);
  2616. return NULL;
  2617. case MOJOSHADER_AST_STATEMENT_DISCARD:
  2618. // !!! FIXME: warn if unreachable statements follow?
  2619. type_check_ast(ctx, ast->stmt.next);
  2620. return NULL;
  2621. case MOJOSHADER_AST_STATEMENT_EMPTY:
  2622. type_check_ast(ctx, ast->stmt.next);
  2623. return NULL;
  2624. case MOJOSHADER_AST_STATEMENT_EXPRESSION:
  2625. // !!! FIXME: warn about expressions without a side-effect here?
  2626. type_check_ast(ctx, ast->exprstmt.expr); // !!! FIXME: This is named badly...
  2627. type_check_ast(ctx, ast->exprstmt.next);
  2628. return NULL;
  2629. case MOJOSHADER_AST_STATEMENT_IF:
  2630. push_scope(ctx); // new scope for "if ((int x = blah()) != 0)"
  2631. type_check_ast(ctx, ast->ifstmt.expr);
  2632. type_check_ast(ctx, ast->ifstmt.statement);
  2633. pop_scope(ctx);
  2634. type_check_ast(ctx, ast->ifstmt.next);
  2635. return NULL;
  2636. case MOJOSHADER_AST_STATEMENT_TYPEDEF:
  2637. type_check_ast(ctx, ast->typedefstmt.type_info);
  2638. type_check_ast(ctx, ast->typedefstmt.next);
  2639. return NULL;
  2640. case MOJOSHADER_AST_STATEMENT_SWITCH:
  2641. {
  2642. ctx->switch_count++;
  2643. MOJOSHADER_astSwitchCases *cases = ast->switchstmt.cases;
  2644. // !!! FIXME: expr must be POD (no structs, arrays, etc!).
  2645. datatype = type_check_ast(ctx, ast->switchstmt.expr);
  2646. while (cases)
  2647. {
  2648. // !!! FIXME: case must be POD (no structs, arrays, etc!).
  2649. datatype2 = type_check_ast(ctx, cases->expr);
  2650. add_type_coercion(ctx, NULL, datatype,
  2651. &cases->expr, datatype2);
  2652. type_check_ast(ctx, cases->statement);
  2653. cases = cases->next;
  2654. } // while
  2655. ctx->switch_count--;
  2656. type_check_ast(ctx, ast->switchstmt.next);
  2657. return NULL;
  2658. } // case
  2659. case MOJOSHADER_AST_SWITCH_CASE:
  2660. assert(0 && "Should be done by MOJOSHADER_AST_STATEMENT_SWITCH.");
  2661. return NULL;
  2662. case MOJOSHADER_AST_STATEMENT_STRUCT:
  2663. type_check_ast(ctx, ast->structstmt.struct_info);
  2664. type_check_ast(ctx, ast->structstmt.next);
  2665. return NULL;
  2666. case MOJOSHADER_AST_STATEMENT_VARDECL:
  2667. type_check_ast(ctx, ast->vardeclstmt.declaration);
  2668. type_check_ast(ctx, ast->vardeclstmt.next);
  2669. return NULL;
  2670. case MOJOSHADER_AST_STATEMENT_BLOCK:
  2671. push_scope(ctx); // new vars declared here live until '}'.
  2672. type_check_ast(ctx, ast->blockstmt.statements);
  2673. pop_scope(ctx);
  2674. type_check_ast(ctx, ast->blockstmt.next);
  2675. return NULL;
  2676. case MOJOSHADER_AST_STATEMENT_FOR:
  2677. ctx->loop_count++;
  2678. push_scope(ctx); // new scope for "for (int x = 0; ...)"
  2679. type_check_ast(ctx, ast->forstmt.var_decl);
  2680. type_check_ast(ctx, ast->forstmt.initializer);
  2681. type_check_ast(ctx, ast->forstmt.looptest);
  2682. type_check_ast(ctx, ast->forstmt.counter);
  2683. type_check_ast(ctx, ast->forstmt.statement);
  2684. pop_scope(ctx);
  2685. ctx->loop_count--;
  2686. type_check_ast(ctx, ast->forstmt.next);
  2687. return NULL;
  2688. case MOJOSHADER_AST_STATEMENT_DO:
  2689. ctx->loop_count++;
  2690. // !!! FIXME: should there be a push_scope() here?
  2691. type_check_ast(ctx, ast->dostmt.statement);
  2692. push_scope(ctx); // new scope for "while ((int x = blah()) != 0)"
  2693. type_check_ast(ctx, ast->dostmt.expr);
  2694. pop_scope(ctx);
  2695. ctx->loop_count--;
  2696. type_check_ast(ctx, ast->dostmt.next);
  2697. return NULL;
  2698. case MOJOSHADER_AST_STATEMENT_WHILE:
  2699. ctx->loop_count++;
  2700. push_scope(ctx); // new scope for "while ((int x = blah()) != 0)"
  2701. type_check_ast(ctx, ast->whilestmt.expr);
  2702. type_check_ast(ctx, ast->whilestmt.statement);
  2703. pop_scope(ctx);
  2704. ctx->loop_count--;
  2705. type_check_ast(ctx, ast->whilestmt.next);
  2706. return NULL;
  2707. case MOJOSHADER_AST_STATEMENT_RETURN:
  2708. // !!! FIXME: type coercion to outer function's return type.
  2709. // !!! FIXME: warn if unreachable statements follow?
  2710. type_check_ast(ctx, ast->returnstmt.expr);
  2711. type_check_ast(ctx, ast->returnstmt.next);
  2712. return NULL;
  2713. case MOJOSHADER_AST_COMPUNIT_FUNCTION:
  2714. assert(!ctx->is_func_scope);
  2715. // We have to tapdance here to make sure the function is in
  2716. // the global scope, but it's parameters are pushed as variables
  2717. // in the function's scope.
  2718. datatype = type_check_ast(ctx, ast->funcunit.declaration);
  2719. ast->funcunit.index = push_function(ctx,
  2720. ast->funcunit.declaration->identifier,
  2721. datatype, ast->funcunit.definition == NULL);
  2722. // not just a declaration, but a full function definition?
  2723. if (ast->funcunit.definition != NULL)
  2724. {
  2725. assert(ctx->loop_count == 0);
  2726. assert(ctx->switch_count == 0);
  2727. ctx->is_func_scope = 1;
  2728. ctx->var_index = 0; // reset this every function.
  2729. push_scope(ctx); // so function params are in function scope.
  2730. // repush the parameters before checking the actual function.
  2731. MOJOSHADER_astFunctionParameters *param;
  2732. for (param = ast->funcunit.declaration->params; param; param = param->next)
  2733. push_variable(ctx, param->identifier, param->datatype);
  2734. type_check_ast(ctx, ast->funcunit.definition);
  2735. pop_scope(ctx);
  2736. ctx->is_func_scope = 0;
  2737. assert(ctx->loop_count == 0);
  2738. assert(ctx->switch_count == 0);
  2739. } // else
  2740. type_check_ast(ctx, ast->funcunit.next);
  2741. return NULL;
  2742. case MOJOSHADER_AST_COMPUNIT_TYPEDEF:
  2743. type_check_ast(ctx, ast->typedefunit.type_info);
  2744. type_check_ast(ctx, ast->typedefunit.next);
  2745. return NULL;
  2746. case MOJOSHADER_AST_COMPUNIT_STRUCT:
  2747. type_check_ast(ctx, ast->structunit.struct_info);
  2748. type_check_ast(ctx, ast->structunit.next);
  2749. return NULL;
  2750. case MOJOSHADER_AST_COMPUNIT_VARIABLE:
  2751. type_check_ast(ctx, ast->varunit.declaration);
  2752. type_check_ast(ctx, ast->varunit.next);
  2753. return NULL;
  2754. case MOJOSHADER_AST_SCALAR_OR_ARRAY:
  2755. assert(0 && "Should be done by other AST nodes.");
  2756. return NULL;
  2757. case MOJOSHADER_AST_TYPEDEF:
  2758. {
  2759. MOJOSHADER_astScalarOrArray *soa = ast->typdef.details;
  2760. datatype = get_usertype(ctx, soa->identifier);
  2761. if (datatype != NULL)
  2762. {
  2763. fail(ctx, "typedef already defined");
  2764. ast->typdef.datatype = datatype;
  2765. return datatype;
  2766. } // if
  2767. datatype = build_datatype(ctx, ast->typdef.isconst,
  2768. ast->typdef.datatype, soa);
  2769. if (datatype == NULL)
  2770. return NULL; // out of memory?
  2771. push_usertype(ctx, soa->identifier, datatype);
  2772. ast->typdef.datatype = datatype;
  2773. return ast->typdef.datatype;
  2774. } // case
  2775. case MOJOSHADER_AST_FUNCTION_PARAMS:
  2776. assert(0 && "Should be done by MOJOSHADER_AST_FUNCTION_SIGNATURE");
  2777. case MOJOSHADER_AST_FUNCTION_SIGNATURE:
  2778. {
  2779. MOJOSHADER_astFunctionParameters *param;
  2780. const MOJOSHADER_astDataType *dtparams[64];
  2781. int i = 0;
  2782. for (param = ast->funcsig.params; param; param = param->next)
  2783. {
  2784. assert(i <= STATICARRAYLEN(dtparams)); // laziness.
  2785. sanitize_datatype(ctx, param->datatype);
  2786. if (param->initializer != NULL)
  2787. {
  2788. datatype2 = type_check_ast(ctx, param->initializer);
  2789. add_type_coercion(ctx, NULL, param->datatype,
  2790. &param->initializer, datatype2);
  2791. } // if
  2792. dtparams[i] = param->datatype;
  2793. i++;
  2794. } // for
  2795. ast->funcsig.datatype = build_function_datatype(ctx,
  2796. ast->funcsig.datatype,
  2797. i, dtparams, 0);
  2798. return ast->funcsig.datatype;
  2799. } // case
  2800. case MOJOSHADER_AST_STRUCT_DECLARATION:
  2801. {
  2802. // !!! FIXME: We don't handle struct predeclaration at all right now
  2803. // !!! FIXME: (neither does the grammar)...not only does that mean
  2804. // !!! FIXME: you need to know the struct definition up front, but
  2805. // !!! FIXME: you can't do "struct XXX *next;" for a self-referencing
  2806. // !!! FIXME: linked list struct thing. This probably isn't a big
  2807. // !!! FIXME: deal, as there aren't (CURRENTLY!) pointers in HLSL,
  2808. // !!! FIXME: but you never know.
  2809. const MOJOSHADER_astStructMembers *mbrs;
  2810. // !!! FIXME: count this during parsing?
  2811. int count = 0;
  2812. mbrs = ast->structdecl.members;
  2813. while (mbrs != NULL)
  2814. {
  2815. count++;
  2816. mbrs = mbrs->next;
  2817. } // while
  2818. // !!! FIXME: this is hacky.
  2819. MOJOSHADER_astDataTypeStructMember *dtmbrs;
  2820. void *ptr = Malloc(ctx, sizeof (*dtmbrs) * count);
  2821. if (ptr == NULL)
  2822. return NULL;
  2823. if (!buffer_append(ctx->garbage, &ptr, sizeof (ptr)))
  2824. {
  2825. Free(ctx, ptr);
  2826. return NULL;
  2827. } // if
  2828. dtmbrs = (MOJOSHADER_astDataTypeStructMember *) ptr;
  2829. ptr = Malloc(ctx, sizeof (MOJOSHADER_astDataType));
  2830. if (ptr == NULL)
  2831. return NULL;
  2832. if (!buffer_append(ctx->garbage, &ptr, sizeof (ptr)))
  2833. {
  2834. Free(ctx, ptr);
  2835. return NULL;
  2836. } // if
  2837. MOJOSHADER_astDataType *dt = (MOJOSHADER_astDataType *) ptr;
  2838. mbrs = ast->structdecl.members;
  2839. int i;
  2840. for (i = 0; i < count; i++)
  2841. {
  2842. // !!! FIXME: current grammar forbids const keyword on struct members!
  2843. dtmbrs[i].datatype = build_datatype(ctx, 0, mbrs->datatype, mbrs->details);
  2844. dtmbrs[i].identifier = mbrs->details->identifier; // cached!
  2845. mbrs = mbrs->next;
  2846. } // for
  2847. dt->structure.type = MOJOSHADER_AST_DATATYPE_STRUCT;
  2848. dt->structure.members = dtmbrs;
  2849. dt->structure.member_count = count;
  2850. ast->structdecl.datatype = dt;
  2851. // !!! FIXME: this shouldn't push for anonymous structs: "struct { int x; } myvar;"
  2852. // !!! FIXME: but right now, the grammar is wrong and requires a name for the struct.
  2853. push_usertype(ctx, ast->structdecl.name, ast->structdecl.datatype);
  2854. return ast->structdecl.datatype;
  2855. } // case
  2856. case MOJOSHADER_AST_STRUCT_MEMBER:
  2857. assert(0 && "Should be done by MOJOSHADER_AST_STRUCT_DECLARATION.");
  2858. return NULL;
  2859. case MOJOSHADER_AST_VARIABLE_DECLARATION:
  2860. {
  2861. MOJOSHADER_astVariableDeclaration *decl = &ast->vardecl;
  2862. // this is true now, but we'll fill in ->datatype no matter what.
  2863. assert((decl->datatype && !decl->anonymous_datatype) ||
  2864. (!decl->datatype && decl->anonymous_datatype));
  2865. // An anonymous struct? That AST node does the heavy lifting.
  2866. if (decl->anonymous_datatype != NULL)
  2867. datatype = type_check_ast(ctx, decl->anonymous_datatype);
  2868. else
  2869. {
  2870. datatype = build_datatype(ctx, (decl->attributes & MOJOSHADER_AST_VARATTR_CONST) != 0,
  2871. decl->datatype, decl->details);
  2872. } // else
  2873. while (decl != NULL)
  2874. {
  2875. decl->datatype = datatype;
  2876. push_variable(ctx, decl->details->identifier, datatype);
  2877. if (decl->initializer != NULL)
  2878. {
  2879. datatype2 = type_check_ast(ctx, decl->initializer);
  2880. add_type_coercion(ctx, NULL, datatype, &decl->initializer, datatype2);
  2881. } // if
  2882. type_check_ast(ctx, decl->annotations);
  2883. type_check_ast(ctx, decl->lowlevel);
  2884. decl = decl->next;
  2885. } // while
  2886. return datatype;
  2887. } // case
  2888. case MOJOSHADER_AST_ANNOTATION:
  2889. {
  2890. MOJOSHADER_astAnnotations *anno = &ast->annotations;
  2891. while (anno)
  2892. {
  2893. type_check_ast(ctx, anno->initializer);
  2894. anno = anno->next;
  2895. } // while
  2896. return NULL;
  2897. } // case
  2898. case MOJOSHADER_AST_PACK_OFFSET:
  2899. case MOJOSHADER_AST_VARIABLE_LOWLEVEL:
  2900. return NULL; // no-op (for now, at least).
  2901. default:
  2902. assert(0 && "unexpected type");
  2903. } // switch
  2904. return NULL;
  2905. } // type_check_ast
  2906. static inline void semantic_analysis(Context *ctx)
  2907. {
  2908. type_check_ast(ctx, ctx->ast);
  2909. } // semantic_analysis
  2910. // !!! FIXME: isn't this a cut-and-paste of somewhere else?
  2911. static inline int64 strtoi64(const char *str, unsigned int len)
  2912. {
  2913. int64 retval = 0;
  2914. int64 mult = 1;
  2915. int i = 0;
  2916. while ((len) && (*str == ' '))
  2917. {
  2918. str++;
  2919. len--;
  2920. } // while
  2921. if ((len) && (*str == '-'))
  2922. {
  2923. mult = -1;
  2924. str++;
  2925. len--;
  2926. } // if
  2927. while (i < len)
  2928. {
  2929. const char ch = str[i];
  2930. if ((ch < '0') || (ch > '9'))
  2931. break;
  2932. i++;
  2933. } // while
  2934. while (--i >= 0)
  2935. {
  2936. const char ch = str[i];
  2937. retval += ((int64) (ch - '0')) * mult;
  2938. mult *= 10;
  2939. } // while
  2940. return retval;
  2941. } // strtoi64
  2942. // !!! FIXME: isn't this a cut-and-paste of somewhere else?
  2943. static inline double strtodouble(const char *_str, unsigned int len)
  2944. {
  2945. // !!! FIXME: laziness prevails.
  2946. char *str = (char *) alloca(len+1);
  2947. memcpy(str, _str, len);
  2948. str[len] = '\0';
  2949. return strtod(str, NULL);
  2950. } // strtodouble
  2951. #if 0
  2952. // This does not check correctness (POSITIONT993842 passes, etc).
  2953. static int is_semantic(const Context *ctx, const char *token,
  2954. const unsigned int tokenlen)
  2955. {
  2956. static const char *names[] = {
  2957. "BINORMAL", "BLENDINDICES", "BLENDWEIGHT",
  2958. "COLOR", "NORMAL", "POSITION", "POSITIONT", "PSIZE", "TANGENT",
  2959. "TEXCOORD", "FOG", "TESSFACTOR", "TEXCOORD", "VFACE", "VPOS",
  2960. "DEPTH", NULL
  2961. };
  2962. // !!! FIXME: DX10 has SV_* ("System Value Semantics").
  2963. const char **i;
  2964. for (i = names; *i; i++)
  2965. {
  2966. const char *name = *i;
  2967. const size_t namelen = strlen(name);
  2968. if (tokenlen < namelen)
  2969. continue;
  2970. else if (memcmp(token, name, namelen) != 0)
  2971. continue;
  2972. for (name += namelen; *name; name++)
  2973. {
  2974. if ((*name < '0') || (*name > '9'))
  2975. break;
  2976. } // for
  2977. if (*name == '\0')
  2978. return 1;
  2979. } // for
  2980. return 0;
  2981. } // is_semantic
  2982. #endif
  2983. static int convert_to_lemon_token(Context *ctx, const char *token,
  2984. unsigned int tokenlen, const Token tokenval)
  2985. {
  2986. switch (tokenval)
  2987. {
  2988. case ((Token) ','): return TOKEN_HLSL_COMMA;
  2989. case ((Token) '='): return TOKEN_HLSL_ASSIGN;
  2990. case ((Token) TOKEN_ADDASSIGN): return TOKEN_HLSL_ADDASSIGN;
  2991. case ((Token) TOKEN_SUBASSIGN): return TOKEN_HLSL_SUBASSIGN;
  2992. case ((Token) TOKEN_MULTASSIGN): return TOKEN_HLSL_MULASSIGN;
  2993. case ((Token) TOKEN_DIVASSIGN): return TOKEN_HLSL_DIVASSIGN;
  2994. case ((Token) TOKEN_MODASSIGN): return TOKEN_HLSL_MODASSIGN;
  2995. case ((Token) TOKEN_LSHIFTASSIGN): return TOKEN_HLSL_LSHIFTASSIGN;
  2996. case ((Token) TOKEN_RSHIFTASSIGN): return TOKEN_HLSL_RSHIFTASSIGN;
  2997. case ((Token) TOKEN_ANDASSIGN): return TOKEN_HLSL_ANDASSIGN;
  2998. case ((Token) TOKEN_ORASSIGN): return TOKEN_HLSL_ORASSIGN;
  2999. case ((Token) TOKEN_XORASSIGN): return TOKEN_HLSL_XORASSIGN;
  3000. case ((Token) '?'): return TOKEN_HLSL_QUESTION;
  3001. case ((Token) TOKEN_OROR): return TOKEN_HLSL_OROR;
  3002. case ((Token) TOKEN_ANDAND): return TOKEN_HLSL_ANDAND;
  3003. case ((Token) '|'): return TOKEN_HLSL_OR;
  3004. case ((Token) '^'): return TOKEN_HLSL_XOR;
  3005. case ((Token) '&'): return TOKEN_HLSL_AND;
  3006. case ((Token) TOKEN_EQL): return TOKEN_HLSL_EQL;
  3007. case ((Token) TOKEN_NEQ): return TOKEN_HLSL_NEQ;
  3008. case ((Token) '<'): return TOKEN_HLSL_LT;
  3009. case ((Token) TOKEN_LEQ): return TOKEN_HLSL_LEQ;
  3010. case ((Token) '>'): return TOKEN_HLSL_GT;
  3011. case ((Token) TOKEN_GEQ): return TOKEN_HLSL_GEQ;
  3012. case ((Token) TOKEN_LSHIFT): return TOKEN_HLSL_LSHIFT;
  3013. case ((Token) TOKEN_RSHIFT): return TOKEN_HLSL_RSHIFT;
  3014. case ((Token) '+'): return TOKEN_HLSL_PLUS;
  3015. case ((Token) '-'): return TOKEN_HLSL_MINUS;
  3016. case ((Token) '*'): return TOKEN_HLSL_STAR;
  3017. case ((Token) '/'): return TOKEN_HLSL_SLASH;
  3018. case ((Token) '%'): return TOKEN_HLSL_PERCENT;
  3019. case ((Token) '!'): return TOKEN_HLSL_EXCLAMATION;
  3020. case ((Token) '~'): return TOKEN_HLSL_COMPLEMENT;
  3021. case ((Token) TOKEN_DECREMENT): return TOKEN_HLSL_MINUSMINUS;
  3022. case ((Token) TOKEN_INCREMENT): return TOKEN_HLSL_PLUSPLUS;
  3023. case ((Token) '.'): return TOKEN_HLSL_DOT;
  3024. case ((Token) '['): return TOKEN_HLSL_LBRACKET;
  3025. case ((Token) ']'): return TOKEN_HLSL_RBRACKET;
  3026. case ((Token) '('): return TOKEN_HLSL_LPAREN;
  3027. case ((Token) ')'): return TOKEN_HLSL_RPAREN;
  3028. case ((Token) TOKEN_INT_LITERAL): return TOKEN_HLSL_INT_CONSTANT;
  3029. case ((Token) TOKEN_FLOAT_LITERAL): return TOKEN_HLSL_FLOAT_CONSTANT;
  3030. case ((Token) TOKEN_STRING_LITERAL): return TOKEN_HLSL_STRING_LITERAL;
  3031. case ((Token) ':'): return TOKEN_HLSL_COLON;
  3032. case ((Token) ';'): return TOKEN_HLSL_SEMICOLON;
  3033. case ((Token) '{'): return TOKEN_HLSL_LBRACE;
  3034. case ((Token) '}'): return TOKEN_HLSL_RBRACE;
  3035. //case ((Token) TOKEN_PP_PRAGMA): return TOKEN_HLSL_PRAGMA;
  3036. //case ((Token) '\n'): return TOKEN_HLSL_NEWLINE;
  3037. case ((Token) TOKEN_IDENTIFIER):
  3038. #define tokencmp(t) ((tokenlen == strlen(t)) && (memcmp(token, t, tokenlen) == 0))
  3039. //case ((Token) ''): return TOKEN_HLSL_TYPECAST
  3040. //if (tokencmp("")) return TOKEN_HLSL_TYPE_NAME
  3041. //if (tokencmp("...")) return TOKEN_HLSL_ELIPSIS
  3042. if (tokencmp("else")) return TOKEN_HLSL_ELSE;
  3043. if (tokencmp("inline")) return TOKEN_HLSL_INLINE;
  3044. if (tokencmp("void")) return TOKEN_HLSL_VOID;
  3045. if (tokencmp("in")) return TOKEN_HLSL_IN;
  3046. if (tokencmp("inout")) return TOKEN_HLSL_INOUT;
  3047. if (tokencmp("out")) return TOKEN_HLSL_OUT;
  3048. if (tokencmp("uniform")) return TOKEN_HLSL_UNIFORM;
  3049. if (tokencmp("linear")) return TOKEN_HLSL_LINEAR;
  3050. if (tokencmp("centroid")) return TOKEN_HLSL_CENTROID;
  3051. if (tokencmp("nointerpolation")) return TOKEN_HLSL_NOINTERPOLATION;
  3052. if (tokencmp("noperspective")) return TOKEN_HLSL_NOPERSPECTIVE;
  3053. if (tokencmp("sample")) return TOKEN_HLSL_SAMPLE;
  3054. if (tokencmp("struct")) return TOKEN_HLSL_STRUCT;
  3055. if (tokencmp("typedef")) return TOKEN_HLSL_TYPEDEF;
  3056. if (tokencmp("const")) return TOKEN_HLSL_CONST;
  3057. if (tokencmp("packoffset")) return TOKEN_HLSL_PACKOFFSET;
  3058. if (tokencmp("register")) return TOKEN_HLSL_REGISTER;
  3059. if (tokencmp("extern")) return TOKEN_HLSL_EXTERN;
  3060. if (tokencmp("shared")) return TOKEN_HLSL_SHARED;
  3061. if (tokencmp("static")) return TOKEN_HLSL_STATIC;
  3062. if (tokencmp("volatile")) return TOKEN_HLSL_VOLATILE;
  3063. if (tokencmp("row_major")) return TOKEN_HLSL_ROWMAJOR;
  3064. if (tokencmp("column_major")) return TOKEN_HLSL_COLUMNMAJOR;
  3065. if (tokencmp("bool")) return TOKEN_HLSL_BOOL;
  3066. if (tokencmp("int")) return TOKEN_HLSL_INT;
  3067. if (tokencmp("uint")) return TOKEN_HLSL_UINT;
  3068. if (tokencmp("half")) return TOKEN_HLSL_HALF;
  3069. if (tokencmp("float")) return TOKEN_HLSL_FLOAT;
  3070. if (tokencmp("double")) return TOKEN_HLSL_DOUBLE;
  3071. if (tokencmp("string")) return TOKEN_HLSL_STRING;
  3072. if (tokencmp("snorm")) return TOKEN_HLSL_SNORM;
  3073. if (tokencmp("unorm")) return TOKEN_HLSL_UNORM;
  3074. if (tokencmp("buffer")) return TOKEN_HLSL_BUFFER;
  3075. if (tokencmp("vector")) return TOKEN_HLSL_VECTOR;
  3076. if (tokencmp("matrix")) return TOKEN_HLSL_MATRIX;
  3077. if (tokencmp("break")) return TOKEN_HLSL_BREAK;
  3078. if (tokencmp("continue")) return TOKEN_HLSL_CONTINUE;
  3079. if (tokencmp("discard")) return TOKEN_HLSL_DISCARD;
  3080. if (tokencmp("return")) return TOKEN_HLSL_RETURN;
  3081. if (tokencmp("while")) return TOKEN_HLSL_WHILE;
  3082. if (tokencmp("for")) return TOKEN_HLSL_FOR;
  3083. if (tokencmp("unroll")) return TOKEN_HLSL_UNROLL;
  3084. if (tokencmp("loop")) return TOKEN_HLSL_LOOP;
  3085. if (tokencmp("do")) return TOKEN_HLSL_DO;
  3086. if (tokencmp("if")) return TOKEN_HLSL_IF;
  3087. if (tokencmp("branch")) return TOKEN_HLSL_BRANCH;
  3088. if (tokencmp("flatten")) return TOKEN_HLSL_FLATTEN;
  3089. if (tokencmp("switch")) return TOKEN_HLSL_SWITCH;
  3090. if (tokencmp("forcecase")) return TOKEN_HLSL_FORCECASE;
  3091. if (tokencmp("call")) return TOKEN_HLSL_CALL;
  3092. if (tokencmp("case")) return TOKEN_HLSL_CASE;
  3093. if (tokencmp("default")) return TOKEN_HLSL_DEFAULT;
  3094. if (tokencmp("sampler")) return TOKEN_HLSL_SAMPLER;
  3095. if (tokencmp("sampler1D")) return TOKEN_HLSL_SAMPLER1D;
  3096. if (tokencmp("sampler2D")) return TOKEN_HLSL_SAMPLER2D;
  3097. if (tokencmp("sampler3D")) return TOKEN_HLSL_SAMPLER3D;
  3098. if (tokencmp("samplerCUBE")) return TOKEN_HLSL_SAMPLERCUBE;
  3099. if (tokencmp("sampler_state")) return TOKEN_HLSL_SAMPLER_STATE;
  3100. if (tokencmp("SamplerState")) return TOKEN_HLSL_SAMPLERSTATE;
  3101. if (tokencmp("true")) return TOKEN_HLSL_TRUE;
  3102. if (tokencmp("false")) return TOKEN_HLSL_FALSE;
  3103. if (tokencmp("SamplerComparisonState")) return TOKEN_HLSL_SAMPLERCOMPARISONSTATE;
  3104. if (tokencmp("isolate")) return TOKEN_HLSL_ISOLATE;
  3105. if (tokencmp("maxInstructionCount")) return TOKEN_HLSL_MAXINSTRUCTIONCOUNT;
  3106. if (tokencmp("noExpressionOptimizations")) return TOKEN_HLSL_NOEXPRESSIONOPTIMIZATIONS;
  3107. if (tokencmp("unused")) return TOKEN_HLSL_UNUSED;
  3108. if (tokencmp("xps")) return TOKEN_HLSL_XPS;
  3109. #undef tokencmp
  3110. // get a canonical copy of the string now, as we'll need it.
  3111. token = stringcache_len(ctx->strcache, token, tokenlen);
  3112. if (get_usertype(ctx, token) != NULL)
  3113. return TOKEN_HLSL_USERTYPE;
  3114. return TOKEN_HLSL_IDENTIFIER;
  3115. case TOKEN_EOI: return 0;
  3116. default: assert(0 && "unexpected token from lexer\n"); return 0;
  3117. } // switch
  3118. return 0;
  3119. } // convert_to_lemon_token
  3120. static void delete_ir(Context *ctx, void *_ir); // !!! FIXME: move this code around.
  3121. static void destroy_context(Context *ctx)
  3122. {
  3123. if (ctx != NULL)
  3124. {
  3125. MOJOSHADER_free f = ((ctx->free != NULL) ? ctx->free : MOJOSHADER_internal_free);
  3126. void *d = ctx->malloc_data;
  3127. size_t i = 0;
  3128. // !!! FIXME: this is kinda hacky.
  3129. const size_t count = buffer_size(ctx->garbage) / sizeof (void *);
  3130. if (count > 0)
  3131. {
  3132. void **garbage = (void **) buffer_flatten(ctx->garbage);
  3133. if (garbage != NULL)
  3134. {
  3135. for (i = 0; i < count; i++)
  3136. f(garbage[i], d);
  3137. f(garbage, d);
  3138. } // if
  3139. } // if
  3140. buffer_destroy(ctx->garbage);
  3141. delete_compilation_unit(ctx, (MOJOSHADER_astCompilationUnit*)ctx->ast);
  3142. destroy_symbolmap(ctx, &ctx->usertypes);
  3143. destroy_symbolmap(ctx, &ctx->variables);
  3144. stringcache_destroy(ctx->strcache);
  3145. errorlist_destroy(ctx->errors);
  3146. errorlist_destroy(ctx->warnings);
  3147. if (ctx->ir != NULL)
  3148. {
  3149. for (i = 0; i <= ctx->user_func_index; i++)
  3150. delete_ir(ctx, ctx->ir[i]);
  3151. f(ctx->ir, d);
  3152. } // if
  3153. // !!! FIXME: more to clean up here, now.
  3154. f(ctx, d);
  3155. } // if
  3156. } // destroy_context
  3157. static Context *build_context(MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  3158. {
  3159. if (!m) m = MOJOSHADER_internal_malloc;
  3160. if (!f) f = MOJOSHADER_internal_free;
  3161. Context *ctx = (Context *) m(sizeof (Context), d);
  3162. if (ctx == NULL)
  3163. return NULL;
  3164. memset(ctx, '\0', sizeof (Context));
  3165. ctx->malloc = m;
  3166. ctx->free = f;
  3167. ctx->malloc_data = d;
  3168. //ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
  3169. create_symbolmap(ctx, &ctx->usertypes); // !!! FIXME: check for failure.
  3170. create_symbolmap(ctx, &ctx->variables); // !!! FIXME: check for failure.
  3171. ctx->strcache = stringcache_create(MallocBridge, FreeBridge, ctx); // !!! FIXME: check for failure.
  3172. ctx->errors = errorlist_create(MallocBridge, FreeBridge, ctx); // !!! FIXME: check for failure.
  3173. ctx->warnings = errorlist_create(MallocBridge, FreeBridge, ctx); // !!! FIXME: check for failure.
  3174. // !!! FIXME: this feels hacky.
  3175. ctx->garbage = buffer_create(256*sizeof(void*),MallocBridge,FreeBridge,ctx); // !!! FIXME: check for failure.
  3176. ctx->dt_none.type = MOJOSHADER_AST_DATATYPE_NONE;
  3177. ctx->dt_bool.type = MOJOSHADER_AST_DATATYPE_BOOL;
  3178. ctx->dt_int.type = MOJOSHADER_AST_DATATYPE_INT;
  3179. ctx->dt_uint.type = MOJOSHADER_AST_DATATYPE_UINT;
  3180. ctx->dt_float.type = MOJOSHADER_AST_DATATYPE_FLOAT;
  3181. ctx->dt_float_snorm.type = MOJOSHADER_AST_DATATYPE_FLOAT_SNORM;
  3182. ctx->dt_float_unorm.type = MOJOSHADER_AST_DATATYPE_FLOAT_UNORM;
  3183. ctx->dt_half.type = MOJOSHADER_AST_DATATYPE_HALF;
  3184. ctx->dt_double.type = MOJOSHADER_AST_DATATYPE_DOUBLE;
  3185. ctx->dt_string.type = MOJOSHADER_AST_DATATYPE_STRING;
  3186. ctx->dt_sampler1d.type = MOJOSHADER_AST_DATATYPE_SAMPLER_1D;
  3187. ctx->dt_sampler2d.type = MOJOSHADER_AST_DATATYPE_SAMPLER_2D;
  3188. ctx->dt_sampler3d.type = MOJOSHADER_AST_DATATYPE_SAMPLER_3D;
  3189. ctx->dt_samplercube.type = MOJOSHADER_AST_DATATYPE_SAMPLER_CUBE;
  3190. ctx->dt_samplerstate.type = MOJOSHADER_AST_DATATYPE_SAMPLER_STATE;
  3191. ctx->dt_samplercompstate.type = MOJOSHADER_AST_DATATYPE_SAMPLER_COMPARISON_STATE;
  3192. #define INIT_DT_BUFFER(t) \
  3193. ctx->dt_buf_##t.type = MOJOSHADER_AST_DATATYPE_BUFFER; \
  3194. ctx->dt_buf_##t.buffer.base = &ctx->dt_##t;
  3195. INIT_DT_BUFFER(bool);
  3196. INIT_DT_BUFFER(int);
  3197. INIT_DT_BUFFER(uint);
  3198. INIT_DT_BUFFER(half);
  3199. INIT_DT_BUFFER(float);
  3200. INIT_DT_BUFFER(double);
  3201. INIT_DT_BUFFER(float_snorm);
  3202. INIT_DT_BUFFER(float_unorm);
  3203. #undef INIT_DT_BUFFER
  3204. return ctx;
  3205. } // build_context
  3206. // This macro salsa is kinda nasty, but it's the smallest, least error-prone
  3207. // way I can find to do this well in C. :/
  3208. #define ADD_INTRINSIC(fn, ret, params) do { \
  3209. push_function(ctx, fn, \
  3210. build_function_datatype(ctx, ret, STATICARRAYLEN(params), params, 1), \
  3211. 0); \
  3212. } while (0)
  3213. #define ADD_INTRINSIC_VECTOR(typestr, code) do { \
  3214. const MOJOSHADER_astDataType *dt; \
  3215. dt = get_usertype(ctx, typestr "1"); code; \
  3216. dt = get_usertype(ctx, typestr "2"); code; \
  3217. dt = get_usertype(ctx, typestr "3"); code; \
  3218. dt = get_usertype(ctx, typestr "4"); code; \
  3219. } while (0)
  3220. #define ADD_INTRINSIC_VECTOR_FLOAT(code) { \
  3221. ADD_INTRINSIC_VECTOR("float", code); \
  3222. ADD_INTRINSIC_VECTOR("half", code); \
  3223. ADD_INTRINSIC_VECTOR("double", code); \
  3224. }
  3225. #define ADD_INTRINSIC_VECTOR_INT(code) { \
  3226. ADD_INTRINSIC_VECTOR("int", code); \
  3227. ADD_INTRINSIC_VECTOR("uint", code); \
  3228. }
  3229. #define ADD_INTRINSIC_VECTOR_BOOL(code) { \
  3230. ADD_INTRINSIC_VECTOR("bool", code); \
  3231. }
  3232. #define ADD_INTRINSIC_MATRIX(typestr, code) do { \
  3233. const MOJOSHADER_astDataType *dt; \
  3234. dt = get_usertype(ctx, typestr "1x1"); code; \
  3235. dt = get_usertype(ctx, typestr "1x2"); code; \
  3236. dt = get_usertype(ctx, typestr "1x3"); code; \
  3237. dt = get_usertype(ctx, typestr "1x4"); code; \
  3238. dt = get_usertype(ctx, typestr "2x1"); code; \
  3239. dt = get_usertype(ctx, typestr "2x2"); code; \
  3240. dt = get_usertype(ctx, typestr "2x3"); code; \
  3241. dt = get_usertype(ctx, typestr "2x4"); code; \
  3242. dt = get_usertype(ctx, typestr "3x1"); code; \
  3243. dt = get_usertype(ctx, typestr "3x2"); code; \
  3244. dt = get_usertype(ctx, typestr "3x3"); code; \
  3245. dt = get_usertype(ctx, typestr "3x4"); code; \
  3246. dt = get_usertype(ctx, typestr "4x1"); code; \
  3247. dt = get_usertype(ctx, typestr "4x2"); code; \
  3248. dt = get_usertype(ctx, typestr "4x3"); code; \
  3249. dt = get_usertype(ctx, typestr "4x4"); code; \
  3250. } while (0)
  3251. #define ADD_INTRINSIC_MATRIX_FLOAT(code) { \
  3252. ADD_INTRINSIC_MATRIX("float", code); \
  3253. ADD_INTRINSIC_MATRIX("half", code); \
  3254. ADD_INTRINSIC_MATRIX("double", code); \
  3255. }
  3256. #define ADD_INTRINSIC_MATRIX_INT(code) { \
  3257. ADD_INTRINSIC_MATRIX("int", code); \
  3258. ADD_INTRINSIC_MATRIX("uint", code); \
  3259. }
  3260. #define ADD_INTRINSIC_MATRIX_BOOL(code) { \
  3261. ADD_INTRINSIC_MATRIX("bool", code); \
  3262. }
  3263. #define ADD_INTRINSIC_ANY(scalar, typestr, code) do { \
  3264. { const MOJOSHADER_astDataType *dt = scalar; code; } \
  3265. ADD_INTRINSIC_VECTOR(typestr, code); \
  3266. ADD_INTRINSIC_MATRIX(typestr, code); \
  3267. } while (0)
  3268. #define ADD_INTRINSIC_ANY_FLOAT(code) do { \
  3269. ADD_INTRINSIC_ANY(&ctx->dt_double, "double", code); \
  3270. ADD_INTRINSIC_ANY(&ctx->dt_half, "half", code); \
  3271. ADD_INTRINSIC_ANY(&ctx->dt_float, "float", code); \
  3272. } while (0)
  3273. #define ADD_INTRINSIC_ANY_INT(code) do { \
  3274. ADD_INTRINSIC_ANY(&ctx->dt_uint, "uint", code); \
  3275. ADD_INTRINSIC_ANY(&ctx->dt_int, "int", code); \
  3276. } while (0)
  3277. #define ADD_INTRINSIC_ANY_BOOL(code) ADD_INTRINSIC_ANY(&ctx->dt_bool, "bool", code)
  3278. static void add_intrinsic1(Context *ctx, const char *fn,
  3279. const MOJOSHADER_astDataType *ret,
  3280. const MOJOSHADER_astDataType *dt1)
  3281. {
  3282. const MOJOSHADER_astDataType *params[] = { dt1 };
  3283. ADD_INTRINSIC(fn, ret, params);
  3284. } // add_intrinsic1
  3285. static void add_intrinsic2(Context *ctx, const char *fn,
  3286. const MOJOSHADER_astDataType *ret,
  3287. const MOJOSHADER_astDataType *dt1,
  3288. const MOJOSHADER_astDataType *dt2)
  3289. {
  3290. const MOJOSHADER_astDataType *params[] = { dt1, dt2 };
  3291. ADD_INTRINSIC(fn, ret, params);
  3292. } // add_intrinsic2
  3293. static void add_intrinsic3(Context *ctx, const char *fn,
  3294. const MOJOSHADER_astDataType *ret,
  3295. const MOJOSHADER_astDataType *dt1,
  3296. const MOJOSHADER_astDataType *dt2,
  3297. const MOJOSHADER_astDataType *dt3)
  3298. {
  3299. const MOJOSHADER_astDataType *params[] = { dt1, dt2, dt3 };
  3300. ADD_INTRINSIC(fn, ret, params);
  3301. } // add_intrinsic3
  3302. static void add_intrinsic4(Context *ctx, const char *fn,
  3303. const MOJOSHADER_astDataType *ret,
  3304. const MOJOSHADER_astDataType *dt1,
  3305. const MOJOSHADER_astDataType *dt2,
  3306. const MOJOSHADER_astDataType *dt3,
  3307. const MOJOSHADER_astDataType *dt4)
  3308. {
  3309. const MOJOSHADER_astDataType *params[] = { dt1, dt2, dt3, dt4 };
  3310. ADD_INTRINSIC(fn, ret, params);
  3311. } // add_intrinsic4
  3312. // PLEASE NOTE that add_intrinsic*() is called AFTER the various
  3313. // ADD_INTRINSIC_* macros, even though these look like functions that
  3314. // should be called first. They might be called multiple times by the macro.
  3315. // The variable "dt" is defined by the macro for use by your code.
  3316. static void add_intrinsic_SAME1_ANYf(Context *ctx, const char *fn)
  3317. {
  3318. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
  3319. } // add_intrinsic_SAME1_ANYf
  3320. static void add_intrinsic_SAME1_ANYfi(Context *ctx, const char *fn)
  3321. {
  3322. ADD_INTRINSIC_ANY_INT(add_intrinsic1(ctx, fn, dt, dt));
  3323. add_intrinsic_SAME1_ANYf(ctx, fn);
  3324. } // add_intrinsic_SAME1_ANYfi
  3325. static void add_intrinsic_BOOL_ANYf(Context *ctx, const char *fn)
  3326. {
  3327. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
  3328. } // add_intrinsic_BOOL_ANYf
  3329. static void add_intrinsic_BOOL_ANYfib(Context *ctx, const char *fn)
  3330. {
  3331. ADD_INTRINSIC_ANY_BOOL(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
  3332. ADD_INTRINSIC_ANY_INT(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
  3333. add_intrinsic_BOOL_ANYf(ctx, fn);
  3334. } // add_intrinsic_BOOL_ANYfib
  3335. static void add_intrinsic_SAME1_ANYf_SAME1(Context *ctx, const char *fn)
  3336. {
  3337. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dt));
  3338. } // add_intrinsic_SAME1_ANYf_SAME1
  3339. static void add_intrinsic_SAME1_ANYfi_SAME1(Context *ctx, const char *fn)
  3340. {
  3341. ADD_INTRINSIC_ANY_INT(add_intrinsic2(ctx, fn, dt, dt, dt));
  3342. add_intrinsic_SAME1_ANYf_SAME1(ctx, fn);
  3343. } // add_intrinsic_SAME1_ANYfi_SAME1
  3344. static void add_intrinsic_SAME1_ANYf_SAME1_SAME1(Context *ctx, const char *fn)
  3345. {
  3346. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
  3347. } // add_intrinsic_SAME1_ANYf_SAME1_SAME1
  3348. static void add_intrinsic_SAME1_ANYfi_SAME1_SAME1(Context *ctx, const char *fn)
  3349. {
  3350. ADD_INTRINSIC_ANY_INT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
  3351. add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, fn);
  3352. } // add_intrinsic_SAME1_ANYfi_SAME1_SAME1
  3353. static void add_intrinsic_SAME1_Mfib(Context *ctx, const char *fn)
  3354. {
  3355. ADD_INTRINSIC_MATRIX_BOOL(add_intrinsic1(ctx, fn, dt, dt));
  3356. ADD_INTRINSIC_MATRIX_INT(add_intrinsic1(ctx, fn, dt, dt));
  3357. ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
  3358. } // add_intrinsic_SAME1_Mfib
  3359. static void add_intrinsic_SAME1_Vf(Context *ctx, const char *fn)
  3360. {
  3361. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
  3362. } // add_intrinsic_SAME1_Vf
  3363. static void add_intrinsic_SAME1_Vf_SAME1_SAME1(Context *ctx, const char *fn)
  3364. {
  3365. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
  3366. } // add_intrinsic_SAME1_Vf_SAME1_SAME1
  3367. static void add_intrinsic_SAME1_Vf_SAME1_f(Context *ctx, const char *fn)
  3368. {
  3369. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, dt->user.details->vector.base));
  3370. } // add_intrinsic_SAME1_Vf_SAME1_f
  3371. static void add_intrinsic_VOID_ANYf(Context *ctx, const char *fn)
  3372. {
  3373. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, NULL, dt));
  3374. } // add_intrinsic_VOID_ANYf
  3375. static void add_intrinsic_VOID_ANYf_SAME1_SAME1(Context *ctx, const char *fn)
  3376. {
  3377. ADD_INTRINSIC_ANY_FLOAT(add_intrinsic3(ctx, fn, NULL, dt, dt, dt));
  3378. } // add_intrinsic_VOID_ANYf_SAME1_SAME1
  3379. static void add_intrinsic_f_SQUAREMATRIXf(Context *ctx, const char *fn)
  3380. {
  3381. add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float1x1"));
  3382. add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float2x2"));
  3383. add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float3x3"));
  3384. add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float4x4"));
  3385. } // add_intrinsic_f_SQUAREMATRIXf
  3386. static void add_intrinsic_f_Vf(Context *ctx, const char *fn)
  3387. {
  3388. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic1(ctx, fn, dt->user.details->vector.base, dt));
  3389. } // add_intrinsic_f_Vf
  3390. static void add_intrinsic_fi_Vfi_SAME1(Context *ctx, const char *fn)
  3391. {
  3392. ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dt->user.details->vector.base, dt, dt));
  3393. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt->user.details->vector.base, dt, dt));
  3394. } // add_intrinsic_fi_Vfi_SAME1
  3395. static void add_intrinsic_f_Vf_SAME1(Context *ctx, const char *fn)
  3396. {
  3397. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt->user.details->vector.base, dt, dt));
  3398. } // add_intrinsic_f_Vf_SAME1
  3399. static void add_intrinsic_3f_3f_3f(Context *ctx, const char *fn)
  3400. {
  3401. const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float3");
  3402. add_intrinsic2(ctx, fn, dt, dt, dt);
  3403. } // add_intrinsic_3f_3f_3f
  3404. static void add_intrinsic_4f_f_f_f(Context *ctx, const char *fn)
  3405. {
  3406. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3407. const MOJOSHADER_astDataType *f = &ctx->dt_float;
  3408. add_intrinsic3(ctx, fn, f4, f, f, f);
  3409. } // add_intrinsic_4f_f_f_f
  3410. static void add_intrinsic_4f_s1_4f(Context *ctx, const char *fn)
  3411. {
  3412. const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
  3413. add_intrinsic2(ctx, fn, dt, &ctx->dt_sampler1d, dt);
  3414. } // add_intrinsic_4f_s1_4f
  3415. static void add_intrinsic_4f_s1_f(Context *ctx, const char *fn)
  3416. {
  3417. const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
  3418. add_intrinsic2(ctx, fn, dt, &ctx->dt_sampler1d, &ctx->dt_float);
  3419. } // add_intrinsic_4f_s1_f
  3420. static void add_intrinsic_4f_s1_f_f_f(Context *ctx, const char *fn)
  3421. {
  3422. const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
  3423. const MOJOSHADER_astDataType *f = &ctx->dt_float;
  3424. add_intrinsic4(ctx, fn, dt, &ctx->dt_sampler1d, f, f, f);
  3425. } // add_intrinsic_4f_s1_f_f_f
  3426. static void add_intrinsic_4f_s2_2f(Context *ctx, const char *fn)
  3427. {
  3428. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3429. const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
  3430. add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler2d, f2);
  3431. } // add_intrinsic_4f_s2_2f
  3432. static void add_intrinsic_4f_s2_2f_2f_2f(Context *ctx, const char *fn)
  3433. {
  3434. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3435. const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
  3436. add_intrinsic4(ctx, fn, f4, &ctx->dt_sampler2d, f2, f2, f2);
  3437. } // add_intrinsic_4f_s2_2f_2f_2f
  3438. static void add_intrinsic_4f_s2_4f(Context *ctx, const char *fn)
  3439. {
  3440. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3441. add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler2d, f4);
  3442. } // add_intrinsic_4f_s2_4f
  3443. static void add_intrinsic_4f_s3_3f(Context *ctx, const char *fn)
  3444. {
  3445. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3446. const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
  3447. add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler3d, f3);
  3448. } // add_intrinsic_4f_s3_3f
  3449. static void add_intrinsic_4f_s3_3f_3f_3f(Context *ctx, const char *fn)
  3450. {
  3451. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3452. const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
  3453. add_intrinsic4(ctx, fn, f4, &ctx->dt_sampler3d, f3, f3, f3);
  3454. } // add_intrinsic_4f_s3_3f_3f_3f
  3455. static void add_intrinsic_4f_s3_4f(Context *ctx, const char *fn)
  3456. {
  3457. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3458. add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler3d, f4);
  3459. } // add_intrinsic_4f_s3_4f
  3460. static void add_intrinsic_4f_sc_3f(Context *ctx, const char *fn)
  3461. {
  3462. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3463. const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
  3464. add_intrinsic2(ctx, fn, f4, &ctx->dt_samplercube, f3);
  3465. } // add_intrinsic_4f_sc_3f
  3466. static void add_intrinsic_4f_sc_3f_3f_3f(Context *ctx, const char *fn)
  3467. {
  3468. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3469. const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
  3470. add_intrinsic4(ctx, fn, f4, &ctx->dt_samplercube, f3, f3, f3);
  3471. } // add_intrinsic_4f_sc_3f_3f_3f
  3472. static void add_intrinsic_4f_sc_4f(Context *ctx, const char *fn)
  3473. {
  3474. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3475. add_intrinsic2(ctx, fn, f4, &ctx->dt_samplercube, f4);
  3476. } // add_intrinsic_4f_sc_4f
  3477. static void add_intrinsic_4i_4f(Context *ctx, const char *fn)
  3478. {
  3479. const MOJOSHADER_astDataType *i4 = get_usertype(ctx, "int4");
  3480. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3481. add_intrinsic1(ctx, fn, i4, f4);
  3482. } // add_intrinsic_4i_4f
  3483. static void add_intrinsic_mul(Context *ctx, const char *fn)
  3484. {
  3485. // mul() is nasty, since there's a bunch of overloads that aren't just
  3486. // related to vector size.
  3487. // !!! FIXME: needs half, double, uint...
  3488. const MOJOSHADER_astDataType *dtf = &ctx->dt_float;
  3489. const MOJOSHADER_astDataType *dti = &ctx->dt_int;
  3490. const MOJOSHADER_astDataType *f1 = get_usertype(ctx, "float1");
  3491. const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
  3492. const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
  3493. const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
  3494. const MOJOSHADER_astDataType *i1 = get_usertype(ctx, "int1");
  3495. const MOJOSHADER_astDataType *i2 = get_usertype(ctx, "int2");
  3496. const MOJOSHADER_astDataType *i3 = get_usertype(ctx, "int3");
  3497. const MOJOSHADER_astDataType *i4 = get_usertype(ctx, "int4");
  3498. const MOJOSHADER_astDataType *f1x1 = get_usertype(ctx, "float1x1");
  3499. const MOJOSHADER_astDataType *f1x2 = get_usertype(ctx, "float1x2");
  3500. const MOJOSHADER_astDataType *f1x3 = get_usertype(ctx, "float1x3");
  3501. const MOJOSHADER_astDataType *f1x4 = get_usertype(ctx, "float1x4");
  3502. const MOJOSHADER_astDataType *f2x1 = get_usertype(ctx, "float2x1");
  3503. const MOJOSHADER_astDataType *f2x2 = get_usertype(ctx, "float2x2");
  3504. const MOJOSHADER_astDataType *f2x3 = get_usertype(ctx, "float2x3");
  3505. const MOJOSHADER_astDataType *f2x4 = get_usertype(ctx, "float2x4");
  3506. const MOJOSHADER_astDataType *f3x1 = get_usertype(ctx, "float3x1");
  3507. const MOJOSHADER_astDataType *f3x2 = get_usertype(ctx, "float3x2");
  3508. const MOJOSHADER_astDataType *f3x3 = get_usertype(ctx, "float3x3");
  3509. const MOJOSHADER_astDataType *f3x4 = get_usertype(ctx, "float3x4");
  3510. const MOJOSHADER_astDataType *f4x1 = get_usertype(ctx, "float4x1");
  3511. const MOJOSHADER_astDataType *f4x2 = get_usertype(ctx, "float4x2");
  3512. const MOJOSHADER_astDataType *f4x3 = get_usertype(ctx, "float4x3");
  3513. const MOJOSHADER_astDataType *f4x4 = get_usertype(ctx, "float4x4");
  3514. const MOJOSHADER_astDataType *i1x1 = get_usertype(ctx, "int1x1");
  3515. const MOJOSHADER_astDataType *i1x2 = get_usertype(ctx, "int1x2");
  3516. const MOJOSHADER_astDataType *i1x3 = get_usertype(ctx, "int1x3");
  3517. const MOJOSHADER_astDataType *i1x4 = get_usertype(ctx, "int1x4");
  3518. const MOJOSHADER_astDataType *i2x1 = get_usertype(ctx, "int2x1");
  3519. const MOJOSHADER_astDataType *i2x2 = get_usertype(ctx, "int2x2");
  3520. const MOJOSHADER_astDataType *i2x3 = get_usertype(ctx, "int2x3");
  3521. const MOJOSHADER_astDataType *i2x4 = get_usertype(ctx, "int2x4");
  3522. const MOJOSHADER_astDataType *i3x1 = get_usertype(ctx, "int3x1");
  3523. const MOJOSHADER_astDataType *i3x2 = get_usertype(ctx, "int3x2");
  3524. const MOJOSHADER_astDataType *i3x3 = get_usertype(ctx, "int3x3");
  3525. const MOJOSHADER_astDataType *i3x4 = get_usertype(ctx, "int3x4");
  3526. const MOJOSHADER_astDataType *i4x1 = get_usertype(ctx, "int4x1");
  3527. const MOJOSHADER_astDataType *i4x2 = get_usertype(ctx, "int4x2");
  3528. const MOJOSHADER_astDataType *i4x3 = get_usertype(ctx, "int4x3");
  3529. const MOJOSHADER_astDataType *i4x4 = get_usertype(ctx, "int4x4");
  3530. // scalar * scalar
  3531. add_intrinsic2(ctx, fn, dti, dti, dti);
  3532. add_intrinsic2(ctx, fn, dtf, dtf, dtf);
  3533. // scalar * vector
  3534. ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dt, dti, dt));
  3535. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt, dtf, dt));
  3536. // scalar * matrix
  3537. ADD_INTRINSIC_MATRIX_INT(add_intrinsic2(ctx, fn, dt, dti, dt));
  3538. ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic2(ctx, fn, dt, dtf, dt));
  3539. // vector * scalar
  3540. ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dt, dt, dti));
  3541. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dtf));
  3542. // vector * vector
  3543. ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dti, dt, dt));
  3544. ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dtf, dt, dt));
  3545. // vector * matrix
  3546. add_intrinsic2(ctx, fn, i1, i1, i1x1);
  3547. add_intrinsic2(ctx, fn, i2, i1, i1x2);
  3548. add_intrinsic2(ctx, fn, i3, i1, i1x3);
  3549. add_intrinsic2(ctx, fn, i4, i1, i1x4);
  3550. add_intrinsic2(ctx, fn, i1, i2, i2x1);
  3551. add_intrinsic2(ctx, fn, i2, i2, i2x2);
  3552. add_intrinsic2(ctx, fn, i3, i2, i2x3);
  3553. add_intrinsic2(ctx, fn, i4, i2, i2x4);
  3554. add_intrinsic2(ctx, fn, i1, i3, i3x1);
  3555. add_intrinsic2(ctx, fn, i2, i3, i3x2);
  3556. add_intrinsic2(ctx, fn, i3, i3, i3x3);
  3557. add_intrinsic2(ctx, fn, i4, i3, i3x4);
  3558. add_intrinsic2(ctx, fn, i1, i4, i4x1);
  3559. add_intrinsic2(ctx, fn, i2, i4, i4x2);
  3560. add_intrinsic2(ctx, fn, i3, i4, i4x3);
  3561. add_intrinsic2(ctx, fn, i4, i4, i4x4);
  3562. add_intrinsic2(ctx, fn, f1, f1, f1x1);
  3563. add_intrinsic2(ctx, fn, f2, f1, f1x2);
  3564. add_intrinsic2(ctx, fn, f3, f1, f1x3);
  3565. add_intrinsic2(ctx, fn, f4, f1, f1x4);
  3566. add_intrinsic2(ctx, fn, f1, f2, f2x1);
  3567. add_intrinsic2(ctx, fn, f2, f2, f2x2);
  3568. add_intrinsic2(ctx, fn, f3, f2, f2x3);
  3569. add_intrinsic2(ctx, fn, f4, f2, f2x4);
  3570. add_intrinsic2(ctx, fn, f1, f3, f3x1);
  3571. add_intrinsic2(ctx, fn, f2, f3, f3x2);
  3572. add_intrinsic2(ctx, fn, f3, f3, f3x3);
  3573. add_intrinsic2(ctx, fn, f4, f3, f3x4);
  3574. add_intrinsic2(ctx, fn, f1, f4, f4x1);
  3575. add_intrinsic2(ctx, fn, f2, f4, f4x2);
  3576. add_intrinsic2(ctx, fn, f3, f4, f4x3);
  3577. add_intrinsic2(ctx, fn, f4, f4, f4x4);
  3578. // matrix * scalar
  3579. ADD_INTRINSIC_MATRIX_INT(add_intrinsic2(ctx, fn, dt, dt, dti));
  3580. ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dtf));
  3581. // matrix * vector
  3582. add_intrinsic2(ctx, fn, i1, i1x1, i1);
  3583. add_intrinsic2(ctx, fn, i1, i1x2, i2);
  3584. add_intrinsic2(ctx, fn, i1, i1x3, i3);
  3585. add_intrinsic2(ctx, fn, i1, i1x4, i4);
  3586. add_intrinsic2(ctx, fn, i2, i2x1, i1);
  3587. add_intrinsic2(ctx, fn, i2, i2x2, i2);
  3588. add_intrinsic2(ctx, fn, i2, i2x3, i3);
  3589. add_intrinsic2(ctx, fn, i2, i2x4, i4);
  3590. add_intrinsic2(ctx, fn, i3, i3x1, i1);
  3591. add_intrinsic2(ctx, fn, i3, i3x2, i2);
  3592. add_intrinsic2(ctx, fn, i3, i3x3, i3);
  3593. add_intrinsic2(ctx, fn, i3, i3x4, i4);
  3594. add_intrinsic2(ctx, fn, i4, i4x1, i1);
  3595. add_intrinsic2(ctx, fn, i4, i4x2, i2);
  3596. add_intrinsic2(ctx, fn, i4, i4x3, i3);
  3597. add_intrinsic2(ctx, fn, i4, i4x4, i4);
  3598. add_intrinsic2(ctx, fn, f1, f1x1, f1);
  3599. add_intrinsic2(ctx, fn, f1, f1x2, f2);
  3600. add_intrinsic2(ctx, fn, f1, f1x3, f3);
  3601. add_intrinsic2(ctx, fn, f1, f1x4, f4);
  3602. add_intrinsic2(ctx, fn, f2, f2x1, f1);
  3603. add_intrinsic2(ctx, fn, f2, f2x2, f2);
  3604. add_intrinsic2(ctx, fn, f2, f2x3, f3);
  3605. add_intrinsic2(ctx, fn, f2, f2x4, f4);
  3606. add_intrinsic2(ctx, fn, f3, f3x1, f1);
  3607. add_intrinsic2(ctx, fn, f3, f3x2, f2);
  3608. add_intrinsic2(ctx, fn, f3, f3x3, f3);
  3609. add_intrinsic2(ctx, fn, f3, f3x4, f4);
  3610. add_intrinsic2(ctx, fn, f4, f4x1, f1);
  3611. add_intrinsic2(ctx, fn, f4, f4x2, f2);
  3612. add_intrinsic2(ctx, fn, f4, f4x3, f3);
  3613. add_intrinsic2(ctx, fn, f4, f4x4, f4);
  3614. // matrix * matrix
  3615. add_intrinsic2(ctx, fn, i1x1, i1x1, i1x1);
  3616. add_intrinsic2(ctx, fn, i1x2, i1x1, i1x2);
  3617. add_intrinsic2(ctx, fn, i1x3, i1x1, i1x3);
  3618. add_intrinsic2(ctx, fn, i1x4, i1x1, i1x4);
  3619. add_intrinsic2(ctx, fn, i1x1, i1x2, i2x1);
  3620. add_intrinsic2(ctx, fn, i1x2, i1x2, i2x2);
  3621. add_intrinsic2(ctx, fn, i1x3, i1x2, i2x3);
  3622. add_intrinsic2(ctx, fn, i1x4, i1x2, i2x4);
  3623. add_intrinsic2(ctx, fn, i1x1, i1x3, i3x1);
  3624. add_intrinsic2(ctx, fn, i1x2, i1x3, i3x2);
  3625. add_intrinsic2(ctx, fn, i1x3, i1x3, i3x3);
  3626. add_intrinsic2(ctx, fn, i1x4, i1x3, i3x4);
  3627. add_intrinsic2(ctx, fn, i1x1, i1x4, i4x1);
  3628. add_intrinsic2(ctx, fn, i1x2, i1x4, i4x2);
  3629. add_intrinsic2(ctx, fn, i1x3, i1x4, i4x3);
  3630. add_intrinsic2(ctx, fn, i1x4, i1x4, i4x4);
  3631. add_intrinsic2(ctx, fn, i2x1, i2x1, i1x1);
  3632. add_intrinsic2(ctx, fn, i2x2, i2x1, i1x2);
  3633. add_intrinsic2(ctx, fn, i2x3, i2x1, i1x3);
  3634. add_intrinsic2(ctx, fn, i2x4, i2x1, i1x4);
  3635. add_intrinsic2(ctx, fn, i2x1, i2x2, i2x1);
  3636. add_intrinsic2(ctx, fn, i2x2, i2x2, i2x2);
  3637. add_intrinsic2(ctx, fn, i2x3, i2x2, i2x3);
  3638. add_intrinsic2(ctx, fn, i2x4, i2x2, i2x4);
  3639. add_intrinsic2(ctx, fn, i2x1, i2x3, i3x1);
  3640. add_intrinsic2(ctx, fn, i2x2, i2x3, i3x2);
  3641. add_intrinsic2(ctx, fn, i2x3, i2x3, i3x3);
  3642. add_intrinsic2(ctx, fn, i2x4, i2x3, i3x4);
  3643. add_intrinsic2(ctx, fn, i2x1, i2x4, i4x1);
  3644. add_intrinsic2(ctx, fn, i2x2, i2x4, i4x2);
  3645. add_intrinsic2(ctx, fn, i2x3, i2x4, i4x3);
  3646. add_intrinsic2(ctx, fn, i2x4, i2x4, i4x4);
  3647. add_intrinsic2(ctx, fn, i3x1, i3x1, i1x1);
  3648. add_intrinsic2(ctx, fn, i3x2, i3x1, i1x2);
  3649. add_intrinsic2(ctx, fn, i3x3, i3x1, i1x3);
  3650. add_intrinsic2(ctx, fn, i3x4, i3x1, i1x4);
  3651. add_intrinsic2(ctx, fn, i3x1, i3x2, i2x1);
  3652. add_intrinsic2(ctx, fn, i3x2, i3x2, i2x2);
  3653. add_intrinsic2(ctx, fn, i3x3, i3x2, i2x3);
  3654. add_intrinsic2(ctx, fn, i3x4, i3x2, i2x4);
  3655. add_intrinsic2(ctx, fn, i3x1, i3x3, i3x1);
  3656. add_intrinsic2(ctx, fn, i3x2, i3x3, i3x2);
  3657. add_intrinsic2(ctx, fn, i3x3, i3x3, i3x3);
  3658. add_intrinsic2(ctx, fn, i3x4, i3x3, i3x4);
  3659. add_intrinsic2(ctx, fn, i3x1, i3x4, i4x1);
  3660. add_intrinsic2(ctx, fn, i3x2, i3x4, i4x2);
  3661. add_intrinsic2(ctx, fn, i3x3, i3x4, i4x3);
  3662. add_intrinsic2(ctx, fn, i3x4, i3x4, i4x4);
  3663. add_intrinsic2(ctx, fn, i4x1, i4x1, i1x1);
  3664. add_intrinsic2(ctx, fn, i4x2, i4x1, i1x2);
  3665. add_intrinsic2(ctx, fn, i4x3, i4x1, i1x3);
  3666. add_intrinsic2(ctx, fn, i4x4, i4x1, i1x4);
  3667. add_intrinsic2(ctx, fn, i4x1, i4x2, i2x1);
  3668. add_intrinsic2(ctx, fn, i4x2, i4x2, i2x2);
  3669. add_intrinsic2(ctx, fn, i4x3, i4x2, i2x3);
  3670. add_intrinsic2(ctx, fn, i4x4, i4x2, i2x4);
  3671. add_intrinsic2(ctx, fn, i4x1, i4x3, i3x1);
  3672. add_intrinsic2(ctx, fn, i4x2, i4x3, i3x2);
  3673. add_intrinsic2(ctx, fn, i4x3, i4x3, i3x3);
  3674. add_intrinsic2(ctx, fn, i4x4, i4x3, i3x4);
  3675. add_intrinsic2(ctx, fn, i4x1, i4x4, i4x1);
  3676. add_intrinsic2(ctx, fn, i4x2, i4x4, i4x2);
  3677. add_intrinsic2(ctx, fn, i4x3, i4x4, i4x3);
  3678. add_intrinsic2(ctx, fn, i4x4, i4x4, i4x4);
  3679. add_intrinsic2(ctx, fn, f1x1, f1x1, f1x1);
  3680. add_intrinsic2(ctx, fn, f1x2, f1x1, f1x2);
  3681. add_intrinsic2(ctx, fn, f1x3, f1x1, f1x3);
  3682. add_intrinsic2(ctx, fn, f1x4, f1x1, f1x4);
  3683. add_intrinsic2(ctx, fn, f1x1, f1x2, f2x1);
  3684. add_intrinsic2(ctx, fn, f1x2, f1x2, f2x2);
  3685. add_intrinsic2(ctx, fn, f1x3, f1x2, f2x3);
  3686. add_intrinsic2(ctx, fn, f1x4, f1x2, f2x4);
  3687. add_intrinsic2(ctx, fn, f1x1, f1x3, f3x1);
  3688. add_intrinsic2(ctx, fn, f1x2, f1x3, f3x2);
  3689. add_intrinsic2(ctx, fn, f1x3, f1x3, f3x3);
  3690. add_intrinsic2(ctx, fn, f1x4, f1x3, f3x4);
  3691. add_intrinsic2(ctx, fn, f1x1, f1x4, f4x1);
  3692. add_intrinsic2(ctx, fn, f1x2, f1x4, f4x2);
  3693. add_intrinsic2(ctx, fn, f1x3, f1x4, f4x3);
  3694. add_intrinsic2(ctx, fn, f1x4, f1x4, f4x4);
  3695. add_intrinsic2(ctx, fn, f2x1, f2x1, f1x1);
  3696. add_intrinsic2(ctx, fn, f2x2, f2x1, f1x2);
  3697. add_intrinsic2(ctx, fn, f2x3, f2x1, f1x3);
  3698. add_intrinsic2(ctx, fn, f2x4, f2x1, f1x4);
  3699. add_intrinsic2(ctx, fn, f2x1, f2x2, f2x1);
  3700. add_intrinsic2(ctx, fn, f2x2, f2x2, f2x2);
  3701. add_intrinsic2(ctx, fn, f2x3, f2x2, f2x3);
  3702. add_intrinsic2(ctx, fn, f2x4, f2x2, f2x4);
  3703. add_intrinsic2(ctx, fn, f2x1, f2x3, f3x1);
  3704. add_intrinsic2(ctx, fn, f2x2, f2x3, f3x2);
  3705. add_intrinsic2(ctx, fn, f2x3, f2x3, f3x3);
  3706. add_intrinsic2(ctx, fn, f2x4, f2x3, f3x4);
  3707. add_intrinsic2(ctx, fn, f2x1, f2x4, f4x1);
  3708. add_intrinsic2(ctx, fn, f2x2, f2x4, f4x2);
  3709. add_intrinsic2(ctx, fn, f2x3, f2x4, f4x3);
  3710. add_intrinsic2(ctx, fn, f2x4, f2x4, f4x4);
  3711. add_intrinsic2(ctx, fn, f3x1, f3x1, f1x1);
  3712. add_intrinsic2(ctx, fn, f3x2, f3x1, f1x2);
  3713. add_intrinsic2(ctx, fn, f3x3, f3x1, f1x3);
  3714. add_intrinsic2(ctx, fn, f3x4, f3x1, f1x4);
  3715. add_intrinsic2(ctx, fn, f3x1, f3x2, f2x1);
  3716. add_intrinsic2(ctx, fn, f3x2, f3x2, f2x2);
  3717. add_intrinsic2(ctx, fn, f3x3, f3x2, f2x3);
  3718. add_intrinsic2(ctx, fn, f3x4, f3x2, f2x4);
  3719. add_intrinsic2(ctx, fn, f3x1, f3x3, f3x1);
  3720. add_intrinsic2(ctx, fn, f3x2, f3x3, f3x2);
  3721. add_intrinsic2(ctx, fn, f3x3, f3x3, f3x3);
  3722. add_intrinsic2(ctx, fn, f3x4, f3x3, f3x4);
  3723. add_intrinsic2(ctx, fn, f3x1, f3x4, f4x1);
  3724. add_intrinsic2(ctx, fn, f3x2, f3x4, f4x2);
  3725. add_intrinsic2(ctx, fn, f3x3, f3x4, f4x3);
  3726. add_intrinsic2(ctx, fn, f3x4, f3x4, f4x4);
  3727. add_intrinsic2(ctx, fn, f4x1, f4x1, f1x1);
  3728. add_intrinsic2(ctx, fn, f4x2, f4x1, f1x2);
  3729. add_intrinsic2(ctx, fn, f4x3, f4x1, f1x3);
  3730. add_intrinsic2(ctx, fn, f4x4, f4x1, f1x4);
  3731. add_intrinsic2(ctx, fn, f4x1, f4x2, f2x1);
  3732. add_intrinsic2(ctx, fn, f4x2, f4x2, f2x2);
  3733. add_intrinsic2(ctx, fn, f4x3, f4x2, f2x3);
  3734. add_intrinsic2(ctx, fn, f4x4, f4x2, f2x4);
  3735. add_intrinsic2(ctx, fn, f4x1, f4x3, f3x1);
  3736. add_intrinsic2(ctx, fn, f4x2, f4x3, f3x2);
  3737. add_intrinsic2(ctx, fn, f4x3, f4x3, f3x3);
  3738. add_intrinsic2(ctx, fn, f4x4, f4x3, f3x4);
  3739. add_intrinsic2(ctx, fn, f4x1, f4x4, f4x1);
  3740. add_intrinsic2(ctx, fn, f4x2, f4x4, f4x2);
  3741. add_intrinsic2(ctx, fn, f4x3, f4x4, f4x3);
  3742. add_intrinsic2(ctx, fn, f4x4, f4x4, f4x4);
  3743. } // add_intrinsic_mul
  3744. static void init_builtins(Context *ctx)
  3745. {
  3746. // add in standard typedefs...
  3747. const struct
  3748. {
  3749. const char *str;
  3750. const MOJOSHADER_astDataType *datatype;
  3751. } types[] = {
  3752. { "bool", &ctx->dt_bool },
  3753. { "int", &ctx->dt_int },
  3754. { "uint", &ctx->dt_uint },
  3755. { "half", &ctx->dt_half },
  3756. { "float", &ctx->dt_float },
  3757. { "double", &ctx->dt_double },
  3758. };
  3759. int i, j, k;
  3760. for (i = 0; i < STATICARRAYLEN(types); i++)
  3761. {
  3762. char buf[32];
  3763. int len;
  3764. const MOJOSHADER_astDataType *dt;
  3765. for (j = 1; j <= 4; j++)
  3766. {
  3767. // "float2"
  3768. dt = new_datatype_vector(ctx, types[i].datatype, j);
  3769. len = snprintf(buf, sizeof (buf), "%s%d", types[i].str, j);
  3770. push_usertype(ctx, stringcache_len(ctx->strcache, buf, len), dt);
  3771. for (k = 1; k <= 4; k++)
  3772. {
  3773. // "float2x2"
  3774. dt = new_datatype_matrix(ctx, types[i].datatype, j, k);
  3775. len = snprintf(buf, sizeof (buf), "%s%dx%d", types[i].str,j,k);
  3776. push_usertype(ctx, stringcache_len(ctx->strcache,buf,len), dt);
  3777. } // for
  3778. } // for
  3779. } // for
  3780. // !!! FIXME: block these out by pixel/vertex/etc shader.
  3781. // !!! FIXME: calculate actual shader model (or maybe just let bytecode verifier throw up?).
  3782. const int shader_model = 3;
  3783. if (shader_model >= 1)
  3784. {
  3785. add_intrinsic_SAME1_ANYfi(ctx, stringcache(ctx->strcache, "abs"));
  3786. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "acos"));
  3787. add_intrinsic_BOOL_ANYfib(ctx, stringcache(ctx->strcache, "all"));
  3788. add_intrinsic_BOOL_ANYfib(ctx, stringcache(ctx->strcache, "any"));
  3789. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "asin"));
  3790. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "atan"));
  3791. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "atan2"));
  3792. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ceil"));
  3793. add_intrinsic_SAME1_ANYfi_SAME1_SAME1(ctx, stringcache(ctx->strcache, "clamp"));
  3794. add_intrinsic_VOID_ANYf(ctx, stringcache(ctx->strcache, "clip"));
  3795. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "cos"));
  3796. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "cosh"));
  3797. add_intrinsic_3f_3f_3f(ctx, stringcache(ctx->strcache, "cross"));
  3798. add_intrinsic_4i_4f(ctx, stringcache(ctx->strcache, "D3DCOLORtoUBYTE4"));
  3799. add_intrinsic_f_Vf_SAME1(ctx, stringcache(ctx->strcache, "distance"));
  3800. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "degrees"));
  3801. add_intrinsic_f_SQUAREMATRIXf(ctx, stringcache(ctx->strcache, "determinant"));
  3802. add_intrinsic_fi_Vfi_SAME1(ctx, stringcache(ctx->strcache, "dot"));
  3803. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "exp"));
  3804. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "exp2"));
  3805. add_intrinsic_SAME1_Vf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "faceforward"));
  3806. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "floor"));
  3807. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "fmod"));
  3808. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "frac"));
  3809. add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isfinite"));
  3810. add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isinf"));
  3811. add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isnan"));
  3812. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "ldexp"));
  3813. add_intrinsic_f_Vf(ctx, stringcache(ctx->strcache, "length"));
  3814. add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "lerp"));
  3815. add_intrinsic_4f_f_f_f(ctx, stringcache(ctx->strcache, "lit"));
  3816. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log"));
  3817. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log10"));
  3818. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log2"));
  3819. add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "max"));
  3820. add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "min"));
  3821. add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "modf")); // !!! FIXME: out var?
  3822. add_intrinsic_mul(ctx, stringcache(ctx->strcache, "mul"));
  3823. add_intrinsic_f_Vf(ctx, stringcache(ctx->strcache, "noise"));
  3824. add_intrinsic_SAME1_Vf(ctx, stringcache(ctx->strcache, "normalize"));
  3825. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "pow"));
  3826. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "radians"));
  3827. add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "reflect"));
  3828. add_intrinsic_SAME1_Vf_SAME1_f(ctx, stringcache(ctx->strcache, "refract"));
  3829. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "round"));
  3830. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "rsqrt"));
  3831. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "saturate"));
  3832. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sign"));
  3833. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sin"));
  3834. add_intrinsic_VOID_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "sincos")); // !!! FIXME: out var?
  3835. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sinh"));
  3836. add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "smoothstep"));
  3837. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sqrt"));
  3838. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "step"));
  3839. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "tan"));
  3840. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "tanh"));
  3841. add_intrinsic_4f_s1_f(ctx, stringcache(ctx->strcache, "tex1D"));
  3842. add_intrinsic_4f_s2_2f(ctx, stringcache(ctx->strcache, "tex2D"));
  3843. add_intrinsic_4f_s3_3f(ctx, stringcache(ctx->strcache, "tex3D"));
  3844. add_intrinsic_4f_sc_3f(ctx, stringcache(ctx->strcache, "texCUBE"));
  3845. add_intrinsic_SAME1_Mfib(ctx, stringcache(ctx->strcache, "transpose"));
  3846. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "trunc"));
  3847. } // if
  3848. if (shader_model >= 2)
  3849. {
  3850. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ddx"));
  3851. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ddy"));
  3852. add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "frexp"));
  3853. add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "fwidth"));
  3854. add_intrinsic_4f_s1_f_f_f(ctx, stringcache(ctx->strcache, "tex1D"));
  3855. add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dbias"));
  3856. add_intrinsic_4f_s1_f_f_f(ctx, stringcache(ctx->strcache, "tex1Dgrad"));
  3857. add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dproj"));
  3858. add_intrinsic_4f_s2_2f_2f_2f(ctx, stringcache(ctx->strcache, "tex2D"));
  3859. add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dbias"));
  3860. add_intrinsic_4f_s2_2f_2f_2f(ctx, stringcache(ctx->strcache, "tex2Dgrad"));
  3861. add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dproj"));
  3862. add_intrinsic_4f_s3_3f_3f_3f(ctx, stringcache(ctx->strcache, "tex3D"));
  3863. add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dbias"));
  3864. add_intrinsic_4f_s3_3f_3f_3f(ctx, stringcache(ctx->strcache, "tex3Dgrad"));
  3865. add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dproj"));
  3866. add_intrinsic_4f_sc_3f_3f_3f(ctx, stringcache(ctx->strcache, "texCUBE"));
  3867. add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBEbias"));
  3868. add_intrinsic_4f_sc_3f_3f_3f(ctx, stringcache(ctx->strcache, "texCUBEgrad"));
  3869. add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBEproj"));
  3870. } // if
  3871. if (shader_model >= 3)
  3872. {
  3873. add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dlod"));
  3874. add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dlod"));
  3875. add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dlod"));
  3876. add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBElod"));
  3877. } // if
  3878. } // init_builtins
  3879. // parse the source code into an AST.
  3880. static void parse_source(Context *ctx, const char *filename,
  3881. const char *source, unsigned int sourcelen,
  3882. const MOJOSHADER_preprocessorDefine *defines,
  3883. unsigned int define_count,
  3884. MOJOSHADER_includeOpen include_open,
  3885. MOJOSHADER_includeClose include_close)
  3886. {
  3887. TokenData data;
  3888. unsigned int tokenlen;
  3889. Token tokenval;
  3890. const char *token;
  3891. int lemon_token;
  3892. const char *fname;
  3893. Preprocessor *pp;
  3894. void *parser;
  3895. if (!include_open) include_open = MOJOSHADER_internal_include_open;
  3896. if (!include_close) include_close = MOJOSHADER_internal_include_close;
  3897. pp = preprocessor_start(filename, source, sourcelen, include_open,
  3898. include_close, defines, define_count, 0,
  3899. MallocBridge, FreeBridge, ctx);
  3900. if (pp == NULL)
  3901. {
  3902. assert(ctx->out_of_memory); // shouldn't fail for any other reason.
  3903. return;
  3904. } // if
  3905. parser = ParseHLSLAlloc(ctx->malloc, ctx->malloc_data);
  3906. if (parser == NULL)
  3907. {
  3908. assert(ctx->out_of_memory); // shouldn't fail for any other reason.
  3909. preprocessor_end(pp);
  3910. return;
  3911. } // if
  3912. // !!! FIXME: check if (parser == NULL)...
  3913. init_builtins(ctx);
  3914. SymbolScope *start_scope = ctx->usertypes.scope;
  3915. #if DEBUG_COMPILER_PARSER
  3916. ParseHLSLTrace(stdout, "COMPILER: ");
  3917. #endif
  3918. // Run the preprocessor/lexer/parser...
  3919. int is_pragma = 0; // !!! FIXME: remove this later when we can parse #pragma.
  3920. int skipping = 0; // !!! FIXME: remove this later when we can parse #pragma.
  3921. do {
  3922. token = preprocessor_nexttoken(pp, &tokenlen, &tokenval);
  3923. if (ctx->out_of_memory)
  3924. break;
  3925. fname = preprocessor_sourcepos(pp, &ctx->sourceline);
  3926. ctx->sourcefile = fname ? stringcache(ctx->strcache, fname) : 0;
  3927. if ((tokenval == TOKEN_HASH) || (tokenval == TOKEN_HASHHASH))
  3928. tokenval = TOKEN_BAD_CHARS;
  3929. if (tokenval == TOKEN_BAD_CHARS)
  3930. {
  3931. fail(ctx, "Bad characters in source file");
  3932. continue;
  3933. } // else if
  3934. else if (tokenval == TOKEN_PREPROCESSING_ERROR)
  3935. {
  3936. fail(ctx, token); // this happens to be null-terminated.
  3937. continue;
  3938. } // else if
  3939. else if (tokenval == TOKEN_PP_PRAGMA)
  3940. {
  3941. assert(!is_pragma);
  3942. is_pragma = 1;
  3943. skipping = 1;
  3944. continue;
  3945. }
  3946. else if (tokenval == ((Token) '\n'))
  3947. {
  3948. assert(is_pragma);
  3949. is_pragma = 0;
  3950. skipping = 0;
  3951. continue;
  3952. }
  3953. else if (skipping)
  3954. {
  3955. continue;
  3956. }
  3957. // !!! FIXME: this is a mess, decide who should be doing this stuff, and only do it once.
  3958. lemon_token = convert_to_lemon_token(ctx, token, tokenlen, tokenval);
  3959. switch (lemon_token)
  3960. {
  3961. case TOKEN_HLSL_INT_CONSTANT:
  3962. data.i64 = strtoi64(token, tokenlen);
  3963. break;
  3964. case TOKEN_HLSL_FLOAT_CONSTANT:
  3965. data.dbl = strtodouble(token, tokenlen);
  3966. break;
  3967. case TOKEN_HLSL_USERTYPE:
  3968. data.string = stringcache_len(ctx->strcache, token, tokenlen);
  3969. data.datatype = get_usertype(ctx, data.string); // !!! FIXME: do we need this? It's kind of useless during parsing.
  3970. assert(data.datatype != NULL);
  3971. break;
  3972. case TOKEN_HLSL_STRING_LITERAL:
  3973. case TOKEN_HLSL_IDENTIFIER:
  3974. data.string = stringcache_len(ctx->strcache, token, tokenlen);
  3975. break;
  3976. default:
  3977. data.i64 = 0;
  3978. break;
  3979. } // switch
  3980. ParseHLSL(parser, lemon_token, data, ctx);
  3981. // this probably isn't perfect, but it's good enough for surviving
  3982. // the parse. We'll sort out correctness once we have a tree.
  3983. if (lemon_token == TOKEN_HLSL_LBRACE)
  3984. push_scope(ctx);
  3985. else if (lemon_token == TOKEN_HLSL_RBRACE)
  3986. pop_scope(ctx);
  3987. } while (tokenval != TOKEN_EOI);
  3988. // Clean out extra usertypes; they are dummies until semantic analysis.
  3989. while (ctx->usertypes.scope != start_scope)
  3990. pop_symbol(ctx, &ctx->usertypes);
  3991. ParseHLSLFree(parser, ctx->free, ctx->malloc_data);
  3992. preprocessor_end(pp);
  3993. } // parse_source
  3994. /* Intermediate representation... */
  3995. static inline int generate_ir_label(Context *ctx)
  3996. {
  3997. return ctx->ir_label_count++;
  3998. } // generate_ir_label
  3999. static inline int generate_ir_temp(Context *ctx)
  4000. {
  4001. return ctx->ir_temp_count++;
  4002. } // generate_ir_temp
  4003. static const LoopLabels *push_ir_loop(Context *ctx, const int isswitch)
  4004. {
  4005. // !!! FIXME: cache these allocations?
  4006. LoopLabels *retval = (LoopLabels *)Malloc(ctx, sizeof (LoopLabels));
  4007. if (retval)
  4008. {
  4009. retval->start = (isswitch) ? -1 : generate_ir_label(ctx);
  4010. retval->end = generate_ir_label(ctx);
  4011. retval->prev = ctx->ir_loop;
  4012. ctx->ir_loop = retval;
  4013. } // if
  4014. return retval;
  4015. } // push_ir_loop
  4016. static void pop_ir_loop(Context *ctx)
  4017. {
  4018. assert(ctx->ir_loop != NULL);
  4019. LoopLabels *labels = ctx->ir_loop;
  4020. ctx->ir_loop = ctx->ir_loop->prev;
  4021. Free(ctx, labels);
  4022. } // pop_ir_loop
  4023. #define NEW_IR_NODE(retval, cls, typ) \
  4024. cls *retval = (cls *) Malloc(ctx, sizeof (cls)); \
  4025. do { \
  4026. if (retval == NULL) { return NULL; } \
  4027. retval->ir.type = typ; \
  4028. retval->ir.filename = ctx->sourcefile; \
  4029. retval->ir.line = ctx->sourceline; \
  4030. } while (0)
  4031. #define NEW_IR_EXPR(retval, cls, typ, dt, numelems) \
  4032. cls *retval = (cls *) Malloc(ctx, sizeof (cls)); \
  4033. do { \
  4034. if (retval == NULL) { return NULL; } \
  4035. retval->info.ir.type = typ; \
  4036. retval->info.ir.filename = ctx->sourcefile; \
  4037. retval->info.ir.line = ctx->sourceline; \
  4038. retval->info.type = dt; \
  4039. retval->info.elements = numelems; \
  4040. } while (0)
  4041. // syntactic sugar.
  4042. static inline MOJOSHADER_irNode *build_ir(Context *ctx, void *_ast);
  4043. static inline MOJOSHADER_irExpression *build_ir_expr(Context *ctx, void *_ast)
  4044. {
  4045. MOJOSHADER_irNode *retval = build_ir(ctx, _ast);
  4046. assert(!retval || (retval->ir.type > MOJOSHADER_IR_START_RANGE_EXPR));
  4047. assert(!retval || (retval->ir.type < MOJOSHADER_IR_END_RANGE_EXPR));
  4048. return (MOJOSHADER_irExpression *) retval;
  4049. } // build_ir_expr
  4050. static inline MOJOSHADER_irStatement *build_ir_stmt(Context *ctx, void *_ast)
  4051. {
  4052. MOJOSHADER_irNode *retval = build_ir(ctx, _ast);
  4053. assert(!retval || (retval->ir.type > MOJOSHADER_IR_START_RANGE_STMT));
  4054. assert(!retval || (retval->ir.type < MOJOSHADER_IR_END_RANGE_STMT));
  4055. return (MOJOSHADER_irStatement *) retval;
  4056. } // build_ir_stmt
  4057. static MOJOSHADER_irExpression *new_ir_binop(Context *ctx,
  4058. const MOJOSHADER_irBinOpType op,
  4059. MOJOSHADER_irExpression *left,
  4060. MOJOSHADER_irExpression *right)
  4061. {
  4062. if ((!left) || (!right)) return NULL;
  4063. NEW_IR_EXPR(retval, MOJOSHADER_irBinOp, MOJOSHADER_IR_BINOP, left->info.type, left->info.elements);
  4064. assert(left->info.type == right->info.type);
  4065. assert(left->info.elements == right->info.elements);
  4066. retval->op = op;
  4067. retval->left = left;
  4068. retval->right = right;
  4069. return (MOJOSHADER_irExpression *) retval;
  4070. } // new_ir_binop
  4071. static MOJOSHADER_irExpression *new_ir_eseq(Context *ctx,
  4072. MOJOSHADER_irStatement *stmt,
  4073. MOJOSHADER_irExpression *expr)
  4074. {
  4075. if (!expr) return NULL;
  4076. NEW_IR_EXPR(retval, MOJOSHADER_irESeq, MOJOSHADER_IR_ESEQ, expr->info.type, expr->info.elements);
  4077. retval->stmt = stmt;
  4078. retval->expr = expr;
  4079. return (MOJOSHADER_irExpression *) retval;
  4080. } // new_ir_eseq
  4081. static MOJOSHADER_irExpression *new_ir_temp(Context *ctx, const int index,
  4082. const MOJOSHADER_astDataTypeType type,
  4083. const int elements)
  4084. {
  4085. NEW_IR_EXPR(retval, MOJOSHADER_irTemp, MOJOSHADER_IR_TEMP, type, elements);
  4086. retval->index = index;
  4087. return (MOJOSHADER_irExpression *) retval;
  4088. } // new_ir_temp
  4089. #define NEW_IR_BINOP(op,l,r) new_ir_binop(ctx, MOJOSHADER_IR_BINOP_##op, l, r)
  4090. #define EASY_IR_BINOP(op) \
  4091. NEW_IR_BINOP(op, build_ir_expr(ctx, ast->binary.left), \
  4092. build_ir_expr(ctx, ast->binary.right))
  4093. // You have to fill in ->value yourself!
  4094. static MOJOSHADER_irExpression *new_ir_constant(Context *ctx,
  4095. const MOJOSHADER_astDataTypeType type,
  4096. const int elements)
  4097. {
  4098. NEW_IR_EXPR(retval, MOJOSHADER_irConstant, MOJOSHADER_IR_CONSTANT, type, elements);
  4099. return (MOJOSHADER_irExpression *) retval;
  4100. } // new_ir_constant
  4101. static MOJOSHADER_irExpression *new_ir_constint(Context *ctx, const int val)
  4102. {
  4103. NEW_IR_EXPR(retval, MOJOSHADER_irConstant, MOJOSHADER_IR_CONSTANT, MOJOSHADER_AST_DATATYPE_INT, 1);
  4104. retval->value.ival[0] = val;
  4105. return (MOJOSHADER_irExpression *) retval;
  4106. } // new_ir_constint
  4107. static MOJOSHADER_irExpression *new_ir_constfloat(Context *ctx, const float val)
  4108. {
  4109. NEW_IR_EXPR(retval, MOJOSHADER_irConstant, MOJOSHADER_IR_CONSTANT, MOJOSHADER_AST_DATATYPE_FLOAT, 1);
  4110. retval->value.fval[0] = val;
  4111. return (MOJOSHADER_irExpression *) retval;
  4112. } // new_ir_constfloat
  4113. static MOJOSHADER_irExpression *new_ir_constbool(Context *ctx, const int val)
  4114. {
  4115. // !!! FIXME: cache true and false in (ctx), ignore in delete_ir().
  4116. NEW_IR_EXPR(retval, MOJOSHADER_irConstant, MOJOSHADER_IR_CONSTANT, MOJOSHADER_AST_DATATYPE_BOOL, 1);
  4117. retval->value.ival[0] = val;
  4118. return (MOJOSHADER_irExpression *) retval;
  4119. } // new_ir_constbool
  4120. static MOJOSHADER_irExpression *new_ir_convert(Context *ctx, MOJOSHADER_irExpression *expr,
  4121. const MOJOSHADER_astDataTypeType type,
  4122. const int elements)
  4123. {
  4124. NEW_IR_EXPR(retval, MOJOSHADER_irConvert, MOJOSHADER_IR_CONVERT, type, elements);
  4125. retval->expr = expr;
  4126. return (MOJOSHADER_irExpression *) retval;
  4127. } // new_ir_convert
  4128. static MOJOSHADER_irExpression *new_ir_construct(Context *ctx, MOJOSHADER_irExprList *args,
  4129. const MOJOSHADER_astDataTypeType type,
  4130. const int elements)
  4131. {
  4132. NEW_IR_EXPR(retval, MOJOSHADER_irConstruct, MOJOSHADER_IR_CONSTRUCT, type, elements);
  4133. retval->args = args;
  4134. return (MOJOSHADER_irExpression *) retval;
  4135. } // new_ir_construct
  4136. static MOJOSHADER_irExpression *new_ir_call(Context *ctx, const int index,
  4137. MOJOSHADER_irExprList *args,
  4138. const MOJOSHADER_astDataTypeType type,
  4139. const int elements)
  4140. {
  4141. NEW_IR_EXPR(retval, MOJOSHADER_irCall, MOJOSHADER_IR_CALL, type, elements);
  4142. retval->args = args;
  4143. retval->index = index;
  4144. return (MOJOSHADER_irExpression *) retval;
  4145. } // new_ir_call
  4146. static MOJOSHADER_irExpression *new_ir_swizzle(Context *ctx,
  4147. MOJOSHADER_irExpression *expr,
  4148. const char *channels,
  4149. const MOJOSHADER_astDataTypeType type,
  4150. const int elements)
  4151. {
  4152. NEW_IR_EXPR(retval, MOJOSHADER_irSwizzle, MOJOSHADER_IR_SWIZZLE, type, elements);
  4153. retval->expr = expr;
  4154. memcpy(retval->channels, channels, sizeof (retval->channels));
  4155. return (MOJOSHADER_irExpression *) retval;
  4156. } // new_ir_swizzle
  4157. static MOJOSHADER_irExpression *new_ir_memory(Context *ctx, const int index,
  4158. const MOJOSHADER_astDataTypeType type,
  4159. const int elements)
  4160. {
  4161. NEW_IR_EXPR(retval, MOJOSHADER_irMemory, MOJOSHADER_IR_MEMORY, type, elements);
  4162. retval->index = index;
  4163. return (MOJOSHADER_irExpression *) retval;
  4164. } // new_ir_memory
  4165. static MOJOSHADER_irExpression *new_ir_array(Context *ctx,
  4166. MOJOSHADER_irExpression *array,
  4167. MOJOSHADER_irExpression *element,
  4168. const MOJOSHADER_astDataTypeType type,
  4169. const int elements)
  4170. {
  4171. NEW_IR_EXPR(retval, MOJOSHADER_irArray, MOJOSHADER_IR_ARRAY, type, elements);
  4172. retval->array = array;
  4173. retval->element = element;
  4174. return (MOJOSHADER_irExpression *) retval;
  4175. } // new_ir_array
  4176. static MOJOSHADER_irStatement *new_ir_seq(Context *ctx,
  4177. MOJOSHADER_irStatement *first,
  4178. MOJOSHADER_irStatement *next)
  4179. {
  4180. assert((first != NULL) || (next != NULL));
  4181. if (first == NULL) // don't generate a SEQ if unnecessary.
  4182. return next;
  4183. else if (next == NULL)
  4184. return first;
  4185. NEW_IR_NODE(retval, MOJOSHADER_irSeq, MOJOSHADER_IR_SEQ);
  4186. retval->first = first;
  4187. retval->next = next;
  4188. return (MOJOSHADER_irStatement *) retval;
  4189. } // new_ir_seq
  4190. static MOJOSHADER_irStatement *new_ir_jump(Context *ctx, const int label)
  4191. {
  4192. NEW_IR_NODE(retval, MOJOSHADER_irJump, MOJOSHADER_IR_JUMP);
  4193. retval->label = label;
  4194. return (MOJOSHADER_irStatement *) retval;
  4195. } // new_ir_jump
  4196. static MOJOSHADER_irStatement *new_ir_cjump(Context *ctx,
  4197. const MOJOSHADER_irConditionType cond,
  4198. MOJOSHADER_irExpression *left,
  4199. MOJOSHADER_irExpression *right,
  4200. const int iftrue, const int iffalse)
  4201. {
  4202. NEW_IR_NODE(retval, MOJOSHADER_irCJump, MOJOSHADER_IR_CJUMP);
  4203. retval->cond = cond;
  4204. retval->left = left;
  4205. retval->right = right;
  4206. retval->iftrue = iftrue;
  4207. retval->iffalse = iffalse;
  4208. return (MOJOSHADER_irStatement *) retval;
  4209. } // new_ir_cjump
  4210. static MOJOSHADER_irStatement *new_ir_label(Context *ctx, const int index)
  4211. {
  4212. NEW_IR_NODE(retval, MOJOSHADER_irLabel, MOJOSHADER_IR_LABEL);
  4213. retval->index = index;
  4214. return (MOJOSHADER_irStatement *) retval;
  4215. } // new_ir_label
  4216. static MOJOSHADER_irStatement *new_ir_move(Context *ctx,
  4217. MOJOSHADER_irExpression *dst,
  4218. MOJOSHADER_irExpression *src,
  4219. const int writemask)
  4220. {
  4221. NEW_IR_NODE(retval, MOJOSHADER_irMove, MOJOSHADER_IR_MOVE);
  4222. assert(dst && src && (dst->info.type == src->info.type));
  4223. assert(dst && src && (dst->info.elements == src->info.elements));
  4224. retval->dst = dst;
  4225. retval->src = src;
  4226. retval->writemask = writemask;
  4227. return (MOJOSHADER_irStatement *) retval;
  4228. } // new_ir_move
  4229. static MOJOSHADER_irStatement *new_ir_expr_stmt(Context *ctx, MOJOSHADER_irExpression *expr)
  4230. {
  4231. NEW_IR_NODE(retval, MOJOSHADER_irExprStmt, MOJOSHADER_IR_EXPR_STMT);
  4232. retval->expr = expr;
  4233. return (MOJOSHADER_irStatement *) retval;
  4234. } // new_ir_expr_stmt
  4235. static MOJOSHADER_irStatement *new_ir_discard(Context *ctx)
  4236. {
  4237. NEW_IR_NODE(retval, MOJOSHADER_irDiscard, MOJOSHADER_IR_DISCARD);
  4238. return (MOJOSHADER_irStatement *) retval;
  4239. } // new_ir_discard
  4240. static MOJOSHADER_irExprList *new_ir_exprlist(Context *ctx, MOJOSHADER_irExpression *expr)
  4241. {
  4242. NEW_IR_NODE(retval, MOJOSHADER_irExprList, MOJOSHADER_IR_EXPRLIST);
  4243. retval->expr = expr;
  4244. retval->next = NULL;
  4245. return (MOJOSHADER_irExprList *) retval;
  4246. } // new_ir_exprlist
  4247. // This handles most comparison operators (less-than, equals, etc...)
  4248. static MOJOSHADER_irExpression *build_ir_compare(Context *ctx,
  4249. const MOJOSHADER_irConditionType operation,
  4250. MOJOSHADER_irExpression *left,
  4251. MOJOSHADER_irExpression *right,
  4252. MOJOSHADER_irExpression *tval,
  4253. MOJOSHADER_irExpression *fval)
  4254. {
  4255. /* The gist...
  4256. cjump x < y, t, f // '<' is whatever operation
  4257. t:
  4258. move tmp, tval
  4259. jump join
  4260. f:
  4261. move tmp, fval
  4262. join:
  4263. */
  4264. const int t = generate_ir_label(ctx);
  4265. const int f = generate_ir_label(ctx);
  4266. const int join = generate_ir_label(ctx);
  4267. const int tmp = generate_ir_temp(ctx);
  4268. assert(tval && fval && (tval->info.type == fval->info.type));
  4269. assert(tval && fval && (tval->info.elements == fval->info.elements));
  4270. const MOJOSHADER_astDataTypeType dt = tval->info.type;
  4271. const int elements = tval->info.elements;
  4272. return new_ir_eseq(ctx,
  4273. new_ir_seq(ctx, new_ir_cjump(ctx, operation, left, right, t, f),
  4274. new_ir_seq(ctx, new_ir_label(ctx, t),
  4275. new_ir_seq(ctx, new_ir_move(ctx, new_ir_temp(ctx, tmp, dt, elements), tval, -1),
  4276. new_ir_seq(ctx, new_ir_jump(ctx, join),
  4277. new_ir_seq(ctx, new_ir_label(ctx, f),
  4278. new_ir_seq(ctx, new_ir_move(ctx, new_ir_temp(ctx, tmp, dt, elements), fval, -1),
  4279. new_ir_label(ctx, join))))))),
  4280. new_ir_temp(ctx, tmp, dt, elements));
  4281. } // build_ir_compare
  4282. #define EASY_IR_COMPARE(op) \
  4283. build_ir_compare(ctx, MOJOSHADER_IR_COND_##op, \
  4284. build_ir_expr(ctx, ast->binary.left), \
  4285. build_ir_expr(ctx, ast->binary.right), \
  4286. new_ir_constbool(ctx, 1), \
  4287. new_ir_constbool(ctx, 0))
  4288. // This handles && and || operators.
  4289. static MOJOSHADER_irExpression *build_ir_logical_and_or(Context *ctx,
  4290. const MOJOSHADER_astExpressionBinary *ast,
  4291. const int left_testval)
  4292. {
  4293. /* The gist...
  4294. cjump left == left_testval, maybe, f
  4295. maybe:
  4296. cjump right == true, t, f
  4297. t:
  4298. move tmp, 1
  4299. jump join
  4300. f:
  4301. move tmp, 0
  4302. join:
  4303. */
  4304. assert(ast->left->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4305. assert(ast->right->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4306. const int t = generate_ir_label(ctx);
  4307. const int f = generate_ir_label(ctx);
  4308. const int maybe = generate_ir_label(ctx);
  4309. const int join = generate_ir_label(ctx);
  4310. const int tmp = generate_ir_temp(ctx);
  4311. return new_ir_eseq(ctx,
  4312. new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->left), new_ir_constbool(ctx, left_testval), maybe, f),
  4313. new_ir_seq(ctx, new_ir_label(ctx, maybe),
  4314. new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->right), new_ir_constbool(ctx, 1), t, f),
  4315. new_ir_seq(ctx, new_ir_label(ctx, t),
  4316. new_ir_seq(ctx, new_ir_move(ctx, new_ir_temp(ctx, tmp, MOJOSHADER_AST_DATATYPE_BOOL, 1), new_ir_constbool(ctx, 1), -1),
  4317. new_ir_seq(ctx, new_ir_jump(ctx, join),
  4318. new_ir_seq(ctx, new_ir_label(ctx, f),
  4319. new_ir_seq(ctx, new_ir_move(ctx, new_ir_temp(ctx, tmp, MOJOSHADER_AST_DATATYPE_BOOL, 1), new_ir_constbool(ctx, 0), -1),
  4320. new_ir_label(ctx, join))))))))),
  4321. new_ir_temp(ctx, tmp, MOJOSHADER_AST_DATATYPE_BOOL, 1));
  4322. } // build_ir_logical_and_or
  4323. static inline MOJOSHADER_irExpression *build_ir_logical_and(Context *ctx,
  4324. const MOJOSHADER_astExpressionBinary *ast)
  4325. {
  4326. // this needs to not evaluate (right) if (left) is false!
  4327. return build_ir_logical_and_or(ctx, ast, 1);
  4328. } // build_ir_logical_and
  4329. static inline MOJOSHADER_irExpression *build_ir_logical_or(Context *ctx,
  4330. const MOJOSHADER_astExpressionBinary *ast)
  4331. {
  4332. // this needs to not evaluate (right) if (left) is true!
  4333. return build_ir_logical_and_or(ctx, ast, 0);
  4334. } // build_ir_logical_or
  4335. static inline MOJOSHADER_irStatement *build_ir_no_op(Context *ctx)
  4336. {
  4337. return new_ir_label(ctx, generate_ir_label(ctx));
  4338. } // build_ir_no_op
  4339. static MOJOSHADER_irStatement *build_ir_ifstmt(Context *ctx,
  4340. const MOJOSHADER_astIfStatement *ast)
  4341. {
  4342. assert(ast->expr->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4343. // !!! FIXME: ast->attributes?
  4344. // IF statement without an ELSE.
  4345. if (ast->else_statement == NULL)
  4346. {
  4347. /* The gist...
  4348. cjump expr, t, join
  4349. t:
  4350. statement
  4351. join:
  4352. */
  4353. const int t = generate_ir_label(ctx);
  4354. const int join = generate_ir_label(ctx);
  4355. return new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->expr), new_ir_constbool(ctx, 1), t, join),
  4356. new_ir_seq(ctx, new_ir_label(ctx, t),
  4357. new_ir_seq(ctx, build_ir_stmt(ctx, ast->statement),
  4358. new_ir_seq(ctx, new_ir_label(ctx, join),
  4359. build_ir_stmt(ctx, ast->next)))));
  4360. } // if
  4361. // IF statement _with_ an ELSE.
  4362. /* The gist...
  4363. cjump expr, t, f
  4364. t:
  4365. statement
  4366. jump join
  4367. f:
  4368. elsestatement
  4369. join:
  4370. */
  4371. const int t = generate_ir_label(ctx);
  4372. const int f = generate_ir_label(ctx);
  4373. const int join = generate_ir_label(ctx);
  4374. return new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->expr), new_ir_constbool(ctx, 1), t, f),
  4375. new_ir_seq(ctx, new_ir_label(ctx, t),
  4376. new_ir_seq(ctx, build_ir_stmt(ctx, ast->statement),
  4377. new_ir_seq(ctx, new_ir_jump(ctx, join),
  4378. new_ir_seq(ctx, new_ir_label(ctx, f),
  4379. new_ir_seq(ctx, build_ir_stmt(ctx, ast->else_statement),
  4380. new_ir_seq(ctx, new_ir_label(ctx, join),
  4381. build_ir_stmt(ctx, ast->next))))))));
  4382. } // build_ir_ifstmt
  4383. static MOJOSHADER_irStatement *build_ir_forstmt(Context *ctx,
  4384. const MOJOSHADER_astForStatement *ast)
  4385. {
  4386. // !!! FIXME: ast->unroll
  4387. assert(ast->looptest->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4388. /* The gist...
  4389. initializer // (or var_decl->initializer!)
  4390. test:
  4391. cjump looptest == true, loop, join
  4392. loop:
  4393. statement
  4394. increment: // needs to be here; this is where "continue" jumps!
  4395. counter
  4396. jump test
  4397. join:
  4398. */
  4399. const int test = generate_ir_label(ctx);
  4400. const int loop = generate_ir_label(ctx);
  4401. const LoopLabels *labels = push_ir_loop(ctx, 0);
  4402. if (labels == NULL)
  4403. return NULL; // out of memory...
  4404. const int increment = labels->start;
  4405. const int join = labels->end;
  4406. assert( (ast->var_decl && !ast->initializer) ||
  4407. (!ast->var_decl && ast->initializer) );
  4408. MOJOSHADER_irStatement *init = NULL;
  4409. if (ast->var_decl != NULL)
  4410. {
  4411. //sdfsdf
  4412. // !!! FIXME: map the initializer to the variable? Need fix to var_decl parsing.
  4413. // new_ir_move(ctx, FIXME MAP TO REGISTER ast->var_decl->index, build_ir_expr(ctx, ast->fsdf));
  4414. // FIXME
  4415. // init = build_ir_vardecl(ctx, ast->var_decl);
  4416. } // if
  4417. else
  4418. {
  4419. // init = build_ir_expr(ctx, ast->initializer);
  4420. } // else
  4421. MOJOSHADER_irStatement *retval =
  4422. new_ir_seq(ctx, init,
  4423. new_ir_seq(ctx, new_ir_label(ctx, test),
  4424. new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->looptest), new_ir_constbool(ctx, 1), loop, join),
  4425. new_ir_seq(ctx, new_ir_label(ctx, loop),
  4426. new_ir_seq(ctx, build_ir_stmt(ctx, ast->statement),
  4427. new_ir_seq(ctx, new_ir_label(ctx, increment),
  4428. new_ir_seq(ctx, new_ir_expr_stmt(ctx, build_ir_expr(ctx, ast->counter)),
  4429. new_ir_seq(ctx, new_ir_jump(ctx, test),
  4430. new_ir_label(ctx, join)))))))));
  4431. pop_ir_loop(ctx);
  4432. return new_ir_seq(ctx, retval, build_ir_stmt(ctx, ast->next));
  4433. } // build_ir_forstmt
  4434. static MOJOSHADER_irStatement *build_ir_whilestmt(Context *ctx,
  4435. const MOJOSHADER_astWhileStatement *ast)
  4436. {
  4437. // !!! FIXME: ast->unroll
  4438. assert(ast->expr->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4439. /* The gist...
  4440. loop:
  4441. cjump expr == true, t, join
  4442. t:
  4443. statement
  4444. jump loop
  4445. join:
  4446. */
  4447. const LoopLabels *labels = push_ir_loop(ctx, 0);
  4448. if (labels == NULL)
  4449. return NULL; // out of memory...
  4450. const int loop = labels->start;
  4451. const int t = generate_ir_label(ctx);
  4452. const int join = labels->end;
  4453. MOJOSHADER_irStatement *retval =
  4454. new_ir_seq(ctx, new_ir_label(ctx, loop),
  4455. new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->expr), new_ir_constbool(ctx, 1), t, join),
  4456. new_ir_seq(ctx, new_ir_label(ctx, t),
  4457. new_ir_seq(ctx, build_ir_stmt(ctx, ast->statement),
  4458. new_ir_seq(ctx, new_ir_jump(ctx, loop),
  4459. new_ir_label(ctx, join))))));
  4460. pop_ir_loop(ctx);
  4461. return new_ir_seq(ctx, retval, build_ir_stmt(ctx, ast->next));
  4462. } // build_ir_whilestmt
  4463. static MOJOSHADER_irStatement *build_ir_dostmt(Context *ctx,
  4464. const MOJOSHADER_astDoStatement *ast)
  4465. {
  4466. // !!! FIXME: ast->unroll
  4467. assert(ast->expr->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4468. /* The gist...
  4469. loop:
  4470. statement
  4471. cjump expr == true, loop, join
  4472. join:
  4473. */
  4474. const LoopLabels *labels = push_ir_loop(ctx, 0);
  4475. if (labels == NULL)
  4476. return NULL; // out of memory...
  4477. const int loop = labels->start;
  4478. const int join = labels->end;
  4479. MOJOSHADER_irStatement *retval =
  4480. new_ir_seq(ctx, new_ir_label(ctx, loop),
  4481. new_ir_seq(ctx, build_ir_stmt(ctx, ast->statement),
  4482. new_ir_seq(ctx, new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, ast->expr), new_ir_constbool(ctx, 1), loop, join),
  4483. new_ir_label(ctx, join))));
  4484. pop_ir_loop(ctx);
  4485. return new_ir_seq(ctx, retval, build_ir_stmt(ctx, ast->next));
  4486. } // build_ir_dostmt
  4487. static MOJOSHADER_irStatement *build_ir_switch(Context *ctx, const MOJOSHADER_astSwitchStatement *ast)
  4488. {
  4489. // Dithering down to a list of if-statements in all cases
  4490. // isn't ideal, but we can't do jumptables in D3D bytecode.
  4491. // !!! FIXME: attributes?
  4492. /* The gist...
  4493. move tmp, expr
  4494. cjump tmp == case1expr, case1, testcase2
  4495. testcase2: // etc
  4496. cjump tmp == case2expr, case2, join
  4497. case1:
  4498. case1stmt // might have a break in it somewhere.
  4499. case2:
  4500. case2stmt
  4501. join:
  4502. */
  4503. const LoopLabels *labels = push_ir_loop(ctx, 1);
  4504. if (labels == NULL)
  4505. return NULL; // out of memory...
  4506. const int join = labels->end;
  4507. const int elems = datatype_elems(ctx, ast->expr->datatype);
  4508. const MOJOSHADER_astDataTypeType dt = datatype_base(ctx, ast->expr->datatype)->type;
  4509. const MOJOSHADER_astSwitchCases *cases = ast->cases;
  4510. const int tmp = generate_ir_temp(ctx);
  4511. MOJOSHADER_irStatement *startseqs = new_ir_move(ctx, new_ir_temp(ctx, tmp, dt, elems), build_ir_expr(ctx, ast->expr), -1);
  4512. MOJOSHADER_irStatement *testseqs = startseqs;
  4513. MOJOSHADER_irStatement *startcaseseqs = NULL;
  4514. MOJOSHADER_irStatement *caseseqs = NULL;
  4515. while (cases)
  4516. {
  4517. const int t = generate_ir_label(ctx);
  4518. const int f = (cases->next == NULL) ? join : generate_ir_label(ctx);
  4519. MOJOSHADER_irStatement *cjump = new_ir_cjump(ctx, MOJOSHADER_IR_COND_EQL, build_ir_expr(ctx, cases->expr), new_ir_temp(ctx, tmp, dt, elems), t, f);
  4520. if (cases->next == NULL) // last one, do the join label.
  4521. {
  4522. testseqs = new_ir_seq(ctx, testseqs, cjump);
  4523. caseseqs = new_ir_seq(ctx, caseseqs, new_ir_seq(ctx, new_ir_label(ctx, t), build_ir_stmt(ctx, cases->statement)));
  4524. caseseqs = new_ir_seq(ctx, caseseqs, new_ir_label(ctx, f));
  4525. } // if
  4526. else
  4527. {
  4528. testseqs = new_ir_seq(ctx, testseqs, new_ir_seq(ctx, cjump, new_ir_label(ctx, f)));
  4529. caseseqs = new_ir_seq(ctx, caseseqs, new_ir_seq(ctx, new_ir_label(ctx, t), build_ir_stmt(ctx, cases->statement)));
  4530. } // else
  4531. if (startcaseseqs == NULL)
  4532. startcaseseqs = caseseqs;
  4533. cases = cases->next;
  4534. } // while
  4535. pop_ir_loop(ctx);
  4536. return new_ir_seq(ctx, startseqs, new_ir_seq(ctx, startcaseseqs, build_ir_stmt(ctx, ast->next)));
  4537. } // build_ir_switch
  4538. static MOJOSHADER_irExpression *build_ir_increxpr(Context *ctx, const MOJOSHADER_astDataType *_dt,
  4539. const int val)
  4540. {
  4541. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, _dt);
  4542. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4543. const int elems = datatype_elems(ctx, dt);
  4544. MOJOSHADER_irConstant *retval = (MOJOSHADER_irConstant *) new_ir_constant(ctx, type, elems);
  4545. int i;
  4546. switch (type)
  4547. {
  4548. case MOJOSHADER_AST_DATATYPE_BOOL:
  4549. case MOJOSHADER_AST_DATATYPE_INT:
  4550. case MOJOSHADER_AST_DATATYPE_UINT:
  4551. for (i = 0; i < elems; i++)
  4552. retval->value.ival[i] = (int) val;
  4553. break;
  4554. case MOJOSHADER_AST_DATATYPE_FLOAT:
  4555. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM:
  4556. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM:
  4557. case MOJOSHADER_AST_DATATYPE_HALF:
  4558. case MOJOSHADER_AST_DATATYPE_DOUBLE:
  4559. for (i = 0; i < elems; i++)
  4560. retval->value.fval[i] = (float) val;
  4561. break;
  4562. default:
  4563. assert(0 && "Semantic analysis should have caught this!");
  4564. } // switch
  4565. return (MOJOSHADER_irExpression *) retval;
  4566. } // build_ir_increxpr
  4567. static MOJOSHADER_irExpression *build_ir_preincdec(Context *ctx, MOJOSHADER_astExpressionUnary *ast, const MOJOSHADER_irBinOpType binop)
  4568. {
  4569. /* The gist...
  4570. move expr, expr + 1
  4571. return expr
  4572. */
  4573. // !!! FIXME: can you writemask an increment operator?
  4574. MOJOSHADER_irExpression *constant = build_ir_increxpr(ctx, ast->datatype, 1);
  4575. return new_ir_eseq(ctx,
  4576. new_ir_move(ctx,
  4577. build_ir_expr(ctx, ast->operand),
  4578. new_ir_binop(ctx, binop, build_ir_expr(ctx, ast->operand), constant), -1),
  4579. build_ir_expr(ctx, ast->operand));
  4580. } // build_ir_preincdec
  4581. static MOJOSHADER_irExpression *build_ir_postincdec(Context *ctx, MOJOSHADER_astExpressionUnary *ast, const MOJOSHADER_irBinOpType binop)
  4582. {
  4583. /* The gist...
  4584. move tmp, expr
  4585. move expr, expr + 1
  4586. return tmp
  4587. */
  4588. // !!! FIXME: can you writemask an increment operator?
  4589. MOJOSHADER_irExpression *constant = build_ir_increxpr(ctx, ast->datatype, 1);
  4590. const int tmp = generate_ir_temp(ctx);
  4591. return new_ir_eseq(ctx,
  4592. new_ir_seq(ctx,
  4593. new_ir_move(ctx, new_ir_temp(ctx, tmp, constant->info.type, constant->info.elements), build_ir_expr(ctx, ast->operand), -1),
  4594. new_ir_move(ctx, build_ir_expr(ctx, ast->operand),
  4595. new_ir_binop(ctx, binop, build_ir_expr(ctx, ast->operand), constant), -1)),
  4596. new_ir_temp(ctx, tmp, constant->info.type, constant->info.elements));
  4597. } // build_ir_postincdec
  4598. static MOJOSHADER_irExpression *build_ir_convert(Context *ctx, const MOJOSHADER_astExpressionCast *ast)
  4599. {
  4600. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4601. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4602. const int elems = datatype_elems(ctx, dt);
  4603. return new_ir_convert(ctx, build_ir_expr(ctx, ast->operand), type, elems);
  4604. } // build_ir_convert
  4605. static MOJOSHADER_irExprList *build_ir_exprlist(Context *ctx, MOJOSHADER_astArguments *args)
  4606. {
  4607. MOJOSHADER_irExprList *retval = NULL;
  4608. MOJOSHADER_irExprList *prev = NULL;
  4609. while (args != NULL)
  4610. {
  4611. assert((retval && prev) || ((!retval) && (!prev)));
  4612. MOJOSHADER_irExprList *item = new_ir_exprlist(ctx, build_ir_expr(ctx, args->argument));
  4613. if (prev == NULL)
  4614. prev = retval = item;
  4615. else
  4616. prev->next = item;
  4617. args = args->next;
  4618. } // while
  4619. return retval;
  4620. } // build_ir_exprlist
  4621. static MOJOSHADER_irExpression *build_ir_constructor(Context *ctx, const MOJOSHADER_astExpressionConstructor *ast)
  4622. {
  4623. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4624. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4625. const int elems = datatype_elems(ctx, dt);
  4626. assert(elems <= 16); // just in case (matrix4x4 constructor is largest).
  4627. return new_ir_construct(ctx, build_ir_exprlist(ctx, ast->args), type, elems);
  4628. } // build_ir_constructor
  4629. static MOJOSHADER_irExpression *build_ir_call(Context *ctx, const MOJOSHADER_astExpressionCallFunction *ast)
  4630. {
  4631. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4632. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4633. const int elems = datatype_elems(ctx, dt);
  4634. return new_ir_call(ctx, ast->identifier->index, build_ir_exprlist(ctx, ast->args), type, elems);
  4635. } // build_ir_call
  4636. static char swiz_to_channel(const char swiz)
  4637. {
  4638. if ((swiz == 'r') || (swiz == 'x')) return 0;
  4639. if ((swiz == 'g') || (swiz == 'y')) return 1;
  4640. if ((swiz == 'b') || (swiz == 'z')) return 2;
  4641. if ((swiz == 'a') || (swiz == 'w')) return 3;
  4642. assert(0 && "Should have been caught by semantic analysis.");
  4643. return 0;
  4644. } // swiz_to_channel
  4645. static MOJOSHADER_irExpression *build_ir_swizzle(Context *ctx, const MOJOSHADER_astExpressionDerefStruct *ast)
  4646. {
  4647. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4648. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4649. const int elems = datatype_elems(ctx, dt);
  4650. char chans[4] = { 0, 0, 0, 0 };
  4651. const char *swizstr = ast->member;
  4652. int i;
  4653. for (i = 0; swizstr[i]; i++)
  4654. chans[i] = swiz_to_channel(swizstr[i]);
  4655. return new_ir_swizzle(ctx, build_ir_expr(ctx, ast->identifier), chans, type, elems);
  4656. } // build_ir_swizzle
  4657. static MOJOSHADER_irExpression *build_ir_identifier(Context *ctx, const MOJOSHADER_astExpressionIdentifier *ast)
  4658. {
  4659. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4660. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4661. const int elems = datatype_elems(ctx, dt);
  4662. return new_ir_memory(ctx, ast->index, type, elems);
  4663. } // build_ir_identifier
  4664. static MOJOSHADER_irExpression *build_ir_derefstruct(Context *ctx, const MOJOSHADER_astExpressionDerefStruct *ast)
  4665. {
  4666. // There are only three possible IR nodes that contain a struct:
  4667. // an irTemp, an irMemory, or an irESeq that results in a temp or memory.
  4668. // As such, we figure out which it is, and offset appropriately for the
  4669. // member.
  4670. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4671. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4672. const int elems = datatype_elems(ctx, dt);
  4673. MOJOSHADER_irExpression *expr = build_ir_expr(ctx, ast->identifier);
  4674. MOJOSHADER_irExpression *finalexpr = expr;
  4675. if (expr == NULL)
  4676. return NULL;
  4677. assert(!ast->isswizzle);
  4678. while (finalexpr->ir.type == MOJOSHADER_IR_ESEQ)
  4679. finalexpr = finalexpr->eseq.expr;
  4680. if (finalexpr->ir.type == MOJOSHADER_IR_TEMP)
  4681. finalexpr->temp.index += ast->member_index;
  4682. else if (finalexpr->ir.type == MOJOSHADER_IR_MEMORY)
  4683. finalexpr->memory.index += ast->member_index;
  4684. else
  4685. assert(0 && "Unexpected condition");
  4686. // Replace the struct type with the type of the member.
  4687. expr->info.type = type;
  4688. expr->info.elements = elems;
  4689. return expr;
  4690. } // build_ir_derefstruct
  4691. static MOJOSHADER_irExpression *build_ir_derefarray(Context *ctx, const MOJOSHADER_astExpressionBinary *ast)
  4692. {
  4693. // In most compilers, arrays dither down to offsets into memory, but
  4694. // they're somewhat special in D3D, since they might have to deal with
  4695. // vectors, etc...so we keep them as first-class citizens of the IR,
  4696. // and let the optimizer/codegen sort it out.
  4697. // !!! FIXME: this might be the wrong move. Maybe remove this IR node type?
  4698. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->datatype);
  4699. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4700. const int elems = datatype_elems(ctx, dt);
  4701. // !!! FIXME: Array dereference of a vector can become a simple swizzle operation, if we have a constant index.
  4702. // !!! FIXME: Matrix dereference of a vector can become a simple reference to a temp/memory, if we have a constant index.
  4703. return new_ir_array(ctx, build_ir_expr(ctx, ast->left), build_ir_expr(ctx, ast->right), type, elems);
  4704. } // build_ir_derefarray
  4705. static MOJOSHADER_irExpression *build_ir_assign_binop(Context *ctx,
  4706. const MOJOSHADER_irBinOpType op,
  4707. const MOJOSHADER_astExpressionBinary *ast)
  4708. {
  4709. MOJOSHADER_irExpression *lvalue = build_ir_expr(ctx, ast->left);
  4710. MOJOSHADER_irExpression *rvalue = build_ir_expr(ctx, ast->right);
  4711. const MOJOSHADER_astDataTypeType type = lvalue->info.type;
  4712. const int elems = lvalue->info.elements;
  4713. const int tmp = generate_ir_temp(ctx);
  4714. // Semantic analysis should have inserted casts if necessary.
  4715. assert(type == rvalue->info.type);
  4716. assert(elems == rvalue->info.elements);
  4717. // The destination must eventually be lvalue, which means memory or temp.
  4718. MOJOSHADER_irExpression *dst = lvalue;
  4719. while (dst->ir.type == MOJOSHADER_IR_ESEQ)
  4720. dst = dst->eseq.expr;
  4721. if (dst->ir.type == MOJOSHADER_IR_TEMP)
  4722. dst = new_ir_temp(ctx, dst->temp.index, dst->info.type, dst->info.elements);
  4723. else if (dst->ir.type == MOJOSHADER_IR_MEMORY)
  4724. dst = new_ir_memory(ctx, dst->memory.index, dst->info.type, dst->info.elements);
  4725. else
  4726. assert(0 && "Unexpected condition");
  4727. // !!! FIXME: write masking!
  4728. return new_ir_eseq(ctx,
  4729. new_ir_seq(ctx,
  4730. new_ir_move(ctx, new_ir_temp(ctx, tmp, type, elems), new_ir_binop(ctx, op, lvalue, rvalue), -1),
  4731. new_ir_move(ctx, dst, new_ir_temp(ctx, tmp, type, elems), -1)),
  4732. new_ir_temp(ctx, tmp, type, elems));
  4733. } // build_ir_assign_binop
  4734. static MOJOSHADER_irExpression *build_ir_assign(Context *ctx,
  4735. const MOJOSHADER_astExpressionBinary *ast)
  4736. {
  4737. MOJOSHADER_irExpression *lvalue = build_ir_expr(ctx, ast->left);
  4738. MOJOSHADER_irExpression *rvalue = build_ir_expr(ctx, ast->right);
  4739. const MOJOSHADER_astDataTypeType type = lvalue->info.type;
  4740. const int elems = lvalue->info.elements;
  4741. const int tmp = generate_ir_temp(ctx);
  4742. // Semantic analysis should have inserted casts if necessary.
  4743. assert(type == rvalue->info.type);
  4744. assert(elems == rvalue->info.elements);
  4745. // !!! FIXME: write masking!
  4746. // !!! FIXME: whole array/struct assignments need to become a sequence of moves.
  4747. return new_ir_eseq(ctx,
  4748. new_ir_seq(ctx,
  4749. new_ir_move(ctx, new_ir_temp(ctx, tmp, type, elems), rvalue, -1),
  4750. new_ir_move(ctx, lvalue, new_ir_temp(ctx, tmp, type, elems), -1)),
  4751. new_ir_temp(ctx, tmp, type, elems));
  4752. } // build_ir_assign
  4753. // The AST must be perfect and normalized and sane here. If there are any
  4754. // strange corner cases, you should strive to handle them in semantic
  4755. // analysis, so conversion to IR can proceed with a minimum of drama.
  4756. static void *build_ir_internal(Context *ctx, void *_ast);
  4757. static inline MOJOSHADER_irNode *build_ir(Context *ctx, void *_ast)
  4758. {
  4759. return (MOJOSHADER_irNode *) build_ir_internal(ctx, _ast);
  4760. } // build_ir
  4761. static void *build_ir_internal(Context *ctx, void *_ast)
  4762. {
  4763. if ((_ast == NULL) || (ctx->out_of_memory))
  4764. return NULL;
  4765. MOJOSHADER_astNode *ast = (MOJOSHADER_astNode *) _ast;
  4766. // upkeep so we report correct error locations...
  4767. ctx->sourcefile = ast->ast.filename;
  4768. ctx->sourceline = ast->ast.line;
  4769. switch (ast->ast.type)
  4770. {
  4771. case MOJOSHADER_AST_OP_PREINCREMENT: // !!! FIXME: sequence points?
  4772. return build_ir_preincdec(ctx, &ast->unary, MOJOSHADER_IR_BINOP_ADD);
  4773. case MOJOSHADER_AST_OP_POSTINCREMENT: // !!! FIXME: sequence points?
  4774. return build_ir_postincdec(ctx, &ast->unary, MOJOSHADER_IR_BINOP_ADD);
  4775. case MOJOSHADER_AST_OP_PREDECREMENT: // !!! FIXME: sequence points?
  4776. return build_ir_preincdec(ctx, &ast->unary, MOJOSHADER_IR_BINOP_SUBTRACT);
  4777. case MOJOSHADER_AST_OP_POSTDECREMENT: // !!! FIXME: sequence points?
  4778. return build_ir_postincdec(ctx, &ast->unary, MOJOSHADER_IR_BINOP_SUBTRACT);
  4779. case MOJOSHADER_AST_OP_COMPLEMENT:
  4780. return NEW_IR_BINOP(XOR, build_ir_expr(ctx, ast->unary.operand),
  4781. new_ir_constint(ctx, 0xFFFFFFFF));
  4782. case MOJOSHADER_AST_OP_NEGATE: // !!! FIXME: -0.0f != +0.0f
  4783. return NEW_IR_BINOP(SUBTRACT, build_ir_increxpr(ctx, ast->unary.datatype, -1),
  4784. build_ir_expr(ctx, ast->unary.operand));
  4785. case MOJOSHADER_AST_OP_NOT: // operand must be bool here!
  4786. assert(ast->unary.operand->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4787. return NEW_IR_BINOP(XOR, build_ir_expr(ctx, ast->unary.operand),
  4788. new_ir_constint(ctx, 1));
  4789. case MOJOSHADER_AST_OP_DEREF_ARRAY:
  4790. return build_ir_derefarray(ctx, &ast->binary);
  4791. case MOJOSHADER_AST_OP_DEREF_STRUCT:
  4792. if (ast->derefstruct.isswizzle)
  4793. return build_ir_swizzle(ctx, &ast->derefstruct);
  4794. return build_ir_derefstruct(ctx, &ast->derefstruct);
  4795. case MOJOSHADER_AST_OP_COMMA:
  4796. // evaluate and throw away left, return right.
  4797. return new_ir_eseq(ctx, new_ir_expr_stmt(ctx, build_ir_expr(ctx, ast->binary.left)),
  4798. build_ir_expr(ctx, ast->binary.right));
  4799. case MOJOSHADER_AST_OP_LESSTHAN: return EASY_IR_COMPARE(LT);
  4800. case MOJOSHADER_AST_OP_GREATERTHAN: return EASY_IR_COMPARE(GT);
  4801. case MOJOSHADER_AST_OP_LESSTHANOREQUAL: return EASY_IR_COMPARE(LEQ);
  4802. case MOJOSHADER_AST_OP_GREATERTHANOREQUAL: return EASY_IR_COMPARE(GEQ);
  4803. case MOJOSHADER_AST_OP_NOTEQUAL: return EASY_IR_COMPARE(NEQ);
  4804. case MOJOSHADER_AST_OP_EQUAL: return EASY_IR_COMPARE(EQL);
  4805. case MOJOSHADER_AST_OP_MULTIPLY: return EASY_IR_BINOP(MULTIPLY);
  4806. case MOJOSHADER_AST_OP_DIVIDE: return EASY_IR_BINOP(DIVIDE);
  4807. case MOJOSHADER_AST_OP_MODULO: return EASY_IR_BINOP(MODULO);
  4808. case MOJOSHADER_AST_OP_ADD: return EASY_IR_BINOP(ADD);
  4809. case MOJOSHADER_AST_OP_SUBTRACT: return EASY_IR_BINOP(SUBTRACT);
  4810. case MOJOSHADER_AST_OP_LSHIFT: return EASY_IR_BINOP(LSHIFT);
  4811. case MOJOSHADER_AST_OP_RSHIFT: return EASY_IR_BINOP(RSHIFT);
  4812. case MOJOSHADER_AST_OP_BINARYAND: return EASY_IR_BINOP(AND);
  4813. case MOJOSHADER_AST_OP_BINARYXOR: return EASY_IR_BINOP(XOR);
  4814. case MOJOSHADER_AST_OP_BINARYOR: return EASY_IR_BINOP(OR);
  4815. case MOJOSHADER_AST_OP_LOGICALAND:
  4816. return build_ir_logical_and(ctx, &ast->binary);
  4817. case MOJOSHADER_AST_OP_LOGICALOR:
  4818. return build_ir_logical_or(ctx, &ast->binary);
  4819. case MOJOSHADER_AST_OP_ASSIGN:
  4820. return build_ir_assign(ctx, &ast->binary);
  4821. case MOJOSHADER_AST_OP_MULASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_MULTIPLY, &ast->binary);
  4822. case MOJOSHADER_AST_OP_DIVASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_DIVIDE, &ast->binary);
  4823. case MOJOSHADER_AST_OP_MODASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_MODULO, &ast->binary);
  4824. case MOJOSHADER_AST_OP_ADDASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_ADD, &ast->binary);
  4825. case MOJOSHADER_AST_OP_SUBASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_SUBTRACT, &ast->binary);
  4826. case MOJOSHADER_AST_OP_LSHIFTASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_LSHIFT, &ast->binary);
  4827. case MOJOSHADER_AST_OP_RSHIFTASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_RSHIFT, &ast->binary);
  4828. case MOJOSHADER_AST_OP_ANDASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_AND, &ast->binary);
  4829. case MOJOSHADER_AST_OP_XORASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_XOR, &ast->binary);
  4830. case MOJOSHADER_AST_OP_ORASSIGN: return build_ir_assign_binop(ctx, MOJOSHADER_IR_BINOP_OR, &ast->binary);
  4831. case MOJOSHADER_AST_OP_CONDITIONAL:
  4832. assert(ast->binary.left->datatype->type == MOJOSHADER_AST_DATATYPE_BOOL);
  4833. return build_ir_compare(ctx, MOJOSHADER_IR_COND_EQL,
  4834. build_ir_expr(ctx, ast->ternary.left),
  4835. new_ir_constbool(ctx, 1),
  4836. build_ir_expr(ctx, ast->ternary.center),
  4837. build_ir_expr(ctx, ast->ternary.right));
  4838. case MOJOSHADER_AST_OP_IDENTIFIER:
  4839. return build_ir_identifier(ctx, &ast->identifier);
  4840. case MOJOSHADER_AST_OP_INT_LITERAL:
  4841. return new_ir_constint(ctx, ast->intliteral.value);
  4842. case MOJOSHADER_AST_OP_FLOAT_LITERAL:
  4843. return new_ir_constfloat(ctx, ast->floatliteral.value);
  4844. case MOJOSHADER_AST_OP_BOOLEAN_LITERAL:
  4845. return new_ir_constbool(ctx, ast->boolliteral.value);
  4846. case MOJOSHADER_AST_OP_CALLFUNC:
  4847. return build_ir_call(ctx, &ast->callfunc);
  4848. case MOJOSHADER_AST_OP_CONSTRUCTOR:
  4849. return build_ir_constructor(ctx, &ast->constructor);
  4850. case MOJOSHADER_AST_OP_CAST:
  4851. return build_ir_convert(ctx, &ast->cast);
  4852. case MOJOSHADER_AST_STATEMENT_BREAK:
  4853. {
  4854. const LoopLabels *labels = ctx->ir_loop;
  4855. assert(labels != NULL); // semantic analysis should catch this.
  4856. return new_ir_jump(ctx, labels->end);
  4857. } // case
  4858. case MOJOSHADER_AST_STATEMENT_CONTINUE:
  4859. {
  4860. const LoopLabels *labels = ctx->ir_loop;
  4861. assert(labels != NULL); // semantic analysis should catch this.
  4862. return new_ir_jump(ctx, labels->start);
  4863. } // case
  4864. case MOJOSHADER_AST_STATEMENT_DISCARD:
  4865. return new_ir_seq(ctx, new_ir_discard(ctx), build_ir_stmt(ctx, ast->discardstmt.next));
  4866. case MOJOSHADER_AST_STATEMENT_EMPTY:
  4867. return build_ir(ctx, ast->stmt.next); // skip it, do next thing.
  4868. case MOJOSHADER_AST_STATEMENT_EXPRESSION:
  4869. return new_ir_seq(ctx, new_ir_expr_stmt(ctx, build_ir_expr(ctx, ast->exprstmt.expr)), build_ir_stmt(ctx, ast->exprstmt.next));
  4870. case MOJOSHADER_AST_STATEMENT_IF:
  4871. return build_ir_ifstmt(ctx, &ast->ifstmt);
  4872. case MOJOSHADER_AST_STATEMENT_TYPEDEF: // ignore this, move on.
  4873. return build_ir(ctx, ast->typedefstmt.next);
  4874. case MOJOSHADER_AST_STATEMENT_SWITCH:
  4875. return build_ir_switch(ctx, &ast->switchstmt);
  4876. case MOJOSHADER_AST_STATEMENT_STRUCT: // ignore this, move on.
  4877. return build_ir(ctx, ast->structstmt.next);
  4878. case MOJOSHADER_AST_STATEMENT_VARDECL: // ignore this, move on.
  4879. return build_ir(ctx, ast->vardeclstmt.next);
  4880. case MOJOSHADER_AST_STATEMENT_BLOCK:
  4881. return new_ir_seq(ctx, build_ir_stmt(ctx, ast->blockstmt.statements), build_ir_stmt(ctx, ast->blockstmt.next));
  4882. case MOJOSHADER_AST_STATEMENT_FOR:
  4883. return build_ir_forstmt(ctx, &ast->forstmt);
  4884. case MOJOSHADER_AST_STATEMENT_DO:
  4885. return build_ir_dostmt(ctx, &ast->dostmt);
  4886. case MOJOSHADER_AST_STATEMENT_WHILE:
  4887. return build_ir_whilestmt(ctx, &ast->whilestmt);
  4888. case MOJOSHADER_AST_STATEMENT_RETURN:
  4889. {
  4890. const int label = ctx->ir_end;
  4891. assert(label >= 0); // parser should have caught this!
  4892. MOJOSHADER_irStatement *retval = NULL;
  4893. if (ast->returnstmt.expr != NULL)
  4894. {
  4895. // !!! FIXME: whole array/struct returns need to move more into the temp.
  4896. const MOJOSHADER_astDataType *dt = reduce_datatype(ctx, ast->returnstmt.expr->datatype);
  4897. const MOJOSHADER_astDataTypeType type = datatype_base(ctx, dt)->type;
  4898. const int elems = datatype_elems(ctx, dt);
  4899. assert(ctx->ir_ret >= 0);
  4900. retval = new_ir_move(ctx, new_ir_temp(ctx, ctx->ir_ret, type, elems), build_ir_expr(ctx, ast->returnstmt.expr), -1);
  4901. } // if
  4902. return new_ir_seq(ctx, retval, new_ir_jump(ctx, label));
  4903. } // case
  4904. case MOJOSHADER_AST_COMPUNIT_TYPEDEF:
  4905. case MOJOSHADER_AST_COMPUNIT_STRUCT:
  4906. case MOJOSHADER_AST_COMPUNIT_VARIABLE:
  4907. case MOJOSHADER_AST_COMPUNIT_FUNCTION:
  4908. case MOJOSHADER_AST_ARGUMENTS:
  4909. case MOJOSHADER_AST_OP_STRING_LITERAL:
  4910. case MOJOSHADER_AST_SWITCH_CASE:
  4911. case MOJOSHADER_AST_SCALAR_OR_ARRAY:
  4912. case MOJOSHADER_AST_TYPEDEF:
  4913. case MOJOSHADER_AST_FUNCTION_PARAMS:
  4914. case MOJOSHADER_AST_FUNCTION_SIGNATURE:
  4915. case MOJOSHADER_AST_STRUCT_DECLARATION:
  4916. case MOJOSHADER_AST_STRUCT_MEMBER:
  4917. case MOJOSHADER_AST_VARIABLE_DECLARATION:
  4918. case MOJOSHADER_AST_ANNOTATION:
  4919. case MOJOSHADER_AST_PACK_OFFSET:
  4920. case MOJOSHADER_AST_VARIABLE_LOWLEVEL:
  4921. assert(0 && "Shouldn't hit this in build_ir.");
  4922. return NULL;
  4923. default:
  4924. assert(0 && "unexpected type");
  4925. return NULL;
  4926. } // switch
  4927. } // build_ir
  4928. static void print_ir(FILE *io, unsigned int depth, void *_ir)
  4929. {
  4930. MOJOSHADER_irNode *ir = (MOJOSHADER_irNode *) _ir;
  4931. if (ir == NULL)
  4932. return;
  4933. const char *fname = strrchr(ir->ir.filename, '/');
  4934. if (fname != NULL)
  4935. fname++;
  4936. else
  4937. {
  4938. fname = strrchr(ir->ir.filename, '\\');
  4939. if (fname != NULL)
  4940. fname++;
  4941. else
  4942. fname = ir->ir.filename;
  4943. } // else
  4944. int i;
  4945. for (i = 0; i < depth; i++)
  4946. fprintf(io, " ");
  4947. depth++;
  4948. fprintf(io, "[ %s:%d ", fname, ir->ir.line);
  4949. switch (ir->ir.type)
  4950. {
  4951. case MOJOSHADER_IR_LABEL:
  4952. fprintf(io, "LABEL %d ]\n", ir->stmt.label.index);
  4953. break;
  4954. case MOJOSHADER_IR_CONSTANT:
  4955. fprintf(io, "CONSTANT ");
  4956. switch (ir->expr.constant.info.type)
  4957. {
  4958. case MOJOSHADER_AST_DATATYPE_BOOL:
  4959. case MOJOSHADER_AST_DATATYPE_INT:
  4960. case MOJOSHADER_AST_DATATYPE_UINT:
  4961. for (i = 0; i < ir->expr.constant.info.elements-1; i++)
  4962. fprintf(io, "%d, ", ir->expr.constant.value.ival[i]);
  4963. if (ir->expr.constant.info.elements > 0)
  4964. fprintf(io, "%d", ir->expr.constant.value.ival[i]);
  4965. break;
  4966. case MOJOSHADER_AST_DATATYPE_FLOAT:
  4967. case MOJOSHADER_AST_DATATYPE_FLOAT_SNORM:
  4968. case MOJOSHADER_AST_DATATYPE_FLOAT_UNORM:
  4969. case MOJOSHADER_AST_DATATYPE_HALF:
  4970. case MOJOSHADER_AST_DATATYPE_DOUBLE:
  4971. for (i = 0; i < ir->expr.constant.info.elements-1; i++)
  4972. fprintf(io, "%ff, ", ir->expr.constant.value.fval[i]);
  4973. if (ir->expr.constant.info.elements > 0)
  4974. fprintf(io, "%ff", ir->expr.constant.value.fval[i]);
  4975. break;
  4976. default: assert(0 && "shouldn't happen");
  4977. } // switch
  4978. fprintf(io, " ]\n");
  4979. break;
  4980. case MOJOSHADER_IR_TEMP:
  4981. fprintf(io, "TEMP %d ]\n", ir->expr.temp.index);
  4982. break;
  4983. case MOJOSHADER_IR_DISCARD:
  4984. fprintf(io, "DISCARD ]\n");
  4985. break;
  4986. case MOJOSHADER_IR_SWIZZLE:
  4987. fprintf(io, "SWIZZLE");
  4988. for (i = 0; i < ir->expr.swizzle.info.elements-1; i++)
  4989. fprintf(io, " %d", (int) ir->expr.swizzle.channels[i]);
  4990. fprintf(io, " ]\n");
  4991. print_ir(io, depth, ir->expr.swizzle.expr);
  4992. break;
  4993. case MOJOSHADER_IR_CONSTRUCT:
  4994. fprintf(io, "CONSTRUCT ]\n");
  4995. print_ir(io, depth, ir->expr.construct.args);
  4996. break;
  4997. case MOJOSHADER_IR_CONVERT:
  4998. fprintf(io, "CONVERT ]\n");
  4999. print_ir(io, depth, ir->expr.convert.expr);
  5000. break;
  5001. case MOJOSHADER_IR_BINOP:
  5002. fprintf(io, "BINOP ");
  5003. switch (ir->expr.binop.op)
  5004. {
  5005. #define PRINT_IR_BINOP(x) \
  5006. case MOJOSHADER_IR_BINOP_##x: fprintf(io, #x); break;
  5007. PRINT_IR_BINOP(ADD)
  5008. PRINT_IR_BINOP(SUBTRACT)
  5009. PRINT_IR_BINOP(MULTIPLY)
  5010. PRINT_IR_BINOP(DIVIDE)
  5011. PRINT_IR_BINOP(MODULO)
  5012. PRINT_IR_BINOP(AND)
  5013. PRINT_IR_BINOP(OR)
  5014. PRINT_IR_BINOP(XOR)
  5015. PRINT_IR_BINOP(LSHIFT)
  5016. PRINT_IR_BINOP(RSHIFT)
  5017. PRINT_IR_BINOP(UNKNOWN)
  5018. #undef PRINT_IR_BINOP
  5019. default: assert(0 && "unexpected case"); break;
  5020. } // switch
  5021. fprintf(io, " ]\n");
  5022. print_ir(io, depth, ir->expr.binop.left);
  5023. print_ir(io, depth, ir->expr.binop.right);
  5024. break;
  5025. case MOJOSHADER_IR_MEMORY:
  5026. fprintf(io, "MEMORY %d ]\n", ir->expr.memory.index);
  5027. break;
  5028. case MOJOSHADER_IR_CALL:
  5029. fprintf(io, "CALL %d ]\n", ir->expr.call.index);
  5030. print_ir(io, depth, ir->expr.call.args);
  5031. break;
  5032. case MOJOSHADER_IR_ESEQ:
  5033. fprintf(io, "ESEQ ]\n");
  5034. print_ir(io, depth, ir->expr.eseq.stmt);
  5035. break;
  5036. case MOJOSHADER_IR_ARRAY:
  5037. fprintf(io, "ARRAY ]\n");
  5038. print_ir(io, depth, ir->expr.array.array);
  5039. print_ir(io, depth, ir->expr.array.element);
  5040. break;
  5041. case MOJOSHADER_IR_MOVE:
  5042. fprintf(io, "MOVE ]\n");
  5043. print_ir(io, depth, ir->stmt.move.dst);
  5044. print_ir(io, depth, ir->stmt.move.src);
  5045. break;
  5046. case MOJOSHADER_IR_EXPR_STMT:
  5047. fprintf(io, "EXPRSTMT ]\n");
  5048. print_ir(io, depth, ir->stmt.expr.expr);
  5049. break;
  5050. case MOJOSHADER_IR_JUMP:
  5051. fprintf(io, "JUMP %d ]\n", ir->stmt.jump.label);
  5052. break;
  5053. case MOJOSHADER_IR_CJUMP:
  5054. fprintf(io, "CJUMP ");
  5055. switch (ir->stmt.cjump.cond)
  5056. {
  5057. #define PRINT_IR_COND(x) \
  5058. case MOJOSHADER_IR_COND_##x: fprintf(io, #x); break;
  5059. PRINT_IR_COND(EQL)
  5060. PRINT_IR_COND(NEQ)
  5061. PRINT_IR_COND(LT)
  5062. PRINT_IR_COND(GT)
  5063. PRINT_IR_COND(LEQ)
  5064. PRINT_IR_COND(GEQ)
  5065. PRINT_IR_COND(UNKNOWN)
  5066. #undef PRINT_IR_COND
  5067. default: assert(0 && "unexpected case"); break;
  5068. } // switch
  5069. fprintf(io, " %d %d ]\n", ir->stmt.cjump.iftrue, ir->stmt.cjump.iffalse);
  5070. print_ir(io, depth, ir->stmt.cjump.left);
  5071. print_ir(io, depth, ir->stmt.cjump.right);
  5072. break;
  5073. case MOJOSHADER_IR_SEQ:
  5074. fprintf(io, "SEQ ]\n");
  5075. print_ir(io, depth, ir->stmt.seq.first);
  5076. print_ir(io, depth, ir->stmt.seq.next); // !!! FIXME: don't recurse?
  5077. break;
  5078. case MOJOSHADER_IR_EXPRLIST:
  5079. fprintf(io, "EXPRLIST ]\n");
  5080. print_ir(io, depth, ir->misc.exprlist.expr);
  5081. print_ir(io, depth, ir->misc.exprlist.next); // !!! FIXME: don't recurse?
  5082. break;
  5083. default: assert(0 && "unexpected IR node"); break;
  5084. } // switch
  5085. } // print_ir
  5086. static void print_whole_ir(Context *ctx, FILE *io)
  5087. {
  5088. if (ctx->ir != NULL)
  5089. {
  5090. int i;
  5091. for (i = 0; i <= ctx->user_func_index; i++)
  5092. {
  5093. printf("[FUNCTION %d ]\n", i);
  5094. print_ir(io, 1, ctx->ir[i]);
  5095. } // for
  5096. } // if
  5097. } // print_whole_ir
  5098. static void delete_ir(Context *ctx, void *_ir)
  5099. {
  5100. MOJOSHADER_irNode *ir = (MOJOSHADER_irNode *) _ir;
  5101. if (ir == NULL)
  5102. return;
  5103. switch (ir->ir.type)
  5104. {
  5105. case MOJOSHADER_IR_JUMP:
  5106. case MOJOSHADER_IR_LABEL:
  5107. case MOJOSHADER_IR_CONSTANT:
  5108. case MOJOSHADER_IR_TEMP:
  5109. case MOJOSHADER_IR_DISCARD:
  5110. case MOJOSHADER_IR_MEMORY:
  5111. break; // nothing extra to free here.
  5112. case MOJOSHADER_IR_BINOP:
  5113. delete_ir(ctx, ir->expr.binop.left);
  5114. delete_ir(ctx, ir->expr.binop.right);
  5115. break;
  5116. case MOJOSHADER_IR_CALL:
  5117. delete_ir(ctx, ir->expr.call.args);
  5118. break;
  5119. case MOJOSHADER_IR_ESEQ:
  5120. delete_ir(ctx, ir->expr.eseq.stmt);
  5121. delete_ir(ctx, ir->expr.eseq.expr);
  5122. break;
  5123. case MOJOSHADER_IR_ARRAY:
  5124. delete_ir(ctx, ir->expr.array.array);
  5125. delete_ir(ctx, ir->expr.array.element);
  5126. break;
  5127. case MOJOSHADER_IR_MOVE:
  5128. delete_ir(ctx, ir->stmt.move.dst);
  5129. delete_ir(ctx, ir->stmt.move.src);
  5130. break;
  5131. case MOJOSHADER_IR_EXPR_STMT:
  5132. delete_ir(ctx, ir->stmt.expr.expr);
  5133. break;
  5134. case MOJOSHADER_IR_CJUMP:
  5135. delete_ir(ctx, ir->stmt.cjump.left);
  5136. delete_ir(ctx, ir->stmt.cjump.right);
  5137. break;
  5138. case MOJOSHADER_IR_SEQ:
  5139. delete_ir(ctx, ir->stmt.seq.first);
  5140. delete_ir(ctx, ir->stmt.seq.next); // !!! FIXME: don't recurse?
  5141. break;
  5142. case MOJOSHADER_IR_EXPRLIST:
  5143. delete_ir(ctx, ir->misc.exprlist.expr);
  5144. delete_ir(ctx, ir->misc.exprlist.next); // !!! FIXME: don't recurse?
  5145. break;
  5146. case MOJOSHADER_IR_SWIZZLE:
  5147. delete_ir(ctx, ir->expr.swizzle.expr);
  5148. break;
  5149. case MOJOSHADER_IR_CONSTRUCT:
  5150. delete_ir(ctx, ir->expr.construct.args);
  5151. break;
  5152. case MOJOSHADER_IR_CONVERT:
  5153. delete_ir(ctx, ir->expr.convert.expr);
  5154. break;
  5155. default: assert(0 && "unexpected IR node"); break;
  5156. } // switch
  5157. Free(ctx, ir);
  5158. } // delete_ir
  5159. static void intermediate_representation(Context *ctx)
  5160. {
  5161. const MOJOSHADER_astCompilationUnit *ast = NULL;
  5162. const MOJOSHADER_astCompilationUnitFunction *astfn = NULL;
  5163. const size_t arraylen = (ctx->user_func_index+1) * sizeof (MOJOSHADER_irStatement *);
  5164. ctx->ir = (MOJOSHADER_irStatement **)Malloc(ctx, arraylen);
  5165. if (ctx->ir == NULL)
  5166. return;
  5167. memset(ctx->ir, '\0', arraylen);
  5168. ctx->ir_end = -1;
  5169. ctx->ir_ret = -1;
  5170. for (ast = &ctx->ast->compunit; ast != NULL; ast = ast->next)
  5171. {
  5172. assert(ast->ast.type > MOJOSHADER_AST_COMPUNIT_START_RANGE);
  5173. assert(ast->ast.type < MOJOSHADER_AST_COMPUNIT_END_RANGE);
  5174. if (ast->ast.type != MOJOSHADER_AST_COMPUNIT_FUNCTION)
  5175. continue; // only care about functions right now.
  5176. astfn = (MOJOSHADER_astCompilationUnitFunction *) ast;
  5177. if (astfn->definition == NULL) // just a predeclare; skip.
  5178. continue;
  5179. assert(ctx->ir_loop == NULL); // parser should have caught this!
  5180. assert(ctx->ir_end < 0); // parser should have caught this!
  5181. assert(ctx->ir_ret < 0); // parser should have caught this!
  5182. const int start = generate_ir_label(ctx); // !!! FIXME: store somewhere.
  5183. const int end = generate_ir_label(ctx);
  5184. ctx->ir_end = end;
  5185. if (astfn->declaration->datatype != NULL)
  5186. ctx->ir_ret = generate_ir_temp(ctx);
  5187. MOJOSHADER_irStatement *funcseq = new_ir_seq(ctx, new_ir_label(ctx, start), build_ir_stmt(ctx, astfn->definition));
  5188. funcseq = new_ir_seq(ctx, funcseq, new_ir_label(ctx, end));
  5189. assert(ctx->ir_loop == NULL); // parser should have caught this!
  5190. ctx->ir_end = -1;
  5191. ctx->ir_ret = -1;
  5192. assert(astfn->index <= ctx->user_func_index);
  5193. assert(ctx->ir[astfn->index] == NULL);
  5194. ctx->ir[astfn->index] = funcseq;
  5195. } // for
  5196. print_whole_ir(ctx, stdout);
  5197. // done with the AST, nuke it.
  5198. // !!! FIXME: we're going to need CTAB data from this at some point.
  5199. delete_compilation_unit(ctx, (MOJOSHADER_astCompilationUnit *) ctx->ast);
  5200. ctx->ast = NULL;
  5201. } // intermediate_representation
  5202. static MOJOSHADER_astData MOJOSHADER_out_of_mem_ast_data = {
  5203. 1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0, 0
  5204. };
  5205. // !!! FIXME: cut and paste from assembler.
  5206. static const MOJOSHADER_astData *build_failed_ast(Context *ctx)
  5207. {
  5208. assert(isfail(ctx));
  5209. if (ctx->out_of_memory)
  5210. return &MOJOSHADER_out_of_mem_ast_data;
  5211. MOJOSHADER_astData *retval = NULL;
  5212. retval = (MOJOSHADER_astData *) Malloc(ctx, sizeof (MOJOSHADER_astData));
  5213. if (retval == NULL)
  5214. return &MOJOSHADER_out_of_mem_ast_data;
  5215. memset(retval, '\0', sizeof (MOJOSHADER_astData));
  5216. retval->source_profile = ctx->source_profile;
  5217. retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  5218. retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  5219. retval->malloc_data = ctx->malloc_data;
  5220. retval->error_count = errorlist_count(ctx->errors);
  5221. retval->errors = errorlist_flatten(ctx->errors);
  5222. if (ctx->out_of_memory)
  5223. {
  5224. Free(ctx, retval);
  5225. return &MOJOSHADER_out_of_mem_ast_data;
  5226. } // if
  5227. return retval;
  5228. } // build_failed_ast
  5229. static const MOJOSHADER_astData *build_astdata(Context *ctx)
  5230. {
  5231. MOJOSHADER_astData *retval = NULL;
  5232. if (ctx->out_of_memory)
  5233. return &MOJOSHADER_out_of_mem_ast_data;
  5234. retval = (MOJOSHADER_astData *) Malloc(ctx, sizeof (MOJOSHADER_astData));
  5235. if (retval == NULL)
  5236. return &MOJOSHADER_out_of_mem_ast_data;
  5237. memset(retval, '\0', sizeof (MOJOSHADER_astData));
  5238. retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  5239. retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  5240. retval->malloc_data = ctx->malloc_data;
  5241. if (!isfail(ctx))
  5242. {
  5243. retval->source_profile = ctx->source_profile;
  5244. retval->ast = ctx->ast;
  5245. } // if
  5246. retval->error_count = errorlist_count(ctx->errors);
  5247. retval->errors = errorlist_flatten(ctx->errors);
  5248. if (ctx->out_of_memory)
  5249. {
  5250. Free(ctx, retval);
  5251. return &MOJOSHADER_out_of_mem_ast_data;
  5252. } // if
  5253. retval->opaque = ctx;
  5254. return retval;
  5255. } // build_astdata
  5256. static void choose_src_profile(Context *ctx, const char *srcprofile)
  5257. {
  5258. ctx->source_profile = srcprofile;
  5259. #define TEST_PROFILE(x) if (strcmp(srcprofile, x) == 0) { return; }
  5260. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_VS_1_1);
  5261. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_VS_2_0);
  5262. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_VS_3_0);
  5263. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_1_1);
  5264. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_1_2);
  5265. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_1_3);
  5266. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_1_4);
  5267. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_2_0);
  5268. TEST_PROFILE(MOJOSHADER_SRC_PROFILE_HLSL_PS_3_0);
  5269. #undef TEST_PROFILE
  5270. fail(ctx, "Unknown profile");
  5271. } // choose_src_profile
  5272. static MOJOSHADER_compileData MOJOSHADER_out_of_mem_compile_data = {
  5273. 1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  5274. };
  5275. // !!! FIXME: cut and paste from assembler.
  5276. static const MOJOSHADER_compileData *build_failed_compile(Context *ctx)
  5277. {
  5278. assert(isfail(ctx));
  5279. MOJOSHADER_compileData *retval = NULL;
  5280. retval = (MOJOSHADER_compileData *) Malloc(ctx, sizeof (MOJOSHADER_compileData));
  5281. if (retval == NULL)
  5282. return &MOJOSHADER_out_of_mem_compile_data;
  5283. memset(retval, '\0', sizeof (MOJOSHADER_compileData));
  5284. retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  5285. retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  5286. retval->malloc_data = ctx->malloc_data;
  5287. retval->source_profile = ctx->source_profile;
  5288. retval->error_count = errorlist_count(ctx->errors);
  5289. retval->errors = errorlist_flatten(ctx->errors);
  5290. retval->warning_count = errorlist_count(ctx->warnings);
  5291. retval->warnings = errorlist_flatten(ctx->warnings);
  5292. if (ctx->out_of_memory) // in case something failed up there.
  5293. {
  5294. MOJOSHADER_freeCompileData(retval);
  5295. return &MOJOSHADER_out_of_mem_compile_data;
  5296. } // if
  5297. return retval;
  5298. } // build_failed_compile
  5299. static const MOJOSHADER_compileData *build_compiledata(Context *ctx)
  5300. {
  5301. assert(!isfail(ctx));
  5302. MOJOSHADER_compileData *retval = NULL;
  5303. retval = (MOJOSHADER_compileData *) Malloc(ctx, sizeof (MOJOSHADER_compileData));
  5304. if (retval == NULL)
  5305. return &MOJOSHADER_out_of_mem_compile_data;
  5306. memset(retval, '\0', sizeof (MOJOSHADER_compileData));
  5307. retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  5308. retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  5309. retval->malloc_data = ctx->malloc_data;
  5310. retval->source_profile = ctx->source_profile;
  5311. if (!isfail(ctx))
  5312. {
  5313. // !!! FIXME: build output and output_len here.
  5314. } // if
  5315. if (!isfail(ctx))
  5316. {
  5317. // !!! FIXME: build symbols and symbol_count here.
  5318. } // if
  5319. retval->error_count = errorlist_count(ctx->errors);
  5320. retval->errors = errorlist_flatten(ctx->errors);
  5321. retval->warning_count = errorlist_count(ctx->warnings);
  5322. retval->warnings = errorlist_flatten(ctx->warnings);
  5323. if (ctx->out_of_memory) // in case something failed up there.
  5324. {
  5325. MOJOSHADER_freeCompileData(retval);
  5326. return &MOJOSHADER_out_of_mem_compile_data;
  5327. } // if
  5328. return retval;
  5329. } // build_compiledata
  5330. // API entry point...
  5331. // !!! FIXME: move this (and a lot of other things) to mojoshader_ast.c.
  5332. const MOJOSHADER_astData *MOJOSHADER_parseAst(const char *srcprofile,
  5333. const char *filename, const char *source,
  5334. unsigned int sourcelen,
  5335. const MOJOSHADER_preprocessorDefine *defs,
  5336. unsigned int define_count,
  5337. MOJOSHADER_includeOpen include_open,
  5338. MOJOSHADER_includeClose include_close,
  5339. MOJOSHADER_malloc m, MOJOSHADER_free f,
  5340. void *d)
  5341. {
  5342. const MOJOSHADER_astData *retval = NULL;
  5343. Context *ctx = NULL;
  5344. if ( ((m == NULL) && (f != NULL)) || ((m != NULL) && (f == NULL)) )
  5345. return &MOJOSHADER_out_of_mem_ast_data; // supply both or neither.
  5346. ctx = build_context(m, f, d);
  5347. if (ctx == NULL)
  5348. return &MOJOSHADER_out_of_mem_ast_data;
  5349. choose_src_profile(ctx, srcprofile);
  5350. if (!isfail(ctx))
  5351. {
  5352. parse_source(ctx, filename, source, sourcelen, defs, define_count,
  5353. include_open, include_close);
  5354. } // if
  5355. if (!isfail(ctx))
  5356. retval = build_astdata(ctx); // ctx isn't destroyed yet!
  5357. else
  5358. {
  5359. retval = (MOJOSHADER_astData *) build_failed_ast(ctx);
  5360. destroy_context(ctx);
  5361. } // else
  5362. return retval;
  5363. } // MOJOSHADER_parseAst
  5364. void MOJOSHADER_freeAstData(const MOJOSHADER_astData *_data)
  5365. {
  5366. MOJOSHADER_astData *data = (MOJOSHADER_astData *) _data;
  5367. if ((data == NULL) || (data == &MOJOSHADER_out_of_mem_ast_data))
  5368. return; // no-op.
  5369. // !!! FIXME: this needs to live for deleting the stringcache and the ast.
  5370. Context *ctx = (Context *) data->opaque;
  5371. MOJOSHADER_free f = (data->free == NULL) ? MOJOSHADER_internal_free : data->free;
  5372. void *d = data->malloc_data;
  5373. int i;
  5374. // we don't f(data->source_profile), because that's internal static data.
  5375. for (i = 0; i < data->error_count; i++)
  5376. {
  5377. f((void *) data->errors[i].error, d);
  5378. f((void *) data->errors[i].filename, d);
  5379. } // for
  5380. f((void *) data->errors, d);
  5381. // don't delete data->ast (it'll delete with the context).
  5382. f(data, d);
  5383. destroy_context(ctx); // finally safe to destroy this.
  5384. } // MOJOSHADER_freeAstData
  5385. const MOJOSHADER_compileData *MOJOSHADER_compile(const char *srcprofile,
  5386. const char *filename, const char *source,
  5387. unsigned int sourcelen,
  5388. const MOJOSHADER_preprocessorDefine *defs,
  5389. unsigned int define_count,
  5390. MOJOSHADER_includeOpen include_open,
  5391. MOJOSHADER_includeClose include_close,
  5392. MOJOSHADER_malloc m, MOJOSHADER_free f,
  5393. void *d)
  5394. {
  5395. // !!! FIXME: cut and paste from MOJOSHADER_parseAst().
  5396. MOJOSHADER_compileData *retval = NULL;
  5397. Context *ctx = NULL;
  5398. if ( ((m == NULL) && (f != NULL)) || ((m != NULL) && (f == NULL)) )
  5399. return &MOJOSHADER_out_of_mem_compile_data; // supply both or neither.
  5400. ctx = build_context(m, f, d);
  5401. if (ctx == NULL)
  5402. return &MOJOSHADER_out_of_mem_compile_data;
  5403. choose_src_profile(ctx, srcprofile);
  5404. if (!isfail(ctx))
  5405. {
  5406. parse_source(ctx, filename, source, sourcelen, defs, define_count,
  5407. include_open, include_close);
  5408. } // if
  5409. if (!isfail(ctx))
  5410. semantic_analysis(ctx);
  5411. if (!isfail(ctx))
  5412. intermediate_representation(ctx);
  5413. if (isfail(ctx))
  5414. retval = (MOJOSHADER_compileData *) build_failed_compile(ctx);
  5415. else
  5416. retval = (MOJOSHADER_compileData *) build_compiledata(ctx);
  5417. destroy_context(ctx);
  5418. return retval;
  5419. } // MOJOSHADER_compile
  5420. void MOJOSHADER_freeCompileData(const MOJOSHADER_compileData *_data)
  5421. {
  5422. MOJOSHADER_compileData *data = (MOJOSHADER_compileData *) _data;
  5423. if ((data == NULL) || (data == &MOJOSHADER_out_of_mem_compile_data))
  5424. return; // no-op.
  5425. MOJOSHADER_free f = (data->free == NULL) ? MOJOSHADER_internal_free : data->free;
  5426. void *d = data->malloc_data;
  5427. int i;
  5428. // we don't f(data->source_profile), because that's internal static data.
  5429. for (i = 0; i < data->error_count; i++)
  5430. {
  5431. f((void *) data->errors[i].error, d);
  5432. f((void *) data->errors[i].filename, d);
  5433. } // for
  5434. f((void *) data->errors, d);
  5435. for (i = 0; i < data->warning_count; i++)
  5436. {
  5437. f((void *) data->warnings[i].error, d);
  5438. f((void *) data->warnings[i].filename, d);
  5439. } // for
  5440. f((void *) data->warnings, d);
  5441. for (i = 0; i < data->symbol_count; i++)
  5442. {
  5443. f((void *) data->symbols[i].name, d);
  5444. // !!! FIXME: this is missing stuff (including freeing substructs).
  5445. } // for
  5446. f((void *) data->symbols, d);
  5447. f((void *) data->output, d);
  5448. f(data, d);
  5449. } // MOJOSHADER_freeCompileData
  5450. // end of mojoshader_compiler.c ...