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 Doc
46 import qualified Language.Symantic.Document.Term.IO as DocIO
47 import qualified Language.Symantic.Grammar as G
48 import qualified Language.Symantic.Lib as Sym
50 import qualified Hcompta.LCC.Sym as LCC.Sym
51 import qualified Hcompta.LCC as LCC
52 import qualified Hcompta.LCC.Lib.Strict as S
53 import Hcompta.LCC.Read ()
54 import Hcompta.LCC.Write (Writeable(..))
55 import Hcompta.LCC.Write as Write
57 -- dbg :: Show a => String -> a -> a
58 -- dbg msg x = trace (msg ++ " = " ++ show x) x
62 runInputT defaultSettings
63 { historyFile = Just ".hcompta.history"
64 , autoAddHistory = False
66 MC.evalStateStrict evalTeUnit $
67 S.evalState (LCC.state_sym @LCC.Sym.SRC @(Proxy Eval ': LCC.Sym.SS)) $
70 loop :: forall src ss.
74 -- Syms ss (BetaT View) =>
77 Gram_Term src ss (G src ss (SS.StateT (TermVT src ss '[]) (InputT IO))) =>
78 Bool -> Integer -> REPL src ss ()
82 <> (if ok then "32" else "31")
85 <> "\SOH\ESC[34;1m\STX>\SOH\ESC[0;48;05;233m\STX "
87 line <- readLine prompt
91 void $ REPL $ lift $ lift $
93 HL.addHistoryRemovingAllDupes l
94 REPL (parseTe $ Text.pack l) >>= \case
96 liftIO $ putStr $ P.parseErrorPretty err
100 Command_Def nam ast -> runTe nam ast
101 Command_Bind nam ast -> runTe nam ast
102 Command_Eval ast -> runTe "ans" ast
111 MC.modify $ \(imps::Imports NameTe, mods) ->
112 (imps, insTerm nam te mods)
116 when (nam == NameTe "base") $ MC.put r
117 Left (Error_Eval_Cannot_prove_Constraint (TypeVT q)) ->
118 printTy q >>= ansiIO . ("Cannot prove Constraint: " <>)
122 Sym.TermVT src ss '[] ->
123 Sym.Modules src ss ->
126 Sym.insertTermVT ([] `Sym.Mod` t) n $
127 Sym.Fixity2 Sym.infixN5
129 type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (TermVT src ss '[])) = 'False
130 -- type instance MC.CanDo (S.StateT (LCC.State_Sym src ss) m) (MC.EffState (EvalVT src)) = 'False
135 (S.StateT (LCC.State_Sym src ss) m)
139 = Command_Eval (AST_Term src ss)
140 | Command_Def NameTe (AST_Term src ss)
141 | Command_Bind NameTe (AST_Term src ss)
147 Gram_Term src ss (G src ss m) =>
149 S.StateT (LCC.State_Sym src ss) m
150 (Either (P.ParseError Char Void) (Command src ss))
151 parseTe = P.runParserT g ""
153 g :: G src ss m (Command src ss)
160 <$ G.optional (G.try $ G.symbol "let")
178 ( SourceInj (TypeVT src) src
179 , SourceInj (KindK src) src
180 , SourceInj (AST_Type src) src
187 -- , Syms ss (BetaT View)
191 Either (Error_Term src) (TermVT src ss '[])
192 readTe = Sym.readTerm CtxTyZ
194 -- | Lifted 'Doc.ansiIO' on 'IO.stdout'. Helper.
195 ansiIO :: MonadIO m => DocIO.TermIO -> m ()
196 ansiIO = liftIO . DocIO.runTermIO IO.stdout
198 -- * Type 'Error_Eval'
200 = Error_Eval_Cannot_prove_Constraint (TypeVT src)
208 -- Syms ss (BetaT View) =>
210 SourceInj (TypeVT src) src =>
213 S.StateT (LCC.State_Sym src ss)
214 (SS.StateT (TermVT src ss '[]) m)
215 (Either (Error_Eval src) (TermVT src ss '[]))
216 evalTe te@(TermVT (Term q t (TeSym sym))) = do
217 printTy (q #> t) >>= ansiIO . ("Type: " <>)
218 -- liftIO $ Text.putStrLn $ "View: " <> view (betaT $ sym CtxTeZ)
220 io:@aTy | Just HRefl <- proj_ConstKiTy @_ @IO io -> do
221 case proveConstraint q of
222 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q
224 a <- liftIO $ eval $ sym CtxTeZ
225 let r = TermVT $ teEval_uneval aTy a
229 r@(TermVT (Term q' t' (TeSym sym'))) <- completeTe te
230 printTy (q' #> t') >>= ansiIO . ("Type: Completed: " <>)
231 case proveConstraint q' of
232 Nothing -> return $ Left $ Error_Eval_Cannot_prove_Constraint $ TypeVT q'
234 let a = eval $ sym' CtxTeZ
243 -- Syms ss (BetaT View) =>
244 SourceInj (TypeVT src) src =>
247 S.StateT (LCC.State_Sym src ss)
248 (SS.StateT (TermVT src ss '[]) m)
251 liftIO $ putStrLn "completeTe"
252 st :: TermVT src ss '[] <- MC.get
253 case betaTerms $ G.BinTree0 t `G.BinTree2` G.BinTree0 st of
255 liftIO $ putStrLn "completeTe: Left"
258 liftIO $ putStrLn "completeTe: Right"
262 forall src ss m vs t d.
268 S.StateT (LCC.State_Sym src ss) m d
270 (impsTy, _ :: Sym.ModulesTy src) <- MC.get
273 { config_Doc_Type_vars_numbering = False
274 , config_Doc_Type_imports = impsTy
275 } 0 ty <> Doc.newline
277 printTe :: Source src => MonadIO m => Type src vs a -> a -> m ()
279 case proveConstraint $ LCC.Sym.tyWriteable
280 (allocVarsR (lenVars aTy) $ LCC.Sym.tyContext_Write @_ @'[] ~> LCC.Sym.tyANSI_IO) aTy of
281 Just Dict -> ansiIO $ write a Write.inh
283 case proveConstraint $ Sym.tyShow aTy of
284 Nothing -> putStrLn $ "No Show instance for type: " <> show aTy
291 -- /Read Eval Print Loop/ monad.
292 newtype REPL src ss a
294 { unREPL :: S.StateT (LCC.State_Sym src ss)
295 (SS.StateT (TermVT src ss '[])
302 -- , MonadState State_REPL
305 instance MonadTrans (REPL src ss) where
306 lift = REPL . lift . lift
308 type instance MC.CanDo (REPL src ss) (MC.EffState (LCC.State_Sym src ss)) = 'False
309 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.Modules src ss)) = 'False
310 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.Imports ns, Sym.ModulesTy src)) = 'False
311 type instance MC.CanDo (REPL src ss) (MC.EffState (Sym.TermVT src ss '[])) = 'False
312 -- type instance MC.CanDo (REPL src ss) (MC.EffState (EvalVT src)) = 'False
315 -- * Type 'State_REPL'
316 data State_REPL src ss
318 { state_repl_terms :: LCC.State_Sym src ss
319 , state_repl_db :: db
322 -- State_REPL src ss db
323 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
324 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (State_REPL src ss db) m) where
325 stateN _px = S.StateT . SS.state
327 -- LCC.State_Sym src ss
328 type instance MC.CanDo (S.StateT (State_REPL src ss db) m) (MC.EffState (State_REPL src ss db)) = 'True
329 instance Monad m => MC.MonadStateN 'MC.Zero (State_REPL src ss db) (S.StateT (LCC.State_Sym src ss) m) where
330 stateN _px f = S.StateT $ SS.state $ \st ->
331 (\a -> st{state_repl_terms=a}) <$> f (state_repl_terms st)
335 readLine :: String -> REPL src ss (Maybe String)
337 line <- REPL . lift . lift $ getInputLine prompt
339 Just l@(':':_) -> return $ Just l
340 Just l@(_:_) | L.last l == ' ' -> readLines l
341 Just l -> return $ Just l
342 Nothing -> return Nothing
344 readLines :: String -> REPL src ss (Maybe String)
346 line <- REPL . lift . lift $ getInputLine ""
348 Just l@(_:_) | L.last l == ' ' -> readLines $ acc <> l
349 Just l -> return $ Just $ acc <> l
350 Nothing -> return $ Just acc
361 Sym.Imports Sym.NameTy ->
362 Sym.Modules src ss -> d
363 docModules imps (Sym.Modules mods) =
365 (\p m doc -> docModule imps p m <> doc)
376 Sym.Imports Sym.NameTy ->
377 Sym.PathMod -> Sym.Module src ss -> d
378 docModule imps m Sym.ByFixity
383 go docFixityInfix byInfix <>
384 go docFixityPrefix byPrefix <>
385 go docFixityPostfix byPostfix
387 go :: (fixy -> d) -> ModuleFixy src ss fixy -> d
395 docFixy token_fixity <>
396 Doc.space <> Doc.bold (Doc.yellower "::") <> Doc.space <>
397 docTokenTerm imps (t Sym.noSource) <>
407 Sym.Imports Sym.NameTy ->
408 Sym.Token_Term src ss -> d
409 docTokenTerm imps t =
410 case Sym.readTerm CtxTyZ (G.BinTree0 t) of
411 Left{} -> error "[BUG] docTokenTerm: readTerm failed"
412 Right (Sym.TermVT te) ->
413 Sym.docType Sym.config_Doc_Type
414 { config_Doc_Type_vars_numbering = False
415 , config_Doc_Type_imports = imps
416 } 0 $ Sym.typeOfTerm te
418 docFixityInfix :: (Doc.Decorable t, Doc.Colorable t, Doc.Textable t) => Infix -> t
419 docFixityInfix = \case
420 Sym.Infix Nothing 5 -> Doc.empty
425 Sym.AssocB Sym.SideL -> "l"
426 Sym.AssocB Sym.SideR -> "r" in
427 Doc.magenta $ " infix" <> maybe Doc.empty docAssoc a <>
428 Doc.space <> Doc.bold (Doc.bluer (Doc.int p))
429 docFixityPrefix :: (Doc.Decorable t, Doc.Colorable t, Doc.Textable t) => Unifix -> t
430 docFixityPrefix p = Doc.magenta $ " prefix " <> Doc.bold (Doc.bluer (Doc.int $ Sym.unifix_prece p))
431 docFixityPostfix :: (Doc.Decorable t, Doc.Colorable t, Doc.Textable t) => Unifix -> t
432 docFixityPostfix p = Doc.magenta $ " postfix " <> Doc.bold (Doc.bluer (Doc.int $ Sym.unifix_prece p))
437 PathMod -> NameTe -> d
438 docPathTe ms (NameTe n) =
440 L.intersperse (Doc.charH '.') $
441 ((\(NameMod m) -> Doc.textH m) <$> ms) <>
442 [(if isOp n then id else Doc.yellower) $ Doc.text n]
444 isOp = T.all $ \case '_' -> True; '\'' -> True; c -> Char.isAlphaNum c
451 let sym@(LCC.State_Sym (impsTy,_modsTy) (_impsTe,patchModsTe -> modsTe)) =
452 LCC.state_sym @LCC.Sym.SRC @LCC.Sym.SS
453 (`Doc.ansiIO` IO.stderr) $ docModules impsTy modsTe
454 let arg = Text.unwords $ Text.pack <$> args
455 ast <- printError $ parseTe sym arg
457 ast <- (foldr1 G.BinTree2 <$>) $ forM args $ \arg -> do
458 printError $ parseTe sym $ Text.pack arg
460 _te <- printError $ readTe ast
464 forM_ args $ \arg -> do
465 ast <- printError $ parseTe (impsTy, modsTy) (impsTe, modsTe) $ Text.pack arg
466 te <- printError $ readTe ast
470 patchModsTe = Sym.deleteDefTermInfix ([] `Mod` "$")
472 printError :: Show err => MonadIO m => Either err a -> m a
473 printError (Left err) = liftIO $ error $ show err
474 printError (Right a) = return a
480 G.Gram_Source src (G src ss m) =>
481 Gram_Term src ss (G src ss m) =>
482 LCC.State_Sym src ss ->
483 Text -> Either (P.ParseError Char P.Dec) (Command src ss)
487 P.runParserT g "" inp
489 g :: G src ss Identity (Command src ss)
491 G.try (Command_Def <$> Sym.g_NameTe <* G.lexeme (G.char '=') <*> Sym.g_term <* G.eoi) G.<+>
492 (Command_Eval <$> Sym.g_term <* G.eoi)
496 evalTeUnit :: Source src => SymInj ss () => TermVT src ss '[]
497 evalTeUnit = TermVT $ Sym.teUnit -- Term noConstraint Sym.tyUnit $ teSym @() $ Sym.unit
500 evalTeUnit :: Source src => EvalVT src
501 evalTeUnit = EvalVT (Sym.tyUnit @_ @'[]) $ eval Sym.unit
504 data EvalVT src = forall vs t. EvalVT (Type src vs t) t
507 SourceInj (TypeVT src) src =>
511 Either (Error_Beta src) (EvalVT src)
512 appEvalVT (EvalVT tf te_fun) (EvalVT ta te_arg) =
513 let (tf',ta') = appendVars tf ta in
515 Nothing -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf'
518 (Error_Beta_Unify `left`) $
519 case (unQualsTy af, unQualsTy ta') of
520 (TypeK af', TypeK ta'') -> unifyType mempty af' ta''
521 let tf'' = subst mgu tf'
522 let ta'' = subst mgu ta'
523 appEval tf'' te_fun ta'' te_arg $ \tr te_res ->
524 normalizeVarsTy tr $ \tr' ->
528 forall src vs fun arg ret.
529 SourceInj (TypeVT src) src =>
531 Type src vs fun -> fun ->
532 Type src vs arg -> arg ->
533 (forall res. Type src vs res -> res -> ret) ->
534 Either (Error_Beta src) ret
535 appEval tf fun ta arg k =
537 a2b :@ a2b_a :@ a2b_b
538 | Just HRefl <- proj_ConstKiTy @(K (->)) @(->) a2b ->
539 case a2b_a `eqType` ta of
540 Nothing -> Left $ Error_Beta_Type_mismatch (TypeVT a2b_a) (TypeVT ta)
541 Just Refl -> Right $ k a2b_b $ fun arg
542 _ -> Left $ Error_Beta_Term_not_a_function $ TypeVT tf
547 -- * Class 'Sym_Eval'
548 type instance Sym Eval = Sym_Eval
549 class Sym_Eval term where
550 uneval :: a -> term a
551 default uneval :: Sym_Eval (UnT term) => Trans term => a -> term a
552 uneval = trans . uneval
555 instance Sym_Eval Eval where
558 instance Sym_Eval View where
559 uneval = View $ \_p _v -> "()"
560 instance (Sym_Eval r1, Sym_Eval r2) => Sym_Eval (Dup r1 r2) where
561 uneval = uneval `Dup` uneval
565 instance (Sym_Eval term, Sym_Lambda term) => Sym_Eval (BetaT term)
568 instance NameTyOf Eval where
569 nameTyOf _c = [] `Mod` "Eval"
570 instance ClassInstancesFor Eval where
571 instance TypeInstancesFor Eval
572 instance FixityOf Eval
577 ) => Gram_Term_AtomsFor src ss g Eval where
578 instance ModuleFor src ss Eval
581 tyEval :: Source src => LenInj vs => Type src vs Eval
582 tyEval = tyConst @(K Eval) @Eval
586 Source src => SymInj ss Eval =>
587 Type src vs a -> a ->
588 Term src ss ts vs (() #> a)
590 Term (noConstraintLen $ lenVars ty) ty $
592 TeSym $ \_c -> uneval a