Checker.hx 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  1. package hxsl;
  2. using hxsl.Ast;
  3. private enum FieldAccess {
  4. FField( e : TExpr );
  5. FGlobal( g : TGlobal, arg : TExpr, variants : Array<FunType> );
  6. }
  7. private enum WithType {
  8. NoValue;
  9. Value;
  10. InBlock;
  11. With( t : Type );
  12. }
  13. /**
  14. Type Checker : will take an untyped Expr and turn it into a typed TExpr, resolving identifiers and ensuring type safety.
  15. **/
  16. class Checker {
  17. static var vec2 = TVec(2, VFloat);
  18. static var vec3 = TVec(3, VFloat);
  19. static var vec4 = TVec(4, VFloat);
  20. static var ivec2 = TVec(2, VInt);
  21. static var ivec3 = TVec(3, VInt);
  22. static var ivec4 = TVec(4, VInt);
  23. var vars : Map<String,TVar>;
  24. var globals : Map<String,{ g : TGlobal, t : Type }>;
  25. var curFun : TFunction;
  26. var inLoop : Bool;
  27. var inWhile : Bool;
  28. public var inits : Array<{ v : TVar, e : TExpr }>;
  29. public function new() {
  30. globals = initGlobals();
  31. }
  32. static var GLOBALS = null;
  33. static function initGlobals() {
  34. var globals = GLOBALS;
  35. if( GLOBALS != null ) return GLOBALS;
  36. var globals = new Map();
  37. var genType = [TFloat, vec2, vec3, vec4];
  38. var genIType = [TInt, ivec2, ivec3, ivec4];
  39. var baseType = [TFloat, TBool, TInt];
  40. var genSqMatType = [TMat2, TMat3, TMat4];
  41. var genFloat = [for( t in genType ) { args : [ { name : "value", type : t } ], ret : t } ];
  42. var genFloat2 = [for( t in genType ) { args : [ { name : "a", type : t }, { name : "b", type : t } ], ret : t } ];
  43. var genWithFloat = [for( t in genType ) { args : [ { name : "a", type : t }, { name : "b", type : TFloat } ], ret : t } ];
  44. var genSqMat = [for( t in genSqMatType ) { args : [ { name : "value", type : t } ], ret : t } ];
  45. var texDefs = [
  46. { dim : T1D, arr : false, uv : TFloat, iuv : TInt },
  47. { dim : T2D, arr : false, uv : vec2, iuv : ivec2 },
  48. { dim : T3D, arr : false, uv : vec3, iuv : ivec3 },
  49. { dim : TCube, arr : false, uv : vec3, iuv : ivec3 },
  50. { dim : T1D, arr : true, uv : vec2, iuv : ivec2 },
  51. { dim : T2D, arr : true, uv : vec3, iuv : ivec3 },
  52. { dim : TCube, arr : true, uv : vec4, iuv : ivec4 },
  53. ];
  54. var gvars = new Map();
  55. for( g in Ast.TGlobal.createAll() ) {
  56. var def = switch( g ) {
  57. case Vec2, Vec3, Vec4, Mat2, Mat3, Mat3x4, Mat4, IVec2, IVec3, IVec4, BVec2, BVec3, BVec4: [];
  58. case Radians, Degrees, Cos, Sin, Tan, Asin, Acos, Exp, Log, Exp2, Log2, Sqrt, Inversesqrt, Abs, Sign, Floor, Ceil, RoundEven, Fract, Saturate: genFloat;
  59. case Atan: genFloat.concat(genFloat2);
  60. case Pow: genFloat2;
  61. case LReflect:
  62. genFloat2;
  63. case Mod, Min, Max:
  64. genFloat2.concat(genWithFloat);
  65. case Length:
  66. [for( t in genType ) { args : [ { name : "value", type : t } ], ret : TFloat } ];
  67. case Distance, Dot:
  68. [for( t in genType ) { args : [ { name : "a", type : t }, { name : "b", type : t } ], ret : TFloat } ];
  69. case Normalize:
  70. genFloat;
  71. case Cross:
  72. [ { args : [ { name : "a", type : vec3 }, { name : "b", type : vec3 } ], ret : vec3 } ];
  73. case Transpose:
  74. genSqMat;
  75. case Texture:
  76. [for( t in texDefs ) { args : [{ name : "tex", type : TSampler(t.dim,t.arr) }, { name : "uv", type : t.uv }], ret : vec4 }];
  77. case TextureLod:
  78. [for( t in texDefs ) { args : [{ name : "tex", type : TSampler(t.dim,t.arr) }, { name : "uv", type : t.uv }, { name : "lod", type : TFloat }], ret : vec4 }];
  79. case Texel:
  80. [for( t in texDefs ) { args : [{ name : "tex", type : TSampler(t.dim,t.arr) }, { name : "pos", type : t.iuv }], ret : vec4 }];
  81. case TextureSize:
  82. [];
  83. case ToInt:
  84. [for( t in baseType ) { args : [ { name : "value", type : t } ], ret : TInt } ];
  85. case ToFloat:
  86. [for( t in baseType ) { args : [ { name : "value", type : t } ], ret : TFloat } ];
  87. case ToBool:
  88. [for( t in baseType ) { args : [ { name : "value", type : t } ], ret : TBool } ];
  89. case Clamp:
  90. var r = [ { args : [ { name : "value", type : TInt }, { name : "min", type : TInt }, { name : "max", type : TInt } ], ret : TInt } ];
  91. for( t in genType ) {
  92. r.push( { args : [ { name : "value", type : t }, { name : "min", type : t }, { name : "max", type : t } ], ret : t } );
  93. if( t != TFloat )
  94. r.push( { args : [ { name : "value", type : t }, { name : "min", type : TFloat }, { name : "max", type : TFloat } ], ret : t } );
  95. }
  96. r;
  97. case Mix:
  98. var r = [];
  99. for( t in genType ) {
  100. r.push( { args : [ { name : "x", type : t }, { name : "y", type : t }, { name : "a", type : t } ], ret : t } );
  101. if( t != TFloat )
  102. r.push( { args : [ { name : "x", type : t }, { name : "y", type : t }, { name : "a", type : TFloat } ], ret : t } );
  103. }
  104. r;
  105. case InvLerp:
  106. [ { args : [{ name : "a", type : TFloat }, { name : "x", type : TFloat }, { name : "y", type : TFloat } ], ret : TFloat } ];
  107. case Step:
  108. var r = [];
  109. for( t in genType ) {
  110. r.push( { args : [ { name : "edge", type : t }, { name : "x", type : t } ], ret : t } );
  111. if( t != TFloat )
  112. r.push( { args : [ { name : "edge", type : TFloat }, { name : "x", type : t } ], ret : t } );
  113. }
  114. r;
  115. case Smoothstep:
  116. var r = [];
  117. for( t in genType ) {
  118. r.push( { args : [ { name : "edge0", type : t }, { name : "edge1", type : t }, { name : "x", type : t } ], ret : t } );
  119. if( t != TFloat )
  120. r.push( { args : [ { name : "edge0", type : TFloat }, { name : "edge1", type : TFloat }, { name : "x", type : t } ], ret : t } );
  121. }
  122. r;
  123. case DFdx, DFdy, Fwidth:
  124. genFloat;
  125. case Pack:
  126. [ { args : [ { name : "value", type : TFloat } ], ret : vec4 } ];
  127. case Unpack:
  128. [ { args : [ { name : "value", type : vec4 } ], ret : TFloat } ];
  129. case UnpackNormal:
  130. [ { args : [ { name : "value", type : vec4 } ], ret : vec3 } ];
  131. case PackNormal:
  132. [ { args : [ { name : "value", type : vec3 } ], ret : vec4 } ];
  133. case ChannelRead:
  134. [
  135. { args : [ { name : "channel", type : TChannel(1) }, { name : "uv", type : vec2 } ], ret : TFloat },
  136. { args : [ { name : "channel", type : TChannel(2) }, { name : "uv", type : vec2 } ], ret : vec2 },
  137. { args : [ { name : "channel", type : TChannel(3) }, { name : "uv", type : vec2 } ], ret : vec3 },
  138. { args : [ { name : "channel", type : TChannel(4) }, { name : "uv", type : vec2 } ], ret : vec4 },
  139. ];
  140. case ChannelReadLod:
  141. [
  142. { args : [ { name : "channel", type : TChannel(1) }, { name : "uv", type : vec2 }, { name : "lod", type : TFloat } ], ret : TFloat },
  143. { args : [ { name : "channel", type : TChannel(2) }, { name : "uv", type : vec2 }, { name : "lod", type : TFloat } ], ret : vec2 },
  144. { args : [ { name : "channel", type : TChannel(3) }, { name : "uv", type : vec2 }, { name : "lod", type : TFloat } ], ret : vec3 },
  145. { args : [ { name : "channel", type : TChannel(4) }, { name : "uv", type : vec2 }, { name : "lod", type : TFloat } ], ret : vec4 },
  146. ];
  147. case ChannelFetch:
  148. [
  149. { args : [ { name : "channel", type : TChannel(1) }, { name : "pos", type : ivec2 } ], ret : TFloat },
  150. { args : [ { name : "channel", type : TChannel(2) }, { name : "pos", type : ivec2 } ], ret : vec2 },
  151. { args : [ { name : "channel", type : TChannel(3) }, { name : "pos", type : ivec2 } ], ret : vec3 },
  152. { args : [ { name : "channel", type : TChannel(4) }, { name : "pos", type : ivec2 } ], ret : vec4 },
  153. { args : [ { name : "channel", type : TChannel(1) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : TFloat },
  154. { args : [ { name : "channel", type : TChannel(2) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec2 },
  155. { args : [ { name : "channel", type : TChannel(3) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec3 },
  156. { args : [ { name : "channel", type : TChannel(4) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec4 },
  157. ];
  158. case ChannelTextureSize:
  159. [
  160. { args : [ { name: "channel", type: TChannel(1) } ], ret: vec2 },
  161. { args : [ { name: "channel", type: TChannel(2) } ], ret: vec2 },
  162. { args : [ { name: "channel", type: TChannel(3) } ], ret: vec2 },
  163. { args : [ { name: "channel", type: TChannel(4) } ], ret: vec2 },
  164. { args : [ { name: "channel", type: TChannel(1) }, { name : "lod", type : TInt } ], ret: vec2 },
  165. { args : [ { name: "channel", type: TChannel(2) }, { name : "lod", type : TInt } ], ret: vec2 },
  166. { args : [ { name: "channel", type: TChannel(3) }, { name : "lod", type : TInt } ], ret: vec2 },
  167. { args : [ { name: "channel", type: TChannel(4) }, { name : "lod", type : TInt } ], ret: vec2 },
  168. ];
  169. case ScreenToUv:
  170. [{ args : [{ name : "screenPos", type : vec2 }], ret : vec2 }];
  171. case UvToScreen:
  172. [{ args : [{ name : "uv", type : vec2 }], ret : vec2 }];
  173. case Trace, GroupMemoryBarrier:
  174. [];
  175. case FloatBitsToInt, FloatBitsToUint:
  176. [for( i => t in genType ) { args : [ { name: "x", type: t } ], ret: genIType[i] }];
  177. case IntBitsToFloat, UintBitsToFloat:
  178. [for( i => t in genType ) { args : [ { name: "x", type: genIType[i] } ], ret: t }];
  179. case SetLayout:
  180. [
  181. { args : [{ name : "x", type : TInt },{ name : "y", type : TInt },{ name : "z", type : TInt }], ret : TVoid },
  182. { args : [{ name : "x", type : TInt },{ name : "y", type : TInt }], ret : TVoid },
  183. { args : [{ name : "x", type : TInt }], ret : TVoid }
  184. ];
  185. case ImageStore:
  186. [];
  187. case VertexID, InstanceID, FragCoord, FrontFacing:
  188. null;
  189. case AtomicAdd:
  190. [{ args : [{ name : "buf", type : TBuffer(TInt, SConst(0), RW) },{ name : "index", type : TInt }, { name : "data", type : TInt }], ret : TInt }];
  191. case _ if( g.getName().indexOf("_") > 0 ):
  192. var name = g.getName();
  193. var idx = name.indexOf("_");
  194. var vname = name.substr(0, idx);
  195. vname = vname.charAt(0).toLowerCase() + vname.substr(1);
  196. var vl = gvars.get(vname);
  197. if( vl == null ) {
  198. vl = [];
  199. gvars.set(vname, vl);
  200. }
  201. var vt = switch( g ) {
  202. case ComputeVar_GlobalInvocation, ComputeVar_LocalInvocation, ComputeVar_WorkGroup:
  203. ivec3;
  204. case ComputeVar_LocalInvocationIndex:
  205. TInt;
  206. default:
  207. throw "Unknown type for global var "+g;
  208. }
  209. var fname = name.substr(idx+1);
  210. fname = fname.charAt(0).toLowerCase() + fname.substr(1);
  211. vl.push({ name : fname, type : vt });
  212. null;
  213. case UnpackSnorm4x8:
  214. [ { args : [ { name : "value", type : TInt } ], ret : vec4 } ];
  215. case UnpackUnorm4x8:
  216. [ { args : [ { name : "value", type : TInt } ], ret : vec4 } ];
  217. default:
  218. throw "Unsupported global "+g;
  219. }
  220. if( def != null )
  221. globals.set(g.toString(), { t : TFun(def), g : g } );
  222. }
  223. globals.set("vertexID", { t : TInt, g : VertexID });
  224. globals.set("instanceID", { t : TInt, g : InstanceID });
  225. globals.set("fragCoord", { t : vec4, g : FragCoord });
  226. globals.set("frontFacing", { t : TBool, g : FrontFacing });
  227. for( gname => vl in gvars )
  228. globals.set(gname, { t : TStruct([
  229. for( v in vl )
  230. {
  231. name: v.name,
  232. kind : Global,
  233. type : v.type,
  234. id : 0
  235. }
  236. ]), g : null });
  237. globals.set("int", globals.get("toInt"));
  238. globals.set("float", globals.get("toFloat"));
  239. globals.set("reflect", globals.get("lReflect"));
  240. for( i in 2...5 ) {
  241. globals.set("ivec"+i, globals.get("iVec"+i));
  242. globals.remove("iVec"+i);
  243. }
  244. globals.remove("lReflect");
  245. globals.remove("toInt");
  246. globals.remove("toFloat");
  247. GLOBALS = globals;
  248. return globals;
  249. }
  250. function error( msg : String, pos : Position ) : Dynamic {
  251. return Ast.Error.t(msg,pos);
  252. }
  253. public dynamic function warning( msg : String, pos : Position ) {
  254. }
  255. public dynamic function loadShader( path : String ) : Expr {
  256. throw "Not implemented";
  257. return null;
  258. }
  259. public function check( name : String, shader : Expr ) : ShaderData {
  260. vars = new Map();
  261. inits = [];
  262. inLoop = false;
  263. inWhile = false;
  264. var funs = [];
  265. checkExpr(shader, funs, false, false);
  266. var tfuns = [];
  267. for( f in funs ) {
  268. var pos = f.p, f = f.f;
  269. var args : Array<TVar> = [for( a in f.args ) {
  270. if( a.type == null ) error("Argument type required", pos);
  271. if( a.expr != null ) error("Optional argument not supported", pos);
  272. if( a.kind == null ) a.kind = Local;
  273. if( a.kind != Local ) error("Argument should be local", pos);
  274. if( a.qualifiers.length != 0 ) error("No qualifier allowed for argument", pos);
  275. { id : Tools.allocVarId(), name : a.name, kind : Local, type : a.type };
  276. }];
  277. var kind = switch( f.name ) {
  278. case "vertex": Vertex;
  279. case "fragment": Fragment;
  280. case "main": Main;
  281. default: StringTools.startsWith(f.name,"__init__") ? Init : Helper;
  282. }
  283. if( args.length != 0 && kind != Helper )
  284. error(kind+" function should have no argument", pos);
  285. var fv : TVar = {
  286. id : Tools.allocVarId(),
  287. name : f.name,
  288. kind : Function,
  289. type : TFun([{ args : [for( a in args ) { type : a.type, name : a.name }], ret : f.ret == null ? TVoid : f.ret }]),
  290. };
  291. var f : TFunction = {
  292. kind : kind,
  293. ref : fv,
  294. args : args,
  295. ret : f.ret == null ? TVoid : f.ret,
  296. expr : null,
  297. };
  298. if( vars.exists(fv.name) )
  299. error("Duplicate function name", pos);
  300. vars.set(fv.name,fv);
  301. tfuns.push(f);
  302. }
  303. for( i in 0...tfuns.length )
  304. typeFun(tfuns[i], funs[i].f.expr);
  305. var localInits = [];
  306. for( i in inits.copy() ) {
  307. if( i.v.kind == Local ) {
  308. localInits.push({ e : TBinop(OpAssign,{ e : TVar(i.v), p : i.e.p, t : i.v.type },i.e), p : i.e.p, t : i.v.type });
  309. inits.remove(i);
  310. }
  311. }
  312. if( localInits.length > 0 ) {
  313. var fv : TVar = {
  314. id : Tools.allocVarId(),
  315. name : "__init__consts__",
  316. kind : Function,
  317. type : TFun([{ args : [], ret : TVoid }]),
  318. };
  319. if( vars.exists(fv.name) )
  320. error("assert", localInits[0].p);
  321. vars.set(fv.name, fv);
  322. tfuns.push({
  323. kind : Init,
  324. ref : fv,
  325. args : [],
  326. ret : TVoid,
  327. expr : { e : TBlock(localInits), p : localInits[0].p, t : TVoid },
  328. });
  329. }
  330. var vars = Lambda.array(vars);
  331. vars.sort(function(v1, v2) return (v1.id < 0 ? -v1.id : v1.id) - (v2.id < 0 ? -v2.id : v2.id));
  332. return {
  333. name : name,
  334. vars : vars,
  335. funs : tfuns,
  336. };
  337. }
  338. function saveVars() {
  339. var old = new Map();
  340. for( v in vars.keys() )
  341. old.set(v, vars.get(v));
  342. return old;
  343. }
  344. function typeFun( f : TFunction, e : Expr ) {
  345. var old = saveVars();
  346. for( a in f.args )
  347. vars.set(a.name, a);
  348. curFun = f;
  349. f.expr = typeExpr(e,NoValue);
  350. vars = old;
  351. }
  352. function tryUnify( t1 : Type, t2 : Type ) {
  353. if( t1.equals(t2) )
  354. return true;
  355. switch( [t1, t2] ) {
  356. case [TVec(s1, t1), TVec(s2, t2)] if( s1 == s2 && t1 == t2 ):
  357. return true;
  358. case [TArray(t1, size1), TArray(t2, size2)]:
  359. switch( [size1,size2] ) {
  360. case [SConst(a),SConst(b)] if( a == b ):
  361. case [SVar(v1),SVar(v2)] if( v1 == v2 ):
  362. default: return false;
  363. }
  364. return tryUnify(t1,t2);
  365. case [TChannel(n1), TChannel(n2)] if( n1 == n2 ):
  366. return true;
  367. case [TSampler(dim1, arr1), TSampler(dim2, arr2)]:
  368. return dim1 == dim2 && arr1 == arr2;
  369. case [TRWTexture(dim1, arr1, chans1), TRWTexture(dim2, arr2, chans2)]:
  370. return dim1 == dim2 && arr1 == arr2 && chans1 == chans2;
  371. default:
  372. }
  373. return false;
  374. }
  375. function unify( t1 : Type, t2 : Type, p : Position ) {
  376. if( !tryUnify(t1,t2) )
  377. error(t1.toString() + " should be " + t2.toString(), p);
  378. }
  379. function unifyExpr( e : TExpr, t : Type ) {
  380. if( !tryUnify(e.t, t) ) {
  381. if( e.t == TInt && t == TFloat ) {
  382. toFloat(e);
  383. return;
  384. }
  385. error(e.t.toString() + " should be " + t.toString(), e.p);
  386. }
  387. }
  388. function checkWrite( e : TExpr ) {
  389. switch( e.e ) {
  390. case TVar(v):
  391. switch( v.kind ) {
  392. case Var, Output:
  393. return;
  394. case Local if( v.qualifiers == null || v.qualifiers.indexOf(Final) < 0 ):
  395. return;
  396. case Param, Local if( v.type.match(TBuffer(_,_,RW|RWPartial) | TRWTexture(_)) ):
  397. return;
  398. default:
  399. }
  400. case TSwiz(e, _), TField(e, _):
  401. checkWrite(e);
  402. return;
  403. case TArray(e, _):
  404. checkWrite(e);
  405. return;
  406. default:
  407. }
  408. error("This expression cannot be assigned", e.p);
  409. }
  410. function typeWith( e : Expr, ?t : Type ) {
  411. if( t == null )
  412. return typeExpr(e, Value);
  413. var e = typeExpr(e, With(t));
  414. unifyExpr(e, t);
  415. return e;
  416. }
  417. function typeExpr( e : Expr, with : WithType ) : TExpr {
  418. var type = null;
  419. var ed = switch( e.expr ) {
  420. case EConst(c):
  421. type = switch( c ) {
  422. case CInt(i):
  423. switch( with ) {
  424. case With(TFloat):
  425. c = CFloat(i);
  426. TFloat;
  427. default:
  428. TInt;
  429. }
  430. case CString(_): TString;
  431. case CNull: TVoid;
  432. case CBool(_): TBool;
  433. case CFloat(_): TFloat;
  434. };
  435. TConst(c);
  436. case EMeta(name, args, e):
  437. var e = typeExpr(e, with);
  438. type = e.t;
  439. TMeta(name, [for( c in args ) switch( c.expr ) {
  440. case EConst(c): c;
  441. case EIdent(i): CString(i); // convert ident to string
  442. default: error("Metadata parameter should be constant", c.pos);
  443. }], e);
  444. case EBlock(el):
  445. var old = saveVars();
  446. var el = el.copy(), tl = [];
  447. with = propagate(with);
  448. if( el.length == 0 && with != NoValue ) error("Value expected", e.pos);
  449. while( true ) {
  450. var e = el.shift();
  451. if( e == null ) break;
  452. // split vars decls
  453. switch( e.expr ) {
  454. case EVars(vl) if( vl.length > 1 ):
  455. var v0 = vl.shift();
  456. el.unshift(e);
  457. e = { expr : EVars([v0]), pos : e.pos };
  458. default:
  459. }
  460. var ew = switch( e.expr ) {
  461. case EVars(_): InBlock;
  462. default: if( el.length == 0 ) with else NoValue;
  463. }
  464. var et = typeExpr(e, ew);
  465. if( el.length != 0 && !et.hasSideEffect() ) warning("This expression has no side effect", e.pos);
  466. tl.push(et);
  467. }
  468. vars = old;
  469. type = with == NoValue ? TVoid : tl[tl.length - 1].t;
  470. TBlock(tl);
  471. case EBinop(op, e1, e2):
  472. var e1 = typeExpr(e1, Value);
  473. var e2 = typeExpr(e2, With(e1.t));
  474. switch( op ) {
  475. case OpAssign:
  476. checkWrite(e1);
  477. unify(e2.t, e1.t, e2.p);
  478. type = e1.t;
  479. case OpAssignOp(op):
  480. checkWrite(e1);
  481. unify(typeBinop(op, e1, e2, e.pos), e1.t, e2.p);
  482. type = e1.t;
  483. default:
  484. type = typeBinop(op, e1, e2, e.pos);
  485. }
  486. TBinop(op, e1, e2);
  487. case EIdent(name):
  488. var v = vars.get(name);
  489. if( v != null ) {
  490. var canCall = switch( name ) {
  491. case "vertex", "fragment", "main": false;
  492. default: !StringTools.startsWith(name,"__init__");
  493. }
  494. if( !canCall )
  495. error("Function cannot be accessed", e.pos);
  496. type = v.type;
  497. TVar(v);
  498. } else {
  499. var g = globals.get(name);
  500. if( g != null && g.g != null ) {
  501. type = g.t;
  502. TGlobal(g.g);
  503. } else {
  504. switch( name ) {
  505. case "PI":
  506. type = TFloat;
  507. TConst(CFloat(Math.PI));
  508. default:
  509. error("Unknown identifier '" + name + "'", e.pos);
  510. }
  511. }
  512. }
  513. case EField({ expr : EIdent(name) }, f) if( vars.get(name) == null && globals.get(name) != null && globals.get(name).g == null ):
  514. switch( globals.get(name).t ) {
  515. case TStruct(vl):
  516. for( v in vl )
  517. if( v.name == f ) {
  518. var g = name.charAt(0).toUpperCase()+name.substr(1)+"_"+f.charAt(0).toUpperCase()+f.substr(1);
  519. return { e : TGlobal(Ast.TGlobal.createByName(g)), t : v.type, p : e.pos };
  520. }
  521. error(name+" field should be "+[for( v in vl ) v.name].join("|"), e.pos);
  522. default:
  523. throw "assert";
  524. }
  525. case EField(e1, f):
  526. var e1 = typeExpr(e1, Value);
  527. var ef = fieldAccess(e1, f, with, e.pos);
  528. if( ef == null ) error(e1.t.toString() + " has no field '" + f + "'", e.pos);
  529. switch( ef ) {
  530. case FField(ef):
  531. type = ef.t;
  532. ef.e;
  533. case FGlobal(_):
  534. // not closure support
  535. error("Global function must be called immediately", e.pos);
  536. }
  537. case ECall({ expr: EField({ expr: EIdent("Syntax") }, target) }, args):
  538. if ( args.length == 0 )
  539. error("Syntax." + target + " should have a string as first argument", e.pos);
  540. var code = switch ( args[0].expr ) {
  541. case EConst(CString(code)): code;
  542. default: error("Syntax." + target + " should have a string as first argument", args[0].pos);
  543. }
  544. var sargs: Array<Ast.SyntaxArg> = [];
  545. for ( i in 1...args.length ) {
  546. var arg = args[i];
  547. switch ( arg.expr ) {
  548. case EMeta(flags = ("rw"|"r"|"w"), _, flaggedArg):
  549. sargs.push({ e : typeExpr(flaggedArg, Value), access : switch( flags ) {
  550. case "r": Read;
  551. case "w": Write;
  552. case "rw": ReadWrite;
  553. default: throw "assert";
  554. }
  555. });
  556. default:
  557. error("Syntax." + target + " arguments should have an access meta of @r, @w or @rw", arg.pos);
  558. }
  559. }
  560. return { e: TSyntax(target, code, sargs), t: TVoid, p: e.pos };
  561. case ECall(e1, args):
  562. function makeCall(e1) {
  563. return switch( e1.t ) {
  564. case TFun(variants):
  565. var e = unifyCallParams(e1, args, variants, e.pos);
  566. type = e.t;
  567. e.e;
  568. default:
  569. error(e1.t.toString() + " cannot be called", e.pos);
  570. }
  571. }
  572. switch( e1.expr ) {
  573. case EField(e1, f):
  574. var e1 = typeExpr(e1, Value);
  575. var ef = fieldAccess(e1, f, with, e.pos);
  576. if( ef == null ) error(e1.t.toString() + " has no field '" + f + "'", e.pos);
  577. switch( ef ) {
  578. case FField(ef):
  579. makeCall(ef);
  580. case FGlobal(g, arg, variants):
  581. var eg = { e : TGlobal(g), t : TFun(variants), p : e1.p };
  582. if( variants.length == 0 ) {
  583. var args = [for( a in args ) typeExpr(a, Value)];
  584. args.unshift(arg);
  585. var e = specialGlobal(g, eg, args, e.pos);
  586. type = e.t;
  587. e.e;
  588. } else {
  589. var e = unifyCallParams(eg, args, variants, e.pos);
  590. switch( [e.e, eg.t] ) {
  591. case [TCall(_, args), TFun([f])]:
  592. args.unshift(arg);
  593. f.args.unshift({ name : "_", type : arg.t });
  594. default:
  595. throw "assert";
  596. }
  597. type = e.t;
  598. e.e;
  599. }
  600. }
  601. default:
  602. makeCall(typeExpr(e1, Value));
  603. }
  604. case EParenthesis(e):
  605. var e = typeExpr(e, with);
  606. type = e.t;
  607. TParenthesis(e);
  608. case EFunction(_):
  609. throw "assert";
  610. case EVars(vl):
  611. if( with != InBlock )
  612. error("Cannot declare a variable outside of a block", e.pos);
  613. if( vl.length != 1 ) throw "assert";
  614. var v = vl[0];
  615. if( v.kind == null ) v.kind = Local;
  616. if( v.kind != Local ) error("Should be local var", e.pos);
  617. if( v.qualifiers.length != 0 ) error("Unexpected qualifier", e.pos);
  618. var tv = makeVar(vl[0],e.pos);
  619. var init = v.expr == null ? null : typeWith(v.expr, tv.type);
  620. if( tv.type == null ) {
  621. if( init == null ) error("Type required for unitialized local var", e.pos);
  622. tv.type = init.t;
  623. }
  624. vars.set(tv.name, tv);
  625. type = TVoid;
  626. TVarDecl(tv, init);
  627. case EUnop(op,e1):
  628. var e1 = typeExpr(e1, Value);
  629. switch( op ) {
  630. case OpNot:
  631. unifyExpr(e1, TBool);
  632. type = TBool;
  633. TUnop(op, e1);
  634. case OpNeg:
  635. switch( e1.t ) {
  636. case TFloat, TInt, TVec(_,VFloat|VInt):
  637. default: error("Cannot negate " + e1.t.toString(), e.pos);
  638. }
  639. type = e1.t;
  640. TUnop(op, e1);
  641. case OpIncrement, OpDecrement:
  642. switch( e1.t ) {
  643. case TFloat, TInt:
  644. default: error("Cannot increment " + e1.t.toString(), e.pos);
  645. }
  646. type = TVoid;
  647. TBinop(OpAssignOp(op == OpIncrement ? OpAdd : OpSub), e1, { e : TConst(CInt(1)), t : TInt, p : e1.p });
  648. default:
  649. error("Operation non supported", e.pos);
  650. }
  651. case EIf(cond, e1, e2):
  652. with = propagate(with);
  653. var cond = typeWith(cond, TBool);
  654. var e1 = typeExpr(e1, with);
  655. var e2 = e2 == null ? null : typeExpr(e2, with);
  656. if( with == NoValue ) {
  657. type = TVoid;
  658. TIf(cond, e1, e2);
  659. } else {
  660. if( e2 == null ) error("Missing else", e.pos);
  661. if( tryUnify(e1.t, e2.t) )
  662. type = e1.t;
  663. else {
  664. unifyExpr(e2, e1.t);
  665. type = e2.t;
  666. }
  667. TIf(cond, e1, e2);
  668. }
  669. case EDiscard:
  670. type = TVoid;
  671. TDiscard;
  672. case EReturn(e1):
  673. if( (e1 == null) != (curFun.ret == TVoid) )
  674. error("This function should return " + curFun.ret.toString(), e.pos);
  675. var e = e1 == null ? null : typeWith(e1, curFun.ret);
  676. type = TVoid;
  677. TReturn(e);
  678. case EFor(v, it, block):
  679. type = TVoid;
  680. var it = typeExpr(it, Value);
  681. switch( it.t ) {
  682. case TArray(t, _):
  683. var v : TVar = {
  684. id : Tools.allocVarId(),
  685. name : v,
  686. type : t,
  687. kind : Local,
  688. };
  689. var old = vars.get(v.name);
  690. vars.set(v.name, v);
  691. var oldL = inLoop;
  692. inLoop = true;
  693. var block = typeExpr(block, NoValue);
  694. inLoop = oldL;
  695. if( old == null ) vars.remove(v.name) else vars.set(v.name, old);
  696. TFor(v, it, block);
  697. default:
  698. error("Cannot iterate on " + it.t.toString(), it.p);
  699. }
  700. case EWhile(cond, loop, normalWhile):
  701. type = TVoid;
  702. var cond = typeWith(cond, TBool);
  703. var oldL = inLoop, oldW = inWhile;
  704. inLoop = true;
  705. inWhile = true;
  706. var loop = typeExpr(loop, NoValue);
  707. inLoop = oldL;
  708. inWhile = oldW;
  709. TWhile(cond, loop, normalWhile);
  710. case EContinue:
  711. if( !inLoop ) error("Continue outside loop", e.pos);
  712. type = TVoid;
  713. TContinue;
  714. case EBreak:
  715. if( !inLoop ) error("Break outside loop", e.pos);
  716. type = TVoid;
  717. TBreak;
  718. case EArray(e1, e2):
  719. var e1 = typeExpr(e1, Value);
  720. var e2 = typeExpr(e2, With(TInt));
  721. unify(e2.t, TInt, e2.p);
  722. switch( e1.t ) {
  723. case TArray(t, size), TBuffer(t,size, Uniform), TBuffer(t,size, Partial):
  724. switch( [size, e2.e] ) {
  725. case [SConst(v), TConst(CInt(i))] if( i >= v ):
  726. error("Indexing outside array bounds", e.pos);
  727. case [_, TConst(CInt(i))] if( i < 0 ):
  728. error("Cannot index with negative value", e.pos);
  729. default:
  730. }
  731. type = t;
  732. case TBuffer(t, size, _):
  733. type = t;
  734. case TMat2:
  735. type = vec2;
  736. case TMat3:
  737. type = vec3;
  738. case TMat4, TMat3x4:
  739. type = vec4;
  740. case TVec(_, VFloat):
  741. type = TFloat;
  742. case TVec(_, VInt):
  743. type = TInt;
  744. default:
  745. error("Cannot index " + e1.t.toString() + " : should be an array", e.pos);
  746. }
  747. TExprDef.TArray(e1, e2);
  748. case EArrayDecl(el):
  749. if( el.length == 0 ) error("Empty array not supported", e.pos);
  750. var el = [for( e in el ) typeExpr(e, Value)];
  751. var t = el[0].t;
  752. for( i in 1...el.length )
  753. unifyExpr(el[i], t);
  754. type = TArray(t, SConst(el.length));
  755. TArrayDecl(el);
  756. case ESwitch(e, cases, def):
  757. var et = typeExpr(e, Value);
  758. var cases = [for( c in cases ) { values : [for( v in c.values ) typeWith(v, et.t)], expr : typeExpr(c.expr, with) }];
  759. var def = def == null ? null : typeExpr(def, with);
  760. type = TVoid;
  761. TSwitch(et, cases, def);
  762. }
  763. if( type == null ) throw "assert";
  764. return { e : ed, t : type, p : e.pos };
  765. }
  766. function propagate( with : WithType ) {
  767. return switch( with ) {
  768. case InBlock: NoValue;
  769. default: with;
  770. }
  771. }
  772. function checkExpr( e : Expr, funs : Array<{ f : FunDecl, p : Position, inherit : Bool }>, isImport, isExtends ) {
  773. switch( e.expr ) {
  774. case EBlock(el):
  775. for( e in el )
  776. checkExpr(e,funs, isImport, isExtends);
  777. case EFunction(f):
  778. if( isImport && (f.name == "fragment" || f.name == "vertex" || StringTools.startsWith(f.name,"__init__")) )
  779. return;
  780. for( f2 in funs.copy() ){
  781. if( f2.f.name == f.name && f2.inherit )
  782. funs.remove(f2);
  783. }
  784. funs.push({ f : f, p : e.pos, inherit : isExtends || isImport });
  785. case EVars(vl):
  786. for( v in vl ) {
  787. if( v.kind == null ) {
  788. v.kind = Local;
  789. for( q in v.qualifiers )
  790. switch( q ) {
  791. case Const(_): v.kind = Param;
  792. default:
  793. }
  794. }
  795. var einit = null;
  796. if( v.expr != null ) {
  797. if( v.kind != Param && v.kind != Local )
  798. error("Cannot initialize variable declaration if not @param or local", v.expr.pos);
  799. var e = typeExpr(v.expr, v.type == null ? Value : With(v.type));
  800. if( v.type == null )
  801. v.type = e.t;
  802. else
  803. unify(e.t, v.type, v.expr.pos);
  804. checkConst(e);
  805. einit = e;
  806. }
  807. if( v.type == null ) error("Type required for variable declaration", e.pos);
  808. if( isImport && v.kind == Param )
  809. continue;
  810. if( vars.exists(v.name) ) error("Duplicate var decl '" + v.name + "'", e.pos);
  811. var v = makeVar(v, e.pos);
  812. switch( v.type ) {
  813. case TSampler(T3D, true), TRWTexture(T3D, true, _), TRWTexture(_,_,3):
  814. error("Unsupported texture type", e.pos);
  815. default:
  816. }
  817. if( einit != null )
  818. inits.push({ v : v, e : einit });
  819. else if( v.qualifiers != null && v.qualifiers.indexOf(Final) >= 0 )
  820. error("Final variable needs initializer", e.pos);
  821. vars.set(v.name, v);
  822. }
  823. case ECall( { expr : EIdent("import") }, [e]):
  824. var path = [];
  825. function loop( e : Expr ) {
  826. switch( e.expr ) {
  827. case EIdent(n): path.push(n);
  828. case EField(e, f): loop(e); path.push(f);
  829. default:
  830. error("Should be a shader type path", e.pos);
  831. }
  832. }
  833. loop(e);
  834. var sexpr = null;
  835. try sexpr = loadShader(path.join(".")) catch( err : haxe.macro.Expr.Error ) throw err catch( err : Dynamic ) error(Std.string(err), e.pos);
  836. if( sexpr != null )
  837. checkExpr(sexpr, funs, true, isExtends);
  838. case ECall( { expr : EIdent("extends") }, [e]):
  839. var path = [];
  840. function loop( e : Expr ) {
  841. switch( e.expr ) {
  842. case EIdent(n): path.push(n);
  843. case EField(e, f): loop(e); path.push(f);
  844. case EConst(CString(s)): path.push(s);
  845. default:
  846. error("Should be a shader type path", e.pos);
  847. }
  848. }
  849. loop(e);
  850. var sexpr = null;
  851. try sexpr = loadShader(path.join(".")) catch( err : Error ) error(Std.string(err), e.pos);
  852. if( sexpr != null )
  853. checkExpr(sexpr, funs, isImport, true);
  854. default:
  855. error("This expression is not allowed at shader declaration level", e.pos);
  856. }
  857. }
  858. function checkConst( e : TExpr ) {
  859. switch( e.e ) {
  860. case TConst(_):
  861. case TParenthesis(e): checkConst(e);
  862. case TCall({ e : TGlobal(Vec2 | Vec3 | Vec4 | IVec2 | IVec3 | IVec4) }, args):
  863. for( a in args ) checkConst(a);
  864. case TArrayDecl(el):
  865. for( e in el ) checkConst(e);
  866. default:
  867. error("This expression should be constant", e.p);
  868. }
  869. }
  870. function makeVar( v : VarDecl, pos : Position, ?parent : TVar ) {
  871. var tv : TVar = {
  872. id : Tools.allocVarId(),
  873. name : v.name,
  874. kind : v.kind,
  875. type : v.type,
  876. qualifiers : v.qualifiers
  877. };
  878. if( parent != null )
  879. tv.parent = parent;
  880. if( tv.kind == null ) {
  881. if( parent == null )
  882. tv.kind = Local;
  883. else
  884. tv.kind = parent.kind;
  885. } else if( parent != null && tv.kind != parent.kind ) {
  886. switch( [parent.kind, tv.kind] ) {
  887. case [Global, Var]:
  888. // allow declaring Vars inside globals (pseudo globals built by shader)
  889. default:
  890. error("Variable " + parent.kind + " cannot be changed to " + tv.kind, pos);
  891. }
  892. }
  893. if( v.qualifiers.length > 0 ) {
  894. tv.qualifiers = v.qualifiers;
  895. for( q in v.qualifiers )
  896. switch( q ) {
  897. case Private:
  898. case Const(_):
  899. var p = parent;
  900. while( p != null ) {
  901. if( !p.isStruct() ) error("@const only allowed in structure", pos);
  902. p = p.parent;
  903. }
  904. if( tv.kind != Global && tv.kind != Param ) error("@const only allowed on parameter or global", pos);
  905. case Final: if( tv.kind != Local ) error("final only allowed on local", pos);
  906. case PerObject: if( tv.kind != Global ) error("@perObject only allowed on global", pos);
  907. case PerInstance(_): if( tv.kind != Input && tv.kind != Param && (tv.kind != Global || v.qualifiers.indexOf(PerObject) < 0) ) error("@perInstance only allowed on input/param", pos);
  908. case Nullable: if( tv.kind != Param ) error("@nullable only allowed on parameter or global", pos);
  909. case Name(_):
  910. if( parent != null ) error("Cannot have an explicit name for a structure variable", pos);
  911. if( tv.kind != Global ) error("Explicit name is only allowed for global var", pos);
  912. case Shared:
  913. if( parent != null ) error("Cannot share a structure field", pos);
  914. if( tv.kind != Param ) error("Can only share a @param", pos);
  915. case Precision(_):
  916. switch( v.type ) {
  917. case TVec(_, VFloat), TFloat:
  918. default:
  919. error("Precision qualifier not supported on " + v.type, pos);
  920. }
  921. case Range(min,max):
  922. switch( v.type ) {
  923. case TFloat, TInt, TVec(_, VFloat):
  924. default:
  925. error("Precision qualifier not supported on " + v.type, pos);
  926. }
  927. case Borrow(source):
  928. if ( v.kind != Local ) error("Borrow should not have a type qualifier", pos);
  929. case Sampler(_):
  930. switch( v.type ) {
  931. case TSampler(_), TArray(TSampler(_), _):
  932. default: error("Sampler should be on sampler type or sampler array", pos);
  933. }
  934. case Ignore, Doc(_):
  935. case Flat: if( tv.kind != Local ) error("flat only allowed on local", pos);
  936. }
  937. }
  938. if( tv.type != null )
  939. tv.type = makeVarType(tv.type, tv, pos);
  940. return tv;
  941. }
  942. function makeVarType( vt : Type, parent : TVar, pos : Position ) {
  943. switch( vt ) {
  944. case TStruct(vl):
  945. // mutate to allow TArray to access previously declared vars
  946. var vl = vl.copy();
  947. parent.type = TStruct(vl);
  948. for( i in 0...vl.length ) {
  949. var v = vl[i];
  950. vl[i] = makeVar( { type : v.type, qualifiers : v.qualifiers, name : v.name, kind : v.kind, expr : null }, pos, parent);
  951. }
  952. return parent.type;
  953. case TArray(t, size), TBuffer(t,size,_):
  954. switch( t ) {
  955. case TArray(_):
  956. error("Multidimentional arrays are not allowed", pos);
  957. default:
  958. }
  959. var s = switch( size ) {
  960. case SConst(_): size;
  961. case SVar(v):
  962. var path = v.name.split(".");
  963. var v2 = null;
  964. for( n in path ) {
  965. if( v2 == null ) {
  966. v2 = vars.get(n);
  967. // special handling when we reference our own variable which is being currently declared
  968. if( v2 == null && parent != null ) {
  969. var p = parent;
  970. while( p.parent != null )
  971. p = p.parent;
  972. if( p.name == n )
  973. v2 = p;
  974. }
  975. } else {
  976. v2 = switch( v2.type ) {
  977. case TStruct(vl):
  978. var f = null;
  979. for( v in vl )
  980. if( v.name == n ) {
  981. f = v;
  982. break;
  983. }
  984. f;
  985. default:
  986. null;
  987. }
  988. }
  989. if( v2 == null ) break;
  990. }
  991. if( v2 == null ) error("Array size variable '" + v.name + "'not found", pos);
  992. if( !v2.isConst() ) error("Array size variable '" + v.name + "'should be a constant", pos);
  993. SVar(v2);
  994. }
  995. t = makeVarType(t,parent,pos);
  996. return switch( vt ) {
  997. case TArray(_): TArray(t, s);
  998. case TBuffer(_,_,kind): TBuffer(t,s,kind);
  999. default: throw "assert";
  1000. }
  1001. default:
  1002. return vt;
  1003. }
  1004. }
  1005. function isParentArray( v : TVar ) {
  1006. if( v.parent == null )
  1007. return false;
  1008. switch( v.parent.type ) {
  1009. case TStruct(_):
  1010. return isParentArray(v.parent);
  1011. case TBuffer(_), TArray(_):
  1012. return true;
  1013. default:
  1014. return false;
  1015. }
  1016. }
  1017. function fieldAccess( e : TExpr, f : String, with : WithType, pos : Position ) : FieldAccess {
  1018. var ef = switch( e.t ) {
  1019. case TStruct(vl):
  1020. var found = null;
  1021. for( v in vl )
  1022. if( v.name == f ) {
  1023. found = v;
  1024. break;
  1025. }
  1026. if( found == null )
  1027. null;
  1028. else if( isParentArray(found) )
  1029. { e : TField(e,f), t : found.type, p : pos };
  1030. else
  1031. { e : TVar(found), t : found.type, p : pos };
  1032. default:
  1033. null;
  1034. }
  1035. if( ef != null )
  1036. return FField(ef);
  1037. var g = globals.get(f);
  1038. if( g == null ) {
  1039. var gl : TGlobal = switch( [f, e.t] ) {
  1040. case ["get", TSampler(_)]: Texture;
  1041. case ["get", TChannel(_)]: ChannelRead;
  1042. case ["getLod", TSampler(_)]: TextureLod;
  1043. case ["getLod", TChannel(_)]: ChannelReadLod;
  1044. case ["fetch"|"fetchLod", TSampler(_)]: Texel;
  1045. case ["fetch"|"fetchLod", TChannel(_)]: ChannelFetch;
  1046. case ["size", TSampler(_) | TRWTexture(_)]: TextureSize;
  1047. case ["size", TChannel(_)]: ChannelTextureSize;
  1048. case ["store", TRWTexture(_)]: ImageStore;
  1049. default: null;
  1050. }
  1051. if( gl != null ) {
  1052. if( f == "get" && inWhile ) error("Cannot use .get() in while loop, use .getLod instead", pos);
  1053. g = globals.get(gl.toString());
  1054. }
  1055. }
  1056. if( g != null ) {
  1057. switch( g.t ) {
  1058. case TFun(variants):
  1059. var sel = [];
  1060. for( v in variants ) {
  1061. if( v.args.length == 0 || !tryUnify(e.t, v.args[0].type) ) continue;
  1062. var args = v.args.copy();
  1063. args.shift();
  1064. sel.push({ args : args, ret : v.ret });
  1065. }
  1066. if( sel.length > 0 || variants.length == 0 )
  1067. return FGlobal(g.g, e, sel);
  1068. default:
  1069. }
  1070. switch( [g.g, e.t] ) {
  1071. case [Length, TArray(_)]:
  1072. return FField({ e : TCall({ e : TGlobal(Length), t : TVoid, p : pos },[e]), t : TInt, p : pos });
  1073. default:
  1074. }
  1075. }
  1076. // swizzle ?
  1077. var stype;
  1078. var ncomps = switch( e.t ) {
  1079. case TFloat: stype = VFloat; 1;
  1080. case TInt: stype = VInt; 1;
  1081. case TBool: stype = VBool; 1;
  1082. case TVec(size, t): stype = t; size;
  1083. case TBytes(size): stype = VFloat; size;
  1084. default: stype = null; 0;
  1085. }
  1086. if( ncomps > 0 && f.length <= 4 ) {
  1087. var str = "xrsygtzbpwaq";
  1088. var comps = [X, Y, Z, W];
  1089. var cat = -1;
  1090. var out = [];
  1091. for( i in 0...f.length ) {
  1092. var idx = str.indexOf(f.charAt(i));
  1093. if( idx < 0 ) return null;
  1094. var icat = idx % 3;
  1095. if( cat < 0 ) cat = icat else if( icat != cat ) return null; // down't allow .ryz
  1096. var cid = Std.int(idx / 3);
  1097. if( cid >= ncomps )
  1098. error(e.t.toString() + " does not have component " + f.charAt(i), pos);
  1099. out.push(comps[cid]);
  1100. }
  1101. return FField( { e : TSwiz(e, out), t: out.length == 1 ? stype.toType() : TVec(out.length,stype), p:pos } );
  1102. }
  1103. return null;
  1104. }
  1105. function getSizeType(size,vtype) {
  1106. return switch( size ) {
  1107. case 1: vtype == VInt ? TInt : TFloat;
  1108. case 2: vtype == VInt ? ivec2 : vec2;
  1109. case 3: vtype == VInt ? ivec3 : vec3;
  1110. case 4: vtype == VInt ? ivec4 : vec4;
  1111. default: throw "assert";
  1112. }
  1113. }
  1114. function specialGlobal( g : TGlobal, e : TExpr, args : Array<TExpr>, pos : Position ) : TExpr {
  1115. var type = null;
  1116. inline function checkLength(n,t) {
  1117. var skip = false;
  1118. if( args.length == 1 && (t == TInt || t == TFloat) ) {
  1119. switch( args[0].t ) {
  1120. case TVec(n2,t2) if( (t2 == VInt || t2 == VFloat) && n2 == n ): skip = true;
  1121. default: false;
  1122. }
  1123. }
  1124. if( skip ) return;
  1125. var tsize = 0;
  1126. for( a in args )
  1127. switch( a.t ) {
  1128. case TVec(size, k):
  1129. if( k.toType() != t )
  1130. unify(a.t, t, a.p);
  1131. tsize += size;
  1132. default:
  1133. unifyExpr(a, t);
  1134. tsize++; // if we manage to unify
  1135. }
  1136. if( tsize != n && tsize > 1 )
  1137. error(g.toString() + " requires " + n + " "+t.toString()+" values but has " + tsize, pos);
  1138. }
  1139. switch( g ) {
  1140. case Vec2:
  1141. checkLength(2,TFloat);
  1142. type = TVec(2,VFloat);
  1143. case Vec3:
  1144. checkLength(3,TFloat);
  1145. type = TVec(3,VFloat);
  1146. case Vec4:
  1147. checkLength(4,TFloat);
  1148. type = TVec(4,VFloat);
  1149. case IVec2, IVec3, IVec4:
  1150. var k = switch(g) {
  1151. case IVec2: 2;
  1152. case IVec3: 3;
  1153. case IVec4: 4;
  1154. default: throw "assert";
  1155. }
  1156. if( args.length == 1 ) {
  1157. switch( args[0].t ) {
  1158. case TInt, TFloat:
  1159. default:
  1160. checkLength(k,TInt);
  1161. }
  1162. } else
  1163. checkLength(k,TInt);
  1164. type = TVec(k,VInt);
  1165. case BVec2:
  1166. checkLength(2,TBool);
  1167. type = TVec(2,VBool);
  1168. case BVec3:
  1169. checkLength(3,TBool);
  1170. type = TVec(3,VBool);
  1171. case BVec4:
  1172. checkLength(4,TBool);
  1173. type = TVec(4,VBool);
  1174. case Mat3x4:
  1175. switch( ([for( a in args ) a.t]) ) {
  1176. case [TMat4]: type = TMat3x4;
  1177. case [TVec(4, VFloat), TVec(4, VFloat), TVec(4, VFloat)]: type = TMat3x4;
  1178. default:
  1179. error("Cannot apply " + g.toString() + " to these parameters", pos);
  1180. }
  1181. case Mat2:
  1182. switch( ([for( a in args ) a.t]) ) {
  1183. case [TMat2]: type = TMat2;
  1184. case [TVec(2, VFloat), TVec(2, VFloat)]: type = TMat2;
  1185. case [TFloat, TFloat, TFloat, TFloat]: type = TMat2;
  1186. default:
  1187. error("Cannot apply " + g.toString() + " to these parameters", pos);
  1188. }
  1189. case Mat3:
  1190. switch( ([for( a in args ) a.t]) ) {
  1191. case [TMat3x4 | TMat4]: type = TMat3;
  1192. case [TVec(3, VFloat), TVec(3, VFloat), TVec(3, VFloat)]: type = TMat3;
  1193. case [TFloat, TFloat, TFloat, TFloat, TFloat, TFloat, TFloat, TFloat, TFloat]: type = TMat3;
  1194. default:
  1195. error("Cannot apply " + g.toString() + " to these parameters", pos);
  1196. }
  1197. case Mat4:
  1198. switch( ([for( a in args ) a.t]) ) {
  1199. case [TMat4]: type = TMat4;
  1200. case [TVec(4, VFloat), TVec(4, VFloat), TVec(4, VFloat), TVec(4, VFloat)]: type = TMat4;
  1201. default:
  1202. error("Cannot apply " + g.toString() + " to these parameters", pos);
  1203. }
  1204. case Trace:
  1205. type = TVoid;
  1206. case ImageStore:
  1207. switch( ([for( a in args ) a.t]) ) {
  1208. case [TRWTexture(dim,arr,chans), uv, color]:
  1209. var szt = getSizeType(Tools.getDimSize(dim,arr),VInt);
  1210. unify(uv, szt, args[1].p);
  1211. unify(color, chans == 1 ? TFloat : TVec(chans,VFloat), args[2].p);
  1212. type = TVoid;
  1213. default:
  1214. error("Cannot apply " + g.toString() + " to these parameters", pos);
  1215. }
  1216. case TextureSize:
  1217. if( args.length != 1 )
  1218. error("TextureSize() requires one single argument", pos);
  1219. switch( args[0].t ) {
  1220. case TSampler(dim,arr), TRWTexture(dim,arr,_):
  1221. type = getSizeType(Tools.getDimSize(dim,arr),VFloat);
  1222. default:
  1223. unify(args[0].t, TSampler(T2D,false), args[0].p);
  1224. type = vec2;
  1225. }
  1226. default:
  1227. }
  1228. if( type == null )
  1229. throw "Custom Global not supported " + g;
  1230. return { e : TCall(e, args), t : type, p : pos };
  1231. }
  1232. function unifyCallParams( efun : TExpr, args : Array<Expr>, variants : Array<FunType>, pos : Position ) {
  1233. var minArgs = 1000, maxArgs = -1000, sel = [];
  1234. for( v in variants ) {
  1235. var n = v.args.length;
  1236. if( n < minArgs ) minArgs = n;
  1237. if( n > maxArgs ) maxArgs = n;
  1238. if( n == args.length ) sel.push(v);
  1239. }
  1240. switch( sel ) {
  1241. case [] if( variants.length == 0 ):
  1242. switch( efun.e ) {
  1243. case TGlobal(g):
  1244. return specialGlobal(g, efun, [for( a in args ) typeExpr(a,Value)], pos);
  1245. default:
  1246. throw "assert";
  1247. }
  1248. case []:
  1249. return error("Function expects " + (minArgs == maxArgs ? "" + minArgs : minArgs + "-" + maxArgs) + " arguments", pos);
  1250. case [f]:
  1251. var targs = [];
  1252. for( i in 0...args.length ) {
  1253. var ft = f.args[i].type;
  1254. var a = typeExpr(args[i], With(ft));
  1255. try {
  1256. unifyExpr(a, ft);
  1257. } catch( e : Error ) {
  1258. e.msg += " for argument '" + f.args[i].name + "'";
  1259. throw e;
  1260. }
  1261. targs.push(a);
  1262. }
  1263. if( variants.length > 1 ) efun.t = TFun([f]);
  1264. return { e : TCall(efun, targs), t : f.ret, p : pos };
  1265. default:
  1266. var bestMatch = null, mcount = -1;
  1267. for( f in sel ) {
  1268. var outArgs = [];
  1269. for( i in 0...args.length ) {
  1270. var a = typeExpr(args[i], With(f.args[i].type));
  1271. if( !tryUnify(a.t, f.args[i].type) )
  1272. break;
  1273. outArgs.push(a);
  1274. }
  1275. if( outArgs.length > mcount ) {
  1276. bestMatch = f;
  1277. mcount = outArgs.length;
  1278. if( mcount == args.length ) {
  1279. efun.t = TFun([f]);
  1280. return { e : TCall(efun, outArgs), t : f.ret, p : pos };
  1281. }
  1282. }
  1283. }
  1284. for( i in 0...args.length )
  1285. try {
  1286. var e = typeExpr(args[i], Value);
  1287. unify(e.t, bestMatch.args[i].type, e.p);
  1288. } catch( e : Error ) {
  1289. e.msg += " for argument '" + bestMatch.args[i].name + "'";
  1290. throw e;
  1291. }
  1292. throw "assert";
  1293. }
  1294. }
  1295. function toFloat( e : TExpr ) {
  1296. if( e.t != TInt ) throw "assert";
  1297. switch( e.e ) {
  1298. case TConst(CInt(v)):
  1299. e.e = TConst(CFloat(v));
  1300. e.t = TFloat;
  1301. default:
  1302. e.e = TCall( { e : TGlobal(ToFloat), t : TFun([]), p : e.p }, [{ e : e.e, t : e.t, p : e.p }]);
  1303. e.t = TFloat;
  1304. }
  1305. }
  1306. function typeBinop(op, e1:TExpr, e2:TExpr, pos : Position) {
  1307. return switch( op ) {
  1308. case OpAssign, OpAssignOp(_): throw "assert";
  1309. case OpMult, OpAdd, OpSub, OpDiv, OpMod:
  1310. switch( [op, e1.t, e2.t] ) {
  1311. case [OpMult,TVec(4,VFloat), TMat4]:
  1312. vec4;
  1313. case [OpMult,TVec(3,VFloat), TMat3x4]:
  1314. vec3;
  1315. case [OpMult, TVec(3,VFloat), TMat3]:
  1316. vec3;
  1317. case [OpMult, TVec(2,VFloat), TMat2]:
  1318. vec2;
  1319. case [_, TInt, TInt]: TInt;
  1320. case [_, TFloat, TFloat]: TFloat;
  1321. case [_, TInt, TFloat]: toFloat(e1); TFloat;
  1322. case [_, TFloat, TInt]: toFloat(e2); TFloat;
  1323. case [_, TVec(a,VFloat), TVec(b,VFloat)] if( a == b ): TVec(a,VFloat);
  1324. case [_, TVec(a,VInt), TVec(b,VInt)] if( a == b ): TVec(a,VInt);
  1325. case [_, TFloat, TVec(_,VFloat)]: e2.t;
  1326. case [_, TVec(_,VFloat), TFloat]: e1.t;
  1327. case [_, TInt, TVec(_, VFloat)]: toFloat(e1); e2.t;
  1328. case [_, TVec(_,VFloat), TInt]: toFloat(e2); e1.t;
  1329. case [OpMult, TMat4, TMat4]: TMat4;
  1330. default:
  1331. var opName = switch( op ) {
  1332. case OpMult: "multiply";
  1333. case OpAdd: "add";
  1334. case OpSub: "subtract";
  1335. case OpDiv: "divide";
  1336. default: throw "assert";
  1337. }
  1338. error("Cannot " + opName + " " + e1.t.toString() + " and " + e2.t.toString(), pos);
  1339. }
  1340. case OpLt, OpGt, OpLte, OpGte, OpEq, OpNotEq:
  1341. switch( e1.t ) {
  1342. case TFloat, TInt, TString if( e2.t != TVoid ):
  1343. unifyExpr(e2, e1.t);
  1344. TBool;
  1345. case TBool if( (op == OpEq || op == OpNotEq) && e2.t != TVoid ):
  1346. unifyExpr(e2, e1.t);
  1347. TBool;
  1348. case TVec(_) if( e2.t != TVoid ):
  1349. unifyExpr(e2, e1.t);
  1350. e1.t;
  1351. default:
  1352. switch( [e1.e, e2.e] ) {
  1353. case [TVar(v), TConst(CNull)], [TConst(CNull), TVar(v)]:
  1354. if( !v.hasQualifier(Nullable) )
  1355. error("Variable is not declared as nullable", e1.p);
  1356. TBool;
  1357. default:
  1358. error("Cannot compare " + e1.t.toString() + " and " + e2.t.toString(), pos);
  1359. }
  1360. }
  1361. case OpBoolAnd, OpBoolOr:
  1362. unifyExpr(e1, TBool);
  1363. unifyExpr(e2, TBool);
  1364. TBool;
  1365. case OpInterval:
  1366. unifyExpr(e1, TInt);
  1367. unifyExpr(e2, TInt);
  1368. TArray(TInt, SConst(0));
  1369. case OpShl, OpShr, OpUShr, OpOr, OpAnd, OpXor:
  1370. unifyExpr(e1, TInt);
  1371. unifyExpr(e2, TInt);
  1372. TInt;
  1373. default:
  1374. error("Unsupported operator " + op, pos);
  1375. }
  1376. }
  1377. }