type.go (3002B)
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 15 package shader 16 17 import ( 18 "fmt" 19 "go/ast" 20 gconstant "go/constant" 21 22 "github.com/hajimehoshi/ebiten/v2/internal/shaderir" 23 ) 24 25 func (cs *compileState) parseType(block *block, expr ast.Expr) (shaderir.Type, bool) { 26 switch t := expr.(type) { 27 case *ast.Ident: 28 switch t.Name { 29 case "bool": 30 return shaderir.Type{Main: shaderir.Bool}, true 31 case "int": 32 return shaderir.Type{Main: shaderir.Int}, true 33 case "float": 34 return shaderir.Type{Main: shaderir.Float}, true 35 case "vec2": 36 return shaderir.Type{Main: shaderir.Vec2}, true 37 case "vec3": 38 return shaderir.Type{Main: shaderir.Vec3}, true 39 case "vec4": 40 return shaderir.Type{Main: shaderir.Vec4}, true 41 case "mat2": 42 return shaderir.Type{Main: shaderir.Mat2}, true 43 case "mat3": 44 return shaderir.Type{Main: shaderir.Mat3}, true 45 case "mat4": 46 return shaderir.Type{Main: shaderir.Mat4}, true 47 default: 48 cs.addError(t.Pos(), fmt.Sprintf("unexpected type: %s", t.Name)) 49 return shaderir.Type{}, false 50 } 51 case *ast.ArrayType: 52 if t.Len == nil { 53 cs.addError(t.Pos(), fmt.Sprintf("array length must be specified")) 54 return shaderir.Type{}, false 55 } 56 var length int 57 if _, ok := t.Len.(*ast.Ellipsis); ok { 58 length = -1 // Determine the length later. 59 } else { 60 exprs, _, _, ok := cs.parseExpr(block, t.Len, true) 61 if !ok { 62 return shaderir.Type{}, false 63 } 64 if len(exprs) != 1 { 65 cs.addError(t.Pos(), fmt.Sprintf("invalid length of array")) 66 return shaderir.Type{}, false 67 } 68 if exprs[0].Type != shaderir.NumberExpr { 69 cs.addError(t.Pos(), fmt.Sprintf("length of array must be a constant number")) 70 return shaderir.Type{}, false 71 } 72 l, ok := gconstant.Int64Val(exprs[0].Const) 73 if !ok { 74 cs.addError(t.Pos(), fmt.Sprintf("length of array must be an integer")) 75 return shaderir.Type{}, false 76 } 77 length = int(l) 78 } 79 80 elm, ok := cs.parseType(block, t.Elt) 81 if !ok { 82 return shaderir.Type{}, false 83 } 84 if elm.Main == shaderir.Array { 85 cs.addError(t.Pos(), fmt.Sprintf("array of array is forbidden")) 86 return shaderir.Type{}, false 87 } 88 return shaderir.Type{ 89 Main: shaderir.Array, 90 Sub: []shaderir.Type{elm}, 91 Length: length, 92 }, true 93 case *ast.StructType: 94 cs.addError(t.Pos(), "struct is not implemented") 95 return shaderir.Type{}, false 96 default: 97 cs.addError(t.Pos(), fmt.Sprintf("unepxected type: %v", t)) 98 return shaderir.Type{}, false 99 } 100 }