parsing cleaner
[minfp.git] / check.icl
1 implementation module check
2
3 import StdEnv
4
5 import Data.Either
6 import Data.List
7 import Control.Monad
8
9 import ast
10
11 check :: [Function] -> Either [String] Expression
12 check fs
13 # dups = filter (\x->length x > 1) (groupBy (\(Function i _ _) (Function j _ _)->i == j) fs)
14 | length dups > 0 = Left ["Duplicate functions: ":[toString n\\[(Function n _ _):_]<-dups]]
15 = case partition (\a->a=:(Function ['start'] _ _)) fs of
16 ([], _) = Left ["No start function defined"]
17 ([Function _ [] e], fs) = Right (foldr (\(Function i a e)->Let i a e) e fs)
18 ([Function _ _ _], _) = Left ["Start cannot have arguments"]
19
20 //import qualified Data.Map as DM
21 //from Data.Map import instance Functor (Map k)
22 //import qualified Data.Set as DS
23 //import Data.Functor
24 //import Data.Func
25 //import Data.Either
26 //import Data.List
27 //import Data.Maybe
28 //import Control.Applicative
29 //import Control.Monad
30 //import Control.Monad.Trans
31 //import qualified Control.Monad.State as MS
32 //import Control.Monad.State => qualified gets, put, modify
33 //import Control.Monad.RWST => qualified put
34 //
35 //import ast
36 //
37 //check :: AST -> Either [String] (AST, [([Char], Scheme)])
38 //check (AST fs) = pure (AST fs, [])/*case inferAST preamble fs of
39 // Left e = Left e
40 // Right s = Right (AST fs, 'DM'.toList s)
41 //where
42 // preamble = 'DM'.fromList
43 // [(['if'], Forall [['a']] $ TFun TBool $ TFun (TVar ['a']) $ TFun (TVar ['a']) $ TVar ['a'])
44 // ,(['eq'], Forall [] $ TFun TInt $ TFun TInt TBool)
45 // ,(['mul'], Forall [] $ TFun TInt $ TFun TInt TInt)
46 // ,(['div'], Forall [] $ TFun TInt $ TFun TInt TInt)
47 // ,(['add'], Forall [] $ TFun TInt $ TFun TInt TInt)
48 // ,(['sub'], Forall [] $ TFun TInt $ TFun TInt TInt)
49 // ]
50 //*/
51 //
52 //:: TypeEnv :== 'DM'.Map [Char] Scheme
53 //:: Constraint :== (Type, Type)
54 //:: Subst :== 'DM'.Map [Char] Type
55 //:: Unifier :== (Subst, [Constraint])
56 //:: Infer a :== RWST TypeEnv [Constraint] InferState (Either [String]) a
57 //:: InferState = { count :: Int }
58 //:: Scheme = Forall [[Char]] Type
59 //:: Solve a :== StateT Unifier (Either [String]) a
60 //
61 //nullSubst :: Subst
62 //nullSubst = 'DM'.newMap
63 //
64 //uni :: Type Type -> Infer ()
65 //uni t1 t2 = tell [(t1, t2)]
66 //
67 //inEnv :: ([Char], Scheme) (Infer a) -> Infer a
68 //inEnv (x, sc) m = local (\e->'DM'.put x sc $ 'DM'.del x e) m
69 //
70 //letters :: [[Char]]
71 //letters = [1..] >>= flip replicateM ['a'..'z']
72 //
73 //fresh :: Infer Type
74 //fresh = get >>= \s=:{count}->'Control.Monad.RWST'.put {s & count=count + 1} >>| pure (TVar $ letters !! count)
75 //
76 //class Substitutable a
77 //where
78 // apply :: Subst a -> a
79 // ftv :: a -> [[Char]]
80 //
81 //instance Substitutable Type
82 //where
83 // apply s t=:(TVar a) = maybe t id $ 'DM'.get a s
84 // apply s (TFun t1 t2) = TFun (apply s t1) (apply s t2)
85 // apply _ t = t
86 //
87 // ftv (TVar a) = [a]
88 // ftv (TFun t1 t2) = union (ftv t1) (ftv t2)
89 // ftv t = []
90 //
91 //instance Substitutable Scheme
92 //where
93 // apply s (Forall as t) = Forall as $ apply (foldr 'DM'.del s as) t
94 // ftv (Forall as t) = difference (ftv t) as
95 //
96 //instance Substitutable [a] | Substitutable a
97 //where
98 // apply s ls = map (apply s) ls
99 // ftv t = foldr (union o ftv) [] t
100 //
101 //instance Substitutable TypeEnv where
102 // apply s env = fmap (apply s) env
103 // ftv env = ftv $ 'DM'.elems env
104 //
105 //instance Substitutable Constraint where
106 // apply s (t1, t2) = (apply s t1, apply s t2)
107 // ftv (t1, t2) = union (ftv t1) (ftv t2)
108 //
109 //instantiate :: Scheme -> Infer Type
110 //instantiate (Forall as t) = mapM (const fresh) as
111 // >>= \as`->let s = 'DM'.fromList $ zip2 as as` in pure $ apply s t
112 //
113 //generalize :: TypeEnv Type -> Scheme
114 //generalize env t = Forall (difference (ftv t) (ftv env)) t
115 //
116 ////:: Expression
117 //// = Lit Value
118 //// | Var [Char]
119 //// | App Expression Expression
120 //// | Lambda [Char] Expression
121 //// | Builtin [Char] [Expression]
122 //inferExpr :: TypeEnv Expression -> Either [String] Scheme
123 //inferExpr env ex = case runRWST (infer ex) env {count=0} of
124 // Left e = Left e
125 // Right (ty, st, cs) = case runStateT solver ('DM'.newMap, cs) of
126 // Left e = Left e
127 // Right (s, _) = Right (closeOver (apply s ty))
128 //
129 //closeOver :: Type -> Scheme
130 //closeOver t = normalize (generalize 'DM'.newMap t)
131 //
132 //normalize :: Scheme -> Scheme
133 //normalize t = t
134 //
135 //inferAST :: TypeEnv [Function] -> Either [String] TypeEnv
136 //inferAST env [] = Right env
137 //inferAST env [Function name args body:rest] = case inferExpr env (foldr Lambda body args) of
138 // Left e = Left e
139 // Right ty = inferAST ('DM'.put name ty env) rest
140 //
141 //inferFunc :: [Function] -> Infer ()
142 //inferFunc [] = pure ()
143 //inferFunc [Function name args body:rest]
144 // = ask
145 // >>= \en->infer (foldr Lambda body args)
146 // >>= \t1->inEnv (name, generalize en t1) (inferFunc rest)
147 // >>= \_->pure ()
148 //
149 //infer :: Expression -> Infer Type
150 //infer (Lit v) = case v of
151 // Int _ = pure TInt
152 // Bool _ = pure TBool
153 //infer (Var s) = asks ('DM'.get s)
154 // >>= maybe (liftT $ Left ["Unbound variable " +++ toString s]) instantiate
155 //infer (App e1 e2)
156 // = infer e1
157 // >>= \t1->infer e2
158 // >>= \t2->fresh
159 // >>= \tv->uni t1 (TFun t2 tv)
160 // >>| pure tv
161 //infer (Lambda s e)
162 // = fresh
163 // >>= \tv->inEnv (s, Forall [] tv) (infer e)
164 // >>= \t-> pure (TFun tv t)
165 ////infer (Let x e1 e2)
166 //// = ask
167 //// >>= \en->infer e1
168 //// >>= \t1->inEnv (x, generalize en t1) (infer e2)
169 //
170 //unifies :: Type Type -> Solve Unifier
171 //unifies TInt TInt = pure ('DM'.newMap, [])
172 //unifies TBool TBool = pure ('DM'.newMap, [])
173 //unifies (TVar a) (TVar b)
174 // | a == b = pure ('DM'.newMap, [])
175 //unifies (TVar v) t = tbind v t
176 //unifies t (TVar v) = tbind v t
177 //unifies (TFun t1 t2) (TFun t3 t4) = unifyMany [t1, t2] [t3, t4]
178 //unifies t1 t2 = liftT $ Left ["Cannot unify " +++ toString t1 +++ " with " +++ toString t2]
179 //
180 //unifyMany :: [Type] [Type] -> Solve Unifier
181 //unifyMany [] [] = pure ('DM'.newMap, [])
182 //unifyMany [t1:ts1] [t2:ts2] = unifies t1 t2
183 // >>= \(su1, cs1)->unifyMany (apply su1 ts1) (apply su1 ts2)
184 // >>= \(su2, cs2)->pure (su2 `compose` su1, cs1 ++ cs2)
185 //unifyMany t1 t2 = liftT $ Left ["Length difference in unifyMany"]
186 //
187 //(`compose`) infix 1 :: Subst Subst -> Subst
188 //(`compose`) s1 s2 = 'DM'.union (apply s1 <$> s2) s1
189 //
190 //tbind :: [Char] Type -> Solve Unifier
191 //tbind a (TVar b)
192 // | a == b = pure ('DM'.newMap, [])
193 //tbind a t
194 // | occursCheck a t = liftT $ Left ["Infinite type " +++ toString a +++ toString t]
195 // = pure $ ('DM'.singleton a t, [])
196 //
197 //occursCheck :: [Char] a -> Bool | Substitutable a
198 //occursCheck a t = isMember a $ ftv t
199 //
200 //solver :: Solve Subst
201 //solver = getState >>= \(su, cs)->case cs of
202 // [] = pure su
203 // [(t1, t2):cs0] = unifies t1 t2
204 // >>= \(su1, cs1)->'MS'.put (su1 `compose` su, cs1 ++ (apply su1 cs0))
205 // >>| solver