mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 18:52:44 +01:00
shader: Implement variable initialization in multiple-value context
This commit is contained in:
parent
1ca5dd16b2
commit
84fb951729
@ -257,17 +257,20 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i, v := range vs {
|
|
||||||
b.vars = append(b.vars, v)
|
base := len(b.vars)
|
||||||
if inits[i] != nil {
|
b.vars = append(b.vars, vs...)
|
||||||
|
|
||||||
|
if len(inits) > 0 {
|
||||||
|
for i := range vs {
|
||||||
b.ir.Stmts = append(b.ir.Stmts, shaderir.Stmt{
|
b.ir.Stmts = append(b.ir.Stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
{
|
{
|
||||||
Type: shaderir.LocalVariable,
|
Type: shaderir.LocalVariable,
|
||||||
Index: len(b.vars) - 1,
|
Index: base + i,
|
||||||
},
|
},
|
||||||
*inits[i],
|
inits[i],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -305,18 +308,38 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr, []shaderir.Stmt) {
|
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []shaderir.Expr, []shaderir.Stmt) {
|
||||||
|
if len(vs.Names) != len(vs.Values) && len(vs.Values) != 1 && len(vs.Values) != 0 {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("the numbers of lhs and rhs don't match"))
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
var t shaderir.Type
|
var t shaderir.Type
|
||||||
if vs.Type != nil {
|
if vs.Type != nil {
|
||||||
t = s.parseType(vs.Type)
|
t = s.parseType(vs.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars []variable
|
var (
|
||||||
var inits []*shaderir.Expr
|
vars []variable
|
||||||
var stmts []shaderir.Stmt
|
inits []shaderir.Expr
|
||||||
|
stmts []shaderir.Stmt
|
||||||
|
)
|
||||||
|
|
||||||
for i, n := range vs.Names {
|
for i, n := range vs.Names {
|
||||||
var init ast.Expr
|
var init ast.Expr
|
||||||
if len(vs.Values) > 0 {
|
switch len(vs.Values) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
init = vs.Values[0]
|
||||||
|
if t.Main == shaderir.None {
|
||||||
|
ts := s.detectType(block, init)
|
||||||
|
if len(ts) != len(vs.Names) {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("the numbers of lhs and rhs don't match"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t = ts[i]
|
||||||
|
}
|
||||||
|
default:
|
||||||
init = vs.Values[i]
|
init = vs.Values[i]
|
||||||
if t.Main == shaderir.None {
|
if t.Main == shaderir.None {
|
||||||
ts := s.detectType(block, init)
|
ts := s.detectType(block, init)
|
||||||
@ -326,20 +349,25 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
|
|||||||
t = ts[0]
|
t = ts[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := n.Name
|
name := n.Name
|
||||||
vars = append(vars, variable{
|
vars = append(vars, variable{
|
||||||
name: name,
|
name: name,
|
||||||
typ: t,
|
typ: t,
|
||||||
})
|
})
|
||||||
|
|
||||||
var expr *shaderir.Expr
|
if len(vs.Values) > 1 || (len(vs.Values) == 1 && len(inits) == 0) {
|
||||||
if init != nil {
|
es, ss := s.parseExpr(block, init)
|
||||||
e, ss := s.parseExpr(block, init)
|
inits = append(inits, es...)
|
||||||
expr = &e[0]
|
|
||||||
stmts = append(stmts, ss...)
|
stmts = append(stmts, ss...)
|
||||||
}
|
}
|
||||||
inits = append(inits, expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(inits) > 0 && len(vars) != len(inits) {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
return vars, inits, stmts
|
return vars, inits, stmts
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,6 +783,11 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t := f.ir.Return; t.Main != shaderir.None {
|
if t := f.ir.Return; t.Main != shaderir.None {
|
||||||
|
if len(outParams) == 0 {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("a function returning value cannot have out-params so far: %s", e.Fun))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
idx := len(block.vars)
|
idx := len(block.vars)
|
||||||
block.vars = append(block.vars, variable{
|
block.vars = append(block.vars, variable{
|
||||||
typ: t,
|
typ: t,
|
||||||
@ -797,18 +830,18 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: What about the other params?
|
if len(outParams) == 0 {
|
||||||
if len(outParams) > 0 {
|
// TODO: Is this an error?
|
||||||
return []shaderir.Expr{
|
|
||||||
{
|
|
||||||
Type: shaderir.LocalVariable,
|
|
||||||
Index: outParams[0],
|
|
||||||
},
|
|
||||||
}, stmts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Is an empty expression work?
|
var exprs []shaderir.Expr
|
||||||
return nil, stmts
|
for _, p := range outParams {
|
||||||
|
exprs = append(exprs, shaderir.Expr{
|
||||||
|
Type: shaderir.LocalVariable,
|
||||||
|
Index: p,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return exprs, stmts
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
if i, ok := block.findLocalVariable(e.Name); ok {
|
if i, ok := block.findLocalVariable(e.Name); ok {
|
||||||
return []shaderir.Expr{
|
return []shaderir.Expr{
|
||||||
|
@ -205,6 +205,35 @@ func Bar(x vec2) vec2 {
|
|||||||
void F1(in vec2 l0, out vec2 l1) {
|
void F1(in vec2 l0, out vec2 l1) {
|
||||||
l1 = l0;
|
l1 = l0;
|
||||||
return;
|
return;
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "call multiple out params",
|
||||||
|
Src: `package main
|
||||||
|
|
||||||
|
func Foo(x vec2) vec2 {
|
||||||
|
var xx, yx float = Bar(x.x, x.y)
|
||||||
|
return vec2(xx, yx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bar(x float) (float, float) {
|
||||||
|
return x, x
|
||||||
|
}`,
|
||||||
|
VS: `void F0(in vec2 l0, out vec2 l1) {
|
||||||
|
float l2 = 0.0;
|
||||||
|
float l3 = 0.0;
|
||||||
|
float l4 = 0.0;
|
||||||
|
float l5 = 0.0;
|
||||||
|
F1((l0).x, (l0).y, l2, l3);
|
||||||
|
l4 = l2;
|
||||||
|
l5 = l3;
|
||||||
|
l1 = vec2(l4, l5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void F1(in float l0, out float l1, out float l2) {
|
||||||
|
l1 = l0;
|
||||||
|
l2 = l0;
|
||||||
|
return;
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user