From a9b94a183b3d9a17dfa440db659822b38ca9c8d1 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 16 Aug 2020 18:40:43 +0900 Subject: [PATCH] shader: Implement swapping variables Fixes #1248 --- internal/shader/stmt.go | 38 ++++++++++++++++--- .../shader/testdata/issue1248.expected.vs | 26 +++++++++++++ internal/shader/testdata/issue1248.go | 9 +++++ 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 internal/shader/testdata/issue1248.expected.vs create mode 100644 internal/shader/testdata/issue1248.go diff --git a/internal/shader/stmt.go b/internal/shader/stmt.go index 0bcca9d21..1edf65975 100644 --- a/internal/shader/stmt.go +++ b/internal/shader/stmt.go @@ -42,7 +42,6 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP } stmts = append(stmts, ss...) case token.ASSIGN: - // TODO: What about the statement `a,b = b,a?` if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 { cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed")) return nil, false @@ -498,10 +497,39 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr, } } - stmts = append(stmts, shaderir.Stmt{ - Type: shaderir.Assign, - Exprs: []shaderir.Expr{l[0], r[0]}, - }) + if len(lhs) == 1 { + stmts = append(stmts, shaderir.Stmt{ + Type: shaderir.Assign, + Exprs: []shaderir.Expr{l[0], r[0]}, + }) + } else { + // For variable swapping, use temporary variables. + block.vars = append(block.vars, variable{ + typ: origts[0], + }) + idx := len(block.vars) - 1 + stmts = append(stmts, + shaderir.Stmt{ + Type: shaderir.Assign, + Exprs: []shaderir.Expr{ + { + Type: shaderir.LocalVariable, + Index: idx, + }, + r[0], + }, + }, + shaderir.Stmt{ + Type: shaderir.Assign, + Exprs: []shaderir.Expr{ + l[0], + { + Type: shaderir.LocalVariable, + Index: idx, + }, + }, + }) + } } else { if i == 0 { var ss []shaderir.Stmt diff --git a/internal/shader/testdata/issue1248.expected.vs b/internal/shader/testdata/issue1248.expected.vs new file mode 100644 index 000000000..33d56c435 --- /dev/null +++ b/internal/shader/testdata/issue1248.expected.vs @@ -0,0 +1,26 @@ +void F0(out vec2 l0); + +void F0(out vec2 l0) { + vec2 l1 = vec2(0); + vec2 l2 = vec2(0); + vec2 l3 = vec2(0); + vec2 l4 = vec2(0); + vec2 l5 = vec2(0); + vec2 l6 = vec2(0); + vec2 l7 = vec2(0); + vec2 l8 = vec2(0); + vec2 l9 = vec2(0); + vec2 l10 = vec2(0); + l3 = l2; + l1 = l3; + l4 = l1; + l2 = l4; + l8 = l6; + l5 = l8; + l9 = l7; + l6 = l9; + l10 = l5; + l7 = l10; + l0 = l1; + return; +} diff --git a/internal/shader/testdata/issue1248.go b/internal/shader/testdata/issue1248.go new file mode 100644 index 000000000..a808266af --- /dev/null +++ b/internal/shader/testdata/issue1248.go @@ -0,0 +1,9 @@ +package main + +func Foo() vec2 { + var a, b vec2 + a, b = b, a + var c, d, e vec2 + c, d, e = d, e, c + return a +}