mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
parent
0246a6407e
commit
59a80cf953
@ -390,6 +390,14 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
|
|||||||
},
|
},
|
||||||
}, []shaderir.Type{t}, nil, true
|
}, []shaderir.Type{t}, nil, true
|
||||||
}
|
}
|
||||||
|
if c, ok := block.findConstant(e.Name); ok {
|
||||||
|
return []shaderir.Expr{
|
||||||
|
{
|
||||||
|
Type: shaderir.NumberExpr,
|
||||||
|
Const: c.value,
|
||||||
|
},
|
||||||
|
}, []shaderir.Type{c.typ}, nil, true
|
||||||
|
}
|
||||||
if i, ok := cs.findFunction(e.Name); ok {
|
if i, ok := cs.findFunction(e.Name); ok {
|
||||||
return []shaderir.Expr{
|
return []shaderir.Expr{
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ package shader
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
gconstant "go/constant"
|
||||||
"go/token"
|
"go/token"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -30,9 +31,9 @@ type variable struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type constant struct {
|
type constant struct {
|
||||||
name string
|
name string
|
||||||
typ shaderir.Type
|
typ shaderir.Type
|
||||||
init ast.Expr
|
value gconstant.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
type function struct {
|
type function struct {
|
||||||
@ -154,6 +155,23 @@ func (b *block) findLocalVariableByIndex(idx int) (shaderir.Type, bool) {
|
|||||||
return shaderir.Type{}, false
|
return shaderir.Type{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *block) findConstant(name string) (constant, bool) {
|
||||||
|
if name == "" || name == "_" {
|
||||||
|
panic("shader: constant name must be non-empty and non-underscore")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range b.consts {
|
||||||
|
if c.name == name {
|
||||||
|
return c, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b.outer != nil {
|
||||||
|
return b.outer.findConstant(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return constant{}, false
|
||||||
|
}
|
||||||
|
|
||||||
type ParseError struct {
|
type ParseError struct {
|
||||||
errs []string
|
errs []string
|
||||||
}
|
}
|
||||||
@ -304,7 +322,10 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) ([]shaderir.Stmt, bool)
|
|||||||
case token.CONST:
|
case token.CONST:
|
||||||
for _, s := range d.Specs {
|
for _, s := range d.Specs {
|
||||||
s := s.(*ast.ValueSpec)
|
s := s.(*ast.ValueSpec)
|
||||||
cs := cs.parseConstant(b, s)
|
cs, ok := cs.parseConstant(b, s)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
b.consts = append(b.consts, cs...)
|
b.consts = append(b.consts, cs...)
|
||||||
}
|
}
|
||||||
case token.VAR:
|
case token.VAR:
|
||||||
@ -528,25 +549,41 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
|
|||||||
return vars, inits, stmts, true
|
return vars, inits, stmts, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) []constant {
|
func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) ([]constant, bool) {
|
||||||
var t shaderir.Type
|
var t shaderir.Type
|
||||||
if vs.Type != nil {
|
if vs.Type != nil {
|
||||||
var ok bool
|
var ok bool
|
||||||
t, ok = s.parseType(block, vs.Type)
|
t, ok = s.parseType(block, vs.Type)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cs []constant
|
var cs []constant
|
||||||
for i, n := range vs.Names {
|
for i, n := range vs.Names {
|
||||||
|
es, _, ss, ok := s.parseExpr(block, vs.Values[i], false)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if len(ss) > 0 {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("invalid constant expression: %s", n))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if len(es) != 1 {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("invalid constant expression: %s", n))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if es[0].Type != shaderir.NumberExpr {
|
||||||
|
s.addError(vs.Pos(), fmt.Sprintf("constant expresion must be a number but not: %s", n))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
cs = append(cs, constant{
|
cs = append(cs, constant{
|
||||||
name: n.Name,
|
name: n.Name,
|
||||||
typ: t,
|
typ: t,
|
||||||
init: vs.Values[i],
|
value: es[0].Const,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return cs
|
return cs, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *compileState) parseFuncParams(block *block, d *ast.FuncDecl) (in, out []variable) {
|
func (cs *compileState) parseFuncParams(block *block, d *ast.FuncDecl) (in, out []variable) {
|
||||||
|
6
internal/shader/testdata/const.expected.vs
vendored
Normal file
6
internal/shader/testdata/const.expected.vs
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
void F0(out vec2 l0);
|
||||||
|
|
||||||
|
void F0(out vec2 l0) {
|
||||||
|
l0 = vec2(3.5000000000e+00);
|
||||||
|
return;
|
||||||
|
}
|
8
internal/shader/testdata/const.go
vendored
Normal file
8
internal/shader/testdata/const.go
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const a = 1
|
||||||
|
const b = 2 + 0.5
|
||||||
|
|
||||||
|
func Foo() vec2 {
|
||||||
|
return vec2(a + b)
|
||||||
|
}
|
6
internal/shader/testdata/const2.expected.vs
vendored
Normal file
6
internal/shader/testdata/const2.expected.vs
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
void F0(out vec2 l0);
|
||||||
|
|
||||||
|
void F0(out vec2 l0) {
|
||||||
|
l0 = vec2(3.5000000000e+00);
|
||||||
|
return;
|
||||||
|
}
|
7
internal/shader/testdata/const2.go
vendored
Normal file
7
internal/shader/testdata/const2.go
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func Foo() vec2 {
|
||||||
|
const a = 1
|
||||||
|
const b = a + 2 + 0.5
|
||||||
|
return vec2(b)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user