internal/shaderir: use ConstType just for an assetion

Updates #2550
This commit is contained in:
Hajime Hoshi 2023-07-27 23:00:55 +09:00
parent f3023ae88e
commit e225f118fb
6 changed files with 146 additions and 74 deletions

View File

@ -353,18 +353,39 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
cs.addError(e.Pos(), err.Error()) cs.addError(e.Pos(), err.Error())
return nil, nil, nil, false return nil, nil, nil, false
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Vec2} t = shaderir.Type{Main: shaderir.Vec2}
case shaderir.Vec3F: case shaderir.Vec3F:
if err := checkArgsForVec3BuiltinFunc(args, argts); err != nil { if err := checkArgsForVec3BuiltinFunc(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
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Vec3} t = shaderir.Type{Main: shaderir.Vec3}
case shaderir.Vec4F: case shaderir.Vec4F:
if err := checkArgsForVec4BuiltinFunc(args, argts); err != nil { if err := checkArgsForVec4BuiltinFunc(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
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Vec4} t = shaderir.Type{Main: shaderir.Vec4}
case shaderir.IVec2F: case shaderir.IVec2F:
if err := checkArgsForIVec2BuiltinFunc(args, argts); err != nil { if err := checkArgsForIVec2BuiltinFunc(args, argts); err != nil {
@ -389,18 +410,39 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
cs.addError(e.Pos(), err.Error()) cs.addError(e.Pos(), err.Error())
return nil, nil, nil, false return nil, nil, nil, false
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Mat2} t = shaderir.Type{Main: shaderir.Mat2}
case shaderir.Mat3F: case shaderir.Mat3F:
if err := checkArgsForMat3BuiltinFunc(args, argts); err != nil { if err := checkArgsForMat3BuiltinFunc(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
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Mat3} t = shaderir.Type{Main: shaderir.Mat3}
case shaderir.Mat4F: case shaderir.Mat4F:
if err := checkArgsForMat4BuiltinFunc(args, argts); err != nil { if err := checkArgsForMat4BuiltinFunc(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
} }
for i := range args {
if args[i].Const == nil {
continue
}
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
t = shaderir.Type{Main: shaderir.Mat4} t = shaderir.Type{Main: shaderir.Mat4}
case shaderir.TexelAt: case shaderir.TexelAt:
if len(args) != 2 { if len(args) != 2 {
@ -598,16 +640,21 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
} }
for i, p := range f.ir.InParams { for i, p := range f.ir.InParams {
if args[i].Const != nil && p.Main == shaderir.Int {
if !cs.forceToInt(e, &args[i]) {
return nil, nil, nil, false
}
}
if !canAssign(&p, &argts[i], args[i].Const) { if !canAssign(&p, &argts[i], args[i].Const) {
cs.addError(e.Pos(), fmt.Sprintf("cannot use type %s as type %s in argument", argts[i].String(), p.String())) cs.addError(e.Pos(), fmt.Sprintf("cannot use type %s as type %s in argument", argts[i].String(), p.String()))
return nil, nil, nil, false return nil, nil, nil, false
} }
if args[i].Const != nil {
switch p.Main {
case shaderir.Int:
args[i].Const = gconstant.ToInt(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Int}
case shaderir.Float:
args[i].Const = gconstant.ToFloat(args[i].Const)
argts[i] = shaderir.Type{Main: shaderir.Float}
}
}
} }
var outParams []int var outParams []int

View File

@ -507,15 +507,18 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
} }
t = shaderir.Type{Main: shaderir.Bool} t = shaderir.Type{Main: shaderir.Bool}
case shaderir.Int: case shaderir.Int:
if !cs.forceToInt(stmt, &expr) { if gconstant.ToInt(expr.Const).Kind() == gconstant.Unknown {
cs.addError(stmt.Pos(), fmt.Sprintf("cannot use type %s as type %s in return argument", t.String(), &outT))
return nil, false return nil, false
} }
expr.Const = gconstant.ToInt(expr.Const)
t = shaderir.Type{Main: shaderir.Int} t = shaderir.Type{Main: shaderir.Int}
case shaderir.Float: case shaderir.Float:
if gconstant.ToFloat(expr.Const).Kind() == gconstant.Unknown { if gconstant.ToFloat(expr.Const).Kind() == gconstant.Unknown {
cs.addError(stmt.Pos(), fmt.Sprintf("cannot use type %s as type %s in return argument", t.String(), &outT)) cs.addError(stmt.Pos(), fmt.Sprintf("cannot use type %s as type %s in return argument", t.String(), &outT))
return nil, false return nil, false
} }
expr.Const = gconstant.ToFloat(expr.Const)
t = shaderir.Type{Main: shaderir.Float} t = shaderir.Type{Main: shaderir.Float}
} }
} }
@ -843,7 +846,7 @@ func canAssign(lt *shaderir.Type, rt *shaderir.Type, rc gconstant.Value) bool {
case shaderir.Bool: case shaderir.Bool:
return rc.Kind() == gconstant.Bool return rc.Kind() == gconstant.Bool
case shaderir.Int: case shaderir.Int:
return canTruncateToInteger(rc) return gconstant.ToInt(rc).Kind() != gconstant.Unknown
case shaderir.Float: case shaderir.Float:
return gconstant.ToFloat(rc).Kind() != gconstant.Unknown return gconstant.ToFloat(rc).Kind() != gconstant.Unknown
} }

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"go/constant" "go/constant"
"go/token" "go/token"
"math"
"regexp" "regexp"
"strings" "strings"
@ -377,29 +378,30 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
} }
func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string { func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
switch t { switch v.Kind() {
case shaderir.ConstTypeNone: case constant.Bool:
if v.Kind() == constant.Bool { if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
if constant.BoolVal(v) { return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
return "true"
}
return "false"
} }
fallthrough if constant.BoolVal(v) {
case shaderir.ConstTypeFloat: return "true"
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
} }
if i := constant.ToFloat(v); i.Kind() == constant.Float { return "false"
x, _ := constant.Float64Val(i) case constant.Int:
return fmt.Sprintf("%.10e", x) if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
} }
case shaderir.ConstTypeInt: x, _ := constant.Int64Val(v)
if i := constant.ToInt(v); i.Kind() == constant.Int { return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(i) case constant.Float:
return fmt.Sprintf("%d", x) if t != shaderir.ConstTypeFloat && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for float: %d)", t)
} }
x, _ := constant.Float64Val(v)
if i := math.Floor(x); i == x {
return fmt.Sprintf("%d.0", int64(i))
}
return fmt.Sprintf("%.10e", x)
} }
return fmt.Sprintf("?(unexpected literal: %s)", v) return fmt.Sprintf("?(unexpected literal: %s)", v)
} }

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"go/constant" "go/constant"
"go/token" "go/token"
"math"
"regexp" "regexp"
"strings" "strings"
@ -310,29 +311,30 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
} }
func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string { func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
switch t { switch v.Kind() {
case shaderir.ConstTypeNone: case constant.Bool:
if v.Kind() == constant.Bool { if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
if constant.BoolVal(v) { return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
return "true"
}
return "false"
} }
fallthrough if constant.BoolVal(v) {
case shaderir.ConstTypeFloat: return "true"
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
} }
if i := constant.ToFloat(v); i.Kind() == constant.Float { return "false"
x, _ := constant.Float64Val(i) case constant.Int:
return fmt.Sprintf("%.10e", x) if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
} }
case shaderir.ConstTypeInt: x, _ := constant.Int64Val(v)
if i := constant.ToInt(v); i.Kind() == constant.Int { return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(i) case constant.Float:
return fmt.Sprintf("%d", x) if t != shaderir.ConstTypeFloat && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for float: %d)", t)
} }
x, _ := constant.Float64Val(v)
if i := math.Floor(x); i == x {
return fmt.Sprintf("%d.0", int64(i))
}
return fmt.Sprintf("%.10e", x)
} }
return fmt.Sprintf("?(unexpected literal: %s)", v) return fmt.Sprintf("?(unexpected literal: %s)", v)
} }

