From 2dc6cbe51aae26483a8bd7da3cf943d2e23385df Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 29 Jul 2020 12:02:07 +0900 Subject: [PATCH] shader: Make parseType return a boolean value indicating ok --- internal/shader/shader.go | 27 ++++++++++++++++++----- internal/shader/type.go | 45 +++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/internal/shader/shader.go b/internal/shader/shader.go index e8e8a4b46..5f963ec38 100644 --- a/internal/shader/shader.go +++ b/internal/shader/shader.go @@ -260,7 +260,10 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) ([]shaderir.Stmt, bool) // TODO: Parse other types for _, s := range d.Specs { s := s.(*ast.TypeSpec) - t := cs.parseType(b, s.Type) + t, ok := cs.parseType(b, s.Type) + if !ok { + return nil, false + } b.types = append(b.types, typ{ name: s.Name.Name, ir: t, @@ -385,7 +388,11 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl var declt shaderir.Type if vs.Type != nil { - declt = s.parseType(block, vs.Type) + var ok bool + declt, ok = s.parseType(block, vs.Type) + if !ok { + return nil, nil, nil, false + } } var ( @@ -483,7 +490,11 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) []constant { var t shaderir.Type if vs.Type != nil { - t = s.parseType(block, vs.Type) + var ok bool + t, ok = s.parseType(block, vs.Type) + if !ok { + return nil + } } var cs []constant @@ -499,7 +510,10 @@ func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) []constant func (cs *compileState) parseFuncParams(block *block, d *ast.FuncDecl) (in, out []variable) { for _, f := range d.Type.Params.List { - t := cs.parseType(block, f.Type) + t, ok := cs.parseType(block, f.Type) + if !ok { + return + } for _, n := range f.Names { in = append(in, variable{ name: n.Name, @@ -513,7 +527,10 @@ func (cs *compileState) parseFuncParams(block *block, d *ast.FuncDecl) (in, out } for _, f := range d.Type.Results.List { - t := cs.parseType(block, f.Type) + t, ok := cs.parseType(block, f.Type) + if !ok { + return + } if len(f.Names) == 0 { out = append(out, variable{ name: "", diff --git a/internal/shader/type.go b/internal/shader/type.go index 036d983f9..c3b8c3c06 100644 --- a/internal/shader/type.go +++ b/internal/shader/type.go @@ -22,72 +22,75 @@ import ( "github.com/hajimehoshi/ebiten/internal/shaderir" ) -func (cs *compileState) parseType(block *block, expr ast.Expr) shaderir.Type { +func (cs *compileState) parseType(block *block, expr ast.Expr) (shaderir.Type, bool) { switch t := expr.(type) { case *ast.Ident: switch t.Name { case "bool": - return shaderir.Type{Main: shaderir.Bool} + return shaderir.Type{Main: shaderir.Bool}, true case "int": - return shaderir.Type{Main: shaderir.Int} + return shaderir.Type{Main: shaderir.Int}, true case "float": - return shaderir.Type{Main: shaderir.Float} + return shaderir.Type{Main: shaderir.Float}, true case "vec2": - return shaderir.Type{Main: shaderir.Vec2} + return shaderir.Type{Main: shaderir.Vec2}, true case "vec3": - return shaderir.Type{Main: shaderir.Vec3} + return shaderir.Type{Main: shaderir.Vec3}, true case "vec4": - return shaderir.Type{Main: shaderir.Vec4} + return shaderir.Type{Main: shaderir.Vec4}, true case "mat2": - return shaderir.Type{Main: shaderir.Mat2} + return shaderir.Type{Main: shaderir.Mat2}, true case "mat3": - return shaderir.Type{Main: shaderir.Mat3} + return shaderir.Type{Main: shaderir.Mat3}, true case "mat4": - return shaderir.Type{Main: shaderir.Mat4} + return shaderir.Type{Main: shaderir.Mat4}, true default: cs.addError(t.Pos(), fmt.Sprintf("unexpected type: %s", t.Name)) - return shaderir.Type{} + return shaderir.Type{}, false } case *ast.ArrayType: if t.Len == nil { cs.addError(t.Pos(), fmt.Sprintf("array length must be specified")) - return shaderir.Type{} + return shaderir.Type{}, false } // TODO: Parse ellipsis exprs, _, _, ok := cs.parseExpr(block, t.Len) if !ok { - return shaderir.Type{} + return shaderir.Type{}, false } if len(exprs) != 1 { cs.addError(t.Pos(), fmt.Sprintf("invalid length of array")) - return shaderir.Type{} + return shaderir.Type{}, false } if exprs[0].Type != shaderir.NumberExpr { cs.addError(t.Pos(), fmt.Sprintf("length of array must be a constant number")) - return shaderir.Type{} + return shaderir.Type{}, false } len, ok := gconstant.Int64Val(exprs[0].Const) if !ok { cs.addError(t.Pos(), fmt.Sprintf("length of array must be an integer")) - return shaderir.Type{} + return shaderir.Type{}, false } - elm := cs.parseType(block, t.Elt) + elm, ok := cs.parseType(block, t.Elt) + if !ok { + return shaderir.Type{}, false + } if elm.Main == shaderir.Array { cs.addError(t.Pos(), fmt.Sprintf("array of array is forbidden")) - return shaderir.Type{} + return shaderir.Type{}, false } return shaderir.Type{ Main: shaderir.Array, Sub: []shaderir.Type{elm}, Length: int(len), - } + }, true case *ast.StructType: cs.addError(t.Pos(), "struct is not implemented") - return shaderir.Type{} + return shaderir.Type{}, false default: cs.addError(t.Pos(), fmt.Sprintf("unepxected type: %v", t)) - return shaderir.Type{} + return shaderir.Type{}, false } }