shaderir: Use constant.Value for number literals

Updates #1190
This commit is contained in:
Hajime Hoshi 2020-06-21 01:22:30 +09:00
parent 4b5de9f445
commit 912135d1e7
6 changed files with 47 additions and 31 deletions

View File

@ -17,8 +17,8 @@ package shader
import ( import (
"fmt" "fmt"
"go/ast" "go/ast"
gconstant "go/constant"
"go/token" "go/token"
"strconv"
"strings" "strings"
"github.com/hajimehoshi/ebiten/internal/shaderir" "github.com/hajimehoshi/ebiten/internal/shaderir"
@ -759,27 +759,17 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
case *ast.BasicLit: case *ast.BasicLit:
switch e.Kind { switch e.Kind {
case token.INT: case token.INT:
v, err := strconv.ParseInt(e.Value, 10, 32)
if err != nil {
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
return nil, nil, nil
}
return []shaderir.Expr{ return []shaderir.Expr{
{ {
Type: shaderir.IntExpr, Type: shaderir.NumberExpr,
Int: int32(v), Const: gconstant.MakeFromLiteral(e.Value, e.Kind, 0),
}, },
}, []shaderir.Type{{Main: shaderir.Int}}, nil }, []shaderir.Type{{Main: shaderir.Int}}, nil
case token.FLOAT: case token.FLOAT:
v, err := strconv.ParseFloat(e.Value, 32)
if err != nil {
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
return nil, nil, nil
}
return []shaderir.Expr{ return []shaderir.Expr{
{ {
Type: shaderir.FloatExpr, Type: shaderir.NumberExpr,
Float: float32(v), Const: gconstant.MakeFromLiteral(e.Value, e.Kind, 0),
}, },
}, []shaderir.Type{{Main: shaderir.Float}}, nil }, []shaderir.Type{{Main: shaderir.Float}}, nil
default: default:

View File

@ -1,7 +1,7 @@
void F0(in vec2 l0, out vec4 l1) { void F0(in vec2 l0, out vec4 l1) {
float l2 = float(0); float l2 = float(0);
l2 = 0.000000000e+00; l2 = 0.0;
l2 = (l2) + (1.000000000e+00); l2 = (l2) + (1.0);
l1 = vec4(l0, l2, l2); l1 = vec4(l0, l2, l2);
return; return;
} }

View File

@ -1,6 +1,6 @@
void F0(in vec2 l0, out vec4 l1) { void F0(in vec2 l0, out vec4 l1) {
vec4 l2 = vec4(0); vec4 l2 = vec4(0);
l2 = (vec4(0.000000000e+00)) * (vec4(0.000000000e+00)); l2 = (vec4(0.0)) * (vec4(0.0));
l1 = l2; l1 = l2;
return; return;
} }

View File

@ -16,6 +16,7 @@ package shaderir
import ( import (
"fmt" "fmt"
"go/constant"
"strings" "strings"
) )
@ -234,11 +235,24 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string {
var glslExpr func(e *Expr) string var glslExpr func(e *Expr) string
glslExpr = func(e *Expr) string { glslExpr = func(e *Expr) string {
switch e.Type { switch e.Type {
case IntExpr: case NumberExpr:
// TODO: Cast to int if the context requries integers. switch e.ConstType {
return fmt.Sprintf("%d.0", e.Int) case ConstTypeNone, ConstTypeFloat:
case FloatExpr: if i := constant.ToInt(e.Const); i.Kind() == constant.Int {
return fmt.Sprintf("%.9e", e.Float) x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d.0", x)
}
if i := constant.ToFloat(e.Const); i.Kind() == constant.Float {
x, _ := constant.Float64Val(i)
return fmt.Sprintf("%.9e", x)
}
case ConstTypeInt:
if i := constant.ToInt(e.Const); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d", x)
}
}
return fmt.Sprintf("?(unexpected literal: %s)", e.Const)
case UniformVariable: case UniformVariable:
return fmt.Sprintf("U%d", e.Index) return fmt.Sprintf("U%d", e.Index)
case LocalVariable: case LocalVariable:
@ -321,6 +335,7 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string {
lines = append(lines, p.glslBlock(&s.Blocks[0], level+1, localVarIndex)...) lines = append(lines, p.glslBlock(&s.Blocks[0], level+1, localVarIndex)...)
lines = append(lines, idt+"}") lines = append(lines, idt+"}")
case Assign: case Assign:
// TODO: Give an appropriate context
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, glslExpr(&s.Exprs[0]), glslExpr(&s.Exprs[1]))) lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, glslExpr(&s.Exprs[0]), glslExpr(&s.Exprs[1])))
case If: case If:
lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, glslExpr(&s.Exprs[0]))) lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, glslExpr(&s.Exprs[0])))
@ -366,6 +381,7 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string {
if len(s.Exprs) == 0 { if len(s.Exprs) == 0 {
lines = append(lines, idt+"return;") lines = append(lines, idt+"return;")
} else { } else {
// TODO: Give an appropriate context.
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, glslExpr(&s.Exprs[0]))) lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, glslExpr(&s.Exprs[0])))
} }
case Discard: case Discard:

View File

@ -15,6 +15,7 @@
package shaderir_test package shaderir_test
import ( import (
"go/constant"
"testing" "testing"
. "github.com/hajimehoshi/ebiten/internal/shaderir" . "github.com/hajimehoshi/ebiten/internal/shaderir"
@ -76,8 +77,8 @@ func forStmt(init, end int, op Op, delta int, block Block) Stmt {
func floatExpr(value float32) Expr { func floatExpr(value float32) Expr {
return Expr{ return Expr{
Type: FloatExpr, Type: NumberExpr,
Float: value, Const: constant.MakeFloat64(float64(value)),
} }
} }
@ -561,14 +562,14 @@ varying vec3 V0;`,
}, },
}, },
GlslVS: `void F0(in float l0, in float l1, out float l2) { GlslVS: `void F0(in float l0, in float l1, out float l2) {
if ((l0) == (0.000000000e+00)) { if ((l0) == (0.0)) {
l2 = l0; l2 = l0;
} else { } else {
l2 = l1; l2 = l1;
} }
}`, }`,
GlslFS: `void F0(in float l0, in float l1, out float l2) { GlslFS: `void F0(in float l0, in float l1, out float l2) {
if ((l0) == (0.000000000e+00)) { if ((l0) == (0.0)) {
l2 = l0; l2 = l0;
} else { } else {
l2 = l1; l2 = l1;

View File

@ -16,6 +16,7 @@
package shaderir package shaderir
import ( import (
"go/constant"
"go/token" "go/token"
) )
@ -85,11 +86,20 @@ const (
Discard Discard
) )
type ConstType int
const (
ConstTypeNone ConstType = iota
ConstTypeBool
ConstTypeInt
ConstTypeFloat
)
type Expr struct { type Expr struct {
Type ExprType Type ExprType
Exprs []Expr Exprs []Expr
Int int32 Const constant.Value
Float float32 ConstType ConstType
BuiltinFunc BuiltinFunc BuiltinFunc BuiltinFunc
Swizzling string Swizzling string
Index int Index int
@ -99,8 +109,7 @@ type Expr struct {
type ExprType int type ExprType int
const ( const (
IntExpr ExprType = iota NumberExpr ExprType = iota
FloatExpr
UniformVariable UniformVariable
LocalVariable LocalVariable
StructMember StructMember