mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +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
|
||||
}
|
||||
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 {
|
||||
return []shaderir.Expr{
|
||||
{
|
||||
|
@ -17,6 +17,7 @@ package shader
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
gconstant "go/constant"
|
||||
"go/token"
|
||||
"strings"
|
||||
|
||||
@ -30,9 +31,9 @@ type variable struct {
|
||||
}
|
||||
|
||||
type constant struct {
|
||||
name string
|
||||
typ shaderir.Type
|
||||
init ast.Expr
|
||||
name string
|
||||
typ shaderir.Type
|
||||
value gconstant.Value
|
||||
}
|
||||
|
||||
type function struct {
|
||||
@ -154,6 +155,23 @@ func (b *block) findLocalVariableByIndex(idx int) (shaderir.Type, bool) {
|
||||
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 {
|
||||
errs []string
|
||||
}
|
||||
@ -304,7 +322,10 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) ([]shaderir.Stmt, bool)
|
||||
case token.CONST:
|
||||
for _, s := range d.Specs {
|
||||
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...)
|
||||
}
|
||||
case token.VAR:
|
||||
@ -528,25 +549,41 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
|
||||
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
|
||||
if vs.Type != nil {
|
||||
var ok bool
|
||||
t, ok = s.parseType(block, vs.Type)
|
||||
if !ok {
|
||||
return nil
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
var cs []constant
|
||||
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{
|
||||
name: n.Name,
|
||||
typ: t,
|
||||
init: vs.Values[i],
|
||||
name: n.Name,
|
||||
typ: t,
|
||||
value: es[0].Const,
|
||||
})
|
||||
}
|
||||
return cs
|
||||
return cs, true
|
||||
}
|
||||
|
||||
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