mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 11:48:55 +01:00
internal/shader: bug fix: check types correctly for assign operators
Closes #1950
This commit is contained in:
parent
83bd0772d4
commit
d110716dc0
@ -87,25 +87,38 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
|||||||
}
|
}
|
||||||
stmts = append(stmts, ss...)
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
if op == shaderir.ModOp {
|
// Treat an integer literal as an integer constant value.
|
||||||
if lts[0].Main != shaderir.Int || rts[0].Main != shaderir.Int {
|
|
||||||
var wrongType shaderir.Type
|
|
||||||
if lts[0].Main != shaderir.Int {
|
|
||||||
wrongType = lts[0]
|
|
||||||
} else {
|
|
||||||
wrongType = rts[0]
|
|
||||||
}
|
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator %% not defined on %s", wrongType.String()))
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if rhs[0].Type == shaderir.NumberExpr && rts[0].Main == shaderir.Int {
|
if rhs[0].Type == shaderir.NumberExpr && rts[0].Main == shaderir.Int {
|
||||||
if !cs.forceToInt(stmt, &rhs[0]) {
|
if !cs.forceToInt(stmt, &rhs[0]) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lts[0].Main != rts[0].Main {
|
||||||
|
switch lts[0].Main {
|
||||||
|
case shaderir.Int:
|
||||||
|
if !cs.forceToInt(stmt, &rhs[0]) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
case shaderir.Float:
|
||||||
|
if rhs[0].Const != nil && rhs[0].Const.Kind() == gconstant.Int {
|
||||||
|
rhs[0].Const = gconstant.ToFloat(rhs[0].Const)
|
||||||
|
rhs[0].ConstType = shaderir.ConstTypeFloat
|
||||||
|
} else {
|
||||||
|
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: mismatched types %s and %s", lts[0].String(), rts[0].String()))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: mismatched types %s and %s", lts[0].String(), rts[0].String()))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == shaderir.ModOp && lts[0].Main != shaderir.Int {
|
||||||
|
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator %% not defined on %s", lts[0].String()))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
stmts = append(stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
|
4
internal/shader/testdata/for.expected.vs
vendored
4
internal/shader/testdata/for.expected.vs
vendored
@ -5,11 +5,11 @@ void F0(out vec2 l0) {
|
|||||||
vec2 l3 = vec2(0);
|
vec2 l3 = vec2(0);
|
||||||
l1 = vec2(0.0);
|
l1 = vec2(0.0);
|
||||||
for (int l2 = 0; l2 < 100; l2++) {
|
for (int l2 = 0; l2 < 100; l2++) {
|
||||||
(l1).x = ((l1).x) + (l2);
|
(l1).x = ((l1).x) + (float(l2));
|
||||||
}
|
}
|
||||||
l3 = vec2(0.0);
|
l3 = vec2(0.0);
|
||||||
for (float l4 = 10.0; l4 >= 0.0; l4 -= 2.0) {
|
for (float l4 = 10.0; l4 >= 0.0; l4 -= 2.0) {
|
||||||
(l3).x = ((l3).x) + (l4);
|
(l3).x = ((l3).x) + (float(l4));
|
||||||
}
|
}
|
||||||
l0 = l1;
|
l0 = l1;
|
||||||
return;
|
return;
|
||||||
|
4
internal/shader/testdata/for.go
vendored
4
internal/shader/testdata/for.go
vendored
@ -3,11 +3,11 @@ package main
|
|||||||
func Foo() vec2 {
|
func Foo() vec2 {
|
||||||
v := vec2(0)
|
v := vec2(0)
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
v.x += i
|
v.x += float(i)
|
||||||
}
|
}
|
||||||
v2 := vec2(0)
|
v2 := vec2(0)
|
||||||
for i := 10.0; i >= 0; i -= 2 {
|
for i := 10.0; i >= 0; i -= 2 {
|
||||||
v2.x += i
|
v2.x += float(i)
|
||||||
}
|
}
|
||||||
_ = v2
|
_ = v2
|
||||||
return v
|
return v
|
||||||
|
2
internal/shader/testdata/for2.expected.vs
vendored
2
internal/shader/testdata/for2.expected.vs
vendored
@ -5,7 +5,7 @@ void F0(out vec2 l0) {
|
|||||||
vec2 l3 = vec2(0);
|
vec2 l3 = vec2(0);
|
||||||
l1 = vec2(0.0);
|
l1 = vec2(0.0);
|
||||||
for (int l2 = 0; l2 < 100; l2++) {
|
for (int l2 = 0; l2 < 100; l2++) {
|
||||||
(l1).x = ((l1).x) + (l2);
|
(l1).x = ((l1).x) + (float(l2));
|
||||||
if (((l1).x) >= (100.0)) {
|
if (((l1).x) >= (100.0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
2
internal/shader/testdata/for2.go
vendored
2
internal/shader/testdata/for2.go
vendored
@ -3,7 +3,7 @@ package main
|
|||||||
func Foo() vec2 {
|
func Foo() vec2 {
|
||||||
v := vec2(0)
|
v := vec2(0)
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
v.x += i
|
v.x += float(i)
|
||||||
if v.x >= 100 {
|
if v.x >= 100 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1351,6 +1351,16 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
|
|
||||||
if _, err := ebiten.NewShader([]byte(`package main
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 2
|
||||||
|
a %= 1.0
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
a := 2
|
a := 2
|
||||||
a %= 0.5
|
a %= 0.5
|
||||||
@ -1369,3 +1379,65 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
t.Errorf("error must be non-nil but was nil")
|
t.Errorf("error must be non-nil but was nil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderOperatorAssign(t *testing.T) {
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1.0
|
||||||
|
a += 2
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1.0
|
||||||
|
a += 2.0
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1.0
|
||||||
|
a += 2.1
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1
|
||||||
|
a += 2
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1
|
||||||
|
a += 2.0
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
a := 1
|
||||||
|
a += 2.1
|
||||||
|
return vec4(a)
|
||||||
|
}`)); err == nil {
|
||||||
|
t.Errorf("error must be non-nil but was nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user