-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathParseInput.hs
More file actions
88 lines (70 loc) · 2.27 KB
/
ParseInput.hs
File metadata and controls
88 lines (70 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module ParseInput
( lambdaInteract
)
where
import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char
import qualified Text.Megaparsec.Char.Lexer as L
import Types
import Lambda
import Control.Monad.Trans.State.Strict
as TSS
import Control.Monad.Reader
type Parser = Parsec Void String
lambdaInteract :: String -> IO [String]
lambdaInteract input = case parseLambdaExpr input of
Left _ -> pure [ "Parse error, please check if you're missing $-signs." ]
Right expr ->
(\(t, m) ->
reverse
. map (\temp -> "=> " ++ runReader (showTerm m temp) Nothing)
. (\(normalForm, s) -> (:) normalForm . safeTail . init $ s)
$ runState (eval t) [t]
)
<$> runRename expr
--prettyPrint :: String -> IO String
--prettyPrint input = case parseLambdaExpr input of
-- Left err -> pure $ "Parse error at offset: " ++ show
-- (pstateOffset $ bundlePosState err)
-- Right expr -> (\(t, m) -> showTerm m t) <$> runRename expr
safeTail :: [a] -> [a]
safeTail [] = []
safeTail (_ : xs) = xs
sc :: Parser ()
sc = L.space space1 lineCmnt blockCmnt
where
lineCmnt = L.skipLineComment "//"
blockCmnt = L.skipBlockComment "/*" "*/"
lexeme :: Parser a -> Parser a
lexeme = L.lexeme sc
symbol :: String -> Parser String
symbol = L.symbol sc
parens :: Parser a -> Parser a
parens = between (symbol "(") (symbol ")")
integer :: Parser Integer
integer = lexeme L.decimal
identifier :: Parser String
identifier = (lexeme . try) p
where p = (:) <$> letterChar <*> many alphaNumChar
number :: Parser Term
number = Num <$> integer
variable :: Parser Term
variable = Var <$> identifier
lambda :: Parser Term
lambda = do
_ <- symbol "/"
x <- identifier
_ <- symbol "."
t <- try term <|> parens term
pure $ Lam x t
application :: Parser Term
application = do
_ <- symbol "$"
t1 <- try term <|> parens term
t2 <- try term <|> parens term
pure $ App t1 t2
term :: Parser Term
term = try number <|> try variable <|> lambda <|> application
parseLambdaExpr :: String -> Either (ParseErrorBundle String Void) Term
parseLambdaExpr = parse term ""