shaderir: Add indexing

Fixes #1235
This commit is contained in:
Hajime Hoshi 2020-07-29 23:49:39 +09:00
parent a0549820fd
commit ac16564e95
3 changed files with 62 additions and 0 deletions

View File

@ -499,6 +499,66 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
},
}, []shaderir.Type{t}, stmts, true
case *ast.IndexExpr:
var stmts []shaderir.Stmt
// Parse the index first
exprs, _, ss, ok := cs.parseExpr(block, e.Index)
if !ok {
return nil, nil, nil, false
}
stmts = append(stmts, ss...)
if len(exprs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at an index expression"))
return nil, nil, nil, false
}
idx := exprs[0]
if idx.Type != shaderir.NumberExpr {
cs.addError(e.Pos(), fmt.Sprintf("an index must be a constant number"))
return nil, nil, nil, false
}
idx.ConstType = shaderir.ConstTypeInt
exprs, ts, ss, ok := cs.parseExpr(block, e.X)
if !ok {
return nil, nil, nil, false
}
stmts = append(stmts, ss...)
if len(exprs) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at an index expression"))
return nil, nil, nil, false
}
x := exprs[0]
t := ts[0]
var typ shaderir.Type
switch t.Main {
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
typ = shaderir.Type{Main: shaderir.Float}
case shaderir.Mat2:
typ = shaderir.Type{Main: shaderir.Vec2}
case shaderir.Mat3:
typ = shaderir.Type{Main: shaderir.Vec3}
case shaderir.Mat4:
typ = shaderir.Type{Main: shaderir.Vec4}
case shaderir.Array:
typ = t.Sub[0]
default:
cs.addError(e.Pos(), fmt.Sprintf("index operator cannot be applied to the type %s", t.String()))
return nil, nil, nil, false
}
return []shaderir.Expr{
{
Type: shaderir.Index,
Exprs: []shaderir.Expr{
x,
idx,
},
},
}, []shaderir.Type{typ}, stmts, true
default:
cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
}

View File

@ -14,6 +14,7 @@ void F1(out vec2[2] l0) {
vec2[2] l2 = vec2[2](vec2(0), vec2(0));
(l1)[0] = vec2(1.0);
l2 = l1;
((l2)[1]).y = vec2(2.0);
l0 = l2;
return;
}

View File

@ -9,5 +9,6 @@ func Foo() [2]vec2 {
func Bar() [2]vec2 {
x := [2]vec2{vec2(1)}
x[1].y = vec2(2)
return x
}