From ba9d27b8ba163044bfc66756770cb50c927473f0 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 10 May 2020 23:19:39 +0900 Subject: [PATCH] shader: Rename type -> basicType --- internal/shader/block.go | 8 +-- internal/shader/shader.go | 103 ++++++++++++++++----------------- internal/shader/shader_test.go | 21 +++++++ internal/shader/type.go | 84 +++++++++++++-------------- 4 files changed, 118 insertions(+), 98 deletions(-) diff --git a/internal/shader/block.go b/internal/shader/block.go index e63df174e..aecdf03dd 100644 --- a/internal/shader/block.go +++ b/internal/shader/block.go @@ -40,15 +40,15 @@ func (b *block) dump(indent int) []string { if v.init != nil { init = " = " + dumpExpr(v.init) } - lines = append(lines, fmt.Sprintf("%svar %s %s%s", idt, v.name, v.typ, init)) + lines = append(lines, fmt.Sprintf("%svar %s %s%s", idt, v.name, v.basicType, init)) } for _, c := range b.consts { - lines = append(lines, fmt.Sprintf("%sconst %s %s = %s", idt, c.name, c.typ, dumpExpr(c.init))) + lines = append(lines, fmt.Sprintf("%sconst %s %s = %s", idt, c.name, c.basicType, dumpExpr(c.init))) } for _, f := range b.funcs { var args []string for _, a := range f.args { - args = append(args, fmt.Sprintf("%s %s", a.name, a.typ)) + args = append(args, fmt.Sprintf("%s %s", a.name, a.basicType)) } var rets []string for _, r := range f.rets { @@ -56,7 +56,7 @@ func (b *block) dump(indent int) []string { if name == "" { name = "_" } - rets = append(rets, fmt.Sprintf("%s %s", name, r.typ)) + rets = append(rets, fmt.Sprintf("%s %s", name, r.basicType)) } l := fmt.Sprintf("func %s(%s)", f.name, strings.Join(args, ", ")) if len(rets) > 0 { diff --git a/internal/shader/shader.go b/internal/shader/shader.go index a63c09751..36dc7d66f 100644 --- a/internal/shader/shader.go +++ b/internal/shader/shader.go @@ -25,6 +25,7 @@ import ( ) const ( + // TODO: Remove this. This struct is a user-defined struct. varyingStructName = "VertexOut" ) @@ -33,15 +34,15 @@ var ( ) type variable struct { - name string - typ typ - init ast.Expr + name string + basicType basicType + init ast.Expr } type constant struct { - name string - typ typ - init ast.Expr + name string + basicType basicType + init ast.Expr } type function struct { @@ -129,12 +130,10 @@ func (sh *Shader) parseDecl(b *block, d ast.Decl, global bool) { case *ast.GenDecl: switch d.Tok { case token.TYPE: - // TODO: Parse regular structs or other types + // TODO: Parse other types for _, s := range d.Specs { s := s.(*ast.TypeSpec) - if s.Name.Name == varyingStructName { - sh.parseVaryingStruct(s) - } + sh.parseStruct(s) } case token.CONST: for _, s := range d.Specs { @@ -151,11 +150,11 @@ func (sh *Shader) parseDecl(b *block, d ast.Decl, global bool) { continue } for i, v := range vs { - if 'A' <= v.name[0] && v.name[0] <= 'Z' { - sh.uniforms = append(sh.uniforms, v) - } else { + if v.name[0] < 'A' || 'Z' < v.name[0] { sh.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name)) } + // TODO: Check RHS + sh.uniforms = append(sh.uniforms, v) } } case token.IMPORT: @@ -170,7 +169,7 @@ func (sh *Shader) parseDecl(b *block, d ast.Decl, global bool) { } } -func (sh *Shader) parseVaryingStruct(t *ast.TypeSpec) { +func (sh *Shader) parseStruct(t *ast.TypeSpec) { s, ok := t.Type.(*ast.StructType) if !ok { sh.addError(t.Type.Pos(), fmt.Sprintf("%s must be a struct but not", t.Name)) @@ -194,22 +193,22 @@ func (sh *Shader) parseVaryingStruct(t *ast.TypeSpec) { continue } t := parseType(f.Type) - if t == typNone { + if t == basicTypeNone { sh.addError(f.Type.Pos(), fmt.Sprintf("unexpected type: %s", f.Type)) continue } - if t != typVec4 { + if t != basicTypeVec4 { sh.addError(f.Type.Pos(), fmt.Sprintf("position must be vec4 but %s", t)) continue } sh.position = variable{ - name: f.Names[0].Name, - typ: t, + name: f.Names[0].Name, + basicType: t, } continue } t := parseType(f.Type) - if t == typNone { + if t == basicTypeNone { sh.addError(f.Type.Pos(), fmt.Sprintf("unexpected type: %s", f.Type)) continue } @@ -219,18 +218,18 @@ func (sh *Shader) parseVaryingStruct(t *ast.TypeSpec) { } for _, n := range f.Names { sh.varyings = append(sh.varyings, variable{ - name: n.Name, - typ: t, + name: n.Name, + basicType: t, }) } } } func (s *Shader) parseVariable(block *block, vs *ast.ValueSpec) []variable { - var t typ + var t basicType if vs.Type != nil { t = parseType(vs.Type) - if t == typNone { + if t == basicTypeNone { s.addError(vs.Type.Pos(), fmt.Sprintf("unexpected type: %s", vs.Type)) return nil } @@ -241,25 +240,25 @@ func (s *Shader) parseVariable(block *block, vs *ast.ValueSpec) []variable { var init ast.Expr if len(vs.Values) > 0 { init = vs.Values[i] - if t == typNone { + if t == basicTypeNone { t = s.detectType(block, init) } } name := n.Name vars = append(vars, variable{ - name: name, - typ: t, - init: init, + name: name, + basicType: t, + init: init, }) } return vars } func (s *Shader) parseConstant(vs *ast.ValueSpec) []constant { - var t typ + var t basicType if vs.Type != nil { t = parseType(vs.Type) - if t == typNone { + if t == basicTypeNone { s.addError(vs.Type.Pos(), fmt.Sprintf("unexpected type: %s", vs.Type)) return nil } @@ -268,9 +267,9 @@ func (s *Shader) parseConstant(vs *ast.ValueSpec) []constant { var cs []constant for i, n := range vs.Names { cs = append(cs, constant{ - name: n.Name, - typ: t, - init: vs.Values[i], + name: n.Name, + basicType: t, + init: vs.Values[i], }) } return cs @@ -289,14 +288,14 @@ func (sh *Shader) parseFunc(d *ast.FuncDecl, block *block) function { var args []variable for _, f := range d.Type.Params.List { t := parseType(f.Type) - if t == typNone { + if t == basicTypeNone { sh.addError(f.Type.Pos(), fmt.Sprintf("unexpected type: %s", f.Type)) continue } for _, n := range f.Names { args = append(args, variable{ - name: n.Name, - typ: t, + name: n.Name, + basicType: t, }) } } @@ -305,20 +304,20 @@ func (sh *Shader) parseFunc(d *ast.FuncDecl, block *block) function { if d.Type.Results != nil { for _, f := range d.Type.Results.List { t := parseType(f.Type) - if t == typNone { + if t == basicTypeNone { sh.addError(f.Type.Pos(), fmt.Sprintf("unexpected type: %s", f.Type)) continue } if len(f.Names) == 0 { rets = append(rets, variable{ - name: "", - typ: t, + name: "", + basicType: t, }) } else { for _, n := range f.Names { rets = append(rets, variable{ - name: n.Name, - typ: t, + name: n.Name, + basicType: t, }) } } @@ -348,7 +347,7 @@ func (sh *Shader) parseBlock(outer *block, b *ast.BlockStmt) *block { name: s.(*ast.Ident).Name, } if len(l.Rhs) > 0 { - v.typ = sh.detectType(block, l.Rhs[i]) + v.basicType = sh.detectType(block, l.Rhs[i]) } block.vars = append(block.vars, v) } @@ -396,31 +395,31 @@ func (sh *Shader) parseBlock(outer *block, b *ast.BlockStmt) *block { return block } -func (s *Shader) detectType(b *block, expr ast.Expr) typ { +func (s *Shader) detectType(b *block, expr ast.Expr) basicType { switch e := expr.(type) { case *ast.BasicLit: if e.Kind == token.FLOAT { - return typFloat + return basicTypeFloat } if e.Kind == token.INT { s.addError(expr.Pos(), fmt.Sprintf("integer literal is not implemented yet: %s", e.Value)) } else { s.addError(expr.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value)) } - return typNone + return basicTypeNone case *ast.CompositeLit: return parseType(e.Type) case *ast.Ident: n := e.Name for _, v := range b.vars { if v.name == n { - return v.typ + return v.basicType } } if b == &s.global { for _, v := range s.uniforms { if v.name == n { - return v.typ + return v.basicType } } } @@ -428,12 +427,12 @@ func (s *Shader) detectType(b *block, expr ast.Expr) typ { return s.detectType(b.outer, e) } s.addError(expr.Pos(), fmt.Sprintf("unexpected identity: %s", n)) - return typNone + return basicTypeNone //case *ast.SelectorExpr: //return fmt.Sprintf("%s.%s", dumpExpr(e.X), dumpExpr(e.Sel)) default: s.addError(expr.Pos(), fmt.Sprintf("detecting type not implemented: %#v", expr)) - return typNone + return basicTypeNone } } @@ -442,14 +441,14 @@ func (s *Shader) Dump() string { var lines []string if s.position.name != "" { - lines = append(lines, fmt.Sprintf("var %s varying %s // position", s.position.name, s.position.typ)) + lines = append(lines, fmt.Sprintf("var %s varying %s // position", s.position.name, s.position.basicType)) } for _, v := range s.varyings { - lines = append(lines, fmt.Sprintf("var %s varying %s", v.name, v.typ)) + lines = append(lines, fmt.Sprintf("var %s varying %s", v.name, v.basicType)) } for _, u := range s.uniforms { - lines = append(lines, fmt.Sprintf("var %s uniform %s", u.name, u.typ)) + lines = append(lines, fmt.Sprintf("var %s uniform %s", u.name, u.basicType)) } lines = append(lines, s.global.dump(0)...) @@ -462,7 +461,7 @@ func (s *Shader) GlslVertex() string { for _, v := range s.varyings { // TODO: variable names must be escaped not to conflict with keywords. - lines = append(lines, fmt.Sprintf("varying %s %s;", v.typ.glslString(), v.name)) + lines = append(lines, fmt.Sprintf("varying %s %s;", v.basicType.glslString(), v.name)) } return strings.Join(lines, "\n") + "\n" } diff --git a/internal/shader/shader_test.go b/internal/shader/shader_test.go index d60b28ea0..234438816 100644 --- a/internal/shader/shader_test.go +++ b/internal/shader/shader_test.go @@ -113,6 +113,27 @@ func F() { } `, }, + /*{ + Name: "Struct", + Src: `package main + + type S struct { + M0 float + M1, M2 vec2 + M3, M4, M5 vec3 + } + `, + Dump: `var V0 uniform float + type S struct { + M0 float + M1 vec2 + M2 vec2 + M3 vec3 + M4 vec3 + M5 vec3 + } + `, + },*/ } for _, tc := range tests { s, err := NewShader([]byte(tc.Src)) diff --git a/internal/shader/type.go b/internal/shader/type.go index 674df2228..1b4430734 100644 --- a/internal/shader/type.go +++ b/internal/shader/type.go @@ -19,96 +19,96 @@ import ( "go/ast" ) -type typ int +type basicType int // TODO: What about array types? const ( - typNone typ = iota - typFloat - typVec2 - typVec3 - typVec4 - typMat2 - typMat3 - typMat4 - typSampler2d + basicTypeNone basicType = iota + basicTypeFloat + basicTypeVec2 + basicTypeVec3 + basicTypeVec4 + basicTypeMat2 + basicTypeMat3 + basicTypeMat4 + basicTypeSampler2d ) -func parseType(expr ast.Expr) typ { +func parseType(expr ast.Expr) basicType { switch t := expr.(type) { case *ast.Ident: switch t.Name { case "float": - return typFloat + return basicTypeFloat case "vec2": - return typVec2 + return basicTypeVec2 case "vec3": - return typVec3 + return basicTypeVec3 case "vec4": - return typVec4 + return basicTypeVec4 case "mat2": - return typMat2 + return basicTypeMat2 case "mat3": - return typMat3 + return basicTypeMat3 case "mat4": - return typMat4 + return basicTypeMat4 case "sampler2d": - return typSampler2d + return basicTypeSampler2d } // TODO: Parse array types } - return typNone + return basicTypeNone } -func (t typ) String() string { +func (t basicType) String() string { switch t { - case typNone: + case basicTypeNone: return "(none)" - case typFloat: + case basicTypeFloat: return "float" - case typVec2: + case basicTypeVec2: return "vec2" - case typVec3: + case basicTypeVec3: return "vec3" - case typVec4: + case basicTypeVec4: return "vec4" - case typMat2: + case basicTypeMat2: return "mat2" - case typMat3: + case basicTypeMat3: return "mat3" - case typMat4: + case basicTypeMat4: return "mat4" - case typSampler2d: + case basicTypeSampler2d: return "sampler2d" default: return fmt.Sprintf("unknown(%d)", t) } } -func (t typ) numeric() bool { - return t != typNone && t != typSampler2d +func (t basicType) numeric() bool { + return t != basicTypeNone && t != basicTypeSampler2d } -func (t typ) glslString() string { +func (t basicType) glslString() string { switch t { - case typNone: + case basicTypeNone: return "?(none)" - case typFloat: + case basicTypeFloat: return "float" - case typVec2: + case basicTypeVec2: return "vec2" - case typVec3: + case basicTypeVec3: return "vec3" - case typVec4: + case basicTypeVec4: return "vec4" - case typMat2: + case basicTypeMat2: return "mat2" - case typMat3: + case basicTypeMat3: return "mat3" - case typMat4: + case basicTypeMat4: return "mat4" - case typSampler2d: + case basicTypeSampler2d: return "?(sampler2d)" default: return fmt.Sprintf("?(%d)", t)