mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/shader: bug fix: stricter type checks for the built-in functions
Closes #2712
This commit is contained in:
parent
ef08873f30
commit
287545b02a
@ -291,14 +291,20 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
|||||||
}
|
}
|
||||||
case shaderir.IntF:
|
case shaderir.IntF:
|
||||||
if len(args) == 1 && args[0].Const != nil {
|
if len(args) == 1 && args[0].Const != nil {
|
||||||
if !canTruncateToInteger(args[0].Const) {
|
var v int64
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[0].Const.String()))
|
switch args[0].Const.Kind() {
|
||||||
return nil, nil, nil, false
|
case gconstant.Int:
|
||||||
|
v, _ = gconstant.Int64Val(args[0].Const)
|
||||||
|
case gconstant.Float:
|
||||||
|
fv, _ := gconstant.Float64Val(args[0].Const)
|
||||||
|
v = int64(fv)
|
||||||
|
default:
|
||||||
|
panic("not reached")
|
||||||
}
|
}
|
||||||
return []shaderir.Expr{
|
return []shaderir.Expr{
|
||||||
{
|
{
|
||||||
Type: shaderir.NumberExpr,
|
Type: shaderir.NumberExpr,
|
||||||
Const: gconstant.ToInt(args[0].Const),
|
Const: gconstant.MakeInt64(v),
|
||||||
ConstType: shaderir.ConstTypeInt,
|
ConstType: shaderir.ConstTypeInt,
|
||||||
},
|
},
|
||||||
}, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
|
}, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
|
||||||
@ -357,19 +363,19 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
|||||||
}
|
}
|
||||||
t = shaderir.Type{Main: shaderir.Vec4}
|
t = shaderir.Type{Main: shaderir.Vec4}
|
||||||
case shaderir.IVec2F:
|
case shaderir.IVec2F:
|
||||||
if err := checkArgsForVec2BuiltinFunc(args, argts); err != nil {
|
if err := checkArgsForIVec2BuiltinFunc(args, argts); err != nil {
|
||||||
cs.addError(e.Pos(), err.Error())
|
cs.addError(e.Pos(), err.Error())
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
t = shaderir.Type{Main: shaderir.IVec2}
|
t = shaderir.Type{Main: shaderir.IVec2}
|
||||||
case shaderir.IVec3F:
|
case shaderir.IVec3F:
|
||||||
if err := checkArgsForVec3BuiltinFunc(args, argts); err != nil {
|
if err := checkArgsForIVec3BuiltinFunc(args, argts); err != nil {
|
||||||
cs.addError(e.Pos(), err.Error())
|
cs.addError(e.Pos(), err.Error())
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
t = shaderir.Type{Main: shaderir.IVec3}
|
t = shaderir.Type{Main: shaderir.IVec3}
|
||||||
case shaderir.IVec4F:
|
case shaderir.IVec4F:
|
||||||
if err := checkArgsForVec4BuiltinFunc(args, argts); err != nil {
|
if err := checkArgsForIVec4BuiltinFunc(args, argts); err != nil {
|
||||||
cs.addError(e.Pos(), err.Error())
|
cs.addError(e.Pos(), err.Error())
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
|
@ -1653,8 +1653,8 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "i := 1.0; a := vec3(i, i, i); _ = a", err: false},
|
{stmt: "i := 1.0; a := vec3(i, i, i); _ = a", err: false},
|
||||||
{stmt: "a := vec3(vec2(1), 1); _ = a", err: false},
|
{stmt: "a := vec3(vec2(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := vec3(1, vec2(1)); _ = a", err: false},
|
{stmt: "a := vec3(1, vec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := vec3(ivec2(1), 1); _ = a", err: false},
|
{stmt: "a := vec3(ivec2(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := vec3(1, ivec2(1)); _ = a", err: false},
|
{stmt: "a := vec3(1, ivec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := vec3(vec3(1), 1); _ = a", err: true},
|
{stmt: "a := vec3(vec3(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := vec3(1, vec3(1)); _ = a", err: true},
|
{stmt: "a := vec3(1, vec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := vec3(vec3(1), vec3(1), vec3(1)); _ = a", err: true},
|
{stmt: "a := vec3(vec3(1), vec3(1), vec3(1)); _ = a", err: true},
|
||||||
@ -1678,15 +1678,15 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "i := 1.0; a := vec4(i, i, i, i); _ = a", err: false},
|
{stmt: "i := 1.0; a := vec4(i, i, i, i); _ = a", err: false},
|
||||||
{stmt: "a := vec4(vec2(1), 1, 1); _ = a", err: false},
|
{stmt: "a := vec4(vec2(1), 1, 1); _ = a", err: false},
|
||||||
{stmt: "a := vec4(1, vec2(1), 1); _ = a", err: false},
|
{stmt: "a := vec4(1, vec2(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := vec4(ivec2(1), 1, 1); _ = a", err: false},
|
{stmt: "a := vec4(ivec2(1), 1, 1); _ = a", err: true},
|
||||||
{stmt: "a := vec4(1, ivec2(1), 1); _ = a", err: false},
|
{stmt: "a := vec4(1, ivec2(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := vec4(1, 1, vec2(1)); _ = a", err: false},
|
{stmt: "a := vec4(1, 1, vec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := vec4(vec2(1), vec2(1)); _ = a", err: false},
|
{stmt: "a := vec4(vec2(1), vec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := vec4(ivec2(1), ivec2(1)); _ = a", err: false},
|
{stmt: "a := vec4(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := vec4(vec3(1), 1); _ = a", err: false},
|
{stmt: "a := vec4(vec3(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := vec4(1, vec3(1)); _ = a", err: false},
|
{stmt: "a := vec4(1, vec3(1)); _ = a", err: false},
|
||||||
{stmt: "a := vec4(ivec3(1), 1); _ = a", err: false},
|
{stmt: "a := vec4(ivec3(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := vec4(1, ivec3(1)); _ = a", err: false},
|
{stmt: "a := vec4(1, ivec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := vec4(vec4(1), 1); _ = a", err: true},
|
{stmt: "a := vec4(vec4(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := vec4(1, vec4(1)); _ = a", err: true},
|
{stmt: "a := vec4(1, vec4(1)); _ = a", err: true},
|
||||||
{stmt: "a := vec4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
{stmt: "a := vec4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
||||||
@ -1695,7 +1695,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := ivec2(1); _ = a", err: false},
|
{stmt: "a := ivec2(1); _ = a", err: false},
|
||||||
{stmt: "a := ivec2(1.0); _ = a", err: false},
|
{stmt: "a := ivec2(1.0); _ = a", err: false},
|
||||||
{stmt: "i := 1; a := ivec2(i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec2(i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec2(i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec2(i); _ = a", err: true},
|
||||||
{stmt: "a := ivec2(vec2(1)); _ = a", err: false},
|
{stmt: "a := ivec2(vec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec2(vec3(1)); _ = a", err: true},
|
{stmt: "a := ivec2(vec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec2(ivec2(1)); _ = a", err: false},
|
{stmt: "a := ivec2(ivec2(1)); _ = a", err: false},
|
||||||
@ -1704,7 +1704,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := ivec2(1, 1); _ = a", err: false},
|
{stmt: "a := ivec2(1, 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec2(1.0, 1.0); _ = a", err: false},
|
{stmt: "a := ivec2(1.0, 1.0); _ = a", err: false},
|
||||||
{stmt: "i := 1; a := ivec2(i, i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec2(i, i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec2(i, i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec2(i, i); _ = a", err: true},
|
||||||
{stmt: "a := ivec2(vec2(1), 1); _ = a", err: true},
|
{stmt: "a := ivec2(vec2(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := ivec2(1, vec2(1)); _ = a", err: true},
|
{stmt: "a := ivec2(1, vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec2(ivec2(1), 1); _ = a", err: true},
|
{stmt: "a := ivec2(ivec2(1), 1); _ = a", err: true},
|
||||||
@ -1714,9 +1714,9 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
|
|
||||||
{stmt: "a := ivec3(1); _ = a", err: false},
|
{stmt: "a := ivec3(1); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(1.0); _ = a", err: false},
|
{stmt: "a := ivec3(1.0); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(1.1); _ = a", err: false},
|
{stmt: "a := ivec3(1.1); _ = a", err: true},
|
||||||
{stmt: "i := 1; a := ivec3(i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec3(i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec3(i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec3(i); _ = a", err: true},
|
||||||
{stmt: "a := ivec3(vec3(1)); _ = a", err: false},
|
{stmt: "a := ivec3(vec3(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(vec2(1)); _ = a", err: true},
|
{stmt: "a := ivec3(vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec3(vec4(1)); _ = a", err: true},
|
{stmt: "a := ivec3(vec4(1)); _ = a", err: true},
|
||||||
@ -1726,11 +1726,11 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
|
|
||||||
{stmt: "a := ivec3(1, 1, 1); _ = a", err: false},
|
{stmt: "a := ivec3(1, 1, 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(1.0, 1.0, 1.0); _ = a", err: false},
|
{stmt: "a := ivec3(1.0, 1.0, 1.0); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(1.1, 1.1, 1.1); _ = a", err: false},
|
{stmt: "a := ivec3(1.1, 1.1, 1.1); _ = a", err: true},
|
||||||
{stmt: "i := 1; a := ivec3(i, i, i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec3(i, i, i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec3(i, i, i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec3(i, i, i); _ = a", err: true},
|
||||||
{stmt: "a := ivec3(vec2(1), 1); _ = a", err: false},
|
{stmt: "a := ivec3(vec2(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := ivec3(1, vec2(1)); _ = a", err: false},
|
{stmt: "a := ivec3(1, vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec3(ivec2(1), 1); _ = a", err: false},
|
{stmt: "a := ivec3(ivec2(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(1, ivec2(1)); _ = a", err: false},
|
{stmt: "a := ivec3(1, ivec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec3(vec3(1), 1); _ = a", err: true},
|
{stmt: "a := ivec3(vec3(1), 1); _ = a", err: true},
|
||||||
@ -1741,7 +1741,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := ivec4(1); _ = a", err: false},
|
{stmt: "a := ivec4(1); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1.0); _ = a", err: false},
|
{stmt: "a := ivec4(1.0); _ = a", err: false},
|
||||||
{stmt: "i := 1; a := ivec4(i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec4(i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec4(i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec4(i); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(vec4(1)); _ = a", err: false},
|
{stmt: "a := ivec4(vec4(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(vec2(1)); _ = a", err: true},
|
{stmt: "a := ivec4(vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(vec3(1)); _ = a", err: true},
|
{stmt: "a := ivec4(vec3(1)); _ = a", err: true},
|
||||||
@ -1751,19 +1751,19 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
|
|
||||||
{stmt: "a := ivec4(1, 1, 1, 1); _ = a", err: false},
|
{stmt: "a := ivec4(1, 1, 1, 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
{stmt: "a := ivec4(1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1.1, 1.1, 1.1, 1.1); _ = a", err: false},
|
{stmt: "a := ivec4(1.1, 1.1, 1.1, 1.1); _ = a", err: true},
|
||||||
{stmt: "i := 1; a := ivec4(i, i, i, i); _ = a", err: false},
|
{stmt: "i := 1; a := ivec4(i, i, i, i); _ = a", err: false},
|
||||||
{stmt: "i := 1.0; a := ivec4(i, i, i, i); _ = a", err: false},
|
{stmt: "i := 1.0; a := ivec4(i, i, i, i); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(vec2(1), 1, 1); _ = a", err: false},
|
{stmt: "a := ivec4(vec2(1), 1, 1); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(1, vec2(1), 1); _ = a", err: false},
|
{stmt: "a := ivec4(1, vec2(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(1, 1, vec2(1)); _ = a", err: false},
|
{stmt: "a := ivec4(1, 1, vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(ivec2(1), 1, 1); _ = a", err: false},
|
{stmt: "a := ivec4(ivec2(1), 1, 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1, ivec2(1), 1); _ = a", err: false},
|
{stmt: "a := ivec4(1, ivec2(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1, 1, ivec2(1)); _ = a", err: false},
|
{stmt: "a := ivec4(1, 1, ivec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(vec2(1), vec2(1)); _ = a", err: false},
|
{stmt: "a := ivec4(vec2(1), vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(ivec2(1), ivec2(1)); _ = a", err: false},
|
{stmt: "a := ivec4(ivec2(1), ivec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(vec3(1), 1); _ = a", err: false},
|
{stmt: "a := ivec4(vec3(1), 1); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(1, vec3(1)); _ = a", err: false},
|
{stmt: "a := ivec4(1, vec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := ivec4(ivec3(1), 1); _ = a", err: false},
|
{stmt: "a := ivec4(ivec3(1), 1); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(1, ivec3(1)); _ = a", err: false},
|
{stmt: "a := ivec4(1, ivec3(1)); _ = a", err: false},
|
||||||
{stmt: "a := ivec4(vec4(1), 1); _ = a", err: true},
|
{stmt: "a := ivec4(vec4(1), 1); _ = a", err: true},
|
||||||
@ -1782,7 +1782,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := mat2(mat4(1)); _ = a", err: true},
|
{stmt: "a := mat2(mat4(1)); _ = a", err: true},
|
||||||
|
|
||||||
{stmt: "a := mat2(vec2(1), vec2(1)); _ = a", err: false},
|
{stmt: "a := mat2(vec2(1), vec2(1)); _ = a", err: false},
|
||||||
{stmt: "a := mat2(ivec2(1), ivec2(1)); _ = a", err: false},
|
{stmt: "a := mat2(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1, 1); _ = a", err: true},
|
{stmt: "a := mat2(1, 1); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1, vec2(1)); _ = a", err: true},
|
{stmt: "a := mat2(1, vec2(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat2(vec2(1), vec3(1)); _ = a", err: true},
|
{stmt: "a := mat2(vec2(1), vec3(1)); _ = a", err: true},
|
||||||
@ -1810,7 +1810,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := mat3(mat4(1)); _ = a", err: true},
|
{stmt: "a := mat3(mat4(1)); _ = a", err: true},
|
||||||
|
|
||||||
{stmt: "a := mat3(vec3(1), vec3(1), vec3(1)); _ = a", err: false},
|
{stmt: "a := mat3(vec3(1), vec3(1), vec3(1)); _ = a", err: false},
|
||||||
{stmt: "a := mat3(ivec3(1), ivec3(1), ivec3(1)); _ = a", err: false},
|
{stmt: "a := mat3(ivec3(1), ivec3(1), ivec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat3(1, 1, 1); _ = a", err: true},
|
{stmt: "a := mat3(1, 1, 1); _ = a", err: true},
|
||||||
{stmt: "a := mat3(1, 1, vec3(1)); _ = a", err: true},
|
{stmt: "a := mat3(1, 1, vec3(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat3(vec3(1), vec3(1), vec4(1)); _ = a", err: true},
|
{stmt: "a := mat3(vec3(1), vec3(1), vec4(1)); _ = a", err: true},
|
||||||
@ -1838,7 +1838,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
|||||||
{stmt: "a := mat4(mat3(1)); _ = a", err: true},
|
{stmt: "a := mat4(mat3(1)); _ = a", err: true},
|
||||||
|
|
||||||
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||||
{stmt: "a := mat4(ivec4(1), ivec4(1), ivec4(1), ivec4(1)); _ = a", err: false},
|
{stmt: "a := mat4(ivec4(1), ivec4(1), ivec4(1), ivec4(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat4(1, 1, 1, 1); _ = a", err: true},
|
{stmt: "a := mat4(1, 1, 1, 1); _ = a", err: true},
|
||||||
{stmt: "a := mat4(1, 1, 1, vec4(1)); _ = a", err: true},
|
{stmt: "a := mat4(1, 1, 1, vec4(1)); _ = a", err: true},
|
||||||
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec2(1)); _ = a", err: true},
|
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec2(1)); _ = a", err: true},
|
||||||
@ -3341,3 +3341,40 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #2712
|
||||||
|
func TestSyntaxCast(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
stmt string
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{stmt: "a := int(1); _ = a", err: false},
|
||||||
|
{stmt: "a := int(1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := int(1.1); _ = a", err: false},
|
||||||
|
{stmt: "a := float(1); _ = a", err: false},
|
||||||
|
{stmt: "a := float(1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := float(1.1); _ = a", err: false},
|
||||||
|
{stmt: "a := 1; _ = int(a)", err: false},
|
||||||
|
{stmt: "a := 1.0; _ = int(a)", err: false},
|
||||||
|
{stmt: "a := 1.1; _ = int(a)", err: false},
|
||||||
|
{stmt: "a := 1; _ = float(a)", err: false},
|
||||||
|
{stmt: "a := 1.0; _ = float(a)", err: false},
|
||||||
|
{stmt: "a := 1.1; _ = float(a)", err: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
stmt := c.stmt
|
||||||
|
src := fmt.Sprintf(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
%s
|
||||||
|
return position
|
||||||
|
}`, stmt)
|
||||||
|
_, err := compileToIR([]byte(src))
|
||||||
|
if err == nil && c.err {
|
||||||
|
t.Errorf("%s must return an error but does not", stmt)
|
||||||
|
} else if err != nil && !c.err {
|
||||||
|
t.Errorf("%s must not return nil but returned %v", stmt, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -106,13 +106,17 @@ func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (sh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func canBeFloatImplicitly(expr shaderir.Expr, t shaderir.Type) bool {
|
func canBeFloat(expr shaderir.Expr, t shaderir.Type) bool {
|
||||||
if expr.Const != nil && canTruncateToFloat(expr.Const) {
|
if expr.Const != nil {
|
||||||
return true
|
if t.Main == shaderir.Float {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if canTruncateToFloat(expr.Const) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// canBeFloatImplicitly is used for a cast-like functions like float() or vec2().
|
|
||||||
// A non-constant integer value is acceptable.
|
|
||||||
if t.Main == shaderir.Int {
|
if t.Main == shaderir.Int {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -122,6 +126,23 @@ func canBeFloatImplicitly(expr shaderir.Expr, t shaderir.Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canBeInt(expr shaderir.Expr, t shaderir.Type) bool {
|
||||||
|
if expr.Const != nil {
|
||||||
|
if t.Main == shaderir.Float {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if canTruncateToInteger(expr.Const) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Main == shaderir.Int {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func checkArgsForBoolBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
func checkArgsForBoolBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||||
if len(args) != len(argts) {
|
if len(args) != len(argts) {
|
||||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||||
@ -150,7 +171,7 @@ func checkArgsForIntBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) err
|
|||||||
if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
|
if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if args[0].Const != nil && canTruncateToInteger(args[0].Const) {
|
if args[0].Const != nil && (args[0].Const.Kind() == gconstant.Float || args[0].Const.Kind() == gconstant.Int) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid arguments for int: (%s)", argts[0].String())
|
return fmt.Errorf("invalid arguments for int: (%s)", argts[0].String())
|
||||||
@ -164,7 +185,10 @@ func checkArgsForFloatBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) e
|
|||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return fmt.Errorf("number of float's arguments must be 1 but %d", len(args))
|
return fmt.Errorf("number of float's arguments must be 1 but %d", len(args))
|
||||||
}
|
}
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if args[0].Const != nil && (args[0].Const.Kind() == gconstant.Float || args[0].Const.Kind() == gconstant.Int) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid arguments for float: (%s)", argts[0].String())
|
return fmt.Errorf("invalid arguments for float: (%s)", argts[0].String())
|
||||||
@ -177,14 +201,15 @@ func checkArgsForVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 {
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) {
|
if canBeFloat(args[0], argts[0]) && canBeFloat(args[1], argts[1]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -205,21 +230,22 @@ func checkArgsForVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 {
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
if canBeFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) {
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && canBeFloat(args[1], argts[1]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
if canBeFloat(args[0], argts[0]) && canBeFloat(args[1], argts[1]) && canBeFloat(args[2], argts[2]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -240,34 +266,35 @@ func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 {
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 3 {
|
if canBeFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 && canBeFloatImplicitly(args[1], argts[1]) {
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 && canBeFloat(args[1], argts[1]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && argts[2].IsVector() && argts[2].VectorElementCount() == 2 {
|
if canBeFloat(args[0], argts[0]) && canBeFloat(args[1], argts[1]) && argts[2].IsFloatVector() && argts[2].VectorElementCount() == 2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 && canBeFloatImplicitly(args[2], argts[2]) {
|
if canBeFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 && canBeFloat(args[2], argts[2]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && canBeFloat(args[1], argts[1]) && canBeFloat(args[2], argts[2]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) && canBeFloatImplicitly(args[3], argts[3]) {
|
if canBeFloat(args[0], argts[0]) && canBeFloat(args[1], argts[1]) && canBeFloat(args[2], argts[2]) && canBeFloat(args[3], argts[3]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -281,6 +308,120 @@ func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
return fmt.Errorf("invalid arguments for vec4: (%s)", strings.Join(str, ", "))
|
return fmt.Errorf("invalid arguments for vec4: (%s)", strings.Join(str, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkArgsForIVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||||
|
if len(args) != len(argts) {
|
||||||
|
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(args) {
|
||||||
|
case 1:
|
||||||
|
if canBeInt(args[0], argts[0]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if canBeInt(args[0], argts[0]) && canBeInt(args[1], argts[1]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid number of arguments for vec2")
|
||||||
|
}
|
||||||
|
|
||||||
|
var str []string
|
||||||
|
for _, t := range argts {
|
||||||
|
str = append(str, t.String())
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid arguments for ivec2: (%s)", strings.Join(str, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkArgsForIVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||||
|
if len(args) != len(argts) {
|
||||||
|
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(args) {
|
||||||
|
case 1:
|
||||||
|
if canBeInt(args[0], argts[0]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if canBeInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && canBeInt(args[1], argts[1]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if canBeInt(args[0], argts[0]) && canBeInt(args[1], argts[1]) && canBeInt(args[2], argts[2]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid number of arguments for vec3")
|
||||||
|
}
|
||||||
|
|
||||||
|
var str []string
|
||||||
|
for _, t := range argts {
|
||||||
|
str = append(str, t.String())
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid arguments for ivec3: (%s)", strings.Join(str, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkArgsForIVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||||
|
if len(args) != len(argts) {
|
||||||
|
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(args) {
|
||||||
|
case 1:
|
||||||
|
if canBeInt(args[0], argts[0]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Allow any vectors to perform a cast-like function.
|
||||||
|
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if canBeInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 3 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 3 && canBeInt(args[1], argts[1]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if canBeInt(args[0], argts[0]) && canBeInt(args[1], argts[1]) && argts[2].IsIntVector() && argts[2].VectorElementCount() == 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if canBeInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 && canBeInt(args[2], argts[2]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && canBeInt(args[1], argts[1]) && canBeInt(args[2], argts[2]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
if canBeInt(args[0], argts[0]) && canBeInt(args[1], argts[1]) && canBeInt(args[2], argts[2]) && canBeInt(args[3], argts[3]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid number of arguments for vec4")
|
||||||
|
}
|
||||||
|
|
||||||
|
var str []string
|
||||||
|
for _, t := range argts {
|
||||||
|
str = append(str, t.String())
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid arguments for ivec4: (%s)", strings.Join(str, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||||
if len(args) != len(argts) {
|
if len(args) != len(argts) {
|
||||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||||
@ -288,20 +429,20 @@ func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].Main == shaderir.Mat2 {
|
if argts[0].Main == shaderir.Mat2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
ok := true
|
ok := true
|
||||||
for i := range argts {
|
for i := range argts {
|
||||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
if !canBeFloat(args[i], argts[i]) {
|
||||||
ok = false
|
ok = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -327,22 +468,22 @@ func checkArgsForMat3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].Main == shaderir.Mat3 {
|
if argts[0].Main == shaderir.Mat3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 &&
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 &&
|
||||||
argts[1].IsVector() && argts[1].VectorElementCount() == 3 &&
|
argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 &&
|
||||||
argts[2].IsVector() && argts[2].VectorElementCount() == 3 {
|
argts[2].IsFloatVector() && argts[2].VectorElementCount() == 3 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 9:
|
case 9:
|
||||||
ok := true
|
ok := true
|
||||||
for i := range argts {
|
for i := range argts {
|
||||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
if !canBeFloat(args[i], argts[i]) {
|
||||||
ok = false
|
ok = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -368,23 +509,23 @@ func checkArgsForMat4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
|||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 1:
|
case 1:
|
||||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
if canBeFloat(args[0], argts[0]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if argts[0].Main == shaderir.Mat4 {
|
if argts[0].Main == shaderir.Mat4 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 &&
|
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 4 &&
|
||||||
argts[1].IsVector() && argts[1].VectorElementCount() == 4 &&
|
argts[1].IsFloatVector() && argts[1].VectorElementCount() == 4 &&
|
||||||
argts[2].IsVector() && argts[2].VectorElementCount() == 4 &&
|
argts[2].IsFloatVector() && argts[2].VectorElementCount() == 4 &&
|
||||||
argts[3].IsVector() && argts[3].VectorElementCount() == 4 {
|
argts[3].IsFloatVector() && argts[3].VectorElementCount() == 4 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case 16:
|
case 16:
|
||||||
ok := true
|
ok := true
|
||||||
for i := range argts {
|
for i := range argts {
|
||||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
if !canBeFloat(args[i], argts[i]) {
|
||||||
ok = false
|
ok = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,10 @@ func ResolveUntypedConstsForBinaryOp(lhs, rhs constant.Value, lhst, rhst Type) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if lhst.Main == None {
|
if lhst.Main == None {
|
||||||
if (rhst.Main == Float || rhst.isFloatVector() || rhst.IsMatrix()) && constant.ToFloat(lhs).Kind() != constant.Unknown {
|
if (rhst.Main == Float || rhst.IsFloatVector() || rhst.IsMatrix()) && constant.ToFloat(lhs).Kind() != constant.Unknown {
|
||||||
return constant.ToFloat(lhs), rhs, true
|
return constant.ToFloat(lhs), rhs, true
|
||||||
}
|
}
|
||||||
if (rhst.Main == Int || rhst.isIntVector()) && constant.ToInt(lhs).Kind() != constant.Unknown {
|
if (rhst.Main == Int || rhst.IsIntVector()) && constant.ToInt(lhs).Kind() != constant.Unknown {
|
||||||
return constant.ToInt(lhs), rhs, true
|
return constant.ToInt(lhs), rhs, true
|
||||||
}
|
}
|
||||||
if rhst.Main == Bool && lhs.Kind() == constant.Bool {
|
if rhst.Main == Bool && lhs.Kind() == constant.Bool {
|
||||||
@ -52,10 +52,10 @@ func ResolveUntypedConstsForBinaryOp(lhs, rhs constant.Value, lhst, rhst Type) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rhst.Main == None {
|
if rhst.Main == None {
|
||||||
if (lhst.Main == Float || lhst.isFloatVector() || lhst.IsMatrix()) && constant.ToFloat(rhs).Kind() != constant.Unknown {
|
if (lhst.Main == Float || lhst.IsFloatVector() || lhst.IsMatrix()) && constant.ToFloat(rhs).Kind() != constant.Unknown {
|
||||||
return lhs, constant.ToFloat(rhs), true
|
return lhs, constant.ToFloat(rhs), true
|
||||||
}
|
}
|
||||||
if (lhst.Main == Int || lhst.isIntVector()) && constant.ToInt(rhs).Kind() != constant.Unknown {
|
if (lhst.Main == Int || lhst.IsIntVector()) && constant.ToInt(rhs).Kind() != constant.Unknown {
|
||||||
return lhs, constant.ToInt(rhs), true
|
return lhs, constant.ToInt(rhs), true
|
||||||
}
|
}
|
||||||
if lhst.Main == Bool && rhs.Kind() == constant.Bool {
|
if lhst.Main == Bool && rhs.Kind() == constant.Bool {
|
||||||
@ -122,7 +122,7 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
|||||||
if lhst.Main == IVec4 && rhst.Main == IVec4 {
|
if lhst.Main == IVec4 && rhst.Main == IVec4 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return (lhst.Main == Int || lhst.isIntVector()) && rhst.Main == Int
|
return (lhst.Main == Int || lhst.IsIntVector()) && rhst.Main == Int
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhst.Equal(&rhst) {
|
if lhst.Equal(&rhst) {
|
||||||
@ -164,16 +164,16 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
|||||||
// fallback
|
// fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhst.isFloatVector() && rhst.Main == Float {
|
if lhst.IsFloatVector() && rhst.Main == Float {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if rhst.isFloatVector() && lhst.Main == Float {
|
if rhst.IsFloatVector() && lhst.Main == Float {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if lhst.isIntVector() && rhst.Main == Int {
|
if lhst.IsIntVector() && rhst.Main == Int {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if rhst.isIntVector() && lhst.Main == Int {
|
if rhst.IsIntVector() && lhst.Main == Int {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ func (t *Type) IsVector() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) isFloatVector() bool {
|
func (t *Type) IsFloatVector() bool {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case Vec2, Vec3, Vec4:
|
case Vec2, Vec3, Vec4:
|
||||||
return true
|
return true
|
||||||
@ -134,7 +134,7 @@ func (t *Type) isFloatVector() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) isIntVector() bool {
|
func (t *Type) IsIntVector() bool {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case IVec2, IVec3, IVec4:
|
case IVec2, IVec3, IVec4:
|
||||||
return true
|
return true
|
||||||
|
Loading…
Reference in New Issue
Block a user