{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UnboxedTuples #-} module Parsers.Tiny where import Control.Monad (Monad(..)) import Data.Char (Char) import Data.Either (Either(..)) import Data.Function (($)) import Data.Semigroup (Semigroup(..)) import Data.String (String, IsString(..)) import Data.Text (Text) import Data.Text.IO (readFile) import System.IO (IO, FilePath) import Test.Tasty import Test.Tasty.Golden import Text.Show (Show(..)) import qualified Data.ByteString.Lazy as BSL import qualified Data.IORef as IORef import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL import qualified Language.Haskell.TH.Syntax as TH import qualified Symantic.Parser as P import qualified Symantic.Parser.Haskell as H --import Golden.Utils p_Tiny = p_CmdSeq P.<* P.eof -- (!. / %{eof}) p_CmdSeq = P.some (p_Cmd p_SEMICOLON{-^cmdSeq-}) p_Cmd = p_IfCmd <|> p_RepeatCmd / p_ReadCmd / p_WriteCmd / p_AssignCmd -- conditional :: Eq a => [H.Haskell (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b p_Cmd = P.conditional [] [p_IfCmd, p_RepeatCmd, p_ReadCmd, p_WriteCmd, p_AssignCmd] empty ((\c -> haskell c [||c||]) Prelude.<$> ["", ]) (look anyChar) op empty p_IfCmd = p_IF p_Exp^ifExp p_THEN^ifThen p_CmdSeq^ifThenCmdSeq (p_ELSE p_CmdSeq^ifElseCmdSeq / '') p_END^ifEnd p_RepeatCmd = p_REPEAT p_CmdSeq^repeatCmdSeq p_UNTIL^repeatUntil p_Exp^repeatExp p_AssignCmd = p_NAME p_ASSIGNMENT^assignOp p_Exp^assignExp p_ReadCmd = p_READ p_NAME^readName p_WriteCmd = p_WRITE p_Exp^writeExp p_Exp = p_SimpleExp ((p_LESS / p_EQUAL) p_SimpleExp^simpleExp / '') p_SimpleExp = p_Term ((p_ADD / p_SUB) p_Term^term)* p_Term = p_Factor ((p_MUL / p_DIV) p_Factor^factor)* p_Factor = p_OPENPAR p_Exp^openParExp p_CLOSEPAR^closePar / p_NUMBER / p_NAME p_ADD = lex "+" p_ASSIGNMENT = lex ":=" p_CLOSEPAR = lex ")" p_DIV = lex "/" p_IF = lex "if" p_ELSE = lex "else" p_END = lex "end" p_EQUAL = lex "=" p_LESS = lex "<" p_MUL = lex "*" p_NAME = !p_RESERVED lex (some (oneOf ['a' .. 'z'])) p_NUMBER = lex (some (oneOf ['0' .. '9'])) p_OPENPAR = lex "(" p_READ = lex "read" p_REPEAT = lex "repeat" p_SEMICOLON = lex ";" p_SUB = lex "-" p_THEN = lex "then" p_UNTIL = lex "until" p_WRITE = lex "write" p_RESERVED = (p_IF / p_ELSE / p_END / p_READ / p_REPEAT / p_THEN / p_UNTIL / p_WRITE) ![a-z]+ p_Sp = (" " P.<|> "\n")* lex = (p_Sp *>)