[WHLSL] Remove generics from the interpreter
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Aug 2018 22:52:44 +0000 (22:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Aug 2018 22:52:44 +0000 (22:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187988

Patch by Thomas Denney <tdenney@apple.com> on 2018-08-20
Reviewed by Myles C. Maxfield.

This patch completely removes generic and protocol support from WHLSL
whilst adding back any features that were originally implemented with
generics.

Many of the changes in this patch just remove occurrences of type
arguments and type parameters --- although there are some cases where
they have been deliberately left in --- as well as removing tests only
relevant to those features. These changes are not listed below.

* WebGPUShadingLanguageRI/All.js: Add/remove JS dependencies
* WebGPUShadingLanguageRI/AutoWrapper.js:
(AutoWrapper.prototype.visitConstexprTypeParameter): Deleted.
* WebGPUShadingLanguageRI/BuiltinVectorCasts.js: Added. The built-in
vectors have many constructors for different scalar and vector types.
These were originally implemented with generics.
* WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Adds the
equality operator for built-in vectors, again this was removed with
generics.
* WebGPUShadingLanguageRI/BuiltinVectorGetter.js: Added, as above.
Built-in vectors only support the getter and setter, and not the ander.
* WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js: Added.
* WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js: Added.
* WebGPUShadingLanguageRI/BuiltinVectorSetter.js: Added.
* WebGPUShadingLanguageRI/CallExpression.js: Adds support for
instantiating functions which cannot be discovered earlier in
preparation because their types are absent (specifically support for the
operator &[] for array references and the length operator for array
references). Previously support for these was implemented with generics.
(CallExpression.resolve):
(CallExpression.prototype.resolve):
(CallExpression.prototype._resolveByInstantiation):
(CallExpression.prototype._resolveToOperatorAnderIndexer):
(CallExpression.prototype._resolveToOperatorLength):
(CallExpression.prototype.resolveToOverload):
(CallExpression.prototype.becomeCast):
(CallExpression.prototype.toString):
(CallExpression):
* WebGPUShadingLanguageRI/CallExpressionTypeArgumentResolver.js: Added.
We support syntax like vector<int, 2>(a, b) for constructing vectors;
this new preparation step resolves them to specific constructors.
* WebGPUShadingLanguageRI/CallFunction.js:
* WebGPUShadingLanguageRI/Checker.js:
* WebGPUShadingLanguageRI/ConstexprFolder.js:
* WebGPUShadingLanguageRI/CreateLiteralType.js:
* WebGPUShadingLanguageRI/ExpressionFinder.js:
* WebGPUShadingLanguageRI/FlattenProtocolExtends.js: Removed.
* WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js:
* WebGPUShadingLanguageRI/Func.js:
* WebGPUShadingLanguageRI/FuncDef.js:
* WebGPUShadingLanguageRI/FuncInstantiator.js: Deleted.
* WebGPUShadingLanguageRI/InferTypesForCall.js: Removed usage of type arguments.
* WebGPUShadingLanguageRI/Inline.js: Remove use of FuncInstantiator.
* WebGPUShadingLanguageRI/Inliner.js: Ditto.
* WebGPUShadingLanguageRI/Intrinsics.js:
* WebGPUShadingLanguageRI/Lexer.js:
* WebGPUShadingLanguageRI/LiteralTypeChecker.js:
* WebGPUShadingLanguageRI/NameContext.js:
(NameContext.prototype.add):
(NameContext.prototype.get let):
(NameContext.underlyingThings.prototype.else):
(NameContext.prototype.resolveFuncOverload):
* WebGPUShadingLanguageRI/NameFinder.js:
* WebGPUShadingLanguageRI/NameResolver.js:
(NameResolver.prototype.visitFunc):
(NameResolver.prototype.visitFuncDef):
(NameResolver.prototype.visitTypeDef):
(NameResolver.prototype.visitStructType):
(NameResolver.prototype.visitTypeRef):
(NameResolver.prototype.visitCallExpression):
(NameResolver.prototype.visitVectorType):
(NameResolver):
(NameResolver.prototype._visitTypeParametersAndBuildNameContext): Deleted.
(NameResolver.prototype.visitProtocolDecl): Deleted.
* WebGPUShadingLanguageRI/NativeFunc.js:
(NativeFunc):
* WebGPUShadingLanguageRI/NativeFuncInstance.js: Deleted.
* WebGPUShadingLanguageRI/NativeType.js:
(NativeType):
(NativeType.prototype.get name):
(NativeType.prototype.toString):
(NativeType.prototype.get typeParameters): Deleted.
(NativeType.prototype.instantiate): Deleted.
* WebGPUShadingLanguageRI/Node.js:
(Node.prototype.commit):
(Node):
(Node.prototype.substitute): Deleted.
(Node.prototype.substituteToUnification): Deleted.
* WebGPUShadingLanguageRI/OperatorAnderIndex.js: Added, previously
implemented with generics.
* WebGPUShadingLanguageRI/OperatorArrayRefLength.js: Ditto.
* WebGPUShadingLanguageRI/OperatorBool.js: Ditto.
* WebGPUShadingLanguageRI/Parse.js: Removed everything related to
generics and protocols.
* WebGPUShadingLanguageRI/Prepare.js: Added new stages.
* WebGPUShadingLanguageRI/Program.js:
(Program):
(Program.prototype.get types):
(Program.prototype.add):
(Program.prototype.get protocols): Deleted.
* WebGPUShadingLanguageRI/ProtocolDecl.js: Removed.
* WebGPUShadingLanguageRI/ProtocolRef.js: Removed.
* WebGPUShadingLanguageRI/RecursiveTypeChecker.js:
* WebGPUShadingLanguageRI/ResolveCallExpressionsWithTypeArguments.js: Added.
* WebGPUShadingLanguageRI/ResolveNames.js:
* WebGPUShadingLanguageRI/ResolveOverloadImpl.js:
* WebGPUShadingLanguageRI/ResolveTypeDefs.js:
(resolveTypeDefsInProtocols): Deleted.
* WebGPUShadingLanguageRI/Rewriter.js: Changes for new classes.
* WebGPUShadingLanguageRI/SPIRV.html:
* WebGPUShadingLanguageRI/SPIRVCodegen.js:
* WebGPUShadingLanguageRI/StandardLibrary.js: Replace old generic features.
* WebGPUShadingLanguageRI/StatementCloner.js: Changes for new classes.
(StructLayoutBuilder):
* WebGPUShadingLanguageRI/StructType.js:
* WebGPUShadingLanguageRI/SwizzleOp.js:
(SwizzleOp):
(SwizzleOp.prototype.get baseTypeName):
(SwizzleOp.prototype.toString):
(SwizzleOp.functions.):
(SwizzleOp.functions):
(SwizzleOp.prototype.instantiateImplementation):
(SwizzleOp.allSwizzleOperators.): Deleted.
(SwizzleOp.allSwizzleOperators): Deleted.
* WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js: Added,
previously implemented with generics.
* WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Ditto.
* WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Ditto.
* WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js: Ditto.
* WebGPUShadingLanguageRI/SynthesizeOperatorBool.js: Ditto.
* WebGPUShadingLanguageRI/SynthesizeStructAccessors.js:
(synthesizeStructAccessors.setupImplementationData):
(synthesizeStructAccessors.createFieldType):
(synthesizeStructAccessors.createTypeRef):
(synthesizeStructAccessors.setupAnder):
(synthesizeStructAccessors):
(synthesizeStructAccessors.createTypeParameters): Deleted.
(synthesizeStructAccessors.): Deleted.
* WebGPUShadingLanguageRI/Test.html:
* WebGPUShadingLanguageRI/Test.js: Removed redundant tests and added new
tests for changed language features.
* WebGPUShadingLanguageRI/Type.js:
* WebGPUShadingLanguageRI/TypeDef.js:
* WebGPUShadingLanguageRI/TypeDefResolver.js:
* WebGPUShadingLanguageRI/TypeParameterRewriter.js: Removed.
* WebGPUShadingLanguageRI/TypeRef.js:
* WebGPUShadingLanguageRI/TypeVariable.js: Removed.
* WebGPUShadingLanguageRI/UnificationContext.js:
* WebGPUShadingLanguageRI/VectorType.js: Added.
* WebGPUShadingLanguageRI/Visitor.js: Changes for new classes.
* WebGPUShadingLanguageRI/WSL.md: Removed description of
generics/protocols.
* WebGPUShadingLanguageRI/WrapChecker.js:
(WrapChecker):
(WrapChecker.visitConstexprTypeParameter): Deleted.
(WrapChecker.prototype.visitFuncParameter): Deleted.
(WrapChecker.prototype.visitTypeVariable): Deleted.
* WebGPUShadingLanguageRI/index.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235096 268f45cc-cd09-0410-ab3c-d52691b4dbfc

75 files changed:
Tools/ChangeLog
Tools/WebGPUShadingLanguageRI/All.js
Tools/WebGPUShadingLanguageRI/AutoWrapper.js
Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js [moved from Tools/WebGPUShadingLanguageRI/ProtocolRef.js with 54% similarity]
Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js [moved from Tools/WebGPUShadingLanguageRI/Substitution.js with 51% similarity]
Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/CallExpression.js
Tools/WebGPUShadingLanguageRI/CallFunction.js
Tools/WebGPUShadingLanguageRI/Checker.js
Tools/WebGPUShadingLanguageRI/ConstexprFolder.js
Tools/WebGPUShadingLanguageRI/CreateLiteralType.js
Tools/WebGPUShadingLanguageRI/Evaluator.js
Tools/WebGPUShadingLanguageRI/ExpressionFinder.js
Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js [deleted file]
Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js
Tools/WebGPUShadingLanguageRI/Func.js
Tools/WebGPUShadingLanguageRI/FuncDef.js
Tools/WebGPUShadingLanguageRI/FuncInstantiator.js [deleted file]
Tools/WebGPUShadingLanguageRI/InferTypesForCall.js
Tools/WebGPUShadingLanguageRI/Inline.js
Tools/WebGPUShadingLanguageRI/Inliner.js
Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js [deleted file]
Tools/WebGPUShadingLanguageRI/Intrinsics.js
Tools/WebGPUShadingLanguageRI/Lexer.js
Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js
Tools/WebGPUShadingLanguageRI/NameContext.js
Tools/WebGPUShadingLanguageRI/NameFinder.js
Tools/WebGPUShadingLanguageRI/NameResolver.js
Tools/WebGPUShadingLanguageRI/NativeFunc.js
Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js [deleted file]
Tools/WebGPUShadingLanguageRI/NativeType.js
Tools/WebGPUShadingLanguageRI/Node.js
Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js [moved from Tools/WebGPUShadingLanguageRI/TypeOrVariableRef.js with 64% similarity]
Tools/WebGPUShadingLanguageRI/OperatorBool.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/Parse.js
Tools/WebGPUShadingLanguageRI/Prepare.js
Tools/WebGPUShadingLanguageRI/Program.js
Tools/WebGPUShadingLanguageRI/ProtocolDecl.js [deleted file]
Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js [deleted file]
Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/ResolveNames.js
Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js
Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js
Tools/WebGPUShadingLanguageRI/Rewriter.js
Tools/WebGPUShadingLanguageRI/SPIRV.html
Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js
Tools/WebGPUShadingLanguageRI/StandardLibrary.js
Tools/WebGPUShadingLanguageRI/StatementCloner.js
Tools/WebGPUShadingLanguageRI/StructLayoutBuilder.js
Tools/WebGPUShadingLanguageRI/StructType.js
Tools/WebGPUShadingLanguageRI/SwizzleOp.js
Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js [moved from Tools/WebGPUShadingLanguageRI/TypeVariableTracker.js with 56% similarity]
Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js [moved from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js with 58% similarity]
Tools/WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js
Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js [moved from Tools/WebGPUShadingLanguageRI/Protocol.js with 69% similarity]
Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js
Tools/WebGPUShadingLanguageRI/Test.html
Tools/WebGPUShadingLanguageRI/Test.js
Tools/WebGPUShadingLanguageRI/Type.js
Tools/WebGPUShadingLanguageRI/TypeDef.js
Tools/WebGPUShadingLanguageRI/TypeDefResolver.js
Tools/WebGPUShadingLanguageRI/TypeParameterRewriter.js [deleted file]
Tools/WebGPUShadingLanguageRI/TypeRef.js
Tools/WebGPUShadingLanguageRI/TypeVariable.js [deleted file]
Tools/WebGPUShadingLanguageRI/UnificationContext.js
Tools/WebGPUShadingLanguageRI/VectorType.js [moved from Tools/WebGPUShadingLanguageRI/ConstexprTypeParameter.js with 56% similarity]
Tools/WebGPUShadingLanguageRI/Visitor.js
Tools/WebGPUShadingLanguageRI/WSL.md [deleted file]
Tools/WebGPUShadingLanguageRI/WrapChecker.js
Tools/WebGPUShadingLanguageRI/index.html

index cb2ec2b..bd20638 100644 (file)
@@ -1,5 +1,170 @@
 2018-08-20  Thomas Denney  <tdenney@apple.com>
 
+        [WHLSL] Remove generics from the interpreter
+        https://bugs.webkit.org/show_bug.cgi?id=187988
+
+        Reviewed by Myles C. Maxfield.
+
+        This patch completely removes generic and protocol support from WHLSL
+        whilst adding back any features that were originally implemented with
+        generics.
+
+        Many of the changes in this patch just remove occurrences of type
+        arguments and type parameters --- although there are some cases where
+        they have been deliberately left in --- as well as removing tests only
+        relevant to those features. These changes are not listed below.
+
+        * WebGPUShadingLanguageRI/All.js: Add/remove JS dependencies
+        * WebGPUShadingLanguageRI/AutoWrapper.js:
+        (AutoWrapper.prototype.visitConstexprTypeParameter): Deleted.
+        * WebGPUShadingLanguageRI/BuiltinVectorCasts.js: Added. The built-in
+        vectors have many constructors for different scalar and vector types.
+        These were originally implemented with generics.
+        * WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Adds the
+        equality operator for built-in vectors, again this was removed with
+        generics.
+        * WebGPUShadingLanguageRI/BuiltinVectorGetter.js: Added, as above.
+        Built-in vectors only support the getter and setter, and not the ander.
+        * WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js: Added.
+        * WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js: Added.
+        * WebGPUShadingLanguageRI/BuiltinVectorSetter.js: Added.
+        * WebGPUShadingLanguageRI/CallExpression.js: Adds support for
+        instantiating functions which cannot be discovered earlier in
+        preparation because their types are absent (specifically support for the
+        operator &[] for array references and the length operator for array
+        references). Previously support for these was implemented with generics.
+        (CallExpression.resolve):
+        (CallExpression.prototype.resolve):
+        (CallExpression.prototype._resolveByInstantiation):
+        (CallExpression.prototype._resolveToOperatorAnderIndexer):
+        (CallExpression.prototype._resolveToOperatorLength):
+        (CallExpression.prototype.resolveToOverload):
+        (CallExpression.prototype.becomeCast):
+        (CallExpression.prototype.toString):
+        (CallExpression):
+        * WebGPUShadingLanguageRI/CallExpressionTypeArgumentResolver.js: Added.
+        We support syntax like vector<int, 2>(a, b) for constructing vectors;
+        this new preparation step resolves them to specific constructors.
+        * WebGPUShadingLanguageRI/CallFunction.js:
+        * WebGPUShadingLanguageRI/Checker.js:
+        * WebGPUShadingLanguageRI/ConstexprFolder.js:
+        * WebGPUShadingLanguageRI/CreateLiteralType.js:
+        * WebGPUShadingLanguageRI/ExpressionFinder.js:
+        * WebGPUShadingLanguageRI/FlattenProtocolExtends.js: Removed.
+        * WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js:
+        * WebGPUShadingLanguageRI/Func.js:
+        * WebGPUShadingLanguageRI/FuncDef.js:
+        * WebGPUShadingLanguageRI/FuncInstantiator.js: Deleted.
+        * WebGPUShadingLanguageRI/InferTypesForCall.js: Removed usage of type arguments.
+        * WebGPUShadingLanguageRI/Inline.js: Remove use of FuncInstantiator.
+        * WebGPUShadingLanguageRI/Inliner.js: Ditto.
+        * WebGPUShadingLanguageRI/Intrinsics.js:
+        * WebGPUShadingLanguageRI/Lexer.js:
+        * WebGPUShadingLanguageRI/LiteralTypeChecker.js:
+        * WebGPUShadingLanguageRI/NameContext.js:
+        (NameContext.prototype.add):
+        (NameContext.prototype.get let):
+        (NameContext.underlyingThings.prototype.else):
+        (NameContext.prototype.resolveFuncOverload):
+        * WebGPUShadingLanguageRI/NameFinder.js:
+        * WebGPUShadingLanguageRI/NameResolver.js:
+        (NameResolver.prototype.visitFunc):
+        (NameResolver.prototype.visitFuncDef):
+        (NameResolver.prototype.visitTypeDef):
+        (NameResolver.prototype.visitStructType):
+        (NameResolver.prototype.visitTypeRef):
+        (NameResolver.prototype.visitCallExpression):
+        (NameResolver.prototype.visitVectorType):
+        (NameResolver):
+        (NameResolver.prototype._visitTypeParametersAndBuildNameContext): Deleted.
+        (NameResolver.prototype.visitProtocolDecl): Deleted.
+        * WebGPUShadingLanguageRI/NativeFunc.js:
+        (NativeFunc):
+        * WebGPUShadingLanguageRI/NativeFuncInstance.js: Deleted.
+        * WebGPUShadingLanguageRI/NativeType.js:
+        (NativeType):
+        (NativeType.prototype.get name):
+        (NativeType.prototype.toString):
+        (NativeType.prototype.get typeParameters): Deleted.
+        (NativeType.prototype.instantiate): Deleted.
+        * WebGPUShadingLanguageRI/Node.js:
+        (Node.prototype.commit):
+        (Node):
+        (Node.prototype.substitute): Deleted.
+        (Node.prototype.substituteToUnification): Deleted.
+        * WebGPUShadingLanguageRI/OperatorAnderIndex.js: Added, previously
+        implemented with generics.
+        * WebGPUShadingLanguageRI/OperatorArrayRefLength.js: Ditto.
+        * WebGPUShadingLanguageRI/OperatorBool.js: Ditto.
+        * WebGPUShadingLanguageRI/Parse.js: Removed everything related to
+        generics and protocols.
+        * WebGPUShadingLanguageRI/Prepare.js: Added new stages.
+        * WebGPUShadingLanguageRI/Program.js:
+        (Program):
+        (Program.prototype.get types):
+        (Program.prototype.add):
+        (Program.prototype.get protocols): Deleted.
+        * WebGPUShadingLanguageRI/ProtocolDecl.js: Removed.
+        * WebGPUShadingLanguageRI/ProtocolRef.js: Removed.
+        * WebGPUShadingLanguageRI/RecursiveTypeChecker.js:
+        * WebGPUShadingLanguageRI/ResolveCallExpressionsWithTypeArguments.js: Added.
+        * WebGPUShadingLanguageRI/ResolveNames.js:
+        * WebGPUShadingLanguageRI/ResolveOverloadImpl.js:
+        * WebGPUShadingLanguageRI/ResolveTypeDefs.js:
+        (resolveTypeDefsInProtocols): Deleted.
+        * WebGPUShadingLanguageRI/Rewriter.js: Changes for new classes.
+        * WebGPUShadingLanguageRI/SPIRV.html:
+        * WebGPUShadingLanguageRI/SPIRVCodegen.js:
+        * WebGPUShadingLanguageRI/StandardLibrary.js: Replace old generic features.
+        * WebGPUShadingLanguageRI/StatementCloner.js: Changes for new classes.
+        (StructLayoutBuilder):
+        * WebGPUShadingLanguageRI/StructType.js:
+        * WebGPUShadingLanguageRI/SwizzleOp.js:
+        (SwizzleOp):
+        (SwizzleOp.prototype.get baseTypeName):
+        (SwizzleOp.prototype.toString):
+        (SwizzleOp.functions.):
+        (SwizzleOp.functions):
+        (SwizzleOp.prototype.instantiateImplementation):
+        (SwizzleOp.allSwizzleOperators.): Deleted.
+        (SwizzleOp.allSwizzleOperators): Deleted.
+        * WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js: Added,
+        previously implemented with generics.
+        * WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Ditto.
+        * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Ditto.
+        * WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js: Ditto.
+        * WebGPUShadingLanguageRI/SynthesizeOperatorBool.js: Ditto.
+        * WebGPUShadingLanguageRI/SynthesizeStructAccessors.js:
+        (synthesizeStructAccessors.setupImplementationData):
+        (synthesizeStructAccessors.createFieldType):
+        (synthesizeStructAccessors.createTypeRef):
+        (synthesizeStructAccessors.setupAnder):
+        (synthesizeStructAccessors):
+        (synthesizeStructAccessors.createTypeParameters): Deleted.
+        (synthesizeStructAccessors.): Deleted.
+        * WebGPUShadingLanguageRI/Test.html:
+        * WebGPUShadingLanguageRI/Test.js: Removed redundant tests and added new
+        tests for changed language features.
+        * WebGPUShadingLanguageRI/Type.js:
+        * WebGPUShadingLanguageRI/TypeDef.js:
+        * WebGPUShadingLanguageRI/TypeDefResolver.js:
+        * WebGPUShadingLanguageRI/TypeParameterRewriter.js: Removed.
+        * WebGPUShadingLanguageRI/TypeRef.js:
+        * WebGPUShadingLanguageRI/TypeVariable.js: Removed.
+        * WebGPUShadingLanguageRI/UnificationContext.js:
+        * WebGPUShadingLanguageRI/VectorType.js: Added.
+        * WebGPUShadingLanguageRI/Visitor.js: Changes for new classes.
+        * WebGPUShadingLanguageRI/WSL.md: Removed description of
+        generics/protocols.
+        * WebGPUShadingLanguageRI/WrapChecker.js:
+        (WrapChecker):
+        (WrapChecker.visitConstexprTypeParameter): Deleted.
+        (WrapChecker.prototype.visitFuncParameter): Deleted.
+        (WrapChecker.prototype.visitTypeVariable): Deleted.
+        * WebGPUShadingLanguageRI/index.html:
+
+2018-08-20  Thomas Denney  <tdenney@apple.com>
+
         Added Thomas Denney to contributors.json.
         https://bugs.webkit.org/show_bug.cgi?id=188525
 
index 15dd7cc..8152527 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +34,8 @@ load("Visitor.js");
 load("CreateLiteral.js");
 load("CreateLiteralType.js");
 load("PropertyAccessExpression.js");
+load("SwizzleOp.js");
+load("NativeType.js");
 
 load("AddressSpace.js");
 load("AnonymousVariable.js");
@@ -44,13 +46,19 @@ load("AutoWrapper.js");
 load("Block.js");
 load("BoolLiteral.js");
 load("Break.js");
+load("BuiltinVectorConstructors.js");
+load("BuiltinVectorGetter.js");
+load("BuiltinVectorSetter.js");
+load("BuiltinVectorIndexGetter.js");
+load("BuiltinVectorIndexSetter.js");
+load("BuiltinVectorEqualityOperator.js");
 load("CallExpression.js");
 load("CallFunction.js");
 load("Check.js");
 load("CheckLiteralTypes.js");
 load("CheckLoops.js");
-load("CheckRecursiveTypes.js");
 load("CheckRecursion.js");
+load("CheckRecursiveTypes.js");
 load("CheckReturns.js");
 load("CheckUnreachableCode.js");
 load("CheckWrapped.js");
@@ -58,12 +66,11 @@ load("Checker.js");
 load("CloneProgram.js");
 load("CommaExpression.js");
 load("ConstexprFolder.js");
-load("ConstexprTypeParameter.js");
 load("Continue.js");
 load("ConvertPtrToArrayRefExpression.js");
-load("DereferenceExpression.js");
 load("DoWhileLoop.js");
 load("DotExpression.js");
+load("DereferenceExpression.js");
 load("EArrayRef.js");
 load("EBuffer.js");
 load("EBufferBuilder.js");
@@ -77,7 +84,6 @@ load("ExpressionFinder.js");
 load("ExternalOrigin.js");
 load("Field.js");
 load("FindHighZombies.js");
-load("FlattenProtocolExtends.js");
 load("FlattenedStructOffsetGatherer.js");
 load("FloatLiteral.js");
 load("FloatLiteralType.js");
@@ -85,7 +91,6 @@ load("FoldConstexprs.js");
 load("ForLoop.js");
 load("Func.js");
 load("FuncDef.js");
-load("FuncInstantiator.js");
 load("FuncParameter.js");
 load("FunctionLikeBlock.js");
 load("HighZombieFinder.js");
@@ -95,7 +100,6 @@ load("IndexExpression.js");
 load("InferTypesForCall.js");
 load("Inline.js");
 load("Inliner.js");
-load("InstantiateImmediates.js");
 load("IntLiteral.js");
 load("IntLiteralType.js");
 load("Intrinsics.js");
@@ -112,27 +116,24 @@ load("NameContext.js");
 load("NameFinder.js");
 load("NameResolver.js");
 load("NativeFunc.js");
-load("NativeFuncInstance.js");
-load("NativeType.js");
-load("NativeTypeInstance.js");
 load("NormalUsePropertyResolver.js");
 load("NullLiteral.js");
 load("NullType.js");
+load("OperatorAnderIndex.js");
+load("OperatorArrayRefLength.js");
+load("OperatorBool.js");
 load("OriginKind.js");
 load("OverloadResolutionFailure.js");
 load("Parse.js");
 load("Prepare.js");
+load("PropertyResolver.js");
 load("Program.js");
 load("ProgramWithUnnecessaryThingsRemoved.js");
-load("PropertyResolver.js");
-load("Protocol.js");
-load("ProtocolDecl.js");
-load("ProtocolFuncDecl.js");
-load("ProtocolRef.js");
 load("PtrType.js");
 load("ReadModifyWriteExpression.js");
 load("RecursionChecker.js");
 load("RecursiveTypeChecker.js");
+load("RemoveTypeArguments.js");
 load("ResolveNames.js");
 load("ResolveOverloadImpl.js");
 load("ResolveProperties.js");
@@ -144,19 +145,18 @@ load("StandardLibrary.js");
 load("StatementCloner.js");
 load("StructLayoutBuilder.js");
 load("StructType.js");
-load("Substitution.js");
 load("SwitchCase.js");
 load("SwitchStatement.js");
+load("SynthesizeArrayOperatorLength.js");
 load("SynthesizeEnumFunctions.js");
 load("SynthesizeStructAccessors.js");
+load("SynthesizeOperatorBool.js");
+load("SynthesizeCopyConstructorOperator.js");
+load("SynthesizeDefaultConstructorOperator.js");
 load("TrapStatement.js");
 load("TypeDef.js");
 load("TypeDefResolver.js");
-load("TypeOrVariableRef.js");
-load("TypeParameterRewriter.js");
 load("TypeRef.js");
-load("TypeVariable.js");
-load("TypeVariableTracker.js");
 load("TypedValue.js");
 load("UintLiteral.js");
 load("UintLiteralType.js");
@@ -164,10 +164,10 @@ load("UnificationContext.js");
 load("UnreachableCodeChecker.js");
 load("VariableDecl.js");
 load("VariableRef.js");
+load("VectorType.js");
 load("VisitingSet.js");
 load("WSyntaxError.js");
 load("WTrapError.js");
 load("WTypeError.js");
 load("WhileLoop.js");
-load("WrapChecker.js");
-
+load("WrapChecker.js");
\ No newline at end of file
index 80ae7d9..ad196b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,11 +35,6 @@ class AutoWrapper extends Rewriter {
         return node;
     }
     
-    visitConstexprTypeParameter(node)
-    {
-        return VariableRef.wrap(node);
-    }
-    
     visitFuncParameter(node)
     {
         return VariableRef.wrap(node);
diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js
new file mode 100644 (file)
index 0000000..2704b43
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class BuiltinVectorConstructors {
+    constructor(baseTypeName, parameterSizes)
+    {
+        this._baseTypeName = baseTypeName;
+        this._parameterSizes = parameterSizes;
+    }
+
+    get baseTypeName() { return this._baseTypeName; }
+    get parameterSizes() { return this._parameterSizes; }
+    get outputSize()
+    {
+        return this.parameterSizes.reduce((a, b) => a + b, 0);
+    }
+
+    toString()
+    {
+        return `native operator ${this.baseTypeName}${this.outputSize}(${this.parameterSizes.map(x => x == 1 ? this.baseTypeName : this.baseTypeName + x).join(",")})`;
+    }
+
+    static functions()
+    {
+        if (!this._functions) {
+            this._functions = [];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes) {
+                    for (let paramSizes of this._vectorParameterSizesForMaximumSize(size))
+                        this._functions.push(new BuiltinVectorConstructors(typeName, paramSizes));
+                }
+            }
+        }
+        return this._functions;
+    }
+
+    static _vectorParameterSizesForMaximumSize(maxSize)
+    {
+        let variants = [ [ maxSize ] ];
+        for (let splitPoint = 1; splitPoint < maxSize; splitPoint++) {
+            for (let v of BuiltinVectorConstructors._vectorParameterSizesForMaximumSize(maxSize - splitPoint))
+                variants.push([ splitPoint ].concat(v));
+        }
+        return variants;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = (args) => {
+            const result = new EPtr(new EBuffer(this.outputSize), 0);
+            let offset = 0;
+            for (let i = 0; i < args.length; i++) {
+                for (let j = 0; j < this.parameterSizes[i]; j++)
+                    result.set(offset++, args[i].get(j));
+            }
+            return result;
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-class ProtocolRef extends Protocol {
-    constructor(origin, name)
+class BuiltinVectorEqualityOperator {
+    constructor(baseTypeName, size)
     {
-        super(origin, name);
-        this.protocolDecl = null;
+        this._baseTypeName = baseTypeName;
+        this._size = size;
     }
-    
-    inherits(other)
+
+    get baseTypeName() { return this._baseTypeName; }
+    get size() { return this._size; }
+
+    toString()
     {
-        return this.protocolDecl.inherits(other);
+        return `native bool operator==(${this.baseTypeName}${this.size},${this.baseTypeName}${this.size})`;
     }
-    
-    hasHeir(type)
+
+    static functions()
     {
-        return this.protocolDecl.hasHeir(type);
+        if (!this._functions) {
+            this._functions = [];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes)
+                    this._functions.push(new BuiltinVectorEqualityOperator(typeName, size));
+            }
+        }
+        return this._functions;
     }
-    
-    get isPrimitive()
+
+    instantiateImplementation(func)
     {
-        return this.protocolDecl.isPrimitive;
+        func.implementation = ([ref1, ref2], node) => {
+            for (let i = 0; i < this.size; i++) {
+                if (ref1.get(i) != ref2.get(i))
+                    return EPtr.box(false);
+            }
+            return EPtr.box(true);
+        };
+        func.implementationData = this;
     }
-}
+}
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-class Substitution extends Rewriter {
-    constructor(parameters, argumentList)
+class BuiltinVectorGetter {
+    constructor(baseTypeName, size, elementName, index)
     {
-        super();
-        if (parameters.length != argumentList.length)
-            throw new Error("Parameters and arguments are mismatched");
-        this._map = new Map();
-        for (let i = 0; i < parameters.length; ++i)
-            this._map.set(parameters[i], argumentList[i]);
+        this._baseTypeName = baseTypeName;
+        this._size = size;
+        this._elementName = elementName;
+        this._index = index;
     }
-    
-    get map() { return this._map; }
-    
-    visitTypeRef(node)
+
+    get baseTypeName() { return this._baseTypeName; }
+    get size() { return this._size; }
+    get elementName() { return this._elementName; }
+    get index() { return this._index; }
+
+    toString()
     {
-        let replacement = this._map.get(node.type);
-        if (replacement) {
-            if (node.typeArguments.length)
-                throw new Error("Unexpected type arguments on type variable");
-            let result = replacement.visit(new AutoWrapper());
-            return result;
-        }
-        
-        let result = super.visitTypeRef(node);
-        return result;
+        return `native ${this.baseTypeName} operator.${this.elementName}(${this.baseTypeName}${this.size})`;
     }
 
-    visitVariableRef(node)
+    static functions()
     {
-        let replacement = this._map.get(node.variable);
-        if (replacement)
-            return replacement.visit(new AutoWrapper());
-        
-        return super.visitVariableRef(node);
+        if (!this._functions) {
+            this._functions = [];
+
+            const elements = [ "x", "y", "z", "w" ];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes) {
+                    for (let i = 0; i < size; i++)
+                        this._functions.push(new BuiltinVectorGetter(typeName, size, elements[i], i));
+                }
+            }
+        }
+        return this._functions;
     }
-}
 
+    instantiateImplementation(func)
+    {
+        func.implementation = ([vec], node) => {
+            return EPtr.box(vec.get(this.index));
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js
new file mode 100644 (file)
index 0000000..f7262fc
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class BuiltinVectorIndexGetter {
+    constructor(baseTypeName, size)
+    {
+        this._baseTypeName = baseTypeName;
+        this._size = size;
+    }
+
+    get baseTypeName() { return this._baseTypeName; }
+    get size() { return this._size; }
+
+    toString()
+    {
+        return `native ${this.baseTypeName} operator[](${this.baseTypeName}${this.size},uint)`;
+    }
+
+    static functions()
+    {
+        if (!this._allIndexGetters) {
+            this._allIndexGetters = [];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes)
+                    this._allIndexGetters.push(new BuiltinVectorIndexGetter(typeName, size));
+            }
+        }
+        return this._allIndexGetters;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([vec, index], node) => {
+            const indexValue = index.loadValue();
+            if (indexValue >= 0 && indexValue < this.size)
+                return EPtr.box(vec.get(index.loadValue()));
+            else
+                throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`);
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js
new file mode 100644 (file)
index 0000000..2fe5d67
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class BuiltinVectorIndexSetter {
+    constructor(baseTypeName, size)
+    {
+        this._baseTypeName = baseTypeName;
+        this._size = size;
+    }
+
+    get baseTypeName() { return this._baseTypeName; }
+    get size() { return this._size; }
+    get elementName() { return this._elementName; }
+    get index() { return this._index; }
+
+    toString()
+    {
+        return `native ${this.baseTypeName}${this.size} operator[]=(${this.baseTypeName}${this.size},uint,${this.baseTypeName})`;
+    }
+
+    static functions()
+    {
+        if (!this._functions) {
+            this._functions = [];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes)
+                    this._functions.push(new BuiltinVectorIndexSetter(typeName, size));
+            }
+        }
+        return this._functions;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([base, index, value], node) => {
+            const indexValue = index.loadValue();
+            if (indexValue >= 0 && indexValue < this.size) {
+                let result = new EPtr(new EBuffer(this.size), 0);
+                result.copyFrom(base, this.size);
+                result.plus(indexValue).copyFrom(value, 1);
+                return result;
+            } else
+                throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`);
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js
new file mode 100644 (file)
index 0000000..a2d763b
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+class BuiltinVectorSetter {
+    constructor(baseTypeName, size, elementName, index)
+    {
+        this._baseTypeName = baseTypeName;
+        this._size = size;
+        this._elementName = elementName;
+        this._index = index;
+    }
+
+    get baseTypeName() { return this._baseTypeName; }
+    get size() { return this._size; }
+    get elementName() { return this._elementName; }
+    get index() { return this._index; }
+
+    toString()
+    {
+        return `native ${this.baseTypeName}${this.size} operator.${this.elementName}=(${this.baseTypeName}${this.size},${this.baseTypeName})`;
+    }
+
+    static functions()
+    {
+        if (!this._functions) {
+            this._functions = [];
+        
+            const elements = [ "x", "y", "z", "w" ];
+
+            for (let typeName of VectorElementTypes) {
+                for (let size of VectorElementSizes) {
+                    for (let i = 0; i < size; i++)
+                        this._functions.push(new BuiltinVectorSetter(typeName, size, elements[i], i));
+                }
+            }
+        }
+        return this._functions;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([base, value], node) => {
+            let result = new EPtr(new EBuffer(this.size), 0);
+            result.copyFrom(base, this.size);
+            result.plus(this.index).copyFrom(value, 1);
+            return result;
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
index b5ae0fe..6dba153 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,80 +42,121 @@ class CallExpression extends Expression {
     get isCast() { return this._isCast; }
     get returnType() { return this._returnType; }
     
-    static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType)
+    static resolve(origin, possibleOverloads, name, argumentList, argumentTypes, returnType, program)
     {
-        let call = new CallExpression(origin, name, typeArguments, argumentList);
+        let call = new CallExpression(origin, name, [], argumentList);
         call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
         call.possibleOverloads = possibleOverloads;
         if (returnType)
             call.setCastData(returnType);
-        return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments)};
+        return {call, resultType: call.resolve(possibleOverloads, program)};
     }
-    
-    resolve(possibleOverloads, typeParametersInScope, typeArguments)
+
+    resolve(possibleOverloads, program)
     {
         if (!possibleOverloads)
             throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name);
-        
-        let overload = null;
+
         let failures = [];
-        for (let typeParameter of typeParametersInScope) {
-            if (!(typeParameter instanceof TypeVariable))
-                continue;
-            if (!typeParameter.protocol)
-                continue;
-            let signatures =
-                typeParameter.protocol.protocolDecl.signaturesByNameWithTypeVariable(this.name, typeParameter);
-            if (!signatures)
-                continue;
-            overload = resolveOverloadImpl(signatures, this.typeArguments, this.argumentTypes, this.returnType);
-            if (overload.func)
-                break;
-            failures.push(...overload.failures);
-            overload = null;
-        }
-        if (!overload) {
-            overload = resolveOverloadImpl(
-                possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType);
-            if (!overload.func) {
-                failures.push(...overload.failures);
-                let message = "Did not find function named " + this.name + " for call with ";
-                if (this.typeArguments.length)
-                    message += "type arguments <" + this.typeArguments + "> and ";
-                message += "argument types (" + this.argumentTypes + ")";
-                if (this.returnType)
-                    message +=" and return type " + this.returnType;
-                if (failures.length)
-                    message += ", but considered:\n" + failures.join("\n")
-                throw new WTypeError(this.origin.originString, message);
-            }
+        let overload = resolveOverloadImpl(possibleOverloads, this.argumentTypes, this.returnType);
+
+        if (!overload.func) {
+            const func = this._resolveByInstantiation(program);
+            if (func)
+                overload.func = func;
         }
-        for (let i = 0; i < typeArguments.length; ++i) {
-            let typeArgumentType = typeArguments[i];
-            let typeParameter = overload.func.typeParameters[i];
-            if (!(typeParameter instanceof ConstexprTypeParameter))
-                continue;
-            if (!typeParameter.type.equalsWithCommit(typeArgumentType))
-                throw new Error("At " + this.origin.originString + " constexpr type argument and parameter types not equal: argument = " + typeArgumentType + ", parameter = " + typeParameter.type);
+
+
+        if (!overload.func) {
+            failures.push(...overload.failures);
+            let message = "Did not find function named " + this.name + " for call with ";
+            message += "argument types (" + this.argumentTypes + ")";
+            if (this.returnType)
+                message +=" and return type " + this.returnType;
+            if (failures.length)
+                message += ", but considered:\n" + failures.join("\n")
+            throw new WTypeError(this.origin.originString, message);
         }
+
         for (let i = 0; i < this.argumentTypes.length; ++i) {
             let argumentType = this.argumentTypes[i];
-            let parameterType = overload.func.parameters[i].type.substituteToUnification(
-                overload.func.typeParameters, overload.unificationContext);
+            let parameterType = overload.func.parameters[i].type;
             let result = argumentType.equalsWithCommit(parameterType);
             if (!result)
                 throw new Error("At " + this.origin.originString + " argument and parameter types not equal after type argument substitution: argument = " + argumentType + ", parameter = " + parameterType);
         }
         return this.resolveToOverload(overload);
     }
+
+    _resolveByInstantiation(program)
+    {
+        let func;
+        if (this.name == "operator&[]")
+            func = this._resolveWithOperatorAnderIndexer(program);
+        else if (this.name == "operator.length")
+            func = this._resolveWithOperatorLength(program);
+        else
+            return null;
+
+        program.add(func);
+        return func;
+    }
+
+    _resolveWithOperatorAnderIndexer(program)
+    {
+        let arrayRefType = this.argumentTypes[0];
+        if (!arrayRefType.isArrayRef)
+            throw new WTypeError(this.origin.originString, `Expected ${arrayRefType} to be an array ref type for operator&[]`);
+
+        let indexType = this.argumentTypes[1];
+        const addressSpace = arrayRefType.addressSpace;
+
+        // The later checkLiteralTypes stage will verify that the literal can be represented as a uint.
+        const uintType = TypeRef.wrap(program.types.get("uint"));
+        indexType.type = uintType;
+
+        const elementType = this.argumentTypes[0].elementType;
+        this.resultType = this._returnType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
+
+        let arrayRefAccessor = new OperatorAnderIndexer(this.returnType.toString(), addressSpace);
+        const func = new NativeFunc(this.origin, "operator&[]", this.resultType, [
+            new FuncParameter(this.origin, null, arrayRefType),
+            new FuncParameter(this.origin, null, uintType)
+        ], false, null);
+
+        arrayRefAccessor.instantiateImplementation(func);
+
+        return func;
+    }
+
+    _resolveWithOperatorLength(program)
+    {
+        this.resultType = this._returnType = TypeRef.wrap(program.types.get("uint"));
+
+        if (this.argumentTypes[0].isArray) {
+            const arrayType = this.argumentTypes[0];
+            const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
+                new FuncParameter(this.origin, null, arrayType)
+            ], false, null);
+            func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue);
+            return func;
+        } else if (this.argumentTypes[0].isArrayRef) {
+            const arrayRefType = this.argumentTypes[0];
+            const addressSpace = arrayRefType.addressSpace;
+            const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace);
+            const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
+                new FuncParameter(this.origin, null, arrayRefType)
+            ], false, null);
+            operatorLength.instantiateImplementation(func);
+            return func;
+        } else
+            throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`);
+    }
     
     resolveToOverload(overload)
     {
         this.func = overload.func;
-        this.actualTypeArguments = overload.typeArguments.map(typeArgument => typeArgument instanceof Type ? typeArgument.visit(new AutoWrapper()) : typeArgument);
-        this.instantiatedActualTypeArguments = this.actualTypeArguments;
-        let result = overload.func.returnType.substituteToUnification(
-            overload.func.typeParameters, overload.unificationContext);
+        let result = overload.func.returnType;
         if (!result)
             throw new Error("Null return type");
         result = result.visit(new AutoWrapper());
@@ -125,11 +166,10 @@ class CallExpression extends Expression {
     
     becomeCast(returnType)
     {
-        this._returnType = new TypeRef(this.origin, this.name, this._typeArguments);
+        this._returnType = new TypeRef(this.origin, this.name);
         this._returnType.type = returnType;
         this._name = "operator cast";
         this._isCast = true;
-        this._typeArguments = [];
     }
     
     setCastData(returnType)
@@ -141,8 +181,6 @@ class CallExpression extends Expression {
     toString()
     {
         return (this.isCast ? "operator " + this.returnType : this.name) +
-            "<" + this.typeArguments + ">" +
-            (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") +
             "(" + this.argumentList + ")";
     }
 }
index f0f039f..7aaf0ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 "use strict";
 
 // This allows you to pass structs and arrays in-place, but it's a more annoying API.
-function callFunction(program, name, typeArguments, argumentList)
+function callFunction(program, name, argumentList)
 {
     let argumentTypes = argumentList.map(argument => argument.type);
-    let funcOrFailures = resolveInlinedFunction(program, name, typeArguments, argumentTypes, true);
+    let funcOrFailures = resolveInlinedFunction(program, name, argumentTypes, true);
     if (!(funcOrFailures instanceof Func)) {
         let failures = funcOrFailures;
-        throw new WTypeError("<callFunction>", "Cannot resolve function call " + name + "<" + typeArguments + ">(" + argumentList + ")" + (failures.length ? "; tried:\n" + failures.join("\n") : ""));
+        throw new WTypeError("<callFunction>", "Cannot resolve function call " + name + "(" + argumentList + ")" + (failures.length ? "; tried:\n" + failures.join("\n") : ""));
     }
     let func = funcOrFailures;
     for (let i = 0; i < func.parameters.length; ++i) {
-        let type = argumentTypes[i].instantiatedType;
+        let type = argumentTypes[i];
         type.visit(new StructLayoutBuilder());
         func.parameters[i].ePtr.copyFrom(argumentList[i].ePtr, type.size);
     }
     let result = new Evaluator(program).runFunc(func);
-    return new TypedValue(func.uninstantiatedReturnType, result);
+    return new TypedValue(func.returnType, result);
 }
 
index 8d55c50..1a14c86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,8 +43,6 @@ class Checker extends Visitor {
         
         for (let type of node.types.values())
             doStatement(type);
-        for (let protocol of node.protocols.values())
-            doStatement(protocol);
         for (let funcs of node.functions.values()) {
             for (let func of funcs) {
                 this.visitFunc(func);
@@ -59,8 +57,6 @@ class Checker extends Visitor {
     _checkShaderType(node)
     {
         // FIXME: Relax these checks once we have implemented support for textures and samplers.
-        if (node.typeParameters.length != 0)
-            throw new WTypeError(node.origin.originString, "Entry point " + node.name + " must not have type arguments.");
         let shaderFunc = node;
         switch (node.shaderType) {
         case "vertex":
@@ -84,15 +80,6 @@ class Checker extends Visitor {
         if (!func.name.startsWith("operator"))
             throw new Error("Bad operator overload name: " + func.name);
         
-        let typeVariableTracker = new TypeVariableTracker();
-        for (let parameterType of func.parameterTypes)
-            parameterType.visit(typeVariableTracker);
-        Node.visit(func.returnTypeForOverloadResolution, typeVariableTracker);
-        for (let typeParameter of func.typeParameters) {
-            if (!typeVariableTracker.set.has(typeParameter))
-                throw new WTypeError(typeParameter.origin.originString, "Type parameter " + typeParameter + " to operator " + func.toDeclString() + " is not inferrable from value parameters");
-        }
-        
         let checkGetter = (kind) => {
             let numExpectedParameters = kind == "index" ? 2 : 1;
             if (func.parameters.length != numExpectedParameters)
@@ -115,11 +102,10 @@ class Checker extends Visitor {
             if (!getterFuncs)
                 throw new WTypeError(func.origin.originString, "Every setter must have a matching getter, but did not find any function named " + getterName + " to match " + func.name);
             let argumentTypes = func.parameterTypes.slice(0, numExpectedParameters - 1);
-            let overload = resolveOverloadImpl(getterFuncs, [], argumentTypes, null);
+            let overload = resolveOverloadImpl(getterFuncs, argumentTypes, null);
             if (!overload.func)
                 throw new WTypeError(func.origin.originString, "Did not find function named " + func.name + " with arguments " + argumentTypes + (overload.failures.length ? "; tried:\n" + overload.failures.join("\n") : ""));
-            let resultType = overload.func.returnType.substituteToUnification(
-                overload.func.typeParameters, overload.unificationContext);
+            let resultType = overload.func.returnType;
             if (!resultType.equals(valueType))
                 throw new WTypeError(func.origin.originString, "Setter and getter must agree on value type (getter at " + overload.func.origin.originString + " says " + resultType + " while this setter says " + valueType + ")");
         };
@@ -207,27 +193,6 @@ class Checker extends Visitor {
         node.body.visit(this);
     }
     
-    visitNativeFunc(node)
-    {
-    }
-    
-    visitProtocolDecl(node)
-    {
-        for (let signature of node.signatures) {
-            let typeVariableTracker = new TypeVariableTracker();
-            for (let parameterType of signature.parameterTypes)
-                parameterType.visit(typeVariableTracker);
-            Node.visit(signature.returnTypeForOverloadResolution, typeVariableTracker);
-            for (let typeParameter of signature.typeParameters) {
-                if (!typeVariableTracker.set.has(typeParameter))
-                    throw WTypeError(typeParameter.origin.originString, "Type parameter to protocol signature not inferrable from value parameters");
-            }
-            if (!typeVariableTracker.set.has(node.typeVariable))
-                throw new WTypeError(signature.origin.originString, "Protocol's type variable (" + node.name + ") not mentioned in signature: " + signature);
-            this._checkOperatorOverload(signature, name => node.signaturesByName(name));
-        }
-    }
-    
     visitEnumType(node)
     {
         node.baseType.visit(this);
@@ -278,29 +243,31 @@ class Checker extends Visitor {
             throw new WTypeError(node.origin.originString, "Enum does not have a member with the value zero");
     }
     
-    _checkTypeArguments(origin, typeParameters, typeArguments)
-    {
-        for (let i = 0; i < typeParameters.length; ++i) {
-            let argumentIsType = typeArguments[i] instanceof Type;
-            let result = typeArguments[i].visit(this);
-            if (argumentIsType) {
-                let result = typeArguments[i].inherits(typeParameters[i].protocol);
-                if (!result.result)
-                    throw new WTypeError(origin.originString, "Type argument does not inherit protocol: " + result.reason);
-            } else {
-                if (!result.equalsWithCommit(typeParameters[i].type))
-                    throw new WTypeError(origin.originString, "Wrong type for constexpr");
-            }
-        }
-    }
-    
     visitTypeRef(node)
     {
         if (!node.type)
             throw new Error("Type reference without a type in checker: " + node + " at " + node.origin);
         if (!(node.type instanceof StructType))
             node.type.visit(this);
-        this._checkTypeArguments(node.origin, node.type.typeParameters, node.typeArguments);
+    }
+
+    visitVectorType(node)
+    {
+        node.elementType.visit(this);
+
+        let isKnownAllowedVectorElementType = false;
+        for (let vectorElementTypeName of VectorElementTypes) {
+            const vectorElementType = this._program.globalNameContext.get(Type, vectorElementTypeName);
+            if (!vectorElementType)
+                throw new WTypeError(`${vectorElementType} is listed in VectorElementTypes, but it is not a known native type in the standard library or intrinsics.`);
+            if (vectorElementType.equals(node.elementType)) {
+                isKnownAllowedVectorElementType = true;
+                break;
+            }
+        }
+
+        if (!isKnownAllowedVectorElementType)
+            throw new WTypeError(`${node.elementType} is not a permitted vector element type.`);
     }
     
     visitArrayType(node)
@@ -312,8 +279,8 @@ class Checker extends Visitor {
         
         let type = node.numElements.visit(this);
         
-        if (!type.equalsWithCommit(this._program.intrinsics.uint32))
-            throw new WTypeError(node.origin.originString, "Array length must be a uint32");
+        if (!type.equalsWithCommit(this._program.intrinsics.uint))
+            throw new WTypeError(node.origin.originString, "Array length must be a uint");
     }
     
     visitVariableDecl(node)
@@ -401,7 +368,7 @@ class Checker extends Visitor {
             node.numElements = elementType.numElements;
             elementType = elementType.elementType;
         } else
-            node.numElements = UintLiteral.withType(node.origin, 1, this._program.intrinsics.uint32);
+            node.numElements = UintLiteral.withType(node.origin, 1, this._program.intrinsics.uint);
             
         return new ArrayRefType(node.origin, node.lValue.addressSpace, elementType);
     }
@@ -426,8 +393,8 @@ class Checker extends Visitor {
         
         try {
             let result = CallExpression.resolve(
-                node.origin, node.possibleGetOverloads, this._currentStatement.typeParameters,
-                node.getFuncName, [], [node.base, ...extraArgs], [baseType, ...extraArgTypes], null);
+                node.origin, node.possibleGetOverloads,
+                node.getFuncName, [node.base, ...extraArgs], [baseType, ...extraArgTypes], null, this._program);
             node.callForGet = result.call;
             node.resultTypeForGet = result.resultType;
         } catch (e) {
@@ -440,9 +407,9 @@ class Checker extends Visitor {
             let baseForAnd = baseType.argumentForAndOverload(node.origin, node.base);
             
             let result = CallExpression.resolve(
-                node.origin, node.possibleAndOverloads, this._currentStatement.typeParameters,
-                node.andFuncName, [], [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes],
-                null);
+                node.origin, node.possibleAndOverloads,
+                node.andFuncName, [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes],
+                null, this._program);
             node.callForAnd = result.call;
             node.resultTypeForAnd = result.resultType.unifyNode.returnTypeFromAndOverload(node.origin);
         } catch (e) {
@@ -466,8 +433,8 @@ class Checker extends Visitor {
         
         try {
             let result = CallExpression.resolve(
-                node.origin, node.possibleSetOverloads, this._currentStatement.typeParameters,
-                node.setFuncName, [], [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null);
+                node.origin, node.possibleSetOverloads,
+                node.setFuncName, [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null, this._program);
             node.callForSet = result.call;
             if (!result.resultType.equals(baseType))
                 throw new WTypeError(node.origin.originString, "Result type of setter " + result.call.func + " is not the base type " + baseType);
@@ -675,7 +642,6 @@ class Checker extends Visitor {
     
     visitCallExpression(node)
     {
-        let typeArguments = node.typeArguments.map(typeArgument => typeArgument.visit(this));
         let argumentTypes = node.argumentList.map(argument => {
             let newArgument = argument.visit(this);
             if (!newArgument)
@@ -687,7 +653,7 @@ class Checker extends Visitor {
         if (node.returnType)
             node.returnType.visit(this);
 
-        let result = node.resolve(node.possibleOverloads, this._currentStatement.typeParameters, typeArguments);
+        let result = node.resolve(node.possibleOverloads, this._program);
         return result;
     }
 }
index 1e5ad66..5451332 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,7 +34,6 @@ class ConstexprFolder extends Visitor {
         super.visitCallExpression(node);
         
         if (node.name == "operator-"
-            && !node.typeArguments.length
             && node.argumentList.length == 1
             && node.argumentList[0].unifyNode.isConstexpr
             && node.argumentList[0].unifyNode.negConstexpr) {
@@ -42,9 +41,5 @@ class ConstexprFolder extends Visitor {
             return;
         }
     }
-    
-    visitTypeOrVariableRef(node)
-    {
-    }
 }
 
index 12914da..8c5df26 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,7 @@ function createLiteralType(config)
             super();
             this._origin = origin;
             this._value = value;
-            this.preferredType = new TypeRef(origin, config.preferredTypeName, []);
+            this.preferredType = new TypeRef(origin, config.preferredTypeName);
         }
         
         get origin() { return this._origin; }
@@ -58,7 +58,7 @@ function createLiteralType(config)
         prepareToVerify(unificationContext)
         {
             let realThis = unificationContext.find(this);
-            if (realThis instanceof TypeVariable || realThis.isLiteral) {
+            if (realThis.isLiteral) {
                 return () => {
                     if (realThis.unify(unificationContext, this.preferredType))
                         return {result: true};
index 58ced89..394407e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -307,7 +307,7 @@ class Evaluator extends Visitor {
         let callArguments = [];
         for (let i = 0; i < node.argumentList.length; ++i) {
             let argument = node.argumentList[i];
-            let type = node.nativeFuncInstance.parameterTypes[i];
+            let type = node.func.parameterTypes[i];
             if (!type || !argument)
                 throw new Error("Cannot get type or argument; i = " + i + ", argument = " + argument + ", type = " + type + "; in " + node);
             let argumentValue = argument.visit(this);
@@ -324,7 +324,7 @@ class Evaluator extends Visitor {
         let result = EBuffer.allowAllocation(
             () => node.func.implementation(callArguments.map(thunk => thunk()), node));
         
-        result = this._snapshot(node.nativeFuncInstance.returnType, node.resultEPtr, result);
+        result = this._snapshot(node.func.returnType, node.resultEPtr, result);
         return result;
     }
 }
index 30e6b03..984a543 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,8 +35,6 @@ class ExpressionFinder extends Visitor {
     visitFunc(node)
     {
         this._callback(node.returnType);
-        for (let typeParameter of node.typeParameters)
-            typeParameter.visit(this);
         for (let parameter of node.parameters)
             parameter.visit(this);
     }
@@ -46,11 +44,6 @@ class ExpressionFinder extends Visitor {
         this._callback(node.type);
     }
     
-    visitConstexprTypeParameter(node)
-    {
-        this._callback(node.type);
-    }
-    
     visitAssignment(node)
     {
         this._callback(node);
diff --git a/Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js b/Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js
deleted file mode 100644 (file)
index 76172d9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-function flattenProtocolExtends(program)
-{
-    let visiting = new VisitingSet();
-    
-    function flatten(protocol)
-    {
-        if (!protocol.extends.length)
-            return;
-        
-        visiting.doVisit(protocol, () => {
-            for (let parent of protocol.extends) {
-                parent = parent.protocolDecl;
-                flatten(parent);
-                for (let signature of parent.signatures) {
-                    let newSignature = signature.visit(
-                        new Substitution([parent.typeVariable], [protocol.typeVariable]));
-                    protocol.add(newSignature);
-                }
-            }
-            protocol.extends = [];
-        });
-    }
-    
-    for (let protocol of program.protocols.values())
-        flatten(protocol);
-}
-
index 01015ce..1970f8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,5 +62,17 @@ class FlattenedStructOffsetGatherer extends Visitor {
         super.visitTypeRef(node);
         Node.visit(node.type, this);
     }
+
+    visitVectorType(node)
+    {
+        const fieldNames = [ "x", "y", "z", "w" ];
+        for (let i = 0; i < node.numElementsValue; i++) {
+            this._result.push({
+                name: this._name.join(".") + "." + fieldNames[i],
+                offset: this._offset + i * node.elementType.size,
+                type: node.elementType.name
+            });
+        }
+    }
 }
 
index 6fa7c9d..cbc2c33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,7 +25,7 @@
 "use strict";
 
 class Func extends Node {
-    constructor(origin, name, returnType, typeParameters, parameters, isCast, shaderType)
+    constructor(origin, name, returnType, parameters, isCast, shaderType)
     {
         if (!(origin instanceof LexerToken))
             throw new Error("Bad origin: " + origin);
@@ -39,7 +39,6 @@ class Func extends Node {
         this._origin = origin;
         this._name = name;
         this._returnType = returnType;
-        this._typeParameters = typeParameters;
         this._parameters = parameters;
         this._isCast = isCast;
         this._shaderType = shaderType;
@@ -48,8 +47,6 @@ class Func extends Node {
     get origin() { return this._origin; }
     get name() { return this._name; }
     get returnType() { return this._returnType; }
-    get typeParameters() { return this._typeParameters; }
-    get typeParametersForCallResolution() { return this.typeParameters; }
     get parameters() { return this._parameters; }
     get parameterTypes() { return this.parameters.map(parameter => parameter.type); }
     get isCast() { return this._isCast; }
@@ -65,9 +62,9 @@ class Func extends Node {
         if (this.shaderType)
             result += this.shaderType + " ";
         if (this.isCast)
-            result += "operator<" + this.typeParameters + "> " + this.returnType;
+            result += `operator ${this.returnType}`;
         else
-            result += this.returnType + " " + this.name + "<" + this.typeParameters + ">";
+            result += `${this.returnType} ${this.name}`;
         return result + "(" + this.parameters + ")";
     }
     
index 11fa092..d68e403 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,9 +25,9 @@
 "use strict";
 
 class FuncDef extends Func {
-    constructor(origin, name, returnType, typeParameters, parameters, body, isCast, shaderType)
+    constructor(origin, name, returnType, parameters, body, isCast, shaderType)
     {
-        super(origin, name, returnType, typeParameters, parameters, isCast, shaderType);
+        super(origin, name, returnType, parameters, isCast, shaderType);
         this._body = body;
         this.isRestricted = false;
     }
@@ -36,8 +36,6 @@ class FuncDef extends Func {
     
     rewrite(rewriter)
     {
-        if (this._typeParameters.length)
-            throw new Error("Cannot rewrite an uninstantiated function");
         this._returnType = this._returnType.visit(rewriter);
         this._parameters = this._parameters.map(parameter => parameter.visit(rewriter));
         this._body = this.body.visit(rewriter);
diff --git a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js b/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js
deleted file mode 100644 (file)
index 892862a..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class FuncInstantiator {
-    constructor(program)
-    {
-        this._program = program;
-        this._instances = new Map();
-    }
-    
-    get instances() { return this._instances; }
-    
-    // Returns a Func object that uniquely identifies a particular system of type arguments. You must
-    // intantiate things with concrete types, because this code casually assumes this. Note that this
-    // will return a different func from `func` no matter what. This ensures that we can use the
-    // returned func for rewrites that instantiate types without destroying our ability to do overload
-    // resolutions on the original Program.
-    getUnique(func, typeArguments)
-    {
-        class FindTypeVariable extends Visitor {
-            visitTypeRef(node)
-            {
-                for (let typeArgument of node.typeArguments)
-                    typeArgument.visit(this);
-            }
-            
-            visitTypeVariable(node) {
-                throw new Error("Unexpected type variable: " + node + " when instantiating " + func + " with arguments " + typeArguments);
-            }
-        }
-        for (let typeArgument of typeArguments)
-            typeArgument.visit(new FindTypeVariable());
-        
-        let instances = this._instances.get(func);
-        if (!instances)
-            this._instances.set(func, instances = []);
-        
-        for (let instance of instances) {
-            let ok = true;
-            for (let i = instance.typeArguments.length; i--;) {
-                if (!instance.typeArguments[i].equals(typeArguments[i])) {
-                    ok = false;
-                    break;
-                }
-            }
-            if (!ok)
-                continue;
-            return instance.func;
-        }
-        
-        let thisInstantiator = this;
-        
-        class InstantiationSubstitution extends Substitution {
-            visitCallExpression(node)
-            {
-                let result = super.visitCallExpression(node);
-                
-                // We may have to re-resolve the function call, if it was a call to a protocol
-                // signature.
-                if (result.func instanceof ProtocolFuncDecl) {
-                    let overload = resolveOverloadImpl(result.possibleOverloads, result.typeArguments, result.argumentTypes, result.returnType);
-                    if (!overload.func)
-                        throw new Error("Could not resolve protocol signature function call during instantiation: " + result.func + (overload.failures.length ? "; tried:\n" + overload.failures.join("\n") : ""));
-                    result.resolveToOverload(overload);
-                }
-                
-                if (result.func.isNative)
-                    result.nativeFuncInstance = thisInstantiator.getUnique(result.func, result.actualTypeArguments);
-                
-                return result;
-            }
-        }
-        
-        let substitution = new InstantiationSubstitution(func.typeParameters, typeArguments);
-
-        class InstantiationInstantiateImmediates extends InstantiateImmediates {
-            visitCallExpression(node)
-            {
-                // We need to preserve certain things that would have instantiated, but that we cannot
-                // instantiate without breaking chain-instantiations (generic function calls generic
-                // function so therefore the instantiated generic function must still have the original
-                // (uninstantiated) types to instantiate the generic function that it calls).
-                let result = new CallExpression(
-                    node.origin, node.name, node.typeArguments,
-                    node.argumentList.map(argument => Node.visit(argument, this)));
-                result = this.processDerivedCallData(node, result);
-                
-                result.argumentTypes = Array.from(node.argumentTypes);
-                if (node.isCast)
-                    result.setCastData(node.returnType);
-                result.actualTypeArguments = Array.from(node.actualTypeArguments);
-                
-                return result;
-            }
-        }
-
-        let instantiateImmediates = new InstantiationInstantiateImmediates();
-        
-        class Instantiate {
-            visitFuncDef(func)
-            {
-                let returnType = func.returnType.visit(substitution);
-                returnType = returnType.visit(instantiateImmediates);
-                let parameters = func.parameters.map(parameter => parameter.visit(substitution));
-                parameters = parameters.map(parameter => parameter.visit(instantiateImmediates));
-                let body = func.body.visit(substitution);
-                body = body.visit(instantiateImmediates);
-                return new FuncDef(
-                    func.origin, func.name, returnType, [], parameters, body, func.isCast,
-                    func.shaderType);
-            }
-            
-            visitNativeFunc(func)
-            {
-                return new NativeFuncInstance(
-                    func,
-                    func.returnType.visit(substitution).visit(instantiateImmediates),
-                    func.parameters.map(parameter => parameter.visit(substitution).visit(instantiateImmediates)),
-                    func.isCast,
-                    func.shaderType,
-                    func.instantiateImplementation(substitution));
-            }
-        }
-        let resultingFunc = func.visit(new Instantiate());
-        resultingFunc.uninstantiatedReturnType = func.returnType.visit(substitution);
-        let instance = {func: resultingFunc, typeArguments};
-        instances.push(instance);
-        return resultingFunc;
-    }
-}
-
index 446b351..5f32ed1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-function inferTypesForCall(func, typeArguments, argumentTypes, returnType)
+function inferTypesForCall(func, argumentTypes, returnType)
 {
-    if (typeArguments.length && typeArguments.length != func.typeParameters.length)
-        return {failure: new OverloadResolutionFailure(func, "Wrong number of type arguments (passed " + typeArguments.length + ", require " + func.typeParameters.length + ")")};
     if (argumentTypes.length != func.parameters.length)
         return {failure: new OverloadResolutionFailure(func, "Wrong number of arguments (passed " + argumentTypes.length + ", require " + func.parameters.length + ")")};
-    let unificationContext = new UnificationContext(func.typeParametersForCallResolution);
-    for (let i = 0; i < typeArguments.length; ++i) {
-        let argument = typeArguments[i];
-        let parameter = func.typeParameters[i];
-        if (!argument.unify(unificationContext, parameter))
-            return {failure: new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + parameter.name + " does not match (passed " + argument + ", require " + parameter + ")")};
-    }
+    let unificationContext = new UnificationContext();
+
     for (let i = 0; i < argumentTypes.length; ++i) {
         if (!argumentTypes[i])
             throw new Error("Null argument type at i = " + i);
         if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type))
             return {failure: new OverloadResolutionFailure(func, "Argument #" + (i + 1) + " " + (func.parameters[i].name ? "for parameter " + func.parameters[i].name + " " : "") + "does not match (passed " + argumentTypes[i] + ", require " + func.parameters[i].type + ")")};
     }
-    if (returnType && !returnType.unify(unificationContext, func.returnType))
+    if (returnType && !returnType.unify(unificationContext, func.returnType)) {
+        if (func.returnType.toString() == "vector") {
+            returnType.unify(unificationContext, func.returnType)
+        }
         return {failure: new OverloadResolutionFailure(func, "Return type " + func.returnType + " does not match " + returnType)};
+    }
     let verificationResult = unificationContext.verify();
     if (!verificationResult.result)
         return {failure: new OverloadResolutionFailure(func, verificationResult.reason)};
-    let shouldBuildTypeArguments = !typeArguments.length;
-    if (shouldBuildTypeArguments)
-        typeArguments = [];
-    for (let typeParameter of func.typeParameters) {
-        let typeArgument = unificationContext.find(typeParameter);
-        if (typeArgument == typeParameter)
-            return {failure: new OverloadResolutionFailure(func, "Type parameter " + typeParameter + " did not get assigned a type")};
-        if (shouldBuildTypeArguments)
-            typeArguments.push(typeArgument);
-    }
-    return {func, unificationContext, typeArguments};
+
+    return {func, unificationContext};
 }
 
index f02873b..8ba9ad7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 function inline(program)
 {
     for (let funcList of program.functions.values()) {
-        for (let func of funcList) {
-            if (!func.typeParameters.length) {
-                func = program.funcInstantiator.getUnique(func, [])
-                _inlineFunction(program, func, new VisitingSet(func));
-            }
-        }
+        for (let func of funcList)
+            _inlineFunction(program, func, new VisitingSet(func));
     }
 }
 
 function _inlineFunction(program, func, visiting)
 {
-    if (func.typeParameters.length)
-        throw new Error("Cannot inline function that has type parameters");
     if (func.inlined || func.isNative)
         return;
     
@@ -55,14 +49,13 @@ function _inlineFunction(program, func, visiting)
     func.inlined = true;
 }
 
-function resolveInlinedFunction(program, name, typeArguments, argumentTypes, allowEntryPoint = false)
+function resolveInlinedFunction(program, name, argumentTypes, allowEntryPoint = false)
 {
-    let overload = program.globalNameContext.resolveFuncOverload(name, typeArguments, argumentTypes, undefined, allowEntryPoint);
+    let overload = program.globalNameContext.resolveFuncOverload(name, argumentTypes, undefined, allowEntryPoint);
     if (!overload.func)
         return overload.failures;
-    if (!overload.func.typeParameters)
-        return overload.func;
-    let func = program.funcInstantiator.getUnique(overload.func, overload.typeArguments);
-    _inlineFunction(program, func, new VisitingSet(overload.func));
+
+    let func = overload.func;
+    _inlineFunction(program, func, new VisitingSet(func));
     return func;
 }
index 491ef3e..56c40df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,10 +35,10 @@ class Inliner extends Rewriter {
     visitCallExpression(node)
     {
         let result = super.visitCallExpression(node);
-        if (result.nativeFuncInstance)
+        if (result.func.isNative)
             return result;
-        return this._visiting.doVisit(node.func, () => {
-            let func = this._program.funcInstantiator.getUnique(result.func, result.actualTypeArguments);
+        return this._visiting.doVisit(result.func, () => {
+            let func = result.func;
             if (func.isNative)
                 throw new Error("Unexpected native func: " + func);
             _inlineFunction(this._program, func, this._visiting);
diff --git a/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js b/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js
deleted file mode 100644 (file)
index 2b39ed6..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class InstantiateImmediates extends Rewriter {
-    visitTypeRef(node)
-    {
-        node = super.visitTypeRef(node);
-        if (!node.type.instantiate) {
-            if (node.typeArguments.length)
-                throw new Error("type does not support instantiation: " + type + " (" + type.constructor.name + ")");
-            return node;
-        }
-        return node.type.instantiate(node.typeArguments).visit(new AutoWrapper());
-    }
-    
-    visitReferenceType(node)
-    {
-        return node;
-    }
-}
-
index 933dfe0..50d40c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,11 +31,11 @@ class Intrinsics {
 
         // NOTE: Intrinsic resolution happens before type name resolution, so the strings we use here
         // to catch the intrinsics must be based on the type names that StandardLibrary.js uses.
-        // For example, if a native function is declared using "int" rather than "int32", then we must
+        // For example, if a native function is declared using "int" rather than "int", then we must
         // use "int" here, since we don't yet know that they are the same type.
         
         this._map.set(
-            "native typedef void<>",
+            "native typedef void",
             type => {
                 this.void = type;
                 type.size = 0;
@@ -57,9 +57,9 @@ class Intrinsics {
         }
 
         this._map.set(
-            "native typedef int32<>",
+            "native typedef int",
             type => {
-                this.int32 = type;
+                this.int = type;
                 type.isPrimitive = true;
                 type.isInt = true;
                 type.isNumber = true;
@@ -82,9 +82,9 @@ class Intrinsics {
             });
 
         this._map.set(
-            "native typedef uint32<>",
+            "native typedef uint",
             type => {
-                this.uint32 = type;
+                this.uint = type;
                 type.isPrimitive = true;
                 type.isInt = true;
                 type.isNumber = true;
@@ -105,9 +105,9 @@ class Intrinsics {
             });
 
         this._map.set(
-            "native typedef uint8<>",
+            "native typedef uchar",
             type => {
-                this.uint8 = type;
+                this.uchar = type;
                 type.isInt = true;
                 type.isNumber = true;
                 type.isSigned = false;
@@ -127,7 +127,7 @@ class Intrinsics {
             });
 
         this._map.set(
-            "native typedef float32<>",
+            "native typedef float",
             type => {
                 this.float = type;
                 type.isPrimitive = true;
@@ -142,407 +142,401 @@ class Intrinsics {
             });
 
         this._map.set(
-            "native typedef bool<>",
+            "native typedef bool",
             type => {
                 this.bool = type;
                 type.isPrimitive = true;
                 type.size = 1;
                 type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false);
             });
+
+        for (let vectorType of VectorElementTypes) {
+            for (let vectorSize of VectorElementSizes)
+                this._map.set(`native typedef vector<${vectorType}, ${vectorSize}>`, type => {});
+        }
         
         this._map.set(
-            "native operator<> int32(uint32)",
+            "native operator int(uint)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
             });
         
         this._map.set(
-            "native operator<> int32(uint8)",
+            "native operator int(uchar)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
             });
         
         this._map.set(
-            "native operator<> int32(float)",
+            "native operator int(float)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
             });
         
         this._map.set(
-            "native operator<> uint32(int32)",
+            "native operator uint(int)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
             });
         
         this._map.set(
-            "native operator<> uint32(uint8)",
+            "native operator uint(uchar)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
             });
         
         this._map.set(
-            "native operator<> uint32(float)",
+            "native operator uint(float)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
             });
         
         this._map.set(
-            "native operator<> uint8(int32)",
+            "native operator uchar(int)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
             });
         
         this._map.set(
-            "native operator<> uint8(uint32)",
+            "native operator uchar(uint)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
             });
         
         this._map.set(
-            "native operator<> uint8(float)",
+            "native operator uchar(float)",
             func => {
                 func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
             });
         
         this._map.set(
-            "native operator<> float(int32)",
+            "native operator float(int)",
             func => {
                 func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
             });
         
         this._map.set(
-            "native operator<> float(uint32)",
+            "native operator float(uint)",
             func => {
                 func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
             });
         
         this._map.set(
-            "native operator<> float(uint8)",
+            "native operator float(uchar)",
             func => {
                 func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
             });
         
         this._map.set(
-            "native int operator+<>(int,int)",
+            "native int operator+(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() + right.loadValue()) | 0);
             });
         
         this._map.set(
-            "native uint operator+<>(uint,uint)",
+            "native uint operator+(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() + right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native float operator+<>(float,float)",
+            "native float operator+(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(Math.fround(left.loadValue() + right.loadValue()));
             });
         
         this._map.set(
-            "native int operator-<>(int,int)",
+            "native int operator-(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() - right.loadValue()) | 0);
             });
         
         this._map.set(
-            "native uint operator-<>(uint,uint)",
+            "native uint operator-(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() - right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native float operator-<>(float,float)",
+            "native float operator-(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(Math.fround(left.loadValue() - right.loadValue()));
             });
         
         this._map.set(
-            "native int operator*<>(int,int)",
+            "native int operator*(int,int)",
             func => {
-                func.implementation = ([left, right]) =>
-                    EPtr.box((left.loadValue() * right.loadValue()) | 0);
+                func.implementation = ([left, right]) => {
+                    return EPtr.box((left.loadValue() * right.loadValue()) | 0);
+                };
             });
         
         this._map.set(
-            "native uint operator*<>(uint,uint)",
+            "native uint operator*(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() * right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native float operator*<>(float,float)",
+            "native float operator*(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(Math.fround(left.loadValue() * right.loadValue()));
             });
         
         this._map.set(
-            "native int operator/<>(int,int)",
+            "native int operator/(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() / right.loadValue()) | 0);
             });
         
         this._map.set(
-            "native uint operator/<>(uint,uint)",
+            "native uint operator/(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() / right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native int operator&<>(int,int)",
+            "native int operator&(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() & right.loadValue());
             });
         
         this._map.set(
-            "native uint operator&<>(uint,uint)",
+            "native uint operator&(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() & right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native int operator|<>(int,int)",
+            "native int operator|(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() | right.loadValue());
             });
         
         this._map.set(
-            "native uint operator|<>(uint,uint)",
+            "native uint operator|(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() | right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native int operator^<>(int,int)",
+            "native int operator^(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() ^ right.loadValue());
             });
         
         this._map.set(
-            "native uint operator^<>(uint,uint)",
+            "native uint operator^(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native int operator<<<>(int,uint)",
+            "native int operator<<(int,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() << right.loadValue());
             });
         
         this._map.set(
-            "native uint operator<<<>(uint,uint)",
+            "native uint operator<<(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box((left.loadValue() << right.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native int operator>><>(int,uint)",
+            "native int operator>>(int,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() >> right.loadValue());
             });
         
         this._map.set(
-            "native uint operator>><>(uint,uint)",
+            "native uint operator>>(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() >>> right.loadValue());
             });
         
         this._map.set(
-            "native int operator~<>(int)",
+            "native int operator~(int)",
             func => {
                 func.implementation = ([value]) => EPtr.box(~value.loadValue());
             });
         
         this._map.set(
-            "native uint operator~<>(uint)",
+            "native uint operator~(uint)",
             func => {
                 func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0);
             });
         
         this._map.set(
-            "native float operator/<>(float,float)",
+            "native float operator/(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(Math.fround(left.loadValue() / right.loadValue()));
             });
         
         this._map.set(
-            "native bool operator==<>(int,int)",
+            "native bool operator==(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() == right.loadValue());
             });
         
         this._map.set(
-            "native bool operator==<>(uint,uint)",
+            "native bool operator==(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() == right.loadValue());
             });
         
         this._map.set(
-            "native bool operator==<>(bool,bool)",
+            "native bool operator==(bool,bool)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() == right.loadValue());
             });
         
         this._map.set(
-            "native bool operator==<>(float,float)",
+            "native bool operator==(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() == right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<<>(int,int)",
+            "native bool operator<(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() < right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<<>(uint,uint)",
+            "native bool operator<(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() < right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<<>(float,float)",
+            "native bool operator<(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() < right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<=<>(int,int)",
+            "native bool operator<=(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() <= right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<=<>(uint,uint)",
+            "native bool operator<=(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() <= right.loadValue());
             });
         
         this._map.set(
-            "native bool operator<=<>(float,float)",
+            "native bool operator<=(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() <= right.loadValue());
             });
         
         this._map.set(
-            "native bool operator><>(int,int)",
+            "native bool operator>(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() > right.loadValue());
             });
         
         this._map.set(
-            "native bool operator><>(uint,uint)",
+            "native bool operator>(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() > right.loadValue());
             });
         
         this._map.set(
-            "native bool operator><>(float,float)",
+            "native bool operator>(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() > right.loadValue());
             });
         
         this._map.set(
-            "native bool operator>=<>(int,int)",
+            "native bool operator>=(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() >= right.loadValue());
             });
         
         this._map.set(
-            "native bool operator>=<>(uint,uint)",
+            "native bool operator>=(uint,uint)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() >= right.loadValue());
             });
         
         this._map.set(
-            "native bool operator>=<>(float,float)",
+            "native bool operator>=(float,float)",
             func => {
                 func.implementation = ([left, right]) =>
                     EPtr.box(left.loadValue() >= right.loadValue());
             });
-        
-        for (let addressSpace of addressSpaces) {
-            this._map.set(
-                `native T* ${addressSpace} operator&[]<T>(T[] ${addressSpace},uint)`,
-                func => {
-                    func.implementation = ([ref, index], node) => {
-                        ref = ref.loadValue();
-                        if (!ref)
-                            throw new WTrapError(node.origin.originString, "Null dereference");
-                        index = index.loadValue();
-                        if (index > ref.length)
-                            throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref);
-                        return EPtr.box(ref.ptr.plus(index * node.instantiatedActualTypeArguments[0].size));
-                    };
-                });
 
-            this._map.set(
-                `native uint operator.length<T>(T[] ${addressSpace})`,
-                func => {
-                    func.implementation = ([ref], node) => {
-                        ref = ref.loadValue();
-                        if (!ref)
-                            return EPtr.box(0);
-                        return EPtr.box(ref.length);
-                    };
-                });
-        }
+        for (let nativeVectorTypeName of allVectorTypeNames())
+            this._map.set(`native typedef ${nativeVectorTypeName}`, type => {
+                type.isPrimitive = true;
+            });
 
-        for (let swizzle of SwizzleOp.allSwizzleOperators()) {
-            this._map.set(swizzle.toString(), 
-            func => {
-                func.implementation = ([vec], node) => {
-                    const outputBuffer = new EBuffer(swizzle.outSize);
-                    const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 };
-                    for (let i = 0; i < swizzle.outSize; i++)
-                        outputBuffer.set(i, vec.get(readIndices[swizzle.components[i]]));
-                    
-                    
-                    return new EPtr(outputBuffer, 0);
-                },
-                func.implementationData = swizzle;
-            });
-            console.log(swizzle.toString());
-        }
+        for (let swizzle of SwizzleOp.functions())
+            this._map.set(swizzle.toString(), func => swizzle.instantiateImplementation(func));
+
+        for (let boolOp of OperatorBool.functions())
+            this._map.set(boolOp.toString(), func => boolOp.instantiateImplementation(func));
+
+        for (let anderIndex of OperatorAnderIndexer.functions())
+            this._map.set(anderIndex.toString(), func => anderIndex.instantiateImplementation(func));
+
+        for (let cast of BuiltinVectorConstructors.functions())
+            this._map.set(cast.toString(), func => cast.instantiateImplementation(func));
+
+        for (let getter of BuiltinVectorIndexGetter.functions())
+            this._map.set(getter.toString(), func => getter.instantiateImplementation(func));
+
+        for (let setter of BuiltinVectorIndexSetter.functions())
+            this._map.set(setter.toString(), func => setter.instantiateImplementation(func));
+
+        for (let equalityOperator of BuiltinVectorEqualityOperator.functions())
+            this._map.set(equalityOperator.toString(), func => equalityOperator.instantiateImplementation(func));
+
+        for (let getter of BuiltinVectorGetter.functions())
+            this._map.set(getter.toString(), func => getter.instantiateImplementation(func));
+
+        for (let setter of BuiltinVectorSetter.functions())
+            this._map.set(setter.toString(), func => setter.instantiateImplementation(func));
     }
     
     add(thing)
index be2165d..956dca3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -122,7 +122,7 @@ class Lexer {
         
         // FIXME: Make this do Unicode.
         if (Lexer._textIsIdentifierImpl(relevantText)) {
-            if (/^(struct|protocol|typedef|if|else|enum|continue|break|switch|case|default|for|while|do|return|constant|device|threadgroup|thread|operator|null|true|false)$/.test(RegExp.lastMatch))
+            if (/^(struct|typedef|if|else|enum|continue|break|switch|case|default|for|while|do|return|constant|device|threadgroup|thread|operator|null|true|false)$/.test(RegExp.lastMatch))
                 return result("keyword");
             
             if (this._originKind == "native" && /^(native|restricted)$/.test(RegExp.lastMatch))
index 849d034..90e3417 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,6 +43,8 @@ class LiteralTypeChecker extends Visitor {
     {
         if (!node.type)
             throw new Error(node + " at " + node.origin.originString + " does not have type");
+        if (!node.type.type.canRepresent(node.value))
+            throw new Error(`${node.value} at ${node.origin.originString} cannot be represented by ${node.type}`);
     }
 }
 
index c31bc42..1bab3fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,7 +48,7 @@ class NameContext {
             return;
         if (!thing.origin)
             throw new Error("Thing does not have origin: " + thing);
-        
+
         if (thing.isNative && !thing.implementation) {
             if (!this._intrinsics)
                 throw new Error("Native function in a scope that does not recognize intrinsics");
@@ -68,8 +68,10 @@ class NameContext {
             array.push(thing);
             return;
         }
+
         if (this._map.has(thing.name))
             throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name);
+
         this._set.add(thing);
         this._map.set(thing.name, thing);
     }
@@ -104,13 +106,13 @@ class NameContext {
         yield thing;
     }
     
-    resolveFuncOverload(name, typeArguments, argumentTypes, returnType, allowEntryPoint = false)
+    resolveFuncOverload(name, argumentTypes, returnType, allowEntryPoint = false)
     {
         let functions = this.get(Func, name);
         if (!functions)
             return {failures: []};
         
-        return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType, allowEntryPoint);
+        return resolveOverloadImpl(functions, argumentTypes, returnType, allowEntryPoint);
     }
     
     get currentStatement()
index fc2fdbd..50603d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,12 +43,6 @@ class NameFinder extends Visitor {
         this._worklist.push(name);
     }
     
-    visitProtocolRef(node)
-    {
-        this.add(node.name);
-        super.visitProtocolRef(node);
-    }
-    
     visitTypeRef(node)
     {
         this.add(node.name);
@@ -60,11 +54,6 @@ class NameFinder extends Visitor {
         this.add(node.name);
         super.visitVariableRef(node);
     }
-    
-    visitTypeOrVariableRef(node)
-    {
-        this.add(node.name);
-    }
 
     _handlePropertyAccess(node)
     {
index 731964f..a2af1d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,19 +41,9 @@ class NameResolver extends Visitor {
         this._nameContext.doStatement(statement, () => statement.visit(this));
     }
     
-    _visitTypeParametersAndBuildNameContext(node)
-    {
-        let nameContext = new NameContext(this._nameContext);
-        for (let typeParameter of node.typeParameters) {
-            nameContext.add(typeParameter);
-            typeParameter.visit(this);
-        }
-        return nameContext;
-    }
-    
     visitFunc(node)
     {
-        let checker = new NameResolver(this._visitTypeParametersAndBuildNameContext(node));
+        let checker = new NameResolver(new NameContext(this._nameContext));
         node.returnType.visit(checker);
         for (let parameter of node.parameters)
             parameter.visit(checker);
@@ -61,16 +51,14 @@ class NameResolver extends Visitor {
     
     visitFuncDef(node)
     {
-        let contextWithTypeParameters = this._visitTypeParametersAndBuildNameContext(node);
-        let checkerWithTypeParameters = new NameResolver(contextWithTypeParameters);
-        node.returnType.visit(checkerWithTypeParameters);
-        let contextWithParameters = new NameContext(contextWithTypeParameters);
+        let funcDefNameContext = new NameContext(this._nameContext);
+        let funcDefNameResolver = new NameResolver(funcDefNameContext);
+        node.returnType.visit(funcDefNameResolver);
         for (let parameter of node.parameters) {
-            parameter.visit(checkerWithTypeParameters);
-            contextWithParameters.add(parameter);
+            parameter.visit(funcDefNameResolver);
+            funcDefNameContext.add(parameter);
         }
-        let checkerWithParameters = new NameResolver(contextWithParameters);
-        node.body.visit(checkerWithParameters);
+        node.body.visit(funcDefNameResolver);
     }
     
     visitBlock(node)
@@ -115,41 +103,9 @@ class NameResolver extends Visitor {
         node.body.visit(newResolver);
     }
     
-    visitProtocolDecl(node)
-    {
-        for (let parent of node.extends)
-            parent.visit(this);
-        let nameContext = new NameContext(this._nameContext);
-        nameContext.add(node.typeVariable);
-        let checker = new NameResolver(nameContext);
-        for (let signature of node.signatures)
-            signature.visit(checker);
-    }
-    
-    visitProtocolRef(node)
-    {
-        let result = this._nameContext.get(Protocol, node.name);
-        if (!result)
-            throw new WTypeError(node.origin.originString, "Could not find protocol named " + node.name);
-        node.protocolDecl = result;
-    }
-    
-    visitProtocolFuncDecl(node)
-    {
-        this.visitFunc(node);
-        let funcs = this._nameContext.get(Func, node.name);
-        if (!funcs)
-            throw new WTypeError(node.origin.originString, "Cannot find any functions named " + node.name);
-        node.possibleOverloads = funcs;
-    }
-    
     visitTypeDef(node)
     {
         let nameContext = new NameContext(this._nameContext);
-        for (let typeParameter of node.typeParameters) {
-            typeParameter.visit(this);
-            nameContext.add(typeParameter);
-        }
         let checker = new NameResolver(nameContext);
         node.type.visit(checker);
     }
@@ -157,41 +113,13 @@ class NameResolver extends Visitor {
     visitStructType(node)
     {
         let nameContext = new NameContext(this._nameContext);
-        for (let typeParameter of node.typeParameters) {
-            typeParameter.visit(this);
-            nameContext.add(typeParameter);
-        }
         let checker = new NameResolver(nameContext);
         for (let field of node.fields)
             field.visit(checker);
     }
     
-    _resolveTypeArguments(typeArguments)
-    {
-        for (let i = 0; i < typeArguments.length; ++i) {
-            let typeArgument = typeArguments[i];
-            if (typeArgument instanceof TypeOrVariableRef) {
-                let thing = this._nameContext.get(Anything, typeArgument.name);
-                if (!thing)
-                    new WTypeError(typeArgument.origin.originString, "Could not find type or variable named " + typeArgument.name);
-                if (thing instanceof Value)
-                    typeArguments[i] = new VariableRef(typeArgument.origin, typeArgument.name);
-                else if (thing instanceof Type)
-                    typeArguments[i] = new TypeRef(typeArgument.origin, typeArgument.name, []);
-                else
-                    throw new WTypeError(typeArgument.origin.originString, "Type argument resolved to wrong kind of thing: " + thing.kind);
-            }
-            
-            if (typeArgument[i] instanceof Value
-                && !typeArgument[i].isConstexpr)
-                throw new WTypeError(typeArgument[i].origin.originString, "Expected constexpr");
-        }
-    }
-    
     visitTypeRef(node)
     {
-        this._resolveTypeArguments(node.typeArguments);
-        
         let type = node.type;
         if (!type) {
             type = this._nameContext.get(Type, node.name);
@@ -199,18 +127,6 @@ class NameResolver extends Visitor {
                 throw new WTypeError(node.origin.originString, "Could not find type named " + node.name);
             node.type = type;
         }
-        
-        if (type.typeParameters.length != node.typeArguments.length)
-            throw new WTypeError(node.origin.originString, "Wrong number of type arguments (passed " + node.typeArguments.length + ", expected " + type.typeParameters.length + ")");
-        for (let i = 0; i < type.typeParameters.length; ++i) {
-            let parameterIsType = type.typeParameters[i] instanceof TypeVariable;
-            let argumentIsType = node.typeArguments[i] instanceof Type;
-            node.typeArguments[i].visit(this);
-            if (parameterIsType && !argumentIsType)
-                throw new WTypeError(node.origin.originString, "Expected type, but got value at argument #" + i);
-            if (!parameterIsType && argumentIsType)
-                throw new WTypeError(node.origin.originString, "Expected value, but got type at argument #" + i);
-        }
     }
     
     visitReferenceType(node)
@@ -279,8 +195,6 @@ class NameResolver extends Visitor {
     
     visitCallExpression(node)
     {
-        this._resolveTypeArguments(node.typeArguments);
-        
         let funcs = this._nameContext.get(Func, node.name);
         if (funcs)
             node.possibleOverloads = funcs;
@@ -296,5 +210,9 @@ class NameResolver extends Visitor {
         
         super.visitCallExpression(node);
     }
-}
 
+    visitVectorType(node)
+    {
+        node.elementType.visit(this);
+    }
+}
index a553352..997bd48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 "use strict";
 
 class NativeFunc extends Func {
-    constructor(origin, name, returnType, typeParameters, parameters, isCast, shaderType)
+    constructor(origin, name, returnType, parameters, isCast, shaderType)
     {
-        super(origin, name, returnType, typeParameters, parameters, isCast, shaderType);
+        super(origin, name, returnType, parameters, isCast, shaderType);
         this.isRestricted = false;
         this.implementation = null;
         this._implementationData = null;
         this.instantiateImplementation = (substitution) => {};
         this.visitImplementationData = (implementationData, visitor) => null;
-        this.didLayoutStructsInImplementationData = implementationData => null;
     }
 
     get isNative() { return true; }
diff --git a/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js b/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js
deleted file mode 100644 (file)
index c99b782..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class NativeFuncInstance extends Func {
-    constructor(func, returnType, parameters, isCast, shaderType, implementationData)
-    {
-        super(func.origin, func.name, returnType, [], parameters, isCast, shaderType);
-        this._func = func;
-        this._implementationData = implementationData;
-    }
-    
-    get func() { return this._func; }
-    get isNative() { return true; }
-    get implementationData() { return this._implementationData; }
-
-    toDeclString()
-    {
-        return "native " + super.toDeclString();
-    }
-}
-
index b8b1a47..e2d851c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 "use strict";
 
 class NativeType extends Type {
-    constructor(origin, name, typeParameters)
+    constructor(origin, name)
     {
-        if (!(typeParameters instanceof Array))
-            throw new Error("type parameters not array: " + typeParameters);
         super();
         this._origin = origin;
         this._name = name;
-        this._typeParameters = typeParameters;
         this._isNumber = false;
         this._isInt = false;
         this._isFloating = false;
@@ -41,7 +38,6 @@ class NativeType extends Type {
     
     get origin() { return this._origin; }
     get name() { return this._name; }
-    get typeParameters() { return this._typeParameters; }
     get isNative() { return true; }
     
     // We let Intrinsics.js set these as it likes.
@@ -54,18 +50,21 @@ class NativeType extends Type {
     get isPrimitive() { return this._isPrimitive; }
     set isPrimitive(value) { this._isPrimitive = value; }
     
-    instantiate(typeArguments)
+    toString()
     {
-        if (typeArguments.length != this.typeParameters.length)
-            throw new Error("Wrong number of type arguments to instantiation");
-        if (!typeArguments.length)
-            return this;
-        return new NativeTypeInstance(this, typeArguments);
+        return `native typedef ${this.name}`;
     }
     
-    toString()
+    static create(origin, name, typeArguments)
     {
-        return "native typedef " + this.name + "<" + this.typeParameters + ">";
+        // FIXME: For native types like Texture1D this should resolve the type to something concrete by changing the type name.
+        if (typeArguments.length)
+            throw new WTypeError(origin.originString, `${name}<${typeArguments.join(",")}>: Support for native types with type arguments is currently unimplemented.`);
+
+        if (allVectorTypeNames().indexOf(name) > -1)
+            return new VectorType(origin, name);
+
+        return new NativeType(origin, name);
     }
 }
 
index 8810301..c4ba48c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -118,16 +118,4 @@ class Node {
         unificationContext.commit();
         return unificationContext.find(this);
     }
-    
-    substitute(parameters, argumentList)
-    {
-        return this.visit(new Substitution(parameters, argumentList));
-    }
-    
-    substituteToUnification(parameters, unificationContext)
-    {
-        return this.substitute(
-            parameters,
-            parameters.map(type => unificationContext.find(type)));
-    }
 }
diff --git a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js
new file mode 100644 (file)
index 0000000..670371f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class OperatorAnderIndexer {
+    constructor(baseTypeName, addressSpace)
+    {
+        this._baseTypeName = baseTypeName;
+        this._addressSpace = addressSpace;
+    }
+
+    get addressSpace() { return this._addressSpace; }
+    get baseTypeName() { return this._baseTypeName; }
+
+    toString()
+    {
+        return `native ${this.baseTypeName}* ${this.addressSpace} operator&[](${this.baseTypeName}[] ${this.addressSpace},uint)`;
+    }
+
+    static functions()
+    {
+        if (!this._functions) {
+            this._functions = [];
+
+            const typeNames = [ "uint", "int", "float", "bool" ].concat(allVectorTypeNames());
+            const addressSpaces = [ "thread", "threadgroup", "device", "constant" ];
+
+            for (let addressSpace of addressSpaces) {
+                for (let typeName of typeNames)
+                    this._functions.push(new OperatorAnderIndexer(typeName, addressSpace));
+            }
+        }
+        return this._functions;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([ref, index], node) => {
+            ref = ref.loadValue();
+            if (!ref)
+                throw new WTrapError(node.origin.originString, "Null dereference");
+            index = index.loadValue();
+            if (index > ref.length)
+                throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref);
+            return EPtr.box(ref.ptr.plus(index * node.argumentTypes[0].elementType.size));
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-class TypeOrVariableRef extends Node {
-    constructor(origin, name)
+class OperatorArrayRefLength {
+    constructor(baseTypeName, addressSpace)
     {
-        super();
-        this._origin = origin;
-        this._name = name;
+        this._baseTypeName = baseTypeName;
+        this._addressSpace = addressSpace;
     }
-    
-    get origin() { return this._origin; }
-    get name() { return this._name; }
+
+    get addressSpace() { return this._addressSpace; }
+    get baseTypeName() { return this._baseTypeName; }
 
     toString()
     {
-        return this.name;
+        return `native uint ${this.addressSpace} operator.length(${this.baseTypeName}[] ${this.addressSpace})`;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([ref], node) => {
+            ref = ref.loadValue();
+            if (!ref)
+                return EPtr.box(0);
+            return EPtr.box(ref.length);
+        };
+        func.implementationData = this;
     }
-}
+}
\ No newline at end of file
diff --git a/Tools/WebGPUShadingLanguageRI/OperatorBool.js b/Tools/WebGPUShadingLanguageRI/OperatorBool.js
new file mode 100644 (file)
index 0000000..58bb0e0
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+class OperatorBool {
+    constructor(baseTypeName)
+    {
+        this._baseTypeName = baseTypeName;
+    }
+
+    get baseTypeName() { return this._baseTypeName; }
+
+    toString()
+    {
+        return `native operator bool(${this.baseTypeName})`;
+    }
+
+    static functions()
+    {
+        // FIXME: These operators should be in the standard library where possible.
+        if (!OperatorBool._functions) {
+            OperatorBool._functions = [];
+
+            // bool is not included because this is generated by the copy constructor.
+            // FIXME: Include all native types.
+            const typeNames = [ "uchar", "uint", "int", "float" ].concat(allVectorTypeNames());
+
+            for (let typeName of typeNames)
+                OperatorBool._functions.push(new OperatorBool(typeName));
+        }
+        return OperatorBool._functions;
+    }
+
+    instantiateImplementation(func)
+    {
+        func.implementation = ([ref], node) => {
+            const size = node.argumentTypes[0].size;
+            for (let i = 0; i < size; ++i) {
+                if (!!ref.get(i))
+                    return EPtr.box(true);
+            }
+            return EPtr.box(false);
+        }
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
index 6d2b431..c4ae9de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -121,12 +121,6 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         return result;
     }
     
-    function parseProtocolRef()
-    {
-        let protocolToken = consumeKind("identifier");
-        return new ProtocolRef(protocolToken, protocolToken.text);
-    }
-    
     function consumeEndOfTypeArgs()
     {
         let rightShift = tryConsume(">>");
@@ -136,34 +130,6 @@ function parse(program, origin, originKind, lineNumberOffset, text)
             consume(">");
     }
     
-    function parseTypeParameters()
-    {
-        if (!test("<"))
-            return [];
-        
-        let result = [];
-        consume("<");
-        while (!test(">")) {
-            let constexpr = lexer.backtrackingScope(() => {
-                let type = parseType();
-                let name = consumeKind("identifier");
-                assertNext(",", ">", ">>");
-                return new ConstexprTypeParameter(type.origin, name.text, type);
-            });
-            if (constexpr)
-                result.push(constexpr);
-            else {
-                let name = consumeKind("identifier");
-                let protocol = tryConsume(":") ? parseProtocolRef() : null;
-                result.push(new TypeVariable(name, name.text, protocol));
-            }
-            if (!tryConsume(","))
-                break;
-        }
-        consumeEndOfTypeArgs();
-        return result;
-    }
-    
     function parseTerm()
     {
         let token;
@@ -233,7 +199,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         if (!test("<"))
             return [];
-        
+
         let result = [];
         consume("<");
         while (!test(">")) {
@@ -248,13 +214,13 @@ function parse(program, origin, originKind, lineNumberOffset, text)
             // In the future we'll allow constexprs to do more things, and then we'll still have
             // the problem that something of the form T[1][2][3]... can either be a type or a
             // constexpr, and we can figure out in the checker which it is.
-            let typeOrVariableRef = lexer.backtrackingScope(() => {
+            let typeRef = lexer.backtrackingScope(() => {
                 let result = consumeKind("identifier");
                 assertNext(",", ">", ">>");
-                return new TypeOrVariableRef(result, result.text);
+                return new TypeRef(result, result.text);
             });
-            if (typeOrVariableRef)
-                result.push(typeOrVariableRef);
+            if (typeRef)
+                result.push(typeRef);
             else {
                 let constexpr = lexer.backtrackingScope(() => {
                     let result = parseConstexpr();
@@ -318,11 +284,10 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         let origin = consume("typedef");
         let name = consumeKind("identifier").text;
-        let typeParameters = parseTypeParameters();
         consume("=");
-        let type = parseType();
+        let type = parseType(true);
         consume(";");
-        return new TypeDef(origin, name, typeParameters, type);
+        return new TypeDef(origin, name, type);
     }
     
     function genericParseLeft(texts, nextParser, constructor)
@@ -547,7 +512,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let operator = tryConsume("=", "+=", "-=", "*=", "/=", "%=", "^=", "|=", "&=");
         if (!operator) {
             if (mode == "required")
-                lexer.fail("Expected assignment");
+                lexer.fail("Expected assignment: " + lexer._text.substring(lexer._index));
             return lhs;
         }
         if (operator.text == "=")
@@ -858,13 +823,11 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let origin;
         let returnType;
         let name;
-        let typeParameters;
         let isCast;
         let shaderType;
         let operatorToken = tryConsume("operator");
         if (operatorToken) {
             origin = operatorToken;
-            typeParameters = parseTypeParameters();
             returnType = parseType();
             name = "operator cast";
             isCast = true;
@@ -877,44 +840,17 @@ function parse(program, origin, originKind, lineNumberOffset, text)
             } else
                 origin = returnType.origin;
             name = parseFuncName();
-            typeParameters = parseTypeParameters();
             isCast = false;
         }
         let parameters = parseParameters();
-        return new Func(origin, name, returnType, typeParameters, parameters, isCast, shaderType);
-    }
-
-    function parseProtocolFuncDecl()
-    {
-        let func = parseFuncDecl();
-        return new ProtocolFuncDecl(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast, func.shaderType);
+        return new Func(origin, name, returnType, parameters, isCast, shaderType);
     }
     
     function parseFuncDef()
     {
         let func = parseFuncDecl();
         let body = parseBlock();
-        return new FuncDef(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, body, func.isCast, func.shaderType);
-    }
-    
-    function parseProtocolDecl()
-    {
-        let origin = consume("protocol");
-        let name = consumeKind("identifier").text;
-        let result = new ProtocolDecl(origin, name);
-        if (tryConsume(":")) {
-            while (!test("{")) {
-                result.addExtends(parseProtocolRef());
-                if (!tryConsume(","))
-                    break;
-            }
-        }
-        consume("{");
-        while (!tryConsume("}")) {
-            result.add(parseProtocolFuncDecl());
-            consume(";");
-        }
-        return result;
+        return new FuncDef(func.origin, func.name, func.returnType, func.parameters, body, func.isCast, func.shaderType);
     }
     
     function parseField()
@@ -929,8 +865,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         let origin = consume("struct");
         let name = consumeKind("identifier").text;
-        let typeParameters = parseTypeParameters();
-        let result = new StructType(origin, name, typeParameters);
+        let result = new StructType(origin, name);
         consume("{");
         while (!tryConsume("}"))
             result.add(parseField());
@@ -941,7 +876,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         let func = parseFuncDecl();
         consume(";");
-        return new NativeFunc(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast, func.shaderType);
+        return new NativeFunc(func.origin, func.name, func.returnType, func.parameters, func.isCast, func.shaderType);
     }
     
     function parseNative()
@@ -949,9 +884,9 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let origin = consume("native");
         if (tryConsume("typedef")) {
             let name = consumeKind("identifier");
-            let parameters = parseTypeParameters();
+            let args = parseTypeArguments();
             consume(";");
-            return new NativeType(origin, name.text, parameters);
+            return NativeType.create(origin, name.text, args);
         }
         return parseNativeFunc();
     }
@@ -985,7 +920,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         if (tryConsume(":"))
             baseType = parseType();
         else
-            baseType = new TypeRef(name, "int", []);
+            baseType = new TypeRef(name, "int");
         consume("{");
         let result = new EnumType(name, name.text, baseType);
         while (!test("}")) {
@@ -1013,8 +948,6 @@ function parse(program, origin, originKind, lineNumberOffset, text)
             program.add(parseStructType());
         else if (token.text == "enum")
             program.add(parseEnumType());
-        else if (token.text == "protocol")
-            program.add(parseProtocolDecl());
         else
             program.add(parseFuncDef());
     }
index a2048a9..7b16139 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,18 +40,21 @@ let prepare = (() => {
         }
         
         foldConstexprs(program);
+        removeTypeArguments(program);
+
         let nameResolver = createNameResolver(program);
         resolveNamesInTypes(program, nameResolver);
-        resolveNamesInProtocols(program, nameResolver);
         resolveTypeDefsInTypes(program);
-        resolveTypeDefsInProtocols(program);
         checkRecursiveTypes(program);
         synthesizeStructAccessors(program);
+        synthesizeOperatorBool(program);
         synthesizeEnumFunctions(program);
+        synthesizeArrayOperatorLength(program);
+        synthesizeCopyConstructorOperator(program);
+        synthesizeDefaultConstructorOperator(program);
         resolveNamesInFunctions(program, nameResolver);
         resolveTypeDefsInFunctions(program);
         
-        flattenProtocolExtends(program);
         check(program);
         checkLiteralTypes(program);
         resolveProperties(program);
@@ -64,6 +67,7 @@ let prepare = (() => {
         checkRecursion(program);
         checkProgramWrapped(program);
         findHighZombies(program);
+        program.visit(new StructLayoutBuilder());
         inline(program);
         
         return program;
index bbc4b24..06625d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,8 +31,6 @@ class Program extends Node {
         this._topLevelStatements = [];
         this._functions = new Map();
         this._types = new Map();
-        this._protocols = new Map();
-        this._funcInstantiator = new FuncInstantiator(this);
         this._globalNameContext = new NameContext();
         this._globalNameContext.program = this;
         this._globalNameContext.recognizeIntrinsics();
@@ -42,8 +40,6 @@ class Program extends Node {
     get topLevelStatements() { return this._topLevelStatements; }
     get functions() { return this._functions; }
     get types() { return this._types; }
-    get protocols() { return this._protocols; }
-    get funcInstantiator() { return this._funcInstantiator; }
     get globalNameContext() { return this._globalNameContext; }
     
     add(statement)
@@ -56,8 +52,6 @@ class Program extends Node {
             array.push(statement);
         } else if (statement instanceof Type)
             this._types.set(statement.name, statement);
-        else if (statement instanceof Protocol)
-            this._protocols.set(statement.name, statement);
         else
             throw new Error("Statement is not a function or type: " + statement);
         this._topLevelStatements.push(statement);
diff --git a/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js b/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js
deleted file mode 100644 (file)
index b50bcfc..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class ProtocolDecl extends Protocol {
-    constructor(origin, name)
-    {
-        super(origin, name);
-        this.extends = [];
-        this._signatures = [];
-        this._signatureMap = new Map();
-        this._typeVariable = new TypeVariable(origin, name, null);
-    }
-    
-    addExtends(protocol)
-    {
-        this.extends.push(protocol);
-    }
-    
-    add(signature)
-    {
-        if (!(signature instanceof ProtocolFuncDecl))
-            throw new Error("Signature isn't a ProtocolFuncDecl but a " + signature.constructor.name);
-        
-        signature.protocolDecl = this;
-        this._signatures.push(signature);
-        let overloads = this._signatureMap.get(signature.name);
-        if (!overloads)
-            this._signatureMap.set(signature.name, overloads = []);
-        overloads.push(signature);
-    }
-    
-    get signatures() { return this._signatures; }
-    signaturesByName(name) { return this._signatureMap.get(name); }
-    get typeVariable() { return this._typeVariable; }
-    
-    signaturesByNameWithTypeVariable(name, typeVariable)
-    {
-        let substitution = new Substitution([this.typeVariable], [typeVariable]);
-        let result = this.signaturesByName(name);
-        if (!result)
-            return null;
-        return result.map(signature => signature.visit(substitution));
-    }
-    
-    inherits(otherProtocol)
-    {
-        if (!otherProtocol)
-            return {result: true};
-        
-        if (otherProtocol instanceof ProtocolRef)
-            otherProtocol = otherProtocol.protocolDecl;
-        
-        for (let otherSignature of otherProtocol.signatures) {
-            let signatures = this.signaturesByName(otherSignature.name);
-            if (!signatures)
-                return {result: false, reason: "Protocol " + this.name + " does not have a function named " + otherSignature.name + " (looking at signature " + otherSignature + ")"};
-            let overload = resolveOverloadImpl(
-                signatures, [],
-                otherSignature.parameterTypes,
-                otherSignature.returnTypeForOverloadResolution);
-            if (!overload.func)
-                return {result: false, reason: "Did not find matching signature for " + otherSignature + " in " + this.name + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")};
-            let substitutedReturnType =
-                overload.func.returnType.substituteToUnification(
-                    overload.func.typeParameters, overload.unificationContext);
-            if (!substitutedReturnType.equals(otherSignature.returnType))
-                return {result: false, reason: "Return type mismatch between " + otherSignature.returnType + " and " + substitutedReturnType};
-        }
-        return {result: true};
-    }
-    
-    hasHeir(type)
-    {
-        let substitution = new Substitution([this._typeVariable], [type]);
-        let signatures = this.signatures;
-        for (let originalSignature of signatures) {
-            let signature = originalSignature.visit(substitution);
-            let overload = resolveOverloadImpl(signature.possibleOverloads, signature.typeParameters, signature.parameterTypes, signature.returnTypeForOverloadResolution);
-            if (!overload.func)
-                return {result: false, reason: "Did not find matching signature for " + originalSignature + " (at " + originalSignature.origin.originString + ") with type " + type + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")};
-            
-            let substitutedReturnType = overload.func.returnType.substituteToUnification(
-                overload.func.typeParameters, overload.unificationContext);
-            if (!substitutedReturnType.equals(signature.returnType))
-                return {result: false, reason: "At signature " + originalSignature + " (at " + originalSignature.origin.originString + "): return type mismatch between " + signature.returnType + " and " + substitutedReturnType + " in found function " + overload.func.toDeclString()};
-        }
-        return {result: true};
-    }
-    
-    toString()
-    {
-        return "protocol " + this.name + " { " + this.signatures.join("; ") + "; }";
-    }
-}
-
-
diff --git a/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js b/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js
deleted file mode 100644 (file)
index 89b5c9b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class ProtocolFuncDecl extends Func {
-    get typeParametersForCallResolution()
-    {
-        return this.typeParameters.concat(this.protocolDecl.typeVariable);
-    }
-}
-
diff --git a/Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js b/Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js
new file mode 100644 (file)
index 0000000..7f90870
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function removeTypeArguments(program)
+{
+    class RemoveTypeArguments extends Visitor {
+        static resolveNameAndArguments(node)
+        {
+            if (!node.typeArguments)
+                return node.name;
+
+            switch (node.name) {
+            case "vector":
+                if (node.typeArguments.length != 2)
+                    throw new WSyntaxError(node.originString, `${node.name} should have 2 type arguments, got ${node.typeArguments.length}.`);
+
+                const elementTypeName = node.typeArguments[0].name;
+                const lengthValue = node.typeArguments[1].value;
+
+                if (VectorElementTypes.indexOf(elementTypeName) < 0)
+                    throw new WSyntaxError(node.originString, `${elementTypeName} is not a valid vector element type.`);
+                if (VectorElementSizes.indexOf(lengthValue) < 0)
+                    throw new WSyntaxError(node.originString, `${lengthValue} is not a valid size for vectors with element type ${elementTypeName}.`);
+
+                return `${elementTypeName}${lengthValue}`;
+            // FIXME: Further cases for matrices, textures, etc.
+            default:
+                if (node.typeArguments.length)
+                    throw new WSyntaxError(`${node.name}${arguments.join(", ")} is not a permitted generic type or function`);
+                return node.name;
+            }
+        }
+
+        visitTypeRef(node)
+        {
+            node._name = RemoveTypeArguments.resolveNameAndArguments(node);
+            node._typeArguments = null;
+        }
+
+        visitCallExpression(node)
+        {
+            node._name = RemoveTypeArguments.resolveNameAndArguments(node);
+            if (!node._name || !node._name.length)
+                throw new Error("lazy");
+            node._typeArguments = null;
+        }
+    }
+
+    program.visit(new RemoveTypeArguments());
+}
\ No newline at end of file
index 1922e8e..2e402c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,12 +35,6 @@ function resolveNamesInTypes(program, nameResolver)
         nameResolver.doStatement(type);
 }
 
-function resolveNamesInProtocols(program, nameResolver)
-{
-    for (let protocol of program.protocols.values())
-        nameResolver.doStatement(protocol);
-}
-
 function resolveNamesInFunctions(program, nameResolver)
 {
     for (let funcs of program.functions.values()) {
index 7e22156..d0f1e34 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,7 +24,7 @@
  */
 "use strict";
 
-function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType, allowEntryPoint = false)
+function resolveOverloadImpl(functions, argumentTypes, returnType, allowEntryPoint = false)
 {
     if (!functions)
         throw new Error("Null functions; that should have been caught by the caller.");
@@ -36,7 +36,7 @@ function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType
             failures.push(new OverloadResolutionFailure(func, "Function is a " + func.shaderType + " shader, so it cannot be called from within an existing shader."))
             continue;
         }
-        let overload = inferTypesForCall(func, typeArguments, argumentTypes, returnType);
+        let overload = inferTypesForCall(func, argumentTypes, returnType);
         if (overload.failure)
             failures.push(overload.failure);
         else
@@ -74,7 +74,6 @@ function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType
             let parameterFunc = successes[j].func;
             let overload = inferTypesForCall(
                 parameterFunc,
-                typeArguments.length ? argumentFunc.typeParameters : [],
                 argumentFunc.parameterTypes,
                 argumentFunc.returnTypeForOverloadResolution);
             if (!overload.func) {
index 3bd2a4d..9143f8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,13 +31,6 @@ function resolveTypeDefsInTypes(program)
         type.visit(resolver);
 }
 
-function resolveTypeDefsInProtocols(program)
-{
-    let resolver = new TypeDefResolver();
-    for (let protocol of program.protocols.values())
-        protocol.visit(resolver);
-}
-
 function resolveTypeDefsInFunctions(program)
 {
     let resolver = new TypeDefResolver();
index f40d6b8..b56cd60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,40 +53,10 @@ class Rewriter {
     // that.
     visitFuncDef(node) { return node; }
     visitNativeFunc(node) { return node; }
-    visitNativeFuncInstance(node) { return node; }
     visitNativeType(node) { return node; }
     visitTypeDef(node) { return node; }
     visitStructType(node) { return node; }
-    visitConstexprTypeParameter(node) { return node; }
-    visitProtocolDecl(node) { return node; }
     visitEnumType(node) { return node; }
-
-    // This is almost wrong. We instantiate Func in Substitution in ProtocolDecl. Then, we end up
-    // not rewriting type variables. I think that just works because not rewriting them there is OK.
-    // Everywhere else, it's mandatory that we don't rewrite these because we always assume that
-    // type variables are outside the scope of rewriting.
-    visitTypeVariable(node) { return node; }
-
-    visitProtocolFuncDecl(node)
-    {
-        let result = new ProtocolFuncDecl(
-            node.origin, node.name,
-            node.returnType.visit(this),
-            node.typeParameters.map(parameter => parameter.visit(this)),
-            node.parameters.map(parameter => parameter.visit(this)),
-            node.isCast,
-            node.shaderType);
-        result.protocolDecl = node.protocolDecl;
-        result.possibleOverloads = node.possibleOverloads;
-        return result;
-    }
-    
-    visitNativeTypeInstance(node)
-    {
-        return new NativeTypeInstance(
-            node.type.visit(this),
-            node.typeArguments.map(argument => argument.visit(this)));
-    }
     
     visitFuncParameter(node)
     {
@@ -125,15 +95,11 @@ class Rewriter {
         }));
     }
     
-    visitProtocolRef(node)
-    {
-        return node;
-    }
-    
     visitTypeRef(node)
     {
-        let result = new TypeRef(node.origin, node.name, node.typeArguments.map(typeArgument => typeArgument.visit(this)));
-        result.type = Node.visit(node.type, this);
+        let result = new TypeRef(node.origin, node.name);
+        if (node.type)
+            result.type = Node.visit(node.type, this);
         return result;
     }
     
@@ -317,19 +283,10 @@ class Rewriter {
 
     processDerivedCallData(node, result)
     {
-        let handleTypeArguments = actualTypeArguments => {
-            if (actualTypeArguments)
-                return actualTypeArguments.map(actualTypeArgument => actualTypeArgument.visit(this));
-            else
-                return null;
-        }
-        result.actualTypeArguments = handleTypeArguments(node.actualTypeArguments);
-        result.instantiatedActualTypeArguments = handleTypeArguments(node.instantiatedActualTypeArguments);
         let argumentTypes = node.argumentTypes;
         if (argumentTypes)
             result.argumentTypes = argumentTypes.map(argumentType => argumentType.visit(this));
         result.func = node.func;
-        result.nativeFuncInstance = node.nativeFuncInstance;
         result.possibleOverloads = node.possibleOverloads;
         if (node.isCast)
             result.setCastData(node.returnType.visit(this));
@@ -341,8 +298,7 @@ class Rewriter {
     visitCallExpression(node)
     {
         let result = new CallExpression(
-            node.origin, node.name,
-            node.typeArguments.map(typeArgument => typeArgument.visit(this)),
+            node.origin, node.name, null,
             node.argumentList.map(argument => Node.visit(argument, this)));
         return this.processDerivedCallData(node, result);
     }
@@ -412,7 +368,7 @@ class Rewriter {
     
     visitAnonymousVariable(node)
     {
-        let result = new AnonymousVariable(node.origin, node.type.visit(this));
+        let result = new AnonymousVariable(node.origin, Node.visit(node.type, this));
         result._index = node._index;
         this._mapNode(node, result);
         result.ePtr = node.ePtr;
@@ -423,5 +379,12 @@ class Rewriter {
     {
         return new IdentityExpression(node.target.visit(this));
     }
+
+    visitVectorType(node)
+    {
+        const vecType = new VectorType(node.origin, node.name);
+        vecType._elementType = node.elementType.visit(this);
+        return vecType;
+    }
 }
 
index 93f6b9b..c7b3940 100644 (file)
@@ -18,6 +18,7 @@ td {
     <script src="CreateLiteralType.js"></script>
     <script src="PropertyAccessExpression.js"></script>
     <script src="SwizzleOp.js"></script>
+    <script src="NativeType.js"></script>
 
     <script src="AddressSpace.js"></script>
     <script src="AnonymousVariable.js"></script>
@@ -28,6 +29,12 @@ td {
     <script src="Block.js"></script>
     <script src="BoolLiteral.js"></script>
     <script src="Break.js"></script>
+    <script src="BuiltinVectorConstructors.js"></script>
+    <script src="BuiltinVectorGetter.js"></script>
+    <script src="BuiltinVectorSetter.js"></script>
+    <script src="BuiltinVectorIndexGetter.js"></script>
+    <script src="BuiltinVectorIndexSetter.js"></script>
+    <script src="BuiltinVectorEqualityOperator.js"></script>
     <script src="CallExpression.js"></script>
     <script src="CallFunction.js"></script>
     <script src="Check.js"></script>
@@ -42,7 +49,6 @@ td {
     <script src="CloneProgram.js"></script>
     <script src="CommaExpression.js"></script>
     <script src="ConstexprFolder.js"></script>
-    <script src="ConstexprTypeParameter.js"></script>
     <script src="Continue.js"></script>
     <script src="ConvertPtrToArrayRefExpression.js"></script>
     <script src="DoWhileLoop.js"></script>
@@ -61,7 +67,6 @@ td {
     <script src="ExternalOrigin.js"></script>
     <script src="Field.js"></script>
     <script src="FindHighZombies.js"></script>
-    <script src="FlattenProtocolExtends.js"></script>
     <script src="FlattenedStructOffsetGatherer.js"></script>
     <script src="FloatLiteral.js"></script>
     <script src="FloatLiteralType.js"></script>
@@ -69,7 +74,6 @@ td {
     <script src="ForLoop.js"></script>
     <script src="Func.js"></script>
     <script src="FuncDef.js"></script>
-    <script src="FuncInstantiator.js"></script>
     <script src="FuncParameter.js"></script>
     <script src="FunctionLikeBlock.js"></script>
     <script src="HighZombieFinder.js"></script>
@@ -79,7 +83,6 @@ td {
     <script src="InferTypesForCall.js"></script>
     <script src="Inline.js"></script>
     <script src="Inliner.js"></script>
-    <script src="InstantiateImmediates.js"></script>
     <script src="IntLiteral.js"></script>
     <script src="IntLiteralType.js"></script>
     <script src="Intrinsics.js"></script>
@@ -96,12 +99,12 @@ td {
     <script src="NameFinder.js"></script>
     <script src="NameResolver.js"></script>
     <script src="NativeFunc.js"></script>
-    <script src="NativeFuncInstance.js"></script>
-    <script src="NativeType.js"></script>
-    <script src="NativeTypeInstance.js"></script>
     <script src="NormalUsePropertyResolver.js"></script>
     <script src="NullLiteral.js"></script>
     <script src="NullType.js"></script>
+    <script src="OperatorAnderIndex.js"></script>
+    <script src="OperatorArrayRefLength.js"></script>
+    <script src="OperatorBool.js"></script>
     <script src="OriginKind.js"></script>
     <script src="OverloadResolutionFailure.js"></script>
     <script src="Parse.js"></script>
@@ -109,14 +112,11 @@ td {
     <script src="PropertyResolver.js"></script>
     <script src="Program.js"></script>
     <script src="ProgramWithUnnecessaryThingsRemoved.js"></script>
-    <script src="Protocol.js"></script>
-    <script src="ProtocolDecl.js"></script>
-    <script src="ProtocolFuncDecl.js"></script>
-    <script src="ProtocolRef.js"></script>
     <script src="PtrType.js"></script>
     <script src="ReadModifyWriteExpression.js"></script>
     <script src="RecursionChecker.js"></script>
     <script src="RecursiveTypeChecker.js"></script>
+    <script src="RemoveTypeArguments.js"></script>
     <script src="ResolveNames.js"></script>
     <script src="ResolveOverloadImpl.js"></script>
     <script src="ResolveProperties.js"></script>
@@ -124,27 +124,22 @@ td {
     <script src="Return.js"></script>
     <script src="ReturnChecker.js"></script>
     <script src="ReturnException.js"></script>
-    <script src="SPIR-V.js"></script>
-    <script src="SPIRVCodegen.js"></script>
-    <script src="SPIRVTypeAnalyzer.js"></script>
-    <script src="SPIRVVariableAnalyzer.js"></script>
     <script src="StandardLibrary.js"></script>
     <script src="StatementCloner.js"></script>
     <script src="StructLayoutBuilder.js"></script>
     <script src="StructType.js"></script>
-    <script src="Substitution.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="SynthesizeOperatorBool.js"></script>
+    <script src="SynthesizeCopyConstructorOperator.js"></script>
+    <script src="SynthesizeDefaultConstructorOperator.js"></script>
     <script src="TrapStatement.js"></script>
     <script src="TypeDef.js"></script>
     <script src="TypeDefResolver.js"></script>
-    <script src="TypeOrVariableRef.js"></script>
-    <script src="TypeParameterRewriter.js"></script>
     <script src="TypeRef.js"></script>
-    <script src="TypeVariable.js"></script>
-    <script src="TypeVariableTracker.js"></script>
     <script src="TypedValue.js"></script>
     <script src="UintLiteral.js"></script>
     <script src="UintLiteralType.js"></script>
@@ -152,6 +147,7 @@ td {
     <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="WSyntaxError.js"></script>
     <script src="WTrapError.js"></script>
index b4f5085..9844e08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,7 +53,7 @@ function generateSPIRV(spirv, program)
     typeMap.set(program.intrinsics.uint32, currentId++);
 
     for (let entryPoint of findEntryPoints()) {
-        let inlinedShader = program.funcInstantiator.getUnique(entryPoint, []);
+        let inlinedShader = entryPoint;
         _inlineFunction(program, inlinedShader, new VisitingSet(entryPoint));
 
         let typeAnalyzer = new SPIRVTypeAnalyzer(program, typeMap, currentId);
index 1988723..06b251c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,51 +31,54 @@ let standardLibrary = `
 
 // Need to bootstrap void first.
 native typedef void;
