shader: Use shaderir.Type instead of typ struct

This commit is contained in:
Hajime Hoshi 2020-06-07 19:36:38 +09:00
parent 63677e0e50
commit 2ffbd49602
2 changed files with 48 additions and 70 deletions

View File

@ -26,12 +26,12 @@ import (
type variable struct { type variable struct {
name string name string
typ typ typ shaderir.Type
} }
type constant struct { type constant struct {
name string name string
typ typ typ shaderir.Type
init ast.Expr init ast.Expr
} }
@ -69,6 +69,11 @@ func (cs *compileState) findUniformVariable(name string) (int, bool) {
return 0, false return 0, false
} }
type typ struct {
name string
ir shaderir.Type
}
type block struct { type block struct {
types []typ types []typ
vars []variable vars []variable
@ -179,8 +184,10 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
for _, s := range d.Specs { for _, s := range d.Specs {
s := s.(*ast.TypeSpec) s := s.(*ast.TypeSpec)
t := cs.parseType(s.Type) t := cs.parseType(s.Type)
t.name = s.Name.Name b.types = append(b.types, typ{
b.types = append(b.types, t) name: s.Name.Name,
ir: t,
})
} }
case token.CONST: case token.CONST:
for _, s := range d.Specs { for _, s := range d.Specs {
@ -202,13 +209,13 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
} }
} }
cs.uniforms = append(cs.uniforms, v.name) cs.uniforms = append(cs.uniforms, v.name)
cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir) cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ)
} }
continue continue
} }
for i, v := range vs { for i, v := range vs {
b.vars = append(b.vars, v) b.vars = append(b.vars, v)
b.ir.LocalVars = append(b.ir.LocalVars, v.typ.ir) b.ir.LocalVars = append(b.ir.LocalVars, v.typ)
if inits[i] != nil { if inits[i] != nil {
b.ir.Stmts = append(b.ir.Stmts, shaderir.Stmt{ b.ir.Stmts = append(b.ir.Stmts, shaderir.Stmt{
Type: shaderir.Assign, Type: shaderir.Assign,
@ -248,7 +255,7 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
} }
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr, []shaderir.Stmt) { func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr, []shaderir.Stmt) {
var t typ var t shaderir.Type
if vs.Type != nil { if vs.Type != nil {
t = s.parseType(vs.Type) t = s.parseType(vs.Type)
} }
@ -260,7 +267,7 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
var init ast.Expr var init ast.Expr
if len(vs.Values) > 0 { if len(vs.Values) > 0 {
init = vs.Values[i] init = vs.Values[i]
if t.ir.Main == shaderir.None { if t.Main == shaderir.None {
t = s.detectType(block, init) t = s.detectType(block, init)
} }
} }
@ -282,7 +289,7 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
} }
func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant { func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant {
var t typ var t shaderir.Type
if vs.Type != nil { if vs.Type != nil {
t = s.parseType(vs.Type) t = s.parseType(vs.Type)
} }
@ -318,7 +325,7 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) function {
name: n.Name, name: n.Name,
typ: t, typ: t,
}) })
inT = append(inT, t.ir) inT = append(inT, t)
} }
} }
@ -333,14 +340,14 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) function {
name: "", name: "",
typ: t, typ: t,
}) })
outT = append(outT, t.ir) outT = append(outT, t)
} else { } else {
for _, n := range f.Names { for _, n := range f.Names {
outParams = append(outParams, variable{ outParams = append(outParams, variable{
name: n.Name, name: n.Name,
typ: t, typ: t,
}) })
outT = append(outT, t.ir) outT = append(outT, t)
} }
} }
} }
@ -448,7 +455,7 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
} }
v.typ = cs.detectType(block, l.Rhs[i]) v.typ = cs.detectType(block, l.Rhs[i])
block.vars = append(block.vars, v) block.vars = append(block.vars, v)
block.ir.LocalVars = append(block.ir.LocalVars, v.typ.ir) block.ir.LocalVars = append(block.ir.LocalVars, v.typ)
// Prase RHS first for the order of the statements. // Prase RHS first for the order of the statements.
rhs, stmts := cs.parseExpr(block, l.Rhs[i]) rhs, stmts := cs.parseExpr(block, l.Rhs[i])
@ -510,43 +517,39 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
return block return block
} }
func (s *compileState) detectType(b *block, expr ast.Expr) typ { func (s *compileState) detectType(b *block, expr ast.Expr) shaderir.Type {
switch e := expr.(type) { switch e := expr.(type) {
case *ast.BasicLit: case *ast.BasicLit:
switch e.Kind { switch e.Kind {
case token.FLOAT: case token.FLOAT:
return typ{ return shaderir.Type{Main: shaderir.Float}
ir: shaderir.Type{Main: shaderir.Float},
}
case token.INT: case token.INT:
return typ{ return shaderir.Type{Main: shaderir.Int}
ir: shaderir.Type{Main: shaderir.Int},
}
} }
s.addError(expr.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value)) s.addError(expr.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
return typ{} return shaderir.Type{}
case *ast.CallExpr: case *ast.CallExpr:
n := e.Fun.(*ast.Ident).Name n := e.Fun.(*ast.Ident).Name
f, ok := shaderir.ParseBuiltinFunc(n) f, ok := shaderir.ParseBuiltinFunc(n)
if ok { if ok {
switch f { switch f {
case shaderir.Vec2F: case shaderir.Vec2F:
return typ{ir: shaderir.Type{Main: shaderir.Vec2}} return shaderir.Type{Main: shaderir.Vec2}
case shaderir.Vec3F: case shaderir.Vec3F:
return typ{ir: shaderir.Type{Main: shaderir.Vec3}} return shaderir.Type{Main: shaderir.Vec3}
case shaderir.Vec4F: case shaderir.Vec4F:
return typ{ir: shaderir.Type{Main: shaderir.Vec4}} return shaderir.Type{Main: shaderir.Vec4}
case shaderir.Mat2F: case shaderir.Mat2F:
return typ{ir: shaderir.Type{Main: shaderir.Mat2}} return shaderir.Type{Main: shaderir.Mat2}
case shaderir.Mat3F: case shaderir.Mat3F:
return typ{ir: shaderir.Type{Main: shaderir.Mat3}} return shaderir.Type{Main: shaderir.Mat3}
case shaderir.Mat4F: case shaderir.Mat4F:
return typ{ir: shaderir.Type{Main: shaderir.Mat4}} return shaderir.Type{Main: shaderir.Mat4}
// TODO: Add more functions // TODO: Add more functions
} }
} }
s.addError(expr.Pos(), fmt.Sprintf("unexpected call: %s", n)) s.addError(expr.Pos(), fmt.Sprintf("unexpected call: %s", n))
return typ{} return shaderir.Type{}
case *ast.CompositeLit: case *ast.CompositeLit:
return s.parseType(e.Type) return s.parseType(e.Type)
case *ast.Ident: case *ast.Ident:
@ -559,7 +562,7 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ {
if b == &s.global { if b == &s.global {
for i, v := range s.uniforms { for i, v := range s.uniforms {
if v == n { if v == n {
return typ{ir: s.ir.Uniforms[i]} return s.ir.Uniforms[i]
} }
} }
} }
@ -567,12 +570,12 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ {
return s.detectType(b.outer, e) return s.detectType(b.outer, e)
} }
s.addError(expr.Pos(), fmt.Sprintf("unexpected identifier: %s", n)) s.addError(expr.Pos(), fmt.Sprintf("unexpected identifier: %s", n))
return typ{} return shaderir.Type{}
//case *ast.SelectorExpr: //case *ast.SelectorExpr:
//return fmt.Sprintf("%s.%s", dumpExpr(e.X), dumpExpr(e.Sel)) //return fmt.Sprintf("%s.%s", dumpExpr(e.X), dumpExpr(e.Sel))
default: default:
s.addError(expr.Pos(), fmt.Sprintf("detecting type not implemented: %#v", expr)) s.addError(expr.Pos(), fmt.Sprintf("detecting type not implemented: %#v", expr))
return typ{} return shaderir.Type{}
} }
} }

