module TestImport
( testParseMode
, testPrintMode
, Name(..)
, ValueExpr(..)
-- * Re-exports
, module X
)
where
-- re-exports
import Language.Egison.Syntax.Pattern.Expr
as X
import Language.Egison.Parser.Pattern
as X
( Parsable(..) )
import Language.Egison.Pretty.Pattern
as X
( prettyExpr )
-- main
import Data.Text ( pack )
import Data.Functor ( void )
import Data.Void ( Void )
import Control.Applicative ( (<|>)
, some
)
import Text.Megaparsec ( Parsec )
import qualified Text.Megaparsec as Parsec
( chunk
, single
, parse
)
import qualified Text.Megaparsec.Char as Parsec
( letterChar )
import qualified Text.Megaparsec.Char.Lexer as Parsec
( decimal )
import Language.Egison.Syntax.Pattern.Expr
( Expr(..) )
import Language.Egison.Parser.Pattern ( ParseMode(..)
, ParseFixity(..)
, Fixity(..)
, Precedence(..)
, Associativity(..)
)
import Language.Egison.Pretty.Pattern ( PrintMode(..)
, PrintFixity(..)
)
newtype Name = Name String
deriving (Show, Eq, Ord)
newtype ValueExpr = ValueExprInt Int
deriving newtype Num
deriving stock (Show, Eq)
unParsec :: Parsec Void String a -> (String -> Either String a)
unParsec p input = case Parsec.parse p "test" input of
Left e -> Left (show e)
Right x -> Right x
testFixities :: [Fixity Name]
testFixities =
[ Fixity AssocRight (Precedence 5) (Name "++")
, Fixity AssocRight (Precedence 5) (Name ":")
, Fixity AssocLeft (Precedence 4) (Name "|>")
, Fixity AssocRight (Precedence 4) (Name "<|")
]
toParseFixity :: Fixity Name -> ParseFixity Name String
toParseFixity fixity@(Fixity _ _ (Name name)) = ParseFixity fixity
$ unParsec parser
where parser = void $ Parsec.chunk name
toPrintFixity :: Fixity Name -> PrintFixity Name
toPrintFixity fixity@(Fixity _ _ (Name name)) = PrintFixity fixity $ pack name
testParseName :: Parsec Void String Name
testParseName = withParens <|> name
where
name = Name <$> some Parsec.letterChar
ops = Parsec.chunk "++"
withParens = do
op <- Parsec.single '(' *> ops <* Parsec.single ')'
pure $ Name op
testParseValueExpr :: Parsec Void String ValueExpr
testParseValueExpr = withParens <|> dec
where
dec = ValueExprInt <$> Parsec.decimal
withParens = do
d <- Parsec.chunk "(-" *> dec <* Parsec.single ')'
pure $ negate d
testParseMode :: ParseMode Name Name ValueExpr String
testParseMode = ParseMode { filename = "test"
, fixities = map toParseFixity testFixities
, blockComment = Just ("{-", "-}")
, lineComment = Just "--"
, varNameParser = unParsec testParseName
, nameParser = unParsec testParseName
, valueExprParser = unParsec testParseValueExpr
}
testPrintMode :: PrintMode Name Name ValueExpr
testPrintMode = PrintMode { fixities = map toPrintFixity testFixities
, varNamePrinter = namePrinter
, namePrinter
, valueExprPrinter = valueExprPrinter
, pageMode = Nothing
}
where
namePrinter (Name name) = pack name
valueExprPrinter (ValueExprInt i) = pack $ show i