-
-native typedef uint8;
-native typedef int32;
-native typedef uint32;
 native typedef bool;
-typedef int = int32;
-typedef uint = uint32;
-
-native typedef float32;
-typedef float = float32;
-
-native operator int32(uint32);
-native operator int32(uint8);
-native operator int32(float);
-native operator uint32(int32);
-native operator uint32(uint8);
-native operator uint32(float);
-native operator uint8(int32);
-native operator uint8(uint32);
-native operator uint8(float);
-native operator float(int32);
-native operator float(uint32);
-native operator float(uint8);
+native typedef uchar;
+native typedef uint;
+native typedef int;
+native typedef float;
+
+// FIXME: Add support for these types to Intrinsics.js
+// native typedef ushort;
+// native typedef char;
+// native typedef short;
+// native typedef half;
+// native typedef atomic_int;
+// native typedef atomic_uint;
+
+native operator int(uint);
+native operator int(uchar);
+native operator int(float);
+native operator uint(int);
+native operator uint(uchar);
+native operator uint(float);
+native operator uchar(int);
+native operator uchar(uint);
+native operator uchar(float);
+native operator float(int);
+native operator float(uint);
+native operator float(uchar);
 
 native int operator+(int, int);
 native uint operator+(uint, uint);
-uint8 operator+(uint8 a, uint8 b) { return uint8(uint(a) + uint(b)); }
+uchar operator+(uchar a, uchar b) { return uchar(uint(a) + uint(b)); }
 native float operator+(float, float);
 int operator++(int value) { return value + 1; }
 uint operator++(uint value) { return value + 1; }
