Advertisement
Guest User

Untitled

a guest
May 24th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 12.69 KB | None | 0 0
  1. {-# LANGUAGE DuplicateRecordFields      #-}
  2. {-# LANGUAGE FlexibleContexts           #-}
  3. {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  4. {-# LANGUAGE MultiParamTypeClasses      #-}
  5. {-# LANGUAGE OverloadedStrings          #-}
  6. module Interpreter where
  7. -- :set -XOverloadedStrings
  8. import           Control.Monad              (replicateM_, void)
  9. import           Control.Monad.Catch        (Exception, MonadCatch, MonadThrow, catch, throwM)
  10. import           Control.Monad.Cont         (callCC)
  11. import           Control.Monad.Reader       (MonadReader, asks, local, runReaderT)
  12. import           Control.Monad.State        (MonadIO, MonadState, StateT, get,
  13.                                              liftIO, modify, put, runStateT)
  14. import           Data.Functor.Identity
  15. import qualified Data.Map.Strict            as Map
  16. import           Data.Typeable              (Typeable)
  17. import           Data.Void                  (Void)
  18. import           System.IO
  19. import           System.IO.Unsafe
  20.  
  21. import qualified Data.ByteString            as PackedStr
  22. import qualified Data.ByteString.Internal   as BS (c2w)
  23. import qualified Data.ByteString.UTF8       as S8
  24. -- import Data.ByteString.Char8
  25. -- import  Prelude (elem, Show, IO, String, Int, empty, show)
  26.  
  27. import           Text.Megaparsec
  28. import           Text.Megaparsec.Byte       (alphaNumChar, char, eol, letterChar, string)
  29. import qualified Text.Megaparsec.Byte.Lexer as L
  30. import           Text.Megaparsec.Expr
  31.  
  32.  
  33. data Expression = Const Int
  34.     | Var String
  35.     | BoolVal Bool
  36.     | Add {a :: Expression, b :: Expression}
  37.     | Sub {a :: Expression, b :: Expression}
  38.     | Mul {a :: Expression, b :: Expression}
  39.     | Div {a :: Expression, b :: Expression}
  40.     | Eq {a :: Expression, b :: Expression}
  41.     | NEq {a :: Expression, b :: Expression}
  42.     | Lt {a :: Expression, b :: Expression}
  43.     | Gt {a :: Expression, b :: Expression}
  44.     | LtEq {a :: Expression, b :: Expression}
  45.     | GtEq {a :: Expression, b :: Expression}
  46.     | Let String Expression Expression deriving (Show, Read, Eq)
  47. --     | Let Expr Var
  48.  
  49. data ExpressionException = DivisionByZero | UndefinedVariable String deriving (Show, Read, Eq, Typeable)
  50. instance Exception ExpressionException
  51.  
  52. type ExpressionMap = Map.Map String Int
  53.  
  54. evalBool :: (MonadReader ExpressionMap t, MonadThrow t) => Expression -> t Bool
  55. evalBool expr = case expr of
  56.     (BoolVal e1_ ) -> return e1_
  57.     (Eq a_ b_) -> do
  58.         l_ <- eval a_
  59.         r_ <- eval b_
  60.         return $ l_ == r_
  61.     (NEq a_ b_) -> do
  62.         l_ <- eval a_
  63.         r_ <- eval b_
  64.         return $ l_ /= r_
  65.     (Lt a_ b_) -> do
  66.         l_ <- eval a_
  67.         r_ <- eval b_
  68.         return $ l_ < r_
  69.     (Gt a_ b_) -> do
  70.         l_ <- eval a_
  71.         r_ <- eval b_
  72.         return $ l_ > r_
  73.     (GtEq a_ b_) -> do
  74.         l_ <- eval a_
  75.         r_ <- eval b_
  76.         return $ l_ >= r_
  77.     (LtEq a_ b_) -> do
  78.         l_ <- eval a_
  79.         r_ <- eval b_
  80.         return $ l_ <= r_
  81.  
  82. eval :: (MonadReader ExpressionMap t, MonadThrow t) => Expression -> t Int
  83. eval expr = case expr of
  84.     (Const c) -> return c
  85.     (Var x) -> asks (Map.lookup x) >>= maybe (throwM (UndefinedVariable x)) return
  86.     (Add x y) ->  do
  87.         a1 <- eval x
  88.         b1 <- eval y
  89.         return $ a1 + b1
  90.     (Sub x y) -> do
  91.         a1 <- eval x
  92.         b1 <- eval y
  93.         return $ a1 - b1
  94.     (Mul x y) -> do
  95.         a1 <- eval x
  96.         b1 <- eval y
  97.         return $ a1 * b1
  98.     (Div x y) -> do
  99.         a1 <- eval x
  100.         b1 <- eval y
  101.         case b1 of
  102.             0 -> throwM DivisionByZero
  103.             _ -> return $ a1 `div` b1
  104.     (Let name value expr_) ->
  105.         eval value >>= \val_ -> local (Map.insert name val_) (eval expr_)
  106.  
  107.  
  108.  
  109. runEval :: (MonadThrow t) => Expression -> ExpressionMap -> t Int
  110. runEval expr = runReaderT (eval expr)
  111.  
  112. runEvalBool :: (MonadThrow t) => Expression -> ExpressionMap -> t Bool
  113. runEvalBool expr = runReaderT (evalBool expr)
  114.  
  115. data Statement =
  116.     Assignment  {var :: String, val :: Expression}
  117.     | Reassignment  {var :: String, val :: Expression}
  118.     | InState  {var :: String}
  119.     | OutState  {val :: Expression}
  120.     | IfState {cond :: Expression, e1 :: [Statement], e2 :: [Statement]}
  121.     | Break {var :: String}
  122.     | ForLoop  {val    :: Expression, to_ :: Expression, body  :: [Statement]}
  123.     deriving (Read, Show, Eq, Typeable)
  124.  
  125.  
  126. data StatementException =
  127.     ValReassignmentException String
  128.     | ComputationException Statement ExpressionException
  129.     | UndefinedVariableException String
  130.     deriving ( Show, Eq, Typeable)
  131.  
  132.  
  133. instance Exception StatementException
  134. type MutableContext = StateT ExpressionMap (Either StatementException)
  135.  
  136. assign :: (MonadState ExpressionMap t, MonadCatch t) => String -> Int -> t ()
  137. assign variable value = do
  138.     map_ <- get
  139.     case Map.lookup variable map_ of
  140.         Nothing -> put $ Map.insert variable value map_
  141.         Just _  -> throwM (ValReassignmentException variable)
  142.  
  143. reassign :: (MonadState ExpressionMap t, MonadCatch t) => String -> Int -> t ()
  144. reassign variable value = do
  145.     map_ <- get
  146.     case Map.lookup variable map_ of
  147.         Just _  -> put $ Map.insert variable value map_
  148.         Nothing -> throwM (UndefinedVariableException variable)
  149.  
  150. overwrite :: (MonadState ExpressionMap t, MonadCatch t) => String -> Int -> t ()
  151. overwrite variable value = modify $ Map.insert variable value
  152.  
  153. evaluateExpression :: MonadCatch t => Statement -> Expression -> ExpressionMap -> t Int
  154. evaluateExpression stmt expr varz = catch (runEval expr varz) (\e -> throwM $ ComputationException stmt e)
  155.  
  156. evaluateExpressionBool :: MonadCatch t => Statement -> Expression -> ExpressionMap -> t Bool
  157. evaluateExpressionBool stmt expr varz = catch (runEvalBool expr varz) (\e -> throwM $ ComputationException stmt e)
  158.  
  159. evaluateStatement :: (MonadState ExpressionMap t, MonadCatch t, MonadIO t) => [Statement] -> t ExpressionMap
  160. evaluateStatement statements = {-callCC $ \exit -> do-}
  161.     case statements of
  162.         [] -> get
  163.         (x:xs) -> do
  164.             let t = Assignment {var = "x", val = Const 1}
  165.             vars <- get
  166.             value <-
  167.                 case x of
  168.                     InState _  -> read <$> liftIO getLine
  169.                     IfState {} -> evaluateExpression t (val t) vars
  170.                     _          -> evaluateExpression x (val x) vars
  171.             cond <- case x of
  172.                     IfState c _ _ -> evaluateExpressionBool x c vars
  173.                     _             -> return True
  174.             case x of
  175. --                 (Break _) ->  exit "m"
  176.                 (IfState _ l r)  ->
  177.                         replicateM_ 1 (if cond then evaluateStatement l else evaluateStatement r)
  178.                 (Assignment v _)   -> assign v value
  179.                 (Reassignment v _) -> reassign v value
  180.                 (InState v)        -> overwrite v value
  181.                 (OutState _)       -> liftIO $ print value
  182.                 (ForLoop _ to_ stmts) -> do
  183.                             to <- evaluateExpression x to_ vars
  184.                             replicateM_ (to - value) (evaluateStatement stmts)
  185.             evaluateStatement xs
  186.  
  187.  
  188. newtype StatementContext t = StatementContext {runStmt :: StateT ExpressionMap IO t}
  189.     deriving (Functor, Applicative, Monad, MonadIO, MonadState ExpressionMap, MonadThrow, MonadCatch)
  190.  
  191. executeProgram :: StatementContext t -> IO t
  192. executeProgram ctx = fst <$> runStateT (runStmt ctx) Map.empty
  193. runStatement :: [Statement] -> IO ExpressionMap
  194. runStatement = executeProgram . evaluateStatement
  195. runStatement_ :: [Statement] -> IO ()
  196. runStatement_ = void . executeProgram . evaluateStatement
  197.  
  198.  
  199. type Parser = Parsec Void S8.ByteString
  200.  
  201. newtype ParseException = ParseException (ParseError (Token S8.ByteString) Void)
  202.     deriving (Read, Show, Eq, Typeable)
  203.  
  204. instance Exception ParseException
  205.  
  206. space :: Parser ()
  207. space = skipSome (char (BS.c2w ' '))
  208.  
  209. indent :: Parser ()
  210. indent = skipMany (char (BS.c2w ' '))
  211.  
  212. spaceConsumer :: Parser ()
  213. spaceConsumer = L.space space empty empty
  214.  
  215. lexeme :: Parser a -> Parser a
  216. lexeme = L.lexeme spaceConsumer
  217.  
  218. symbol :: S8.ByteString -> Parser S8.ByteString
  219. symbol = L.symbol spaceConsumer
  220.  
  221. lParenthesis :: Parser S8.ByteString
  222. lParenthesis = symbol "("
  223. rParenthesis :: Parser S8.ByteString
  224. rParenthesis = symbol ")"
  225. parenthesis :: Parser a -> Parser a
  226. parenthesis = between lParenthesis rParenthesis
  227. parenthesis_ :: Parser a -> Parser a
  228. parenthesis_ = between (symbol "{") (symbol "}")
  229.  
  230. eqParser :: Parser S8.ByteString
  231. eqParser = symbol "="
  232.  
  233. intParser :: Parser Int
  234. intParser = lexeme L.decimal
  235.  
  236. skipWord :: S8.ByteString -> Parser ()
  237. skipWord w = lexeme (string w *> notFollowedBy alphaNumChar)
  238.  
  239.  
  240. pack :: ParsecT Void S8.ByteString Data.Functor.Identity.Identity S8.ByteString
  241. pack = PackedStr.pack <$> ((:) <$> letterChar <*> many alphaNumChar)
  242.  
  243. keywordsList :: [S8.ByteString]
  244. keywordsList = ["let", "mut", "for", "break", "true", "false", "in", "if", "then", "else"]
  245.  
  246. checkKeyWord :: Monad t => S8.ByteString -> t S8.ByteString
  247. checkKeyWord w = if w `elem` keywordsList
  248.                 then fail $ "KeyWord !! - " ++ show w
  249.                 else return w
  250.  
  251. identifierParser :: Parser S8.ByteString
  252. identifierParser = (lexeme . try) $
  253.     do
  254.     w <- pack
  255.     checkKeyWord w
  256.  
  257. boolList :: [S8.ByteString]
  258. boolList = ["true", "false"]
  259.  
  260. boolParser :: Parser Bool
  261. boolParser = (lexeme . try) $ do
  262.                             c <- pack
  263.                             if c `elem` boolList
  264.                                 then return $ c == "true"
  265.                                 else fail $ "should be bool" ++ show c
  266.  
  267. identifierToStrParserSafe :: ParsecT Void S8.ByteString Data.Functor.Identity.Identity String
  268. identifierToStrParserSafe = S8.toString <$> identifierParser
  269.  
  270. operators :: [[Operator Parser Expression]]
  271. operators =
  272.         [   [ InfixL (Eq <$ symbol "==")
  273.             , InfixL (NEq <$ symbol "!=")
  274.             , InfixL (GtEq <$ symbol ">=")
  275.             , InfixL (LtEq <$ symbol "<=")
  276.             , InfixL (Gt <$ symbol ">")
  277.             , InfixL (Lt <$ symbol "<")
  278.             ]
  279.         ,
  280.             [ InfixL (Mul <$ symbol "*")
  281.             , InfixL (Div <$ symbol "/")
  282.             ]
  283.         ,   [ InfixL (Add <$ symbol "+")
  284.             , InfixL (Sub <$ symbol "-")
  285.             ]
  286.         ]
  287.  
  288. termParser :: Parser Expression
  289. termParser =  indent *> (parenthesis expressionParser
  290.     <|> Const <$> intParser
  291.     <|> Var <$> identifierToStrParserSafe
  292.     <|> BoolVal <$> boolParser
  293.     <|> Let
  294.             <$> (skipWord "let" *> identifierToStrParserSafe <* eqParser)
  295.             <*> (expressionParser <* symbol "in")
  296.             <*> expressionParser)
  297.  
  298. expressionParser :: Parser Expression
  299. expressionParser = makeExprParser termParser operators
  300.  
  301.  
  302.  
  303. statementParser :: Parser Statement
  304. statementParser = indent *> (
  305.           Assignment
  306.                   <$> (skipWord "mut" *> identifierToStrParserSafe <* eqParser)
  307.                   <*> expressionParser
  308.           <|> OutState <$> (symbol "<" *> expressionParser)
  309.           <|> InState <$> (symbol ">" *> identifierToStrParserSafe)
  310.           <|> Break <$> (S8.toString <$> symbol "break")
  311.           <|> ForLoop
  312.                   <$> (skipWord "for" *> expressionParser)
  313.                   <*> (skipWord "to" *> expressionParser )
  314.                   <*> parenthesis_ programParser
  315.           <|> IfState
  316.                   <$> (skipWord "if" *> expressionParser)
  317.                   <*> (skipWord "then" *> parenthesis_ programParser)
  318.                   <*> (skipWord "else" *> parenthesis_ programParser)
  319.           <|> Reassignment
  320.                   <$> (identifierToStrParserSafe <* eqParser)
  321.                   <*> expressionParser
  322.         ) <* indent
  323.  
  324.  
  325. parseExpressions :: MonadThrow t => S8.ByteString -> t Expression
  326. parseExpressions  inp = either (throwM . ParseException) return $ parse expressionParser "" inp
  327. parseWithExpressionEvaluation :: MonadThrow t => S8.ByteString -> t Int
  328. parseWithExpressionEvaluation input = parseExpressions input >>= flip runEval Map.empty
  329. parseStatement :: MonadThrow t => S8.ByteString -> t Statement
  330. parseStatement inp =  either (throwM . ParseException) return $ parse statementParser "" inp
  331. parseWithStatementEvaluation :: (MonadIO t, MonadCatch t) => S8.ByteString -> t ExpressionMap
  332. parseWithStatementEvaluation input = parseStatement input >>= \stmt -> fst <$> runStateT (evaluateStatement [stmt]) Map.empty
  333. programParser :: Parser [Statement]
  334. programParser = spaceConsumer *> many (statementParser <* eol)
  335. runProgram_ :: String -> S8.ByteString -> IO ExpressionMap
  336. runProgram_ name input = either (throwM . ParseException) return (parse programParser name input) >>= runStatement
  337.  
  338.  
  339. --
  340. runProgram name file = do
  341.     text <- PackedStr.readFile $ file
  342.     runProgram_ name text
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement