+2018-10-09 Dean Jackson <dino@apple.com>
+
+ Update WHLSL to Metal tester with semantics
+ https://bugs.webkit.org/show_bug.cgi?id=190416
+ <rdar://problem/45145139>
+
+ Reviewed by Myles Maxfield.
+
+ A few small changes to the WHLSL to Metal tools:
+ - Make it compile by adding some missing JS files :)
+ - Add semantics to the default shader
+ - Add FIXMEs to the other shaders
+ - Create an in-browser test for the WHLSLToMetal codepath
+ - Fix typos in the semantics checker
+
+ * WebGPUShadingLanguageRI/Checker.js:
+ (Checker.prototype._checkSemantics.checkSemanticTypes):
+ (Checker.prototype._checkSemantics.checkSemanticForShaderType):
+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.m:
+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Default.whlsl:
+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Julia.whlsl:
+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Mandelbrot.whlsl:
+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj:
+ * WebGPUShadingLanguageRI/Metal/WhlslToMsl.html: Added.
+
2018-10-09 Jer Noble <jer.noble@apple.com>
Crash when closing WKWebView during enter fullscreen animation
function checkSemanticTypes(items) {
for (let item of items) {
if (item.semantic && !item.semantic.isAcceptableType(item.type, program))
- throw new WTypeError(node.origin.originString, `Semantic ${item.semantic} is unnacceptable type ${item.type}`);
+ throw new WTypeError(node.origin.originString, `Semantic ${item.semantic} is unacceptable type ${item.type}`);
}
}
checkSemanticTypes(inputGatherer.result);
function checkSemanticForShaderType(items, direction) {
for (let item of items) {
if (item.semantic && !item.semantic.isAcceptableForShaderType(direction, node.shaderType))
- throw new WTypeError(node.origin.originString, `Semantic ${item.semantic} is unnacceptable as an ${direction} of shader type ${node.shaderType}`);
+ throw new WTypeError(node.origin.originString, `Semantic ${item.semantic} is unacceptable as an ${direction} of shader type ${node.shaderType}`);
}
}
checkSemanticForShaderType(inputGatherer.result, "input");
{
JSValue *compileFunction = [self.context objectForKeyedSubscript:@"whlslToMsl"];
if (compileFunction) {
- JSValue * result = [compileFunction callWithArguments:@[whlslSource]];
+ JSValue *result = [compileFunction callWithArguments:@[whlslSource]];
if (result) {
if ([result hasProperty:@"_error"] && [result hasProperty:@"_metalShaderLanguageSource"] && [result hasProperty:@"_originalFunctionNameToMangledNames"]) {
if ([[result valueForProperty:@"_error"] isNull]) {
struct VertexInput {
- float2 position;
- float2 uv;
+ float2 position : attribute(0);
+ float2 uv : attribute(1);
}
struct VertexOutput {
- float4 wsl_Position;
- float4 color;
+ float4 position : SV_Position;
+ float4 color : attribute(0);
+}
+
+struct FragmentInput {
+ float4 color : attribute(0);
}
struct FragmentOutput {
- float4 wsl_Color;
+ float4 color : SV_Target0;
}
vertex VertexOutput vertexShader(VertexInput vertexInput) {
VertexOutput result;
- result.wsl_Position = float4(vertexInput.position, 0., 1.);
+ result.position = float4(vertexInput.position, 0., 1.);
result.color = float4(vertexInput.uv, 0.0, 1.0);
return result;
}
-fragment FragmentOutput fragmentShader(VertexOutput stageIn) {
+fragment FragmentOutput fragmentShader(FragmentInput fragmentInput) {
FragmentOutput result;
- result.wsl_Color = stageIn.color;
+ result.color = fragmentInput.color;
return result;
}
+// FIXME: This won't compile. Needs semantics.
+
struct VertexInput {
float2 position;
float2 uv;
+// FIXME: This won't compile. Needs semantics.
+
struct VertexInput {
float2 position;
float2 uv;
objects = {
/* Begin PBXBuildFile section */
+ 31F11709216BFE92009A36D5 /* FuncAttribute.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F116C4216BFE90009A36D5 /* FuncAttribute.js */; };
+ 31F1170A216BFE92009A36D5 /* BuiltInSemantic.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F116C5216BFE90009A36D5 /* BuiltInSemantic.js */; };
+ 31F11732216BFE93009A36D5 /* ResourceSemantic.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11704216BFE90009A36D5 /* ResourceSemantic.js */; };
+ 31F11733216BFE93009A36D5 /* FuncNumThreadsAttribute.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11705216BFE91009A36D5 /* FuncNumThreadsAttribute.js */; };
+ 31F11734216BFE93009A36D5 /* Semantic.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11706216BFE91009A36D5 /* Semantic.js */; };
+ 31F11735216BFE93009A36D5 /* CheckNativeFuncStages.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11707216BFE92009A36D5 /* CheckNativeFuncStages.js */; };
+ 31F11736216BFE93009A36D5 /* SpecializationConstantSemantic.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11708216BFE92009A36D5 /* SpecializationConstantSemantic.js */; };
+ 31F11776216BFEEC009A36D5 /* StageInOutSemantic.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F11737216BFEEB009A36D5 /* StageInOutSemantic.js */; };
+ 31F1179F216BFF07009A36D5 /* MSLInsertTrapParameter.js in Resources */ = {isa = PBXBuildFile; fileRef = 31F1179E216BFF07009A36D5 /* MSLInsertTrapParameter.js */; };
E906B04621139B7700AD1C5E /* Julia.whlsl in Resources */ = {isa = PBXBuildFile; fileRef = E906B04521139B7700AD1C5E /* Julia.whlsl */; };
E921D6362138C02600775099 /* OperatorAnderIndexer.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6322138C02600775099 /* OperatorAnderIndexer.js */; };
E921D6372138C02600775099 /* MatrixType.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6332138C02600775099 /* MatrixType.js */; };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 31F116C4216BFE90009A36D5 /* FuncAttribute.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = FuncAttribute.js; path = ../../../FuncAttribute.js; sourceTree = "<group>"; };
+ 31F116C5216BFE90009A36D5 /* BuiltInSemantic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BuiltInSemantic.js; path = ../../../BuiltInSemantic.js; sourceTree = "<group>"; };
+ 31F11704216BFE90009A36D5 /* ResourceSemantic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ResourceSemantic.js; path = ../../../ResourceSemantic.js; sourceTree = "<group>"; };
+ 31F11705216BFE91009A36D5 /* FuncNumThreadsAttribute.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = FuncNumThreadsAttribute.js; path = ../../../FuncNumThreadsAttribute.js; sourceTree = "<group>"; };
+ 31F11706216BFE91009A36D5 /* Semantic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Semantic.js; path = ../../../Semantic.js; sourceTree = "<group>"; };
+ 31F11707216BFE92009A36D5 /* CheckNativeFuncStages.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckNativeFuncStages.js; path = ../../../CheckNativeFuncStages.js; sourceTree = "<group>"; };
+ 31F11708216BFE92009A36D5 /* SpecializationConstantSemantic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SpecializationConstantSemantic.js; path = ../../../SpecializationConstantSemantic.js; sourceTree = "<group>"; };
+ 31F11737216BFEEB009A36D5 /* StageInOutSemantic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = StageInOutSemantic.js; path = ../../../StageInOutSemantic.js; sourceTree = "<group>"; };
+ 31F1179E216BFF07009A36D5 /* MSLInsertTrapParameter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLInsertTrapParameter.js; path = ../../MSLInsertTrapParameter.js; sourceTree = "<group>"; };
E906B04521139B7700AD1C5E /* Julia.whlsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Julia.whlsl; sourceTree = "<group>"; };
E921D6322138C02600775099 /* OperatorAnderIndexer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = OperatorAnderIndexer.js; path = ../../../OperatorAnderIndexer.js; sourceTree = "<group>"; };
E921D6332138C02600775099 /* MatrixType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MatrixType.js; path = ../../../MatrixType.js; sourceTree = "<group>"; };
E95569B020F56CD600F5CF34 /* Break.js */,
E921D6342138C02600775099 /* BuiltinMatrixGetter.js */,
E921D6352138C02600775099 /* BuiltinMatrixSetter.js */,
+ 31F116C5216BFE90009A36D5 /* BuiltInSemantic.js */,
E941ACB92134A5BB00392BA9 /* BuiltinVectorGetter.js */,
E941ACBC2134A5BB00392BA9 /* BuiltinVectorSetter.js */,
E95569BF20F56CD700F5CF34 /* CallExpression.js */,
E95569C120F56CD700F5CF34 /* Checker.js */,
E95569B620F56CD600F5CF34 /* CheckLiteralTypes.js */,
E95569B320F56CD600F5CF34 /* CheckLoops.js */,
+ 31F11707216BFE92009A36D5 /* CheckNativeFuncStages.js */,
E94C06FA20F56CA300672992 /* CheckRecursion.js */,
E95569BB20F56CD600F5CF34 /* CheckRecursiveTypes.js */,
E95569B220F56CD600F5CF34 /* CheckReturns.js */,
E95569EB20F56D0500F5CF34 /* FoldConstexprs.js */,
E9FCEB5A20F56D93009B3629 /* ForLoop.js */,
E9FCEB5520F56D92009B3629 /* Func.js */,
+ 31F116C4216BFE90009A36D5 /* FuncAttribute.js */,
E95569E820F56D0500F5CF34 /* FuncDef.js */,
+ 31F11705216BFE91009A36D5 /* FuncNumThreadsAttribute.js */,
E95569E920F56D0500F5CF34 /* FuncParameter.js */,
E95569E620F56D0500F5CF34 /* FunctionLikeBlock.js */,
E94C06FB20F56CA300672992 /* HighZombieFinder.js */,
E92789AC213F3364001EA73E /* MSLFunctionDeclaration.js */,
E92789AB213F3364001EA73E /* MSLFunctionDefinition.js */,
E973E5C7213F3385005D79FC /* MSLFunctionForwardDeclaration.js */,
+ 31F1179E216BFF07009A36D5 /* MSLInsertTrapParameter.js */,
E97ED7E1214B822900AD1140 /* MSLNameMangler.js */,
E97ED7E4214B822900AD1140 /* MSLNativeFunctionCall.js */,
E973E5C8213F3385005D79FC /* MSLStatementEmitter.js */,
E92D103820F56E4F00D776B2 /* ResolveOverloadImpl.js */,
E92D103620F56E4F00D776B2 /* ResolveProperties.js */,
E92D103720F56E4F00D776B2 /* ResolveTypeDefs.js */,
+ 31F11704216BFE90009A36D5 /* ResourceSemantic.js */,
E92D103E20F56E6100D776B2 /* Return.js */,
E92D104020F56E6200D776B2 /* ReturnChecker.js */,
E92D104220F56E6200D776B2 /* ReturnException.js */,
E92D104120F56E6200D776B2 /* Rewriter.js */,
E9D7CB9D214B82B800F1C918 /* Sampler.js */,
+ 31F11706216BFE91009A36D5 /* Semantic.js */,
+ 31F11708216BFE92009A36D5 /* SpecializationConstantSemantic.js */,
+ 31F11737216BFEEB009A36D5 /* StageInOutSemantic.js */,
E92D103F20F56E6200D776B2 /* StandardLibrary.js */,
E92D104820F56E7300D776B2 /* StatementCloner.js */,
E92D104920F56E7300D776B2 /* StructLayoutBuilder.js */,
isa = PBXNativeTarget;
buildConfigurationList = E94C06EA20F56A4200672992 /* Build configuration list for PBXNativeTarget "WHLSL Tests" */;
buildPhases = (
- E925653C21234AA1001A89D9 /* ShellScript */,
E94C06BC20F56A4000672992 /* Sources */,
E94C06BD20F56A4000672992 /* Frameworks */,
E94C06BE20F56A4000672992 /* Resources */,
};
buildConfigurationList = E94C06BB20F56A4000672992 /* Build configuration list for PBXProject "WHLSL Tests" */;
compatibilityVersion = "Xcode 9.3";
- developmentRegion = en;
+ developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
E92D111F20F7060E00D776B2 /* Break.js in Resources */,
E921D6382138C02600775099 /* BuiltinMatrixGetter.js in Resources */,
E921D6392138C02600775099 /* BuiltinMatrixSetter.js in Resources */,
+ 31F1170A216BFE92009A36D5 /* BuiltInSemantic.js in Resources */,
E941ACCA2134A5BC00392BA9 /* BuiltinVectorGetter.js in Resources */,
E941ACCD2134A5BC00392BA9 /* BuiltinVectorSetter.js in Resources */,
E92D112020F7060E00D776B2 /* CallExpression.js in Resources */,
E92D112320F7060E00D776B2 /* Checker.js in Resources */,
E92D112420F7060E00D776B2 /* CheckLiteralTypes.js in Resources */,
E92D112520F7060E00D776B2 /* CheckLoops.js in Resources */,
+ 31F11735216BFE93009A36D5 /* CheckNativeFuncStages.js in Resources */,
E92D112620F7060E00D776B2 /* CheckRecursion.js in Resources */,
E92D112720F7060E00D776B2 /* CheckRecursiveTypes.js in Resources */,
E92D112820F7060E00D776B2 /* CheckReturns.js in Resources */,
E92D114B20F7060E00D776B2 /* FoldConstexprs.js in Resources */,
E92D114C20F7060E00D776B2 /* ForLoop.js in Resources */,
E92D114D20F7060E00D776B2 /* Func.js in Resources */,
+ 31F11709216BFE92009A36D5 /* FuncAttribute.js in Resources */,
E92D114E20F7060E00D776B2 /* FuncDef.js in Resources */,
+ 31F11733216BFE93009A36D5 /* FuncNumThreadsAttribute.js in Resources */,
E92D115020F7060E00D776B2 /* FuncParameter.js in Resources */,
E92D115120F7060E00D776B2 /* FunctionLikeBlock.js in Resources */,
E92D115220F7060E00D776B2 /* HighZombieFinder.js in Resources */,
E973E5DE213F341D005D79FC /* MSLFunctionDeclaration.js in Resources */,
E973E5DF213F341D005D79FC /* MSLFunctionDefinition.js in Resources */,
E973E5CE213F3385005D79FC /* MSLFunctionForwardDeclaration.js in Resources */,
+ 31F1179F216BFF07009A36D5 /* MSLInsertTrapParameter.js in Resources */,
E9D7CBA8214B9E5F00F1C918 /* MSLNameMangler.js in Resources */,
E9D7CBA9214B9E5F00F1C918 /* MSLNativeFunctionCall.js in Resources */,
E973E5CF213F3385005D79FC /* MSLStatementEmitter.js in Resources */,
E92D118320F7060E00D776B2 /* ResolveOverloadImpl.js in Resources */,
E92D118420F7060E00D776B2 /* ResolveProperties.js in Resources */,
E92D118520F7060E00D776B2 /* ResolveTypeDefs.js in Resources */,
+ 31F11732216BFE93009A36D5 /* ResourceSemantic.js in Resources */,
E92D118620F7060E00D776B2 /* Return.js in Resources */,
E92D118720F7060E00D776B2 /* ReturnChecker.js in Resources */,
E92D118820F7060E00D776B2 /* ReturnException.js in Resources */,
E92D118920F7060E00D776B2 /* Rewriter.js in Resources */,
E9D7CBA3214B82B800F1C918 /* Sampler.js in Resources */,
+ 31F11734216BFE93009A36D5 /* Semantic.js in Resources */,
+ 31F11736216BFE93009A36D5 /* SpecializationConstantSemantic.js in Resources */,
+ 31F11776216BFEEC009A36D5 /* StageInOutSemantic.js in Resources */,
E92D118A20F7060E00D776B2 /* StandardLibrary.js in Resources */,
E92D118B20F7060E00D776B2 /* StatementCloner.js in Resources */,
E92D118C20F7060E00D776B2 /* StructLayoutBuilder.js in Resources */,
};
/* End PBXResourcesBuildPhase section */
-/* Begin PBXShellScriptBuildPhase section */
- E925653C21234AA1001A89D9 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- );
- outputFileListPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd \"$SRCROOT/..\"\ntsc\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
/* Begin PBXSourcesBuildPhase section */
E94C06BC20F56A4000672992 /* Sources */ = {
isa = PBXSourcesBuildPhase;
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system;
+}
+h1 {
+ padding: 20px 20px;
+ text-align: center;
+ font-size: 50px;
+}
+main {
+ margin: 0 auto;
+ padding: 20px;
+ display: grid;
+ grid-template-columns: 45% 45%;
+ grid-column-gap: 10px;
+ grid-template-rows: auto 500px auto;
+ grid-row-gap: 10px;
+ justify-content: center;
+}
+textarea {
+ padding: 5px;
+ margin: 0;
+ font-family: monospace;
+ font-size: 20px;
+ overflow: scroll;
+}
+#output {
+ padding: 5px;
+ margin: 0;
+ font-family: monospace;
+ overflow: scroll;
+ border: 1px solid #888;
+ box-sizing: border-box;
+ font-size: 20px;
+}
+#controls {
+ padding: 5px;
+ margin: 0;
+ text-align: center;
+}
+button {
+ width: 200px;
+ font-size: 20px;
+ background: linear-gradient(to bottom, #aae, #aaf);
+ border: 1px solid #ccd;
+ border-radius: 3px;
+}
+button:active {
+ background: linear-gradient(to bottom, #dde, #eef);
+ color: black;
+}
+</style>
+<script src="../Node.js"></script>
+<script src="../Type.js"></script>
+<script src="../ReferenceType.js"></script>
+<script src="../Value.js"></script>
+<script src="../Expression.js"></script>
+<script src="../Rewriter.js"></script>
+<script src="../Visitor.js"></script>
+<script src="../CreateLiteral.js"></script>
+<script src="../CreateLiteralType.js"></script>
+<script src="../PropertyAccessExpression.js"></script>
+<script src="../NativeType.js"></script>
+<script src="../Semantic.js"></script>
+<script src="../AddressSpace.js"></script>
+<script src="../AllocateAtEntryPoints.js"></script>
+<script src="../AnonymousVariable.js"></script>
+<script src="../ArrayRefType.js"></script>
+<script src="../ArrayType.js"></script>
+<script src="../Assignment.js"></script>
+<script src="../AutoWrapper.js"></script>
+<script src="../Block.js"></script>
+<script src="../BoolLiteral.js"></script>
+<script src="../Break.js"></script>
+<script src="../BuiltInSemantic.js"></script>
+<script src="../BuiltinMatrixGetter.js"></script>
+<script src="../BuiltinMatrixSetter.js"></script>
+<script src="../BuiltinVectorGetter.js"></script>
+<script src="../BuiltinVectorSetter.js"></script>
+<script src="../CallExpression.js"></script>
+<script src="../CallFunction.js"></script>
+<script src="../Casts.js"></script>
+<script src="../Check.js"></script>
+<script src="../CheckLiteralTypes.js"></script>
+<script src="../CheckLoops.js"></script>
+<script src="../CheckNativeFuncStages.js"></script>
+<script src="../CheckRecursion.js"></script>
+<script src="../CheckRecursiveTypes.js"></script>
+<script src="../CheckReturns.js"></script>
+<script src="../CheckTypesWithArguments.js"></script>
+<script src="../CheckUnreachableCode.js"></script>
+<script src="../CheckWrapped.js"></script>
+<script src="../Checker.js"></script>
+<script src="../CloneProgram.js"></script>
+<script src="../CommaExpression.js"></script>
+<script src="../ConstexprFolder.js"></script>
+<script src="../Continue.js"></script>
+<script src="../ConvertPtrToArrayRefExpression.js"></script>
+<script src="../DoWhileLoop.js"></script>
+<script src="../DotExpression.js"></script>
+<script src="../DereferenceExpression.js"></script>
+<script src="../EArrayRef.js"></script>
+<script src="../EBuffer.js"></script>
+<script src="../EBufferBuilder.js"></script>
+<script src="../EPtr.js"></script>
+<script src="../EnumLiteral.js"></script>
+<script src="../EnumMember.js"></script>
+<script src="../EnumType.js"></script>
+<script src="../EvaluationCommon.js"></script>
+<script src="../Evaluator.js"></script>
+<script src="../ExpressionFinder.js"></script>
+<script src="../ExternalOrigin.js"></script>
+<script src="../Field.js"></script>
+<script src="../FindHighZombies.js"></script>
+<script src="../FlattenedStructOffsetGatherer.js"></script>
+<script src="../FloatLiteral.js"></script>
+<script src="../FloatLiteralType.js"></script>
+<script src="../FoldConstexprs.js"></script>
+<script src="../ForLoop.js"></script>
+<script src="../Func.js"></script>
+<script src="../FuncAttribute.js"></script>
+<script src="../FuncDef.js"></script>
+<script src="../FuncNumThreadsAttribute.js"></script>
+<script src="../FuncParameter.js"></script>
+<script src="../FunctionLikeBlock.js"></script>
+<script src="../HighZombieFinder.js"></script>
+<script src="../IdentityExpression.js"></script>
+<script src="../IfStatement.js"></script>
+<script src="../IndexExpression.js"></script>
+<script src="../InferTypesForCall.js"></script>
+<script src="../Inline.js"></script>
+<script src="../Inliner.js"></script>
+<script src="../IntLiteral.js"></script>
+<script src="../IntLiteralType.js"></script>
+<script src="../Intrinsics.js"></script>
+<script src="../LayoutBuffers.js"></script>
+<script src="../Lexer.js"></script>
+<script src="../LexerToken.js"></script>
+<script src="../LiteralTypeChecker.js"></script>
+<script src="../LogicalExpression.js"></script>
+<script src="../LogicalNot.js"></script>
+<script src="../LoopChecker.js"></script>
+<script src="../MakeArrayRefExpression.js"></script>
+<script src="../MakePtrExpression.js"></script>
+<script src="../MatrixType.js"></script>
+<script src="../NameContext.js"></script>
+<script src="../NameFinder.js"></script>
+<script src="../NameResolver.js"></script>
+<script src="../NativeFunc.js"></script>
+<script src="../NormalUsePropertyResolver.js"></script>
+<script src="../NullLiteral.js"></script>
+<script src="../NullType.js"></script>
+<script src="../OperatorAnderIndexer.js"></script>
+<script src="../OperatorArrayRefLength.js"></script>
+<script src="../OriginKind.js"></script>
+<script src="../OverloadResolutionFailure.js"></script>
+<script src="../Parse.js"></script>
+<script src="../Prepare.js"></script>
+<script src="../PropertyResolver.js"></script>
+<script src="../Program.js"></script>
+<script src="../ProgramWithUnnecessaryThingsRemoved.js"></script>
+<script src="../PtrType.js"></script>
+<script src="../ReadModifyWriteExpression.js"></script>
+<script src="../RecursionChecker.js"></script>
+<script src="../RecursiveTypeChecker.js"></script>
+<script src="../ResolveNames.js"></script>
+<script src="../ResolveOverloadImpl.js"></script>
+<script src="../ResolveProperties.js"></script>
+<script src="../ResolveTypeDefs.js"></script>
+<script src="../ResourceSemantic.js"></script>
+<script src="../Return.js"></script>
+<script src="../ReturnChecker.js"></script>
+<script src="../ReturnException.js"></script>
+<script src="../Sampler.js"></script>
+<script src="../SpecializationConstantSemantic.js"></script>
+<script src="../StageInOutSemantic.js"></script>
+<script src="../StandardLibrary.js"></script>
+<script src="../StatementCloner.js"></script>
+<script src="../StructLayoutBuilder.js"></script>
+<script src="../StructType.js"></script>
+<script src="../SwitchCase.js"></script>
+<script src="../SwitchStatement.js"></script>
+<script src="../SynthesizeArrayOperatorLength.js"></script>
+<script src="../SynthesizeEnumFunctions.js"></script>
+<script src="../SynthesizeStructAccessors.js"></script>
+<script src="../SynthesizeCopyConstructorOperator.js"></script>
+<script src="../SynthesizeDefaultConstructorOperator.js"></script>
+<script src="../TernaryExpression.js"></script>
+<script src="../Texture.js"></script>
+<script src="../TextureOperations.js"></script>
+<script src="../TrapStatement.js"></script>
+<script src="../TypeDef.js"></script>
+<script src="../TypeDefResolver.js"></script>
+<script src="../TypeRef.js"></script>
+<script src="../TypeOverloadResolutionFailure.js"></script>
+<script src="../TypedValue.js"></script>
+<script src="../UintLiteral.js"></script>
+<script src="../UintLiteralType.js"></script>
+<script src="../UnificationContext.js"></script>
+<script src="../UnreachableCodeChecker.js"></script>
+<script src="../VariableDecl.js"></script>
+<script src="../VariableRef.js"></script>
+<script src="../VectorType.js"></script>
+<script src="../VisitingSet.js"></script>
+<script src="../WLexicalError.js"></script>
+<script src="../WSyntaxError.js"></script>
+<script src="../WTrapError.js"></script>
+<script src="../WTypeError.js"></script>
+<script src="../WhileLoop.js"></script>
+<script src="../WrapChecker.js"></script>
+
+<script src="MSLBackend.js"></script>
+<script src="MSLCompileResult.js"></script>
+<script src="MSLConstexprEmitter.js"></script>
+<script src="MSLFunctionDeclaration.js"></script>
+<script src="MSLFunctionDefinition.js"></script>
+<script src="MSLFunctionForwardDeclaration.js"></script>
+<script src="MSLInsertTrapParameter.js"></script>
+<script src="MSLNameMangler.js"></script>
+<script src="MSLNativeFunctionCall.js"></script>
+<script src="MSLStatementEmitter.js"></script>
+<script src="MSLTypeAttributesMap.js"></script>
+<script src="MSLTypeAttributes.js"></script>
+<script src="MSLTypeUnifier.js"></script>
+<script src="TypeOf.js"></script>
+<script src="WhlslToMsl.js"></script>
+<script>
+function init() {
+ let b = document.querySelector("button");
+ b.addEventListener("click", compile);
+}
+
+function compile() {
+ let source = document.querySelector("textarea").value;
+ let output = document.querySelector("#output");
+ output.textContent = "Compiling...";
+ let result = whlslToMsl(source);
+ output.textContent = JSON.stringify(result);
+}
+
+window.addEventListener("load", init, false);
+</script>
+</head>
+<body>
+<header>
+<h1>WHLSL to MSL</h1>
+</header>
+<main>
+<h2>WHSL Source</h2>
+<h2>Compiled Output</h2>
+<textarea id="source">
+struct VertexInput {
+ float2 position : attribute(0);
+ float2 uv : attribute(1);
+}
+
+struct VertexOutput {
+ float4 position : SV_Position;
+ float4 color : attribute(0);
+}
+
+struct FragmentInput {
+ float4 color : attribute(0);
+}
+
+struct FragmentOutput {
+ float4 color : SV_Target0;
+}
+
+vertex VertexOutput vertexShader(VertexInput vertexInput) {
+ VertexOutput result;
+ result.position = float4(vertexInput.position, 0., 1.);
+ result.color = float4(vertexInput.uv, 0.0, 1.0);
+ return result;
+}
+
+fragment FragmentOutput fragmentShader(FragmentInput fragmentInput) {
+ FragmentOutput result;
+ result.color = fragmentInput.color;
+ return result;
+}
+</textarea>
+<div id="output">
+No compiled output.
+</div>
+<div id="controls">
+<button>Compile</button>
+</div>
+</main>
+</body>
+</html>
\ No newline at end of file