-uint8 operator++(uint8 value) { return value + 1; }
+uchar operator++(uchar value) { return value + 1; }
 native int operator-(int, int);
 native uint operator-(uint, uint);
-uint8 operator-(uint8 a, uint8 b) { return uint8(uint(a) - uint(b)); }
+uchar operator-(uchar a, uchar b) { return uchar(uint(a) - uint(b)); }
 native float operator-(float, float);
 int operator--(int value) { return value - 1; }
 uint operator--(uint value) { return value - 1; }
-uint8 operator--(uint8 value) { return value - 1; }
+uchar operator--(uchar value) { return value - 1; }
 native int operator*(int, int);
 native uint operator*(uint, uint);
-uint8 operator*(uint8 a, uint8 b) { return uint8(uint(a) * uint(b)); }
+uchar operator*(uchar a, uchar b) { return uchar(uint(a) * uint(b)); }
 native float operator*(float, float);
 native int operator/(int, int);
 native uint operator/(uint, uint);
-uint8 operator/(uint8 a, uint8 b) { return uint8(uint(a) / uint(b)); }
+uchar operator/(uchar a, uchar b) { return uchar(uint(a) / uint(b)); }
 native int operator&(int, int);
 native int operator|(int, int);
 native int operator^(int, int);
@@ -88,33 +91,33 @@ native uint operator^(uint, uint);
 native uint operator~(uint);
 native uint operator<<(uint, uint);
 native uint operator>>(uint, uint);
