shader: Parse initial values of variables

This commit is contained in:
Hajime Hoshi 2020-06-07 16:21:02 +09:00
parent e14cd559b6
commit 869a61d9be
2 changed files with 77 additions and 11 deletions

View File

@ -191,23 +191,35 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
case token.VAR: case token.VAR:
for _, s := range d.Specs { for _, s := range d.Specs {
s := s.(*ast.ValueSpec) s := s.(*ast.ValueSpec)
vs := cs.parseVariable(b, s) vs, inits := cs.parseVariable(b, s)
if b == &cs.global { if b == &cs.global {
// TODO: Should rhs be ignored?
for i, v := range vs { for i, v := range vs {
if !strings.HasPrefix(v.name, "__") { if !strings.HasPrefix(v.name, "__") {
if v.name[0] < 'A' || 'Z' < v.name[0] { if v.name[0] < 'A' || 'Z' < v.name[0] {
cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name)) cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name))
} }
} }
// TODO: Check rhs
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.ir)
} }
continue continue
} }
for _, 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.ir)
if inits[i] != nil {
b.ir.Stmts = append(b.ir.Stmts, shaderir.Stmt{
Type: shaderir.Assign,
Exprs: []shaderir.Expr{
{
Type: shaderir.LocalVariable,
Index: len(b.vars) - 1,
},
*inits[i],
},
})
}
} }
} }
case token.IMPORT: case token.IMPORT:
@ -234,13 +246,14 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
} }
} }
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) []variable { func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr) {
var t typ var t typ
if vs.Type != nil { if vs.Type != nil {
t = s.parseType(vs.Type) t = s.parseType(vs.Type)
} }
var vars []variable var vars []variable
var inits []*shaderir.Expr
for i, n := range vs.Names { for i, n := range vs.Names {
var init ast.Expr var init ast.Expr
if len(vs.Values) > 0 { if len(vs.Values) > 0 {
@ -250,18 +263,19 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) []variable
} }
} }
name := n.Name name := n.Name
var e shaderir.Expr
if init != nil {
e = s.parseExpr(block, init)
}
// TODO: Add an assign statement for e.
_ = e
vars = append(vars, variable{ vars = append(vars, variable{
name: name, name: name,
typ: t, typ: t,
}) })
var expr *shaderir.Expr
if init != nil {
e := s.parseExpr(block, init)
expr = &e
} }
return vars inits = append(inits, expr)
}
return vars, inits
} }
func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant { func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant {

View File

@ -59,6 +59,58 @@ func Foo(foo vec2) vec4 {
VS: `void F0(in vec2 l0, out vec4 l1) { VS: `void F0(in vec2 l0, out vec4 l1) {
l1 = vec4(l0, 0.0, 1.0); l1 = vec4(l0, 0.0, 1.0);
return; return;
}`,
},
{
Name: "var init",
Src: `package main
func Foo(foo vec2) vec4 {
var ret vec4 = vec4(foo, 0, 1)
return ret
}`,
VS: `void F0(in vec2 l0, out vec4 l1) {
vec4 l2 = vec4(0.0);
l2 = vec4(l0, 0.0, 1.0);
l1 = l2;
return;
}`,
},
{
Name: "var init 2",
Src: `package main
func Foo(foo vec2) vec4 {
var bar1 vec4 = vec4(foo, 0, 1)
bar1.x = bar1.x
var bar2 vec4 = bar1
return bar2
}`,
VS: `void F0(in vec2 l0, out vec4 l1) {
vec4 l2 = vec4(0.0);
vec4 l3 = vec4(0.0);
l2 = vec4(l0, 0.0, 1.0);
(l2).x = (l2).x;
l3 = l2;
l1 = l3;
return;
}`,
},
{
Name: "var multiple init",
Src: `package main
func Foo(foo vec2) vec4 {
var bar1, bar2 vec2 = foo, foo
return vec4(bar1, bar2)
}`,
VS: `void F0(in vec2 l0, out vec4 l1) {
vec2 l2 = vec2(0.0);
vec2 l3 = vec2(0.0);
l2 = l0;
l3 = l0;
l1 = vec4(l2, l3);
return;
}`, }`,
}, },
{ {