mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
parent
face5fd870
commit
e8cdf885c0
@ -486,24 +486,78 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
|||||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
|
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
for i := range args {
|
|
||||||
// If the argument is a non-typed constant value, treat this as a float value (#1874).
|
switch callee.BuiltinFunc {
|
||||||
if args[i].Const != nil && argts[i].Main == shaderir.None && gconstant.ToFloat(args[i].Const).Kind() != gconstant.Unknown {
|
case shaderir.Min, shaderir.Max:
|
||||||
args[i].Const = gconstant.ToFloat(args[i].Const)
|
if args[0].Const != nil && args[1].Const != nil {
|
||||||
argts[i] = shaderir.Type{Main: shaderir.Float}
|
if gconstant.ToInt(args[0].Const).Kind() != gconstant.Unknown && gconstant.ToInt(args[1].Const).Kind() != gconstant.Unknown {
|
||||||
|
args[0].Const = gconstant.ToInt(args[0].Const)
|
||||||
|
args[1].Const = gconstant.ToInt(args[1].Const)
|
||||||
|
argts[0] = shaderir.Type{Main: shaderir.Int}
|
||||||
|
argts[1] = shaderir.Type{Main: shaderir.Int}
|
||||||
|
} else if gconstant.ToFloat(args[0].Const).Kind() != gconstant.Unknown && gconstant.ToFloat(args[1].Const).Kind() != gconstant.Unknown {
|
||||||
|
args[0].Const = gconstant.ToFloat(args[0].Const)
|
||||||
|
args[1].Const = gconstant.ToFloat(args[1].Const)
|
||||||
|
argts[0] = shaderir.Type{Main: shaderir.Float}
|
||||||
|
argts[1] = shaderir.Type{Main: shaderir.Float}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if argts[i].Main != shaderir.Float && argts[i].Main != shaderir.Vec2 && argts[i].Main != shaderir.Vec3 && argts[i].Main != shaderir.Vec4 {
|
if argts[0].IsIntVector() && args[1].Const != nil {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
v := gconstant.ToInt(args[1].Const)
|
||||||
return nil, nil, nil, false
|
if v.Kind() == gconstant.Unknown {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[1].Const.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
args[1].Const = v
|
||||||
|
argts[1] = shaderir.Type{Main: shaderir.Int}
|
||||||
|
}
|
||||||
|
if argts[0].IsFloatVector() && args[1].Const != nil {
|
||||||
|
v := gconstant.ToFloat(args[1].Const)
|
||||||
|
if v.Kind() == gconstant.Unknown {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[1].Const.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
args[1].Const = v
|
||||||
|
argts[1] = shaderir.Type{Main: shaderir.Float}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for i := range args {
|
||||||
|
if args[i].Const != nil && argts[i].Main == shaderir.None {
|
||||||
|
// If the argument is a non-typed constant value, treat this as a float value (#1874).
|
||||||
|
if gconstant.ToFloat(args[i].Const).Kind() != gconstant.Unknown {
|
||||||
|
args[i].Const = gconstant.ToFloat(args[i].Const)
|
||||||
|
argts[i] = shaderir.Type{Main: shaderir.Float}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range args {
|
||||||
|
switch callee.BuiltinFunc {
|
||||||
|
case shaderir.Min, shaderir.Max:
|
||||||
|
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() && argts[i].Main != shaderir.Int && !argts[i].IsIntVector() {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivecN value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch callee.BuiltinFunc {
|
switch callee.BuiltinFunc {
|
||||||
case shaderir.Mod, shaderir.Min, shaderir.Max:
|
case shaderir.Mod:
|
||||||
if !argts[0].Equal(&argts[1]) && argts[1].Main != shaderir.Float {
|
if !argts[0].Equal(&argts[1]) && argts[1].Main != shaderir.Float {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
|
case shaderir.Min, shaderir.Max:
|
||||||
|
if !(argts[0].Equal(&argts[1]) || (argts[0].IsFloatVector() && argts[1].Main == shaderir.Float) || (argts[0].IsIntVector() && argts[1].Main == shaderir.Int)) {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float or int but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
case shaderir.Step:
|
case shaderir.Step:
|
||||||
if !argts[0].Equal(&argts[1]) && argts[0].Main != shaderir.Float {
|
if !argts[0].Equal(&argts[1]) && argts[0].Main != shaderir.Float {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("the first argument for %s must equal to the second argument %s or float but %s", callee.BuiltinFunc, argts[1].String(), argts[0].String()))
|
cs.addError(e.Pos(), fmt.Sprintf("the first argument for %s must equal to the second argument %s or float but %s", callee.BuiltinFunc, argts[1].String(), argts[0].String()))
|
||||||
|
@ -2275,6 +2275,81 @@ func TestSyntaxBuiltinFuncDoubleArgsType2(t *testing.T) {
|
|||||||
|
|
||||||
funcs := []string{
|
funcs := []string{
|
||||||
"mod",
|
"mod",
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
for _, f := range funcs {
|
||||||
|
stmt := strings.ReplaceAll(c.stmt, "{{.Func}}", f)
|
||||||
|
src := fmt.Sprintf(`package main
|
||||||
|
|
||||||
|
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||||
|
%s
|
||||||
|
return dstPos
|
||||||
|
}`, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSyntaxBuiltinFuncArgsMinMax(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
stmt string
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{stmt: "a := {{.Func}}(); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1); _ = a", err: true}, // TODO: Allow this (#2677).
|
||||||
|
{stmt: "a := {{.Func}}(false, false); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, 1); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1.0, 1); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1, 1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1.1, 1); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1, 1.1); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(int(1), int(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1, vec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, vec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, vec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, ivec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, ivec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(1, ivec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec2(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(vec2(1), vec2(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(vec2(1), vec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec2(1), vec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec3(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(vec3(1), vec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec3(1), vec3(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(vec3(1), vec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec4(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(vec4(1), vec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec4(1), vec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(vec4(1), vec4(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(mat2(1), mat2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), 1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), 1.1); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), ivec2(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), ivec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec2(1), ivec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), 1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), 1.1); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), ivec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), ivec3(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(ivec3(1), ivec4(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), 1.0); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), 1.1); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), ivec2(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), ivec3(1)); _ = a", err: true},
|
||||||
|
{stmt: "a := {{.Func}}(ivec4(1), ivec4(1)); _ = a", err: false},
|
||||||
|
{stmt: "a := {{.Func}}(1, 1, 1); _ = a", err: true}, // TODO: Allow this (#2677).
|
||||||
|
}
|
||||||
|
|
||||||
|
funcs := []string{
|
||||||
"min",
|
"min",
|
||||||
"max",
|
"max",
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user