-uint8 operator&(uint8 a, uint8 b) { return uint8(uint(a) & uint(b)); }
-uint8 operator|(uint8 a, uint8 b) { return uint8(uint(a) | uint(b)); }
-uint8 operator^(uint8 a, uint8 b) { return uint8(uint(a) ^ uint(b)); }
-uint8 operator~(uint8 value) { return uint8(~uint(value)); }
-uint8 operator<<(uint8 a, uint b) { return uint8(uint(a) << (b & 7)); }
-uint8 operator>>(uint8 a, uint b) { return uint8(uint(a) >> (b & 7)); }
+uchar operator&(uchar a, uchar b) { return uchar(uint(a) & uint(b)); }
+uchar operator|(uchar a, uchar b) { return uchar(uint(a) | uint(b)); }
+uchar operator^(uchar a, uchar b) { return uchar(uint(a) ^ uint(b)); }
+uchar operator~(uchar value) { return uchar(~uint(value)); }
+uchar operator<<(uchar a, uint b) { return uchar(uint(a) << (b & 7)); }
+uchar operator>>(uchar a, uint b) { return uchar(uint(a) >> (b & 7)); }
 native float operator/(float, float);
 native bool operator==(int, int);
 native bool operator==(uint, uint);
-bool operator==(uint8 a, uint8 b) { return uint(a) == uint(b); }
+bool operator==(uchar a, uchar b) { return uint(a) == uint(b); }
 native bool operator==(bool, bool);
 native bool operator==(float, float);
 native bool operator<(int, int);
 native bool operator<(uint, uint);
