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())
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}
case shaderir.Vec3F:
if err := checkArgsForVec3BuiltinFunc(args, argts); err != nil {
cs.addError(e.Pos(), err.Error())
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}
case shaderir.Vec4F:
if err := checkArgsForVec4BuiltinFunc(args, argts); err != nil {
cs.addError(e.Pos(), err.Error())
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}
case shaderir.IVec2F:
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())
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}
case shaderir.Mat3F:
if err := checkArgsForMat3BuiltinFunc(args, argts); err != nil {
cs.addError(e.Pos(), err.Error())
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}
case shaderir.Mat4F:
if err := checkArgsForMat4BuiltinFunc(args, argts); err != nil {
cs.addError(e.Pos(), err.Error())
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}
case shaderir.TexelAt:
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 {
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) {
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
}
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

View File

@ -507,15 +507,18 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
}
t = shaderir.Type{Main: shaderir.Bool}
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
}
expr.Const = gconstant.ToInt(expr.Const)
t = shaderir.Type{Main: shaderir.Int}
case shaderir.Float:
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))
return nil, false
}
expr.Const = gconstant.ToFloat(expr.Const)
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:
return rc.Kind() == gconstant.Bool
case shaderir.Int:
return canTruncateToInteger(rc)
return gconstant.ToInt(rc).Kind() != gconstant.Unknown
case shaderir.Float:
return gconstant.ToFloat(rc).Kind() != gconstant.Unknown
}

View File

@ -18,6 +18,7 @@ import (
"fmt"
"go/constant"
"go/token"
"math"
"regexp"
"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 {
switch t {
case shaderir.ConstTypeNone:
if v.Kind() == constant.Bool {
if constant.BoolVal(v) {
return "true"
}
return "false"
switch v.Kind() {
case constant.Bool:
if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
}
fallthrough
case shaderir.ConstTypeFloat:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
if constant.BoolVal(v) {
return "true"
}
if i := constant.ToFloat(v); i.Kind() == constant.Float {
x, _ := constant.Float64Val(i)
return fmt.Sprintf("%.10e", x)
return "false"
case constant.Int:
if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
}
case shaderir.ConstTypeInt:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(v)
return fmt.Sprintf("%d", x)
case constant.Float:
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)
}

View File

@ -18,6 +18,7 @@ import (
"fmt"
"go/constant"
"go/token"
"math"
"regexp"
"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 {
switch t {
case shaderir.ConstTypeNone:
if v.Kind() == constant.Bool {
if constant.BoolVal(v) {
return "true"
}
return "false"
switch v.Kind() {
case constant.Bool:
if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
}
fallthrough
case shaderir.ConstTypeFloat:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
if constant.BoolVal(v) {
return "true"
}
if i := constant.ToFloat(v); i.Kind() == constant.Float {
x, _ := constant.Float64Val(i)
return fmt.Sprintf("%.10e", x)
return "false"
case constant.Int:
if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
}
case shaderir.ConstTypeInt:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(v)
return fmt.Sprintf("%d", x)
case constant.Float:
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)
}

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 {
return shaderir.Stmt{
Type: shaderir.For,
Blocks: []*shaderir.Block{block},
ForVarType: t,
ForVarIndex: index,
ForInit: constant.MakeInt64(int64(init)),
ForEnd: constant.MakeInt64(int64(end)),
ForOp: op,
ForDelta: constant.MakeInt64(int64(delta)),
switch t.Main {
case shaderir.Int:
return shaderir.Stmt{
Type: shaderir.For,
Blocks: []*shaderir.Block{block},
ForVarType: t,
ForVarIndex: index,
ForInit: constant.MakeInt64(int64(init)),
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"
"go/constant"
"go/token"
"math"
"regexp"
"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 {
switch t {
case shaderir.ConstTypeNone:
if v.Kind() == constant.Bool {
if constant.BoolVal(v) {
return "true"
}
return "false"
switch v.Kind() {
case constant.Bool:
if t != shaderir.ConstTypeBool && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for bool: %d)", t)
}
fallthrough
case shaderir.ConstTypeFloat:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
if constant.BoolVal(v) {
return "true"
}
if i := constant.ToFloat(v); i.Kind() == constant.Float {
x, _ := constant.Float64Val(i)
return fmt.Sprintf("%.10e", x)
return "false"
case constant.Int:
if t != shaderir.ConstTypeInt && t != shaderir.ConstTypeNone {
return fmt.Sprintf("!(unexpected const-type for int: %d)", t)
}
case shaderir.ConstTypeInt:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d", x)
x, _ := constant.Int64Val(v)
return fmt.Sprintf("%d", x)
case constant.Float:
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)
}