shader: Bug fix: Resolve types in a binary expression correctly

This commit is contained in:
Hajime Hoshi 2020-06-20 17:49:23 +09:00
parent f36d6c02a9
commit 5e0e12d290
3 changed files with 40 additions and 14 deletions

View File

@ -833,23 +833,43 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
var stmts []shaderir.Stmt var stmts []shaderir.Stmt
// Prase RHS first for the order of the statements. // Prase LHS first for the order of the statements.
rhs, t0, ss := cs.parseExpr(block, e.Y) lhs, ts, ss := cs.parseExpr(block, e.X)
if len(rhs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.Y))
return nil, nil, nil
}
stmts = append(stmts, ss...)
lhs, t1, ss := cs.parseExpr(block, e.X)
if len(lhs) != 1 { if len(lhs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.X)) cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.X))
return nil, nil, nil return nil, nil, nil
} }
stmts = append(stmts, ss...) stmts = append(stmts, ss...)
lhst := ts[0]
// TODO: Check the compatibility of t0 and t1 rhs, ts, ss := cs.parseExpr(block, e.Y)
_ = t1 if len(rhs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a binary operator: %s", e.Y))
return nil, nil, nil
}
stmts = append(stmts, ss...)
rhst := ts[0]
var t shaderir.Type
if lhst.Equal(&rhst) {
t = lhst
} else if lhst.Main == shaderir.Float || lhst.Main == shaderir.Int {
switch rhst.Main {
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
t = rhst
default:
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", e.X, e.Op, e.Y))
return nil, nil, nil
}
} else if rhst.Main == shaderir.Float || rhst.Main == shaderir.Int {
switch lhst.Main {
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
t = lhst
default:
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", e.X, e.Op, e.Y))
return nil, nil, nil
}
}
return []shaderir.Expr{ return []shaderir.Expr{
{ {
@ -857,7 +877,7 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
Op: op, Op: op,
Exprs: []shaderir.Expr{lhs[0], rhs[0]}, Exprs: []shaderir.Expr{lhs[0], rhs[0]},
}, },
}, t0, stmts }, []shaderir.Type{t}, stmts
case *ast.CallExpr: case *ast.CallExpr:
var ( var (
callee shaderir.Expr callee shaderir.Expr

View File

@ -2,8 +2,13 @@ void F0(out vec2 l0) {
vec2 l1 = vec2(0); vec2 l1 = vec2(0);
vec2 l2 = vec2(0); vec2 l2 = vec2(0);
vec2 l3 = vec2(0); vec2 l3 = vec2(0);
vec2 l4 = vec2(0);
vec2 l5 = vec2(0);
vec2 l6 = vec2(0);
F1(l3); F1(l3);
l2 = (1.0) * (l3); l2 = (1.0) * (l3);
F1(l6);
l5 = (l6) * (1.0);
l0 = l2; l0 = l2;
return; return;
} }

View File

@ -1,8 +1,9 @@
package main package main
func Foo() vec2 { func Foo() vec2 {
x := 1 * Bar() x0 := 1 * Bar()
return x x1 := Bar() * 1
return x0
} }
func Bar() vec2 { func Bar() vec2 {