-bool operator<(uint8 a, uint8 b) { return uint(a) < uint(b); }
+bool operator<(uchar a, uchar b) { return uint(a) < uint(b); }
 native bool operator<(float, float);
 native bool operator<=(int, int);
 native bool operator<=(uint, uint);
-bool operator<=(uint8 a, uint8 b) { return uint(a) <= uint(b); }
+bool operator<=(uchar a, uchar b) { return uint(a) <= uint(b); }
 native bool operator<=(float, float);
 native bool operator>(int, int);
 native bool operator>(uint, uint);
-bool operator>(uint8 a, uint8 b) { return uint(a) > uint(b); }
+bool operator>(uchar a, uchar b) { return uint(a) > uint(b); }
 native bool operator>(float, float);
 native bool operator>=(int, int);
 native bool operator>=(uint, uint);
-bool operator>=(uint8 a, uint8 b) { return uint(a) >= uint(b); }
+bool operator>=(uchar a, uchar b) { return uint(a) >= uint(b); }
 native bool operator>=(float, float);
 
 bool operator&(bool a, bool b)
@@ -145,245 +148,54 @@ bool operator~(bool value)
     return !value;
 }
 
-protocol Addable {
-    Addable operator+(Addable, Addable);
-}
-
-protocol Equatable {
-    bool operator==(Equatable, Equatable);
-}
-
-restricted operator<T> T()
-{
-    T defaultValue;
-    return defaultValue;
-}
-
-restricted operator<T> T(T x)
-{
-    return x;
-}
-
-operator<T:Equatable> bool(T x)
-{
-    return x != T();
-}
+native typedef uchar2;
+native typedef uchar3;
+native typedef uchar4;
 
