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 Data.Void (Void)
27 import Prelude (error, succ, Integer, undefined)
28 import System.Console.Haskeline as HL
29 import System.IO (IO, putStr, putStrLn, print)
30 import Text.Show (Show(..))
31 import qualified Control.Monad.Classes as MC
32 import qualified Control.Monad.Classes.Run as MC
33 import qualified Control.Monad.Trans.State.Strict as SS
34 import qualified Data.Char as Char
35 import qualified Data.List as L
36 import qualified Data.Map.Strict as Map
37 import qualified Data.Text as T
38 import qualified Data.Text as Text
39 import qualified Data.Text.IO as Text
40 import qualified System.Console.Haskeline.History as HL
41 import qualified System.IO as IO
42 import qualified Text.Megaparsec as P
44 import Language.Symantic as Sym
45 import qualified Language.Symantic.Document as D
46 import qualified Language.Symantic.Grammar as G
47 import qualified Language.Symantic.Lib as Sym
49 import qualified Hcompta.LCC.Sym as LCC.Sym
50 import qualified Hcompta.LCC as LCC
51 import qualified Hcompta.LCC.Lib.Strict as S
52 import Hcompta.LCC.Read ()
53 import Hcompta.LCC.Write (Writeable(..), context_write)
55 -- dbg :: Show a => String -> a -> a
56 -- dbg msg x = trace (msg ++ " = " ++ show x) x
60 runInputT defaultSettings
61 { historyFile = Just ".hcompta.history"
62 , autoAddHistory = False
64 MC.evalStateStrict evalTeUnit $
65 S.evalState (LCC.state_sym @LCC.Sym.SRC @(Proxy Eval ': LCC.Sym.SS)) $
68 loop :: forall src ss.
72 -- Syms ss (BetaT View) =>
75 Gram_Term src ss (G src ss (SS.StateT (TermVT src ss '[]) (InputT IO))) =>
76 Bool -> Integer -> REPL src ss ()
80 <> (if ok then "32" else "31")
83 <> "\SOH\ESC[34;1m\STX>\SOH\ESC[0;48;05;233m\STX "
85 line <- readLine prompt
89 void $ REPL $ lift $ lift $
91 HL.addHistoryRemovingAllDupes l
92 REPL (parseTe $ Text.pack l) >>= \case
94 liftIO $ putStr $ P.parseErrorPretty err
98 Command_Def nam ast -> runTe nam ast
99 Command_Bind nam ast -> runTe nam ast
100 Command_Eval ast -> runTe "ans" ast
109 MC.modify $ \(imps::Imports NameTe, mods) ->
110 (imps, insTerm nam te mods)
114 when (nam == NameTe "base") $ MC.put r
115 Left (Error_Eval_Cannot_prove_Constraint (TypeVT q)) ->
116 printTy q >>= ansiIO . ("Cannot prove Constraint: " <>)
120 Sym.TermVT src ss '[] ->
121 Sym.Modules src ss ->
124 Sym.insertTermVT ([] `Sym.Mod` t) n $
125 Sym.Fixity2 Sym.infixN5
127 type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (TermVT src ss '[])) = 'False
128 -- type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (EvalVT src)) = 'False
133 (S.StateT (LCC.State_Sym src ss) m)
137 = Command_Eval (AST_Term src ss)
138 | Command_Def NameTe (AST_Term src ss)
139 | Command_Bind NameTe (AST_Term src ss)
145 Gram_Term src ss (G src ss m) =>
147 S.StateT (LCC.State_Sym src ss) m
148 (Either (P.ParseError Char Void) (Command src ss))
149 parseTe = P.runParserT g ""
151 g :: G src ss m (Command src ss)
158 <$ G.optional (G.try $ G.symbol "let")
176 ( SourceInj (TypeVT src) src
177 , SourceInj (KindK src) src
178 , SourceInj (AST_Type src) src
185 -- , Syms ss (BetaT View)
189 Either (Error_Term src) (TermVT src ss '[])
190 readTe = Sym.readTerm CtxTyZ
192 -- | Lifted 'D.ansiIO' on 'IO.stdout'. Helper.
193 ansiIO :: MonadIO m => D.ANSI_IO -> m ()
194 ansiIO = liftIO . (`D.ansiIO` IO.stdout)
196 -- * Type 'Error_Eval'
198 = Error_Eval_Cannot_prove_Constraint (TypeVT src)
206 -- Syms ss (BetaT View) =>
208 SourceInj (TypeVT src) src =>
211 S.StateT (LCC.State_Sym src ss)
212 (SS.StateT (TermVT src ss '[]) m)
213 (Either (Error_Eval src) (TermVT src ss '[]))
214 evalTe te@(TermVT (Term q t (TeSym sym))) = do
215 printTy (q #> t) >>= ansiIO . ("Type: " <>)
216 -- liftIO $ Text.putStrLn $ "View: " <> view (betaT $ sym CtxTeZ)
218 io:@aTy | Just HRefl <- proj_ConstKiTy @_ @IO io -> do
219 case proveConstraint q of
220 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q
222 a <- liftIO $ eval $ sym CtxTeZ
223 let r = TermVT $ teEval_uneval aTy a
227 r@(TermVT (Term q' t' (TeSym sym'))) <- completeTe te
228 printTy (q' #> t') >>= ansiIO . ("Type: Completed: " <>)
229 case proveConstraint q' of
230 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q'
232 let a = eval $ sym' CtxTeZ
241 -- Syms ss (BetaT View) =>
242 SourceInj (TypeVT src) src =>
245 S.StateT (LCC.State_Sym src ss)
246 (SS.StateT (TermVT src ss '[]) m)
249 liftIO $ putStrLn "completeTe"
250 st :: TermVT src ss '[] <- MC.get
251 case betaTerms $ G.BinTree0 t `G.BinTree2` G.BinTree0 st of
253 liftIO $ putStrLn "completeTe: Left"
256 liftIO $ putStrLn "completeTe: Right"
260 forall src ss m vs t d.
266 S.StateT (LCC.State_Sym src ss) m d
268 (impsTy, _ :: Sym.ModulesTy src) <- MC.get
271 { config_Doc_Type_vars_numbering = False
272 , config_Doc_Type_imports = impsTy
275 printTe :: Source src => MonadIO m => Type src vs a -> a -> m ()
277 case proveConstraint $ LCC.Sym.tyWriteable
278 (allocVarsR (lenVars aTy) $ LCC.Sym.tyContext_Write @_ @'[] ~> LCC.Sym.tyANSI_IO) aTy of
279 Just Dict -> ansiIO $ write a context_write
281 case proveConstraint $ Sym.tyShow aTy of
282 Nothing -> putStrLn $ "No Show instance for type: " <> show aTy
289 -- /Read Eval Print Loop/ monad.
290 newtype REPL src ss a
292 { unREPL :: S.StateT (LCC.State_Sym src ss)
293 (SS.StateT (TermVT src ss '[])
300 -- , MonadState State_REPL
303 instance MonadTrans (REPL src ss) where
304 lift = REPL . lift . lift
306 type instance MC.CanDo (REPL src ss) (MC.EffState (LCC.State_Sym src ss)) = 'False
307 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.Modules src ss)) = 'False
308 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.ModulesTy src)) = 'False
309 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.TermVT src ss '[])) = 'False
310 -- type instance MC.CanDo (REPL src ss) (MC.EffState (EvalVT src)) = 'False
313 -- * Type 'State_REPL'
314 data State_REPL src ss
316 { state_repl_terms :: LCC.State_Sym src ss
317 , state_repl_db :: db
320 -- State_REPL src ss db
321 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
322 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (State_REPL src ss db) m) where
323 stateN _px = S.StateT . SS.state
325 -- LCC.State_Sym src ss
326 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
327 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (LCC.State_Sym src ss) m) where
328 stateN _px f = S.StateT $ SS.state $ \st ->
329 (\a -> st{state_repl_terms=a}) <$> f (state_repl_terms st)
333 readLine :: String -> REPL src ss (Maybe String)
335 line <- REPL . lift . lift $ getInputLine prompt
337 Just l@(':':_) -> return $ Just l
338 Just l@(_:_) | L.last l == ' ' -> readLines l
339 Just l -> return $ Just l
340 Nothing -> return Nothing
342 readLines :: String -> REPL src ss (Maybe String)
344 line <- REPL . lift . lift $ getInputLine ""
346 Just l@(_:_) | L.last l == ' ' -> readLines $ acc <> l
347 Just l -> return $ Just $ acc <> l
348 Nothing -> return $ Just acc
357 D.Doc_Decoration d =>
359 Sym.Imports Sym.NameTy ->
360 Sym.Modules src ss -> d
361 docModules imps (Sym.Modules mods) =
363 (\p m doc -> docModule imps p m <> doc)
372 D.Doc_Decoration d =>
374 Sym.Imports Sym.NameTy ->
375 Sym.PathMod -> Sym.Module src ss -> d
376 docModule imps m Sym.ByFixity
381 go docFixityInfix byInfix <>
382 go docFixityPrefix byPrefix <>
383 go docFixityPostfix byPostfix
385 go :: (fixy -> d) -> ModuleFixy src ss fixy -> d
393 docFixy token_fixity <>
394 D.space <> D.bold (D.yellower "::") <> D.space <>
395 docTokenTerm imps (t Sym.noSource) <>
405 Sym.Imports Sym.NameTy ->
406 Sym.Token_Term src ss -> d
407 docTokenTerm imps t =
408 case Sym.readTerm CtxTyZ (G.BinTree0 t) of
409 Left{} -> error "[BUG] docTokenTerm: readTerm failed"
410 Right (Sym.TermVT te) ->
411 Sym.docType Sym.config_Doc_Type
412 { config_Doc_Type_vars_numbering = False
413 , config_Doc_Type_imports = imps
414 } 0 $ Sym.typeOfTerm te
416 docFixityInfix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Infix -> t
417 docFixityInfix = \case
418 Sym.Infix Nothing 5 -> D.empty
423 Sym.AssocB Sym.SideL -> "l"
424 Sym.AssocB Sym.SideR -> "r" in
425 D.magenta $ " infix" <> maybe D.empty docAssoc a <>
426 D.space <> D.bold (D.bluer (D.int p))
427 docFixityPrefix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Unifix -> t
428 docFixityPrefix p = D.magenta $ " prefix " <> D.bold (D.bluer (D.int $ Sym.unifix_prece p))
429 docFixityPostfix :: (D.Doc_Decoration t, D.Doc_Color t, D.Doc_Text t) => Unifix -> t
430 docFixityPostfix p = D.magenta $ " postfix " <> D.bold (D.bluer (D.int $ Sym.unifix_prece p))
435 PathMod -> NameTe -> d
436 docPathTe ms (NameTe n) =
438 L.intersperse (D.charH '.') $
439 ((\(NameMod m) -> D.textH m) <$> ms) <>
440 [(if isOp n then id else D.yellower) $ D.text n]
442 isOp = T.all $ \case '_' -> True; '\'' -> True; c -> Char.isAlphaNum c
449 let sym@(LCC.State_Sym (impsTy,_modsTy) (_impsTe,patchModsTe -> modsTe)) =
450 LCC.state_sym @LCC.Sym.SRC @LCC.Sym.SS
451 (`D.ansiIO` IO.stderr) $ docModules impsTy modsTe
452 let arg = Text.unwords $ Text.pack <$> args
453 ast <- printError $ parseTe sym arg
455 ast <- (foldr1 G.BinTree2 <$>) $ forM args $ \arg -> do
456 printError $ parseTe sym $ Text.pack arg
458 _te <- printError $ readTe ast
462 forM_ args $ \arg -> do
463 ast <- printError $ parseTe (impsTy, modsTy) (impsTe, modsTe) $ Text.pack arg
464 te <- printError $ readTe ast
468 patchModsTe = Sym.deleteDefTermInfix ([] `Mod` "$")
470 printError :: Show err => MonadIO m => Either err a -> m a
471 printError (Left err) = liftIO $ error $ show err
472 printError (Right a) = return a
478 G.Gram_Source src (G src ss m) =>
479 Gram_Term src ss (G src ss m) =>
480 LCC.State_Sym src ss ->
481 Text -> Either (P.ParseError Char P.Dec) (Command src ss)
485 P.runParserT g "" inp
487 g :: G src ss Identity (Command src ss)
489 G.try (Command_Def <$> Sym.g_NameTe <* G.lexeme (G.char '=') <*> Sym.g_term <* G.eoi) G.<+>
490 (Command_Eval <$> Sym.g_term <* G.eoi)
494 evalTeUnit :: Source src => SymInj ss () => TermVT src ss '[]
495 evalTeUnit = TermVT $ Sym.teUnit -- Term noConstraint Sym.tyUnit $ teSym @() $ Sym.unit
498 evalTeUnit :: Source src => EvalVT src
499 evalTeUnit = EvalVT (Sym.tyUnit @_ @'[]) $ eval Sym.unit
502 data EvalVT src = forall vs t. EvalVT (Type src vs t) t
505 SourceInj (TypeVT src) src =>
509 Either (Error_Beta src) (EvalVT src)
510 appEvalVT (EvalVT tf te_fun) (EvalVT ta te_arg) =
511 let (tf',ta') = appendVars tf ta in
513 Nothing -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf'
516 (Error_Beta_Unify `left`) $
517 case (unQualsTy af, unQualsTy ta') of
518 (TypeK af', TypeK ta'') -> unifyType mempty af' ta''
519 let tf'' = subst mgu tf'
520 let ta'' = subst mgu ta'
521 appEval tf'' te_fun ta'' te_arg $ \tr te_res ->
522 normalizeVarsTy tr $ \tr' ->
526 forall src vs fun arg ret.
527 SourceInj (TypeVT src) src =>
529 Type src vs fun -> fun ->
530 Type src vs arg -> arg ->
531 (forall res. Type src vs res -> res -> ret) ->
532 Either (Error_Beta src) ret
533 appEval tf fun ta arg k =
535 a2b :@ a2b_a :@ a2b_b
536 | Just HRefl <- proj_ConstKiTy @(K (->)) @(->) a2b ->
537 case a2b_a `eqType` ta of
538 Nothing -> Left $ Error_Beta_Type_mismatch (TypeVT a2b_a) (TypeVT ta)
539 Just Refl -> Right $ k a2b_b $ fun arg
540 _ -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf
545 -- * Class 'Sym_Eval'
546 type instance Sym Eval = Sym_Eval
547 class Sym_Eval term where
548 uneval :: a -> term a
549 default uneval :: Sym_Eval (UnT term) => Trans term => a -> term a
550 uneval = trans . uneval
553 instance Sym_Eval Eval where
556 instance Sym_Eval View where
557 uneval = View $ \_p _v -> "()"
558 instance (Sym_Eval r1, Sym_Eval r2) => Sym_Eval (Dup r1 r2) where
559 uneval = uneval `Dup` uneval
563 instance (Sym_Eval term, Sym_Lambda term) => Sym_Eval (BetaT term)
566 instance NameTyOf Eval where
567 nameTyOf _c = [] `Mod` "Eval"
568 instance ClassInstancesFor Eval where
569 instance TypeInstancesFor Eval
570 instance FixityOf Eval
575 ) => Gram_Term_AtomsFor src ss g Eval where
576 instance ModuleFor src ss Eval
579 tyEval :: Source src => LenInj vs => Type src vs Eval
580 tyEval = tyConst @(K Eval) @Eval
584 Source src => SymInj ss Eval =>
585 Type src vs a -> a ->
586 Term src ss ts vs (() #> a)
588 Term (noConstraintLen $ lenVars ty) ty $
590 TeSym $ \_c -> uneval a