mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
shader: Bug fix: Treat multiple-context at return correctly
This commit is contained in:
parent
2fb1033183
commit
d001f49ad7
@ -378,9 +378,10 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
|||||||
})
|
})
|
||||||
|
|
||||||
case *ast.ReturnStmt:
|
case *ast.ReturnStmt:
|
||||||
if len(stmt.Results) != len(outParams) {
|
if len(stmt.Results) != len(outParams) && len(stmt.Results) != 1 {
|
||||||
if !(len(stmt.Results) == 0 && len(outParams) > 0 && outParams[0].name != "") {
|
if !(len(stmt.Results) == 0 && len(outParams) > 0 && outParams[0].name != "") {
|
||||||
// TODO: Implenet multiple-value context.
|
// TODO: Check variable shadowings.
|
||||||
|
// https://golang.org/ref/spec#Return_statements
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("the number of returning variables must be %d but %d", len(outParams), len(stmt.Results)))
|
cs.addError(stmt.Pos(), fmt.Sprintf("the number of returning variables must be %d but %d", len(outParams), len(stmt.Results)))
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@ -393,42 +394,51 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
|||||||
}
|
}
|
||||||
stmts = append(stmts, ss...)
|
stmts = append(stmts, ss...)
|
||||||
if len(exprs) == 0 {
|
if len(exprs) == 0 {
|
||||||
|
if len(exprs) != len(outParams) {
|
||||||
|
cs.addError(stmt.Pos(), fmt.Sprintf("the number of returning variables must be %d but %d", len(outParams), len(stmt.Results)))
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(exprs) > 1 {
|
if len(exprs) > 1 {
|
||||||
cs.addError(r.Pos(), "multiple-value context with return is not implemented yet")
|
if len(stmt.Results) > 1 || len(outParams) == 1 {
|
||||||
continue
|
cs.addError(r.Pos(), "single-value context and multiple-value context cannot be mixed")
|
||||||
}
|
return nil, false
|
||||||
|
}
|
||||||
t := ts[0]
|
if len(exprs) != len(outParams) {
|
||||||
expr := exprs[0]
|
cs.addError(stmt.Pos(), fmt.Sprintf("the number of returning variables must be %d but %d", len(outParams), len(stmt.Results)))
|
||||||
if expr.Type == shaderir.NumberExpr {
|
|
||||||
switch outParams[i].typ.Main {
|
|
||||||
case shaderir.Int:
|
|
||||||
if !cs.forceToInt(stmt, &expr) {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
t = shaderir.Type{Main: shaderir.Int}
|
|
||||||
case shaderir.Float:
|
|
||||||
t = shaderir.Type{Main: shaderir.Float}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !t.Equal(&outParams[i].typ) {
|
for j, t := range ts {
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("cannot use type %s as type %s in return argument", &t, &outParams[i].typ))
|
expr := exprs[j]
|
||||||
return nil, false
|
if expr.Type == shaderir.NumberExpr {
|
||||||
}
|
switch outParams[i+j].typ.Main {
|
||||||
|
case shaderir.Int:
|
||||||
|
if !cs.forceToInt(stmt, &expr) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
t = shaderir.Type{Main: shaderir.Int}
|
||||||
|
case shaderir.Float:
|
||||||
|
t = shaderir.Type{Main: shaderir.Float}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stmts = append(stmts, shaderir.Stmt{
|
if !t.Equal(&outParams[i+j].typ) {
|
||||||
Type: shaderir.Assign,
|
cs.addError(stmt.Pos(), fmt.Sprintf("cannot use type %s as type %s in return argument", &t, &outParams[i].typ))
|
||||||
Exprs: []shaderir.Expr{
|
return nil, false
|
||||||
{
|
}
|
||||||
Type: shaderir.LocalVariable,
|
|
||||||
Index: len(inParams) + i,
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
|
Type: shaderir.Assign,
|
||||||
|
Exprs: []shaderir.Expr{
|
||||||
|
{
|
||||||
|
Type: shaderir.LocalVariable,
|
||||||
|
Index: len(inParams) + i + j,
|
||||||
|
},
|
||||||
|
expr,
|
||||||
},
|
},
|
||||||
expr,
|
})
|
||||||
},
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
stmts = append(stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Return,
|
Type: shaderir.Return,
|
||||||
|
36
internal/shader/testdata/out2.expected.vs
vendored
Normal file
36
internal/shader/testdata/out2.expected.vs
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
void F0(out float l0, out float l1[4], out vec4 l2);
|
||||||
|
void F1(out float l0, out float l1[4], out vec4 l2);
|
||||||
|
|
||||||
|
void F0(out float l0, out float l1[4], out vec4 l2) {
|
||||||
|
l0 = float(0);
|
||||||
|
l1[0] = float(0);
|
||||||
|
l1[1] = float(0);
|
||||||
|
l1[2] = float(0);
|
||||||
|
l1[3] = float(0);
|
||||||
|
l2 = vec4(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void F1(out float l0, out float l1[4], out vec4 l2) {
|
||||||
|
float l3 = float(0);
|
||||||
|
float l4[4];
|
||||||
|
l4[0] = float(0);
|
||||||
|
l4[1] = float(0);
|
||||||
|
l4[2] = float(0);
|
||||||
|
l4[3] = float(0);
|
||||||
|
vec4 l5 = vec4(0);
|
||||||
|
l0 = float(0);
|
||||||
|
l1[0] = float(0);
|
||||||
|
l1[1] = float(0);
|
||||||
|
l1[2] = float(0);
|
||||||
|
l1[3] = float(0);
|
||||||
|
l2 = vec4(0);
|
||||||
|
F0(l3, l4, l5);
|
||||||
|
l0 = l3;
|
||||||
|
l1[0] = l4[0];
|
||||||
|
l1[1] = l4[1];
|
||||||
|
l1[2] = l4[2];
|
||||||
|
l1[3] = l4[3];
|
||||||
|
l2 = l5;
|
||||||
|
return;
|
||||||
|
}
|
9
internal/shader/testdata/out2.go
vendored
Normal file
9
internal/shader/testdata/out2.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func Foo() (a float, b [4]float, c vec4) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Foo2() (a float, b [4]float, c vec4) {
|
||||||
|
return Foo()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user