From 869a61d9be83810f0fda150148005ce1e942fa63 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 7 Jun 2020 16:21:02 +0900 Subject: [PATCH] shader: Parse initial values of variables --- internal/shader/shader.go | 36 ++++++++++++++++------- internal/shader/shader_test.go | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/internal/shader/shader.go b/internal/shader/shader.go index f03e90cdb..680ca0d9a 100644 --- a/internal/shader/shader.go +++ b/internal/shader/shader.go @@ -191,23 +191,35 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) { case token.VAR: for _, s := range d.Specs { s := s.(*ast.ValueSpec) - vs := cs.parseVariable(b, s) + vs, inits := cs.parseVariable(b, s) if b == &cs.global { + // TODO: Should rhs be ignored? for i, v := range vs { if !strings.HasPrefix(v.name, "__") { 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)) } } - // TODO: Check rhs cs.uniforms = append(cs.uniforms, v.name) cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir) } continue } - for _, v := range vs { + for i, v := range vs { b.vars = append(b.vars, v) 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: @@ -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 if vs.Type != nil { t = s.parseType(vs.Type) } var vars []variable + var inits []*shaderir.Expr for i, n := range vs.Names { var init ast.Expr if len(vs.Values) > 0 { @@ -250,18 +263,19 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) []variable } } 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{ name: name, typ: t, }) + + var expr *shaderir.Expr + if init != nil { + e := s.parseExpr(block, init) + expr = &e + } + inits = append(inits, expr) } - return vars + return vars, inits } func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant { diff --git a/internal/shader/shader_test.go b/internal/shader/shader_test.go index 4446119cd..2cea24b4c 100644 --- a/internal/shader/shader_test.go +++ b/internal/shader/shader_test.go @@ -59,6 +59,58 @@ func Foo(foo vec2) vec4 { VS: `void F0(in vec2 l0, out vec4 l1) { l1 = vec4(l0, 0.0, 1.0); 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; }`, }, {