diff --git a/internal/shader/expr.go b/internal/shader/expr.go index 7a1cfeb5b..704880649 100644 --- a/internal/shader/expr.go +++ b/internal/shader/expr.go @@ -52,6 +52,7 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr, default: cs.addError(e.Pos(), fmt.Sprintf("literal not implemented: %#v", e)) } + case *ast.BinaryExpr: var stmts []shaderir.Stmt @@ -119,6 +120,24 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr, switch { case op == shaderir.LessThanOp || op == shaderir.LessThanEqualOp || op == shaderir.GreaterThanOp || op == shaderir.GreaterThanEqualOp || op == shaderir.EqualOp || op == shaderir.NotEqualOp || op == shaderir.AndAnd || op == shaderir.OrOr: t = shaderir.Type{Main: shaderir.Bool} + case lhs[0].Type == shaderir.NumberExpr && rhs[0].Type != shaderir.NumberExpr: + if rhst.Main == shaderir.Int { + if !canTruncateToInteger(lhs[0].Const) { + cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", lhs[0].Const.String())) + return nil, nil, nil, false + } + lhs[0].ConstType = shaderir.ConstTypeInt + } + t = rhst + case lhs[0].Type != shaderir.NumberExpr && rhs[0].Type == shaderir.NumberExpr: + if lhst.Main == shaderir.Int { + if !canTruncateToInteger(rhs[0].Const) { + cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", rhs[0].Const.String())) + return nil, nil, nil, false + } + rhs[0].ConstType = shaderir.ConstTypeInt + } + t = lhst case lhst.Equal(&rhst): t = lhst case lhst.Main == shaderir.Float || lhst.Main == shaderir.Int: @@ -162,6 +181,7 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr, Exprs: []shaderir.Expr{lhs[0], rhs[0]}, }, }, []shaderir.Type{t}, stmts, true + case *ast.CallExpr: var ( callee shaderir.Expr diff --git a/internal/shader/stmt.go b/internal/shader/stmt.go index fea45233b..0bcca9d21 100644 --- a/internal/shader/stmt.go +++ b/internal/shader/stmt.go @@ -73,12 +73,22 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP } stmts = append(stmts, ss...) - lhs, _, ss, ok := cs.parseExpr(block, stmt.Lhs[0]) + lhs, ts, ss, ok := cs.parseExpr(block, stmt.Lhs[0]) if !ok { return nil, false } stmts = append(stmts, ss...) + if rhs[0].Type == shaderir.NumberExpr { + if ts[0].Main == shaderir.Int { + if !canTruncateToInteger(rhs[0].Const) { + cs.addError(stmt.Pos(), fmt.Sprintf("constant %s truncated to integer", rhs[0].Const.String())) + return nil, false + } + rhs[0].ConstType = shaderir.ConstTypeInt + } + } + stmts = append(stmts, shaderir.Stmt{ Type: shaderir.Assign, Exprs: []shaderir.Expr{ diff --git a/internal/shader/testdata/issue1245.expected.fs b/internal/shader/testdata/issue1245.expected.fs index 526590953..60c2b318d 100644 --- a/internal/shader/testdata/issue1245.expected.fs +++ b/internal/shader/testdata/issue1245.expected.fs @@ -1,6 +1,6 @@ void main(void) { vec4 l0 = vec4(0); - for (int l1 = 0; l1 < 4; l1++) { + for (float l1 = 0.0; l1 < 4.0; l1++) { (l0).x = ((l0).x) + ((l1) * (1.000000000e-02)); } gl_FragColor = l0; diff --git a/internal/shader/testdata/issue1245.expected.vs b/internal/shader/testdata/issue1245.expected.vs index 3231f8a88..988724832 100644 --- a/internal/shader/testdata/issue1245.expected.vs +++ b/internal/shader/testdata/issue1245.expected.vs @@ -2,7 +2,7 @@ attribute vec2 A0; void main(void) { vec4 l0 = vec4(0); - for (int l1 = 0; l1 < 4; l1++) { + for (float l1 = 0.0; l1 < 4.0; l1++) { (l0).x = ((l0).x) + ((l1) * (1.000000000e-02)); } gl_Position = l0; diff --git a/internal/shader/testdata/issue1245.go b/internal/shader/testdata/issue1245.go index 25f8a3962..124872e28 100644 --- a/internal/shader/testdata/issue1245.go +++ b/internal/shader/testdata/issue1245.go @@ -2,7 +2,7 @@ package main func Vertex(position vec2) vec4 { var v vec4 - for i := 0; i < 4.0; i++ { + for i := 0.0; i < 4.0; i++ { v.x += i * 0.01 } return v @@ -10,7 +10,7 @@ func Vertex(position vec2) vec4 { func Fragment(position vec4) vec4 { var v vec4 - for i := 0; i < 4.0; i++ { + for i := 0.0; i < 4.0; i++ { v.x += i * 0.01 } return v diff --git a/internal/shader/testdata/issue1299.expected.vs b/internal/shader/testdata/issue1299.expected.vs new file mode 100644 index 000000000..054cdb520 --- /dev/null +++ b/internal/shader/testdata/issue1299.expected.vs @@ -0,0 +1,11 @@ +void F0(out int l0); + +void F0(out int l0) { + int l1 = 0; + l1 = 1; + l1 = (l1) * (2); + l1 = (l1) + (2); + l1 = (2) - (l1); + l0 = l1; + return; +} diff --git a/internal/shader/testdata/issue1299.go b/internal/shader/testdata/issue1299.go new file mode 100644 index 000000000..81a35dfb6 --- /dev/null +++ b/internal/shader/testdata/issue1299.go @@ -0,0 +1,9 @@ +package main + +func Foo() int { + x := 1 + x *= 2 + x = x + 2 + x = 2 - x + return x +}