diff --git a/src/Language/Ruby/Syntax.hs b/src/Language/Ruby/Syntax.hs index e99db7a5f..a47e58060 100644 --- a/src/Language/Ruby/Syntax.hs +++ b/src/Language/Ruby/Syntax.hs @@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds, TemplateHaskell #-} module Language.Ruby.Syntax where -import Control.Monad.Free.Freer hiding (Return) import Data.Functor.Union import qualified Data.Syntax as Syntax import Data.Syntax.Assignment @@ -15,7 +14,7 @@ import Text.Parser.TreeSitter.Language import Text.Parser.TreeSitter.Ruby -- | The type of Ruby syntax. -type Syntax = Union +type Syntax = '[Comment.Comment , Declaration.Class , Declaration.Method @@ -34,7 +33,10 @@ type Syntax = Union -- | A program in some syntax functor, over which we can perform analyses. -type Program = Freer Syntax +type Program = Cofree (Union Syntax) () + +term :: InUnion Syntax f => () -> f Program -> Program +term a f = cofree $ a :< inj f -- | Statically-known rules corresponding to symbols in the grammar. @@ -42,44 +44,44 @@ mkSymbolDatatype (mkName "Grammar") tree_sitter_ruby -- | Assignment from AST in Ruby’s grammar onto a program in Ruby’s syntax. -assignment :: Assignment Grammar [Program (Maybe a)] +assignment :: Assignment Grammar [Program] assignment = rule Program *> children (many declaration) -declaration :: Assignment Grammar (Program (Maybe a)) +declaration :: Assignment Grammar Program declaration = comment <|> class' <|> method -class' :: Assignment Grammar (Program (Maybe a)) -class' = wrapU <$ rule Class - <*> children (Declaration.Class <$> constant <*> pure [] <*> many declaration) +class' :: Assignment Grammar Program +class' = term () <$ rule Class + <*> children (Declaration.Class <$> constant <*> pure [] <*> many declaration) -constant :: Assignment Grammar (Program a) -constant = wrapU . Syntax.Identifier <$ rule Constant <*> content +constant :: Assignment Grammar Program +constant = term () . Syntax.Identifier <$ rule Constant <*> content -identifier :: Assignment Grammar (Program a) -identifier = wrapU . Syntax.Identifier <$ rule Identifier <*> content +identifier :: Assignment Grammar Program +identifier = term () . Syntax.Identifier <$ rule Identifier <*> content -method :: Assignment Grammar (Program (Maybe a)) -method = wrapU <$ rule Method - <*> children (Declaration.Method <$> identifier <*> pure [] <*> (wrapU <$> many statement)) +method :: Assignment Grammar Program +method = term () <$ rule Method + <*> children (Declaration.Method <$> identifier <*> pure [] <*> (term () <$> many statement)) -statement :: Assignment Grammar (Program a) -statement = wrapU . Statement.Return <$ rule Return <*> children (optional expr) - <|> wrapU . Statement.Yield <$ rule Yield <*> children (optional expr) +statement :: Assignment Grammar Program +statement = term () . Statement.Return <$ rule Return <*> children (optional expr) + <|> term () . Statement.Yield <$ rule Yield <*> children (optional expr) <|> expr -comment :: Assignment Grammar (Program a) -comment = wrapU . Comment.Comment <$ rule Comment <*> content +comment :: Assignment Grammar Program +comment = term () . Comment.Comment <$ rule Comment <*> content -if' :: Assignment Grammar (Program a) +if' :: Assignment Grammar Program if' = go If - where go symbol = wrapU <$ rule symbol <*> children (Statement.If <$> statement <*> (wrapU <$> many statement) <*> (go Elsif <|> wrapU <$ rule Else <*> children (many statement))) + where go symbol = term () <$ rule symbol <*> children (Statement.If <$> statement <*> (term () <$> many statement) <*> (go Elsif <|> term () <$ rule Else <*> children (many statement))) -expr :: Assignment Grammar (Program a) +expr :: Assignment Grammar Program expr = if' <|> literal -literal :: Assignment Grammar (Program a) -literal = wrapU Literal.true <$ rule Language.Ruby.Syntax.True <* content - <|> wrapU Literal.false <$ rule Language.Ruby.Syntax.False <* content +literal :: Assignment Grammar Program +literal = term () Literal.true <$ rule Language.Ruby.Syntax.True <* content + <|> term () Literal.false <$ rule Language.Ruby.Syntax.False <* content -optional :: Assignment Grammar (Program a) -> Assignment Grammar (Program a) -optional a = a <|> pure (wrapU []) +optional :: Assignment Grammar Program -> Assignment Grammar Program +optional a = a <|> pure (() `term` [])