@@ -593,7 +593,17 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
593 -- further inlined to help with totality checking.
593 -- further inlined to help with totality checking.
594 let pdef = map debind $ map (simple_lhs (tt_ctxt ist)) pats
594 let pdef = map debind $ map (simple_lhs (tt_ctxt ist)) pats
596− logLvl 5 $ "Initial typechecked patterns:\n" ++ show pdef
596+ logLvl 5 $ "Initial typechecked patterns:\n" ++ show pats
597+ logLvl 5 $ "Initial typechecked pattern def:\n" ++ show pdef
599+ -- Look for 'static' names and generate new specialised
600+ -- definitions for them
602+ {- Not fully implemented yet!
603+ mapM_ (\ e -> case e of
605+ Right (l, r) -> elabPE info fc r) pats
598 -- TODO: Inlining on initial definition happens here.
608 -- TODO: Inlining on initial definition happens here.
@@ -747,12 +757,67 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
747 -- user defined transformation rules later)
757 -- user defined transformation rules later)
748 doTransforms ist pats =
758 doTransforms ist pats =
749 case specNames opts of
759 case specNames opts of
750− Nothing -> pats
760+ Nothing -> pats
751− Just ns -> partial_eval (tt_ctxt ist) ns pats
761+ Just ns -> partial_eval (tt_ctxt ist) ns pats
763+-- Find 'static' applications in a term and partially evaluate them
764+elabPE :: ElabInfo -> FC -> Term -> Idris ()
767+ let sa = getSpecApps ist [] r
768+ mapM_ (mkSpecialised ist) sa
770+ mkSpecialised ist specapp = do
771+ let specTy = getSpecTy ist specapp
772+ let (n, newnm, [(lhs, rhs)]) = getSpecClause ist specapp
773+ let undef = case lookupDef newnm (tt_ctxt ist) of
776+ when (undef && all (concreteArg ist) (snd specapp)) $ do
777+ let opts = [Specialise ((n, Nothing) :
778+ (mapMaybe specName (snd specapp)))]
779+ iputStrLn (show specapp)
780+ iputStrLn $ "PE definition type : " ++ (show specTy)
781+ ++ "\n" ++ show opts
782+ iputStrLn $ "PE definition " ++ show newnm ++ ":\n" ++
783+ (show lhs ++ " = " ++ show rhs)
784+ elabType info defaultSyntax "" fc opts newnm specTy
785+ let def = [PClause fc newnm lhs [] rhs []]
786+ elabClauses info fc opts newnm def
788+ specName (ImplicitS, tm)
789+ | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
790+ specName (ExplicitS, tm)
791+ | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
792+ specName _ = Nothing
794+ concreteArg ist (ImplicitS, tm) = concreteTm ist tm
795+ concreteArg ist (ExplicitS, tm) = concreteTm ist tm
796+ concreteArg ist _ = True
798+ concreteTm ist tm | (P _ n _, _) <- unApply tm =
799+ case lookupTy n (tt_ctxt ist) of
802+ concreteTm ist _ = False
804+ -- get the type of a specialised application
805+ getSpecTy ist (n, args)
806+ = case lookupTy n (tt_ctxt ist) of
807+ [ty] -> let specty = normalise (tt_ctxt ist) [] (specType args ty) in
808+ trace (show specty) $ mkPE_TyDecl ist args
809+ (explicitNames specty)
810+-- (normalise (tt_ctxt ist) [] (specType args ty))
811+ _ -> error "Can't happen (getSpecTy)"
813+ getSpecClause ist (n, args)
814+ = let newnm = UN (show (nsroot n) ++ "__spectest") in -- UN (show n ++ show (map snd args)) in
815+ (n, newnm, mkPE_TermDecl ist newnm n args)
753-- Elaborate a value, returning any new bindings created (this will only
819-- Elaborate a value, returning any new bindings created (this will only
754-- happen if elaborating as a pattern clause)
820-- happen if elaborating as a pattern clause)
756elabValBind :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
821elabValBind :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
757elabValBind info aspat tm_in
822elabValBind info aspat tm_in
758 = do ctxt <- getContext
823 = do ctxt <- getContext