• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package sem
16
17import (
18	"fmt"
19
20	"dawn.googlesource.com/tint/tools/src/cmd/intrinsic-gen/ast"
21)
22
23// Sem is the root of the semantic tree
24type Sem struct {
25	Enums        []*Enum
26	Types        []*Type
27	TypeMatchers []*TypeMatcher
28	EnumMatchers []*EnumMatcher
29	Functions    []*Function
30	// Maximum number of open-types used across all intrinsics
31	MaxOpenTypes int
32	// Maximum number of open-numbers used across all intrinsics
33	MaxOpenNumbers int
34	// The alphabetically sorted list of unique parameter names
35	UniqueParameterNames []string
36}
37
38// New returns a new Sem
39func New() *Sem {
40	return &Sem{
41		Enums:        []*Enum{},
42		Types:        []*Type{},
43		TypeMatchers: []*TypeMatcher{},
44		EnumMatchers: []*EnumMatcher{},
45		Functions:    []*Function{},
46	}
47}
48
49// Enum describes an enumerator
50type Enum struct {
51	Decl    ast.EnumDecl
52	Name    string
53	Entries []*EnumEntry
54}
55
56// FindEntry returns the enum entry with the given name
57func (e *Enum) FindEntry(name string) *EnumEntry {
58	for _, entry := range e.Entries {
59		if entry.Name == name {
60			return entry
61		}
62	}
63	return nil
64}
65
66// EnumEntry is an entry in an enumerator
67type EnumEntry struct {
68	Enum       *Enum
69	Name       string
70	IsInternal bool // True if this entry is not part of the WGSL grammar
71}
72
73// Format implements the fmt.Formatter interface
74func (e EnumEntry) Format(w fmt.State, verb rune) {
75	if e.IsInternal {
76		fmt.Fprint(w, "[[internal]] ")
77	}
78	fmt.Fprint(w, e.Name)
79}
80
81// Type declares a type
82type Type struct {
83	TemplateParams []TemplateParam
84	Decl           ast.TypeDecl
85	Name           string
86	DisplayName    string
87}
88
89// TypeMatcher declares a type matcher
90type TypeMatcher struct {
91	TemplateParams []TemplateParam
92	Decl           ast.MatcherDecl
93	Name           string
94	Types          []*Type
95}
96
97// EnumMatcher declares a enum matcher
98type EnumMatcher struct {
99	TemplateParams []TemplateParam
100	Decl           ast.MatcherDecl
101	Name           string
102	Enum           *Enum
103	Options        []*EnumEntry
104}
105
106// TemplateEnumParam is a template enum parameter
107type TemplateEnumParam struct {
108	Name    string
109	Enum    *Enum
110	Matcher *EnumMatcher // Optional
111}
112
113// TemplateTypeParam is a template type parameter
114type TemplateTypeParam struct {
115	Name string
116	Type ResolvableType
117}
118
119// TemplateNumberParam is a template type parameter
120type TemplateNumberParam struct {
121	Name string
122}
123
124// Function describes the overloads of an intrinsic function
125type Function struct {
126	Name      string
127	Overloads []*Overload
128}
129
130// Overload describes a single overload of a function
131type Overload struct {
132	Decl             ast.FunctionDecl
133	Function         *Function
134	TemplateParams   []TemplateParam
135	OpenTypes        []*TemplateTypeParam
136	OpenNumbers      []TemplateParam
137	ReturnType       *FullyQualifiedName
138	Parameters       []Parameter
139	CanBeUsedInStage StageUses
140	IsDeprecated     bool // True if this overload is deprecated
141}
142
143// StageUses describes the stages an overload can be used in
144type StageUses struct {
145	Vertex   bool
146	Fragment bool
147	Compute  bool
148}
149
150// List returns the stage uses as a string list
151func (u StageUses) List() []string {
152	out := []string{}
153	if u.Vertex {
154		out = append(out, "vertex")
155	}
156	if u.Fragment {
157		out = append(out, "fragment")
158	}
159	if u.Compute {
160		out = append(out, "compute")
161	}
162	return out
163}
164
165// Format implements the fmt.Formatter interface
166func (o Overload) Format(w fmt.State, verb rune) {
167	fmt.Fprintf(w, "fn %v", o.Function.Name)
168	if len(o.TemplateParams) > 0 {
169		fmt.Fprintf(w, "<")
170		for i, t := range o.TemplateParams {
171			if i > 0 {
172				fmt.Fprint(w, ", ")
173			}
174			fmt.Fprintf(w, "%v", t)
175		}
176		fmt.Fprintf(w, ">")
177	}
178	fmt.Fprint(w, "(")
179	for i, p := range o.Parameters {
180		if i > 0 {
181			fmt.Fprint(w, ", ")
182		}
183		fmt.Fprintf(w, "%v", p)
184	}
185	fmt.Fprint(w, ")")
186	if o.ReturnType != nil {
187		fmt.Fprintf(w, " -> %v", o.ReturnType)
188	}
189}
190
191// Parameter describes a single parameter of a function overload
192type Parameter struct {
193	Name string
194	Type FullyQualifiedName
195}
196
197// Format implements the fmt.Formatter interface
198func (p Parameter) Format(w fmt.State, verb rune) {
199	if p.Name != "" {
200		fmt.Fprintf(w, "%v: ", p.Name)
201	}
202	fmt.Fprintf(w, "%v", p.Type)
203}
204
205// FullyQualifiedName is the usage of a Type, TypeMatcher or TemplateTypeParam
206type FullyQualifiedName struct {
207	Target            Named
208	TemplateArguments []interface{}
209}
210
211// Format implements the fmt.Formatter interface
212func (f FullyQualifiedName) Format(w fmt.State, verb rune) {
213	fmt.Fprint(w, f.Target.GetName())
214	if len(f.TemplateArguments) > 0 {
215		fmt.Fprintf(w, "<")
216		for i, t := range f.TemplateArguments {
217			if i > 0 {
218				fmt.Fprint(w, ", ")
219			}
220			fmt.Fprintf(w, "%v", t)
221		}
222		fmt.Fprintf(w, ">")
223	}
224}
225
226// TemplateParam is a TemplateEnumParam, TemplateTypeParam or TemplateNumberParam
227type TemplateParam interface {
228	Named
229	isTemplateParam()
230}
231
232func (*TemplateEnumParam) isTemplateParam()   {}
233func (*TemplateTypeParam) isTemplateParam()   {}
234func (*TemplateNumberParam) isTemplateParam() {}
235
236// ResolvableType is a Type, TypeMatcher or TemplateTypeParam
237type ResolvableType interface {
238	Named
239	isResolvableType()
240}
241
242func (*Type) isResolvableType()              {}
243func (*TypeMatcher) isResolvableType()       {}
244func (*TemplateTypeParam) isResolvableType() {}
245
246// Named is something that can be looked up by name
247type Named interface {
248	isNamed()
249	GetName() string
250}
251
252func (*Enum) isNamed()                {}
253func (*EnumEntry) isNamed()           {}
254func (*Type) isNamed()                {}
255func (*TypeMatcher) isNamed()         {}
256func (*EnumMatcher) isNamed()         {}
257func (*TemplateTypeParam) isNamed()   {}
258func (*TemplateEnumParam) isNamed()   {}
259func (*TemplateNumberParam) isNamed() {}
260
261// GetName returns the name of the Enum
262func (e *Enum) GetName() string { return e.Name }
263
264// GetName returns the name of the EnumEntry
265func (e *EnumEntry) GetName() string { return e.Name }
266
267// GetName returns the name of the Type
268func (t *Type) GetName() string { return t.Name }
269
270// GetName returns the name of the TypeMatcher
271func (t *TypeMatcher) GetName() string { return t.Name }
272
273// GetName returns the name of the EnumMatcher
274func (e *EnumMatcher) GetName() string { return e.Name }
275
276// GetName returns the name of the TemplateTypeParam
277func (t *TemplateTypeParam) GetName() string { return t.Name }
278
279// GetName returns the name of the TemplateEnumParam
280func (t *TemplateEnumParam) GetName() string { return t.Name }
281
282// GetName returns the name of the TemplateNumberParam
283func (t *TemplateNumberParam) GetName() string { return t.Name }
284