diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-02-10 23:48:44 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-02-10 23:48:44 +0100 |
commit | deb0c0a1561c9d710dc2a392a0cd8516e819b98e (patch) | |
tree | 9c7250c4b6a31f66fb8e979fffcb1ed8afd1b3b3 | |
parent | 711bc2ba919b09f6567869b873509817ead328bd (diff) |
simplification
-rw-r--r-- | src/LambdaCube/Compiler/CoreToIR.hs | 246 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Infer.hs | 8 |
2 files changed, 118 insertions, 136 deletions
diff --git a/src/LambdaCube/Compiler/CoreToIR.hs b/src/LambdaCube/Compiler/CoreToIR.hs index 51ded9a4..59926eba 100644 --- a/src/LambdaCube/Compiler/CoreToIR.hs +++ b/src/LambdaCube/Compiler/CoreToIR.hs | |||
@@ -38,8 +38,6 @@ import LambdaCube.Compiler.Parser (up, Up (..)) | |||
38 | import Data.Version | 38 | import Data.Version |
39 | import Paths_lambdacube_compiler (version) | 39 | import Paths_lambdacube_compiler (version) |
40 | 40 | ||
41 | (<&>) = flip (<$>) | ||
42 | |||
43 | -------------------------------------------------------------------------- | 41 | -------------------------------------------------------------------------- |
44 | 42 | ||
45 | type CG = State IR.Pipeline | 43 | type CG = State IR.Pipeline |
@@ -117,7 +115,7 @@ mergeSlot a b = a | |||
117 | } | 115 | } |
118 | 116 | ||
119 | getSlot :: ExpTV -> CG (IR.Command,[(String,IR.InputType)]) | 117 | getSlot :: ExpTV -> CG (IR.Command,[(String,IR.InputType)]) |
120 | getSlot e@(Prim2 "fetch_" (EString slotName) attrs) = do | 118 | getSlot e@(A2 "fetch_" (EString slotName) attrs) = do |
121 | let input = compAttribute attrs | 119 | let input = compAttribute attrs |
122 | slot = IR.Slot | 120 | slot = IR.Slot |
123 | { IR.slotName = slotName | 121 | { IR.slotName = slotName |
@@ -134,7 +132,7 @@ getSlot e@(Prim2 "fetch_" (EString slotName) attrs) = do | |||
134 | Just i -> do | 132 | Just i -> do |
135 | modify (\s -> s {IR.slots = update i (mergeSlot (sv ! i) slot) sv}) | 133 | modify (\s -> s {IR.slots = update i (mergeSlot (sv ! i) slot) sv}) |
136 | return (IR.RenderSlot i,input) | 134 | return (IR.RenderSlot i,input) |
137 | getSlot e@(Prim1 "fetchArrays_" attrs) = do | 135 | getSlot e@(A1 "fetchArrays_" attrs) = do |
138 | let (input,values) = unzip [((name,ty),(name,value)) | (i,(ty,value)) <- zip [0..] (compAttributeValue attrs), let name = "attribute_" ++ show i] | 136 | let (input,values) = unzip [((name,ty),(name,value)) | (i,(ty,value)) <- zip [0..] (compAttributeValue attrs), let name = "attribute_" ++ show i] |
139 | stream = IR.StreamData | 137 | stream = IR.StreamData |
140 | { IR.streamData = Map.fromList values | 138 | { IR.streamData = Map.fromList values |
@@ -173,16 +171,16 @@ addProgramToSlot prgName (IR.RenderStream streamName) = do | |||
173 | } | 171 | } |
174 | modify (\s -> s {IR.streams = update streamName stream' sv}) | 172 | modify (\s -> s {IR.streams = update streamName stream' sv}) |
175 | 173 | ||
176 | getFragFilter (Prim2 "map" (EtaPrim2 "filterFragment" p) x) = (Just p, x) | 174 | getFragFilter (A2 "map" (EtaPrim2 "filterFragment" p) x) = (Just p, x) |
177 | getFragFilter x = (Nothing, x) | 175 | getFragFilter x = (Nothing, x) |
178 | 176 | ||
179 | getVertexShader (Prim2 "map" (EtaPrim2 "mapPrimitive" f@(etaRed -> Just (_, o))) x) = ((Just f, tyOf o), x) | 177 | getVertexShader (A2 "map" (EtaPrim2 "mapPrimitive" f@(etaRed -> Just (_, o))) x) = ((Just f, tyOf o), x) |
180 | getVertexShader x = ((Nothing, getPrim' $ tyOf x), x) | 178 | getVertexShader x = ((Nothing, getPrim' $ tyOf x), x) |
181 | 179 | ||
182 | getFragmentShader (Prim2 "map" (EtaPrim2 "mapFragment" f@(etaRed -> Just (_, frago))) x) = ((Just f, tyOf frago), x) | 180 | getFragmentShader (A2 "map" (EtaPrim2 "mapFragment" f@(etaRed -> Just (_, frago))) x) = ((Just f, tyOf frago), x) |
183 | getFragmentShader x = ((Nothing, getPrim'' $ tyOf x), x) | 181 | getFragmentShader x = ((Nothing, getPrim'' $ tyOf x), x) |
184 | 182 | ||
185 | removeDepthHandler (Prim2 "map" (EtaPrim1 "noDepth") x) = x | 183 | removeDepthHandler (A2 "map" (EtaPrim1 "noDepth") x) = x |
186 | removeDepthHandler x = x | 184 | removeDepthHandler x = x |
187 | 185 | ||
188 | getCommands :: ExpTV -> CG ([IR.Command],[IR.Command]) | 186 | getCommands :: ExpTV -> CG ([IR.Command],[IR.Command]) |
@@ -193,7 +191,7 @@ getCommands e = case e of | |||
193 | (subCmds,cmds) <- getCommands a | 191 | (subCmds,cmds) <- getCommands a |
194 | return (subCmds,IR.SetRenderTarget rt : cmds) | 192 | return (subCmds,IR.SetRenderTarget rt : cmds) |
195 | 193 | ||
196 | Prim3 "Accumulate" actx (getFragmentShader . removeDepthHandler -> (frag, getFragFilter -> (ffilter, Prim3 "foldr" (Prim0 "++") (A0 "Nil") (Prim2 "map" (EtaPrim3 "rasterizePrimitive" ints rctx) (getVertexShader -> (vert, input)))))) fbuf -> do | 194 | A3 "Accumulate" actx (getFragmentShader . removeDepthHandler -> (frag, getFragFilter -> (ffilter, A3 "foldr" (A0 "++") (A0 "Nil") (A2 "map" (EtaPrim3 "rasterizePrimitive" ints rctx) (getVertexShader -> (vert, input)))))) fbuf -> do |
197 | 195 | ||
198 | backend <- gets IR.backend | 196 | backend <- gets IR.backend |
199 | let (vertexInput, pUniforms, vertSrc, fragSrc) = genGLSLs backend (compRC' rctx) ints vert frag ffilter | 197 | let (vertexInput, pUniforms, vertSrc, fragSrc) = genGLSLs backend (compRC' rctx) ints vert frag ffilter |
@@ -231,7 +229,7 @@ getCommands e = case e of | |||
231 | ] | 229 | ] |
232 | return (subFbufCmds <> txtCmds, fbufCommands <> cmds) | 230 | return (subFbufCmds <> txtCmds, fbufCommands <> cmds) |
233 | 231 | ||
234 | Prim1 "FrameBuffer" a -> return ([],[IR.ClearRenderTarget (Vector.fromList $ map (uncurry IR.ClearImage) $ compFrameBuffer a)]) | 232 | A1 "FrameBuffer" a -> return ([],[IR.ClearRenderTarget (Vector.fromList $ map (uncurry IR.ClearImage) $ compFrameBuffer a)]) |
235 | 233 | ||
236 | x -> error $ "getCommands " ++ ppShow x | 234 | x -> error $ "getCommands " ++ ppShow x |
237 | 235 | ||
@@ -248,13 +246,13 @@ getRenderTextureCommands l = mconcat <$> mapM f l | |||
248 | return ([(n,IR.TextureImage texture 0 Nothing)], subCmds <> (IR.SetRenderTarget rt:cmds)) | 246 | return ([(n,IR.TextureImage texture 0 Nothing)], subCmds <> (IR.SetRenderTarget rt:cmds)) |
249 | f _ = return mempty | 247 | f _ = return mempty |
250 | 248 | ||
251 | getTextureFun (Prim1 "PrjImageColor" a) = (,) a $ \[_, x] -> x | 249 | getTextureFun (A1 "PrjImageColor" a) = (,) a $ \[_, x] -> x |
252 | getTextureFun (Prim1 "PrjImage" a) = (,) a $ \[x] -> x | 250 | getTextureFun (A1 "PrjImage" a) = (,) a $ \[x] -> x |
253 | 251 | ||
254 | compFrameBuffer x = case x of | 252 | compFrameBuffer x = case x of |
255 | ETuple a -> concatMap compFrameBuffer a | 253 | ETuple a -> concatMap compFrameBuffer a |
256 | Prim1 "DepthImage" a -> [(IR.Depth, compValue a)] | 254 | A1 "DepthImage" a -> [(IR.Depth, compValue a)] |
257 | Prim1 "ColorImage" a -> [(IR.Color, compValue a)] | 255 | A1 "ColorImage" a -> [(IR.Color, compValue a)] |
258 | x -> error $ "compFrameBuffer " ++ ppShow x | 256 | x -> error $ "compFrameBuffer " ++ ppShow x |
259 | 257 | ||
260 | compSemantics x = case x of | 258 | compSemantics x = case x of |
@@ -372,9 +370,23 @@ compInputType x = case x of | |||
372 | TMat 4 4 TFloat -> IR.M44F | 370 | TMat 4 4 TFloat -> IR.M44F |
373 | x -> error $ "compInputType " ++ ppShow x | 371 | x -> error $ "compInputType " ++ ppShow x |
374 | 372 | ||
373 | -- todo: remove | ||
374 | toGLSLType msg = \case | ||
375 | TBool -> "bool" | ||
376 | TWord -> "uint" | ||
377 | TInt -> "int" | ||
378 | TFloat -> "float" | ||
379 | TTuple [] -> "void" | ||
380 | x@(TVec n t) | Just s <- vecConName x -> s | ||
381 | TMat i j TFloat | is234 i && is234 j -> "mat" ++ if i == j then show i else show i ++ "x" ++ show j | ||
382 | t -> error $ "toGLSLType: " ++ msg ++ " " ++ ppShow t | ||
383 | |||
384 | is234 = (`elem` [2,3,4]) | ||
385 | |||
386 | |||
375 | compAttribute x = case x of | 387 | compAttribute x = case x of |
376 | ETuple a -> concatMap compAttribute a | 388 | ETuple a -> concatMap compAttribute a |
377 | Prim1 "Attribute" (EString s) -> [(s, compInputType $ tyOf x)] | 389 | A1 "Attribute" (EString s) -> [(s, compInputType $ tyOf x)] |
378 | x -> error $ "compAttribute " ++ ppShow x | 390 | x -> error $ "compAttribute " ++ ppShow x |
379 | 391 | ||
380 | compList (A2 "Cons" a x) = compValue a : compList x | 392 | compList (A2 "Cons" a x) = compValue a : compList x |
@@ -597,8 +609,6 @@ genGLSLs backend | |||
597 | varyingOut WebGL1 _ = ["varying"] | 609 | varyingOut WebGL1 _ = ["varying"] |
598 | varyingOut OpenGL33 i = [i, "out"] | 610 | varyingOut OpenGL33 i = [i, "out"] |
599 | 611 | ||
600 | genGLSLs _ _ _ _ _ _ = error $ "genGLSLs " -- ++ show e --ppShow e | ||
601 | |||
602 | eTuple (ETuple l) = l | 612 | eTuple (ETuple l) = l |
603 | eTuple x = [x] | 613 | eTuple x = [x] |
604 | 614 | ||
@@ -612,66 +622,42 @@ data Uniform | |||
612 | 622 | ||
613 | type Uniforms = Map String (Uniform, (IR.InputType, String)) | 623 | type Uniforms = Map String (Uniform, (IR.InputType, String)) |
614 | 624 | ||
625 | getSwizzChar = \case | ||
626 | A0 "Sx" -> Just 'x' | ||
627 | A0 "Sy" -> Just 'y' | ||
628 | A0 "Sz" -> Just 'z' | ||
629 | A0 "Sw" -> Just 'w' | ||
630 | _ -> Nothing | ||
631 | |||
632 | showSwizzProj x a = "(" <+> a <+> ")." <> text x | ||
633 | |||
615 | genGLSL :: [SName] -> ExpTV -> WriterT Uniforms (State [String]) Doc | 634 | genGLSL :: [SName] -> ExpTV -> WriterT Uniforms (State [String]) Doc |
616 | genGLSL dns e = case e of | 635 | genGLSL dns e = case e of |
617 | 636 | ||
618 | Prim1 "Uniform" (EString s) -> do | ||
619 | tell $ Map.singleton s $ (,) UUniform (compInputType $ tyOf e, toGLSLType "1" $ tyOf e) | ||
620 | pure $ text s | ||
621 | A3 "Sampler" _ _ (A1 "Texture2DSlot" (EString s)) -> do | ||
622 | tell $ Map.singleton s $ (,) UTexture2DSlot (IR.FTexture2D{-compInputType $ tyOf e -- TODO-}, "sampler2D") | ||
623 | pure $ text s | ||
624 | A3 "Sampler" _ _ (A2 "Texture2D" (A2 "V2" (EInt w) (EInt h)) b) -> do | ||
625 | s <- newName | ||
626 | tell $ Map.singleton s $ (,) (UTexture2D w h b) (IR.FTexture2D, "sampler2D") | ||
627 | pure $ text s | ||
628 | |||
629 | ELit a -> pure $ text $ show a | 637 | ELit a -> pure $ text $ show a |
630 | Var i _ -> pure $ text $ dns !! i | 638 | Var i _ -> pure $ text $ dns !! i |
631 | 639 | ||
632 | -- texturing | 640 | Con cn xs -> case cn of |
633 | A3 "Sampler" _ _ _ -> error "sampler GLSL codegen is not supported" | 641 | "primIfThenElse" -> case xs of [a, b, c] -> hsep <$> sequence [gen a, pure "?", gen b, pure ":", gen c] |
634 | Fun "texture2D" xs -> functionCall "texture2D" xs | 642 | |
635 | 643 | "swizzscalar" -> case xs of [e, getSwizzChar -> Just s] -> showSwizzProj [s] <$> gen e | |
636 | -- temp builtins FIXME: get rid of these | 644 | "swizzvector" -> case xs of [e, Con ((`elem` ["V2","V3","V4"]) -> True) (traverse getSwizzChar -> Just s)] -> showSwizzProj s <$> gen e |
637 | Prim1 "primIntToWord" a -> error $ "WebGL 1 does not support uint types: " ++ ppShow e | 645 | |
638 | Prim1 "primIntToFloat" a -> gen a -- FIXME: does GLSL support implicit int to float cast??? | 646 | "Uniform" -> case xs of |
639 | Prim2 "primCompareInt" a b -> error $ "GLSL codegen does not support: " ++ ppShow e | 647 | [EString s] -> do |
640 | Prim2 "primCompareWord" a b -> error $ "GLSL codegen does not support: " ++ ppShow e | 648 | tell $ Map.singleton s $ (,) UUniform (compInputType $ tyOf e, toGLSLType "1" $ tyOf e) |
641 | Prim2 "primCompareFloat" a b -> error $ "GLSL codegen does not support: " ++ ppShow e | 649 | pure $ text s |
642 | Prim1 "primNegateInt" a -> (text "-" <+>) . parens <$> (gen a) | 650 | "Sampler" -> case xs of |
643 | Prim1 "primNegateWord" a -> error $ "WebGL 1 does not support uint types: " ++ ppShow e | 651 | [_, _, A1 "Texture2DSlot" (EString s)] -> do |
644 | Prim1 "primNegateFloat" a -> (text "-" <+>) . parens <$> (gen a) | 652 | tell $ Map.singleton s $ (,) UTexture2DSlot (IR.FTexture2D{-compInputType $ tyOf e -- TODO-}, "sampler2D") |
645 | 653 | pure $ text s | |
646 | -- vectors | 654 | [_, _, A2 "Texture2D" (A2 "V2" (EInt w) (EInt h)) b] -> do |
647 | Con n xs | n `elem` ["V2", "V3", "V4"], Just f <- vecConName $ tyOf e -> functionCall f xs | 655 | s <- newName |
648 | -- bool | 656 | tell $ Map.singleton s $ (,) (UTexture2D w h b) (IR.FTexture2D, "sampler2D") |
649 | A0 "True" -> pure $ text "true" | 657 | pure $ text s |
650 | A0 "False" -> pure $ text "false" | 658 | |
651 | -- matrices | 659 | 'P':'r':'i':'m':n | n'@(_:_) <- trName (dropS n) -> call n' xs |
652 | Con "M22F" xs -> functionCall "mat2" xs | 660 | where |
653 | Con "M23F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
654 | Con "M24F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
655 | Con "M32F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
656 | Con "M33F" xs -> functionCall "mat3" xs | ||
657 | Con "M34F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
658 | Con "M42F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
659 | Con "M43F" xs -> error "WebGL 1 does not support matrices with this dimension" | ||
660 | Con "M44F" xs -> functionCall "mat4" xs -- where gen = gen | ||
661 | |||
662 | Prim3 "primIfThenElse" a b c -> hsep <$> sequence [gen a, pure "?", gen b, pure ":", gen c] | ||
663 | -- TODO: Texture Lookup Functions | ||
664 | SwizzProj a x -> gen a <&> \a -> "(" <+> a <+> (")." <> text x) | ||
665 | ELam _ _ -> error "GLSL codegen for lambda function is not supported yet" | ||
666 | ETuple _ -> pure $ error "GLSL codegen for tuple is not supported yet" | ||
667 | |||
668 | -- Primitive Functions | ||
669 | Fun "==" xs -> binOp "==" xs | ||
670 | Fun ('P':'r':'i':'m':n) xs | n'@(_:_) <- trName (dropS n) -> case n' of | ||
671 | (c:_) | isAlpha c -> functionCall n' xs | ||
672 | [op, '_'] -> prefixOp [op] xs | ||
673 | n' -> binOp n' xs | ||
674 | where | ||
675 | ifType p a b = if all (p . tyOf) xs then a else b | 661 | ifType p a b = if all (p . tyOf) xs then a else b |
676 | 662 | ||
677 | dropS n | 663 | dropS n |
@@ -759,13 +745,40 @@ genGLSL dns e = case e of | |||
759 | 745 | ||
760 | _ -> "" | 746 | _ -> "" |
761 | 747 | ||
748 | n | n@(_:_) <- trName n -> call n xs | ||
749 | where | ||
750 | trName n = case n of | ||
751 | "texture2D" -> "texture2D" | ||
752 | |||
753 | "True" -> "true" | ||
754 | "False" -> "false" | ||
755 | |||
756 | "M22F" -> "mat2" | ||
757 | "M33F" -> "mat3" | ||
758 | "M44F" -> "mat4" | ||
759 | |||
760 | "==" -> "==" | ||
761 | |||
762 | n | n `elem` ["primNegateWord", "primNegateInt", "primNegateFloat"] -> "-_" | ||
763 | n | n `elem` ["V2", "V3", "V4"], Just f <- vecConName $ tyOf e -> f | ||
764 | _ -> "" | ||
765 | |||
766 | -- not supported | ||
767 | "Sampler" -> error "sampler GLSL codegen is not supported" | ||
768 | n | n `elem` ["primIntToWord", "primIntToFloat", "primCompareInt", "primCompareWord", "primCompareFloat"] -> error $ "WebGL 1 does not support: " ++ ppShow e | ||
769 | n | n `elem` ["M23F", "M24F", "M32F", "M34F", "M42F", "M43F"] -> error "WebGL 1 does not support matrices with this dimension" | ||
770 | (tupName -> Just n) -> pure $ error "GLSL codegen for tuple is not supported yet" | ||
771 | |||
762 | x -> error $ "GLSL codegen - unsupported expression: " ++ ppShow x | 772 | x -> error $ "GLSL codegen - unsupported expression: " ++ ppShow x |
763 | where | 773 | where |
764 | newName = gets head <* modify tail | 774 | newName = gets head <* modify tail |
765 | 775 | ||
766 | prefixOp o [a] = (text o <+>) . parens <$> (gen a) | 776 | call f xs = case f of |
767 | binOp o [a, b] = hsep <$> sequence [parens <$> gen a, pure $ text o, parens <$> gen b] | 777 | (c:_) | isAlpha c -> case xs of |
768 | functionCall f a = (text f <+>) . parens . hcat . intersperse "," <$> mapM gen a | 778 | [] -> return $ text f |
779 | xs -> (text f <+>) . parens . hcat . intersperse "," <$> mapM gen xs | ||
780 | [op, '_'] -> case xs of [a] -> (text [op] <+>) . parens <$> (gen a) | ||
781 | o -> case xs of [a, b] -> hsep <$> sequence [parens <$> gen a, pure $ text o, parens <$> gen b] | ||
769 | 782 | ||
770 | gen = genGLSL dns | 783 | gen = genGLSL dns |
771 | 784 | ||
@@ -801,26 +814,14 @@ vecConName = \case | |||
801 | TVec n t | is234 n, Just s <- scalarType t -> Just $ s ++ "vec" ++ show n | 814 | TVec n t | is234 n, Just s <- scalarType t -> Just $ s ++ "vec" ++ show n |
802 | t -> Nothing | 815 | t -> Nothing |
803 | 816 | ||
804 | -- todo: remove | ||
805 | toGLSLType msg = \case | ||
806 | TBool -> "bool" | ||
807 | TWord -> "uint" | ||
808 | TInt -> "int" | ||
809 | TFloat -> "float" | ||
810 | TTuple [] -> "void" | ||
811 | x@(TVec n t) | Just s <- vecConName x -> s | ||
812 | TMat i j TFloat | is234 i && is234 j -> "mat" ++ if i == j then show i else show i ++ "x" ++ show j | ||
813 | t -> error $ "toGLSLType: " ++ msg ++ " " ++ ppShow t | ||
814 | |||
815 | is234 = (`elem` [2,3,4]) | ||
816 | |||
817 | |||
818 | -------------------------------------------------------------------------------- | 817 | -------------------------------------------------------------------------------- |
819 | 818 | ||
820 | -- expression + type + type of local variables | 819 | -- expression + type + type of local variables |
821 | data ExpTV = ExpTV I.Exp I.Exp [I.Exp] | 820 | data ExpTV = ExpTV_ I.Exp I.Exp [I.Exp] |
822 | deriving (Show, Eq) | 821 | deriving (Show, Eq) |
823 | 822 | ||
823 | pattern ExpTV a b c <- ExpTV_ a b c where ExpTV a b c = ExpTV_ (unLab' a) (unLab' b) c | ||
824 | |||
824 | type Ty = ExpTV | 825 | type Ty = ExpTV |
825 | 826 | ||
826 | tyOf :: ExpTV -> Ty | 827 | tyOf :: ExpTV -> Ty |
@@ -832,7 +833,6 @@ toExp (x, xt) = ExpTV x xt [] | |||
832 | pattern Pi h a b <- (mkPi -> Just (h, a, b)) | 833 | pattern Pi h a b <- (mkPi -> Just (h, a, b)) |
833 | pattern Lam h a b <- (mkLam -> Just (h, a, b)) | 834 | pattern Lam h a b <- (mkLam -> Just (h, a, b)) |
834 | pattern Con h b <- (mkCon -> Just (h, b)) | 835 | pattern Con h b <- (mkCon -> Just (h, b)) |
835 | pattern Fun h b <- (mkFun -> Just (h, b)) | ||
836 | pattern App a b <- (mkApp -> Just (a, b)) | 836 | pattern App a b <- (mkApp -> Just (a, b)) |
837 | pattern Var a b <- (mkVar -> Just (a, b)) | 837 | pattern Var a b <- (mkVar -> Just (a, b)) |
838 | pattern ELit l <- ExpTV (I.ELit l) _ _ | 838 | pattern ELit l <- ExpTV (I.ELit l) _ _ |
@@ -848,46 +848,49 @@ infix 1 .@ | |||
848 | mkVar (ExpTV (unLab -> I.Var i) t vs) = Just (i, ExpTV t I.TType vs) | 848 | mkVar (ExpTV (unLab -> I.Var i) t vs) = Just (i, ExpTV t I.TType vs) |
849 | mkVar _ = Nothing | 849 | mkVar _ = Nothing |
850 | 850 | ||
851 | mkPi (ExpTV (I.Pi b x y) _ vs) = Just (b, x .@ vs, y .@ up 1 <$> (x: vs)) | 851 | mkPi (ExpTV (I.Pi b x y) _ vs) = Just (b, x .@ vs, y .@ addToEnv x vs) |
852 | mkPi _ = Nothing | 852 | mkPi _ = Nothing |
853 | 853 | ||
854 | mkLam (ExpTV (unLab -> I.Lam y) (I.Pi b x yt) vs) = Just (b, x .@ vs, ExpTV y yt $ up 1 <$> (x: vs)) | 854 | mkLam (ExpTV (unLab -> I.Lam y) (I.Pi b x yt) vs) = Just (b, x .@ vs, ExpTV y yt $ addToEnv x vs) |
855 | mkLam _ = Nothing | 855 | mkLam _ = Nothing |
856 | 856 | ||
857 | mkCon (ExpTV (unLab -> I.Con s n xs) et vs) = Just (untick $ show s, chain vs (I.conType et s) $ I.mkConPars n et ++ xs) | 857 | mkCon (ExpTV (I.Con s n xs) et vs) = Just (untick $ show s, chain vs (I.conType et s) $ I.mkConPars n et ++ xs) |
858 | mkCon (ExpTV (unLab -> I.TyCon s xs) et vs) = Just (untick $ show s, chain vs (I.nType s) xs) | 858 | mkCon (ExpTV (I.TyCon s xs) et vs) = Just (untick $ show s, chain vs (I.nType s) xs) |
859 | mkCon (ExpTV (I.Neut (I.Fun s i xs def)) et vs) = Just (untick $ show s, chain vs (I.nType s) xs) | ||
860 | mkCon (ExpTV (I.CaseFun s xs n) et vs) = Just (untick $ show s, chain vs (I.nType s) $ I.makeCaseFunPars' (mkEnv vs) n ++ xs ++ [I.Neut n]) | ||
861 | mkCon (ExpTV (I.TyCaseFun s [m, t, f] n) et vs) = Just (untick $ show s, chain vs (I.nType s) [m, t, I.Neut n, f]) | ||
859 | mkCon _ = Nothing | 862 | mkCon _ = Nothing |
860 | 863 | ||
861 | mkFun (ExpTV (unLab -> I.Neut (I.Fun s i xs def)) et vs) = Just (untick $ show s, chain vs (I.nType s) xs) | ||
862 | mkFun (ExpTV (unLab -> I.CaseFun s xs n) et vs) = Just (untick $ show s, chain vs (I.nType s) $ I.makeCaseFunPars' vs n ++ xs ++ [I.Neut n]) | ||
863 | mkFun (ExpTV (unLab -> I.TyCaseFun s [m, t, f] n) et vs) = Just (untick $ show s, chain vs (I.nType s) [m, t, I.Neut n, f]) | ||
864 | mkFun _ = Nothing | ||
865 | |||
866 | mkApp (ExpTV (unLab -> I.Neut (I.App_ a b)) et vs) = Just (ExpTV (I.Neut a) t vs, head $ chain vs t [b]) | 864 | mkApp (ExpTV (unLab -> I.Neut (I.App_ a b)) et vs) = Just (ExpTV (I.Neut a) t vs, head $ chain vs t [b]) |
867 | where t = I.neutType' vs a | 865 | where t = I.neutType' (mkEnv vs) a |
868 | mkApp _ = Nothing | 866 | mkApp _ = Nothing |
869 | 867 | ||
870 | chain vs t@(I.Pi Hidden at y) (a: as) = chain vs (I.appTy t a) as | 868 | chain vs t@(I.Pi Hidden at y) (a: as) = chain vs (I.appTy t a) as |
871 | chain vs t xs = chain' vs [] t xs | 869 | chain vs t xs = chain' vs t xs |
872 | 870 | ||
873 | chain' vs acc t [] = reverse acc | 871 | chain' vs t [] = [] |
874 | chain' vs acc t@(I.Pi b at y) (a: as) = chain' vs (ExpTV a at vs: acc) (I.appTy t a) as | 872 | chain' vs t@(I.Pi b at y) (a: as) = ExpTV a at vs: chain' vs (I.appTy t a) as |
875 | chain' vs acc t _ = error $ "chain: " ++ show t | 873 | chain' vs t _ = error $ "chain: " ++ show t |
876 | 874 | ||
877 | mkTVar i (ExpTV t _ vs) = ExpTV (I.Var i) t vs | 875 | mkTVar i (ExpTV t _ vs) = ExpTV (I.Var i) t vs |
878 | 876 | ||
879 | unLab (I.FixLabel_ f _ _ x) = unLab x | ||
880 | unLab (I.LabelEnd x) = unLab x | ||
881 | unLab x = x | 877 | unLab x = x |
882 | 878 | ||
879 | unLab' (I.FixLabel_ f _ _ x) = {-trace_ ("fix " ++ show f) $ -} unLab' x | ||
880 | unLab' x = x | ||
881 | |||
883 | instance I.Subst I.Exp ExpTV where | 882 | instance I.Subst I.Exp ExpTV where |
884 | subst i0 x (ExpTV a at vs) = ExpTV (subst i0 x a) (subst i0 x at) (subst i0 x <$> vs) | 883 | subst i0 x (ExpTV a at vs) = ExpTV (subst i0 x a) (subst i0 x at) (zipWith (\i -> subst (i0+i) $ up i x{-todo: review-}) [1..] vs) |
884 | |||
885 | addToEnv x xs = x: xs | ||
886 | mkEnv xs = {-trace_ ("mk " ++ show (length xs)) $ -} zipWith up [1..] xs | ||
885 | 887 | ||
886 | instance Up ExpTV where | 888 | instance Up ExpTV where |
887 | up_ n i (ExpTV x xt vs) = ExpTV (up_ n i x) (up_ n i xt) (up_ n i <$> vs) | 889 | up_ n i (ExpTV x xt vs) = error "up @ExpTV" --ExpTV (up_ n i x) (up_ n i xt) (up_ n i <$> vs) |
888 | used i (ExpTV x xt vs) = used i x || used i xt -- || any (used i) vs{-?-} | 890 | used i (ExpTV x xt vs) = used i x || used i xt -- || any (used i) vs{-?-} |
889 | fold = error "fold @ExpTV" | 891 | fold = error "fold @ExpTV" |
890 | maxDB_ (ExpTV a b cs) = maxDB_ a <> maxDB_ b -- <> foldMap maxDB_ cs{-?-} | 892 | maxDB_ (ExpTV a b cs) = maxDB_ a <> maxDB_ b -- <> foldMap maxDB_ cs{-?-} |
893 | closedExp (ExpTV a b cs) = ExpTV (closedExp a) (closedExp b) cs | ||
891 | 894 | ||
892 | instance PShow ExpTV where | 895 | instance PShow ExpTV where |
893 | pShowPrec p (ExpTV x t _) = pShowPrec p (x, t) | 896 | pShowPrec p (ExpTV x t _) = pShowPrec p (x, t) |
@@ -901,7 +904,7 @@ untick s = s | |||
901 | -------------------------------------------------------------------------------- ExpTV conversion -- TODO: remove | 904 | -------------------------------------------------------------------------------- ExpTV conversion -- TODO: remove |
902 | 905 | ||
903 | etaRed (ELam _ (App f (EVar 0))) | Just f' <- I.down 0 f = etaRed f' | 906 | etaRed (ELam _ (App f (EVar 0))) | Just f' <- I.down 0 f = etaRed f' |
904 | etaRed (ELam _ (Prim3 (tupCaseName -> Just k) _ x (EVar 0))) | Just x' <- I.down 0 x | 907 | etaRed (ELam _ (A3 (tupCaseName -> Just k) _ x (EVar 0))) | Just x' <- I.down 0 x |
905 | = uncurry (\ps e -> Just (ps, e)) $ getPats k x' | 908 | = uncurry (\ps e -> Just (ps, e)) $ getPats k x' |
906 | etaRed (ELam p i) = Just (getPVars p, i) | 909 | etaRed (ELam p i) = Just (getPVars p, i) |
907 | etaRed x = Nothing | 910 | etaRed x = Nothing |
@@ -920,10 +923,10 @@ pattern EtaPrim4 s x1 x2 x3 <- (getEtaPrim -> Just (s, [x1, x2, x3])) | |||
920 | pattern EtaPrim5 s x1 x2 x3 x4 <- (getEtaPrim -> Just (s, [x1, x2, x3, x4])) | 923 | pattern EtaPrim5 s x1 x2 x3 x4 <- (getEtaPrim -> Just (s, [x1, x2, x3, x4])) |
921 | pattern EtaPrim2_2 s <- (getEtaPrim2 -> Just (s, [])) | 924 | pattern EtaPrim2_2 s <- (getEtaPrim2 -> Just (s, [])) |
922 | 925 | ||
923 | getEtaPrim (ELam _ (Fun s (initLast -> Just (traverse (I.down 0) -> Just xs, EVar 0)))) = Just (s, xs) | 926 | getEtaPrim (ELam _ (Con s (initLast -> Just (traverse (I.down 0) -> Just xs, EVar 0)))) = Just (s, xs) |
924 | getEtaPrim _ = Nothing | 927 | getEtaPrim _ = Nothing |
925 | 928 | ||
926 | getEtaPrim2 (ELam _ (ELam _ (Fun s (initLast -> Just (initLast -> Just (traverse (I.down 0) -> Just (traverse (I.down 0) -> Just xs), EVar 0), EVar 0))))) = Just (s, xs) | 929 | getEtaPrim2 (ELam _ (ELam _ (Con s (initLast -> Just (initLast -> Just (traverse (I.down 0) -> Just (traverse (I.down 0) -> Just xs), EVar 0), EVar 0))))) = Just (s, xs) |
927 | getEtaPrim2 _ = Nothing | 930 | getEtaPrim2 _ = Nothing |
928 | 931 | ||
929 | initLast [] = Nothing | 932 | initLast [] = Nothing |
@@ -942,13 +945,6 @@ tupCaseName _ = Nothing | |||
942 | pattern EVar n <- Var n _ | 945 | pattern EVar n <- Var n _ |
943 | pattern ELam t b <- Lam Visible t b | 946 | pattern ELam t b <- Lam Visible t b |
944 | 947 | ||
945 | pattern Prim0 n <- Fun n [] | ||
946 | pattern Prim1 n a <- Fun n [a] | ||
947 | pattern Prim2 n a b <- Fun n [a, b] | ||
948 | pattern Prim3 n a b c <- Fun n [a, b, c] | ||
949 | pattern Prim4 n a b c d <- Fun n [a, b, c, d] | ||
950 | pattern Prim5 n a b c d e <- Fun n [a, b, c, d, e] | ||
951 | |||
952 | pattern A0 n <- Con n [] | 948 | pattern A0 n <- Con n [] |
953 | pattern A1 n a <- Con n [a] | 949 | pattern A1 n a <- Con n [a] |
954 | pattern A2 n a b <- Con n [a, b] | 950 | pattern A2 n a b <- Con n [a, b] |
@@ -994,17 +990,3 @@ tupName = \case | |||
994 | "Tuple7" -> Just 7 | 990 | "Tuple7" -> Just 7 |
995 | _ -> Nothing | 991 | _ -> Nothing |
996 | 992 | ||
997 | pattern SwizzProj a b <- (getSwizzProj -> Just (a, b)) | ||
998 | |||
999 | getSwizzProj = \case | ||
1000 | Prim2 "swizzscalar" e (getSwizzChar -> Just s) -> Just (e, [s]) | ||
1001 | Prim2 "swizzvector" e (Con ((`elem` ["V2","V3","V4"]) -> True) (traverse getSwizzChar -> Just s)) -> Just (e, s) | ||
1002 | _ -> Nothing | ||
1003 | |||
1004 | getSwizzChar = \case | ||
1005 | A0 "Sx" -> Just 'x' | ||
1006 | A0 "Sy" -> Just 'y' | ||
1007 | A0 "Sz" -> Just 'z' | ||
1008 | A0 "Sw" -> Just 'w' | ||
1009 | _ -> Nothing | ||
1010 | |||
diff --git a/src/LambdaCube/Compiler/Infer.hs b/src/LambdaCube/Compiler/Infer.hs index 09fa3ac3..617f5c81 100644 --- a/src/LambdaCube/Compiler/Infer.hs +++ b/src/LambdaCube/Compiler/Infer.hs | |||
@@ -271,10 +271,10 @@ unlabelend a = a | |||
271 | 271 | ||
272 | -------------------------------------------------------------------------------- low-level toolbox | 272 | -------------------------------------------------------------------------------- low-level toolbox |
273 | 273 | ||
274 | class Up a => Subst b a where | 274 | class Subst b a where |
275 | subst :: Int -> b -> a -> a | 275 | subst :: Int -> b -> a -> a |
276 | 276 | ||
277 | down :: (Subst Exp a) => Int -> a -> Maybe a | 277 | down :: (Subst Exp a, Up a{-used-}) => Int -> a -> Maybe a |
278 | down t x | used t x = Nothing | 278 | down t x | used t x = Nothing |
279 | | otherwise = Just $ subst t (error "impossible: down" :: Exp) x | 279 | | otherwise = Just $ subst t (error "impossible: down" :: Exp) x |
280 | 280 | ||
@@ -631,7 +631,7 @@ data CEnv a | |||
631 | | Assign !Int ExpType (CEnv a) -- De Bruijn index decreasing assign reservedOp, only for metavariables (non-recursive) | 631 | | Assign !Int ExpType (CEnv a) -- De Bruijn index decreasing assign reservedOp, only for metavariables (non-recursive) |
632 | deriving (Show, Functor) | 632 | deriving (Show, Functor) |
633 | 633 | ||
634 | instance (Subst Exp a) => Up (CEnv a) where | 634 | instance (Subst Exp a, Up a) => Up (CEnv a) where |
635 | up1_ i = \case | 635 | up1_ i = \case |
636 | MEnd a -> MEnd $ up1_ i a | 636 | MEnd a -> MEnd $ up1_ i a |
637 | Meta a b -> Meta (up1_ i a) (up1_ (i+1) b) | 637 | Meta a b -> Meta (up1_ i a) (up1_ (i+1) b) |
@@ -647,7 +647,7 @@ instance (Subst Exp a) => Up (CEnv a) where | |||
647 | 647 | ||
648 | maxDB_ _ = error "maxDB_ @(CEnv _)" | 648 | maxDB_ _ = error "maxDB_ @(CEnv _)" |
649 | 649 | ||
650 | instance (Subst Exp a) => Subst Exp (CEnv a) where | 650 | instance (Subst Exp a, Up a) => Subst Exp (CEnv a) where |
651 | subst i x = \case | 651 | subst i x = \case |
652 | MEnd a -> MEnd $ subst i x a | 652 | MEnd a -> MEnd $ subst i x a |
653 | Meta a b -> Meta (subst i x a) (subst (i+1) (up 1 x) b) | 653 | Meta a b -> Meta (subst i x a) (subst (i+1) (up 1 x) b) |