expr.go 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  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 && t.Length == -1 {
  990. t.Length = len(e.Elts)
  991. }
  992. idx := block.totalLocalVariableCount()
  993. block.vars = append(block.vars, variable{
  994. typ: t,
  995. })
  996. var stmts []shaderir.Stmt
  997. for i, e := range e.Elts {
  998. exprs, _, ss, ok := cs.parseExpr(block, fname, e, markLocalVariableUsed)
  999. if !ok {
  1000. return nil, nil, nil, false
  1001. }
  1002. if len(exprs) != 1 {
  1003. cs.addError(e.Pos(), "multiple-value context is not available at a composite literal")
  1004. return nil, nil, nil, false
  1005. }
  1006. expr := exprs[0]
  1007. if expr.Const != nil {
  1008. switch t.Sub[0].Main {
  1009. case shaderir.Bool:
  1010. if expr.Const.Kind() != gconstant.Bool {
  1011. cs.addError(e.Pos(), fmt.Sprintf("cannot %s to type bool", expr.Const.String()))
  1012. }
  1013. case shaderir.Int:
  1014. if !canTruncateToInteger(expr.Const) {
  1015. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", expr.Const.String()))
  1016. return nil, nil, nil, false
  1017. }
  1018. expr.Const = gconstant.ToInt(expr.Const)
  1019. case shaderir.Float:
  1020. if !canTruncateToFloat(expr.Const) {
  1021. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to float", expr.Const.String()))
  1022. return nil, nil, nil, false
  1023. }
  1024. expr.Const = gconstant.ToFloat(expr.Const)
  1025. default:
  1026. cs.addError(e.Pos(), fmt.Sprintf("constant %s cannot be used for the array type %s", expr.Const.String(), t.String()))
  1027. return nil, nil, nil, false
  1028. }
  1029. }
  1030. stmts = append(stmts, ss...)
  1031. stmts = append(stmts, shaderir.Stmt{
  1032. Type: shaderir.Assign,
  1033. Exprs: []shaderir.Expr{
  1034. {
  1035. Type: shaderir.Index,
  1036. Exprs: []shaderir.Expr{
  1037. {
  1038. Type: shaderir.LocalVariable,
  1039. Index: idx,
  1040. },
  1041. {
  1042. Type: shaderir.NumberExpr,
  1043. Const: gconstant.MakeInt64(int64(i)),
  1044. },
  1045. },
  1046. },
  1047. expr,
  1048. },
  1049. })
  1050. }
  1051. return []shaderir.Expr{
  1052. {
  1053. Type: shaderir.LocalVariable,
  1054. Index: idx,
  1055. },
  1056. }, []shaderir.Type{t}, stmts, true
  1057. case *ast.IndexExpr:
  1058. var stmts []shaderir.Stmt
  1059. // Parse the index first
  1060. exprs, _, ss, ok := cs.parseExpr(block, fname, e.Index, true)
  1061. if !ok {
  1062. return nil, nil, nil, false
  1063. }
  1064. stmts = append(stmts, ss...)
  1065. if len(exprs) != 1 {
  1066. cs.addError(e.Pos(), "multiple-value context is not available at an index expression")
  1067. return nil, nil, nil, false
  1068. }
  1069. idx := exprs[0]
  1070. if idx.Const != nil {
  1071. if !canTruncateToInteger(idx.Const) {
  1072. cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", idx.Const.String()))
  1073. return nil, nil, nil, false
  1074. }
  1075. }
  1076. exprs, ts, ss, ok := cs.parseExpr(block, fname, e.X, markLocalVariableUsed)
  1077. if !ok {
  1078. return nil, nil, nil, false
  1079. }
  1080. stmts = append(stmts, ss...)
  1081. if len(exprs) != 1 {
  1082. cs.addError(e.Pos(), "multiple-value context is not available at an index expression")
  1083. return nil, nil, nil, false
  1084. }
  1085. if len(ts) == 0 {
  1086. cs.addError(e.Pos(), "unexpected index expression")
  1087. return nil, nil, nil, false
  1088. }
  1089. x := exprs[0]
  1090. t := ts[0]
  1091. var typ shaderir.Type
  1092. switch t.Main {
  1093. case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
  1094. typ = shaderir.Type{Main: shaderir.Float}
  1095. case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
  1096. typ = shaderir.Type{Main: shaderir.Int}
  1097. case shaderir.Mat2:
  1098. typ = shaderir.Type{Main: shaderir.Vec2}
  1099. case shaderir.Mat3:
  1100. typ = shaderir.Type{Main: shaderir.Vec3}
  1101. case shaderir.Mat4:
  1102. typ = shaderir.Type{Main: shaderir.Vec4}
  1103. case shaderir.Array:
  1104. typ = t.Sub[0]
  1105. default:
  1106. cs.addError(e.Pos(), fmt.Sprintf("index operator cannot be applied to the type %s", t.String()))
  1107. return nil, nil, nil, false
  1108. }
  1109. return []shaderir.Expr{
  1110. {
  1111. Type: shaderir.Index,
  1112. Exprs: []shaderir.Expr{
  1113. x,
  1114. idx,
  1115. },
  1116. },
  1117. }, []shaderir.Type{typ}, stmts, true
  1118. default:
  1119. cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
  1120. }
  1121. return nil, nil, nil, false
  1122. }
  1123. func isValidSwizzling(swizzling string, t shaderir.Type) bool {
  1124. if !shaderir.IsValidSwizzling(swizzling) {
  1125. return false
  1126. }
  1127. switch t.Main {
  1128. case shaderir.Vec2, shaderir.IVec2:
  1129. return !strings.ContainsAny(swizzling, "zwbapq")
  1130. case shaderir.Vec3, shaderir.IVec3:
  1131. return !strings.ContainsAny(swizzling, "waq")
  1132. case shaderir.Vec4, shaderir.IVec4:
  1133. return true
  1134. default:
  1135. return false
  1136. }
  1137. }
  1138. func resolveConstKind(exprs []shaderir.Expr, ts []shaderir.Type) (kind gconstant.Kind, allConsts bool) {
  1139. if len(exprs) != len(ts) {
  1140. panic("not reached")
  1141. }
  1142. allConsts = true
  1143. for _, expr := range exprs {
  1144. if expr.Const == nil {
  1145. allConsts = false
  1146. }
  1147. }
  1148. if !allConsts {
  1149. for _, t := range ts {
  1150. if t.Main == shaderir.None {
  1151. continue
  1152. }
  1153. if t.Main == shaderir.Float {
  1154. return gconstant.Float, false
  1155. }
  1156. if t.Main == shaderir.Int {
  1157. return gconstant.Int, false
  1158. }
  1159. return gconstant.Unknown, false
  1160. }
  1161. }
  1162. kind = gconstant.Unknown
  1163. for _, t := range ts {
  1164. switch t.Main {
  1165. case shaderir.None:
  1166. continue
  1167. case shaderir.Int:
  1168. switch kind {
  1169. case gconstant.Unknown:
  1170. kind = gconstant.Int
  1171. case gconstant.Int:
  1172. case gconstant.Float:
  1173. return gconstant.Unknown, true
  1174. }
  1175. case shaderir.Float:
  1176. switch kind {
  1177. case gconstant.Unknown:
  1178. kind = gconstant.Float
  1179. case gconstant.Int:
  1180. return gconstant.Unknown, true
  1181. case gconstant.Float:
  1182. }
  1183. }
  1184. }
  1185. if kind != gconstant.Unknown {
  1186. return kind, true
  1187. }
  1188. // Prefer floats over integers for non-typed constant values.
  1189. // For example, max(1.0, 1) should return a float value.
  1190. for _, expr := range exprs {
  1191. if expr.Const.Kind() == gconstant.Float {
  1192. return gconstant.Float, true
  1193. }
  1194. }
  1195. return gconstant.Int, true
  1196. }