From e3e91c0d751efae1582e272e1f1f85a8a7454d4a Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 1 Jun 2022 20:44:50 +0000 Subject: [PATCH] tools: intrinsic-gen - [[decoration]] -> @attribute More closely resembles WGSL. Change-Id: Ia1b93bb443b4e3bf9329f8026d1924f12648cb7b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92245 Commit-Queue: Ben Clayton Kokoro: Kokoro Reviewed-by: Antonio Maiorano --- src/tint/intrinsics.def | 146 +++++++++--------- src/tint/resolver/intrinsic_table.inl | 18 +-- tools/src/cmd/intrinsic-gen/ast/ast.go | 46 +++--- tools/src/cmd/intrinsic-gen/lexer/lexer.go | 4 +- .../src/cmd/intrinsic-gen/lexer/lexer_test.go | 7 +- tools/src/cmd/intrinsic-gen/parser/parser.go | 105 ++++++------- .../cmd/intrinsic-gen/parser/parser_test.go | 70 ++++----- .../src/cmd/intrinsic-gen/resolver/resolve.go | 36 ++--- .../intrinsic-gen/resolver/resolver_test.go | 10 +- tools/src/cmd/intrinsic-gen/tok/tok.go | 3 +- 10 files changed, 217 insertions(+), 228 deletions(-) diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def index 28be2d9f85..0c7cfb4c91 100644 --- a/src/tint/intrinsics.def +++ b/src/tint/intrinsics.def @@ -30,7 +30,7 @@ enum storage_class { workgroup uniform storage - [[internal]] handle + @internal handle } // https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode @@ -62,7 +62,7 @@ enum texel_format { //////////////////////////////////////////////////////////////////////////////// // WGSL primitive types // -// Types may be decorated with [[precedence(N)]] to prioritize which type // +// Types may be decorated with @precedence(N) to prioritize which type // // will be picked when multiple types of a matcher match. // // This is used to ensure that abstract numerical types materialize to the // // concrete type with the lowest conversion rank. // @@ -71,11 +71,11 @@ enum texel_format { // https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section type bool -[[precedence(4), display("abstract-float")]] type af -[[precedence(3), display("abstract-int")]] type ai -[[precedence(2)]] type i32 -[[precedence(1)]] type u32 -[[precedence(0)]] type f32 +@precedence(4) @display("abstract-float") type af +@precedence(3) @display("abstract-int") type ai +@precedence(2) type i32 +@precedence(1) type u32 +@precedence(0) type f32 type vec2 type vec3 type vec4 @@ -88,8 +88,8 @@ type mat3x4 type mat4x2 type mat4x3 type mat4x4 -[[display("vec{N}<{T}>")]] type vec -[[display("mat{N}x{M}<{T}>")]] type mat +@display("vec{N}<{T}>") type vec +@display("mat{N}x{M}<{T}>") type mat type ptr type atomic type array @@ -114,9 +114,9 @@ type texture_storage_3d type texture_external type __modf_result -[[display("__modf_result_vec{N}")]] type __modf_result_vec +@display("__modf_result_vec{N}") type __modf_result_vec type __frexp_result -[[display("__frexp_result_vec{N}")]] type __frexp_result_vec +@display("__frexp_result_vec{N}") type __frexp_result_vec type __atomic_compare_exchange_result @@ -363,18 +363,18 @@ fn distance(vec, vec) -> f32 fn dot(vec, vec) -> T fn dot4I8Packed(u32, u32) -> i32 fn dot4U8Packed(u32, u32) -> u32 -[[stage("fragment")]] fn dpdx(f32) -> f32 -[[stage("fragment")]] fn dpdx(vec) -> vec -[[stage("fragment")]] fn dpdxCoarse(f32) -> f32 -[[stage("fragment")]] fn dpdxCoarse(vec) -> vec -[[stage("fragment")]] fn dpdxFine(f32) -> f32 -[[stage("fragment")]] fn dpdxFine(vec) -> vec -[[stage("fragment")]] fn dpdy(f32) -> f32 -[[stage("fragment")]] fn dpdy(vec) -> vec -[[stage("fragment")]] fn dpdyCoarse(f32) -> f32 -[[stage("fragment")]] fn dpdyCoarse(vec) -> vec -[[stage("fragment")]] fn dpdyFine(f32) -> f32 -[[stage("fragment")]] fn dpdyFine(vec) -> vec +@stage("fragment") fn dpdx(f32) -> f32 +@stage("fragment") fn dpdx(vec) -> vec +@stage("fragment") fn dpdxCoarse(f32) -> f32 +@stage("fragment") fn dpdxCoarse(vec) -> vec +@stage("fragment") fn dpdxFine(f32) -> f32 +@stage("fragment") fn dpdxFine(vec) -> vec +@stage("fragment") fn dpdy(f32) -> f32 +@stage("fragment") fn dpdy(vec) -> vec +@stage("fragment") fn dpdyCoarse(f32) -> f32 +@stage("fragment") fn dpdyCoarse(vec) -> vec +@stage("fragment") fn dpdyFine(f32) -> f32 +@stage("fragment") fn dpdyFine(vec) -> vec fn exp(f32) -> f32 fn exp(vec) -> vec fn exp2(f32) -> f32 @@ -394,12 +394,12 @@ fn fract(f32) -> f32 fn fract(vec) -> vec fn frexp(f32) -> __frexp_result fn frexp(vec) -> __frexp_result_vec -[[stage("fragment")]] fn fwidth(f32) -> f32 -[[stage("fragment")]] fn fwidth(vec) -> vec -[[stage("fragment")]] fn fwidthCoarse(f32) -> f32 -[[stage("fragment")]] fn fwidthCoarse(vec) -> vec -[[stage("fragment")]] fn fwidthFine(f32) -> f32 -[[stage("fragment")]] fn fwidthFine(vec) -> vec +@stage("fragment") fn fwidth(f32) -> f32 +@stage("fragment") fn fwidth(vec) -> vec +@stage("fragment") fn fwidthCoarse(f32) -> f32 +@stage("fragment") fn fwidthCoarse(vec) -> vec +@stage("fragment") fn fwidthFine(f32) -> f32 +@stage("fragment") fn fwidthFine(vec) -> vec fn insertBits(T, T, u32, u32) -> T fn insertBits(vec, vec, u32, u32) -> vec fn inverseSqrt(f32) -> f32 @@ -448,13 +448,13 @@ fn sinh(f32) -> f32 fn sinh(vec) -> vec fn smoothstep(f32, f32, f32) -> f32 fn smoothstep(vec, vec, vec) -> vec -[[deprecated]] fn smoothStep(f32, f32, f32) -> f32 -[[deprecated]] fn smoothStep(vec, vec, vec) -> vec +@deprecated fn smoothStep(f32, f32, f32) -> f32 +@deprecated fn smoothStep(vec, vec, vec) -> vec fn sqrt(f32) -> f32 fn sqrt(vec) -> vec fn step(f32, f32) -> f32 fn step(vec, vec) -> vec -[[stage("compute")]] fn storageBarrier() +@stage("compute") fn storageBarrier() fn tan(f32) -> f32 fn tan(vec) -> vec fn tanh(f32) -> f32 @@ -467,7 +467,7 @@ fn unpack2x16snorm(u32) -> vec2 fn unpack2x16unorm(u32) -> vec2 fn unpack4x8snorm(u32) -> vec4 fn unpack4x8unorm(u32) -> vec4 -[[stage("compute")]] fn workgroupBarrier() +@stage("compute") fn workgroupBarrier() fn textureDimensions(texture: texture_1d) -> i32 fn textureDimensions(texture: texture_1d, level: i32) -> i32 @@ -531,35 +531,35 @@ fn textureNumLevels(texture: texture_depth_cube) -> i32 fn textureNumLevels(texture: texture_depth_cube_array) -> i32 fn textureNumSamples(texture: texture_multisampled_2d) -> i32 fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32 -[[stage("fragment")]] fn textureSample(texture: texture_1d, sampler: sampler, coords: f32) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2, offset: vec2) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, offset: vec2) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3, offset: vec3) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_cube, sampler: sampler, coords: vec3) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> vec4 -[[stage("fragment")]] fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2) -> f32 -[[stage("fragment")]] fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2, offset: vec2) -> f32 -[[stage("fragment")]] fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> f32 -[[stage("fragment")]] fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, offset: vec2) -> f32 -[[stage("fragment")]] fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3) -> f32 -[[stage("fragment")]] fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> f32 -[[stage("fragment")]] fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32, offset: vec2) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32, offset: vec2) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32, offset: vec3) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_cube, sampler: sampler, coords: vec3, bias: f32) -> vec4 -[[stage("fragment")]] fn textureSampleBias(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32, bias: f32) -> vec4 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> f32 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, offset: vec2) -> f32 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> f32 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32, offset: vec2) -> f32 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3, depth_ref: f32) -> f32 -[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3, array_index: i32, depth_ref: f32) -> f32 +@stage("fragment") fn textureSample(texture: texture_1d, sampler: sampler, coords: f32) -> vec4 +@stage("fragment") fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2) -> vec4 +@stage("fragment") fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2, offset: vec2) -> vec4 +@stage("fragment") fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> vec4 +@stage("fragment") fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, offset: vec2) -> vec4 +@stage("fragment") fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3) -> vec4 +@stage("fragment") fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3, offset: vec3) -> vec4 +@stage("fragment") fn textureSample(texture: texture_cube, sampler: sampler, coords: vec3) -> vec4 +@stage("fragment") fn textureSample(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> vec4 +@stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2) -> f32 +@stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2, offset: vec2) -> f32 +@stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> f32 +@stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, offset: vec2) -> f32 +@stage("fragment") fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3) -> f32 +@stage("fragment") fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> f32 +@stage("fragment") fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32, offset: vec2) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32, offset: vec2) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32, offset: vec3) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_cube, sampler: sampler, coords: vec3, bias: f32) -> vec4 +@stage("fragment") fn textureSampleBias(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32, bias: f32) -> vec4 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> f32 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, offset: vec2) -> f32 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> f32 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32, offset: vec2) -> f32 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3, depth_ref: f32) -> f32 +@stage("fragment") fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3, array_index: i32, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, offset: vec2) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> f32 @@ -611,17 +611,17 @@ fn textureLoad(texture: texture_depth_2d_array, coords: vec2, array_index: fn textureLoad(texture: texture_depth_multisampled_2d, coords: vec2, sample_index: i32) -> f32 fn textureLoad(texture: texture_external, coords: vec2) -> vec4 -[[stage("fragment", "compute")]] fn atomicLoad(ptr, read_write>) -> T -[[stage("fragment", "compute")]] fn atomicStore(ptr, read_write>, T) -[[stage("fragment", "compute")]] fn atomicAdd(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicSub(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicMax(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicMin(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicAnd(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicOr(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicXor(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicExchange(ptr, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicCompareExchangeWeak(ptr, read_write>, T, T) -> __atomic_compare_exchange_result +@stage("fragment", "compute") fn atomicLoad(ptr, read_write>) -> T +@stage("fragment", "compute") fn atomicStore(ptr, read_write>, T) +@stage("fragment", "compute") fn atomicAdd(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicSub(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicMax(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicMin(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicAnd(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicOr(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicXor(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicExchange(ptr, read_write>, T) -> T +@stage("fragment", "compute") fn atomicCompareExchangeWeak(ptr, read_write>, T, T) -> __atomic_compare_exchange_result //////////////////////////////////////////////////////////////////////////////// // Type constructors // diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl index 7a422fb6f7..ab634f4e1c 100644 --- a/src/tint/resolver/intrinsic_table.inl +++ b/src/tint/resolver/intrinsic_table.inl @@ -52,7 +52,7 @@ std::string Bool::String(MatchState*) const { } /// TypeMatcher for 'type af' -/// @see src/tint/intrinsics.def:74:51 +/// @see src/tint/intrinsics.def:74:48 class Af : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -81,7 +81,7 @@ std::string Af::String(MatchState*) const { } /// TypeMatcher for 'type ai' -/// @see src/tint/intrinsics.def:75:51 +/// @see src/tint/intrinsics.def:75:48 class Ai : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -110,7 +110,7 @@ std::string Ai::String(MatchState*) const { } /// TypeMatcher for 'type i32' -/// @see src/tint/intrinsics.def:76:24 +/// @see src/tint/intrinsics.def:76:21 class I32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -137,7 +137,7 @@ std::string I32::String(MatchState*) const { } /// TypeMatcher for 'type u32' -/// @see src/tint/intrinsics.def:77:24 +/// @see src/tint/intrinsics.def:77:21 class U32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -164,7 +164,7 @@ std::string U32::String(MatchState*) const { } /// TypeMatcher for 'type f32' -/// @see src/tint/intrinsics.def:78:24 +/// @see src/tint/intrinsics.def:78:21 class F32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -587,7 +587,7 @@ std::string Mat4X4::String(MatchState* state) const { } /// TypeMatcher for 'type vec' -/// @see src/tint/intrinsics.def:91:37 +/// @see src/tint/intrinsics.def:91:34 class Vec : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -628,7 +628,7 @@ std::string Vec::String(MatchState* state) const { } /// TypeMatcher for 'type mat' -/// @see src/tint/intrinsics.def:92:37 +/// @see src/tint/intrinsics.def:92:34 class Mat : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -1416,7 +1416,7 @@ std::string ModfResult::String(MatchState*) const { } /// TypeMatcher for 'type __modf_result_vec' -/// @see src/tint/intrinsics.def:117:42 +/// @see src/tint/intrinsics.def:117:39 class ModfResultVec : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. @@ -1478,7 +1478,7 @@ std::string FrexpResult::String(MatchState*) const { } /// TypeMatcher for 'type __frexp_result_vec' -/// @see src/tint/intrinsics.def:119:43 +/// @see src/tint/intrinsics.def:119:40 class FrexpResultVec : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules. diff --git a/tools/src/cmd/intrinsic-gen/ast/ast.go b/tools/src/cmd/intrinsic-gen/ast/ast.go index 75b74c73c8..55e7cc0e6e 100644 --- a/tools/src/cmd/intrinsic-gen/ast/ast.go +++ b/tools/src/cmd/intrinsic-gen/ast/ast.go @@ -85,15 +85,15 @@ func (e EnumDecl) Format(w fmt.State, verb rune) { // EnumEntry describes an entry in a enumerator type EnumEntry struct { - Source tok.Source - Name string - Decorations Decorations + 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.Decorations) > 0 { - fmt.Fprintf(w, "%v %v", e.Decorations, e.Name) + if len(e.Attributes) > 0 { + fmt.Fprintf(w, "%v %v", e.Attributes, e.Name) } else { fmt.Fprint(w, e.Name) } @@ -136,7 +136,7 @@ type IntrinsicDecl struct { Source tok.Source Kind IntrinsicKind Name string - Decorations Decorations + Attributes Attributes TemplateParams TemplateParams Parameters Parameters ReturnType *TemplatedName @@ -243,15 +243,15 @@ func (t TemplatedName) Format(w fmt.State, verb rune) { // TypeDecl describes a type declaration type TypeDecl struct { Source tok.Source - Decorations Decorations + Attributes Attributes 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) + if len(p.Attributes) > 0 { + p.Attributes.Format(w, verb) fmt.Fprintf(w, " type %v", p.Name) } fmt.Fprintf(w, "type %v", p.Name) @@ -296,13 +296,13 @@ func (t TemplateParam) Format(w fmt.State, verb rune) { } } -// Decorations is a list of Decoration +// Attributes is a list of Attribute // Example: // [[a(x), b(y)]] -type Decorations []Decoration +type Attributes []Attribute // Format implements the fmt.Formatter interface -func (l Decorations) Format(w fmt.State, verb rune) { +func (l Attributes) Format(w fmt.State, verb rune) { fmt.Fprint(w, "[[") for i, d := range l { if i > 0 { @@ -313,30 +313,30 @@ func (l Decorations) Format(w fmt.State, verb rune) { 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 { +// 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 &d + return &a } } return nil } -// Decoration describes a single decoration +// Attribute describes a single attribute // Example: -// a(x) -type Decoration struct { +// @a(x) +type Attribute struct { Source tok.Source Name string Values []string } // Format implements the fmt.Formatter interface -func (d Decoration) Format(w fmt.State, verb rune) { +func (d Attribute) Format(w fmt.State, verb rune) { fmt.Fprintf(w, "%v", d.Name) if len(d.Values) > 0 { fmt.Fprintf(w, "(") diff --git a/tools/src/cmd/intrinsic-gen/lexer/lexer.go b/tools/src/cmd/intrinsic-gen/lexer/lexer.go index a81875e684..d8a486a41f 100644 --- a/tools/src/cmd/intrinsic-gen/lexer/lexer.go +++ b/tools/src/cmd/intrinsic-gen/lexer/lexer.go @@ -52,6 +52,8 @@ func (l *lexer) lex() error { l.next() case '\n': l.next() + case '@': + l.tok(1, tok.Attr) case '(': l.tok(1, tok.Lparen) case ')': @@ -89,8 +91,6 @@ func (l *lexer) lex() error { l.skip(l.count(toFirst('\n'))) l.next() // Consume newline case l.match("/", tok.Divide): - case l.match("[[", tok.Ldeco): - case l.match("]]", tok.Rdeco): case l.match("->", tok.Arrow): case l.match("-", tok.Minus): case l.match("fn", tok.Function): diff --git a/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go b/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go index f17eb23ff8..21d5787fe7 100644 --- a/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go +++ b/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go @@ -127,11 +127,8 @@ func TestLexTokens(t *testing.T) { {">", tok.Token{Kind: tok.Gt, Runes: []rune(">"), Source: tok.Source{ S: loc(1, 1, 0), E: loc(1, 2, 1), }}}, - {"[[", tok.Token{Kind: tok.Ldeco, Runes: []rune("[["), Source: tok.Source{ - S: loc(1, 1, 0), E: loc(1, 3, 2), - }}}, - {"]]", tok.Token{Kind: tok.Rdeco, Runes: []rune("]]"), Source: tok.Source{ - S: loc(1, 1, 0), E: loc(1, 3, 2), + {"@", tok.Token{Kind: tok.Attr, Runes: []rune("@"), Source: tok.Source{ + S: loc(1, 1, 0), E: loc(1, 2, 1), }}}, {"(", tok.Token{Kind: tok.Lparen, Runes: []rune("("), Source: tok.Source{ S: loc(1, 1, 0), E: loc(1, 2, 1), diff --git a/tools/src/cmd/intrinsic-gen/parser/parser.go b/tools/src/cmd/intrinsic-gen/parser/parser.go index f381b3a7b0..b1a87f187b 100644 --- a/tools/src/cmd/intrinsic-gen/parser/parser.go +++ b/tools/src/cmd/intrinsic-gen/parser/parser.go @@ -43,40 +43,40 @@ type parser struct { func (p *parser) parse() (*ast.AST, error) { out := ast.AST{} - var decorations ast.Decorations + var attributes ast.Attributes for p.err == nil { t := p.peek(0) if t == nil { break } switch t.Kind { - case tok.Ldeco: - decorations = append(decorations, p.decorations()...) + case tok.Attr: + attributes = append(attributes, p.attributes()...) case tok.Enum: - if len(decorations) > 0 { - p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source) + if len(attributes) > 0 { + p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source) } out.Enums = append(out.Enums, p.enumDecl()) case tok.Match: - if len(decorations) > 0 { - p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source) + if len(attributes) > 0 { + p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source) } out.Matchers = append(out.Matchers, p.matcherDecl()) case tok.Type: - out.Types = append(out.Types, p.typeDecl(decorations)) - decorations = nil + out.Types = append(out.Types, p.typeDecl(attributes)) + attributes = nil case tok.Function: - out.Builtins = append(out.Builtins, p.builtinDecl(decorations)) - decorations = nil + out.Builtins = append(out.Builtins, p.builtinDecl(attributes)) + attributes = nil case tok.Operator: - out.Operators = append(out.Operators, p.operatorDecl(decorations)) - decorations = nil + out.Operators = append(out.Operators, p.operatorDecl(attributes)) + attributes = nil case tok.Constructor: - out.Constructors = append(out.Constructors, p.constructorDecl(decorations)) - decorations = nil + out.Constructors = append(out.Constructors, p.constructorDecl(attributes)) + attributes = nil case tok.Converter: - out.Converters = append(out.Converters, p.converterDecl(decorations)) - decorations = nil + out.Converters = append(out.Converters, p.converterDecl(attributes)) + attributes = nil default: p.err = fmt.Errorf("%v unexpected token '%v'", t.Source, t.Kind) } @@ -99,9 +99,9 @@ func (p *parser) enumDecl() ast.EnumDecl { } func (p *parser) enumEntry() ast.EnumEntry { - decos := p.decorations() + decos := p.attributes() name := p.expect(tok.Identifier, "enum entry") - return ast.EnumEntry{Source: name.Source, Decorations: decos, Name: string(name.Runes)} + return ast.EnumEntry{Source: name.Source, Attributes: decos, Name: string(name.Runes)} } func (p *parser) matcherDecl() ast.MatcherDecl { @@ -118,13 +118,13 @@ func (p *parser) matcherDecl() ast.MatcherDecl { return m } -func (p *parser) typeDecl(decos ast.Decorations) ast.TypeDecl { +func (p *parser) typeDecl(decos ast.Attributes) ast.TypeDecl { p.expect(tok.Type, "type declaration") name := p.expect(tok.Identifier, "type name") m := ast.TypeDecl{ - Source: name.Source, - Decorations: decos, - Name: string(name.Runes), + Source: name.Source, + Attributes: decos, + Name: string(name.Runes), } if p.peekIs(0, tok.Lt) { m.TemplateParams = p.templateParams() @@ -132,13 +132,10 @@ func (p *parser) typeDecl(decos ast.Decorations) ast.TypeDecl { return m } -func (p *parser) decorations() ast.Decorations { - if p.match(tok.Ldeco) == nil { - return nil - } - out := ast.Decorations{} - for p.err == nil { - name := p.expect(tok.Identifier, "decoration name") +func (p *parser) attributes() ast.Attributes { + var out ast.Attributes + for p.match(tok.Attr) != nil && p.err == nil { + name := p.expect(tok.Identifier, "attribute name") values := []string{} if p.match(tok.Lparen) != nil { for p.err == nil { @@ -147,29 +144,25 @@ func (p *parser) decorations() ast.Decorations { break } } - p.expect(tok.Rparen, "decoration values") + p.expect(tok.Rparen, "attribute values") } - out = append(out, ast.Decoration{ + out = append(out, ast.Attribute{ Source: name.Source, Name: string(name.Runes), Values: values, }) - if p.match(tok.Comma) == nil { - break - } } - p.expect(tok.Rdeco, "decoration list") return out } -func (p *parser) builtinDecl(decos ast.Decorations) ast.IntrinsicDecl { +func (p *parser) builtinDecl(decos ast.Attributes) ast.IntrinsicDecl { p.expect(tok.Function, "function declaration") name := p.expect(tok.Identifier, "function name") f := ast.IntrinsicDecl{ - Source: name.Source, - Kind: ast.Builtin, - Decorations: decos, - Name: string(name.Runes), + Source: name.Source, + Kind: ast.Builtin, + Attributes: decos, + Name: string(name.Runes), } if p.peekIs(0, tok.Lt) { f.TemplateParams = p.templateParams() @@ -182,14 +175,14 @@ func (p *parser) builtinDecl(decos ast.Decorations) ast.IntrinsicDecl { return f } -func (p *parser) operatorDecl(decos ast.Decorations) ast.IntrinsicDecl { +func (p *parser) operatorDecl(decos ast.Attributes) ast.IntrinsicDecl { p.expect(tok.Operator, "operator declaration") name := p.next() f := ast.IntrinsicDecl{ - Source: name.Source, - Kind: ast.Operator, - Decorations: decos, - Name: string(name.Runes), + Source: name.Source, + Kind: ast.Operator, + Attributes: decos, + Name: string(name.Runes), } if p.peekIs(0, tok.Lt) { f.TemplateParams = p.templateParams() @@ -202,14 +195,14 @@ func (p *parser) operatorDecl(decos ast.Decorations) ast.IntrinsicDecl { return f } -func (p *parser) constructorDecl(decos ast.Decorations) ast.IntrinsicDecl { +func (p *parser) constructorDecl(decos ast.Attributes) ast.IntrinsicDecl { p.expect(tok.Constructor, "constructor declaration") name := p.next() f := ast.IntrinsicDecl{ - Source: name.Source, - Kind: ast.Constructor, - Decorations: decos, - Name: string(name.Runes), + Source: name.Source, + Kind: ast.Constructor, + Attributes: decos, + Name: string(name.Runes), } if p.peekIs(0, tok.Lt) { f.TemplateParams = p.templateParams() @@ -222,14 +215,14 @@ func (p *parser) constructorDecl(decos ast.Decorations) ast.IntrinsicDecl { return f } -func (p *parser) converterDecl(decos ast.Decorations) ast.IntrinsicDecl { +func (p *parser) converterDecl(decos ast.Attributes) ast.IntrinsicDecl { p.expect(tok.Converter, "converter declaration") name := p.next() f := ast.IntrinsicDecl{ - Source: name.Source, - Kind: ast.Converter, - Decorations: decos, - Name: string(name.Runes), + Source: name.Source, + Kind: ast.Converter, + Attributes: decos, + Name: string(name.Runes), } if p.peekIs(0, tok.Lt) { f.TemplateParams = p.templateParams() diff --git a/tools/src/cmd/intrinsic-gen/parser/parser_test.go b/tools/src/cmd/intrinsic-gen/parser/parser_test.go index 0dea9b3239..405aad2d5e 100644 --- a/tools/src/cmd/intrinsic-gen/parser/parser_test.go +++ b/tools/src/cmd/intrinsic-gen/parser/parser_test.go @@ -43,15 +43,15 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "enum E { A [[deco]] B C }", + "enum E { A @attr B C }", ast.AST{ Enums: []ast.EnumDecl{{ Name: "E", Entries: []ast.EnumEntry{ {Name: "A"}, { - Decorations: ast.Decorations{{ - Name: "deco", + Attributes: ast.Attributes{{ + Name: "attr", Values: []string{}, }}, Name: "B", @@ -81,43 +81,43 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco]] type T", + "@attr type T", ast.AST{ Types: []ast.TypeDecl{{ - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{}}, }, Name: "T", }}, }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco_a, deco_b]] type T", + "@attr_a @attr_b type T", ast.AST{ Types: []ast.TypeDecl{{ - Decorations: ast.Decorations{ - {Name: "deco_a", Values: []string{}}, - {Name: "deco_b", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr_a", Values: []string{}}, + {Name: "attr_b", Values: []string{}}, }, Name: "T", }}, }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - `[[deco("a", "b")]] type T`, ast.AST{ + `@attr("a", "b") type T`, ast.AST{ Types: []ast.TypeDecl{{ - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{"a", "b"}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{"a", "b"}}, }, Name: "T", }}, }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - `[[deco(1, "x")]] type T`, ast.AST{ + `@attr(1, "x") type T`, ast.AST{ Types: []ast.TypeDecl{{ - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{"1", "x"}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{"1", "x"}}, }, Name: "T", }}, @@ -157,13 +157,13 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco]] fn F()", + "@attr fn F()", ast.AST{ Builtins: []ast.IntrinsicDecl{{ Kind: ast.Builtin, Name: "F", - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{}}, }, Parameters: ast.Parameters{}, }}, @@ -281,13 +281,13 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco]] op F()", + "@attr op F()", ast.AST{ Operators: []ast.IntrinsicDecl{{ Kind: ast.Operator, Name: "F", - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{}}, }, Parameters: ast.Parameters{}, }}, @@ -405,13 +405,13 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco]] ctor F()", + "@attr ctor F()", ast.AST{ Constructors: []ast.IntrinsicDecl{{ Kind: ast.Constructor, Name: "F", - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{}}, }, Parameters: ast.Parameters{}, }}, @@ -529,13 +529,13 @@ func TestParser(t *testing.T) { }, }, { /////////////////////////////////////////////////////////////////// utils.ThisLine(), - "[[deco]] conv F()", + "@attr conv F()", ast.AST{ Converters: []ast.IntrinsicDecl{{ Kind: ast.Converter, Name: "F", - Decorations: ast.Decorations{ - {Name: "deco", Values: []string{}}, + Attributes: ast.Attributes{ + {Name: "attr", Values: []string{}}, }, Parameters: ast.Parameters{}, }}, @@ -672,16 +672,16 @@ func TestErrors(t *testing.T) { "test.txt:1:1 unexpected token 'integer'", }, { - "[[123]]", - "test.txt:1:3 expected 'ident' for decoration name, got 'integer'", - }, - { - "[[abc", - "expected ']]' for decoration list, but reached end of file", + "@123", + "test.txt:1:2 expected 'ident' for attribute name, got 'integer'", }, } { got, err := parser.Parse(test.src, "test.txt") - if gotErr := err.Error(); test.expect != gotErr { + gotErr := "" + if err != nil { + gotErr = err.Error() + } + if test.expect != gotErr { t.Errorf(`Parse() returned error "%+v", expected error "%+v"`, gotErr, test.expect) } if got != nil { diff --git a/tools/src/cmd/intrinsic-gen/resolver/resolve.go b/tools/src/cmd/intrinsic-gen/resolver/resolve.go index 4972a3d7f3..f3894d427d 100644 --- a/tools/src/cmd/intrinsic-gen/resolver/resolve.go +++ b/tools/src/cmd/intrinsic-gen/resolver/resolve.go @@ -130,14 +130,14 @@ func (r *resolver) enum(e ast.EnumDecl) error { Name: ast.Name, Enum: s, } - if internal := ast.Decorations.Take("internal"); internal != nil { + if internal := ast.Attributes.Take("internal"); internal != nil { entry.IsInternal = true if len(internal.Values) != 0 { - return fmt.Errorf("%v unexpected value for internal decoration", ast.Source) + return fmt.Errorf("%v unexpected value for internal attribute", ast.Source) } } - if len(ast.Decorations) != 0 { - return fmt.Errorf("%v unknown decoration", ast.Decorations[0].Source) + if len(ast.Attributes) != 0 { + return fmt.Errorf("%v unknown attribute", ast.Attributes[0].Source) } if err := r.globals.declare(entry, e.Source); err != nil { return err @@ -173,16 +173,16 @@ func (r *resolver) ty(a ast.TypeDecl) error { } t.TemplateParams = templateParams - // Scan for decorations - if d := a.Decorations.Take("display"); d != nil { + // Scan for attributes + if d := a.Attributes.Take("display"); d != nil { if len(d.Values) != 1 { - return fmt.Errorf("%v expected a single value for 'display' decoration", d.Source) + return fmt.Errorf("%v expected a single value for 'display' attribute", d.Source) } t.DisplayName = d.Values[0] } - if d := a.Decorations.Take("precedence"); d != nil { + if d := a.Attributes.Take("precedence"); d != nil { if len(d.Values) != 1 { - return fmt.Errorf("%v expected a single integer value for 'precedence' decoration", d.Source) + return fmt.Errorf("%v expected a single integer value for 'precedence' attribute", d.Source) } n, err := strconv.Atoi(d.Values[0]) if err != nil { @@ -191,8 +191,8 @@ func (r *resolver) ty(a ast.TypeDecl) error { t.Precedence = n } - if len(a.Decorations) != 0 { - return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source) + if len(a.Attributes) != 0 { + return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source) } return nil @@ -302,8 +302,8 @@ func (r *resolver) intrinsic( TemplateParams: templateParams, } - // Process overload decorations - if stageDeco := a.Decorations.Take("stage"); stageDeco != nil { + // Process overload attributes + if stageDeco := a.Attributes.Take("stage"); stageDeco != nil { for stageDeco != nil { for _, stage := range stageDeco.Values { switch stage { @@ -317,7 +317,7 @@ func (r *resolver) intrinsic( return fmt.Errorf("%v unknown stage '%v'", stageDeco.Source, stage) } } - stageDeco = a.Decorations.Take("stage") + stageDeco = a.Attributes.Take("stage") } } else { overload.CanBeUsedInStage = sem.StageUses{ @@ -326,14 +326,14 @@ func (r *resolver) intrinsic( Compute: true, } } - if deprecated := a.Decorations.Take("deprecated"); deprecated != nil { + if deprecated := a.Attributes.Take("deprecated"); deprecated != nil { overload.IsDeprecated = true if len(deprecated.Values) != 0 { - return fmt.Errorf("%v unexpected value for deprecated decoration", deprecated.Source) + return fmt.Errorf("%v unexpected value for deprecated attribute", deprecated.Source) } } - if len(a.Decorations) != 0 { - return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source) + if len(a.Attributes) != 0 { + return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source) } // Append the overload to the intrinsic diff --git a/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go b/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go index 7ce9236760..6679431619 100644 --- a/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go +++ b/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go @@ -44,7 +44,7 @@ func TestResolver(t *testing.T) { `type X`, success, }, { - `[[display("Y")]] type X`, + `@display("Y") type X`, success, }, { ` @@ -188,14 +188,14 @@ First declared here: file.txt:1:6 file.txt:1:13 'X' already declared First declared here: file.txt:1:6`, }, { - `[[meow]] type X`, + `@meow type X`, ` -file.txt:1:3 unknown decoration +file.txt:1:2 unknown attribute `, }, { - `[[display("Y", "Z")]] type X`, + `@display("Y", "Z") type X`, ` -file.txt:1:3 expected a single value for 'display' decoration`, +file.txt:1:2 expected a single value for 'display' attribute`, }, { ` enum e { a } diff --git a/tools/src/cmd/intrinsic-gen/tok/tok.go b/tools/src/cmd/intrinsic-gen/tok/tok.go index c5def48b99..b34f19ec55 100644 --- a/tools/src/cmd/intrinsic-gen/tok/tok.go +++ b/tools/src/cmd/intrinsic-gen/tok/tok.go @@ -37,6 +37,7 @@ const ( And Kind = "&" AndAnd Kind = "&&" Arrow Kind = "->" + Attr Kind = "@" Assign Kind = "=" Colon Kind = ":" Comma Kind = "," @@ -46,7 +47,6 @@ const ( Ge Kind = ">=" Gt Kind = ">" Lbrace Kind = "{" - Ldeco Kind = "[[" Le Kind = "<=" Lparen Kind = "(" Lt Kind = "<" @@ -58,7 +58,6 @@ const ( OrOr Kind = "||" Plus Kind = "+" Rbrace Kind = "}" - Rdeco Kind = "]]" Rparen Kind = ")" Shl Kind = "<<" Shr Kind = ">>"