mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/shader: refactoring
This commit is contained in:
parent
0657e67cef
commit
5a1109e56a
@ -34,22 +34,6 @@ func canTruncateToFloat(v gconstant.Value) bool {
|
||||
return gconstant.ToFloat(v).Kind() != gconstant.Unknown
|
||||
}
|
||||
|
||||
func isModAvailableForConsts(lhs, rhs *shaderir.Expr) bool {
|
||||
// % is available only when
|
||||
// 1) both are untyped (constant) integers
|
||||
// 2) either is an typed integer and the other is truncatable to an integer
|
||||
if lhs.Const.Kind() == gconstant.Int && rhs.Const.Kind() == gconstant.Int {
|
||||
return true
|
||||
}
|
||||
if lhs.Const.Kind() == gconstant.Int && canTruncateToInteger(rhs.Const) {
|
||||
return true
|
||||
}
|
||||
if rhs.Const.Kind() == gconstant.Int && canTruncateToInteger(lhs.Const) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isValidForModOp(lhs, rhs *shaderir.Expr, lhst, rhst shaderir.Type) bool {
|
||||
isInt := func(s *shaderir.Expr, t shaderir.Type) bool {
|
||||
if t.Main == shaderir.Int {
|
||||
@ -78,22 +62,6 @@ func isValidForModOp(lhs, rhs *shaderir.Expr, lhst, rhst shaderir.Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func goConstantKindString(k gconstant.Kind) string {
|
||||
switch k {
|
||||
case gconstant.Bool:
|
||||
return "bool"
|
||||
case gconstant.String:
|
||||
return "string"
|
||||
case gconstant.Int:
|
||||
return "int"
|
||||
case gconstant.Float:
|
||||
return "float"
|
||||
case gconstant.Complex:
|
||||
return "complex"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
var textureVariableRe = regexp.MustCompile(`\A__t(\d+)\z`)
|
||||
|
||||
func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, markLocalVariableUsed bool) ([]shaderir.Expr, []shaderir.Type, []shaderir.Stmt, bool) {
|
||||
@ -161,14 +129,16 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
|
||||
if lhs[0].Const != nil && rhs[0].Const != nil {
|
||||
if !shaderir.AreValidTypesForBinaryOp(op2, &lhs[0], &rhs[0], lhst, rhst) {
|
||||
// TODO: Show a better type name for untyped constants.
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
||||
var v gconstant.Value
|
||||
var t shaderir.Type
|
||||
switch op {
|
||||
case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ, token.LAND, token.LOR:
|
||||
if !shaderir.AreValidTypesForBinaryOp(op2, &lhs[0], &rhs[0], lhst, rhst) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
switch op {
|
||||
case token.LAND, token.LOR:
|
||||
b := gconstant.BoolVal(gconstant.BinaryOp(lhs[0].Const, op, rhs[0].Const))
|
||||
@ -178,16 +148,6 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.Bool}
|
||||
case token.REM:
|
||||
if !isModAvailableForConsts(&lhs[0], &rhs[0]) {
|
||||
var wrongTypeName string
|
||||
if lhs[0].Const.Kind() != gconstant.Int {
|
||||
wrongTypeName = goConstantKindString(lhs[0].Const.Kind())
|
||||
} else {
|
||||
wrongTypeName = goConstantKindString(rhs[0].Const.Kind())
|
||||
}
|
||||
cs.addError(e.Pos(), fmt.Sprintf("invalid operation: operator %% not defined on untyped %s", wrongTypeName))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if !cs.forceToInt(e, &lhs[0]) {
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
@ -196,11 +156,6 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
if !shaderir.AreValidTypesForBinaryOp(op2, &lhs[0], &rhs[0], lhst, rhst) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
||||
v = gconstant.BinaryOp(lhs[0].Const, op, rhs[0].Const)
|
||||
|
||||
switch {
|
||||
|
@ -36,6 +36,10 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
|
||||
// If both are untyped consts, compare the constants and try to truncate them if necessary.
|
||||
if lhst.Main == None && rhst.Main == None {
|
||||
// For %, both operands must be integers if both are constants. Truncatable to an integer is not enough.
|
||||
if op == ModOp {
|
||||
return lhs.Const.Kind() == constant.Int && rhs.Const.Kind() == constant.Int
|
||||
}
|
||||
if lhs.Const.Kind() == rhs.Const.Kind() {
|
||||
return true
|
||||
}
|
||||
@ -61,6 +65,10 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
|
||||
// If lhs is untyped and rhs is not, compare the constant and the type and try to truncate the constant if necessary.
|
||||
if lhst.Main == None {
|
||||
// For %, if only one of the operands is a constant, try to truncate it.
|
||||
if op == ModOp {
|
||||
return constant.ToInt(lhs.Const).Kind() != constant.Unknown && rhst.Main == Int
|
||||
}
|
||||
if rhst.Main == Float {
|
||||
return constant.ToFloat(lhs.Const).Kind() != constant.Unknown
|
||||
}
|
||||
@ -75,6 +83,9 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
|
||||
// Ditto.
|
||||
if rhst.Main == None {
|
||||
if op == ModOp {
|
||||
return constant.ToInt(rhs.Const).Kind() != constant.Unknown && lhst.Main == Int
|
||||
}
|
||||
if lhst.Main == Float {
|
||||
return constant.ToFloat(rhs.Const).Kind() != constant.Unknown
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user