diff --git a/src/Language/Ruby/Assignment.hs b/src/Language/Ruby/Assignment.hs index 12bf85714..7e1e18115 100644 --- a/src/Language/Ruby/Assignment.hs +++ b/src/Language/Ruby/Assignment.hs @@ -74,6 +74,7 @@ type Syntax = '[ , Syntax.Identifier , Syntax.Paren , Syntax.Program + , Ruby.Syntax.Send , Ruby.Syntax.Class , Ruby.Syntax.Load , Ruby.Syntax.LowPrecedenceBoolean @@ -83,7 +84,8 @@ type Syntax = '[ ] type Term = Term.Term (Union Syntax) (Record Location) -type Assignment = HasCallStack => Assignment.Assignment [] Grammar Term +type Assignment' a = HasCallStack => Assignment.Assignment [] Grammar a +type Assignment = Assignment' Term -- | Assignment from AST in Ruby’s grammar onto a program in Ruby’s syntax. assignment :: Assignment @@ -291,9 +293,12 @@ pair :: Assignment pair = makeTerm <$> symbol Pair <*> children (Literal.KeyValue <$> expression <*> (expression <|> emptyTerm)) methodCall :: Assignment -methodCall = makeTerm' <$> symbol MethodCall <*> children (require <|> load <|> regularCall) +methodCall = makeTerm' <$> symbol MethodCall <*> children (require <|> load <|> funcCall <|> regularCall) where - regularCall = inj <$> (Expression.Call <$> pure [] <*> expression <*> args <*> (block <|> emptyTerm)) + funcCall = inj <$> (Ruby.Syntax.Send Nothing <$> methodSelector <*> args) -- TODO block + + regularCall = inj <$> (symbol Call *> children (Ruby.Syntax.Send <$> (Just <$> expression) <*> methodSelector) <*> args) -- TODO block + require = inj <$> (symbol Identifier *> do s <- source guard (s `elem` ["require", "require_relative"]) @@ -306,10 +311,13 @@ methodCall = makeTerm' <$> symbol MethodCall <*> children (require <|> load <|> loadArgs = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children (some expression) nameExpression = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children expression -call :: Assignment -call = makeTerm <$> symbol Call <*> children (Expression.MemberAccess <$> expression <*> (expression <|> args)) +methodSelector :: Assignment +methodSelector = mk Identifier <|> mk Identifier' where - args = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children expressions + mk s = makeTerm <$> symbol s <*> (Syntax.Identifier <$> (name <$> source)) + +call :: Assignment +call = makeTerm <$> symbol Call <*> children (Ruby.Syntax.Send <$> (Just <$> expression) <*> methodSelector <*> pure []) rescue :: Assignment rescue = rescue' diff --git a/src/Language/Ruby/Syntax.hs b/src/Language/Ruby/Syntax.hs index f69a1cf74..bf7662989 100644 --- a/src/Language/Ruby/Syntax.hs +++ b/src/Language/Ruby/Syntax.hs @@ -36,6 +36,16 @@ maybeFailNotFound name = maybeFail notFound cleanNameOrPath :: ByteString -> String cleanNameOrPath = BC.unpack . dropRelativePrefix . stripQuotes +data Send a = Send { sendReceiver :: Maybe a, sendSelector :: a, sendArgs :: [a] } + deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable, FreeVariables1) + +instance Eq1 Send where liftEq = genericLiftEq +instance Ord1 Send where liftCompare = genericLiftCompare +instance Show1 Send where liftShowsPrec = genericLiftShowsPrec + +instance Evaluatable Send where + eval (Send _ _ _) = fail "send unimplemented!" + data Require a = Require { requireRelative :: Bool, requirePath :: !a } deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable, FreeVariables1)