Editor/Prism/Text/LanguageDb/SlangLanguage.cs

A static C# class that defines the Slang language database used by the editor Prism subsystem. It declares language metadata and many sets/lists of tokens: versions, keywords, modifiers, literals, built-in types and object types, attributes, intrinsics, operators, stages, preprocessor directives, and a LanguageDefinition instance assembled from those collections.

Reflection
namespace Editor.Prism.Text.LanguageDb;

/// <summary>
/// The Slang language database. Slang is a superset of HLSL, so everything in
/// <see cref="HlslLanguage"/> still applies; this adds the module system, generics, interfaces,
/// auto-diff and the 109 <c>attribute_syntax</c> names, all transcribed from the official TextMate
/// grammar and <c>core.meta.slang</c>.
/// </summary>
public static class SlangLanguage
{
	/// <summary>The language version Prism pins its generated modules to.</summary>
	public const string LanguageVersion = "2026";

	/// <summary>Every language version the compiler accepts, newest last.</summary>
	public static readonly IReadOnlyList<string> LanguageVersions = new[] { "2018", "2025", "2026", "202c" };

	/// <summary>Aliases accepted in place of a version number.</summary>
	public static readonly IReadOnlyList<string> LanguageVersionAliases = new[]
	{
		"default", "legacy", "202a", "202b", "latest", "next"
	};

	/// <summary>Control-flow keywords, from <c>keyword.control.slang</c>.</summary>
	public static readonly IReadOnlySet<string> ControlKeywords = Set(
		"if", "else", "switch", "case", "default", "return", "try", "throw", "throws", "catch",
		"while", "for", "do", "break", "continue", "discard", "defer",
		"spirv_asm", "__target_switch", "__stage_switch", "__intrinsic_asm", "__GPU_FOREACH" );

	/// <summary>Declaration keywords, from <c>keyword.declaration.slang</c>.</summary>
	public static readonly IReadOnlySet<string> Keywords = Set(
		"let", "var", "func", "typedef", "typealias", "property", "get", "set",
		"class", "struct", "interface", "enum", "extension", "associatedtype",
		"namespace", "using", "import", "module", "implementing",
		"cbuffer", "tbuffer", "where", "syntax", "attribute_syntax", "semantic", "type_param",
		"__generic", "__extension", "__init", "__subscript", "__import", "__include",
		"__ignored_block", "__transparent_block", "__file_decl",
		"__require_capability", "__generic_value_param", "typename",
		"operator", "sizeof", "alignof", "countof", "register", "packoffset", "this", "This",
		"as", "is", "no_diff", "fwd_diff", "bwd_diff", "__fwd_diff", "__bwd_diff",
		"__dispatch_kernel", "each", "expand", "optional", "nonempty", "__return_val",
		"__first", "__last", "__trimFirst", "__trimLast", "__packBranch",
		"__getAddress", "__floatAsInt" );

	/// <summary>Storage and interpolation modifiers, from <c>storage.modifier</c>.</summary>
	public static readonly IReadOnlySet<string> Modifiers = Set(
		"static", "const", "extern", "inline",
		"public", "private", "internal", "protected",
		"uniform", "dynamic_uniform", "groupshared", "shared", "volatile", "coherent", "restrict",
		"readonly", "writeonly", "export", "override", "__extern_cpp", "param", "require",
		"row_major", "column_major",
		"nointerpolation", "noperspective", "linear", "sample", "centroid", "precise",
		"in", "out", "inout", "ref", "__ref", "__constref",
		"dyn", "some", "implicit", "noncopyable", "constexpr", "mutating",
		"highp", "lowp", "mediump", "__builtin", "__global",
		"point", "line", "triangle", "lineadj", "triangleadj",
		"vertices", "indices", "primitives", "payload",
		"__prefix", "__postfix", "__exported", "layout", "hitAttributeEXT",
		"__intrinsic_op", "__target_intrinsic", "__specialized_for_target",
		"__glsl_extension", "__glsl_version", "__spirv_version", "__wgsl_extension", "__cuda_sm_version",
		"__builtin_type", "__builtin_requirement", "__magic_type", "__magic_enum",
		"__intrinsic_type", "__implicit_conversion", "__attributeTarget",
		"snorm", "unorm", "globallycoherent" );

	/// <summary>Literal keywords.</summary>
	public static readonly IReadOnlySet<string> Literals = Set( "true", "false", "nullptr", "none", "NULL" );

	/// <summary>Every built-in type spelling, scalars plus the vector and matrix grids.</summary>
	public static readonly IReadOnlySet<string> BuiltinTypes = BuildBuiltinTypes();

	/// <summary>Built-in library and resource type names.</summary>
	public static readonly IReadOnlySet<string> ObjectTypes = BuildObjectTypes();

	/// <summary>
	/// The stage strings accepted by <c>[shader("…")]</c> and by <c>-stage</c>, from
	/// <c>slang-profile-defs.h</c>. <c>fragment</c> is an alias of <c>pixel</c>, and <c>task</c> of
	/// <c>amplification</c>.
	/// </summary>
	public static readonly IReadOnlyList<string> Stages = new[]
	{
		"vertex", "hull", "tesscontrol", "domain", "tesseval", "geometry", "pixel", "fragment",
		"compute", "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable",
		"mesh", "amplification", "task", "dispatch", "node"
	};

	/// <summary>Preprocessor directive names, including the Slang-only <c>#language</c>.</summary>
	public static readonly IReadOnlySet<string> PreprocessorDirectives = Set(
		"define", "elif", "else", "endif", "error", "warning", "if", "ifdef", "ifndef",
		"include", "line", "pragma", "undef", "language", "version", "extension" );

	/// <summary>Every <c>attribute_syntax</c> name declared by the core and diff modules.</summary>
	public static readonly IReadOnlySet<string> Attributes = Set(
		// Entry point / pipeline
		"shader", "Shader", "numthreads", "NumThreads", "WaveSize", "maxtessfactor",
		"outputcontrolpoints", "outputtopology", "partitioning", "patchconstantfunc", "domain",
		"maxvertexcount", "instance", "earlydepthstencil", "raypayload", "Shader64BitIndexing",
		"DerivativeGroupQuad", "DerivativeGroupLinear", "MaximallyReconverges", "QuadDerivatives",
		"RequireFullQuads",

		// Control flow / optimisation
		"unroll", "ForceUnroll", "loop", "fastopt", "allow_uav_condition", "MaxIters",
		"flatten", "branch", "forcecase", "call", "ForceInline", "noinline",
		"__unsafeForceInlineEarly", "__AlwaysFoldIntoUseSiteAttribute",

		// Members / functions
		"mutating", "nonmutating", "constref", "__ref", "NoDiscard", "__readNone", "__NoSideEffect",
		"sealed", "open", "OverloadRank", "deprecated", "RemovedSince", "anyValueSize", "Specialize",
		"builtin", "NonUniformReturn", "noRefInline", "__NonCopyableType", "__FunctionInterface",

		// Types / enums
		"UnscopedEnum", "Flags", "__AttributeUsage", "format", "vk_image_format", "COM", "KnownBuiltin",

		// Vulkan / SPIR-V
		"vk_binding", "gl_binding", "vk_shader_record", "shader_record", "vk_push_constant",
		"push_constant", "vk_location", "vk_index", "vk_offset", "vk_spirv_instruction",
		"vk_input_attachment_index", "spv_target_env_1_3", "disable_array_flattening",
		"__vulkanRayPayload", "__vulkanCallablePayload", "__vulkanHitObjectAttributes",
		"__vulkanHitAttributes", "__requiresNVAPI", "__GLSLRequireShaderInputParameter",

		// Capabilities / diagnostics / modules
		"require", "allow", "ExperimentalModule",

		// Interop / host
		"DllImport", "DllExport", "__extern", "TorchEntryPoint", "CudaDeviceExport",
		"CUDADeviceExport", "CudaHost", "CUDAHost", "CudaKernel", "CUDAKernel", "AutoPyBindCUDA",
		"PyExport",

		// Auto-diff
		"Differentiable", "BackwardDifferentiable", "ForwardDifferentiable", "TreatAsDifferentiable",
		"MaybeDifferentiable", "HasTrivialForwardDerivative", "PreferCheckpoint",
		"ForwardDerivative", "BackwardDerivative", "ForwardDerivativeOf", "BackwardDerivativeOf",
		"PrimalSubstitute", "PrimalSubstituteOf", "DerivativeMember", "NoDiffThis",

		// HLSL attributes Slang also accepts
		"RootSignature", "WaveOpsIncludeHelperLanes", "clipplanes" );

	/// <summary>
	/// Intrinsics the Slang core module adds on top of the HLSL catalogue. They are legal in a
	/// <c>.slang</c> module but must never be emitted into a <c>.shader</c>.
	/// </summary>
	public static readonly IReadOnlySet<string> ExtraIntrinsics = Set(
		// Math
		"acosh", "asinh", "atanh", "cospi", "sinpi", "tanpi", "copysign", "exp10", "fabs", "fdim",
		"fmax", "fmax3", "fmedian3", "fmin", "fmin3", "fract", "max3", "median3", "min3", "mod",
		"nextafter", "powr", "rint",

		// Packing and conversion
		"packHalf2x16", "packSnorm2x16", "packSnorm4x8", "packUnorm2x16", "packUnorm4x8",
		"packInt4x8", "packInt4x8Clamp", "packUint4x8", "packUint4x8Clamp",
		"unpackHalf2x16ToFloat", "unpackHalf2x16ToHalf",
		"unpackSnorm2x16ToFloat", "unpackSnorm2x16ToHalf",
		"unpackSnorm4x8ToFloat", "unpackSnorm4x8ToHalf",
		"unpackUnorm2x16ToFloat", "unpackUnorm2x16ToHalf",
		"unpackUnorm4x8ToFloat", "unpackUnorm4x8ToHalf",
		"unpackInt4x8ToInt16", "unpackInt4x8ToInt32",
		"unpackUint4x8ToUint16", "unpackUint4x8ToUint32",
		"reinterpret", "bit_cast",

		// Derivatives and fragment ops
		"fwidth_coarse", "fwidth_fine", "EvaluateAttributeAtCentroid",

		// Texture and buffer members Slang adds
		"SampleLevelZero", "SampleCmpBias", "SampleCmpGrad", "SubpassLoad",
		"Load2Aligned", "Load3Aligned", "Load4Aligned",
		"Store2Aligned", "Store3Aligned", "Store4Aligned",
		"loadCoherent", "storeCoherent",

		// Barriers
		"AllMemoryBarrierWithWaveSync", "AllMemoryBarrierWithWaveMaskSync",
		"GroupMemoryBarrierWithWaveSync", "GroupMemoryBarrierWithWaveMaskSync",

		// Atomics
		"InterlockedAdd64", "InterlockedAddF16", "InterlockedAddF16x2", "InterlockedAddF32",
		"InterlockedAddF64", "InterlockedAddI64", "InterlockedAnd64", "InterlockedOr64",
		"InterlockedXor64", "InterlockedMin64", "InterlockedMax64", "InterlockedExchange64",
		"InterlockedExchangeFloat", "InterlockedCompareExchange64", "InterlockedCompareExchangeU64",
		"InterlockedCompareStore64",

		// Wave and subgroup
		"WaveGetNumWaves", "WaveGetWaveIndex", "WaveGetActiveMask", "WaveGetConvergedMask",
		"WaveGetActiveMulti", "WaveGetConvergedMulti", "WaveGetLaneEqMask", "WaveGetLaneGeMask",
		"WaveGetLaneGtMask", "WaveGetLaneLeMask", "WaveGetLaneLtMask",
		"WavePrefixMin", "WavePrefixMax", "WavePrefixBitAnd", "WavePrefixBitOr", "WavePrefixBitXor",
		"WaveBroadcastLaneAt", "WaveShuffle", "WaveRotate", "WaveClusteredRotate",
		"WaveMaskBallot", "WaveMaskAllTrue", "WaveMaskAnyTrue", "WaveMaskAllEqual",
		"WaveMaskIsFirstLane", "WaveMaskCountBits", "WaveMaskSum", "WaveMaskProduct",
		"WaveMaskMin", "WaveMaskMax", "WaveMaskBitAnd", "WaveMaskBitOr", "WaveMaskBitXor",
		"WaveMaskMatch", "WaveMaskPrefixSum", "WaveMaskPrefixProduct", "WaveMaskPrefixCountBits",
		"WaveMaskPrefixMin", "WaveMaskPrefixMax", "WaveMaskPrefixBitAnd", "WaveMaskPrefixBitOr",
		"WaveMaskPrefixBitXor", "WaveMaskReadLaneAt", "WaveMaskReadLaneFirst",
		"WaveMaskBroadcastLaneAt", "WaveMaskShuffle",
		"WaveMultiSum", "WaveMultiProduct", "WaveMultiMin", "WaveMultiMax",
		"WaveMultiBitAnd", "WaveMultiBitOr", "WaveMultiBitXor",
		"WaveMultiPrefixExclusiveMin", "WaveMultiPrefixExclusiveMax",

		// Ray tracing
		"TraceMotionRay", "RayCurrentTime", "ObjectToWorld", "WorldToObject",
		"HitTriangleVertexPosition", "ReorderThread", "MakeMiss", "MakeMotionMiss", "MakeNop",
		"IsHit", "IsMiss", "IsNop", "GetRayDesc", "GetShaderTableIndex", "SetShaderTableIndex",
		"LoadLocalRootTableConstant", "GetInstanceID", "GetInstanceIndex", "GetGeometryIndex",
		"GetPrimitiveIndex", "GetHitKind", "GetRayFlags", "GetRayTMin", "GetRayTCurrent",
		"GetObjectRayOrigin", "GetObjectRayDirection", "GetObjectToWorld", "GetWorldToObject",
		"GetWorldRayOrigin", "GetWorldRayDirection", "GetAttributes",
		"CandidateRayBarycentrics", "CandidateRayFrontFace", "CandidateRayGeometryIndex",
		"CandidateRayInstanceCustomIndex", "CandidateRayInstanceId", "CandidateRayPrimitiveIndex",
		"CandidateRayObjectRayOrigin", "CandidateRayObjectRayDirection",
		"CandidateRayObjectToWorld", "CandidateRayWorldToObject",
		"CommittedRayBarycentrics", "CommittedRayFrontFace", "CommittedRayGeometryIndex",
		"CommittedRayInstanceCustomIndex", "CommittedRayInstanceId", "CommittedRayPrimitiveIndex",
		"CommittedRayObjectRayOrigin", "CommittedRayObjectRayDirection",
		"CommittedRayObjectToWorld", "CommittedRayWorldToObject",

		// Misc / debug / cooperative
		"static_assert", "debugBreak", "clock2x32ARB", "clockARB", "getRealtimeClock",
		"getRealtimeClockLow", "GetCurrentTime", "coopVecMatMul", "coopVecMatMulAdd",
		"coopVecMatMulPacked", "diffPair", "makeTuple", "concat" );