View File

@ -68,15 +68,31 @@ func ifStmt(cond shaderir.Expr, block *shaderir.Block, elseBlock *shaderir.Block
} }
func forStmt(t shaderir.Type, index, init, end int, op shaderir.Op, delta int, block *shaderir.Block) shaderir.Stmt { func forStmt(t shaderir.Type, index, init, end int, op shaderir.Op, delta int, block *shaderir.Block) shaderir.Stmt {
return shaderir.Stmt{ switch t.Main {
Type: shaderir.For, case shaderir.Int:
Blocks: []*shaderir.Block{block}, return shaderir.Stmt{
ForVarType: t, Type: shaderir.For,
ForVarIndex: index, Blocks: []*shaderir.Block{block},
ForInit: constant.MakeInt64(int64(init)), ForVarType: t,
ForEnd: constant.MakeInt64(int64(end)), ForVarIndex: index,
ForOp: op, ForInit: constant.MakeInt64(int64(init)),
ForDelta: constant.MakeInt64(int64(delta)), ForEnd: constant.MakeInt64(int64(end)),
ForOp: op,
ForDelta: constant.MakeInt64(int64(delta)),
}
case shaderir.Float:
return shaderir.Stmt{
Type: shaderir.For,
Blocks: []*shaderir.Block{block},
ForVarType: t,
ForVarIndex: index,
ForInit: constant.MakeFloat64(float64(init)),
ForEnd: constant.MakeFloat64(float64(end)),
ForOp: op,
ForDelta: constant.MakeFloat64(float64(delta)),
}
default:
panic("not reached")
} }
} }

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"go/constant" "go/constant"
"go/token" "go/token"
"math"
"regexp" "regexp"
"strings" "strings"
@ -260,29 +261,30 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
} }
func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string { func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
switch t { switch v.Kind() {
case shaderir.ConstTypeNone: case constant.Bool:
if v.Kind() == constant.Bool { if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
if constant.BoolVal(v) { return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
return "true"
}
return "false"
} }
fallthrough if constant.BoolVal(v) {
case shaderir.ConstTypeFloat: return "true"
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
} }
if i := constant.ToFloat(v); i.Kind() == constant.Float { return "false"
x, _ := constant.Float64Val(i) case constant.Int:
return fmt.Sprintf("%.10e", x) if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
} }
case shaderir.ConstTypeInt: x, _ := constant.Int64Val(v)
if i := constant.ToInt(v); i.Kind() == constant.Int { return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(i) case constant.Float:
return fmt.Sprintf("%d", x) if t != shaderir.ConstTypeFloat && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for float: %d)", t)
} }
x, _ := constant.Float64Val(v)
if i := math.Floor(x); i == x {
return fmt.Sprintf("%d.0", int64(i))
}
return fmt.Sprintf("%.10e", x)
} }
return fmt.Sprintf("?(unexpected literal: %s)", v) return fmt.Sprintf("?(unexpected literal: %s)", v)
} }