-struct vec2<T> {
-    T x;
-    T y;
-}
+native typedef uint2;
+native typedef uint3;
+native typedef uint4;
 
-typedef int2 = vec2<int>;
-typedef uint2 = vec2<uint>;
-typedef float2 = vec2<float>;
+native typedef int2;
+native typedef int3;
+native typedef int4;
 
-operator<T> vec2<T>(T x, T y)
-{
-    vec2<T> result;
-    result.x = x;
-    result.y = y;
-    return result;
-}
-
-bool operator==<T:Equatable>(vec2<T> a, vec2<T> b)
-{
-    return a.x == b.x && a.y == b.y;
-}
-
-thread T* operator&[]<T>(thread vec2<T>* foo, uint index)
-{
-    if (index == 0)
-        return &foo->x;
-    if (index == 1)
-        return &foo->y;
-    trap;
-}
-
-struct vec3<T> {
-    T x;
-    T y;
-    T z;
-}
-
-typedef int3 = vec3<int>;
-typedef uint3 = vec3<uint>;
-typedef float3 = vec3<float>;
-
-operator<T> vec3<T>(T x, T y, T z)
-{
-    vec3<T> result;
-    result.x = x;
-    result.y = y;
-    result.z = z;
-    return result;
-}
-
-operator<T> vec3<T>(vec2<T> v2, T z)
-{
-    vec3<T> result;
-    result.x = v2.x;
-    result.y = v2.y;
-    result.z = z;
-    return result;
-}
-
-operator<T> vec3<T>(T x, vec2<T> v2)
-{
-    vec3<T> result;
-    result.x = x;
-    result.y = v2.x;
-    result.z = v2.y;
-    return result;
-}
-
-bool operator==<T:Equatable>(vec3<T> a, vec3<T> b)
-{
-    return a.x == b.x && a.y == b.y && a.z == b.z;
-}
-
-thread T* operator&[]<T>(thread vec3<T>* foo, uint index)
-{
-    if (index == 0)
-        return &foo->x;
-    if (index == 1)
-        return &foo->y;
-    if (index == 2)
-        return &foo->z;
-    trap;
-}
-
-struct vec4<T> {
-    T x;
-    T y;
-    T z;
-    T w;
-}
-
-typedef int4 = vec4<int>;
-typedef uint4 = vec4<uint>;
-typedef float4 = vec4<float>;
-
-operator<T> vec4<T>(T x, T y, T z, T w)
-{
-    vec4<T> result;
-    result.x = x;
-    result.y = y;
-    result.z = z;
-    result.w = w;
-    return result;
-}
-
-operator<T> vec4<T>(vec2<T> v2, T z, T w)
-{
-    vec4<T> result;
-    result.x = v2.x;
-    result.y = v2.y;
-    result.z = z;
-    result.w = w;
-    return result;
-}
-
-operator<T> vec4<T>(T x, vec2<T> v2, T w)
-{
-    vec4<T> result;
-    result.x = x;
-    result.y = v2.x;
-    result.z = v2.y;
-    result.w = w;
-    return result;
-}
-
-operator<T> vec4<T>(T x, T y, vec2<T> v2)
-{
-    vec4<T> result;
-    result.x = x;
-    result.y = y;
-    result.z = v2.x;
-    result.w = v2.y;
-    return result;
-}
-
-operator<T> vec4<T>(vec2<T> v2a, vec2<T> v2b)
-{
-    vec4<T> result;
-    result.x = v2a.x;
-    result.y = v2a.y;
-    result.z = v2b.x;
-    result.w = v2b.y;
-    return result;
-}
-
-operator<T> vec4<T>(vec3<T> v3, T w)
-{
-    vec4<T> result;
-    result.x = v3.x;
-    result.y = v3.y;
-    result.z = v3.z;
-    result.w = w;
-    return result;
-}
+native typedef float2;
+native typedef float3;
+native typedef float4;
+`;
 
-operator<T> vec4<T>(T x, vec3<T> v3)
-{
-    vec4<T> result;
-    result.x = x;
-    result.y = v3.x;
-    result.z = v3.y;
-    result.w = v3.z;
-    return result;
-}
+// FIXME: Once the standard library has been replaced with a new version, this comments should be removed.
+// This list is used to restrict the availability of vector types available in the langauge.
+// Permissible vector element types must appear in this list and in the standard library
+const VectorElementTypes = [ /*"bool",*/ "uchar", /*"char", "ushort", "short",*/ "uint", "int", /* "half", */"float" ];
+const VectorElementSizes = [ 2, 3, 4 ];
 
-bool operator==<T:Equatable>(vec4<T> a, vec4<T> b)
+function allVectorTypeNames()
 {
-    return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
-}
-
-thread T* operator&[]<T>(thread vec4<T>* foo, uint index)
-{
-    if (index == 0)
-        return &foo->x;
-    if (index == 1)
-        return &foo->y;
-    if (index == 2)
-        return &foo->z;
-    if (index == 3)
-        return &foo->w;
-    trap;
+    const names = [];
+    for (let elementType of VectorElementTypes) {
+        for (let size of VectorElementSizes)
+            names.push(`${elementType}${size}`);
+    }
+    return names;
 }
 
-native thread T* operator&[]<T>(thread T[], uint);
-native threadgroup T* operator&[]<T>(threadgroup T[], uint);
-native device T* operator&[]<T>(device T[], uint);
-native constant T* operator&[]<T>(constant T[], uint);
+// Provides operator&[]
+standardLibrary += OperatorAnderIndexer.functions().join(";\n") + ";\n";
 
-native uint operator.length<T>(thread T[]);
-native uint operator.length<T>(threadgroup T[]);
-native uint operator.length<T>(device T[]);
-native uint operator.length<T>(constant T[]);
+// Native vector types are like structs in the langauge, but they do not have the ander field access.
+// It is not possible to take the address of a vector field.
+standardLibrary += BuiltinVectorGetter.functions().join(";\n") + ";\n";
+standardLibrary += BuiltinVectorSetter.functions().join(";\n") + ";\n";
+standardLibrary += BuiltinVectorIndexGetter.functions().join(";\n") + ";\n";
+standardLibrary += BuiltinVectorIndexSetter.functions().join(";\n") + ";\n";
 
-uint operator.length<T, uint length>(T[length])
-{
-    return length;
-}
-`;
-
-function intToString(x)
-{
-    switch (x) {
-    case 0:
-        return "x";
-    case 1:
-        return "y";
-    case 2:
-        return "z";
-    case 3:
-        return "w";
-    default:
-        throw new Error("Could not generate standard library.");
-    }
-}
+// FIXME: For native types these could be included as source in the standard library.
+// https://bugs.webkit.org/show_bug.cgi?id=188685
+standardLibrary += OperatorBool.functions().join(";\n") + ";\n";
+standardLibrary += BuiltinVectorEqualityOperator.functions().join(";\n") + ";\n";
 
