diff options
author | Péter Diviánszky <divipp@gmail.com> | 2015-12-19 15:15:42 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2015-12-19 15:15:42 +0100 |
commit | 0fceae00351621f81dc5e5a9a76997765e0c2394 (patch) | |
tree | 3c79e9164c91852365b4929a67ec38584fa51a55 /prototypes | |
parent | 54ad6ad562dcc78da03929dccc21fc9e4307b004 (diff) |
switch to new compiler
Diffstat (limited to 'prototypes')
87 files changed, 0 insertions, 4459 deletions
diff --git a/prototypes/CGExp.hs b/prototypes/CGExp.hs deleted file mode 100644 index 5477e485..00000000 --- a/prototypes/CGExp.hs +++ /dev/null | |||
@@ -1,332 +0,0 @@ | |||
1 | {-# LANGUAGE LambdaCase #-} | ||
2 | {-# LANGUAGE ViewPatterns #-} | ||
3 | {-# LANGUAGE PatternSynonyms #-} | ||
4 | {-# LANGUAGE FlexibleContexts #-} | ||
5 | {-# LANGUAGE FlexibleInstances #-} | ||
6 | {-# LANGUAGE NoMonomorphismRestriction #-} | ||
7 | {-# LANGUAGE DeriveFunctor #-} | ||
8 | {-# LANGUAGE DeriveFoldable #-} | ||
9 | {-# LANGUAGE DeriveTraversable #-} | ||
10 | {-# LANGUAGE RecursiveDo #-} | ||
11 | module CGExp | ||
12 | ( module CGExp | ||
13 | , Lit(..), Export(..), ModuleR(..) | ||
14 | ) where | ||
15 | |||
16 | import Control.Monad.Reader | ||
17 | import Control.Monad.State | ||
18 | import Control.Monad.Except | ||
19 | import Control.Monad.Identity | ||
20 | import Control.Monad.Writer | ||
21 | import Control.Arrow | ||
22 | import qualified Data.Set as S | ||
23 | import qualified Data.Map as M | ||
24 | import Text.Parsec.Pos | ||
25 | |||
26 | import Pretty | ||
27 | import qualified Infer as I | ||
28 | import Infer (SName, Lit(..), Visibility(..), Export(..), ModuleR(..)) | ||
29 | |||
30 | -------------------------------------------------------------------------------- | ||
31 | |||
32 | data Exp_ a | ||
33 | = Pi_ Visibility SName a a | ||
34 | | Lam_ Visibility Pat a a | ||
35 | | Con_ (SName, a) [a] | ||
36 | | ELit_ Lit | ||
37 | | Fun_ (SName, a) [a] | ||
38 | | App_ a a | ||
39 | | Var_ SName a | ||
40 | | TType_ | ||
41 | | Let_ Pat a a | ||
42 | | EFieldProj_ a SName | ||
43 | deriving (Show, Eq, Functor, Foldable, Traversable) | ||
44 | |||
45 | instance PShow Exp where pShowPrec p = text . show | ||
46 | |||
47 | pattern Pi h n a b = Exp (Pi_ h n a b) | ||
48 | pattern Lam h n a b = Exp (Lam_ h n a b) | ||
49 | pattern Con a b = Exp (Con_ a b) | ||
50 | pattern ELit a = Exp (ELit_ a) | ||
51 | pattern Fun a b = Exp (Fun_ a b) | ||
52 | pattern EApp a b = Exp (App_ a b) | ||
53 | pattern Var a b = Exp (Var_ a b) | ||
54 | pattern TType = Exp TType_ | ||
55 | pattern ELet a b c = Exp (Let_ a b c) | ||
56 | pattern EFieldProj a b = Exp (EFieldProj_ a b) | ||
57 | |||
58 | newtype Exp = Exp (Exp_ Exp) | ||
59 | deriving (Show, Eq) | ||
60 | |||
61 | type ConvM a = StateT [SName] (Reader [SName]) a | ||
62 | |||
63 | newName = gets head <* modify tail | ||
64 | |||
65 | toExp :: I.Exp -> Exp | ||
66 | toExp = flip runReader [] . flip evalStateT freshTypeVars . f | ||
67 | where | ||
68 | f = \case | ||
69 | I.FunN "swizzvector" [_, _, _, exp, getSwizzVec -> Just (concat -> s)] -> newName >>= \n -> do | ||
70 | e <- f exp | ||
71 | return $ app' (EFieldProj (Pi Visible n (tyOf e) (TVec (length s) TFloat)) s) e | ||
72 | I.FunN "swizzscalar" [_, _, exp, mkSwizzStr -> Just s] -> newName >>= \n -> do | ||
73 | e <- f exp | ||
74 | return $ app' (EFieldProj (Pi Visible n (tyOf e) TFloat) s) e | ||
75 | I.Var i -> asks $ uncurry Var . (!!! i) | ||
76 | I.Pi b x y -> newName >>= \n -> do | ||
77 | t <- f x | ||
78 | Pi b n t <$> local ((n, t):) (f y) | ||
79 | I.Lam b x y -> newName >>= \n -> do | ||
80 | t <- f x | ||
81 | Lam b (PVar t n) t <$> local ((n, t):) (f y) | ||
82 | I.Con (I.ConName s _ _ t) xs -> con s <$> f t <*> mapM f xs | ||
83 | I.TyCon (I.TyConName s _ _ t _ _) xs -> con s <$> f t <*> mapM f xs | ||
84 | I.ELit l -> pure $ ELit l | ||
85 | I.Fun (I.FunName s _ t) xs -> fun s <$> f t <*> mapM f xs | ||
86 | I.CaseFun (I.CaseFunName s t _) xs -> fun s <$> f t <*> mapM f xs | ||
87 | I.App a b -> app' <$> f a <*> f b | ||
88 | I.Label x _ -> f x | ||
89 | I.TType -> pure TType | ||
90 | I.LabelEnd x -> f x | ||
91 | z -> error $ "toExp: " ++ show z | ||
92 | |||
93 | getSwizzVec = \case | ||
94 | I.VV2 _ (mkSwizzStr -> Just sx) (mkSwizzStr -> Just sy) -> Just [sx, sy] | ||
95 | I.VV3 _ (mkSwizzStr -> Just sx) (mkSwizzStr -> Just sy) (mkSwizzStr -> Just sz) -> Just [sx, sy, sz] | ||
96 | I.VV4 _ (mkSwizzStr -> Just sx) (mkSwizzStr -> Just sy) (mkSwizzStr -> Just sz) (mkSwizzStr -> Just sw) -> Just [sx, sy, sz, sw] | ||
97 | _ -> Nothing | ||
98 | |||
99 | mkSwizzStr = \case | ||
100 | I.ConN "Sx" [] -> Just "x" | ||
101 | I.ConN "Sy" [] -> Just "y" | ||
102 | I.ConN "Sz" [] -> Just "z" | ||
103 | I.ConN "Sw" [] -> Just "w" | ||
104 | _ -> Nothing | ||
105 | |||
106 | xs !!! i | i < 0 || i >= length xs = error $ show xs ++ " !! " ++ show i | ||
107 | xs !!! i = xs !! i | ||
108 | |||
109 | untick ('\'': s) = s | ||
110 | untick s = s | ||
111 | |||
112 | fun s t xs = Fun (untick s, t) xs | ||
113 | |||
114 | con (untick -> s) t xs = Con (s, t) xs | ||
115 | |||
116 | freeVars :: Exp -> S.Set SName | ||
117 | freeVars = \case | ||
118 | Var n _ -> S.singleton n | ||
119 | Con _ xs -> S.unions $ map freeVars xs | ||
120 | ELit _ -> mempty | ||
121 | Fun _ xs -> S.unions $ map freeVars xs | ||
122 | EApp a b -> freeVars a `S.union` freeVars b | ||
123 | Pi _ n a b -> freeVars a `S.union` (S.delete n $ freeVars b) | ||
124 | Lam _ n a b -> freeVars a `S.union` (foldr S.delete (freeVars b) (patVars n)) | ||
125 | EFieldProj a _ -> freeVars a | ||
126 | TType -> mempty | ||
127 | ELet n a b -> freeVars a `S.union` (foldr S.delete (freeVars b) (patVars n)) | ||
128 | |||
129 | type Ty = Exp | ||
130 | |||
131 | tyOf :: Exp -> Ty | ||
132 | tyOf = \case | ||
133 | Lam h (PVar _ n) t x -> Pi h n t $ tyOf x | ||
134 | EApp f x -> app (tyOf f) x | ||
135 | Var _ t -> t | ||
136 | Pi{} -> Type | ||
137 | Con (_, t) xs -> foldl app t xs | ||
138 | Fun (_, t) xs -> foldl app t xs | ||
139 | ELit l -> toExp $ I.litType l | ||
140 | TType -> TType | ||
141 | ELet a b c -> tyOf $ EApp (ELam a c) b | ||
142 | EFieldProj t s -> t | ||
143 | x -> error $ "tyOf: " ++ show x | ||
144 | where | ||
145 | app (Pi _ n a b) x = substE n x b | ||
146 | |||
147 | substE n x = \case | ||
148 | z@(Var n' _) | n' == n -> x | ||
149 | | otherwise -> z | ||
150 | Pi h n' a b | n == n' -> Pi h n' (substE n x a) b | ||
151 | Pi h n' a b -> Pi h n' (substE n x a) (substE n x b) | ||
152 | Lam h n' a b -> Lam h n' (substE n x a) $ if n `elem` patVars n' then b else substE n x b | ||
153 | Con cn xs -> Con cn (map (substE n x) xs) | ||
154 | Fun cn xs -> Fun cn (map (substE n x) xs) | ||
155 | TType -> TType | ||
156 | EApp a b -> app' (substE n x a) (substE n x b) | ||
157 | z -> error $ "substE: " ++ show z | ||
158 | |||
159 | app' (Lam _ (PVar _ n) _ x) b = substE n b x | ||
160 | app' a b = EApp a b | ||
161 | |||
162 | -------------------------------------------------------------------------------- | ||
163 | |||
164 | data Pat | ||
165 | = PVar Exp SName | ||
166 | | PTuple [Pat] | ||
167 | deriving (Eq, Show) | ||
168 | |||
169 | instance PShow Pat where pShowPrec p = text . show | ||
170 | |||
171 | patVars (PVar _ n) = [n] | ||
172 | patVars (PTuple ps) = concatMap patVars ps | ||
173 | |||
174 | patTy (PVar t _) = t | ||
175 | patTy (PTuple ps) = Con ("Tuple" ++ show (length ps), tupTy $ length ps) $ map patTy ps | ||
176 | |||
177 | tupTy n = foldr (:~>) Type $ replicate n Type | ||
178 | |||
179 | ------------- | ||
180 | |||
181 | pattern EVar n <- Var n _ | ||
182 | pattern TVar t n = Var n t | ||
183 | |||
184 | pattern ELam n b <- Lam Visible n _ b where ELam n b = Lam Visible n (patTy n) b | ||
185 | |||
186 | pattern a :~> b = Pi Visible "" a b | ||
187 | infixr 1 :~> | ||
188 | |||
189 | pattern PrimN n xs <- Fun (n, t) (filterRelevant (n, 0) t -> xs) where PrimN n xs = Fun (n, hackType n) xs | ||
190 | pattern Prim1 n a = PrimN n [a] | ||
191 | pattern Prim2 n a b = PrimN n [a, b] | ||
192 | pattern Prim3 n a b c <- PrimN n [a, b, c] | ||
193 | pattern Prim4 n a b c d <- PrimN n [a, b, c, d] | ||
194 | pattern Prim5 n a b c d e <- PrimN n [a, b, c, d, e] | ||
195 | |||
196 | -- todo: remove | ||
197 | hackType = \case | ||
198 | "Output" -> TType | ||
199 | "Bool" -> TType | ||
200 | "Float" -> TType | ||
201 | "Nat" -> TType | ||
202 | "Zero" -> TNat | ||
203 | "Succ" -> TNat :~> TNat | ||
204 | "String" -> TType | ||
205 | "Sampler" -> TType | ||
206 | "VecS" -> TType :~> TNat :~> TType | ||
207 | -- "EFieldProj" -> Pi Visible "projt" TType $ Pi Visible "projt2" TString $ Pi Visible "projvec" (TVec (error "pn1") TFloat) (TVec (error "pn2") TFloat) | ||
208 | n -> error $ "type of " ++ show n | ||
209 | |||
210 | filterRelevant _ _ [] = [] | ||
211 | filterRelevant i (Pi h n t t') (x: xs) = (if h == Visible || exception i then (x:) else id) $ filterRelevant (id *** (+1) $ i) (substE n x t') xs | ||
212 | where | ||
213 | -- todo: remove | ||
214 | exception i = i `elem` [("ColorImage", 0), ("DepthImage", 0), ("StencilImage", 0)] | ||
215 | |||
216 | pattern AN n xs <- Con (n, t) (filterRelevant (n, 0) t -> xs) where AN n xs = Con (n, hackType n) xs | ||
217 | pattern A0 n = AN n [] | ||
218 | pattern A1 n a = AN n [a] | ||
219 | pattern A2 n a b = AN n [a, b] | ||
220 | pattern A3 n a b c <- AN n [a, b, c] | ||
221 | pattern A4 n a b c d <- AN n [a, b, c, d] | ||
222 | pattern A5 n a b c d e <- AN n [a, b, c, d, e] | ||
223 | |||
224 | pattern TCon0 n = A0 n | ||
225 | pattern TCon t n = Con (n, t) [] | ||
226 | |||
227 | pattern Type = TType | ||
228 | pattern Star = TType | ||
229 | pattern TUnit <- A0 "Tuple0" | ||
230 | pattern TBool <- A0 "Bool" | ||
231 | pattern TWord <- A0 "Word" | ||
232 | pattern TInt <- A0 "Int" | ||
233 | pattern TNat = A0 "Nat" | ||
234 | pattern TFloat = A0 "Float" | ||
235 | pattern TString = A0 "String" | ||
236 | pattern TList n <- A1 "List" n | ||
237 | |||
238 | pattern TSampler = A0 "Sampler" | ||
239 | pattern TFrameBuffer a b <- A2 "FrameBuffer" a b | ||
240 | pattern Depth n <- A1 "Depth" n | ||
241 | pattern Stencil n <- A1 "Stencil" n | ||
242 | pattern Color n <- A1 "Color" n | ||
243 | |||
244 | pattern Zero = A0 "Zero" | ||
245 | pattern Succ n = A1 "Succ" n | ||
246 | |||
247 | pattern TVec n a = A2 "VecS" a (Nat n) | ||
248 | pattern TMat i j a <- A3 "Mat" (Nat i) (Nat j) a | ||
249 | |||
250 | pattern Nat n <- (fromNat -> Just n) where Nat n = toNat n | ||
251 | |||
252 | toNat :: Int -> Exp | ||
253 | toNat 0 = Zero | ||
254 | toNat n = Succ (toNat $ n-1) | ||
255 | |||
256 | fromNat :: Exp -> Maybe Int | ||
257 | fromNat Zero = Just 0 | ||
258 | fromNat (Succ n) = (1 +) <$> fromNat n | ||
259 | |||
260 | pattern TTuple xs <- (getTuple -> Just xs) | ||
261 | pattern ETuple xs <- (getTuple -> Just xs) | ||
262 | |||
263 | getTuple = \case | ||
264 | AN "Tuple0" [] -> Just [] | ||
265 | AN "Tuple2" [a, b] -> Just [a, b] | ||
266 | AN "Tuple3" [a, b, c] -> Just [a, b, c] | ||
267 | AN "Tuple4" [a, b, c, d] -> Just [a, b, c, d] | ||
268 | AN "Tuple5" [a, b, c, d, e] -> Just [a, b, c, d, e] | ||
269 | AN "Tuple6" [a, b, c, d, e, f] -> Just [a, b, c, d, e, f] | ||
270 | AN "Tuple7" [a, b, c, d, e, f, g] -> Just [a, b, c, d, e, f, g] | ||
271 | _ -> Nothing | ||
272 | |||
273 | pattern ERecord a <- (const Nothing -> Just a) | ||
274 | |||
275 | -------------------------------------------------------------------------------- | ||
276 | |||
277 | showN = id | ||
278 | show5 = show | ||
279 | |||
280 | pattern ExpN a = a | ||
281 | |||
282 | newtype ErrorMsg = ErrorMsg String | ||
283 | instance Show ErrorMsg where show (ErrorMsg s) = s | ||
284 | |||
285 | type ErrorT = ExceptT ErrorMsg | ||
286 | mapError f e = e | ||
287 | pattern InFile :: String -> ErrorMsg -> ErrorMsg | ||
288 | pattern InFile s e <- ((,) "?" -> (s, e)) where InFile _ e = e | ||
289 | |||
290 | type Info = (SourcePos, SourcePos, String) | ||
291 | type Infos = [Info] | ||
292 | |||
293 | type PolyEnv = I.GlobalEnv | ||
294 | |||
295 | joinPolyEnvs :: MonadError ErrorMsg m => Bool -> [PolyEnv] -> m PolyEnv | ||
296 | joinPolyEnvs _ = return . mconcat | ||
297 | getPolyEnv = id | ||
298 | |||
299 | type MName = SName | ||
300 | type VarMT = StateT FreshVars | ||
301 | type FreshVars = [String] | ||
302 | freshTypeVars = (flip (:) <$> map show [0..] <*> ['a'..'z']) | ||
303 | |||
304 | throwErrorTCM :: MonadError ErrorMsg m => Doc -> m a | ||
305 | throwErrorTCM d = throwError $ ErrorMsg $ show d | ||
306 | |||
307 | infos = const [] | ||
308 | |||
309 | type EName = SName | ||
310 | |||
311 | parseLC :: MonadError ErrorMsg m => FilePath -> String -> m ModuleR | ||
312 | parseLC f s = either (throwError . ErrorMsg) return (I.parse f s) | ||
313 | |||
314 | inference_ :: PolyEnv -> ModuleR -> ErrorT (WriterT Infos (VarMT Identity)) PolyEnv | ||
315 | inference_ pe m = mdo | ||
316 | defs <- either (throwError . ErrorMsg) return $ definitions m $ I.mkGlobalEnv' defs `I.joinGlobalEnv'` I.extractGlobalEnv' pe | ||
317 | either (throwError . ErrorMsg) return $ I.infer pe defs | ||
318 | |||
319 | reduce = id | ||
320 | |||
321 | type Item = (I.Exp, I.Exp) | ||
322 | |||
323 | tyOfItem :: Item -> Exp | ||
324 | tyOfItem = toExp . snd | ||
325 | |||
326 | pattern ISubst a b <- ((,) () -> (a, (toExp -> b, tb))) | ||
327 | |||
328 | dummyPos :: SourcePos | ||
329 | dummyPos = newPos "" 0 0 | ||
330 | |||
331 | showErr e = (dummyPos, dummyPos, e) | ||
332 | |||
diff --git a/prototypes/CoreToGLSL.hs b/prototypes/CoreToGLSL.hs deleted file mode 120000 index b9ebdd27..00000000 --- a/prototypes/CoreToGLSL.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../CoreToGLSL.hs \ No newline at end of file | ||
diff --git a/prototypes/CoreToIR.hs b/prototypes/CoreToIR.hs deleted file mode 120000 index 7f32ac4d..00000000 --- a/prototypes/CoreToIR.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../CoreToIR.hs \ No newline at end of file | ||
diff --git a/prototypes/Driver.hs b/prototypes/Driver.hs deleted file mode 120000 index 882f3164..00000000 --- a/prototypes/Driver.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../Driver.hs \ No newline at end of file | ||
diff --git a/prototypes/IR.hs b/prototypes/IR.hs deleted file mode 120000 index ae04b92e..00000000 --- a/prototypes/IR.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../IR.hs \ No newline at end of file | ||
diff --git a/prototypes/Infer.hs b/prototypes/Infer.hs deleted file mode 100644 index d4cb8775..00000000 --- a/prototypes/Infer.hs +++ /dev/null | |||
@@ -1,2247 +0,0 @@ | |||
1 | {-# LANGUAGE LambdaCase #-} | ||
2 | {-# LANGUAGE ViewPatterns #-} | ||
3 | {-# LANGUAGE PatternSynonyms #-} | ||
4 | {-# LANGUAGE FlexibleContexts #-} | ||
5 | {-# LANGUAGE FlexibleInstances #-} | ||
6 | {-# LANGUAGE NoMonomorphismRestriction #-} | ||
7 | {-# LANGUAGE OverloadedStrings #-} | ||
8 | {-# LANGUAGE DeriveFunctor #-} | ||
9 | {-# LANGUAGE ScopedTypeVariables #-} | ||
10 | {-# LANGUAGE RecursiveDo #-} | ||
11 | module Infer | ||
12 | ( Binder (..), SName, Lit(..), Visibility(..), FunName(..), CaseFunName(..), ConName(..), TyConName(..), Export(..), ModuleR(..) | ||
13 | , Exp (..), GlobalEnv | ||
14 | , pattern Var, pattern Fun, pattern CaseFun, pattern App, pattern FunN, pattern ConN, pattern VV2, pattern VV3, pattern VV4, pattern Pi | ||
15 | , parse | ||
16 | , mkGlobalEnv', joinGlobalEnv', extractGlobalEnv' | ||
17 | , litType, infer | ||
18 | ) where | ||
19 | |||
20 | import Data.Monoid | ||
21 | import Data.Maybe | ||
22 | import Data.List | ||
23 | import Data.Char | ||
24 | import Data.String | ||
25 | import qualified Data.Set as Set | ||
26 | import qualified Data.Map as Map | ||
27 | |||
28 | import Control.Monad.Except | ||
29 | import Control.Monad.Reader | ||
30 | import Control.Monad.State | ||
31 | import Control.Monad.Identity | ||
32 | import Control.Arrow | ||
33 | import Control.Applicative hiding (optional) | ||
34 | import Control.Exception hiding (try) | ||
35 | |||
36 | import Text.Parsec hiding (parse, label, Empty, State, (<|>), many, optional) | ||
37 | import qualified Text.Parsec.Token as Pa | ||
38 | import Text.Parsec.Pos | ||
39 | import Text.Parsec.Indentation hiding (Any) | ||
40 | import Text.Parsec.Indentation.Char | ||
41 | import Text.Parsec.Indentation.Token | ||
42 | |||
43 | import Debug.Trace | ||
44 | |||
45 | import qualified Pretty as P | ||
46 | |||
47 | -------------------------------------------------------------------------------- source data | ||
48 | |||
49 | type SName = String | ||
50 | |||
51 | data Stmt | ||
52 | = Let SName MFixity (Maybe SExp) [Visibility]{-source arity-} SExp | ||
53 | | Data SName [(Visibility, SExp)]{-parameters-} SExp{-type-} [(SName, SExp)]{-constructor names and types-} | ||
54 | | Primitive (Maybe Bool{-Just True: type constructor; Just False: constructor; Nothing: function-}) SName SExp{-type-} | ||
55 | | PrecDef SName Fixity | ||
56 | | ValueDef ([SName], Pat) SExp | ||
57 | |||
58 | -- eliminated during parsing | ||
59 | | TypeAnn SName SExp -- intermediate | ||
60 | | FunAlt SName [((Visibility, SExp), Pat)] (Maybe SExp) SExp | ||
61 | deriving (Show) | ||
62 | |||
63 | data SExp | ||
64 | = SGlobal SName | ||
65 | | SBind Binder SExp SExp | ||
66 | | SApp Visibility SExp SExp | ||
67 | | SLet SExp SExp -- let x = e in f --> SLet e f{-x is Var 0-} | ||
68 | | SVar !Int | ||
69 | | STyped ExpType | ||
70 | deriving (Eq, Show) | ||
71 | |||
72 | type FixityMap = Map.Map SName Fixity | ||
73 | type ConsMap = Map.Map SName ((SName{-type name-}, Int{-num of indices-}), [(SName, Int)]{-constructors with arities-}) | ||
74 | type GlobalEnv' = (FixityMap, ConsMap) | ||
75 | |||
76 | type Fixity = (Maybe FixityDir, Int) | ||
77 | type MFixity = Maybe Fixity | ||
78 | data FixityDir = FDLeft | FDRight deriving (Show) | ||
79 | |||
80 | data Binder | ||
81 | = BPi Visibility | ||
82 | | BLam Visibility | ||
83 | | BMeta -- a metavariable is like a floating hidden lambda | ||
84 | deriving (Eq, Show) | ||
85 | |||
86 | data Visibility = Hidden | Visible | ||
87 | deriving (Eq, Show) | ||
88 | |||
89 | sLit a = STyped (ELit a, litType a) | ||
90 | pattern SType = STyped (TType, TType) | ||
91 | pattern SPi h a b = SBind (BPi h) a b | ||
92 | pattern SLam h a b = SBind (BLam h) a b | ||
93 | pattern Wildcard t = SBind BMeta t (SVar 0) | ||
94 | pattern SAppH a b = SApp Hidden a b | ||
95 | pattern SAppV a b = SApp Visible a b | ||
96 | pattern SAnn a t = STyped (Lam Visible TType (Lam Visible (Var 0) (Var 0)), TType :~> Var 0 :~> Var 1) `SAppV` t `SAppV` a -- a :: t ~~> id t a | ||
97 | pattern TyType a = STyped (Lam Visible TType (Var 0), TType :~> TType) `SAppV` a | ||
98 | -- same as (a :: TType) -- a :: TType ~~> (\(x :: TType) -> x) a | ||
99 | --pattern CheckSame' a b c = SGlobal "checkSame" `SAppV` STyped a `SAppV` STyped b `SAppV` c | ||
100 | pattern SCstr a b = SGlobal "cstr" `SAppV` a `SAppV` b -- a ~ b | ||
101 | pattern SLabelEnd a = SGlobal "labelend" `SAppV` a | ||
102 | |||
103 | isPi (BPi _) = True | ||
104 | isPi _ = False | ||
105 | |||
106 | infixl 1 `SAppV`, `SAppH`, `App` | ||
107 | |||
108 | -------------------------------------------------------------------------------- destination data | ||
109 | |||
110 | data Exp | ||
111 | = Bind Binder Exp Exp -- TODO: prohibit meta binder here; BLam is not allowed | ||
112 | | Lam Visibility Exp Exp | ||
113 | | Con ConName [Exp] | ||
114 | | TyCon TyConName [Exp] | ||
115 | | ELit Lit | ||
116 | | Assign !Int Exp Exp -- De Bruijn index decreasing assign operator, only for metavariables (non-recursive) -- TODO: remove | ||
117 | | Label Exp{-function alternatives are obeyed during reduction-} Exp{-functions are treated like constants-} | ||
118 | -- label is used also for getting fixity info | ||
119 | | LabelEnd Exp | ||
120 | | Neut Neutral | ||
121 | | TType | ||
122 | deriving (Show) | ||
123 | |||
124 | data Neutral | ||
125 | = Fun_ FunName [Exp] | ||
126 | | CaseFun_ CaseFunName [Exp] | ||
127 | | App_ Exp{-todo: Neutral-} Exp | ||
128 | | Var_ !Int -- De Bruijn variable | ||
129 | deriving (Show) | ||
130 | |||
131 | type Type = Exp | ||
132 | |||
133 | data ConName = ConName SName MFixity Int Type | ||
134 | instance Show ConName where show (ConName n _ _ _) = n | ||
135 | instance Eq ConName where ConName n _ _ _ == ConName n' _ _ _ = n == n' | ||
136 | |||
137 | conTypeName :: ConName -> TyConName | ||
138 | conTypeName (ConName _ _ _ t) = case snd (getParams t) of | ||
139 | TyCon n _ -> n | ||
140 | _ -> error "impossible" | ||
141 | |||
142 | data TyConName = TyConName SName MFixity Int{-num of indices-} Type [ConName]{-constructors-} Type{-case type-} | ||
143 | instance Show TyConName where show (TyConName n _ _ _ _ _) = n | ||
144 | instance Eq TyConName where TyConName n _ _ _ _ _ == TyConName n' _ _ _ _ _ = n == n' | ||
145 | |||
146 | data FunName = FunName SName MFixity Type | ||
147 | instance Show FunName where show (FunName n _ _) = n | ||
148 | instance Eq FunName where FunName n _ _ == FunName n' _ _ = n == n' | ||
149 | |||
150 | data CaseFunName = CaseFunName SName Type Int{-num of parameters-} | ||
151 | instance Show CaseFunName where show (CaseFunName n _ _) = n | ||
152 | instance Eq CaseFunName where CaseFunName n _ _ == CaseFunName n' _ _ = n == n' | ||
153 | |||
154 | caseName (c:cs) = toLower c: cs ++ "Case" | ||
155 | |||
156 | type ExpType = (Exp, Type) | ||
157 | |||
158 | pattern Fun a b = Neut (Fun_ a b) | ||
159 | pattern CaseFun a b = Neut (CaseFun_ a b) | ||
160 | pattern FunN a b <- Fun (FunName a _ _) b | ||
161 | pattern CaseFunN a b <- CaseFun (CaseFunName a _ _) b | ||
162 | pattern TFun a t b <- Fun (FunName a _ t) b where TFun a t b = Fun (FunName a Nothing t) b | ||
163 | pattern TCaseFun a t i b = CaseFun (CaseFunName a t i) b | ||
164 | pattern App a b = Neut (App_ a b) | ||
165 | pattern Var a = Neut (Var_ a) | ||
166 | |||
167 | data Lit | ||
168 | = LInt !Int | ||
169 | | LChar Char | ||
170 | | LFloat Double | ||
171 | | LString String | ||
172 | deriving (Eq) | ||
173 | |||
174 | instance Show Lit where | ||
175 | show = \case | ||
176 | LFloat x -> show x | ||
177 | LString x -> show x | ||
178 | LInt x -> show x | ||
179 | LChar x -> show x | ||
180 | |||
181 | pattern Lam' b <- Lam _ _ b | ||
182 | pattern Pi h a b = Bind (BPi h) a b | ||
183 | pattern Meta a b = Bind BMeta a b | ||
184 | |||
185 | pattern Cstr a b = TFun "cstr" (TType :~> TType :~> TType){-todo-} [a, b] | ||
186 | pattern ReflCstr x = TFun "reflCstr" (TType :~> Cstr (Var 0) (Var 0)) [x] | ||
187 | pattern Coe a b w x = TFun "coe" (TType :~> TType :~> Cstr (Var 1) (Var 0) :~> Var 2 :~> Var 2) [a,b,w,x] | ||
188 | |||
189 | pattern ConN s a <- Con (ConName s _ _ _) a | ||
190 | pattern TyConN s a <- TyCon (TyConName s _ _ _ _ _) a | ||
191 | pattern TCon s i t a <- Con (ConName s _ i t) a where TCon s i t a = Con (ConName s Nothing i t) a -- todo: don't match on type | ||
192 | pattern TTyCon s t a <- TyCon (TyConName s _ _ t _ _) a where TTyCon s t a = TyCon (TyConName s Nothing (error "todo: inum") t (error "todo: tcn cons 2") $ error "TTyCon") a | ||
193 | pattern TTyCon0 s <- TyCon (TyConName s _ _ TType _ _) [] where TTyCon0 s = TyCon (TyConName s Nothing (error "todo: inum2") TType (error "todo: tcn cons 3") $ error "TTyCon0") [] | ||
194 | pattern Sigma a b <- TyConN "Sigma" [a, Lam' b] where Sigma a b = TTyCon "Sigma" (error "sigmatype") [a, Lam Visible a{-todo: don't duplicate-} b] | ||
195 | pattern Unit = TTyCon0 "Unit" | ||
196 | pattern TT = TCon "TT" 0 Unit [] | ||
197 | pattern T2 a b = TFun "T2" (TType :~> TType :~> TType) [a, b] | ||
198 | pattern T2C a b = TCon "T2C" (-1) (Unit :~> Unit :~> Unit) [a, b] | ||
199 | pattern Empty = TTyCon0 "Empty" | ||
200 | pattern TInt = TTyCon0 "Int" | ||
201 | pattern TNat = TTyCon0 "Nat" | ||
202 | pattern TBool = TTyCon0 "Bool" | ||
203 | pattern TFloat = TTyCon0 "Float" | ||
204 | pattern TString = TTyCon0 "String" | ||
205 | pattern TChar = TTyCon0 "Char" | ||
206 | pattern TOrdering = TTyCon0 "'Ordering" | ||
207 | pattern Zero = TCon "Zero" 0 TNat [] | ||
208 | pattern Succ n = TCon "Succ" 1 (TNat :~> TNat) [n] | ||
209 | --pattern TVec a b = TTyCon "'Vec" (TNat :~> TType :~> TType) [a, b] | ||
210 | pattern TVec a b = TTyCon "'VecS" (TType :~> TNat :~> TType) [b, a] | ||
211 | pattern TFrameBuffer a b = TTyCon "'FrameBuffer" (TNat :~> TType :~> TType) [a, b] | ||
212 | pattern TRecord a = TTyCon "'RecordC" TRecordType [a] | ||
213 | pattern TList a = TTyCon "'List" (TType :~> TType) [a] | ||
214 | pattern Tuple2 a b c d = TCon "Tuple2" 0 Tuple2Type [a, b, c, d] | ||
215 | pattern Tuple0 = TCon "Tuple0" 0 Tuple0Type [] | ||
216 | pattern VV2 t x y = TCon "V2" 0 V2Type [t, x, y] | ||
217 | pattern VV3 t x y z = TCon "V3" 1 V3Type [t, x, y, z] | ||
218 | pattern VV4 t x y z w = TCon "V4" 2 V4Type [t, x, y, z, w] | ||
219 | pattern CSplit a b c <- FunN "Split" [a, b, c] | ||
220 | |||
221 | pattern Tuple0Type :: Exp | ||
222 | pattern Tuple0Type <- _ where Tuple0Type = TTyCon0 "'Tuple0" | ||
223 | pattern Tuple2Type :: Exp | ||
224 | pattern Tuple2Type <- _ where Tuple2Type = Pi Hidden TType $ Pi Hidden TType $ Var 1 :~> Var 1 :~> tTuple2 (Var 3) (Var 2) | ||
225 | pattern V2Type :: Exp | ||
226 | pattern V2Type <- _ where V2Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> TVec (toNatE 2) (Var 2) | ||
227 | pattern V3Type :: Exp | ||
228 | pattern V3Type <- _ where V3Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> Var 2 :~> TVec (toNatE 3) (Var 3) | ||
229 | pattern V4Type :: Exp | ||
230 | pattern V4Type <- _ where V4Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> Var 2 :~> Var 3 :~> TVec (toNatE 4) (Var 4) | ||
231 | pattern TRecordType :: Exp | ||
232 | pattern TRecordType <- _ where TRecordType = TList SListEType :~> TType | ||
233 | pattern NilType :: Exp | ||
234 | pattern NilType <- _ where NilType = Pi Hidden TType $ TList (Var 0) | ||
235 | pattern ConsType :: Exp | ||
236 | pattern ConsType <- _ where ConsType = Pi Hidden TType $ Var 0 :~> TList (Var 1) :~> TList (Var 2) | ||
237 | |||
238 | pattern VNil = TCon "Nil" 0 NilType [SListEType] | ||
239 | pattern VCons a b = TCon "Cons" 1 ConsType [SListEType, VT2 a, b] | ||
240 | |||
241 | pattern VT2 :: (String, Exp) -> Exp | ||
242 | pattern VT2 se <- TCon "Tuple2" 0 _ (listT2 -> Just se) where VT2 (s, e) = Tuple2 TString TType (ELit $ LString s) e | ||
243 | |||
244 | listT2 [_, _, ELit (LString s), e] = Just (s, e) | ||
245 | listT2 x = Nothing | ||
246 | |||
247 | pattern SListEType :: Exp | ||
248 | pattern SListEType <- _ where SListEType = tTuple2 TString TType | ||
249 | |||
250 | tTuple2 a b = TTyCon "'Tuple2" (TType :~> TType :~> TType) [a, b] | ||
251 | tTuple3 a b c = TTyCon "'Tuple3" (TType :~> TType :~> TType :~> TType) [a, b, c] | ||
252 | tMat a b c = TTyCon "'Mat" (TNat :~> TNat :~> TType :~> TType) [a, b, c] | ||
253 | |||
254 | toNatE :: Int -> Exp | ||
255 | toNatE 0 = Zero | ||
256 | toNatE n | n > 0 = Succ (toNatE (n - 1)) | ||
257 | |||
258 | t2C TT TT = TT | ||
259 | t2C a b = T2C a b | ||
260 | |||
261 | t2 Unit a = a | ||
262 | t2 a Unit = a | ||
263 | t2 Empty _ = Empty | ||
264 | t2 _ Empty = Empty | ||
265 | t2 a b = TFun "T2" (TType :~> TType :~> TType) [a, b] | ||
266 | |||
267 | pattern EInt a = ELit (LInt a) | ||
268 | pattern EFloat a = ELit (LFloat a) | ||
269 | |||
270 | mkBool False = TCon "False" 0 TBool [] | ||
271 | mkBool True = VTrue | ||
272 | pattern VTrue = TCon "True" 1 TBool [] | ||
273 | |||
274 | pattern LCon <- (isCon -> True) | ||
275 | pattern CFun <- (caseFunName -> True) | ||
276 | |||
277 | pattern a :~> b = Bind (BPi Visible) a b | ||
278 | |||
279 | infixr 1 :~> | ||
280 | |||
281 | caseFunName (Fun f _) = True | ||
282 | caseFunName (CaseFun f _) = True | ||
283 | caseFunName _ = False | ||
284 | |||
285 | isCon = \case | ||
286 | TType -> True | ||
287 | Con _ _ -> True | ||
288 | TyCon _ _ -> True | ||
289 | ELit _ -> True | ||
290 | _ -> False | ||
291 | |||
292 | -------------------------------------------------------------------------------- environments | ||
293 | |||
294 | -- SExp + Exp zipper | ||
295 | data Env | ||
296 | = EBind1 Binder Env SExp -- zoom into first parameter of SBind | ||
297 | | EBind2 Binder Exp Env -- zoom into second parameter of SBind | ||
298 | | EApp1 Visibility Env SExp | ||
299 | | EApp2 Visibility Exp Env | ||
300 | | ELet1 Env SExp | ||
301 | | ELet2 ExpType Env | ||
302 | | EGlobal GlobalEnv [Stmt] | ||
303 | | ELabelEnd Env | ||
304 | |||
305 | | EBind1' Binder Env Exp -- todo: move Exp zipper constructor to a separate ADT (if needed) | ||
306 | | EPrim SName [Exp] Env [Exp] -- todo: move Exp zipper constructor to a separate ADT (if needed) | ||
307 | |||
308 | | EAssign Int Exp Env | ||
309 | | CheckType Exp Env | ||
310 | | CheckSame Exp Env | ||
311 | | CheckAppType Visibility Exp Env SExp | ||
312 | deriving Show | ||
313 | |||
314 | --pattern CheckAppType h t te b = EApp1 h (CheckType t te) b | ||
315 | |||
316 | type GlobalEnv = Map.Map SName (Exp, Type) | ||
317 | |||
318 | extractEnv :: Env -> GlobalEnv | ||
319 | extractEnv = either id extractEnv . parent | ||
320 | |||
321 | parent = \case | ||
322 | EAssign _ _ x -> Right x | ||
323 | EBind2 _ _ x -> Right x | ||
324 | EBind1 _ x _ -> Right x | ||
325 | EBind1' _ x _ -> Right x | ||
326 | EApp1 _ x _ -> Right x | ||
327 | EApp2 _ _ x -> Right x | ||
328 | ELet1 x _ -> Right x | ||
329 | ELet2 _ x -> Right x | ||
330 | CheckType _ x -> Right x | ||
331 | CheckSame _ x -> Right x | ||
332 | CheckAppType _ _ x _ -> Right x | ||
333 | EPrim _ _ x _ -> Right x | ||
334 | ELabelEnd x -> Right x | ||
335 | EGlobal x _ -> Left x | ||
336 | |||
337 | |||
338 | initEnv :: GlobalEnv | ||
339 | initEnv = Map.fromList | ||
340 | [ (,) "Type" (TType, TType) -- needed? | ||
341 | ] | ||
342 | |||
343 | -- monad used during elaborating statments -- TODO: use zippers instead | ||
344 | type ElabStmtM m = StateT GlobalEnv (ExceptT String m) | ||
345 | |||
346 | -------------------------------------------------------------------------------- low-level toolbox | ||
347 | |||
348 | getFunName (fst . getApps' -> Fun f _) = Just f | ||
349 | getFunName _ = Nothing | ||
350 | |||
351 | label x (LabelEnd y) = y | ||
352 | label x y = Label x y | ||
353 | |||
354 | pattern UBind a b c = {-UnLabel-} (Bind a b c) -- todo: review | ||
355 | pattern UApp a b = {-UnLabel-} (App a b) -- todo: review | ||
356 | pattern UVar n = Var n | ||
357 | |||
358 | instance Eq Exp where | ||
359 | Label a _ == Label a' _ = a == a' | ||
360 | Lam' a == Lam' a' = a == a' | ||
361 | Bind a b c == Bind a' b' c' = (a, b, c) == (a', b', c') | ||
362 | -- Assign a b c == Assign a' b' c' = (a, b, c) == (a', b', c') | ||
363 | Fun a b == Fun a' b' = (a, b) == (a', b') | ||
364 | CaseFun a b == CaseFun a' b' = (a, b) == (a', b') | ||
365 | Con a b == Con a' b' = (a, b) == (a', b') | ||
366 | TyCon a b == TyCon a' b' = (a, b) == (a', b') | ||
367 | TType == TType = True | ||
368 | ELit l == ELit l' = l == l' | ||
369 | App a b == App a' b' = (a, b) == (a', b') | ||
370 | Var a == Var a' = a == a' | ||
371 | LabelEnd a == LabelEnd a' = a == a' -- ??? | ||
372 | _ == _ = False | ||
373 | |||
374 | assign :: (Int -> Exp -> Exp -> a) -> (Int -> Exp -> Exp -> a) -> Int -> Exp -> Exp -> a | ||
375 | assign _ clet i (Var j) b | i > j = clet j (Var (i-1)) $ substE "assign" j (Var (i-1)) $ up1E i b | ||
376 | assign clet _ i a b = clet i a b | ||
377 | |||
378 | handleLet i j f | ||
379 | | i > j = f (i-1) j | ||
380 | | i <= j = f i (j+1) | ||
381 | |||
382 | foldS g f i = \case | ||
383 | SApp _ a b -> foldS g f i a <> foldS g f i b | ||
384 | SLet a b -> foldS g f i a <> foldS g f (i+1) b | ||
385 | SBind _ a b -> foldS g f i a <> foldS g f (i+1) b | ||
386 | STyped (e, t) -> foldE f i e <> foldE f i t | ||
387 | SVar j -> foldE f i (Var j) | ||
388 | SGlobal x -> g i x | ||
389 | |||
390 | foldE f i = \case | ||
391 | Label x _ -> foldE f i x | ||
392 | Var k -> f i k | ||
393 | Lam' b -> {-foldE f i t <> todo: explain why this is not needed -} foldE f (i+1) b | ||
394 | Bind _ a b -> foldE f i a <> foldE f (i+1) b | ||
395 | Fun _ as -> foldMap (foldE f i) as | ||
396 | CaseFun _ as -> foldMap (foldE f i) as | ||
397 | Con _ as -> foldMap (foldE f i) as | ||
398 | TyCon _ as -> foldMap (foldE f i) as | ||
399 | TType -> mempty | ||
400 | ELit _ -> mempty | ||
401 | App a b -> foldE f i a <> foldE f i b | ||
402 | Assign j x a -> handleLet i j $ \i' j' -> foldE f i' x <> foldE f i' a | ||
403 | LabelEnd x -> foldE f i x | ||
404 | |||
405 | freeS = nub . foldS (\_ s -> [s]) mempty 0 | ||
406 | freeE = foldE (\i k -> Set.fromList [k - i | k >= i]) 0 | ||
407 | |||
408 | usedS = (getAny .) . foldS mempty ((Any .) . (==)) | ||
409 | usedE = (getAny .) . foldE ((Any .) . (==)) | ||
410 | |||
411 | mapS = mapS_ (const SGlobal) | ||
412 | mapS_ gg ff = mapS__ gg ff $ \i j -> case ff i $ Var j of | ||
413 | Var k -> SVar k | ||
414 | -- x -> STyped x -- todo | ||
415 | mapS__ gg f1 f2 h e = g e where | ||
416 | g i = \case | ||
417 | SApp v a b -> SApp v (g i a) (g i b) | ||
418 | SLet a b -> SLet (g i a) (g (h i) b) | ||
419 | SBind k a b -> SBind k (g i a) (g (h i) b) | ||
420 | STyped (x, t) -> STyped (f1 i x, f1 i t) | ||
421 | SVar j -> f2 i j | ||
422 | SGlobal x -> gg i x | ||
423 | |||
424 | rearrangeS :: (Int -> Int) -> SExp -> SExp | ||
425 | rearrangeS f = mapS__ (const SGlobal) (const id) (\i j -> SVar $ if j < i then j else i + f (j - i)) (+1) 0 | ||
426 | |||
427 | upS__ i n = mapS (\i -> upE i n) (+1) i | ||
428 | upS = upS__ 0 1 | ||
429 | |||
430 | up1E i = \case | ||
431 | Var k -> Var $ if k >= i then k+1 else k | ||
432 | Lam h a b -> Lam h (up1E i a) (up1E (i+1) b) | ||
433 | Bind h a b -> Bind h (up1E i a) (up1E (i+1) b) | ||
434 | Fun s as -> Fun s $ map (up1E i) as | ||
435 | CaseFun s as -> CaseFun s $ map (up1E i) as | ||
436 | Con s as -> Con s $ map (up1E i) as | ||
437 | TyCon s as -> TyCon s $ map (up1E i) as | ||
438 | TType -> TType | ||
439 | ELit l -> ELit l | ||
440 | App a b -> App (up1E i a) (up1E i b) | ||
441 | Assign j a b -> handleLet i j $ \i' j' -> assign Assign Assign j' (up1E i' a) (up1E i' b) | ||
442 | Label x y -> Label (up1E i x) $ up1E i y | ||
443 | LabelEnd x -> LabelEnd $ up1E i x | ||
444 | |||
445 | upE i n e = iterateN n (up1E i) e | ||
446 | |||
447 | substSS :: Int -> SExp -> SExp -> SExp | ||
448 | substSS k x = mapS__ (const SGlobal) (error "substSS") (\(i, x) j -> case compare j i of | ||
449 | EQ -> x | ||
450 | GT -> SVar $ j - 1 | ||
451 | LT -> SVar j | ||
452 | ) ((+1) *** upS) (k, x) | ||
453 | substS j x = mapS (uncurry $ substE "substS") ((+1) *** up1E 0) (j, x) | ||
454 | substSG j x = mapS_ (\x i -> if i == j then x else SGlobal i) (const id) upS x | ||
455 | |||
456 | substE err = substE_ (error $ "substE: todo: environment required in " ++ err) -- todo: remove | ||
457 | |||
458 | substE_ :: Env -> Int -> Exp -> Exp -> Exp | ||
459 | substE_ te i x = \case | ||
460 | Label z v -> label (substE "slab" i x z) $ substE_ te{-todo: label env?-} i x v | ||
461 | Var k -> case compare k i of GT -> Var $ k - 1; LT -> Var k; EQ -> x | ||
462 | Lam h a b -> let -- question: is mutual recursion good here? | ||
463 | a' = substE_ (EBind1' (BLam h) te b') i x a | ||
464 | b' = substE_ (EBind2 (BLam h) a' te) (i+1) (up1E 0 x) b | ||
465 | in Lam h a' b' | ||
466 | Bind h a b -> let -- question: is mutual recursion good here? | ||
467 | a' = substE_ (EBind1' h te b') i x a | ||
468 | b' = substE_ (EBind2 h a' te) (i+1) (up1E 0 x) b | ||
469 | in Bind h a' b' | ||
470 | Fun s as -> eval te $ Fun s [substE_ te{-todo: precise env?-} i x a | (xs, a, ys) <- holes as] | ||
471 | CaseFun s as -> eval te $ CaseFun s [substE_ te{-todo: precise env?-} i x a | (xs, a, ys) <- holes as] | ||
472 | Con s as -> Con s [substE_ te{-todo-} i x a | (xs, a, ys) <- holes as] | ||
473 | TyCon s as -> TyCon s [substE_ te{-todo-} i x a | (xs, a, ys) <- holes as] | ||
474 | TType -> TType | ||
475 | ELit l -> ELit l | ||
476 | App a b -> app_ (substE_ te i x a) (substE_ te i x b) -- todo: precise env? | ||
477 | Assign j a b | ||
478 | | j > i, Just a' <- downE i a -> assign Assign Assign (j-1) a' (substE "sa" i (substE "sa" (j-1) a' x) b) | ||
479 | | j > i, Just x' <- downE (j-1) x -> assign Assign Assign (j-1) (substE "sa" i x' a) (substE "sa" i x' b) | ||
480 | | j < i, Just a' <- downE (i-1) a -> assign Assign Assign j a' (substE "sa" (i-1) (substE "sa" j a' x) b) | ||
481 | | j < i, Just x' <- downE j x -> assign Assign Assign j (substE "sa" (i-1) x' a) (substE "sa" (i-1) x' b) | ||
482 | | j == i -> Meta (cstr x a) $ up1E 0 b | ||
483 | LabelEnd a -> LabelEnd $ substE_ te i x a | ||
484 | |||
485 | downS t x | usedS t x = Nothing | ||
486 | | otherwise = Just $ substS t (error "impossible: downS") x | ||
487 | downE t x | usedE t x = Nothing | ||
488 | | otherwise = Just $ substE_ (error "impossible") t (error "impossible: downE") x | ||
489 | |||
490 | varType :: String -> Int -> Env -> (Binder, Exp) | ||
491 | varType err n_ env = f n_ env where | ||
492 | f n (EAssign i x es) = id *** substE "varType" i x $ f (if n < i then n else n+1) es | ||
493 | f n (EBind2 b t es) = if n == 0 then (b, up1E 0 t) else id *** up1E 0 $ f (n-1) es | ||
494 | f n (ELet2 (x, t) es) = if n == 0 then (BLam Visible{-??-}, up1E 0 t) else id *** up1E 0 $ f (n-1) es | ||
495 | f n e = either (error $ "varType: " ++ err ++ "\n" ++ show n_ ++ "\n" ++ showEnv env) (f n) $ parent e | ||
496 | |||
497 | -------------------------------------------------------------------------------- reduction | ||
498 | |||
499 | infixl 1 `app_` | ||
500 | |||
501 | app_ :: Exp -> Exp -> Exp | ||
502 | app_ (Lam' x) a = substE "app" 0 a x | ||
503 | app_ (Con s xs) a = Con s (xs ++ [a]) | ||
504 | app_ (TyCon s xs) a = TyCon s (xs ++ [a]) | ||
505 | app_ (Label x e) a = label (app_ x a) $ app_ e a | ||
506 | app_ (LabelEnd x) a = LabelEnd (app_ x a) -- ??? | ||
507 | app_ f a = App f a | ||
508 | |||
509 | eval te = \case | ||
510 | App a b -> app_ a b | ||
511 | Cstr a b -> cstr a b | ||
512 | ReflCstr a -> reflCstr te a | ||
513 | Coe a b c d -> coe a b c d | ||
514 | CaseFun (CaseFunName n t pars) (drop (pars + 1) -> ps@(last -> Con (ConName _ _ i _) (drop pars -> vs))) | i /= (-1) -> foldl app_ (ps !! i) vs | ||
515 | T2 a b -> t2 a b | ||
516 | FunN "T2C" [a, b] -> t2C a b | ||
517 | |||
518 | FunN "primAdd" [EInt i, EInt j] -> EInt (i + j) | ||
519 | FunN "primSub" [EInt i, EInt j] -> EInt (i - j) | ||
520 | FunN "primMod" [EInt i, EInt j] -> EInt (i `mod` j) | ||
521 | FunN "primSqrt" [EInt i] -> EInt $ round $ sqrt $ fromIntegral i | ||
522 | FunN "primIntEq" [EInt i, EInt j] -> mkBool (i == j) | ||
523 | FunN "primIntLess" [EInt i, EInt j] -> mkBool (i < j) | ||
524 | |||
525 | FunN "compare" [_,_,EInt x, EInt y] -> mkOrdering $ x `compare` y | ||
526 | FunN "primCompareFloat" [EFloat x, EFloat y] -> mkOrdering $ x `compare` y | ||
527 | FunN "PrimGreaterThan" [_, _, _, _, _, _, _, EFloat x, EFloat y] -> mkBool $ x > y | ||
528 | FunN "PrimSubS" [_, _, _, _, EFloat x, EFloat y] -> EFloat (x - y) | ||
529 | FunN "PrimSubS" [_, _, _, _, EInt x, EInt y] -> EInt (x - y) | ||
530 | FunN "PrimAddS" [_, _, _, _, EFloat x, EFloat y] -> EFloat (x + y) | ||
531 | FunN "PrimMulS" [_, _, _, _, EFloat x, EFloat y] -> EFloat (x * y) | ||
532 | FunN "zeroComp" [TVec (fromNatE -> Just 2) t@TFloat, TT] -> VV2 t (EFloat 0) (EFloat 0) | ||
533 | FunN "zeroComp" [TVec (fromNatE -> Just 3) t@TFloat, TT] -> VV3 t (EFloat 0) (EFloat 0) (EFloat 0) | ||
534 | FunN "zeroComp" [TVec (fromNatE -> Just 4) t@TFloat, TT] -> VV4 t (EFloat 0) (EFloat 0) (EFloat 0) (EFloat 0) | ||
535 | FunN "oneComp" [TVec (fromNatE -> Just 2) t@TFloat, TT] -> VV2 t (EFloat 1) (EFloat 1) | ||
536 | FunN "oneComp" [TVec (fromNatE -> Just 3) t@TFloat, TT] -> VV3 t (EFloat 1) (EFloat 1) (EFloat 1) | ||
537 | FunN "oneComp" [TVec (fromNatE -> Just 4) t@TFloat, TT] -> VV4 t (EFloat 1) (EFloat 1) (EFloat 1) (EFloat 1) | ||
538 | FunN "oneComp" [TVec (fromNatE -> Just 2) t@TBool, TT] -> VV2 t VTrue VTrue | ||
539 | FunN "oneComp" [TVec (fromNatE -> Just 3) t@TBool, TT] -> VV3 t VTrue VTrue VTrue | ||
540 | FunN "oneComp" [TVec (fromNatE -> Just 4) t@TBool, TT] -> VV4 t VTrue VTrue VTrue VTrue | ||
541 | |||
542 | -- todo: elim | ||
543 | Fun n@(FunName "natElim" _ _) [a, z, s, Succ x] -> let -- todo: replace let with better abstraction | ||
544 | sx = s `app_` x | ||
545 | in sx `app_` eval (EApp2 Visible sx te) (Fun n [a, z, s, x]) | ||
546 | FunN "natElim" [_, z, s, Zero] -> z | ||
547 | Fun na@(FunName "finElim" _ _) [m, z, s, n, ConN "FSucc" [i, x]] -> let six = s `app_` i `app_` x-- todo: replace let with better abstraction | ||
548 | in six `app_` eval (EApp2 Visible six te) (Fun na [m, z, s, i, x]) | ||
549 | FunN "finElim" [m, z, s, n, ConN "FZero" [i]] -> z `app_` i | ||
550 | |||
551 | FunN "matchInt" [t, f, TyConN "Int" []] -> t | ||
552 | FunN "matchInt" [t, f, c@LCon] -> f `app_` c | ||
553 | FunN "matchList" [t, f, TyConN "List" [a]] -> t `app_` a | ||
554 | FunN "matchList" [t, f, c@LCon] -> f `app_` c | ||
555 | |||
556 | FunN "Component" [TVec (fromNatE -> Just 3) TFloat] -> Unit | ||
557 | FunN "Component" [TVec (fromNatE -> Just 4) TBool] -> Unit | ||
558 | FunN "Component" [TVec (fromNatE -> Just 4) TFloat] -> Unit | ||
559 | FunN "Floating" [TVec (fromNatE -> Just 2) TFloat] -> Unit | ||
560 | FunN "Floating" [TVec (fromNatE -> Just 4) TFloat] -> Unit | ||
561 | Fun n@(FunName "Eq_" _ _) [TyConN "List" [a]] -> eval te $ Fun n [a] | ||
562 | FunN "Eq_" [TInt] -> Unit | ||
563 | FunN "Eq_" [LCon] -> Empty | ||
564 | FunN "Monad" [TyConN "IO" []] -> Unit | ||
565 | FunN "Signed" [TFloat] -> Unit | ||
566 | FunN "Num" [TFloat] -> Unit | ||
567 | FunN "Num" [TInt] -> Unit | ||
568 | FunN "ValidFrameBuffer" [n] -> Unit -- todo | ||
569 | FunN "ValidOutput" [n] -> Unit -- todo | ||
570 | FunN "AttributeTuple" [n] -> Unit -- todo | ||
571 | FunN "fromInt" [TInt, _, n@EInt{}] -> n | ||
572 | |||
573 | FunN "VecScalar" [Succ Zero, t] -> t | ||
574 | FunN "VecScalar" [n@(Succ (Succ _)), t] -> TVec n t | ||
575 | FunN "TFFrameBuffer" [TyConN "'Image" [n, t]] -> TFrameBuffer n t | ||
576 | FunN "TFFrameBuffer" [TyConN "'Tuple2" [TyConN "'Image" [i@(fromNatE -> Just n), t], TyConN "'Image" [fromNatE -> Just n', t']]] | ||
577 | | n == n' -> TFrameBuffer i $ tTuple2 t t' -- todo | ||
578 | FunN "TFFrameBuffer" [TyConN "'Tuple3" [TyConN "'Image" [i@(fromNatE -> Just n), t], TyConN "'Image" [fromNatE -> Just n', t'], TyConN "'Image" [fromNatE -> Just n'', t'']]] | ||
579 | | n == n' && n == n'' -> TFrameBuffer i $ tTuple3 t t' t'' -- todo | ||
580 | FunN "FragOps" [TyConN "'FragmentOperation" [t]] -> t | ||
581 | FunN "FragOps" [TyConN "'Tuple2" [TyConN "'FragmentOperation" [t], TyConN "'FragmentOperation" [t']]] -> tTuple2 t t' | ||
582 | FunN "FTRepr'" [TyConN "'Tuple2" [TyConN "'Interpolated" [t], TyConN "'Interpolated" [t']]] -> tTuple2 t t' -- todo | ||
583 | FunN "FTRepr'" [TyConN "'Tuple2" [TyConN "'List" [t], TyConN "'List" [t']]] -> tTuple2 t t' -- todo | ||
584 | FunN "FTRepr'" [TyConN "'List" [t]] -> t -- todo | ||
585 | FunN "FTRepr'" [TyConN "'Interpolated" [t]] -> t -- todo | ||
586 | FunN "ColorRepr" [TTuple0] -> TTuple0 | ||
587 | FunN "ColorRepr" [t@NoTup] -> TTyCon "'Color" (TType :~> TType) [t] -- todo | ||
588 | FunN "JoinTupleType" [a@TyConN{}, TTuple0] -> a | ||
589 | FunN "JoinTupleType" [a@NoTup, b@NoTup] -> tTuple2 a b -- todo | ||
590 | FunN "TFMat" [TVec i a, TVec j a'] | a == a' -> tMat i j a -- todo | ||
591 | FunN "MatVecElem" [TVec _ a] -> a | ||
592 | FunN "MatVecElem" [TyConN "'Mat" [_, _, a]] -> a | ||
593 | FunN "MatVecScalarElem" [TVec _ a@TFloat] -> a | ||
594 | FunN "MatVecScalarElem" [a] | a `elem` [TFloat, TBool, TInt] -> a | ||
595 | FunN "fromInt" [TFloat, _, EInt i] -> EFloat $ fromIntegral i | ||
596 | FunN "Split" [TRecord (fromVList -> Just xs), TRecord (fromVList -> Just ys), z] -> t2 (foldr1 t2 [cstr t t' | (n, t) <- xs, (n', t') <- ys, n == n']) $ cstr z (TRecord $ toVList $ filter ((`notElem` map fst ys) . fst) xs) | ||
597 | FunN "Split" [TRecord (fromVList -> Just xs), z, TRecord (fromVList -> Just ys)] -> t2 (foldr1 t2 [cstr t t' | (n, t) <- xs, (n', t') <- ys, n == n']) $ cstr z (TRecord $ toVList $ filter ((`notElem` map fst ys) . fst) xs) | ||
598 | FunN "Split" [z, TRecord (fromVList -> Just xs), TRecord (fromVList -> Just ys)] -> t2 (foldr1 t2 [cstr t t' | (n, t) <- xs, (n', t') <- ys, n == n']) $ cstr z (TRecord $ toVList $ xs ++ filter ((`notElem` map fst xs) . fst) ys) | ||
599 | FunN "project" [_, _, _, ELit (LString s), _, ConN "RecordCons" [fromVList -> Just ns, vs]] | ||
600 | | Just i <- elemIndex s $ map fst ns -> tupsToList vs !! i | ||
601 | FunN "Vec" [a, b] -> TVec a b | ||
602 | FunN "swizzvector" [_, _, _, getVec -> Just (t, vs), getVec' t vs -> Just f] -> f | ||
603 | FunN "swizzscalar" [_, _, getVec -> Just (t, vs), getSwizz -> Just i] -> vs !! i | ||
604 | |||
605 | x -> x | ||
606 | |||
607 | getVec (VV2 t x y) = Just (t, [x, y]) | ||
608 | getVec (VV3 t x y z) = Just (t, [x, y, z]) | ||
609 | getVec (VV4 t x y z w) = Just (t, [x, y, z, w]) | ||
610 | getVec _ = Nothing | ||
611 | |||
612 | getVec' t vs (VV2 _ (getSwizz -> Just sx) (getSwizz -> Just sy)) = Just $ VV2 t (selSwizz sx vs) (selSwizz sy vs) | ||
613 | getVec' t vs (VV3 _ (getSwizz -> Just sx) (getSwizz -> Just sy) (getSwizz -> Just sz)) = Just $ VV3 t (selSwizz sx vs) (selSwizz sy vs) (selSwizz sz vs) | ||
614 | getVec' t vs (VV4 _ (getSwizz -> Just sx) (getSwizz -> Just sy) (getSwizz -> Just sz) (getSwizz -> Just sw)) = Just $ VV4 t (selSwizz sx vs) (selSwizz sy vs) (selSwizz sz vs) (selSwizz sw vs) | ||
615 | getVec' _ _ _ = Nothing | ||
616 | |||
617 | selSwizz i = (!! i) | ||
618 | |||
619 | getSwizz = \case | ||
620 | ConN "Sx" [] -> Just 0 | ||
621 | ConN "Sy" [] -> Just 1 | ||
622 | ConN "Sz" [] -> Just 2 | ||
623 | ConN "Sw" [] -> Just 3 | ||
624 | _ -> Nothing | ||
625 | |||
626 | toVList = foldr VCons VNil | ||
627 | fromVList :: Exp -> Maybe [(String, Exp)] | ||
628 | fromVList (VCons a b) = (a:) <$> fromVList b | ||
629 | fromVList VNil = Just [] | ||
630 | fromVList x = Nothing | ||
631 | |||
632 | tupsToList (Tuple2 _ _ x xs) = x: tupsToList xs | ||
633 | tupsToList Tuple0 = [] | ||
634 | |||
635 | mkOrdering = \case | ||
636 | LT -> TCon "LT" 0 TOrdering [] | ||
637 | EQ -> TCon "EQ" 1 TOrdering [] | ||
638 | GT -> TCon "GT" 2 TOrdering [] | ||
639 | |||
640 | pattern TTuple0 = TTyCon "'Tuple0" TType [] | ||
641 | pattern NoTup <- (noTup -> True) | ||
642 | |||
643 | noTup (TyConN s _) = take 6 s /= "'Tuple" -- todo | ||
644 | noTup _ = False | ||
645 | |||
646 | fromNatE :: Exp -> Maybe Int | ||
647 | fromNatE Zero = Just 0 | ||
648 | fromNatE (Succ n) = (1 +) <$> fromNatE n | ||
649 | |||
650 | -- todo | ||
651 | coe a b c d | a == b = d -- todo | ||
652 | coe a b c d = Coe a b c d | ||
653 | |||
654 | reflCstr te = \case | ||
655 | {- | ||
656 | Unit -> TT | ||
657 | TType -> TT -- ? | ||
658 | Con n xs -> foldl (t2C te{-todo: more precise env-}) TT $ map (reflCstr te{-todo: more precise env-}) xs | ||
659 | TyCon n xs -> foldl (t2C te{-todo: more precise env-}) TT $ map (reflCstr te{-todo: more precise env-}) xs | ||
660 | x -> {-error $ "reflCstr: " ++ show x-} ReflCstr x | ||
661 | -} | ||
662 | x -> TT | ||
663 | |||
664 | cstr = cstr__ [] | ||
665 | where | ||
666 | cstr__ = cstr_ | ||
667 | |||
668 | cstr_ [] a a' | a == a' = Unit | ||
669 | cstr_ ns TType TType = Unit | ||
670 | cstr_ ns (Con a []) (Con a' []) | a == a' = Unit | ||
671 | cstr_ ns (TyCon a []) (TyCon a' []) | a == a' = Unit | ||
672 | cstr_ ns (Var i) (Var i') | i == i', i < length ns = Unit | ||
673 | cstr_ (_: ns) (downE 0 -> Just a) (downE 0 -> Just a') = cstr__ ns a a' | ||
674 | cstr_ ((t, t'): ns) (UApp (downE 0 -> Just a) (UVar 0)) (UApp (downE 0 -> Just a') (UVar 0)) = traceInj2 (a, "V0") (a', "V0") $ cstr__ ns a a' | ||
675 | cstr_ ((t, t'): ns) a (UApp (downE 0 -> Just a') (UVar 0)) = traceInj (a', "V0") a $ cstr__ ns (Lam Visible t a) a' | ||
676 | cstr_ ((t, t'): ns) (UApp (downE 0 -> Just a) (UVar 0)) a' = traceInj (a, "V0") a' $ cstr__ ns a (Lam Visible t' a') | ||
677 | cstr_ ns (Lam h a b) (Lam h' a' b') | h == h' = t2 (cstr__ ns a a') (cstr__ ((a, a'): ns) b b') | ||
678 | cstr_ ns (UBind h a b) (UBind h' a' b') | h == h' = t2 (cstr__ ns a a') (cstr__ ((a, a'): ns) b b') | ||
679 | cstr_ ns (unApp -> Just (a, b)) (unApp -> Just (a', b')) = traceInj2 (a, show b) (a', show b') $ t2 (cstr__ ns a a') (cstr__ ns b b') | ||
680 | -- cstr_ ns (Label f xs _) (Label f' xs' _) | f == f' = foldr1 T2 $ zipWith (cstr__ ns) xs xs' | ||
681 | cstr_ ns (FunN "VecScalar" [a, b]) (TVec a' b') = t2 (cstr__ ns a a') (cstr__ ns b b') | ||
682 | cstr_ ns (FunN "VecScalar" [a, b]) (FunN "VecScalar" [a', b']) = t2 (cstr__ ns a a') (cstr__ ns b b') | ||
683 | cstr_ ns (FunN "VecScalar" [a, b]) t@(TTyCon0 n) | isElemTy n = t2 (cstr__ ns a (toNatE 1)) (cstr__ ns b t) | ||
684 | cstr_ ns t@(TTyCon0 n) (FunN "VecScalar" [a, b]) | isElemTy n = t2 (cstr__ ns a (toNatE 1)) (cstr__ ns b t) | ||
685 | cstr_ ns@[] (FunN "TFMat" [x, y]) (TyConN "'Mat" [i, j, a]) = t2 (cstr__ ns x (TVec i a)) (cstr__ ns y (TVec j a)) | ||
686 | cstr_ ns@[] (TyConN "'Tuple2" [x, y]) (FunN "JoinTupleType" [x'@NoTup, y']) = t2 (cstr__ ns x x') (cstr__ ns y y') | ||
687 | cstr_ ns@[] (TyConN "'Color" [x]) (FunN "ColorRepr" [x']) = cstr__ ns x x' | ||
688 | -- cstr_ ns (TyConN "'FrameBuffer" [a, b]) (FunN "TFFrameBuffer" [TyConN "'Image" [a', b']]) = T2 (cstr__ ns a a') (cstr__ ns b b') | ||
689 | cstr_ [] a@App{} a'@App{} = Cstr a a' | ||
690 | cstr_ [] a@CFun a'@CFun = Cstr a a' | ||
691 | cstr_ [] a@LCon a'@CFun = Cstr a a' | ||
692 | cstr_ [] a@LCon a'@App{} = Cstr a a' | ||
693 | cstr_ [] a@CFun a'@LCon = Cstr a a' | ||
694 | cstr_ [] a@App{} a'@LCon = Cstr a a' | ||
695 | cstr_ [] a a' | isVar a || isVar a' = Cstr a a' | ||
696 | cstr_ ns a a' = trace_ ("!----------------------------! type error:\n" ++ show ns ++ "\nfst:\n" ++ show a ++ "\nsnd:\n" ++ show a') Empty | ||
697 | |||
698 | unApp (UApp a b) = Just (a, b) -- TODO: injectivity check | ||
699 | unApp (Con a xs@(_:_)) = Just (Con a (init xs), last xs) | ||
700 | unApp (TyCon a xs@(_:_)) = Just (TyCon a (init xs), last xs) | ||
701 | unApp _ = Nothing | ||
702 | |||
703 | isVar UVar{} = True | ||
704 | isVar (UApp a b) = isVar a | ||
705 | isVar _ = False | ||
706 | |||
707 | traceInj2 (a, a') (b, b') c | debug && (susp a || susp b) = trace_ (" inj'? " ++ show a ++ " : " ++ a' ++ " ---- " ++ show b ++ " : " ++ b') c | ||
708 | traceInj2 _ _ c = c | ||
709 | traceInj (x, y) z a | debug && susp x = trace_ (" inj? " ++ show x ++ " : " ++ y ++ " ---- " ++ show z) a | ||
710 | traceInj _ _ a = a | ||
711 | |||
712 | susp Con{} = False | ||
713 | susp TyCon{} = False | ||
714 | susp _ = True | ||
715 | |||
716 | isElemTy n = n `elem` ["Bool", "Float", "Int"] | ||
717 | |||
718 | |||
719 | cstr' h x y e = EApp2 h (coe (up1E 0 x) (up1E 0 y) (Var 0) (up1E 0 e)) . EBind2 BMeta (cstr x y) | ||
720 | |||
721 | -------------------------------------------------------------------------------- simple typing | ||
722 | |||
723 | litType = \case | ||
724 | LInt _ -> TInt | ||
725 | LFloat _ -> TFloat | ||
726 | LString _ -> TString | ||
727 | LChar _ -> TChar | ||
728 | |||
729 | expType_ te = \case | ||
730 | Lam h t x -> Pi h t $ expType_ (EBind2 (BLam h) t te) x | ||
731 | App f x -> app (expType_ te{-todo: precise env-} f) x | ||
732 | Var i -> snd $ varType "C" i te | ||
733 | Pi{} -> TType | ||
734 | Label x _ -> expType_ te x | ||
735 | TFun _ t ts -> foldl app t ts | ||
736 | TCaseFun _ t _ ts -> foldl app t ts | ||
737 | TCon _ _ t ts -> foldl app t ts | ||
738 | TTyCon _ t ts -> foldl app t ts | ||
739 | TType -> TType | ||
740 | ELit l -> litType l | ||
741 | Meta{} -> error "meta type" | ||
742 | Assign{} -> error "let type" | ||
743 | LabelEnd x -> expType_ te x | ||
744 | where | ||
745 | app (Pi _ a b) x = substE "expType_" 0 x b | ||
746 | app t x = error $ "app: " ++ show t | ||
747 | |||
748 | -------------------------------------------------------------------------------- inference | ||
749 | |||
750 | type TCM m = ExceptT String m | ||
751 | |||
752 | runTCM = either error id . runExcept | ||
753 | |||
754 | -- todo: do only if NoTypeNamespace extension is not on | ||
755 | lookupName s@('\'':s') m = maybe (Map.lookup s' m) Just $ Map.lookup s m | ||
756 | lookupName s m = Map.lookup s m | ||
757 | elemIndex' s@('\'':s') m = maybe (elemIndex s' m) Just $ elemIndex s m | ||
758 | elemIndex' s m = elemIndex s m | ||
759 | notElem' s@('\'':s') m = notElem s m && notElem s' m | ||
760 | notElem' s m = notElem s m | ||
761 | |||
762 | getDef te s = maybe (throwError $ "getDef: can't find: " ++ s) return (lookupName s $ extractEnv te) | ||
763 | |||
764 | both f = f *** f | ||
765 | |||
766 | inferN :: forall m . Monad m => TraceLevel -> Env -> SExp -> TCM m ExpType | ||
767 | inferN tracelevel = infer where | ||
768 | |||
769 | infer :: Env -> SExp -> TCM m ExpType | ||
770 | infer te exp = (if tracelevel >= 1 then trace_ ("infer: " ++ showEnvSExp te exp) else id) $ (if debug then fmap (recheck' "infer" te *** id) else id) $ case exp of | ||
771 | SLabelEnd x -> infer (ELabelEnd te) x | ||
772 | SVar i -> focus te (Var i) | ||
773 | STyped et -> focus_ te et | ||
774 | SGlobal s -> focus_ te =<< getDef te s | ||
775 | SApp h a b -> infer (EApp1 h te b) a | ||
776 | SLet a b -> infer (ELet1 te b{-in-}) a{-let-} -- infer te (SLam Visible (Wildcard SType) b `SAppV` a) | ||
777 | SBind h a b -> infer ((if h /= BMeta then CheckType TType else id) $ EBind1 h te $ (if isPi h then TyType else id) b) a | ||
778 | |||
779 | checkN :: Env -> SExp -> Exp -> TCM m ExpType | ||
780 | checkN te x t = (if tracelevel >= 1 then trace_ $ "check: " ++ showEnvSExpType te x t else id) $ checkN_ te x t | ||
781 | |||
782 | checkN_ te e t | ||
783 | | SLabelEnd x <- e = checkN_ (ELabelEnd te) x t | ||
784 | | SApp h a b <- e = infer (CheckAppType h t te b) a | ||
785 | | SLam h a b <- e, Pi h' x y <- t, h == h' = if checkSame te a x then checkN (EBind2 (BLam h) x te) b y else error "checkN" | ||
786 | | Pi Hidden a b <- t, notHiddenLam e = checkN (EBind2 (BLam Hidden) a te) (upS e) b | ||
787 | | otherwise = infer (CheckType t te) e | ||
788 | where | ||
789 | -- todo | ||
790 | notHiddenLam = \case | ||
791 | SLam Visible _ _ -> True | ||
792 | SGlobal s | Lam Hidden _ _ <- fst $ fromMaybe (error $ "infer: can't find: " ++ s) $ lookupName s $ extractEnv te -> False | ||
793 | -- todo: use type instead of expr. | ||
794 | | otherwise -> True | ||
795 | _ -> False | ||
796 | |||
797 | -- todo | ||
798 | checkSame te (Wildcard _) a = True | ||
799 | checkSame te (SBind BMeta SType (STyped (Var 0, _))) a = True | ||
800 | checkSame te a b = error $ "checkSame: " ++ show (a, b) | ||
801 | |||
802 | hArgs (Pi Hidden _ b) = 1 + hArgs b | ||
803 | hArgs _ = 0 | ||
804 | |||
805 | focus env e = focus_ env (e, expType_ env e) | ||
806 | |||
807 | focus_ :: Env -> ExpType -> TCM m ExpType | ||
808 | focus_ env (e, et) = (if tracelevel >= 1 then trace_ $ "focus: " ++ showEnvExp env e else id) $ (if debug then fmap (recheck' "focus" env *** id) else id) $ case env of | ||
809 | ELabelEnd te -> focus_ te (LabelEnd e, et) | ||
810 | CheckSame x te -> focus_ (EBind2 BMeta (cstr x e) te) (up1E 0 e, up1E 0 et) | ||
811 | CheckAppType h t te b | ||
812 | | Pi h' x (downE 0 -> Just y) <- et, h == h' -> focus_ (EBind2 BMeta (cstr t y) $ EApp1 h te b) (up1E 0 e, up1E 0 et) | ||
813 | | otherwise -> focus_ (EApp1 h (CheckType t te) b) (e, et) | ||
814 | EApp1 h te b | ||
815 | | Pi h' x y <- et, h == h' -> checkN (EApp2 h e te) b x | ||
816 | | Pi Hidden x y <- et, h == Visible -> focus_ (EApp1 Hidden env $ Wildcard $ Wildcard SType) (e, et) -- e b --> e _ b | ||
817 | | otherwise -> infer (CheckType (Var 2) $ cstr' h (upE 0 2 et) (Pi Visible (Var 1) (Var 1)) (upE 0 2 e) $ EBind2 BMeta TType $ EBind2 BMeta TType te) (upS__ 0 3 b) | ||
818 | ELet1 te b{-in-} -> replaceMetas "let" Lam e >>= \e' -> infer (ELet2 (addType_ te e'{-let-}) te) b{-in-} | ||
819 | ELet2 (x{-let-}, xt) te -> focus_ te (substE "app2" 0 (x{-let-}) ( e{-in-}), et) | ||
820 | CheckType t te | ||
821 | | hArgs et > hArgs t | ||
822 | -> focus_ (EApp1 Hidden (CheckType t te) $ Wildcard $ Wildcard SType) (e, et) | ||
823 | | otherwise -> focus_ (EBind2 BMeta (cstr t et) te) (up1E 0 e, up1E 0 et) | ||
824 | EApp2 h a te -> focus te $ app_ a e -- h?? | ||
825 | EBind1 h te b -> infer (EBind2 h e te) b | ||
826 | EBind2 BMeta tt te | ||
827 | | Unit <- tt -> refocus te $ both (substE_ te 0 TT) (e, et) | ||
828 | | Empty <- tt -> throwError "halt" -- todo: better error msg | ||
829 | | T2 x y <- tt -> let | ||
830 | te' = EBind2 BMeta (up1E 0 y) $ EBind2 BMeta x te | ||
831 | in focus_ te' $ both (substE_ te' 2 (t2C (Var 1) (Var 0)) . upE 0 2) (e, et) | ||
832 | | Cstr a b <- tt, a == b -> refocus te $ both (substE "inferN2" 0 TT) (e, et) | ||
833 | | Cstr a b <- tt, Just r <- cst a b -> r | ||
834 | | Cstr a b <- tt, Just r <- cst b a -> r | ||
835 | | EBind2 h x te' <- te, h /= BMeta{-todo: remove-}, Just x' <- downE 0 tt, x == x' | ||
836 | -> refocus (EBind2 h x te') $ both (substE "inferN3" 1 (Var 0)) (e, et) | ||
837 | | EBind2 h x te' <- te, h /= BMeta, Just b' <- downE 0 tt | ||
838 | -> refocus (EBind2 h (up1E 0 x) $ EBind2 BMeta b' te') $ both (substE "inferN3" 2 (Var 0) . up1E 0) (e, et) | ||
839 | | ELet2 (x, xt) te' <- te, Just b' <- downE 0 tt | ||
840 | -> refocus (ELet2 (up1E 0 x, up1E 0 xt) $ EBind2 BMeta b' te') $ both (substE "inferN32" 2 (Var 0) . up1E 0) (e, et) | ||
841 | | EBind1 h te' x <- te -> refocus (EBind1 h (EBind2 BMeta tt te') $ upS__ 1 1 x) (e, et) | ||
842 | | ELet1 te' x <- te, {-usedE 0 e, -} floatLetMeta $ expType_ env $ replaceMetas' Lam $ Bind BMeta tt e --not (tt == TType) {-todo: tweak?-} | ||
843 | -> refocus (ELet1 (EBind2 BMeta tt te') $ upS__ 1 1 x) (e, et) | ||
844 | | CheckAppType h t te' x <- te -> refocus (CheckAppType h (up1E 0 t) (EBind2 BMeta tt te') $ upS x) (e, et) | ||
845 | | EApp1 h te' x <- te -> refocus (EApp1 h (EBind2 BMeta tt te') $ upS x) (e, et) | ||
846 | | EApp2 h x te' <- te -> refocus (EApp2 h (up1E 0 x) $ EBind2 BMeta tt te') (e, et) | ||
847 | | CheckType t te' <- te -> refocus (CheckType (up1E 0 t) $ EBind2 BMeta tt te') (e, et) | ||
848 | | ELabelEnd te' <- te -> refocus (ELabelEnd $ EBind2 BMeta tt te') (e, et) | ||
849 | | otherwise -> focus_ te (Bind BMeta tt e, et {-???-}) | ||
850 | where | ||
851 | cst x = \case | ||
852 | Var i | fst (varType "X" i te) == BMeta | ||
853 | , Just y <- downE i x | ||
854 | -> Just $ assign'' te i y $ both (substE_ te 0 ({-ReflCstr y-}TT) . substE_ te (i+1) (up1E 0 y)) (e, et) | ||
855 | _ -> Nothing | ||
856 | EBind2 (BLam h) a te -> focus_ te (Lam h a e, Pi h a e) | ||
857 | EBind2 (BPi h) a te -> focus_ te (Bind (BPi h) a e, TType) | ||
858 | EAssign i b te -> case te of | ||
859 | EBind2 h x te' | i > 0, Just b' <- downE 0 b | ||
860 | -> refocus' (EBind2 h (substE "inferN5" (i-1) b' x) (EAssign (i-1) b' te')) (e, et) | ||
861 | ELet2 (x, xt) te' | i > 0, Just b' <- downE 0 b | ||
862 | -> refocus' (ELet2 (substE "inferN51" (i-1) b' x, substE "inferN52" (i-1) b' xt) (EAssign (i-1) b' te')) (e, et) | ||
863 | ELet1 te' x -> refocus' (ELet1 (EAssign i b te') $ substS (i+1) (up1E 0 b) x) (e, et) | ||
864 | EBind1 h te' x -> refocus' (EBind1 h (EAssign i b te') $ substS (i+1) (up1E 0 b) x) (e, et) | ||
865 | CheckAppType h t te' x -> refocus' (CheckAppType h (substE "inferN6" i b t) (EAssign i b te') $ substS i b x) (e, et) | ||
866 | EApp1 h te' x -> refocus' (EApp1 h (EAssign i b te') $ substS i b x) (e, et) | ||
867 | EApp2 h x te' -> refocus' (EApp2 h (substE_ te'{-todo: precise env-} i b x) $ EAssign i b te') (e, et) | ||
868 | CheckType t te' -> refocus' (CheckType (substE "inferN8" i b t) $ EAssign i b te') (e, et) | ||
869 | ELabelEnd te' -> refocus' (ELabelEnd $ EAssign i b te') (e, et) | ||
870 | EAssign j a te' | i < j | ||
871 | -> focus_ (EAssign (j-1) (substE "ea" i b a) $ EAssign i (upE (j-1) 1 b) te') (e, et) | ||
872 | te@EBind2{} -> maybe (assign' te i b (e, et)) (flip refocus' (e, et)) $ pull i te | ||
873 | te@EAssign{} -> maybe (assign' te i b (e, et)) (flip refocus' (e, et)) $ pull i te | ||
874 | -- todo: CheckSame Exp Env | ||
875 | where | ||
876 | pull i = \case | ||
877 | EBind2 BMeta _ te | i == 0 -> Just te | ||
878 | EBind2 h x te -> EBind2 h <$> downE (i-1) x <*> pull (i-1) te | ||
879 | EAssign j b te -> EAssign (if j <= i then j else j-1) <$> downE i b <*> pull (if j <= i then i+1 else i) te | ||
880 | _ -> Nothing | ||
881 | EGlobal{} -> return (e, et) | ||
882 | _ -> error $ "focus: " ++ show env | ||
883 | where | ||
884 | assign', assign'' :: Env -> Int -> Exp -> ExpType -> TCM m ExpType | ||
885 | assign' te i x (e, t) = assign (\i x e -> focus te (Assign i x e)) (foc te) i x e | ||
886 | assign'' te i x (e, t) = assign (foc te) (foc te) i x e | ||
887 | foc te i x = focus $ EAssign i x te | ||
888 | |||
889 | refocus, refocus' :: Env -> ExpType -> TCM m ExpType | ||
890 | refocus = refocus_ focus_ | ||
891 | refocus' = refocus_ refocus' | ||
892 | |||
893 | refocus_ f e (Bind BMeta x a, t) = f (EBind2 BMeta x e) (a, t) | ||
894 | refocus_ _ e (Assign i x a, t) = focus (EAssign i x e) a | ||
895 | refocus_ _ e (a, t) = focus e a | ||
896 | |||
897 | -------------------------------------------------------------------------------- debug support | ||
898 | |||
899 | type Message = String | ||
900 | |||
901 | recheck :: Message -> Env -> Exp -> Exp | ||
902 | recheck msg e = if debug_light then recheck' msg e else id | ||
903 | |||
904 | recheck' :: Message -> Env -> Exp -> Exp | ||
905 | recheck' msg' e x = {-length (showExp e') `seq` -} e' | ||
906 | where | ||
907 | e' = recheck_ "main" (checkEnv e) x | ||
908 | checkEnv = \case | ||
909 | e@EGlobal{} -> e | ||
910 | EBind1 h e b -> EBind1 h (checkEnv e) b | ||
911 | EBind2 h t e -> EBind2 h (recheckEnv e t) $ checkEnv e -- E [\(x :: t) -> e] -> check E [t] | ||
912 | ELet1 e b -> ELet1 (checkEnv e) b | ||
913 | ELet2 (x, t) e -> ELet2 (recheckEnv e x, recheckEnv e t{-?-}) $ checkEnv e | ||
914 | EApp1 h e b -> EApp1 h (checkEnv e) b | ||
915 | EApp2 h a e -> EApp2 h (recheckEnv {-(EApp1 h e _)-}e a) $ checkEnv e -- E [a x] -> check | ||
916 | EAssign i x e -> EAssign i (recheckEnv e $ up1E i x) $ checkEnv e -- __ <i := x> | ||
917 | CheckType x e -> CheckType (recheckEnv e x) $ checkEnv e | ||
918 | CheckSame x e -> CheckSame (recheckEnv e x) $ checkEnv e | ||
919 | CheckAppType h x e y -> CheckAppType h (recheckEnv e x) (checkEnv e) y | ||
920 | |||
921 | recheckEnv = recheck_ "env" | ||
922 | |||
923 | recheck_ msg te = \case | ||
924 | Var k -> Var k | ||
925 | Lam h a b -> Lam h (ch True te{-ok?-} a) $ ch False (EBind2 (BLam h) a te) b | ||
926 | Bind h a b -> Bind h (ch (h /= BMeta) te{-ok?-} a) $ ch (isPi h) (EBind2 h a te) b | ||
927 | App a b -> appf (recheck'' "app1" te{-ok?-} a) (recheck'' "app2" (EApp2 Visible a te) b) | ||
928 | Label z x -> Label (recheck_ msg te z) x | ||
929 | ELit l -> ELit l | ||
930 | TType -> TType | ||
931 | Con s [] -> Con s [] | ||
932 | Con s as -> reApp $ recheck_ "prim" te $ foldl App (Con s []) as | ||
933 | TyCon s [] -> TyCon s [] | ||
934 | TyCon s as -> reApp $ recheck_ "prim" te $ foldl App (TyCon s []) as | ||
935 | CaseFun s [] -> CaseFun s [] | ||
936 | CaseFun s as -> reApp $ recheck_ "fun" te $ foldl App (CaseFun s []) as | ||
937 | Fun s [] -> Fun s [] | ||
938 | Fun s as -> reApp $ recheck_ "fun" te $ foldl App (Fun s []) as | ||
939 | LabelEnd x -> LabelEnd $ recheck_ msg te x | ||
940 | where | ||
941 | reApp (App f x) = case reApp f of | ||
942 | Fun s args -> Fun s $ args ++ [x] | ||
943 | CaseFun s args -> CaseFun s $ args ++ [x] | ||
944 | Con s args -> Con s $ args ++ [x] | ||
945 | TyCon s args -> TyCon s $ args ++ [x] | ||
946 | reApp x = x | ||
947 | |||
948 | -- todo: remove | ||
949 | appf' (a, Pi h x y) (b, x') | ||
950 | | x == x' = (b: a, substE "recheck" 0 b y) | ||
951 | | otherwise = error_ $ "recheck0 " ++ msg ++ "\nexpected: " ++ showEnvExp te x ++ "\nfound: " ++ showEnvExp te x' ++ "\nin term: " ++ showEnvExp te b | ||
952 | |||
953 | appf (a, Pi h x y) (b, x') | ||
954 | | x == x' = app_ a b | ||
955 | | otherwise = error_ $ "recheck " ++ msg' ++ "; " ++ msg ++ "\nexpected: " ++ showEnvExp te{-todo-} x ++ "\nfound: " ++ showEnvExp te{-todo-} x' ++ "\nin term: " ++ showEnvExp te (App a b) | ||
956 | appf (a, t) (b, x') | ||
957 | = error_ $ "recheck " ++ msg' ++ "; " ++ msg ++ "\nnot a pi type: " ++ showEnvExp te{-todo-} t ++ "\n\n" ++ showEnvExp e x | ||
958 | |||
959 | recheck'' msg te a = (b, expType_ te b) where b = recheck_ msg te a | ||
960 | |||
961 | ch False te e = recheck_ "ch" te e | ||
962 | ch True te e = case recheck'' "check" te e of | ||
963 | (e', TType) -> e' | ||
964 | _ -> error_ $ "recheck'':\n" ++ showEnvExp te e | ||
965 | |||
966 | -------------------------------------------------------------------------------- statements | ||
967 | |||
968 | addParams ps t = foldr (uncurry SPi) t ps | ||
969 | |||
970 | getParamsS (SPi h t x) = ((h, t):) *** id $ getParamsS x | ||
971 | getParamsS x = ([], x) | ||
972 | |||
973 | getApps (SApp h a b) = id *** (++ [(h, b)]) $ getApps a -- todo: make it efficient | ||
974 | getApps x = (x, []) | ||
975 | |||
976 | getApps' (App a b) = id *** (++ [b]) $ getApps' a -- todo: make it efficient | ||
977 | getApps' x = (x, []) | ||
978 | |||
979 | arity :: Exp -> Int | ||
980 | arity = length . arity_ | ||
981 | arity_ = map fst . fst . getParams | ||
982 | |||
983 | getParams :: Exp -> ([(Visibility, Exp)], Exp) | ||
984 | getParams (Pi h a b) = ((h, a):) *** id $ getParams b | ||
985 | getParams x = ([], x) | ||
986 | |||
987 | apps a b = foldl SAppV (SGlobal a) b | ||
988 | apps' a b = foldl sapp (SGlobal a) b | ||
989 | |||
990 | replaceMetas err bind = \case | ||
991 | Meta a t -> bind Hidden a <$> replaceMetas err bind t | ||
992 | Assign i x t -> bind Hidden (cstr (Var i) $ upE i 1 x) . up1E 0 . upE i 1 <$> replaceMetas err bind t -- todo: remove? | ||
993 | t -> checkMetas err t | ||
994 | |||
995 | replaceMetas' bind = \case | ||
996 | Meta a t -> bind Hidden a $ replaceMetas' bind t | ||
997 | Assign i x t -> bind Hidden (cstr (Var i) $ upE i 1 x) . up1E 0 . upE i 1 $ replaceMetas' bind t | ||
998 | t -> t | ||
999 | |||
1000 | -- todo: remove | ||
1001 | checkMetas err = \case | ||
1002 | x@Meta{} -> throwError $ "checkMetas " ++ err ++ ": " ++ show x | ||
1003 | x@Assign{} -> throwError $ "checkMetas " ++ err ++ ": " ++ show x | ||
1004 | Lam h a b -> Lam h <$> f a <*> f b | ||
1005 | Bind (BLam _) _ _ -> error "impossible: chm" | ||
1006 | Bind h a b -> Bind h <$> f a <*> f b | ||
1007 | Label z v -> Label <$> f z <*> pure v | ||
1008 | App a b -> App <$> f a <*> f b | ||
1009 | Fun s xs -> Fun s <$> mapM f xs | ||
1010 | CaseFun s xs -> CaseFun s <$> mapM f xs | ||
1011 | Con s xs -> Con s <$> mapM f xs | ||
1012 | TyCon s xs -> TyCon s <$> mapM f xs | ||
1013 | x@TType -> pure x | ||
1014 | x@ELit{} -> pure x | ||
1015 | x@Var{} -> pure x | ||
1016 | LabelEnd x -> LabelEnd <$> f x | ||
1017 | where | ||
1018 | f = checkMetas err | ||
1019 | |||
1020 | getGEnv f = gets (flip EGlobal mempty) >>= f | ||
1021 | inferTerm msg tr f t = getGEnv $ \env -> let env' = f env in smartTrace $ \tr -> | ||
1022 | fmap (\t -> if tr_light then length (showExp $ fst t) `seq` t else t) $ fmap (addType . recheck msg env') $ replaceMetas "lam" Lam . fst =<< lift (inferN (if tr then trace_level else 0) env' t) | ||
1023 | inferType tr t = getGEnv $ \env -> fmap (recheck "inferType" env) $ replaceMetas "pi" Pi . fst =<< lift (inferN (if tr then trace_level else 0) (CheckType TType env) t) | ||
1024 | |||
1025 | smartTrace :: MonadError String m => (Bool -> m a) -> m a | ||
1026 | smartTrace f | trace_level >= 2 = f True | ||
1027 | smartTrace f | trace_level == 0 = f False | ||
1028 | smartTrace f = catchError (f False) $ \err -> | ||
1029 | trace_ (unlines | ||
1030 | [ "---------------------------------" | ||
1031 | , err | ||
1032 | , "try again with trace" | ||
1033 | , "---------------------------------" | ||
1034 | ]) $ f True | ||
1035 | |||
1036 | addToEnv :: Monad m => String -> (Exp, Exp) -> ElabStmtM m () | ||
1037 | --addToEnv s (x, t) | Just msg <- ambiguityCheck s t = throwError msg | ||
1038 | addToEnv s (x, t) = do | ||
1039 | maybe (pure ()) throwError_ $ ambiguityCheck s t | ||
1040 | (if tr_light then trace_ (s ++ " :: " ++ showExp t) else id) $ modify $ Map.alter (Just . maybe (x, t) (const $ error $ "already defined: " ++ s)) s | ||
1041 | |||
1042 | -- Ambiguous: (Int ~ F a) => Int | ||
1043 | -- Not ambiguous: (Show a, a ~ F b) => b | ||
1044 | ambiguityCheck :: String -> Exp -> Maybe String | ||
1045 | ambiguityCheck s ty = case ambigVars ty of | ||
1046 | [] -> Nothing | ||
1047 | err -> Just $ s ++ " has ambiguous type:\n" ++ showExp ty ++ "\nproblematic vars:\n" ++ show err | ||
1048 | |||
1049 | ambigVars :: Exp -> [(Int, Exp)] | ||
1050 | ambigVars ty = [(n, c) | (n, c) <- hid, not $ any (`Set.member` defined) $ Set.insert n $ freeE c] | ||
1051 | where | ||
1052 | defined = dependentVars hid $ freeE ty' | ||
1053 | |||
1054 | i = length hid_ | ||
1055 | hid = zipWith (\k t -> (k, upE 0 (k+1) t)) (reverse [0..i-1]) hid_ | ||
1056 | (hid_, ty') = hiddenVars ty | ||
1057 | |||
1058 | floatLetMeta :: Exp -> Bool | ||
1059 | floatLetMeta ty = (i-1) `Set.member` defined | ||
1060 | where | ||
1061 | defined = dependentVars hid $ Set.map (+i) $ freeE ty | ||
1062 | |||
1063 | i = length hid_ | ||
1064 | hid = zipWith (\k t -> (k, upE 0 (k+1) t)) (reverse [0..i-1]) hid_ | ||
1065 | (hid_, ty') = hiddenVars ty | ||
1066 | |||
1067 | hiddenVars (Pi Hidden a b) = (a:) *** id $ hiddenVars b | ||
1068 | hiddenVars t = ([], t) | ||
1069 | |||
1070 | -- compute dependent type vars in constraints | ||
1071 | -- Example: dependentVars [(a, b) ~ F b c, d ~ F e] [c] == [a,b,c] | ||
1072 | dependentVars :: [(Int, Exp)] -> Set.Set Int -> Set.Set Int | ||
1073 | dependentVars ie s = cycle mempty s | ||
1074 | where | ||
1075 | freeVars = freeE | ||
1076 | |||
1077 | cycle acc s | ||
1078 | | Set.null s = acc | ||
1079 | | otherwise = cycle (acc <> s) (grow s Set.\\ acc) | ||
1080 | |||
1081 | grow = flip foldMap ie $ \case | ||
1082 | (n, t) -> (Set.singleton n <-> freeVars t) <> case t of | ||
1083 | Cstr ty f -> freeVars ty <-> freeVars f | ||
1084 | CSplit a b c -> freeVars a <-> (freeVars b <> freeVars c) | ||
1085 | -- CUnify{} -> mempty --error "dependentVars: impossible" | ||
1086 | _ -> mempty | ||
1087 | -- (n, ISubst False x) -> (Set.singleton n <-> freeVars x) | ||
1088 | where | ||
1089 | a --> b = \s -> if Set.null $ a `Set.intersection` s then mempty else b | ||
1090 | a <-> b = (a --> b) <> (b --> a) | ||
1091 | |||
1092 | expType = expType_ (EGlobal initEnv []) | ||
1093 | addType x = (x, expType x) | ||
1094 | addType_ te x = (x, expType_ te x) | ||
1095 | |||
1096 | downTo n m = map SVar [n+m-1, n+m-2..n] | ||
1097 | |||
1098 | defined' = Map.keys | ||
1099 | |||
1100 | addF = gets $ addForalls . defined' | ||
1101 | |||
1102 | fixType = Pi Hidden TType $ Pi Visible (Pi Visible (Var 0) (Var 1)) (Var 1) -- forall a . (a -> a) -> a | ||
1103 | |||
1104 | handleStmt :: MonadFix m => Stmt -> ElabStmtM m () | ||
1105 | handleStmt = \case | ||
1106 | PrecDef{} -> return () | ||
1107 | -- non-recursive let | ||
1108 | Let n mf mt ar (downS 0 -> Just t_) -> {-trace ("begin: " ++ n) $ -} do | ||
1109 | af <- addF | ||
1110 | (x, t) <- inferTerm n tr id (maybe id (flip SAnn . af) mt t_) | ||
1111 | let addLams [] _ e = Fun (FunName n mf t) $ reverse e | ||
1112 | addLams (h: ar) (Pi h' d t) e | h == h' = Lam h d $ addLams ar t (Var 0: map (up1E 0) e) | ||
1113 | addLams ar@(Visible: _) (Pi h@Hidden d t) e = Lam h d $ addLams ar t (Var 0: map (up1E 0) e) | ||
1114 | addToEnv n (label (addLams ar t []) x, t) | ||
1115 | -- recursive let | ||
1116 | Let n mf mt ar t_ -> do | ||
1117 | af <- addF | ||
1118 | (x@(Lam Hidden _ e), _) | ||
1119 | <- {-trace ("beg: " ++ n) $ -} inferTerm n tr (EBind2 BMeta fixType) (SAppV (SVar 0) $ SLam Visible (Wildcard SType) $ maybe id (flip SAnn . af) mt t_) | ||
1120 | let | ||
1121 | par i (Lam Hidden k z) = Lam Hidden k $ par (i+1) z | ||
1122 | par i (Var i' `App` _ `App` f) | i == i' = x where | ||
1123 | x = label (Fun (FunName n mf t) $ map Var $ reverse [0..i-1]) $ f `app_` x | ||
1124 | |||
1125 | x' = x `app_` (Lam Hidden TType $ Lam Visible (Pi Visible (Var 0) (Var 1)) $ TFun "f_i_x" fixType [Var 1, Var 0]) | ||
1126 | t = expType x' | ||
1127 | |||
1128 | {- trace_ (n ++ ": " ++ showExp t) $ -} | ||
1129 | addToEnv n (par 0 e, traceD ("addToEnv: " ++ n ++ " = " ++ showExp x') t) | ||
1130 | -- primitive | ||
1131 | Primitive con n t_ -> do | ||
1132 | t <- inferType tr =<< ($ t_) <$> addF | ||
1133 | addToEnv n $ flip (,) t $ case con of | ||
1134 | Just True -> TyCon (TyConName n Nothing (error "todo: inum3") t (error "todo: tcn cons 1") $ error "tycon case type") [] | ||
1135 | Just False -> Con (ConName n Nothing (-1) t) [] | ||
1136 | Nothing -> {-Label (Fun (FunName n Nothing t) []) $ -} f t | ||
1137 | where | ||
1138 | f (Pi h a b) = Lam h a $ f b | ||
1139 | f _ = TFun n t $ map Var $ reverse [0..arity t - 1] | ||
1140 | Data s ps t_ cs -> do | ||
1141 | af <- gets $ addForalls . (s:) . defined' | ||
1142 | vty <- inferType tr $ addParams ps t_ | ||
1143 | let | ||
1144 | pnum' = length $ filter ((== Visible) . fst) ps | ||
1145 | inum = arity vty - length ps | ||
1146 | |||
1147 | mkConstr j (cn, af -> ct) | ||
1148 | | c == SGlobal s && take pnum' xs == downTo (length . fst . getParamsS $ ct) pnum' | ||
1149 | = do | ||
1150 | cty <- removeHiddenUnit <$> inferType tr (addParams [(Hidden, x) | (Visible, x) <- ps] ct) | ||
1151 | let pars = zipWith (\x -> id *** STyped . flip (,) TType . upE x (1+j)) [0..] $ drop (length ps) $ fst $ getParams cty | ||
1152 | act = length . fst . getParams $ cty | ||
1153 | acts = map fst . fst . getParams $ cty | ||
1154 | conn = ConName cn Nothing j cty | ||
1155 | addToEnv cn (Con conn [], cty) | ||
1156 | return ( conn | ||
1157 | , addParams pars | ||
1158 | $ foldl SAppV (SVar $ j + length pars) $ drop pnum' xs ++ [apps' cn (zip acts $ downTo (j+1+length pars) (length ps) ++ downTo 0 (act- length ps))] | ||
1159 | ) | ||
1160 | | otherwise = throwError $ "illegal data definition (parameters are not uniform) " -- ++ show (c, cn, take pnum' xs, act) | ||
1161 | where | ||
1162 | (c, map snd -> xs) = getApps $ snd $ getParamsS ct | ||
1163 | |||
1164 | motive = addParams (replicate inum (Visible, Wildcard SType)) $ | ||
1165 | SPi Visible (apps' s $ zip (map fst ps) (downTo inum $ length ps) ++ zip (map fst $ fst $ getParamsS t_) (downTo 0 inum)) SType | ||
1166 | |||
1167 | addToEnv'' s t cs ct = addToEnv s (TyCon (TyConName s Nothing inum t cs ct) [], t) | ||
1168 | addToEnv''' _ s t i = addToEnv s (f t, t) | ||
1169 | where | ||
1170 | f (Pi h a b) = Lam h a $ f b | ||
1171 | f _ = TCaseFun s t i $ map Var $ reverse [0..arity t - 1] | ||
1172 | mdo | ||
1173 | addToEnv'' s vty (map fst cons) ct | ||
1174 | cons <- zipWithM mkConstr [0..] cs | ||
1175 | ct <- inferType tr | ||
1176 | ( (\x -> traceD ("type of case-elim before elaboration: " ++ showSExp x) x) $ addParams | ||
1177 | ( [(Hidden, x) | (_, x) <- ps] | ||
1178 | ++ (Visible, motive) | ||
1179 | : map ((,) Visible . snd) cons | ||
1180 | ++ replicate inum (Hidden, Wildcard SType) | ||
1181 | ++ [(Visible, apps' s $ zip (map fst ps) (downTo (inum + length cs + 1) $ length ps) ++ zip (map fst $ fst $ getParamsS t_) (downTo 0 inum))] | ||
1182 | ) | ||
1183 | $ foldl SAppV (SVar $ length cs + inum + 1) $ downTo 1 inum ++ [SVar 0] | ||
1184 | ) | ||
1185 | addToEnv''' False (caseName s) ct (length ps) | ||
1186 | |||
1187 | removeHiddenUnit (Pi Hidden Unit (downE 0 -> Just t)) = removeHiddenUnit t | ||
1188 | removeHiddenUnit (Pi h a b) = Pi h a $ removeHiddenUnit b | ||
1189 | removeHiddenUnit t = t | ||
1190 | |||
1191 | -------------------------------------------------------------------------------- parser | ||
1192 | |||
1193 | addForalls :: [SName] -> SExp -> SExp | ||
1194 | addForalls defined x = foldl f x [v | v <- reverse $ freeS x, v `notElem'` defined] | ||
1195 | where | ||
1196 | f e v = SPi Hidden (Wildcard SType) $ substSG v (SVar 0) $ upS e | ||
1197 | |||
1198 | defined defs = ("Type":) $ flip foldMap defs $ \case | ||
1199 | TypeAnn x _ -> [x] | ||
1200 | Let x _ _ _ _ -> [x] | ||
1201 | Data x _ _ cs -> x: map fst cs | ||
1202 | Primitive _ x _ -> [x] | ||
1203 | |||
1204 | type InnerP = Reader GlobalEnv' | ||
1205 | |||
1206 | type P = ParsecT (IndentStream (CharIndentStream String)) SourcePos InnerP | ||
1207 | |||
1208 | lexer :: Pa.GenTokenParser (IndentStream (CharIndentStream String)) SourcePos InnerP | ||
1209 | lexer = makeTokenParser $ makeIndentLanguageDef style | ||
1210 | where | ||
1211 | style = Pa.LanguageDef | ||
1212 | { Pa.commentStart = "{-" | ||
1213 | , Pa.commentEnd = "-}" | ||
1214 | , Pa.commentLine = "--" | ||
1215 | , Pa.nestedComments = True | ||
1216 | , Pa.identStart = letter <|> oneOf "_" | ||
1217 | , Pa.identLetter = alphaNum <|> oneOf "_'" | ||
1218 | , Pa.opStart = Pa.opLetter style | ||
1219 | , Pa.opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~" | ||
1220 | , Pa.reservedOpNames= ["->", "=>", "~", "\\", "|", "::", "<-", "=", "@", ".."] | ||
1221 | , Pa.reservedNames = ["forall", "data", "builtins", "builtincons", "builtintycons", "_", "case", "of", "where", "import", "module", "let", "in", "infix", "infixr", "infixl", "if", "then", "else", "class", "instance"] | ||
1222 | , Pa.caseSensitive = True | ||
1223 | } | ||
1224 | |||
1225 | position :: P SourcePos | ||
1226 | position = getPosition | ||
1227 | |||
1228 | positionBeforeSpace :: P SourcePos | ||
1229 | positionBeforeSpace = getState | ||
1230 | |||
1231 | optional :: P a -> P (Maybe a) | ||
1232 | optional = optionMaybe | ||
1233 | |||
1234 | keyword :: String -> P () | ||
1235 | keyword = Pa.reserved lexer | ||
1236 | |||
1237 | operator :: String -> P () | ||
1238 | operator = Pa.reservedOp lexer | ||
1239 | |||
1240 | tick (Just True, _) ('\'':n) = n | ||
1241 | tick (Just True, _) n | n `elem` ["Type", "Nat", "Float", "Int", "Bool", "IO", "Unit", "Empty", "T2"] = n | ||
1242 | | otherwise = '\'': n | ||
1243 | tick _ n = n | ||
1244 | |||
1245 | lcIdents ns = tick ns <$> ((++) <$> (option [] $ ("'" <$ char '\'')) <*> Pa.identifier lexer) | ||
1246 | |||
1247 | lcOps = Pa.operator lexer | ||
1248 | |||
1249 | ident = id | ||
1250 | parens = Pa.parens lexer | ||
1251 | braces = Pa.braces lexer | ||
1252 | brackets = Pa.brackets lexer | ||
1253 | commaSep = Pa.commaSep lexer | ||
1254 | commaSep1 = Pa.commaSep1 lexer | ||
1255 | dot = Pa.dot lexer | ||
1256 | comma = Pa.comma lexer | ||
1257 | colon = Pa.colon lexer | ||
1258 | natural = Pa.natural lexer | ||
1259 | integer = Pa.integer lexer | ||
1260 | float = Pa.float lexer | ||
1261 | charLiteral = Pa.charLiteral lexer | ||
1262 | stringLiteral = Pa.stringLiteral lexer | ||
1263 | whiteSpace = Pa.whiteSpace lexer | ||
1264 | |||
1265 | data Extension | ||
1266 | = NoImplicitPrelude | ||
1267 | | NoTypeNamespace | ||
1268 | | NoConstructorNamespace | ||
1269 | deriving (Eq, Ord, Show) | ||
1270 | |||
1271 | type Name = String | ||
1272 | type DefinitionR = Stmt | ||
1273 | |||
1274 | data Export = ExportModule Name | ExportId Name | ||
1275 | |||
1276 | data ModuleR | ||
1277 | = Module | ||
1278 | { extensions :: [Extension] | ||
1279 | , moduleImports :: [Name] -- TODO | ||
1280 | , moduleExports :: Maybe [Export] | ||
1281 | , definitions :: GlobalEnv' -> Either String [DefinitionR] | ||
1282 | } | ||
1283 | |||
1284 | (<&>) = flip (<$>) | ||
1285 | |||
1286 | -------------------------------------------------------------------------------- parser combinators | ||
1287 | |||
1288 | -- see http://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/comment-page-1/#comment-6602 | ||
1289 | try' s m = try m <?> s | ||
1290 | {- | ||
1291 | qualified_ id = do | ||
1292 | q <- try' "qualification" $ upperCase' <* dot | ||
1293 | (N t qs n i) <- qualified_ id | ||
1294 | return $ N t (q:qs) n i | ||
1295 | <|> | ||
1296 | id | ||
1297 | where | ||
1298 | upperCase' = (:) <$> satisfy isUpper <*> many (satisfy isAlphaNum) | ||
1299 | -} | ||
1300 | -------------------------------------------------------------------------------- identifiers | ||
1301 | |||
1302 | check msg p m = try' msg $ do | ||
1303 | x <- m | ||
1304 | if p x then return x else fail $ msg ++ " expected" | ||
1305 | |||
1306 | --upperCase, lowerCase, symbols, colonSymbols :: P String | ||
1307 | upperCase (Nothing, _) = mzero -- todo | ||
1308 | upperCase ns = (if snd ns then check "uppercase ident" (isUpper . head) else id) $ ident $ lcIdents ns | ||
1309 | lowerCase ns = (if snd ns then check "lowercase ident" (isLower . head) else id) (ident $ lcIdents ns) <|> try (('_':) <$ char '_' <*> ident (lcIdents ns)) | ||
1310 | symbols = check "symbols" ((/=':') . head) $ ident lcOps | ||
1311 | colonSymbols = "Cons" <$ operator ":" <|> check "symbols" ((==':') . head) (ident lcOps) | ||
1312 | |||
1313 | -------------------------------------------------------------------------------- | ||
1314 | |||
1315 | pattern ExpN' :: String -> P.Doc -> String | ||
1316 | pattern ExpN' s p <- ((,) undefined -> (p, s)) where ExpN' s p = s | ||
1317 | pattern ExpN s = s | ||
1318 | |||
1319 | --typeConstructor, upperCaseIdent, typeVar, var, varId, qIdent, operator', conOperator, moduleName :: P Name | ||
1320 | --typeConstructor = upperCase <&> \i -> TypeN' i (Pa.text i) | ||
1321 | upperCaseIdent ns = upperCase ns <&> ExpN | ||
1322 | --typeVar = (\p i -> TypeN' i $ P.text $ i ++ show p) <$> position <*> lowerCase | ||
1323 | var ns = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> lowerCase ns | ||
1324 | qIdent ns = {-qualified_ todo-} (var ns <|> upperCaseIdent ns) | ||
1325 | conOperator = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> colonSymbols | ||
1326 | varId ns = var ns <|> parens operator' | ||
1327 | backquotedIdent = try' "backquoted" $ char '`' *> (ExpN <$> ((:) <$> satisfy isAlpha <*> many (satisfy isAlphaNum))) <* char '`' <* whiteSpace | ||
1328 | operator' = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> symbols | ||
1329 | <|> conOperator | ||
1330 | <|> backquotedIdent | ||
1331 | moduleName = {-qualified_ todo-} upperCaseIdent (Just False, False) | ||
1332 | |||
1333 | -------------------------------------------------------------------------------- fixity declarations | ||
1334 | |||
1335 | fixityDef :: P [DefinitionR] | ||
1336 | fixityDef = do | ||
1337 | dir <- Nothing <$ keyword "infix" | ||
1338 | <|> Just FDLeft <$ keyword "infixl" | ||
1339 | <|> Just FDRight <$ keyword "infixr" | ||
1340 | localIndentation Gt $ do | ||
1341 | i <- natural | ||
1342 | ns <- commaSep1 operator' | ||
1343 | return [PrecDef n (dir, fromIntegral i) | n <- ns] | ||
1344 | |||
1345 | -------------------------------------------------------------------------------- | ||
1346 | |||
1347 | export :: Namespace -> P Export | ||
1348 | export ns = | ||
1349 | ExportModule <$ keyword "module" <*> moduleName | ||
1350 | <|> ExportId <$> varId ns | ||
1351 | |||
1352 | parseExtensions :: P [Extension] | ||
1353 | parseExtensions = do | ||
1354 | try (string "{-#") | ||
1355 | simpleSpace | ||
1356 | string "LANGUAGE" | ||
1357 | simpleSpace | ||
1358 | s <- commaSep ext | ||
1359 | simpleSpace | ||
1360 | string "#-}" | ||
1361 | simpleSpace | ||
1362 | return s | ||
1363 | where | ||
1364 | simpleSpace = skipMany (satisfy isSpace) | ||
1365 | |||
1366 | ext = do | ||
1367 | s <- some $ satisfy isAlphaNum | ||
1368 | case s of | ||
1369 | "NoImplicitPrelude" -> return NoImplicitPrelude | ||
1370 | "NoTypeNamespace" -> return NoTypeNamespace | ||
1371 | "NoConstructorNamespace" -> return NoConstructorNamespace | ||
1372 | _ -> fail $ "language extension expected instead of " ++ s | ||
1373 | |||
1374 | importlist ns = parens (commaSep (varId ns <|> upperCaseIdent ns)) | ||
1375 | |||
1376 | parse :: SourceName -> String -> Either String ModuleR | ||
1377 | parse f str = x | ||
1378 | where | ||
1379 | x = (show +++ id) . flip runReader (error "globalenv used") . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ str | ||
1380 | |||
1381 | p = do | ||
1382 | getPosition >>= setState | ||
1383 | setPosition =<< flip setSourceName f <$> getPosition | ||
1384 | exts <- concat <$> many parseExtensions | ||
1385 | let ns = (if NoTypeNamespace `elem` exts then Nothing else Just False, not $ NoConstructorNamespace `elem` exts) | ||
1386 | whiteSpace | ||
1387 | header <- optional $ do | ||
1388 | modn <- keyword "module" *> moduleName | ||
1389 | exps <- optional (parens $ commaSep $ export ns) | ||
1390 | keyword "where" | ||
1391 | return (modn, exps) | ||
1392 | idefs <- many $ keyword "import" *> moduleName | ||
1393 | <* optional (keyword "hiding" *> importlist ns <|> importlist ns) | ||
1394 | <* optional (keyword "as" *> moduleName) | ||
1395 | |||
1396 | st <- getParserState | ||
1397 | |||
1398 | let defs ge = (show +++ id) . flip runReader ge . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ "" | ||
1399 | where | ||
1400 | p = do | ||
1401 | setParserState st | ||
1402 | parseStmts SLabelEnd ns [] <* eof | ||
1403 | return $ Module | ||
1404 | { extensions = exts | ||
1405 | , moduleImports = if NoImplicitPrelude `elem` exts | ||
1406 | then idefs | ||
1407 | else ExpN "Prelude": idefs | ||
1408 | , moduleExports = join $ snd <$> header | ||
1409 | , definitions = defs | ||
1410 | } | ||
1411 | |||
1412 | parseType ns mb vs = maybe id option mb $ operator "::" *> parseTTerm ns PrecLam vs | ||
1413 | patVar ns = lcIdents ns <|> "" <$ keyword "_" | ||
1414 | patVar2 ns = lowerCase ns <|> "" <$ keyword "_" | ||
1415 | typedId ns mb vs = (,) <$> patVar ns <*> localIndentation Gt {-TODO-} (parseType ns mb vs) | ||
1416 | typedId' ns mb vs = (,) <$> commaSep1 (varId ns <|> patVar ns) <*> localIndentation Gt {-TODO-} (parseType ns mb vs) | ||
1417 | |||
1418 | telescope ns mb vs = option (vs, []) $ do | ||
1419 | (x, vt) <- | ||
1420 | operator "@" *> (maybe empty (\x -> flip (,) (Hidden, x) <$> patVar ns) mb <|> parens (f Hidden)) | ||
1421 | <|> try (parens $ f Visible) | ||
1422 | <|> maybe ((,) "" . (,) Visible <$> parseTerm ns PrecAtom vs) (\x -> flip (,) (Visible, x) <$> patVar ns) mb | ||
1423 | (id *** (vt:)) <$> telescope ns mb (x: vs) | ||
1424 | where | ||
1425 | f v = (id *** (,) v) <$> typedId ns mb vs | ||
1426 | |||
1427 | parseClause ns e = do | ||
1428 | (fe, p) <- pattern' ns e | ||
1429 | localIndentation Gt $ do | ||
1430 | x <- operator "->" *> parseETerm ns PrecLam fe | ||
1431 | f <- parseWhereBlock ns fe | ||
1432 | return (p, f x) | ||
1433 | |||
1434 | patternAtom ns vs = | ||
1435 | (,) vs . flip ViewPat eqPP . SAppV (SGlobal "primCompareFloat") . sLit . LFloat <$> try float | ||
1436 | <|> (,) vs . flip ViewPat eqPP . SAppV (SGlobal "primCompareInt") . sLit . LInt . fromIntegral <$> natural | ||
1437 | <|> (,) <$> ((:vs) <$> patVar2 ns) <*> (pure PVar) | ||
1438 | <|> (,) vs . flip PCon [] <$> upperCaseIdent ns | ||
1439 | <|> (id *** mkListPat) <$> brackets (patlist ns vs <|> pure (vs, [])) | ||
1440 | <|> (id *** mkTupPat) <$> parens (patlist ns vs) | ||
1441 | |||
1442 | eqPP = ParPat [PCon "EQ" []] | ||
1443 | truePP = ParPat [PCon "True" []] | ||
1444 | |||
1445 | patlist ns vs = commaSep1' (\vs -> (\(vs, p) t -> (vs, patType p t)) <$> pattern' ns vs <*> parseType ns (Just $ Wildcard SType) vs) vs | ||
1446 | |||
1447 | mkListPat (p: ps) = PCon "Cons" $ map (ParPat . (:[])) [p, mkListPat ps] | ||
1448 | mkListPat [] = PCon "Nil" [] | ||
1449 | |||
1450 | pattern' ns vs = | ||
1451 | {-((,) vs . PLit . LFloat) <$> try float | ||
1452 | <|> -}pCon <$> upperCaseIdent ns <*> patterns ns vs | ||
1453 | <|> (patternAtom ns vs >>= \(vs, p) -> option (vs, p) ((id *** (\p' -> PCon "Cons" (ParPat . (:[]) <$> [p, p']))) <$ operator ":" <*> pattern' ns vs)) | ||
1454 | |||
1455 | patterns ns vs = | ||
1456 | do patternAtom ns vs >>= \(vs, p) -> patterns ns vs >>= \(vs, ps) -> pure (vs, ParPat [p]: ps) | ||
1457 | <|> pure (vs, []) | ||
1458 | |||
1459 | pCon i (vs, x) = (vs, PCon i x) | ||
1460 | |||
1461 | patType p (Wildcard SType) = p | ||
1462 | patType p t = PatType (ParPat [p]) t | ||
1463 | |||
1464 | mkTupPat :: [Pat] -> Pat | ||
1465 | mkTupPat [x] = x | ||
1466 | mkTupPat ps = PCon ("Tuple" ++ show (length ps)) (ParPat . (:[]) <$> ps) | ||
1467 | |||
1468 | commaSep1' :: (t -> P (t, a)) -> t -> P (t, [a]) | ||
1469 | commaSep1' p vs = | ||
1470 | p vs >>= \(vs, x) -> (\(vs, xs) -> (vs, x: xs)) <$ comma <*> commaSep1' p vs | ||
1471 | <|> pure (vs, [x]) | ||
1472 | |||
1473 | commaSep' :: (t -> P (t, a)) -> t -> P (t, [a]) | ||
1474 | commaSep' p vs = | ||
1475 | commaSep1' p vs | ||
1476 | <|> pure (vs, []) | ||
1477 | |||
1478 | telescope' ns vs = option (vs, []) $ do | ||
1479 | (vs', vt) <- | ||
1480 | operator "@" *> (f Hidden <$> patternAtom ns vs) | ||
1481 | <|> f Visible <$> patternAtom ns vs | ||
1482 | (id *** (vt:)) <$> telescope' ns vs' | ||
1483 | where | ||
1484 | f h (vs, PatType (ParPat [p]) t) = (vs, ((h, t), p)) | ||
1485 | f h (vs, p) = (vs, ((h, Wildcard SType), p)) | ||
1486 | |||
1487 | parseStmts lend ns e = (asks $ \ge -> pairTypeAnns ge . concat) <*> some (parseStmt ns e) | ||
1488 | where | ||
1489 | pairTypeAnns ge ds = concatMap f $ groupBy h ds where | ||
1490 | h (FunAlt n _ _ _) (FunAlt m _ _ _) = m == n | ||
1491 | h _ _ = False | ||
1492 | |||
1493 | f [TypeAnn{}] = [] | ||
1494 | f [p@PrecDef{}] = [p] | ||
1495 | |||
1496 | f fs@((FunAlt n vs _ _): _) = [Let n (listToMaybe [t | PrecDef n' t <- ds, n' == n]) | ||
1497 | (listToMaybe [t | TypeAnn n' t <- ds, n' == n]) | ||
1498 | (map (fst . fst) vs) | ||
1499 | (foldr (uncurry SLam) (compileGuardTree lend ge $ Alts | ||
1500 | [ compilePatts (zip (map snd vs) $ reverse [0..length vs - 1]) gs x | ||
1501 | | FunAlt _ vs gs x <- fs | ||
1502 | ]) (map fst vs)) | ||
1503 | ] | ||
1504 | f x = x | ||
1505 | |||
1506 | parseStmt :: Namespace -> [String] -> P [Stmt] | ||
1507 | parseStmt ns e = | ||
1508 | do con <- Nothing <$ keyword "builtins" <|> Just False <$ keyword "builtincons" <|> Just True <$ keyword "builtintycons" | ||
1509 | fmap concat $ localIndentation Gt $ localAbsoluteIndentation $ many $ do | ||
1510 | (\(vs, t) -> Primitive con <$> vs <*> pure t) <$> typedId' ns Nothing [] | ||
1511 | <|> do keyword "data" | ||
1512 | localIndentation Gt $ do | ||
1513 | x <- lcIdents (typeNS ns) | ||
1514 | (nps, ts) <- telescope (typeNS ns) (Just SType) e | ||
1515 | t <- parseType (typeNS ns) (Just SType) nps | ||
1516 | let mkConTy mk (nps', ts') = | ||
1517 | ( if mk then Just $ take (length nps' - length nps) nps' else Nothing | ||
1518 | , foldr (uncurry SPi) (foldl SAppV (SGlobal x) $ downTo (length ts') $ length ts) ts') | ||
1519 | cs <- | ||
1520 | do keyword "where" *> localIndentation Ge (localAbsoluteIndentation $ many $ (id *** (,) Nothing) <$> typedId' ns Nothing nps) | ||
1521 | <|> do operator "=" *> | ||
1522 | sepBy1 ((,) <$> (pure <$> lcIdents ns) | ||
1523 | <*> ( braces (mkConTy True <$> (telescopeDataFields (typeNS ns) nps)) | ||
1524 | <|> (mkConTy False <$> telescope (typeNS ns) Nothing nps)) ) | ||
1525 | (operator "|") | ||
1526 | <|> pure [] | ||
1527 | ge <- ask | ||
1528 | return $ mkData ge x ts t $ concatMap (\(vs, t) -> (,) <$> vs <*> pure t) cs | ||
1529 | <|> do (vs, t) <- try $ typedId' ns Nothing [] | ||
1530 | return $ TypeAnn <$> vs <*> pure t | ||
1531 | <|> fixityDef | ||
1532 | <|> do (n, (fe, ts)) <- | ||
1533 | do try' "operator definition" $ do | ||
1534 | (e', a1) <- patternAtom ns ("": e) | ||
1535 | localIndentation Gt $ do | ||
1536 | n <- operator' | ||
1537 | (e'', a2) <- patternAtom ns $ take (length e' - length e - 1) e' ++ n: e | ||
1538 | lookAhead $ operator "=" <|> operator "|" | ||
1539 | return (n, (e'', (,) (Visible, Wildcard SType) <$> [a1, a2])) | ||
1540 | <|> do try $ do | ||
1541 | n <- varId ns | ||
1542 | localIndentation Gt $ (,) n <$> telescope' (expNS ns) (n: e) <* (lookAhead $ operator "=" <|> operator "|") | ||
1543 | localIndentation Gt $ do | ||
1544 | gu <- option Nothing $ do | ||
1545 | operator "|" | ||
1546 | Just <$> parseETerm ns PrecOp fe | ||
1547 | operator "=" | ||
1548 | rhs <- parseETerm ns PrecLam fe | ||
1549 | f <- parseWhereBlock ns fe | ||
1550 | return $ pure $ FunAlt n ts gu $ f rhs | ||
1551 | <|> pure . uncurry ValueDef <$> valueDef ns e | ||
1552 | where | ||
1553 | telescopeDataFields ns vs = option (vs, []) $ do | ||
1554 | (x, vt) <- do name <- var (expNS ns) | ||
1555 | operator "::" | ||
1556 | term <- parseTerm ns PrecLam vs | ||
1557 | return (name, (Visible, term)) | ||
1558 | (id *** (vt:)) <$> (comma *> telescopeDataFields ns (x: vs) <|> pure (vs, [])) | ||
1559 | |||
1560 | mkData ge x ts t cs = [Data x ts t $ (id *** snd) <$> cs] ++ concatMap mkProj cs | ||
1561 | where | ||
1562 | mkProj (cn, (Just fs, _)) = [ Let fn Nothing Nothing [Visible] | ||
1563 | $ upS $ patLam SLabelEnd ge (PCon cn $ replicate (length fs) $ ParPat [PVar]) $ SVar i | ||
1564 | | (i, fn) <- zip [0..] fs] | ||
1565 | mkProj _ = [] | ||
1566 | -- data F = X {a :: A, b :: B} | ||
1567 | -- a (X w _) = w | ||
1568 | -- b (X _ w) = w | ||
1569 | |||
1570 | parseWhereBlock ns fe = option id $ do | ||
1571 | keyword "where" | ||
1572 | dcls <- localIndentation Ge (localAbsoluteIndentation $ parseStmts id ns fe) | ||
1573 | ge <- ask | ||
1574 | return $ mkLets ge dcls | ||
1575 | |||
1576 | type DBNames = [SName] -- De Bruijn variable names | ||
1577 | |||
1578 | valueDef :: Namespace -> DBNames -> P ((DBNames, Pat), SExp) | ||
1579 | valueDef ns e = do | ||
1580 | (e', p) <- try $ pattern' ns e <* operator "=" | ||
1581 | localIndentation Gt $ do | ||
1582 | ex <- parseETerm ns PrecLam e | ||
1583 | return ((take (length e' - length e) e', p), ex) | ||
1584 | |||
1585 | pattern TPVar t = ParPat [PatType (ParPat [PVar]) t] | ||
1586 | |||
1587 | sapp a (v, b) = SApp v a b | ||
1588 | |||
1589 | type Namespace = (Maybe Bool {-True: type namespace-}, Bool) | ||
1590 | |||
1591 | parseTTerm ns = parseTerm $ typeNS ns | ||
1592 | parseETerm ns = parseTerm $ expNS ns | ||
1593 | |||
1594 | typeNS = (True <$) *** id | ||
1595 | expNS = (False <$) *** id | ||
1596 | |||
1597 | parseTerm :: Namespace -> Prec -> [String] -> P SExp | ||
1598 | parseTerm ns PrecLam e = | ||
1599 | mkIf <$ keyword "if" <*> parseTerm ns PrecLam e <* keyword "then" <*> parseTerm ns PrecLam e <* keyword "else" <*> parseTerm ns PrecLam e | ||
1600 | <|> do (tok, ns) <- (SPi . const Hidden <$ operator "." <|> SPi . const Visible <$ operator "->", typeNS ns) <$ keyword "forall" | ||
1601 | (fe, ts) <- telescope ns (Just $ Wildcard SType) e | ||
1602 | f <- tok | ||
1603 | t' <- parseTerm ns PrecLam fe | ||
1604 | return $ foldr (uncurry f) t' ts | ||
1605 | <|> do (tok, ns) <- (asks (patLam_ id) <* operator "->", expNS ns) <$ operator "\\" | ||
1606 | (fe, ts) <- telescope' ns e | ||
1607 | f <- tok | ||
1608 | t' <- parseTerm ns PrecLam fe | ||
1609 | return $ foldr (uncurry f) t' ts | ||
1610 | <|> do (asks compileCase) <* keyword "case" <*> parseETerm ns PrecLam e | ||
1611 | <* keyword "of" <*> localIndentation Ge (localAbsoluteIndentation $ some $ parseClause ns e) | ||
1612 | <|> do (asks $ \ge -> compileGuardTree id ge . Alts) <*> parseSomeGuards ns (const True) e | ||
1613 | <|> do t <- parseTerm ns PrecEq e | ||
1614 | option t $ mkPi <$> (Visible <$ operator "->" <|> Hidden <$ operator "=>") <*> pure t <*> parseTTerm ns PrecLam e | ||
1615 | parseTerm ns PrecEq e = parseTerm ns PrecAnn e >>= \t -> option t $ SCstr t <$ operator "~" <*> parseTTerm ns PrecAnn e | ||
1616 | parseTerm ns PrecAnn e = parseTerm ns PrecOp e >>= \t -> option t $ SAnn t <$> parseType ns Nothing e | ||
1617 | parseTerm ns PrecOp e = (asks $ \dcls -> calculatePrecs dcls e) <*> p' where | ||
1618 | p' = (\(t, xs) -> (mkNat ns 0, ("-!", t): xs)) <$ operator "-" <*> p_ | ||
1619 | <|> p_ | ||
1620 | p_ = (,) <$> parseTerm ns PrecApp e <*> (option [] $ operator' >>= p) | ||
1621 | p op = do (exp, op') <- try ((,) <$> parseTerm ns PrecApp e <*> operator') | ||
1622 | ((op, exp):) <$> p op' | ||
1623 | <|> pure . (,) op <$> parseTerm ns PrecLam e | ||
1624 | parseTerm ns PrecApp e = | ||
1625 | try {- TODO: adjust try for better error messages e.g. don't use braces -} | ||
1626 | (foldl sapp <$> (sVar e <$> upperCaseIdent ns) <*> braces (commaSep $ lcIdents ns *> operator "=" *> ((,) Visible <$> parseTerm ns PrecLam e))) <|> | ||
1627 | (foldl sapp <$> parseTerm ns PrecSwiz e <*> many | ||
1628 | ( (,) Visible <$> parseTerm ns PrecSwiz e | ||
1629 | <|> (,) Hidden <$ operator "@" <*> parseTTerm ns PrecSwiz e)) | ||
1630 | parseTerm ns PrecSwiz e = do | ||
1631 | t <- parseTerm ns PrecProj e | ||
1632 | try (mkSwizzling t <$ char '%' <*> manyNM 1 4 (satisfy (`elem` ("xyzwrgba" :: [Char]))) <* whiteSpace) <|> pure t | ||
1633 | parseTerm ns PrecProj e = do | ||
1634 | t <- parseTerm ns PrecAtom e | ||
1635 | try (mkProjection t <$ char '.' <*> (sepBy1 (sLit . LString <$> lcIdents ns) (char '.'))) <|> pure t | ||
1636 | parseTerm ns PrecAtom e = | ||
1637 | sLit . LChar <$> try charLiteral | ||
1638 | <|> sLit . LString <$> stringLiteral | ||
1639 | <|> sLit . LFloat <$> try float | ||
1640 | <|> sLit . LInt . fromIntegral <$ char '#' <*> natural | ||
1641 | <|> mkNat ns <$> natural | ||
1642 | <|> Wildcard (Wildcard SType) <$ keyword "_" | ||
1643 | <|> sVar e <$> (lcIdents ns <|> try (varId ns)) | ||
1644 | <|> mkDotDot <$> try (operator "[" *> parseTerm ns PrecLam e <* operator ".." ) <*> parseTerm ns PrecLam e <* operator "]" | ||
1645 | <|> listCompr ns e | ||
1646 | <|> mkList ns <$> brackets (commaSep $ parseTerm ns PrecLam e) | ||
1647 | <|> mkTuple ns <$> parens (commaSep $ parseTerm ns PrecLam e) | ||
1648 | <|> mkRecord <$> braces (commaSep $ ((,) <$> lowerCase ns <* colon <*> parseTerm ns PrecLam e)) | ||
1649 | <|> do keyword "let" | ||
1650 | dcls <- localIndentation Ge (localAbsoluteIndentation $ parseStmts id ns e) | ||
1651 | ge <- ask | ||
1652 | mkLets ge dcls <$ keyword "in" <*> parseTerm ns PrecLam e | ||
1653 | |||
1654 | mkSwizzling term = swizzcall | ||
1655 | where | ||
1656 | sc c = SGlobal $ 'S':c:[] | ||
1657 | swizzcall [x] = SGlobal "swizzscalar" `SAppV` term `SAppV` (sc . synonym) x | ||
1658 | swizzcall xs = SGlobal "swizzvector" `SAppV` term `SAppV` swizzparam xs | ||
1659 | swizzparam xs = foldl (\exp s -> exp `SAppV` s) (vec xs) $ map (sc . synonym) xs | ||
1660 | vec xs = SGlobal $ case length xs of | ||
1661 | 0 -> error "impossible: swizzling parsing returned empty pattern" | ||
1662 | 1 -> error "impossible: swizzling went to vector for one scalar" | ||
1663 | n -> "V" ++ show n | ||
1664 | synonym 'r' = 'x' | ||
1665 | synonym 'g' = 'y' | ||
1666 | synonym 'b' = 'z' | ||
1667 | synonym 'a' = 'w' | ||
1668 | synonym c = c | ||
1669 | |||
1670 | mkProjection term = foldl (\exp field -> SGlobal "project" `SAppV` field `SAppV` exp) term | ||
1671 | |||
1672 | -- Creates: RecordCons @[("x", _), ("y", _), ("z", _)] (1.0, (2.0, (3.0, ()))) | ||
1673 | mkRecord xs = SGlobal "RecordCons" `SAppH` names `SAppV` values | ||
1674 | where | ||
1675 | (names, values) = mkNames *** mkValues $ unzip xs | ||
1676 | |||
1677 | mkNameTuple v = SGlobal "Tuple2" `SAppV` (sLit $ LString v) `SAppV` Wildcard SType | ||
1678 | mkNames = foldr (\n ns -> SGlobal "Cons" `SAppV` (mkNameTuple n) `SAppV` ns) | ||
1679 | (SGlobal "Nil") | ||
1680 | |||
1681 | mkValues = foldr (\x xs -> SGlobal "Tuple2" `SAppV` x `SAppV` xs) | ||
1682 | (SGlobal "Tuple0") | ||
1683 | |||
1684 | sVar e x = maybe (SGlobal x) SVar $ elemIndex' x e | ||
1685 | |||
1686 | mkIf b t f = SGlobal "primIfThenElse" `SAppV` b `SAppV` t `SAppV` f | ||
1687 | |||
1688 | mkDotDot e f = SGlobal "fromTo" `SAppV` e `SAppV` f | ||
1689 | |||
1690 | -- n, m >= 1, n < m | ||
1691 | manyNM n m p = do | ||
1692 | xs <- many1 p | ||
1693 | let lxs = length xs | ||
1694 | unless (n <= lxs && lxs <= m) . fail $ unwords ["manyNM", show n, show m, "found", show lxs, "occurences."] | ||
1695 | return xs | ||
1696 | |||
1697 | -------------------------------------------------------------------------------- list comprehensions | ||
1698 | {- example | ||
1699 | |||
1700 | dbs<<[ x | y <- [1..10], let x = y * y]>> | ||
1701 | --> | ||
1702 | dbs<<[ _ | y <- [1..10], let x = y * y]>> $ dbs<<x>> | ||
1703 | --> | ||
1704 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1705 | SLam | ||
1706 | | PVar <- Var 0 = y:dbs<<[ _ | let x = y * y]>> $ exp | ||
1707 | | _ = <<[]>> | ||
1708 | <<[1..10]>> | ||
1709 | ) (SGlobal "x") | ||
1710 | --> | ||
1711 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1712 | SLam | ||
1713 | | PVar <- Var 0 = SLet (y:dbs<<y * y>>) ((x:y:dbs<<[ _ ]>>) $ exp) | ||
1714 | | _ = <<[]>> | ||
1715 | <<[1..10]>> | ||
1716 | ) (SGlobal "x") | ||
1717 | --> | ||
1718 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1719 | SLam | ||
1720 | | PVar <- Var 0 = SLet (y:dbs<<y * y>>) ((x:y:dbs<<[ _ ]>>) $ exp) | ||
1721 | | _ = <<[]>> | ||
1722 | <<[1..10]>> | ||
1723 | ) (SGlobal "x") | ||
1724 | --> | ||
1725 | SGlobal "concatMap" `SAppV` | ||
1726 | SLam | ||
1727 | | PVar <- Var 0 = SLet (Var 0 * Var 0) (Var 0) | ||
1728 | | _ = <<[]>> | ||
1729 | <<[1..10]>> | ||
1730 | --> | ||
1731 | -} | ||
1732 | |||
1733 | generator, letdecl, boolExpression :: Namespace -> DBNames -> P (DBNames, SExp -> SExp) | ||
1734 | |||
1735 | generator ns dbs = do | ||
1736 | (dbs', pat) <- try $ pattern' ns dbs <* operator "<-" | ||
1737 | exp <- parseTerm ns PrecLam dbs | ||
1738 | ge <- ask | ||
1739 | return $ (,) ({-join traceShow-} dbs') $ \e -> application | ||
1740 | [ SGlobal "concatMap" | ||
1741 | , SLam Visible (Wildcard SType) $ compileGuardTree id ge $ Alts | ||
1742 | [ compilePatts [(pat, 0)] Nothing $ {-upS $ -} e | ||
1743 | , GuardLeaf $ SGlobal "Nil" | ||
1744 | ] | ||
1745 | , exp | ||
1746 | ] | ||
1747 | |||
1748 | letdecl ns dbs = ask >>= \ge -> keyword "let" *> ((\((dbs', p), e) -> ({-join traceShow dbs' ++ -} dbs, \exp -> {-traceShow exp $ -} mkLets ge [ValueDef (dbs', p) e] exp)) <$> valueDef ns dbs) | ||
1749 | |||
1750 | boolExpression ns dbs = do | ||
1751 | pred <- parseTerm ns PrecLam dbs | ||
1752 | return (dbs, \e -> application [SGlobal "primIfThenElse", pred, e, SGlobal "Nil"]) | ||
1753 | |||
1754 | application = foldl1 SAppV | ||
1755 | |||
1756 | listCompr :: Namespace -> DBNames -> P SExp | ||
1757 | listCompr ns dbs = (\e (dbs', fs) -> foldr ($) (deBruinify (take (length dbs' - length dbs) dbs') e) fs) | ||
1758 | <$> try' "List comprehension" ((SGlobal "singleton" `SAppV`) <$ operator "[" <*> parseTerm ns PrecLam dbs <* operator "|") | ||
1759 | <*> commaSep' (liftA2 (<|>) (generator ns) $ liftA2 (<|>) (letdecl ns) (boolExpression ns)) dbs <* operator "]" | ||
1760 | |||
1761 | deBruinify :: DBNames -> SExp -> SExp | ||
1762 | deBruinify [] e = e | ||
1763 | deBruinify (n: ns) e = substSG n (SVar 0) $ upS $ deBruinify ns e | ||
1764 | |||
1765 | -- deBruinify ["a","b"] <<a * b>> --> Var 0 * Var 1 | ||
1766 | |||
1767 | -------------------------------------------------------------------------------- | ||
1768 | |||
1769 | calculatePrecs :: GlobalEnv' -> [SName] -> (SExp, [(SName, SExp)]) -> SExp | ||
1770 | calculatePrecs _ vs (e, []) = e | ||
1771 | calculatePrecs dcls vs (e, xs) = calcPrec (\op x y -> op `SAppV` x `SAppV` y) (getFixity dcls . gf) e $ (sVar vs *** id) <$> xs | ||
1772 | where | ||
1773 | gf (SGlobal n) = n | ||
1774 | gf (SVar i) = vs !! i | ||
1775 | |||
1776 | getFixity :: GlobalEnv' -> SName -> Fixity | ||
1777 | getFixity (fm, _) n = fromMaybe (Just FDLeft, 9) $ Map.lookup n fm | ||
1778 | |||
1779 | mkGlobalEnv' :: [Stmt] -> GlobalEnv' | ||
1780 | mkGlobalEnv' ss = | ||
1781 | ( Map.fromList [(s, f) | PrecDef s f <- ss] | ||
1782 | , Map.fromList [(cn, ((t, length (fst $ getParamsS ty){-todo-}), (id *** f) <$> cs)) | Data t ps ty cs <- ss, (cn, ct) <- cs] | ||
1783 | ) | ||
1784 | where | ||
1785 | f ct = length $ filter ((==Visible) . fst) $ fst $ getParamsS ct | ||
1786 | |||
1787 | extractGlobalEnv' :: GlobalEnv -> GlobalEnv' | ||
1788 | extractGlobalEnv' ge = | ||
1789 | ( Map.fromList | ||
1790 | [ (n, f) | (n, (d, _)) <- Map.toList ge, f <- maybeToList $ case d of | ||
1791 | Con (ConName _ f _ _) [] -> f | ||
1792 | TyCon (TyConName _ f _ _ _ _) [] -> f | ||
1793 | Label (getFunName -> Just (FunName _ f _)) _ -> f | ||
1794 | Fun (FunName _ f _) [] -> f | ||
1795 | _ -> Nothing | ||
1796 | ] | ||
1797 | , Map.fromList | ||
1798 | [ (n, case conTypeName cn of TyConName t _ inum _ cons _ -> ((t, inum), map f cons)) | ||
1799 | | (n, (Con cn [], _)) <- Map.toList ge | ||
1800 | ] | ||
1801 | ) | ||
1802 | where | ||
1803 | f (ConName n _ _ ct) = (n, length $ filter ((==Visible) . fst) $ fst $ getParams ct) | ||
1804 | |||
1805 | joinGlobalEnv' (fm, cm) (fm', cm') = (Map.union fm fm', Map.union cm cm') | ||
1806 | |||
1807 | calcPrec | ||
1808 | :: (Show e) | ||
1809 | => (e -> e -> e -> e) | ||
1810 | -> (e -> Fixity) | ||
1811 | -> e | ||
1812 | -> [(e, e)] | ||
1813 | -> e | ||
1814 | calcPrec app getFixity e es = compileOps [((Nothing, -1), undefined, e)] es | ||
1815 | where | ||
1816 | compileOps [(_, _, e)] [] = e | ||
1817 | compileOps acc [] = compileOps (shrink acc) [] | ||
1818 | compileOps acc@((p, g, e1): ee) es_@((op, e'): es) = case compareFixity (pr, op) (p, g) of | ||
1819 | Right GT -> compileOps ((pr, op, e'): acc) es | ||
1820 | Right LT -> compileOps (shrink acc) es_ | ||
1821 | Left err -> error err | ||
1822 | where | ||
1823 | pr = getFixity op | ||
1824 | |||
1825 | shrink ((_, op, e): (pr, op', e'): es) = (pr, op', app op e' e): es | ||
1826 | |||
1827 | compareFixity ((dir, i), op) ((dir', i'), op') | ||
1828 | | i > i' = Right GT | ||
1829 | | i < i' = Right LT | ||
1830 | | otherwise = case (dir, dir') of | ||
1831 | (Just FDLeft, Just FDLeft) -> Right LT | ||
1832 | (Just FDRight, Just FDRight) -> Right GT | ||
1833 | _ -> Left $ "fixity error:" ++ show (op, op') | ||
1834 | |||
1835 | mkPi Hidden (getTTuple -> Just (n, xs)) b | n == length xs = foldr (sNonDepPi Hidden) b xs | ||
1836 | mkPi h a b = sNonDepPi h a b | ||
1837 | |||
1838 | sNonDepPi h a b = SPi h a $ upS b | ||
1839 | |||
1840 | getTTuple (SAppV (getTTuple -> Just (n, xs)) z) = Just (n, xs ++ [z]{-todo: eff-}) | ||
1841 | getTTuple (SGlobal s@(splitAt 6 -> ("'Tuple", reads -> [(n, "")]))) = Just (n :: Int, []) | ||
1842 | getTTuple _ = Nothing | ||
1843 | |||
1844 | mkLets :: GlobalEnv' -> [Stmt]{-where block-} -> SExp{-main expression-} -> SExp{-big let with lambdas; replaces global names with de bruijn indices-} | ||
1845 | mkLets _ [] e = e | ||
1846 | mkLets ge (Let n _ mt _ (downS 0 -> Just x): ds) e | ||
1847 | = SLet ({-maybe id (flip SAnn . af) mt-}{-todo-} x) (substSG n (SVar 0) $ upS $ mkLets ge ds e) | ||
1848 | mkLets ge (ValueDef (ns, p) x: ds) e = patLam id ge p (deBruinify ns $ mkLets ge ds e) `SAppV` x -- (p = e; f) --> (\p -> f) e | ||
1849 | mkLets _ (x: ds) e = error $ "mkLets: " ++ show x | ||
1850 | |||
1851 | patLam f ge = patLam_ f ge (Visible, Wildcard SType) | ||
1852 | |||
1853 | patLam_ :: (SExp -> SExp) -> GlobalEnv' -> (Visibility, SExp) -> Pat -> SExp -> SExp | ||
1854 | patLam_ f ge (v, t) p e = SLam v t $ compileGuardTree f ge $ compilePatts [(p, 0)] Nothing e | ||
1855 | |||
1856 | mkTuple _ [x] = x | ||
1857 | mkTuple (Just True, _) xs = foldl SAppV (SGlobal $ "'Tuple" ++ show (length xs)) xs | ||
1858 | mkTuple (Just False, _) xs = foldl SAppV (SGlobal $ "Tuple" ++ show (length xs)) xs | ||
1859 | mkTuple _ xs = error "mkTuple" | ||
1860 | |||
1861 | mkList (Just True, _) [x] = SGlobal "'List" `SAppV` x | ||
1862 | mkList (Just False, _) xs = foldr (\x l -> SGlobal "Cons" `SAppV` x `SAppV` l) (SGlobal "Nil") xs | ||
1863 | mkList _ xs = error "mkList" | ||
1864 | |||
1865 | parseSomeGuards ns f e = do | ||
1866 | pos <- sourceColumn <$> getPosition <* operator "|" | ||
1867 | guard $ f pos | ||
1868 | (e', f) <- | ||
1869 | do (e', PCon p vs) <- try $ pattern' ns e <* operator "<-" | ||
1870 | x <- parseETerm ns PrecEq e | ||
1871 | return (e', \gs' gs -> GuardNode x p vs (Alts gs'): gs) | ||
1872 | <|> do x <- parseETerm ns PrecEq e | ||
1873 | return (e, \gs' gs -> [GuardNode x "True" [] $ Alts gs', GuardNode x "False" [] $ Alts gs]) | ||
1874 | f <$> (parseSomeGuards ns (> pos) e' <|> (:[]) . GuardLeaf <$ operator "->" <*> parseETerm ns PrecLam e') | ||
1875 | <*> (parseSomeGuards ns (== pos) e <|> pure []) | ||
1876 | |||
1877 | findAdt (_, cm) con = case Map.lookup con cm of | ||
1878 | Just i -> i | ||
1879 | _ -> error $ "findAdt:" ++ con | ||
1880 | |||
1881 | mkNat (Just False, _) n = SGlobal "fromInt" `SAppV` sLit (LInt $ fromIntegral n) | ||
1882 | mkNat _ n = toNat n | ||
1883 | |||
1884 | toNat 0 = SGlobal "Zero" | ||
1885 | toNat n = SAppV (SGlobal "Succ") $ toNat (n-1) | ||
1886 | |||
1887 | -------------------------------------------------------------------------------- | ||
1888 | |||
1889 | -- parallel patterns like v@(f -> [])@(Just x) | ||
1890 | newtype ParPat = ParPat [Pat] | ||
1891 | deriving Show | ||
1892 | |||
1893 | data Pat | ||
1894 | = PVar -- Int | ||
1895 | | PCon SName [ParPat] | ||
1896 | | ViewPat SExp ParPat | ||
1897 | | PatType ParPat SExp | ||
1898 | deriving Show | ||
1899 | |||
1900 | data GuardTree | ||
1901 | = GuardNode SExp Name [ParPat] GuardTree -- _ <- _ | ||
1902 | | Alts [GuardTree] -- _ | _ | ||
1903 | | GuardLeaf SExp -- _ -> e | ||
1904 | deriving Show | ||
1905 | |||
1906 | mapGT k i = \case | ||
1907 | GuardNode e c pps gt -> GuardNode (i k e) c ({-todo: up-} pps) $ mapGT (k + sum (map varPP pps)) i gt | ||
1908 | Alts gts -> Alts $ map (mapGT k i) gts | ||
1909 | GuardLeaf e -> GuardLeaf $ i k e | ||
1910 | |||
1911 | upGT k i = mapGT k $ \k -> upS__ k i | ||
1912 | |||
1913 | substGT i j = mapGT 0 $ \k -> rearrangeS $ \r -> if r == k + i then k + j else if r > k + i then r - 1 else r | ||
1914 | {- | ||
1915 | substGT :: Int -> Int -> GuardTree -> GuardTree | ||
1916 | substGT i x = \case | ||
1917 | GuardNode e n ps t -> GuardNode (substS i (Var x) e) n ps{-todo-} $ substGT i x | ||
1918 | Alts gs -> Alts $ substGT i x <$> gs | ||
1919 | GuardLeaf e -> substS i (Var x) e | ||
1920 | -} | ||
1921 | |||
1922 | mapPP f = \case | ||
1923 | ParPat ps -> ParPat (mapP f <$> ps) | ||
1924 | |||
1925 | mapP :: (SExp -> SExp) -> Pat -> Pat | ||
1926 | mapP f = \case | ||
1927 | PVar -> PVar | ||
1928 | PCon n pp -> PCon n (mapPP f <$> pp) | ||
1929 | ViewPat e pp -> ViewPat (f e) (mapPP f pp) | ||
1930 | PatType pp e -> PatType (mapPP f pp) (f e) | ||
1931 | |||
1932 | upP i j = mapP (upS__ i j) | ||
1933 | |||
1934 | varPP = \case | ||
1935 | ParPat ps -> sum $ map varP ps | ||
1936 | |||
1937 | varP = \case | ||
1938 | PVar -> 1 | ||
1939 | PCon n pp -> sum $ map varPP pp | ||
1940 | ViewPat e pp -> varPP pp | ||
1941 | PatType pp e -> varPP pp | ||
1942 | |||
1943 | |||
1944 | alts (Alts xs) = concatMap alts xs | ||
1945 | alts x = [x] | ||
1946 | |||
1947 | compileGuardTree :: (SExp -> SExp) -> GlobalEnv' -> GuardTree -> SExp | ||
1948 | compileGuardTree node adts t = (\x -> traceD (" ! :" ++ showSExp x) x) $ guardTreeToCases t | ||
1949 | where | ||
1950 | guardTreeToCases :: GuardTree -> SExp | ||
1951 | guardTreeToCases t = case alts t of | ||
1952 | [] -> node $ SGlobal "undefined" | ||
1953 | GuardLeaf e: _ -> node e | ||
1954 | ts@(GuardNode f s _ _: _) -> | ||
1955 | mkCase t inum f $ | ||
1956 | [ (n, guardTreeToCases $ Alts $ map (filterGuardTree (upS__ 0 n f) cn 0 n . upGT 0 n) ts) | ||
1957 | | (cn, n) <- cns | ||
1958 | ] | ||
1959 | where | ||
1960 | ((t, inum), cns) = findAdt adts s | ||
1961 | |||
1962 | mkCase :: SName -> Int -> SExp -> [(Int, SExp)] -> SExp | ||
1963 | mkCase t inum f cs = foldl SAppV (SGlobal (caseName t) `SAppV` iterateN (1 + inum) (SLam Visible $ Wildcard SType) (Wildcard SType)) | ||
1964 | [iterateN vs (SLam Visible (Wildcard SType)) e | (vs, e) <- cs] | ||
1965 | `SAppV` f | ||
1966 | |||
1967 | filterGuardTree :: SExp -> SName{-constr.-} -> Int -> Int{-number of constr. params-} -> GuardTree -> GuardTree | ||
1968 | filterGuardTree f s k ns = \case | ||
1969 | GuardLeaf e -> GuardLeaf e | ||
1970 | Alts ts -> Alts $ map (filterGuardTree f s k ns) ts | ||
1971 | GuardNode f' s' ps gs | ||
1972 | | f /= f' -> GuardNode f' s' ps $ filterGuardTree (upS__ 0 su f) s (su + k) ns gs | ||
1973 | | s == s' -> filterGuardTree f s k ns $ guardNodes (zips [k+ns-1, k+ns-2..] ps) gs | ||
1974 | | otherwise -> Alts [] | ||
1975 | where | ||
1976 | zips is ps = zip (map SVar $ zipWith (+) is $ sums $ map varPP ps) ps | ||
1977 | su = sum $ map varPP ps | ||
1978 | sums = scanl (+) 0 | ||
1979 | |||
1980 | guardNodes :: [(SExp, ParPat)] -> GuardTree -> GuardTree | ||
1981 | guardNodes [] l = l | ||
1982 | guardNodes ((v, ParPat ws): vs) e = guardNode v ws $ guardNodes vs e | ||
1983 | |||
1984 | guardNode :: SExp -> [Pat] -> GuardTree -> GuardTree | ||
1985 | -- guardNode v [] e = e | ||
1986 | guardNode v (w: []) e = case w of | ||
1987 | PVar -> {-todo guardNode v (subst x v ws) $ -} varGuardNode 0 v e | ||
1988 | ViewPat f (ParPat p) -> guardNode (f `SAppV` v) p {- $ guardNode v ws -} e | ||
1989 | PCon s ps' -> GuardNode v s ps' {- $ guardNode v ws -} e | ||
1990 | |||
1991 | varGuardNode v (SVar e) gt = substGT v e gt | ||
1992 | |||
1993 | compileCase ge x cs | ||
1994 | = SLam Visible (Wildcard SType) (compileGuardTree id ge $ Alts [compilePatts [(p, 0)] Nothing e | (p, e) <- cs]) `SAppV` x | ||
1995 | |||
1996 | -- todo: clenup | ||
1997 | compilePatts :: [(Pat, Int)] -> Maybe SExp -> SExp -> GuardTree | ||
1998 | compilePatts ps gu = cp [] ps | ||
1999 | where | ||
2000 | cp ps' [] e = case gu of | ||
2001 | Nothing -> rhs | ||
2002 | Just ge -> GuardNode (rearrangeS (f $ reverse ps') ge) "True" [] rhs | ||
2003 | where rhs = GuardLeaf $ rearrangeS (f $ reverse ps') e | ||
2004 | cp ps' ((p@PVar, i): xs) e = cp (p: ps') xs e | ||
2005 | cp ps' ((p@(PCon n ps), i): xs) e = GuardNode (SVar $ i + sum (map (fromMaybe 0 . ff) ps')) n ps $ cp (p: ps') xs e | ||
2006 | cp ps' ((p@(ViewPat f (ParPat [PCon n ps])), i): xs) e | ||
2007 | = GuardNode (SAppV f $ SVar $ i + sum (map (fromMaybe 0 . ff) ps')) n ps $ cp (p: ps') xs e | ||
2008 | |||
2009 | m = length ps | ||
2010 | |||
2011 | ff PVar = Nothing | ||
2012 | ff p = Just $ varP p | ||
2013 | |||
2014 | f ps i | ||
2015 | | i >= s = i - s + m + sum vs' | ||
2016 | | i < s = case vs_ !! n of | ||
2017 | Nothing -> m + sum vs' - 1 - n | ||
2018 | Just _ -> m + sum vs' - 1 - (m + sum (take n vs') + j) | ||
2019 | where | ||
2020 | i' = s - 1 - i | ||
2021 | (n, j) = concat (zipWith (\k j -> zip (repeat j) [0..k-1]) vs [0..]) !! i' | ||
2022 | |||
2023 | vs_ = map ff ps | ||
2024 | vs = map (fromMaybe 1) vs_ | ||
2025 | vs' = map (fromMaybe 0) vs_ | ||
2026 | s = sum vs | ||
2027 | |||
2028 | |||
2029 | -------------------------------------------------------------------------------- pretty print | ||
2030 | |||
2031 | showExp :: Exp -> String | ||
2032 | showExp = showDoc . expDoc | ||
2033 | |||
2034 | showSExp :: SExp -> String | ||
2035 | showSExp = showDoc . sExpDoc | ||
2036 | |||
2037 | showEnv :: Env -> String | ||
2038 | showEnv e = showDoc $ envDoc e $ pure $ shAtom $ underlined "<<HERE>>" | ||
2039 | |||
2040 | showEnvExp :: Env -> Exp -> String | ||
2041 | showEnvExp e c = showDoc $ envDoc e $ epar <$> expDoc c | ||
2042 | |||
2043 | showEnvSExp :: Env -> SExp -> String | ||
2044 | showEnvSExp e c = showDoc $ envDoc e $ epar <$> sExpDoc c | ||
2045 | |||
2046 | showEnvSExpType :: Env -> SExp -> Exp -> String | ||
2047 | showEnvSExpType e c t = showDoc $ envDoc e $ epar <$> (shAnn "::" False <$> sExpDoc c <**> expDoc t) | ||
2048 | where | ||
2049 | infixl 4 <**> | ||
2050 | (<**>) :: Doc_ (a -> b) -> Doc_ a -> Doc_ b | ||
2051 | a <**> b = get >>= \s -> lift $ evalStateT a s <*> evalStateT b s | ||
2052 | |||
2053 | showDoc :: Doc -> String | ||
2054 | showDoc = str . flip runReader [] . flip evalStateT (flip (:) <$> iterate ('\'':) "" <*> ['a'..'z']) | ||
2055 | |||
2056 | type Doc_ a = StateT [String] (Reader [String]) a | ||
2057 | type Doc = Doc_ PrecString | ||
2058 | |||
2059 | envDoc :: Env -> Doc -> Doc | ||
2060 | envDoc x m = case x of | ||
2061 | EGlobal{} -> m | ||
2062 | EBind1 h ts b -> envDoc ts $ join $ shLam (usedS 0 b) h <$> m <*> pure (sExpDoc b) | ||
2063 | EBind2 h a ts -> envDoc ts $ join $ shLam True h <$> expDoc a <*> pure m | ||
2064 | EApp1 h ts b -> envDoc ts $ shApp h <$> m <*> sExpDoc b | ||
2065 | EApp2 h (Lam Visible TType (Var 0)) ts -> envDoc ts $ shApp h (shAtom "tyType") <$> m | ||
2066 | EApp2 h a ts -> envDoc ts $ shApp h <$> expDoc a <*> m | ||
2067 | ELet1 ts b -> envDoc ts $ shLet_ m (sExpDoc b) | ||
2068 | ELet2 (x, _) ts -> envDoc ts $ shLet_ (expDoc x) m | ||
2069 | EAssign i x ts -> envDoc ts $ shLet i (expDoc x) m | ||
2070 | CheckType t ts -> envDoc ts $ shAnn ":" False <$> m <*> expDoc t | ||
2071 | CheckSame t ts -> envDoc ts $ shCstr <$> m <*> expDoc t | ||
2072 | CheckAppType h t te b -> envDoc (EApp1 h (CheckType t te) b) m | ||
2073 | ELabelEnd ts -> envDoc ts $ shApp Visible (shAtom "labEnd") <$> m | ||
2074 | |||
2075 | expDoc :: Exp -> Doc | ||
2076 | expDoc e = fmap inGreen <$> f e | ||
2077 | where | ||
2078 | f = \case | ||
2079 | Label x _ -> f x | ||
2080 | Var k -> shVar k | ||
2081 | App a b -> shApp Visible <$> f a <*> f b | ||
2082 | Lam h a b -> join $ shLam (usedE 0 b) (BLam h) <$> f a <*> pure (f b) | ||
2083 | Bind h a b -> join $ shLam (usedE 0 b) h <$> f a <*> pure (f b) | ||
2084 | Cstr a b -> shCstr <$> f a <*> f b | ||
2085 | FunN s xs -> foldl (shApp Visible) (shAtom s) <$> mapM f xs | ||
2086 | CaseFunN s xs -> foldl (shApp Visible) (shAtom s) <$> mapM f xs | ||
2087 | ConN s xs -> foldl (shApp Visible) (shAtom s) <$> mapM f xs | ||
2088 | TyConN s xs -> foldl (shApp Visible) (shAtom s) <$> mapM f xs | ||
2089 | TType -> pure $ shAtom "Type" | ||
2090 | ELit l -> pure $ shAtom $ show l | ||
2091 | Assign i x e -> shLet i (f x) (f e) | ||
2092 | LabelEnd x -> shApp Visible (shAtom "labend") <$> f x | ||
2093 | |||
2094 | sExpDoc :: SExp -> Doc | ||
2095 | sExpDoc = \case | ||
2096 | SGlobal s -> pure $ shAtom s | ||
2097 | SAnn a b -> shAnn ":" False <$> sExpDoc a <*> sExpDoc b | ||
2098 | TyType a -> shApp Visible (shAtom "tyType") <$> sExpDoc a | ||
2099 | SApp h a b -> shApp h <$> sExpDoc a <*> sExpDoc b | ||
2100 | -- Wildcard t -> shAnn True (shAtom "_") <$> sExpDoc t | ||
2101 | SBind h a b -> join $ shLam (usedS 0 b) h <$> sExpDoc a <*> pure (sExpDoc b) | ||
2102 | SLet a b -> shLet_ (sExpDoc a) (sExpDoc b) | ||
2103 | STyped (e, t) -> expDoc e | ||
2104 | SVar i -> expDoc (Var i) | ||
2105 | |||
2106 | shVar i = asks $ shAtom . lookupVarName where | ||
2107 | lookupVarName xs | i < length xs && i >= 0 = xs !! i | ||
2108 | lookupVarName _ = "V" ++ show i | ||
2109 | |||
2110 | shLet i a b = shVar i >>= \i' -> local (dropNth i) $ shLam' <$> (cpar . shLet' (fmap inBlue i') <$> a) <*> b | ||
2111 | shLet_ a b = (gets head <* modify tail) >>= \i -> shLam' <$> (cpar . shLet' (shAtom i) <$> a) <*> local (i:) b | ||
2112 | shLam used h a b = (gets head <* modify tail) >>= \i -> | ||
2113 | let lam = case h of | ||
2114 | BPi _ -> shArr | ||
2115 | _ -> shLam' | ||
2116 | p = case h of | ||
2117 | BMeta -> cpar . shAnn ":" True (shAtom $ inBlue i) | ||
2118 | BLam h -> vpar h | ||
2119 | BPi h -> vpar h | ||
2120 | vpar Hidden = brace . shAnn ":" True (shAtom $ inGreen i) | ||
2121 | vpar Visible = ann (shAtom $ inGreen i) | ||
2122 | ann | used = shAnn ":" False | ||
2123 | | otherwise = const id | ||
2124 | in lam (p a) <$> local (i:) b | ||
2125 | |||
2126 | ----------------------------------------- | ||
2127 | |||
2128 | data PS a = PS Prec a deriving (Functor) | ||
2129 | type PrecString = PS String | ||
2130 | |||
2131 | getPrec (PS p _) = p | ||
2132 | prec i s = PS i (s i) | ||
2133 | str (PS _ s) = s | ||
2134 | |||
2135 | data Prec | ||
2136 | = PrecAtom -- ( _ ) ... | ||
2137 | | PrecAtom' | ||
2138 | | PrecProj -- _ ._ {left} | ||
2139 | | PrecSwiz -- _%_ {left} | ||
2140 | | PrecApp -- _ _ {left} | ||
2141 | | PrecOp | ||
2142 | | PrecArr -- _ -> _ {right} | ||
2143 | | PrecEq -- _ ~ _ | ||
2144 | | PrecAnn -- _ :: _ {right} | ||
2145 | | PrecLet -- _ := _ | ||
2146 | | PrecLam -- \ _ -> _ {right} {accum} | ||
2147 | deriving (Eq, Ord) | ||
2148 | |||
2149 | lpar, rpar :: PrecString -> Prec -> String | ||
2150 | lpar (PS i s) j = par (i >. j) s where | ||
2151 | PrecLam >. i = i > PrecAtom' | ||
2152 | i >. PrecLam = i >= PrecArr | ||
2153 | PrecApp >. PrecApp = False | ||
2154 | i >. j = i >= j | ||
2155 | rpar (PS i s) j = par (i >. j) s where | ||
2156 | PrecLam >. PrecLam = False | ||
2157 | PrecLam >. i = i > PrecAtom' | ||
2158 | PrecArr >. PrecArr = False | ||
2159 | PrecAnn >. PrecAnn = False | ||
2160 | i >. j = i >= j | ||
2161 | |||
2162 | par True s = "(" ++ s ++ ")" | ||
2163 | par False s = s | ||
2164 | |||
2165 | isAtom = (==PrecAtom) . getPrec | ||
2166 | isAtom' = (<=PrecAtom') . getPrec | ||
2167 | |||
2168 | shAtom = PS PrecAtom | ||
2169 | shAtom' = PS PrecAtom' | ||
2170 | shAnn _ True x y | str y `elem` ["Type", inGreen "Type"] = x | ||
2171 | shAnn s simp x y | isAtom x && isAtom y = shAtom' $ str x <> s <> str y | ||
2172 | shAnn s simp x y = prec PrecAnn $ lpar x <> " " <> const s <> " " <> rpar y | ||
2173 | shApp Hidden x y = prec PrecApp $ lpar x <> " " <> const (str $ brace y) | ||
2174 | shApp h x y = prec PrecApp $ lpar x <> " " <> rpar y | ||
2175 | shArr x y | isAtom x && isAtom y = shAtom' $ str x <> "->" <> str y | ||
2176 | shArr x y = prec PrecArr $ lpar x <> " -> " <> rpar y | ||
2177 | shCstr x y | isAtom x && isAtom y = shAtom' $ str x <> "~" <> str y | ||
2178 | shCstr x y = prec PrecEq $ lpar x <> " ~ " <> rpar y | ||
2179 | shLet' x y | isAtom x && isAtom y = shAtom' $ str x <> ":=" <> str y | ||
2180 | shLet' x y = prec PrecLet $ lpar x <> " := " <> rpar y | ||
2181 | shLam' x y | PrecLam <- getPrec y = prec PrecLam $ "\\" <> lpar x <> " " <> pure (dropC $ str y) | ||
2182 | shLam' x y | isAtom x && isAtom y = shAtom' $ "\\" <> str x <> "->" <> str y | ||
2183 | shLam' x y = prec PrecLam $ "\\" <> lpar x <> " -> " <> rpar y | ||
2184 | brace s = shAtom $ "{" <> str s <> "}" | ||
2185 | cpar s | isAtom' s = s -- TODO: replace with lpar, rpar | ||
2186 | cpar s = shAtom $ par True $ str s | ||
2187 | epar s = fmap underlined s | ||
2188 | |||
2189 | dropC (ESC s (dropC -> x)) = ESC s x | ||
2190 | dropC (x: xs) = xs | ||
2191 | |||
2192 | pattern ESC a b <- (splitESC -> Just (a, b)) where ESC a b | all (/='m') a = "\ESC[" ++ a ++ "m" ++ b | ||
2193 | |||
2194 | splitESC ('\ESC':'[': (span (/='m') -> (a, ~(c: b)))) | c == 'm' = Just (a, b) | ||
2195 | splitESC _ = Nothing | ||
2196 | |||
2197 | instance IsString (Prec -> String) where fromString = const | ||
2198 | |||
2199 | inGreen = withEsc 32 | ||
2200 | inBlue = withEsc 34 | ||
2201 | inRed = withEsc 31 | ||
2202 | underlined = withEsc 47 | ||
2203 | withEsc i s = ESC (show i) $ s ++ ESC "" "" | ||
2204 | |||
2205 | correctEscs = (++ "\ESC[K") . f ["39","49"] where | ||
2206 | f acc (ESC i@(_:_) cs) = ESC i $ f (i:acc) cs | ||
2207 | f (a: acc) (ESC "" cs) = ESC (compOld (cType a) acc) $ f acc cs | ||
2208 | f acc (c: cs) = c: f acc cs | ||
2209 | f acc [] = [] | ||
2210 | |||
2211 | compOld x xs = head $ filter ((== x) . cType) xs | ||
2212 | |||
2213 | cType n | ||
2214 | | "30" <= n && n <= "39" = 0 | ||
2215 | | "40" <= n && n <= "49" = 1 | ||
2216 | | otherwise = 2 | ||
2217 | |||
2218 | |||
2219 | putStrLn_ = putStrLn . correctEscs | ||
2220 | error_ = error . correctEscs | ||
2221 | trace_ = trace . correctEscs | ||
2222 | throwError_ = throwError . correctEscs | ||
2223 | traceD x = if debug then trace_ x else id | ||
2224 | |||
2225 | -------------------------------------------------------------------------------- main | ||
2226 | |||
2227 | type TraceLevel = Int | ||
2228 | trace_level = 0 :: TraceLevel -- 0: no trace | ||
2229 | tr = False --trace_level >= 2 | ||
2230 | tr_light = trace_level >= 1 | ||
2231 | |||
2232 | debug = False--True--tr | ||
2233 | debug_light = True--False | ||
2234 | |||
2235 | infer :: GlobalEnv -> [Stmt] -> Either String GlobalEnv | ||
2236 | infer env = fmap (forceGE . snd) . runExcept . flip runStateT (initEnv <> env) . mapM_ handleStmt | ||
2237 | |||
2238 | forceGE x = length (concatMap (uncurry (++) . (showExp *** showExp)) $ Map.elems x) `seq` x | ||
2239 | |||
2240 | fromRight ~(Right x) = x | ||
2241 | |||
2242 | -------------------------------------------------------------------------------- utils | ||
2243 | |||
2244 | dropNth i xs = take i xs ++ drop (i+1) xs | ||
2245 | iterateN n f e = iterate f e !! n | ||
2246 | holes xs = [(as, x, bs) | (as, x: bs) <- zip (inits xs) (tails xs)] | ||
2247 | |||
diff --git a/prototypes/Linear.hs b/prototypes/Linear.hs deleted file mode 120000 index 5f80cf33..00000000 --- a/prototypes/Linear.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../Linear.hs \ No newline at end of file | ||
diff --git a/prototypes/Parser.hs b/prototypes/Parser.hs deleted file mode 100644 index 75a3a722..00000000 --- a/prototypes/Parser.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | module Parser where | ||
diff --git a/prototypes/Pretty.hs b/prototypes/Pretty.hs deleted file mode 120000 index eb36e481..00000000 --- a/prototypes/Pretty.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../Pretty.hs \ No newline at end of file | ||
diff --git a/prototypes/TODO b/prototypes/TODO deleted file mode 100644 index 9329cd9f..00000000 --- a/prototypes/TODO +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | |||
2 | Done: | ||
3 | |||
4 | - pattern match compiler prototípus | ||
5 | - beépítve a korábbi fordítóba | ||
6 | - IORef-es/STRef-es kiértékelő | ||
7 | -> ennek a használata elbonyolítaná az implementációt: | ||
8 | - mindent monadikussá kellene tenni, ez különösen fájdalmas mintaillesztéskor | ||
9 | - plusz típusváltozó minden típuban / vagy IO mindenhol | ||
10 | - explicit sharing mindenhol | ||
11 | - tiszta hatékony interpreter + típusellenőrző függő típusozáshoz | ||
12 | - tiszta, a Haskell lusta kiértékelését használja sharingre | ||
13 | - külön kiértékelő típusozás közben és típusozás után a hatékonyság növelésére | ||
14 | - type erasure a hatékonyság növelésére (az dep. type ellensúlyozására) | ||
15 | - memory leak ellen védett De Bruijn változók | ||
16 | - a kifejezésektől különválasztott típus a hatékonyság növelésére | ||
17 | - többszöri próbálkozás az beépítésre az előző fordítóba | ||
18 | még meglévő különbségek: | ||
19 | - nincs különválasztva a típusozás közbeni és utáni kiértékelés | ||
20 | - globális nevek vs. De Bruijn | ||
21 | - ad-hoc rejtett argumentumok (működnek vele a dep. rekordokkal emulált típusosztályok) | ||
22 | - ad-hoc RankNTypes (magic, valahogy működnek vele a dep. rekordokkal emulált típusosztályok) | ||
23 | - ad-hoc type erasure (megy konstruktorokra, nem megy a felhasználó által definiált kifejezésekre) | ||
24 | - nincs különválasztva a típus | ||
25 | - a kompozícionális típusozó nem tudja felhasználni a típusban megadott segítséget | ||
26 | - ez kizárja pl. RankNType-ot, és a függő típusozást | ||
27 | - a meglévő példákhoz nem kellett, összetettebb dep. rekordos típusosztályoknál kritikus lehet | ||
28 | - típusozó prototípus | ||
29 | - irányított (figyelembe veszi a megadott típusokat) | ||
30 | - dependens | ||
31 | - rejtett argumentumok | ||
32 | - RankNTypes | ||
33 | - pattern matching compiler beépítése | ||
34 | - több implementáció kipróbálása, a legutolsó zippereket használ | ||
35 | - könyebb debugolás | ||
36 | - eddigi leghatékonyabb | ||
37 | - kicsi implementáció, és bővíthetőnek is látszik | ||
38 | - címkézés a jobb mintaillesztés támogatáshoz | ||
39 | |||
40 | összefoglaló TODO lista | ||
41 | |||
42 | fő tennivaló: a típusozó kiegészítése | ||
43 | - syntactic sugars | ||
44 | - type classes as a syntax sugar | ||
45 | - egyszerűbb, átlátható szemantika | ||
46 | - könnyebb a más nyelvi elemekkel való viszonyát tisztázni | ||
47 | - modulárisabb implementáció | ||
48 | - könnyebben karbantartható | ||
49 | - könnyebben tesztelhető implementáció | ||
50 | - teljesítmény javítás, több check | ||
51 | |||
52 | |||
53 | -------------------------------------------------------------------------------- short-term TODOs | ||
54 | - GLSL codegen doesn't support Vector and tuple patterns (not compiler frontend related): | ||
55 | fragment02tuple | ||
56 | fragment02vectorpattern | ||
57 | fragment05uniform | ||
58 | - recheck should not fail - coe missing? | ||
59 | - fix loop | ||
60 | primes | ||
61 | recursivetexture01 | ||
62 | - (a ~ b) + (a ~ c) ---> b ~ c (fragment06tailrecursion) | ||
63 | |||
64 | -------------------------------------------------------------------------------- TODOs after 100% tests (completion & cleanup) | ||
65 | |||
66 | - @ patterns | ||
67 | - guards | ||
68 | - guards + where | ||
69 | - complete & review builtin reductions & move out into libraries | ||
70 | - type annotation in where blocks | ||
71 | - dependent prelude should work again | ||
72 | |||
73 | - constructor operator fixities (also in patterns) | ||
74 | - local pattern matching functions | ||
75 | - mutual recursion (as a language extension) | ||
76 | - record filed name handling | ||
77 | |||
78 | - data Wrong = Wrong a | ||
79 | |||
80 | - basic refactoring | ||
81 | |||
82 | - de-brunify move away from parser? / refactoring | ||
83 | |||
84 | - ambiguity check | ||
85 | - suppress univ. polymorphic ambiguity | ||
86 | - konstans megadott típus szigorúan vétele | ||
87 | - prohibit constraints like a ~ List a, a ~ a -> a, etc. | ||
88 | |||
89 | - bug fix (as needed) | ||
90 | - (~) :: forall a b . a -> b -> Type ? | ||
91 | - bug: head <-> tail csere nem jelez hibát, viszont recheck fails | ||
92 | - coe korrektebb használata (másmikor kell beszúrni) ? | ||
93 | - app típusozás jobban | ||
94 | - label + let arity in recursive definitions | ||
95 | |||
96 | |||
97 | -------------------------------------------------------------------------------- medium-term TODOs | ||
98 | |||
99 | - type classes | ||
100 | - generate type-case functions | ||
101 | - class parse + desugaring | ||
102 | - instance parse (drop it first) | ||
103 | - type class desugaring | ||
104 | - super class "visszaállítás" | ||
105 | - Constraint type: uniqueness of witnesses 0-1 elemű típusokra | ||
106 | |||
107 | - better error messages | ||
108 | - location infó | ||
109 | - jobb normalizáció elkerülés (String => [Char] lehetőleg ne) | ||
110 | - kompozícionálisabb inference? | ||
111 | |||
112 | - systematic micro tests (with quickcheck?) | ||
113 | |||
114 | - performance | ||
115 | - típus-érték különválasztás (vs. church style lambda) | ||
116 | - lam változó típusának kitörlése | ||
117 | expType | ||
118 | recheck | ||
119 | envDoc, expDoc | ||
120 | cstr | ||
121 | foldE ? | ||
122 | - neutrális termek külön | ||
123 | - konstruktorok univ. pol. típusainak kitörlése | ||
124 | - irrelevance + erasure | ||
125 | - max. De Bruijn index számolás | ||
126 | |||
127 | - ügyesebb De Bruijn (kitörlős) | ||
128 | - interpretált De Bruijn | ||
129 | - coe / type class irrelevance switch | ||
130 | |||
131 | - injektivitás inferencia | ||
132 | |||
133 | - open functions, type families syntax | ||
134 | |||
135 | - dep. pattern matching | ||
136 | - evalXXX deriválás | ||
137 | |||
138 | - frekvenciák | ||
139 | |||
140 | - separate LambdaCube 3D specific parts | ||
141 | |||
142 | -------------------------------------------------------------------------------- cleanup after medium-term TODOs | ||
143 | |||
144 | - huge refactoring, documentation, test cases, ... | ||
145 | |||
146 | milestone: 1.0 compiler | ||
147 | |||
148 | |||
149 | -------------------------------------------------------------------------------- notes | ||
150 | -------------------------------------------------------------------------------- | ||
151 | |||
152 | -------------------------------------------------------------------------------- row polymorphism | ||
153 | |||
154 | builtins | ||
155 | Split :: Type -> Type -> Type -> Constraint --Type | ||
156 | |||
157 | |||
158 | data RecordC (xs :: List (Pair String Type)) | ||
159 | = RecordCons (tuptype (map snd xs)) | ||
160 | |||
161 | tuptype [] = () | ||
162 | tuptype (x: xs) = (x, tuptype xs) | ||
163 | |||
164 | Record :: List (Pair String Type) -> Type | ||
165 | Record xs = RecordC (sortBy fst xs) | ||
166 | |||
167 | builtins | ||
168 | project :: forall (xs :: List [(String, Type)]) . (s :: String) -> (Split (RecordC xs) (RecordC [(s, a)] b) -> RecordC xs -> a | ||
169 | |||
170 | -- project = ... | ||
171 | |||
172 | |||
173 | w :: Split a b c | ||
174 | iff | ||
175 | a = Record as | ||
176 | b = Record bs | ||
177 | c = Record cs | ||
178 | |||
179 | bs `sublist` as | ||
180 | cs `sublist` as | ||
181 | map fst bs `disjunct` map fst cs | ||
182 | |||
183 | |||
184 | :: Record {x: Float} | ||
185 | |||
186 | |||
187 | v1 :: Record {x: Float, y: Float, z: Float} | ||
188 | v1 = {x: 1.0, y: 2.0, z: 3.0} ----> RecordCons @[("x", _), ("y", _), ("z", _)] (1.0, (2.0, (3.0, ()))) | ||
189 | v2 = {x: 1.0, y: 2.0, z: 3.0, a: 4.0} | ||
190 | |||
191 | f :: (Split a (Record {x: Float, y: Float}) b) => a -> Float | ||
192 | f v = v.x +! v.y | ||
193 | |||
194 | r = f v1 +! f v2 -- this is valid | ||
195 | |||
196 | |||
197 | exp.field -----> project field exp | ||
198 | |||
199 | f v1 -- a ~ Record {x: Float, y: Float, z: Float} | ||
200 | |||
201 | |||
202 | eval | ||
203 | Split (Record xs) (Record ys) c = eval $ c ~ Record (xs \\ ys) | ||
204 | Split (Record xs) c (Record ys) = eval $ c ~ Record (xs \\ ys) | ||
205 | Split a (Record xs) (Record ys) = eval $ a ~ Record (xs ++ ys) | ||
206 | |||
207 | |||
diff --git a/prototypes/Text b/prototypes/Text deleted file mode 120000 index 4ea788ba..00000000 --- a/prototypes/Text +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../Text \ No newline at end of file | ||
diff --git a/prototypes/Type.hs b/prototypes/Type.hs deleted file mode 100644 index 8e1e6af5..00000000 --- a/prototypes/Type.hs +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | module Type ( module CGExp ) where | ||
2 | import CGExp | ||
diff --git a/prototypes/Typecheck.hs b/prototypes/Typecheck.hs deleted file mode 100644 index dc82a9a0..00000000 --- a/prototypes/Typecheck.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | module Typecheck where | ||
diff --git a/prototypes/create-test-report.sh b/prototypes/create-test-report.sh deleted file mode 100755 index 4d26467a..00000000 --- a/prototypes/create-test-report.sh +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #! /bin/sh | ||
2 | |||
3 | CABAL_NAME=lambdacube-compiler | ||
4 | |||
5 | HPC_DIR=dist/hpc/${CABAL_NAME} | ||
6 | HPC_REPO_DIR=$HPC_DIR | ||
7 | |||
8 | TEST_DIR=src/UnitTest | ||
9 | TIX=lambdacube-compiler-test-suite.tix | ||
10 | |||
11 | hpc report ${TIX} --hpcdir=${HPC_DIR} --xml-output > ${HPC_REPO_DIR}/result.xml | ||
12 | hpc markup ${TIX} --hpcdir=${HPC_DIR} --destdir=${HPC_REPO_DIR} | ||
diff --git a/prototypes/lambdacube-compiler.cabal b/prototypes/lambdacube-compiler.cabal deleted file mode 100644 index 76d26c98..00000000 --- a/prototypes/lambdacube-compiler.cabal +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | -- Initial lambdacube-dsl.cabal generated by cabal init. For further | ||
2 | -- documentation, see http://haskell.org/cabal/users-guide/ | ||
3 | |||
4 | name: lambdacube-compiler | ||
5 | version: 0.2.0.0 | ||
6 | homepage: lambdacube3d.com | ||
7 | license: BSD3 | ||
8 | license-file: LICENSE | ||
9 | author: Csaba Hruska, Peter Divianszky | ||
10 | maintainer: csaba.hruska@gmail.com | ||
11 | category: Graphics | ||
12 | build-type: Simple | ||
13 | cabal-version: >=1.10 | ||
14 | |||
15 | Flag profiling | ||
16 | Description: Enable profiling | ||
17 | Default: False | ||
18 | |||
19 | library | ||
20 | -- indentation parser modules | ||
21 | exposed-modules: Text.Parser.Indentation.Implementation, | ||
22 | Text.Parsec.Indentation, | ||
23 | Text.Parsec.Indentation.Char, | ||
24 | Text.Parsec.Indentation.Token | ||
25 | exposed-modules: | ||
26 | -- Compiler | ||
27 | Pretty | ||
28 | Type | ||
29 | Typecheck | ||
30 | Parser | ||
31 | IR | ||
32 | Linear | ||
33 | CoreToIR | ||
34 | CoreToGLSL | ||
35 | Infer | ||
36 | CGExp | ||
37 | Driver | ||
38 | other-extensions: | ||
39 | LambdaCase | ||
40 | PatternSynonyms | ||
41 | ViewPatterns | ||
42 | TypeSynonymInstances | ||
43 | FlexibleInstances | ||
44 | NoMonomorphismRestriction | ||
45 | TypeFamilies | ||
46 | RecordWildCards | ||
47 | DeriveFunctor | ||
48 | DeriveFoldable | ||
49 | DeriveTraversable | ||
50 | GeneralizedNewtypeDeriving | ||
51 | OverloadedStrings | ||
52 | TupleSections | ||
53 | MonadComprehensions | ||
54 | ExistentialQuantification | ||
55 | ScopedTypeVariables | ||
56 | ParallelListComp | ||
57 | build-depends: | ||
58 | -- compiler | ||
59 | aeson >= 0.9 && <1, | ||
60 | base >=4.7 && <4.9, | ||
61 | containers >=0.5 && <0.6, | ||
62 | deepseq, | ||
63 | directory, | ||
64 | exceptions >= 0.8 && <0.9, | ||
65 | filepath, | ||
66 | mtl >=2.2 && <2.3, | ||
67 | parsec >= 3.1 && <3.2, | ||
68 | pretty-compact >=1.0 && <1.1, | ||
69 | text >= 1.2 && <1.3, | ||
70 | vector >= 0.11 && <0.12 | ||
71 | hs-source-dirs: . | ||
72 | default-language: Haskell2010 | ||
73 | |||
74 | executable lambdacube-compiler-test-suite | ||
75 | hs-source-dirs: . | ||
76 | main-is: runTests.hs | ||
77 | |||
78 | build-depends: | ||
79 | aeson >= 0.9 && <1, | ||
80 | base < 4.9, | ||
81 | containers >=0.5 && <0.6, | ||
82 | deepseq, | ||
83 | directory, | ||
84 | exceptions >= 0.8 && <0.9, | ||
85 | filepath, | ||
86 | mtl >=2.2 && <2.3, | ||
87 | lambdacube-compiler, | ||
88 | parsec >= 3.1 && <3.2, | ||
89 | pretty-compact >=1.0 && <1.1, | ||
90 | text >= 1.2 && <1.3, | ||
91 | vector >= 0.11 && <0.12 | ||
92 | default-language: Haskell2010 | ||
93 | if flag(profiling) | ||
94 | GHC-Options: -O2 -fhpc -hpcdir dist/hpc/lambdacube-compiler -prof -fprof-auto -rtsopts | ||
95 | else | ||
96 | GHC-Options: -O2 -fhpc -hpcdir dist/hpc/lambdacube-compiler | ||
diff --git a/prototypes/run-test-suite.sh b/prototypes/run-test-suite.sh deleted file mode 100755 index 9ced8e55..00000000 --- a/prototypes/run-test-suite.sh +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | if [ "$1" == "--profile" ] ; then | ||
4 | shift | ||
5 | cabal clean | ||
6 | cabal sandbox delete | ||
7 | cabal sandbox init | ||
8 | cabal install --only-dependencies --enable-library-profiling --enable-executable-profiling | ||
9 | cabal configure --flags "profiling" --enable-library-profiling --enable-executable-profiling | ||
10 | cabal build | ||
11 | cabal run lambdacube-compiler-test-suite -- $@ +RTS -p | ||
12 | ./create-test-report.sh | ||
13 | rm lambdacube-compiler-test-suite.tix | ||
14 | cabal sandbox delete | ||
15 | cabal clean | ||
16 | else | ||
17 | cabal run lambdacube-compiler-test-suite -- $@ | ||
18 | ./create-test-report.sh | ||
19 | rm lambdacube-compiler-test-suite.tix | ||
20 | fi | ||
diff --git a/prototypes/runTests.hs b/prototypes/runTests.hs deleted file mode 120000 index 74e37a7a..00000000 --- a/prototypes/runTests.hs +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../runTests.hs \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/Builtins.lc b/prototypes/tests/accept/Builtins.lc deleted file mode 100644 index 187a6e9e..00000000 --- a/prototypes/tests/accept/Builtins.lc +++ /dev/null | |||
@@ -1,568 +0,0 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | ||
2 | -- module Builtins where | ||
3 | |||
4 | builtins | ||
5 | cstr :: Type -> Type -> Type | ||
6 | -- reflCstr :: forall (a :: Type) -> cstr a a | ||
7 | T2 :: Type -> Type -> Type | ||
8 | T2C :: Unit -> Unit -> Unit | ||
9 | |||
10 | data Unit = TT | ||
11 | |||
12 | -- TODO: generate? | ||
13 | data Tuple0 = Tuple0 | ||
14 | data Tuple1 a = Tuple1 a | ||
15 | data Tuple2 a b = Tuple2 a b | ||
16 | data Tuple3 a b c = Tuple3 a b c | ||
17 | data Tuple4 a b c d = Tuple4 a b c d | ||
18 | data Tuple5 a b c d e = Tuple5 a b c d e | ||
19 | |||
20 | id x = x | ||
21 | |||
22 | data Bool = False | True | ||
23 | |||
24 | data Ordering = LT | EQ | GT | ||
25 | |||
26 | primIfThenElse :: Bool -> a -> a -> a | ||
27 | primIfThenElse True a b = a | ||
28 | primIfThenElse False a b = b | ||
29 | |||
30 | --------------------------------------- | ||
31 | |||
32 | data Nat = Zero | Succ Nat | ||
33 | |||
34 | builtintycons | ||
35 | Int :: Type | ||
36 | Word :: Type | ||
37 | Float :: Type | ||
38 | Char :: Type | ||
39 | String :: Type | ||
40 | |||
41 | {- | ||
42 | type family TFVec (n :: Nat) a -- may be a data family | ||
43 | type family VecScalar (n :: Nat) a | ||
44 | type family TFMat i j -- may be a data family | ||
45 | type family MatVecElem a | ||
46 | type family MatVecScalarElem a | ||
47 | type family FTRepr' a | ||
48 | type family ColorRepr a | ||
49 | type family TFFrameBuffer a | ||
50 | type family FragOps a | ||
51 | type family JoinTupleType t1 t2 | ||
52 | class AttributeTuple a | ||
53 | class ValidOutput a | ||
54 | class ValidFrameBuffer a | ||
55 | -} | ||
56 | builtins | ||
57 | TFVec :: Nat -> Type -> Type | ||
58 | VecScalar :: Nat -> Type -> Type | ||
59 | TFMat :: Type -> Type -> Type | ||
60 | MatVecElem :: Type -> Type | ||
61 | MatVecScalarElem :: Type -> Type | ||
62 | FTRepr' :: Type -> Type | ||
63 | ColorRepr :: Type -> Type | ||
64 | TFFrameBuffer :: Type -> Type | ||
65 | FragOps :: Type -> Type | ||
66 | JoinTupleType :: Type -> Type -> Type | ||
67 | |||
68 | AttributeTuple :: Type -> Type | ||
69 | ValidOutput :: Type -> Type | ||
70 | ValidFrameBuffer :: Type -> Type | ||
71 | |||
72 | data VecS (a :: Type) :: Nat -> Type where | ||
73 | V2 :: a -> a -> VecS a 2 | ||
74 | V3 :: a -> a -> a -> VecS a 3 | ||
75 | V4 :: a -> a -> a -> a -> VecS a 4 | ||
76 | |||
77 | builtins | ||
78 | Vec :: Nat -> Type -> Type | ||
79 | --Vec n t = VecS t n | ||
80 | |||
81 | |||
82 | data Mat :: Nat -> Nat -> Type -> Type where | ||
83 | M22F :: Vec 2 Float -> Vec 2 Float -> Mat 2 2 Float | ||
84 | M23F :: Vec 2 Float -> Vec 2 Float -> Vec 2 Float -> Mat 2 3 Float | ||
85 | M24F :: Vec 2 Float -> Vec 2 Float -> Vec 2 Float -> Vec 2 Float -> Mat 2 4 Float | ||
86 | M32F :: Vec 3 Float -> Vec 3 Float -> Mat 3 2 Float | ||
87 | M33F :: Vec 3 Float -> Vec 3 Float -> Vec 3 Float -> Mat 3 3 Float | ||
88 | M34F :: Vec 3 Float -> Vec 3 Float -> Vec 3 Float -> Vec 3 Float -> Mat 3 4 Float | ||
89 | M42F :: Vec 4 Float -> Vec 4 Float -> Mat 4 2 Float | ||
90 | M43F :: Vec 4 Float -> Vec 4 Float -> Vec 4 Float -> Mat 4 3 Float | ||
91 | M44F :: Vec 4 Float -> Vec 4 Float -> Vec 4 Float -> Vec 4 Float -> Mat 4 4 Float | ||
92 | |||
93 | |||
94 | builtins | ||
95 | CNum, Signed, Num, Component, Integral, NumComponent, Floating :: Type -> Type | ||
96 | |||
97 | fromInt :: Num a => Int -> a | ||
98 | compare :: Num a => a -> a -> Ordering | ||
99 | negate :: Num a => a -> a | ||
100 | |||
101 | vec2 :: Component a => a -> a -> Vec 2 a | ||
102 | vec3 :: Component a => a -> a -> a -> Vec 3 a | ||
103 | vec4 :: Component a => a -> a -> a -> a -> Vec 4 a | ||
104 | zeroComp :: Component a => a | ||
105 | oneComp :: Component a => a | ||
106 | |||
107 | --------------------------------------- swizzling | ||
108 | |||
109 | data Swizz = Sx | Sy | Sz | Sw | ||
110 | |||
111 | builtins | ||
112 | swizzvector :: forall n . forall m . Vec n a -> Vec m Swizz -> Vec m a | ||
113 | swizzscalar :: forall n . Vec n a -> Swizz -> a | ||
114 | |||
115 | {- | ||
116 | --------------------------------------- type classes | ||
117 | |||
118 | class CNum a | ||
119 | |||
120 | instance CNum Int | ||
121 | instance CNum Float | ||
122 | |||
123 | class Signed a | ||
124 | |||
125 | instance Signed Int | ||
126 | instance Signed Float | ||
127 | |||
128 | class Num a where | ||
129 | fromInt :: Int -> a | ||
130 | compare :: a -> a -> Ordering | ||
131 | negate :: a -> a | ||
132 | -} | ||
133 | builtins | ||
134 | primIntToWord :: Int -> Word | ||
135 | primIntToFloat :: Int -> Float | ||
136 | primCompareInt :: Int -> Int -> Ordering | ||
137 | primCompareWord :: Word -> Word -> Ordering | ||
138 | primCompareFloat :: Float -> Float -> Ordering | ||
139 | primNegateInt :: Int -> Int | ||
140 | primNegateWord :: Word -> Word | ||
141 | primNegateFloat :: Float -> Float | ||
142 | |||
143 | {- | ||
144 | instance Num Int where | ||
145 | fromInt = id | ||
146 | compare = primCompareInt | ||
147 | negate = primNegateInt | ||
148 | instance Num Word where | ||
149 | fromInt = primIntToWord | ||
150 | compare = primCompareWord | ||
151 | negate = primNegateWord | ||
152 | instance Num Float where | ||
153 | fromInt = primIntToFloat | ||
154 | compare = primCompareFloat | ||
155 | negate = primNegateFloat | ||
156 | |||
157 | class Component a where | ||
158 | vec2 :: a -> a -> Vec 2 a | ||
159 | vec3 :: a -> a -> a -> Vec 3 a | ||
160 | vec4 :: a -> a -> a -> a -> Vec 4 a | ||
161 | zeroComp :: a | ||
162 | oneComp :: a | ||
163 | -- PrimZero, PrimOne :: {- (Component a) => -- TODO -} a | ||
164 | |||
165 | |||
166 | instance Component Bool where | ||
167 | vec2 = V2 | ||
168 | vec3 = V3 | ||
169 | vec4 = V4 | ||
170 | zeroComp = False | ||
171 | oneComp = True | ||
172 | |||
173 | instance Component Int where | ||
174 | vec2 = V2 | ||
175 | vec3 = V3 | ||
176 | vec4 = V4 | ||
177 | zeroComp = 0 | ||
178 | oneComp = 1 | ||
179 | |||
180 | instance Component Word where | ||
181 | vec2 = V2 | ||
182 | vec3 = V3 | ||
183 | vec4 = V4 | ||
184 | zeroComp = 0 | ||
185 | oneComp = 1 | ||
186 | |||
187 | instance Component Float where | ||
188 | vec2 = V2 | ||
189 | vec3 = V3 | ||
190 | vec4 = V4 | ||
191 | zeroComp = 0 | ||
192 | oneComp = 1 | ||
193 | |||
194 | instance Component (Vec 2 Float) where | ||
195 | vec2 = V2 | ||
196 | vec3 = V3 | ||
197 | vec4 = V4 | ||
198 | zeroComp = V2 0.0 0.0 | ||
199 | oneComp = V2 1.0 1.0 | ||
200 | instance Component (Vec 3 Float) where | ||
201 | vec2 = V2 | ||
202 | vec3 = V3 | ||
203 | vec4 = V4 | ||
204 | zeroComp = V3 0.0 0.0 0.0 | ||
205 | oneComp = V3 1.0 1.0 1.0 | ||
206 | instance Component (Vec 4 Float) where | ||
207 | vec2 = V2 | ||
208 | vec3 = V3 | ||
209 | vec4 = V4 | ||
210 | zeroComp = V4 0.0 0.0 0.0 0.0 | ||
211 | oneComp = V4 1.0 1.0 1.0 1.0 | ||
212 | |||
213 | --instance Component (Vec 2 Bool) where | ||
214 | --instance Component (Vec 3 Bool) where | ||
215 | |||
216 | instance Component (Vec 4 Bool) where | ||
217 | vec2 = V2 | ||
218 | vec3 = V3 | ||
219 | vec4 = V4 | ||
220 | zeroComp = V4 False False False False | ||
221 | oneComp = V4 True True True True | ||
222 | |||
223 | class Integral a | ||
224 | |||
225 | instance Integral Int | ||
226 | instance Integral Word | ||
227 | |||
228 | class NumComponent a | ||
229 | |||
230 | instance NumComponent Int | ||
231 | instance NumComponent Word | ||
232 | instance NumComponent Float | ||
233 | instance NumComponent (Vec 2 Float) | ||
234 | instance NumComponent (Vec 3 Float) | ||
235 | instance NumComponent (Vec 4 Float) | ||
236 | |||
237 | class Floating a | ||
238 | |||
239 | instance Floating Float | ||
240 | instance Floating (Vec 2 Float) | ||
241 | instance Floating (Vec 3 Float) | ||
242 | instance Floating (Vec 4 Float) | ||
243 | instance Floating (Mat 2 2 Float) | ||
244 | instance Floating (Mat 2 3 Float) | ||
245 | instance Floating (Mat 2 4 Float) | ||
246 | instance Floating (Mat 3 2 Float) | ||
247 | instance Floating (Mat 3 3 Float) | ||
248 | instance Floating (Mat 3 4 Float) | ||
249 | instance Floating (Mat 4 2 Float) | ||
250 | instance Floating (Mat 4 3 Float) | ||
251 | instance Floating (Mat 4 4 Float) | ||
252 | -} | ||
253 | |||
254 | data BlendingFactor | ||
255 | = Zero' --- FIXME: modified | ||
256 | | One | ||
257 | | SrcColor | ||
258 | | OneMinusSrcColor | ||
259 | | DstColor | ||
260 | | OneMinusDstColor | ||
261 | | SrcAlpha | ||
262 | | OneMinusSrcAlpha | ||
263 | | DstAlpha | ||
264 | | OneMinusDstAlpha | ||
265 | | ConstantColor | ||
266 | | OneMinusConstantColor | ||
267 | | ConstantAlpha | ||
268 | | OneMinusConstantAlpha | ||
269 | | SrcAlphaSaturate | ||
270 | |||
271 | data BlendEquation | ||
272 | = FuncAdd | ||
273 | | FuncSubtract | ||
274 | | FuncReverseSubtract | ||
275 | | Min | ||
276 | | Max | ||
277 | |||
278 | data LogicOperation | ||
279 | = Clear | ||
280 | | And | ||
281 | | AndReverse | ||
282 | | Copy | ||
283 | | AndInverted | ||
284 | | Noop | ||
285 | | Xor | ||
286 | | Or | ||
287 | | Nor | ||
288 | | Equiv | ||
289 | | Invert | ||
290 | | OrReverse | ||
291 | | CopyInverted | ||
292 | | OrInverted | ||
293 | | Nand | ||
294 | | Set | ||
295 | |||
296 | data StencilOperation | ||
297 | = OpZero | ||
298 | | OpKeep | ||
299 | | OpReplace | ||
300 | | OpIncr | ||
301 | | OpIncrWrap | ||
302 | | OpDecr | ||
303 | | OpDecrWrap | ||
304 | | OpInvert | ||
305 | |||
306 | data ComparisonFunction | ||
307 | = Never | ||
308 | | Less | ||
309 | | Equal | ||
310 | | Lequal | ||
311 | | Greater | ||
312 | | Notequal | ||
313 | | Gequal | ||
314 | | Always | ||
315 | |||
316 | data ProvokingVertex | ||
317 | = LastVertex | ||
318 | | FirstVertex | ||
319 | |||
320 | data FrontFace | ||
321 | = CW | ||
322 | | CCW | ||
323 | |||
324 | data CullMode | ||
325 | = CullFront FrontFace | ||
326 | | CullBack FrontFace | ||
327 | | CullNone | ||
328 | |||
329 | data PointSize | ||
330 | = PointSize Float | ||
331 | | ProgramPointSize | ||
332 | |||
333 | data PolygonMode | ||
334 | = PolygonFill | ||
335 | | PolygonPoint PointSize | ||
336 | | PolygonLine Float | ||
337 | |||
338 | data PolygonOffset | ||
339 | = NoOffset | ||
340 | | Offset Float Float | ||
341 | |||
342 | data PointSpriteCoordOrigin | ||
343 | = LowerLeft | ||
344 | | UpperLeft | ||
345 | |||
346 | |||
347 | data Depth a where | ||
348 | data Stencil a where | ||
349 | data Color a where | ||
350 | |||
351 | data PrimitiveType | ||
352 | = Triangle | ||
353 | | Line | ||
354 | | Point | ||
355 | | TriangleAdjacency | ||
356 | | LineAdjacency | ||
357 | |||
358 | builtincons | ||
359 | PrimTexture :: () -> Vec 2 Float -> Vec 4 Float | ||
360 | |||
361 | builtincons | ||
362 | Uniform :: String -> t | ||
363 | Attribute :: String -> t | ||
364 | |||
365 | data FragmentOut a where | ||
366 | FragmentOut :: (a ~ ColorRepr t) => t -> FragmentOut a | ||
367 | FragmentOutDepth :: (x ~ ColorRepr t, a ~ JoinTupleType (Depth Float) x) => Float -> t | ||
368 | -> FragmentOut a | ||
369 | FragmentOutRastDepth :: (x ~ ColorRepr t, a ~ JoinTupleType (Depth Float) x) => t | ||
370 | -> FragmentOut a | ||
371 | |||
372 | data VertexOut a where | ||
373 | VertexOut :: (a ~ FTRepr' x) => Vec 4 Float -> Float -> (){-TODO-} -> x -> VertexOut a | ||
374 | |||
375 | data RasterContext :: PrimitiveType -> Type where | ||
376 | TriangleCtx :: CullMode -> PolygonMode -> PolygonOffset -> ProvokingVertex -> RasterContext Triangle | ||
377 | PointCtx :: PointSize -> Float -> PointSpriteCoordOrigin -> RasterContext Point | ||
378 | LineCtx :: Float -> ProvokingVertex -> RasterContext Line | ||
379 | |||
380 | data FetchPrimitive :: PrimitiveType -> Type where | ||
381 | Points :: FetchPrimitive Point | ||
382 | Lines :: FetchPrimitive Line | ||
383 | Triangles :: FetchPrimitive Triangle | ||
384 | LinesAdjacency :: FetchPrimitive LineAdjacency | ||
385 | TrianglesAdjacency :: FetchPrimitive TriangleAdjacency | ||
386 | |||
387 | data AccumulationContext a where | ||
388 | AccumulationContext :: (a ~ FragOps t) => t -> AccumulationContext a | ||
389 | |||
390 | data Image (a :: Nat) :: Type -> Type where | ||
391 | ColorImage :: (Num t, color ~ VecScalar d t) | ||
392 | => color -> Image a (Color color) | ||
393 | DepthImage :: Float -> Image a (Depth Float) | ||
394 | StencilImage :: Int -> Image a (Stencil Int) | ||
395 | |||
396 | data Interpolated t where | ||
397 | Smooth, NoPerspective | ||
398 | :: (Floating t) => t -> Interpolated t | ||
399 | Flat :: t -> Interpolated t | ||
400 | |||
401 | data Blending :: Type -> Type where | ||
402 | NoBlending :: Blending t | ||
403 | BlendLogicOp :: (Integral t) => LogicOperation -> Blending t | ||
404 | Blend :: (BlendEquation, BlendEquation) | ||
405 | -> ((BlendingFactor, BlendingFactor), (BlendingFactor, BlendingFactor)) | ||
406 | -> Vec 4 Float -> Blending Float | ||
407 | |||
408 | {- TODO: more precise kinds | ||
409 | FragmentOperation :: Semantic -> * | ||
410 | FragmentOut :: Semantic -> * | ||
411 | VertexOut :: ??? | ||
412 | -} | ||
413 | |||
414 | data FragmentOperation :: Type -> Type where | ||
415 | ColorOp :: (mask ~ VecScalar d Bool, color ~ VecScalar d c, Num c) => Blending c -> mask | ||
416 | -> FragmentOperation (Color color) | ||
417 | DepthOp :: ComparisonFunction -> Bool -> FragmentOperation (Depth Float) | ||
418 | StencilOp :: StencilTests -> StencilOps -> StencilOps -> FragmentOperation (Stencil Int32) | ||
419 | |||
420 | data FragmentFilter t where | ||
421 | PassAll :: FragmentFilter t | ||
422 | Filter :: (t -> Bool) -> FragmentFilter t | ||
423 | |||
424 | data VertexStream (a :: PrimitiveType) t where | ||
425 | Fetch :: (AttributeTuple t) => String -> FetchPrimitive a -> t -> VertexStream a t | ||
426 | FetchArrays :: (AttributeTuple t, t ~ FTRepr' t') => FetchPrimitive a -> t' -> VertexStream a t | ||
427 | |||
428 | data PrimitiveStream (p :: PrimitiveType) :: Nat -> Type -> Type where | ||
429 | Transform :: (a -> VertexOut b) -> VertexStream p a -> PrimitiveStream p 1 b | ||
430 | |||
431 | -- Render Operations | ||
432 | data FragmentStream (n :: Nat) a where | ||
433 | Rasterize :: RasterContext x -> PrimitiveStream x n a -> FragmentStream n a | ||
434 | |||
435 | data FrameBuffer (n :: Nat) b where | ||
436 | Accumulate :: (ValidOutput b) => | ||
437 | AccumulationContext b | ||
438 | -> FragmentFilter a | ||
439 | -> (a -> FragmentOut b) | ||
440 | -> FragmentStream n a | ||
441 | -> FrameBuffer n b | ||
442 | -> FrameBuffer n b | ||
443 | |||
444 | FrameBuffer :: (ValidFrameBuffer b, FrameBuffer n b ~ TFFrameBuffer a) | ||
445 | => a -> FrameBuffer n b | ||
446 | |||
447 | |||
448 | data Output where | ||
449 | ScreenOut :: FrameBuffer a b -> Output | ||
450 | |||
451 | builtins | ||
452 | -- * Primitive Functions * | ||
453 | -- Arithmetic Functions (componentwise) | ||
454 | |||
455 | PrimAdd, PrimSub, PrimMul :: (t ~ MatVecElem a, Num t) => a -> a -> a | ||
456 | PrimAddS, PrimSubS, PrimMulS :: (t ~ MatVecScalarElem a, Num t) => a -> t -> a | ||
457 | PrimDiv, PrimMod :: (Num t, a ~ VecScalar d t) => a -> a -> a | ||
458 | PrimDivS, PrimModS :: (Num t, a ~ VecScalar d t) => a -> t -> a | ||
459 | PrimNeg :: (t ~ MatVecScalarElem a, Signed t) => a -> a | ||
460 | -- Bit-wise Functions | ||
461 | PrimBAnd, PrimBOr, PrimBXor :: (Integral t, a ~ VecScalar d t) => a -> a -> a | ||
462 | PrimBAndS, PrimBOrS, PrimBXorS:: (Integral t, a ~ VecScalar d t) => a -> t -> a | ||
463 | PrimBNot :: (Integral t, a ~ VecScalar d t) => a -> a | ||
464 | PrimBShiftL, PrimBShiftR :: (Integral t, a ~ VecScalar d t, b ~ VecScalar d Word) => a -> b -> a | ||
465 | PrimBShiftLS, PrimBShiftRS :: (Integral t, a ~ VecScalar d t) => a -> Word -> a | ||
466 | -- Logic Functions | ||
467 | PrimAnd, PrimOr, PrimXor :: Bool -> Bool -> Bool | ||
468 | PrimNot :: (a ~ VecScalar d Bool) => a -> a | ||
469 | PrimAny, PrimAll :: (a ~ VecScalar d Bool) => a -> Bool | ||
470 | |||
471 | -- Angle, Trigonometry and Exponential Functions | ||
472 | PrimACos, PrimACosH, PrimASin, PrimASinH, PrimATan, PrimATanH, PrimCos, PrimCosH, PrimDegrees, PrimRadians, PrimSin, PrimSinH, PrimTan, PrimTanH, PrimExp, PrimLog, PrimExp2, PrimLog2, PrimSqrt, PrimInvSqrt | ||
473 | :: (a ~ VecScalar d Float) => a -> a | ||
474 | PrimPow, PrimATan2 :: (a ~ VecScalar d Float) => a -> a -> a | ||
475 | -- Common Functions | ||
476 | PrimFloor, PrimTrunc, PrimRound, PrimRoundEven, PrimCeil, PrimFract | ||
477 | :: (a ~ VecScalar d Float) => a -> a | ||
478 | PrimMin, PrimMax :: (Num t, a ~ VecScalar d t) => a -> a -> a | ||
479 | PrimMinS, PrimMaxS :: (Num t, a ~ VecScalar d t) => a -> t -> a | ||
480 | PrimIsNan, PrimIsInf :: (a ~ VecScalar d Float, b ~ VecScalar d Bool) => a -> b | ||
481 | PrimAbs, PrimSign :: (Signed t, a ~ VecScalar d t) => a -> a | ||
482 | PrimModF :: (a ~ VecScalar d Float) => a -> (a, a) | ||
483 | PrimClamp :: (Num t, a ~ VecScalar d t) => a -> a -> a -> a | ||
484 | PrimClampS :: (Num t, a ~ VecScalar d t) => a -> t -> t -> a | ||
485 | PrimMix :: (a ~ VecScalar d Float) => a -> a -> a -> a | ||
486 | PrimMixS :: (a ~ VecScalar d Float) => a -> a -> Float -> a | ||
487 | PrimMixB :: (a ~ VecScalar d Float, b ~ VecScalar d Bool) => a -> a -> b -> a | ||
488 | PrimStep :: (a ~ TFVec d Float) => a -> a -> a | ||
489 | PrimStepS :: (a ~ VecScalar d Float) => Float -> a -> a | ||
490 | PrimSmoothStep :: (a ~ TFVec d Float) => a -> a -> a -> a | ||
491 | PrimSmoothStepS :: (a ~ VecScalar d Float) => Float -> Float -> a -> a | ||
492 | |||
493 | -- Integer/Floatonversion Functions | ||
494 | PrimFloatBitsToInt :: (fv ~ VecScalar d Float, iv ~ VecScalar d Int) => fv -> iv | ||
495 | PrimFloatBitsToUInt :: (fv ~ VecScalar d Float, uv ~ VecScalar d Word) => fv -> uv | ||
496 | PrimIntBitsToFloat :: (fv ~ VecScalar d Float, iv ~ VecScalar d Int) => iv -> fv | ||
497 | PrimUIntBitsToFloat :: (fv ~ VecScalar d Float, uv ~ VecScalar d Word) => uv -> fv | ||
498 | -- Geometric Functions | ||
499 | PrimLength :: (a ~ VecScalar d Float) => a -> Float | ||
500 | PrimDistance, PrimDot | ||
501 | :: (a ~ VecScalar d Float) => a -> a -> Float | ||
502 | PrimCross :: (a ~ VecScalar 3 Float) => a -> a -> a | ||
503 | PrimNormalize :: (a ~ VecScalar d Float) => a -> a | ||
504 | PrimFaceForward, PrimRefract | ||
505 | :: (a ~ VecScalar d Float) => a -> a -> a -> a | ||
506 | PrimReflect :: (a ~ VecScalar d Float) => a -> a -> a | ||
507 | -- Matrix Functions | ||
508 | PrimTranspose :: (a ~ TFMat h w, b ~ TFMat w h) => a -> b | ||
509 | PrimDeterminant :: (m ~ TFMat s s) => m -> Float | ||
510 | PrimInverse :: (m ~ TFMat s s) => m -> m | ||
511 | PrimOuterProduct :: (m ~ TFMat h w) => w -> h -> m | ||
512 | PrimMulMatVec :: (m ~ TFMat h w) => m -> w -> h | ||
513 | PrimMulVecMat :: (m ~ TFMat h w) => h -> m -> w | ||
514 | PrimMulMatMat :: (a ~ TFMat i j, b ~ TFMat j k, c ~ TFMat i k) => a -> b -> c | ||
515 | -- Vector and Scalar Relational Functions | ||
516 | PrimLessThan, PrimLessThanEqual, PrimGreaterThan, PrimGreaterThanEqual, PrimEqualV, PrimNotEqualV | ||
517 | :: (Num t, a ~ VecScalar d t, b ~ VecScalar d Bool) => a -> a -> b | ||
518 | PrimEqual, PrimNotEqual | ||
519 | :: (t ~ MatVecScalarElem a) => a -> a -> Bool | ||
520 | -- Fragment Processing Functions | ||
521 | PrimDFdx, PrimDFdy, PrimFWidth | ||
522 | :: (a ~ VecScalar d Float) => a -> a | ||
523 | -- Noise Functions | ||
524 | PrimNoise1 :: (a ~ VecScalar d Float) => a -> Float | ||
525 | PrimNoise2 :: (a ~ VecScalar d Float, b ~ VecScalar 2 Float) => a -> b | ||
526 | PrimNoise3 :: (a ~ VecScalar d Float, b ~ VecScalar 3 Float) => a -> b | ||
527 | PrimNoise4 :: (a ~ VecScalar d Float, b ~ VecScalar 4 Float) => a -> b | ||
528 | |||
529 | {- | ||
530 | -- Vec/Mat (de)construction | ||
531 | PrimTupToV2 :: Component a => PrimFun stage ((a,a) -> V2 a) | ||
532 | PrimTupToV3 :: Component a => PrimFun stage ((a,a,a) -> V3 a) | ||
533 | PrimTupToV4 :: Component a => PrimFun stage ((a,a,a,a) -> V4 a) | ||
534 | PrimV2ToTup :: Component a => PrimFun stage (V2 a -> (a,a)) | ||
535 | PrimV3ToTup :: Component a => PrimFun stage (V3 a -> (a,a,a)) | ||
536 | PrimV4ToTup :: Component a => PrimFun stage (V4 a -> (a,a,a,a)) | ||
537 | -} | ||
538 | |||
539 | -------------------- | ||
540 | -- * Texture support | ||
541 | -- FIXME: currently only Float RGBA 2D texture is supported | ||
542 | |||
543 | builtincons | ||
544 | PrjImage :: FrameBuffer 1 a -> Image 1 a | ||
545 | PrjImageColor :: FrameBuffer 1 (Depth Float, Color (Vec 4 Float)) -> Image 1 (Color (Vec 4 Float)) | ||
546 | |||
547 | data Texture where | ||
548 | Texture2DSlot :: String -- texture slot name | ||
549 | -> Texture | ||
550 | |||
551 | Texture2D :: Vec 2 Int -- FIXME: use Word here | ||
552 | -> Image 1 (Color (Vec 4 Float)) | ||
553 | -> Texture | ||
554 | |||
555 | data Filter | ||
556 | = PointFilter | ||
557 | | LinearFilter | ||
558 | |||
559 | data EdgeMode | ||
560 | = Repeat | ||
561 | | MirroredRepeat | ||
562 | | ClampToEdge | ||
563 | |||
564 | data Sampler = Sampler Filter EdgeMode Texture | ||
565 | |||
566 | builtincons | ||
567 | texture2D :: Sampler -> Vec 2 Float -> Vec 4 Float | ||
568 | |||
diff --git a/prototypes/tests/accept/DepPrelude.lc b/prototypes/tests/accept/DepPrelude.lc deleted file mode 100644 index facb4b7b..00000000 --- a/prototypes/tests/accept/DepPrelude.lc +++ /dev/null | |||
@@ -1,568 +0,0 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | ||
2 | {-# LANGUAGE NoTypeNamespace #-} | ||
3 | {-# LANGUAGE NoConstructorNamespace #-} | ||
4 | -- contains the lambda-pi prelude (http://www.andres-loeh.de/LambdaPi/prelude.lp) adatpted to the lc compiler prototype | ||
5 | builtintycons | ||
6 | Int :: Type | ||
7 | |||
8 | data Unit = TT | ||
9 | |||
10 | builtins | ||
11 | cstr :: Type -> Type -> Type -- TODO | ||
12 | -- cstr :: forall (a :: Type) (b :: Type) -> a -> b -> Type | ||
13 | -- reflCstr :: forall (a :: Type) -> cstr a a | ||
14 | coe :: forall (a :: Type) (b :: Type) -> cstr a b -> a -> b | ||
15 | |||
16 | tyType (a :: Type) = a | ||
17 | id a = a | ||
18 | const x y = x | ||
19 | const' :: forall a b . a -> b -> a | ||
20 | const' x y = x | ||
21 | const'' :: forall b a . a -> b -> a | ||
22 | const'' x y = x | ||
23 | id' a = id a | ||
24 | id'' = id id | ||
25 | app f x = f x | ||
26 | comp f g x = f (g x) | ||
27 | app2 f x y = f x y | ||
28 | flip f x y = f y x | ||
29 | scomb a b c = a c (b c) | ||
30 | |||
31 | builtins fix :: forall a . (a -> a) -> a | ||
32 | builtins f_i_x :: forall a . (a -> a) -> a | ||
33 | |||
34 | data Sigma a (b :: a -> Type) = Pair (x :: a) (b x) | ||
35 | |||
36 | -- undefined = undefined | ||
37 | builtins | ||
38 | undefined :: forall (a :: Type) . a | ||
39 | |||
40 | data Empty | ||
41 | --data T2 a b = T2C a b | ||
42 | builtins | ||
43 | T2 :: Type -> Type -> Type | ||
44 | T2C :: Unit -> Unit -> Unit | ||
45 | |||
46 | -- identity function, used for type annotations internally | ||
47 | typeAnn = \(A :: Type) (a :: A) -> a | ||
48 | |||
49 | data Bool = False | True | ||
50 | |||
51 | otherwise = True | ||
52 | |||
53 | if' b t f = case b of True -> t | ||
54 | False -> f | ||
55 | |||
56 | -- higher-order unification test | ||
57 | htest b = if' b id | ||
58 | htest' b = if' b id :: (forall a . a -> a) -> _ | ||
59 | htest'' b = if' b id :: _ -> (forall a . a -> a) | ||
60 | |||
61 | data List a = Nil' | Cons' a (List a) | ||
62 | |||
63 | builtins | ||
64 | primAdd, primSub, primMod | ||
65 | :: Int -> Int -> Int | ||
66 | primSqrt :: Int -> Int | ||
67 | primIntEq, primIntLess | ||
68 | :: Int -> Int -> Bool | ||
69 | |||
70 | dcomp | ||
71 | (X :: Type) | ||
72 | (Y :: X -> Type) | ||
73 | (Z :: forall (x :: X) -> Y x -> Type) | ||
74 | (f :: forall x (y :: Y x) -> Z x y) | ||
75 | (g :: forall (x :: X) -> Y x) | ||
76 | (x :: X) | ||
77 | = f x (g x) | ||
78 | dcomp' | ||
79 | @X | ||
80 | @(Y :: X -> _) | ||
81 | @(Z :: forall x -> Y x -> _) | ||
82 | (f :: forall x . forall y -> Z x y) | ||
83 | (g :: forall x -> Y x) | ||
84 | x | ||
85 | = f (g x) | ||
86 | dcomp'' | ||
87 | :: forall | ||
88 | X | ||
89 | (Y :: X -> _) | ||
90 | (Z :: forall x -> Y x -> _) | ||
91 | . forall | ||
92 | (f :: forall x . forall y -> Z x y) | ||
93 | (g :: forall x -> Y x) x | ||
94 | -> Z x (g x) | ||
95 | dcomp'' f g x = f (g x) | ||
96 | |||
97 | listMap f xs = | ||
98 | | Nil' <- xs -> Nil' | ||
99 | | Cons' x xs <- xs -> Cons' (f x) (listMap f xs) | ||
100 | foldr c n xs = case xs of | ||
101 | Nil' -> n | ||
102 | Cons' x xs -> c x (foldr c n xs) | ||
103 | |||
104 | concat xs ys = foldr Cons' ys xs | ||
105 | |||
106 | from n = Cons' n (from (primAdd #1 n)) | ||
107 | head x = case x of | ||
108 | Nil' -> undefined | ||
109 | Cons' x _ -> x | ||
110 | tail = listCase (\_ -> _) undefined (\_ xs -> xs) | ||
111 | nth n xs = | ||
112 | | primIntEq #0 n -> head xs | ||
113 | | otherwise -> nth (primSub n #1) (tail xs) | ||
114 | filter p xs = | ||
115 | | Nil' <- xs -> Nil' | ||
116 | | Cons' x xs <- xs -> | ||
117 | | p x -> Cons' x (filter p xs) | ||
118 | | otherwise -> filter p xs | ||
119 | takeWhile p xs = | ||
120 | | Nil' <- xs -> Nil' | ||
121 | | Cons' x xs <- xs -> | ||
122 | | p x -> Cons' x (takeWhile p xs) | ||
123 | | otherwise -> Nil' | ||
124 | and' a b = boolCase (\_ -> _) False b a | ||
125 | or' a b = boolCase (\_ -> _) b True a | ||
126 | not' = boolCase (\_ -> _) True False | ||
127 | all p = listCase (\_ -> _) True (\x xs -> and' (p x) (all p xs)) | ||
128 | intLEq n m = or' (primIntLess n m) (primIntEq n m) | ||
129 | {- todo | ||
130 | primes = | ||
131 | Cons' #2 (Cons' #3 (filter (\x -> all (\i -> not' (primIntEq #0 (primMod x i))) ( | ||
132 | takeWhile (\p -> (\m -> or' (primIntLess p m) (primIntEq p m)) (primSqrt x)) primes | ||
133 | )) (from #5))) | ||
134 | |||
135 | nthPrimes n = nth n primes | ||
136 | main = nthPrimes #10 | ||
137 | -} | ||
138 | data Nat = Zero | Succ Nat | ||
139 | data Fin :: Nat -> Type where | ||
140 | FZero :: Fin (Succ n) | ||
141 | FSucc :: Fin n -> Fin (Succ n) | ||
142 | data Vec a :: Nat -> Type where | ||
143 | Nil :: Vec a Zero | ||
144 | Cons :: a -> Vec a n -> Vec a (Succ n) | ||
145 | data Eq @a :: a -> a -> Type where | ||
146 | Refl :: Eq x x | ||
147 | |||
148 | wrong | ||
149 | x = 1 1 | ||
150 | |||
151 | vec = Vec _ | ||
152 | |||
153 | builtins | ||
154 | natElim :: forall m -> m Zero -> (forall n -> m n -> m (Succ n)) -> forall b -> m b | ||
155 | |||
156 | --natElim (m :: Nat -> Type) (z :: m Zero) (s :: forall n -> m n -> m (Succ n)) = fix (\natElim -> natCase m z (\n -> s n (natElim n))) | ||
157 | |||
158 | builtins | ||
159 | finElim :: | ||
160 | forall (m :: forall n -> Fin n -> _) | ||
161 | -> (forall n . m (Succ n) FZero) | ||
162 | -> (forall n . forall f -> m n f -> m (Succ n) (FSucc f)) | ||
163 | -> forall n f -> m n f | ||
164 | |||
165 | -- addition of natural numbers | ||
166 | plus = | ||
167 | natElim | ||
168 | (\_ -> _) -- motive | ||
169 | (\n -> n) -- case for Zero | ||
170 | (\p rec n -> Succ (rec n)) -- case for Succ | ||
171 | |||
172 | -- predecessor, mapping 0 to 0 | ||
173 | pred = | ||
174 | natElim | ||
175 | (\_ -> _) | ||
176 | Zero | ||
177 | (\n' _ -> n') | ||
178 | |||
179 | -- a simpler elimination scheme for natural numbers | ||
180 | natFold = | ||
181 | \mz ms -> natElim | ||
182 | (\_ -> _) | ||
183 | mz | ||
184 | (\_ rec -> ms rec) | ||
185 | |||
186 | -- an eliminator for natural numbers that has special | ||
187 | -- cases for 0 and 1 | ||
188 | nat1Elim = \m m0 m1 ms -> natElim m m0 | ||
189 | (\p rec -> natElim (\n -> m (Succ n)) m1 ms p) | ||
190 | |||
191 | -- an eliminator for natural numbers that has special | ||
192 | -- cases for 0, 1 and 2 | ||
193 | nat2Elim = \m m0 m1 m2 ms -> nat1Elim m m0 m1 | ||
194 | (\p rec -> natElim (\n -> m (Succ (Succ n))) m2 ms p) | ||
195 | |||
196 | -- increment by one | ||
197 | inc = natFold (Succ Zero) Succ | ||
198 | |||
199 | -- embed Fin into Nat | ||
200 | finNat = finElim (\_ _ -> Nat) | ||
201 | Zero | ||
202 | (\_ rec -> Succ rec) | ||
203 | |||
204 | -- unit type | ||
205 | Unit' = Fin 1 | ||
206 | -- constructor | ||
207 | U = FZero :: Unit' | ||
208 | -- eliminator | ||
209 | |||
210 | unitElim = \m mu -> finElim (nat1Elim (\n -> Fin n -> Type) | ||
211 | (\_ -> Unit') | ||
212 | (\x -> m x) | ||
213 | (\_ _ _ -> Unit')) | ||
214 | (\ @n -> natElim (\n -> natElim (\n -> Fin (Succ n) -> Type) | ||
215 | (\x -> m x) | ||
216 | (\_ _ _ -> Unit') | ||
217 | n FZero) | ||
218 | mu | ||
219 | (\_ _ -> U) n) | ||
220 | (\ @n f _ -> finElim (\n f -> natElim (\n -> Fin (Succ n) -> Type) | ||
221 | (\x -> m x) | ||
222 | (\_ _ _ -> Unit') | ||
223 | n (FSucc f)) | ||
224 | U | ||
225 | (\_ _ -> U) | ||
226 | n f) | ||
227 | 1 | ||
228 | |||
229 | -- empty type | ||
230 | Void = Fin 0 | ||
231 | -- eliminator | ||
232 | voidElim m = finElim (natElim (\n -> Fin n -> Type) | ||
233 | (\x -> m x) | ||
234 | (\_ _ _ -> _)) | ||
235 | U | ||
236 | (\_ _ -> U) | ||
237 | 0 | ||
238 | |||
239 | -- type of booleans | ||
240 | Bool' = Fin 2 | ||
241 | -- constructors | ||
242 | False' = FZero :: Bool' | ||
243 | True' = FSucc FZero :: Bool' | ||
244 | -- eliminator | ||
245 | |||
246 | boolElim = \m mf mt -> finElim ( nat2Elim (\n -> Fin n -> Type) | ||
247 | (\_ -> Unit') (\_ -> Unit') | ||
248 | (\x -> m x) | ||
249 | (\_ _ _ -> Unit')) | ||
250 | (\ @n -> nat1Elim (\n -> nat1Elim (\n -> Fin (Succ n) -> Type) | ||
251 | (\_ -> Unit') | ||
252 | (\x -> m x) | ||
253 | (\_ _ _ -> Unit') | ||
254 | n FZero) | ||
255 | U mf (\_ _ -> U) n) | ||
256 | (\ @n f _ -> finElim (\n f -> nat1Elim (\n -> Fin (Succ n) -> Type) | ||
257 | (\_ -> Unit') | ||
258 | (\x -> m x) | ||
259 | (\_ _ _ -> Unit') | ||
260 | n (FSucc f)) | ||
261 | (\ @n -> natElim | ||
262 | (\n -> natElim | ||
263 | (\n -> Fin (Succ (Succ n)) -> Type) | ||
264 | (\x -> m x) | ||
265 | (\_ _ _ -> Unit') | ||
266 | n (FSucc FZero)) | ||
267 | mt (\_ _ -> U) n) | ||
268 | (\ @n f _ -> finElim | ||
269 | (\n f -> natElim | ||
270 | (\n -> Fin (Succ (Succ n)) -> Type) | ||
271 | (\x -> m x) | ||
272 | (\_ _ _ -> Unit') | ||
273 | n (FSucc (FSucc f))) | ||
274 | U | ||
275 | (\_ _ -> U) | ||
276 | n f) | ||
277 | n f) | ||
278 | 2 | ||
279 | |||
280 | |||
281 | -- boolean not, and, or, equivalence, xor | ||
282 | not = boolElim (\_ -> _) True' False' | ||
283 | and = boolElim (\_ -> _) (const False') id | ||
284 | or = boolElim (\_ -> _) id (const True') | ||
285 | iff = boolElim (\_ -> _) not id | ||
286 | xor = boolElim (\_ -> _) id not | ||
287 | |||
288 | -- even, odd, isZero, isSucc | ||
289 | even = natFold True' not | ||
290 | odd = natFold False' not | ||
291 | isZero = natFold True' (const False') | ||
292 | isSucc = natFold False' (const True') | ||
293 | |||
294 | -- equality on natural numbers | ||
295 | natEq = | ||
296 | natElim | ||
297 | (\_ -> _) | ||
298 | (natElim | ||
299 | (\_ -> _) | ||
300 | True' | ||
301 | (\n' _ -> False')) | ||
302 | (\m' rec_m' -> natElim | ||
303 | (\_ -> _) | ||
304 | False' | ||
305 | (\n' _ -> rec_m' n')) | ||
306 | |||
307 | -- "oh so true" | ||
308 | Prop = boolElim (\_ -> _) Void Unit' | ||
309 | |||
310 | -- reflexivity of equality on natural numbers | ||
311 | pNatEqRefl = | ||
312 | natElim | ||
313 | (\n -> Prop (natEq n n)) | ||
314 | U | ||
315 | (\_ rec -> rec) | ||
316 | -- :: forall (n :: Nat) -> Prop (natEq n n) | ||
317 | |||
318 | -- alias for type-level negation | ||
319 | Not a = a -> Void | ||
320 | |||
321 | -- Leibniz prinicple: forall a b . (a -> b) -> forall (x :: a) (y :: a) -> Eq x y -> Eq (f x) (f y) | ||
322 | leibniz f x y = eqCase | ||
323 | (\x y _ -> Eq (f x) (f y)) | ||
324 | Refl @x @y | ||
325 | |||
326 | -- symmetry of (general) equality | ||
327 | symm x y = eqCase (\x y _ -> Eq y x) Refl @x @y | ||
328 | |||
329 | -- transitivity of (general) equality | ||
330 | tran eq_x_y = eqCase | ||
331 | (\x y _ -> forall z -> Eq y z -> Eq x z) | ||
332 | (\_ x -> x) | ||
333 | eq_x_y _ | ||
334 | |||
335 | -- apply an equality proof on two types | ||
336 | apply = eqCase (\a b _ -> a -> b) id | ||
337 | |||
338 | p1IsNot0 p = apply | ||
339 | (leibniz | ||
340 | (natElim (\_ -> _) Void (\_ _ -> Unit')) | ||
341 | 1 0 p) | ||
342 | U | ||
343 | |||
344 | -- proof that 0 is not 1 | ||
345 | p0IsNot1 p = p1IsNot0 (symm 0 1 p) | ||
346 | |||
347 | -- proof that zero is not a successor | ||
348 | p0IsNoSucc = | ||
349 | natElim | ||
350 | (\n -> Not (Eq 0 (Succ n))) | ||
351 | p0IsNot1 | ||
352 | (\n' rec_n' eq_0_SSn' -> | ||
353 | rec_n' (leibniz pred Zero (Succ (Succ n')) eq_0_SSn')) | ||
354 | |||
355 | -- generate a vector of given length from a specified element (replicate) | ||
356 | |||
357 | replicate = | ||
358 | natElim | ||
359 | (\n -> forall a -> a -> Vec a n) | ||
360 | (\_ _ -> Nil) | ||
361 | (\n' rec_n' a x -> Cons x (rec_n' a x)) | ||
362 | |||
363 | -- alternative definition of replicate | ||
364 | replicate' = | ||
365 | natElim | ||
366 | (\n -> _ -> vec n) | ||
367 | (\_ -> Nil) | ||
368 | (\n' rec_n' x -> Cons x (rec_n' x)) | ||
369 | |||
370 | replicate'' x = natElim vec Nil (\n' rec_n' -> Cons x rec_n') | ||
371 | |||
372 | -- generate a vector of given length n, containing the natural numbers smaller than n | ||
373 | fromto = natElim vec Nil (\n' rec_n' -> Cons n' rec_n') | ||
374 | |||
375 | builtins | ||
376 | vecElim :: | ||
377 | forall (m :: forall k -> vec k -> _) -> | ||
378 | m Zero Nil | ||
379 | -> (forall l . forall x xs -> m l xs -> m (Succ l) (Cons x xs)) | ||
380 | -> forall k xs -> m k xs | ||
381 | |||
382 | -- append two vectors | ||
383 | append = vecElim | ||
384 | (\m _ -> forall n -> vec n -> vec (plus m n)) | ||
385 | (\_ v -> v) | ||
386 | (\v vs rec n w -> Cons v (rec n w)) | ||
387 | |||
388 | -- helper function for tail, see below | ||
389 | tail' a = vecElim (\m v -> forall n -> Eq m (Succ n) -> Vec a n) | ||
390 | (\n eq_0_SuccN -> voidElim (\_ -> _) | ||
391 | (p0IsNoSucc n eq_0_SuccN)) | ||
392 | (\ @m' v vs rec_m' n eq_SuccM'_SuccN -> | ||
393 | eqCase | ||
394 | (\m' n e -> Vec a m' -> Vec a n) | ||
395 | id | ||
396 | @m' @n | ||
397 | (leibniz pred (Succ m') (Succ n) eq_SuccM'_SuccN) vs) | ||
398 | |||
399 | -- compute the tail of a vector | ||
400 | tailVec = \n v -> tail' _ (Succ n) v n Refl | ||
401 | |||
402 | -- projection out of a vector | ||
403 | at = | ||
404 | vecElim (\n v -> Fin n -> _) | ||
405 | (\f -> voidElim (\_ -> _) f) | ||
406 | (\ @n' v vs rec_n' f_SuccN' -> | ||
407 | finElim (\n _ -> Eq n (Succ n') -> _) | ||
408 | (\e -> v) | ||
409 | (\ @n f_N _ eq_SuccN_SuccN' -> | ||
410 | rec_n' (eqCase | ||
411 | (\x y e -> Fin x -> Fin y) | ||
412 | id | ||
413 | @n @n' | ||
414 | (leibniz pred | ||
415 | (Succ n) (Succ n') eq_SuccN_SuccN') | ||
416 | f_N)) | ||
417 | (Succ n') | ||
418 | f_SuccN' | ||
419 | Refl) | ||
420 | |||
421 | -- head of a vector | ||
422 | headVec n v = at (Succ n) v FZero | ||
423 | |||
424 | -- vector map | ||
425 | map f = vecElim (\n _ -> vec n) Nil (\x _ rec -> Cons (f x) rec) | ||
426 | |||
427 | -- proofs that 0 is the neutral element of addition | ||
428 | -- one direction is trivial by definition of plus: | ||
429 | p0PlusNisN = Refl :: forall n . Eq (plus 0 n) n | ||
430 | |||
431 | -- the other direction requires induction on N: | ||
432 | pNPlus0isN = | ||
433 | natElim (\n -> Eq (plus n 0) n) | ||
434 | Refl | ||
435 | (\n' rec -> leibniz Succ (plus n' 0) n' rec) | ||
436 | |||
437 | testNoNorm = Refl :: Eq (primIntEq #3 #3) True | ||
438 | |||
439 | True'' = FSucc FZero :: Bool' | ||
440 | |||
441 | |||
442 | data EqD a = EqDC (a -> a -> Bool) | ||
443 | |||
444 | eqInt = EqDC primIntEq | ||
445 | |||
446 | builtins | ||
447 | matchInt :: Type -> (Type -> Type) -> Type -> Type | ||
448 | matchList :: (Type -> Type) -> (Type -> Type) -> Type -> Type | ||
449 | |||
450 | Eq_ :: Type -> Type | ||
451 | Eq_ a = matchInt Unit (matchList Eq_ (\_ -> Empty)) a | ||
452 | |||
453 | builtins eqD :: Eq_ a => EqD a | ||
454 | |||
455 | eq = eqDCase (\_ -> _) id eqD | ||
456 | |||
457 | eq' = eqDCase (\_ -> _) id | ||
458 | |||
459 | eqList = EqDC (\as bs -> listCase (\_ -> _) (listCase (\_ -> _) True (\_ _ -> False) bs) (\a as -> listCase (\_ -> _) False (\b bs -> and' (eq a b) (eq as bs)) bs) as) | ||
460 | |||
461 | main_ = eq' eqList (Cons' #3 Nil') Nil' | ||
462 | main'' = eq (Cons' #3 Nil') Nil' | ||
463 | |||
464 | data MonadD (m :: Type -> Type) = MonadDC (forall a . a -> m a) (forall a b . m a -> (a -> m b) -> m b) | ||
465 | |||
466 | data Identity a = IdentityC a | ||
467 | |||
468 | identityMonad = MonadDC IdentityC (\m f -> identityCase (\_ -> _) f m) | ||
469 | |||
470 | Char = Int | ||
471 | |||
472 | data IO a where | ||
473 | IORet :: a -> IO a | ||
474 | PutChar :: Char -> IO a -> IO a | ||
475 | GetChar :: (Char -> IO a) -> IO a | ||
476 | |||
477 | data ReaderT r (m :: Type -> Type) a = ReaderTC (r -> m a) | ||
478 | |||
479 | ----------------------------- | ||
480 | |||
481 | builtins | ||
482 | ifIdentity1 :: forall a . a -> ((Type -> Type) -> a) -> (Type -> Type) -> a | ||
483 | ifReaderT1 :: forall a . (Type -> (Type -> Type) -> a) -> ((Type -> Type) -> a) -> (Type -> Type) -> a | ||
484 | |||
485 | builtins | ||
486 | Monad :: (Type -> Type) -> Type | ||
487 | --let Monad = fix (\Monad -> ifIdentity1 Unit (ifReaderT1 (\r m -> Monad m) (\_ -> Empty))) | ||
488 | |||
489 | ----------------- recursive definition | ||
490 | builtins monadD :: forall m . Monad m => MonadD m | ||
491 | -- let monadD = fix (\monadD @t -> ifIdentity_1 identityMonad (ifReaderT_1 (\r m -> monadReaderT) undefined t)) | ||
492 | |||
493 | return = monadDCase (\_ -> _) (\r _ -> r) monadD | ||
494 | bind = monadDCase (\_ -> _) (\_ b -> b) monadD | ||
495 | |||
496 | monadReaderT = MonadDC (\a -> ReaderTC (\r -> return a)) | ||
497 | (\m f -> ReaderTC (\r -> | ||
498 | readerTCase (\_ -> _) | ||
499 | (\g -> bind | ||
500 | (g r) | ||
501 | (\a -> readerTCase (\_ -> _) (\h -> h r) (f a))) | ||
502 | m)) | ||
503 | -- :: forall r m . Monad m => MonadD (ReaderT r m) | ||
504 | |||
505 | IOBind ma f = case ma of | ||
506 | IORet a -> f a | ||
507 | PutChar i r -> PutChar i (bind r f) | ||
508 | GetChar g -> GetChar (\i -> bind (g i) f) | ||
509 | |||
510 | monadIO = MonadDC IORet IOBind | ||
511 | -------------------------- end of recursive definition | ||
512 | |||
513 | liftReaderT m = ReaderTC (\r -> m) | ||
514 | |||
515 | bind' m m' = bind m (const m') | ||
516 | fmap f m = bind m (comp return f) | ||
517 | |||
518 | sequence = listCase (\_ -> _) (return Nil') (\x xs -> bind x (\vx -> fmap (Cons' vx) (sequence xs))) | ||
519 | sequence_ = listCase (\_ -> _) (return TT) (\x xs -> bind' x (sequence_ xs)) | ||
520 | |||
521 | mapM f = comp sequence (listMap f) | ||
522 | mapM_ f = comp sequence_ (listMap f) | ||
523 | |||
524 | putChar i = PutChar i (return TT) | ||
525 | getChar = GetChar return | ||
526 | |||
527 | putStr = mapM_ putChar | ||
528 | putStrLn = comp putStr (flip concat (Cons' #0 Nil')) | ||
529 | |||
530 | -- todo -- getLine = bind getChar (\c -> boolCase (\_ -> _) (bind getLine (\cs -> return (Cons' c cs))) (return Nil') (eq c #0)) | ||
531 | |||
532 | --let mex_ = return' monadReaderT #3 | ||
533 | mex = return #3 :: IO Int | ||
534 | mex' = return #3 :: ReaderT Bool IO Int | ||
535 | |||
536 | -- todo -- main' = bind getLine putStrLn | ||
537 | |||
538 | |||
539 | data Exp :: Type -> Type where | ||
540 | EInt :: Int -> Exp Int | ||
541 | EApp :: Exp (a -> b) -> Exp a -> Exp b | ||
542 | ECond :: Exp Bool -> Exp a -> Exp a -> Exp a | ||
543 | |||
544 | expCase' :: forall | ||
545 | (c :: forall a -> Exp a -> Type) | ||
546 | -> (forall d -> c Int (EInt d)) | ||
547 | -> (forall f g . forall i j -> c g (EApp @f @g i j)) | ||
548 | -> (forall l . forall m n o -> c l (ECond @l m n o)) | ||
549 | -> forall q | ||
550 | (r :: Exp q) -> c q r | ||
551 | expCase' m i a c x e = expCase m i a c @x e | ||
552 | |||
553 | expCase'' :: forall | ||
554 | (c :: forall a -> Exp a -> Type) | ||
555 | -> (forall d -> c Int (EInt d)) | ||
556 | -> (forall f g . forall i j -> c g (EApp @f @g i j)) | ||
557 | -> (forall l . forall m n o -> c l (ECond @l m n o)) | ||
558 | -> forall q | ||
559 | . forall (r :: Exp q) -> c q r | ||
560 | expCase'' m i a c @x e = expCase' m i a c x e | ||
561 | |||
562 | -- todo -- eval :: forall a . Exp a -> a | ||
563 | eval = expCase (\b _ -> b) -- todo: how to guess the motive | ||
564 | (\i -> i) | ||
565 | (\f a -> eval f (eval a)) | ||
566 | (\b m n -> boolCase (\_ -> _) (eval n) (eval m) (eval b)) | ||
567 | :: forall a . Exp a -> a | ||
568 | |||
diff --git a/prototypes/tests/accept/Graphics.lc b/prototypes/tests/accept/Graphics.lc deleted file mode 120000 index 974d8372..00000000 --- a/prototypes/tests/accept/Graphics.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/Graphics.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/Material.lc b/prototypes/tests/accept/Material.lc deleted file mode 120000 index d8ac6673..00000000 --- a/prototypes/tests/accept/Material.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/Material.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/NewStyle.lc b/prototypes/tests/accept/NewStyle.lc deleted file mode 120000 index 68032c3f..00000000 --- a/prototypes/tests/accept/NewStyle.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/NewStyle.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/Prelude.lc b/prototypes/tests/accept/Prelude.lc deleted file mode 100644 index 35d27f0a..00000000 --- a/prototypes/tests/accept/Prelude.lc +++ /dev/null | |||
@@ -1,311 +0,0 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | ||
2 | module Prelude | ||
3 | ( module Prelude | ||
4 | , module Builtins | ||
5 | ) where | ||
6 | |||
7 | import Builtins | ||
8 | |||
9 | infixr 9 . | ||
10 | infixl 7 `PrimMulMatVec`, `PrimDot` | ||
11 | infixr 3 *** | ||
12 | infixr 5 : | ||
13 | infixr 0 $ | ||
14 | --infixl 0 & | ||
15 | |||
16 | const x y = x | ||
17 | |||
18 | otherwise = True | ||
19 | |||
20 | --undefined = undefined | ||
21 | |||
22 | builtins | ||
23 | undefined :: forall (a :: Type) . a | ||
24 | |||
25 | x & f = f x | ||
26 | |||
27 | ($) = \f x -> f x | ||
28 | (.) = \f g x -> f (g x) | ||
29 | |||
30 | uncurry f (x, y) = f x y | ||
31 | |||
32 | (***) f g (x, y) = (f x, g y) | ||
33 | |||
34 | data List a = Nil | Cons a (List a) | ||
35 | |||
36 | pi = 3.14 | ||
37 | |||
38 | zip :: [a] -> [b] -> [(a,b)] | ||
39 | zip [] xs = [] | ||
40 | zip xs [] = [] | ||
41 | zip (a: as) (b: bs) = (a,b): zip as bs | ||
42 | |||
43 | unzip :: [(a,b)] -> ([a],[b]) | ||
44 | unzip [] = ([],[]) | ||
45 | unzip ((a,b):xs) = (a:as,b:bs) | ||
46 | where (as,bs) = unzip xs | ||
47 | |||
48 | filter pred [] = [] | ||
49 | filter pred (x:xs) = case pred x of | ||
50 | True -> (x : filter pred xs) | ||
51 | False -> (filter pred xs) | ||
52 | |||
53 | tail :: [a] -> [a] | ||
54 | tail (_: xs) = xs | ||
55 | |||
56 | pairs :: [a] -> [(a, a)] | ||
57 | pairs v = zip v (tail v) | ||
58 | |||
59 | foldl' f e [] = e | ||
60 | foldl' f e (x: xs) = foldl' f (f e x) xs | ||
61 | |||
62 | singleton a = [a] | ||
63 | |||
64 | append [] ys = ys | ||
65 | append (x:xs) ys = x : append xs ys | ||
66 | |||
67 | concat = foldl' append [] | ||
68 | |||
69 | map _ [] = [] | ||
70 | map f (x:xs) = f x : map f xs | ||
71 | |||
72 | concatMap :: (a -> [b]) -> [a] -> [b] | ||
73 | concatMap f x = concat (map f x) | ||
74 | |||
75 | split [] = ([], []) | ||
76 | split (x: xs) = (x: bs, as) where (as, bs) = split xs | ||
77 | |||
78 | mergeBy f (x:xs) (y:ys) = case f x y of | ||
79 | LT -> x: mergeBy f xs (y:ys) | ||
80 | _ -> y: mergeBy f (x:xs) ys | ||
81 | mergeBy f [] xs = xs | ||
82 | mergeBy f xs [] = xs | ||
83 | |||
84 | sortBy f [] = [] | ||
85 | sortBy f [x] = [x] | ||
86 | sortBy f xs = uncurry (mergeBy f) ((sortBy f *** sortBy f) (split xs)) | ||
87 | |||
88 | data Maybe a | ||
89 | = Nothing | ||
90 | | Just a | ||
91 | -- deriving (Eq, Ord, Show) | ||
92 | |||
93 | |||
94 | snd (Tuple2 a b) = b | ||
95 | |||
96 | -- Row polymorphism | ||
97 | builtins | ||
98 | Split :: Type -> Type -> Type -> Type {- TODO - LATER: Constraint -} | ||
99 | |||
100 | tuptype :: List Type -> Type | ||
101 | tuptype [] = 'Tuple0 | ||
102 | tuptype (x:xs) = 'Tuple2 x (tuptype xs) | ||
103 | |||
104 | data RecordC (xs :: List (Tuple2 String Type)) | ||
105 | = RecordCons (tuptype (map snd xs)) | ||
106 | |||
107 | builtins | ||
108 | record :: List (Tuple2 String Type) -> Type | ||
109 | --record xs = RecordCons ({- TODO: sortBy fst-} xs) | ||
110 | |||
111 | builtins | ||
112 | project :: forall (xs :: List (Tuple2 String Type)) . forall (s :: String) -> Split (RecordC xs) (RecordC ('Cons ('Tuple2 s a) 'Nil)) b => RecordC xs -> a | ||
113 | |||
114 | |||
115 | --------------------------------------- HTML colors | ||
116 | |||
117 | rgb r g b = V4 r g b 1.0 | ||
118 | |||
119 | black = rgb 0.0 0.0 0.0 | ||
120 | gray = rgb 0.5 0.5 0.5 | ||
121 | silver = rgb 0.75 0.75 0.75 | ||
122 | white = rgb 1.0 1.0 1.0 | ||
123 | maroon = rgb 0.5 0.0 0.0 | ||
124 | red = rgb 1.0 0.0 0.0 | ||
125 | olive = rgb 0.5 0.5 0.0 | ||
126 | yellow = rgb 1.0 1.0 0.0 | ||
127 | green = rgb 0.0 0.5 0.0 | ||
128 | lime = rgb 0.0 1.0 0.0 | ||
129 | teal = rgb 0.0 0.5 0.5 | ||
130 | aqua = rgb 0.0 1.0 1.0 | ||
131 | navy = rgb 0.0 0.0 0.5 | ||
132 | blue = rgb 0.0 0.0 1.0 | ||
133 | purple = rgb 0.5 0.0 0.5 | ||
134 | fuchsia = rgb 1.0 0.0 1.0 | ||
135 | |||
136 | colorImage1 = ColorImage @1 | ||
137 | colorImage2 = ColorImage @2 | ||
138 | |||
139 | depthImage1 = DepthImage @1 | ||
140 | |||
141 | v3FToV4F :: Vec 3 Float -> Vec 4 Float | ||
142 | v3FToV4F v = V4 0.0 0.0 0.0 1.0 --- todo! -- V4 v%x v%y v%z 1 | ||
143 | |||
144 | ------------ | ||
145 | -- * WebGL 1 | ||
146 | ------------ | ||
147 | |||
148 | -- angle and trigonometric | ||
149 | radians = PrimRadians | ||
150 | degrees = PrimDegrees | ||
151 | sin = PrimSin | ||
152 | cos = PrimCos | ||
153 | tan = PrimTan | ||
154 | asin = PrimASin | ||
155 | acos = PrimACos | ||
156 | atan = PrimATan | ||
157 | atan2 = PrimATan2 | ||
158 | |||
159 | -- exponential functions | ||
160 | pow = PrimPow | ||
161 | exp = PrimExp | ||
162 | log = PrimLog | ||
163 | exp2 = PrimExp2 | ||
164 | log2 = PrimLog2 | ||
165 | sqrt = PrimSqrt | ||
166 | inversesqrt = PrimInvSqrt | ||
167 | |||
168 | -- common functions | ||
169 | abs = PrimAbs | ||
170 | sign = PrimSign | ||
171 | floor = PrimFloor | ||
172 | ceil = PrimCeil | ||
173 | fract = PrimFract | ||
174 | mod = PrimMod | ||
175 | min = PrimMin | ||
176 | max = PrimMax | ||
177 | clamp = PrimClamp | ||
178 | clampS = PrimClampS | ||
179 | mix = PrimMix | ||
180 | step = PrimStep | ||
181 | smoothstep = PrimSmoothStep | ||
182 | |||
183 | -- geometric functions | ||
184 | length = PrimLength | ||
185 | distance = PrimDistance | ||
186 | dot = PrimDot | ||
187 | cross = PrimCross | ||
188 | normalize = PrimNormalize | ||
189 | faceforward = PrimFaceForward | ||
190 | reflect = PrimReflect | ||
191 | refract = PrimRefract | ||
192 | |||
193 | -- operators | ||
194 | infixl 7 *, /, % | ||
195 | infixl 6 +, - | ||
196 | infix 4 ==, /=, <, <=, >=, > | ||
197 | |||
198 | infixr 3 && | ||
199 | infixr 2 || | ||
200 | |||
201 | infix 7 `dot` -- dot | ||
202 | infix 7 `cross` -- cross | ||
203 | |||
204 | infixr 7 *. -- mulmv | ||
205 | infixl 7 .* -- mulvm | ||
206 | infixl 7 .*. -- mulmm | ||
207 | |||
208 | -- arithemtic | ||
209 | a + b = PrimAdd a b | ||
210 | a - b = PrimSub a b | ||
211 | a * b = PrimMul a b | ||
212 | a / b = PrimDiv a b | ||
213 | a % b = PrimMod a b | ||
214 | |||
215 | neg a = PrimNeg a | ||
216 | |||
217 | -- comparison | ||
218 | a == b = PrimEqual a b | ||
219 | a /= b = PrimNotEqual a b | ||
220 | a < b = PrimLessThan a b | ||
221 | a <= b = PrimLessThanEqual a b | ||
222 | a >= b = PrimGreaterThanEqual a b | ||
223 | a > b = PrimGreaterThan a b | ||
224 | |||
225 | -- logical | ||
226 | a && b = PrimAnd a b | ||
227 | a || b = PrimOr a b | ||
228 | not a = PrimNot a | ||
229 | any a = PrimAny a | ||
230 | all a = PrimAll a | ||
231 | |||
232 | -- matrix functions | ||
233 | a .*. b = PrimMulMatMat a b | ||
234 | a *. b = PrimMulMatVec a b | ||
235 | a .* b = PrimMulVecMat a b | ||
236 | |||
237 | dFdx = PrimDFdx | ||
238 | dFdy = PrimDFdy | ||
239 | |||
240 | -- extra | ||
241 | round = PrimRound | ||
242 | |||
243 | |||
244 | -- temp hack for vector <---> scalar operators | ||
245 | infixl 7 *!, /!, %! | ||
246 | infixl 6 +!, -! | ||
247 | |||
248 | -- arithemtic | ||
249 | a +! b = PrimAddS a b | ||
250 | a -! b = PrimSubS a b | ||
251 | a *! b = PrimMulS a b | ||
252 | a /! b = PrimDivS a b | ||
253 | a %! b = PrimModS a b | ||
254 | |||
255 | ------------------ | ||
256 | -- common matrices | ||
257 | ------------------ | ||
258 | {- | ||
259 | -- | Perspective transformation matrix in row major order. | ||
260 | perspective :: Float -- ^ Near plane clipping distance (always positive). | ||
261 | -> Float -- ^ Far plane clipping distance (always positive). | ||
262 | -> Float -- ^ Field of view of the y axis, in radians. | ||
263 | -> Float -- ^ Aspect ratio, i.e. screen's width\/height. | ||
264 | -> Mat 4 4 Float | ||
265 | perspective n f fovy aspect = --transpose $ | ||
266 | M44F (V4F (2*n/(r-l)) 0 (-(r+l)/(r-l)) 0) | ||
267 | (V4F 0 (2*n/(t-b)) ((t+b)/(t-b)) 0) | ||
268 | (V4F 0 0 (-(f+n)/(f-n)) (-2*f*n/(f-n))) | ||
269 | (V4F 0 0 (-1) 0) | ||
270 | where | ||
271 | t = n*tan(fovy/2) | ||
272 | b = -t | ||
273 | r = aspect*t | ||
274 | l = -r | ||
275 | -} | ||
276 | rotMatrixZ a = M44F (V4 c s 0 0) (V4 (-s) c 0 0) (V4 0 0 1 0) (V4 0 0 0 1) | ||
277 | where | ||
278 | c = cos a | ||
279 | s = sin a | ||
280 | |||
281 | rotMatrixY a = M44F (V4 c 0 (-s) 0) (V4 0 1 0 0) (V4 s 0 c 0) (V4 0 0 0 1) | ||
282 | where | ||
283 | c = cos a | ||
284 | s = sin a | ||
285 | |||
286 | rotMatrixX a = M44F (V4 1 0 0 0) (V4 0 c s 0) (V4 0 (-s) c 0) (V4 0 0 0 1) | ||
287 | where | ||
288 | c = cos a | ||
289 | s = sin a | ||
290 | |||
291 | rotationEuler a b c = rotMatrixY a .*. rotMatrixX b .*. rotMatrixZ c | ||
292 | |||
293 | {- | ||
294 | -- | Camera transformation matrix. | ||
295 | lookat :: Vec 3 Float -- ^ Camera position. | ||
296 | -> Vec 3 Float -- ^ Target position. | ||
297 | -> Vec 3 Float -- ^ Upward direction. | ||
298 | -> M44F | ||
299 | lookat pos target up = translateBefore4 (neg pos) (orthogonal $ toOrthoUnsafe r) | ||
300 | where | ||
301 | w = normalize $ pos - target | ||
302 | u = normalize $ up `cross` w | ||
303 | v = w `cross` u | ||
304 | r = transpose $ Mat3 u v w | ||
305 | -} | ||
306 | |||
307 | scale t v = v * V4 t t t 1.0 | ||
308 | |||
309 | fromTo :: Float -> Float -> [Float] | ||
310 | fromTo a b = if a > b then [] else a:fromTo (a +! 1.0) b | ||
311 | |||
diff --git a/prototypes/tests/accept/PrimReduce.lc b/prototypes/tests/accept/PrimReduce.lc deleted file mode 120000 index 587d6508..00000000 --- a/prototypes/tests/accept/PrimReduce.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/PrimReduce.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/SampleMaterial.lc b/prototypes/tests/accept/SampleMaterial.lc deleted file mode 120000 index b8627b81..00000000 --- a/prototypes/tests/accept/SampleMaterial.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/SampleMaterial.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/ambig.lc b/prototypes/tests/accept/ambig.lc deleted file mode 120000 index 9259c4a8..00000000 --- a/prototypes/tests/accept/ambig.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/ambig.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/concatmap01.lc b/prototypes/tests/accept/concatmap01.lc deleted file mode 120000 index 43cee1d5..00000000 --- a/prototypes/tests/accept/concatmap01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/concatmap01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/data.lc b/prototypes/tests/accept/data.lc deleted file mode 100644 index 60731eb8..00000000 --- a/prototypes/tests/accept/data.lc +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | data Data0 = Data0 | ||
2 | |||
3 | data Data1 a b c = Data1 a b c | ||
4 | |||
5 | data Data2 = Data21 Int | ||
6 | | Data22 { x :: Int, y::Int } | ||
7 | | Data23 { x :: Int } | ||
8 | | Data24 { } | ||
9 | |||
10 | data Data5 a5 b5 c5 = Data51 { a5::a5} | ||
11 | | Data52 { a5::a5, b5::b5, c5::c5 } | ||
12 | | Data53 Int a5 Float b5 c5 | ||
13 | |||
14 | {- | ||
15 | f (Data41 {}) = 5 | ||
16 | f (Data42 {c4=c}) = c | ||
17 | f d = a4 d | ||
18 | -} | ||
diff --git a/prototypes/tests/accept/dotdot01.lc b/prototypes/tests/accept/dotdot01.lc deleted file mode 120000 index 8274c557..00000000 --- a/prototypes/tests/accept/dotdot01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/dotdot01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/dotdot02.lc b/prototypes/tests/accept/dotdot02.lc deleted file mode 120000 index 78248be7..00000000 --- a/prototypes/tests/accept/dotdot02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/dotdot02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/empty.lc b/prototypes/tests/accept/empty.lc deleted file mode 100644 index ae71538d..00000000 --- a/prototypes/tests/accept/empty.lc +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | ||
2 | |||
3 | data Empty | ||
diff --git a/prototypes/tests/accept/example06.lc b/prototypes/tests/accept/example06.lc deleted file mode 120000 index 9a1cd6f1..00000000 --- a/prototypes/tests/accept/example06.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/example06.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/example07.lc b/prototypes/tests/accept/example07.lc deleted file mode 120000 index 70995cd0..00000000 --- a/prototypes/tests/accept/example07.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/example07.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/example08.lc b/prototypes/tests/accept/example08.lc deleted file mode 120000 index 206a7ce5..00000000 --- a/prototypes/tests/accept/example08.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/example08.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fetcharrays01.lc b/prototypes/tests/accept/fetcharrays01.lc deleted file mode 120000 index 190d5855..00000000 --- a/prototypes/tests/accept/fetcharrays01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fetcharrays01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fragment01.lc b/prototypes/tests/accept/fragment01.lc deleted file mode 120000 index 9a7d18cb..00000000 --- a/prototypes/tests/accept/fragment01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fragment01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fragment03swizzling.lc b/prototypes/tests/accept/fragment03swizzling.lc deleted file mode 120000 index f9b6c97e..00000000 --- a/prototypes/tests/accept/fragment03swizzling.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fragment03swizzling.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fragment04ifthenelse.lc b/prototypes/tests/accept/fragment04ifthenelse.lc deleted file mode 120000 index 15510f2c..00000000 --- a/prototypes/tests/accept/fragment04ifthenelse.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fragment04ifthenelse.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fragment07let.lc b/prototypes/tests/accept/fragment07let.lc deleted file mode 120000 index 42f8d268..00000000 --- a/prototypes/tests/accept/fragment07let.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fragment07let.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/framebuffer01.lc b/prototypes/tests/accept/framebuffer01.lc deleted file mode 120000 index f6f5b060..00000000 --- a/prototypes/tests/accept/framebuffer01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/framebuffer01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/framebuffer02.lc b/prototypes/tests/accept/framebuffer02.lc deleted file mode 120000 index 8a5e36e8..00000000 --- a/prototypes/tests/accept/framebuffer02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/framebuffer02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/framebuffer03.lc b/prototypes/tests/accept/framebuffer03.lc deleted file mode 120000 index ab6ddf42..00000000 --- a/prototypes/tests/accept/framebuffer03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/framebuffer03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/framebuffer04.lc b/prototypes/tests/accept/framebuffer04.lc deleted file mode 120000 index ddd9144d..00000000 --- a/prototypes/tests/accept/framebuffer04.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/framebuffer04.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/framebuffer05.lc b/prototypes/tests/accept/framebuffer05.lc deleted file mode 120000 index 99d73bbd..00000000 --- a/prototypes/tests/accept/framebuffer05.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/framebuffer05.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/fromto.lc b/prototypes/tests/accept/fromto.lc deleted file mode 120000 index 3656552c..00000000 --- a/prototypes/tests/accept/fromto.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/fromto.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx00.lc b/prototypes/tests/accept/gfx00.lc deleted file mode 120000 index ac68f6dc..00000000 --- a/prototypes/tests/accept/gfx00.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx00.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx01.lc b/prototypes/tests/accept/gfx01.lc deleted file mode 120000 index fdcd64c2..00000000 --- a/prototypes/tests/accept/gfx01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx02.lc b/prototypes/tests/accept/gfx02.lc deleted file mode 120000 index 7ac40c46..00000000 --- a/prototypes/tests/accept/gfx02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx03.lc b/prototypes/tests/accept/gfx03.lc deleted file mode 120000 index 01d05167..00000000 --- a/prototypes/tests/accept/gfx03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx04.lc b/prototypes/tests/accept/gfx04.lc deleted file mode 120000 index 8ab3d531..00000000 --- a/prototypes/tests/accept/gfx04.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx04.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/gfx05.lc b/prototypes/tests/accept/gfx05.lc deleted file mode 120000 index 8ff2c366..00000000 --- a/prototypes/tests/accept/gfx05.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/gfx05.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/heartbeat01.lc b/prototypes/tests/accept/heartbeat01.lc deleted file mode 120000 index 4915e9e2..00000000 --- a/prototypes/tests/accept/heartbeat01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/heartbeat01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/id.lc b/prototypes/tests/accept/id.lc deleted file mode 120000 index 033be71e..00000000 --- a/prototypes/tests/accept/id.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/id.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/ifThenElse01.lc b/prototypes/tests/accept/ifThenElse01.lc deleted file mode 120000 index 910b04fa..00000000 --- a/prototypes/tests/accept/ifThenElse01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/ifThenElse01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/instantiate.lc b/prototypes/tests/accept/instantiate.lc deleted file mode 120000 index 4bba908b..00000000 --- a/prototypes/tests/accept/instantiate.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/instantiate.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/let.lc b/prototypes/tests/accept/let.lc deleted file mode 120000 index fce72e3b..00000000 --- a/prototypes/tests/accept/let.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/let.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/letIndent.lc b/prototypes/tests/accept/letIndent.lc deleted file mode 120000 index ef9d2cc4..00000000 --- a/prototypes/tests/accept/letIndent.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/letIndent.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/line01.lc b/prototypes/tests/accept/line01.lc deleted file mode 120000 index a7dbf6ec..00000000 --- a/prototypes/tests/accept/line01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/line01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/listcompr01.lc b/prototypes/tests/accept/listcompr01.lc deleted file mode 120000 index 9245a221..00000000 --- a/prototypes/tests/accept/listcompr01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/listcompr01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/listcompr02.lc b/prototypes/tests/accept/listcompr02.lc deleted file mode 120000 index 14a8e390..00000000 --- a/prototypes/tests/accept/listcompr02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/listcompr02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/listcompr03.lc b/prototypes/tests/accept/listcompr03.lc deleted file mode 120000 index b612974c..00000000 --- a/prototypes/tests/accept/listcompr03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/listcompr03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/listcompr04.lc b/prototypes/tests/accept/listcompr04.lc deleted file mode 120000 index 0bb81d2c..00000000 --- a/prototypes/tests/accept/listcompr04.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/listcompr04.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/listcompr05.lc b/prototypes/tests/accept/listcompr05.lc deleted file mode 120000 index cd8cacd0..00000000 --- a/prototypes/tests/accept/listcompr05.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/listcompr05.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/point01.lc b/prototypes/tests/accept/point01.lc deleted file mode 120000 index 279582fa..00000000 --- a/prototypes/tests/accept/point01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/point01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/record01.lc b/prototypes/tests/accept/record01.lc deleted file mode 120000 index 22769059..00000000 --- a/prototypes/tests/accept/record01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/record01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/record02.lc b/prototypes/tests/accept/record02.lc deleted file mode 120000 index b6adcf48..00000000 --- a/prototypes/tests/accept/record02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/record02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/recursivetexture02.lc b/prototypes/tests/accept/recursivetexture02.lc deleted file mode 120000 index 97bf2b71..00000000 --- a/prototypes/tests/accept/recursivetexture02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/recursivetexture02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce01.lc b/prototypes/tests/accept/reduce01.lc deleted file mode 120000 index 4907dfa3..00000000 --- a/prototypes/tests/accept/reduce01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce02.lc b/prototypes/tests/accept/reduce02.lc deleted file mode 120000 index 3a26d616..00000000 --- a/prototypes/tests/accept/reduce02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce03.lc b/prototypes/tests/accept/reduce03.lc deleted file mode 120000 index a39bc4b3..00000000 --- a/prototypes/tests/accept/reduce03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce04.lc b/prototypes/tests/accept/reduce04.lc deleted file mode 120000 index 2d6d9cd5..00000000 --- a/prototypes/tests/accept/reduce04.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce04.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce05.lc b/prototypes/tests/accept/reduce05.lc deleted file mode 120000 index 29b9a695..00000000 --- a/prototypes/tests/accept/reduce05.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce05.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/reduce06.lc b/prototypes/tests/accept/reduce06.lc deleted file mode 120000 index d8415c9c..00000000 --- a/prototypes/tests/accept/reduce06.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/reduce06.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/simple02.lc b/prototypes/tests/accept/simple02.lc deleted file mode 120000 index 9daa3328..00000000 --- a/prototypes/tests/accept/simple02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/simple02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/simple03.lc b/prototypes/tests/accept/simple03.lc deleted file mode 120000 index 12f5db1e..00000000 --- a/prototypes/tests/accept/simple03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/simple03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/swizzling.lc b/prototypes/tests/accept/swizzling.lc deleted file mode 120000 index a36ac043..00000000 --- a/prototypes/tests/accept/swizzling.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/swizzling.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/texture01.lc b/prototypes/tests/accept/texture01.lc deleted file mode 120000 index 69504d89..00000000 --- a/prototypes/tests/accept/texture01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/texture01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/texture02.lc b/prototypes/tests/accept/texture02.lc deleted file mode 120000 index ec570de7..00000000 --- a/prototypes/tests/accept/texture02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/texture02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/typeclass0.lc b/prototypes/tests/accept/typeclass0.lc deleted file mode 120000 index 87bfef05..00000000 --- a/prototypes/tests/accept/typeclass0.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/typeclass0.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/uniformparam01.lc b/prototypes/tests/accept/uniformparam01.lc deleted file mode 120000 index 52da0bc6..00000000 --- a/prototypes/tests/accept/uniformparam01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/uniformparam01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/uniformparam02.lc b/prototypes/tests/accept/uniformparam02.lc deleted file mode 120000 index a4337d3a..00000000 --- a/prototypes/tests/accept/uniformparam02.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/uniformparam02.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/uniformparam03.lc b/prototypes/tests/accept/uniformparam03.lc deleted file mode 120000 index 13143d6e..00000000 --- a/prototypes/tests/accept/uniformparam03.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/uniformparam03.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/accept/zip01.lc b/prototypes/tests/accept/zip01.lc deleted file mode 120000 index 8854d4fa..00000000 --- a/prototypes/tests/accept/zip01.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../tests/accept/zip01.lc \ No newline at end of file | ||
diff --git a/prototypes/tests/demo/.placeholder b/prototypes/tests/demo/.placeholder deleted file mode 100644 index e69de29b..00000000 --- a/prototypes/tests/demo/.placeholder +++ /dev/null | |||
diff --git a/prototypes/tests/reject/.placeholder b/prototypes/tests/reject/.placeholder deleted file mode 100644 index e69de29b..00000000 --- a/prototypes/tests/reject/.placeholder +++ /dev/null | |||
diff --git a/prototypes/tests/reject/data.lc b/prototypes/tests/reject/data.lc deleted file mode 100644 index 4f609a33..00000000 --- a/prototypes/tests/reject/data.lc +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | data Data1 = Data1 a b c | ||
diff --git a/prototypes/tests/reject/empty.lc b/prototypes/tests/reject/empty.lc deleted file mode 100644 index 5349cc9b..00000000 --- a/prototypes/tests/reject/empty.lc +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | ||
2 | |||
3 | data Empty2 = | ||