mirror of
https://github.com/github/semantic.git
synced 2024-11-28 10:15:55 +03:00
Use Statement exclusively for imperative semantics
This commit is contained in:
parent
40ea6d0767
commit
7e2c8eed3a
@ -34,8 +34,6 @@ import Data.Abstract.Name as X
|
||||
import Data.Abstract.Package as Package
|
||||
import Data.Abstract.Ref as X
|
||||
import Data.Scientific (Scientific)
|
||||
import Data.Semigroup.App
|
||||
import Data.Semigroup.Foldable
|
||||
import Data.Semigroup.Reducer hiding (unit)
|
||||
import Data.Semilattice.Lower
|
||||
import Data.Sum
|
||||
@ -217,11 +215,6 @@ instance Apply Evaluatable fs => Evaluatable (Sum fs) where
|
||||
instance Evaluatable s => Evaluatable (TermF s a) where
|
||||
eval = eval . termFOut
|
||||
|
||||
-- | '[]' is treated as an imperative sequence of statements/declarations s.t.:
|
||||
--
|
||||
-- 1. Each statement’s effects on the store are accumulated;
|
||||
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
|
||||
-- 3. Only the last statement’s return value is returned.
|
||||
-- | '[]' uses the default eval. Use Data.Syntax.Statements if you need an imperative sequence.
|
||||
instance Evaluatable [] where
|
||||
-- 'nonEmpty' and 'foldMap1' enable us to return the last statement’s result instead of 'unit' for non-empty lists.
|
||||
eval = maybe (pure (Rval unit)) (runApp . foldMap1 (App . subtermRef)) . nonEmpty
|
||||
eval _ = throwResumable (Unspecialized ("Eval unspecialized for []"))
|
||||
|
@ -30,12 +30,6 @@ makeTerm a = makeTerm' a . inject
|
||||
makeTerm' :: (HasCallStack, Semigroup a, Foldable f) => a -> f (Term f a) -> Term f a
|
||||
makeTerm' a f = termIn (sconcat (a :| (termAnnotation <$> toList f))) f
|
||||
|
||||
-- | Lift syntax and an annotation into a term, injecting the syntax into a union & ensuring the annotation encompasses all children. Removes extra structure if term is a list of a single item.
|
||||
makeTerm'' :: (HasCallStack, f :< fs, Semigroup a, Apply Foldable fs, Foldable f) => a -> f (Term (Sum fs) a) -> Term (Sum fs) a
|
||||
makeTerm'' a children = case toList children of
|
||||
[x] -> x
|
||||
_ -> makeTerm' a (inject children)
|
||||
|
||||
-- | Lift non-empty syntax into a term, injecting the syntax into a union & appending all subterms’.annotations to make the new term’s annotation.
|
||||
makeTerm1 :: (HasCallStack, f :< fs, Semigroup a, Apply Foldable fs) => f (Term (Sum fs) a) -> Term (Sum fs) a
|
||||
makeTerm1 = makeTerm1' . inject
|
||||
@ -46,11 +40,26 @@ makeTerm1' f = case toList f of
|
||||
a : _ -> makeTerm' (termAnnotation a) f
|
||||
_ -> error "makeTerm1': empty structure"
|
||||
|
||||
-- FIXME: I think this might be an anti-pattern.
|
||||
-- | Lift syntax and an annotation into a term, injecting the syntax into a union & ensuring the annotation encompasses all children. Removes extra structure if term is a list of a single item.
|
||||
makeStatementTerm :: (HasCallStack, f :< fs, Statements :< fs, Semigroup a, Apply Foldable fs, Foldable f) => a -> f (Term (Sum fs) a) -> Term (Sum fs) a
|
||||
makeStatementTerm a children = case toList children of
|
||||
[x] -> x
|
||||
xs -> makeTerm' a (inject (Statements xs))
|
||||
|
||||
-- | Construct an empty term at the current position.
|
||||
emptyTerm :: (HasCallStack, Empty :< fs, Apply Foldable fs) => Assignment.Assignment ast grammar (Term (Sum fs) (Record Location))
|
||||
emptyTerm = makeTerm . startLocation <$> Assignment.location <*> pure Empty
|
||||
where startLocation ann = Range (start (getField ann)) (start (getField ann)) :. Span (spanStart (getField ann)) (spanStart (getField ann)) :. Nil
|
||||
|
||||
-- | Construct zero or more Statements.
|
||||
manyStatements :: (Enum grammar, Eq1 ast, Ix grammar, Show grammar) => Assignment.Assignment ast grammar (Term f a) -> Assignment.Assignment ast grammar (Statements (Term f a))
|
||||
manyStatements expr = Exts.fromList <$> (many expr)
|
||||
|
||||
-- | Construct an empty list of Statements.
|
||||
emptyStatements :: Assignment.Assignment ast grammar (Statements (Term f a))
|
||||
emptyStatements = pure (Exts.fromList [])
|
||||
|
||||
-- | Catch assignment errors into an error term.
|
||||
handleError :: (HasCallStack, Error :< fs, Enum grammar, Eq1 ast, Ix grammar, Show grammar, Apply Foldable fs) => Assignment.Assignment ast grammar (Term (Sum fs) (Record Location)) -> Assignment.Assignment ast grammar (Term (Sum fs) (Record Location))
|
||||
handleError = flip catchError (\ err -> makeTerm <$> Assignment.location <*> pure (errorSyntax (either id show <$> err) []) <* Assignment.source)
|
||||
@ -132,6 +141,10 @@ instance Evaluatable Program where
|
||||
eval (Program statements) = eval statements
|
||||
|
||||
-- | Imperative sequence of statements/declarations
|
||||
--
|
||||
-- 1. Each statement’s effects on the store are accumulated;
|
||||
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
|
||||
-- 3. Only the last statement’s return value is returned.
|
||||
newtype Statements a = Statements [a]
|
||||
deriving (Diffable, Eq, Foldable, Functor, Generic1, Hashable1, Mergeable, Ord, Show, Traversable, FreeVariables1, Declarations1, ToJSONFields1)
|
||||
|
||||
@ -140,6 +153,11 @@ instance Ord1 Statements where liftCompare = genericLiftCompare
|
||||
instance Show1 Statements where liftShowsPrec = genericLiftShowsPrec
|
||||
instance ToJSON1 Statements
|
||||
|
||||
-- | Imperative sequence of statements is evaluated s.t:
|
||||
--
|
||||
-- 1. Each statement’s effects on the store are accumulated;
|
||||
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
|
||||
-- 3. Only the last statement’s return value is returned.
|
||||
instance Evaluatable Statements where
|
||||
eval (Statements xs) = maybe (pure (Rval unit)) (runApp . foldMap1 (App . subtermRef)) (nonEmpty xs)
|
||||
|
||||
@ -148,6 +166,7 @@ instance Exts.IsList (Statements a) where
|
||||
fromList = Statements
|
||||
toList (Statements xs) = xs
|
||||
|
||||
|
||||
-- | An accessibility modifier, e.g. private, public, protected, etc.
|
||||
newtype AccessibilityModifier a = AccessibilityModifier ByteString
|
||||
deriving (Diffable, Eq, Foldable, Functor, Generic1, Hashable1, Mergeable, Ord, Show, Traversable, FreeVariables1, Declarations1, ToJSONFields1)
|
||||
|
@ -9,7 +9,7 @@ module Language.Go.Assignment
|
||||
import Assigning.Assignment hiding (Assignment, Error)
|
||||
import Data.Abstract.Name (name)
|
||||
import Data.Record
|
||||
import Data.Syntax (contextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1)
|
||||
import Data.Syntax (contextualize, emptyStatements, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, parseError)
|
||||
import Language.Go.Grammar as Grammar
|
||||
import Language.Go.Syntax as Go.Syntax
|
||||
import Language.Go.Type as Go.Type
|
||||
@ -209,10 +209,10 @@ types =
|
||||
]
|
||||
|
||||
identifiers :: Assignment
|
||||
identifiers = makeTerm'' <$> location <*> manyTerm identifier
|
||||
identifiers = makeStatementTerm <$> location <*> manyTerm identifier
|
||||
|
||||
expressions :: Assignment
|
||||
expressions = makeTerm'' <$> location <*> manyTerm expression
|
||||
expressions = makeStatementTerm <$> location <*> manyTerm expression
|
||||
|
||||
|
||||
-- Literals
|
||||
@ -384,7 +384,7 @@ functionDeclaration = makeTerm <$> (symbol FunctionDeclaration <|> symbol FuncL
|
||||
returnParameters = makeTerm <$> symbol ParameterList <*> children (manyTerm expression)
|
||||
|
||||
importDeclaration :: Assignment
|
||||
importDeclaration = makeTerm'' <$> symbol ImportDeclaration <*> children (manyTerm (importSpec <|> importSpecList))
|
||||
importDeclaration = makeStatementTerm <$> symbol ImportDeclaration <*> children (manyTerm (importSpec <|> importSpecList))
|
||||
where
|
||||
-- `import . "lib/Math"`
|
||||
dotImport = inject <$> (flip Go.Syntax.Import <$> dot <*> importFromPath)
|
||||
@ -401,7 +401,7 @@ importDeclaration = makeTerm'' <$> symbol ImportDeclaration <*> children (manyTe
|
||||
dot = makeTerm <$> symbol Dot <*> (Literal.TextElement <$> source)
|
||||
underscore = makeTerm <$> symbol BlankIdentifier <*> (Literal.TextElement <$> source)
|
||||
importSpec = makeTerm' <$> symbol ImportSpec <*> children (sideEffectImport <|> dotImport <|> namedImport <|> plainImport)
|
||||
importSpecList = makeTerm <$> symbol ImportSpecList <*> children (manyTerm (importSpec <|> comment))
|
||||
importSpecList = makeTerm <$> symbol ImportSpecList <*> children (manyStatements (importSpec <|> comment))
|
||||
importFromPath = symbol InterpretedStringLiteral *> (importPath <$> source)
|
||||
|
||||
indexExpression :: Assignment
|
||||
@ -609,9 +609,6 @@ manyTerm = many . term
|
||||
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyStatements expr = fromList <$> (manyTerm expr)
|
||||
|
||||
emptyStatements :: Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
emptyStatements = pure (fromList [])
|
||||
|
||||
-- | Match a term and contextualize any comments preceeding or proceeding the term.
|
||||
term :: Assignment -> Assignment
|
||||
term term' = contextualize comment term' <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm)
|
||||
|
@ -9,7 +9,7 @@ module Language.Haskell.Assignment
|
||||
import Assigning.Assignment hiding (Assignment, Error)
|
||||
import Data.Record
|
||||
import Data.Sum
|
||||
import Data.Syntax (emptyTerm, handleError, parseError, makeTerm, makeTerm'', contextualize, postContextualize)
|
||||
import Data.Syntax (emptyTerm, handleError, parseError, makeTerm, contextualize, postContextualize)
|
||||
import Language.Haskell.Grammar as Grammar
|
||||
import qualified Assigning.Assignment as Assignment
|
||||
import qualified Data.Abstract.Name as Name
|
||||
@ -48,7 +48,7 @@ module' = makeTerm
|
||||
|
||||
|
||||
expressions :: Assignment
|
||||
expressions = makeTerm'' <$> location <*> many expression
|
||||
expressions = makeTerm <$> location <*> many expression
|
||||
|
||||
expression :: Assignment
|
||||
expression = term (handleError (choice expressionChoices))
|
||||
|
@ -117,6 +117,7 @@ type Syntax = '[
|
||||
, Syntax.ScalarType
|
||||
, Syntax.ShellCommand
|
||||
, Syntax.SimpleVariable
|
||||
, Syntax.Statements
|
||||
, Syntax.Static
|
||||
, Syntax.Text
|
||||
, Syntax.TraitDeclaration
|
||||
@ -390,12 +391,12 @@ scalarType :: Assignment
|
||||
scalarType = makeTerm <$> symbol ScalarType <*> (Syntax.ScalarType <$> source)
|
||||
|
||||
compoundStatement :: Assignment
|
||||
compoundStatement = makeTerm <$> symbol CompoundStatement <*> children (manyTerm statement)
|
||||
compoundStatement = makeTerm <$> symbol CompoundStatement <*> children (manyStatements statement)
|
||||
|
||||
objectCreationExpression :: Assignment
|
||||
objectCreationExpression = (makeTerm <$> symbol ObjectCreationExpression <*> children (Expression.New <$> ((:) <$> term classTypeDesignator <*> (arguments <|> pure []))))
|
||||
|
||||
<|> (makeTerm <$> symbol ObjectCreationExpression <*> children (makeAnonClass <$ token AnonNew <* token AnonClass <*> emptyTerm <*> (arguments <|> pure []) <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyTerm classMemberDeclaration)))
|
||||
<|> (makeTerm <$> symbol ObjectCreationExpression <*> children (makeAnonClass <$ token AnonNew <* token AnonClass <*> emptyTerm <*> (arguments <|> pure []) <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyStatements classMemberDeclaration)))
|
||||
where makeAnonClass identifier args baseClause interfaceClause declarations = Declaration.Class [] identifier (args <> [baseClause, interfaceClause]) declarations
|
||||
|
||||
classMemberDeclaration :: Assignment
|
||||
@ -602,7 +603,7 @@ functionDefinition = makeTerm <$> symbol FunctionDefinition <*> children (makeFu
|
||||
makeFunction identifier parameters returnType statement = Declaration.Function [returnType] identifier parameters statement
|
||||
|
||||
classDeclaration :: Assignment
|
||||
classDeclaration = makeTerm <$> symbol ClassDeclaration <*> children (makeClass <$> (term classModifier <|> emptyTerm) <*> term name <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyTerm classMemberDeclaration))
|
||||
classDeclaration = makeTerm <$> symbol ClassDeclaration <*> children (makeClass <$> (term classModifier <|> emptyTerm) <*> term name <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyStatements classMemberDeclaration))
|
||||
where
|
||||
makeClass modifier name baseClause interfaceClause declarations = Declaration.Class [modifier] name [baseClause, interfaceClause] declarations
|
||||
|
||||
@ -734,7 +735,7 @@ functionStaticDeclaration :: Assignment
|
||||
functionStaticDeclaration = makeTerm <$> symbol FunctionStaticDeclaration <*> children (Declaration.VariableDeclaration <$> manyTerm staticVariableDeclaration)
|
||||
|
||||
staticVariableDeclaration :: Assignment
|
||||
staticVariableDeclaration = makeTerm <$> symbol StaticVariableDeclaration <*> children (Statement.Assignment <$> pure [] <*> term variableName <*> (term expression <|> emptyTerm))
|
||||
staticVariableDeclaration = makeTerm <$> symbol StaticVariableDeclaration <*> children (Statement.Assignment [] <$> term variableName <*> (term expression <|> emptyTerm))
|
||||
|
||||
comment :: Assignment
|
||||
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
|
||||
@ -767,6 +768,9 @@ someTerm = fmap NonEmpty.toList . someTerm'
|
||||
someTerm' :: Assignment -> Assignment.Assignment [] Grammar (NonEmpty Term)
|
||||
someTerm' = NonEmpty.some1 . commentedTerm
|
||||
|
||||
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyStatements expr = fromList <$> (manyTerm expr)
|
||||
|
||||
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
|
||||
infixTerm :: Assignment
|
||||
-> Assignment
|
||||
|
@ -10,7 +10,7 @@ module Language.Python.Assignment
|
||||
import Assigning.Assignment hiding (Assignment, Error)
|
||||
import Data.Abstract.Name (name)
|
||||
import Data.Record
|
||||
import Data.Syntax (contextualize, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1, parseError, postContextualize)
|
||||
import Data.Syntax (contextualize, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, parseError, postContextualize)
|
||||
import GHC.Stack
|
||||
import Language.Python.Grammar as Grammar
|
||||
import Language.Python.Syntax as Python.Syntax
|
||||
@ -82,6 +82,7 @@ type Syntax =
|
||||
, Syntax.Error
|
||||
, Syntax.Identifier
|
||||
, Syntax.Program
|
||||
, Syntax.Statements
|
||||
, Type.Annotation
|
||||
, []
|
||||
]
|
||||
@ -91,7 +92,7 @@ type Assignment = HasCallStack => Assignment.Assignment [] Grammar Term
|
||||
|
||||
-- | Assignment from AST in Python's grammar onto a program in Python's syntax.
|
||||
assignment :: Assignment
|
||||
assignment = handleError $ makeTerm <$> symbol Module <*> children (Syntax.Program <$> manyStatements expression) <|> parseError
|
||||
assignment = handleError $ makeTerm <$> symbol Module <*> children (Syntax.Program . fromList <$> manyTerm expression) <|> parseError
|
||||
|
||||
expression :: Assignment
|
||||
expression = handleError (choice expressionChoices)
|
||||
@ -163,14 +164,15 @@ expressionChoices =
|
||||
, yield
|
||||
]
|
||||
|
||||
|
||||
expressions :: Assignment
|
||||
expressions = makeTerm'' <$> location <*> manyTerm expression
|
||||
expressions = makeStatementTerm <$> location <*> manyTerm expression
|
||||
|
||||
expressionStatement :: Assignment
|
||||
expressionStatement = makeTerm'' <$> symbol ExpressionStatement <*> children (someTerm expression)
|
||||
expressionStatement = makeStatementTerm <$> symbol ExpressionStatement <*> children (someTerm expression)
|
||||
|
||||
expressionList :: Assignment
|
||||
expressionList = makeTerm'' <$> symbol ExpressionList <*> children (someTerm expression)
|
||||
expressionList = makeStatementTerm <$> symbol ExpressionList <*> children (someTerm expression)
|
||||
|
||||
listSplat :: Assignment
|
||||
listSplat = makeTerm <$> symbol ListSplat <*> (Syntax.Identifier . name <$> source)
|
||||
@ -241,7 +243,7 @@ functionDefinition =
|
||||
makeFunctionDeclaration loc (functionName', functionParameters, ty, functionBody) = makeTerm loc $ Type.Annotation (makeTerm loc $ Declaration.Function [] functionName' functionParameters functionBody) (fromMaybe (makeTerm loc Syntax.Empty) ty)
|
||||
|
||||
classDefinition :: Assignment
|
||||
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class <$> pure [] <*> term expression <*> argumentList <*> expressions)
|
||||
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class [] <$> term expression <*> argumentList <*> expressions)
|
||||
where argumentList = symbol ArgumentList *> children (manyTerm expression)
|
||||
<|> pure []
|
||||
|
||||
@ -360,7 +362,7 @@ comment :: Assignment
|
||||
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
|
||||
|
||||
import' :: Assignment
|
||||
import' = makeTerm'' <$> symbol ImportStatement <*> children (manyTerm (aliasedImport <|> plainImport))
|
||||
import' = makeStatementTerm <$> symbol ImportStatement <*> children (manyTerm (aliasedImport <|> plainImport))
|
||||
<|> makeTerm <$> symbol ImportFromStatement <*> children (Python.Syntax.Import <$> importPath <*> (wildcard <|> some (aliasImportSymbol <|> importSymbol)))
|
||||
where
|
||||
-- `import a as b`
|
||||
@ -385,7 +387,7 @@ import' = makeTerm'' <$> symbol ImportStatement <*> children (manyTerm (aliase
|
||||
makeNameAliasPair from Nothing = (from, from)
|
||||
|
||||
assertStatement :: Assignment
|
||||
assertStatement = makeTerm <$> symbol AssertStatement <*> children (Expression.Call <$> pure [] <*> (makeTerm <$> symbol AnonAssert <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
assertStatement = makeTerm <$> symbol AssertStatement <*> children (Expression.Call [] <$> (makeTerm <$> symbol AnonAssert <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
|
||||
printStatement :: Assignment
|
||||
printStatement = do
|
||||
@ -399,19 +401,19 @@ printStatement = do
|
||||
printCallTerm location identifier = makeTerm location <$> (Expression.Call [] identifier <$> manyTerm expression <*> emptyTerm)
|
||||
|
||||
nonlocalStatement :: Assignment
|
||||
nonlocalStatement = makeTerm <$> symbol NonlocalStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonNonlocal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
nonlocalStatement = makeTerm <$> symbol NonlocalStatement <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonNonlocal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
|
||||
globalStatement :: Assignment
|
||||
globalStatement = makeTerm <$> symbol GlobalStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonGlobal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
globalStatement = makeTerm <$> symbol GlobalStatement <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonGlobal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
|
||||
await :: Assignment
|
||||
await = makeTerm <$> symbol Await <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonAwait <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
await = makeTerm <$> symbol Await <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonAwait <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
|
||||
|
||||
returnStatement :: Assignment
|
||||
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> term (expressionList <|> emptyTerm))
|
||||
|
||||
deleteStatement :: Assignment
|
||||
deleteStatement = makeTerm <$> symbol DeleteStatement <*> children (Expression.Call <$> pure [] <*> term deleteIdentifier <* symbol ExpressionList <*> children (manyTerm expression) <*> emptyTerm)
|
||||
deleteStatement = makeTerm <$> symbol DeleteStatement <*> children (Expression.Call [] <$> term deleteIdentifier <* symbol ExpressionList <*> children (manyTerm expression) <*> emptyTerm)
|
||||
where deleteIdentifier = makeTerm <$> symbol AnonDel <*> (Syntax.Identifier . name <$> source)
|
||||
|
||||
raiseStatement :: Assignment
|
||||
@ -423,7 +425,7 @@ ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> ter
|
||||
makeElif (loc, makeIf) rest = makeTerm loc (makeIf rest)
|
||||
|
||||
execStatement :: Assignment
|
||||
execStatement = makeTerm <$> symbol ExecStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> location <*> (Syntax.Identifier . name <$> source)) <*> manyTerm (string <|> expression) <*> emptyTerm)
|
||||
execStatement = makeTerm <$> symbol ExecStatement <*> children (Expression.Call [] <$> term (makeTerm <$> location <*> (Syntax.Identifier . name <$> source)) <*> manyTerm (string <|> expression) <*> emptyTerm)
|
||||
|
||||
passStatement :: Assignment
|
||||
passStatement = makeTerm <$> symbol PassStatement <*> (Statement.NoOp <$> emptyTerm <* advance)
|
||||
@ -447,7 +449,7 @@ slice = makeTerm <$> symbol Slice <*> children
|
||||
<*> (term expression <|> emptyTerm))
|
||||
|
||||
call :: Assignment
|
||||
call = makeTerm <$> symbol Call <*> children (Expression.Call <$> pure [] <*> term (identifier <|> expression) <*> (symbol ArgumentList *> children (manyTerm expression) <|> someTerm comprehension) <*> emptyTerm)
|
||||
call = makeTerm <$> symbol Call <*> children (Expression.Call [] <$> term (identifier <|> expression) <*> (symbol ArgumentList *> children (manyTerm expression) <|> someTerm comprehension) <*> emptyTerm)
|
||||
|
||||
boolean :: Assignment
|
||||
boolean = makeTerm <$> token Grammar.True <*> pure Literal.true
|
||||
@ -476,6 +478,7 @@ conditionalExpression = makeTerm <$> symbol ConditionalExpression <*> children (
|
||||
|
||||
|
||||
-- Helpers
|
||||
|
||||
-- | Match a term optionally preceded by comment(s), or a sequence of comments if the term is not present.
|
||||
manyTerm :: Assignment -> Assignment.Assignment [] Grammar [Term]
|
||||
manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm))
|
||||
@ -486,7 +489,6 @@ someTerm term = some (contextualize comment term <|> makeTerm1 <$> (Syntax.Conte
|
||||
term :: Assignment -> Assignment
|
||||
term term = contextualize comment (postContextualize comment term)
|
||||
|
||||
|
||||
-- | Match a left-associated infix chain of terms, optionally followed by comments. Like 'chainl1' but assigning comment nodes automatically.
|
||||
chainl1Term :: Assignment -> Assignment.Assignment [] Grammar (Term -> Term -> Term) -> Assignment
|
||||
chainl1Term expr op = postContextualize (comment <|> symbol AnonLambda *> empty) expr `chainl1` op
|
||||
@ -495,9 +497,6 @@ chainl1Term expr op = postContextualize (comment <|> symbol AnonLambda *> empty)
|
||||
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
|
||||
manyTermsTill step end = manyTill (step <|> comment) end
|
||||
|
||||
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyStatements expr = fromList <$> (manyTerm expr)
|
||||
|
||||
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
|
||||
infixTerm :: HasCallStack
|
||||
=> Assignment
|
||||
|
@ -10,7 +10,19 @@ import Assigning.Assignment hiding (Assignment, Error)
|
||||
import Data.Abstract.Name (name)
|
||||
import Data.List (elem)
|
||||
import Data.Record
|
||||
import Data.Syntax (contextualize, postContextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1)
|
||||
import Data.Syntax
|
||||
( contextualize
|
||||
, emptyTerm
|
||||
, handleError
|
||||
, infixContext
|
||||
, makeTerm
|
||||
, makeTerm'
|
||||
, makeTerm1
|
||||
, makeStatementTerm
|
||||
, manyStatements
|
||||
, parseError
|
||||
, postContextualize
|
||||
)
|
||||
import Language.Ruby.Grammar as Grammar
|
||||
import qualified Assigning.Assignment as Assignment
|
||||
import Data.Sum
|
||||
@ -146,10 +158,10 @@ expressionChoices =
|
||||
mk s construct = makeTerm <$> symbol s <*> children ((construct .) . fromMaybe <$> emptyTerm <*> optional (symbol ArgumentList *> children expressions))
|
||||
|
||||
expressions :: Assignment
|
||||
expressions = makeTerm'' <$> location <*> many expression
|
||||
expressions = makeStatementTerm <$> location <*> many expression
|
||||
|
||||
parenthesizedExpressions :: Assignment
|
||||
parenthesizedExpressions = makeTerm'' <$> symbol ParenthesizedStatements <*> children (many expression)
|
||||
parenthesizedExpressions = makeTerm <$> symbol ParenthesizedStatements <*> children (manyStatements expression)
|
||||
|
||||
withExtendedScope :: Assignment' a -> Assignment' a
|
||||
withExtendedScope inner = do
|
||||
@ -262,9 +274,8 @@ parameter = postContextualize comment (term uncontextualizedParameter)
|
||||
optionalParameter = symbol OptionalParameter *> children (lhsIdent <* expression)
|
||||
|
||||
method :: Assignment
|
||||
method = makeTerm <$> symbol Method <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> emptyTerm <*> methodSelector <*> params <*> expressions')
|
||||
method = makeTerm <$> symbol Method <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> emptyTerm <*> methodSelector <*> params <*> expressions)
|
||||
where params = symbol MethodParameters *> children (many parameter) <|> pure []
|
||||
expressions' = makeTerm <$> location <*> many expression
|
||||
|
||||
singletonMethod :: Assignment
|
||||
singletonMethod = makeTerm <$> symbol SingletonMethod <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> expression <*> methodSelector <*> params <*> expressions)
|
||||
@ -493,11 +504,8 @@ term term = contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> som
|
||||
where heredocEnd = makeTerm <$> symbol HeredocEnd <*> (Literal.TextElement <$> source)
|
||||
|
||||
-- | Match a series of terms or comments until a delimiter is matched.
|
||||
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
|
||||
manyTermsTill step end = manyTill (step <|> comment) end
|
||||
|
||||
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyStatements expr = fromList <$> (many expr)
|
||||
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyTermsTill step end = fromList <$> manyTill (step <|> comment) end
|
||||
|
||||
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
|
||||
infixTerm :: HasCallStack
|
||||
|
@ -11,7 +11,7 @@ import Data.Abstract.Name (name)
|
||||
import qualified Assigning.Assignment as Assignment
|
||||
import Data.Record
|
||||
import Data.Sum
|
||||
import Data.Syntax (emptyTerm, handleError, parseError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1, contextualize, postContextualize)
|
||||
import Data.Syntax (emptyTerm, emptyStatements, handleError, parseError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, contextualize, postContextualize)
|
||||
import qualified Data.Syntax as Syntax
|
||||
import qualified Data.Syntax.Comment as Comment
|
||||
import qualified Data.Syntax.Declaration as Declaration
|
||||
@ -558,10 +558,10 @@ constructorTy :: Assignment
|
||||
constructorTy = makeTerm <$> symbol ConstructorType <*> children (TypeScript.Syntax.Constructor <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> term ty)
|
||||
|
||||
statementBlock :: Assignment
|
||||
statementBlock = makeTerm <$> symbol StatementBlock <*> children (manyTerm statement)
|
||||
statementBlock = makeTerm <$> symbol StatementBlock <*> children (manyStatements statement)
|
||||
|
||||
classBodyStatements :: Assignment
|
||||
classBodyStatements = makeTerm'' <$> symbol ClassBody <*> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
|
||||
classBodyStatements = makeStatementTerm <$> symbol ClassBody <*> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
|
||||
where
|
||||
contextualize' (cs, formalParams) = case nonEmpty cs of
|
||||
Just cs -> toList cs ++ formalParams
|
||||
@ -863,9 +863,6 @@ manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Conte
|
||||
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
manyStatements expr = fromList <$> (manyTerm expr)
|
||||
|
||||
emptyStatements :: Assignment.Assignment [] Grammar (Syntax.Statements Term)
|
||||
emptyStatements = pure (fromList [])
|
||||
|
||||
term :: Assignment -> Assignment
|
||||
term term = contextualize comment (postContextualize comment term)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user