1
1
module Main where
2
2
3
- import Data.List (deleteBy , find , intersect , nub , permutations , union )
3
+ import Data.List (deleteBy , find , foldl' , intercalate , intersect , nub , permutations , union )
4
+
4
5
import System.IO
6
+ import System.Directory (doesFileExist , makeAbsolute )
5
7
6
8
import Types
7
- import Typechecker
8
- import Evaluator
9
+ import Typechecker ( typecheck )
10
+ import Evaluator ( eval , replace )
9
11
import Parser
10
12
11
13
-- Entry point of program
@@ -23,9 +25,6 @@ repl ts = do
23
25
inp <- getLine
24
26
case parseInput inp of
25
27
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
29
28
Context -> case ts of
30
29
[] -> putStrLn " ~> Context currently empty!" >> repl ts
31
30
_ -> do putStrLn " \n ~> Current Context:"
@@ -44,7 +43,7 @@ repl ts = do
44
43
" :clear Clear current context\n " ] >> repl ts
45
44
(Expr e) -> case typecheck ts e of
46
45
(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)
48
47
d (x: y: zs) = if x == y then x else d (y: zs)
49
48
o = d $ iterate ((flip f) ts) e
50
49
in (print (eval o)) >> repl ts
@@ -59,12 +58,26 @@ repl ts = do
59
58
(Right tau) -> putStrLn $ " This expression has type " ++ show tau
60
59
repl ts
61
60
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
66
74
NoParse -> putStrLn " ~> Error: Could not parse input!" >> repl ts
67
75
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
+
68
81
-- Returns a version of the second expression, that has no shared
69
82
-- variables with the first expression. This is to avoid capture.
70
83
make_disjoint :: Exp -> Exp -> Exp
0 commit comments