	/// <summary>Multi-character operators, longest first. Slang adds <c>-&gt;</c> and <c>=&gt;</c>.</summary>
	public static readonly IReadOnlyList<string> Operators = new[]
	{
		"<<=", ">>=",
		"->", "=>", "::", "++", "--", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
		"==", "!=", "<=", ">=", "&&", "||", "<<", ">>", "..",
		"+", "-", "*", "/", "%", "=", "<", ">", "!", "&", "|", "^", "~", "?", ":", ".", "#", "@"
	};

	/// <summary>The shared Slang language definition.</summary>
	public static readonly LanguageDefinition Definition = new()
	{
		Id = "slang",
		DisplayName = "Slang",
		FileExtensions = new[] { "slang", "slangh" },
		Keywords = Keywords,
		ControlKeywords = ControlKeywords,
		Modifiers = Modifiers,
		BuiltinTypes = BuiltinTypes,
		ObjectTypes = ObjectTypes,
		Literals = Literals,
		Attributes = Attributes,
		Semantics = HlslLanguage.SemanticNames,
		PreprocessorDirectives = PreprocessorDirectives,
		PredefinedMacros = HlslLanguage.PredefinedMacros,
		ExtraIntrinsics = ExtraIntrinsics,
		Operators = Operators,
		Punctuation = "()[]{},;",
		Comments = CommentRules.CFamily,
		CompletionTriggers = new[] { '.', '#', '[', ':', '<' },
		IncludeSearchPaths = SboxSymbols.IncludeSearchPaths,
		VirtualIncludes = SboxSymbols.VirtualIncludes,
		SupportsAnnotations = false,
		SupportsModules = true,
		SupportsAngleBracketIncludes = true,
		HasVfxBlocks = false,
		HasSboxSymbols = false
	};

