shader: Make parseType return a boolean value indicating ok

This commit is contained in:
Hajime Hoshi 2020-07-29 12:02:07 +09:00
parent d9c54bc0d0
commit 2dc6cbe51a
2 changed files with 46 additions and 26 deletions

View File

@ -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: "",

View File

@ -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
}
}