diff --git a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs index 480c616c5a..8692affa79 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs @@ -173,13 +173,13 @@ private static void PrintGeneratedQs(IEnumerable evaluatedTree, Com if (Options.IsCodeSnippet(file)) { var subtree = evaluatedTree.Select(ns => FilterBySourceFile.Apply(ns, file)).Where(ns => ns.Elements.Any()); - var code = new string[] { "" }.Concat(StripSnippetWrapping(subtree).Select(SyntaxTreeToQs.Default.ToCode)); + var code = new string[] { "" }.Concat(StripSnippetWrapping(subtree).Select(SyntaxTreeToQsharp.Default.ToCode)); logger.Log(InformationCode.FormattedQsCode, Enumerable.Empty(), messageParam: code.ToArray()); } else { var imports = evaluatedTree.ToImmutableDictionary(ns => ns.Name, ns => compilation.OpenDirectives(file, ns.Name).ToImmutableArray()); - SyntaxTreeToQs.Apply(out List, string>> generated, evaluatedTree, (file, imports)); + SyntaxTreeToQsharp.Apply(out List, string>> generated, evaluatedTree, (file, imports)); var code = new string[] { "" }.Concat(generated.Single().Values.Select(nsCode => $"{nsCode}{Environment.NewLine}")); logger.Log(InformationCode.FormattedQsCode, Enumerable.Empty(), file.Value, messageParam: code.ToArray()); }; diff --git a/src/QsCompiler/CommandLineTool/Commands/Format.cs b/src/QsCompiler/CommandLineTool/Commands/Format.cs index d9864bbd0b..59494a4097 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Format.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Format.cs @@ -73,13 +73,13 @@ private static IEnumerable GenerateQsCode(Compilation compilation, NonNu if (Options.IsCodeSnippet(file)) { var subtree = compilation.SyntaxTree.Values.Select(ns => FilterBySourceFile.Apply(ns, file)).Where(ns => ns.Elements.Any()); - return DiagnoseCompilation.StripSnippetWrapping(subtree).Select(SyntaxTreeToQs.Default.ToCode); + return DiagnoseCompilation.StripSnippetWrapping(subtree).Select(SyntaxTreeToQsharp.Default.ToCode); } else { var imports = compilation.SyntaxTree.Values .ToImmutableDictionary(ns => ns.Name, ns => compilation.OpenDirectives(file, ns.Name).ToImmutableArray()); - var success = SyntaxTreeToQs.Apply(out List, string>> generated, compilation.SyntaxTree.Values, (file, imports)); + var success = SyntaxTreeToQsharp.Apply(out List, string>> generated, compilation.SyntaxTree.Values, (file, imports)); if (!success) logger?.Log(WarningCode.UnresolvedItemsInGeneratedQs, Enumerable.Empty(), file.Value); return generated.Single().Select(entry => diff --git a/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs b/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs index e9f3a868fc..aee6fbebf4 100644 --- a/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs +++ b/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs @@ -220,7 +220,7 @@ private static IEnumerable OpenDirectiveSuggestions(this FileContentMa string CharacteristicsAnnotation(Characteristics c) { - var charEx = SyntaxTreeToQs.CharacteristicsExpression(SymbolResolution.ResolveCharacteristics(c)); + var charEx = SyntaxTreeToQsharp.CharacteristicsExpression(SymbolResolution.ResolveCharacteristics(c)); return charEx == null ? "" : $"{Keywords.qsCharacteristics.id} {charEx}"; } diff --git a/src/QsCompiler/Compiler/RewriteSteps/ClassicallyControlled.cs b/src/QsCompiler/Compiler/RewriteSteps/ClassicallyControlled.cs index dd7088f28f..01410bf9ff 100644 --- a/src/QsCompiler/Compiler/RewriteSteps/ClassicallyControlled.cs +++ b/src/QsCompiler/Compiler/RewriteSteps/ClassicallyControlled.cs @@ -5,7 +5,7 @@ using System.Linq; using Microsoft.Quantum.QsCompiler.DataTypes; using Microsoft.Quantum.QsCompiler.SyntaxTree; -using Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlledTransformation; +using Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlled; namespace Microsoft.Quantum.QsCompiler.BuiltInRewriteSteps @@ -28,7 +28,7 @@ public ClassicallyControlled() public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { - transformed = ClassicallyControlledTransformation.Apply(compilation); + transformed = ReplaceClassicalControl.Apply(compilation); return true; } diff --git a/src/QsCompiler/Compiler/RewriteSteps/IntrinsicResolution.cs b/src/QsCompiler/Compiler/RewriteSteps/IntrinsicResolution.cs index 01acc81c90..724efbb601 100644 --- a/src/QsCompiler/Compiler/RewriteSteps/IntrinsicResolution.cs +++ b/src/QsCompiler/Compiler/RewriteSteps/IntrinsicResolution.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Microsoft.Quantum.QsCompiler.SyntaxTree; -using Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolutionTransformation; +using Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolution; namespace Microsoft.Quantum.QsCompiler.BuiltInRewriteSteps @@ -35,7 +35,7 @@ public IntrinsicResolution(QsCompilation environment) public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { - transformed = IntrinsicResolutionTransformation.Apply(this.Environment, compilation); + transformed = ReplaceWithTargetIntrinsics.Apply(this.Environment, compilation); return true; } diff --git a/src/QsCompiler/Compiler/RewriteSteps/Monomorphization.cs b/src/QsCompiler/Compiler/RewriteSteps/Monomorphization.cs index 333593163d..e510b22b0e 100644 --- a/src/QsCompiler/Compiler/RewriteSteps/Monomorphization.cs +++ b/src/QsCompiler/Compiler/RewriteSteps/Monomorphization.cs @@ -4,8 +4,8 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Quantum.QsCompiler.SyntaxTree; -using Microsoft.Quantum.QsCompiler.Transformations.MonomorphizationTransformation; -using Microsoft.Quantum.QsCompiler.Transformations.MonomorphizationValidationTransformation; +using Microsoft.Quantum.QsCompiler.Transformations.Monomorphization; +using Microsoft.Quantum.QsCompiler.Transformations.Monomorphization.Validation; namespace Microsoft.Quantum.QsCompiler.BuiltInRewriteSteps @@ -33,7 +33,7 @@ public Monomorphization() public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { - transformed = MonomorphizationTransformation.Apply(compilation); + transformed = Monomorphize.Apply(compilation); return true; } @@ -42,7 +42,7 @@ public bool PreconditionVerification(QsCompilation compilation) => public bool PostconditionVerification(QsCompilation compilation) { - try { MonomorphizationValidationTransformation.Apply(compilation); } + try { ValidateMonomorphization.Apply(compilation); } catch { return false; } return true; } diff --git a/src/QsCompiler/Core/ExpressionTransformation.fs b/src/QsCompiler/Core/ExpressionTransformation.fs index 828c1b5335..3c530ad83d 100644 --- a/src/QsCompiler/Core/ExpressionTransformation.fs +++ b/src/QsCompiler/Core/ExpressionTransformation.fs @@ -46,304 +46,287 @@ type ExpressionKindTransformationBase internal (options : TransformationOptions, new () = new ExpressionKindTransformationBase (TransformationOptions.Default) - // methods invoked before selective expressions - - abstract member beforeCallLike : TypedExpression * TypedExpression -> TypedExpression * TypedExpression - default this.beforeCallLike (method, arg) = (method, arg) - - abstract member beforeFunctorApplication : TypedExpression -> TypedExpression - default this.beforeFunctorApplication ex = ex - - abstract member beforeModifierApplication : TypedExpression -> TypedExpression - default this.beforeModifierApplication ex = ex - - abstract member beforeBinaryOperatorExpression : TypedExpression * TypedExpression -> TypedExpression * TypedExpression - default this.beforeBinaryOperatorExpression (lhs, rhs) = (lhs, rhs) - - abstract member beforeUnaryOperatorExpression : TypedExpression -> TypedExpression - default this.beforeUnaryOperatorExpression ex = ex - - // nodes containing subexpressions or subtypes - abstract member onIdentifier : Identifier * QsNullable> -> ExpressionKind - default this.onIdentifier (sym, tArgs) = - let tArgs = tArgs |> QsNullable<_>.Map (fun ts -> ts |> Seq.map this.Types.Transform |> ImmutableArray.CreateRange) + abstract member OnIdentifier : Identifier * QsNullable> -> ExpressionKind + default this.OnIdentifier (sym, tArgs) = + let tArgs = tArgs |> QsNullable<_>.Map (fun ts -> ts |> Seq.map this.Types.OnType |> ImmutableArray.CreateRange) Identifier |> Node.BuildOr InvalidExpr (sym, tArgs) - abstract member onOperationCall : TypedExpression * TypedExpression -> ExpressionKind - default this.onOperationCall (method, arg) = - let method, arg = this.Expressions.Transform method, this.Expressions.Transform arg + abstract member OnOperationCall : TypedExpression * TypedExpression -> ExpressionKind + default this.OnOperationCall (method, arg) = + let method, arg = this.Expressions.OnTypedExpression method, this.Expressions.OnTypedExpression arg CallLikeExpression |> Node.BuildOr InvalidExpr (method, arg) - abstract member onFunctionCall : TypedExpression * TypedExpression -> ExpressionKind - default this.onFunctionCall (method, arg) = - let method, arg = this.Expressions.Transform method, this.Expressions.Transform arg + abstract member OnFunctionCall : TypedExpression * TypedExpression -> ExpressionKind + default this.OnFunctionCall (method, arg) = + let method, arg = this.Expressions.OnTypedExpression method, this.Expressions.OnTypedExpression arg CallLikeExpression |> Node.BuildOr InvalidExpr (method, arg) - abstract member onPartialApplication : TypedExpression * TypedExpression -> ExpressionKind - default this.onPartialApplication (method, arg) = - let method, arg = this.Expressions.Transform method, this.Expressions.Transform arg + abstract member OnPartialApplication : TypedExpression * TypedExpression -> ExpressionKind + default this.OnPartialApplication (method, arg) = + let method, arg = this.Expressions.OnTypedExpression method, this.Expressions.OnTypedExpression arg CallLikeExpression |> Node.BuildOr InvalidExpr (method, arg) - abstract member onAdjointApplication : TypedExpression -> ExpressionKind - default this.onAdjointApplication ex = - let ex = this.Expressions.Transform ex + abstract member OnCallLikeExpression : TypedExpression * TypedExpression -> ExpressionKind + default this.OnCallLikeExpression (method, arg) = + match method.ResolvedType.Resolution with + | _ when TypedExpression.IsPartialApplication (CallLikeExpression (method, arg)) -> this.OnPartialApplication (method, arg) + | ExpressionType.Operation _ -> this.OnOperationCall (method, arg) + | _ -> this.OnFunctionCall (method, arg) + + abstract member OnAdjointApplication : TypedExpression -> ExpressionKind + default this.OnAdjointApplication ex = + let ex = this.Expressions.OnTypedExpression ex AdjointApplication |> Node.BuildOr InvalidExpr ex - abstract member onControlledApplication : TypedExpression -> ExpressionKind - default this.onControlledApplication ex = - let ex = this.Expressions.Transform ex + abstract member OnControlledApplication : TypedExpression -> ExpressionKind + default this.OnControlledApplication ex = + let ex = this.Expressions.OnTypedExpression ex ControlledApplication |> Node.BuildOr InvalidExpr ex - abstract member onUnwrapApplication : TypedExpression -> ExpressionKind - default this.onUnwrapApplication ex = - let ex = this.Expressions.Transform ex + abstract member OnUnwrapApplication : TypedExpression -> ExpressionKind + default this.OnUnwrapApplication ex = + let ex = this.Expressions.OnTypedExpression ex UnwrapApplication |> Node.BuildOr InvalidExpr ex - abstract member onValueTuple : ImmutableArray -> ExpressionKind - default this.onValueTuple vs = - let values = vs |> Seq.map this.Expressions.Transform |> ImmutableArray.CreateRange + abstract member OnValueTuple : ImmutableArray -> ExpressionKind + default this.OnValueTuple vs = + let values = vs |> Seq.map this.Expressions.OnTypedExpression |> ImmutableArray.CreateRange ValueTuple |> Node.BuildOr InvalidExpr values - abstract member onArrayItem : TypedExpression * TypedExpression -> ExpressionKind - default this.onArrayItem (arr, idx) = - let arr, idx = this.Expressions.Transform arr, this.Expressions.Transform idx + abstract member OnArrayItem : TypedExpression * TypedExpression -> ExpressionKind + default this.OnArrayItem (arr, idx) = + let arr, idx = this.Expressions.OnTypedExpression arr, this.Expressions.OnTypedExpression idx ArrayItem |> Node.BuildOr InvalidExpr (arr, idx) - abstract member onNamedItem : TypedExpression * Identifier -> ExpressionKind - default this.onNamedItem (ex, acc) = - let ex = this.Expressions.Transform ex + abstract member OnNamedItem : TypedExpression * Identifier -> ExpressionKind + default this.OnNamedItem (ex, acc) = + let ex = this.Expressions.OnTypedExpression ex NamedItem |> Node.BuildOr InvalidExpr (ex, acc) - abstract member onValueArray : ImmutableArray -> ExpressionKind - default this.onValueArray vs = - let values = vs |> Seq.map this.Expressions.Transform |> ImmutableArray.CreateRange + abstract member OnValueArray : ImmutableArray -> ExpressionKind + default this.OnValueArray vs = + let values = vs |> Seq.map this.Expressions.OnTypedExpression |> ImmutableArray.CreateRange ValueArray |> Node.BuildOr InvalidExpr values - abstract member onNewArray : ResolvedType * TypedExpression -> ExpressionKind - default this.onNewArray (bt, idx) = - let bt, idx = this.Types.Transform bt, this.Expressions.Transform idx + abstract member OnNewArray : ResolvedType * TypedExpression -> ExpressionKind + default this.OnNewArray (bt, idx) = + let bt, idx = this.Types.OnType bt, this.Expressions.OnTypedExpression idx NewArray |> Node.BuildOr InvalidExpr (bt, idx) - abstract member onStringLiteral : NonNullable * ImmutableArray -> ExpressionKind - default this.onStringLiteral (s, exs) = - let exs = exs |> Seq.map this.Expressions.Transform |> ImmutableArray.CreateRange + abstract member OnStringLiteral : NonNullable * ImmutableArray -> ExpressionKind + default this.OnStringLiteral (s, exs) = + let exs = exs |> Seq.map this.Expressions.OnTypedExpression |> ImmutableArray.CreateRange StringLiteral |> Node.BuildOr InvalidExpr (s, exs) - abstract member onRangeLiteral : TypedExpression * TypedExpression -> ExpressionKind - default this.onRangeLiteral (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnRangeLiteral : TypedExpression * TypedExpression -> ExpressionKind + default this.OnRangeLiteral (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs RangeLiteral |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onCopyAndUpdateExpression : TypedExpression * TypedExpression * TypedExpression -> ExpressionKind - default this.onCopyAndUpdateExpression (lhs, accEx, rhs) = - let lhs, accEx, rhs = this.Expressions.Transform lhs, this.Expressions.Transform accEx, this.Expressions.Transform rhs + abstract member OnCopyAndUpdateExpression : TypedExpression * TypedExpression * TypedExpression -> ExpressionKind + default this.OnCopyAndUpdateExpression (lhs, accEx, rhs) = + let lhs, accEx, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression accEx, this.Expressions.OnTypedExpression rhs CopyAndUpdate |> Node.BuildOr InvalidExpr (lhs, accEx, rhs) - abstract member onConditionalExpression : TypedExpression * TypedExpression * TypedExpression -> ExpressionKind - default this.onConditionalExpression (cond, ifTrue, ifFalse) = - let cond, ifTrue, ifFalse = this.Expressions.Transform cond, this.Expressions.Transform ifTrue, this.Expressions.Transform ifFalse + abstract member OnConditionalExpression : TypedExpression * TypedExpression * TypedExpression -> ExpressionKind + default this.OnConditionalExpression (cond, ifTrue, ifFalse) = + let cond, ifTrue, ifFalse = this.Expressions.OnTypedExpression cond, this.Expressions.OnTypedExpression ifTrue, this.Expressions.OnTypedExpression ifFalse CONDITIONAL |> Node.BuildOr InvalidExpr (cond, ifTrue, ifFalse) - abstract member onEquality : TypedExpression * TypedExpression -> ExpressionKind - default this.onEquality (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnEquality : TypedExpression * TypedExpression -> ExpressionKind + default this.OnEquality (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs EQ |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onInequality : TypedExpression * TypedExpression -> ExpressionKind - default this.onInequality (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnInequality : TypedExpression * TypedExpression -> ExpressionKind + default this.OnInequality (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs NEQ |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLessThan : TypedExpression * TypedExpression -> ExpressionKind - default this.onLessThan (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnLessThan : TypedExpression * TypedExpression -> ExpressionKind + default this.OnLessThan (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs LT |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLessThanOrEqual : TypedExpression * TypedExpression -> ExpressionKind - default this.onLessThanOrEqual (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnLessThanOrEqual : TypedExpression * TypedExpression -> ExpressionKind + default this.OnLessThanOrEqual (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs LTE |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onGreaterThan : TypedExpression * TypedExpression -> ExpressionKind - default this.onGreaterThan (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnGreaterThan : TypedExpression * TypedExpression -> ExpressionKind + default this.OnGreaterThan (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs GT |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onGreaterThanOrEqual : TypedExpression * TypedExpression -> ExpressionKind - default this.onGreaterThanOrEqual (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnGreaterThanOrEqual : TypedExpression * TypedExpression -> ExpressionKind + default this.OnGreaterThanOrEqual (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs GTE |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLogicalAnd : TypedExpression * TypedExpression -> ExpressionKind - default this.onLogicalAnd (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnLogicalAnd : TypedExpression * TypedExpression -> ExpressionKind + default this.OnLogicalAnd (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs AND |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLogicalOr : TypedExpression * TypedExpression -> ExpressionKind - default this.onLogicalOr (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnLogicalOr : TypedExpression * TypedExpression -> ExpressionKind + default this.OnLogicalOr (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs OR |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onAddition : TypedExpression * TypedExpression -> ExpressionKind - default this.onAddition (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnAddition : TypedExpression * TypedExpression -> ExpressionKind + default this.OnAddition (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs ADD |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onSubtraction : TypedExpression * TypedExpression -> ExpressionKind - default this.onSubtraction (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnSubtraction : TypedExpression * TypedExpression -> ExpressionKind + default this.OnSubtraction (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs SUB |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onMultiplication : TypedExpression * TypedExpression -> ExpressionKind - default this.onMultiplication (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnMultiplication : TypedExpression * TypedExpression -> ExpressionKind + default this.OnMultiplication (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs MUL |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onDivision : TypedExpression * TypedExpression -> ExpressionKind - default this.onDivision (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnDivision : TypedExpression * TypedExpression -> ExpressionKind + default this.OnDivision (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs DIV |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onExponentiate : TypedExpression * TypedExpression -> ExpressionKind - default this.onExponentiate (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnExponentiate : TypedExpression * TypedExpression -> ExpressionKind + default this.OnExponentiate (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs POW |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onModulo : TypedExpression * TypedExpression -> ExpressionKind - default this.onModulo (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnModulo : TypedExpression * TypedExpression -> ExpressionKind + default this.OnModulo (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs MOD |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLeftShift : TypedExpression * TypedExpression -> ExpressionKind - default this.onLeftShift (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnLeftShift : TypedExpression * TypedExpression -> ExpressionKind + default this.OnLeftShift (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs LSHIFT |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onRightShift : TypedExpression * TypedExpression -> ExpressionKind - default this.onRightShift (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnRightShift : TypedExpression * TypedExpression -> ExpressionKind + default this.OnRightShift (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs RSHIFT |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onBitwiseExclusiveOr : TypedExpression * TypedExpression -> ExpressionKind - default this.onBitwiseExclusiveOr (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnBitwiseExclusiveOr : TypedExpression * TypedExpression -> ExpressionKind + default this.OnBitwiseExclusiveOr (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs BXOR |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onBitwiseOr : TypedExpression * TypedExpression -> ExpressionKind - default this.onBitwiseOr (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnBitwiseOr : TypedExpression * TypedExpression -> ExpressionKind + default this.OnBitwiseOr (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs BOR |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onBitwiseAnd : TypedExpression * TypedExpression -> ExpressionKind - default this.onBitwiseAnd (lhs, rhs) = - let lhs, rhs = this.Expressions.Transform lhs, this.Expressions.Transform rhs + abstract member OnBitwiseAnd : TypedExpression * TypedExpression -> ExpressionKind + default this.OnBitwiseAnd (lhs, rhs) = + let lhs, rhs = this.Expressions.OnTypedExpression lhs, this.Expressions.OnTypedExpression rhs BAND |> Node.BuildOr InvalidExpr (lhs, rhs) - abstract member onLogicalNot : TypedExpression -> ExpressionKind - default this.onLogicalNot ex = - let ex = this.Expressions.Transform ex + abstract member OnLogicalNot : TypedExpression -> ExpressionKind + default this.OnLogicalNot ex = + let ex = this.Expressions.OnTypedExpression ex NOT |> Node.BuildOr InvalidExpr ex - abstract member onNegative : TypedExpression -> ExpressionKind - default this.onNegative ex = - let ex = this.Expressions.Transform ex + abstract member OnNegative : TypedExpression -> ExpressionKind + default this.OnNegative ex = + let ex = this.Expressions.OnTypedExpression ex NEG |> Node.BuildOr InvalidExpr ex - abstract member onBitwiseNot : TypedExpression -> ExpressionKind - default this.onBitwiseNot ex = - let ex = this.Expressions.Transform ex + abstract member OnBitwiseNot : TypedExpression -> ExpressionKind + default this.OnBitwiseNot ex = + let ex = this.Expressions.OnTypedExpression ex BNOT |> Node.BuildOr InvalidExpr ex // leaf nodes - abstract member onUnitValue : unit -> ExpressionKind - default this.onUnitValue () = ExpressionKind.UnitValue + abstract member OnUnitValue : unit -> ExpressionKind + default this.OnUnitValue () = ExpressionKind.UnitValue - abstract member onMissingExpression : unit -> ExpressionKind - default this.onMissingExpression () = MissingExpr + abstract member OnMissingExpression : unit -> ExpressionKind + default this.OnMissingExpression () = MissingExpr - abstract member onInvalidExpression : unit -> ExpressionKind - default this.onInvalidExpression () = InvalidExpr + abstract member OnInvalidExpression : unit -> ExpressionKind + default this.OnInvalidExpression () = InvalidExpr - abstract member onIntLiteral : int64 -> ExpressionKind - default this.onIntLiteral i = IntLiteral i + abstract member OnIntLiteral : int64 -> ExpressionKind + default this.OnIntLiteral i = IntLiteral i - abstract member onBigIntLiteral : BigInteger -> ExpressionKind - default this.onBigIntLiteral b = BigIntLiteral b + abstract member OnBigIntLiteral : BigInteger -> ExpressionKind + default this.OnBigIntLiteral b = BigIntLiteral b - abstract member onDoubleLiteral : double -> ExpressionKind - default this.onDoubleLiteral d = DoubleLiteral d + abstract member OnDoubleLiteral : double -> ExpressionKind + default this.OnDoubleLiteral d = DoubleLiteral d - abstract member onBoolLiteral : bool -> ExpressionKind - default this.onBoolLiteral b = BoolLiteral b + abstract member OnBoolLiteral : bool -> ExpressionKind + default this.OnBoolLiteral b = BoolLiteral b - abstract member onResultLiteral : QsResult -> ExpressionKind - default this.onResultLiteral r = ResultLiteral r + abstract member OnResultLiteral : QsResult -> ExpressionKind + default this.OnResultLiteral r = ResultLiteral r - abstract member onPauliLiteral : QsPauli -> ExpressionKind - default this.onPauliLiteral p = PauliLiteral p + abstract member OnPauliLiteral : QsPauli -> ExpressionKind + default this.OnPauliLiteral p = PauliLiteral p // transformation root called on each node - member private this.dispatchCallLikeExpression (method, arg) = - match method.ResolvedType.Resolution with - | _ when TypedExpression.IsPartialApplication (CallLikeExpression (method, arg)) -> this.onPartialApplication (method, arg) - | ExpressionType.Operation _ -> this.onOperationCall (method, arg) - | _ -> this.onFunctionCall (method, arg) - - abstract member Transform : ExpressionKind -> ExpressionKind - default this.Transform kind = + abstract member OnExpressionKind : ExpressionKind -> ExpressionKind + default this.OnExpressionKind kind = if options.Disable then kind else let transformed = kind |> function - | Identifier (sym, tArgs) -> this.onIdentifier (sym, tArgs) - | CallLikeExpression (method,arg) -> this.dispatchCallLikeExpression ((method, arg) |> this.beforeCallLike) - | AdjointApplication ex -> this.onAdjointApplication (ex |> (this.beforeFunctorApplication >> this.beforeModifierApplication)) - | ControlledApplication ex -> this.onControlledApplication (ex |> (this.beforeFunctorApplication >> this.beforeModifierApplication)) - | UnwrapApplication ex -> this.onUnwrapApplication (ex |> this.beforeModifierApplication) - | UnitValue -> this.onUnitValue () - | MissingExpr -> this.onMissingExpression () - | InvalidExpr -> this.onInvalidExpression () - | ValueTuple vs -> this.onValueTuple vs - | ArrayItem (arr, idx) -> this.onArrayItem (arr, idx) - | NamedItem (ex, acc) -> this.onNamedItem (ex, acc) - | ValueArray vs -> this.onValueArray vs - | NewArray (bt, idx) -> this.onNewArray (bt, idx) - | IntLiteral i -> this.onIntLiteral i - | BigIntLiteral b -> this.onBigIntLiteral b - | DoubleLiteral d -> this.onDoubleLiteral d - | BoolLiteral b -> this.onBoolLiteral b - | ResultLiteral r -> this.onResultLiteral r - | PauliLiteral p -> this.onPauliLiteral p - | StringLiteral (s, exs) -> this.onStringLiteral (s, exs) - | RangeLiteral (lhs, rhs) -> this.onRangeLiteral (lhs, rhs) - | CopyAndUpdate (lhs, accEx, rhs) -> this.onCopyAndUpdateExpression (lhs, accEx, rhs) - | CONDITIONAL (cond, ifTrue, ifFalse) -> this.onConditionalExpression (cond, ifTrue, ifFalse) - | EQ (lhs,rhs) -> this.onEquality ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | NEQ (lhs,rhs) -> this.onInequality ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | LT (lhs,rhs) -> this.onLessThan ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | LTE (lhs,rhs) -> this.onLessThanOrEqual ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | GT (lhs,rhs) -> this.onGreaterThan ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | GTE (lhs,rhs) -> this.onGreaterThanOrEqual ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | AND (lhs,rhs) -> this.onLogicalAnd ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | OR (lhs,rhs) -> this.onLogicalOr ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | ADD (lhs,rhs) -> this.onAddition ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | SUB (lhs,rhs) -> this.onSubtraction ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | MUL (lhs,rhs) -> this.onMultiplication ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | DIV (lhs,rhs) -> this.onDivision ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | POW (lhs,rhs) -> this.onExponentiate ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | MOD (lhs,rhs) -> this.onModulo ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | LSHIFT (lhs,rhs) -> this.onLeftShift ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | RSHIFT (lhs,rhs) -> this.onRightShift ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | BXOR (lhs,rhs) -> this.onBitwiseExclusiveOr ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | BOR (lhs,rhs) -> this.onBitwiseOr ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | BAND (lhs,rhs) -> this.onBitwiseAnd ((lhs, rhs) |> this.beforeBinaryOperatorExpression) - | NOT ex -> this.onLogicalNot (ex |> this.beforeUnaryOperatorExpression) - | NEG ex -> this.onNegative (ex |> this.beforeUnaryOperatorExpression) - | BNOT ex -> this.onBitwiseNot (ex |> this.beforeUnaryOperatorExpression) + | Identifier (sym, tArgs) -> this.OnIdentifier (sym, tArgs) + | CallLikeExpression (method,arg) -> this.OnCallLikeExpression (method, arg) + | AdjointApplication ex -> this.OnAdjointApplication (ex) + | ControlledApplication ex -> this.OnControlledApplication (ex) + | UnwrapApplication ex -> this.OnUnwrapApplication (ex) + | UnitValue -> this.OnUnitValue () + | MissingExpr -> this.OnMissingExpression () + | InvalidExpr -> this.OnInvalidExpression () + | ValueTuple vs -> this.OnValueTuple vs + | ArrayItem (arr, idx) -> this.OnArrayItem (arr, idx) + | NamedItem (ex, acc) -> this.OnNamedItem (ex, acc) + | ValueArray vs -> this.OnValueArray vs + | NewArray (bt, idx) -> this.OnNewArray (bt, idx) + | IntLiteral i -> this.OnIntLiteral i + | BigIntLiteral b -> this.OnBigIntLiteral b + | DoubleLiteral d -> this.OnDoubleLiteral d + | BoolLiteral b -> this.OnBoolLiteral b + | ResultLiteral r -> this.OnResultLiteral r + | PauliLiteral p -> this.OnPauliLiteral p + | StringLiteral (s, exs) -> this.OnStringLiteral (s, exs) + | RangeLiteral (lhs, rhs) -> this.OnRangeLiteral (lhs, rhs) + | CopyAndUpdate (lhs, accEx, rhs) -> this.OnCopyAndUpdateExpression (lhs, accEx, rhs) + | CONDITIONAL (cond, ifTrue, ifFalse) -> this.OnConditionalExpression (cond, ifTrue, ifFalse) + | EQ (lhs,rhs) -> this.OnEquality (lhs, rhs) + | NEQ (lhs,rhs) -> this.OnInequality (lhs, rhs) + | LT (lhs,rhs) -> this.OnLessThan (lhs, rhs) + | LTE (lhs,rhs) -> this.OnLessThanOrEqual (lhs, rhs) + | GT (lhs,rhs) -> this.OnGreaterThan (lhs, rhs) + | GTE (lhs,rhs) -> this.OnGreaterThanOrEqual (lhs, rhs) + | AND (lhs,rhs) -> this.OnLogicalAnd (lhs, rhs) + | OR (lhs,rhs) -> this.OnLogicalOr (lhs, rhs) + | ADD (lhs,rhs) -> this.OnAddition (lhs, rhs) + | SUB (lhs,rhs) -> this.OnSubtraction (lhs, rhs) + | MUL (lhs,rhs) -> this.OnMultiplication (lhs, rhs) + | DIV (lhs,rhs) -> this.OnDivision (lhs, rhs) + | POW (lhs,rhs) -> this.OnExponentiate (lhs, rhs) + | MOD (lhs,rhs) -> this.OnModulo (lhs, rhs) + | LSHIFT (lhs,rhs) -> this.OnLeftShift (lhs, rhs) + | RSHIFT (lhs,rhs) -> this.OnRightShift (lhs, rhs) + | BXOR (lhs,rhs) -> this.OnBitwiseExclusiveOr (lhs, rhs) + | BOR (lhs,rhs) -> this.OnBitwiseOr (lhs, rhs) + | BAND (lhs,rhs) -> this.OnBitwiseAnd (lhs, rhs) + | NOT ex -> this.OnLogicalNot (ex) + | NEG ex -> this.OnNegative (ex) + | BNOT ex -> this.OnBitwiseNot (ex) id |> Node.BuildOr kind transformed @@ -378,35 +361,35 @@ and ExpressionTransformationBase internal (options : TransformationOptions, _int // supplementary expression information - abstract member onRangeInformation : QsNullable -> QsNullable - default this.onRangeInformation r = r + abstract member OnRangeInformation : QsNullable -> QsNullable + default this.OnRangeInformation r = r - abstract member onExpressionInformation : InferredExpressionInformation -> InferredExpressionInformation - default this.onExpressionInformation info = info + abstract member OnExpressionInformation : InferredExpressionInformation -> InferredExpressionInformation + default this.OnExpressionInformation info = info // nodes containing subexpressions or subtypes /// If DisableRebuild is set to true, this method won't walk the types in the dictionary. - abstract member onTypeParamResolutions : ImmutableDictionary<(QsQualifiedName*NonNullable), ResolvedType> -> ImmutableDictionary<(QsQualifiedName*NonNullable), ResolvedType> - default this.onTypeParamResolutions typeParams = + abstract member OnTypeParamResolutions : ImmutableDictionary<(QsQualifiedName*NonNullable), ResolvedType> -> ImmutableDictionary<(QsQualifiedName*NonNullable), ResolvedType> + default this.OnTypeParamResolutions typeParams = let asTypeParameter (key) = QsTypeParameter.New (fst key, snd key, Null) let filteredTypeParams = typeParams - |> Seq.map (fun kv -> this.Types.onTypeParameter (kv.Key |> asTypeParameter), kv.Value) - |> Seq.choose (function | TypeParameter tp, value -> Some ((tp.Origin, tp.TypeName), this.Types.Transform value) | _ -> None) + |> Seq.map (fun kv -> this.Types.OnTypeParameter (kv.Key |> asTypeParameter), kv.Value) + |> Seq.choose (function | TypeParameter tp, value -> Some ((tp.Origin, tp.TypeName), this.Types.OnType value) | _ -> None) |> Seq.map (fun (key, value) -> new KeyValuePair<_,_>(key, value)) ImmutableDictionary.CreateRange |> Node.BuildOr typeParams filteredTypeParams // transformation root called on each node - abstract member Transform : TypedExpression -> TypedExpression - default this.Transform (ex : TypedExpression) = + abstract member OnTypedExpression : TypedExpression -> TypedExpression + default this.OnTypedExpression (ex : TypedExpression) = if options.Disable then ex else - let range = this.onRangeInformation ex.Range - let typeParamResolutions = this.onTypeParamResolutions ex.TypeParameterResolutions - let kind = this.ExpressionKinds.Transform ex.Expression - let exType = this.Types.Transform ex.ResolvedType - let inferredInfo = this.onExpressionInformation ex.InferredInformation + let range = this.OnRangeInformation ex.Range + let typeParamResolutions = this.OnTypeParamResolutions ex.TypeParameterResolutions + let kind = this.ExpressionKinds.OnExpressionKind ex.Expression + let exType = this.Types.OnType ex.ResolvedType + let inferredInfo = this.OnExpressionInformation ex.InferredInformation TypedExpression.New |> Node.BuildOr ex (kind, typeParamResolutions, exType, inferredInfo, range) diff --git a/src/QsCompiler/Core/NamespaceTransformation.fs b/src/QsCompiler/Core/NamespaceTransformation.fs index 3c0f40bcba..670913bef7 100644 --- a/src/QsCompiler/Core/NamespaceTransformation.fs +++ b/src/QsCompiler/Core/NamespaceTransformation.fs @@ -38,203 +38,191 @@ type NamespaceTransformationBase internal (options : TransformationOptions, _int new () = new NamespaceTransformationBase(TransformationOptions.Default) - // methods invoked before selective nodes - - abstract member beforeNamespaceElement : QsNamespaceElement -> QsNamespaceElement - default this.beforeNamespaceElement e = e - - abstract member beforeCallable : QsCallable -> QsCallable - default this.beforeCallable c = c - - abstract member beforeSpecialization : QsSpecialization -> QsSpecialization - default this.beforeSpecialization spec = spec - - abstract member beforeSpecializationImplementation : SpecializationImplementation -> SpecializationImplementation - default this.beforeSpecializationImplementation impl = impl - - abstract member beforeGeneratedImplementation : QsGeneratorDirective -> QsGeneratorDirective - default this.beforeGeneratedImplementation dir = dir - - // subconstructs used within declarations - abstract member onLocation : QsNullable -> QsNullable - default this.onLocation l = l + abstract member OnLocation : QsNullable -> QsNullable + default this.OnLocation l = l - abstract member onDocumentation : ImmutableArray -> ImmutableArray - default this.onDocumentation doc = doc + abstract member OnDocumentation : ImmutableArray -> ImmutableArray + default this.OnDocumentation doc = doc - abstract member onSourceFile : NonNullable -> NonNullable - default this.onSourceFile f = f + abstract member OnSourceFile : NonNullable -> NonNullable + default this.OnSourceFile f = f - abstract member onAttribute : QsDeclarationAttribute -> QsDeclarationAttribute - default this.onAttribute att = att + abstract member OnAttribute : QsDeclarationAttribute -> QsDeclarationAttribute + default this.OnAttribute att = att - abstract member onTypeItems : QsTuple -> QsTuple - default this.onTypeItems tItem = + abstract member OnTypeItems : QsTuple -> QsTuple + default this.OnTypeItems tItem = match tItem with | QsTuple items as original -> - let transformed = items |> Seq.map this.onTypeItems |> ImmutableArray.CreateRange + let transformed = items |> Seq.map this.OnTypeItems |> ImmutableArray.CreateRange QsTuple |> Node.BuildOr original transformed | QsTupleItem (Anonymous itemType) as original -> - let t = this.Statements.Expressions.Types.Transform itemType + let t = this.Statements.Expressions.Types.OnType itemType QsTupleItem << Anonymous |> Node.BuildOr original t | QsTupleItem (Named item) as original -> let loc = item.Position, item.Range - let t = this.Statements.Expressions.Types.Transform item.Type - let info = this.Statements.Expressions.onExpressionInformation item.InferredInformation + let t = this.Statements.Expressions.Types.OnType item.Type + let info = this.Statements.Expressions.OnExpressionInformation item.InferredInformation QsTupleItem << Named << LocalVariableDeclaration<_>.New info.IsMutable |> Node.BuildOr original (loc, item.VariableName, t, info.HasLocalQuantumDependency) - abstract member onArgumentTuple : QsArgumentTuple -> QsArgumentTuple - default this.onArgumentTuple arg = + abstract member OnArgumentTuple : QsArgumentTuple -> QsArgumentTuple + default this.OnArgumentTuple arg = match arg with | QsTuple items as original -> - let transformed = items |> Seq.map this.onArgumentTuple |> ImmutableArray.CreateRange + let transformed = items |> Seq.map this.OnArgumentTuple |> ImmutableArray.CreateRange QsTuple |> Node.BuildOr original transformed | QsTupleItem item as original -> let loc = item.Position, item.Range - let t = this.Statements.Expressions.Types.Transform item.Type - let info = this.Statements.Expressions.onExpressionInformation item.InferredInformation + let t = this.Statements.Expressions.Types.OnType item.Type + let info = this.Statements.Expressions.OnExpressionInformation item.InferredInformation QsTupleItem << LocalVariableDeclaration<_>.New info.IsMutable |> Node.BuildOr original (loc, item.VariableName, t, info.HasLocalQuantumDependency) - abstract member onSignature : ResolvedSignature -> ResolvedSignature - default this.onSignature (s : ResolvedSignature) = + abstract member OnSignature : ResolvedSignature -> ResolvedSignature + default this.OnSignature (s : ResolvedSignature) = let typeParams = s.TypeParameters - let argType = this.Statements.Expressions.Types.Transform s.ArgumentType - let returnType = this.Statements.Expressions.Types.Transform s.ReturnType - let info = this.Statements.Expressions.Types.onCallableInformation s.Information + let argType = this.Statements.Expressions.Types.OnType s.ArgumentType + let returnType = this.Statements.Expressions.Types.OnType s.ReturnType + let info = this.Statements.Expressions.Types.OnCallableInformation s.Information ResolvedSignature.New |> Node.BuildOr s ((argType, returnType), info, typeParams) // specialization declarations and implementations - abstract member onProvidedImplementation : QsArgumentTuple * QsScope -> QsArgumentTuple * QsScope - default this.onProvidedImplementation (argTuple, body) = - let argTuple = this.onArgumentTuple argTuple - let body = this.Statements.Transform body + abstract member OnProvidedImplementation : QsArgumentTuple * QsScope -> QsArgumentTuple * QsScope + default this.OnProvidedImplementation (argTuple, body) = + let argTuple = this.OnArgumentTuple argTuple + let body = this.Statements.OnScope body argTuple, body - abstract member onSelfInverseDirective : unit -> unit - default this.onSelfInverseDirective () = () - - abstract member onInvertDirective : unit -> unit - default this.onInvertDirective () = () - - abstract member onDistributeDirective : unit -> unit - default this.onDistributeDirective () = () - - abstract member onInvalidGeneratorDirective : unit -> unit - default this.onInvalidGeneratorDirective () = () - - abstract member onExternalImplementation : unit -> unit - default this.onExternalImplementation () = () - - abstract member onIntrinsicImplementation : unit -> unit - default this.onIntrinsicImplementation () = () - - member this.dispatchGeneratedImplementation (dir : QsGeneratorDirective) = - match this.beforeGeneratedImplementation dir with - | SelfInverse -> this.onSelfInverseDirective (); SelfInverse - | Invert -> this.onInvertDirective(); Invert - | Distribute -> this.onDistributeDirective(); Distribute - | InvalidGenerator -> this.onInvalidGeneratorDirective(); InvalidGenerator - - member this.dispatchSpecializationImplementation (impl : SpecializationImplementation) = - let Build kind transformed = kind |> Node.BuildOr impl transformed - match this.beforeSpecializationImplementation impl with - | External -> this.onExternalImplementation(); External - | Intrinsic -> this.onIntrinsicImplementation(); Intrinsic - | Generated dir -> this.dispatchGeneratedImplementation dir |> Build Generated - | Provided (argTuple, body) -> this.onProvidedImplementation (argTuple, body) |> Build Provided - - abstract member onSpecializationImplementation : QsSpecialization -> QsSpecialization - default this.onSpecializationImplementation (spec : QsSpecialization) = - let source = this.onSourceFile spec.SourceFile - let loc = this.onLocation spec.Location - let attributes = spec.Attributes |> Seq.map this.onAttribute |> ImmutableArray.CreateRange - let typeArgs = spec.TypeArguments |> QsNullable<_>.Map (fun args -> args |> Seq.map this.Statements.Expressions.Types.Transform |> ImmutableArray.CreateRange) - let signature = this.onSignature spec.Signature - let impl = this.dispatchSpecializationImplementation spec.Implementation - let doc = this.onDocumentation spec.Documentation + abstract member OnSelfInverseDirective : unit -> unit + default this.OnSelfInverseDirective () = () + + abstract member OnInvertDirective : unit -> unit + default this.OnInvertDirective () = () + + abstract member OnDistributeDirective : unit -> unit + default this.OnDistributeDirective () = () + + abstract member OnInvalidGeneratorDirective : unit -> unit + default this.OnInvalidGeneratorDirective () = () + + abstract member OnExternalImplementation : unit -> unit + default this.OnExternalImplementation () = () + + abstract member OnIntrinsicImplementation : unit -> unit + default this.OnIntrinsicImplementation () = () + + abstract member OnGeneratedImplementation : QsGeneratorDirective -> QsGeneratorDirective + default this.OnGeneratedImplementation (directive : QsGeneratorDirective) = + match directive with + | SelfInverse -> this.OnSelfInverseDirective (); SelfInverse + | Invert -> this.OnInvertDirective(); Invert + | Distribute -> this.OnDistributeDirective(); Distribute + | InvalidGenerator -> this.OnInvalidGeneratorDirective(); InvalidGenerator + + abstract member OnSpecializationImplementation : SpecializationImplementation -> SpecializationImplementation + default this.OnSpecializationImplementation (implementation : SpecializationImplementation) = + let Build kind transformed = kind |> Node.BuildOr implementation transformed + match implementation with + | External -> this.OnExternalImplementation(); External + | Intrinsic -> this.OnIntrinsicImplementation(); Intrinsic + | Generated dir -> this.OnGeneratedImplementation dir |> Build Generated + | Provided (argTuple, body) -> this.OnProvidedImplementation (argTuple, body) |> Build Provided + + /// This method is defined for the sole purpose of eliminating code duplication for each of the specialization kinds. + /// It is hence not intended and should never be needed for public use. + member private this.OnSpecializationKind (spec : QsSpecialization) = + let source = this.OnSourceFile spec.SourceFile + let loc = this.OnLocation spec.Location + let attributes = spec.Attributes |> Seq.map this.OnAttribute |> ImmutableArray.CreateRange + let typeArgs = spec.TypeArguments |> QsNullable<_>.Map (fun args -> args |> Seq.map this.Statements.Expressions.Types.OnType |> ImmutableArray.CreateRange) + let signature = this.OnSignature spec.Signature + let impl = this.OnSpecializationImplementation spec.Implementation + let doc = this.OnDocumentation spec.Documentation let comments = spec.Comments QsSpecialization.New spec.Kind (source, loc) |> Node.BuildOr spec (spec.Parent, attributes, typeArgs, signature, impl, doc, comments) - abstract member onBodySpecialization : QsSpecialization -> QsSpecialization - default this.onBodySpecialization spec = this.onSpecializationImplementation spec + abstract member OnBodySpecialization : QsSpecialization -> QsSpecialization + default this.OnBodySpecialization spec = this.OnSpecializationKind spec - abstract member onAdjointSpecialization : QsSpecialization -> QsSpecialization - default this.onAdjointSpecialization spec = this.onSpecializationImplementation spec + abstract member OnAdjointSpecialization : QsSpecialization -> QsSpecialization + default this.OnAdjointSpecialization spec = this.OnSpecializationKind spec - abstract member onControlledSpecialization : QsSpecialization -> QsSpecialization - default this.onControlledSpecialization spec = this.onSpecializationImplementation spec + abstract member OnControlledSpecialization : QsSpecialization -> QsSpecialization + default this.OnControlledSpecialization spec = this.OnSpecializationKind spec - abstract member onControlledAdjointSpecialization : QsSpecialization -> QsSpecialization - default this.onControlledAdjointSpecialization spec = this.onSpecializationImplementation spec + abstract member OnControlledAdjointSpecialization : QsSpecialization -> QsSpecialization + default this.OnControlledAdjointSpecialization spec = this.OnSpecializationKind spec - member this.dispatchSpecialization (spec : QsSpecialization) = - let spec = this.beforeSpecialization spec + abstract member OnSpecializationDeclaration : QsSpecialization -> QsSpecialization + default this.OnSpecializationDeclaration (spec : QsSpecialization) = match spec.Kind with - | QsSpecializationKind.QsBody -> this.onBodySpecialization spec - | QsSpecializationKind.QsAdjoint -> this.onAdjointSpecialization spec - | QsSpecializationKind.QsControlled -> this.onControlledSpecialization spec - | QsSpecializationKind.QsControlledAdjoint -> this.onControlledAdjointSpecialization spec + | QsSpecializationKind.QsBody -> this.OnBodySpecialization spec + | QsSpecializationKind.QsAdjoint -> this.OnAdjointSpecialization spec + | QsSpecializationKind.QsControlled -> this.OnControlledSpecialization spec + | QsSpecializationKind.QsControlledAdjoint -> this.OnControlledAdjointSpecialization spec - // type and callable declarations and implementations - - abstract member onType : QsCustomType -> QsCustomType - default this.onType t = - let source = this.onSourceFile t.SourceFile - let loc = this.onLocation t.Location - let attributes = t.Attributes |> Seq.map this.onAttribute |> ImmutableArray.CreateRange - let underlyingType = this.Statements.Expressions.Types.Transform t.Type - let typeItems = this.onTypeItems t.TypeItems - let doc = this.onDocumentation t.Documentation - let comments = t.Comments - QsCustomType.New (source, loc) |> Node.BuildOr t (t.FullName, attributes, typeItems, underlyingType, doc, comments) - - abstract member onCallableImplementation : QsCallable -> QsCallable - default this.onCallableImplementation (c : QsCallable) = - let source = this.onSourceFile c.SourceFile - let loc = this.onLocation c.Location - let attributes = c.Attributes |> Seq.map this.onAttribute |> ImmutableArray.CreateRange - let signature = this.onSignature c.Signature - let argTuple = this.onArgumentTuple c.ArgumentTuple - let specializations = c.Specializations |> Seq.sortBy (fun c -> c.Kind) |> Seq.map this.dispatchSpecialization |> ImmutableArray.CreateRange - let doc = this.onDocumentation c.Documentation + // type and callable declarations + + /// This method is defined for the sole purpose of eliminating code duplication for each of the callable kinds. + /// It is hence not intended and should never be needed for public use. + member private this.OnCallableKind (c : QsCallable) = + let source = this.OnSourceFile c.SourceFile + let loc = this.OnLocation c.Location + let attributes = c.Attributes |> Seq.map this.OnAttribute |> ImmutableArray.CreateRange + let signature = this.OnSignature c.Signature + let argTuple = this.OnArgumentTuple c.ArgumentTuple + let specializations = c.Specializations |> Seq.sortBy (fun c -> c.Kind) |> Seq.map this.OnSpecializationDeclaration |> ImmutableArray.CreateRange + let doc = this.OnDocumentation c.Documentation let comments = c.Comments QsCallable.New c.Kind (source, loc) |> Node.BuildOr c (c.FullName, attributes, argTuple, signature, specializations, doc, comments) - abstract member onOperation : QsCallable -> QsCallable - default this.onOperation c = this.onCallableImplementation c + abstract member OnOperation : QsCallable -> QsCallable + default this.OnOperation c = this.OnCallableKind c - abstract member onFunction : QsCallable -> QsCallable - default this.onFunction c = this.onCallableImplementation c + abstract member OnFunction : QsCallable -> QsCallable + default this.OnFunction c = this.OnCallableKind c - abstract member onTypeConstructor : QsCallable -> QsCallable - default this.onTypeConstructor c = this.onCallableImplementation c + abstract member OnTypeConstructor : QsCallable -> QsCallable + default this.OnTypeConstructor c = this.OnCallableKind c - member this.dispatchCallable (c : QsCallable) = - let c = this.beforeCallable c + abstract member OnCallableDeclaration : QsCallable -> QsCallable + default this.OnCallableDeclaration (c : QsCallable) = match c.Kind with - | QsCallableKind.Function -> this.onFunction c - | QsCallableKind.Operation -> this.onOperation c - | QsCallableKind.TypeConstructor -> this.onTypeConstructor c + | QsCallableKind.Function -> this.OnFunction c + | QsCallableKind.Operation -> this.OnOperation c + | QsCallableKind.TypeConstructor -> this.OnTypeConstructor c + + abstract member OnTypeDeclaration : QsCustomType -> QsCustomType + default this.OnTypeDeclaration t = + let source = this.OnSourceFile t.SourceFile + let loc = this.OnLocation t.Location + let attributes = t.Attributes |> Seq.map this.OnAttribute |> ImmutableArray.CreateRange + let underlyingType = this.Statements.Expressions.Types.OnType t.Type + let typeItems = this.OnTypeItems t.TypeItems + let doc = this.OnDocumentation t.Documentation + let comments = t.Comments + QsCustomType.New (source, loc) |> Node.BuildOr t (t.FullName, attributes, typeItems, underlyingType, doc, comments) - // transformation roots called on each namespace + // transformation roots called on each namespace or namespace element - member this.dispatchNamespaceElement element = - match this.beforeNamespaceElement element with - | QsCustomType t -> t |> this.onType |> QsCustomType - | QsCallable c -> c |> this.dispatchCallable |> QsCallable + abstract member OnNamespaceElement : QsNamespaceElement -> QsNamespaceElement + default this.OnNamespaceElement element = + if options.Disable then element else + match element with + | QsCustomType t -> t |> this.OnTypeDeclaration |> QsCustomType + | QsCallable c -> c |> this.OnCallableDeclaration |> QsCallable - abstract member Transform : QsNamespace -> QsNamespace - default this.Transform ns = + abstract member OnNamespace : QsNamespace -> QsNamespace + default this.OnNamespace ns = if options.Disable then ns else let name = ns.Name let doc = ns.Documentation.AsEnumerable().SelectMany(fun entry -> - entry |> Seq.map (fun doc -> entry.Key, this.onDocumentation doc)).ToLookup(fst, snd) - let elements = ns.Elements |> Seq.map this.dispatchNamespaceElement |> ImmutableArray.CreateRange + entry |> Seq.map (fun doc -> entry.Key, this.OnDocumentation doc)).ToLookup(fst, snd) + let elements = ns.Elements |> Seq.map this.OnNamespaceElement |> ImmutableArray.CreateRange QsNamespace.New |> Node.BuildOr ns (name, elements, doc) diff --git a/src/QsCompiler/Core/StatementTransformation.fs b/src/QsCompiler/Core/StatementTransformation.fs index 604de39b00..40a155da8c 100644 --- a/src/QsCompiler/Core/StatementTransformation.fs +++ b/src/QsCompiler/Core/StatementTransformation.fs @@ -41,148 +41,141 @@ type StatementKindTransformationBase internal (options : TransformationOptions, new () = new StatementKindTransformationBase(TransformationOptions.Default) - // methods invoked before selective statements - - abstract member beforeVariableDeclaration : SymbolTuple -> SymbolTuple - default this.beforeVariableDeclaration syms = syms - - // subconstructs used within statements - abstract member onSymbolTuple : SymbolTuple -> SymbolTuple - default this.onSymbolTuple syms = syms + abstract member OnSymbolTuple : SymbolTuple -> SymbolTuple + default this.OnSymbolTuple syms = syms - abstract member onQubitInitializer : ResolvedInitializer -> ResolvedInitializer - default this.onQubitInitializer init = + abstract member OnQubitInitializer : ResolvedInitializer -> ResolvedInitializer + default this.OnQubitInitializer init = let transformed = init.Resolution |> function | SingleQubitAllocation -> SingleQubitAllocation - | QubitRegisterAllocation ex as orig -> QubitRegisterAllocation |> Node.BuildOr orig (this.Expressions.Transform ex) - | QubitTupleAllocation is as orig -> QubitTupleAllocation |> Node.BuildOr orig (is |> Seq.map this.onQubitInitializer |> ImmutableArray.CreateRange) + | QubitRegisterAllocation ex as orig -> QubitRegisterAllocation |> Node.BuildOr orig (this.Expressions.OnTypedExpression ex) + | QubitTupleAllocation is as orig -> QubitTupleAllocation |> Node.BuildOr orig (is |> Seq.map this.OnQubitInitializer |> ImmutableArray.CreateRange) | InvalidInitializer -> InvalidInitializer ResolvedInitializer.New |> Node.BuildOr init transformed - abstract member onPositionedBlock : QsNullable * QsPositionedBlock -> QsNullable * QsPositionedBlock - default this.onPositionedBlock (intro : QsNullable, block : QsPositionedBlock) = - let location = this.Statements.onLocation block.Location + abstract member OnPositionedBlock : QsNullable * QsPositionedBlock -> QsNullable * QsPositionedBlock + default this.OnPositionedBlock (intro : QsNullable, block : QsPositionedBlock) = + let location = this.Statements.OnLocation block.Location let comments = block.Comments - let expr = intro |> QsNullable<_>.Map this.Expressions.Transform - let body = this.Statements.Transform block.Body + let expr = intro |> QsNullable<_>.Map this.Expressions.OnTypedExpression + let body = this.Statements.OnScope block.Body let PositionedBlock (expr, body, location, comments) = expr, QsPositionedBlock.New comments location body PositionedBlock |> Node.BuildOr (intro, block) (expr, body, location, comments) // statements containing subconstructs or expressions - abstract member onVariableDeclaration : QsBinding -> QsStatementKind - default this.onVariableDeclaration stm = - let rhs = this.Expressions.Transform stm.Rhs - let lhs = this.onSymbolTuple stm.Lhs + abstract member OnVariableDeclaration : QsBinding -> QsStatementKind + default this.OnVariableDeclaration stm = + let rhs = this.Expressions.OnTypedExpression stm.Rhs + let lhs = this.OnSymbolTuple stm.Lhs QsVariableDeclaration << QsBinding.New stm.Kind |> Node.BuildOr EmptyStatement (lhs, rhs) - abstract member onValueUpdate : QsValueUpdate -> QsStatementKind - default this.onValueUpdate stm = - let rhs = this.Expressions.Transform stm.Rhs - let lhs = this.Expressions.Transform stm.Lhs + abstract member OnValueUpdate : QsValueUpdate -> QsStatementKind + default this.OnValueUpdate stm = + let rhs = this.Expressions.OnTypedExpression stm.Rhs + let lhs = this.Expressions.OnTypedExpression stm.Lhs QsValueUpdate << QsValueUpdate.New |> Node.BuildOr EmptyStatement (lhs, rhs) - abstract member onConditionalStatement : QsConditionalStatement -> QsStatementKind - default this.onConditionalStatement stm = + abstract member OnConditionalStatement : QsConditionalStatement -> QsStatementKind + default this.OnConditionalStatement stm = let cases = stm.ConditionalBlocks |> Seq.map (fun (c, b) -> - let cond, block = this.onPositionedBlock (Value c, b) + let cond, block = this.OnPositionedBlock (Value c, b) let invalidCondition () = failwith "missing condition in if-statement" cond.ValueOrApply invalidCondition, block) |> ImmutableArray.CreateRange - let defaultCase = stm.Default |> QsNullable<_>.Map (fun b -> this.onPositionedBlock (Null, b) |> snd) + let defaultCase = stm.Default |> QsNullable<_>.Map (fun b -> this.OnPositionedBlock (Null, b) |> snd) QsConditionalStatement << QsConditionalStatement.New |> Node.BuildOr EmptyStatement (cases, defaultCase) - abstract member onForStatement : QsForStatement -> QsStatementKind - default this.onForStatement stm = - let iterVals = this.Expressions.Transform stm.IterationValues - let loopVar = fst stm.LoopItem |> this.onSymbolTuple - let loopVarType = this.Expressions.Types.Transform (snd stm.LoopItem) - let body = this.Statements.Transform stm.Body + abstract member OnForStatement : QsForStatement -> QsStatementKind + default this.OnForStatement stm = + let iterVals = this.Expressions.OnTypedExpression stm.IterationValues + let loopVar = fst stm.LoopItem |> this.OnSymbolTuple + let loopVarType = this.Expressions.Types.OnType (snd stm.LoopItem) + let body = this.Statements.OnScope stm.Body QsForStatement << QsForStatement.New |> Node.BuildOr EmptyStatement ((loopVar, loopVarType), iterVals, body) - abstract member onWhileStatement : QsWhileStatement -> QsStatementKind - default this.onWhileStatement stm = - let condition = this.Expressions.Transform stm.Condition - let body = this.Statements.Transform stm.Body + abstract member OnWhileStatement : QsWhileStatement -> QsStatementKind + default this.OnWhileStatement stm = + let condition = this.Expressions.OnTypedExpression stm.Condition + let body = this.Statements.OnScope stm.Body QsWhileStatement << QsWhileStatement.New |> Node.BuildOr EmptyStatement (condition, body) - abstract member onRepeatStatement : QsRepeatStatement -> QsStatementKind - default this.onRepeatStatement stm = - let repeatBlock = this.onPositionedBlock (Null, stm.RepeatBlock) |> snd - let successCondition, fixupBlock = this.onPositionedBlock (Value stm.SuccessCondition, stm.FixupBlock) + abstract member OnRepeatStatement : QsRepeatStatement -> QsStatementKind + default this.OnRepeatStatement stm = + let repeatBlock = this.OnPositionedBlock (Null, stm.RepeatBlock) |> snd + let successCondition, fixupBlock = this.OnPositionedBlock (Value stm.SuccessCondition, stm.FixupBlock) let invalidCondition () = failwith "missing success condition in repeat-statement" QsRepeatStatement << QsRepeatStatement.New |> Node.BuildOr EmptyStatement (repeatBlock, successCondition.ValueOrApply invalidCondition, fixupBlock) - abstract member onConjugation : QsConjugation -> QsStatementKind - default this.onConjugation stm = - let outer = this.onPositionedBlock (Null, stm.OuterTransformation) |> snd - let inner = this.onPositionedBlock (Null, stm.InnerTransformation) |> snd + abstract member OnConjugation : QsConjugation -> QsStatementKind + default this.OnConjugation stm = + let outer = this.OnPositionedBlock (Null, stm.OuterTransformation) |> snd + let inner = this.OnPositionedBlock (Null, stm.InnerTransformation) |> snd QsConjugation << QsConjugation.New |> Node.BuildOr EmptyStatement (outer, inner) - abstract member onExpressionStatement : TypedExpression -> QsStatementKind - default this.onExpressionStatement ex = - let transformed = this.Expressions.Transform ex + abstract member OnExpressionStatement : TypedExpression -> QsStatementKind + default this.OnExpressionStatement ex = + let transformed = this.Expressions.OnTypedExpression ex QsExpressionStatement |> Node.BuildOr EmptyStatement transformed - abstract member onReturnStatement : TypedExpression -> QsStatementKind - default this.onReturnStatement ex = - let transformed = this.Expressions.Transform ex + abstract member OnReturnStatement : TypedExpression -> QsStatementKind + default this.OnReturnStatement ex = + let transformed = this.Expressions.OnTypedExpression ex QsReturnStatement |> Node.BuildOr EmptyStatement transformed - abstract member onFailStatement : TypedExpression -> QsStatementKind - default this.onFailStatement ex = - let transformed = this.Expressions.Transform ex + abstract member OnFailStatement : TypedExpression -> QsStatementKind + default this.OnFailStatement ex = + let transformed = this.Expressions.OnTypedExpression ex QsFailStatement |> Node.BuildOr EmptyStatement transformed - abstract member onQubitScope : QsQubitScope -> QsStatementKind - default this.onQubitScope (stm : QsQubitScope) = + /// This method is defined for the sole purpose of eliminating code duplication for each of the specialization kinds. + /// It is hence not intended and should never be needed for public use. + member private this.OnQubitScopeKind (stm : QsQubitScope) = let kind = stm.Kind - let rhs = this.onQubitInitializer stm.Binding.Rhs - let lhs = this.onSymbolTuple stm.Binding.Lhs - let body = this.Statements.Transform stm.Body + let rhs = this.OnQubitInitializer stm.Binding.Rhs + let lhs = this.OnSymbolTuple stm.Binding.Lhs + let body = this.Statements.OnScope stm.Body QsQubitScope << QsQubitScope.New kind |> Node.BuildOr EmptyStatement ((lhs, rhs), body) - abstract member onAllocateQubits : QsQubitScope -> QsStatementKind - default this.onAllocateQubits stm = this.onQubitScope stm + abstract member OnAllocateQubits : QsQubitScope -> QsStatementKind + default this.OnAllocateQubits stm = this.OnQubitScopeKind stm - abstract member onBorrowQubits : QsQubitScope -> QsStatementKind - default this.onBorrowQubits stm = this.onQubitScope stm + abstract member OnBorrowQubits : QsQubitScope -> QsStatementKind + default this.OnBorrowQubits stm = this.OnQubitScopeKind stm + + abstract member OnQubitScope : QsQubitScope -> QsStatementKind + default this.OnQubitScope (stm : QsQubitScope) = + match stm.Kind with + | Allocate -> this.OnAllocateQubits stm + | Borrow -> this.OnBorrowQubits stm // leaf nodes - abstract member onEmptyStatement : unit -> QsStatementKind - default this.onEmptyStatement () = EmptyStatement + abstract member OnEmptyStatement : unit -> QsStatementKind + default this.OnEmptyStatement () = EmptyStatement // transformation root called on each statement - member private this.dispatchQubitScope (stm : QsQubitScope) = - match stm.Kind with - | Allocate -> this.onAllocateQubits stm - | Borrow -> this.onBorrowQubits stm - - abstract member Transform : QsStatementKind -> QsStatementKind - default this.Transform kind = + abstract member OnStatementKind : QsStatementKind -> QsStatementKind + default this.OnStatementKind kind = if options.Disable then kind else - let beforeBinding (stm : QsBinding) = { stm with Lhs = this.beforeVariableDeclaration stm.Lhs } - let beforeForStatement (stm : QsForStatement) = {stm with LoopItem = (this.beforeVariableDeclaration (fst stm.LoopItem), snd stm.LoopItem)} - let beforeQubitScope (stm : QsQubitScope) = {stm with Binding = {stm.Binding with Lhs = this.beforeVariableDeclaration stm.Binding.Lhs}} let transformed = kind |> function - | QsExpressionStatement ex -> this.onExpressionStatement (ex) - | QsReturnStatement ex -> this.onReturnStatement (ex) - | QsFailStatement ex -> this.onFailStatement (ex) - | QsVariableDeclaration stm -> this.onVariableDeclaration (stm |> beforeBinding) - | QsValueUpdate stm -> this.onValueUpdate (stm) - | QsConditionalStatement stm -> this.onConditionalStatement (stm) - | QsForStatement stm -> this.onForStatement (stm |> beforeForStatement) - | QsWhileStatement stm -> this.onWhileStatement (stm) - | QsRepeatStatement stm -> this.onRepeatStatement (stm) - | QsConjugation stm -> this.onConjugation (stm) - | QsQubitScope stm -> this.dispatchQubitScope (stm |> beforeQubitScope) - | EmptyStatement -> this.onEmptyStatement () + | QsExpressionStatement ex -> this.OnExpressionStatement ex + | QsReturnStatement ex -> this.OnReturnStatement ex + | QsFailStatement ex -> this.OnFailStatement ex + | QsVariableDeclaration stm -> this.OnVariableDeclaration stm + | QsValueUpdate stm -> this.OnValueUpdate stm + | QsConditionalStatement stm -> this.OnConditionalStatement stm + | QsForStatement stm -> this.OnForStatement stm + | QsWhileStatement stm -> this.OnWhileStatement stm + | QsRepeatStatement stm -> this.OnRepeatStatement stm + | QsConjugation stm -> this.OnConjugation stm + | QsQubitScope stm -> this.OnQubitScope stm + | EmptyStatement -> this.OnEmptyStatement () id |> Node.BuildOr kind transformed @@ -217,16 +210,16 @@ and StatementTransformationBase internal (options : TransformationOptions, _inte // supplementary statement information - abstract member onLocation : QsNullable -> QsNullable - default this.onLocation loc = loc + abstract member OnLocation : QsNullable -> QsNullable + default this.OnLocation loc = loc /// If DisableRebuild is set to true, this method won't walk the local variables declared by the statement. - abstract member onLocalDeclarations : LocalDeclarations -> LocalDeclarations - default this.onLocalDeclarations decl = + abstract member OnLocalDeclarations : LocalDeclarations -> LocalDeclarations + default this.OnLocalDeclarations decl = let onLocalVariableDeclaration (local : LocalVariableDeclaration>) = let loc = local.Position, local.Range - let info = this.Expressions.onExpressionInformation local.InferredInformation - let varType = this.Expressions.Types.Transform local.Type + let info = this.Expressions.OnExpressionInformation local.InferredInformation + let varType = this.Expressions.Types.OnType local.Type LocalVariableDeclaration.New info.IsMutable (loc, local.VariableName, varType, info.HasLocalQuantumDependency) let variableDeclarations = decl.Variables |> Seq.map onLocalVariableDeclaration LocalDeclarations.New << ImmutableArray.CreateRange |> Node.BuildOr decl variableDeclarations @@ -234,18 +227,18 @@ and StatementTransformationBase internal (options : TransformationOptions, _inte // transformation roots called on each statement or statement block - abstract member onStatement : QsStatement -> QsStatement - default this.onStatement stm = + abstract member OnStatement : QsStatement -> QsStatement + default this.OnStatement stm = if options.Disable then stm else - let location = this.onLocation stm.Location + let location = this.OnLocation stm.Location let comments = stm.Comments - let kind = this.StatementKinds.Transform stm.Statement - let varDecl = this.onLocalDeclarations stm.SymbolDeclarations + let kind = this.StatementKinds.OnStatementKind stm.Statement + let varDecl = this.OnLocalDeclarations stm.SymbolDeclarations QsStatement.New comments location |> Node.BuildOr stm (kind, varDecl) - abstract member Transform : QsScope -> QsScope - default this.Transform scope = + abstract member OnScope : QsScope -> QsScope + default this.OnScope scope = if options.Disable then scope else - let parentSymbols = this.onLocalDeclarations scope.KnownSymbols - let statements = scope.Statements |> Seq.map this.onStatement |> ImmutableArray.CreateRange + let parentSymbols = this.OnLocalDeclarations scope.KnownSymbols + let statements = scope.Statements |> Seq.map this.OnStatement |> ImmutableArray.CreateRange QsScope.New |> Node.BuildOr scope (statements, parentSymbols) diff --git a/src/QsCompiler/Core/SyntaxGenerator.fs b/src/QsCompiler/Core/SyntaxGenerator.fs index 4f380781d9..d7dfe233d9 100644 --- a/src/QsCompiler/Core/SyntaxGenerator.fs +++ b/src/QsCompiler/Core/SyntaxGenerator.fs @@ -18,19 +18,19 @@ open Microsoft.Quantum.QsCompiler.Transformations.Core type private StripPositionInfoFromType (parent : StripPositionInfo) = inherit TypeTransformation(parent) - override this.onRangeInformation _ = Null + override this.OnRangeInformation _ = Null and private StripPositionInfoFromExpression (parent : StripPositionInfo) = inherit ExpressionTransformation(parent) - override this.onRangeInformation _ = Null + override this.OnRangeInformation _ = Null and private StripPositionInfoFromStatement(parent : StripPositionInfo) = inherit StatementTransformation(parent) - override this.onLocation _ = Null + override this.OnLocation _ = Null and private StripPositionInfoFromNamespace(parent : StripPositionInfo) = inherit NamespaceTransformation(parent) - override this.onLocation _ = Null + override this.OnLocation _ = Null and public StripPositionInfo private (_internal_) = inherit SyntaxTreeTransformation() @@ -44,10 +44,10 @@ and public StripPositionInfo private (_internal_) = this.Namespaces <- new StripPositionInfoFromNamespace(this) static member public Default = defaultInstance - static member public Apply t = defaultInstance.Types.Transform t - static member public Apply e = defaultInstance.Expressions.Transform e - static member public Apply s = defaultInstance.Statements.Transform s - static member public Apply a = defaultInstance.Namespaces.Transform a + static member public Apply t = defaultInstance.Types.OnType t + static member public Apply e = defaultInstance.Expressions.OnTypedExpression e + static member public Apply s = defaultInstance.Statements.OnScope s + static member public Apply a = defaultInstance.Namespaces.OnNamespace a module SyntaxGenerator = diff --git a/src/QsCompiler/Core/TypeTransformation.fs b/src/QsCompiler/Core/TypeTransformation.fs index eaa280c69a..90696145c1 100644 --- a/src/QsCompiler/Core/TypeTransformation.fs +++ b/src/QsCompiler/Core/TypeTransformation.fs @@ -22,114 +22,114 @@ type TypeTransformationBase(options : TransformationOptions) = // supplementary type information - abstract member onRangeInformation : QsRangeInfo -> QsRangeInfo - default this.onRangeInformation r = r + abstract member OnRangeInformation : QsRangeInfo -> QsRangeInfo + default this.OnRangeInformation r = r - abstract member onCharacteristicsExpression : ResolvedCharacteristics -> ResolvedCharacteristics - default this.onCharacteristicsExpression fs = fs + abstract member OnCharacteristicsExpression : ResolvedCharacteristics -> ResolvedCharacteristics + default this.OnCharacteristicsExpression fs = fs - abstract member onCallableInformation : CallableInformation -> CallableInformation - default this.onCallableInformation opInfo = - let characteristics = this.onCharacteristicsExpression opInfo.Characteristics + abstract member OnCallableInformation : CallableInformation -> CallableInformation + default this.OnCallableInformation opInfo = + let characteristics = this.OnCharacteristicsExpression opInfo.Characteristics let inferred = opInfo.InferredInformation CallableInformation.New |> Node.BuildOr opInfo (characteristics, inferred) // nodes containing subtypes - abstract member onUserDefinedType : UserDefinedType -> ExpressionType - default this.onUserDefinedType udt = + abstract member OnUserDefinedType : UserDefinedType -> ExpressionType + default this.OnUserDefinedType udt = let ns, name = udt.Namespace, udt.Name - let range = this.onRangeInformation udt.Range + let range = this.OnRangeInformation udt.Range ExpressionType.UserDefinedType << UserDefinedType.New |> Node.BuildOr InvalidType (ns, name, range) - abstract member onTypeParameter : QsTypeParameter -> ExpressionType - default this.onTypeParameter tp = + abstract member OnTypeParameter : QsTypeParameter -> ExpressionType + default this.OnTypeParameter tp = let origin = tp.Origin let name = tp.TypeName - let range = this.onRangeInformation tp.Range + let range = this.OnRangeInformation tp.Range ExpressionType.TypeParameter << QsTypeParameter.New |> Node.BuildOr InvalidType (origin, name, range) - abstract member onOperation : (ResolvedType * ResolvedType) * CallableInformation -> ExpressionType - default this.onOperation ((it, ot), info) = - let transformed = (this.Transform it, this.Transform ot), this.onCallableInformation info + abstract member OnOperation : (ResolvedType * ResolvedType) * CallableInformation -> ExpressionType + default this.OnOperation ((it, ot), info) = + let transformed = (this.OnType it, this.OnType ot), this.OnCallableInformation info ExpressionType.Operation |> Node.BuildOr InvalidType transformed - abstract member onFunction : ResolvedType * ResolvedType -> ExpressionType - default this.onFunction (it, ot) = - let transformed = this.Transform it, this.Transform ot + abstract member OnFunction : ResolvedType * ResolvedType -> ExpressionType + default this.OnFunction (it, ot) = + let transformed = this.OnType it, this.OnType ot ExpressionType.Function |> Node.BuildOr InvalidType transformed - abstract member onTupleType : ImmutableArray -> ExpressionType - default this.onTupleType ts = - let transformed = ts |> Seq.map this.Transform |> ImmutableArray.CreateRange + abstract member OnTupleType : ImmutableArray -> ExpressionType + default this.OnTupleType ts = + let transformed = ts |> Seq.map this.OnType |> ImmutableArray.CreateRange ExpressionType.TupleType |> Node.BuildOr InvalidType transformed - abstract member onArrayType : ResolvedType -> ExpressionType - default this.onArrayType b = - ExpressionType.ArrayType |> Node.BuildOr InvalidType (this.Transform b) + abstract member OnArrayType : ResolvedType -> ExpressionType + default this.OnArrayType b = + ExpressionType.ArrayType |> Node.BuildOr InvalidType (this.OnType b) // leaf nodes - abstract member onUnitType : unit -> ExpressionType - default this.onUnitType () = ExpressionType.UnitType + abstract member OnUnitType : unit -> ExpressionType + default this.OnUnitType () = ExpressionType.UnitType - abstract member onQubit : unit -> ExpressionType - default this.onQubit () = ExpressionType.Qubit + abstract member OnQubit : unit -> ExpressionType + default this.OnQubit () = ExpressionType.Qubit - abstract member onMissingType : unit -> ExpressionType - default this.onMissingType () = ExpressionType.MissingType + abstract member OnMissingType : unit -> ExpressionType + default this.OnMissingType () = ExpressionType.MissingType - abstract member onInvalidType : unit -> ExpressionType - default this.onInvalidType () = ExpressionType.InvalidType + abstract member OnInvalidType : unit -> ExpressionType + default this.OnInvalidType () = ExpressionType.InvalidType - abstract member onInt : unit -> ExpressionType - default this.onInt () = ExpressionType.Int + abstract member OnInt : unit -> ExpressionType + default this.OnInt () = ExpressionType.Int - abstract member onBigInt : unit -> ExpressionType - default this.onBigInt () = ExpressionType.BigInt + abstract member OnBigInt : unit -> ExpressionType + default this.OnBigInt () = ExpressionType.BigInt - abstract member onDouble : unit -> ExpressionType - default this.onDouble () = ExpressionType.Double + abstract member OnDouble : unit -> ExpressionType + default this.OnDouble () = ExpressionType.Double - abstract member onBool : unit -> ExpressionType - default this.onBool () = ExpressionType.Bool + abstract member OnBool : unit -> ExpressionType + default this.OnBool () = ExpressionType.Bool - abstract member onString : unit -> ExpressionType - default this.onString () = ExpressionType.String + abstract member OnString : unit -> ExpressionType + default this.OnString () = ExpressionType.String - abstract member onResult : unit -> ExpressionType - default this.onResult () = ExpressionType.Result + abstract member OnResult : unit -> ExpressionType + default this.OnResult () = ExpressionType.Result - abstract member onPauli : unit -> ExpressionType - default this.onPauli () = ExpressionType.Pauli + abstract member OnPauli : unit -> ExpressionType + default this.OnPauli () = ExpressionType.Pauli - abstract member onRange : unit -> ExpressionType - default this.onRange () = ExpressionType.Range + abstract member OnRange : unit -> ExpressionType + default this.OnRange () = ExpressionType.Range // transformation root called on each node - member this.Transform (t : ResolvedType) = + member this.OnType (t : ResolvedType) = if options.Disable then t else let transformed = t.Resolution |> function - | ExpressionType.UnitType -> this.onUnitType () - | ExpressionType.Operation ((it, ot), fs) -> this.onOperation ((it, ot), fs) - | ExpressionType.Function (it, ot) -> this.onFunction (it, ot) - | ExpressionType.TupleType ts -> this.onTupleType ts - | ExpressionType.ArrayType b -> this.onArrayType b - | ExpressionType.UserDefinedType udt -> this.onUserDefinedType udt - | ExpressionType.TypeParameter tp -> this.onTypeParameter tp - | ExpressionType.Qubit -> this.onQubit () - | ExpressionType.MissingType -> this.onMissingType () - | ExpressionType.InvalidType -> this.onInvalidType () - | ExpressionType.Int -> this.onInt () - | ExpressionType.BigInt -> this.onBigInt () - | ExpressionType.Double -> this.onDouble () - | ExpressionType.Bool -> this.onBool () - | ExpressionType.String -> this.onString () - | ExpressionType.Result -> this.onResult () - | ExpressionType.Pauli -> this.onPauli () - | ExpressionType.Range -> this.onRange () + | ExpressionType.UnitType -> this.OnUnitType () + | ExpressionType.Operation ((it, ot), fs) -> this.OnOperation ((it, ot), fs) + | ExpressionType.Function (it, ot) -> this.OnFunction (it, ot) + | ExpressionType.TupleType ts -> this.OnTupleType ts + | ExpressionType.ArrayType b -> this.OnArrayType b + | ExpressionType.UserDefinedType udt -> this.OnUserDefinedType udt + | ExpressionType.TypeParameter tp -> this.OnTypeParameter tp + | ExpressionType.Qubit -> this.OnQubit () + | ExpressionType.MissingType -> this.OnMissingType () + | ExpressionType.InvalidType -> this.OnInvalidType () + | ExpressionType.Int -> this.OnInt () + | ExpressionType.BigInt -> this.OnBigInt () + | ExpressionType.Double -> this.OnDouble () + | ExpressionType.Bool -> this.OnBool () + | ExpressionType.String -> this.OnString () + | ExpressionType.Result -> this.OnResult () + | ExpressionType.Pauli -> this.OnPauli () + | ExpressionType.Range -> this.OnRange () ResolvedType.New |> Node.BuildOr t transformed diff --git a/src/QsCompiler/DocumentationParser/DocItem.cs b/src/QsCompiler/DocumentationParser/DocItem.cs index 5afd8aa0a3..b07de0d4be 100644 --- a/src/QsCompiler/DocumentationParser/DocItem.cs +++ b/src/QsCompiler/DocumentationParser/DocItem.cs @@ -26,7 +26,7 @@ internal abstract class DocItem protected readonly string replacement; /// - /// The item's kind, as a string (Utilities.OperationKind, .FunctionKind, or .UdtKind) + /// The item's kind, as a string (Utils.OperationKind, .FunctionKind, or .UdtKind) /// internal string ItemType => this.itemType; /// diff --git a/src/QsCompiler/DocumentationParser/Utils.cs b/src/QsCompiler/DocumentationParser/Utils.cs index dc29e4b450..1b79293474 100644 --- a/src/QsCompiler/DocumentationParser/Utils.cs +++ b/src/QsCompiler/DocumentationParser/Utils.cs @@ -124,7 +124,7 @@ internal static YamlNode BuildSequenceMappingNode(Dictionary pai /// The resolved type /// A string containing the source representation of the type internal static string ResolvedTypeToString(ResolvedType t) => - SyntaxTreeToQs.Default.ToCode(t); + SyntaxTreeToQsharp.Default.ToCode(t); /// /// Populates a YAML mapping node with information describing a Q# resolved type. diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/CallableInlining.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/CallableInlining.fs index d3abc4e661..0b851d4630 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/CallableInlining.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/CallableInlining.fs @@ -10,6 +10,7 @@ open Microsoft.Quantum.QsCompiler.Experimental.Utils open Microsoft.Quantum.QsCompiler.SyntaxExtensions open Microsoft.Quantum.QsCompiler.SyntaxTokens open Microsoft.Quantum.QsCompiler.SyntaxTree +open Microsoft.Quantum.QsCompiler.Transformations /// Represents all the functors applied to an operation call @@ -83,8 +84,8 @@ type private InliningInfo = { maybe { let! functors, callable, arg = InliningInfo.TrySplitCall callables expr.Expression let! specArgs, body = InliningInfo.TryGetProvidedImpl callable functors - let body = ReplaceTypeParams(expr.TypeParameterResolutions).Statements.Transform body - let returnType = ReplaceTypeParams(expr.TypeParameterResolutions).Expressions.Types.Transform callable.Signature.ReturnType + let body = ReplaceTypeParams(expr.TypeParameterResolutions).Statements.OnScope body + let returnType = ReplaceTypeParams(expr.TypeParameterResolutions).Types.OnType callable.Signature.ReturnType return { functors = functors; callable = callable; arg = arg; specArgs = specArgs; body = body; returnType = returnType } } @@ -101,21 +102,23 @@ type CallableInlining private (_private_ : string) = new CallableInlining("_private_") then this.Namespaces <- new CallableInliningNamespaces(this) this.Statements <- new CallableInliningStatements(this, callables) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for CallableInlining and private CallableInliningNamespaces (parent : CallableInlining) = inherit NamespaceTransformationBase(parent) - override __.Transform x = - let x = base.Transform x - VariableRenaming().Namespaces.Transform x + override __.OnNamespace x = + let x = base.OnNamespace x + VariableRenaming().Namespaces.OnNamespace x - override __.onCallableImplementation c = + override __.OnCallableDeclaration c = let renamerVal = VariableRenaming() - let c = renamerVal.Namespaces.onCallableImplementation c + let c = renamerVal.Namespaces.OnCallableDeclaration c parent.CurrentCallable <- Some c parent.Renamer <- Some renamerVal - base.onCallableImplementation c + base.OnCallableDeclaration c /// private helper class for CallableInlining and private CallableInliningStatements (parent : CallableInlining, callables : ImmutableDictionary<_,_>) = @@ -160,7 +163,7 @@ and private CallableInliningStatements (parent : CallableInlining, callables : I let newBinding = QsBinding.New ImmutableBinding (toSymbolTuple ii.specArgs, ii.arg) let newStatements = ii.body.Statements.Insert (0, newBinding |> QsVariableDeclaration |> wrapStmt) - |> Seq.map renamer.Statements.onStatement + |> Seq.map renamer.Statements.OnStatement |> Seq.map (fun s -> s.Statement) |> ImmutableArray.CreateRange return ii, newStatements diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/ConstantPropagation.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/ConstantPropagation.fs index f797e91263..7539adbbf0 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/ConstantPropagation.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/ConstantPropagation.fs @@ -26,14 +26,15 @@ type ConstantPropagation private (_private_ : string) = this.Namespaces <- new ConstantPropagationNamespaces(this) this.StatementKinds <- new ConstantPropagationStatementKinds(this, callables) this.Expressions <- (new ExpressionEvaluator(callables, this.Constants, 1000)).Expressions + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for ConstantPropagation and private ConstantPropagationNamespaces(parent : ConstantPropagation) = inherit NamespaceTransformationBase(parent) - override __.onProvidedImplementation (argTuple, body) = + override __.OnProvidedImplementation (argTuple, body) = parent.Constants.Clear() - base.onProvidedImplementation (argTuple, body) + base.OnProvidedImplementation (argTuple, body) /// private helper class for ConstantPropagation and private ConstantPropagationStatementKinds (parent : ConstantPropagation, callables) = @@ -55,17 +56,17 @@ and private ConstantPropagationStatementKinds (parent : ConstantPropagation, cal && Seq.forall id sub) expr.Fold folder - override so.onVariableDeclaration stm = - let lhs = so.onSymbolTuple stm.Lhs - let rhs = so.Expressions.Transform stm.Rhs + override so.OnVariableDeclaration stm = + let lhs = so.OnSymbolTuple stm.Lhs + let rhs = so.Expressions.OnTypedExpression stm.Rhs if stm.Kind = ImmutableBinding then defineVarTuple (shouldPropagate callables) parent.Constants (lhs, rhs) QsBinding.New stm.Kind (lhs, rhs) |> QsVariableDeclaration - override this.onConditionalStatement stm = + override this.OnConditionalStatement stm = let cbList, cbListEnd = stm.ConditionalBlocks |> Seq.fold (fun s (cond, block) -> - let newCond = this.Expressions.Transform cond + let newCond = this.Expressions.OnTypedExpression cond match newCond.Expression with | BoolLiteral true -> s @ [Null, block] | BoolLiteral false -> s @@ -73,8 +74,8 @@ and private ConstantPropagationStatementKinds (parent : ConstantPropagation, cal ) [] |> List.ofSeq |> takeWhilePlus1 (fun (c, _) -> c <> Null) let newDefault = cbListEnd |> Option.map (snd >> Value) |? stm.Default - let cbList = cbList |> List.map (fun (c, b) -> this.onPositionedBlock (c, b)) - let newDefault = match newDefault with Value x -> this.onPositionedBlock (Null, x) |> snd |> Value | Null -> Null + let cbList = cbList |> List.map (fun (c, b) -> this.OnPositionedBlock (c, b)) + let newDefault = match newDefault with Value x -> this.OnPositionedBlock (Null, x) |> snd |> Value | Null -> Null match cbList, newDefault with | [], Value x -> @@ -86,10 +87,10 @@ and private ConstantPropagationStatementKinds (parent : ConstantPropagation, cal let cases = cbList |> Seq.map (fun (c, b) -> (c.ValueOrApply invalidCondition, b)) QsConditionalStatement.New (cases, newDefault) |> QsConditionalStatement - override this.onQubitScope (stm : QsQubitScope) = + override this.OnQubitScope (stm : QsQubitScope) = let kind = stm.Kind - let lhs = this.onSymbolTuple stm.Binding.Lhs - let rhs = this.onQubitInitializer stm.Binding.Rhs + let lhs = this.OnSymbolTuple stm.Binding.Lhs + let rhs = this.OnQubitInitializer stm.Binding.Rhs jointFlatten (lhs, rhs) |> Seq.iter (fun (l, r) -> match l, r.Resolution with @@ -100,6 +101,6 @@ and private ConstantPropagationStatementKinds (parent : ConstantPropagation, cal defineVar (fun _ -> true) parent.Constants (name.Value, expr) | _ -> ()) - let body = this.Statements.Transform stm.Body + let body = this.Statements.OnScope stm.Body QsQubitScope.New kind ((lhs, rhs), body) |> QsQubitScope diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/LoopUnrolling.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/LoopUnrolling.fs index 52623198a8..dc0fe183d8 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/LoopUnrolling.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/LoopUnrolling.fs @@ -18,24 +18,26 @@ type LoopUnrolling private (_private_ : string) = new LoopUnrolling("_private_") then this.Namespaces <- new LoopUnrollingNamespaces(this) this.StatementKinds <- new LoopUnrollingStatementKinds(this, callables, maxSize) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for LoopUnrolling and private LoopUnrollingNamespaces (parent : LoopUnrolling) = inherit NamespaceTransformationBase(parent) - override __.Transform x = - let x = base.Transform x - VariableRenaming().Namespaces.Transform x + override __.OnNamespace x = + let x = base.OnNamespace x + VariableRenaming().Namespaces.OnNamespace x /// private helper class for LoopUnrolling and private LoopUnrollingStatementKinds (parent : LoopUnrolling, callables, maxSize) = inherit Core.StatementKindTransformation(parent) - override this.onForStatement stm = - let loopVar = fst stm.LoopItem |> this.onSymbolTuple - let iterVals = this.Expressions.Transform stm.IterationValues - let loopVarType = this.Expressions.Types.Transform (snd stm.LoopItem) - let body = this.Statements.Transform stm.Body + override this.OnForStatement stm = + let loopVar = fst stm.LoopItem |> this.OnSymbolTuple + let iterVals = this.Expressions.OnTypedExpression stm.IterationValues + let loopVarType = this.Expressions.Types.OnType (snd stm.LoopItem) + let body = this.Statements.OnScope stm.Body maybe { let! iterValsList = match iterVals.Expression with @@ -49,7 +51,7 @@ and private LoopUnrollingStatementKinds (parent : LoopUnrolling, callables, maxS let innerScope = { stm.Body with Statements = stm.Body.Statements.Insert(0, variableDecl) } innerScope |> newScopeStatement |> wrapStmt) let outerScope = QsScope.New (iterRange, stm.Body.KnownSymbols) - return outerScope |> newScopeStatement |> this.Transform + return outerScope |> newScopeStatement |> this.OnStatementKind } |? (QsForStatement.New ((loopVar, loopVarType), iterVals, body) |> QsForStatement) diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/StatementGrouping.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/StatementGrouping.fs index 3db0899d45..545444e4a0 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/StatementGrouping.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/StatementGrouping.fs @@ -16,6 +16,8 @@ type StatementGrouping private (_private_ : string) = new () as this = new StatementGrouping("_private_") then this.Statements <- new StatementGroupingStatements(this) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for StatementGrouping and private StatementGroupingStatements (parent : StatementGrouping) = @@ -25,14 +27,14 @@ and private StatementGroupingStatements (parent : StatementGrouping) = /// The statement must have no classical or quantum side effects other than defining a variable. let isPureClassical stmt = let c = SideEffectChecker() - c.Statements.onStatement stmt |> ignore + c.Statements.OnStatement stmt |> ignore not c.HasQuantum && not c.HasMutation && not c.HasInterrupts /// Returns whether a statement is purely quantum. /// The statement must have no classical side effects, but can have quantum side effects. let isPureQuantum stmt = let c = SideEffectChecker() - c.Statements.onStatement stmt |> ignore + c.Statements.OnStatement stmt |> ignore c.HasQuantum && not c.HasMutation && not c.HasInterrupts /// Reorders a list of statements such that the pure classical statements occur before the pure quantum statements @@ -43,9 +45,9 @@ and private StatementGroupingStatements (parent : StatementGrouping) = else a :: reorderStatements (b :: tail) | x -> x - override this.Transform scope = + override this.OnScope scope = let parentSymbols = scope.KnownSymbols - let statements = scope.Statements |> Seq.map this.onStatement |> List.ofSeq |> reorderStatements + let statements = scope.Statements |> Seq.map this.OnStatement |> List.ofSeq |> reorderStatements QsScope.New (statements, parentSymbols) diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/StatementRemoving.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/StatementRemoving.fs index 3bddcbed36..4b8c46d234 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/StatementRemoving.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/StatementRemoving.fs @@ -10,6 +10,7 @@ open Microsoft.Quantum.QsCompiler.Experimental.Utils open Microsoft.Quantum.QsCompiler.SyntaxExtensions open Microsoft.Quantum.QsCompiler.SyntaxTokens open Microsoft.Quantum.QsCompiler.SyntaxTree +open Microsoft.Quantum.QsCompiler.Transformations /// The SyntaxTreeTransformation used to remove useless statements @@ -19,6 +20,8 @@ type StatementRemoval private (_private_ : string) = new (removeFunctions : bool) as this = new StatementRemoval("_private_") then this.Statements <- new VariableRemovalStatements(this, removeFunctions) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for StatementRemoval and private VariableRemovalStatements (parent : StatementRemoval, removeFunctions) = @@ -32,10 +35,10 @@ and private VariableRemovalStatements (parent : StatementRemoval, removeFunction override __.CollectStatements stmt = let c = SideEffectChecker() - c.StatementKinds.Transform stmt |> ignore + c.StatementKinds.OnStatementKind stmt |> ignore let c2 = MutationChecker() - c2.StatementKinds.Transform stmt |> ignore + c2.StatementKinds.OnStatementKind stmt |> ignore match stmt with | QsVariableDeclaration {Lhs = lhs} diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/TransformationBase.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/TransformationBase.fs index 882be57d04..31b2d2e9e8 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/TransformationBase.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/TransformationBase.fs @@ -31,8 +31,8 @@ and private NamespaceTransformationBase (parent : TransformationBase) = inherit NamespaceTransformation(parent) /// Checks whether the syntax tree changed at all - override this.Transform x = - let newX = base.Transform x + override this.OnNamespace x = + let newX = base.OnNamespace x if (x.Elements, x.Name) <> (newX.Elements, newX.Name) then parent.Changed <- true newX diff --git a/src/QsCompiler/Optimizations/OptimizingTransformations/VariableRemoving.fs b/src/QsCompiler/Optimizations/OptimizingTransformations/VariableRemoving.fs index 491bef87ed..9dee12b9df 100644 --- a/src/QsCompiler/Optimizations/OptimizingTransformations/VariableRemoving.fs +++ b/src/QsCompiler/Optimizations/OptimizingTransformations/VariableRemoving.fs @@ -20,22 +20,24 @@ type VariableRemoval(_private_) = new VariableRemoval("_private_") then this.Namespaces <- new VariableRemovalNamespaces(this) this.StatementKinds <- new VariableRemovalStatementKinds(this) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for VariableRemoval and private VariableRemovalNamespaces (parent : VariableRemoval) = inherit NamespaceTransformationBase(parent) - override __.onProvidedImplementation (argTuple, body) = + override __.OnProvidedImplementation (argTuple, body) = let r = ReferenceCounter() - r.Statements.Transform body |> ignore + r.Statements.OnScope body |> ignore parent.ReferenceCounter <- Some r - base.onProvidedImplementation (argTuple, body) + base.OnProvidedImplementation (argTuple, body) /// private helper class for VariableRemoval and private VariableRemovalStatementKinds (parent : VariableRemoval) = inherit Core.StatementKindTransformation(parent) - override stmtKind.onSymbolTuple syms = + override stmtKind.OnSymbolTuple syms = match syms with | VariableName item -> maybe { @@ -44,6 +46,6 @@ and private VariableRemovalStatementKinds (parent : VariableRemoval) = do! check (uses = 0) return DiscardedItem } |? syms - | VariableNameTuple items -> Seq.map stmtKind.onSymbolTuple items |> ImmutableArray.CreateRange |> VariableNameTuple + | VariableNameTuple items -> Seq.map stmtKind.OnSymbolTuple items |> ImmutableArray.CreateRange |> VariableNameTuple | InvalidItem | DiscardedItem -> syms diff --git a/src/QsCompiler/Optimizations/PreEvaluation.fs b/src/QsCompiler/Optimizations/PreEvaluation.fs index 2b73530c7c..71f78c6268 100644 --- a/src/QsCompiler/Optimizations/PreEvaluation.fs +++ b/src/QsCompiler/Optimizations/PreEvaluation.fs @@ -27,12 +27,12 @@ type PreEvaluation = // TODO: this should actually only evaluate everything for each entry point let rec evaluate (tree : _ list) = let mutable tree = tree - tree <- List.map (StripAllKnownSymbols().Namespaces.Transform) tree - tree <- List.map (VariableRenaming().Namespaces.Transform) tree + tree <- List.map (StripAllKnownSymbols().Namespaces.OnNamespace) tree + tree <- List.map (VariableRenaming().Namespaces.OnNamespace) tree let callables = GlobalCallableResolutions tree // needs to be constructed in every iteration let optimizers = script.Invoke callables |> Seq.toList - for opt in optimizers do tree <- List.map opt.Namespaces.Transform tree + for opt in optimizers do tree <- List.map opt.Namespaces.OnNamespace tree if optimizers |> List.exists (fun opt -> opt.CheckChanged()) then evaluate tree else tree diff --git a/src/QsCompiler/Optimizations/PureCircuitFinding.fs b/src/QsCompiler/Optimizations/PureCircuitFinding.fs index d748bfdc8a..67a146ced6 100644 --- a/src/QsCompiler/Optimizations/PureCircuitFinding.fs +++ b/src/QsCompiler/Optimizations/PureCircuitFinding.fs @@ -23,16 +23,18 @@ type PureCircuitFinder private (_private_ : string) = new PureCircuitFinder("_private_") then this.Namespaces <- new PureCircuitFinderNamespaces(this) this.Statements <- new PureCircuitFinderStatements(this, callables) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for PureCircuitFinder and private PureCircuitFinderNamespaces (parent : PureCircuitFinder) = inherit Core.NamespaceTransformation(parent) - override __.onCallableImplementation c = + override __.OnCallableDeclaration c = let r = FindDistinctQubits() - r.Namespaces.onCallableImplementation c |> ignore + r.Namespaces.OnCallableDeclaration c |> ignore parent.DistinctQubitFinder <- Some r - base.onCallableImplementation c + base.OnCallableDeclaration c /// private helper class for PureCircuitFinder and private PureCircuitFinderStatements (parent : PureCircuitFinder, callables : ImmutableDictionary<_,_>) = @@ -48,7 +50,7 @@ and private PureCircuitFinderStatements (parent : PureCircuitFinder, callables : | _ -> false | _ -> false - override this.Transform scope = + override this.OnScope scope = let mutable circuit = ImmutableArray.Empty let mutable newStatements = ImmutableArray.Empty @@ -69,7 +71,7 @@ and private PureCircuitFinderStatements (parent : PureCircuitFinder, callables : circuit <- circuit.Add expr | _ -> finishCircuit() - newStatements <- newStatements.Add (this.onStatement stmt) + newStatements <- newStatements.Add (this.OnStatement stmt) finishCircuit() QsScope.New (newStatements, scope.KnownSymbols) diff --git a/src/QsCompiler/Optimizations/Utils/Evaluation.fs b/src/QsCompiler/Optimizations/Utils/Evaluation.fs index d3443f7608..e352c18b03 100644 --- a/src/QsCompiler/Optimizations/Utils/Evaluation.fs +++ b/src/QsCompiler/Optimizations/Utils/Evaluation.fs @@ -64,7 +64,7 @@ type internal FunctionEvaluator(callables : IDictionary = imperative { let! vars, counter = getState - let result = ExpressionEvaluator(callables, vars, counter / 2).Expressions.Transform expr + let result = ExpressionEvaluator(callables, vars, counter / 2).Expressions.OnTypedExpression expr if isLiteral callables result then return result else yield CouldNotEvaluate ("Not a literal: " + result.Expression.ToString()) } @@ -173,19 +173,20 @@ and internal ExpressionEvaluator private (_private_) = internal new (callables : IDictionary, constants : IDictionary, stmtsLeft : int) as this = new ExpressionEvaluator("_private_") then this.ExpressionKinds <- new ExpressionKindEvaluator(this, callables, constants, stmtsLeft) - + this.Types <- new TypeTransformation(this, TransformationOptions.Disabled) + /// The ExpressionKindTransformation used to evaluate constant expressions and private ExpressionKindEvaluator(parent, callables: IDictionary, constants: IDictionary, stmtsLeft: int) = inherit ExpressionKindTransformation(parent) - member private this.simplify e1 = this.Expressions.Transform e1 + member private this.simplify e1 = this.Expressions.OnTypedExpression e1 member private this.simplify (e1, e2) = - (this.Expressions.Transform e1, this.Expressions.Transform e2) + (this.Expressions.OnTypedExpression e1, this.Expressions.OnTypedExpression e2) member private this.simplify (e1, e2, e3) = - (this.Expressions.Transform e1, this.Expressions.Transform e2, this.Expressions.Transform e3) + (this.Expressions.OnTypedExpression e1, this.Expressions.OnTypedExpression e2, this.Expressions.OnTypedExpression e3) member private this.arithBoolBinaryOp qop bigIntOp doubleOp intOp lhs rhs = let lhs, rhs = this.simplify (lhs, rhs) @@ -209,7 +210,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary IntLiteral (intOp a b) | _ -> qop (lhs, rhs) - override this.onIdentifier (sym, tArgs) = + override this.OnIdentifier (sym, tArgs) = match sym with | LocalVariable name -> match constants.TryGetValue name.Value with @@ -217,7 +218,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary Identifier (sym, tArgs) | _ -> Identifier (sym, tArgs) - override this.onFunctionCall (method, arg) = + override this.OnFunctionCall (method, arg) = let method, arg = this.simplify (method, arg) maybe { match method.Expression with @@ -227,31 +228,31 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary Option.map (fun x -> x.Expression) | CallLikeExpression (baseMethod, partialArg) -> do! check (TypedExpression.IsPartialApplication method.Expression) - return this.Transform (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) + return this.OnExpressionKind (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) | _ -> return! None } |? CallLikeExpression (method, arg) - override this.onOperationCall (method, arg) = + override this.OnOperationCall (method, arg) = let method, arg = this.simplify (method, arg) maybe { match method.Expression with | CallLikeExpression (baseMethod, partialArg) -> do! check (TypedExpression.IsPartialApplication method.Expression) - return this.Transform (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) + return this.OnExpressionKind (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) | _ -> return! None } |? CallLikeExpression (method, arg) - override this.onPartialApplication (method, arg) = + override this.OnPartialApplication (method, arg) = let method, arg = this.simplify (method, arg) maybe { match method.Expression with | CallLikeExpression (baseMethod, partialArg) -> do! check (TypedExpression.IsPartialApplication method.Expression) - return this.Transform (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) + return this.OnExpressionKind (CallLikeExpression (baseMethod, fillPartialArg (partialArg, arg))) | _ -> return! None } |? CallLikeExpression (method, arg) - override this.onUnwrapApplication ex = + override this.OnUnwrapApplication ex = let ex = this.simplify ex match ex.Expression with | CallLikeExpression ({Expression = Identifier (GlobalCallable qualName, types)}, arg) @@ -266,7 +267,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary UnwrapApplication ex - override this.onArrayItem (arr, idx) = + override this.OnArrayItem (arr, idx) = let arr, idx = this.simplify (arr, idx) match arr.Expression, idx.Expression with | ValueArray va, IntLiteral i -> va.[safeCastInt64 i].Expression @@ -274,13 +275,13 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary Seq.map (fun i -> va.[safeCastInt64 i]) |> ImmutableArray.CreateRange |> ValueArray | _ -> ArrayItem (arr, idx) - override this.onNewArray (bt, idx) = + override this.OnNewArray (bt, idx) = let idx = this.simplify idx match idx.Expression with | IntLiteral i -> constructNewArray bt.Resolution (safeCastInt64 i) |? NewArray (bt, idx) | _ -> NewArray (bt, idx) - override this.onCopyAndUpdateExpression (lhs, accEx, rhs) = + override this.OnCopyAndUpdateExpression (lhs, accEx, rhs) = let lhs, accEx, rhs = this.simplify (lhs, accEx, rhs) match lhs.Expression, accEx.Expression, rhs.Expression with | ValueArray va, IntLiteral i, _ -> ValueArray (va.SetItem(safeCastInt64 i, rhs)) @@ -290,44 +291,44 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary CopyAndUpdate (lhs, accEx, rhs) - override this.onConditionalExpression (e1, e2, e3) = + override this.OnConditionalExpression (e1, e2, e3) = let e1 = this.simplify e1 match e1.Expression with | BoolLiteral a -> if a then (this.simplify e2).Expression else (this.simplify e3).Expression | _ -> CONDITIONAL (e1, this.simplify e2, this.simplify e3) - override this.onEquality (lhs, rhs) = + override this.OnEquality (lhs, rhs) = let lhs, rhs = this.simplify (lhs, rhs) match isLiteral callables lhs && isLiteral callables rhs with | true -> BoolLiteral (lhs.Expression = rhs.Expression) | false -> EQ (lhs, rhs) - override this.onInequality (lhs, rhs) = + override this.OnInequality (lhs, rhs) = let lhs, rhs = this.simplify (lhs, rhs) match isLiteral callables lhs && isLiteral callables rhs with | true -> BoolLiteral (lhs.Expression <> rhs.Expression) | false -> NEQ (lhs, rhs) - override this.onLessThan (lhs, rhs) = + override this.OnLessThan (lhs, rhs) = this.arithBoolBinaryOp LT (<) (<) (<) lhs rhs - override this.onLessThanOrEqual (lhs, rhs) = + override this.OnLessThanOrEqual (lhs, rhs) = this.arithBoolBinaryOp LTE (<=) (<=) (<=) lhs rhs - override this.onGreaterThan (lhs, rhs) = + override this.OnGreaterThan (lhs, rhs) = this.arithBoolBinaryOp GT (>) (>) (>) lhs rhs - override this.onGreaterThanOrEqual (lhs, rhs) = + override this.OnGreaterThanOrEqual (lhs, rhs) = this.arithBoolBinaryOp GTE (>=) (>=) (>=) lhs rhs - override this.onLogicalAnd (lhs, rhs) = + override this.OnLogicalAnd (lhs, rhs) = let lhs = this.simplify lhs match lhs.Expression with | BoolLiteral true -> (this.simplify rhs).Expression | BoolLiteral false -> BoolLiteral false | _ -> AND (lhs, this.simplify rhs) - override this.onLogicalOr (lhs, rhs) = + override this.OnLogicalOr (lhs, rhs) = let lhs = this.simplify lhs match lhs.Expression with | BoolLiteral true -> BoolLiteral true @@ -339,7 +340,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary ValueArray (a.AddRange b) @@ -358,7 +359,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary op @@ -381,7 +382,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary this.arithNumBinaryOp MUL (*) (*) (*) lhs rhs // - simplifies multiplication of two constants into single constant - override this.onDivision (lhs, rhs) = + override this.OnDivision (lhs, rhs) = let lhs, rhs = this.simplify (lhs, rhs) match lhs.Expression, rhs.Expression with | op, (BigIntLiteral one) when one.IsOne -> op @@ -407,7 +408,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary op | _ -> this.arithNumBinaryOp DIV (/) (/) (/) lhs rhs - override this.onExponentiate (lhs, rhs) = + override this.OnExponentiate (lhs, rhs) = let lhs, rhs = this.simplify (lhs, rhs) match lhs.Expression, rhs.Expression with | BigIntLiteral a, IntLiteral b -> BigIntLiteral (BigInteger.Pow(a, safeCastInt64 b)) @@ -415,31 +416,31 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary IntLiteral (longPow a b) | _ -> POW (lhs, rhs) - override this.onModulo (lhs, rhs) = + override this.OnModulo (lhs, rhs) = this.intBinaryOp MOD (%) (%) lhs rhs - override this.onLeftShift (lhs, rhs) = + override this.OnLeftShift (lhs, rhs) = this.intBinaryOp LSHIFT (fun l r -> l <<< safeCastBigInt r) (fun l r -> l <<< safeCastInt64 r) lhs rhs - override this.onRightShift (lhs, rhs) = + override this.OnRightShift (lhs, rhs) = this.intBinaryOp RSHIFT (fun l r -> l >>> safeCastBigInt r) (fun l r -> l >>> safeCastInt64 r) lhs rhs - override this.onBitwiseExclusiveOr (lhs, rhs) = + override this.OnBitwiseExclusiveOr (lhs, rhs) = this.intBinaryOp BXOR (^^^) (^^^) lhs rhs - override this.onBitwiseOr (lhs, rhs) = + override this.OnBitwiseOr (lhs, rhs) = this.intBinaryOp BOR (|||) (|||) lhs rhs - override this.onBitwiseAnd (lhs, rhs) = + override this.OnBitwiseAnd (lhs, rhs) = this.intBinaryOp BAND (&&&) (&&&) lhs rhs - override this.onLogicalNot expr = + override this.OnLogicalNot expr = let expr = this.simplify expr match expr.Expression with | BoolLiteral a -> BoolLiteral (not a) | _ -> NOT expr - override this.onNegative expr = + override this.OnNegative expr = let expr = this.simplify expr match expr.Expression with | BigIntLiteral a -> BigIntLiteral (-a) @@ -447,7 +448,7 @@ and private ExpressionKindEvaluator(parent, callables: IDictionary IntLiteral (-a) | _ -> NEG expr - override this.onBitwiseNot expr = + override this.OnBitwiseNot expr = let expr = this.simplify expr match expr.Expression with | IntLiteral a -> IntLiteral (~~~a) diff --git a/src/QsCompiler/Optimizations/Utils/OptimizationTools.fs b/src/QsCompiler/Optimizations/Utils/OptimizationTools.fs index 36636d7102..90e087510f 100644 --- a/src/QsCompiler/Optimizations/Utils/OptimizationTools.fs +++ b/src/QsCompiler/Optimizations/Utils/OptimizationTools.fs @@ -22,26 +22,28 @@ type internal FindDistinctQubits private (_private_) = new FindDistinctQubits("_private_") then this.Namespaces <- new DistinctQubitsNamespaces(this) this.StatementKinds <- new DistinctQubitsStatementKinds(this) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for FindDistinctQubits and private DistinctQubitsNamespaces (parent : FindDistinctQubits) = inherit Core.NamespaceTransformation(parent) - override this.onProvidedImplementation (argTuple, body) = + override this.OnProvidedImplementation (argTuple, body) = argTuple |> toSymbolTuple |> flatten |> Seq.iter (function | VariableName name -> parent.DistinctNames <- parent.DistinctNames.Add name | _ -> ()) - base.onProvidedImplementation (argTuple, body) + base.OnProvidedImplementation (argTuple, body) /// private helper class for FindDistinctQubits and private DistinctQubitsStatementKinds (parent : FindDistinctQubits) = inherit Core.StatementKindTransformation(parent) - override this.onQubitScope stm = + override this.OnQubitScope stm = stm.Binding.Lhs |> flatten |> Seq.iter (function | VariableName name -> parent.DistinctNames <- parent.DistinctNames.Add name | _ -> ()) - base.onQubitScope stm + base.OnQubitScope stm /// A transformation that tracks what variables the transformed code could mutate. @@ -58,25 +60,27 @@ type internal MutationChecker private (_private_) = internal new () as this = new MutationChecker("_private_") then this.StatementKinds <- new MutationCheckerStatementKinds(this) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for MutationChecker and private MutationCheckerStatementKinds(parent : MutationChecker) = inherit Core.StatementKindTransformation(parent) - override this.onVariableDeclaration stm = + override this.OnVariableDeclaration stm = flatten stm.Lhs |> Seq.iter (function | VariableName name -> parent.DeclaredVariables <- parent.DeclaredVariables.Add name | _ -> ()) - base.onVariableDeclaration stm + base.OnVariableDeclaration stm - override this.onValueUpdate stm = + override this.OnValueUpdate stm = match stm.Lhs with | LocalVarTuple v -> flatten v |> Seq.iter (function | VariableName name -> parent.MutatedVariables <- parent.MutatedVariables.Add name | _ -> ()) | _ -> () - base.onValueUpdate stm + base.OnValueUpdate stm /// A transformation that counts how many times each local variable is referenced. @@ -92,23 +96,24 @@ type internal ReferenceCounter private (_private_) = internal new () as this = new ReferenceCounter("_private_") then this.ExpressionKinds <- new ReferenceCounterExpressionKinds(this) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for ReferenceCounter and private ReferenceCounterExpressionKinds(parent : ReferenceCounter) = inherit Core.ExpressionKindTransformation(parent) - override this.onIdentifier (sym, tArgs) = + override this.OnIdentifier (sym, tArgs) = match sym with | LocalVariable name -> parent.UsedVariables <- parent.UsedVariables.Add (name, parent.NumberOfUses name + 1) | _ -> () - base.onIdentifier (sym, tArgs) + base.OnIdentifier (sym, tArgs) /// private helper class for ReplaceTypeParams type private ReplaceTypeParamsTypes(parent : Core.SyntaxTreeTransformation<_>) = inherit Core.TypeTransformation, ResolvedType>>(parent) - override this.onTypeParameter tp = + override this.OnTypeParameter tp = let key = tp.Origin, tp.TypeName match this.SharedState.TryGetValue key with | true, t -> t.Resolution @@ -129,31 +134,31 @@ type internal ReplaceTypeParams private (typeParams: ImmutableDictionary<_, Reso type private SideEffectCheckerExpressionKinds(parent : SideEffectChecker) = inherit Core.ExpressionKindTransformation(parent) - override this.onFunctionCall (method, arg) = + override this.OnFunctionCall (method, arg) = parent.HasOutput <- true - base.onFunctionCall (method, arg) + base.OnFunctionCall (method, arg) - override this.onOperationCall (method, arg) = + override this.OnOperationCall (method, arg) = parent.HasQuantum <- true parent.HasOutput <- true - base.onOperationCall (method, arg) + base.OnOperationCall (method, arg) /// private helper class for SideEffectChecker and private SideEffectCheckerStatementKinds(parent : SideEffectChecker) = inherit Core.StatementKindTransformation(parent) - override this.onValueUpdate stm = + override this.OnValueUpdate stm = let mutatesState = match stm.Lhs with LocalVarTuple x when isAllDiscarded x -> false | _ -> true parent.HasMutation <- parent.HasMutation || mutatesState - base.onValueUpdate stm + base.OnValueUpdate stm - override this.onReturnStatement stm = + override this.OnReturnStatement stm = parent.HasInterrupts <- true - base.onReturnStatement stm + base.OnReturnStatement stm - override this.onFailStatement stm = + override this.OnFailStatement stm = parent.HasInterrupts <- true - base.onFailStatement stm + base.OnFailStatement stm /// A ScopeTransformation that tracks what side effects the transformed code could cause and internal SideEffectChecker private (_private_) = @@ -172,6 +177,7 @@ and internal SideEffectChecker private (_private_) = new SideEffectChecker("_private_") then this.ExpressionKinds <- new SideEffectCheckerExpressionKinds(this) this.StatementKinds <- new SideEffectCheckerStatementKinds(this) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// A ScopeTransformation that replaces one statement with zero or more statements @@ -180,11 +186,11 @@ type [] internal StatementCollectorTransformation(parent : Core.S abstract member CollectStatements: QsStatementKind -> QsStatementKind seq - override this.Transform scope = + override this.OnScope scope = let parentSymbols = scope.KnownSymbols let statements = scope.Statements - |> Seq.map this.onStatement + |> Seq.map this.OnStatement |> Seq.map (fun x -> x.Statement) |> Seq.collect this.CollectStatements |> Seq.map wrapStmt @@ -198,11 +204,13 @@ type internal StripAllKnownSymbols(_private_) = internal new () as this = new StripAllKnownSymbols("_private_") then this.Statements <- new StripAllKnownSymbolsStatements(this) + this.Expressions <- new Core.ExpressionTransformation(this, Core.TransformationOptions.Disabled) + this.Types <- new Core.TypeTransformation(this, Core.TransformationOptions.Disabled) /// private helper class for StripAllKnownSymbols and private StripAllKnownSymbolsStatements(parent : StripAllKnownSymbols) = inherit Core.StatementTransformation(parent) - override this.Transform scope = - QsScope.New (scope.Statements |> Seq.map this.onStatement, LocalDeclarations.Empty) + override this.OnScope scope = + QsScope.New (scope.Statements |> Seq.map this.OnStatement, LocalDeclarations.Empty) diff --git a/src/QsCompiler/Optimizations/Utils/VariableRenaming.fs b/src/QsCompiler/Optimizations/Utils/VariableRenaming.fs index ffc54720f0..9cb58ee935 100644 --- a/src/QsCompiler/Optimizations/Utils/VariableRenaming.fs +++ b/src/QsCompiler/Optimizations/Utils/VariableRenaming.fs @@ -70,6 +70,7 @@ type VariableRenaming private (_private_) = this.Statements <- new VariableRenamingStatements(this) this.StatementKinds <- new VariableRenamingStatementKinds(this) this.ExpressionKinds <- new VariableRenamingExpressionKinds(this) + this.Types <- new TypeTransformation(this, TransformationOptions.Disabled) /// private helper class for VariableRenaming and private VariableRenamingNamespaces (parent : VariableRenaming) = @@ -81,22 +82,22 @@ and private VariableRenamingNamespaces (parent : VariableRenaming) = | QsTupleItem {VariableName = InvalidName} -> () | QsTuple items -> Seq.iter processArgTuple items - override __.onProvidedImplementation (argTuple, body) = + override __.OnProvidedImplementation (argTuple, body) = parent.Clear() do processArgTuple argTuple - base.onProvidedImplementation (argTuple, body) + base.OnProvidedImplementation (argTuple, body) /// private helper class for VariableRenaming and private VariableRenamingStatements (parent : VariableRenaming) = inherit StatementTransformation(parent) - override this.Transform x = + override this.OnScope x = if parent.SkipScope then parent.SkipScope <- false - base.Transform x + base.OnScope x else parent.RenamingStack <- parent.EnterScope parent.RenamingStack - let result = base.Transform x + let result = base.OnScope x parent.RenamingStack <- parent.ExitScope parent.RenamingStack result @@ -104,16 +105,16 @@ and private VariableRenamingStatements (parent : VariableRenaming) = and private VariableRenamingStatementKinds (parent : VariableRenaming) = inherit StatementKindTransformation(parent) - override this.onSymbolTuple syms = + override this.OnSymbolTuple syms = match syms with | VariableName item -> VariableName (NonNullable<_>.New (parent.GenerateUniqueName item.Value)) - | VariableNameTuple items -> Seq.map this.onSymbolTuple items |> ImmutableArray.CreateRange |> VariableNameTuple + | VariableNameTuple items -> Seq.map this.OnSymbolTuple items |> ImmutableArray.CreateRange |> VariableNameTuple | InvalidItem | DiscardedItem -> syms - override this.onRepeatStatement stm = + override this.OnRepeatStatement stm = parent.RenamingStack <- parent.EnterScope parent.RenamingStack parent.SkipScope <- true - let result = base.onRepeatStatement stm + let result = base.OnRepeatStatement stm parent.RenamingStack <- parent.ExitScope parent.RenamingStack result @@ -126,7 +127,7 @@ and private VariableRenamingExpressionKinds (parent : VariableRenaming) = /// Returns None if the key isn't associated with any values. let tryGet key = List.tryPick (Map.tryFind key) - override this.onIdentifier (sym, tArgs) = + override this.OnIdentifier (sym, tArgs) = maybe { let! name = match sym with diff --git a/src/QsCompiler/SyntaxProcessor/DeclarationVerification.fs b/src/QsCompiler/SyntaxProcessor/DeclarationVerification.fs index bc0d830d78..05045779bc 100644 --- a/src/QsCompiler/SyntaxProcessor/DeclarationVerification.fs +++ b/src/QsCompiler/SyntaxProcessor/DeclarationVerification.fs @@ -164,7 +164,7 @@ let rec private singleAdditionalArg mismatchErr (qsSym : QsSymbol) = | sym -> sym |> singleAndOmitted |> nameAndRange false -let private StripRangeInfo = StripPositionInfo.Default.Namespaces.onArgumentTuple +let private StripRangeInfo = StripPositionInfo.Default.Namespaces.OnArgumentTuple /// Given the declared argument tuple of a callable, and the declared symbol tuple for the corresponding body specialization, /// verifies that the symbol tuple indeed has the expected shape for that specialization. diff --git a/src/QsCompiler/SyntaxProcessor/ExpressionVerification.fs b/src/QsCompiler/SyntaxProcessor/ExpressionVerification.fs index 4d07377f87..0e8ed39b8a 100644 --- a/src/QsCompiler/SyntaxProcessor/ExpressionVerification.fs +++ b/src/QsCompiler/SyntaxProcessor/ExpressionVerification.fs @@ -25,11 +25,11 @@ open Microsoft.Quantum.QsCompiler.Transformations.QsCodeOutput type private StripInferredInfoFromType () = inherit TypeTransformationBase() - default this.onCallableInformation opInfo = - let characteristics = this.onCharacteristicsExpression opInfo.Characteristics + default this.OnCallableInformation opInfo = + let characteristics = this.OnCharacteristicsExpression opInfo.Characteristics CallableInformation.New (characteristics, InferredCallableInformation.NoInformation) - override this.onRangeInformation _ = QsRangeInfo.Null -let private StripInferredInfoFromType = (new StripInferredInfoFromType()).Transform + override this.OnRangeInformation _ = QsRangeInfo.Null +let private StripInferredInfoFromType = (new StripInferredInfoFromType()).OnType /// used for type matching arguments in call-like expressions type private Variance = @@ -50,7 +50,7 @@ let private missingFunctors (target : ImmutableHashSet<_>, given) = /// Return the string representation for a ResolveType. /// User defined types are represented by their full name. -let internal toString (t : ResolvedType) = SyntaxTreeToQs.Default.ToCode t +let internal toString (t : ResolvedType) = SyntaxTreeToQsharp.Default.ToCode t /// Given two resolve types, determines and returns a common base type if such a type exists, /// or pushes adds a suitable error using addError and returns invalid type if a common base type does not exist. diff --git a/src/QsCompiler/SyntaxProcessor/StatementVerification.fs b/src/QsCompiler/SyntaxProcessor/StatementVerification.fs index 347196f8e9..34437cfdde 100644 --- a/src/QsCompiler/SyntaxProcessor/StatementVerification.fs +++ b/src/QsCompiler/SyntaxProcessor/StatementVerification.fs @@ -266,11 +266,11 @@ let NewConjugation (outer : QsPositionedBlock, inner : QsPositionedBlock) = | Value loc -> loc let usedInOuter = let accumulate = new AccumulateIdentifiers() - accumulate.Statements.Transform outer.Body |> ignore + accumulate.Statements.OnScope outer.Body |> ignore accumulate.SharedState.UsedLocalVariables let updatedInInner = let accumulate = new AccumulateIdentifiers() - accumulate.Statements.Transform inner.Body |> ignore + accumulate.Statements.OnScope inner.Body |> ignore accumulate.SharedState.ReassignedVariables let updateErrs = updatedInInner |> Seq.filter (fun updated -> usedInOuter.Contains updated.Key) |> Seq.collect id diff --git a/src/QsCompiler/SyntaxProcessor/SyntaxExtensions.fs b/src/QsCompiler/SyntaxProcessor/SyntaxExtensions.fs index cb7c1786da..1ae3433ed8 100644 --- a/src/QsCompiler/SyntaxProcessor/SyntaxExtensions.fs +++ b/src/QsCompiler/SyntaxProcessor/SyntaxExtensions.fs @@ -260,23 +260,23 @@ let private namespaceDocumentation (docs : ILookup, Immutabl PrintSummary allDoc markdown type private TName () = - inherit SyntaxTreeToQs.TypeTransformation() - override this.onCharacteristicsExpression characteristics = + inherit SyntaxTreeToQsharp.TypeTransformation() + override this.OnCharacteristicsExpression characteristics = if characteristics.AreInvalid then this.Output <- "?"; characteristics - else base.onCharacteristicsExpression characteristics - override this.onInvalidType() = + else base.OnCharacteristicsExpression characteristics + override this.OnInvalidType() = this.Output <- "?" InvalidType - override this.onUserDefinedType udt = + override this.OnUserDefinedType udt = this.Output <- udt.Name.Value UserDefinedType udt member this.Apply t = - this.Transform t |> ignore + this.OnType t |> ignore this.Output let private TypeString = new TName() let private TypeName = TypeString.Apply let private CharacteristicsAnnotation (ex, format) = - let charEx = SyntaxTreeToQs.CharacteristicsExpression ex + let charEx = SyntaxTreeToQsharp.CharacteristicsExpression ex if String.IsNullOrWhiteSpace charEx then "" else sprintf "is %s" charEx |> format [] @@ -338,14 +338,14 @@ let private printCallableKind capitalize = function [] let public PrintArgumentTuple item = - SyntaxTreeToQs.ArgumentTuple (item, new Func<_,_>(TypeName)) // note: needs to match the corresponding part of the output constructed by PrintSignature below! + SyntaxTreeToQsharp.ArgumentTuple (item, new Func<_,_>(TypeName)) // note: needs to match the corresponding part of the output constructed by PrintSignature below! [] let public PrintSignature (header : CallableDeclarationHeader) = let callable = QsCallable.New header.Kind (header.SourceFile, Null) (header.QualifiedName, header.Attributes, header.ArgumentTuple, header.Signature, ImmutableArray.Empty, ImmutableArray.Empty, QsComments.Empty); - let signature = SyntaxTreeToQs.DeclarationSignature (callable, new Func<_,_>(TypeName)) + let signature = SyntaxTreeToQsharp.DeclarationSignature (callable, new Func<_,_>(TypeName)) let annotation = CharacteristicsAnnotation (header.Signature.Information.Characteristics, sprintf "%s%s" newLine) sprintf "%s%s" signature annotation @@ -393,7 +393,7 @@ let public DeclarationInfo symbolTable (locals : LocalDeclarations) (currentNS, match qsSym |> globalCallableResolution symbolTable (currentNS, source) with | Some decl, _ -> let functorSupport characteristics = - let charEx = SyntaxTreeToQs.CharacteristicsExpression characteristics + let charEx = SyntaxTreeToQsharp.CharacteristicsExpression characteristics if String.IsNullOrWhiteSpace charEx then "(None)" else charEx let name = sprintf "%s %s" (printCallableKind false decl.Kind) decl.QualifiedName.Name.Value |> withNewLine let ns = sprintf "Namespace: %s" decl.QualifiedName.Namespace.Value |> withNewLine diff --git a/src/QsCompiler/TestTargets/Libraries/Library1/Library1.csproj b/src/QsCompiler/TestTargets/Libraries/Library1/Library1.csproj index 9d5f7d4c16..72dbc58f20 100644 --- a/src/QsCompiler/TestTargets/Libraries/Library1/Library1.csproj +++ b/src/QsCompiler/TestTargets/Libraries/Library1/Library1.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/QsCompiler/TestTargets/Simulation/Example/Example.csproj b/src/QsCompiler/TestTargets/Simulation/Example/Example.csproj index 21f6c31265..2af5587230 100644 --- a/src/QsCompiler/TestTargets/Simulation/Example/Example.csproj +++ b/src/QsCompiler/TestTargets/Simulation/Example/Example.csproj @@ -1,4 +1,4 @@ - + Detailed diff --git a/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj b/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj index e777b80bba..358ecdad77 100644 --- a/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj +++ b/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/QsCompiler/Tests.Compiler/ClassicalControlTests.fs b/src/QsCompiler/Tests.Compiler/ClassicalControlTests.fs index 753354f83b..89be97a4bc 100644 --- a/src/QsCompiler/Tests.Compiler/ClassicalControlTests.fs +++ b/src/QsCompiler/Tests.Compiler/ClassicalControlTests.fs @@ -9,7 +9,7 @@ open Microsoft.Quantum.QsCompiler open Microsoft.Quantum.QsCompiler.CompilationBuilder open Microsoft.Quantum.QsCompiler.DataTypes open Microsoft.Quantum.QsCompiler.SyntaxTree -open Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlledTransformation +open Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlled open Xunit open Microsoft.Quantum.QsCompiler.Transformations.QsCodeOutput open System.Text.RegularExpressions @@ -50,7 +50,7 @@ type ClassicalControlTests () = srcChunks.Length >= testNumber + 1 |> Assert.True let shared = srcChunks.[0] let compilationDataStructures = BuildContent <| shared + srcChunks.[testNumber] - let processedCompilation = ClassicallyControlledTransformation.Apply compilationDataStructures.BuiltCompilation + let processedCompilation = ReplaceClassicalControl.Apply compilationDataStructures.BuiltCompilation Assert.NotNull processedCompilation Signatures.SignatureCheck [Signatures.ClassicalControlNs] Signatures.ClassicalControlSignatures.[testNumber-1] processedCompilation processedCompilation @@ -61,12 +61,12 @@ type ClassicalControlTests () = let GetCtlAdjFromCallable call = call.Specializations |> Seq.find (fun x -> x.Kind = QsSpecializationKind.QsControlledAdjoint) let GetLinesFromSpecialization specialization = - let writer = new SyntaxTreeToQs() + let writer = new SyntaxTreeToQsharp() specialization |> fun x -> match x.Implementation with | Provided (_, body) -> Some body | _ -> None |> Option.get - |> writer.Statements.Transform + |> writer.Statements.OnScope |> ignore writer.SharedState.StatementOutputHandle diff --git a/src/QsCompiler/Tests.Compiler/LinkingTests.fs b/src/QsCompiler/Tests.Compiler/LinkingTests.fs index 0b11ed2847..e97dd4f3ce 100644 --- a/src/QsCompiler/Tests.Compiler/LinkingTests.fs +++ b/src/QsCompiler/Tests.Compiler/LinkingTests.fs @@ -12,9 +12,9 @@ open Microsoft.Quantum.QsCompiler.DataTypes open Microsoft.Quantum.QsCompiler.Diagnostics open Microsoft.Quantum.QsCompiler.SyntaxExtensions open Microsoft.Quantum.QsCompiler.SyntaxTree -open Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolutionTransformation -open Microsoft.Quantum.QsCompiler.Transformations.MonomorphizationTransformation -open Microsoft.Quantum.QsCompiler.Transformations.MonomorphizationValidationTransformation +open Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolution +open Microsoft.Quantum.QsCompiler.Transformations.Monomorphization +open Microsoft.Quantum.QsCompiler.Transformations.Monomorphization.Validation open Xunit open Xunit.Abstractions @@ -71,10 +71,10 @@ type LinkingTests (output:ITestOutputHelper) = let compilationDataStructures = this.BuildContent input - let monomorphicCompilation = MonomorphizationTransformation.Apply compilationDataStructures.BuiltCompilation + let monomorphicCompilation = Monomorphize.Apply compilationDataStructures.BuiltCompilation Assert.NotNull monomorphicCompilation - MonomorphizationValidationTransformation.Apply monomorphicCompilation + ValidateMonomorphization.Apply monomorphicCompilation monomorphicCompilation @@ -83,7 +83,7 @@ type LinkingTests (output:ITestOutputHelper) = let envDS = this.BuildContent environment let sourceDS = this.BuildContent source - IntrinsicResolutionTransformation.Apply(envDS.BuiltCompilation, sourceDS.BuiltCompilation) + ReplaceWithTargetIntrinsics.Apply(envDS.BuiltCompilation, sourceDS.BuiltCompilation) member private this.RunIntrinsicResolutionTest testNumber = diff --git a/src/QsCompiler/Tests.Compiler/OptimizationTests.fs b/src/QsCompiler/Tests.Compiler/OptimizationTests.fs index 85ab888b44..f1b296247e 100644 --- a/src/QsCompiler/Tests.Compiler/OptimizationTests.fs +++ b/src/QsCompiler/Tests.Compiler/OptimizationTests.fs @@ -26,7 +26,7 @@ let private buildCompilation code = let private optimize code = let mutable compilation = buildCompilation code compilation <- PreEvaluation.All compilation - String.Join(Environment.NewLine, compilation.Namespaces |> Seq.map SyntaxTreeToQs.Default.ToCode) + String.Join(Environment.NewLine, compilation.Namespaces |> Seq.map SyntaxTreeToQsharp.Default.ToCode) /// Helper function that saves the compiler output as a test case (in the bin directory) let private createTestCase path = diff --git a/src/QsCompiler/Tests.Compiler/RegexTests.fs b/src/QsCompiler/Tests.Compiler/RegexTests.fs index d8d2745681..afbbd53c62 100644 --- a/src/QsCompiler/Tests.Compiler/RegexTests.fs +++ b/src/QsCompiler/Tests.Compiler/RegexTests.fs @@ -83,23 +83,23 @@ let ``Strip unique variable name resolution`` () = |> List.map NonNullable.New origNames - |> List.map (fun var -> var, NameResolution.StripUniqueName var) + |> List.map (fun var -> var, UniqueVariableNames.StripUniqueName var) |> List.iter Assert.Equal origNames |> List.map NameResolution.SharedState.GenerateUniqueName |> List.map (fun unique -> unique, NameResolution.SharedState.GenerateUniqueName unique) - |> List.map (fun (unique, twiceWrapped) -> unique, NameResolution.StripUniqueName twiceWrapped) + |> List.map (fun (unique, twiceWrapped) -> unique, UniqueVariableNames.StripUniqueName twiceWrapped) |> List.iter Assert.Equal origNames |> List.map (fun var -> var, NameResolution.SharedState.GenerateUniqueName var) |> List.map (fun (var, unique) -> var, NameResolution.SharedState.GenerateUniqueName unique) - |> List.map (fun (var, twiceWrapped) -> var, NameResolution.StripUniqueName twiceWrapped) - |> List.map (fun (var, unique) -> var, NameResolution.StripUniqueName unique) + |> List.map (fun (var, twiceWrapped) -> var, UniqueVariableNames.StripUniqueName twiceWrapped) + |> List.map (fun (var, unique) -> var, UniqueVariableNames.StripUniqueName unique) |> List.iter Assert.Equal origNames |> List.map (fun var -> var, NameResolution.SharedState.GenerateUniqueName var) - |> List.map (fun (var, unique) -> var, NameResolution.StripUniqueName unique) + |> List.map (fun (var, unique) -> var, UniqueVariableNames.StripUniqueName unique) |> List.iter Assert.Equal diff --git a/src/QsCompiler/Tests.Compiler/TestUtils/Signatures.fs b/src/QsCompiler/Tests.Compiler/TestUtils/Signatures.fs index f25d01c1b5..e7fd7462ac 100644 --- a/src/QsCompiler/Tests.Compiler/TestUtils/Signatures.fs +++ b/src/QsCompiler/Tests.Compiler/TestUtils/Signatures.fs @@ -86,7 +86,7 @@ let public SignatureCheck checkedNamespaces targetSignatures compilation = let makeArgsString (args : ResolvedType) = match args.Resolution with | QsTypeKind.UnitType -> "()" - | _ -> args |> SyntaxTreeToQs.Default.ToCode + | _ -> args |> SyntaxTreeToQsharp.Default.ToCode let removeAt i lst = Seq.append diff --git a/src/QsCompiler/Tests.Compiler/TransformationTests.fs b/src/QsCompiler/Tests.Compiler/TransformationTests.fs index 6f134d5a15..2a376638b5 100644 --- a/src/QsCompiler/Tests.Compiler/TransformationTests.fs +++ b/src/QsCompiler/Tests.Compiler/TransformationTests.fs @@ -41,34 +41,34 @@ type private SyntaxCounter private(counter : Counter, ?options) = and private SyntaxCounterNamespaces(parent : SyntaxCounter) = inherit NamespaceTransformation(parent) - override this.beforeCallable (node:QsCallable) = + override this.OnCallableDeclaration (node:QsCallable) = match node.Kind with | Operation -> parent.Counter.opsCount <- parent.Counter.opsCount + 1 | Function -> parent.Counter.funCount <- parent.Counter.funCount + 1 | TypeConstructor -> () - node + base.OnCallableDeclaration node - override this.onType (udt:QsCustomType) = + override this.OnTypeDeclaration (udt:QsCustomType) = parent.Counter.udtCount <- parent.Counter.udtCount + 1 - base.onType udt + base.OnTypeDeclaration udt and private SyntaxCounterStatementKinds(parent : SyntaxCounter) = inherit StatementKindTransformation(parent) - override this.onConditionalStatement (node:QsConditionalStatement) = + override this.OnConditionalStatement (node:QsConditionalStatement) = parent.Counter.ifsCount <- parent.Counter.ifsCount + 1 - base.onConditionalStatement node + base.OnConditionalStatement node - override this.onForStatement (node:QsForStatement) = + override this.OnForStatement (node:QsForStatement) = parent.Counter.forCount <- parent.Counter.forCount + 1 - base.onForStatement node + base.OnForStatement node and private SyntaxCounterExpressionKinds(parent : SyntaxCounter) = inherit ExpressionKindTransformation(parent) - override this.beforeCallLike (op,args) = + override this.OnCallLikeExpression (op,args) = parent.Counter.callsCount <- parent.Counter.callsCount + 1 - base.beforeCallLike (op, args) + base.OnCallLikeExpression (op, args) let private buildSyntaxTree code = @@ -87,7 +87,7 @@ let private buildSyntaxTree code = let ``basic walk`` () = let tree = Path.Combine(Path.GetFullPath ".", "TestCases", "Transformation.qs") |> File.ReadAllText |> buildSyntaxTree let walker = new SyntaxCounter(TransformationOptions.NoRebuild) - tree |> Seq.iter (walker.Namespaces.Transform >> ignore) + tree |> Seq.iter (walker.Namespaces.OnNamespace >> ignore) Assert.Equal (4, walker.Counter.udtCount) Assert.Equal (1, walker.Counter.funCount) @@ -100,7 +100,7 @@ let ``basic walk`` () = let ``basic transformation`` () = let tree = Path.Combine(Path.GetFullPath ".", "TestCases", "Transformation.qs") |> File.ReadAllText |> buildSyntaxTree let walker = new SyntaxCounter() - tree |> Seq.iter (walker.Namespaces.Transform >> ignore) + tree |> Seq.iter (walker.Namespaces.OnNamespace >> ignore) Assert.Equal (4, walker.Counter.udtCount) Assert.Equal (1, walker.Counter.funCount) @@ -133,7 +133,7 @@ let ``generation of open statements`` () = let imports = ImmutableDictionary.Empty.Add(ns.Name, openDirectives) let codeOutput = ref null - SyntaxTreeToQs.Apply (codeOutput, tree, struct (source, imports)) |> Assert.True + SyntaxTreeToQsharp.Apply (codeOutput, tree, struct (source, imports)) |> Assert.True let lines = Utils.SplitLines (codeOutput.Value.Single().[ns.Name]) Assert.Equal(13, lines.Count()) diff --git a/src/QsCompiler/Transformations/BasicTransformations.cs b/src/QsCompiler/Transformations/BasicTransformations.cs index 50ffc41b91..e8195ff9ce 100644 --- a/src/QsCompiler/Transformations/BasicTransformations.cs +++ b/src/QsCompiler/Transformations/BasicTransformations.cs @@ -12,8 +12,8 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.BasicTransformations { - public class GetSourceFiles : - SyntaxTreeTransformation + public class GetSourceFiles + : SyntaxTreeTransformation { public class TransformationState { @@ -22,10 +22,14 @@ public class TransformationState } - private GetSourceFiles() : - base(new TransformationState()) => + private GetSourceFiles() + : base(new TransformationState(), TransformationOptions.NoRebuild) + { this.Namespaces = new NamespaceTransformation(this); - + this.Statements = new StatementTransformation(this, TransformationOptions.Disabled); + this.Expressions = new ExpressionTransformation(this, TransformationOptions.Disabled); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); + } // static methods for convenience @@ -37,7 +41,7 @@ public static ImmutableHashSet> Apply(IEnumerable> Apply(params QsNamespace[] n // helper classes - private class NamespaceTransformation : - NamespaceTransformation + private class NamespaceTransformation + : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } - public override QsSpecialization onSpecializationImplementation(QsSpecialization spec) // short cut to avoid further evaluation + public override QsSpecialization OnSpecializationDeclaration(QsSpecialization spec) // short cut to avoid further evaluation { - this.onSourceFile(spec.SourceFile); + this.OnSourceFile(spec.SourceFile); return spec; } - public override NonNullable onSourceFile(NonNullable f) + public override NonNullable OnSourceFile(NonNullable f) { this.SharedState.SourceFiles.Add(f); - return base.onSourceFile(f); + return base.OnSourceFile(f); } } } @@ -80,8 +83,8 @@ public override NonNullable onSourceFile(NonNullable f) /// The transformation also ensures that the elements in each namespace are ordered according to /// the location at which they are defined in the file. Auto-generated declarations will be ordered alphabetically. /// - public class FilterBySourceFile : - SyntaxTreeTransformation + public class FilterBySourceFile + : SyntaxTreeTransformation { public class TransformationState { @@ -94,10 +97,14 @@ public TransformationState(Func, bool> predicate) => } - public FilterBySourceFile(Func, bool> predicate) - : base(new TransformationState(predicate)) => + public FilterBySourceFile(Func, bool> predicate) + : base(new TransformationState(predicate)) + { this.Namespaces = new NamespaceTransformation(this); - + this.Statements = new StatementTransformation(this, TransformationOptions.Disabled); + this.Expressions = new ExpressionTransformation(this, TransformationOptions.Disabled); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); + } // static methods for convenience @@ -105,7 +112,7 @@ public static QsNamespace Apply(QsNamespace ns, Func, bool> { if (ns == null) throw new ArgumentNullException(nameof(ns)); var filter = new FilterBySourceFile(predicate); - return filter.Namespaces.Transform(ns); + return filter.Namespaces.OnNamespace(ns); } public static QsNamespace Apply(QsNamespace ns, params NonNullable[] fileIds) @@ -117,30 +124,29 @@ public static QsNamespace Apply(QsNamespace ns, params NonNullable[] fil // helper classes - public class NamespaceTransformation : - NamespaceTransformation + public class NamespaceTransformation + : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } // TODO: these overrides needs to be adapted once we support external specializations - public override QsCustomType onType(QsCustomType t) + public override QsCustomType OnTypeDeclaration(QsCustomType t) { if (this.SharedState.Predicate(t.SourceFile)) { this.SharedState.Elements.Add((t.Location.IsValue ? t.Location.Item.Offset.Item1 : (int?)null, QsNamespaceElement.NewQsCustomType(t))); } return t; } - public override QsCallable onCallableImplementation(QsCallable c) + public override QsCallable OnCallableDeclaration(QsCallable c) { if (this.SharedState.Predicate(c.SourceFile)) { this.SharedState.Elements.Add((c.Location.IsValue ? c.Location.Item.Offset.Item1 : (int?)null, QsNamespaceElement.NewQsCallable(c))); } return c; } - public override QsNamespace Transform(QsNamespace ns) + public override QsNamespace OnNamespace(QsNamespace ns) { static int SortComparison((int?, QsNamespaceElement) x, (int?, QsNamespaceElement) y) { @@ -149,7 +155,7 @@ static int SortComparison((int?, QsNamespaceElement) x, (int?, QsNamespaceElemen return x.Item1.HasValue ? -1 : 1; } this.SharedState.Elements.Clear(); - base.Transform(ns); + base.OnNamespace(ns); this.SharedState.Elements.Sort(SortComparison); return new QsNamespace(ns.Name, this.SharedState.Elements.Select(e => e.Item2).ToImmutableArray(), ns.Documentation); } @@ -163,10 +169,11 @@ static int SortComparison((int?, QsNamespaceElement) x, (int?, QsNamespaceElemen /// over all contained expressions evaluates to true. /// If evaluateOnSubexpressions is set to true, the fold is evaluated on all subexpressions as well. /// - public class SelectByFoldingOverExpressions : - SyntaxTreeTransformation + public class SelectByFoldingOverExpressions + : SyntaxTreeTransformation { - public class TransformationState : FoldOverExpressions.IFoldingState + public class TransformationState + : FoldOverExpressions.IFoldingState { public bool Recur { get; } public readonly bool Seed; @@ -192,8 +199,9 @@ public TransformationState(Func condition, Func condition, Func fold, bool seed, bool evaluateOnSubexpressions = true) - : base(new TransformationState(condition, fold, seed, evaluateOnSubexpressions)) - { + : base(new TransformationState(condition, fold, seed, evaluateOnSubexpressions)) + { + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); this.Expressions = new FoldOverExpressions(this); this.Statements = new StatementTransformation( state => new SelectByFoldingOverExpressions(state.Condition, state.ConstructFold, state.Seed, state.Recur), @@ -203,9 +211,8 @@ public SelectByFoldingOverExpressions(Func condition, Fun // helper classes - public class StatementTransformation

: - Core.StatementTransformation - where P : SelectByFoldingOverExpressions + public class StatementTransformation

+ : Core.StatementTransformation where P : SelectByFoldingOverExpressions { protected P SubSelector; protected readonly Func CreateSelector; @@ -215,28 +222,28 @@ public class StatementTransformation

: /// Upon initialization, the FoldResult of the internal state should be set to the specified seed rather than the FoldResult of the given constructor argument. /// public StatementTransformation(Func createSelector, SyntaxTreeTransformation parent) - : base(parent) => + : base(parent) => this.CreateSelector = createSelector ?? throw new ArgumentNullException(nameof(createSelector)); - public override QsStatement onStatement(QsStatement stm) + public override QsStatement OnStatement(QsStatement stm) { this.SubSelector = this.CreateSelector(this.SharedState); - var loc = this.SubSelector.Statements.onLocation(stm.Location); - var stmKind = this.SubSelector.StatementKinds.Transform(stm.Statement); - var varDecl = this.SubSelector.Statements.onLocalDeclarations(stm.SymbolDeclarations); + var loc = this.SubSelector.Statements.OnLocation(stm.Location); + var stmKind = this.SubSelector.StatementKinds.OnStatementKind(stm.Statement); + var varDecl = this.SubSelector.Statements.OnLocalDeclarations(stm.SymbolDeclarations); this.SharedState.FoldResult = this.SharedState.ConstructFold( this.SharedState.FoldResult, this.SubSelector.SharedState.FoldResult); return new QsStatement(stmKind, varDecl, loc, stm.Comments); } - public override QsScope Transform(QsScope scope) + public override QsScope OnScope(QsScope scope) { var statements = new List(); foreach (var statement in scope.Statements) { // StatementKind.Transform sets a new Subselector that walks all expressions contained in statement, // and sets its satisfiesCondition to true if one of them satisfies the condition given on initialization - var transformed = this.onStatement(statement); + var transformed = this.OnStatement(statement); if (this.SubSelector.SharedState.SatisfiesCondition) statements.Add(transformed); } return new QsScope(statements.ToImmutableArray(), scope.KnownSymbols); @@ -251,12 +258,11 @@ public override QsScope Transform(QsScope scope) /// which contain an expression or subexpression (only if evaluateOnSubexpressions is set to true) /// that satisfies the condition given on initialization. /// - public class SelectByAnyContainedExpression : - SelectByFoldingOverExpressions + public class SelectByAnyContainedExpression + : SelectByFoldingOverExpressions { public SelectByAnyContainedExpression(Func condition, bool evaluateOnSubexpressions = true) - : base(condition, (a, b) => a || b, false, evaluateOnSubexpressions) - { } + : base(condition, (a, b) => a || b, false, evaluateOnSubexpressions) { } } ///

@@ -265,12 +271,11 @@ public SelectByAnyContainedExpression(Func condition, boo /// for which all contained expressions or subexpressions satisfy the condition given on initialization. /// Note that subexpressions will only be verified if evaluateOnSubexpressions is set to true (default value). /// - public class SelectByAllContainedExpressions : - SelectByFoldingOverExpressions + public class SelectByAllContainedExpressions + : SelectByFoldingOverExpressions { public SelectByAllContainedExpressions(Func condition, bool evaluateOnSubexpressions = true) - : base(condition, (a, b) => a && b, true, evaluateOnSubexpressions) - { } + : base(condition, (a, b) => a && b, true, evaluateOnSubexpressions) { } } @@ -281,10 +286,10 @@ public SelectByAllContainedExpressions(Func condition, bo /// i.e. the fold it take starting on inner expressions (from the inside out). /// Otherwise the specified folder is only applied to the expression itself. /// The result of the fold is accessible via the FoldResult property in the internal state of the transformation. + /// The transformation itself merely walks expressions and rebuilding is disabled. /// - public class FoldOverExpressions : - Core.ExpressionTransformation - where T : FoldOverExpressions.IFoldingState + public class FoldOverExpressions + : ExpressionTransformation where T : FoldOverExpressions.IFoldingState { public interface IFoldingState { @@ -294,18 +299,16 @@ public interface IFoldingState } - public FoldOverExpressions(SyntaxTreeTransformation parent) - : base(parent) - { } + public FoldOverExpressions(SyntaxTreeTransformation parent) + : base(parent, TransformationOptions.NoRebuild) { } - public FoldOverExpressions(T state) - : base(state) - { } + public FoldOverExpressions(T state) + : base(state) { } - public override TypedExpression Transform(TypedExpression ex) + public override TypedExpression OnTypedExpression(TypedExpression ex) { - ex = this.SharedState.Recur ? base.Transform(ex) : ex; + ex = this.SharedState.Recur ? base.OnTypedExpression(ex) : ex; this.SharedState.FoldResult = this.SharedState.Fold(ex, this.SharedState.FoldResult); return ex; } diff --git a/src/QsCompiler/Transformations/ClassicallyControlledTransformation.cs b/src/QsCompiler/Transformations/ClassicallyControlled.cs similarity index 86% rename from src/QsCompiler/Transformations/ClassicallyControlledTransformation.cs rename to src/QsCompiler/Transformations/ClassicallyControlled.cs index ae414f2140..600c8fde3e 100644 --- a/src/QsCompiler/Transformations/ClassicallyControlledTransformation.cs +++ b/src/QsCompiler/Transformations/ClassicallyControlled.cs @@ -9,21 +9,24 @@ using Microsoft.Quantum.QsCompiler.SyntaxTokens; using Microsoft.Quantum.QsCompiler.SyntaxTree; using Microsoft.Quantum.QsCompiler.Transformations.Core; +using Microsoft.Quantum.QsCompiler.Transformations.SearchAndReplace; -namespace Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlledTransformation +namespace Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlled { using ExpressionKind = QsExpressionKind; using ResolvedTypeKind = QsTypeKind; using TypeArgsResolution = ImmutableArray, ResolvedType>>; - // This transformation works in two passes. - // 1st Pass: Hoist the contents of conditional statements into separate operations, where possible. - // 2nd Pass: On the way down the tree, reshape conditional statements to replace Elif's and - // top level OR and AND conditions with equivalent nested if-else statements. One the way back up - // the tree, convert conditional statements into ApplyIf calls, where possible. - // This relies on anything having type parameters must be a global callable. - public static class ClassicallyControlledTransformation + /// + /// This transformation works in two passes. + /// 1st Pass: Hoist the contents of conditional statements into separate operations, where possible. + /// 2nd Pass: On the way down the tree, reshape conditional statements to replace Elif's and + /// top level OR and AND conditions with equivalent nested if-else statements. One the way back up + /// the tree, convert conditional statements into ApplyIf calls, where possible. + /// This relies on anything having type parameters must be a global callable. + /// + public static class ReplaceClassicalControl { public static QsCompilation Apply(QsCompilation compilation) { @@ -38,7 +41,7 @@ public static QsCompilation Apply(QsCompilation compilation) { var filter = new ConvertConditions(compilation); - return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.Transform(ns)).ToImmutableArray(), compilation.EntryPoints); + return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.OnNamespace(ns)).ToImmutableArray(), compilation.EntryPoints); } public class TransformationState @@ -55,13 +58,15 @@ private ConvertConditions(QsCompilation compilation) : base(new TransformationSt { this.Namespaces = new NamespaceTransformation(this); this.Statements = new StatementTransformation(this); + this.Expressions = new ExpressionTransformation(this, TransformationOptions.Disabled); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } private class NamespaceTransformation : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsCallable onFunction(QsCallable c) => c; // Prevent anything in functions from being considered + public override QsCallable OnFunction(QsCallable c) => c; // Prevent anything in functions from being considered } private class StatementTransformation : StatementTransformation @@ -84,7 +89,7 @@ public StatementTransformation(SyntaxTreeTransformation par var callTypeArguments = expr.Item.TypeArguments; var idTypeArguments = call.Item1.TypeArguments; - var combinedTypeArguments = Utilities.GetCombinedType(callTypeArguments, idTypeArguments); + var combinedTypeArguments = Utils.GetCombinedTypeResolution(callTypeArguments, idTypeArguments); // This relies on anything having type parameters must be a global callable. var newCallIdentifier = call.Item1; @@ -165,10 +170,10 @@ private TypedExpression CreateApplyIfExpression(QsResult result, TypedExpression } var (zeroOpArg, oneOpArg) = (result == QsResult.Zero) - ? (Utilities.CreateValueTupleExpression(condId, condArgs), Utilities.CreateValueTupleExpression(defaultId, defaultArgs)) - : (Utilities.CreateValueTupleExpression(defaultId, defaultArgs), Utilities.CreateValueTupleExpression(condId, condArgs)); + ? (Utils.CreateValueTupleExpression(condId, condArgs), Utils.CreateValueTupleExpression(defaultId, defaultArgs)) + : (Utils.CreateValueTupleExpression(defaultId, defaultArgs), Utils.CreateValueTupleExpression(condId, condArgs)); - controlArgs = Utilities.CreateValueTupleExpression(conditionExpression, zeroOpArg, oneOpArg); + controlArgs = Utils.CreateValueTupleExpression(conditionExpression, zeroOpArg, oneOpArg); targetArgs = ImmutableArray.Create(condArgs.ResolvedType, defaultArgs.ResolvedType); } @@ -199,9 +204,9 @@ private TypedExpression CreateApplyIfExpression(QsResult result, TypedExpression : BuiltIn.ApplyIfOne; } - controlArgs = Utilities.CreateValueTupleExpression( + controlArgs = Utils.CreateValueTupleExpression( conditionExpression, - Utilities.CreateValueTupleExpression(condId, condArgs)); + Utils.CreateValueTupleExpression(condId, condArgs)); targetArgs = ImmutableArray.Create(condArgs.ResolvedType); } @@ -217,12 +222,12 @@ private TypedExpression CreateApplyIfExpression(QsResult result, TypedExpression } // Build the surrounding apply-if call - var controlOpId = Utilities.CreateIdentifierExpression( + var controlOpId = Utils.CreateIdentifierExpression( Identifier.NewGlobalCallable(new QsQualifiedName(controlOpInfo.Namespace, controlOpInfo.Name)), targetArgs .Zip(controlOpInfo.TypeParameters, (type, param) => Tuple.Create(new QsQualifiedName(controlOpInfo.Namespace, controlOpInfo.Name), param, type)) .ToImmutableArray(), - Utilities.GetOperatorResolvedType(props, controlArgs.ResolvedType)); + Utils.GetOperationType(props, controlArgs.ResolvedType)); // Creates identity resolutions for the call expression var opTypeArgResolutions = targetArgs @@ -240,7 +245,7 @@ x.Resolution is ResolvedTypeKind.TupleType tup }) .ToImmutableArray(); - return Utilities.CreateCallLike(controlOpId, controlArgs, opTypeArgResolutions); + return Utils.CreateCallLikeExpression(controlOpId, controlArgs, opTypeArgResolutions); } private QsStatement CreateApplyIfStatement(QsStatement statement, QsResult result, TypedExpression conditionExpression, QsScope conditionScope, QsScope defaultScope) @@ -377,7 +382,7 @@ private QsStatement ReshapeConditional(QsStatement statement) #region Condition Checking Logic - private (bool, TypedExpression, QsScope, QsScope) IsConditionWtihSingleBlock(QsStatement statement) + private (bool, TypedExpression, QsScope, QsScope) IsConditionWithSingleBlock(QsStatement statement) { if (statement.Statement is QsStatementKind.QsConditionalStatement cond && cond.Item.ConditionalBlocks.Length == 1) { @@ -406,9 +411,9 @@ private QsStatement ReshapeConditional(QsStatement statement) #endregion - public override QsScope Transform(QsScope scope) + public override QsScope OnScope(QsScope scope) { - var parentSymbols = this.onLocalDeclarations(scope.KnownSymbols); + var parentSymbols = this.OnLocalDeclarations(scope.KnownSymbols); var statements = new List(); foreach (var statement in scope.Statements) @@ -416,9 +421,9 @@ public override QsScope Transform(QsScope scope) if (statement.Statement is QsStatementKind.QsConditionalStatement) { var stm = ReshapeConditional(statement); - stm = this.onStatement(stm); + stm = this.OnStatement(stm); - var (isCondition, cond, conditionScope, defaultScope) = IsConditionWtihSingleBlock(stm); + var (isCondition, cond, conditionScope, defaultScope) = IsConditionWithSingleBlock(stm); if (isCondition) { @@ -437,7 +442,7 @@ public override QsScope Transform(QsScope scope) } else { - statements.Add(this.onStatement(statement)); + statements.Add(this.OnStatement(statement)); } } @@ -447,18 +452,21 @@ public override QsScope Transform(QsScope scope) } } - // Transformation handling the first pass task of hoisting of the contents of conditional statements. - // If blocks are first validated to see if they can safely be hoisted into their own operation. - // Validation requirements are that there are no return statements and that there are no set statements - // on mutables declared outside the block. Setting mutables declared inside the block is valid. - // If the block is valid, and there is more than one statement in the block, a new operation with the - // block's contents is generated, having all the same type parameters as the calling context - // and all known variables at the start of the block become parameters to the new operation. - // The contents of the conditional block are then replaced with a call to the new operation with all - // the type parameters and known variables being forwarded to the new operation as arguments. - public static class HoistTransformation + + /// + /// Transformation handling the first pass task of hoisting of the contents of conditional statements. + /// If blocks are first validated to see if they can safely be hoisted into their own operation. + /// Validation requirements are that there are no return statements and that there are no set statements + /// on mutables declared outside the block. Setting mutables declared inside the block is valid. + /// If the block is valid, and there is more than one statement in the block, a new operation with the + /// block's contents is generated, having all the same type parameters as the calling context + /// and all known variables at the start of the block become parameters to the new operation. + /// The contents of the conditional block are then replaced with a call to the new operation with all + /// the type parameters and known variables being forwarded to the new operation as arguments. + /// + internal static class HoistTransformation // this class can be made public once its functionality is no longer tied to the classically-controlled transformation { - public static QsCompilation Apply(QsCompilation compilation) => HoistContents.Apply(compilation); + internal static QsCompilation Apply(QsCompilation compilation) => HoistContents.Apply(compilation); private class HoistContents : SyntaxTreeTransformation { @@ -466,7 +474,7 @@ public static QsCompilation Apply(QsCompilation compilation) { var filter = new HoistContents(); - return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.Transform(ns)).ToImmutableArray(), compilation.EntryPoints); + return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.OnNamespace(ns)).ToImmutableArray(), compilation.EntryPoints); } public class CallableDetails @@ -603,7 +611,7 @@ QsSpecialization MakeSpec(QsSpecializationKind kind, ResolvedSignature signature public (QsCallable, ResolvedType) GenerateOperation(QsScope contents) { - var newName = Utilities.AddGuid(CurrentCallable.Callable.FullName); + var newName = UniqueVariableNames.PrependGuid(CurrentCallable.Callable.FullName); var knownVariables = contents.KnownSymbols.IsEmpty ? ImmutableArray>>.Empty @@ -656,54 +664,55 @@ private HoistContents() : base(new TransformationState()) this.StatementKinds = new StatementKindTransformation(this); this.Expressions = new ExpressionTransformation(this); this.ExpressionKinds = new ExpressionKindTransformation(this); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } private class NamespaceTransformation : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsCallable onCallableImplementation(QsCallable c) + public override QsCallable OnCallableDeclaration(QsCallable c) { SharedState.CurrentCallable = new CallableDetails(c); - return base.onCallableImplementation(c); + return base.OnCallableDeclaration(c); } - public override QsSpecialization onBodySpecialization(QsSpecialization spec) + public override QsSpecialization OnBodySpecialization(QsSpecialization spec) { SharedState.InBody = true; - var rtrn = base.onBodySpecialization(spec); + var rtrn = base.OnBodySpecialization(spec); SharedState.InBody = false; return rtrn; } - public override QsSpecialization onAdjointSpecialization(QsSpecialization spec) + public override QsSpecialization OnAdjointSpecialization(QsSpecialization spec) { SharedState.InAdjoint = true; - var rtrn = base.onAdjointSpecialization(spec); + var rtrn = base.OnAdjointSpecialization(spec); SharedState.InAdjoint = false; return rtrn; } - public override QsSpecialization onControlledSpecialization(QsSpecialization spec) + public override QsSpecialization OnControlledSpecialization(QsSpecialization spec) { SharedState.InControlled = true; - var rtrn = base.onControlledSpecialization(spec); + var rtrn = base.OnControlledSpecialization(spec); SharedState.InControlled = false; return rtrn; } - public override QsCallable onFunction(QsCallable c) => c; // Prevent anything in functions from being hoisted + public override QsCallable OnFunction(QsCallable c) => c; // Prevent anything in functions from being hoisted - public override QsNamespace Transform(QsNamespace ns) + public override QsNamespace OnNamespace(QsNamespace ns) { // Control operations list will be populated in the transform SharedState.ControlOperations = new List(); - return base.Transform(ns) + return base.OnNamespace(ns) .WithElements(elems => elems.AddRange(SharedState.ControlOperations.Select(op => QsNamespaceElement.NewQsCallable(op)))); } } - private class StatementKindTransformation : Core.StatementKindTransformation + private class StatementKindTransformation : StatementKindTransformation { public StatementKindTransformation(SyntaxTreeTransformation parent) : base(parent) { } @@ -735,7 +744,7 @@ public StatementKindTransformation(SyntaxTreeTransformation TypedExpression targetArgs = null; if (knownSymbols.Any()) { - targetArgs = Utilities.CreateValueTupleExpression(knownSymbols.Select(var => Utilities.CreateIdentifierExpression( + targetArgs = Utils.CreateValueTupleExpression(knownSymbols.Select(var => Utils.CreateIdentifierExpression( Identifier.NewLocalVariable(var.VariableName), TypeArgsResolution.Empty, var.Type)) @@ -784,39 +793,39 @@ private bool IsScopeSingleCall(QsScope contents) && call.Item1.Expression is ExpressionKind.Identifier; } - public override QsStatementKind onConjugation(QsConjugation stm) + public override QsStatementKind OnConjugation(QsConjugation stm) { var superInWithinBlock = SharedState.InWithinBlock; SharedState.InWithinBlock = true; - var (_, outer) = this.onPositionedBlock(QsNullable.Null, stm.OuterTransformation); + var (_, outer) = this.OnPositionedBlock(QsNullable.Null, stm.OuterTransformation); SharedState.InWithinBlock = superInWithinBlock; - var (_, inner) = this.onPositionedBlock(QsNullable.Null, stm.InnerTransformation); + var (_, inner) = this.OnPositionedBlock(QsNullable.Null, stm.InnerTransformation); return QsStatementKind.NewQsConjugation(new QsConjugation(outer, inner)); } - public override QsStatementKind onReturnStatement(TypedExpression ex) + public override QsStatementKind OnReturnStatement(TypedExpression ex) { SharedState.IsValidScope = false; - return base.onReturnStatement(ex); + return base.OnReturnStatement(ex); } - public override QsStatementKind onValueUpdate(QsValueUpdate stm) + public override QsStatementKind OnValueUpdate(QsValueUpdate stm) { // If lhs contains an identifier found in the scope's known variables (variables from the super-scope), the scope is not valid - var lhs = this.Expressions.Transform(stm.Lhs); + var lhs = this.Expressions.OnTypedExpression(stm.Lhs); if (SharedState.ContainsHoistParamRef) { SharedState.IsValidScope = false; } - var rhs = this.Expressions.Transform(stm.Rhs); + var rhs = this.Expressions.OnTypedExpression(stm.Rhs); return QsStatementKind.NewQsValueUpdate(new QsValueUpdate(lhs, rhs)); } - public override QsStatementKind onConditionalStatement(QsConditionalStatement stm) + public override QsStatementKind OnConditionalStatement(QsConditionalStatement stm) { var contextValidScope = SharedState.IsValidScope; var contextHoistParams = SharedState.CurrentHoistParams; @@ -832,7 +841,7 @@ public override QsStatementKind onConditionalStatement(QsConditionalStatement st ? ImmutableArray>>.Empty : condBlock.Item2.Body.KnownSymbols.Variables; - var (expr, block) = this.onPositionedBlock(QsNullable.NewValue(condBlock.Item1), condBlock.Item2); + var (expr, block) = this.OnPositionedBlock(QsNullable.NewValue(condBlock.Item1), condBlock.Item2); // ToDo: Reduce the number of unnecessary generated operations by generalizing // the condition logic for the conversion and using that condition here @@ -864,7 +873,7 @@ public override QsStatementKind onConditionalStatement(QsConditionalStatement st ? ImmutableArray>>.Empty : stm.Default.Item.Body.KnownSymbols.Variables; - var (_, block) = this.onPositionedBlock(QsNullable.Null, stm.Default.Item); + var (_, block) = this.OnPositionedBlock(QsNullable.Null, stm.Default.Item); if (block.Body.Statements.Length > 0 && SharedState.IsValidScope && !IsScopeSingleCall(block.Body)) // if sub-scope is valid, hoist content { // Hoist the scope to its own operation @@ -897,22 +906,22 @@ public override QsStatementKind onConditionalStatement(QsConditionalStatement st new QsConditionalStatement(stm.ConditionalBlocks, stm.Default)); } - public override QsStatementKind Transform(QsStatementKind kind) + public override QsStatementKind OnStatementKind(QsStatementKind kind) { SharedState.ContainsHoistParamRef = false; // Every statement kind starts off false - return base.Transform(kind); + return base.OnStatementKind(kind); } } - private class ExpressionTransformation : Core.ExpressionTransformation + private class ExpressionTransformation : ExpressionTransformation { public ExpressionTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override TypedExpression Transform(TypedExpression ex) + public override TypedExpression OnTypedExpression(TypedExpression ex) { var contextContainsHoistParamRef = SharedState.ContainsHoistParamRef; SharedState.ContainsHoistParamRef = false; - var rtrn = base.Transform(ex); + var rtrn = base.OnTypedExpression(ex); // If the sub context contains a reference, then the super context contains a reference, // otherwise return the super context to its original value @@ -925,32 +934,34 @@ public override TypedExpression Transform(TypedExpression ex) } } - private class ExpressionKindTransformation : Core.ExpressionKindTransformation + private class ExpressionKindTransformation : ExpressionKindTransformation { public ExpressionKindTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override ExpressionKind onIdentifier(Identifier sym, QsNullable> tArgs) + public override ExpressionKind OnIdentifier(Identifier sym, QsNullable> tArgs) { if (sym is Identifier.LocalVariable local && SharedState.CurrentHoistParams.Any(param => param.VariableName.Equals(local.Item))) { SharedState.ContainsHoistParamRef = true; } - return base.onIdentifier(sym, tArgs); + return base.OnIdentifier(sym, tArgs); } } } - // Transformation that updates the contents of newly generated operations by: - // 1. Rerouting the origins of type parameter references to the new operation - // 2. Changes the IsMutable info on variable that used to be mutable, but are now immutable params to the operation + /// + /// Transformation that updates the contents of newly generated operations by: + /// 1. Rerouting the origins of type parameter references to the new operation + /// 2. Changes the IsMutable info on variable that used to be mutable, but are now immutable params to the operation + /// private class UpdateGeneratedOp : SyntaxTreeTransformation { public static QsCallable Apply(QsCallable qsCallable, ImmutableArray>> parameters, QsQualifiedName oldName, QsQualifiedName newName) { var filter = new UpdateGeneratedOp(parameters, oldName, newName); - return filter.Namespaces.onCallableImplementation(qsCallable); + return filter.Namespaces.OnCallableDeclaration(qsCallable); } public class TransformationState @@ -976,17 +987,17 @@ private UpdateGeneratedOp(ImmutableArray + private class ExpressionTransformation : ExpressionTransformation { public ExpressionTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override ImmutableDictionary>, ResolvedType> onTypeParamResolutions(ImmutableDictionary>, ResolvedType> typeParams) + public override ImmutableDictionary>, ResolvedType> OnTypeParamResolutions(ImmutableDictionary>, ResolvedType> typeParams) { // Prevent keys from having their names updated - return typeParams.ToImmutableDictionary(kvp => kvp.Key, kvp => this.Types.Transform(kvp.Value)); + return typeParams.ToImmutableDictionary(kvp => kvp.Key, kvp => this.Types.OnType(kvp.Value)); } - public override TypedExpression Transform(TypedExpression ex) + public override TypedExpression OnTypedExpression(TypedExpression ex) { // Checks if expression is mutable identifier that is in parameter list if (ex.InferredInformation.IsMutable && @@ -1005,19 +1016,19 @@ id.Item1 is Identifier.LocalVariable variable && // Prevent IsRecursiveIdentifier from propagating beyond the typed expression it is referring to var isRecursiveIdentifier = SharedState.IsRecursiveIdentifier; - var rtrn = base.Transform(ex); + var rtrn = base.OnTypedExpression(ex); SharedState.IsRecursiveIdentifier = isRecursiveIdentifier; return rtrn; } } - private class ExpressionKindTransformation : Core.ExpressionKindTransformation + private class ExpressionKindTransformation : ExpressionKindTransformation { public ExpressionKindTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override ExpressionKind onIdentifier(Identifier sym, QsNullable> tArgs) + public override ExpressionKind OnIdentifier(Identifier sym, QsNullable> tArgs) { - var rtrn = base.onIdentifier(sym, tArgs); + var rtrn = base.OnIdentifier(sym, tArgs); // Then check if this is a recursive identifier // In this context, that is a call back to the original callable from the newly generated operation @@ -1036,7 +1047,7 @@ private class TypeTransformation : TypeTransformation { public TypeTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override ResolvedTypeKind onTypeParameter(QsTypeParameter tp) + public override ResolvedTypeKind OnTypeParameter(QsTypeParameter tp) { // Reroute a type parameter's origin to the newly generated operation if (!SharedState.IsRecursiveIdentifier && SharedState.OldName.Equals(tp.Origin)) @@ -1044,7 +1055,7 @@ public override ResolvedTypeKind onTypeParameter(QsTypeParameter tp) tp = new QsTypeParameter(SharedState.NewName, tp.TypeName, tp.Range); } - return base.onTypeParameter(tp); + return base.OnTypeParameter(tp); } } } diff --git a/src/QsCompiler/Transformations/Utilities.cs b/src/QsCompiler/Transformations/ClassicallyControlledUtils.cs similarity index 74% rename from src/QsCompiler/Transformations/Utilities.cs rename to src/QsCompiler/Transformations/ClassicallyControlledUtils.cs index 438eaf2203..bc030db7a7 100644 --- a/src/QsCompiler/Transformations/Utilities.cs +++ b/src/QsCompiler/Transformations/ClassicallyControlledUtils.cs @@ -10,15 +10,19 @@ using Microsoft.Quantum.QsCompiler.SyntaxTree; -namespace Microsoft.Quantum.QsCompiler.Transformations +namespace Microsoft.Quantum.QsCompiler.Transformations.ClassicallyControlled { using ExpressionKind = QsExpressionKind; using ResolvedTypeKind = QsTypeKind; using TypeArgsResolution = ImmutableArray, ResolvedType>>; - public static class Utilities + /// + /// These tools are specific to the classically-controlled transformation and are not intended for wider use in their current state. + /// They rely on the specific context in which they are invoked during that transformation and are not general purpuse tools. + /// + internal static class Utils { - public static TypedExpression CreateIdentifierExpression(Identifier id, + internal static TypedExpression CreateIdentifierExpression(Identifier id, TypeArgsResolution typeArgsMapping, ResolvedType resolvedType) => new TypedExpression ( @@ -35,7 +39,7 @@ public static TypedExpression CreateIdentifierExpression(Identifier id, QsNullable>.Null ); - public static TypedExpression CreateValueTupleExpression(params TypedExpression[] expressions) => + internal static TypedExpression CreateValueTupleExpression(params TypedExpression[] expressions) => new TypedExpression ( ExpressionKind.NewValueTuple(expressions.ToImmutableArray()), @@ -45,7 +49,7 @@ public static TypedExpression CreateValueTupleExpression(params TypedExpression[ QsNullable>.Null ); - public static TypedExpression CreateCallLike(TypedExpression id, TypedExpression args, TypeArgsResolution typeRes) => + internal static TypedExpression CreateCallLikeExpression(TypedExpression id, TypedExpression args, TypeArgsResolution typeRes) => new TypedExpression ( ExpressionKind.NewCallLikeExpression(id, args), @@ -55,7 +59,7 @@ public static TypedExpression CreateCallLike(TypedExpression id, TypedExpression QsNullable>.Null ); - public static ResolvedType GetOperatorResolvedType(IEnumerable props, ResolvedType argumentType) + internal static ResolvedType GetOperationType(IEnumerable props, ResolvedType argumentType) { var characteristics = new CallableInformation( ResolvedCharacteristics.FromProperties(props), @@ -66,7 +70,7 @@ public static ResolvedType GetOperatorResolvedType(IEnumerable props characteristics)); } - public static TypeArgsResolution GetCombinedType(TypeArgsResolution outer, TypeArgsResolution inner) + internal static TypeArgsResolution GetCombinedTypeResolution(TypeArgsResolution outer, TypeArgsResolution inner) { var outerDict = outer.ToDictionary(x => (x.Item1, x.Item2), x => x.Item3); return inner.Select(innerRes => @@ -81,10 +85,8 @@ public static TypeArgsResolution GetCombinedType(TypeArgsResolution outer, TypeA { return innerRes; } - }).Concat(outerDict.Select(x => Tuple.Create(x.Key.Item1, x.Key.Item2, x.Value))).ToImmutableArray(); + }) + .Concat(outerDict.Select(x => Tuple.Create(x.Key.Item1, x.Key.Item2, x.Value))).ToImmutableArray(); } - - public static QsQualifiedName AddGuid(QsQualifiedName original) => - new QsQualifiedName(original.Namespace, NonNullable.New("_" + Guid.NewGuid().ToString("N") + "_" + original.Name.Value)); } } diff --git a/src/QsCompiler/Transformations/CodeTransformations.cs b/src/QsCompiler/Transformations/CodeTransformations.cs index 0f8494656c..f4f5ccd0af 100644 --- a/src/QsCompiler/Transformations/CodeTransformations.cs +++ b/src/QsCompiler/Transformations/CodeTransformations.cs @@ -28,9 +28,9 @@ public static QsScope GenerateAdjoint(this QsScope scope) { // Since we are pulling purely classical statements up, we are potentially changing the order of declarations. // We therefore need to generate unique variable names before reordering the statements. - scope = new UniqueVariableNames().Statements.Transform(scope); + scope = new UniqueVariableNames().Statements.OnScope(scope); scope = ApplyFunctorToOperationCalls.ApplyAdjoint(scope); - scope = new ReverseOrderOfOperationCalls().Statements.Transform(scope); + scope = new ReverseOrderOfOperationCalls().Statements.OnScope(scope); return StripPositionInfo.Apply(scope); } @@ -58,7 +58,7 @@ public static bool InlineConjugations(this QsCompilation compilation, out QsComp { if (compilation == null) throw new ArgumentNullException(nameof(compilation)); var inline = new InlineConjugations(onException); - var namespaces = compilation.Namespaces.Select(inline.Namespaces.Transform).ToImmutableArray(); + var namespaces = compilation.Namespaces.Select(inline.Namespaces.OnNamespace).ToImmutableArray(); inlined = new QsCompilation(namespaces, compilation.EntryPoints); return inline.SharedState.Success; } diff --git a/src/QsCompiler/Transformations/Conjugations.cs b/src/QsCompiler/Transformations/Conjugations.cs index 27b90a0811..0b00da1ea6 100644 --- a/src/QsCompiler/Transformations/Conjugations.cs +++ b/src/QsCompiler/Transformations/Conjugations.cs @@ -20,7 +20,7 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.Conjugations /// throws an InvalidOperationException if the outer block contains while-loops. /// public class InlineConjugations - : SyntaxTreeTransformation + : SyntaxTreeTransformation { public class TransformationState { @@ -28,10 +28,10 @@ public class TransformationState internal readonly Action OnException; internal Func ResolveNames = - new UniqueVariableNames().Statements.Transform; + new UniqueVariableNames().Statements.OnScope; public void Reset() => - this.ResolveNames = new UniqueVariableNames().Statements.Transform; + this.ResolveNames = new UniqueVariableNames().Statements.OnScope; public TransformationState(Action onException = null) { @@ -42,24 +42,25 @@ public TransformationState(Action onException = null) public InlineConjugations(Action onException = null) - : base(new TransformationState(onException)) + : base(new TransformationState(onException)) { - this.Statements = new StatementTransformation(this); this.Namespaces = new NamespaceTransformation(this); + this.Statements = new StatementTransformation(this); + this.Expressions = new ExpressionTransformation(this, TransformationOptions.Disabled); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } // helper classes - private class StatementTransformation : - StatementTransformation + private class StatementTransformation + : StatementTransformation { public StatementTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } - public override QsScope Transform(QsScope scope) + public override QsScope OnScope(QsScope scope) { var statements = ImmutableArray.CreateBuilder(); foreach (var statement in scope.Statements) @@ -68,34 +69,33 @@ public override QsScope Transform(QsScope scope) { // since we are eliminating scopes, // we need to make sure that the variables defined within the inlined scopes do not clash with other defined variables. - var outer = this.SharedState.ResolveNames(this.Transform(conj.Item.OuterTransformation.Body)); - var inner = this.SharedState.ResolveNames(this.Transform(conj.Item.InnerTransformation.Body)); + var outer = this.SharedState.ResolveNames(this.OnScope(conj.Item.OuterTransformation.Body)); + var inner = this.SharedState.ResolveNames(this.OnScope(conj.Item.InnerTransformation.Body)); var adjOuter = outer.GenerateAdjoint(); // will add a unique name wrapper statements.AddRange(outer.Statements); statements.AddRange(inner.Statements); statements.AddRange(adjOuter.Statements); } - else statements.Add(this.onStatement(statement)); + else statements.Add(this.OnStatement(statement)); } return new QsScope(statements.ToImmutableArray(), scope.KnownSymbols); } } - private class NamespaceTransformation : - NamespaceTransformation + private class NamespaceTransformation + : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } - public override Tuple>, QsScope> onProvidedImplementation + public override Tuple>, QsScope> OnProvidedImplementation (QsTuple> argTuple, QsScope body) { this.SharedState.Reset(); - try { body = this.Transformation.Statements.Transform(body); } + try { body = this.Transformation.Statements.OnScope(body); } catch (Exception ex) { this.SharedState.OnException?.Invoke(ex); diff --git a/src/QsCompiler/Transformations/FunctorGeneration.cs b/src/QsCompiler/Transformations/FunctorGeneration.cs index 299beafc78..f47871d31a 100644 --- a/src/QsCompiler/Transformations/FunctorGeneration.cs +++ b/src/QsCompiler/Transformations/FunctorGeneration.cs @@ -20,8 +20,8 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.FunctorGeneration /// with a call to the operation after application of the functor given on initialization. /// The default values used for auto-generation will be used for the additional functor arguments. /// - public class ApplyFunctorToOperationCalls : - SyntaxTreeTransformation + public class ApplyFunctorToOperationCalls + : SyntaxTreeTransformation { public class TransformationsState { @@ -33,10 +33,11 @@ public TransformationsState(QsFunctor functor) => public ApplyFunctorToOperationCalls(QsFunctor functor) - : base(new TransformationsState(functor)) + : base(new TransformationsState(functor)) { this.StatementKinds = new IgnoreOuterBlockInConjugations(this); this.ExpressionKinds = new ExpressionKindTransformation(this); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } @@ -46,10 +47,10 @@ public ApplyFunctorToOperationCalls(QsFunctor functor) SyntaxGenerator.ImmutableQubitArrayWithName(NonNullable.New(InternalUse.ControlQubitsName)); public static readonly Func ApplyAdjoint = - new ApplyFunctorToOperationCalls(QsFunctor.Adjoint).Statements.Transform; + new ApplyFunctorToOperationCalls(QsFunctor.Adjoint).Statements.OnScope; public static readonly Func ApplyControlled = - new ApplyFunctorToOperationCalls(QsFunctor.Controlled).Statements.Transform; + new ApplyFunctorToOperationCalls(QsFunctor.Controlled).Statements.OnScope; // helper classes @@ -58,19 +59,17 @@ public ApplyFunctorToOperationCalls(QsFunctor functor) /// Replaces each operation call with a call to the operation after application of the given functor. /// The default values used for auto-generation will be used for the additional functor arguments. /// - public class ExpressionKindTransformation : - Core.ExpressionKindTransformation + public class ExpressionKindTransformation + : ExpressionKindTransformation { public ExpressionKindTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } public ExpressionKindTransformation(QsFunctor functor) - : base(new TransformationsState(functor)) - { } + : base(new TransformationsState(functor)) { } - public override QsExpressionKind onOperationCall(TypedExpression method, TypedExpression arg) + public override QsExpressionKind OnOperationCall(TypedExpression method, TypedExpression arg) { if (this.SharedState.FunctorToApply.IsControlled) { @@ -82,7 +81,7 @@ public override QsExpressionKind onOp method = SyntaxGenerator.AdjointOperation(method); } else throw new NotImplementedException("unsupported functor"); - return base.onOperationCall(method, arg); + return base.OnOperationCall(method, arg); } } } @@ -91,22 +90,21 @@ public override QsExpressionKind onOp /// /// Ensures that the outer block of conjugations is ignored during transformation. /// - public class IgnoreOuterBlockInConjugations : - Core.StatementKindTransformation + public class IgnoreOuterBlockInConjugations + : StatementKindTransformation { - public IgnoreOuterBlockInConjugations(SyntaxTreeTransformation parent) - : base(parent) - { } + public IgnoreOuterBlockInConjugations(SyntaxTreeTransformation parent, TransformationOptions options = null) + : base(parent, options ?? TransformationOptions.Default) { } - public IgnoreOuterBlockInConjugations(T sharedInternalState) - : base(sharedInternalState) - { } + public IgnoreOuterBlockInConjugations(T sharedInternalState, TransformationOptions options = null) + : base(sharedInternalState, options ?? TransformationOptions.Default) { } - public override QsStatementKind onConjugation(QsConjugation stm) + + public override QsStatementKind OnConjugation(QsConjugation stm) { var inner = stm.InnerTransformation; - var innerLoc = this.Transformation.Statements.onLocation(inner.Location); - var transformedInner = new QsPositionedBlock(this.Transformation.Statements.Transform(inner.Body), innerLoc, inner.Comments); + var innerLoc = this.Transformation.Statements.OnLocation(inner.Location); + var transformedInner = new QsPositionedBlock(this.Transformation.Statements.OnScope(inner.Body), innerLoc, inner.Comments); return QsStatementKind.NewQsConjugation(new QsConjugation(stm.OuterTransformation, transformedInner)); } } @@ -119,12 +117,13 @@ public override QsStatementKind onConjugation(QsConjugation stm) /// Otherwise the transformation will succeed, but the generated scope is not necessarily valid. /// Throws an InvalidOperationException if the scope to transform contains while-loops. /// - internal class ReverseOrderOfOperationCalls : - SelectByAllContainedExpressions + internal class ReverseOrderOfOperationCalls + : SelectByAllContainedExpressions { - public ReverseOrderOfOperationCalls() : - base(ex => !ex.InferredInformation.HasLocalQuantumDependency, false) // no need to evaluate subexpressions - { + public ReverseOrderOfOperationCalls() + : base(ex => !ex.InferredInformation.HasLocalQuantumDependency, false) // no need to evaluate subexpressions + { + // Do *not* disable transformations; the base class takes care of that! this.StatementKinds = new ReverseLoops(this); this.Statements = new StatementTransformation(this); } @@ -133,19 +132,18 @@ public ReverseOrderOfOperationCalls() : // helper classes private class StatementTransformation - : StatementTransformation + : StatementTransformation { public StatementTransformation(ReverseOrderOfOperationCalls parent) - : base(state => new ReverseOrderOfOperationCalls(), parent) - { } + : base(state => new ReverseOrderOfOperationCalls(), parent) { } - public override QsScope Transform(QsScope scope) + public override QsScope OnScope(QsScope scope) { var topStatements = ImmutableArray.CreateBuilder(); var bottomStatements = new List(); foreach (var statement in scope.Statements) { - var transformed = this.onStatement(statement); + var transformed = this.OnStatement(statement); if (this.SubSelector.SharedState.SatisfiesCondition) topStatements.Add(statement); else bottomStatements.Add(transformed); } @@ -160,21 +158,20 @@ public override QsScope Transform(QsScope scope) /// Outer transformations of conjugations are left unchanged. /// Throws an InvalidOperationException upon while-loops. /// - private class ReverseLoops : - IgnoreOuterBlockInConjugations + private class ReverseLoops + : IgnoreOuterBlockInConjugations { - internal ReverseLoops(ReverseOrderOfOperationCalls parent) : - base(parent) - { } + internal ReverseLoops(ReverseOrderOfOperationCalls parent) + : base(parent) { } - public override QsStatementKind onForStatement(QsForStatement stm) + public override QsStatementKind OnForStatement(QsForStatement stm) { var reversedIterable = SyntaxGenerator.ReverseIterable(stm.IterationValues); stm = new QsForStatement(stm.LoopItem, reversedIterable, stm.Body); - return base.onForStatement(stm); + return base.OnForStatement(stm); } - public override QsStatementKind onWhileStatement(QsWhileStatement stm) => + public override QsStatementKind OnWhileStatement(QsWhileStatement stm) => throw new InvalidOperationException("cannot reverse while-loops"); } } diff --git a/src/QsCompiler/Transformations/IntrinsicResolutionTransformation.cs b/src/QsCompiler/Transformations/IntrinsicResolution.cs similarity index 95% rename from src/QsCompiler/Transformations/IntrinsicResolutionTransformation.cs rename to src/QsCompiler/Transformations/IntrinsicResolution.cs index 1d667cedd2..685ac83d13 100644 --- a/src/QsCompiler/Transformations/IntrinsicResolutionTransformation.cs +++ b/src/QsCompiler/Transformations/IntrinsicResolution.cs @@ -9,9 +9,9 @@ using Microsoft.Quantum.QsCompiler.SyntaxTree; -namespace Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolutionTransformation +namespace Microsoft.Quantum.QsCompiler.Transformations.IntrinsicResolution { - public class IntrinsicResolutionTransformation + public static class ReplaceWithTargetIntrinsics { /// /// Merge the environment-specific syntax tree with the target tree. The resulting tree will @@ -58,7 +58,7 @@ private static IEnumerable MergeElements(IEnumerable>, ResolvedType>; using GetConcreteIdentifierFunc = Func>, ResolvedType>, Identifier>; using ImmutableConcretion = ImmutableDictionary>, ResolvedType>; - public static class MonomorphizationTransformation + public static class Monomorphize { private struct Request { @@ -134,7 +135,7 @@ private static Identifier GetConcreteIdentifier( if (!typesHashSet.IsEmpty) { // Create new name - concreteName = Utilities.AddGuid(globalCallable.Item); + concreteName = UniqueVariableNames.PrependGuid(globalCallable.Item); } requests.Push(new Request() @@ -162,7 +163,7 @@ public static QsCompilation Apply(QsCompilation compilation, List resp .GroupBy(res => res.concreteCallable.FullName.Namespace) .ToImmutableDictionary(group => group.Key, group => group.Select(res => res.concreteCallable))); - return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.Transform(ns)).ToImmutableArray(), compilation.EntryPoints); + return new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.OnNamespace(ns)).ToImmutableArray(), compilation.EntryPoints); } public class TransformationState @@ -182,13 +183,16 @@ public TransformationState(ImmutableDictionary, IEnumerable< private ResolveGenerics(ImmutableDictionary, IEnumerable> namespaceCallables) : base(new TransformationState(namespaceCallables)) { this.Namespaces = new NamespaceTransformation(this); + this.Statements = new StatementTransformation(this, TransformationOptions.Disabled); + this.Expressions = new ExpressionTransformation(this, TransformationOptions.Disabled); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } private class NamespaceTransformation : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsNamespace Transform(QsNamespace ns) + public override QsNamespace OnNamespace(QsNamespace ns) { SharedState.NamespaceCallables.TryGetValue(ns.Name, out IEnumerable concretesInNs); @@ -221,7 +225,7 @@ public static Response Apply(Response current) { originalName = current.originalName, typeResolutions = current.typeResolutions, - concreteCallable = filter.Namespaces.onCallableImplementation(current.concreteCallable) + concreteCallable = filter.Namespaces.OnCallableDeclaration(current.concreteCallable) }; } @@ -245,7 +249,7 @@ private class NamespaceTransformation : NamespaceTransformation parent) : base(parent) { } - public override ResolvedSignature onSignature(ResolvedSignature s) + public override ResolvedSignature OnSignature(ResolvedSignature s) { // Remove the type parameters from the signature s = new ResolvedSignature( @@ -254,7 +258,7 @@ public override ResolvedSignature onSignature(ResolvedSignature s) s.ReturnType, s.Information ); - return base.onSignature(s); + return base.OnSignature(s); } } @@ -262,7 +266,7 @@ private class TypeTransformation : TypeTransformation { public TypeTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsTypeKind onTypeParameter(QsTypeParameter tp) + public override QsTypeKind OnTypeParameter(QsTypeParameter tp) { if (SharedState.TypeParams.TryGetValue(Tuple.Create(tp.Origin, tp.TypeName), out var typeParam)) { @@ -289,7 +293,7 @@ public static Response Apply(Response current, GetConcreteIdentifierFunc getConc { originalName = current.originalName, typeResolutions = current.typeResolutions, - concreteCallable = filter.Namespaces.onCallableImplementation(current.concreteCallable) + concreteCallable = filter.Namespaces.OnCallableDeclaration(current.concreteCallable) }; } @@ -311,27 +315,27 @@ private ReplaceTypeParamCalls(GetConcreteIdentifierFunc getConcreteIdentifier) : this.Types = new TypeTransformation(this); } - private class ExpressionTransformation : Core.ExpressionTransformation + private class ExpressionTransformation : ExpressionTransformation { public ExpressionTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override TypedExpression Transform(TypedExpression ex) + public override TypedExpression OnTypedExpression(TypedExpression ex) { - var range = this.onRangeInformation(ex.Range); - var typeParamResolutions = this.onTypeParamResolutions(ex.TypeParameterResolutions) + var range = this.OnRangeInformation(ex.Range); + var typeParamResolutions = this.OnTypeParamResolutions(ex.TypeParameterResolutions) .Select(kv => new Tuple, ResolvedType>(kv.Key.Item1, kv.Key.Item2, kv.Value)) .ToImmutableArray(); - var exType = this.Types.Transform(ex.ResolvedType); - var inferredInfo = this.onExpressionInformation(ex.InferredInformation); + var exType = this.Types.OnType(ex.ResolvedType); + var inferredInfo = this.OnExpressionInformation(ex.InferredInformation); // Change the order so that Kind is transformed last. // This matters because the onTypeParamResolutions method builds up type param mappings in // the CurrentParamTypes dictionary that are then used, and removed from the // dictionary, in the next global callable identifier found under the Kind transformations. - var kind = this.ExpressionKinds.Transform(ex.Expression); + var kind = this.ExpressionKinds.OnExpressionKind(ex.Expression); return new TypedExpression(kind, typeParamResolutions, exType, inferredInfo, range); } - public override ImmutableConcretion onTypeParamResolutions(ImmutableConcretion typeParams) + public override ImmutableConcretion OnTypeParamResolutions(ImmutableConcretion typeParams) { // Merge the type params into the current dictionary foreach (var kvp in typeParams) @@ -343,11 +347,11 @@ public override ImmutableConcretion onTypeParamResolutions(ImmutableConcretion t } } - private class ExpressionKindTransformation : Core.ExpressionKindTransformation + private class ExpressionKindTransformation : ExpressionKindTransformation { public ExpressionKindTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsExpressionKind onIdentifier(Identifier sym, QsNullable> tArgs) + public override QsExpressionKind OnIdentifier(Identifier sym, QsNullable> tArgs) { if (sym is Identifier.GlobalCallable global) { @@ -370,7 +374,7 @@ public override QsExpressionKind onId throw new ArgumentException($"Local variables cannot have type arguments."); } - return base.onIdentifier(sym, tArgs); + return base.OnIdentifier(sym, tArgs); } } @@ -378,7 +382,7 @@ private class TypeTransformation : TypeTransformation { public TypeTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsTypeKind onTypeParameter(QsTypeParameter tp) + public override QsTypeKind OnTypeParameter(QsTypeParameter tp) { if (SharedState.CurrentParamTypes.TryGetValue(Tuple.Create(tp.Origin, tp.TypeName), out var typeParam)) { diff --git a/src/QsCompiler/Transformations/MonomorphizationValidationTransformation.cs b/src/QsCompiler/Transformations/MonomorphizationValidation.cs similarity index 75% rename from src/QsCompiler/Transformations/MonomorphizationValidationTransformation.cs rename to src/QsCompiler/Transformations/MonomorphizationValidation.cs index 707918029e..02819a440b 100644 --- a/src/QsCompiler/Transformations/MonomorphizationValidationTransformation.cs +++ b/src/QsCompiler/Transformations/MonomorphizationValidation.cs @@ -10,23 +10,23 @@ using Microsoft.Quantum.QsCompiler.Transformations.Core; -namespace Microsoft.Quantum.QsCompiler.Transformations.MonomorphizationValidationTransformation +namespace Microsoft.Quantum.QsCompiler.Transformations.Monomorphization.Validation { - public class MonomorphizationValidationTransformation : SyntaxTreeTransformation + public class ValidateMonomorphization : SyntaxTreeTransformation { public static void Apply(QsCompilation compilation) { - var filter = new MonomorphizationValidationTransformation(); + var filter = new ValidateMonomorphization(); foreach (var ns in compilation.Namespaces) { - filter.Namespaces.Transform(ns); + filter.Namespaces.OnNamespace(ns); } } public class TransformationState { } - public MonomorphizationValidationTransformation() : base(new TransformationState()) + internal ValidateMonomorphization() : base(new TransformationState()) { this.Namespaces = new NamespaceTransformation(this); this.Expressions = new ExpressionTransformation(this); @@ -37,22 +37,22 @@ private class NamespaceTransformation : NamespaceTransformation parent) : base(parent) { } - public override ResolvedSignature onSignature(ResolvedSignature s) + public override ResolvedSignature OnSignature(ResolvedSignature s) { if (s.TypeParameters.Any()) { throw new Exception("Signatures cannot contains type parameters"); } - return base.onSignature(s); + return base.OnSignature(s); } } - private class ExpressionTransformation : Core.ExpressionTransformation + private class ExpressionTransformation : ExpressionTransformation { public ExpressionTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override ImmutableDictionary>, ResolvedType> onTypeParamResolutions(ImmutableDictionary>, ResolvedType> typeParams) + public override ImmutableDictionary>, ResolvedType> OnTypeParamResolutions(ImmutableDictionary>, ResolvedType> typeParams) { if (typeParams.Any()) { @@ -67,7 +67,7 @@ private class TypeTransformation : TypeTransformation { public TypeTransformation(SyntaxTreeTransformation parent) : base(parent) { } - public override QsTypeKind onTypeParameter(QsTypeParameter tp) + public override QsTypeKind OnTypeParameter(QsTypeParameter tp) { throw new Exception("Type Parameter types must be resolved"); } diff --git a/src/QsCompiler/Transformations/CodeOutput.cs b/src/QsCompiler/Transformations/QsharpCodeOutput.cs similarity index 86% rename from src/QsCompiler/Transformations/CodeOutput.cs rename to src/QsCompiler/Transformations/QsharpCodeOutput.cs index 699d5ede1c..28785776d8 100644 --- a/src/QsCompiler/Transformations/CodeOutput.cs +++ b/src/QsCompiler/Transformations/QsharpCodeOutput.cs @@ -48,8 +48,8 @@ public TransformationContext() /// Class used to generate Q# code for compiled Q# namespaces. /// Upon calling Transform, the Output property is set to the Q# code corresponding to the given namespace. /// - public class SyntaxTreeToQs - : SyntaxTreeTransformation + public class SyntaxTreeToQsharp + : SyntaxTreeTransformation { public const string InvalidType = "__UnknownType__"; public const string InvalidSet = "__UnknownSet__"; @@ -102,8 +102,8 @@ internal void InvokeOnInvalid(Action action) } - public SyntaxTreeToQs(TransformationContext context = null) - : base(new TransformationState(context)) + public SyntaxTreeToQsharp(TransformationContext context = null) + : base(new TransformationState(context), TransformationOptions.NoRebuild) { this.Types = new TypeTransformation(this); this.ExpressionKinds = new ExpressionKindTransformation(this); @@ -115,18 +115,18 @@ public SyntaxTreeToQs(TransformationContext context = null) // public methods for convenience - public static SyntaxTreeToQs Default = - new SyntaxTreeToQs(); + public static SyntaxTreeToQsharp Default = + new SyntaxTreeToQsharp(); public string ToCode(ResolvedType t) { - this.Types.Transform(t); + this.Types.OnType(t); return this.SharedState.TypeOutputHandle; } public string ToCode(QsExpressionKind k) { - this.ExpressionKinds.Transform(k); + this.ExpressionKinds.OnExpressionKind(k); return this.SharedState.ExpressionOutputHandle; } @@ -136,7 +136,7 @@ public string ToCode(TypedExpression ex) => public string ToCode(QsStatementKind stmKind) { var nrPreexistingLines = this.SharedState.StatementOutputHandle.Count; - this.StatementKinds.Transform(stmKind); + this.StatementKinds.OnStatementKind(stmKind); return String.Join(Environment.NewLine, this.SharedState.StatementOutputHandle.Skip(nrPreexistingLines)); } @@ -146,7 +146,7 @@ public string ToCode(QsStatement stm) => public string ToCode(QsNamespace ns) { var nrPreexistingLines = this.SharedState.NamespaceOutputHandle.Count; - this.Namespaces.Transform(ns); + this.Namespaces.OnNamespace(ns); return String.Join(Environment.NewLine, this.SharedState.NamespaceOutputHandle.Skip(nrPreexistingLines)); } @@ -212,10 +212,10 @@ public static bool Apply(out List, strin var totNrInvalid = 0; var docComments = ns.Documentation[sourceFile]; - var generator = new SyntaxTreeToQs(context); + var generator = new SyntaxTreeToQsharp(context); generator.SharedState.InvokeOnInvalid(() => ++totNrInvalid); generator.SharedState.NamespaceDocumentation = docComments.Count() == 1 ? docComments.Single() : ImmutableArray.Empty; // let's drop the doc if it is ambiguous - generator.Namespaces.Transform(tree); + generator.Namespaces.OnNamespace(tree); if (totNrInvalid > 0) success = false; nsInFile.Add(ns.Name, String.Join(Environment.NewLine, generator.SharedState.NamespaceOutputHandle)); @@ -234,7 +234,7 @@ public static bool Apply(out List, strin /// that upon calling Transform on a Q# type is set to the Q# code corresponding to that type. /// public class TypeTransformation - : TypeTransformation + : TypeTransformation { private readonly Func TypeToQs; @@ -244,13 +244,15 @@ protected string Output // the sole purpose of this is a shorter name ... set => SharedState.TypeOutputHandle = value; } - public TypeTransformation(SyntaxTreeToQs parent) : base(parent) => + public TypeTransformation(SyntaxTreeToQsharp parent) + : base(parent, TransformationOptions.NoRebuild) => this.TypeToQs = parent.ToCode; - public TypeTransformation() : base(new TransformationState()) => + public TypeTransformation() + : base(new TransformationState(), TransformationOptions.NoRebuild) => this.TypeToQs = t => { - this.Transformation.Types.Transform(t); + this.Transformation.Types.OnType(t); return this.SharedState.TypeOutputHandle; }; @@ -303,104 +305,104 @@ string SetAnnotation(ResolvedCharacteristics charEx) // overrides - public override QsTypeKind onArrayType(ResolvedType b) + public override QsTypeKind OnArrayType(ResolvedType b) { this.Output = $"{this.TypeToQs(b)}[]"; return QsTypeKind.NewArrayType(b); } - public override QsTypeKind onBool() + public override QsTypeKind OnBool() { this.Output = Keywords.qsBool.id; return QsTypeKind.Bool; } - public override QsTypeKind onDouble() + public override QsTypeKind OnDouble() { this.Output = Keywords.qsDouble.id; return QsTypeKind.Double; } - public override QsTypeKind onFunction(ResolvedType it, ResolvedType ot) + public override QsTypeKind OnFunction(ResolvedType it, ResolvedType ot) { this.Output = $"({this.TypeToQs(it)} -> {this.TypeToQs(ot)})"; return QsTypeKind.NewFunction(it, ot); } - public override QsTypeKind onInt() + public override QsTypeKind OnInt() { this.Output = Keywords.qsInt.id; return QsTypeKind.Int; } - public override QsTypeKind onBigInt() + public override QsTypeKind OnBigInt() { this.Output = Keywords.qsBigInt.id; return QsTypeKind.BigInt; } - public override QsTypeKind onInvalidType() + public override QsTypeKind OnInvalidType() { this.SharedState.BeforeInvalidType?.Invoke(); this.Output = InvalidType; return QsTypeKind.InvalidType; } - public override QsTypeKind onMissingType() + public override QsTypeKind OnMissingType() { this.Output = "_"; // needs to be underscore, since this is valid as type argument specifier return QsTypeKind.MissingType; } - public override QsTypeKind onPauli() + public override QsTypeKind OnPauli() { this.Output = Keywords.qsPauli.id; return QsTypeKind.Pauli; } - public override QsTypeKind onQubit() + public override QsTypeKind OnQubit() { this.Output = Keywords.qsQubit.id; return QsTypeKind.Qubit; } - public override QsTypeKind onRange() + public override QsTypeKind OnRange() { this.Output = Keywords.qsRange.id; return QsTypeKind.Range; } - public override QsTypeKind onResult() + public override QsTypeKind OnResult() { this.Output = Keywords.qsResult.id; return QsTypeKind.Result; } - public override QsTypeKind onString() + public override QsTypeKind OnString() { this.Output = Keywords.qsString.id; return QsTypeKind.String; } - public override QsTypeKind onTupleType(ImmutableArray ts) + public override QsTypeKind OnTupleType(ImmutableArray ts) { this.Output = $"({String.Join(", ", ts.Select(this.TypeToQs))})"; return QsTypeKind.NewTupleType(ts); } - public override QsTypeKind onTypeParameter(QsTypeParameter tp) + public override QsTypeKind OnTypeParameter(QsTypeParameter tp) { this.Output = $"'{tp.TypeName.Value}"; return QsTypeKind.NewTypeParameter(tp); } - public override QsTypeKind onUnitType() + public override QsTypeKind OnUnitType() { this.Output = Keywords.qsUnit.id; return QsTypeKind.UnitType; } - public override QsTypeKind onUserDefinedType(UserDefinedType udt) + public override QsTypeKind OnUserDefinedType(UserDefinedType udt) { var isInCurrentNamespace = udt.Namespace.Value == this.SharedState.Context.CurrentNamespace; var isInOpenNamespace = this.SharedState.Context.OpenedNamespaces.Contains(udt.Namespace) && !this.SharedState.Context.SymbolsInCurrentNamespace.Contains(udt.Name); @@ -411,15 +413,15 @@ public override QsTypeKind onUserDefinedType(UserDefinedType udt) return QsTypeKind.NewUserDefinedType(udt); } - public override ResolvedCharacteristics onCharacteristicsExpression(ResolvedCharacteristics set) + public override ResolvedCharacteristics OnCharacteristicsExpression(ResolvedCharacteristics set) { this.Output = CharacteristicsExpression(set, onInvalidSet: this.SharedState.BeforeInvalidSet); return set; } - public override QsTypeKind onOperation(Tuple sign, CallableInformation info) + public override QsTypeKind OnOperation(Tuple sign, CallableInformation info) { - info = base.onCallableInformation(info); + info = this.OnCallableInformation(info); var characteristics = String.IsNullOrWhiteSpace(this.Output) ? "" : $" {Keywords.qsCharacteristics.id} {this.Output}"; this.Output = $"({this.TypeToQs(sign.Item1)} => {this.TypeToQs(sign.Item2)}{characteristics})"; return QsTypeKind.NewOperation(sign, info); @@ -432,7 +434,7 @@ public override QsTypeKind onOperation(Tuple sign, C /// Upon calling Transform, the Output property is set to the Q# code corresponding to an expression of the given kind. /// public class ExpressionKindTransformation - : Core.ExpressionKindTransformation + : ExpressionKindTransformation { // allows to omit unnecessary parentheses private int CurrentPrecedence = 0; @@ -449,8 +451,8 @@ protected string Output // the sole purpose of this is a shorter name ... set => SharedState.ExpressionOutputHandle = value; } - public ExpressionKindTransformation(SyntaxTreeToQs parent) - : base(parent) => + public ExpressionKindTransformation(SyntaxTreeToQsharp parent) + : base(parent, TransformationOptions.NoRebuild) => this.TypeToQs = parent.ToCode; @@ -465,7 +467,7 @@ private static string ReplaceInterpolatedArgs(string text, Func rep private string Recur(int prec, TypedExpression ex) { - this.Transformation.Expressions.Transform(ex); + this.Transformation.Expressions.OnTypedExpression(ex); return prec < this.CurrentPrecedence || this.CurrentPrecedence == int.MaxValue // need to cover the case where prec = currentPrec = MaxValue ? this.Output : $"({this.Output})"; @@ -503,166 +505,166 @@ private QsExpressionKind CallLike(TypedExpression method, TypedExpression arg) // overrides - public override QsExpressionKind onCopyAndUpdateExpression(TypedExpression lhs, TypedExpression acc, TypedExpression rhs) + public override QsExpressionKind OnCopyAndUpdateExpression(TypedExpression lhs, TypedExpression acc, TypedExpression rhs) { TernaryOperator(Keywords.qsCopyAndUpdateOp, lhs, acc, rhs); return QsExpressionKind.NewCopyAndUpdate(lhs, acc, rhs); } - public override QsExpressionKind onConditionalExpression(TypedExpression cond, TypedExpression ifTrue, TypedExpression ifFalse) + public override QsExpressionKind OnConditionalExpression(TypedExpression cond, TypedExpression ifTrue, TypedExpression ifFalse) { TernaryOperator(Keywords.qsConditionalOp, cond, ifTrue, ifFalse); return QsExpressionKind.NewCONDITIONAL(cond, ifTrue, ifFalse); } - public override QsExpressionKind onAddition(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnAddition(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsADDop, lhs, rhs); return QsExpressionKind.NewADD(lhs, rhs); } - public override QsExpressionKind onBitwiseAnd(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnBitwiseAnd(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsBANDop, lhs, rhs); return QsExpressionKind.NewBAND(lhs, rhs); } - public override QsExpressionKind onBitwiseExclusiveOr(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnBitwiseExclusiveOr(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsBXORop, lhs, rhs); return QsExpressionKind.NewBXOR(lhs, rhs); } - public override QsExpressionKind onBitwiseOr(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnBitwiseOr(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsBORop, lhs, rhs); return QsExpressionKind.NewBOR(lhs, rhs); } - public override QsExpressionKind onDivision(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnDivision(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsDIVop, lhs, rhs); return QsExpressionKind.NewDIV(lhs, rhs); } - public override QsExpressionKind onEquality(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnEquality(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsEQop, lhs, rhs); return QsExpressionKind.NewEQ(lhs, rhs); } - public override QsExpressionKind onExponentiate(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnExponentiate(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsPOWop, lhs, rhs); return QsExpressionKind.NewPOW(lhs, rhs); } - public override QsExpressionKind onGreaterThan(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnGreaterThan(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsGTop, lhs, rhs); return QsExpressionKind.NewGT(lhs, rhs); } - public override QsExpressionKind onGreaterThanOrEqual(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnGreaterThanOrEqual(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsGTEop, lhs, rhs); return QsExpressionKind.NewGTE(lhs, rhs); } - public override QsExpressionKind onInequality(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnInequality(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsNEQop, lhs, rhs); return QsExpressionKind.NewNEQ(lhs, rhs); } - public override QsExpressionKind onLeftShift(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnLeftShift(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsLSHIFTop, lhs, rhs); return QsExpressionKind.NewLSHIFT(lhs, rhs); } - public override QsExpressionKind onLessThan(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnLessThan(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsLTop, lhs, rhs); return QsExpressionKind.NewLT(lhs, rhs); } - public override QsExpressionKind onLessThanOrEqual(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnLessThanOrEqual(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsLTEop, lhs, rhs); return QsExpressionKind.NewLTE(lhs, rhs); } - public override QsExpressionKind onLogicalAnd(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnLogicalAnd(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsANDop, lhs, rhs); return QsExpressionKind.NewAND(lhs, rhs); } - public override QsExpressionKind onLogicalOr(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnLogicalOr(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsORop, lhs, rhs); return QsExpressionKind.NewOR(lhs, rhs); } - public override QsExpressionKind onModulo(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnModulo(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsMODop, lhs, rhs); return QsExpressionKind.NewMOD(lhs, rhs); } - public override QsExpressionKind onMultiplication(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnMultiplication(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsMULop, lhs, rhs); return QsExpressionKind.NewMUL(lhs, rhs); } - public override QsExpressionKind onRightShift(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnRightShift(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsRSHIFTop, lhs, rhs); return QsExpressionKind.NewRSHIFT(lhs, rhs); } - public override QsExpressionKind onSubtraction(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnSubtraction(TypedExpression lhs, TypedExpression rhs) { BinaryOperator(Keywords.qsSUBop, lhs, rhs); return QsExpressionKind.NewSUB(lhs, rhs); } - public override QsExpressionKind onNegative(TypedExpression ex) + public override QsExpressionKind OnNegative(TypedExpression ex) { UnaryOperator(Keywords.qsNEGop, ex); return QsExpressionKind.NewNEG(ex); } - public override QsExpressionKind onLogicalNot(TypedExpression ex) + public override QsExpressionKind OnLogicalNot(TypedExpression ex) { UnaryOperator(Keywords.qsNOTop, ex); return QsExpressionKind.NewNOT(ex); } - public override QsExpressionKind onBitwiseNot(TypedExpression ex) + public override QsExpressionKind OnBitwiseNot(TypedExpression ex) { UnaryOperator(Keywords.qsBNOTop, ex); return QsExpressionKind.NewBNOT(ex); } - public override QsExpressionKind onOperationCall(TypedExpression method, TypedExpression arg) + public override QsExpressionKind OnOperationCall(TypedExpression method, TypedExpression arg) { return this.CallLike(method, arg); } - public override QsExpressionKind onFunctionCall(TypedExpression method, TypedExpression arg) + public override QsExpressionKind OnFunctionCall(TypedExpression method, TypedExpression arg) { return this.CallLike(method, arg); } - public override QsExpressionKind onPartialApplication(TypedExpression method, TypedExpression arg) + public override QsExpressionKind OnPartialApplication(TypedExpression method, TypedExpression arg) { return this.CallLike(method, arg); } - public override QsExpressionKind onAdjointApplication(TypedExpression ex) + public override QsExpressionKind OnAdjointApplication(TypedExpression ex) { var op = Keywords.qsAdjointModifier; this.Output = $"{op.op} {this.Recur(op.prec, ex)}"; @@ -670,7 +672,7 @@ public override QsExpressionKind onAdjointApplication(TypedExpression ex) return QsExpressionKind.NewAdjointApplication(ex); } - public override QsExpressionKind onControlledApplication(TypedExpression ex) + public override QsExpressionKind OnControlledApplication(TypedExpression ex) { var op = Keywords.qsControlledModifier; this.Output = $"{op.op} {this.Recur(op.prec, ex)}"; @@ -678,7 +680,7 @@ public override QsExpressionKind onControlledApplication(TypedExpression ex) return QsExpressionKind.NewControlledApplication(ex); } - public override QsExpressionKind onUnwrapApplication(TypedExpression ex) + public override QsExpressionKind OnUnwrapApplication(TypedExpression ex) { var op = Keywords.qsUnwrapModifier; this.Output = $"{this.Recur(op.prec, ex)}{op.op}"; @@ -686,21 +688,21 @@ public override QsExpressionKind onUnwrapApplication(TypedExpression ex) return QsExpressionKind.NewUnwrapApplication(ex); } - public override QsExpressionKind onUnitValue() + public override QsExpressionKind OnUnitValue() { this.Output = "()"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.UnitValue; } - public override QsExpressionKind onMissingExpression() + public override QsExpressionKind OnMissingExpression() { this.Output = "_"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.MissingExpr; } - public override QsExpressionKind onInvalidExpression() + public override QsExpressionKind OnInvalidExpression() { this.SharedState.BeforeInvalidExpression?.Invoke(); this.Output = InvalidExpression; @@ -708,28 +710,28 @@ public override QsExpressionKind onInvalidExpression() return QsExpressionKind.InvalidExpr; } - public override QsExpressionKind onValueTuple(ImmutableArray vs) + public override QsExpressionKind OnValueTuple(ImmutableArray vs) { this.Output = $"({String.Join(", ", vs.Select(v => this.Recur(int.MinValue, v)))})"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.NewValueTuple(vs); } - public override QsExpressionKind onValueArray(ImmutableArray vs) + public override QsExpressionKind OnValueArray(ImmutableArray vs) { this.Output = $"[{String.Join(", ", vs.Select(v => this.Recur(int.MinValue, v)))}]"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.NewValueArray(vs); } - public override QsExpressionKind onNewArray(ResolvedType bt, TypedExpression idx) + public override QsExpressionKind OnNewArray(ResolvedType bt, TypedExpression idx) { this.Output = $"{Keywords.arrayDecl.id} {this.TypeToQs(bt)}[{this.Recur(int.MinValue, idx)}]"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.NewNewArray(bt, idx); } - public override QsExpressionKind onArrayItem(TypedExpression arr, TypedExpression idx) + public override QsExpressionKind OnArrayItem(TypedExpression arr, TypedExpression idx) { var prec = Keywords.qsArrayAccessCombinator.prec; this.Output = $"{this.Recur(prec, arr)}[{this.Recur(int.MinValue, idx)}]"; // Todo: generate contextual open range expression when appropriate @@ -737,29 +739,29 @@ public override QsExpressionKind onArrayItem(TypedExpression arr, TypedExpressio return QsExpressionKind.NewArrayItem(arr, idx); } - public override QsExpressionKind onNamedItem(TypedExpression ex, Identifier acc) + public override QsExpressionKind OnNamedItem(TypedExpression ex, Identifier acc) { - this.onIdentifier(acc, QsNullable>.Null); + this.OnIdentifier(acc, QsNullable>.Null); var (op, itemName) = (Keywords.qsNamedItemCombinator, this.Output); this.Output = $"{this.Recur(op.prec, ex)}{op.op}{itemName}"; - return base.onNamedItem(ex, acc); + return QsExpressionKind.NewNamedItem(ex, acc); } - public override QsExpressionKind onIntLiteral(long i) + public override QsExpressionKind OnIntLiteral(long i) { this.Output = i.ToString(CultureInfo.InvariantCulture); this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.NewIntLiteral(i); } - public override QsExpressionKind onBigIntLiteral(BigInteger b) + public override QsExpressionKind OnBigIntLiteral(BigInteger b) { this.Output = b.ToString("R", CultureInfo.InvariantCulture) + "L"; this.CurrentPrecedence = int.MaxValue; return QsExpressionKind.NewBigIntLiteral(b); } - public override QsExpressionKind onDoubleLiteral(double d) + public override QsExpressionKind OnDoubleLiteral(double d) { this.Output = d.ToString("R", CultureInfo.InvariantCulture); if ((int)d == d) this.Output = $"{this.Output}.0"; @@ -767,7 +769,7 @@ public override QsExpressionKind onDoubleLiteral(double d) return QsExpressionKind.NewDoubleLiteral(d); } - public override QsExpressionKind onBoolLiteral(bool b) + public override QsExpressionKind OnBoolLiteral(bool b) { if (b) this.Output = Keywords.qsTrue.id; else this.Output = Keywords.qsFalse.id; @@ -775,7 +777,7 @@ public override QsExpressionKind onBoolLiteral(bool b) return QsExpressionKind.NewBoolLiteral(b); } - public override QsExpressionKind onStringLiteral(NonNullable s, ImmutableArray exs) + public override QsExpressionKind OnStringLiteral(NonNullable s, ImmutableArray exs) { string InterpolatedArg(int index) => $"{{{this.Recur(int.MinValue, exs[index])}}}"; this.Output = exs.Length == 0 ? $"\"{s.Value}\"" : $"$\"{ReplaceInterpolatedArgs(s.Value, InterpolatedArg)}\""; @@ -783,7 +785,7 @@ public override QsExpressionKind onStringLiteral(NonNullable s, Immutabl return QsExpressionKind.NewStringLiteral(s, exs); } - public override QsExpressionKind onRangeLiteral(TypedExpression lhs, TypedExpression rhs) + public override QsExpressionKind OnRangeLiteral(TypedExpression lhs, TypedExpression rhs) { var op = Keywords.qsRangeOp; var lhsStr = lhs.Expression.IsRangeLiteral ? this.Recur(int.MinValue, lhs) : this.Recur(op.prec, lhs); @@ -792,7 +794,7 @@ public override QsExpressionKind onRangeLiteral(TypedExpression lhs, TypedExpres return QsExpressionKind.NewRangeLiteral(lhs, rhs); } - public override QsExpressionKind onResultLiteral(QsResult r) + public override QsExpressionKind OnResultLiteral(QsResult r) { if (r.IsZero) this.Output = Keywords.qsZero.id; else if (r.IsOne) this.Output = Keywords.qsOne.id; @@ -801,7 +803,7 @@ public override QsExpressionKind onResultLiteral(QsResult r) return QsExpressionKind.NewResultLiteral(r); } - public override QsExpressionKind onPauliLiteral(QsPauli p) + public override QsExpressionKind OnPauliLiteral(QsPauli p) { if (p.IsPauliI) this.Output = Keywords.qsPauliI.id; else if (p.IsPauliX) this.Output = Keywords.qsPauliX.id; @@ -812,7 +814,7 @@ public override QsExpressionKind onPauliLiteral(QsPauli p) return QsExpressionKind.NewPauliLiteral(p); } - public override QsExpressionKind onIdentifier(Identifier sym, QsNullable> tArgs) + public override QsExpressionKind OnIdentifier(Identifier sym, QsNullable> tArgs) { if (sym is Identifier.LocalVariable loc) { this.Output = loc.Item.Value; } @@ -849,7 +851,7 @@ public override QsExpressionKind onIdentifier(Identifier sym, QsNullable public class StatementKindTransformation - : Core.StatementKindTransformation + : StatementKindTransformation { private int CurrentIndendation = 0; @@ -861,8 +863,8 @@ public class StatementKindTransformation private bool PrecededByBlock => TransformationState.PrecededByBlock(this.SharedState.StatementOutputHandle); - public StatementKindTransformation(SyntaxTreeToQs parent) - : base(parent) => + public StatementKindTransformation(SyntaxTreeToQsharp parent) + : base(parent, TransformationOptions.NoRebuild) => this.ExpressionToQs = parent.ToCode; @@ -897,7 +899,7 @@ private void AddBlockStatement(string intro, QsScope statements, bool withWhiteS this.AddComments(comments.OpeningComments); this.AddToOutput($"{intro} {"{"}"); ++this.CurrentIndendation; - this.Transformation.Statements.Transform(statements); + this.Transformation.Statements.OnScope(statements); this.AddComments(comments.ClosingComments); --this.CurrentIndendation; this.AddToOutput("}"); @@ -934,7 +936,7 @@ private string InitializerTuple(ResolvedInitializer init) // overrides - public override QsStatementKind onQubitScope(QsQubitScope stm) + public override QsStatementKind OnQubitScope(QsQubitScope stm) { var symbols = this.SymbolTuple(stm.Binding.Lhs); var initializers = this.InitializerTuple(stm.Binding.Rhs); @@ -948,7 +950,7 @@ public override QsStatementKind onQubitScope(QsQubitScope stm) return QsStatementKind.NewQsQubitScope(stm); } - public override QsStatementKind onForStatement(QsForStatement stm) + public override QsStatementKind OnForStatement(QsForStatement stm) { var symbols = this.SymbolTuple(stm.LoopItem.Item1); var intro = $"{Keywords.qsFor.id} ({symbols} {Keywords.qsRangeIter.id} {this.ExpressionToQs(stm.IterationValues)})"; @@ -956,14 +958,14 @@ public override QsStatementKind onForStatement(QsForStatement stm) return QsStatementKind.NewQsForStatement(stm); } - public override QsStatementKind onWhileStatement(QsWhileStatement stm) + public override QsStatementKind OnWhileStatement(QsWhileStatement stm) { var intro = $"{Keywords.qsWhile.id} ({this.ExpressionToQs(stm.Condition)})"; this.AddBlockStatement(intro, stm.Body); return QsStatementKind.NewQsWhileStatement(stm); } - public override QsStatementKind onRepeatStatement(QsRepeatStatement stm) + public override QsStatementKind OnRepeatStatement(QsRepeatStatement stm) { this.SharedState.StatementComments = stm.RepeatBlock.Comments; this.AddBlockStatement(Keywords.qsRepeat.id, stm.RepeatBlock.Body); @@ -973,7 +975,7 @@ public override QsStatementKind onRepeatStatement(QsRepeatStatement stm) return QsStatementKind.NewQsRepeatStatement(stm); } - public override QsStatementKind onConditionalStatement(QsConditionalStatement stm) + public override QsStatementKind OnConditionalStatement(QsConditionalStatement stm) { var header = Keywords.qsIf.id; if (this.PrecededByCode) this.AddToOutput(""); @@ -992,7 +994,7 @@ public override QsStatementKind onConditionalStatement(QsConditionalStatement st return QsStatementKind.NewQsConditionalStatement(stm); } - public override QsStatementKind onConjugation(QsConjugation stm) + public override QsStatementKind OnConjugation(QsConjugation stm) { this.SharedState.StatementComments = stm.OuterTransformation.Comments; this.AddBlockStatement(Keywords.qsWithin.id, stm.OuterTransformation.Body, true); @@ -1002,25 +1004,25 @@ public override QsStatementKind onConjugation(QsConjugation stm) } - public override QsStatementKind onExpressionStatement(TypedExpression ex) + public override QsStatementKind OnExpressionStatement(TypedExpression ex) { this.AddStatement(this.ExpressionToQs(ex)); return QsStatementKind.NewQsExpressionStatement(ex); } - public override QsStatementKind onFailStatement(TypedExpression ex) + public override QsStatementKind OnFailStatement(TypedExpression ex) { this.AddStatement($"{Keywords.qsFail.id} {this.ExpressionToQs(ex)}"); return QsStatementKind.NewQsFailStatement(ex); } - public override QsStatementKind onReturnStatement(TypedExpression ex) + public override QsStatementKind OnReturnStatement(TypedExpression ex) { this.AddStatement($"{Keywords.qsReturn.id} {this.ExpressionToQs(ex)}"); return QsStatementKind.NewQsReturnStatement(ex); } - public override QsStatementKind onVariableDeclaration(QsBinding stm) + public override QsStatementKind OnVariableDeclaration(QsBinding stm) { string header; if (stm.Kind.IsImmutableBinding) header = Keywords.qsImmutableBinding.id; @@ -1031,7 +1033,7 @@ public override QsStatementKind onVariableDeclaration(QsBinding return QsStatementKind.NewQsVariableDeclaration(stm); } - public override QsStatementKind onValueUpdate(QsValueUpdate stm) + public override QsStatementKind OnValueUpdate(QsValueUpdate stm) { this.AddStatement($"{Keywords.qsValueUpdate.id} {this.ExpressionToQs(stm.Lhs)} = {this.ExpressionToQs(stm.Rhs)}"); return QsStatementKind.NewQsValueUpdate(stm); @@ -1044,25 +1046,24 @@ public override QsStatementKind onValueUpdate(QsValueUpdate stm) /// Upon calling Transform, the Output property is set to the Q# code corresponding to the given statement block. /// public class StatementTransformation - : StatementTransformation + : StatementTransformation { public StatementTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } // overrides - public override QsStatement onStatement(QsStatement stm) + public override QsStatement OnStatement(QsStatement stm) { this.SharedState.StatementComments = stm.Comments; - return base.onStatement(stm); + return base.OnStatement(stm); } } public class NamespaceTransformation - : NamespaceTransformation + : NamespaceTransformation { private int CurrentIndendation = 0; private string CurrentSpecialization = null; @@ -1075,8 +1076,8 @@ public class NamespaceTransformation private List Output => // the sole purpose of this is a shorter name ... this.SharedState.NamespaceOutputHandle; - public NamespaceTransformation(SyntaxTreeToQs parent) - : base(parent) => + public NamespaceTransformation(SyntaxTreeToQsharp parent) + : base(parent, TransformationOptions.NoRebuild) => this.TypeToQs = parent.ToCode; @@ -1125,11 +1126,11 @@ private void ProcessNamespaceElements(IEnumerable elements) var callables = elements.Where(e => e.IsQsCallable); foreach (var t in types) - { this.dispatchNamespaceElement(t); } + { this.OnNamespaceElement(t); } if (types.Any()) this.AddToOutput(""); foreach (var c in callables) - { this.dispatchNamespaceElement(c); } + { this.OnNamespaceElement(c); } } @@ -1170,7 +1171,7 @@ internal static string ArgumentTuple(QsTuple arg, // overrides - public override Tuple>, QsScope> onProvidedImplementation + public override Tuple>, QsScope> OnProvidedImplementation (QsTuple> argTuple, QsScope body) { var functorArg = "(...)"; @@ -1185,7 +1186,7 @@ public override Tuple>, QsScope> void ProcessContent() { this.SharedState.StatementOutputHandle.Clear(); - this.Transformation.Statements.Transform(body); + this.Transformation.Statements.OnScope(body); foreach (var line in this.SharedState.StatementOutputHandle) { this.AddToOutput(line); } } @@ -1203,55 +1204,55 @@ void ProcessContent() return new Tuple>, QsScope>(argTuple, body); } - public override void onInvalidGeneratorDirective() + public override void OnInvalidGeneratorDirective() { this.SharedState.BeforeInvalidFunctorGenerator?.Invoke(); this.AddDirective($"{this.CurrentSpecialization} {InvalidFunctorGenerator}"); } - public override void onDistributeDirective() => + public override void OnDistributeDirective() => this.AddDirective($"{this.CurrentSpecialization} {Keywords.distributeFunctorGenDirective.id}"); - public override void onInvertDirective() => + public override void OnInvertDirective() => this.AddDirective($"{this.CurrentSpecialization} {Keywords.invertFunctorGenDirective.id}"); - public override void onSelfInverseDirective() => + public override void OnSelfInverseDirective() => this.AddDirective($"{this.CurrentSpecialization} {Keywords.selfFunctorGenDirective.id}"); - public override void onIntrinsicImplementation() => + public override void OnIntrinsicImplementation() => this.AddDirective($"{this.CurrentSpecialization} {Keywords.intrinsicFunctorGenDirective.id}"); - public override void onExternalImplementation() + public override void OnExternalImplementation() { this.SharedState.BeforeExternalImplementation?.Invoke(); this.AddDirective($"{this.CurrentSpecialization} {ExternalImplementation}"); } - public override QsSpecialization onBodySpecialization(QsSpecialization spec) + public override QsSpecialization OnBodySpecialization(QsSpecialization spec) { this.CurrentSpecialization = Keywords.bodyDeclHeader.id; - return base.onBodySpecialization(spec); + return base.OnBodySpecialization(spec); } - public override QsSpecialization onAdjointSpecialization(QsSpecialization spec) + public override QsSpecialization OnAdjointSpecialization(QsSpecialization spec) { this.CurrentSpecialization = Keywords.adjDeclHeader.id; - return base.onAdjointSpecialization(spec); + return base.OnAdjointSpecialization(spec); } - public override QsSpecialization onControlledSpecialization(QsSpecialization spec) + public override QsSpecialization OnControlledSpecialization(QsSpecialization spec) { this.CurrentSpecialization = Keywords.ctrlDeclHeader.id; - return base.onControlledSpecialization(spec); + return base.OnControlledSpecialization(spec); } - public override QsSpecialization onControlledAdjointSpecialization(QsSpecialization spec) + public override QsSpecialization OnControlledAdjointSpecialization(QsSpecialization spec) { this.CurrentSpecialization = Keywords.ctrlAdjDeclHeader.id; - return base.onControlledAdjointSpecialization(spec); + return base.OnControlledAdjointSpecialization(spec); } - public override QsSpecialization beforeSpecialization(QsSpecialization spec) + public override QsSpecialization OnSpecializationDeclaration(QsSpecialization spec) { var precededByCode = TransformationState.PrecededByCode(this.Output); var precededByBlock = TransformationState.PrecededByBlock(this.Output); @@ -1260,10 +1261,10 @@ public override QsSpecialization beforeSpecialization(QsSpecialization spec) this.AddComments(spec.Comments.OpeningComments); if (spec.Comments.OpeningComments.Any() && spec.Documentation.Any()) this.AddToOutput(""); this.AddDocumentation(spec.Documentation); - return spec; + return base.OnSpecializationDeclaration(spec); } - public override QsCallable onCallableImplementation(QsCallable c) + public override QsCallable OnCallableDeclaration(QsCallable c) { if (c.Kind.IsTypeConstructor) return c; // no code for these @@ -1273,10 +1274,10 @@ public override QsCallable onCallableImplementation(QsCallable c) if (c.Comments.OpeningComments.Any() && c.Documentation.Any()) this.AddToOutput(""); this.AddDocumentation(c.Documentation); foreach (var attribute in c.Attributes) - { this.onAttribute(attribute); } + { this.OnAttribute(attribute); } var signature = DeclarationSignature(c, this.TypeToQs, this.SharedState.BeforeInvalidSymbol); - this.Transformation.Types.onCharacteristicsExpression(c.Signature.Information.Characteristics); + this.Transformation.Types.OnCharacteristicsExpression(c.Signature.Information.Characteristics); var characteristics = this.SharedState.TypeOutputHandle; var userDefinedSpecs = c.Specializations.Where(spec => spec.Implementation.IsProvided); @@ -1310,12 +1311,12 @@ bool NeedsToBeExplicit(QsSpecialization s) this.AddToOutput($"{declHeader} {signature}"); if (!String.IsNullOrWhiteSpace(characteristics)) this.AddToOutput($"{Keywords.qsCharacteristics.id} {characteristics}"); - this.AddBlock(() => c.Specializations.Select(dispatchSpecialization).ToImmutableArray()); + this.AddBlock(() => c.Specializations.Select(this.OnSpecializationDeclaration).ToImmutableArray()); this.AddToOutput(""); return c; } - public override QsCustomType onType(QsCustomType t) + public override QsCustomType OnTypeDeclaration(QsCustomType t) { this.AddToOutput(""); this.DeclarationComments = t.Comments; // no need to deal with closing comments (can't exist), but need to make sure DeclarationComments is up to date @@ -1323,7 +1324,7 @@ public override QsCustomType onType(QsCustomType t) if (t.Comments.OpeningComments.Any() && t.Documentation.Any()) this.AddToOutput(""); this.AddDocumentation(t.Documentation); foreach (var attribute in t.Attributes) - { this.onAttribute(attribute); } + { this.OnAttribute(attribute); } (string, ResolvedType) GetItemNameAndType(QsTypeItem item) { @@ -1336,22 +1337,22 @@ public override QsCustomType onType(QsCustomType t) return t; } - public override QsDeclarationAttribute onAttribute(QsDeclarationAttribute att) + public override QsDeclarationAttribute OnAttribute(QsDeclarationAttribute att) { // do *not* set DeclarationComments! - this.Transformation.Expressions.Transform(att.Argument); + this.Transformation.Expressions.OnTypedExpression(att.Argument); var arg = this.SharedState.ExpressionOutputHandle; var argStr = att.Argument.Expression.IsValueTuple || att.Argument.Expression.IsUnitValue ? arg : $"({arg})"; var id = att.TypeId.IsValue ? Identifier.NewGlobalCallable(new QsQualifiedName(att.TypeId.Item.Namespace, att.TypeId.Item.Name)) : Identifier.InvalidIdentifier; - this.Transformation.ExpressionKinds.onIdentifier(id, QsNullable>.Null); + this.Transformation.ExpressionKinds.OnIdentifier(id, QsNullable>.Null); this.AddComments(att.Comments.OpeningComments); this.AddToOutput($"@ {this.SharedState.ExpressionOutputHandle}{argStr}"); return att; } - public override QsNamespace Transform(QsNamespace ns) + public override QsNamespace OnNamespace(QsNamespace ns) { if (this.SharedState.Context.CurrentNamespace != ns.Name.Value) { diff --git a/src/QsCompiler/Transformations/SearchAndReplace.cs b/src/QsCompiler/Transformations/SearchAndReplace.cs index f2e0caa587..e12ed5dd81 100644 --- a/src/QsCompiler/Transformations/SearchAndReplace.cs +++ b/src/QsCompiler/Transformations/SearchAndReplace.cs @@ -27,7 +27,7 @@ namespace Microsoft.Quantum.QsCompiler.Transformations.SearchAndReplace /// If a set of source file names is given on initialization, the search is limited to callables and specializations in those files. /// public class IdentifierReferences - : SyntaxTreeTransformation + : SyntaxTreeTransformation { public class Location : IEquatable { @@ -147,7 +147,8 @@ internal void LogIdentifierLocation(TypedExpression ex) } } - public IdentifierReferences(TransformationState state) : base(state) + public IdentifierReferences(TransformationState state) + : base(state, TransformationOptions.NoRebuild) { this.Types = new TypeTransformation(this); this.Expressions = new TypedExpressionWalker(this.SharedState.LogIdentifierLocation, this); @@ -155,12 +156,11 @@ public IdentifierReferences(TransformationState state) : base(state) this.Namespaces = new NamespaceTransformation(this); } - public IdentifierReferences(NonNullable idName, QsLocation defaultOffset, IImmutableSet> limitToSourceFiles = null) : - this(new TransformationState(id => id is Identifier.LocalVariable varName && varName.Item.Value == idName.Value, defaultOffset, limitToSourceFiles)) - { } + public IdentifierReferences(NonNullable idName, QsLocation defaultOffset, IImmutableSet> limitToSourceFiles = null) + : this(new TransformationState(id => id is Identifier.LocalVariable varName && varName.Item.Value == idName.Value, defaultOffset, limitToSourceFiles)) { } - public IdentifierReferences(QsQualifiedName idName, QsLocation defaultOffset, IImmutableSet> limitToSourceFiles = null) : - this(new TransformationState(id => id is Identifier.GlobalCallable cName && cName.Item.Equals(idName), defaultOffset, limitToSourceFiles)) + public IdentifierReferences(QsQualifiedName idName, QsLocation defaultOffset, IImmutableSet> limitToSourceFiles = null) + : this(new TransformationState(id => id is Identifier.GlobalCallable cName && cName.Item.Equals(idName), defaultOffset, limitToSourceFiles)) { if (idName == null) throw new ArgumentNullException(nameof(idName)); } @@ -174,7 +174,7 @@ public static IEnumerable Find(NonNullable idName, QsScope sco var finder = new IdentifierReferences(idName, null, ImmutableHashSet.Create(sourceFile)); finder.SharedState.Source = sourceFile; finder.SharedState.DeclarationOffset = rootLoc; // will throw if null - finder.Statements.Transform(scope ?? throw new ArgumentNullException(nameof(scope))); + finder.Statements.OnScope(scope ?? throw new ArgumentNullException(nameof(scope))); return finder.SharedState.Locations; } @@ -182,7 +182,7 @@ public static IEnumerable Find(QsQualifiedName idName, QsNamespace ns, out Tuple, QsLocation> declarationLocation, IImmutableSet> limitToSourceFiles = null) { var finder = new IdentifierReferences(idName, defaultOffset, limitToSourceFiles); - finder.Namespaces.Transform(ns ?? throw new ArgumentNullException(nameof(ns))); + finder.Namespaces.OnNamespace(ns ?? throw new ArgumentNullException(nameof(ns))); declarationLocation = finder.SharedState.DeclarationLocation; return finder.SharedState.Locations; } @@ -190,87 +190,84 @@ public static IEnumerable Find(QsQualifiedName idName, QsNamespace ns, // helper classes - private class TypeTransformation : - TypeTransformation + private class TypeTransformation + : TypeTransformation { - public TypeTransformation(SyntaxTreeTransformation parent) : - base(parent) - { } + public TypeTransformation(SyntaxTreeTransformation parent) + : base(parent, TransformationOptions.NoRebuild) { } - public override QsTypeKind onUserDefinedType(UserDefinedType udt) + public override QsTypeKind OnUserDefinedType(UserDefinedType udt) { var id = Identifier.NewGlobalCallable(new QsQualifiedName(udt.Namespace, udt.Name)); this.SharedState.LogIdentifierLocation(id, udt.Range); return QsTypeKind.NewUserDefinedType(udt); } - public override QsTypeKind onTypeParameter(QsTypeParameter tp) + public override QsTypeKind OnTypeParameter(QsTypeParameter tp) { var resT = ResolvedType.New(QsTypeKind.NewTypeParameter(tp)); - var id = Identifier.NewLocalVariable(NonNullable.New(SyntaxTreeToQs.Default.ToCode(resT) ?? "")); + var id = Identifier.NewLocalVariable(NonNullable.New(SyntaxTreeToQsharp.Default.ToCode(resT) ?? "")); this.SharedState.LogIdentifierLocation(id, tp.Range); return resT.Resolution; } } - private class StatementTransformation : - StatementTransformation + private class StatementTransformation + : StatementTransformation { public StatementTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } - public override QsNullable onLocation(QsNullable loc) + public override QsNullable OnLocation(QsNullable loc) { this.SharedState.CurrentLocation = loc.IsValue ? loc.Item : null; return loc; } } - private class NamespaceTransformation : - NamespaceTransformation + private class NamespaceTransformation + : NamespaceTransformation { public NamespaceTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } - public override QsCustomType onType(QsCustomType t) + public override QsCustomType OnTypeDeclaration(QsCustomType t) { if (!this.SharedState.IsRelevant(t.SourceFile) || t.Location.IsNull) return t; if (this.SharedState.TrackIdentifier(Identifier.NewGlobalCallable(t.FullName))) { this.SharedState.DeclarationLocation = new Tuple, QsLocation>(t.SourceFile, t.Location.Item); } - return base.onType(t); + return base.OnTypeDeclaration(t); } - public override QsCallable onCallableImplementation(QsCallable c) + public override QsCallable OnCallableDeclaration(QsCallable c) { if (!this.SharedState.IsRelevant(c.SourceFile) || c.Location.IsNull) return c; if (this.SharedState.TrackIdentifier(Identifier.NewGlobalCallable(c.FullName))) { this.SharedState.DeclarationLocation = new Tuple, QsLocation>(c.SourceFile, c.Location.Item); } - return base.onCallableImplementation(c); + return base.OnCallableDeclaration(c); } - public override QsDeclarationAttribute onAttribute(QsDeclarationAttribute att) + public override QsDeclarationAttribute OnAttribute(QsDeclarationAttribute att) { var declRoot = this.SharedState.DeclarationOffset; this.SharedState.DeclarationOffset = att.Offset; - if (att.TypeId.IsValue) this.Transformation.Types.onUserDefinedType(att.TypeId.Item); - this.Transformation.Expressions.Transform(att.Argument); + if (att.TypeId.IsValue) this.Transformation.Types.OnUserDefinedType(att.TypeId.Item); + this.Transformation.Expressions.OnTypedExpression(att.Argument); this.SharedState.DeclarationOffset = declRoot; return att; } - public override QsSpecialization onSpecializationImplementation(QsSpecialization spec) => - this.SharedState.IsRelevant(spec.SourceFile) ? base.onSpecializationImplementation(spec) : spec; + public override QsSpecialization OnSpecializationDeclaration(QsSpecialization spec) => + this.SharedState.IsRelevant(spec.SourceFile) ? base.OnSpecializationDeclaration(spec) : spec; - public override QsNullable onLocation(QsNullable loc) + public override QsNullable OnLocation(QsNullable loc) { this.SharedState.DeclarationOffset = loc.IsValue ? loc.Item.Offset : null; return loc; } - public override NonNullable onSourceFile(NonNullable source) + public override NonNullable OnSourceFile(NonNullable source) { this.SharedState.Source = source; return source; @@ -287,7 +284,7 @@ public override NonNullable onSourceFile(NonNullable source) /// Note that the location information is relative to the root node, i.e. the start position of the containing specialization declaration. /// public class AccumulateIdentifiers - : SyntaxTreeTransformation + : SyntaxTreeTransformation { public class TransformationState { @@ -298,7 +295,7 @@ public class TransformationState private readonly List<(NonNullable, QsLocation)> UsedLocals = new List<(NonNullable, QsLocation)>(); internal TransformationState() => - this.UpdatedExpression = new TypedExpressionWalker(this.UpdatedLocal, this).Transform; + this.UpdatedExpression = new TypedExpressionWalker(this.UpdatedLocal, this).OnTypedExpression; public ILookup, QsLocation> ReassignedVariables => this.UpdatedLocals.ToLookup(var => var.Item1, var => var.Item2); @@ -322,43 +319,42 @@ private Action Add(List<(NonNullable, QsLocation)> accu } - public AccumulateIdentifiers() : - base(new TransformationState()) + public AccumulateIdentifiers() + : base(new TransformationState(), TransformationOptions.NoRebuild) { - this.Expressions = new TypedExpressionWalker(this.SharedState.UsedLocal, this); - this.StatementKinds = new StatementKindTransformation(this); this.Statements = new StatementTransformation(this); + this.StatementKinds = new StatementKindTransformation(this); + this.Expressions = new TypedExpressionWalker(this.SharedState.UsedLocal, this); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } // helper classes - private class StatementTransformation : - StatementTransformation + private class StatementTransformation + : StatementTransformation { public StatementTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } - public override QsStatement onStatement(QsStatement stm) + public override QsStatement OnStatement(QsStatement stm) { this.SharedState.StatementLocation = stm.Location.IsNull ? null : stm.Location.Item; - this.StatementKinds.Transform(stm.Statement); + this.StatementKinds.OnStatementKind(stm.Statement); return stm; } } - private class StatementKindTransformation : - Core.StatementKindTransformation + private class StatementKindTransformation + : StatementKindTransformation { public StatementKindTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent, TransformationOptions.NoRebuild) { } - public override QsStatementKind onValueUpdate(QsValueUpdate stm) + public override QsStatementKind OnValueUpdate(QsValueUpdate stm) { this.SharedState.UpdatedExpression(stm.Lhs); - this.Expressions.Transform(stm.Rhs); + this.Expressions.OnTypedExpression(stm.Rhs); return QsStatementKind.NewQsValueUpdate(stm); } } @@ -373,7 +369,7 @@ public override QsStatementKind onValueUpdate(QsValueUpdate stm) /// This class is *not* threadsafe. /// public class UniqueVariableNames - : SyntaxTreeTransformation + : SyntaxTreeTransformation { public class TransformationState { @@ -402,46 +398,50 @@ internal NonNullable GenerateUniqueName(NonNullable varName) private const string OrigVarName = "origVarName"; private static readonly Regex WrappedVarName = new Regex($"^__{Prefix}[0-9]*__(?<{OrigVarName}>.*)__$"); - public NonNullable StripUniqueName(NonNullable uniqueName) + public UniqueVariableNames() + : base(new TransformationState()) { - var matched = WrappedVarName.Match(uniqueName.Value).Groups[OrigVarName]; - return matched.Success ? NonNullable.New(matched.Value) : uniqueName; + this.StatementKinds = new StatementKindTransformation(this); + this.ExpressionKinds = new ExpressionKindTransformation(this); + this.Types = new TypeTransformation(this, TransformationOptions.Disabled); } - public UniqueVariableNames() : - base(new TransformationState()) + // static methods for convenience + + internal static QsQualifiedName PrependGuid(QsQualifiedName original) => + new QsQualifiedName(original.Namespace, NonNullable.New("_" + Guid.NewGuid().ToString("N") + "_" + original.Name.Value)); + + public static NonNullable StripUniqueName(NonNullable uniqueName) { - this.ExpressionKinds = new ExpressionKindTransformation(this); - this.StatementKinds = new StatementKindTransformation(this); + var matched = WrappedVarName.Match(uniqueName.Value).Groups[OrigVarName]; + return matched.Success ? NonNullable.New(matched.Value) : uniqueName; } // helper classes private class StatementKindTransformation - : Core.StatementKindTransformation + : StatementKindTransformation { public StatementKindTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } - public override SymbolTuple onSymbolTuple(SymbolTuple syms) => + public override SymbolTuple OnSymbolTuple(SymbolTuple syms) => syms is SymbolTuple.VariableNameTuple tuple - ? SymbolTuple.NewVariableNameTuple(tuple.Item.Select(this.onSymbolTuple).ToImmutableArray()) + ? SymbolTuple.NewVariableNameTuple(tuple.Item.Select(this.OnSymbolTuple).ToImmutableArray()) : syms is SymbolTuple.VariableName varName ? SymbolTuple.NewVariableName(this.SharedState.GenerateUniqueName(varName.Item)) : syms; } private class ExpressionKindTransformation - : Core.ExpressionKindTransformation + : ExpressionKindTransformation { public ExpressionKindTransformation(SyntaxTreeTransformation parent) - : base(parent) - { } + : base(parent) { } - public override QsExpressionKind onIdentifier(Identifier sym, QsNullable> tArgs) => + public override QsExpressionKind OnIdentifier(Identifier sym, QsNullable> tArgs) => this.SharedState.AdaptIdentifier(sym, tArgs); } } @@ -452,23 +452,24 @@ public override QsExpressionKind onIdentifier(Identifier sym, QsNullable /// Upon transformation, applies the specified action to each expression and subexpression. /// The action to apply is specified upon construction, and will be applied before recurring into subexpressions. + /// The transformation merely walks expressions and rebuilding is disabled. /// - public class TypedExpressionWalker : - Core.ExpressionTransformation + public class TypedExpressionWalker + : ExpressionTransformation { public TypedExpressionWalker(Action onExpression, SyntaxTreeTransformation parent) - : base(parent) => + : base(parent, TransformationOptions.NoRebuild) => this.OnExpression = onExpression ?? throw new ArgumentNullException(nameof(onExpression)); public TypedExpressionWalker(Action onExpression, T internalState = default) - : base(internalState) => + : base(internalState, TransformationOptions.NoRebuild) => this.OnExpression = onExpression ?? throw new ArgumentNullException(nameof(onExpression)); public readonly Action OnExpression; - public override TypedExpression Transform(TypedExpression ex) + public override TypedExpression OnTypedExpression(TypedExpression ex) { this.OnExpression(ex); - return base.Transform(ex); + return base.OnTypedExpression(ex); } } }