Skip to content

Commit 65cfe4d

Browse files
author
Jonas Betzendahl
committed
allow loading and parsing of source files
1 parent f14fbdf commit 65cfe4d

File tree

5 files changed

+55
-27
lines changed

5 files changed

+55
-27
lines changed

goedelT.cabal

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ executable goedelT
2222
-- other-extensions:
2323
build-depends: base >=4.8,
2424
attoparsec >=0.13,
25-
bytestring >=0.10
25+
bytestring >=0.10,
26+
directory >=1.2.6
2627
hs-source-dirs: src
2728
default-language: Haskell2010

src/Evaluator.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module Evaluator where
1+
module Evaluator (eval, replace) where
22

33
import Types
44

src/Main.hs

+24-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
module Main where
22

3-
import Data.List (deleteBy, find, intersect, nub, permutations, union)
3+
import Data.List (deleteBy, find, foldl', intercalate, intersect, nub, permutations, union)
4+
45
import System.IO
6+
import System.Directory (doesFileExist, makeAbsolute)
57

68
import Types
7-
import Typechecker
8-
import Evaluator
9+
import Typechecker (typecheck)
10+
import Evaluator (eval, replace)
911
import Parser
1012

1113
-- Entry point of program
@@ -23,9 +25,6 @@ repl ts = do
2325
inp <- getLine
2426
case parseInput inp of
2527
Quit -> pure ()
26-
Run -> case find (\(a,_) -> a == "main") ts of
27-
(Just (a,e)) -> print (eval e) >> repl ts
28-
Nothing -> putStrLn "~> No expression \"main\" currently in context." >> repl ts
2928
Context -> case ts of
3029
[] -> putStrLn "~> Context currently empty!" >> repl ts
3130
_ -> do putStrLn "\n~> Current Context:"
@@ -44,7 +43,7 @@ repl ts = do
4443
":clear Clear current context\n"] >> repl ts
4544
(Expr e) -> case typecheck ts e of
4645
(Left r) -> putStrLn ("Error: Typecheck failed!\n" ++ r) >> repl ts
47-
(Right _) -> let f = foldl (\k (n,s) -> (replace (make_disjoint k s) (Placeholder n)) k)
46+
(Right _) -> let f = foldl' (\k (n,s) -> (replace (make_disjoint k s) (Placeholder n)) k)
4847
d (x:y:zs) = if x == y then x else d (y:zs)
4948
o = d $ iterate ((flip f) ts) e
5049
in (print (eval o)) >> repl ts
@@ -59,12 +58,26 @@ repl ts = do
5958
(Right tau) -> putStrLn $ "This expression has type " ++ show tau
6059
repl ts
6160
Clear -> putStrLn "~> Context cleared!" >> repl []
62-
(Load fl) -> do inh <- readFile fl
63-
case parseFile inh of
64-
(Left err) -> putStrLn err >> repl ts
65-
(Right con) -> putStrLn "~> File loaded!" >> repl (ts ++ con)
61+
(Load fl) -> do afl <- makeAbsolute fl
62+
ex <- doesFileExist afl
63+
if ex then do inh <- readFile afl
64+
case parseFile inh of
65+
(Left err) -> putStrLn err >> repl ts
66+
(Right res) -> do let (foo,bar) = foldl' embed ([],[]) res
67+
case bar of
68+
[] -> pure ()
69+
xs -> do putStrLn "~> The following expressions had incorrect types:"
70+
putStrLn (" " ++ (intercalate ", " xs))
71+
putStrLn "~> File loaded!"
72+
repl (ts ++ foo)
73+
else putStrLn "~> That file does not exist!" >> repl ts
6674
NoParse -> putStrLn "~> Error: Could not parse input!" >> repl ts
6775