	private static HashSet<string> Set( params string[] words ) => new( words, StringComparer.Ordinal );

	private static HashSet<string> BuildBuiltinTypes()
	{
		var set = new HashSet<string>( StringComparer.Ordinal )
		{
			"void", "string", "vector", "matrix", "functype", "dword"
		};

		string[] bases =
		{
			"bool", "int", "uint", "half", "float", "double",
			"int8_t", "int16_t", "int32_t", "int64_t",
			"uint8_t", "uint16_t", "uint32_t", "uint64_t",
			"float16_t", "float32_t", "float64_t"
		};

		foreach ( var b in bases )
		{
			set.Add( b );

			for ( var n = 1; n <= 4; n++ )
			{
				set.Add( b + n );

				for ( var c = 1; c <= 4; c++ )
					set.Add( b + n + "x" + c );
			}
		}

		return set;
	}

	private static HashSet<string> BuildObjectTypes()
	{
		var set = new HashSet<string>( StringComparer.Ordinal )
		{
			"String", "Array", "Tuple", "Optional", "Conditional", "Result",
			"Ptr", "ImmutablePtr", "Atomic", "DescriptorHandle", "DifferentialPair",
			"ParameterBlock", "ConstantBuffer", "TextureBuffer",
			"SamplerState", "SamplerComparisonState",
			"SubpassInput", "SubpassInputMS", "RaytracingAccelerationStructure", "RayQuery",
			"NativeRef", "NativeString", "NullPtr", "Ref", "LayoutPtr", "BFloat16",
			"FloatE4M3", "FloatE5M2", "MemoryOrder", "MemoryScope", "AddressSpace", "Access",
			"OutputIndices", "OutputPrimitives", "OutputVertices",
			"DescriptorKind", "DescriptorAccess", "BindlessDescriptorOptions", "_AttributeTargets",
			"IFloat", "IArithmetic", "IComparable", "IDifferentiable", "IFunc", "IRWArray",
			"HitObject", "RayDesc", "BuiltInTriangleIntersectionAttributes",
			"InputPatch", "OutputPatch", "PointStream", "LineStream", "TriangleStream"
		};

		// (Depth|Feedback|RasterizerOrdered|RW)?Texture(1D|2D|3D|Cube)(Array)?(MS(Array)?)?
		string[] texturePrefixes = { "", "Depth", "Feedback", "RasterizerOrdered", "RW" };
		string[] textureShapes = { "1D", "2D", "3D", "Cube" };

		foreach ( var prefix in texturePrefixes )
		{
			foreach ( var shape in textureShapes )
			{
				var stem = prefix + "Texture" + shape;
				set.Add( stem );
				set.Add( stem + "Array" );
				set.Add( stem + "MS" );
				set.Add( stem + "MSArray" );
			}
		}

		// Sampler(1D|2D|3D|Cube)(Array)?(Shadow)?
		foreach ( var shape in textureShapes )
		{
			var stem = "Sampler" + shape;
			set.Add( stem );
			set.Add( stem + "Array" );
			set.Add( stem + "Shadow" );
			set.Add( stem + "ArrayShadow" );
		}

		// (Append|Consume|RW)?StructuredBuffer, (RW)?Buffer, (RW|RasterizerOrdered)?ByteAddressBuffer
		set.Add( "StructuredBuffer" );
		set.Add( "AppendStructuredBuffer" );
		set.Add( "ConsumeStructuredBuffer" );
		set.Add( "RWStructuredBuffer" );
		set.Add( "RasterizerOrderedStructuredBuffer" );
		set.Add( "Buffer" );
		set.Add( "RWBuffer" );
		set.Add( "RasterizerOrderedBuffer" );
		set.Add( "ByteAddressBuffer" );
		set.Add( "RWByteAddressBuffer" );
		set.Add( "RasterizerOrderedByteAddressBuffer" );

		return set;
	}
}