View File

@ -23,64 +23,39 @@ import (
// TODO: What about array types? // TODO: What about array types?
type typ struct { func (cs *compileState) parseType(expr ast.Expr) shaderir.Type {
ir shaderir.Type
name string
}
func (cs *compileState) parseType(expr ast.Expr) typ {
switch t := expr.(type) { switch t := expr.(type) {
case *ast.Ident: case *ast.Ident:
switch t.Name { switch t.Name {
case "bool": case "bool":
return typ{ return shaderir.Type{Main: shaderir.Bool}
ir: shaderir.Type{Main: shaderir.Bool},
}
case "int": case "int":
return typ{ return shaderir.Type{Main: shaderir.Int}
ir: shaderir.Type{Main: shaderir.Int},
}
case "float": case "float":
return typ{ return shaderir.Type{Main: shaderir.Float}
ir: shaderir.Type{Main: shaderir.Float},
}
case "vec2": case "vec2":
return typ{ return shaderir.Type{Main: shaderir.Vec2}
ir: shaderir.Type{Main: shaderir.Vec2},
}
case "vec3": case "vec3":
return typ{ return shaderir.Type{Main: shaderir.Vec3}
ir: shaderir.Type{Main: shaderir.Vec3},
}
case "vec4": case "vec4":
return typ{ return shaderir.Type{Main: shaderir.Vec4}
ir: shaderir.Type{Main: shaderir.Vec4},
}
case "mat2": case "mat2":
return typ{ return shaderir.Type{Main: shaderir.Mat2}
ir: shaderir.Type{Main: shaderir.Mat2},
}
case "mat3": case "mat3":
return typ{ return shaderir.Type{Main: shaderir.Mat3}
ir: shaderir.Type{Main: shaderir.Mat3},
}
case "mat4": case "mat4":
return typ{ return shaderir.Type{Main: shaderir.Mat4}
ir: shaderir.Type{Main: shaderir.Mat4},
}
case "texture2d": case "texture2d":
return typ{ return shaderir.Type{Main: shaderir.Texture2D}
ir: shaderir.Type{Main: shaderir.Texture2D},
}
default: default:
cs.addError(t.Pos(), fmt.Sprintf("unexpected type: %s", t.Name)) cs.addError(t.Pos(), fmt.Sprintf("unexpected type: %s", t.Name))
return typ{} return shaderir.Type{}
} }
case *ast.StructType: case *ast.StructType:
cs.addError(t.Pos(), "struct is not implemented") cs.addError(t.Pos(), "struct is not implemented")
return typ{} return shaderir.Type{}
default: default:
cs.addError(t.Pos(), fmt.Sprintf("unepxected type: %v", t)) cs.addError(t.Pos(), fmt.Sprintf("unepxected type: %v", t))
return typ{} return shaderir.Type{}
} }
} }