-// There are 481 swizzle operators, so we compile them as native functions
-standardLibrary += SwizzleOp.allSwizzleOperators().join(";\n") + ";";
-console.log(standardLibrary);
\ No newline at end of file
+// FIXME: These need to be included as source in the standard library.
+standardLibrary += SwizzleOp.functions().join(";\n") + ";\n";
+standardLibrary += BuiltinVectorConstructors.functions().join(";\n") + ";\n";
index c9479a2..b3948c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 class StatementCloner extends Rewriter {
     visitFuncDef(node)
     {
-        let typeParameters = node.typeParameters.map(typeParameter => typeParameter.visit(this));
         let result = new FuncDef(
             node.origin, node.name,
             node.returnType.visit(this),
-            typeParameters,
             node.parameters.map(parameter => parameter.visit(this)),
             node.body.visit(this),
             node.isCast, node.shaderType);
@@ -44,7 +42,6 @@ class StatementCloner extends Rewriter {
         let result = new NativeFunc(
             node.origin, node.name,
             node.returnType.visit(this),
-            node.typeParameters.map(typeParameter => typeParameter.visit(this)),
             node.parameters.map(parameter => parameter.visit(this)),
             node.isCast, node.shaderType);
         result.isRestricted = node.isRestricted;
@@ -53,63 +50,27 @@ class StatementCloner extends Rewriter {
     
     visitNativeType(node)
     {
-        return new NativeType(
-            node.origin, node.name, node.typeParameters.map(typeParameter => typeParameter.visit(this)));
+        return new NativeType(node.origin, node.name);
     }
     
     visitTypeDef(node)
     {
-        return new TypeDef(
-            node.origin, node.name,
-            node.typeParameters.map(typeParameter => typeParameter.visit(this)),
-            node.type.visit(this));
+        return new TypeDef(node.origin, node.name, node.type.visit(this));
     }
     
     visitStructType(node)
     {
-        let result = new StructType(
-            node.origin, node.name,
-            node.typeParameters.map(typeParameter => typeParameter.visit(this)));
+        let result = new StructType(node.origin, node.name);
         for (let field of node.fields)
             result.add(field.visit(this));
         return result;
     }
     
-    visitConstexprTypeParameter(node)
-    {
-        return new ConstexprTypeParameter(node.origin, node.name, node.type.visit(this));
-    }
-    
-    visitProtocolDecl(node)
-    {
-        let result = new ProtocolDecl(node.origin, node.name);
-        for (let protocol of node.extends)
-            result.addExtends(protocol.visit(this));
-        for (let signature of node.signatures)
-            result.add(signature.visit(this));
-        return result;
-    }
-
-    visitTypeVariable(node)
-    {
-        return new TypeVariable(node.origin, node.name, Node.visit(node.protocol, this));
-    }
-    
-    visitProtocolRef(node)
-    {
-        return new ProtocolRef(node.origin, node.name);
-    }
-    
     visitBoolLiteral(node)
     {
         return new BoolLiteral(node.origin, node.value);
     }
     
-    visitTypeOrVariableRef(node)
-    {
-        return new TypeOrVariableRef(node.origin, node.name);
-    }
-    
     visitEnumType(node)
     {
         let result = new EnumType(node.origin, node.name, node.baseType.visit(this));
index 4f98c57..11b44b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,8 +39,6 @@ class StructLayoutBuilder extends Visitor {
     {
         if (node.size != null)
             return;
-        if (node.typeParameters.length)
-            throw new Error("Cannot do layout for generic type: " + node);
         let oldOffset = this._offset;
         this._offset = 0;
         super.visitStructType(node);
@@ -60,12 +58,6 @@ class StructLayoutBuilder extends Visitor {
         this._offset += size;
     }
     
-    visitNativeFuncInstance(node)
-    {
-        super.visitNativeFuncInstance(node);
-        node.func.didLayoutStructsInImplementationData(node.implementationData);
-    }
-    
     visitTypeRef(node)
     {
         super.visitTypeRef(node);
@@ -76,14 +68,6 @@ class StructLayoutBuilder extends Visitor {
     {
         for (let argument of node.argumentList)
             Node.visit(argument, this);
-        let handleTypeArguments = actualTypeArguments => {
-            if (actualTypeArguments) {
-                for (let argument of actualTypeArguments)
-                    argument.visit(this);
-            }
-        };
-        handleTypeArguments(node.instantiatedActualTypeArguments);
-        Node.visit(node.nativeFuncInstance, this);
         Node.visit(node.resultType, this);
     }
 }
index f9d8c7d..c0ff958 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 "use strict";
 
 class StructType extends Type {
-    constructor(origin, name, typeParameters)
+    constructor(origin, name)
     {
         super();
         this._origin = origin;
         this._name = name;
-        this._typeParameters = typeParameters;
         this._fields = new Map();
     }
     
@@ -44,7 +43,6 @@ class StructType extends Type {
     
     get name() { return this._name; }
     get origin() { return this._origin; }
-    get typeParameters() { return this._typeParameters; }
     
     get fieldNames() { return this._fields.keys(); }
     fieldByName(name) { return this._fields.get(name); }
@@ -58,32 +56,6 @@ class StructType extends Type {
         return result;
     }
     
-    instantiate(typeArguments = null)
-    {
-        let substitution = null;
-        let typeParameters = this.typeParameters;
-        
-        if (typeArguments) {
-            if (typeArguments.length != this.typeParameters.length)
-                throw new WTypeError(this.origin.originString, "Wrong number of type arguments to instantiation");
-            
-            substitution = new Substitution(this.typeParameters, typeArguments);
-            typeParameters = [];
-        }
-        
-        let instantiateImmediates = new InstantiateImmediates();
-        let result = new StructType(this.origin, this.name, typeParameters);
-        for (let field of this.fields) {
-            let newField = field;
-            if (substitution)
-                newField = newField.visit(substitution);
-            newField = newField.visit(instantiateImmediates);
-            result.add(newField);
-        }
-        
-        return result;
-    }
-    
     populateDefaultValue(buffer, offset)
     {
         if (this.size == null)
@@ -94,6 +66,6 @@ class StructType extends Type {
     
     toString()
     {
-        return "struct " + this.name + "<" + this.typeParameters + "> { " + Array.from(this.fields).join("; ") + "; }";
+        return `struct ${this.name} { ${Array.from(this.fields).join("; ")}; }`;
     }
 }
index d1c5bd0..25998ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
 class SwizzleOp {
-    constructor(outSize, components, inSize)
+    constructor(baseTypeName, outSize, components, inSize)
     {
+        this._baseTypeName = baseTypeName;
         this._outSize = outSize;
         this._components = components.slice(); // Shallow clone
         this._inSize = inSize;
     }
 
+    get baseTypeName() { return this._baseTypeName; }
     get outSize() { return this._outSize; }
     get components() { return this._components; }
     get inSize() { return this._inSize; }
 
     toString()
     {
-        return `native vec${this.outSize}<T> operator.${this.components.join("")}<T>(vec${this.inSize}<T> v)`;
+        return `native ${this.baseTypeName}${this.outSize} operator.${this.components.join("")}(${this.baseTypeName}${this.inSize} v)`;
     }
 
-    static allSwizzleOperators()
+    static intToString(x)
     {
-        if (!SwizzleOp._allSwizzleOperators) {
-            SwizzleOp._allSwizzleOperators = [];
-            
-            function _generateSwizzle(maxDepth, maxItems, array) {
+        switch (x) {
+        case 0:
+            return "x";
+        case 1:
+            return "y";
+        case 2:
+            return "z";
+        case 3:
+            return "w";
+        default:
+            throw new Error("Could not generate standard library.");
+        }
+    }
+
+    static functions()
+    {
+        if (!this._functions) {
+            // We can't directly use this._functions in _generateSwizzles.
+            const functions = [];
+
+            function _generateSwizzle(baseTypeName, maxDepth, maxItems, array) {
                 if (!array)
                     array = [];
                 if (array.length == maxDepth) {
-                    SwizzleOp._allSwizzleOperators.push(new SwizzleOp(array.length, array, maxItems));
+                    functions.push(new SwizzleOp(baseTypeName, array.length, array, maxItems));
                     return;
                 }
                 for (let i = 0; i < maxItems; ++i) {
-                    array.push(intToString(i));
-                    _generateSwizzle(maxDepth, maxItems, array);
+                    array.push(SwizzleOp.intToString(i));
+                    _generateSwizzle(baseTypeName, maxDepth, maxItems, array);
                     array.pop();
                 }
             };
-        
-            for (let maxDepth = 2; maxDepth <= 4; maxDepth++) {
-                for (let maxItems = 2; maxItems <= 4; maxItems++)
-                    _generateSwizzle(maxDepth, maxItems);
+
+            for (let typeName of VectorElementTypes) {
+                for (let maxDepth of VectorElementSizes) {
+                    for (let maxItems = 2; maxItems <= 4; maxItems++)
+                        _generateSwizzle(typeName, maxDepth, maxItems);
+                }
             }
+
+            this._functions = functions;
         }
-        return SwizzleOp._allSwizzleOperators;
+        return this._functions;
     }
-}
 
-// Initialise the static member (JS doesn't allow static fields declared in the class)
-SwizzleOp._allSwizzleOperators = null;
\ No newline at end of file
+    instantiateImplementation(func)
+    {
+        func.implementation = ([vec], node) => {
+            const outputBuffer = new EBuffer(this.outSize);
+            const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 };
+            for (let i = 0; i < this.outSize; i++)
+                outputBuffer.set(i, vec.get(readIndices[this.components[i]]));
+
+
+            return new EPtr(outputBuffer, 0);
+        };
+        func.implementationData = this;
+    }
+}
\ No newline at end of file
diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js b/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js
new file mode 100644 (file)
index 0000000..de8df5d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function synthesizeArrayOperatorLength(program)
+{
+    const arrayTypes = new Set();
+
+    class FindArrayTypes extends Visitor {
+        visitArrayType(node)
+        {
+            arrayTypes.add(node);
+        }
+    }
+
+    program.visit(new FindArrayTypes());
+
+    const uint = TypeRef.wrap(program.globalNameContext.get(Type, "uint"));
+    const nameResolver = new NameResolver(program.globalNameContext);
+    uint.visit(nameResolver);
+
+    for (let arrayType of arrayTypes) {
+        const paramType = TypeRef.wrap(arrayType);
+        paramType.visit(nameResolver);
+        paramType.type.elementType.visit(nameResolver);
+
+        let possibleExistingFunctions = program.functions.get("operator.length");
+        if (possibleExistingFunctions) {
+            // Ignore user-defined functions, only include those introduced below.
+            possibleExistingFunctions = possibleExistingFunctions.filter(t => t instanceof NativeFunc);
+            const overloads = resolveOverloadImpl(possibleExistingFunctions, [ paramType ], uint);
+            if (overloads.func)
+                continue;
+        }
+
+        let nativeFunc = new NativeFunc(
+            arrayType.origin, "operator.length", uint,
+            [ new FuncParameter(arrayType.origin, null, paramType) ],
+            false, null);
+        nativeFunc.implementation = ([array]) => EPtr.box(arrayType.numElementsValue);
+        program.add(nativeFunc);
+
+    }
+}
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-class TypeVariableTracker extends Visitor {
-    constructor()
-    {
-        super();
-        this._set = new Set();
-    }
-    
-    get set() { return this._set; }
-    
-    _consider(thing)
-    {
-        if (thing.isUnifiable)
-            this._set.add(thing);
-    }
-    
-    visitTypeRef(node)
-    {
-        if (node.typeArguments.length) {
-            for (let typeArgument of node.typeArguments)
-                typeArgument.visit(this);
-            return;
+function synthesizeCopyConstructorOperator(program)
+{
+    const types = new Set();
+
+    class FindAllTypes extends Visitor {
+        visitNativeType(node)
+        {
+            types.add(node);
+        }
+
+        visitStructType(node)
+        {
+            types.add(node);
+            super.visitStructType(node);
+        }
+
+        visitElementalType(node)
+        {
+            types.add(node);
+            super.visitElementalType(node);
         }
-        this._consider(node.type);
     }
-    
-    visitVariableRef(node)
-    {
-        this._consider(node.variable);
+
+    program.visit(new FindAllTypes());
+
+    for (let type of types) {
+        let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [
+            new FuncParameter(type.origin, null, TypeRef.wrap(type))
+        ], true, null);
+        nativeFunc.implementation = ([arg], node) => {
+            let result = new EPtr(new EBuffer(type.size), 0);
+            result.copyFrom(arg, type.size);
+            return result;
+        };
+        program.add(nativeFunc);
     }
 }
-
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
-class NativeTypeInstance extends Type {
-    constructor(type, typeArguments)
-    {
-        super();
-        this._type = type;
-        this._typeArguments = typeArguments;
-    }
-    
-    get type() { return this._type; }
-    get typeArguments() { return this._typeArguments; }
-    get isPrimitive() { return this._type.isPrimitive; }
-    get isNative() { return true; }
-    
-    unifyImpl(unificationContext, other)
-    {
-        if (this.type != other.type)
-            return false;
-        if (this.typeArguments.length != other.typeArguments.length)
-            return false;
-        for (let i = 0; i < this.typeArguments.length; ++i) {
-            if (!this.typeArguments[i].unify(unificationContext, other.typeArguments[i]))
-                return false;
+function synthesizeDefaultConstructorOperator(program)
+{
+    const types = new Set();
+
+    class FindAllTypes extends Visitor {
+        visitNativeType(node)
+        {
+            types.add(node);
+        }
+
+        visitStructType(node)
+        {
+            types.add(node);
+            super.visitStructType(node);
+        }
+
+        visitElementalType(node)
+        {
+            types.add(node);
+            super.visitElementalType(node);
         }
-        return true;
     }
-    
-    toString()
-    {
-        return this.type + "<" + this.typeArguments + ">";
+
+    program.visit(new FindAllTypes());
+
+    for (let type of types) {
+        let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [], true, null);
+        nativeFunc.implementation = ([], node) => {
+            let result = new EPtr(new EBuffer(type.size), 0);
+            node.type.populateDefaultValue(result.buffer, 0);
+            return result;
+        };
+        program.add(nativeFunc);
     }
 }
-
index 5af2bdf..137ac9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -20,7 +20,7 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 "use strict";
 
@@ -29,37 +29,37 @@ function synthesizeEnumFunctions(program)
     for (let type of program.types.values()) {
         if (!(type instanceof EnumType))
             continue;
-        
+
         let nativeFunc;
         let isCast = false;
         let shaderType;
-        
+
         nativeFunc = new NativeFunc(
-            type.origin, "operator==", new TypeRef(type.origin, "bool", []), [],
+            type.origin, "operator==", new TypeRef(type.origin, "bool"),
             [
-                new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, [])),
-                new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, []))
+                new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name)),
+                new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name))
             ],
             isCast, shaderType);
         nativeFunc.implementation = ([left, right]) => EPtr.box(left.loadValue() == right.loadValue());
         program.add(nativeFunc);
-        
+
         nativeFunc = new NativeFunc(
-            type.origin, "operator.value", type.baseType.visit(new Rewriter()), [],
-            [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, []))],
+            type.origin, "operator.value", type.baseType.visit(new Rewriter()),
+            [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name))],
             isCast, shaderType);
         nativeFunc.implementation = ([value]) => value;
         program.add(nativeFunc);
-        
+
         nativeFunc = new NativeFunc(
-            type.origin, "operator cast", type.baseType.visit(new Rewriter()), [],
-            [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, []))],
+            type.origin, "operator cast", type.baseType.visit(new Rewriter()),
+            [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name))],
             isCast, shaderType);
         nativeFunc.implementation = ([value]) => value;
         program.add(nativeFunc);
-        
+
         nativeFunc = new NativeFunc(
-            type.origin, "operator cast", new TypeRef(type.origin, type.name, []), [],
+            type.origin, "operator cast", new TypeRef(type.origin, type.name),
             [new FuncParameter(type.origin, null, type.baseType.visit(new Rewriter()))],
             isCast, shaderType);
         nativeFunc.implementation = ([value]) => value;
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 "use strict";
 
-class Protocol extends Node {
-    constructor(origin, name)
-    {
-        super();
-        this._origin = origin;
-        this._name = name;
-    }
-    
-    get origin() { return this._origin; }
-    get name() { return this._name; }
-    get kind() { return Protocol; }
-    
-    toString()
-    {
-        return this.name;
+function synthesizeOperatorBool(program)
+{
+    for (let type of program.types.values()) {
+        if (!(type instanceof StructType) && !(type instanceof EnumType))
+            continue;
+        const func = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(program.types.get("bool")), [ new FuncParameter(type.origin, null, TypeRef.wrap(type)) ], true, null);
+        const operatorBool = new OperatorBool(type.name);
+        operatorBool.instantiateImplementation(func);
+        program.add(func);
     }
 }
index f7816f2..bfe6044 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,81 +31,36 @@ function synthesizeStructAccessors(program)
             continue;
         
         for (let field of type.fields) {
-            function createTypeParameters()
-            {
-                return type.typeParameters.map(
-                    typeParameter => typeParameter.visit(new TypeParameterRewriter()));
-            }
-            
-            function createTypeArguments()
-            {
-                return typeParameters.map(typeParameter => typeParameter.visit(new AutoWrapper()));
-            }
-            
             function setupImplementationData(nativeFunc, implementation)
             {
-                nativeFunc.instantiateImplementation = substitution => {
-                    let newType = type.instantiate(nativeFunc.typeParameters.map(typeParameter => {
-                        let substitute = substitution.map.get(typeParameter);
-                        if (!substitute)
-                            throw new Error("Null substitute for type parameter " + typeParameter);
-                        return substitute;
-                    }));
-                    return {type: newType, fieldName: field.name};
-                };
                 nativeFunc.visitImplementationData = (implementationData, visitor) => {
                     // Visiting the type first ensures that the struct layout builder figures out the field's
                     // offset.
                     implementationData.type.visit(visitor);
                 };
-                nativeFunc.didLayoutStructsInImplementationData = implementationData => {
-                    let structSize = implementationData.type.size;
-                    if (structSize == null)
-                        throw new Error("No struct size for " + nativeFunc);
-                    let field = implementationData.type.fieldByName(implementationData.fieldName);
-                    if (!field)
-                        throw new Error("Could not find field");
-                    let offset = field.offset;
-                    let fieldSize = field.type.size;
-                    if (fieldSize == null)
-                        throw new Error("No field size for " + nativeFunc);
-                    if (offset == null)
-                        throw new Error("No offset for " + nativeFunc);
-                    
-                    implementationData.offset = offset;
-                    implementationData.structSize = structSize;
-                    implementationData.fieldSize = fieldSize;
-                };
+
                 nativeFunc.implementation = (argumentList, node) => {
-                    let nativeFuncInstance = node.nativeFuncInstance;
-                    let implementationData = nativeFuncInstance.implementationData;
-                    return implementation(
-                        argumentList,
-                        implementationData.offset,
-                        implementationData.structSize,
-                        implementationData.fieldSize);
+                    return implementation(argumentList, field.offset, type.size, field.type.size);
                 };
             }
             
             function createFieldType()
             {
-                return field.type.visit(new Substitution(type.typeParameters, typeParameters));
+                return field.type.visit(new Rewriter());
             }
             
             function createTypeRef()
             {
-                return TypeRef.instantiate(type, createTypeArguments());
+                return TypeRef.instantiate(type);
             }
             
             let isCast = false;
             let shaderType;
-            let typeParameters;
             let nativeFunc;
 
             // The getter: operator.field
-            typeParameters = createTypeParameters();
             nativeFunc = new NativeFunc(
-                field.origin, "operator." + field.name, createFieldType(), typeParameters,
+                field.origin, "operator." + field.name, createFieldType(),
                 [new FuncParameter(field.origin, null, createTypeRef())], isCast, shaderType);
             setupImplementationData(nativeFunc, ([base], offset, structSize, fieldSize) => {
                 let result = new EPtr(new EBuffer(fieldSize), 0);
@@ -115,9 +70,8 @@ function synthesizeStructAccessors(program)
             program.add(nativeFunc);
             
             // The setter: operator.field=
-            typeParameters = createTypeParameters();
             nativeFunc = new NativeFunc(
-                field.origin, "operator." + field.name + "=", createTypeRef(), typeParameters,
+                field.origin, "operator." + field.name + "=", createTypeRef(),
                 [
                     new FuncParameter(field.origin, null, createTypeRef()),
                     new FuncParameter(field.origin, null, createFieldType())
@@ -134,10 +88,8 @@ function synthesizeStructAccessors(program)
             // The ander: operator&.field
             function setupAnder(addressSpace)
             {
-                typeParameters = createTypeParameters();
                 nativeFunc = new NativeFunc(
                     field.origin, "operator&." + field.name, new PtrType(field.origin, addressSpace, createFieldType()),
-                    typeParameters,
                     [
                         new FuncParameter(
                             field.origin, null,
index a641d30..13f3582 100644 (file)
@@ -12,6 +12,7 @@
 <script src="CreateLiteralType.js"></script>
 <script src="PropertyAccessExpression.js"></script>
 <script src="SwizzleOp.js"></script>
+<script src="NativeType.js"></script>
 
 <script src="AddressSpace.js"></script>
 <script src="AnonymousVariable.js"></script>
 <script src="Block.js"></script>
 <script src="BoolLiteral.js"></script>
 <script src="Break.js"></script>
+<script src="BuiltinVectorConstructors.js"></script>
+<script src="BuiltinVectorGetter.js"></script>
+<script src="BuiltinVectorSetter.js"></script>
+<script src="BuiltinVectorIndexGetter.js"></script>
+<script src="BuiltinVectorIndexSetter.js"></script>
+<script src="BuiltinVectorEqualityOperator.js"></script>
 <script src="CallExpression.js"></script>
 <script src="CallFunction.js"></script>
 <script src="Check.js"></script>
@@ -36,7 +43,6 @@
 <script src="CloneProgram.js"></script>
 <script src="CommaExpression.js"></script>
 <script src="ConstexprFolder.js"></script>
-<script src="ConstexprTypeParameter.js"></script>
 <script src="Continue.js"></script>
 <script src="ConvertPtrToArrayRefExpression.js"></script>
 <script src="DoWhileLoop.js"></script>
@@ -55,7 +61,6 @@
 <script src="ExternalOrigin.js"></script>
 <script src="Field.js"></script>
 <script src="FindHighZombies.js"></script>
-<script src="FlattenProtocolExtends.js"></script>
 <script src="FlattenedStructOffsetGatherer.js"></script>
 <script src="FloatLiteral.js"></script>
 <script src="FloatLiteralType.js"></script>
@@ -63,7 +68,6 @@
 <script src="ForLoop.js"></script>
 <script src="Func.js"></script>
 <script src="FuncDef.js"></script>
-<script src="FuncInstantiator.js"></script>
 <script src="FuncParameter.js"></script>
 <script src="FunctionLikeBlock.js"></script>
 <script src="HighZombieFinder.js"></script>
@@ -73,7 +77,6 @@
 <script src="InferTypesForCall.js"></script>
 <script src="Inline.js"></script>
 <script src="Inliner.js"></script>
-<script src="InstantiateImmediates.js"></script>
 <script src="IntLiteral.js"></script>
 <script src="IntLiteralType.js"></script>
 <script src="Intrinsics.js"></script>
 <script src="NameFinder.js"></script>
 <script src="NameResolver.js"></script>
 <script src="NativeFunc.js"></script>
-<script src="NativeFuncInstance.js"></script>
-<script src="NativeType.js"></script>
-<script src="NativeTypeInstance.js"></script>
 <script src="NormalUsePropertyResolver.js"></script>
 <script src="NullLiteral.js"></script>
 <script src="NullType.js"></script>
+<script src="OperatorAnderIndex.js"></script>
+<script src="OperatorArrayRefLength.js"></script>
+<script src="OperatorBool.js"></script>
 <script src="OriginKind.js"></script>
 <script src="OverloadResolutionFailure.js"></script>
 <script src="Parse.js"></script>
 <script src="PropertyResolver.js"></script>
 <script src="Program.js"></script>
 <script src="ProgramWithUnnecessaryThingsRemoved.js"></script>
-<script src="Protocol.js"></script>
-<script src="ProtocolDecl.js"></script>
-<script src="ProtocolFuncDecl.js"></script>
-<script src="ProtocolRef.js"></script>
 <script src="PtrType.js"></script>
 <script src="ReadModifyWriteExpression.js"></script>
 <script src="RecursionChecker.js"></script>
 <script src="RecursiveTypeChecker.js"></script>
+<script src="RemoveTypeArguments.js"></script>
 <script src="ResolveNames.js"></script>
 <script src="ResolveOverloadImpl.js"></script>
 <script src="ResolveProperties.js"></script>
 <script src="StatementCloner.js"></script>
 <script src="StructLayoutBuilder.js"></script>
 <script src="StructType.js"></script>
-<script src="Substitution.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="SynthesizeOperatorBool.js"></script>
+<script src="SynthesizeCopyConstructorOperator.js"></script>
+<script src="SynthesizeDefaultConstructorOperator.js"></script>
 <script src="TrapStatement.js"></script>
 <script src="TypeDef.js"></script>
 <script src="TypeDefResolver.js"></script>
-<script src="TypeOrVariableRef.js"></script>
-<script src="TypeParameterRewriter.js"></script>
 <script src="TypeRef.js"></script>
-<script src="TypeVariable.js"></script>
-<script src="TypeVariableTracker.js"></script>
 <script src="TypedValue.js"></script>
 <script src="UintLiteral.js"></script>
 <script src="UintLiteralType.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="WSyntaxError.js"></script>
 <script src="WTrapError.js"></script>
@@ -172,6 +172,12 @@ function doTestInBrowser()
 }
 </script>
 
+<style>
+    pre {
+        margin:0;
+    }
+</style>
+
 </head>
 <body onload="doTestInBrowser()">
 <div id="messages"></div>
index 322a0a7..5d07d9b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,9 +26,9 @@
 
 if (this.window) {
     this.print = (text) => {
-        var span = document.createElement("span");
+        var span = document.createElement("pre");
         document.getElementById("messages").appendChild(span);
-        span.innerHTML = text.replace(/ /g, "&nbsp;").replace(/\n/g, "<br>") + "<br>";
+        span.innerText = text;
         window.scrollTo(0,document.body.scrollHeight);
     };
     this.preciseTime = () => performance.now() / 1000;
@@ -55,17 +55,17 @@ function doLex(code)
 
 function makeInt(program, value)
 {
-    return TypedValue.box(program.intrinsics.int32, value);
+    return TypedValue.box(program.intrinsics.int, value);
 }
 
 function makeUint(program, value)
 {
-    return TypedValue.box(program.intrinsics.uint32, value);
+    return TypedValue.box(program.intrinsics.uint, value);
 }
 
-function makeUint8(program, value)
+function makeUchar(program, value)
 {
-    return TypedValue.box(program.intrinsics.uint8, value);
+    return TypedValue.box(program.intrinsics.uchar, value);
 }
 
 function makeBool(program, value)
@@ -99,7 +99,7 @@ function checkNumber(program, result, expected)
 
 function checkInt(program, result, expected)
 {
-    if (!result.type.equals(program.intrinsics.int32))
+    if (!result.type.equals(program.intrinsics.int))
         throw new Error("Wrong result type; result: " + result);
     checkNumber(program, result, expected);
 }
@@ -114,15 +114,15 @@ function checkEnum(program, result, expected)
 
 function checkUint(program, result, expected)
 {
-    if (!result.type.equals(program.intrinsics.uint32))
+    if (!result.type.equals(program.intrinsics.uint))
         throw new Error("Wrong result type: " + result.type);
     if (result.value != expected)
         throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
 }
 
-function checkUint8(program, result, expected)
+function checkUchar(program, result, expected)
 {
-    if (!result.type.equals(program.intrinsics.uint8))
+    if (!result.type.equals(program.intrinsics.uchar))
         throw new Error("Wrong result type: " + result.type);
     if (result.value != expected)
         throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
@@ -187,7 +187,7 @@ tests.commentParsing = function() {
         runs over multiple lines */
         bool foo() { return true; }
     `);
-    checkBool(program, callFunction(program, "foo", [], []), true);
+    checkBool(program, callFunction(program, "foo", []), true);
 
     checkFail(
         () => doPrep(`
@@ -200,92 +200,92 @@ tests.commentParsing = function() {
 
 tests.literalBool = function() {
     let program = doPrep("bool foo() { return true; }");
-    checkBool(program, callFunction(program, "foo", [], []), true);
+    checkBool(program, callFunction(program, "foo", []), true);
 }
 
 tests.identityBool = function() {
     let program = doPrep("bool foo(bool x) { return x; }");
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false);
 }
 
 tests.intSimpleMath = function() {
     let program = doPrep("int foo(int x, int y) { return x + y; }");
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 12);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 12);
     program = doPrep("int foo(int x, int y) { return x - y; }");
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 2);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5), makeInt(program, 7)]), -2);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 2);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 7)]), -2);
     program = doPrep("int foo(int x, int y) { return x * y; }");
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 35);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, -5)]), -35);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 35);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -5)]), -35);
     program = doPrep("int foo(int x, int y) { return x / y; }");
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 2)]), 3);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, -2)]), -3);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 2)]), 3);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -2)]), -3);
 }
 
 tests.uintSimpleMath = function() {
     let program = doPrep("uint foo(uint x, uint y) { return x + y; }");
-    checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 12);
+    checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 12);
     program = doPrep("uint foo(uint x, uint y) { return x - y; }");
-    checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 2);
-    checkUint(program, callFunction(program, "foo", [], [makeUint(program, 5), makeUint(program, 7)]), 4294967294);
+    checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 2);
+    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 7)]), 4294967294);
     program = doPrep("uint foo(uint x, uint y) { return x * y; }");
-    checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 35);
+    checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 35);
     program = doPrep("uint foo(uint x, uint y) { return x / y; }");
-    checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 2)]), 3);
+    checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 2)]), 3);
 }
 
-tests.uint8SimpleMath = function() {
-    let program = doPrep("uint8 foo(uint8 x, uint8 y) { return x + y; }");
-    checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 12);
-    program = doPrep("uint8 foo(uint8 x, uint8 y) { return x - y; }");
-    checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 2);
-    checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 5), makeUint8(program, 7)]), 254);
-    program = doPrep("uint8 foo(uint8 x, uint8 y) { return x * y; }");
-    checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 35);
-    program = doPrep("uint8 foo(uint8 x, uint8 y) { return x / y; }");
-    checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 2)]), 3);
+tests.ucharSimpleMath = function() {
+    let program = doPrep("uchar foo(uchar x, uchar y) { return x + y; }");
+    checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 12);
+    program = doPrep("uchar foo(uchar x, uchar y) { return x - y; }");
+    checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 2);
+    checkUchar(program, callFunction(program, "foo", [makeUchar(program, 5), makeUchar(program, 7)]), 254);
+    program = doPrep("uchar foo(uchar x, uchar y) { return x * y; }");
+    checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 35);
+    program = doPrep("uchar foo(uchar x, uchar y) { return x / y; }");
+    checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 2)]), 3);
 }
 
 tests.equality = function() {
     let program = doPrep("bool foo(uint x, uint y) { return x == y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 7)]), true);
-    program = doPrep("bool foo(uint8 x, uint8 y) { return x == y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 7)]), true);
+    checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), false);
+    checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), true);
+    program = doPrep("bool foo(uchar x, uchar y) { return x == y; }");
+    checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), false);
+    checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), true);
     program = doPrep("bool foo(int x, int y) { return x == y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 7)]), true);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), false);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), true);
     program = doPrep("bool foo(bool x, bool y) { return x == y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true);
 }
 
 tests.logicalNegation = function()
 {
     let program = doPrep("bool foo(bool x) { return !x; }");
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), true);
 }
 
 tests.notEquality = function() {
     let program = doPrep("bool foo(uint x, uint y) { return x != y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 7)]), false);
-    program = doPrep("bool foo(uint8 x, uint8 y) { return x != y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 7)]), false);
+    checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), true);
+    checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), false);
+    program = doPrep("bool foo(uchar x, uchar y) { return x != y; }");
+    checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), true);
+    checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), false);
     program = doPrep("bool foo(int x, int y) { return x != y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 7)]), false);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), true);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), false);
     program = doPrep("bool foo(bool x, bool y) { return x != y; }");
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), false);
 }
 
 tests.equalityTypeFailure = function()
@@ -298,21 +298,13 @@ tests.equalityTypeFailure = function()
 tests.generalNegation = function()
 {
     let program = doPrep("bool foo(int x) { return !x; }");
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7)]), false);
-    checkBool(program, callFunction(program, "foo", [], [makeInt(program, 0)]), true);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 7)]), false);
+    checkBool(program, callFunction(program, "foo", [makeInt(program, 0)]), true);
 }
 
 tests.add1 = function() {
     let program = doPrep("int foo(int x) { return x + 1; }");
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
-}
-
-tests.simpleGeneric = function() {
-    let program = doPrep(`
-        T id<T>(T x) { return x; }
-        int foo(int x) { return id(x) + 1; }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 43);
 }
 
 tests.nameResolutionFailure = function()
@@ -331,7 +323,7 @@ tests.simpleVariable = function()
             return result;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42);
 }
 
 tests.simpleAssignment = function()
@@ -344,7 +336,7 @@ tests.simpleAssignment = function()
             return result;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42);
 }
 
 tests.simpleDefault = function()
@@ -356,7 +348,7 @@ tests.simpleDefault = function()
             return result;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], []), 0);
+    checkInt(program, callFunction(program, "foo", []), 0);
 }
 
 tests.simpleDereference = function()
@@ -369,7 +361,7 @@ tests.simpleDereference = function()
     `);
     let buffer = new EBuffer(1);
     buffer.set(0, 13);
-    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
+    checkInt(program, callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]), 13);
 }
 
 tests.dereferenceStore = function()
