shader: Parse constants

This commit is contained in:
Hajime Hoshi 2020-05-09 04:21:45 +09:00
parent ffae970c26
commit fc0604805a
2 changed files with 69 additions and 13 deletions

View File

@ -32,23 +32,25 @@ var (
kageTagRe = regexp.MustCompile("^`" + `kage:\"(.+)\"` + "`$") kageTagRe = regexp.MustCompile("^`" + `kage:\"(.+)\"` + "`$")
) )
type nameAndType struct { type variable struct {
name string name string
typ typ typ typ
constant bool
init string
} }
type Shader struct { type Shader struct {
// position is the field name of VertexOut that represents a vertex position (gl_Position in GLSL). // position is the field name of VertexOut that represents a vertex position (gl_Position in GLSL).
position nameAndType position variable
// varyings is a collection of varying variables. // varyings is a collection of varying variables.
varyings []nameAndType varyings []variable
// uniforms is a collection of uniform variables. // uniforms is a collection of uniform variables.
uniforms []nameAndType uniforms []variable
// globals is a collection of global variables. // globals is a collection of global variables.
globals []nameAndType globals []variable
errs []string errs []string
} }
@ -100,6 +102,8 @@ func (s *Shader) parse(f *ast.File) {
s.parseVaryingStruct(obj) s.parseVaryingStruct(obj)
default: default:
switch obj.Kind { switch obj.Kind {
case ast.Con:
s.parsePackageLevelConstant(name, obj)
case ast.Var: case ast.Var:
s.parsePackageLevelVariable(name, obj) s.parsePackageLevelVariable(name, obj)
} }
@ -145,7 +149,7 @@ func (sh *Shader) parseVaryingStruct(obj *ast.Object) {
sh.addError(fmt.Sprintf("position must be vec4 but %s", t)) sh.addError(fmt.Sprintf("position must be vec4 but %s", t))
continue continue
} }
sh.position = nameAndType{ sh.position = variable{
name: f.Names[0].Name, name: f.Names[0].Name,
typ: t, typ: t,
} }
@ -161,7 +165,7 @@ func (sh *Shader) parseVaryingStruct(obj *ast.Object) {
continue continue
} }
for _, n := range f.Names { for _, n := range f.Names {
sh.varyings = append(sh.varyings, nameAndType{ sh.varyings = append(sh.varyings, variable{
name: n.Name, name: n.Name,
typ: t, typ: t,
}) })
@ -180,14 +184,52 @@ func (s *Shader) parsePackageLevelVariable(name string, obj *ast.Object) {
s.addError(err.Error()) s.addError(err.Error())
return return
} }
nt := nameAndType{ val := variable{
name: name, name: name,
typ: t, typ: t,
} }
// TODO: Parse initial value.
if 'A' <= name[0] && name[0] <= 'Z' { if 'A' <= name[0] && name[0] <= 'Z' {
s.uniforms = append(s.uniforms, nt) s.uniforms = append(s.uniforms, val)
} else { } else {
s.globals = append(s.globals, nt) s.globals = append(s.globals, val)
}
}
func (s *Shader) parsePackageLevelConstant(name string, obj *ast.Object) {
vs, ok := obj.Decl.(*ast.ValueSpec)
if !ok {
s.addError("value spec expected")
return
}
t, err := parseType(vs.Type)
if err != nil {
s.addError(err.Error())
return
}
for i, v := range vs.Values {
if vs.Names[i].Name != name {
continue
}
var init string
switch v := v.(type) {
case *ast.BasicLit:
if v.Kind != token.INT && v.Kind != token.FLOAT {
s.addError(fmt.Sprintf("literal must be int or float but %s", v.Kind))
return
}
init = v.Value // TODO: This should be math/big.Int or Float.
default:
// TODO: Parse the expression.
}
val := variable{
name: name,
typ: t, // TODO: Treat consts without types
constant: true,
init: init,
}
s.globals = append(s.globals, val)
} }
} }
@ -205,7 +247,15 @@ func (s *Shader) Dump() string {
} }
for _, g := range s.globals { for _, g := range s.globals {
lines = append(lines, fmt.Sprintf("var %s %s", g.name, g.typ)) prefix := "var"
if g.constant {
prefix = "const"
}
init := ""
if g.init != "" {
init = " = " + g.init
}
lines = append(lines, fmt.Sprintf("%s %s %s%s", prefix, g.name, g.typ, init))
} }
return strings.Join(lines, "\n") + "\n" return strings.Join(lines, "\n") + "\n"

View File

@ -40,6 +40,9 @@ var (
Baz, Quux vec3 Baz, Quux vec3
qux vec4 qux vec4
) )
const C1 float = 1
const C2, C3 float = 2, 3
`, `,
Dump: `var Position varying vec4 // position Dump: `var Position varying vec4 // position
var Color varying vec4 var Color varying vec4
@ -48,6 +51,9 @@ var Bar uniform vec2
var Baz uniform vec3 var Baz uniform vec3
var Foo uniform float var Foo uniform float
var Quux uniform vec3 var Quux uniform vec3
const C1 float = 1
const C2 float = 2
const C3 float = 3
var qux vec4 var qux vec4
`, `,
}, },