diff --git a/src/QsCompiler/Tests.Compiler/SyntaxTests.fs b/src/QsCompiler/Tests.Compiler/SyntaxTests.fs index 85894fe784..12429f1787 100644 --- a/src/QsCompiler/Tests.Compiler/SyntaxTests.fs +++ b/src/QsCompiler/Tests.Compiler/SyntaxTests.fs @@ -385,37 +385,149 @@ let ``Complex literal tests`` () = [] let ``Call tests`` () = [ - ("x()", true, toExpr (CallLikeExpression (toIdentifier "x", UnitValue |> toExpr)), []); - ("x(1,2)", true, toExpr (CallLikeExpression (toIdentifier "x", - toTuple [ toInt 1; - toInt 2])), []); - ("Adjoint x()", true, toExpr (CallLikeExpression (AdjointApplication (toIdentifier "x") |> toExpr, - UnitValue |> toExpr)), []); - ("Controlled x()", true, toExpr (CallLikeExpression (ControlledApplication (toIdentifier "x") |> toExpr, - UnitValue |> toExpr)), []); - - ("(x(_,1))(2)", true, toExpr (CallLikeExpression (toTuple [toExpr (CallLikeExpression (toIdentifier "x", - toTuple [ MissingExpr |> toExpr; - toInt 1]) - )], toTuple [ toInt 2 ])), []); - ("(x(_,1))(1,2)", true, toExpr (CallLikeExpression (toTuple [toExpr (CallLikeExpression (toIdentifier "x", - toTuple [ MissingExpr |> toExpr; - toInt 1]) - )], toTuple [ toInt 1; - toInt 2 ])), []); - ("(x(1,(2, _)))(2)", true, toExpr (CallLikeExpression (toTuple [toExpr (CallLikeExpression (toIdentifier "x", - toTuple [ toInt 1; - toTuple [ toInt 2; - MissingExpr |> toExpr]; - ]) - )], toTuple [ toInt 2 ])), []); - ("(x(_,(2, _)))(1,2)", true, toExpr (CallLikeExpression (toTuple [toExpr (CallLikeExpression (toIdentifier "x", - toTuple [ MissingExpr |> toExpr; - toTuple [ toInt 2; - MissingExpr |> toExpr]; - ]) - )], toTuple [ toInt 1; - toInt 2 ])), []); + "x()", true, CallLikeExpression (toIdentifier "x", toExpr UnitValue) |> toExpr, [] + "x(1,2)", true, CallLikeExpression (toIdentifier "x", toTuple [ toInt 1; toInt 2 ]) |> toExpr, [] + "Adjoint x()", + true, + CallLikeExpression (toIdentifier "x" |> AdjointApplication |> toExpr, toExpr UnitValue) |> toExpr, + [] + "Controlled x()", + true, + CallLikeExpression (toIdentifier "x" |> ControlledApplication |> toExpr, toExpr UnitValue) |> toExpr, + [] + "f(1)(2)", + true, + (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "f(1)(2)(3)", + true, + ((CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + toTuple [ toInt 3 ]) + |> CallLikeExpression + |> toExpr, + [] + "f(1)(2)[3]", + true, + (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "(f(1)(2))[3]", + true, + ([ (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr ] + |> toTuple, + toInt 3) + |> ArrayItem + |> toExpr, + [] + "(f(1)(2))[3](4)", + true, + ([ (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr ] + |> toTuple, + toInt 3) + |> ArrayItem + |> toExpr + |> (fun left -> CallLikeExpression (left, toTuple [ toInt 4 ]) |> toExpr), + [] + "f(1)(2)::X", + true, + (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "(f(1)(2))::X", + true, + ([ (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr ] + |> toTuple, + toSymbol "X") + |> NamedItem + |> toExpr, + [] + "(f(1)(2))::X(4)", + true, + ([ (CallLikeExpression (toIdentifier "f", toTuple [ toInt 1 ]) |> toExpr, toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr ] + |> toTuple, + toSymbol "X") + |> NamedItem + |> toExpr + |> (fun left -> CallLikeExpression (left, toTuple [ toInt 4 ]) |> toExpr), + [] + "(x(_,1))(2)", + true, + (toTuple [ CallLikeExpression (toIdentifier "x", toTuple [ toExpr MissingExpr; toInt 1 ]) |> toExpr ], + toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "x(_,1)(2)", + true, + (CallLikeExpression (toIdentifier "x", toTuple [ toExpr MissingExpr; toInt 1 ]) |> toExpr, + toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "(x(_,1))(1,2)", + true, + (toTuple [ CallLikeExpression (toIdentifier "x", toTuple [ toExpr MissingExpr; toInt 1 ]) |> toExpr ], + toTuple [ toInt 1; toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "x(_,1)(1,2)", + true, + (CallLikeExpression (toIdentifier "x", toTuple [ toExpr MissingExpr; toInt 1 ]) |> toExpr, + toTuple [ toInt 1; toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "(x(1,(2, _)))(2)", + true, + ([ CallLikeExpression (toIdentifier "x", toTuple [ toInt 1; toTuple [ toInt 2; toExpr MissingExpr ] ]) + |> toExpr ] + |> toTuple, + toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "x(1,(2, _))(2)", + true, + (CallLikeExpression (toIdentifier "x", toTuple [ toInt 1; toTuple [ toInt 2; toExpr MissingExpr ] ]) + |> toExpr, + toTuple [ toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "(x(_,(2, _)))(1,2)", + true, + ([ (toIdentifier "x", toTuple [ toExpr MissingExpr; toTuple [ toInt 2; toExpr MissingExpr ] ]) + |> CallLikeExpression + |> toExpr ] + |> toTuple, + toTuple [ toInt 1; toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] + "x(_,(2, _))(1,2)", + true, + ((toIdentifier "x", toTuple [ toExpr MissingExpr; toTuple [ toInt 2; toExpr MissingExpr ] ]) + |> CallLikeExpression + |> toExpr, + toTuple [ toInt 1; toInt 2 ]) + |> CallLikeExpression + |> toExpr, + [] ] |> List.iter testExpr diff --git a/src/QsCompiler/TextProcessor/QsExpressionParsing.fs b/src/QsCompiler/TextProcessor/QsExpressionParsing.fs index 5ff61f310f..7e08a4ac74 100644 --- a/src/QsCompiler/TextProcessor/QsExpressionParsing.fs +++ b/src/QsCompiler/TextProcessor/QsExpressionParsing.fs @@ -383,10 +383,11 @@ let private argumentTuple = /// Expects tuple brackets around the argument even if the argument consists of a single tuple item. /// Note that this parser has a dependency on the arrayItemExpr, identifier, and tupleItem expr parsers - /// meaning they process the left-most part of the call-like expression and thus need to be evaluated *after* the callLikeExpr parser. -let internal callLikeExpr = - attempt ((itemAccessExpr <|> identifier <|> tupledItem expr) .>>. argumentTuple) // identifier needs to come *after* arrayItemExpr - |>> fun (callable, arg) -> applyBinary CallLikeExpression () callable arg - +let internal callLikeExpr = + // identifier needs to come *after* arrayItemExpr + itemAccessExpr <|> identifier <|> tupledItem expr .>>. many1 argumentTuple + |>> List.Cons + |>> List.reduce (applyBinary CallLikeExpression ()) // processing terms of operator precedence parsers diff --git a/src/QsCompiler/TextProcessor/QsKeywords.fs b/src/QsCompiler/TextProcessor/QsKeywords.fs index a8c33c839f..d84d4066cd 100644 --- a/src/QsCompiler/TextProcessor/QsKeywords.fs +++ b/src/QsCompiler/TextProcessor/QsKeywords.fs @@ -284,7 +284,7 @@ let qsSetIntersection = QsOperator.New("*" , 20, true) // The call combinator binds stronger than all operators. // All modifiers bind stronger than the call combinator. // The array item combinator binds stronger than all modifiers. -let qsCallCombinator = QsOperator.New("(", ")" , 900 , false) // Op()() is invalid and requires parentheses +let qsCallCombinator = QsOperator.New("(", ")" , 900 , true) // Op()() is fine let qsAdjointModifier = QsOperator.New(qsAdjointFunctor.id , 950 , false) let qsControlledModifier = QsOperator.New(qsControlledFunctor.id , 951 , false) let qsUnwrapModifier = QsOperator.New("!" , 1000, true)