mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 18:52:44 +01:00
shader: Let parseExpr return statements for Call
This commit is contained in:
parent
e117086ca1
commit
e64c806698
@ -191,7 +191,8 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
case token.VAR:
|
case token.VAR:
|
||||||
for _, s := range d.Specs {
|
for _, s := range d.Specs {
|
||||||
s := s.(*ast.ValueSpec)
|
s := s.(*ast.ValueSpec)
|
||||||
vs, inits := cs.parseVariable(b, s)
|
vs, inits, stmts := cs.parseVariable(b, s)
|
||||||
|
b.ir.Stmts = append(b.ir.Stmts, stmts...)
|
||||||
if b == &cs.global {
|
if b == &cs.global {
|
||||||
// TODO: Should rhs be ignored?
|
// TODO: Should rhs be ignored?
|
||||||
for i, v := range vs {
|
for i, v := range vs {
|
||||||
@ -246,7 +247,7 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr) {
|
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variable, []*shaderir.Expr, []shaderir.Stmt) {
|
||||||
var t typ
|
var t typ
|
||||||
if vs.Type != nil {
|
if vs.Type != nil {
|
||||||
t = s.parseType(vs.Type)
|
t = s.parseType(vs.Type)
|
||||||
@ -254,6 +255,7 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
|
|||||||
|
|
||||||
var vars []variable
|
var vars []variable
|
||||||
var inits []*shaderir.Expr
|
var inits []*shaderir.Expr
|
||||||
|
var stmts []shaderir.Stmt
|
||||||
for i, n := range vs.Names {
|
for i, n := range vs.Names {
|
||||||
var init ast.Expr
|
var init ast.Expr
|
||||||
if len(vs.Values) > 0 {
|
if len(vs.Values) > 0 {
|
||||||
@ -270,12 +272,13 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
|
|||||||
|
|
||||||
var expr *shaderir.Expr
|
var expr *shaderir.Expr
|
||||||
if init != nil {
|
if init != nil {
|
||||||
e := s.parseExpr(block, init)
|
e, ss := s.parseExpr(block, init)
|
||||||
expr = &e
|
expr = &e
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
}
|
}
|
||||||
inits = append(inits, expr)
|
inits = append(inits, expr)
|
||||||
}
|
}
|
||||||
return vars, inits
|
return vars, inits, stmts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant {
|
func (s *compileState) parseConstant(vs *ast.ValueSpec) []constant {
|
||||||
@ -446,23 +449,30 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
|
|||||||
v.typ = cs.detectType(block, l.Rhs[i])
|
v.typ = cs.detectType(block, l.Rhs[i])
|
||||||
block.vars = append(block.vars, v)
|
block.vars = append(block.vars, v)
|
||||||
block.ir.LocalVars = append(block.ir.LocalVars, v.typ.ir)
|
block.ir.LocalVars = append(block.ir.LocalVars, v.typ.ir)
|
||||||
|
|
||||||
|
// 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...)
|
||||||
|
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{lhs, rhs},
|
||||||
cs.parseExpr(block, l.Lhs[i]),
|
|
||||||
cs.parseExpr(block, l.Rhs[i]),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case token.ASSIGN:
|
case token.ASSIGN:
|
||||||
// TODO: What about the statement `a,b = b,a?`
|
// TODO: What about the statement `a,b = b,a?`
|
||||||
for i := range l.Rhs {
|
for i := range l.Rhs {
|
||||||
|
// 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...)
|
||||||
|
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{lhs, rhs},
|
||||||
cs.parseExpr(block, l.Lhs[i]),
|
|
||||||
cs.parseExpr(block, l.Rhs[i]),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,7 +488,8 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
|
|||||||
cs.parseDecl(block, l.Decl)
|
cs.parseDecl(block, l.Decl)
|
||||||
case *ast.ReturnStmt:
|
case *ast.ReturnStmt:
|
||||||
for i, r := range l.Results {
|
for i, r := range l.Results {
|
||||||
e := cs.parseExpr(block, r)
|
e, stmts := cs.parseExpr(block, r)
|
||||||
|
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
@ -565,7 +576,7 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *compileState) parseExpr(block *block, expr ast.Expr) shaderir.Expr {
|
func (cs *compileState) parseExpr(block *block, expr ast.Expr) (shaderir.Expr, []shaderir.Stmt) {
|
||||||
switch e := expr.(type) {
|
switch e := expr.(type) {
|
||||||
case *ast.BasicLit:
|
case *ast.BasicLit:
|
||||||
switch e.Kind {
|
switch e.Kind {
|
||||||
@ -573,22 +584,22 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) shaderir.Expr {
|
|||||||
v, err := strconv.ParseInt(e.Value, 10, 32)
|
v, err := strconv.ParseInt(e.Value, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
|
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
|
||||||
return shaderir.Expr{}
|
return shaderir.Expr{}, nil
|
||||||
}
|
}
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.IntExpr,
|
Type: shaderir.IntExpr,
|
||||||
Int: int32(v),
|
Int: int32(v),
|
||||||
}
|
}, nil
|
||||||
case token.FLOAT:
|
case token.FLOAT:
|
||||||
v, err := strconv.ParseFloat(e.Value, 32)
|
v, err := strconv.ParseFloat(e.Value, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
|
cs.addError(e.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
|
||||||
return shaderir.Expr{}
|
return shaderir.Expr{}, nil
|
||||||
}
|
}
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.FloatExpr,
|
Type: shaderir.FloatExpr,
|
||||||
Float: float32(v),
|
Float: float32(v),
|
||||||
}
|
}, nil
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("literal not implemented: %#v", e))
|
cs.addError(e.Pos(), fmt.Sprintf("literal not implemented: %#v", e))
|
||||||
}
|
}
|
||||||
@ -635,60 +646,76 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) shaderir.Expr {
|
|||||||
op = shaderir.OrOr
|
op = shaderir.OrOr
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
|
cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
|
||||||
return shaderir.Expr{}
|
return shaderir.Expr{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var stmts []shaderir.Stmt
|
||||||
|
|
||||||
|
// Prase RHS first for the order of the statements.
|
||||||
|
rhs, ss := cs.parseExpr(block, e.Y)
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
|
lhs, ss := cs.parseExpr(block, e.X)
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.Binary,
|
Type: shaderir.Binary,
|
||||||
Op: op,
|
Op: op,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{lhs, rhs},
|
||||||
cs.parseExpr(block, e.X),
|
}, stmts
|
||||||
cs.parseExpr(block, e.Y),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
exprs := []shaderir.Expr{
|
var exprs []shaderir.Expr
|
||||||
cs.parseExpr(block, e.Fun),
|
var stmts []shaderir.Stmt
|
||||||
}
|
|
||||||
|
// Parse the argument first for the order of the statements.
|
||||||
for _, a := range e.Args {
|
for _, a := range e.Args {
|
||||||
e := cs.parseExpr(block, a)
|
e, ss := cs.parseExpr(block, a)
|
||||||
// TODO: Convert integer literals to float literals if necessary.
|
// TODO: Convert integer literals to float literals if necessary.
|
||||||
exprs = append(exprs, e)
|
exprs = append(exprs, e)
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: When len(stmts) is not 0?
|
||||||
|
expr, ss := cs.parseExpr(block, e.Fun)
|
||||||
|
exprs = append([]shaderir.Expr{expr}, exprs...)
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
|
// TODO: Return statements to call the function separately.
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.Call,
|
Type: shaderir.Call,
|
||||||
Exprs: exprs,
|
Exprs: exprs,
|
||||||
}
|
}, stmts
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
if i, ok := block.findLocalVariable(e.Name); ok {
|
if i, ok := block.findLocalVariable(e.Name); ok {
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.LocalVariable,
|
Type: shaderir.LocalVariable,
|
||||||
Index: i,
|
Index: i,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
if i, ok := cs.findUniformVariable(e.Name); ok {
|
if i, ok := cs.findUniformVariable(e.Name); ok {
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.UniformVariable,
|
Type: shaderir.UniformVariable,
|
||||||
Index: i,
|
Index: i,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
if f, ok := shaderir.ParseBuiltinFunc(e.Name); ok {
|
if f, ok := shaderir.ParseBuiltinFunc(e.Name); ok {
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.BuiltinFuncExpr,
|
Type: shaderir.BuiltinFuncExpr,
|
||||||
BuiltinFunc: f,
|
BuiltinFunc: f,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name))
|
cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name))
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
|
expr, stmts := cs.parseExpr(block, e.X)
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.FieldSelector,
|
Type: shaderir.FieldSelector,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
cs.parseExpr(block, e.X),
|
expr,
|
||||||
{
|
{
|
||||||
Type: shaderir.SwizzlingExpr,
|
Type: shaderir.SwizzlingExpr,
|
||||||
Swizzling: e.Sel.Name,
|
Swizzling: e.Sel.Name,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}, stmts
|
||||||
case *ast.UnaryExpr:
|
case *ast.UnaryExpr:
|
||||||
var op shaderir.Op
|
var op shaderir.Op
|
||||||
switch e.Op {
|
switch e.Op {
|
||||||
@ -700,17 +727,16 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) shaderir.Expr {
|
|||||||
op = shaderir.NotOp
|
op = shaderir.NotOp
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
|
cs.addError(e.Pos(), fmt.Sprintf("unexpected operator: %s", e.Op))
|
||||||
return shaderir.Expr{}
|
return shaderir.Expr{}, nil
|
||||||
}
|
}
|
||||||
|
expr, stmts := cs.parseExpr(block, e.X)
|
||||||
return shaderir.Expr{
|
return shaderir.Expr{
|
||||||
Type: shaderir.Unary,
|
Type: shaderir.Unary,
|
||||||
Op: op,
|
Op: op,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{expr},
|
||||||
cs.parseExpr(block, e.X),
|
}, stmts
|
||||||
},
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
|
cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
|
||||||
}
|
}
|
||||||
return shaderir.Expr{}
|
return shaderir.Expr{}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user