mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
shader: Refactoring: Add statements later
This commit is contained in:
parent
b00666df22
commit
3ca6e41194
@ -621,9 +621,11 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, out
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
for _, l := range b.List {
|
for _, l := range b.List {
|
||||||
if !cs.parseStmt(block, l, inParams) {
|
stmts, ok := cs.parseStmt(block, l, inParams)
|
||||||
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return block, true
|
return block, true
|
||||||
|
@ -22,28 +22,34 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/shaderir"
|
"github.com/hajimehoshi/ebiten/internal/shaderir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variable) bool {
|
func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variable) ([]shaderir.Stmt, bool) {
|
||||||
|
var stmts []shaderir.Stmt
|
||||||
|
|
||||||
switch stmt := stmt.(type) {
|
switch stmt := stmt.(type) {
|
||||||
case *ast.AssignStmt:
|
case *ast.AssignStmt:
|
||||||
switch stmt.Tok {
|
switch stmt.Tok {
|
||||||
case token.DEFINE:
|
case token.DEFINE:
|
||||||
if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 {
|
if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 {
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, true) {
|
ss, ok := cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, true)
|
||||||
return false
|
if !ok {
|
||||||
|
return nil, false
|
||||||
}
|
}
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
case token.ASSIGN:
|
case token.ASSIGN:
|
||||||
// TODO: What about the statement `a,b = b,a?`
|
// TODO: What about the statement `a,b = b,a?`
|
||||||
if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 {
|
if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 {
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
if !cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, false) {
|
ss, ok := cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, false)
|
||||||
return false
|
if !ok {
|
||||||
|
return nil, false
|
||||||
}
|
}
|
||||||
|
stmts = append(stmts, ss...)
|
||||||
case token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN, token.REM_ASSIGN:
|
case token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN, token.REM_ASSIGN:
|
||||||
var op shaderir.Op
|
var op shaderir.Op
|
||||||
switch stmt.Tok {
|
switch stmt.Tok {
|
||||||
@ -58,17 +64,20 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
|||||||
case token.REM_ASSIGN:
|
case token.REM_ASSIGN:
|
||||||
op = shaderir.ModOp
|
op = shaderir.ModOp
|
||||||
}
|
}
|
||||||
rhs, _, stmts, ok := cs.parseExpr(block, stmt.Rhs[0])
|
|
||||||
|
rhs, _, ss, ok := cs.parseExpr(block, stmt.Rhs[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
lhs, _, stmts, ok := cs.parseExpr(block, stmt.Lhs[0])
|
|
||||||
|
lhs, _, ss, ok := cs.parseExpr(block, stmt.Lhs[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
|
||||||
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
lhs[0],
|
lhs[0],
|
||||||
@ -88,9 +97,9 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
|||||||
case *ast.BlockStmt:
|
case *ast.BlockStmt:
|
||||||
b, ok := cs.parseBlock(block, stmt, nil, nil)
|
b, ok := cs.parseBlock(block, stmt, nil, nil)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.BlockStmt,
|
Type: shaderir.BlockStmt,
|
||||||
Blocks: []shaderir.Block{
|
Blocks: []shaderir.Block{
|
||||||
b.ir,
|
b.ir,
|
||||||
@ -98,15 +107,15 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
|||||||
})
|
})
|
||||||
case *ast.DeclStmt:
|
case *ast.DeclStmt:
|
||||||
if !cs.parseDecl(block, stmt.Decl) {
|
if !cs.parseDecl(block, stmt.Decl) {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
case *ast.ReturnStmt:
|
case *ast.ReturnStmt:
|
||||||
for i, r := range stmt.Results {
|
for i, r := range stmt.Results {
|
||||||
exprs, _, stmts, ok := cs.parseExpr(block, r)
|
exprs, _, ss, ok := cs.parseExpr(block, r)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
if len(exprs) == 0 {
|
if len(exprs) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -114,7 +123,7 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
|||||||
cs.addError(r.Pos(), "multiple-context with return is not implemented yet")
|
cs.addError(r.Pos(), "multiple-context with return is not implemented yet")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
{
|
{
|
||||||
@ -125,43 +134,45 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Return,
|
Type: shaderir.Return,
|
||||||
})
|
})
|
||||||
case *ast.ExprStmt:
|
case *ast.ExprStmt:
|
||||||
exprs, _, stmts, ok := cs.parseExpr(block, stmt.X)
|
exprs, _, ss, ok := cs.parseExpr(block, stmt.X)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
for _, expr := range exprs {
|
for _, expr := range exprs {
|
||||||
if expr.Type != shaderir.Call {
|
if expr.Type != shaderir.Call {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.ExprStmt,
|
Type: shaderir.ExprStmt,
|
||||||
Exprs: []shaderir.Expr{expr},
|
Exprs: []shaderir.Expr{expr},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
cs.addError(stmt.Pos(), fmt.Sprintf("unexpected statement: %#v", stmt))
|
cs.addError(stmt.Pos(), fmt.Sprintf("unexpected statement: %#v", stmt))
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
return true
|
return stmts, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr, define bool) bool {
|
func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr, define bool) ([]shaderir.Stmt, bool) {
|
||||||
|
var stmts []shaderir.Stmt
|
||||||
var rhsExprs []shaderir.Expr
|
var rhsExprs []shaderir.Expr
|
||||||
var rhsTypes []shaderir.Type
|
var rhsTypes []shaderir.Type
|
||||||
|
|
||||||
for i, e := range lhs {
|
for i, e := range lhs {
|
||||||
if len(lhs) == len(rhs) {
|
if len(lhs) == len(rhs) {
|
||||||
// Prase RHS first for the order of the statements.
|
// Prase RHS first for the order of the statements.
|
||||||
r, origts, stmts, ok := cs.parseExpr(block, rhs[i])
|
r, origts, ss, ok := cs.parseExpr(block, rhs[i])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
if define {
|
if define {
|
||||||
v := variable{
|
v := variable{
|
||||||
@ -173,7 +184,7 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
|
|||||||
}
|
}
|
||||||
if len(ts) > 1 {
|
if len(ts) > 1 {
|
||||||
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
if len(ts) == 1 {
|
if len(ts) == 1 {
|
||||||
v.typ = ts[0]
|
v.typ = ts[0]
|
||||||
@ -183,14 +194,14 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
|
|||||||
|
|
||||||
if len(r) > 1 {
|
if len(r) > 1 {
|
||||||
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
l, _, stmts, ok := cs.parseExpr(block, lhs[i])
|
l, _, ss, ok := cs.parseExpr(block, lhs[i])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
if r[0].Type == shaderir.NumberExpr {
|
if r[0].Type == shaderir.NumberExpr {
|
||||||
switch block.vars[l[0].Index].typ.Main {
|
switch block.vars[l[0].Index].typ.Main {
|
||||||
@ -201,22 +212,22 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{l[0], r[0]},
|
Exprs: []shaderir.Expr{l[0], r[0]},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
var stmts []shaderir.Stmt
|
var ss []shaderir.Stmt
|
||||||
var ok bool
|
var ok bool
|
||||||
rhsExprs, rhsTypes, stmts, ok = cs.parseExpr(block, rhs[0])
|
rhsExprs, rhsTypes, ss, ok = cs.parseExpr(block, rhs[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
if len(rhsExprs) != len(lhs) {
|
if len(rhsExprs) != len(lhs) {
|
||||||
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
cs.addError(pos, fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if define {
|
if define {
|
||||||
@ -227,17 +238,17 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
|
|||||||
block.vars = append(block.vars, v)
|
block.vars = append(block.vars, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
l, _, stmts, ok := cs.parseExpr(block, lhs[i])
|
l, _, ss, ok := cs.parseExpr(block, lhs[i])
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
block.ir.Stmts = append(block.ir.Stmts, stmts...)
|
stmts = append(stmts, ss...)
|
||||||
|
|
||||||
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
Type: shaderir.Assign,
|
Type: shaderir.Assign,
|
||||||
Exprs: []shaderir.Expr{l[0], rhsExprs[i]},
|
Exprs: []shaderir.Expr{l[0], rhsExprs[i]},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return stmts, true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user