1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 22:31:36 +03:00

Assign into a cofree structure.

This commit is contained in:
Rob Rix 2017-04-19 13:04:07 -04:00
parent 437f240929
commit 6d10209545

View File

@ -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 Rubys grammar onto a program in Rubys 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` [])