1 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# LANGUAGE NoMonomorphismRestriction #-}
4 {-# LANGUAGE ScopedTypeVariables #-}
5 {-# LANGUAGE UndecidableInstances #-}
6 {-# LANGUAGE ViewPatterns #-}
7 {-# OPTIONS_GHC -fno-warn-orphans #-}
10 import Control.Arrow (left)
11 import Control.Applicative (Applicative(..))
12 import Control.Monad (Monad(..), void, when)
13 import Control.Monad.IO.Class (MonadIO(..))
14 import Control.Monad.Trans.Class as MT (MonadTrans(..))
15 import Data.Bool (Bool(..))
16 import Data.Char (Char)
17 import Data.Either (Either(..))
18 import Data.Eq (Eq(..))
19 import Data.Function (($), (.), id)
20 import Data.Functor (Functor(..), (<$>))
21 import Data.Maybe (Maybe(..), maybe)
22 import Data.Monoid (Monoid(..))
23 import Data.Semigroup ((<>))
24 import Data.String (String)
25 import Data.Text (Text)
26 import Prelude (error, succ, Integer, undefined)
27 import System.Console.Haskeline as HL
28 import System.IO (IO, putStr, putStrLn, print)
29 import Text.Show (Show(..))
30 import qualified Control.Monad.Classes as MC
31 import qualified Control.Monad.Classes.Run as MC
32 import qualified Control.Monad.Trans.State.Strict as SS
33 import qualified Data.Char as Char
34 import qualified Data.List as L
35 import qualified Data.Map.Strict as Map
36 import qualified Data.Text as T
37 import qualified Data.Text as Text
38 import qualified Data.Text.IO as Text
39 import qualified System.Console.Haskeline.History as HL
40 import qualified System.IO as IO
41 import qualified Text.Megaparsec as P
43 import Language.Symantic as Sym
44 import qualified Language.Symantic.Document as D
45 import qualified Language.Symantic.Grammar as G
46 import qualified Language.Symantic.Lib as Sym
48 import qualified Hcompta.LCC.Sym as LCC.Sym
49 import qualified Hcompta.LCC as LCC
50 import qualified Hcompta.LCC.Lib.Strict as S
51 import Hcompta.LCC.Read ()
52 import Hcompta.LCC.Write (Writeable(..), context_write)
54 -- dbg :: Show a => String -> a -> a
55 -- dbg msg x = trace (msg ++ " = " ++ show x) x
59 runInputT defaultSettings
60 { historyFile = Just ".hcompta.history"
61 , autoAddHistory = False
63 MC.evalStateStrict evalTeUnit $
64 S.evalState (LCC.state_sym @LCC.Sym.SRC @(Proxy Eval ': LCC.Sym.SS)) $
67 loop :: forall src ss.
71 -- Syms ss (BetaT View) =>
74 Gram_Term src ss (G src ss (SS.StateT (TermVT src ss '[]) (InputT IO))) =>
75 Bool -> Integer -> REPL src ss ()
79 <> (if ok then "32" else "31")
82 <> "\SOH\ESC[34;1m\STX>\SOH\ESC[0;48;05;233m\STX "
84 line <- readLine prompt
88 void $ REPL $ lift $ lift $
90 HL.addHistoryRemovingAllDupes l
91 REPL (parseTe $ Text.pack l) >>= \case
93 liftIO $ putStr $ P.parseErrorPretty err
97 Command_Def nam ast -> runTe nam ast
98 Command_Bind nam ast -> runTe nam ast
99 Command_Eval ast -> runTe "ans" ast
108 MC.modify $ \(imps::Imports NameTe, mods) ->
109 (imps, insTerm nam te mods)
113 when (nam == NameTe "base") $ MC.put r
114 Left (Error_Eval_Cannot_prove_Constraint (TypeVT q)) ->
115 printTy q >>= ansiIO . ("Cannot prove Constraint: " <>)
119 Sym.TermVT src ss '[] ->
120 Sym.Modules src ss ->
123 Sym.insertTermVT ([] `Sym.Mod` t) n $
124 Sym.Fixity2 Sym.infixN5
126 type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (TermVT src ss '[])) = 'False
127 -- type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (EvalVT src)) = 'False
132 (S.StateT (LCC.State_Sym src ss) m)
136 = Command_Eval (AST_Term src ss)
137 | Command_Def NameTe (AST_Term src ss)
138 | Command_Bind NameTe (AST_Term src ss)
144 Gram_Term src ss (G src ss m) =>
146 S.StateT (LCC.State_Sym src ss) m
147 (Either (P.ParseError Char P.Dec) (Command src ss))
148 parseTe = P.runParserT g ""
150 g :: G src ss m (Command src ss)
157 <$ G.optional (G.try $ G.symbol "let")
175 ( SourceInj (TypeVT src) src
176 , SourceInj (KindK src) src
177 , SourceInj (AST_Type src) src
184 -- , Syms ss (BetaT View)
188 Either (Error_Term src) (TermVT src ss '[])
189 readTe = Sym.readTerm CtxTyZ
191 -- | Lifted 'D.ansiIO' on 'IO.stdout'. Helper.
192 ansiIO :: MonadIO m => D.ANSI_IO -> m ()
193 ansiIO = liftIO . (`D.ansiIO` IO.stdout)
195 -- * Type 'Error_Eval'
197 = Error_Eval_Cannot_prove_Constraint (TypeVT src)
205 -- Syms ss (BetaT View) =>
207 SourceInj (TypeVT src) src =>
210 S.StateT (LCC.State_Sym src ss)
211 (SS.StateT (TermVT src ss '[]) m)
212 (Either (Error_Eval src) (TermVT src ss '[]))
213 evalTe te@(TermVT (Term q t (TeSym sym))) = do
214 printTy (q #> t) >>= ansiIO . ("Type: " <>)
215 -- liftIO $ Text.putStrLn $ "View: " <> view (betaT $ sym CtxTeZ)
217 io:@aTy | Just HRefl <- proj_ConstKiTy @_ @IO io -> do
218 case proveConstraint q of
219 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q
221 a <- liftIO $ eval $ sym CtxTeZ
222 let r = TermVT $ teEval_uneval aTy a
226 r@(TermVT (Term q' t' (TeSym sym'))) <- completeTe te
227 printTy (q' #> t') >>= ansiIO . ("Type: Completed: " <>)
228 case proveConstraint q' of
229 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q'
231 let a = eval $ sym' CtxTeZ
240 -- Syms ss (BetaT View) =>
241 SourceInj (TypeVT src) src =>
244 S.StateT (LCC.State_Sym src ss)
245 (SS.StateT (TermVT src ss '[]) m)
248 liftIO $ putStrLn "completeTe"
249 st :: TermVT src ss '[] <- MC.get
250 case betaTerms $ G.BinTree0 t `G.BinTree2` G.BinTree0 st of
252 liftIO $ putStrLn "completeTe: Left"
255 liftIO $ putStrLn "completeTe: Right"
259 forall src ss m vs t d.
265 S.StateT (LCC.State_Sym src ss) m d
267 (impsTy, _ :: Sym.ModulesTy src) <- MC.get
270 { config_Doc_Type_vars_numbering = False
271 , config_Doc_Type_imports = impsTy
274 printTe :: Source src => MonadIO m => Type src vs a -> a -> m ()
276 case proveConstraint $ LCC.Sym.tyWriteable
277 (allocVarsR (lenVars aTy) $ LCC.Sym.tyContext_Write @_ @'[] ~> LCC.Sym.tyANSI_IO) aTy of
278 Just Dict -> ansiIO $ write a context_write
280 case proveConstraint $ Sym.tyShow aTy of
281 Nothing -> putStrLn $ "No Show instance for type: " <> show aTy
288 -- /Read Eval Print Loop/ monad.
289 newtype REPL src ss a
291 { unREPL :: S.StateT (LCC.State_Sym src ss)
292 (SS.StateT (TermVT src ss '[])
299 -- , MonadState State_REPL
302 instance MonadTrans (REPL src ss) where
303 lift = REPL . lift . lift
305 type instance MC.CanDo (REPL src ss) (MC.EffState (LCC.State_Sym src ss)) = 'False
306 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.Modules src ss)) = 'False
307 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.ModulesTy src)) = 'False
308 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.TermVT src ss '[])) = 'False
309 -- type instance MC.CanDo (REPL src ss) (MC.EffState (EvalVT src)) = 'False
312 -- * Type 'State_REPL'
313 data State_REPL src ss
315 { state_repl_terms :: LCC.State_Sym src ss
316 , state_repl_db :: db
319 -- State_REPL src ss db
320 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
321 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (State_REPL src ss db) m) where
322 stateN _px = S.StateT . SS.state
324 -- LCC.State_Sym src ss
325 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
326 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (LCC.State_Sym src ss) m) where
327 stateN _px f = S.StateT $ SS.state $ \st ->
328 (\a -> st{state_repl_terms=a}) <$> f (state_repl_terms st)
332 readLine :: String -> REPL src ss (Maybe String)
334 line <- REPL . lift . lift $ getInputLine prompt
336 Just l@(':':_) -> return $ Just l
337 Just l@(_:_) | L.last l == ' ' -> readLines l
338 Just l -> return $ Just l
339 Nothing -> return Nothing
341 readLines :: String -> REPL src ss (Maybe String)
343 line <- REPL . lift . lift $ getInputLine ""
345 Just l@(_:_) | L.last l == ' ' -> readLines $ acc <> l
346 Just l -> return $ Just $ acc <> l
347 Nothing -> return $ Just acc
356 D.Doc_Decoration d =>
358 Sym.Imports Sym.NameTy ->
359 Sym.Modules src ss -> d
360 docModules imps (Sym.Modules mods) =
362 (\p m doc -> docModule imps p m <> doc)
371 D.Doc_Decoration d =>
373 Sym.Imports Sym.NameTy ->
374 Sym.PathMod -> Sym.Module src ss -> d
375 docModule imps m Sym.ByFixity
380 go docFixityInfix byInfix <>
381 go docFixityPrefix byPrefix <>
382 go docFixityPostfix byPostfix
384 go :: (fixy -> d) -> ModuleFixy src ss fixy -> d
392 docFixy token_fixity <>
393 D.space <> D.bold (D.yellower "::") <> D.space <>
394 docTokenTerm imps (t Sym.noSource) <>
404 Sym.Imports Sym.NameTy ->
405 Sym.Token_Term src ss -> d
406 docTokenTerm imps t =
407 case Sym.readTerm CtxTyZ (G.BinTree0 t) of
408 Left{} -> error "[BUG] docTokenTerm: readTerm failed"
409 Right (Sym.TermVT te) ->
410 Sym.docType Sym.config_Doc_Type
411 { config_Doc_Type_vars_numbering = False
412 , config_Doc_Type_imports = imps
413 } 0 $ Sym.typeOfTerm te
415 docFixityInfix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Infix -> t
416 docFixityInfix = \case
417 Sym.Infix Nothing 5 -> D.empty
422 Sym.AssocB Sym.SideL -> "l"
423 Sym.AssocB Sym.SideR -> "r" in
424 D.magenta $ " infix" <> maybe D.empty docAssoc a <>
425 D.space <> D.bold (D.bluer (D.int p))
426 docFixityPrefix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Unifix -> t
427 docFixityPrefix p = D.magenta $ " prefix " <> D.bold (D.bluer (D.int $ Sym.unifix_prece p))
428 docFixityPostfix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Unifix -> t
429 docFixityPostfix p = D.magenta $ " postfix " <> D.bold (D.bluer (D.int $ Sym.unifix_prece p))
434 PathMod -> NameTe -> d
435 docPathTe ms (NameTe n) =
437 L.intersperse (D.charH '.') $
438 ((\(NameMod m) -> D.textH m) <$> ms) <>
439 [(if isOp n then id else D.yellower) $ D.text n]
441 isOp = T.all $ \case '_' -> True; '\'' -> True; c -> Char.isAlphaNum c
448 let sym@(LCC.State_Sym (impsTy,_modsTy) (_impsTe,patchModsTe -> modsTe)) =
449 LCC.state_sym @LCC.Sym.SRC @LCC.Sym.SS
450 (`D.ansiIO` IO.stderr) $ docModules impsTy modsTe
451 let arg = Text.unwords $ Text.pack <$> args
452 ast <- printError $ parseTe sym arg
454 ast <- (foldr1 G.BinTree2 <$>) $ forM args $ \arg -> do
455 printError $ parseTe sym $ Text.pack arg
457 _te <- printError $ readTe ast
461 forM_ args $ \arg -> do
462 ast <- printError $ parseTe (impsTy, modsTy) (impsTe, modsTe) $ Text.pack arg
463 te <- printError $ readTe ast
467 patchModsTe = Sym.deleteDefTermInfix ([] `Mod` "$")
469 printError :: Show err => MonadIO m => Either err a -> m a
470 printError (Left err) = liftIO $ error $ show err
471 printError (Right a) = return a
477 G.Gram_Source src (G src ss m) =>
478 Gram_Term src ss (G src ss m) =>
479 LCC.State_Sym src ss ->
480 Text -> Either (P.ParseError Char P.Dec) (Command src ss)
484 P.runParserT g "" inp
486 g :: G src ss Identity (Command src ss)
488 G.try (Command_Def <$> Sym.g_NameTe <* G.lexeme (G.char '=') <*> Sym.g_term <* G.eoi) G.<+>
489 (Command_Eval <$> Sym.g_term <* G.eoi)
493 evalTeUnit :: Source src => SymInj ss () => TermVT src ss '[]
494 evalTeUnit = TermVT $ Sym.teUnit -- Term noConstraint Sym.tyUnit $ teSym @() $ Sym.unit
497 evalTeUnit :: Source src => EvalVT src
498 evalTeUnit = EvalVT (Sym.tyUnit @_ @'[]) $ eval Sym.unit
501 data EvalVT src = forall vs t. EvalVT (Type src vs t) t
504 SourceInj (TypeVT src) src =>
508 Either (Error_Beta src) (EvalVT src)
509 appEvalVT (EvalVT tf te_fun) (EvalVT ta te_arg) =
510 let (tf',ta') = appendVars tf ta in
512 Nothing -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf'
515 (Error_Beta_Unify `left`) $
516 case (unQualsTy af, unQualsTy ta') of
517 (TypeK af', TypeK ta'') -> unifyType mempty af' ta''
518 let tf'' = subst mgu tf'
519 let ta'' = subst mgu ta'
520 appEval tf'' te_fun ta'' te_arg $ \tr te_res ->
521 normalizeVarsTy tr $ \tr' ->
525 forall src vs fun arg ret.
526 SourceInj (TypeVT src) src =>
528 Type src vs fun -> fun ->
529 Type src vs arg -> arg ->
530 (forall res. Type src vs res -> res -> ret) ->
531 Either (Error_Beta src) ret
532 appEval tf fun ta arg k =
534 a2b :@ a2b_a :@ a2b_b
535 | Just HRefl <- proj_ConstKiTy @(K (->)) @(->) a2b ->
536 case a2b_a `eqType` ta of
537 Nothing -> Left $ Error_Beta_Type_mismatch (TypeVT a2b_a) (TypeVT ta)
538 Just Refl -> Right $ k a2b_b $ fun arg
539 _ -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf
544 -- * Class 'Sym_Eval'
545 type instance Sym Eval = Sym_Eval
546 class Sym_Eval term where
547 uneval :: a -> term a
548 default uneval :: Sym_Eval (UnT term) => Trans term => a -> term a
549 uneval = trans . uneval
552 instance Sym_Eval Eval where
555 instance Sym_Eval View where
556 uneval = View $ \_p _v -> "()"
557 instance (Sym_Eval r1, Sym_Eval r2) => Sym_Eval (Dup r1 r2) where
558 uneval = uneval `Dup` uneval
562 instance (Sym_Eval term, Sym_Lambda term) => Sym_Eval (BetaT term)
565 instance NameTyOf Eval where
566 nameTyOf _c = [] `Mod` "Eval"
567 instance ClassInstancesFor Eval where
568 instance TypeInstancesFor Eval
569 instance FixityOf Eval
574 ) => Gram_Term_AtomsFor src ss g Eval where
575 instance ModuleFor src ss Eval
578 tyEval :: Source src => LenInj vs => Type src vs Eval
579 tyEval = tyConst @(K Eval) @Eval
583 Source src => SymInj ss Eval =>
584 Type src vs a -> a ->
585 Term src ss ts vs (() #> a)
587 Term (noConstraintLen $ lenVars ty) ty $
589 TeSym $ \_c -> uneval a