Ben Clayton 5a69597698 tint: Add type constructors and converters support to intrinsic-gen
These are currently not used, but the first step towards moving type
constructors and converters over to using the intrinisc table.

This will simplify maintenance of type functions, and will greatly
simplify the [AbstractInt -> i32|u32] [AbstractFloat -> f32|f16] logic.

Bug: tint:1504
Change-Id: I15526670a6ff801e66551ab5adc37b1570ac49de
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90242
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
2022-05-16 09:48:41 +00:00

352 lines
8.0 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/cmd/intrinsic-gen/tok"
)
// AST is the parsed syntax tree of the intrinsic definition file
type AST struct {
Enums []EnumDecl
Types []TypeDecl
Matchers []MatcherDecl
Builtins []IntrinsicDecl
Constructors []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.Constructors {
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
Decorations Decorations
}
// Format implements the fmt.Formatter interface
func (e EnumEntry) Format(w fmt.State, verb rune) {
if len(e.Decorations) > 0 {
fmt.Fprintf(w, "%v %v", e.Decorations, 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, Constructor 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"
// Constructor is a type constructor function.
// Declared with 'ctor'.
Constructor IntrinsicKind = "constructor"
// 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
Decorations Decorations
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 Constructor:
fmt.Fprintf(w, "ctor ")
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.Format(w, verb)
}
fmt.Fprintf(w, ")")
}
// Parameter describes a single parameter of a function
type Parameter struct {
Source tok.Source
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 TemplatedName
type MatcherOptions TemplatedNames
// Format implements the fmt.Formatter interface
func (o MatcherOptions) Format(w fmt.State, verb rune) {
for i, mo := range o {
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, ">")
}
}
// TypeDecl describes a type declaration
type TypeDecl struct {
Source tok.Source
Decorations Decorations
Name string
TemplateParams TemplateParams
}
// Format implements the fmt.Formatter interface
func (p TypeDecl) Format(w fmt.State, verb rune) {
if len(p.Decorations) > 0 {
p.Decorations.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)
}
}
// Decorations is a list of Decoration
// Example:
// [[a(x), b(y)]]
type Decorations []Decoration
// Format implements the fmt.Formatter interface
func (l Decorations) Format(w fmt.State, verb rune) {
fmt.Fprint(w, "[[")
for i, d := range l {
if i > 0 {
fmt.Fprintf(w, ", ")
}
d.Format(w, verb)
}
fmt.Fprint(w, "]]")
}
// Take looks up the decoration with the given name. If the decoration is found
// it is removed from the Decorations list and returned, otherwise nil is
// returned and the Decorations are not altered.
func (l *Decorations) Take(name string) *Decoration {
for i, d := range *l {
if d.Name == name {
*l = append((*l)[:i], (*l)[i+1:]...)
return &d
}
}
return nil
}
// Decoration describes a single decoration
// Example:
// a(x)
type Decoration struct {
Source tok.Source
Name string
Values []string
}
// Format implements the fmt.Formatter interface
func (d Decoration) 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, ")")
}
}