76+
embed :: (Context, [String]) -> (String, Exp, Typ) -> (Context, [String])
77+
embed (con,fs) (nm, ex, tp) = case typecheck con ex of
78+
(Left _) -> (con, fs ++ [nm])
79+
(Right sg) -> if sg == tp then (con ++ [(nm, ex)],fs) else (con, fs ++ [nm])
80+
6881
-- Returns a version of the second expression, that has no shared
6982
-- variables with the first expression. This is to avoid capture.
7083
make_disjoint :: Exp -> Exp -> Exp

src/Parser.hs

+27-12
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,19 @@ parseInput str = case ((parseOnly inputParser) . pack) str of
1616
(Left e) -> NoParse
1717
where
1818
inputParser :: Parser Input
19-
inputParser = ((string ":quit") >> pure Quit)
19+
inputParser = ((string ":q") >> pure Quit)
20+
<|> ((string ":quit") >> pure Quit)
2021
<|> ((string ":context") >> pure Context)
2122
<|> ((string ":clear") >> pure Clear)
2223
<|> ((string ":help") >> pure Help)
23-
<|> ((string ":run") >> pure Run)
2424
<|> letParser
2525
<|> typecheckParser
2626
<|> evalParser
27+
<|> loadParser
2728

2829
loadParser :: Parser Input
2930
loadParser = do string ":load "
30-
filepth <- manyTill letter_ascii endOfLine
31+
filepth <- (many1 anyChar)
3132
pure $ Load filepth
3233

3334
letParser :: Parser Input
@@ -96,8 +97,8 @@ typParser = pNat <|> pVoid <|> pUnit <|> pBool <|> pOption <|> pSum <|> pProduct
9697
sigma <- typParser ; char ')' ; pure $ Sum tau sigma
9798

9899
expParser :: Parser Exp
99-
expParser = pBools <|> pIf <|> pEmpty <|> pFull <|> pWhich <|> pTuple <|> pProject <|>
100-
pVoid <|> pSum <|> pCase <|> pAp <|> pLambda <|> pRec <|> pZ <|> pSucc
100+
expParser = pBools <|> pIf <|> pEmpty <|> pFull <|> pWhich <|> pTuple <|> pProject <|>
101+
pVoid <|> pSum <|> pCase <|> pAp <|> pLambda <|> pRec <|> pZ <|> pSucc
101102
<|> pVar <|> pPlaceholder
102103
where
103104
pPlaceholder :: Parser Exp
@@ -214,12 +215,26 @@ expParser = pBools <|> pIf <|> pEmpty <|> pFull <|> pWhich <|> pTuple <|> pProj
214215
-- File Parsing --
215216
------------------
216217

217-
parseFile :: String -> Either String Context
218-
parseFile = undefined
219-
220-
fileParser :: Parser Context
221-
fileParser = many1 defParser
218+
parseFile :: String -> Either String [(String, Exp, Typ)]
219+
parseFile = (parseOnly fileParser) . pack . init . clearLines
222220
where
223-
defParser :: Parser (String, Exp)
224-
defParser = undefined
221+
commentOrEmpty :: String -> Bool
222+
commentOrEmpty [] = True
223+
commentOrEmpty (x:_) = x == '#'
224+
225+
clearLines :: String -> String
226+
clearLines = unlines . (filter (not . commentOrEmpty)) . lines
227+
228+
fileParser :: Parser [(String, Exp, Typ)]
229+
fileParser = many1 (defParser <* endOfLine)
230+
231+
defParser :: Parser (String, Exp, Typ)
232+
defParser = do nm <- manyTill anyChar space
233+
string ": "
234+
tau <- typParser
235+
endOfLine
236+
string (pack nm)
237+
string " = "
238+
e <- expParser
239+
pure $ (nm, e, tau)
225240

src/Types.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ data Exp = Placeholder String -- Placeholder
4848
deriving (Eq, Ord)
4949

5050
-- Inputs expected on REPL
51-
data Input = Run
52-
| Quit
51+
data Input = Quit
5352
| Help
5453
| Context
5554
| Clear

0 commit comments

Comments
 (0)