expr.go 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. // Copyright 2020 The Ebiten Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package shader
  15. import (
  16. "fmt"
  17. "go/ast"
  18. gconstant "go/constant"
  19. "go/token"
  20. "regexp"
  21. "strconv"
  22. "strings"
  23. "github.com/hajimehoshi/ebiten/v2/internal/shaderir"
  24. )
  25. func canTruncateToInteger(v gconstant.Value) bool {
  26. return gconstant.ToInt(v).Kind() != gconstant.Unknown
  27. }
  28. func canTruncateToFloat(v gconstant.Value) bool {
  29. return gconstant.ToFloat(v).Kind() != gconstant.Unknown
  30. }
  31. var textureVariableRe = regexp.MustCompile(`\A__t(\d+)\z`)
  32. func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, markLocalVariableUsed bool) ([]shaderir.Expr, []shaderir.Type, []shaderir.Stmt, bool) {
  33. switch e := expr.(type) {
  34. case *ast.BasicLit:
  35. switch e.Kind {
  36. case token.INT:
  37. // The type is not determined yet.
  38. return []shaderir.Expr{
  39. {
  40. Type: shaderir.NumberExpr,
  41. Const: gconstant.MakeFromLiteral(e.Value, e.Kind, 0),
  42. },
  43. }, []shaderir.Type{{}}, nil, true
  44. case token.FLOAT:
  45. // The type is not determined yet.
  46. return []shaderir.Expr{
  47. {
  48. Type: shaderir.NumberExpr,
  49. Const: gconstant.MakeFromLiteral(e.Value, e.Kind, 0),
  50. },
  51. }, []shaderir.Type{{}}, nil, true
  52. default:
  53. cs.addError(e.Pos(), fmt.Sprintf("literal not implemented: %#v", e))
  54. }
  55. case *ast.BinaryExpr:
  56. var stmts []shaderir.Stmt
  57. // Prase LHS first for the order of the statements.
  58. lhs, ts, ss, ok := cs.parseExpr(block, fname, e.X, markLocalVariableUsed)
  59. if !ok {
  60. return nil, nil, nil, false
  61. }
  62. if len(lhs) != 1 {
  63. cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.X))
  64. return nil, nil, nil, false
  65. }
  66. stmts = append(stmts, ss...)
  67. if len(ts) == 0 {
  68. cs.addError(e.Pos(), fmt.Sprintf("unexpected binary operator: %s", e.X))
  69. return nil, nil, nil, false
  70. }
  71. lhst := ts[0]
  72. rhs, ts, ss, ok := cs.parseExpr(block, fname, e.Y, markLocalVariableUsed)
  73. if !ok {
  74. return nil, nil, nil, false
  75. }
  76. if len(rhs) != 1 {
  77. cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.Y))
  78. return nil, nil, nil, false
  79. }
  80. stmts = append(stmts, ss...)
  81. if len(ts) == 0 {
  82. cs.addError(e.Pos(), fmt.Sprintf("unexpected binary operator: %s", e.Y))
  83. return nil, nil, nil, false
  84. }
  85. rhst := ts[0]
  86. op := e.Op
  87. // https://pkg.go.dev/go/constant/#BinaryOp
  88. // "To force integer division of Int operands, use op == token.QUO_ASSIGN instead of
  89. // token.QUO; the result is guaranteed to be Int in this case."
  90. if op == token.QUO && lhs[0].Const != nil && lhs[0].Const.Kind() == gconstant.Int && rhs[0].Const != nil && rhs[0].Const.Kind() == gconstant.Int {
  91. op = token.QUO_ASSIGN
  92. }
  93. op2, ok := shaderir.OpFromToken(e.Op, lhst, rhst)
  94. if !ok {
  95. cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
  96. return nil, nil, nil, false
  97. }
  98. // Resolve untyped constants.
  99. l, r, ok := shaderir.ResolveUntypedConstsForBinaryOp(op2, lhs[0].Const, rhs[0].Const, lhst, rhst)
  100. if !ok {
  101. // TODO: Show a better type name for untyped constants.
  102. cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), op, rhst.String()))
  103. return nil, nil, nil, false
  104. }
  105. lhs[0].Const, rhs[0].Const = l, r
  106. // If either is typed, resolve the other type.
  107. // If both are untyped, keep them untyped.
  108. if lhst.Main != shaderir.None || rhst.Main != shaderir.None {
  109. if lhs[0].Const != nil {
  110. switch lhs[0].Const.Kind() {
  111. case gconstant.Float:
  112. lhst = shaderir.Type{Main: shaderir.Float}
  113. case gconstant.Int:
  114. lhst = shaderir.Type{Main: shaderir.Int}
  115. case gconstant.Bool:
  116. lhst = shaderir.Type{Main: shaderir.Bool}
  117. }
  118. }
  119. if rhs[0].Const != nil {
  120. switch rhs[0].Const.Kind() {
  121. case gconstant.Float:
  122. rhst = shaderir.Type{Main: shaderir.Float}
  123. case gconstant.Int:
  124. rhst = shaderir.Type{Main: shaderir.Int}
  125. case gconstant.Bool:
  126. rhst = shaderir.Type{Main: shaderir.Bool}
  127. }
  128. }
  129. }
  130. t, ok := shaderir.TypeFromBinaryOp(op2, lhst, rhst, lhs[0].Const, rhs[0].Const)
  131. if !ok {
  132. // TODO: Show a better type name for untyped constants.
  133. cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), op, rhst.String()))
  134. return nil, nil, nil, false
  135. }
  136. if lhs[0].Const != nil && rhs[0].Const != nil {
  137. var v gconstant.Value
  138. switch op {
  139. case token.LAND, token.LOR:
  140. b := gconstant.BoolVal(gconstant.BinaryOp(lhs[0].Const, op, rhs[0].Const))
  141. v = gconstant.MakeBool(b)
  142. case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
  143. v = gconstant.MakeBool(gconstant.Compare(lhs[0].Const, op, rhs[0].Const))
  144. case token.SHL, token.SHR:
  145. shift, ok := gconstant.Int64Val(rhs[0].Const)
  146. if !ok {
  147. cs.addError(e.Pos(), fmt.Sprintf("unexpected %s type for: %s", rhs[0].Const.String(), e.Op))
  148. return nil, nil, nil, false
  149. }
  150. v = gconstant.Shift(lhs[0].Const, op, uint(shift))
  151. default:
  152. v = gconstant.BinaryOp(lhs[0].Const, op, rhs[0].Const)
  153. }
  154. return []shaderir.Expr{
  155. {
  156. Type: shaderir.NumberExpr,
  157. Const: v,
  158. },
  159. }, []shaderir.Type{t}, stmts, true
  160. }
  161. return []shaderir.Expr{
  162. {
  163. Type: shaderir.Binary,
  164. Op: op2,
  165. Exprs: []shaderir.Expr{lhs[0], rhs[0]},
  166. },
  167. }, []shaderir.Type{t}, stmts, true
  168. case *ast.CallExpr:
  169. var (
  170. callee shaderir.Expr
  171. args []shaderir.Expr
  172. argts []shaderir.Type
  173. stmts []shaderir.Stmt
  174. )
  175. // Parse the argument first for the order of the statements.
  176. for _, a := range e.Args {
  177. es, ts, ss, ok := cs.parseExpr(block, fname, a, markLocalVariableUsed)
  178. if !ok {
  179. return nil, nil, nil, false
  180. }
  181. if len(es) > 1 && len(e.Args) > 1 {
  182. cs.addError(e.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed: %s", e.Fun))
  183. return nil, nil, nil, false
  184. }
  185. for _, expr := range es {
  186. if expr.Type == shaderir.FunctionExpr || expr.Type == shaderir.BuiltinFuncExpr {
  187. cs.addError(e.Pos(), fmt.Sprintf("function name cannot be an argument: %s", e.Fun))
  188. return nil, nil, nil, false
  189. }
  190. }
  191. args = append(args, es...)
  192. argts = append(argts, ts...)
  193. stmts = append(stmts, ss...)
  194. }
  195. // TODO: When len(ss) is not 0?
  196. es, _, ss, ok := cs.parseExpr(block, fname, e.Fun, markLocalVariableUsed)
  197. if !ok {
  198. return nil, nil, nil, false
  199. }
  200. if len(es) != 1 {
  201. cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a callee: %s", e.Fun))
  202. return nil, nil, nil, false
  203. }
  204. callee = es[0]
  205. stmts = append(stmts, ss...)
  206. // For built-in functions, we can call this in this position. Return an expression for the function
  207. // call.
  208. if callee.Type == shaderir.BuiltinFuncExpr {
  209. // Process compile-time evaluations.
  210. switch callee.BuiltinFunc {
  211. case shaderir.Len, shaderir.Cap:
  212. if len(args) != 1 {
  213. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 1 but %d", callee.BuiltinFunc, len(args)))
  214. return nil, nil, nil, false
  215. }
  216. if argts[0].Main != shaderir.Array {
  217. cs.addError(e.Pos(), fmt.Sprintf("%s takes an array but %s", callee.BuiltinFunc, argts[0].String()))
  218. return nil, nil, nil, false
  219. }
  220. return []shaderir.Expr{
  221. {
  222. Type: shaderir.NumberExpr,
  223. Const: gconstant.MakeInt64(int64(argts[0].Length)),
  224. },
  225. }, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
  226. case shaderir.BoolF:
  227. if len(args) == 1 && args[0].Const != nil {
  228. if args[0].Const.Kind() != gconstant.Bool {
  229. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type bool", args[0].Const.String()))
  230. return nil, nil, nil, false
  231. }
  232. return []shaderir.Expr{
  233. {
  234. Type: shaderir.NumberExpr,
  235. Const: args[0].Const,
  236. },
  237. }, []shaderir.Type{{Main: shaderir.Bool}}, stmts, true
  238. }
  239. case shaderir.IntF:
  240. if len(args) == 1 && args[0].Const != nil {
  241. // For constants, a cast-like function doesn't work as a cast.
  242. // For example, `int(1.1)` is invalid.
  243. v := gconstant.ToInt(args[0].Const)
  244. if v.Kind() == gconstant.Unknown {
  245. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[0].Const.String()))
  246. return nil, nil, nil, false
  247. }
  248. return []shaderir.Expr{
  249. {
  250. Type: shaderir.NumberExpr,
  251. Const: v,
  252. },
  253. }, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
  254. }
  255. case shaderir.FloatF:
  256. if len(args) == 1 && args[0].Const != nil {
  257. v := gconstant.ToFloat(args[0].Const)
  258. if v.Kind() == gconstant.Unknown {
  259. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[0].Const.String()))
  260. return nil, nil, nil, false
  261. }
  262. return []shaderir.Expr{
  263. {
  264. Type: shaderir.NumberExpr,
  265. Const: v,
  266. },
  267. }, []shaderir.Type{{Main: shaderir.Float}}, stmts, true
  268. }
  269. }
  270. // Process the expression as a regular function call.
  271. var finalType shaderir.Type
  272. switch callee.BuiltinFunc {
  273. case shaderir.BoolF:
  274. if err := checkArgsForBoolBuiltinFunc(args, argts); err != nil {
  275. cs.addError(e.Pos(), err.Error())
  276. return nil, nil, nil, false
  277. }
  278. finalType = shaderir.Type{Main: shaderir.Bool}
  279. case shaderir.IntF:
  280. if err := checkArgsForIntBuiltinFunc(args, argts); err != nil {
  281. cs.addError(e.Pos(), err.Error())
  282. return nil, nil, nil, false
  283. }
  284. finalType = shaderir.Type{Main: shaderir.Int}
  285. case shaderir.FloatF:
  286. if err := checkArgsForFloatBuiltinFunc(args, argts); err != nil {
  287. cs.addError(e.Pos(), err.Error())
  288. return nil, nil, nil, false
  289. }
  290. finalType = shaderir.Type{Main: shaderir.Float}
  291. case shaderir.Vec2F:
  292. if err := checkArgsForVec2BuiltinFunc(args, argts); err != nil {
  293. cs.addError(e.Pos(), err.Error())
  294. return nil, nil, nil, false
  295. }
  296. for i := range args {
  297. if args[i].Const == nil {
  298. continue
  299. }
  300. args[i].Const = gconstant.ToFloat(args[i].Const)
  301. argts[i] = shaderir.Type{Main: shaderir.Float}
  302. }
  303. finalType = shaderir.Type{Main: shaderir.Vec2}
  304. case shaderir.Vec3F:
  305. if err := checkArgsForVec3BuiltinFunc(args, argts); err != nil {
  306. cs.addError(e.Pos(), err.Error())
  307. return nil, nil, nil, false
  308. }
  309. for i := range args {
  310. if args[i].Const == nil {
  311. continue
  312. }
  313. args[i].Const = gconstant.ToFloat(args[i].Const)
  314. argts[i] = shaderir.Type{Main: shaderir.Float}
  315. }
  316. finalType = shaderir.Type{Main: shaderir.Vec3}
  317. case shaderir.Vec4F:
  318. if err := checkArgsForVec4BuiltinFunc(args, argts); err != nil {
  319. cs.addError(e.Pos(), err.Error())
  320. return nil, nil, nil, false
  321. }
  322. for i := range args {
  323. if args[i].Const == nil {
  324. continue
  325. }
  326. args[i].Const = gconstant.ToFloat(args[i].Const)
  327. argts[i] = shaderir.Type{Main: shaderir.Float}
  328. }
  329. finalType = shaderir.Type{Main: shaderir.Vec4}
  330. case shaderir.IVec2F:
  331. if err := checkArgsForIVec2BuiltinFunc(args, argts); err != nil {
  332. cs.addError(e.Pos(), err.Error())
  333. return nil, nil, nil, false
  334. }
  335. finalType = shaderir.Type{Main: shaderir.IVec2}
  336. case shaderir.IVec3F:
  337. if err := checkArgsForIVec3BuiltinFunc(args, argts); err != nil {
  338. cs.addError(e.Pos(), err.Error())
  339. return nil, nil, nil, false
  340. }
  341. finalType = shaderir.Type{Main: shaderir.IVec3}
  342. case shaderir.IVec4F:
  343. if err := checkArgsForIVec4BuiltinFunc(args, argts); err != nil {
  344. cs.addError(e.Pos(), err.Error())
  345. return nil, nil, nil, false
  346. }
  347. finalType = shaderir.Type{Main: shaderir.IVec4}
  348. case shaderir.Mat2F:
  349. if err := checkArgsForMat2BuiltinFunc(args, argts); err != nil {
  350. cs.addError(e.Pos(), err.Error())
  351. return nil, nil, nil, false
  352. }
  353. for i := range args {
  354. if args[i].Const == nil {
  355. continue
  356. }
  357. args[i].Const = gconstant.ToFloat(args[i].Const)
  358. argts[i] = shaderir.Type{Main: shaderir.Float}
  359. }
  360. finalType = shaderir.Type{Main: shaderir.Mat2}
  361. case shaderir.Mat3F:
  362. if err := checkArgsForMat3BuiltinFunc(args, argts); err != nil {
  363. cs.addError(e.Pos(), err.Error())
  364. return nil, nil, nil, false
  365. }
  366. for i := range args {
  367. if args[i].Const == nil {
  368. continue
  369. }
  370. args[i].Const = gconstant.ToFloat(args[i].Const)
  371. argts[i] = shaderir.Type{Main: shaderir.Float}
  372. }
  373. finalType = shaderir.Type{Main: shaderir.Mat3}
  374. case shaderir.Mat4F:
  375. if err := checkArgsForMat4BuiltinFunc(args, argts); err != nil {
  376. cs.addError(e.Pos(), err.Error())
  377. return nil, nil, nil, false
  378. }
  379. for i := range args {
  380. if args[i].Const == nil {
  381. continue
  382. }
  383. args[i].Const = gconstant.ToFloat(args[i].Const)
  384. argts[i] = shaderir.Type{Main: shaderir.Float}
  385. }
  386. finalType = shaderir.Type{Main: shaderir.Mat4}
  387. case shaderir.TexelAt:
  388. if len(args) != 2 {
  389. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
  390. return nil, nil, nil, false
  391. }
  392. if argts[0].Main != shaderir.Texture {
  393. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as texture value in argument to %s", argts[0].String(), callee.BuiltinFunc))
  394. return nil, nil, nil, false
  395. }
  396. if argts[1].Main != shaderir.Vec2 {
  397. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as vec2 value in argument to %s", argts[1].String(), callee.BuiltinFunc))
  398. return nil, nil, nil, false
  399. }
  400. finalType = shaderir.Type{Main: shaderir.Vec4}
  401. case shaderir.DiscardF:
  402. if len(args) != 0 {
  403. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 0 but %d", callee.BuiltinFunc, len(args)))
  404. return nil, nil, nil, false
  405. }
  406. if fname != cs.fragmentEntry {
  407. cs.addError(e.Pos(), fmt.Sprintf("discard is available only in %s", cs.fragmentEntry))
  408. return nil, nil, nil, false
  409. }
  410. stmts = append(stmts, shaderir.Stmt{
  411. Type: shaderir.Discard,
  412. })
  413. return nil, nil, stmts, true
  414. case shaderir.Clamp, shaderir.Mix, shaderir.Smoothstep, shaderir.Faceforward, shaderir.Refract:
  415. // 3 arguments
  416. if len(args) != 3 {
  417. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 3 but %d", callee.BuiltinFunc, len(args)))
  418. return nil, nil, nil, false
  419. }
  420. switch callee.BuiltinFunc {
  421. case shaderir.Clamp:
  422. if kind, _ := resolveConstKind(args, argts); kind != gconstant.Unknown {
  423. switch kind {
  424. case gconstant.Int:
  425. for i, arg := range args {
  426. if arg.Const == nil {
  427. if argts[i].Main != shaderir.Int {
  428. cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s, %s, and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String(), argts[2].String()))
  429. return nil, nil, nil, false
  430. }
  431. continue
  432. }
  433. v := gconstant.ToInt(arg.Const)
  434. if v.Kind() == gconstant.Unknown {
  435. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", arg.Const.String()))
  436. return nil, nil, nil, false
  437. }
  438. args[i].Const = gconstant.ToInt(args[i].Const)
  439. argts[i] = shaderir.Type{Main: shaderir.Int}
  440. }
  441. case gconstant.Float:
  442. for i, arg := range args {
  443. if arg.Const == nil {
  444. if argts[i].Main != shaderir.Float {
  445. cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s, %s, and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String(), argts[2].String()))
  446. return nil, nil, nil, false
  447. }
  448. continue
  449. }
  450. v := gconstant.ToFloat(arg.Const)
  451. if v.Kind() == gconstant.Unknown {
  452. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", arg.Const.String()))
  453. return nil, nil, nil, false
  454. }
  455. args[i].Const = gconstant.ToFloat(args[i].Const)
  456. argts[i] = shaderir.Type{Main: shaderir.Float}
  457. }
  458. }
  459. }
  460. if argts[0].IsIntVector() {
  461. for i := 1; i < 3; i++ {
  462. if args[i].Const != nil {
  463. v := gconstant.ToInt(args[i].Const)
  464. if v.Kind() == gconstant.Unknown {
  465. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[i].Const.String()))
  466. return nil, nil, nil, false
  467. }
  468. args[i].Const = v
  469. argts[i] = shaderir.Type{Main: shaderir.Int}
  470. }
  471. }
  472. }
  473. if argts[0].IsFloatVector() {
  474. for i := 1; i < 3; i++ {
  475. if args[i].Const != nil {
  476. v := gconstant.ToFloat(args[i].Const)
  477. if v.Kind() == gconstant.Unknown {
  478. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[i].Const.String()))
  479. return nil, nil, nil, false
  480. }
  481. args[i].Const = v
  482. argts[i] = shaderir.Type{Main: shaderir.Float}
  483. }
  484. }
  485. }
  486. default:
  487. for i := range args {
  488. // If the argument is a non-typed constant value, treat this as a float value (#1874).
  489. if args[i].Const != nil && argts[i].Main == shaderir.None && gconstant.ToFloat(args[i].Const).Kind() != gconstant.Unknown {
  490. args[i].Const = gconstant.ToFloat(args[i].Const)
  491. argts[i] = shaderir.Type{Main: shaderir.Float}
  492. }
  493. }
  494. }
  495. for i := range args {
  496. switch callee.BuiltinFunc {
  497. case shaderir.Clamp:
  498. if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() && argts[i].Main != shaderir.Int && !argts[i].IsIntVector() {
  499. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivecN value in argument to %s", argts[i].String(), callee.BuiltinFunc))
  500. return nil, nil, nil, false
  501. }
  502. default:
  503. if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() {
  504. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
  505. return nil, nil, nil, false
  506. }
  507. }
  508. }
  509. switch callee.BuiltinFunc {
  510. case shaderir.Clamp:
  511. if !((argts[0].Equal(&argts[1]) && argts[0].Equal(&argts[2])) ||
  512. (argts[0].IsFloatVector() && argts[1].Main == shaderir.Float && argts[2].Main == shaderir.Float) ||
  513. (argts[0].IsIntVector() && argts[1].Main == shaderir.Int && argts[2].Main == shaderir.Int)) {
  514. cs.addError(e.Pos(), fmt.Sprintf("the second and the third arguments for %s must equal to the first argument %s or float or int but %s and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String(), argts[2].String()))
  515. return nil, nil, nil, false
  516. }
  517. case shaderir.Mix:
  518. if !argts[0].Equal(&argts[1]) {
  519. cs.addError(e.Pos(), fmt.Sprintf("%s and %s don't match in argument to %s", argts[0].String(), argts[1].String(), callee.BuiltinFunc))
  520. return nil, nil, nil, false
  521. }
  522. if !argts[0].Equal(&argts[2]) && argts[2].Main != shaderir.Float {
  523. cs.addError(e.Pos(), fmt.Sprintf("the third arguments for %s must equal to the first/second argument %s or float but %s", callee.BuiltinFunc, argts[0].String(), argts[2].String()))
  524. return nil, nil, nil, false
  525. }
  526. case shaderir.Smoothstep:
  527. if (!argts[0].Equal(&argts[1]) || !argts[0].Equal(&argts[2])) && (argts[0].Main != shaderir.Float || argts[1].Main != shaderir.Float) {
  528. cs.addError(e.Pos(), fmt.Sprintf("the first and the second arguments for %s must equal to the third argument %s or float but %s and %s", callee.BuiltinFunc, argts[2].String(), argts[0].String(), argts[1].String()))
  529. return nil, nil, nil, false
  530. }
  531. case shaderir.Refract:
  532. if !argts[0].Equal(&argts[1]) {
  533. cs.addError(e.Pos(), fmt.Sprintf("%s and %s don't match in argument to %s", argts[0].String(), argts[1].String(), callee.BuiltinFunc))
  534. return nil, nil, nil, false
  535. }
  536. if argts[2].Main != shaderir.Float {
  537. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float value in argument to %s", argts[2].String(), callee.BuiltinFunc))
  538. return nil, nil, nil, false
  539. }
  540. default:
  541. if !argts[0].Equal(&argts[1]) || !argts[0].Equal(&argts[2]) {
  542. cs.addError(e.Pos(), fmt.Sprintf("all the argument types for %s must be the same but %s, %s, and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String(), argts[2].String()))
  543. return nil, nil, nil, false
  544. }
  545. }
  546. switch callee.BuiltinFunc {
  547. case shaderir.Smoothstep:
  548. finalType = argts[2]
  549. default:
  550. finalType = argts[0]
  551. }
  552. case shaderir.Atan2, shaderir.Pow, shaderir.Mod, shaderir.Min, shaderir.Max, shaderir.Step, shaderir.Distance, shaderir.Dot, shaderir.Cross, shaderir.Reflect:
  553. // 2 arguments
  554. if len(args) != 2 {
  555. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
  556. return nil, nil, nil, false
  557. }
  558. switch callee.BuiltinFunc {
  559. case shaderir.Min, shaderir.Max:
  560. if kind, _ := resolveConstKind(args, argts); kind != gconstant.Unknown {
  561. switch kind {
  562. case gconstant.Int:
  563. for i, arg := range args {
  564. if arg.Const == nil {
  565. if argts[i].Main != shaderir.Int {
  566. cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
  567. return nil, nil, nil, false
  568. }
  569. continue
  570. }
  571. v := gconstant.ToInt(arg.Const)
  572. if v.Kind() == gconstant.Unknown {
  573. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", arg.Const.String()))
  574. return nil, nil, nil, false
  575. }
  576. args[i].Const = gconstant.ToInt(args[i].Const)
  577. argts[i] = shaderir.Type{Main: shaderir.Int}
  578. }
  579. case gconstant.Float:
  580. for i, arg := range args {
  581. if arg.Const == nil {
  582. if argts[i].Main != shaderir.Float {
  583. cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
  584. return nil, nil, nil, false
  585. }
  586. continue
  587. }
  588. v := gconstant.ToFloat(arg.Const)
  589. if v.Kind() == gconstant.Unknown {
  590. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", arg.Const.String()))
  591. return nil, nil, nil, false
  592. }
  593. args[i].Const = gconstant.ToFloat(args[i].Const)
  594. argts[i] = shaderir.Type{Main: shaderir.Float}
  595. }
  596. }
  597. }
  598. if argts[0].IsIntVector() && args[1].Const != nil {
  599. v := gconstant.ToInt(args[1].Const)
  600. if v.Kind() == gconstant.Unknown {
  601. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[1].Const.String()))
  602. return nil, nil, nil, false
  603. }
  604. args[1].Const = v
  605. argts[1] = shaderir.Type{Main: shaderir.Int}
  606. }
  607. if argts[0].IsFloatVector() && args[1].Const != nil {
  608. v := gconstant.ToFloat(args[1].Const)
  609. if v.Kind() == gconstant.Unknown {
  610. cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[1].Const.String()))
  611. return nil, nil, nil, false
  612. }
  613. args[1].Const = v
  614. argts[1] = shaderir.Type{Main: shaderir.Float}
  615. }
  616. default:
  617. for i := range args {
  618. if args[i].Const != nil && argts[i].Main == shaderir.None {
  619. // If the argument is a non-typed constant value, treat this as a float value (#1874).
  620. if gconstant.ToFloat(args[i].Const).Kind() != gconstant.Unknown {
  621. args[i].Const = gconstant.ToFloat(args[i].Const)
  622. argts[i] = shaderir.Type{Main: shaderir.Float}
  623. }
  624. }
  625. }
  626. }
  627. for i := range args {
  628. switch callee.BuiltinFunc {
  629. case shaderir.Min, shaderir.Max:
  630. if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() && argts[i].Main != shaderir.Int && !argts[i].IsIntVector() {
  631. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivecN value in argument to %s", argts[i].String(), callee.BuiltinFunc))
  632. return nil, nil, nil, false
  633. }
  634. default:
  635. if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() {
  636. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
  637. return nil, nil, nil, false
  638. }
  639. }
  640. }
  641. switch callee.BuiltinFunc {
  642. case shaderir.Mod:
  643. if !argts[0].Equal(&argts[1]) && argts[1].Main != shaderir.Float {
  644. cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
  645. return nil, nil, nil, false
  646. }
  647. case shaderir.Min, shaderir.Max:
  648. if !(argts[0].Equal(&argts[1]) || (argts[0].IsFloatVector() && argts[1].Main == shaderir.Float) || (argts[0].IsIntVector() && argts[1].Main == shaderir.Int)) {
  649. cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float or int but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
  650. return nil, nil, nil, false
  651. }
  652. case shaderir.Step:
  653. if !argts[0].Equal(&argts[1]) && argts[0].Main != shaderir.Float {
  654. cs.addError(e.Pos(), fmt.Sprintf("the first argument for %s must equal to the second argument %s or float but %s", callee.BuiltinFunc, argts[1].String(), argts[0].String()))
  655. return nil, nil, nil, false
  656. }
  657. case shaderir.Cross:
  658. for i := range argts {
  659. if argts[i].Main != shaderir.Vec3 {
  660. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as vec3 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
  661. return nil, nil, nil, false
  662. }
  663. }
  664. default:
  665. if !argts[0].Equal(&argts[1]) {
  666. cs.addError(e.Pos(), fmt.Sprintf("%s and %s don't match in argument to %s", argts[0].String(), argts[1].String(), callee.BuiltinFunc))
  667. return nil, nil, nil, false
  668. }
  669. }
  670. switch callee.BuiltinFunc {
  671. case shaderir.Distance, shaderir.Dot:
  672. finalType = shaderir.Type{Main: shaderir.Float}
  673. case shaderir.Step:
  674. finalType = argts[1]
  675. default:
  676. finalType = argts[0]
  677. }
  678. default:
  679. // 1 argument
  680. if len(args) != 1 {
  681. cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 1 but %d", callee.BuiltinFunc, len(args)))
  682. return nil, nil, nil, false
  683. }
  684. if args[0].Const != nil && argts[0].Main == shaderir.None {
  685. switch callee.BuiltinFunc {
  686. case shaderir.Abs, shaderir.Sign:
  687. if args[0].Const.Kind() == gconstant.Int {
  688. argts[0] = shaderir.Type{Main: shaderir.Int}
  689. }
  690. if args[0].Const.Kind() == gconstant.Float {
  691. argts[0] = shaderir.Type{Main: shaderir.Float}
  692. }
  693. default:
  694. // If the argument is a non-typed constant value, treat this as a float value (#1874).
  695. if gconstant.ToFloat(args[0].Const).Kind() != gconstant.Unknown {
  696. args[0].Const = gconstant.ToFloat(args[0].Const)
  697. argts[0] = shaderir.Type{Main: shaderir.Float}
  698. }
  699. }
  700. }
  701. switch callee.BuiltinFunc {
  702. case shaderir.Transpose:
  703. if !argts[0].IsMatrix() {
  704. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as mat2, mat3, or mat4 value in argument to %s", argts[0].String(), callee.BuiltinFunc))
  705. return nil, nil, nil, false
  706. }
  707. case shaderir.Abs, shaderir.Sign:
  708. if argts[0].Main != shaderir.Float && !argts[0].IsFloatVector() && argts[0].Main != shaderir.Int && !argts[0].IsIntVector() {
  709. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivenN value in argument to %s", argts[0].String(), callee.BuiltinFunc))
  710. return nil, nil, nil, false
  711. }
  712. default:
  713. if argts[0].Main != shaderir.Float && !argts[0].IsFloatVector() {
  714. cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[0].String(), callee.BuiltinFunc))
  715. return nil, nil, nil, false
  716. }
  717. }
  718. if callee.BuiltinFunc == shaderir.Length {
  719. finalType = shaderir.Type{Main: shaderir.Float}
  720. } else {
  721. finalType = argts[0]
  722. }
  723. }
  724. return []shaderir.Expr{
  725. {
  726. Type: shaderir.Call,
  727. Exprs: append([]shaderir.Expr{callee}, args...),
  728. },
  729. }, []shaderir.Type{finalType}, stmts, true
  730. }
  731. if callee.Type != shaderir.FunctionExpr {
  732. cs.addError(e.Pos(), fmt.Sprintf("function callee must be a function name but %s", e.Fun))
  733. return nil, nil, nil, false
  734. }
  735. f := cs.funcs[callee.Index]
  736. if len(f.ir.InParams) < len(args) {
  737. cs.addError(e.Pos(), fmt.Sprintf("too many arguments in call to %s", e.Fun))
  738. return nil, nil, nil, false
  739. }
  740. if len(f.ir.InParams) > len(args) {
  741. cs.addError(e.Pos(), fmt.Sprintf("not enough arguments in call to %s", e.Fun))
  742. return nil, nil, nil, false
  743. }
  744. for i, p := range f.ir.InParams {
  745. if !canAssign(&p, &argts[i], args[i].Const) {
  746. cs.addError(e.Pos(), fmt.Sprintf("cannot use type %s as type %s in argument", argts[i].String(), p.String()))
  747. return nil, nil, nil, false
  748. }
  749. if args[i].Const != nil {
  750. switch p.Main {
  751. case shaderir.Int:
  752. args[i].Const = gconstant.ToInt(args[i].Const)
  753. argts[i] = shaderir.Type{Main: shaderir.Int}
  754. case shaderir.Float:
  755. args[i].Const = gconstant.ToFloat(args[i].Const)
  756. argts[i] = shaderir.Type{Main: shaderir.Float}
  757. }
  758. }
  759. }
  760. var outParams []int
  761. for _, p := range f.ir.OutParams {
  762. idx := block.totalLocalVariableCount()
  763. block.vars = append(block.vars, variable{
  764. typ: p,
  765. })
  766. args = append(args, shaderir.Expr{
  767. Type: shaderir.LocalVariable,
  768. Index: idx,
  769. })
  770. outParams = append(outParams, idx)
  771. }
  772. if t := f.ir.Return; t.Main != shaderir.None {
  773. if len(outParams) != 0 {
  774. cs.addError(e.Pos(), fmt.Sprintf("a function returning value cannot have out-params so far: %s", e.Fun))
  775. return nil, nil, nil, false
  776. }
  777. // The actual expression here is just a local variable that includes the result of the
  778. // function call.
  779. return []shaderir.Expr{
  780. {
  781. Type: shaderir.Call,
  782. Exprs: append([]shaderir.Expr{callee}, args...),
  783. },
  784. }, []shaderir.Type{t}, stmts, true
  785. }
  786. // Even if the function doesn't return anything, calling the function should be done earlier to keep
  787. // the evaluation order.
  788. stmts = append(stmts, shaderir.Stmt{
  789. Type: shaderir.ExprStmt,
  790. Exprs: []shaderir.Expr{
  791. {
  792. Type: shaderir.Call,
  793. Exprs: append([]shaderir.Expr{callee}, args...),
  794. },
  795. },
  796. })
  797. if len(outParams) == 0 {
  798. // TODO: Is this an error?
  799. }
  800. // These local-variable expressions are used for an outside function callers.
  801. var exprs []shaderir.Expr
  802. for _, p := range outParams {
  803. exprs = append(exprs, shaderir.Expr{
  804. Type: shaderir.LocalVariable,
  805. Index: p,
  806. })
  807. }
  808. return exprs, f.ir.OutParams, stmts, true
  809. case *ast.Ident:
  810. if e.Name == "_" {
  811. // In the context where a local variable is marked as used, any expressions must have its
  812. // meaning. Then, a blank identifier is not available there.
  813. if markLocalVariableUsed {
  814. cs.addError(e.Pos(), "cannot use _ as value")
  815. return nil, nil, nil, false
  816. }
  817. return []shaderir.Expr{
  818. {
  819. Type: shaderir.Blank,
  820. },
  821. }, []shaderir.Type{{}}, nil, true
  822. }
  823. if i, t, ok := block.findLocalVariable(e.Name, markLocalVariableUsed); ok {
  824. return []shaderir.Expr{
  825. {
  826. Type: shaderir.LocalVariable,
  827. Index: i,
  828. },
  829. }, []shaderir.Type{t}, nil, true
  830. }
  831. if c, ok := block.findConstant(e.Name); ok {
  832. return []shaderir.Expr{
  833. {
  834. Type: shaderir.NumberExpr,
  835. Const: c.value,
  836. },
  837. }, []shaderir.Type{c.typ}, nil, true
  838. }
  839. if i, ok := cs.findFunction(e.Name); ok {
  840. return []shaderir.Expr{
  841. {
  842. Type: shaderir.FunctionExpr,
  843. Index: i,
  844. },
  845. }, nil, nil, true
  846. }
  847. if i, ok := cs.findUniformVariable(e.Name); ok {
  848. return []shaderir.Expr{
  849. {
  850. Type: shaderir.UniformVariable,
  851. Index: i,
  852. },
  853. }, []shaderir.Type{cs.ir.Uniforms[i]}, nil, true
  854. }
  855. if f, ok := shaderir.ParseBuiltinFunc(e.Name); ok {
  856. return []shaderir.Expr{
  857. {
  858. Type: shaderir.BuiltinFuncExpr,
  859. BuiltinFunc: f,
  860. },
  861. }, nil, nil, true
  862. }
  863. if m := textureVariableRe.FindStringSubmatch(e.Name); m != nil {
  864. i, _ := strconv.Atoi(m[1])
  865. return []shaderir.Expr{
  866. {
  867. Type: shaderir.TextureVariable,
  868. Index: i,
  869. },
  870. }, []shaderir.Type{{Main: shaderir.Texture}}, nil, true
  871. }
  872. if e.Name == "true" || e.Name == "false" {
  873. return []shaderir.Expr{
  874. {
  875. Type: shaderir.NumberExpr,
  876. Const: gconstant.MakeBool(e.Name == "true"),
  877. },
  878. }, []shaderir.Type{{Main: shaderir.Bool}}, nil, true
  879. }
  880. cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name))
  881. case *ast.ParenExpr:
  882. return cs.parseExpr(block, fname, e.X, markLocalVariableUsed)
  883. case *ast.SelectorExpr:
  884. exprs, types, stmts, ok := cs.parseExpr(block, fname, e.X, true)
  885. if !ok {
  886. return nil, nil, nil, false
  887. }
  888. if len(exprs) != 1 {
  889. cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a selector: %s", e.X))
  890. return nil, nil, nil, false
  891. }
  892. if len(types) == 0 || !isValidSwizzling(e.Sel.Name, types[0]) {
  893. cs.addError(e.Pos(), fmt.Sprintf("unexpected swizzling: %s", e.Sel.Name))
  894. return nil, nil, nil, false
  895. }
  896. var t shaderir.Type
  897. switch types[0].Main {
  898. case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
  899. switch len(e.Sel.Name) {
  900. case 1:
  901. t.Main = shaderir.Float
  902. case 2:
  903. t.Main = shaderir.Vec2
  904. case 3:
  905. t.Main = shaderir.Vec3
  906. case 4:
  907. t.Main = shaderir.Vec4
  908. }
  909. case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
  910. switch len(e.Sel.Name) {
  911. case 1:
  912. t.Main = shaderir.Int
  913. case 2:
  914. t.Main = shaderir.IVec2
  915. case 3:
  916. t.Main = shaderir.IVec3
  917. case 4:
  918. t.Main = shaderir.IVec4
  919. }
  920. }
  921. if t.Equal(&shaderir.Type{}) {
  922. cs.addError(e.Pos(), fmt.Sprintf("unexpected swizzling: %s", e.Sel.Name))
  923. return nil, nil, nil, false
  924. }
  925. return []shaderir.Expr{
  926. {
  927. Type: shaderir.FieldSelector,
  928. Exprs: []shaderir.Expr{
  929. exprs[0],
  930. {
  931. Type: shaderir.SwizzlingExpr,
  932. Swizzling: e.Sel.Name,
  933. },
  934. },
  935. },
  936. }, []shaderir.Type{t}, stmts, true
  937. case *ast.UnaryExpr:
  938. exprs, ts, stmts, ok := cs.parseExpr(block, fname, e.X, markLocalVariableUsed)
  939. if !ok {
  940. return nil, nil, nil, false
  941. }
  942. if len(exprs) != 1 {
  943. cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a unary operator: %s", e.X))
  944. return nil, nil, nil, false
  945. }
  946. if len(ts) == 0 {
  947. cs.addError(e.Pos(), fmt.Sprintf("unexpected unary operator: %s", e.X))
  948. return nil, nil, nil, false
  949. }
  950. if exprs[0].Const != nil {
  951. v := gconstant.UnaryOp(e.Op, exprs[0].Const, 0)
  952. // Use the original type as it is.
  953. // Keep the type untyped if the original expression is untyped (#2705).
  954. return []shaderir.Expr{
  955. {
  956. Type: shaderir.NumberExpr,
  957. Const: v,
  958. },
  959. }, ts[:1], stmts, true
  960. }
  961. var op shaderir.Op
  962. switch e.Op {
  963. case token.ADD:
  964. op = shaderir.Add
  965. case token.SUB:
  966. op = shaderir.Sub
  967. case token.NOT:
  968. op = shaderir.NotOp
  969. default:
  970. cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
  971. return nil, nil, nil, false
  972. }
  973. return []shaderir.Expr{
  974. {
  975. Type: shaderir.Unary,
  976. Op: op,
  977. Exprs: exprs,
  978. },
  979. }, ts[:1], stmts, true
  980. case *ast.CompositeLit:
  981. t, ok := cs.parseType(block, fname, e.Type)
  982. if !ok {
  983. return nil, nil, nil, false
  984. }
  985. if t.Main != shaderir.Array {
  986. cs.addError(e.Pos(), fmt.Sprintf("invalid composite literal type %s", t.String()))
  987. return nil, nil, nil, false
  988. }
  989. if t.Main == shaderir.Array {
  990. if t.Length == -1 {
  991. t.Length = len(e.Elts)
  992. } else if t.Length < len(e.Elts) {
  993. // KeyValueExpr is not supported yet. Just compare the length.
  994. cs.addError(e.Pos(), fmt.Sprintf("too many values in %s literal", t.String()))
  995. return nil, nil, nil, false
  996. }
  997. }
  998. idx := block.totalLocalVariableCount()
  999. block.vars = append(block.vars, variable{
  1000. typ: t,
  1001. })
  1002. var stmts []shaderir.Stmt
  1003. for i, e := range e.Elts {
  1004. exprs, _, ss, ok := cs.parseExpr(block, fname, e, markLocalVariableUsed)
  1005. if !ok {
  1006. return nil, nil, nil, false
  1007. }
  1008. if len(exprs) != 1 {
  1009. cs.addError(e.Pos(), "multiple-value context is not available at a composite literal")
  1010. return nil, nil, nil, false
  1011. }
  1012. expr := exprs[0]
  1013. if expr.Const != nil {
  1014. switch t.Sub[0].Main {
  1015. case shaderir.Bool:
  1016. if expr.Const.Kind() != gconstant.Bool {
  1017. cs.addError(e.Pos(), fmt.Sprintf("cannot %s to type bool", expr.Const.String()))
  1018. }
  1019. case shaderir.Int:
  1020. if !canTruncateToInteger(expr.Const) {
  1021. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", expr.Const.String()))
  1022. return nil, nil, nil, false
  1023. }
  1024. expr.Const = gconstant.ToInt(expr.Const)
  1025. case shaderir.Float:
  1026. if !canTruncateToFloat(expr.Const) {
  1027. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to float", expr.Const.String()))
  1028. return nil, nil, nil, false
  1029. }
  1030. expr.Const = gconstant.ToFloat(expr.Const)
  1031. default:
  1032. cs.addError(e.Pos(), fmt.Sprintf("constant %s cannot be used for the array type %s", expr.Const.String(), t.String()))
  1033. return nil, nil, nil, false
  1034. }
  1035. }
  1036. stmts = append(stmts, ss...)
  1037. stmts = append(stmts, shaderir.Stmt{
  1038. Type: shaderir.Assign,
  1039. Exprs: []shaderir.Expr{
  1040. {
  1041. Type: shaderir.Index,
  1042. Exprs: []shaderir.Expr{
  1043. {
  1044. Type: shaderir.LocalVariable,
  1045. Index: idx,
  1046. },
  1047. {
  1048. Type: shaderir.NumberExpr,
  1049. Const: gconstant.MakeInt64(int64(i)),
  1050. },
  1051. },
  1052. },
  1053. expr,
  1054. },
  1055. })
  1056. }
  1057. return []shaderir.Expr{
  1058. {
  1059. Type: shaderir.LocalVariable,
  1060. Index: idx,
  1061. },
  1062. }, []shaderir.Type{t}, stmts, true
  1063. case *ast.IndexExpr:
  1064. var stmts []shaderir.Stmt
  1065. // Parse the index first
  1066. exprs, _, ss, ok := cs.parseExpr(block, fname, e.Index, true)
  1067. if !ok {
  1068. return nil, nil, nil, false
  1069. }
  1070. stmts = append(stmts, ss...)
  1071. if len(exprs) != 1 {
  1072. cs.addError(e.Pos(), "multiple-value context is not available at an index expression")
  1073. return nil, nil, nil, false
  1074. }
  1075. idx := exprs[0]
  1076. if idx.Const != nil {
  1077. if !canTruncateToInteger(idx.Const) {
  1078. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", idx.Const.String()))
  1079. return nil, nil, nil, false
  1080. }
  1081. }
  1082. exprs, ts, ss, ok := cs.parseExpr(block, fname, e.X, markLocalVariableUsed)
  1083. if !ok {
  1084. return nil, nil, nil, false
  1085. }
  1086. stmts = append(stmts, ss...)
  1087. if len(exprs) != 1 {
  1088. cs.addError(e.Pos(), "multiple-value context is not available at an index expression")
  1089. return nil, nil, nil, false
  1090. }
  1091. if len(ts) == 0 {
  1092. cs.addError(e.Pos(), "unexpected index expression")
  1093. return nil, nil, nil, false
  1094. }
  1095. x := exprs[0]
  1096. t := ts[0]
  1097. // Check the length only when the index is a constant.
  1098. if idx.Const != nil {
  1099. var length int
  1100. switch {
  1101. case t.Main == shaderir.Array:
  1102. length = t.Length
  1103. case t.IsFloatVector() || t.IsIntVector():
  1104. length = t.VectorElementCount()
  1105. case t.IsMatrix():
  1106. length = t.MatrixSize()
  1107. default:
  1108. cs.addError(e.Pos(), fmt.Sprintf("index operator cannot be applied to the type %s", t.String()))
  1109. return nil, nil, nil, false
  1110. }
  1111. v, ok := gconstant.Int64Val(gconstant.ToInt(idx.Const))
  1112. if !ok {
  1113. cs.addError(e.Pos(), fmt.Sprintf("constant %s cannot be used as an index", idx.Const.String()))
  1114. return nil, nil, nil, false
  1115. }
  1116. if v < 0 || int(v) >= length {
  1117. cs.addError(e.Pos(), fmt.Sprintf("index out of range: %d", v))
  1118. return nil, nil, nil, false
  1119. }
  1120. }
  1121. var typ shaderir.Type
  1122. switch t.Main {
  1123. case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
  1124. typ = shaderir.Type{Main: shaderir.Float}
  1125. case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
  1126. typ = shaderir.Type{Main: shaderir.Int}
  1127. case shaderir.Mat2:
  1128. typ = shaderir.Type{Main: shaderir.Vec2}
  1129. case shaderir.Mat3:
  1130. typ = shaderir.Type{Main: shaderir.Vec3}
  1131. case shaderir.Mat4:
  1132. typ = shaderir.Type{Main: shaderir.Vec4}
  1133. case shaderir.Array:
  1134. typ = t.Sub[0]
  1135. default:
  1136. cs.addError(e.Pos(), fmt.Sprintf("index operator cannot be applied to the type %s", t.String()))
  1137. return nil, nil, nil, false
  1138. }
  1139. return []shaderir.Expr{
  1140. {
  1141. Type: shaderir.Index,
  1142. Exprs: []shaderir.Expr{
  1143. x,
  1144. idx,
  1145. },
  1146. },
  1147. }, []shaderir.Type{typ}, stmts, true
  1148. default:
  1149. cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
  1150. }
  1151. return nil, nil, nil, false
  1152. }
  1153. func isValidSwizzling(swizzling string, t shaderir.Type) bool {
  1154. if !shaderir.IsValidSwizzling(swizzling) {
  1155. return false
  1156. }
  1157. switch t.Main {
  1158. case shaderir.Vec2, shaderir.IVec2:
  1159. return !strings.ContainsAny(swizzling, "zwbapq")
  1160. case shaderir.Vec3, shaderir.IVec3:
  1161. return !strings.ContainsAny(swizzling, "waq")
  1162. case shaderir.Vec4, shaderir.IVec4:
  1163. return true
  1164. default:
  1165. return false
  1166. }
  1167. }
  1168. func resolveConstKind(exprs []shaderir.Expr, ts []shaderir.Type) (kind gconstant.Kind, allConsts bool) {
  1169. if len(exprs) != len(ts) {
  1170. panic("not reached")
  1171. }
  1172. allConsts = true
  1173. for _, expr := range exprs {
  1174. if expr.Const == nil {
  1175. allConsts = false
  1176. }
  1177. }
  1178. if !allConsts {
  1179. for _, t := range ts {
  1180. if t.Main == shaderir.None {
  1181. continue
  1182. }
  1183. if t.Main == shaderir.Float {
  1184. return gconstant.Float, false
  1185. }
  1186. if t.Main == shaderir.Int {
  1187. return gconstant.Int, false
  1188. }
  1189. return gconstant.Unknown, false
  1190. }
  1191. }
  1192. kind = gconstant.Unknown
  1193. for _, t := range ts {
  1194. switch t.Main {
  1195. case shaderir.None:
  1196. continue
  1197. case shaderir.Int:
  1198. switch kind {
  1199. case gconstant.Unknown:
  1200. kind = gconstant.Int
  1201. case gconstant.Int:
  1202. case gconstant.Float:
  1203. return gconstant.Unknown, true
  1204. }
  1205. case shaderir.Float:
  1206. switch kind {
  1207. case gconstant.Unknown:
  1208. kind = gconstant.Float
  1209. case gconstant.Int:
  1210. return gconstant.Unknown, true
  1211. case gconstant.Float:
  1212. }
  1213. }
  1214. }
  1215. if kind != gconstant.Unknown {
  1216. return kind, true
  1217. }
  1218. // Prefer floats over integers for non-typed constant values.
  1219. // For example, max(1.0, 1) should return a float value.
  1220. for _, expr := range exprs {
  1221. if expr.Const.Kind() == gconstant.Float {
  1222. return gconstant.Float, true
  1223. }
  1224. }
  1225. return gconstant.Int, true
  1226. }