shaderir: Add Stmt.ForVarType and use constant.Value

Updates #1230
This commit is contained in:
Hajime Hoshi 2020-07-12 22:22:22 +09:00
parent 291d69500b
commit f95ca46c99
3 changed files with 58 additions and 37 deletions

View File

@ -17,6 +17,7 @@ package shaderir
import ( import (
"fmt" "fmt"
"go/constant" "go/constant"
"go/token"
"strings" "strings"
) )
@ -231,6 +232,34 @@ func (p *Program) glslFunc(f *Func) []string {
return lines return lines
} }
func constantToNumberLiteral(t ConstType, v constant.Value) string {
switch t {
case ConstTypeNone:
if v.Kind() == constant.Bool {
if constant.BoolVal(v) {
return "true"
}
return "false"
}
fallthrough
case ConstTypeFloat:
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 {
x, _ := constant.Float64Val(i)
return fmt.Sprintf("%.9e", x)
}
case ConstTypeInt:
if i := constant.ToInt(v); i.Kind() == constant.Int {
x, _ := constant.Int64Val(i)
return fmt.Sprintf("%d", x)
}
}
return fmt.Sprintf("?(unexpected literal: %s)", v)
}
func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int) []string { func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int) []string {
idt := strings.Repeat("\t", level+1) idt := strings.Repeat("\t", level+1)
@ -244,31 +273,7 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int
glslExpr = func(e *Expr) string { glslExpr = func(e *Expr) string {
switch e.Type { switch e.Type {
case NumberExpr: case NumberExpr:
switch e.ConstType { return constantToNumberLiteral(e.ConstType, e.Const)
case ConstTypeNone:
if e.Const.Kind() == constant.Bool {
if constant.BoolVal(e.Const) {
return "true"
}
return "false"
}
fallthrough
case ConstTypeFloat:
if i := constant.ToInt(e.Const); i.Kind() == constant.Int {
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 TextureVariable: case TextureVariable:
@ -364,20 +369,30 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int
} }
lines = append(lines, fmt.Sprintf("%s}", idt)) lines = append(lines, fmt.Sprintf("%s}", idt))
case For: case For:
var ct ConstType
switch s.ForVarType.Main {
case Int:
ct = ConstTypeInt
case Float:
ct = ConstTypeFloat
}
v := s.ForVarIndex v := s.ForVarIndex
var delta string var delta string
switch s.ForDelta { switch val, _ := constant.Float64Val(s.ForDelta); val {
case 0: case 0:
delta = fmt.Sprintf("?(unexpected delta: %d)", s.ForDelta) delta = fmt.Sprintf("?(unexpected delta: %v)", s.ForDelta)
case 1: case 1:
delta = fmt.Sprintf("l%d++", v) delta = fmt.Sprintf("l%d++", v)
case -1: case -1:
delta = fmt.Sprintf("l%d--", v) delta = fmt.Sprintf("l%d--", v)
default: default:
if s.ForDelta > 0 { d := s.ForDelta
delta = fmt.Sprintf("l%d += %d", v, s.ForDelta) if val > 0 {
delta = fmt.Sprintf("l%d += %s", v, constantToNumberLiteral(ct, d))
} else { } else {
delta = fmt.Sprintf("l%d -= %d", v, -s.ForDelta) d = constant.UnaryOp(token.SUB, d, 0)
delta = fmt.Sprintf("l%d -= %s", v, constantToNumberLiteral(ct, d))
} }
} }
var op string var op string
@ -387,7 +402,11 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int
default: default:
op = fmt.Sprintf("?(unexpected op: %s)", string(s.ForOp)) op = fmt.Sprintf("?(unexpected op: %s)", string(s.ForOp))
} }
lines = append(lines, fmt.Sprintf("%sfor (int l%d = %d; l%d %s %d; %s) {", idt, v, s.ForInit, v, op, s.ForEnd, delta))
t := s.ForVarType.Main
init := constantToNumberLiteral(ct, s.ForInit)
end := constantToNumberLiteral(ct, s.ForEnd)
lines = append(lines, fmt.Sprintf("%sfor (%s l%d = %s; l%d %s %s; %s) {", idt, t.Glsl(), v, init, v, op, end, delta))
lines = append(lines, p.glslBlock(topBlock, &s.Blocks[0], level+1, localVarIndex)...) lines = append(lines, p.glslBlock(topBlock, &s.Blocks[0], level+1, localVarIndex)...)
lines = append(lines, fmt.Sprintf("%s}", idt)) lines = append(lines, fmt.Sprintf("%s}", idt))
case Continue: case Continue:

View File

@ -68,11 +68,12 @@ func forStmt(index, init, end int, op Op, delta int, block Block) Stmt {
return Stmt{ return Stmt{
Type: For, Type: For,
Blocks: []Block{block}, Blocks: []Block{block},
ForVarType: Type{Main: Int},
ForVarIndex: index, ForVarIndex: index,
ForInit: init, ForInit: constant.MakeInt64(int64(init)),
ForEnd: end, ForEnd: constant.MakeInt64(int64(end)),
ForOp: op, ForOp: op,
ForDelta: delta, ForDelta: constant.MakeInt64(int64(delta)),
} }
} }

View File

@ -67,11 +67,12 @@ type Stmt struct {
Type StmtType Type StmtType
Exprs []Expr Exprs []Expr
Blocks []Block Blocks []Block
ForVarType Type
ForVarIndex int ForVarIndex int
ForInit int ForInit constant.Value
ForEnd int ForEnd constant.Value
ForOp Op ForOp Op
ForDelta int ForDelta constant.Value
} }
type StmtType int type StmtType int