mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
shader: Implment defining variables in multiple-value context
This commit is contained in:
parent
75706504bf
commit
91fb8e92d8
@ -542,28 +542,69 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
|
||||
case *ast.AssignStmt:
|
||||
switch l.Tok {
|
||||
case token.DEFINE:
|
||||
if len(l.Lhs) != len(l.Rhs) && len(l.Rhs) != 1 {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
return nil
|
||||
}
|
||||
|
||||
var rhsTypes []shaderir.Type
|
||||
for i, e := range l.Lhs {
|
||||
v := variable{
|
||||
name: e.(*ast.Ident).Name,
|
||||
}
|
||||
ts := cs.detectType(block, l.Rhs[i])
|
||||
if len(ts) > 1 {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("the numbers of lhs and rhs don't match"))
|
||||
if len(l.Lhs) == len(l.Rhs) {
|
||||
ts := cs.detectType(block, l.Rhs[i])
|
||||
if len(ts) > 1 {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
}
|
||||
v.typ = ts[0]
|
||||
} else {
|
||||
if i == 0 {
|
||||
rhsTypes = cs.detectType(block, l.Rhs[0])
|
||||
if len(rhsTypes) != len(l.Lhs) {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
}
|
||||
}
|
||||
v.typ = rhsTypes[i]
|
||||
}
|
||||
v.typ = ts[0]
|
||||
block.vars = append(block.vars, v)
|
||||
}
|
||||
|
||||
var rhsExprs []shaderir.Expr
|
||||
for i := range l.Lhs {
|
||||
// Prase RHS first for the order of the statements.
|
||||
rhs, stmts := cs.parseExpr(block, l.Rhs[i])
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
lhs, stmts := cs.parseExpr(block, l.Lhs[i])
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
if len(l.Lhs) == len(l.Rhs) {
|
||||
rhs, stmts := cs.parseExpr(block, l.Rhs[i])
|
||||
if len(rhs) > 1 {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
}
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
|
||||
// TODO: Treat multiple expressions
|
||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||
Type: shaderir.Assign,
|
||||
Exprs: []shaderir.Expr{lhs[0], rhs[0]},
|
||||
})
|
||||
lhs, stmts := cs.parseExpr(block, l.Lhs[i])
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
|
||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||
Type: shaderir.Assign,
|
||||
Exprs: []shaderir.Expr{lhs[0], rhs[0]},
|
||||
})
|
||||
} else {
|
||||
if i == 0 {
|
||||
var stmts []shaderir.Stmt
|
||||
rhsExprs, stmts = cs.parseExpr(block, l.Rhs[0])
|
||||
if len(rhsExprs) != len(l.Lhs) {
|
||||
cs.addError(l.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
}
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
}
|
||||
|
||||
lhs, stmts := cs.parseExpr(block, l.Lhs[i])
|
||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||
|
||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||
Type: shaderir.Assign,
|
||||
Exprs: []shaderir.Expr{lhs[0], rhsExprs[i]},
|
||||
})
|
||||
}
|
||||
}
|
||||
case token.ASSIGN:
|
||||
// TODO: What about the statement `a,b = b,a?`
|
||||
|
17
internal/shader/testdata/define_multiple.expected.vs
vendored
Normal file
17
internal/shader/testdata/define_multiple.expected.vs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
void F0(in vec2 l0, out vec4 l1) {
|
||||
float l2 = 0.0;
|
||||
float l3 = 0.0;
|
||||
float l4 = 0.0;
|
||||
float l5 = 0.0;
|
||||
F1(l4, l5);
|
||||
l2 = l4;
|
||||
l3 = l5;
|
||||
l1 = vec4(l0, l2, l2);
|
||||
return;
|
||||
}
|
||||
|
||||
void F1(out float l0, out float l1) {
|
||||
l0 = 0.0;
|
||||
l1 = 0.0;
|
||||
return;
|
||||
}
|
10
internal/shader/testdata/define_multiple.go
vendored
Normal file
10
internal/shader/testdata/define_multiple.go
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
func Foo(foo vec2) vec4 {
|
||||
r1, r2 := Bar()
|
||||
return vec4(foo, r1, r1)
|
||||
}
|
||||
|
||||
func Bar() (float, float) {
|
||||
return 0, 0
|
||||
}
|
@ -89,7 +89,19 @@ func (cs *compileState) detectType(b *block, expr ast.Expr) []shaderir.Type {
|
||||
return []shaderir.Type{{Main: shaderir.Mat3}}
|
||||
case shaderir.Mat4F:
|
||||
return []shaderir.Type{{Main: shaderir.Mat4}}
|
||||
default:
|
||||
// TODO: Add more functions
|
||||
cs.addError(expr.Pos(), fmt.Sprintf("detecting types is not implemented for: %s", n))
|
||||
}
|
||||
}
|
||||
for _, f := range cs.funcs {
|
||||
if f.name == n {
|
||||
// TODO: Is it correct to combine out-params and return param?
|
||||
ts := f.ir.OutParams
|
||||
if f.ir.Return.Main != shaderir.None {
|
||||
ts = append(ts, f.ir.Return)
|
||||
}
|
||||
return ts
|
||||
}
|
||||
}
|
||||
cs.addError(expr.Pos(), fmt.Sprintf("unexpected call: %s", n))
|
||||
|
Loading…
Reference in New Issue
Block a user