shader: Parse number literals in unary expressions correctly

Fixes #1190
This commit is contained in:
Hajime Hoshi 2020-06-21 21:47:23 +09:00
parent 29b70bea95
commit c36d2165e6
3 changed files with 94 additions and 8 deletions

View File

@ -1136,6 +1136,10 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
}, nil, nil, true
}
cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name))
case *ast.ParenExpr:
return cs.parseExpr(block, e.X)
case *ast.SelectorExpr:
exprs, _, stmts, ok := cs.parseExpr(block, e.X)
if !ok {
@ -1171,7 +1175,31 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
},
},
}, []shaderir.Type{t}, stmts, true
case *ast.UnaryExpr:
exprs, t, stmts, ok := cs.parseExpr(block, e.X)
if !ok {
return nil, nil, nil, false
}
if len(exprs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a unary operator: %s", e.X))
return nil, nil, nil, false
}
if exprs[0].Type == shaderir.NumberExpr {
v := gconstant.UnaryOp(e.Op, exprs[0].Const, 0)
t := shaderir.Type{Main: shaderir.Int}
if v.Kind() == gconstant.Float {
t = shaderir.Type{Main: shaderir.Float}
}
return []shaderir.Expr{
{
Type: shaderir.NumberExpr,
Const: v,
},
}, []shaderir.Type{t}, stmts, true
}
var op shaderir.Op
switch e.Op {
case token.ADD:
@ -1184,14 +1212,6 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
return nil, nil, nil, false
}
exprs, t, stmts, ok := cs.parseExpr(block, e.X)
if !ok {
return nil, nil, nil, false
}
if len(exprs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a unary operator: %s", e.X))
return nil, nil, nil, false
}
return []shaderir.Expr{
{
Type: shaderir.Unary,

View File

@ -0,0 +1,41 @@
void F0(out vec4 l0) {
int l1 = 0;
int l2 = 0;
int l3 = 0;
int l4 = 0;
float l5 = float(0);
float l6 = float(0);
float l7 = float(0);
float l8 = float(0);
l1 = 5;
l2 = -5;
l3 = -5;
l4 = 5;
l5 = 5.0;
l6 = -5.0;
l7 = -5.0;
l8 = 5.0;
l0 = (vec4(l1, l2, l3, l4)) + (vec4(l5, l6, l7, l8));
return;
}
void F1(out vec4 l0) {
int l1 = 0;
int l2 = 0;
int l3 = 0;
int l4 = 0;
float l5 = float(0);
float l6 = float(0);
float l7 = float(0);
float l8 = float(0);
l1 = 5;
l2 = -5;
l3 = -5;
l4 = 5;
l5 = 5.0;
l6 = -5.0;
l7 = -5.0;
l8 = 5.0;
l0 = (vec4(l1, l2, l3, l4)) + (vec4(l5, l6, l7, l8));
return;
}

View File

@ -0,0 +1,25 @@
package main
func Foo1() vec4 {
x0 := +(+5)
x1 := +(-5)
x2 := -(+5)
x3 := -(-5)
x4 := +(+5.0)
x5 := +(-5.0)
x6 := -(+5.0)
x7 := -(-5.0)
return vec4(x0, x1, x2, x3) + vec4(x4, x5, x6, x7)
}
func Foo2() vec4 {
var x0 = +(+5)
var x1 = +(-5)
var x2 = -(+5)
var x3 = -(-5)
var x4 = +(+5.0)
var x5 = +(-5.0)
var x6 = -(+5.0)
var x7 = -(-5.0)
return vec4(x0, x1, x2, x3) + vec4(x4, x5, x6, x7)
}