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 <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2022-06-01 20:44:50 +00:00 committed by Dawn LUCI CQ
parent 0d757d2fad
commit e3e91c0d75
10 changed files with 217 additions and 228 deletions

View File

@ -30,7 +30,7 @@ enum storage_class {
workgroup workgroup
uniform uniform
storage storage
[[internal]] handle @internal handle
} }
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode // https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
@ -62,7 +62,7 @@ enum texel_format {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WGSL primitive types // // 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. // // will be picked when multiple types of a matcher match. //
// This is used to ensure that abstract numerical types materialize to the // // This is used to ensure that abstract numerical types materialize to the //
// concrete type with the lowest conversion rank. // // concrete type with the lowest conversion rank. //
@ -71,11 +71,11 @@ enum texel_format {
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section // https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
type bool type bool
[[precedence(4), display("abstract-float")]] type af @precedence(4) @display("abstract-float") type af
[[precedence(3), display("abstract-int")]] type ai @precedence(3) @display("abstract-int") type ai
[[precedence(2)]] type i32 @precedence(2) type i32
[[precedence(1)]] type u32 @precedence(1) type u32
[[precedence(0)]] type f32 @precedence(0) type f32
type vec2<T> type vec2<T>
type vec3<T> type vec3<T>
type vec4<T> type vec4<T>
@ -88,8 +88,8 @@ type mat3x4<T>
type mat4x2<T> type mat4x2<T>
type mat4x3<T> type mat4x3<T>
type mat4x4<T> type mat4x4<T>
[[display("vec{N}<{T}>")]] type vec<N: num, T> @display("vec{N}<{T}>") type vec<N: num, T>
[[display("mat{N}x{M}<{T}>")]] type mat<N: num, M: num, T> @display("mat{N}x{M}<{T}>") type mat<N: num, M: num, T>
type ptr<S: storage_class, T, A: access> type ptr<S: storage_class, T, A: access>
type atomic<T> type atomic<T>
type array<T> type array<T>
@ -114,9 +114,9 @@ type texture_storage_3d<F: texel_format, A: access>
type texture_external type texture_external
type __modf_result type __modf_result
[[display("__modf_result_vec{N}")]] type __modf_result_vec<N: num> @display("__modf_result_vec{N}") type __modf_result_vec<N: num>
type __frexp_result type __frexp_result
[[display("__frexp_result_vec{N}")]] type __frexp_result_vec<N: num> @display("__frexp_result_vec{N}") type __frexp_result_vec<N: num>
type __atomic_compare_exchange_result<T> type __atomic_compare_exchange_result<T>
@ -363,18 +363,18 @@ fn distance<N: num>(vec<N, f32>, vec<N, f32>) -> f32
fn dot<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> T fn dot<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> T
fn dot4I8Packed(u32, u32) -> i32 fn dot4I8Packed(u32, u32) -> i32
fn dot4U8Packed(u32, u32) -> u32 fn dot4U8Packed(u32, u32) -> u32
[[stage("fragment")]] fn dpdx(f32) -> f32 @stage("fragment") fn dpdx(f32) -> f32
[[stage("fragment")]] fn dpdx<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdx<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn dpdxCoarse(f32) -> f32 @stage("fragment") fn dpdxCoarse(f32) -> f32
[[stage("fragment")]] fn dpdxCoarse<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdxCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn dpdxFine(f32) -> f32 @stage("fragment") fn dpdxFine(f32) -> f32
[[stage("fragment")]] fn dpdxFine<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdxFine<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn dpdy(f32) -> f32 @stage("fragment") fn dpdy(f32) -> f32
[[stage("fragment")]] fn dpdy<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdy<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn dpdyCoarse(f32) -> f32 @stage("fragment") fn dpdyCoarse(f32) -> f32
[[stage("fragment")]] fn dpdyCoarse<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdyCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn dpdyFine(f32) -> f32 @stage("fragment") fn dpdyFine(f32) -> f32
[[stage("fragment")]] fn dpdyFine<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn dpdyFine<N: num>(vec<N, f32>) -> vec<N, f32>
fn exp(f32) -> f32 fn exp(f32) -> f32
fn exp<N: num>(vec<N, f32>) -> vec<N, f32> fn exp<N: num>(vec<N, f32>) -> vec<N, f32>
fn exp2(f32) -> f32 fn exp2(f32) -> f32
@ -394,12 +394,12 @@ fn fract(f32) -> f32
fn fract<N: num>(vec<N, f32>) -> vec<N, f32> fn fract<N: num>(vec<N, f32>) -> vec<N, f32>
fn frexp(f32) -> __frexp_result fn frexp(f32) -> __frexp_result
fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N> fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N>
[[stage("fragment")]] fn fwidth(f32) -> f32 @stage("fragment") fn fwidth(f32) -> f32
[[stage("fragment")]] fn fwidth<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn fwidth<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn fwidthCoarse(f32) -> f32 @stage("fragment") fn fwidthCoarse(f32) -> f32
[[stage("fragment")]] fn fwidthCoarse<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn fwidthCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
[[stage("fragment")]] fn fwidthFine(f32) -> f32 @stage("fragment") fn fwidthFine(f32) -> f32
[[stage("fragment")]] fn fwidthFine<N: num>(vec<N, f32>) -> vec<N, f32> @stage("fragment") fn fwidthFine<N: num>(vec<N, f32>) -> vec<N, f32>
fn insertBits<T: iu32>(T, T, u32, u32) -> T fn insertBits<T: iu32>(T, T, u32, u32) -> T
fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T> fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T>
fn inverseSqrt(f32) -> f32 fn inverseSqrt(f32) -> f32
@ -448,13 +448,13 @@ fn sinh(f32) -> f32
fn sinh<N: num>(vec<N, f32>) -> vec<N, f32> fn sinh<N: num>(vec<N, f32>) -> vec<N, f32>
fn smoothstep(f32, f32, f32) -> f32 fn smoothstep(f32, f32, f32) -> f32
fn smoothstep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> fn smoothstep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
[[deprecated]] fn smoothStep(f32, f32, f32) -> f32 @deprecated fn smoothStep(f32, f32, f32) -> f32
[[deprecated]] fn smoothStep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> @deprecated fn smoothStep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
fn sqrt(f32) -> f32 fn sqrt(f32) -> f32
fn sqrt<N: num>(vec<N, f32>) -> vec<N, f32> fn sqrt<N: num>(vec<N, f32>) -> vec<N, f32>
fn step(f32, f32) -> f32 fn step(f32, f32) -> f32
fn step<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> fn step<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
[[stage("compute")]] fn storageBarrier() @stage("compute") fn storageBarrier()
fn tan(f32) -> f32 fn tan(f32) -> f32
fn tan<N: num>(vec<N, f32>) -> vec<N, f32> fn tan<N: num>(vec<N, f32>) -> vec<N, f32>
fn tanh(f32) -> f32 fn tanh(f32) -> f32
@ -467,7 +467,7 @@ fn unpack2x16snorm(u32) -> vec2<f32>
fn unpack2x16unorm(u32) -> vec2<f32> fn unpack2x16unorm(u32) -> vec2<f32>
fn unpack4x8snorm(u32) -> vec4<f32> fn unpack4x8snorm(u32) -> vec4<f32>
fn unpack4x8unorm(u32) -> vec4<f32> fn unpack4x8unorm(u32) -> vec4<f32>
[[stage("compute")]] fn workgroupBarrier() @stage("compute") fn workgroupBarrier()
fn textureDimensions<T: fiu32>(texture: texture_1d<T>) -> i32 fn textureDimensions<T: fiu32>(texture: texture_1d<T>) -> i32
fn textureDimensions<T: fiu32>(texture: texture_1d<T>, level: i32) -> i32 fn textureDimensions<T: fiu32>(texture: texture_1d<T>, level: i32) -> i32
@ -531,35 +531,35 @@ fn textureNumLevels(texture: texture_depth_cube) -> i32
fn textureNumLevels(texture: texture_depth_cube_array) -> i32 fn textureNumLevels(texture: texture_depth_cube_array) -> i32
fn textureNumSamples<T: fiu32>(texture: texture_multisampled_2d<T>) -> i32 fn textureNumSamples<T: fiu32>(texture: texture_multisampled_2d<T>) -> i32
fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32 fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32
[[stage("fragment")]] fn textureSample(texture: texture_1d<f32>, sampler: sampler, coords: f32) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_1d<f32>, sampler: sampler, coords: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, offset: vec2<i32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, offset: vec2<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, offset: vec2<i32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, offset: vec2<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, offset: vec3<i32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, offset: vec3<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32) -> vec4<f32> @stage("fragment") fn textureSample(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32) -> vec4<f32>
[[stage("fragment")]] fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2<f32>) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2<f32>) -> f32
[[stage("fragment")]] fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2<f32>, offset: vec2<i32>) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2<f32>, offset: vec2<i32>) -> f32
[[stage("fragment")]] fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2<f32>, array_index: i32) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2<f32>, array_index: i32) -> f32
[[stage("fragment")]] fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2<f32>, array_index: i32, offset: vec2<i32>) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2<f32>, array_index: i32, offset: vec2<i32>) -> f32
[[stage("fragment")]] fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3<f32>) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3<f32>) -> f32
[[stage("fragment")]] fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: i32) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: i32) -> f32
[[stage("fragment")]] fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32, offset: vec2<i32>) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32, offset: vec2<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, bias: f32) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, bias: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, bias: f32, offset: vec2<i32>) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, bias: f32, offset: vec2<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, bias: f32) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, bias: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, bias: f32, offset: vec3<i32>) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_3d<f32>, sampler: sampler, coords: vec3<f32>, bias: f32, offset: vec3<i32>) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>, bias: f32) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>, bias: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSampleBias(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32, bias: f32) -> vec4<f32> @stage("fragment") fn textureSampleBias(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32, bias: f32) -> vec4<f32>
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, offset: vec2<i32>) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, offset: vec2<i32>) -> f32
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32, offset: vec2<i32>) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32, offset: vec2<i32>) -> f32
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32
[[stage("fragment")]] fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: i32, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: i32, depth_ref: f32) -> f32
fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32
fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, offset: vec2<i32>) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, offset: vec2<i32>) -> f32
fn textureSampleCompareLevel(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32
@ -611,17 +611,17 @@ fn textureLoad(texture: texture_depth_2d_array, coords: vec2<i32>, array_index:
fn textureLoad(texture: texture_depth_multisampled_2d, coords: vec2<i32>, sample_index: i32) -> f32 fn textureLoad(texture: texture_depth_multisampled_2d, coords: vec2<i32>, sample_index: i32) -> f32
fn textureLoad(texture: texture_external, coords: vec2<i32>) -> vec4<f32> fn textureLoad(texture: texture_external, coords: vec2<i32>) -> vec4<f32>
[[stage("fragment", "compute")]] fn atomicLoad<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T @stage("fragment", "compute") fn atomicLoad<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T
[[stage("fragment", "compute")]] fn atomicStore<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) @stage("fragment", "compute") fn atomicStore<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T)
[[stage("fragment", "compute")]] fn atomicAdd<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicAdd<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicSub<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicSub<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicMax<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicMax<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicMin<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicMin<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicAnd<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicAnd<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicOr<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicOr<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicXor<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicXor<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicExchange<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T @stage("fragment", "compute") fn atomicExchange<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T
[[stage("fragment", "compute")]] fn atomicCompareExchangeWeak<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> @stage("fragment", "compute") fn atomicCompareExchangeWeak<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Type constructors // // Type constructors //

