zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

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 }