summaryrefslogtreecommitdiff
path: root/prototypes
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2015-12-19 15:15:42 +0100
committerPéter Diviánszky <divipp@gmail.com>2015-12-19 15:15:42 +0100
commit0fceae00351621f81dc5e5a9a76997765e0c2394 (patch)
tree3c79e9164c91852365b4929a67ec38584fa51a55 /prototypes
parent54ad6ad562dcc78da03929dccc21fc9e4307b004 (diff)
switch to new compiler
Diffstat (limited to 'prototypes')
-rw-r--r--prototypes/CGExp.hs332
l---------prototypes/CoreToGLSL.hs1
l---------prototypes/CoreToIR.hs1
l---------prototypes/Driver.hs1
l---------prototypes/IR.hs1
-rw-r--r--prototypes/Infer.hs2247
l---------prototypes/Linear.hs1
-rw-r--r--prototypes/Parser.hs1
l---------prototypes/Pretty.hs1
-rw-r--r--prototypes/TODO207
l---------prototypes/Text1
-rw-r--r--prototypes/Type.hs2
-rw-r--r--prototypes/Typecheck.hs1
-rwxr-xr-xprototypes/create-test-report.sh12
-rw-r--r--prototypes/lambdacube-compiler.cabal96
-rwxr-xr-xprototypes/run-test-suite.sh20
l---------prototypes/runTests.hs1
-rw-r--r--prototypes/tests/accept/Builtins.lc568
-rw-r--r--prototypes/tests/accept/DepPrelude.lc568
l---------prototypes/tests/accept/Graphics.lc1
l---------prototypes/tests/accept/Material.lc1
l---------prototypes/tests/accept/NewStyle.lc1
-rw-r--r--prototypes/tests/accept/Prelude.lc311
l---------prototypes/tests/accept/PrimReduce.lc1
l---------prototypes/tests/accept/SampleMaterial.lc1
l---------prototypes/tests/accept/ambig.lc1
l---------prototypes/tests/accept/concatmap01.lc1
-rw-r--r--prototypes/tests/accept/data.lc18
l---------prototypes/tests/accept/dotdot01.lc1
l---------prototypes/tests/accept/dotdot02.lc1
-rw-r--r--prototypes/tests/accept/empty.lc3
l---------prototypes/tests/accept/example06.lc1
l---------prototypes/tests/accept/example07.lc1
l---------prototypes/tests/accept/example08.lc1
l---------prototypes/tests/accept/fetcharrays01.lc1
l---------prototypes/tests/accept/fragment01.lc1
l---------prototypes/tests/accept/fragment03swizzling.lc1
l---------prototypes/tests/accept/fragment04ifthenelse.lc1
l---------prototypes/tests/accept/fragment07let.lc1
l---------prototypes/tests/accept/framebuffer01.lc1
l---------prototypes/tests/accept/framebuffer02.lc1
l---------prototypes/tests/accept/framebuffer03.lc1
l---------prototypes/tests/accept/framebuffer04.lc1
l---------prototypes/tests/accept/framebuffer05.lc1
l---------prototypes/tests/accept/fromto.lc1
l---------prototypes/tests/accept/gfx00.lc1
l---------prototypes/tests/accept/gfx01.lc1
l---------prototypes/tests/accept/gfx02.lc1
l---------prototypes/tests/accept/gfx03.lc1
l---------prototypes/tests/accept/gfx04.lc1
l---------prototypes/tests/accept/gfx05.lc1
l---------prototypes/tests/accept/heartbeat01.lc1
l---------prototypes/tests/accept/id.lc1
l---------prototypes/tests/accept/ifThenElse01.lc1
l---------prototypes/tests/accept/instantiate.lc1
l---------prototypes/tests/accept/let.lc1
l---------prototypes/tests/accept/letIndent.lc1
l---------prototypes/tests/accept/line01.lc1
l---------prototypes/tests/accept/listcompr01.lc1
l---------prototypes/tests/accept/listcompr02.lc1
l---------prototypes/tests/accept/listcompr03.lc1
l---------prototypes/tests/accept/listcompr04.lc1
l---------prototypes/tests/accept/listcompr05.lc1
l---------prototypes/tests/accept/point01.lc1
l---------prototypes/tests/accept/record01.lc1
l---------prototypes/tests/accept/record02.lc1
l---------prototypes/tests/accept/recursivetexture02.lc1
l---------prototypes/tests/accept/reduce01.lc1
l---------prototypes/tests/accept/reduce02.lc1
l---------prototypes/tests/accept/reduce03.lc1
l---------prototypes/tests/accept/reduce04.lc1
l---------prototypes/tests/accept/reduce05.lc1
l---------prototypes/tests/accept/reduce06.lc1
l---------prototypes/tests/accept/simple02.lc1
l---------prototypes/tests/accept/simple03.lc1
l---------prototypes/tests/accept/swizzling.lc1
l---------prototypes/tests/accept/texture01.lc1
l---------prototypes/tests/accept/texture02.lc1
l---------prototypes/tests/accept/typeclass0.lc1
l---------prototypes/tests/accept/uniformparam01.lc1
l---------prototypes/tests/accept/uniformparam02.lc1
l---------prototypes/tests/accept/uniformparam03.lc1
l---------prototypes/tests/accept/zip01.lc1
-rw-r--r--prototypes/tests/demo/.placeholder0
-rw-r--r--prototypes/tests/reject/.placeholder0
-rw-r--r--prototypes/tests/reject/data.lc1
-rw-r--r--prototypes/tests/reject/empty.lc3
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 #-}
11module CGExp
12 ( module CGExp
13 , Lit(..), Export(..), ModuleR(..)
14 ) where
15
16import Control.Monad.Reader
17import Control.Monad.State
18import Control.Monad.Except
19import Control.Monad.Identity
20import Control.Monad.Writer
21import Control.Arrow
22import qualified Data.Set as S
23import qualified Data.Map as M
24import Text.Parsec.Pos
25
26import Pretty
27import qualified Infer as I
28import Infer (SName, Lit(..), Visibility(..), Export(..), ModuleR(..))
29
30--------------------------------------------------------------------------------
31
32data 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
45instance PShow Exp where pShowPrec p = text . show
46
47pattern Pi h n a b = Exp (Pi_ h n a b)
48pattern Lam h n a b = Exp (Lam_ h n a b)
49pattern Con a b = Exp (Con_ a b)
50pattern ELit a = Exp (ELit_ a)
51pattern Fun a b = Exp (Fun_ a b)
52pattern EApp a b = Exp (App_ a b)
53pattern Var a b = Exp (Var_ a b)
54pattern TType = Exp TType_
55pattern ELet a b c = Exp (Let_ a b c)
56pattern EFieldProj a b = Exp (EFieldProj_ a b)
57
58newtype Exp = Exp (Exp_ Exp)
59 deriving (Show, Eq)
60
61type ConvM a = StateT [SName] (Reader [SName]) a
62
63newName = gets head <* modify tail
64
65toExp :: I.Exp -> Exp
66toExp = 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
93getSwizzVec = \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
99mkSwizzStr = \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
106xs !!! i | i < 0 || i >= length xs = error $ show xs ++ " !! " ++ show i
107xs !!! i = xs !! i
108
109untick ('\'': s) = s
110untick s = s
111
112fun s t xs = Fun (untick s, t) xs
113
114con (untick -> s) t xs = Con (s, t) xs
115
116freeVars :: Exp -> S.Set SName
117freeVars = \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
129type Ty = Exp
130
131tyOf :: Exp -> Ty
132tyOf = \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
147substE 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
159app' (Lam _ (PVar _ n) _ x) b = substE n b x
160app' a b = EApp a b
161
162--------------------------------------------------------------------------------
163
164data Pat
165 = PVar Exp SName
166 | PTuple [Pat]
167 deriving (Eq, Show)
168
169instance PShow Pat where pShowPrec p = text . show
170
171patVars (PVar _ n) = [n]
172patVars (PTuple ps) = concatMap patVars ps
173
174patTy (PVar t _) = t
175patTy (PTuple ps) = Con ("Tuple" ++ show (length ps), tupTy $ length ps) $ map patTy ps
176
177tupTy n = foldr (:~>) Type $ replicate n Type
178
179-------------
180
181pattern EVar n <- Var n _
182pattern TVar t n = Var n t
183
184pattern ELam n b <- Lam Visible n _ b where ELam n b = Lam Visible n (patTy n) b
185
186pattern a :~> b = Pi Visible "" a b
187infixr 1 :~>
188
189pattern PrimN n xs <- Fun (n, t) (filterRelevant (n, 0) t -> xs) where PrimN n xs = Fun (n, hackType n) xs
190pattern Prim1 n a = PrimN n [a]
191pattern Prim2 n a b = PrimN n [a, b]
192pattern Prim3 n a b c <- PrimN n [a, b, c]
193pattern Prim4 n a b c d <- PrimN n [a, b, c, d]
194pattern Prim5 n a b c d e <- PrimN n [a, b, c, d, e]
195
196-- todo: remove
197hackType = \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
210filterRelevant _ _ [] = []
211filterRelevant 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
216pattern AN n xs <- Con (n, t) (filterRelevant (n, 0) t -> xs) where AN n xs = Con (n, hackType n) xs
217pattern A0 n = AN n []
218pattern A1 n a = AN n [a]
219pattern A2 n a b = AN n [a, b]
220pattern A3 n a b c <- AN n [a, b, c]
221pattern A4 n a b c d <- AN n [a, b, c, d]
222pattern A5 n a b c d e <- AN n [a, b, c, d, e]
223
224pattern TCon0 n = A0 n
225pattern TCon t n = Con (n, t) []
226
227pattern Type = TType
228pattern Star = TType
229pattern TUnit <- A0 "Tuple0"
230pattern TBool <- A0 "Bool"
231pattern TWord <- A0 "Word"
232pattern TInt <- A0 "Int"
233pattern TNat = A0 "Nat"
234pattern TFloat = A0 "Float"
235pattern TString = A0 "String"
236pattern TList n <- A1 "List" n
237
238pattern TSampler = A0 "Sampler"
239pattern TFrameBuffer a b <- A2 "FrameBuffer" a b
240pattern Depth n <- A1 "Depth" n
241pattern Stencil n <- A1 "Stencil" n
242pattern Color n <- A1 "Color" n
243
244pattern Zero = A0 "Zero"
245pattern Succ n = A1 "Succ" n
246
247pattern TVec n a = A2 "VecS" a (Nat n)
248pattern TMat i j a <- A3 "Mat" (Nat i) (Nat j) a
249
250pattern Nat n <- (fromNat -> Just n) where Nat n = toNat n
251
252toNat :: Int -> Exp
253toNat 0 = Zero
254toNat n = Succ (toNat $ n-1)
255
256fromNat :: Exp -> Maybe Int
257fromNat Zero = Just 0
258fromNat (Succ n) = (1 +) <$> fromNat n
259
260pattern TTuple xs <- (getTuple -> Just xs)
261pattern ETuple xs <- (getTuple -> Just xs)
262
263getTuple = \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
273pattern ERecord a <- (const Nothing -> Just a)
274
275--------------------------------------------------------------------------------
276
277showN = id
278show5 = show
279
280pattern ExpN a = a
281
282newtype ErrorMsg = ErrorMsg String
283instance Show ErrorMsg where show (ErrorMsg s) = s
284
285type ErrorT = ExceptT ErrorMsg
286mapError f e = e
287pattern InFile :: String -> ErrorMsg -> ErrorMsg
288pattern InFile s e <- ((,) "?" -> (s, e)) where InFile _ e = e
289
290type Info = (SourcePos, SourcePos, String)
291type Infos = [Info]
292
293type PolyEnv = I.GlobalEnv
294
295joinPolyEnvs :: MonadError ErrorMsg m => Bool -> [PolyEnv] -> m PolyEnv
296joinPolyEnvs _ = return . mconcat
297getPolyEnv = id
298
299type MName = SName
300type VarMT = StateT FreshVars
301type FreshVars = [String]
302freshTypeVars = (flip (:) <$> map show [0..] <*> ['a'..'z'])
303
304throwErrorTCM :: MonadError ErrorMsg m => Doc -> m a
305throwErrorTCM d = throwError $ ErrorMsg $ show d
306
307infos = const []
308
309type EName = SName
310
311parseLC :: MonadError ErrorMsg m => FilePath -> String -> m ModuleR
312parseLC f s = either (throwError . ErrorMsg) return (I.parse f s)
313
314inference_ :: PolyEnv -> ModuleR -> ErrorT (WriterT Infos (VarMT Identity)) PolyEnv
315inference_ 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
319reduce = id
320
321type Item = (I.Exp, I.Exp)
322
323tyOfItem :: Item -> Exp
324tyOfItem = toExp . snd
325
326pattern ISubst a b <- ((,) () -> (a, (toExp -> b, tb)))
327
328dummyPos :: SourcePos
329dummyPos = newPos "" 0 0
330
331showErr 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 #-}
11module 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
20import Data.Monoid
21import Data.Maybe
22import Data.List
23import Data.Char
24import Data.String
25import qualified Data.Set as Set
26import qualified Data.Map as Map
27
28import Control.Monad.Except
29import Control.Monad.Reader
30import Control.Monad.State
31import Control.Monad.Identity
32import Control.Arrow
33import Control.Applicative hiding (optional)
34import Control.Exception hiding (try)
35
36import Text.Parsec hiding (parse, label, Empty, State, (<|>), many, optional)
37import qualified Text.Parsec.Token as Pa
38import Text.Parsec.Pos
39import Text.Parsec.Indentation hiding (Any)
40import Text.Parsec.Indentation.Char
41import Text.Parsec.Indentation.Token
42
43import Debug.Trace
44
45import qualified Pretty as P
46
47-------------------------------------------------------------------------------- source data
48
49type SName = String
50
51data 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
63data 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
72type FixityMap = Map.Map SName Fixity
73type ConsMap = Map.Map SName ((SName{-type name-}, Int{-num of indices-}), [(SName, Int)]{-constructors with arities-})
74type GlobalEnv' = (FixityMap, ConsMap)
75
76type Fixity = (Maybe FixityDir, Int)
77type MFixity = Maybe Fixity
78data FixityDir = FDLeft | FDRight deriving (Show)
79
80data Binder
81 = BPi Visibility
82 | BLam Visibility
83 | BMeta -- a metavariable is like a floating hidden lambda
84 deriving (Eq, Show)
85
86data Visibility = Hidden | Visible
87 deriving (Eq, Show)
88
89sLit a = STyped (ELit a, litType a)
90pattern SType = STyped (TType, TType)
91pattern SPi h a b = SBind (BPi h) a b
92pattern SLam h a b = SBind (BLam h) a b
93pattern Wildcard t = SBind BMeta t (SVar 0)
94pattern SAppH a b = SApp Hidden a b
95pattern SAppV a b = SApp Visible a b
96pattern 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
97pattern 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
100pattern SCstr a b = SGlobal "cstr" `SAppV` a `SAppV` b -- a ~ b
101pattern SLabelEnd a = SGlobal "labelend" `SAppV` a
102
103isPi (BPi _) = True
104isPi _ = False
105
106infixl 1 `SAppV`, `SAppH`, `App`
107
108-------------------------------------------------------------------------------- destination data
109
110data 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
124data 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
131type Type = Exp
132
133data ConName = ConName SName MFixity Int Type
134instance Show ConName where show (ConName n _ _ _) = n
135instance Eq ConName where ConName n _ _ _ == ConName n' _ _ _ = n == n'
136
137conTypeName :: ConName -> TyConName
138conTypeName (ConName _ _ _ t) = case snd (getParams t) of
139 TyCon n _ -> n
140 _ -> error "impossible"
141
142data TyConName = TyConName SName MFixity Int{-num of indices-} Type [ConName]{-constructors-} Type{-case type-}
143instance Show TyConName where show (TyConName n _ _ _ _ _) = n
144instance Eq TyConName where TyConName n _ _ _ _ _ == TyConName n' _ _ _ _ _ = n == n'
145
146data FunName = FunName SName MFixity Type
147instance Show FunName where show (FunName n _ _) = n
148instance Eq FunName where FunName n _ _ == FunName n' _ _ = n == n'
149
150data CaseFunName = CaseFunName SName Type Int{-num of parameters-}
151instance Show CaseFunName where show (CaseFunName n _ _) = n
152instance Eq CaseFunName where CaseFunName n _ _ == CaseFunName n' _ _ = n == n'
153
154caseName (c:cs) = toLower c: cs ++ "Case"
155
156type ExpType = (Exp, Type)
157
158pattern Fun a b = Neut (Fun_ a b)
159pattern CaseFun a b = Neut (CaseFun_ a b)
160pattern FunN a b <- Fun (FunName a _ _) b
161pattern CaseFunN a b <- CaseFun (CaseFunName a _ _) b
162pattern TFun a t b <- Fun (FunName a _ t) b where TFun a t b = Fun (FunName a Nothing t) b
163pattern TCaseFun a t i b = CaseFun (CaseFunName a t i) b
164pattern App a b = Neut (App_ a b)
165pattern Var a = Neut (Var_ a)
166
167data Lit
168 = LInt !Int
169 | LChar Char
170 | LFloat Double
171 | LString String
172 deriving (Eq)
173
174instance 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
181pattern Lam' b <- Lam _ _ b
182pattern Pi h a b = Bind (BPi h) a b
183pattern Meta a b = Bind BMeta a b
184
185pattern Cstr a b = TFun "cstr" (TType :~> TType :~> TType){-todo-} [a, b]
186pattern ReflCstr x = TFun "reflCstr" (TType :~> Cstr (Var 0) (Var 0)) [x]
187pattern Coe a b w x = TFun "coe" (TType :~> TType :~> Cstr (Var 1) (Var 0) :~> Var 2 :~> Var 2) [a,b,w,x]
188
189pattern ConN s a <- Con (ConName s _ _ _) a
190pattern TyConN s a <- TyCon (TyConName s _ _ _ _ _) a
191pattern 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
192pattern 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
193pattern TTyCon0 s <- TyCon (TyConName s _ _ TType _ _) [] where TTyCon0 s = TyCon (TyConName s Nothing (error "todo: inum2") TType (error "todo: tcn cons 3") $ error "TTyCon0") []
194pattern 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]
195pattern Unit = TTyCon0 "Unit"
196pattern TT = TCon "TT" 0 Unit []
197pattern T2 a b = TFun "T2" (TType :~> TType :~> TType) [a, b]
198pattern T2C a b = TCon "T2C" (-1) (Unit :~> Unit :~> Unit) [a, b]
199pattern Empty = TTyCon0 "Empty"
200pattern TInt = TTyCon0 "Int"
201pattern TNat = TTyCon0 "Nat"
202pattern TBool = TTyCon0 "Bool"
203pattern TFloat = TTyCon0 "Float"
204pattern TString = TTyCon0 "String"
205pattern TChar = TTyCon0 "Char"
206pattern TOrdering = TTyCon0 "'Ordering"
207pattern Zero = TCon "Zero" 0 TNat []
208pattern Succ n = TCon "Succ" 1 (TNat :~> TNat) [n]
209--pattern TVec a b = TTyCon "'Vec" (TNat :~> TType :~> TType) [a, b]
210pattern TVec a b = TTyCon "'VecS" (TType :~> TNat :~> TType) [b, a]
211pattern TFrameBuffer a b = TTyCon "'FrameBuffer" (TNat :~> TType :~> TType) [a, b]
212pattern TRecord a = TTyCon "'RecordC" TRecordType [a]
213pattern TList a = TTyCon "'List" (TType :~> TType) [a]
214pattern Tuple2 a b c d = TCon "Tuple2" 0 Tuple2Type [a, b, c, d]
215pattern Tuple0 = TCon "Tuple0" 0 Tuple0Type []
216pattern VV2 t x y = TCon "V2" 0 V2Type [t, x, y]
217pattern VV3 t x y z = TCon "V3" 1 V3Type [t, x, y, z]
218pattern VV4 t x y z w = TCon "V4" 2 V4Type [t, x, y, z, w]
219pattern CSplit a b c <- FunN "Split" [a, b, c]
220
221pattern Tuple0Type :: Exp
222pattern Tuple0Type <- _ where Tuple0Type = TTyCon0 "'Tuple0"
223pattern Tuple2Type :: Exp
224pattern Tuple2Type <- _ where Tuple2Type = Pi Hidden TType $ Pi Hidden TType $ Var 1 :~> Var 1 :~> tTuple2 (Var 3) (Var 2)
225pattern V2Type :: Exp
226pattern V2Type <- _ where V2Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> TVec (toNatE 2) (Var 2)
227pattern V3Type :: Exp
228pattern V3Type <- _ where V3Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> Var 2 :~> TVec (toNatE 3) (Var 3)
229pattern V4Type :: Exp
230pattern V4Type <- _ where V4Type = Pi Hidden TType $ Var 0 :~> Var 1 :~> Var 2 :~> Var 3 :~> TVec (toNatE 4) (Var 4)
231pattern TRecordType :: Exp
232pattern TRecordType <- _ where TRecordType = TList SListEType :~> TType
233pattern NilType :: Exp
234pattern NilType <- _ where NilType = Pi Hidden TType $ TList (Var 0)
235pattern ConsType :: Exp
236pattern ConsType <- _ where ConsType = Pi Hidden TType $ Var 0 :~> TList (Var 1) :~> TList (Var 2)
237
238pattern VNil = TCon "Nil" 0 NilType [SListEType]
239pattern VCons a b = TCon "Cons" 1 ConsType [SListEType, VT2 a, b]
240
241pattern VT2 :: (String, Exp) -> Exp
242pattern VT2 se <- TCon "Tuple2" 0 _ (listT2 -> Just se) where VT2 (s, e) = Tuple2 TString TType (ELit $ LString s) e
243
244listT2 [_, _, ELit (LString s), e] = Just (s, e)
245listT2 x = Nothing
246
247pattern SListEType :: Exp
248pattern SListEType <- _ where SListEType = tTuple2 TString TType
249
250tTuple2 a b = TTyCon "'Tuple2" (TType :~> TType :~> TType) [a, b]
251tTuple3 a b c = TTyCon "'Tuple3" (TType :~> TType :~> TType :~> TType) [a, b, c]
252tMat a b c = TTyCon "'Mat" (TNat :~> TNat :~> TType :~> TType) [a, b, c]
253
254toNatE :: Int -> Exp
255toNatE 0 = Zero
256toNatE n | n > 0 = Succ (toNatE (n - 1))
257
258t2C TT TT = TT
259t2C a b = T2C a b
260
261t2 Unit a = a
262t2 a Unit = a
263t2 Empty _ = Empty
264t2 _ Empty = Empty
265t2 a b = TFun "T2" (TType :~> TType :~> TType) [a, b]
266
267pattern EInt a = ELit (LInt a)
268pattern EFloat a = ELit (LFloat a)
269
270mkBool False = TCon "False" 0 TBool []
271mkBool True = VTrue
272pattern VTrue = TCon "True" 1 TBool []
273
274pattern LCon <- (isCon -> True)
275pattern CFun <- (caseFunName -> True)
276
277pattern a :~> b = Bind (BPi Visible) a b
278
279infixr 1 :~>
280
281caseFunName (Fun f _) = True
282caseFunName (CaseFun f _) = True
283caseFunName _ = False
284
285isCon = \case
286 TType -> True
287 Con _ _ -> True
288 TyCon _ _ -> True
289 ELit _ -> True
290 _ -> False
291
292-------------------------------------------------------------------------------- environments
293
294-- SExp + Exp zipper
295data 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
316type GlobalEnv = Map.Map SName (Exp, Type)
317
318extractEnv :: Env -> GlobalEnv
319extractEnv = either id extractEnv . parent
320
321parent = \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
338initEnv :: GlobalEnv
339initEnv = Map.fromList
340 [ (,) "Type" (TType, TType) -- needed?
341 ]
342
343-- monad used during elaborating statments -- TODO: use zippers instead
344type ElabStmtM m = StateT GlobalEnv (ExceptT String m)
345
346-------------------------------------------------------------------------------- low-level toolbox
347
348getFunName (fst . getApps' -> Fun f _) = Just f
349getFunName _ = Nothing
350
351label x (LabelEnd y) = y
352label x y = Label x y
353
354pattern UBind a b c = {-UnLabel-} (Bind a b c) -- todo: review
355pattern UApp a b = {-UnLabel-} (App a b) -- todo: review
356pattern UVar n = Var n
357
358instance 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
374assign :: (Int -> Exp -> Exp -> a) -> (Int -> Exp -> Exp -> a) -> Int -> Exp -> Exp -> a
375assign _ clet i (Var j) b | i > j = clet j (Var (i-1)) $ substE "assign" j (Var (i-1)) $ up1E i b
376assign clet _ i a b = clet i a b
377
378handleLet i j f
379 | i > j = f (i-1) j
380 | i <= j = f i (j+1)
381
382foldS 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
390foldE 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
405freeS = nub . foldS (\_ s -> [s]) mempty 0
406freeE = foldE (\i k -> Set.fromList [k - i | k >= i]) 0
407
408usedS = (getAny .) . foldS mempty ((Any .) . (==))
409usedE = (getAny .) . foldE ((Any .) . (==))
410
411mapS = mapS_ (const SGlobal)
412mapS_ gg ff = mapS__ gg ff $ \i j -> case ff i $ Var j of
413 Var k -> SVar k
414 -- x -> STyped x -- todo
415mapS__ 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
424rearrangeS :: (Int -> Int) -> SExp -> SExp
425rearrangeS f = mapS__ (const SGlobal) (const id) (\i j -> SVar $ if j < i then j else i + f (j - i)) (+1) 0
426
427upS__ i n = mapS (\i -> upE i n) (+1) i
428upS = upS__ 0 1
429
430up1E 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
445upE i n e = iterateN n (up1E i) e
446
447substSS :: Int -> SExp -> SExp -> SExp
448substSS 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)
453substS j x = mapS (uncurry $ substE "substS") ((+1) *** up1E 0) (j, x)
454substSG j x = mapS_ (\x i -> if i == j then x else SGlobal i) (const id) upS x
455
456substE err = substE_ (error $ "substE: todo: environment required in " ++ err) -- todo: remove
457
458substE_ :: Env -> Int -> Exp -> Exp -> Exp
459substE_ 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
485downS t x | usedS t x = Nothing
486 | otherwise = Just $ substS t (error "impossible: downS") x
487downE t x | usedE t x = Nothing
488 | otherwise = Just $ substE_ (error "impossible") t (error "impossible: downE") x
489
490varType :: String -> Int -> Env -> (Binder, Exp)
491varType 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
499infixl 1 `app_`
500
501app_ :: Exp -> Exp -> Exp
502app_ (Lam' x) a = substE "app" 0 a x
503app_ (Con s xs) a = Con s (xs ++ [a])
504app_ (TyCon s xs) a = TyCon s (xs ++ [a])
505app_ (Label x e) a = label (app_ x a) $ app_ e a
506app_ (LabelEnd x) a = LabelEnd (app_ x a) -- ???
507app_ f a = App f a
508
509eval 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
607getVec (VV2 t x y) = Just (t, [x, y])
608getVec (VV3 t x y z) = Just (t, [x, y, z])
609getVec (VV4 t x y z w) = Just (t, [x, y, z, w])
610getVec _ = Nothing
611
612getVec' t vs (VV2 _ (getSwizz -> Just sx) (getSwizz -> Just sy)) = Just $ VV2 t (selSwizz sx vs) (selSwizz sy vs)
613getVec' t vs (VV3 _ (getSwizz -> Just sx) (getSwizz -> Just sy) (getSwizz -> Just sz)) = Just $ VV3 t (selSwizz sx vs) (selSwizz sy vs) (selSwizz sz vs)
614getVec' 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)
615getVec' _ _ _ = Nothing
616
617selSwizz i = (!! i)
618
619getSwizz = \case
620 ConN "Sx" [] -> Just 0
621 ConN "Sy" [] -> Just 1
622 ConN "Sz" [] -> Just 2
623 ConN "Sw" [] -> Just 3
624 _ -> Nothing
625
626toVList = foldr VCons VNil
627fromVList :: Exp -> Maybe [(String, Exp)]
628fromVList (VCons a b) = (a:) <$> fromVList b
629fromVList VNil = Just []
630fromVList x = Nothing
631
632tupsToList (Tuple2 _ _ x xs) = x: tupsToList xs
633tupsToList Tuple0 = []
634
635mkOrdering = \case
636 LT -> TCon "LT" 0 TOrdering []
637 EQ -> TCon "EQ" 1 TOrdering []
638 GT -> TCon "GT" 2 TOrdering []
639
640pattern TTuple0 = TTyCon "'Tuple0" TType []
641pattern NoTup <- (noTup -> True)
642
643noTup (TyConN s _) = take 6 s /= "'Tuple" -- todo
644noTup _ = False
645
646fromNatE :: Exp -> Maybe Int
647fromNatE Zero = Just 0
648fromNatE (Succ n) = (1 +) <$> fromNatE n
649
650-- todo
651coe a b c d | a == b = d -- todo
652coe a b c d = Coe a b c d
653
654reflCstr 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
664cstr = 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
719cstr' 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
723litType = \case
724 LInt _ -> TInt
725 LFloat _ -> TFloat
726 LString _ -> TString
727 LChar _ -> TChar
728
729expType_ 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
750type TCM m = ExceptT String m
751
752runTCM = either error id . runExcept
753
754-- todo: do only if NoTypeNamespace extension is not on
755lookupName s@('\'':s') m = maybe (Map.lookup s' m) Just $ Map.lookup s m
756lookupName s m = Map.lookup s m
757elemIndex' s@('\'':s') m = maybe (elemIndex s' m) Just $ elemIndex s m
758elemIndex' s m = elemIndex s m
759notElem' s@('\'':s') m = notElem s m && notElem s' m
760notElem' s m = notElem s m
761
762getDef te s = maybe (throwError $ "getDef: can't find: " ++ s) return (lookupName s $ extractEnv te)
763
764both f = f *** f
765
766inferN :: forall m . Monad m => TraceLevel -> Env -> SExp -> TCM m ExpType
767inferN 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
899type Message = String
900
901recheck :: Message -> Env -> Exp -> Exp
902recheck msg e = if debug_light then recheck' msg e else id
903
904recheck' :: Message -> Env -> Exp -> Exp
905recheck' 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
968addParams ps t = foldr (uncurry SPi) t ps
969
970getParamsS (SPi h t x) = ((h, t):) *** id $ getParamsS x
971getParamsS x = ([], x)
972
973getApps (SApp h a b) = id *** (++ [(h, b)]) $ getApps a -- todo: make it efficient
974getApps x = (x, [])
975
976getApps' (App a b) = id *** (++ [b]) $ getApps' a -- todo: make it efficient
977getApps' x = (x, [])
978
979arity :: Exp -> Int
980arity = length . arity_
981arity_ = map fst . fst . getParams
982
983getParams :: Exp -> ([(Visibility, Exp)], Exp)
984getParams (Pi h a b) = ((h, a):) *** id $ getParams b
985getParams x = ([], x)
986
987apps a b = foldl SAppV (SGlobal a) b
988apps' a b = foldl sapp (SGlobal a) b
989
990replaceMetas 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
995replaceMetas' 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
1001checkMetas 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
1020getGEnv f = gets (flip EGlobal mempty) >>= f
1021inferTerm 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)
1023inferType 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
1025smartTrace :: MonadError String m => (Bool -> m a) -> m a
1026smartTrace f | trace_level >= 2 = f True
1027smartTrace f | trace_level == 0 = f False
1028smartTrace f = catchError (f False) $ \err ->
1029 trace_ (unlines
1030 [ "---------------------------------"
1031 , err
1032 , "try again with trace"
1033 , "---------------------------------"
1034 ]) $ f True
1035
1036addToEnv :: Monad m => String -> (Exp, Exp) -> ElabStmtM m ()
1037--addToEnv s (x, t) | Just msg <- ambiguityCheck s t = throwError msg
1038addToEnv 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
1044ambiguityCheck :: String -> Exp -> Maybe String
1045ambiguityCheck s ty = case ambigVars ty of
1046 [] -> Nothing
1047 err -> Just $ s ++ " has ambiguous type:\n" ++ showExp ty ++ "\nproblematic vars:\n" ++ show err
1048
1049ambigVars :: Exp -> [(Int, Exp)]
1050ambigVars 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
1058floatLetMeta :: Exp -> Bool
1059floatLetMeta 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
1067hiddenVars (Pi Hidden a b) = (a:) *** id $ hiddenVars b
1068hiddenVars 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]
1072dependentVars :: [(Int, Exp)] -> Set.Set Int -> Set.Set Int
1073dependentVars 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
1092expType = expType_ (EGlobal initEnv [])
1093addType x = (x, expType x)
1094addType_ te x = (x, expType_ te x)
1095
1096downTo n m = map SVar [n+m-1, n+m-2..n]
1097
1098defined' = Map.keys
1099
1100addF = gets $ addForalls . defined'
1101
1102fixType = Pi Hidden TType $ Pi Visible (Pi Visible (Var 0) (Var 1)) (Var 1) -- forall a . (a -> a) -> a
1103
1104handleStmt :: MonadFix m => Stmt -> ElabStmtM m ()
1105handleStmt = \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
1187removeHiddenUnit (Pi Hidden Unit (downE 0 -> Just t)) = removeHiddenUnit t
1188removeHiddenUnit (Pi h a b) = Pi h a $ removeHiddenUnit b
1189removeHiddenUnit t = t
1190
1191-------------------------------------------------------------------------------- parser
1192
1193addForalls :: [SName] -> SExp -> SExp
1194addForalls 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
1198defined 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
1204type InnerP = Reader GlobalEnv'
1205
1206type P = ParsecT (IndentStream (CharIndentStream String)) SourcePos InnerP
1207
1208lexer :: Pa.GenTokenParser (IndentStream (CharIndentStream String)) SourcePos InnerP
1209lexer = 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
1225position :: P SourcePos
1226position = getPosition
1227
1228positionBeforeSpace :: P SourcePos
1229positionBeforeSpace = getState
1230
1231optional :: P a -> P (Maybe a)
1232optional = optionMaybe
1233
1234keyword :: String -> P ()
1235keyword = Pa.reserved lexer
1236
1237operator :: String -> P ()
1238operator = Pa.reservedOp lexer
1239
1240tick (Just True, _) ('\'':n) = n
1241tick (Just True, _) n | n `elem` ["Type", "Nat", "Float", "Int", "Bool", "IO", "Unit", "Empty", "T2"] = n
1242 | otherwise = '\'': n
1243tick _ n = n
1244
1245lcIdents ns = tick ns <$> ((++) <$> (option [] $ ("'" <$ char '\'')) <*> Pa.identifier lexer)
1246
1247lcOps = Pa.operator lexer
1248
1249ident = id
1250parens = Pa.parens lexer
1251braces = Pa.braces lexer
1252brackets = Pa.brackets lexer
1253commaSep = Pa.commaSep lexer
1254commaSep1 = Pa.commaSep1 lexer
1255dot = Pa.dot lexer
1256comma = Pa.comma lexer
1257colon = Pa.colon lexer
1258natural = Pa.natural lexer
1259integer = Pa.integer lexer
1260float = Pa.float lexer
1261charLiteral = Pa.charLiteral lexer
1262stringLiteral = Pa.stringLiteral lexer
1263whiteSpace = Pa.whiteSpace lexer
1264
1265data Extension
1266 = NoImplicitPrelude
1267 | NoTypeNamespace
1268 | NoConstructorNamespace
1269 deriving (Eq, Ord, Show)
1270
1271type Name = String
1272type DefinitionR = Stmt
1273
1274data Export = ExportModule Name | ExportId Name
1275
1276data 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
1289try' s m = try m <?> s
1290{-
1291qualified_ 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
1302check 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
1307upperCase (Nothing, _) = mzero -- todo
1308upperCase ns = (if snd ns then check "uppercase ident" (isUpper . head) else id) $ ident $ lcIdents ns
1309lowerCase ns = (if snd ns then check "lowercase ident" (isLower . head) else id) (ident $ lcIdents ns) <|> try (('_':) <$ char '_' <*> ident (lcIdents ns))
1310symbols = check "symbols" ((/=':') . head) $ ident lcOps
1311colonSymbols = "Cons" <$ operator ":" <|> check "symbols" ((==':') . head) (ident lcOps)
1312
1313--------------------------------------------------------------------------------
1314
1315pattern ExpN' :: String -> P.Doc -> String
1316pattern ExpN' s p <- ((,) undefined -> (p, s)) where ExpN' s p = s
1317pattern 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)
1321upperCaseIdent ns = upperCase ns <&> ExpN
1322--typeVar = (\p i -> TypeN' i $ P.text $ i ++ show p) <$> position <*> lowerCase
1323var ns = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> lowerCase ns
1324qIdent ns = {-qualified_ todo-} (var ns <|> upperCaseIdent ns)
1325conOperator = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> colonSymbols
1326varId ns = var ns <|> parens operator'
1327backquotedIdent = try' "backquoted" $ char '`' *> (ExpN <$> ((:) <$> satisfy isAlpha <*> many (satisfy isAlphaNum))) <* char '`' <* whiteSpace
1328operator' = (\p i -> ExpN' i $ P.text $ i ++ show p) <$> position <*> symbols
1329 <|> conOperator
1330 <|> backquotedIdent
1331moduleName = {-qualified_ todo-} upperCaseIdent (Just False, False)
1332
1333-------------------------------------------------------------------------------- fixity declarations
1334
1335fixityDef :: P [DefinitionR]
1336fixityDef = 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
1347export :: Namespace -> P Export
1348export ns =
1349 ExportModule <$ keyword "module" <*> moduleName
1350 <|> ExportId <$> varId ns
1351
1352parseExtensions :: P [Extension]
1353parseExtensions = 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
1374importlist ns = parens (commaSep (varId ns <|> upperCaseIdent ns))
1375
1376parse :: SourceName -> String -> Either String ModuleR
1377parse 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
1412parseType ns mb vs = maybe id option mb $ operator "::" *> parseTTerm ns PrecLam vs
1413patVar ns = lcIdents ns <|> "" <$ keyword "_"
1414patVar2 ns = lowerCase ns <|> "" <$ keyword "_"
1415typedId ns mb vs = (,) <$> patVar ns <*> localIndentation Gt {-TODO-} (parseType ns mb vs)
1416typedId' ns mb vs = (,) <$> commaSep1 (varId ns <|> patVar ns) <*> localIndentation Gt {-TODO-} (parseType ns mb vs)
1417
1418telescope 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
1427parseClause 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
1434patternAtom 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
1442eqPP = ParPat [PCon "EQ" []]
1443truePP = ParPat [PCon "True" []]
1444
1445patlist ns vs = commaSep1' (\vs -> (\(vs, p) t -> (vs, patType p t)) <$> pattern' ns vs <*> parseType ns (Just $ Wildcard SType) vs) vs
1446
1447mkListPat (p: ps) = PCon "Cons" $ map (ParPat . (:[])) [p, mkListPat ps]
1448mkListPat [] = PCon "Nil" []
1449
1450pattern' 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
1455patterns ns vs =
1456 do patternAtom ns vs >>= \(vs, p) -> patterns ns vs >>= \(vs, ps) -> pure (vs, ParPat [p]: ps)
1457 <|> pure (vs, [])
1458
1459pCon i (vs, x) = (vs, PCon i x)
1460
1461patType p (Wildcard SType) = p
1462patType p t = PatType (ParPat [p]) t
1463
1464mkTupPat :: [Pat] -> Pat
1465mkTupPat [x] = x
1466mkTupPat ps = PCon ("Tuple" ++ show (length ps)) (ParPat . (:[]) <$> ps)
1467
1468commaSep1' :: (t -> P (t, a)) -> t -> P (t, [a])
1469commaSep1' p vs =
1470 p vs >>= \(vs, x) -> (\(vs, xs) -> (vs, x: xs)) <$ comma <*> commaSep1' p vs
1471 <|> pure (vs, [x])
1472
1473commaSep' :: (t -> P (t, a)) -> t -> P (t, [a])
1474commaSep' p vs =
1475 commaSep1' p vs
1476 <|> pure (vs, [])
1477
1478telescope' 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
1487parseStmts 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
1506parseStmt :: Namespace -> [String] -> P [Stmt]
1507parseStmt 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
1560mkData 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
1570parseWhereBlock 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
1576type DBNames = [SName] -- De Bruijn variable names
1577
1578valueDef :: Namespace -> DBNames -> P ((DBNames, Pat), SExp)
1579valueDef 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
1585pattern TPVar t = ParPat [PatType (ParPat [PVar]) t]
1586
1587sapp a (v, b) = SApp v a b
1588
1589type Namespace = (Maybe Bool {-True: type namespace-}, Bool)
1590
1591parseTTerm ns = parseTerm $ typeNS ns
1592parseETerm ns = parseTerm $ expNS ns
1593
1594typeNS = (True <$) *** id
1595expNS = (False <$) *** id
1596
1597parseTerm :: Namespace -> Prec -> [String] -> P SExp
1598parseTerm 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
1615parseTerm ns PrecEq e = parseTerm ns PrecAnn e >>= \t -> option t $ SCstr t <$ operator "~" <*> parseTTerm ns PrecAnn e
1616parseTerm ns PrecAnn e = parseTerm ns PrecOp e >>= \t -> option t $ SAnn t <$> parseType ns Nothing e
1617parseTerm 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
1624parseTerm 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))
1630parseTerm 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
1633parseTerm ns PrecProj e = do
1634 t <- parseTerm ns PrecAtom e
1635 try (mkProjection t <$ char '.' <*> (sepBy1 (sLit . LString <$> lcIdents ns) (char '.'))) <|> pure t
1636parseTerm 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
1654mkSwizzling 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
1670mkProjection term = foldl (\exp field -> SGlobal "project" `SAppV` field `SAppV` exp) term
1671
1672-- Creates: RecordCons @[("x", _), ("y", _), ("z", _)] (1.0, (2.0, (3.0, ())))
1673mkRecord 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
1684sVar e x = maybe (SGlobal x) SVar $ elemIndex' x e
1685
1686mkIf b t f = SGlobal "primIfThenElse" `SAppV` b `SAppV` t `SAppV` f
1687
1688mkDotDot e f = SGlobal "fromTo" `SAppV` e `SAppV` f
1689
1690-- n, m >= 1, n < m
1691manyNM 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
1733generator, letdecl, boolExpression :: Namespace -> DBNames -> P (DBNames, SExp -> SExp)
1734
1735generator 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
1748letdecl 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
1750boolExpression ns dbs = do
1751 pred <- parseTerm ns PrecLam dbs
1752 return (dbs, \e -> application [SGlobal "primIfThenElse", pred, e, SGlobal "Nil"])
1753
1754application = foldl1 SAppV
1755
1756listCompr :: Namespace -> DBNames -> P SExp
1757listCompr 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
1761deBruinify :: DBNames -> SExp -> SExp
1762deBruinify [] e = e
1763deBruinify (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
1769calculatePrecs :: GlobalEnv' -> [SName] -> (SExp, [(SName, SExp)]) -> SExp
1770calculatePrecs _ vs (e, []) = e
1771calculatePrecs 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
1776getFixity :: GlobalEnv' -> SName -> Fixity
1777getFixity (fm, _) n = fromMaybe (Just FDLeft, 9) $ Map.lookup n fm
1778
1779mkGlobalEnv' :: [Stmt] -> GlobalEnv'
1780mkGlobalEnv' 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
1787extractGlobalEnv' :: GlobalEnv -> GlobalEnv'
1788extractGlobalEnv' 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
1805joinGlobalEnv' (fm, cm) (fm', cm') = (Map.union fm fm', Map.union cm cm')
1806
1807calcPrec
1808 :: (Show e)
1809 => (e -> e -> e -> e)
1810 -> (e -> Fixity)
1811 -> e
1812 -> [(e, e)]
1813 -> e
1814calcPrec 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
1835mkPi Hidden (getTTuple -> Just (n, xs)) b | n == length xs = foldr (sNonDepPi Hidden) b xs
1836mkPi h a b = sNonDepPi h a b
1837
1838sNonDepPi h a b = SPi h a $ upS b
1839
1840getTTuple (SAppV (getTTuple -> Just (n, xs)) z) = Just (n, xs ++ [z]{-todo: eff-})
1841getTTuple (SGlobal s@(splitAt 6 -> ("'Tuple", reads -> [(n, "")]))) = Just (n :: Int, [])
1842getTTuple _ = Nothing
1843
1844mkLets :: GlobalEnv' -> [Stmt]{-where block-} -> SExp{-main expression-} -> SExp{-big let with lambdas; replaces global names with de bruijn indices-}
1845mkLets _ [] e = e
1846mkLets 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)
1848mkLets 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
1849mkLets _ (x: ds) e = error $ "mkLets: " ++ show x
1850
1851patLam f ge = patLam_ f ge (Visible, Wildcard SType)
1852
1853patLam_ :: (SExp -> SExp) -> GlobalEnv' -> (Visibility, SExp) -> Pat -> SExp -> SExp
1854patLam_ f ge (v, t) p e = SLam v t $ compileGuardTree f ge $ compilePatts [(p, 0)] Nothing e
1855
1856mkTuple _ [x] = x
1857mkTuple (Just True, _) xs = foldl SAppV (SGlobal $ "'Tuple" ++ show (length xs)) xs
1858mkTuple (Just False, _) xs = foldl SAppV (SGlobal $ "Tuple" ++ show (length xs)) xs
1859mkTuple _ xs = error "mkTuple"
1860
1861mkList (Just True, _) [x] = SGlobal "'List" `SAppV` x
1862mkList (Just False, _) xs = foldr (\x l -> SGlobal "Cons" `SAppV` x `SAppV` l) (SGlobal "Nil") xs
1863mkList _ xs = error "mkList"
1864
1865parseSomeGuards 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
1877findAdt (_, cm) con = case Map.lookup con cm of
1878 Just i -> i
1879 _ -> error $ "findAdt:" ++ con
1880
1881mkNat (Just False, _) n = SGlobal "fromInt" `SAppV` sLit (LInt $ fromIntegral n)
1882mkNat _ n = toNat n
1883
1884toNat 0 = SGlobal "Zero"
1885toNat n = SAppV (SGlobal "Succ") $ toNat (n-1)
1886
1887--------------------------------------------------------------------------------
1888
1889-- parallel patterns like v@(f -> [])@(Just x)
1890newtype ParPat = ParPat [Pat]
1891 deriving Show
1892
1893data Pat
1894 = PVar -- Int
1895 | PCon SName [ParPat]
1896 | ViewPat SExp ParPat
1897 | PatType ParPat SExp
1898 deriving Show
1899
1900data GuardTree
1901 = GuardNode SExp Name [ParPat] GuardTree -- _ <- _
1902 | Alts [GuardTree] -- _ | _
1903 | GuardLeaf SExp -- _ -> e
1904 deriving Show
1905
1906mapGT 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
1911upGT k i = mapGT k $ \k -> upS__ k i
1912
1913substGT 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{-
1915substGT :: Int -> Int -> GuardTree -> GuardTree
1916substGT 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
1922mapPP f = \case
1923 ParPat ps -> ParPat (mapP f <$> ps)
1924
1925mapP :: (SExp -> SExp) -> Pat -> Pat
1926mapP 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
1932upP i j = mapP (upS__ i j)
1933
1934varPP = \case
1935 ParPat ps -> sum $ map varP ps
1936
1937varP = \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
1944alts (Alts xs) = concatMap alts xs
1945alts x = [x]
1946
1947compileGuardTree :: (SExp -> SExp) -> GlobalEnv' -> GuardTree -> SExp
1948compileGuardTree 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
1991varGuardNode v (SVar e) gt = substGT v e gt
1992
1993compileCase 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
1997compilePatts :: [(Pat, Int)] -> Maybe SExp -> SExp -> GuardTree
1998compilePatts 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
2031showExp :: Exp -> String
2032showExp = showDoc . expDoc
2033
2034showSExp :: SExp -> String
2035showSExp = showDoc . sExpDoc
2036
2037showEnv :: Env -> String
2038showEnv e = showDoc $ envDoc e $ pure $ shAtom $ underlined "<<HERE>>"
2039
2040showEnvExp :: Env -> Exp -> String
2041showEnvExp e c = showDoc $ envDoc e $ epar <$> expDoc c
2042
2043showEnvSExp :: Env -> SExp -> String
2044showEnvSExp e c = showDoc $ envDoc e $ epar <$> sExpDoc c
2045
2046showEnvSExpType :: Env -> SExp -> Exp -> String
2047showEnvSExpType 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
2053showDoc :: Doc -> String
2054showDoc = str . flip runReader [] . flip evalStateT (flip (:) <$> iterate ('\'':) "" <*> ['a'..'z'])
2055
2056type Doc_ a = StateT [String] (Reader [String]) a
2057type Doc = Doc_ PrecString
2058
2059envDoc :: Env -> Doc -> Doc
2060envDoc 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
2075expDoc :: Exp -> Doc
2076expDoc 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
2094sExpDoc :: SExp -> Doc
2095sExpDoc = \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
2106shVar i = asks $ shAtom . lookupVarName where
2107 lookupVarName xs | i < length xs && i >= 0 = xs !! i
2108 lookupVarName _ = "V" ++ show i
2109
2110shLet i a b = shVar i >>= \i' -> local (dropNth i) $ shLam' <$> (cpar . shLet' (fmap inBlue i') <$> a) <*> b
2111shLet_ a b = (gets head <* modify tail) >>= \i -> shLam' <$> (cpar . shLet' (shAtom i) <$> a) <*> local (i:) b
2112shLam 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
2128data PS a = PS Prec a deriving (Functor)
2129type PrecString = PS String
2130
2131getPrec (PS p _) = p
2132prec i s = PS i (s i)
2133str (PS _ s) = s
2134
2135data 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
2149lpar, rpar :: PrecString -> Prec -> String
2150lpar (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
2155rpar (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
2162par True s = "(" ++ s ++ ")"
2163par False s = s
2164
2165isAtom = (==PrecAtom) . getPrec
2166isAtom' = (<=PrecAtom') . getPrec
2167
2168shAtom = PS PrecAtom
2169shAtom' = PS PrecAtom'
2170shAnn _ True x y | str y `elem` ["Type", inGreen "Type"] = x
2171shAnn s simp x y | isAtom x && isAtom y = shAtom' $ str x <> s <> str y
2172shAnn s simp x y = prec PrecAnn $ lpar x <> " " <> const s <> " " <> rpar y
2173shApp Hidden x y = prec PrecApp $ lpar x <> " " <> const (str $ brace y)
2174shApp h x y = prec PrecApp $ lpar x <> " " <> rpar y
2175shArr x y | isAtom x && isAtom y = shAtom' $ str x <> "->" <> str y
2176shArr x y = prec PrecArr $ lpar x <> " -> " <> rpar y
2177shCstr x y | isAtom x && isAtom y = shAtom' $ str x <> "~" <> str y
2178shCstr x y = prec PrecEq $ lpar x <> " ~ " <> rpar y
2179shLet' x y | isAtom x && isAtom y = shAtom' $ str x <> ":=" <> str y
2180shLet' x y = prec PrecLet $ lpar x <> " := " <> rpar y
2181shLam' x y | PrecLam <- getPrec y = prec PrecLam $ "\\" <> lpar x <> " " <> pure (dropC $ str y)
2182shLam' x y | isAtom x && isAtom y = shAtom' $ "\\" <> str x <> "->" <> str y
2183shLam' x y = prec PrecLam $ "\\" <> lpar x <> " -> " <> rpar y
2184brace s = shAtom $ "{" <> str s <> "}"
2185cpar s | isAtom' s = s -- TODO: replace with lpar, rpar
2186cpar s = shAtom $ par True $ str s
2187epar s = fmap underlined s
2188
2189dropC (ESC s (dropC -> x)) = ESC s x
2190dropC (x: xs) = xs
2191
2192pattern ESC a b <- (splitESC -> Just (a, b)) where ESC a b | all (/='m') a = "\ESC[" ++ a ++ "m" ++ b
2193
2194splitESC ('\ESC':'[': (span (/='m') -> (a, ~(c: b)))) | c == 'm' = Just (a, b)
2195splitESC _ = Nothing
2196
2197instance IsString (Prec -> String) where fromString = const
2198
2199inGreen = withEsc 32
2200inBlue = withEsc 34
2201inRed = withEsc 31
2202underlined = withEsc 47
2203withEsc i s = ESC (show i) $ s ++ ESC "" ""
2204
2205correctEscs = (++ "\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
2219putStrLn_ = putStrLn . correctEscs
2220error_ = error . correctEscs
2221trace_ = trace . correctEscs
2222throwError_ = throwError . correctEscs
2223traceD x = if debug then trace_ x else id
2224
2225-------------------------------------------------------------------------------- main
2226
2227type TraceLevel = Int
2228trace_level = 0 :: TraceLevel -- 0: no trace
2229tr = False --trace_level >= 2
2230tr_light = trace_level >= 1
2231
2232debug = False--True--tr
2233debug_light = True--False
2234
2235infer :: GlobalEnv -> [Stmt] -> Either String GlobalEnv
2236infer env = fmap (forceGE . snd) . runExcept . flip runStateT (initEnv <> env) . mapM_ handleStmt
2237
2238forceGE x = length (concatMap (uncurry (++) . (showExp *** showExp)) $ Map.elems x) `seq` x
2239
2240fromRight ~(Right x) = x
2241
2242-------------------------------------------------------------------------------- utils
2243
2244dropNth i xs = take i xs ++ drop (i+1) xs
2245iterateN n f e = iterate f e !! n
2246holes 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 @@
1module 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
2Done:
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
42fő 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
146milestone: 1.0 compiler
147
148
149-------------------------------------------------------------------------------- notes
150--------------------------------------------------------------------------------
151
152-------------------------------------------------------------------------------- row polymorphism
153
154builtins
155 Split :: Type -> Type -> Type -> Constraint --Type
156
157
158data RecordC (xs :: List (Pair String Type))
159 = RecordCons (tuptype (map snd xs))
160
161tuptype [] = ()
162tuptype (x: xs) = (x, tuptype xs)
163
164Record :: List (Pair String Type) -> Type
165Record xs = RecordC (sortBy fst xs)
166
167builtins
168 project :: forall (xs :: List [(String, Type)]) . (s :: String) -> (Split (RecordC xs) (RecordC [(s, a)] b) -> RecordC xs -> a
169
170-- project = ...
171
172
173w :: Split a b c
174 iff
175a = Record as
176b = Record bs
177c = Record cs
178
179bs `sublist` as
180cs `sublist` as
181map fst bs `disjunct` map fst cs
182
183
184 :: Record {x: Float}
185
186
187v1 :: Record {x: Float, y: Float, z: Float}
188v1 = {x: 1.0, y: 2.0, z: 3.0} ----> RecordCons @[("x", _), ("y", _), ("z", _)] (1.0, (2.0, (3.0, ())))
189v2 = {x: 1.0, y: 2.0, z: 3.0, a: 4.0}
190
191f :: (Split a (Record {x: Float, y: Float}) b) => a -> Float
192f v = v.x +! v.y
193
194r = f v1 +! f v2 -- this is valid
195
196
197 exp.field -----> project field exp
198
199f 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 @@
1module Type ( module CGExp ) where
2import 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 @@
1module 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
3CABAL_NAME=lambdacube-compiler
4
5HPC_DIR=dist/hpc/${CABAL_NAME}
6HPC_REPO_DIR=$HPC_DIR
7
8TEST_DIR=src/UnitTest
9TIX=lambdacube-compiler-test-suite.tix
10
11hpc report ${TIX} --hpcdir=${HPC_DIR} --xml-output > ${HPC_REPO_DIR}/result.xml
12hpc 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
4name: lambdacube-compiler
5version: 0.2.0.0
6homepage: lambdacube3d.com
7license: BSD3
8license-file: LICENSE
9author: Csaba Hruska, Peter Divianszky
10maintainer: csaba.hruska@gmail.com
11category: Graphics
12build-type: Simple
13cabal-version: >=1.10
14
15Flag profiling
16 Description: Enable profiling
17 Default: False
18
19library
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
74executable 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
3if [ "$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
16else
17 cabal run lambdacube-compiler-test-suite -- $@
18 ./create-test-report.sh
19 rm lambdacube-compiler-test-suite.tix
20fi
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
4builtins
5 cstr :: Type -> Type -> Type
6-- reflCstr :: forall (a :: Type) -> cstr a a
7 T2 :: Type -> Type -> Type
8 T2C :: Unit -> Unit -> Unit
9
10data Unit = TT
11
12-- TODO: generate?
13data Tuple0 = Tuple0
14data Tuple1 a = Tuple1 a
15data Tuple2 a b = Tuple2 a b
16data Tuple3 a b c = Tuple3 a b c
17data Tuple4 a b c d = Tuple4 a b c d
18data Tuple5 a b c d e = Tuple5 a b c d e
19
20id x = x
21
22data Bool = False | True
23
24data Ordering = LT | EQ | GT
25
26primIfThenElse :: Bool -> a -> a -> a
27primIfThenElse True a b = a
28primIfThenElse False a b = b
29
30---------------------------------------
31
32data Nat = Zero | Succ Nat
33
34builtintycons
35 Int :: Type
36 Word :: Type
37 Float :: Type
38 Char :: Type
39 String :: Type
40
41{-
42type family TFVec (n :: Nat) a -- may be a data family
43type family VecScalar (n :: Nat) a
44type family TFMat i j -- may be a data family
45type family MatVecElem a
46type family MatVecScalarElem a
47type family FTRepr' a
48type family ColorRepr a
49type family TFFrameBuffer a
50type family FragOps a
51type family JoinTupleType t1 t2
52class AttributeTuple a
53class ValidOutput a
54class ValidFrameBuffer a
55-}
56builtins
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
72data 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
77builtins
78 Vec :: Nat -> Type -> Type
79--Vec n t = VecS t n
80
81
82data 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
94builtins
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
109data Swizz = Sx | Sy | Sz | Sw
110
111builtins
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
118class CNum a
119
120instance CNum Int
121instance CNum Float
122
123class Signed a
124
125instance Signed Int
126instance Signed Float
127
128class Num a where
129 fromInt :: Int -> a
130 compare :: a -> a -> Ordering
131 negate :: a -> a
132-}
133builtins
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{-
144instance Num Int where
145 fromInt = id
146 compare = primCompareInt
147 negate = primNegateInt
148instance Num Word where
149 fromInt = primIntToWord
150 compare = primCompareWord
151 negate = primNegateWord
152instance Num Float where
153 fromInt = primIntToFloat
154 compare = primCompareFloat
155 negate = primNegateFloat
156
157class 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
166instance Component Bool where
167 vec2 = V2
168 vec3 = V3
169 vec4 = V4
170 zeroComp = False
171 oneComp = True
172
173instance Component Int where
174 vec2 = V2
175 vec3 = V3
176 vec4 = V4
177 zeroComp = 0
178 oneComp = 1
179
180instance Component Word where
181 vec2 = V2
182 vec3 = V3
183 vec4 = V4
184 zeroComp = 0
185 oneComp = 1
186
187instance Component Float where
188 vec2 = V2
189 vec3 = V3
190 vec4 = V4
191 zeroComp = 0
192 oneComp = 1
193
194instance 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
200instance 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
206instance 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
216instance 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
223class Integral a
224
225instance Integral Int
226instance Integral Word
227
228class NumComponent a
229
230instance NumComponent Int
231instance NumComponent Word
232instance NumComponent Float
233instance NumComponent (Vec 2 Float)
234instance NumComponent (Vec 3 Float)
235instance NumComponent (Vec 4 Float)
236
237class Floating a
238
239instance Floating Float
240instance Floating (Vec 2 Float)
241instance Floating (Vec 3 Float)
242instance Floating (Vec 4 Float)
243instance Floating (Mat 2 2 Float)
244instance Floating (Mat 2 3 Float)
245instance Floating (Mat 2 4 Float)
246instance Floating (Mat 3 2 Float)
247instance Floating (Mat 3 3 Float)
248instance Floating (Mat 3 4 Float)
249instance Floating (Mat 4 2 Float)
250instance Floating (Mat 4 3 Float)
251instance Floating (Mat 4 4 Float)
252-}
253
254data 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
271data BlendEquation
272 = FuncAdd
273 | FuncSubtract
274 | FuncReverseSubtract
275 | Min
276 | Max
277
278data 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
296data StencilOperation
297 = OpZero
298 | OpKeep
299 | OpReplace
300 | OpIncr
301 | OpIncrWrap
302 | OpDecr
303 | OpDecrWrap
304 | OpInvert
305
306data ComparisonFunction
307 = Never
308 | Less
309 | Equal
310 | Lequal
311 | Greater
312 | Notequal
313 | Gequal
314 | Always
315
316data ProvokingVertex
317 = LastVertex
318 | FirstVertex
319
320data FrontFace
321 = CW
322 | CCW
323
324data CullMode
325 = CullFront FrontFace
326 | CullBack FrontFace
327 | CullNone
328
329data PointSize
330 = PointSize Float
331 | ProgramPointSize
332
333data PolygonMode
334 = PolygonFill
335 | PolygonPoint PointSize
336 | PolygonLine Float
337
338data PolygonOffset
339 = NoOffset
340 | Offset Float Float
341
342data PointSpriteCoordOrigin
343 = LowerLeft
344 | UpperLeft
345
346
347data Depth a where
348data Stencil a where
349data Color a where
350
351data PrimitiveType
352 = Triangle
353 | Line
354 | Point
355 | TriangleAdjacency
356 | LineAdjacency
357
358builtincons
359 PrimTexture :: () -> Vec 2 Float -> Vec 4 Float
360
361builtincons
362 Uniform :: String -> t
363 Attribute :: String -> t
364
365data 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
372data VertexOut a where
373 VertexOut :: (a ~ FTRepr' x) => Vec 4 Float -> Float -> (){-TODO-} -> x -> VertexOut a
374
375data 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
380data 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
387data AccumulationContext a where
388 AccumulationContext :: (a ~ FragOps t) => t -> AccumulationContext a
389
390data 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
396data Interpolated t where
397 Smooth, NoPerspective
398 :: (Floating t) => t -> Interpolated t
399 Flat :: t -> Interpolated t
400
401data 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
414data 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
420data FragmentFilter t where
421 PassAll :: FragmentFilter t
422 Filter :: (t -> Bool) -> FragmentFilter t
423
424data 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
428data PrimitiveStream (p :: PrimitiveType) :: Nat -> Type -> Type where
429 Transform :: (a -> VertexOut b) -> VertexStream p a -> PrimitiveStream p 1 b
430
431 -- Render Operations
432data FragmentStream (n :: Nat) a where
433 Rasterize :: RasterContext x -> PrimitiveStream x n a -> FragmentStream n a
434
435data 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
448data Output where
449 ScreenOut :: FrameBuffer a b -> Output
450
451builtins
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
543builtincons
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
547data 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
555data Filter
556 = PointFilter
557 | LinearFilter
558
559data EdgeMode
560 = Repeat
561 | MirroredRepeat
562 | ClampToEdge
563
564data Sampler = Sampler Filter EdgeMode Texture
565
566builtincons
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
5builtintycons
6 Int :: Type
7
8data Unit = TT
9
10builtins
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
16tyType (a :: Type) = a
17id a = a
18const x y = x
19const' :: forall a b . a -> b -> a
20const' x y = x
21const'' :: forall b a . a -> b -> a
22const'' x y = x
23id' a = id a
24id'' = id id
25app f x = f x
26comp f g x = f (g x)
27app2 f x y = f x y
28flip f x y = f y x
29scomb a b c = a c (b c)
30
31builtins fix :: forall a . (a -> a) -> a
32builtins f_i_x :: forall a . (a -> a) -> a
33
34data Sigma a (b :: a -> Type) = Pair (x :: a) (b x)
35
36-- undefined = undefined
37builtins
38 undefined :: forall (a :: Type) . a
39
40data Empty
41--data T2 a b = T2C a b
42builtins
43 T2 :: Type -> Type -> Type
44 T2C :: Unit -> Unit -> Unit
45
46-- identity function, used for type annotations internally
47typeAnn = \(A :: Type) (a :: A) -> a
48
49data Bool = False | True
50
51otherwise = True
52
53if' b t f = case b of True -> t
54 False -> f
55
56-- higher-order unification test
57htest b = if' b id
58htest' b = if' b id :: (forall a . a -> a) -> _
59htest'' b = if' b id :: _ -> (forall a . a -> a)
60
61data List a = Nil' | Cons' a (List a)
62
63builtins
64 primAdd, primSub, primMod
65 :: Int -> Int -> Int
66 primSqrt :: Int -> Int
67 primIntEq, primIntLess
68 :: Int -> Int -> Bool
69
70dcomp
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)
78dcomp'
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)
86dcomp''
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)
95dcomp'' f g x = f (g x)
96
97listMap f xs =
98 | Nil' <- xs -> Nil'
99 | Cons' x xs <- xs -> Cons' (f x) (listMap f xs)
100foldr c n xs = case xs of
101 Nil' -> n
102 Cons' x xs -> c x (foldr c n xs)
103
104concat xs ys = foldr Cons' ys xs
105
106from n = Cons' n (from (primAdd #1 n))
107head x = case x of
108 Nil' -> undefined
109 Cons' x _ -> x
110tail = listCase (\_ -> _) undefined (\_ xs -> xs)
111nth n xs =
112 | primIntEq #0 n -> head xs
113 | otherwise -> nth (primSub n #1) (tail xs)
114filter p xs =
115 | Nil' <- xs -> Nil'
116 | Cons' x xs <- xs ->
117 | p x -> Cons' x (filter p xs)
118 | otherwise -> filter p xs
119takeWhile p xs =
120 | Nil' <- xs -> Nil'
121 | Cons' x xs <- xs ->
122 | p x -> Cons' x (takeWhile p xs)
123 | otherwise -> Nil'
124and' a b = boolCase (\_ -> _) False b a
125or' a b = boolCase (\_ -> _) b True a
126not' = boolCase (\_ -> _) True False
127all p = listCase (\_ -> _) True (\x xs -> and' (p x) (all p xs))
128intLEq n m = or' (primIntLess n m) (primIntEq n m)
129{- todo
130primes =
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
135nthPrimes n = nth n primes
136main = nthPrimes #10
137-}
138data Nat = Zero | Succ Nat
139data Fin :: Nat -> Type where
140 FZero :: Fin (Succ n)
141 FSucc :: Fin n -> Fin (Succ n)
142data Vec a :: Nat -> Type where
143 Nil :: Vec a Zero
144 Cons :: a -> Vec a n -> Vec a (Succ n)
145data Eq @a :: a -> a -> Type where
146 Refl :: Eq x x
147
148wrong
149 x = 1 1
150
151vec = Vec _
152
153builtins
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
158builtins
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
166plus =
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
173pred =
174 natElim
175 (\_ -> _)
176 Zero
177 (\n' _ -> n')
178
179-- a simpler elimination scheme for natural numbers
180natFold =
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
188nat1Elim = \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
193nat2Elim = \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
197inc = natFold (Succ Zero) Succ
198
199-- embed Fin into Nat
200finNat = finElim (\_ _ -> Nat)
201 Zero
202 (\_ rec -> Succ rec)
203
204-- unit type
205Unit' = Fin 1
206-- constructor
207U = FZero :: Unit'
208-- eliminator
209
210unitElim = \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
230Void = Fin 0
231-- eliminator
232voidElim m = finElim (natElim (\n -> Fin n -> Type)
233 (\x -> m x)
234 (\_ _ _ -> _))
235 U
236 (\_ _ -> U)
237 0
238
239-- type of booleans
240Bool' = Fin 2
241-- constructors
242False' = FZero :: Bool'
243True' = FSucc FZero :: Bool'
244-- eliminator
245
246boolElim = \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
282not = boolElim (\_ -> _) True' False'
283and = boolElim (\_ -> _) (const False') id
284or = boolElim (\_ -> _) id (const True')
285iff = boolElim (\_ -> _) not id
286xor = boolElim (\_ -> _) id not
287
288-- even, odd, isZero, isSucc
289even = natFold True' not
290odd = natFold False' not
291isZero = natFold True' (const False')
292isSucc = natFold False' (const True')
293
294-- equality on natural numbers
295natEq =
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"
308Prop = boolElim (\_ -> _) Void Unit'
309
310-- reflexivity of equality on natural numbers
311pNatEqRefl =
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
319Not 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)
322leibniz f x y = eqCase
323 (\x y _ -> Eq (f x) (f y))
324 Refl @x @y
325
326-- symmetry of (general) equality
327symm x y = eqCase (\x y _ -> Eq y x) Refl @x @y
328
329-- transitivity of (general) equality
330tran 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
336apply = eqCase (\a b _ -> a -> b) id
337
338p1IsNot0 p = apply
339 (leibniz
340 (natElim (\_ -> _) Void (\_ _ -> Unit'))
341 1 0 p)
342 U
343
344-- proof that 0 is not 1
345p0IsNot1 p = p1IsNot0 (symm 0 1 p)
346
347-- proof that zero is not a successor
348p0IsNoSucc =
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
357replicate =
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
364replicate' =
365 natElim
366 (\n -> _ -> vec n)
367 (\_ -> Nil)
368 (\n' rec_n' x -> Cons x (rec_n' x))
369
370replicate'' 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
373fromto = natElim vec Nil (\n' rec_n' -> Cons n' rec_n')
374
375builtins
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
383append = 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
389tail' 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
400tailVec = \n v -> tail' _ (Succ n) v n Refl
401
402-- projection out of a vector
403at =
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
422headVec n v = at (Succ n) v FZero
423
424-- vector map
425map 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:
429p0PlusNisN = Refl :: forall n . Eq (plus 0 n) n
430
431-- the other direction requires induction on N:
432pNPlus0isN =
433 natElim (\n -> Eq (plus n 0) n)
434 Refl
435 (\n' rec -> leibniz Succ (plus n' 0) n' rec)
436
437testNoNorm = Refl :: Eq (primIntEq #3 #3) True
438
439True'' = FSucc FZero :: Bool'
440
441
442data EqD a = EqDC (a -> a -> Bool)
443
444eqInt = EqDC primIntEq
445
446builtins
447 matchInt :: Type -> (Type -> Type) -> Type -> Type
448 matchList :: (Type -> Type) -> (Type -> Type) -> Type -> Type
449
450Eq_ :: Type -> Type
451Eq_ a = matchInt Unit (matchList Eq_ (\_ -> Empty)) a
452
453builtins eqD :: Eq_ a => EqD a
454
455eq = eqDCase (\_ -> _) id eqD
456
457eq' = eqDCase (\_ -> _) id
458
459eqList = EqDC (\as bs -> listCase (\_ -> _) (listCase (\_ -> _) True (\_ _ -> False) bs) (\a as -> listCase (\_ -> _) False (\b bs -> and' (eq a b) (eq as bs)) bs) as)
460
461main_ = eq' eqList (Cons' #3 Nil') Nil'
462main'' = eq (Cons' #3 Nil') Nil'
463
464data MonadD (m :: Type -> Type) = MonadDC (forall a . a -> m a) (forall a b . m a -> (a -> m b) -> m b)
465
466data Identity a = IdentityC a
467
468identityMonad = MonadDC IdentityC (\m f -> identityCase (\_ -> _) f m)
469
470Char = Int
471
472data IO a where
473 IORet :: a -> IO a
474 PutChar :: Char -> IO a -> IO a
475 GetChar :: (Char -> IO a) -> IO a
476
477data ReaderT r (m :: Type -> Type) a = ReaderTC (r -> m a)
478
479-----------------------------
480
481builtins
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
485builtins
486 Monad :: (Type -> Type) -> Type
487--let Monad = fix (\Monad -> ifIdentity1 Unit (ifReaderT1 (\r m -> Monad m) (\_ -> Empty)))
488
489----------------- recursive definition
490builtins monadD :: forall m . Monad m => MonadD m
491-- let monadD = fix (\monadD @t -> ifIdentity_1 identityMonad (ifReaderT_1 (\r m -> monadReaderT) undefined t))
492
493return = monadDCase (\_ -> _) (\r _ -> r) monadD
494bind = monadDCase (\_ -> _) (\_ b -> b) monadD
495
496monadReaderT = 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
505IOBind 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
510monadIO = MonadDC IORet IOBind
511-------------------------- end of recursive definition
512
513liftReaderT m = ReaderTC (\r -> m)
514
515bind' m m' = bind m (const m')
516fmap f m = bind m (comp return f)
517
518sequence = listCase (\_ -> _) (return Nil') (\x xs -> bind x (\vx -> fmap (Cons' vx) (sequence xs)))
519sequence_ = listCase (\_ -> _) (return TT) (\x xs -> bind' x (sequence_ xs))
520
521mapM f = comp sequence (listMap f)
522mapM_ f = comp sequence_ (listMap f)
523
524putChar i = PutChar i (return TT)
525getChar = GetChar return
526
527putStr = mapM_ putChar
528putStrLn = 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
533mex = return #3 :: IO Int
534mex' = return #3 :: ReaderT Bool IO Int
535
536-- todo -- main' = bind getLine putStrLn
537
538
539data 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
544expCase' :: 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
551expCase' m i a c x e = expCase m i a c @x e
552
553expCase'' :: 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
560expCase'' m i a c @x e = expCase' m i a c x e
561
562-- todo -- eval :: forall a . Exp a -> a
563eval = 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 #-}
2module Prelude
3 ( module Prelude
4 , module Builtins
5 ) where
6
7import Builtins
8
9infixr 9 .
10infixl 7 `PrimMulMatVec`, `PrimDot`
11infixr 3 ***
12infixr 5 :
13infixr 0 $
14--infixl 0 &
15
16const x y = x
17
18otherwise = True
19
20--undefined = undefined
21
22builtins
23 undefined :: forall (a :: Type) . a
24
25x & f = f x
26
27($) = \f x -> f x
28(.) = \f g x -> f (g x)
29
30uncurry f (x, y) = f x y
31
32(***) f g (x, y) = (f x, g y)
33
34data List a = Nil | Cons a (List a)
35
36pi = 3.14
37
38zip :: [a] -> [b] -> [(a,b)]
39zip [] xs = []
40zip xs [] = []
41zip (a: as) (b: bs) = (a,b): zip as bs
42
43unzip :: [(a,b)] -> ([a],[b])
44unzip [] = ([],[])
45unzip ((a,b):xs) = (a:as,b:bs)
46 where (as,bs) = unzip xs
47
48filter pred [] = []
49filter pred (x:xs) = case pred x of
50 True -> (x : filter pred xs)
51 False -> (filter pred xs)
52
53tail :: [a] -> [a]
54tail (_: xs) = xs
55
56pairs :: [a] -> [(a, a)]
57pairs v = zip v (tail v)
58
59foldl' f e [] = e
60foldl' f e (x: xs) = foldl' f (f e x) xs
61
62singleton a = [a]
63
64append [] ys = ys
65append (x:xs) ys = x : append xs ys
66
67concat = foldl' append []
68
69map _ [] = []
70map f (x:xs) = f x : map f xs
71
72concatMap :: (a -> [b]) -> [a] -> [b]
73concatMap f x = concat (map f x)
74
75split [] = ([], [])
76split (x: xs) = (x: bs, as) where (as, bs) = split xs
77
78mergeBy 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
81mergeBy f [] xs = xs
82mergeBy f xs [] = xs
83
84sortBy f [] = []
85sortBy f [x] = [x]
86sortBy f xs = uncurry (mergeBy f) ((sortBy f *** sortBy f) (split xs))
87
88data Maybe a
89 = Nothing
90 | Just a
91-- deriving (Eq, Ord, Show)
92
93
94snd (Tuple2 a b) = b
95
96-- Row polymorphism
97builtins
98 Split :: Type -> Type -> Type -> Type {- TODO - LATER: Constraint -}
99
100tuptype :: List Type -> Type
101tuptype [] = 'Tuple0
102tuptype (x:xs) = 'Tuple2 x (tuptype xs)
103
104data RecordC (xs :: List (Tuple2 String Type))
105 = RecordCons (tuptype (map snd xs))
106
107builtins
108 record :: List (Tuple2 String Type) -> Type
109--record xs = RecordCons ({- TODO: sortBy fst-} xs)
110
111builtins
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
117rgb r g b = V4 r g b 1.0
118
119black = rgb 0.0 0.0 0.0
120gray = rgb 0.5 0.5 0.5
121silver = rgb 0.75 0.75 0.75
122white = rgb 1.0 1.0 1.0
123maroon = rgb 0.5 0.0 0.0
124red = rgb 1.0 0.0 0.0
125olive = rgb 0.5 0.5 0.0
126yellow = rgb 1.0 1.0 0.0
127green = rgb 0.0 0.5 0.0
128lime = rgb 0.0 1.0 0.0
129teal = rgb 0.0 0.5 0.5
130aqua = rgb 0.0 1.0 1.0
131navy = rgb 0.0 0.0 0.5
132blue = rgb 0.0 0.0 1.0
133purple = rgb 0.5 0.0 0.5
134fuchsia = rgb 1.0 0.0 1.0
135
136colorImage1 = ColorImage @1
137colorImage2 = ColorImage @2
138
139depthImage1 = DepthImage @1
140
141v3FToV4F :: Vec 3 Float -> Vec 4 Float
142v3FToV4F 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
149radians = PrimRadians
150degrees = PrimDegrees
151sin = PrimSin
152cos = PrimCos
153tan = PrimTan
154asin = PrimASin
155acos = PrimACos
156atan = PrimATan
157atan2 = PrimATan2
158
159-- exponential functions
160pow = PrimPow
161exp = PrimExp
162log = PrimLog
163exp2 = PrimExp2
164log2 = PrimLog2
165sqrt = PrimSqrt
166inversesqrt = PrimInvSqrt
167
168-- common functions
169abs = PrimAbs
170sign = PrimSign
171floor = PrimFloor
172ceil = PrimCeil
173fract = PrimFract
174mod = PrimMod
175min = PrimMin
176max = PrimMax
177clamp = PrimClamp
178clampS = PrimClampS
179mix = PrimMix
180step = PrimStep
181smoothstep = PrimSmoothStep
182
183-- geometric functions
184length = PrimLength
185distance = PrimDistance
186dot = PrimDot
187cross = PrimCross
188normalize = PrimNormalize
189faceforward = PrimFaceForward
190reflect = PrimReflect
191refract = PrimRefract
192
193-- operators
194infixl 7 *, /, %
195infixl 6 +, -
196infix 4 ==, /=, <, <=, >=, >
197
198infixr 3 &&
199infixr 2 ||
200
201infix 7 `dot` -- dot
202infix 7 `cross` -- cross
203
204infixr 7 *. -- mulmv
205infixl 7 .* -- mulvm
206infixl 7 .*. -- mulmm
207
208-- arithemtic
209a + b = PrimAdd a b
210a - b = PrimSub a b
211a * b = PrimMul a b
212a / b = PrimDiv a b
213a % b = PrimMod a b
214
215neg a = PrimNeg a
216
217-- comparison
218a == b = PrimEqual a b
219a /= b = PrimNotEqual a b
220a < b = PrimLessThan a b
221a <= b = PrimLessThanEqual a b
222a >= b = PrimGreaterThanEqual a b
223a > b = PrimGreaterThan a b
224
225-- logical
226a && b = PrimAnd a b
227a || b = PrimOr a b
228not a = PrimNot a
229any a = PrimAny a
230all a = PrimAll a
231
232-- matrix functions
233a .*. b = PrimMulMatMat a b
234a *. b = PrimMulMatVec a b
235a .* b = PrimMulVecMat a b
236
237dFdx = PrimDFdx
238dFdy = PrimDFdy
239
240-- extra
241round = PrimRound
242
243
244-- temp hack for vector <---> scalar operators
245infixl 7 *!, /!, %!
246infixl 6 +!, -!
247
248-- arithemtic
249a +! b = PrimAddS a b
250a -! b = PrimSubS a b
251a *! b = PrimMulS a b
252a /! b = PrimDivS a b
253a %! b = PrimModS a b
254
255------------------
256-- common matrices
257------------------
258{-
259-- | Perspective transformation matrix in row major order.
260perspective :: 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
265perspective 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-}
276rotMatrixZ 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
281rotMatrixY 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
286rotMatrixX 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
291rotationEuler a b c = rotMatrixY a .*. rotMatrixX b .*. rotMatrixZ c
292
293{-
294-- | Camera transformation matrix.
295lookat :: Vec 3 Float -- ^ Camera position.
296 -> Vec 3 Float -- ^ Target position.
297 -> Vec 3 Float -- ^ Upward direction.
298 -> M44F
299lookat 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
307scale t v = v * V4 t t t 1.0
308
309fromTo :: Float -> Float -> [Float]
310fromTo 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 @@
1data Data0 = Data0
2
3data Data1 a b c = Data1 a b c
4
5data Data2 = Data21 Int
6 | Data22 { x :: Int, y::Int }
7 | Data23 { x :: Int }
8 | Data24 { }
9
10data Data5 a5 b5 c5 = Data51 { a5::a5}
11 | Data52 { a5::a5, b5::b5, c5::c5 }
12 | Data53 Int a5 Float b5 c5
13
14{-
15f (Data41 {}) = 5
16f (Data42 {c4=c}) = c
17f 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
3data 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 @@
1data 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
3data Empty2 =