View File

@ -52,7 +52,7 @@ std::string Bool::String(MatchState*) const {
} }
/// TypeMatcher for 'type af' /// TypeMatcher for 'type af'
/// @see src/tint/intrinsics.def:74:51 /// @see src/tint/intrinsics.def:74:48
class Af : public TypeMatcher { class Af : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -81,7 +81,7 @@ std::string Af::String(MatchState*) const {
} }
/// TypeMatcher for 'type ai' /// TypeMatcher for 'type ai'
/// @see src/tint/intrinsics.def:75:51 /// @see src/tint/intrinsics.def:75:48
class Ai : public TypeMatcher { class Ai : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -110,7 +110,7 @@ std::string Ai::String(MatchState*) const {
} }
/// TypeMatcher for 'type i32' /// TypeMatcher for 'type i32'
/// @see src/tint/intrinsics.def:76:24 /// @see src/tint/intrinsics.def:76:21
class I32 : public TypeMatcher { class I32 : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -137,7 +137,7 @@ std::string I32::String(MatchState*) const {
} }
/// TypeMatcher for 'type u32' /// TypeMatcher for 'type u32'
/// @see src/tint/intrinsics.def:77:24 /// @see src/tint/intrinsics.def:77:21
class U32 : public TypeMatcher { class U32 : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -164,7 +164,7 @@ std::string U32::String(MatchState*) const {
} }
/// TypeMatcher for 'type f32' /// TypeMatcher for 'type f32'
/// @see src/tint/intrinsics.def:78:24 /// @see src/tint/intrinsics.def:78:21
class F32 : public TypeMatcher { class F32 : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -587,7 +587,7 @@ std::string Mat4X4::String(MatchState* state) const {
} }
/// TypeMatcher for 'type vec' /// TypeMatcher for 'type vec'
/// @see src/tint/intrinsics.def:91:37 /// @see src/tint/intrinsics.def:91:34
class Vec : public TypeMatcher { class Vec : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.
@ -628,7 +628,7 @@ std::string Vec::String(MatchState* state) const {
} }
/// TypeMatcher for 'type mat' /// TypeMatcher for 'type mat'
/// @see src/tint/intrinsics.def:92:37 /// @see src/tint/intrinsics.def:92:34
class Mat : public TypeMatcher { class Mat : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// 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' /// TypeMatcher for 'type __modf_result_vec'
/// @see src/tint/intrinsics.def:117:42 /// @see src/tint/intrinsics.def:117:39
class ModfResultVec : public TypeMatcher { class ModfResultVec : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// 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' /// TypeMatcher for 'type __frexp_result_vec'
/// @see src/tint/intrinsics.def:119:43 /// @see src/tint/intrinsics.def:119:40
class FrexpResultVec : public TypeMatcher { class FrexpResultVec : public TypeMatcher {
public: public:
/// Checks whether the given type matches the matcher rules. /// Checks whether the given type matches the matcher rules.

View File

@ -87,13 +87,13 @@ func (e EnumDecl) Format(w fmt.State, verb rune) {
type EnumEntry struct { type EnumEntry struct {
Source tok.Source Source tok.Source
Name string Name string
Decorations Decorations Attributes Attributes
} }
// Format implements the fmt.Formatter interface // Format implements the fmt.Formatter interface
func (e EnumEntry) Format(w fmt.State, verb rune) { func (e EnumEntry) Format(w fmt.State, verb rune) {
if len(e.Decorations) > 0 { if len(e.Attributes) > 0 {
fmt.Fprintf(w, "%v %v", e.Decorations, e.Name) fmt.Fprintf(w, "%v %v", e.Attributes, e.Name)
} else { } else {
fmt.Fprint(w, e.Name) fmt.Fprint(w, e.Name)
} }
@ -136,7 +136,7 @@ type IntrinsicDecl struct {
Source tok.Source Source tok.Source
Kind IntrinsicKind Kind IntrinsicKind
Name string Name string
Decorations Decorations Attributes Attributes
TemplateParams TemplateParams TemplateParams TemplateParams
Parameters Parameters Parameters Parameters
ReturnType *TemplatedName ReturnType *TemplatedName
@ -243,15 +243,15 @@ func (t TemplatedName) Format(w fmt.State, verb rune) {
// TypeDecl describes a type declaration // TypeDecl describes a type declaration
type TypeDecl struct { type TypeDecl struct {
Source tok.Source Source tok.Source
Decorations Decorations Attributes Attributes
Name string Name string
TemplateParams TemplateParams TemplateParams TemplateParams
} }
// Format implements the fmt.Formatter interface // Format implements the fmt.Formatter interface
func (p TypeDecl) Format(w fmt.State, verb rune) { func (p TypeDecl) Format(w fmt.State, verb rune) {
if len(p.Decorations) > 0 { if len(p.Attributes) > 0 {
p.Decorations.Format(w, verb) p.Attributes.Format(w, verb)
fmt.Fprintf(w, " type %v", p.Name) fmt.Fprintf(w, " type %v", p.Name)
} }
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: // Example:
// [[a(x), b(y)]] // [[a(x), b(y)]]
type Decorations []Decoration type Attributes []Attribute
// Format implements the fmt.Formatter interface // 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, "[[") fmt.Fprint(w, "[[")
for i, d := range l { for i, d := range l {
if i > 0 { if i > 0 {
@ -313,30 +313,30 @@ func (l Decorations) Format(w fmt.State, verb rune) {
fmt.Fprint(w, "]]") fmt.Fprint(w, "]]")
} }
// Take looks up the decoration with the given name. If the decoration is found // Take looks up the attribute with the given name. If the attribute is found
// it is removed from the Decorations list and returned, otherwise nil is // it is removed from the Attributes list and returned, otherwise nil is
// returned and the Decorations are not altered. // returned and the Attributes are not altered.
func (l *Decorations) Take(name string) *Decoration { func (l *Attributes) Take(name string) *Attribute {
for i, d := range *l { for i, a := range *l {
if d.Name == name { if a.Name == name {
*l = append((*l)[:i], (*l)[i+1:]...) *l = append((*l)[:i], (*l)[i+1:]...)
return &d return &a
} }
} }
return nil return nil
} }
// Decoration describes a single decoration // Attribute describes a single attribute
// Example: // Example:
// a(x) // @a(x)
type Decoration struct { type Attribute struct {
Source tok.Source Source tok.Source
Name string Name string
Values []string Values []string
} }
// Format implements the fmt.Formatter interface // 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) fmt.Fprintf(w, "%v", d.Name)
if len(d.Values) > 0 { if len(d.Values) > 0 {
fmt.Fprintf(w, "(") fmt.Fprintf(w, "(")

View File

@ -52,6 +52,8 @@ func (l *lexer) lex() error {
l.next() l.next()
case '\n': case '\n':
l.next() l.next()
case '@':
l.tok(1, tok.Attr)
case '(': case '(':
l.tok(1, tok.Lparen) l.tok(1, tok.Lparen)
case ')': case ')':
@ -89,8 +91,6 @@ func (l *lexer) lex() error {
l.skip(l.count(toFirst('\n'))) l.skip(l.count(toFirst('\n')))
l.next() // Consume newline l.next() // Consume newline
case l.match("/", tok.Divide): case l.match("/", tok.Divide):
case l.match("[[", tok.Ldeco):
case l.match("]]", tok.Rdeco):
case l.match("->", tok.Arrow): case l.match("->", tok.Arrow):
case l.match("-", tok.Minus): case l.match("-", tok.Minus):
case l.match("fn", tok.Function): case l.match("fn", tok.Function):

View File

@ -127,11 +127,8 @@ func TestLexTokens(t *testing.T) {
{">", tok.Token{Kind: tok.Gt, Runes: []rune(">"), Source: tok.Source{ {">", tok.Token{Kind: tok.Gt, Runes: []rune(">"), Source: tok.Source{
S: loc(1, 1, 0), E: loc(1, 2, 1), S: loc(1, 1, 0), E: loc(1, 2, 1),
}}}, }}},
{"[[", tok.Token{Kind: tok.Ldeco, Runes: []rune("[["), Source: tok.Source{ {"@", tok.Token{Kind: tok.Attr, Runes: []rune("@"), Source: tok.Source{
S: loc(1, 1, 0), E: loc(1, 3, 2), S: loc(1, 1, 0), E: loc(1, 2, 1),
}}},
{"]]", tok.Token{Kind: tok.Rdeco, Runes: []rune("]]"), Source: tok.Source{
S: loc(1, 1, 0), E: loc(1, 3, 2),
}}}, }}},
{"(", tok.Token{Kind: tok.Lparen, Runes: []rune("("), Source: tok.Source{ {"(", tok.Token{Kind: tok.Lparen, Runes: []rune("("), Source: tok.Source{
S: loc(1, 1, 0), E: loc(1, 2, 1), S: loc(1, 1, 0), E: loc(1, 2, 1),

View File

@ -43,40 +43,40 @@ type parser struct {
func (p *parser) parse() (*ast.AST, error) { func (p *parser) parse() (*ast.AST, error) {
out := ast.AST{} out := ast.AST{}
var decorations ast.Decorations var attributes ast.Attributes
for p.err == nil { for p.err == nil {
t := p.peek(0) t := p.peek(0)
if t == nil { if t == nil {
break break
} }
switch t.Kind { switch t.Kind {
case tok.Ldeco: case tok.Attr:
decorations = append(decorations, p.decorations()...) attributes = append(attributes, p.attributes()...)
case tok.Enum: case tok.Enum:
if len(decorations) > 0 { if len(attributes) > 0 {
p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source) p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
} }
out.Enums = append(out.Enums, p.enumDecl()) out.Enums = append(out.Enums, p.enumDecl())
case tok.Match: case tok.Match:
if len(decorations) > 0 { if len(attributes) > 0 {
p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source) p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
} }
out.Matchers = append(out.Matchers, p.matcherDecl()) out.Matchers = append(out.Matchers, p.matcherDecl())
case tok.Type: case tok.Type:
out.Types = append(out.Types, p.typeDecl(decorations)) out.Types = append(out.Types, p.typeDecl(attributes))
decorations = nil attributes = nil
case tok.Function: case tok.Function:
out.Builtins = append(out.Builtins, p.builtinDecl(decorations)) out.Builtins = append(out.Builtins, p.builtinDecl(attributes))
decorations = nil attributes = nil
case tok.Operator: case tok.Operator:
out.Operators = append(out.Operators, p.operatorDecl(decorations)) out.Operators = append(out.Operators, p.operatorDecl(attributes))
decorations = nil attributes = nil
case tok.Constructor: case tok.Constructor:
out.Constructors = append(out.Constructors, p.constructorDecl(decorations)) out.Constructors = append(out.Constructors, p.constructorDecl(attributes))
decorations = nil attributes = nil
case tok.Converter: case tok.Converter:
out.Converters = append(out.Converters, p.converterDecl(decorations)) out.Converters = append(out.Converters, p.converterDecl(attributes))
decorations = nil attributes = nil
default: default:
p.err = fmt.Errorf("%v unexpected token '%v'", t.Source, t.Kind) 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 { func (p *parser) enumEntry() ast.EnumEntry {
decos := p.decorations() decos := p.attributes()
name := p.expect(tok.Identifier, "enum entry") 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 { func (p *parser) matcherDecl() ast.MatcherDecl {
@ -118,12 +118,12 @@ func (p *parser) matcherDecl() ast.MatcherDecl {
return m 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") p.expect(tok.Type, "type declaration")
name := p.expect(tok.Identifier, "type name") name := p.expect(tok.Identifier, "type name")
m := ast.TypeDecl{ m := ast.TypeDecl{
Source: name.Source, Source: name.Source,
Decorations: decos, Attributes: decos,
Name: string(name.Runes), Name: string(name.Runes),
} }
if p.peekIs(0, tok.Lt) { if p.peekIs(0, tok.Lt) {
@ -132,13 +132,10 @@ func (p *parser) typeDecl(decos ast.Decorations) ast.TypeDecl {
return m return m
} }
func (p *parser) decorations() ast.Decorations { func (p *parser) attributes() ast.Attributes {
if p.match(tok.Ldeco) == nil { var out ast.Attributes
return nil for p.match(tok.Attr) != nil && p.err == nil {
} name := p.expect(tok.Identifier, "attribute name")
out := ast.Decorations{}
for p.err == nil {
name := p.expect(tok.Identifier, "decoration name")
values := []string{} values := []string{}
if p.match(tok.Lparen) != nil { if p.match(tok.Lparen) != nil {
for p.err == nil { for p.err == nil {
@ -147,28 +144,24 @@ func (p *parser) decorations() ast.Decorations {
break 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, Source: name.Source,
Name: string(name.Runes), Name: string(name.Runes),
Values: values, Values: values,
}) })
if p.match(tok.Comma) == nil {
break
} }
}
p.expect(tok.Rdeco, "decoration list")
return out 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") p.expect(tok.Function, "function declaration")
name := p.expect(tok.Identifier, "function name") name := p.expect(tok.Identifier, "function name")
f := ast.IntrinsicDecl{ f := ast.IntrinsicDecl{
Source: name.Source, Source: name.Source,
Kind: ast.Builtin, Kind: ast.Builtin,
Decorations: decos, Attributes: decos,
Name: string(name.Runes), Name: string(name.Runes),
} }
if p.peekIs(0, tok.Lt) { if p.peekIs(0, tok.Lt) {
@ -182,13 +175,13 @@ func (p *parser) builtinDecl(decos ast.Decorations) ast.IntrinsicDecl {
return f 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") p.expect(tok.Operator, "operator declaration")
name := p.next() name := p.next()
f := ast.IntrinsicDecl{ f := ast.IntrinsicDecl{
Source: name.Source, Source: name.Source,
Kind: ast.Operator, Kind: ast.Operator,
Decorations: decos, Attributes: decos,
Name: string(name.Runes), Name: string(name.Runes),
} }
if p.peekIs(0, tok.Lt) { if p.peekIs(0, tok.Lt) {
@ -202,13 +195,13 @@ func (p *parser) operatorDecl(decos ast.Decorations) ast.IntrinsicDecl {
return f 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") p.expect(tok.Constructor, "constructor declaration")
name := p.next() name := p.next()
f := ast.IntrinsicDecl{ f := ast.IntrinsicDecl{
Source: name.Source, Source: name.Source,
Kind: ast.Constructor, Kind: ast.Constructor,
Decorations: decos, Attributes: decos,
Name: string(name.Runes), Name: string(name.Runes),
} }
if p.peekIs(0, tok.Lt) { if p.peekIs(0, tok.Lt) {
@ -222,13 +215,13 @@ func (p *parser) constructorDecl(decos ast.Decorations) ast.IntrinsicDecl {
return f 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") p.expect(tok.Converter, "converter declaration")
name := p.next() name := p.next()
f := ast.IntrinsicDecl{ f := ast.IntrinsicDecl{
Source: name.Source, Source: name.Source,
Kind: ast.Converter, Kind: ast.Converter,
Decorations: decos, Attributes: decos,
Name: string(name.Runes), Name: string(name.Runes),
} }
if p.peekIs(0, tok.Lt) { if p.peekIs(0, tok.Lt) {

View File

@ -43,15 +43,15 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"enum E { A [[deco]] B C }", "enum E { A @attr B C }",
ast.AST{ ast.AST{
Enums: []ast.EnumDecl{{ Enums: []ast.EnumDecl{{
Name: "E", Name: "E",
Entries: []ast.EnumEntry{ Entries: []ast.EnumEntry{
{Name: "A"}, {Name: "A"},
{ {
Decorations: ast.Decorations{{ Attributes: ast.Attributes{{
Name: "deco", Name: "attr",
Values: []string{}, Values: []string{},
}}, }},
Name: "B", Name: "B",
@ -81,43 +81,43 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco]] type T", "@attr type T",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{}}, {Name: "attr", Values: []string{}},
}, },
Name: "T", Name: "T",
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco_a, deco_b]] type T", "@attr_a @attr_b type T",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco_a", Values: []string{}}, {Name: "attr_a", Values: []string{}},
{Name: "deco_b", Values: []string{}}, {Name: "attr_b", Values: []string{}},
}, },
Name: "T", Name: "T",
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
`[[deco("a", "b")]] type T`, ast.AST{ `@attr("a", "b") type T`, ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{"a", "b"}}, {Name: "attr", Values: []string{"a", "b"}},
}, },
Name: "T", Name: "T",
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
`[[deco(1, "x")]] type T`, ast.AST{ `@attr(1, "x") type T`, ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{"1", "x"}}, {Name: "attr", Values: []string{"1", "x"}},
}, },
Name: "T", Name: "T",
}}, }},
@ -157,13 +157,13 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco]] fn F()", "@attr fn F()",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
Kind: ast.Builtin, Kind: ast.Builtin,
Name: "F", Name: "F",
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{}}, {Name: "attr", Values: []string{}},
}, },
Parameters: ast.Parameters{}, Parameters: ast.Parameters{},
}}, }},
@ -281,13 +281,13 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco]] op F()", "@attr op F()",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
Kind: ast.Operator, Kind: ast.Operator,
Name: "F", Name: "F",
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{}}, {Name: "attr", Values: []string{}},
}, },
Parameters: ast.Parameters{}, Parameters: ast.Parameters{},
}}, }},
@ -405,13 +405,13 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco]] ctor F()", "@attr ctor F()",
ast.AST{ ast.AST{
Constructors: []ast.IntrinsicDecl{{ Constructors: []ast.IntrinsicDecl{{
Kind: ast.Constructor, Kind: ast.Constructor,
Name: "F", Name: "F",
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{}}, {Name: "attr", Values: []string{}},
}, },
Parameters: ast.Parameters{}, Parameters: ast.Parameters{},
}}, }},
@ -529,13 +529,13 @@ func TestParser(t *testing.T) {
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"[[deco]] conv F()", "@attr conv F()",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
Kind: ast.Converter, Kind: ast.Converter,
Name: "F", Name: "F",
Decorations: ast.Decorations{ Attributes: ast.Attributes{
{Name: "deco", Values: []string{}}, {Name: "attr", Values: []string{}},
}, },
Parameters: ast.Parameters{}, Parameters: ast.Parameters{},
}}, }},
@ -672,16 +672,16 @@ func TestErrors(t *testing.T) {
"test.txt:1:1 unexpected token 'integer'", "test.txt:1:1 unexpected token 'integer'",
}, },
{ {
"[[123]]", "@123",
"test.txt:1:3 expected 'ident' for decoration name, got 'integer'", "test.txt:1:2 expected 'ident' for attribute name, got 'integer'",
},
{
"[[abc",
"expected ']]' for decoration list, but reached end of file",
}, },
} { } {
got, err := parser.Parse(test.src, "test.txt") 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) t.Errorf(`Parse() returned error "%+v", expected error "%+v"`, gotErr, test.expect)
} }
if got != nil { if got != nil {

View File

@ -130,14 +130,14 @@ func (r *resolver) enum(e ast.EnumDecl) error {
Name: ast.Name, Name: ast.Name,
Enum: s, Enum: s,
} }
if internal := ast.Decorations.Take("internal"); internal != nil { if internal := ast.Attributes.Take("internal"); internal != nil {
entry.IsInternal = true entry.IsInternal = true
if len(internal.Values) != 0 { 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 { if len(ast.Attributes) != 0 {
return fmt.Errorf("%v unknown decoration", ast.Decorations[0].Source) return fmt.Errorf("%v unknown attribute", ast.Attributes[0].Source)
} }
if err := r.globals.declare(entry, e.Source); err != nil { if err := r.globals.declare(entry, e.Source); err != nil {
return err return err
@ -173,16 +173,16 @@ func (r *resolver) ty(a ast.TypeDecl) error {
} }
t.TemplateParams = templateParams t.TemplateParams = templateParams
// Scan for decorations // Scan for attributes
if d := a.Decorations.Take("display"); d != nil { if d := a.Attributes.Take("display"); d != nil {
if len(d.Values) != 1 { 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] 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 { 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]) n, err := strconv.Atoi(d.Values[0])
if err != nil { if err != nil {
@ -191,8 +191,8 @@ func (r *resolver) ty(a ast.TypeDecl) error {
t.Precedence = n t.Precedence = n
} }
if len(a.Decorations) != 0 { if len(a.Attributes) != 0 {
return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source) return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source)
} }
return nil return nil
@ -302,8 +302,8 @@ func (r *resolver) intrinsic(
TemplateParams: templateParams, TemplateParams: templateParams,
} }
// Process overload decorations // Process overload attributes
if stageDeco := a.Decorations.Take("stage"); stageDeco != nil { if stageDeco := a.Attributes.Take("stage"); stageDeco != nil {
for stageDeco != nil { for stageDeco != nil {
for _, stage := range stageDeco.Values { for _, stage := range stageDeco.Values {
switch stage { switch stage {
@ -317,7 +317,7 @@ func (r *resolver) intrinsic(
return fmt.Errorf("%v unknown stage '%v'", stageDeco.Source, stage) return fmt.Errorf("%v unknown stage '%v'", stageDeco.Source, stage)
} }
} }
stageDeco = a.Decorations.Take("stage") stageDeco = a.Attributes.Take("stage")
} }
} else { } else {
overload.CanBeUsedInStage = sem.StageUses{ overload.CanBeUsedInStage = sem.StageUses{
@ -326,14 +326,14 @@ func (r *resolver) intrinsic(
Compute: true, Compute: true,
} }
} }
if deprecated := a.Decorations.Take("deprecated"); deprecated != nil { if deprecated := a.Attributes.Take("deprecated"); deprecated != nil {
overload.IsDeprecated = true overload.IsDeprecated = true
if len(deprecated.Values) != 0 { 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 { if len(a.Attributes) != 0 {
return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source) return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source)
} }
// Append the overload to the intrinsic // Append the overload to the intrinsic

View File

@ -44,7 +44,7 @@ func TestResolver(t *testing.T) {
`type X`, `type X`,
success, success,
}, { }, {
`[[display("Y")]] type X`, `@display("Y") type X`,
success, success,
}, { }, {
` `
@ -188,14 +188,14 @@ First declared here: file.txt:1:6
file.txt:1:13 'X' already declared file.txt:1:13 'X' already declared
First declared here: file.txt:1:6`, 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 } enum e { a }

View File

@ -37,6 +37,7 @@ const (
And Kind = "&" And Kind = "&"
AndAnd Kind = "&&" AndAnd Kind = "&&"
Arrow Kind = "->" Arrow Kind = "->"
Attr Kind = "@"
Assign Kind = "=" Assign Kind = "="
Colon Kind = ":" Colon Kind = ":"
Comma Kind = "," Comma Kind = ","
@ -46,7 +47,6 @@ const (
Ge Kind = ">=" Ge Kind = ">="
Gt Kind = ">" Gt Kind = ">"
Lbrace Kind = "{" Lbrace Kind = "{"
Ldeco Kind = "[["
Le Kind = "<=" Le Kind = "<="
Lparen Kind = "(" Lparen Kind = "("
Lt Kind = "<" Lt Kind = "<"
@ -58,7 +58,6 @@ const (
OrOr Kind = "||" OrOr Kind = "||"
Plus Kind = "+" Plus Kind = "+"
Rbrace Kind = "}" Rbrace Kind = "}"
Rdeco Kind = "]]"
Rparen Kind = ")" Rparen Kind = ")"
Shl Kind = "<<" Shl Kind = "<<"
Shr Kind = ">>" Shr Kind = ">>"