From 611b0f32764ea97bafca24b05bf6fb17dd12302a Mon Sep 17 00:00:00 2001 From: Patrick Thomson Date: Fri, 6 Apr 2018 11:43:48 -0400 Subject: [PATCH] Remember parentheses in syntax trees. Adding this wasn't particularly hard. Just need to ensure we don't throw the tokens from the parser away. To test, evaluate `5 * (2 / 3)` versus `5 * 2 / 3`. --- src/Data/Syntax.hs | 11 +++++++++++ src/Language/Go/Assignment.hs | 3 ++- src/Language/PHP/Assignment.hs | 3 ++- src/Language/Python/Assignment.hs | 3 ++- src/Language/TypeScript/Assignment.hs | 3 ++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Data/Syntax.hs b/src/Data/Syntax.hs index 6415e8ca7..5fe5f5de6 100644 --- a/src/Data/Syntax.hs +++ b/src/Data/Syntax.hs @@ -146,6 +146,17 @@ instance Show1 Empty where liftShowsPrec _ _ _ _ = showString "Empty" instance Evaluatable Empty where eval _ = unit +-- | A parenthesized expression or statement. All the languages we target support this concept. + +newtype Paren a = Paren a + deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable, FreeVariables1) + +instance Eq1 Paren where liftEq = genericLiftEq +instance Ord1 Paren where liftCompare = genericLiftCompare +instance Show1 Paren where liftShowsPrec = genericLiftShowsPrec + +instance Evaluatable Paren where + eval (Paren a) = subtermValue a -- | Syntax representing a parsing or assignment error. data Error a = Error { errorCallStack :: ErrorStack, errorExpected :: [String], errorActual :: Maybe String, errorChildren :: [a] } diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index 64dc0814c..032b34cc3 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -89,6 +89,7 @@ type Syntax = , Syntax.Error , Syntax.Empty , Syntax.Identifier + , Syntax.Paren , Syntax.Program , Type.Annotation , Type.Array @@ -428,7 +429,7 @@ parameterDeclaration :: Assignment parameterDeclaration = makeTerm <$> symbol ParameterDeclaration <*> children (manyTerm expression) parenthesizedExpression :: Assignment -parenthesizedExpression = symbol ParenthesizedExpression *> children expressions +parenthesizedExpression = makeTerm <$> symbol ParenthesizedExpression <*> (Syntax.Paren <$> children expressions) selectorExpression :: Assignment selectorExpression = makeTerm <$> symbol SelectorExpression <*> children (Expression.MemberAccess <$> expression <*> expression) diff --git a/src/Language/PHP/Assignment.hs b/src/Language/PHP/Assignment.hs index 4285a6ea0..ebf967c0e 100644 --- a/src/Language/PHP/Assignment.hs +++ b/src/Language/PHP/Assignment.hs @@ -103,6 +103,7 @@ type Syntax = '[ , Syntax.NamespaceUseDeclaration , Syntax.NamespaceUseGroupClause , Syntax.NewVariable + , Syntax.Paren , Syntax.PrintIntrinsic , Syntax.Program , Syntax.PropertyDeclaration @@ -287,7 +288,7 @@ primaryExpression = choice [ ] parenthesizedExpression :: Assignment -parenthesizedExpression = symbol ParenthesizedExpression *> children (term expression) +parenthesizedExpression = makeTerm <$> symbol ParenthesizedExpression <*> (Syntax.Paren <$> children (term expression)) classConstantAccessExpression :: Assignment classConstantAccessExpression = makeTerm <$> symbol ClassConstantAccessExpression <*> children (Expression.MemberAccess <$> term scopeResolutionQualifier <*> term name) diff --git a/src/Language/Python/Assignment.hs b/src/Language/Python/Assignment.hs index ff84207ab..c19df20f3 100644 --- a/src/Language/Python/Assignment.hs +++ b/src/Language/Python/Assignment.hs @@ -79,6 +79,7 @@ type Syntax = , Syntax.Empty , Syntax.Error , Syntax.Identifier + , Syntax.Paren , Syntax.Program , Type.Annotation , [] @@ -190,7 +191,7 @@ keywordArgument :: Assignment keywordArgument = makeTerm <$> symbol KeywordArgument <*> children (Statement.Assignment [] <$> term expression <*> term expression) parenthesizedExpression :: Assignment -parenthesizedExpression = symbol ParenthesizedExpression *> children expressions +parenthesizedExpression = makeTerm <$> symbol ParenthesizedExpression <*> (Syntax.Paren <$> children expressions) parameter :: Assignment parameter = makeTerm <$> symbol DefaultParameter <*> children (Statement.Assignment [] <$> term expression <*> term expression) diff --git a/src/Language/TypeScript/Assignment.hs b/src/Language/TypeScript/Assignment.hs index 28467fc7f..174a4d76c 100644 --- a/src/Language/TypeScript/Assignment.hs +++ b/src/Language/TypeScript/Assignment.hs @@ -86,6 +86,7 @@ type Syntax = '[ , Syntax.Empty , Syntax.Error , Syntax.Identifier + , Syntax.Paren , Syntax.Program , Syntax.Context , Type.Readonly @@ -783,7 +784,7 @@ variableDeclarator = makeVarDecl <$> symbol VariableDeclarator <*> children ((,, where makeVarDecl loc (subject, annotations, value) = makeTerm loc (Statement.Assignment [annotations] subject value) parenthesizedExpression :: Assignment -parenthesizedExpression = symbol ParenthesizedExpression *> children (term expressions) +parenthesizedExpression = makeTerm <$> symbol ParenthesizedExpression <*> (Syntax.Paren <$> children (term expressions)) switchStatement :: Assignment switchStatement = makeTerm <$> symbol SwitchStatement <*> children (Statement.Match <$> term parenthesizedExpression <*> term switchBody)