394 lines
8.7 KiB
Go
394 lines
8.7 KiB
Go
// Copyright 2021 The Tint Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package ast defines AST nodes that are produced by the Tint intrinsic
|
|
// definition parser
|
|
package ast
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/tok"
|
|
)
|
|
|
|
// AST is the parsed syntax tree of the intrinsic definition file
|
|
type AST struct {
|
|
Enums []EnumDecl
|
|
Types []TypeDecl
|
|
Matchers []MatcherDecl
|
|
Builtins []IntrinsicDecl
|
|
Initializers []IntrinsicDecl
|
|
Converters []IntrinsicDecl
|
|
Operators []IntrinsicDecl
|
|
}
|
|
|
|
func (a AST) String() string {
|
|
sb := strings.Builder{}
|
|
for _, e := range a.Enums {
|
|
fmt.Fprintf(&sb, "%v", e)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, p := range a.Types {
|
|
fmt.Fprintf(&sb, "%v", p)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, m := range a.Matchers {
|
|
fmt.Fprintf(&sb, "%v", m)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, b := range a.Builtins {
|
|
fmt.Fprintf(&sb, "%v", b)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, o := range a.Initializers {
|
|
fmt.Fprintf(&sb, "%v", o)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, o := range a.Converters {
|
|
fmt.Fprintf(&sb, "%v", o)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
for _, o := range a.Operators {
|
|
fmt.Fprintf(&sb, "%v", o)
|
|
fmt.Fprintln(&sb)
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
// EnumDecl describes an enumerator
|
|
type EnumDecl struct {
|
|
Source tok.Source
|
|
Name string
|
|
Entries []EnumEntry
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (e EnumDecl) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "enum %v {\n", e.Name)
|
|
for _, e := range e.Entries {
|
|
fmt.Fprintf(w, " %v\n", e)
|
|
}
|
|
fmt.Fprintf(w, "}\n")
|
|
}
|
|
|
|
// EnumEntry describes an entry in a enumerator
|
|
type EnumEntry struct {
|
|
Source tok.Source
|
|
Name string
|
|
Attributes Attributes
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (e EnumEntry) Format(w fmt.State, verb rune) {
|
|
if len(e.Attributes) > 0 {
|
|
fmt.Fprintf(w, "%v %v", e.Attributes, e.Name)
|
|
} else {
|
|
fmt.Fprint(w, e.Name)
|
|
}
|
|
}
|
|
|
|
// MatcherDecl describes a matcher declaration
|
|
type MatcherDecl struct {
|
|
Source tok.Source
|
|
Name string
|
|
Options MatcherOptions
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (m MatcherDecl) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "match %v", m.Name)
|
|
fmt.Fprintf(w, ": ")
|
|
m.Options.Format(w, verb)
|
|
}
|
|
|
|
// IntrinsicKind is either a Builtin, Operator, Initializer or Converter
|
|
type IntrinsicKind string
|
|
|
|
const (
|
|
// Builtin is a builtin function (max, fract, etc).
|
|
// Declared with 'fn'.
|
|
Builtin IntrinsicKind = "builtin"
|
|
// Operator is a unary or binary operator.
|
|
// Declared with 'op'.
|
|
Operator IntrinsicKind = "operator"
|
|
// Initializer is a type initializer function.
|
|
// Declared with 'init'.
|
|
Initializer IntrinsicKind = "initializer"
|
|
// Converter is a type conversion function.
|
|
// Declared with 'conv'.
|
|
Converter IntrinsicKind = "converter"
|
|
)
|
|
|
|
// IntrinsicDecl describes a builtin or operator declaration
|
|
type IntrinsicDecl struct {
|
|
Source tok.Source
|
|
Kind IntrinsicKind
|
|
Name string
|
|
Attributes Attributes
|
|
TemplateParams TemplateParams
|
|
Parameters Parameters
|
|
ReturnType *TemplatedName
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (i IntrinsicDecl) Format(w fmt.State, verb rune) {
|
|
switch i.Kind {
|
|
case Builtin:
|
|
fmt.Fprintf(w, "fn ")
|
|
case Operator:
|
|
fmt.Fprintf(w, "op ")
|
|
case Initializer:
|
|
fmt.Fprintf(w, "init ")
|
|
case Converter:
|
|
fmt.Fprintf(w, "conv ")
|
|
}
|
|
fmt.Fprintf(w, "%v", i.Name)
|
|
i.TemplateParams.Format(w, verb)
|
|
i.Parameters.Format(w, verb)
|
|
if i.ReturnType != nil {
|
|
fmt.Fprintf(w, " -> ")
|
|
i.ReturnType.Format(w, verb)
|
|
}
|
|
}
|
|
|
|
// Parameters is a list of parameter
|
|
type Parameters []Parameter
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (l Parameters) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "(")
|
|
for i, p := range l {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, ", ")
|
|
}
|
|
p.Attributes.Format(w, verb)
|
|
p.Format(w, verb)
|
|
}
|
|
fmt.Fprintf(w, ")")
|
|
}
|
|
|
|
// Parameter describes a single parameter of a function
|
|
type Parameter struct {
|
|
Source tok.Source
|
|
Attributes Attributes
|
|
Name string // Optional
|
|
Type TemplatedName
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (p Parameter) Format(w fmt.State, verb rune) {
|
|
if p.Name != "" {
|
|
fmt.Fprintf(w, "%v: ", p.Name)
|
|
}
|
|
p.Type.Format(w, verb)
|
|
}
|
|
|
|
// MatcherOptions is a list of TemplatedNames or MemberNames
|
|
type MatcherOptions struct {
|
|
Types TemplatedNames
|
|
Enums MemberNames
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (o MatcherOptions) Format(w fmt.State, verb rune) {
|
|
for i, mo := range o.Types {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, " | ")
|
|
}
|
|
mo.Format(w, verb)
|
|
}
|
|
for i, mo := range o.Enums {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, " | ")
|
|
}
|
|
mo.Format(w, verb)
|
|
}
|
|
}
|
|
|
|
// TemplatedNames is a list of TemplatedName
|
|
// Example:
|
|
//
|
|
// a<b>, c<d, e>
|
|
type TemplatedNames []TemplatedName
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (l TemplatedNames) Format(w fmt.State, verb rune) {
|
|
for i, n := range l {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, ", ")
|
|
}
|
|
n.Format(w, verb)
|
|
}
|
|
}
|
|
|
|
// TemplatedName is an identifier with optional templated arguments
|
|
// Example:
|
|
//
|
|
// vec<N, T>
|
|
type TemplatedName struct {
|
|
Source tok.Source
|
|
Name string
|
|
TemplateArgs TemplatedNames
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (t TemplatedName) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "%v", t.Name)
|
|
if len(t.TemplateArgs) > 0 {
|
|
fmt.Fprintf(w, "<")
|
|
t.TemplateArgs.Format(w, verb)
|
|
fmt.Fprintf(w, ">")
|
|
}
|
|
}
|
|
|
|
// MemberNames is a list of MemberName
|
|
// Example:
|
|
//
|
|
// a.b, c.d
|
|
type MemberNames []MemberName
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (l MemberNames) Format(w fmt.State, verb rune) {
|
|
for i, n := range l {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, ", ")
|
|
}
|
|
n.Format(w, verb)
|
|
}
|
|
}
|
|
|
|
// MemberName is two identifiers separated by a dot (Owner.Member)
|
|
type MemberName struct {
|
|
Source tok.Source
|
|
Owner string
|
|
Member string
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (t MemberName) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "%v.%v", t.Owner, t.Member)
|
|
}
|
|
|
|
// TypeDecl describes a type declaration
|
|
type TypeDecl struct {
|
|
Source tok.Source
|
|
Attributes Attributes
|
|
Name string
|
|
TemplateParams TemplateParams
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (p TypeDecl) Format(w fmt.State, verb rune) {
|
|
if len(p.Attributes) > 0 {
|
|
p.Attributes.Format(w, verb)
|
|
fmt.Fprintf(w, " type %v", p.Name)
|
|
}
|
|
fmt.Fprintf(w, "type %v", p.Name)
|
|
p.TemplateParams.Format(w, verb)
|
|
}
|
|
|
|
// TemplateParams is a list of TemplateParam
|
|
// Example:
|
|
//
|
|
// <A, B : TyB>
|
|
type TemplateParams []TemplateParam
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (p TemplateParams) Format(w fmt.State, verb rune) {
|
|
if len(p) > 0 {
|
|
fmt.Fprintf(w, "<")
|
|
for i, tp := range p {
|
|
if i > 0 {
|
|
fmt.Fprintf(w, ", ")
|
|
}
|
|
tp.Format(w, verb)
|
|
}
|
|
fmt.Fprintf(w, ">")
|
|
}
|
|
}
|
|
|
|
// TemplateParam describes a template parameter with optional type
|
|
// Example:
|
|
//
|
|
// <Name>
|
|
// <Name: Type>
|
|
type TemplateParam struct {
|
|
Source tok.Source
|
|
Name string
|
|
Type TemplatedName // Optional
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (t TemplateParam) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "%v", t.Name)
|
|
if t.Type.Name != "" {
|
|
fmt.Fprintf(w, " : ")
|
|
t.Type.Format(w, verb)
|
|
}
|
|
}
|
|
|
|
// Attributes is a list of Attribute
|
|
// Example:
|
|
//
|
|
// [[a(x), b(y)]]
|
|
type Attributes []Attribute
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (l Attributes) Format(w fmt.State, verb rune) {
|
|
for _, d := range l {
|
|
fmt.Fprint(w, "@")
|
|
d.Format(w, verb)
|
|
fmt.Fprint(w, " ")
|
|
}
|
|
}
|
|
|
|
// Take looks up the attribute with the given name. If the attribute is found
|
|
// it is removed from the Attributes list and returned, otherwise nil is
|
|
// returned and the Attributes are not altered.
|
|
func (l *Attributes) Take(name string) *Attribute {
|
|
for i, a := range *l {
|
|
if a.Name == name {
|
|
*l = append((*l)[:i], (*l)[i+1:]...)
|
|
return &a
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Attribute describes a single attribute
|
|
// Example:
|
|
//
|
|
// @a(x)
|
|
type Attribute struct {
|
|
Source tok.Source
|
|
Name string
|
|
Values []any
|
|
}
|
|
|
|
// Format implements the fmt.Formatter interface
|
|
func (d Attribute) Format(w fmt.State, verb rune) {
|
|
fmt.Fprintf(w, "%v", d.Name)
|
|
if len(d.Values) > 0 {
|
|
fmt.Fprintf(w, "(")
|
|
for i, v := range d.Values {
|
|
if i > 0 {
|
|
fmt.Fprint(w, ", ")
|
|
}
|
|
fmt.Fprintf(w, "%v", v)
|
|
}
|
|
fmt.Fprintf(w, ")")
|
|
}
|
|
}
|