@@ -382,7 +374,7 @@ tests.dereferenceStore = function()
     `);
     let buffer = new EBuffer(1);
     buffer.set(0, 13);
-    callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]);
+    callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]);
     if (buffer.get(0) != 52)
         throw new Error("Expected buffer to contain 52 but it contains: " + buffer.get(0));
 }
@@ -396,10 +388,10 @@ tests.simpleMakePtr = function()
             return &x;
         }
     `);
-    let result = callFunction(program, "foo", [], []);
+    let result = callFunction(program, "foo", []);
     if (!result.type.isPtr)
         throw new Error("Return type is not a pointer: " + result.type);
-    if (!result.type.elementType.equals(program.intrinsics.int32))
+    if (!result.type.elementType.equals(program.intrinsics.int))
         throw new Error("Return type is not a pointer to an int: " + result.type);
     if (!(result.value instanceof EPtr))
         throw new Error("Return value is not an EPtr: " + result.value);
@@ -418,7 +410,7 @@ tests.threadArrayLoad = function()
     `);
     let buffer = new EBuffer(1);
     buffer.set(0, 89);
-    let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]);
+    let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
     checkInt(program, result, 89);
 }
 
@@ -432,7 +424,7 @@ tests.threadArrayLoadIntLiteral = function()
     `);
     let buffer = new EBuffer(1);
     buffer.set(0, 89);
-    let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]);
+    let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
     checkInt(program, result, 89);
 }
 
@@ -446,7 +438,7 @@ tests.deviceArrayLoad = function()
     `);
     let buffer = new EBuffer(1);
     buffer.set(0, 89);
-    let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "device", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]);
+    let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "device", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
     checkInt(program, result, 89);
 }
 
@@ -461,12 +453,12 @@ tests.threadArrayStore = function()
     let buffer = new EBuffer(1);
     buffer.set(0, 15);
     let arrayRef = TypedValue.box(
-        new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32),
+        new ArrayRefType(externalOrigin, "thread", program.intrinsics.int),
         new EArrayRef(new EPtr(buffer, 0), 1));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
     if (buffer.get(0) != 65)
         throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
     if (buffer.get(0) != -111)
         throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
 }
@@ -482,12 +474,12 @@ tests.deviceArrayStore = function()
     let buffer = new EBuffer(1);
     buffer.set(0, 15);
     let arrayRef = TypedValue.box(
-        new ArrayRefType(externalOrigin, "device", program.intrinsics.int32),
+        new ArrayRefType(externalOrigin, "device", program.intrinsics.int),
         new EArrayRef(new EPtr(buffer, 0), 1));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
     if (buffer.get(0) != 65)
         throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
     if (buffer.get(0) != -111)
         throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
 }
@@ -503,34 +495,16 @@ tests.deviceArrayStoreIntLiteral = function()
     let buffer = new EBuffer(1);
     buffer.set(0, 15);
     let arrayRef = TypedValue.box(
-        new ArrayRefType(externalOrigin, "device", program.intrinsics.int32),
+        new ArrayRefType(externalOrigin, "device", program.intrinsics.int),
         new EArrayRef(new EPtr(buffer, 0), 1));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
     if (buffer.get(0) != 65)
         throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
-    callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]);
+    callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
     if (buffer.get(0) != -111)
         throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
 }
 
-tests.simpleProtocol = function()
-{
-    let program = doPrep(`
-        protocol MyAddable {
-            MyAddable operator+(MyAddable, MyAddable);
-        }
-        T add<T:MyAddable>(T a, T b)
-        {
-            return a + b;
-        }
-        int foo(int x)
-        {
-            return add(x, 73);
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 45)]), 45 + 73);
-}
-
 tests.typeMismatchReturn = function()
 {
     checkFail(
@@ -584,13 +558,12 @@ tests.badAdd = function()
 {
     checkFail(
         () => doPrep(`
-            void bar<T>(T) { }
             void foo(int x, uint y)
             {
-                bar(x + y);
+                uint z = x + y;
             }
         `),
-        (e) => e instanceof WTypeError && e.message.indexOf("native int32 operator+<>(int32,int32)") != -1);
+        (e) => e instanceof WTypeError && e.message.indexOf("native int operator+(int,int)") != -1);
 }
 
 tests.lexerKeyword = function()
@@ -666,7 +639,7 @@ tests.simpleStruct = function()
     let buffer = new EBuffer(2);
     buffer.set(0, 62);
     buffer.set(1, 24);
-    let result = callFunction(program, "foo", [], [new TypedValue(structType, new EPtr(buffer, 0))]);
+    let result = callFunction(program, "foo", [new TypedValue(structType, new EPtr(buffer, 0))]);
     if (!result.type.equals(structType))
         throw new Error("Wrong result type: " + result.type);
     let x = result.ePtr.get(0);
@@ -677,57 +650,11 @@ tests.simpleStruct = function()
         throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
 }
 
-tests.genericStructInstance = function()
-{
-    let program = doPrep(`
-        struct Foo<T> {
-            T x;
-            T y;
-        }
-        Foo<int> foo(Foo<int> foo)
-        {
-            Foo<int> result;
-            result.x = foo.y;
-            result.y = foo.x;
-            return result;
-        }
-    `);
-    let structType = TypeRef.instantiate(program.types.get("Foo"), [program.intrinsics.int32]);
-    let buffer = new EBuffer(2);
-    buffer.set(0, 62);
-    buffer.set(1, 24);
-    let result = callFunction(program, "foo", [], [new TypedValue(structType, new EPtr(buffer, 0))]);
-    let x = result.ePtr.get(0);
-    let y = result.ePtr.get(1);
-    if (x != 24)
-        throw new Error("Wrong result for x: " + x + " (y = " + y + ")");
-    if (y != 62)
-        throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
-}
-
-tests.doubleGenericCallsDoubleGeneric = function()
-{
-    doPrep(`
-        void foo<T, U>(T, U) { }
-        void bar<V, W>(V x, W y) { foo(x, y); }
-    `);
-}
-
-tests.doubleGenericCallsSingleGeneric = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo<T>(T, T) { }
-            void bar<V, W>(V x, W y) { foo(x, y); }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
 tests.loadNull = function()
 {
     checkFail(
         () => doPrep(`
-            void sink<T>(T) { }
+            void sink(thread int* x) { }
             void foo() { sink(*null); }
         `),
         (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1);
@@ -747,10 +674,10 @@ tests.returnNull = function()
     let program = doPrep(`
         thread int* foo() { return null; }
     `);
-    let result = callFunction(program, "foo", [], []);
+    let result = callFunction(program, "foo", []);
     if (!result.type.isPtr)
         throw new Error("Return type is not a pointer: " + result.type);
-    if (!result.type.elementType.equals(program.intrinsics.int32))
+    if (!result.type.elementType.equals(program.intrinsics.int))
         throw new Error("Return type is not a pointer to an int: " + result.type);
     if (result.value != null)
         throw new Error("Return value is not null: " + result.value);
@@ -766,7 +693,7 @@ tests.dereferenceDefaultNull = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "foo", [], []),
+        () => callFunction(program, "foo", []),
         (e) => e instanceof WTrapError);
 }
 
@@ -780,7 +707,7 @@ tests.defaultInitializedNull = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "foo", [], []),
+        () => callFunction(program, "foo", []),
         (e) => e instanceof WTrapError);
 }
 
@@ -797,47 +724,15 @@ tests.passNullToPtrMonomorphic = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "bar", [], []),
+        () => callFunction(program, "bar", []),
         (e) => e instanceof WTrapError);
 }
 
-tests.passNullToPtrPolymorphic = function()
-{
-    checkFail(
-        () => doPrep(`
-            T foo<T>(thread T* ptr)
-            {
-                return *ptr;
-            }
-            int bar()
-            {
-                return foo(null);
-            }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
-tests.passNullToPolymorphic = function()
-{
-    checkFail(
-        () => doPrep(`
-            T foo<T>(T ptr)
-            {
-                return ptr;
-            }
-            int bar()
-            {
-                return foo(null);
-            }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
 tests.loadNullArrayRef = function()
 {
     checkFail(
         () => doPrep(`
-            void sink<T>(T) { }
+            void sink(thread int* x) { }
             void foo() { sink(null[0u]); }
         `),
         (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1);
@@ -857,10 +752,10 @@ tests.returnNullArrayRef = function()
     let program = doPrep(`
         thread int[] foo() { return null; }
     `);
-    let result = callFunction(program, "foo", [], []);
+    let result = callFunction(program, "foo", []);
     if (!result.type.isArrayRef)
         throw new Error("Return type is not an array reference: " + result.type);
-    if (!result.type.elementType.equals(program.intrinsics.int32))
+    if (!result.type.elementType.equals(program.intrinsics.int))
         throw new Error("Return type is not an int array reference: " + result.type);
     if (result.value != null)
         throw new Error("Return value is not null: " + result.value);
@@ -876,7 +771,7 @@ tests.dereferenceDefaultNullArrayRef = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "foo", [], []),
+        () => callFunction(program, "foo", []),
         (e) => e instanceof WTrapError);
 }
 
@@ -890,7 +785,7 @@ tests.defaultInitializedNullArrayRef = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "foo", [], []),
+        () => callFunction(program, "foo", []),
         (e) => e instanceof WTrapError);
 }
 
@@ -904,7 +799,7 @@ tests.defaultInitializedNullArrayRefIntLiteral = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "foo", [], []),
+        () => callFunction(program, "foo", []),
         (e) => e instanceof WTrapError);
 }
 
@@ -921,36 +816,20 @@ tests.passNullToPtrMonomorphicArrayRef = function()
         }
     `);
     checkFail(
-        () => callFunction(program, "bar", [], []),
+        () => callFunction(program, "bar", []),
         (e) => e instanceof WTrapError);
 }
 
-tests.passNullToPtrPolymorphicArrayRef = function()
-{
-    checkFail(
-        () => doPrep(`
-            T foo<T>(thread T[] ptr)
-            {
-                return ptr[0u];
-            }
-            int bar()
-            {
-                return foo(null);
-            }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
 tests.returnIntLiteralUint = function()
 {
     let program = doPrep("uint foo() { return 42; }");
-    checkNumber(program, callFunction(program, "foo", [], []), 42);
+    checkNumber(program, callFunction(program, "foo", []), 42);
 }
 
 tests.returnIntLiteralFloat = function()
 {
     let program = doPrep("float foo() { return 42; }");
-    checkNumber(program, callFunction(program, "foo", [], []), 42);
+    checkNumber(program, callFunction(program, "foo", []), 42);
 }
 
 tests.badIntLiteralForInt = function()
@@ -974,115 +853,6 @@ tests.badIntLiteralForFloat = function()
         (e) => e instanceof WSyntaxError);
 }
 
-tests.passNullAndNotNull = function()
-{
-    let program = doPrep(`
-        T bar<T>(device T* p, device T*)
-        {
-            return *p;
-        }
-        int foo(device int* p)
-        {
-            return bar(p, null);
-        }
-    `);
-    let buffer = new EBuffer(1);
-    buffer.set(0, 13);
-    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
-}
-
-tests.passNullAndNotNullFullPoly = function()
-{
-    let program = doPrep(`
-        T bar<T>(T p, T)
-        {
-            return p;
-        }
-        int foo(device int* p)
-        {
-            return *bar(p, null);
-        }
-    `);
-    let buffer = new EBuffer(1);
-    buffer.set(0, 13);
-    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
-}
-
-tests.passNullAndNotNullFullPolyReverse = function()
-{
-    let program = doPrep(`
-        T bar<T>(T, T p)
-        {
-            return p;
-        }
-        int foo(device int* p)
-        {
-            return *bar(null, p);
-        }
-    `);
-    let buffer = new EBuffer(1);
-    buffer.set(0, 13);
-    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
-}
-
-tests.nullTypeVariableUnify = function()
-{
-    let left = new NullType(externalOrigin);
-    let right = new TypeVariable(externalOrigin, "T", null);
-    if (left.equals(right))
-        throw new Error("Should not be equal but are: " + left + " and " + right);
-    if (right.equals(left))
-        throw new Error("Should not be equal but are: " + left + " and " + right);
-    
-    function everyOrder(array, callback)
-    {
-        function recurse(array, callback, order)
-        {
-            if (!array.length)
-                return callback.call(null, order);
-            
-            for (let i = 0; i < array.length; ++i) {
-                let nextArray = array.concat();
-                nextArray.splice(i, 1);
-                recurse(nextArray, callback, order.concat([array[i]]));
-            }
-        }
-        
-        recurse(array, callback, []);
-    }
-    
-    function everyPair(things)
-    {
-        let result = [];
-        for (let i = 0; i < things.length; ++i) {
-            for (let j = 0; j < things.length; ++j) {
-                if (i != j)
-                    result.push([things[i], things[j]]);
-            }
-        }
-        return result;
-    }
-    
-    everyOrder(
-        everyPair(["nullType", "variableType", "ptrType"]),
-        order => {
-            let types = {};
-            types.nullType = new NullType(externalOrigin);
-            types.variableType = new TypeVariable(externalOrigin, "T", null);
-            types.ptrType = new PtrType(externalOrigin, "constant", new NativeType(externalOrigin, "foo_t", []));
-            let unificationContext = new UnificationContext([types.variableType]);
-            for (let [leftName, rightName] of order) {
-                let left = types[leftName];
-                let right = types[rightName];
-                let result = left.unify(unificationContext, right);
-                if (!result)
-                    throw new Error("In order " + order + " cannot unify " + left + " with " + right);
-            }
-            if (!unificationContext.verify().result)
-                throw new Error("In order " + order.map(value => "(" + value + ")") + " cannot verify");
-        });
-}
-
 tests.doubleNot = function()
 {
     let program = doPrep(`
@@ -1091,130 +861,22 @@ tests.doubleNot = function()
             return !!x;
         }
     `);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), true);
-    checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), false);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true);
+    checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false);
 }
 
 tests.simpleRecursion = function()
 {
     checkFail(
         () => doPrep(`
-            void foo<T>(T x)
+            void foo(int x)
             {
-                foo(&x);
+                foo(x);
             }
         `),
         (e) => e instanceof WTypeError);
 }
 
-tests.protocolMonoSigPolyDef = function()
-{
-    let program = doPrep(`
-        struct IntAnd<T> {
-            int first;
-            T second;
-        }
-        IntAnd<T> intAnd<T>(int first, T second)
-        {
-            IntAnd<T> result;
-            result.first = first;
-            result.second = second;
-            return result;
-        }
-        protocol IntAndable {
-            IntAnd<int> intAnd(IntAndable, int);
-        }
-        int foo<T:IntAndable>(T first, int second)
-        {
-            IntAnd<int> result = intAnd(first, second);
-            return result.first + result.second;
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12);
-}
-
-tests.protocolPolySigPolyDef = function()
-{
-    let program = doPrep(`
-        struct IntAnd<T> {
-            int first;
-            T second;
-        }
-        IntAnd<T> intAnd<T>(int first, T second)
-        {
-            IntAnd<T> result;
-            result.first = first;
-            result.second = second;
-            return result;
-        }
-        protocol IntAndable {
-            IntAnd<T> intAnd<T>(IntAndable, T);
-        }
-        int foo<T:IntAndable>(T first, int second)
-        {
-            IntAnd<int> result = intAnd(first, second);
-            return result.first + result.second;
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12);
-}
-
-tests.protocolDoublePolySigDoublePolyDef = function()
-{
-    let program = doPrep(`
-        struct IntAnd<T, U> {
-            int first;
-            T second;
-            U third;
-        }
-        IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
-        {
-            IntAnd<T, U> result;
-            result.first = first;
-            result.second = second;
-            result.third = third;
-            return result;
-        }
-        protocol IntAndable {
-            IntAnd<T, U> intAnd<T, U>(IntAndable, T, U);
-        }
-        int foo<T:IntAndable>(T first, int second, int third)
-        {
-            IntAnd<int, int> result = intAnd(first, second, third);
-            return result.first + result.second + result.third;
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39);
-}
-
-tests.protocolDoublePolySigDoublePolyDefExplicit = function()
-{
-    let program = doPrep(`
-        struct IntAnd<T, U> {
-            int first;
-            T second;
-            U third;
-        }
-        IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
-        {
-            IntAnd<T, U> result;
-            result.first = first;
-            result.second = second;
-            result.third = third;
-            return result;
-        }
-        protocol IntAndable {
-            IntAnd<T, U> intAnd<T, U>(IntAndable, T, U);
-        }
-        int foo<T:IntAndable>(T first, int second, int third)
-        {
-            IntAnd<int, int> result = intAnd<int, int>(first, second, third);
-            return result.first + result.second + result.third;
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39);
-}
-
 tests.variableShadowing = function()
 {
     let program = doPrep(`
@@ -1229,7 +891,7 @@ tests.variableShadowing = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], []), 8);
+    checkInt(program, callFunction(program, "foo", []), 8);
     program = doPrep(`
         int foo()
         {
@@ -1242,7 +904,7 @@ tests.variableShadowing = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], []), 7);
+    checkInt(program, callFunction(program, "foo", []), 7);
 }
 
 tests.ifStatement = function()
@@ -1257,13 +919,13 @@ tests.ifStatement = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6);
 }
 
 tests.ifElseStatement = function()
@@ -1280,13 +942,13 @@ tests.ifElseStatement = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9);
 }
 
 tests.ifElseIfStatement = function()
@@ -1303,13 +965,13 @@ tests.ifElseIfStatement = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6);
 }
 
 tests.ifElseIfElseStatement = function()
@@ -1328,13 +990,13 @@ tests.ifElseIfElseStatement = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10);
 }
 
 tests.returnIf = function()
@@ -1387,13 +1049,13 @@ tests.returnIf = function()
             }
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 10);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1419,13 +1081,13 @@ tests.returnIf = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1449,7 +1111,7 @@ tests.returnIf = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 6);
 }
 
 tests.simpleWhile = function()
@@ -1462,71 +1124,7 @@ tests.simpleWhile = function()
             return x;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 16);
-}
-
-tests.protocolMonoPolySigDoublePolyDefExplicit = function()
-{
-    checkFail(
-        () => {
-            let program = doPrep(`
-                struct IntAnd<T, U> {
-                    int first;
-                    T second;
-                    U third;
-                }
-                IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
-                {
-                    IntAnd<T, U> result;
-                    result.first = first;
-                    result.second = second;
-                    result.third = third;
-                    return result;
-                }
-                protocol IntAndable {
-                    IntAnd<T, int> intAnd<T>(IntAndable, T, int);
-                }
-                int foo<T:IntAndable>(T first, int second, int third)
-                {
-                    IntAnd<int, int> result = intAnd<int>(first, second, third);
-                    return result.first + result.second + result.third;
-                }
-            `);
-            callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]);
-        },
-        (e) => e instanceof WTypeError);
-}
-
-tests.ambiguousOverloadSimple = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo<T>(int, T) { }
-            void foo<T>(T, int) { }
-            void bar(int a, int b) { foo(a, b); }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
-tests.ambiguousOverloadOverlapping = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo<T>(int, T) { }
-            void foo<T>(T, T) { }
-            void bar(int a, int b) { foo(a, b); }
-        `),
-        (e) => e instanceof WTypeError);
-}
-
-tests.ambiguousOverloadTieBreak = function()
-{
-    doPrep(`
-        void foo<T>(int, T) { }
-        void foo<T>(T, T) { }
-        void foo(int, int) { }
-        void bar(int a, int b) { foo(a, b); }
-    `);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 16);
 }
 
 tests.intOverloadResolution = function()
@@ -1537,7 +1135,7 @@ tests.intOverloadResolution = function()
         int foo(float) { return 3; }
         int bar() { return foo(42); }
     `);
-    checkInt(program, callFunction(program, "bar", [], []), 1);
+    checkInt(program, callFunction(program, "bar", []), 1);
 }
 
 tests.intOverloadResolutionReverseOrder = function()
@@ -1548,83 +1146,7 @@ tests.intOverloadResolutionReverseOrder = function()
         int foo(int) { return 1; }
         int bar() { return foo(42); }
     `);
-    checkInt(program, callFunction(program, "bar", [], []), 1);
-}
-
-tests.intOverloadResolutionGeneric = function()
-{
-    let program = doPrep(`
-        int foo(int) { return 1; }
-        int foo<T>(T) { return 2; }
-        int bar() { return foo(42); }
-    `);
-    checkInt(program, callFunction(program, "bar", [], []), 1);
-}
-
-tests.intLiteralGeneric = function()
-{
-    let program = doPrep(`
-        int foo<T>(T x) { return 3478; }
-        int bar() { return foo(42); }
-    `);
-    checkInt(program, callFunction(program, "bar", [], []), 3478);
-}
-
-tests.intLiteralGenericWithProtocols = function()
-{
-    let program = doPrep(`
-        protocol MyConvertibleToInt {
-            operator int(MyConvertibleToInt);
-        }
-        int foo<T:MyConvertibleToInt>(T x) { return int(x); }
-        int bar() { return foo(42); }
-    `);
-    checkInt(program, callFunction(program, "bar", [], []), 42);
-}
-
-tests.uintLiteralGeneric = function()
-{
-    let program = doPrep(`
-        int foo<T>(T x) { return 3478; }
-        int bar() { return foo(42u); }
-    `);
-    checkInt(program, callFunction(program, "bar", [], []), 3478);
-}
-
-tests.uintLiteralGenericWithProtocols = function()
-{
-    let program = doPrep(`
-        protocol MyConvertibleToUint {
-            operator uint(MyConvertibleToUint);
-        }
-        uint foo<T:MyConvertibleToUint>(T x) { return uint(x); }
-        uint bar() { return foo(42u); }
-    `);
-    checkUint(program, callFunction(program, "bar", [], []), 42);
-}
-
-tests.intLiteralGenericSpecific = function()
-{
-    let program = doPrep(`
-        T foo<T>(T x) { return x; }
-        int bar() { return foo(int(42)); }
-    `);
-    checkInt(program, callFunction(program, "bar", [], []), 42);
-}
-
-tests.simpleConstexpr = function()
-{
-    let program = doPrep(`
-        int foo<int a>(int b)
-        {
-            return a + b;
-        }
-        int bar(int b)
-        {
-            return foo<42>(b);
-        }
-    `);
-    checkInt(program, callFunction(program, "bar", [], [makeInt(program, 58)]), 58 + 42);
+    checkInt(program, callFunction(program, "bar", []), 1);
 }
 
 tests.break = function()
@@ -1640,8 +1162,8 @@ tests.break = function()
             return x;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 10)]), 20);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 20);
     program = doPrep(`
         int foo(int x)
         {
@@ -1658,8 +1180,8 @@ tests.break = function()
             
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 7);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 10)]), 19);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 19);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1695,7 +1217,7 @@ tests.break = function()
                 return x;
             }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 7);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7);
     program = doPrep(`
             int foo(int x)
             {
@@ -1705,7 +1227,7 @@ tests.break = function()
                 return x;
             }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 1);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 1);
     program = doPrep(`
             int foo()
             {
@@ -1714,7 +1236,7 @@ tests.break = function()
                 }
             }
     `);
-    checkInt(program, callFunction(program, "foo", [], []), 7);
+    checkInt(program, callFunction(program, "foo", []), 7);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1743,7 +1265,7 @@ tests.continue = function()
             return x;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 18);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 18);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1769,8 +1291,8 @@ tests.doWhile = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 11)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 11)]), 8);
     program = doPrep(`
         int foo(int x)
         {
@@ -1782,7 +1304,7 @@ tests.doWhile = function()
             return y;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
     program = doPrep(`
         int foo(int x)
         {
@@ -1798,7 +1320,7 @@ tests.doWhile = function()
             return sum;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 19);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 19);
 }
 
 tests.forLoop = function()
@@ -1814,9 +1336,9 @@ tests.forLoop = function()
             return sum;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
     program = doPrep(`
         int foo(int x)
         {
@@ -1827,9 +1349,9 @@ tests.forLoop = function()
             return sum;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
     program = doPrep(`
         int foo(int x)
         {
@@ -1841,9 +1363,9 @@ tests.forLoop = function()
             return sum;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
     program = doPrep(`
         int foo(int x)
         {
@@