when the "Test suite rlp-test: PASS" hits
i'm like atlas and the world is writing two lines of code
This commit is contained in:
@@ -73,6 +73,9 @@ library
|
|||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
default-language: GHC2021
|
default-language: GHC2021
|
||||||
|
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
|
||||||
executable rlpc
|
executable rlpc
|
||||||
import: warnings
|
import: warnings
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ module Compiler.RLPC
|
|||||||
, flagDDumpOpts
|
, flagDDumpOpts
|
||||||
, flagDDumpAST
|
, flagDDumpAST
|
||||||
, def
|
, def
|
||||||
|
, liftErrorful
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -47,6 +48,7 @@ import Control.Monad.Errorful
|
|||||||
import Compiler.RlpcError
|
import Compiler.RlpcError
|
||||||
import Data.Functor.Identity
|
import Data.Functor.Identity
|
||||||
import Data.Default.Class
|
import Data.Default.Class
|
||||||
|
import Data.Foldable
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Data.Hashable (Hashable)
|
import Data.Hashable (Hashable)
|
||||||
import Data.HashSet (HashSet)
|
import Data.HashSet (HashSet)
|
||||||
@@ -54,26 +56,44 @@ import Data.HashSet qualified as S
|
|||||||
import Data.Coerce
|
import Data.Coerce
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
import Lens.Micro.TH
|
import Lens.Micro.TH
|
||||||
|
import System.Exit
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
newtype RLPCT m a = RLPCT {
|
newtype RLPCT m a = RLPCT {
|
||||||
runRLPCT :: ReaderT RLPCOptions (ErrorfulT RlpcError m) a
|
runRLPCT :: ReaderT RLPCOptions (ErrorfulT RlpcError m) a
|
||||||
}
|
}
|
||||||
|
deriving (Functor, Applicative, Monad)
|
||||||
|
|
||||||
type RLPC = RLPCT Identity
|
type RLPC = RLPCT Identity
|
||||||
|
|
||||||
type RLPCIO = RLPCT IO
|
type RLPCIO = RLPCT IO
|
||||||
|
|
||||||
instance Functor (RLPCT m) where
|
evalRLPC :: RLPCOptions
|
||||||
instance Applicative (RLPCT m) where
|
-> RLPC a
|
||||||
instance Monad (RLPCT m) where
|
-> (Maybe a, [RlpcError])
|
||||||
|
evalRLPC opt r = runRLPCT r
|
||||||
|
& flip runReaderT opt
|
||||||
|
& runErrorful
|
||||||
|
|
||||||
evalRLPC = undefined
|
evalRLPCT :: (Monad m)
|
||||||
|
=> RLPCOptions
|
||||||
|
-> RLPCT m a
|
||||||
|
-> m (Maybe a, [RlpcError])
|
||||||
evalRLPCT = undefined
|
evalRLPCT = undefined
|
||||||
evalRLPCIO = undefined
|
|
||||||
|
|
||||||
liftErrorful :: ErrorfulT e m a -> RLPCT m a
|
evalRLPCIO :: RLPCOptions -> RLPCIO a -> IO a
|
||||||
liftErrorful e = undefined
|
evalRLPCIO opt r = do
|
||||||
|
(ma,es) <- evalRLPCT opt r
|
||||||
|
putRlpcErrs es
|
||||||
|
case ma of
|
||||||
|
Just x -> pure x
|
||||||
|
Nothing -> die "Failed, no code compiled."
|
||||||
|
|
||||||
|
putRlpcErrs :: [RlpcError] -> IO ()
|
||||||
|
putRlpcErrs = traverse_ print
|
||||||
|
|
||||||
|
liftErrorful :: (Monad m, IsRlpcError e) => ErrorfulT e m a -> RLPCT m a
|
||||||
|
liftErrorful e = RLPCT $ lift (liftRlpcErrors e)
|
||||||
|
|
||||||
data RLPCOptions = RLPCOptions
|
data RLPCOptions = RLPCOptions
|
||||||
{ _rlpcLogFile :: Maybe FilePath
|
{ _rlpcLogFile :: Maybe FilePath
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
|
||||||
module Compiler.RlpcError
|
module Compiler.RlpcError
|
||||||
( IsRlpcError(..)
|
( IsRlpcError(..)
|
||||||
, MsgEnvelope(..)
|
, MsgEnvelope(..)
|
||||||
@@ -8,11 +9,16 @@ module Compiler.RlpcError
|
|||||||
, msgSpan
|
, msgSpan
|
||||||
, msgDiagnostic
|
, msgDiagnostic
|
||||||
, msgSeverity
|
, msgSeverity
|
||||||
|
, liftRlpcErrors
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Control.Monad.Errorful
|
import Control.Monad.Errorful
|
||||||
import Lens.Micro.TH
|
import Data.Text (Text)
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import GHC.Exts (IsString(..))
|
||||||
|
import Lens.Micro.Platform
|
||||||
|
import Lens.Micro.Platform.Internal
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
data MsgEnvelope e = MsgEnvelope
|
data MsgEnvelope e = MsgEnvelope
|
||||||
@@ -21,10 +27,17 @@ data MsgEnvelope e = MsgEnvelope
|
|||||||
, _msgSeverity :: Severity
|
, _msgSeverity :: Severity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newtype RlpcError = Text [Text]
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
instance IsString RlpcError where
|
||||||
|
fromString = Text . pure . T.pack
|
||||||
|
|
||||||
class IsRlpcError e where
|
class IsRlpcError e where
|
||||||
liftRlpcError :: e -> RlpcError
|
liftRlpcError :: e -> RlpcError
|
||||||
|
|
||||||
data RlpcError
|
instance IsRlpcError RlpcError where
|
||||||
|
liftRlpcError = id
|
||||||
|
|
||||||
data Severity = SevWarning
|
data Severity = SevWarning
|
||||||
| SevError
|
| SevError
|
||||||
@@ -37,3 +50,8 @@ data SrcSpan = SrcSpan
|
|||||||
|
|
||||||
makeLenses ''MsgEnvelope
|
makeLenses ''MsgEnvelope
|
||||||
|
|
||||||
|
liftRlpcErrors :: (Functor m, IsRlpcError e)
|
||||||
|
=> ErrorfulT e m a
|
||||||
|
-> ErrorfulT RlpcError m a
|
||||||
|
liftRlpcErrors = mapErrorful liftRlpcError
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ module Control.Monad.Errorful
|
|||||||
, runErrorfulT
|
, runErrorfulT
|
||||||
, Errorful
|
, Errorful
|
||||||
, runErrorful
|
, runErrorful
|
||||||
, mapErrors
|
, mapErrorful
|
||||||
, MonadErrorful(..)
|
, MonadErrorful(..)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
@@ -60,6 +60,11 @@ instance (Monad m) => Monad (ErrorfulT e m) where
|
|||||||
Just x -> runErrorfulT (k x)
|
Just x -> runErrorfulT (k x)
|
||||||
Nothing -> pure (Nothing, es)
|
Nothing -> pure (Nothing, es)
|
||||||
|
|
||||||
mapErrors :: (Monad m) => (e -> e') -> ErrorfulT e m a -> ErrorfulT e' m a
|
mapErrorful :: (Functor m) => (e -> e') -> ErrorfulT e m a -> ErrorfulT e' m a
|
||||||
mapErrors f m = undefined
|
mapErrorful f (ErrorfulT m) = ErrorfulT $
|
||||||
|
m & mapped . _2 . mapped %~ f
|
||||||
|
|
||||||
|
-- when microlens-pro drops we can write this as
|
||||||
|
-- mapErrorful f = coerced . mapped . _2 . mappd %~ f
|
||||||
|
-- lol
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ import Core.Syntax
|
|||||||
import Core.TH
|
import Core.TH
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
fac3 = undefined
|
-- fac3 = undefined
|
||||||
sumList = undefined
|
-- sumList = undefined
|
||||||
constDivZero = undefined
|
-- constDivZero = undefined
|
||||||
idCase = undefined
|
-- idCase = undefined
|
||||||
|
|
||||||
{--
|
---
|
||||||
|
|
||||||
letrecExample :: Program'
|
letrecExample :: Program'
|
||||||
letrecExample = [coreProg|
|
letrecExample = [coreProg|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import Control.Monad (foldM, void)
|
|||||||
import Control.Monad.Errorful (Errorful, addFatal)
|
import Control.Monad.Errorful (Errorful, addFatal)
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Control.Monad.Utils (mapAccumLM)
|
import Control.Monad.Utils (mapAccumLM)
|
||||||
|
import Text.Printf
|
||||||
import Core.Syntax
|
import Core.Syntax
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -48,8 +49,20 @@ data TypeError
|
|||||||
| TyErrMissingTypeSig Name
|
| TyErrMissingTypeSig Name
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
-- TODO:
|
|
||||||
instance IsRlpcError TypeError where
|
instance IsRlpcError TypeError where
|
||||||
|
liftRlpcError = \case
|
||||||
|
-- todo: use anti-parser instead of show
|
||||||
|
TyErrCouldNotUnify t u -> Text
|
||||||
|
[ T.pack $ printf "Could not match type `%s' with `%s'."
|
||||||
|
(show t) (show u)
|
||||||
|
, "Expected: " <> tshow t
|
||||||
|
, "Got: " <> tshow u
|
||||||
|
]
|
||||||
|
TyErrRecursiveType t x -> Text
|
||||||
|
[ T.pack $ printf "recursive type error lol"
|
||||||
|
]
|
||||||
|
|
||||||
|
where tshow = T.pack . show
|
||||||
|
|
||||||
-- | Synonym for @Errorful [TypeError]@. This means an @HMError@ action may
|
-- | Synonym for @Errorful [TypeError]@. This means an @HMError@ action may
|
||||||
-- throw any number of fatal or nonfatal errors. Run with @runErrorful@.
|
-- throw any number of fatal or nonfatal errors. Run with @runErrorful@.
|
||||||
@@ -87,10 +100,10 @@ checkCoreProg p = scDefs
|
|||||||
where scname = sc ^. _lhs._1
|
where scname = sc ^. _lhs._1
|
||||||
|
|
||||||
-- | @checkCoreProgR p@ returns @p@ if @p@ successfully typechecks.
|
-- | @checkCoreProgR p@ returns @p@ if @p@ successfully typechecks.
|
||||||
-- checkCoreProgR :: Program' -> RLPC Program'
|
checkCoreProgR :: Program' -> RLPC Program'
|
||||||
checkCoreProgR = undefined
|
checkCoreProgR p = do
|
||||||
|
liftErrorful (checkCoreProg p)
|
||||||
{-# WARNING checkCoreProgR "unimpl" #-}
|
pure p
|
||||||
|
|
||||||
-- | Infer the type of an expression under some context.
|
-- | Infer the type of an expression under some context.
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -169,17 +169,13 @@ lexWith f (AlexPn _ y x,_,_,s) l = pure $ Located y x l (f $ T.take l s)
|
|||||||
-- | The main lexer driver.
|
-- | The main lexer driver.
|
||||||
lexCore :: Text -> RLPC [Located CoreToken]
|
lexCore :: Text -> RLPC [Located CoreToken]
|
||||||
lexCore s = case m of
|
lexCore s = case m of
|
||||||
Left e -> undefined
|
Left e -> error "core lex error"
|
||||||
Right ts -> pure ts
|
Right ts -> pure ts
|
||||||
where
|
where
|
||||||
m = runAlex s lexStream
|
m = runAlex s lexStream
|
||||||
|
|
||||||
{-# WARNING lexCore "unimpl" #-}
|
|
||||||
|
|
||||||
lexCoreR :: Text -> RLPC [Located CoreToken]
|
lexCoreR :: Text -> RLPC [Located CoreToken]
|
||||||
lexCoreR t = undefined
|
lexCoreR = lexCore
|
||||||
|
|
||||||
{-# WARNING lexCoreR "unimpl" #-}
|
|
||||||
|
|
||||||
-- | @lexCore@, but the tokens are stripped of location info. Useful for
|
-- | @lexCore@, but the tokens are stripped of location info. Useful for
|
||||||
-- debugging
|
-- debugging
|
||||||
@@ -200,9 +196,11 @@ data ParseError = ParErrLexical String
|
|||||||
|
|
||||||
-- TODO:
|
-- TODO:
|
||||||
instance IsRlpcError SrcError where
|
instance IsRlpcError SrcError where
|
||||||
|
liftRlpcError = Text . pure . T.pack . show
|
||||||
|
|
||||||
-- TODO:
|
-- TODO:
|
||||||
instance IsRlpcError ParseError where
|
instance IsRlpcError ParseError where
|
||||||
|
liftRlpcError = Text . pure . T.pack . show
|
||||||
|
|
||||||
alexEOF :: Alex (Located CoreToken)
|
alexEOF :: Alex (Located CoreToken)
|
||||||
alexEOF = Alex $ \ st@(AlexState { alex_pos = AlexPn _ y x }) ->
|
alexEOF = Alex $ \ st@(AlexState { alex_pos = AlexPn _ y x }) ->
|
||||||
|
|||||||
@@ -189,7 +189,9 @@ Con : '(' consym ')' { $2 }
|
|||||||
{
|
{
|
||||||
|
|
||||||
parseError :: [Located CoreToken] -> RLPC a
|
parseError :: [Located CoreToken] -> RLPC a
|
||||||
parseError (Located y x l _ : _) = undefined
|
parseError (Located y x l t : _) =
|
||||||
|
error $ show y <> ":" <> show x
|
||||||
|
<> ": parse error at token `" <> show t <> "'"
|
||||||
|
|
||||||
{-# WARNING parseError "unimpl" #-}
|
{-# WARNING parseError "unimpl" #-}
|
||||||
|
|
||||||
@@ -217,9 +219,7 @@ singletonScDef :: (Hashable b) => ScDef b -> Program b
|
|||||||
singletonScDef sc = insScDef sc mempty
|
singletonScDef sc = insScDef sc mempty
|
||||||
|
|
||||||
parseCoreProgR :: [Located CoreToken] -> RLPC Program'
|
parseCoreProgR :: [Located CoreToken] -> RLPC Program'
|
||||||
parseCoreProgR a = undefined
|
parseCoreProgR = parseCoreProg
|
||||||
|
|
||||||
{-# WARNING parseCoreProgR "unimpl" #-}
|
|
||||||
|
|
||||||
happyBind :: RLPC a -> (a -> RLPC b) -> RLPC b
|
happyBind :: RLPC a -> (a -> RLPC b) -> RLPC b
|
||||||
happyBind m k = m >>= k
|
happyBind m k = m >>= k
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ module Core.TH
|
|||||||
( coreExpr
|
( coreExpr
|
||||||
, coreProg
|
, coreProg
|
||||||
, coreProgT
|
, coreProgT
|
||||||
, core
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -14,65 +13,38 @@ import Language.Haskell.TH
|
|||||||
import Language.Haskell.TH.Syntax hiding (Module)
|
import Language.Haskell.TH.Syntax hiding (Module)
|
||||||
import Language.Haskell.TH.Quote
|
import Language.Haskell.TH.Quote
|
||||||
import Control.Monad ((>=>))
|
import Control.Monad ((>=>))
|
||||||
|
import Control.Monad.IO.Class
|
||||||
|
import Control.Arrow ((>>>))
|
||||||
import Compiler.RLPC
|
import Compiler.RLPC
|
||||||
import Data.Default.Class (def)
|
import Data.Default.Class (def)
|
||||||
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Core.Parse
|
import Core.Parse
|
||||||
import Core.Lex
|
import Core.Lex
|
||||||
import Core.Syntax (Expr(Var))
|
import Core.Syntax
|
||||||
import Core.HindleyMilner (checkCoreProgR)
|
import Core.HindleyMilner (checkCoreProgR)
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: write in terms of a String -> QuasiQuoter
|
|
||||||
|
|
||||||
core :: QuasiQuoter
|
|
||||||
core = QuasiQuoter
|
|
||||||
{ quoteExp = qCore
|
|
||||||
, quotePat = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteType = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteDec = error "core quasiquotes may only be used in expressions"
|
|
||||||
}
|
|
||||||
|
|
||||||
coreProg :: QuasiQuoter
|
coreProg :: QuasiQuoter
|
||||||
coreProg = QuasiQuoter
|
coreProg = mkqq $ lexCoreR >=> parseCoreProgR
|
||||||
{ quoteExp = qCoreProg
|
|
||||||
, quotePat = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteType = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteDec = error "core quasiquotes may only be used in expressions"
|
|
||||||
}
|
|
||||||
|
|
||||||
coreExpr :: QuasiQuoter
|
coreExpr :: QuasiQuoter
|
||||||
coreExpr = QuasiQuoter
|
coreExpr = mkqq $ lexCoreR >=> parseCoreExpr
|
||||||
{ quoteExp = qCoreExpr
|
|
||||||
, quotePat = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteType = error "core quasiquotes may only be used in expressions"
|
|
||||||
, quoteDec = error "core quasiquotes may only be used in expressions"
|
|
||||||
}
|
|
||||||
|
|
||||||
-- | Type-checked @coreProg@
|
-- | Type-checked @coreProg@
|
||||||
coreProgT :: QuasiQuoter
|
coreProgT :: QuasiQuoter
|
||||||
coreProgT = QuasiQuoter
|
coreProgT = mkqq $ lexCoreR >=> parseCoreProgR >=> checkCoreProgR
|
||||||
{ quoteExp = qCoreProgT
|
|
||||||
|
mkqq :: (Lift a) => (Text -> RLPC a) -> QuasiQuoter
|
||||||
|
mkqq p = QuasiQuoter
|
||||||
|
{ quoteExp = mkq p
|
||||||
, quotePat = error "core quasiquotes may only be used in expressions"
|
, quotePat = error "core quasiquotes may only be used in expressions"
|
||||||
, quoteType = error "core quasiquotes may only be used in expressions"
|
, quoteType = error "core quasiquotes may only be used in expressions"
|
||||||
, quoteDec = error "core quasiquotes may only be used in expressions"
|
, quoteDec = error "core quasiquotes may only be used in expressions"
|
||||||
}
|
}
|
||||||
|
|
||||||
qCore :: String -> Q Exp
|
mkq :: (Lift a) => (Text -> RLPC a) -> String -> Q Exp
|
||||||
qCore s = undefined
|
mkq parse s = case evalRLPC def (parse $ T.pack s) of
|
||||||
|
(Just a, _) -> lift a
|
||||||
{-# WARNING qCore "unimpl" #-}
|
(Nothing, _) -> error "todo: aaahhbbhjhbdjhabsjh"
|
||||||
|
|
||||||
qCoreExpr :: String -> Q Exp
|
|
||||||
qCoreExpr s = undefined
|
|
||||||
|
|
||||||
{-# WARNING qCoreExpr "unimpl" #-}
|
|
||||||
|
|
||||||
qCoreProg :: String -> Q Exp
|
|
||||||
qCoreProg s = undefined
|
|
||||||
|
|
||||||
{-# WARNING qCoreProg "unimpl" #-}
|
|
||||||
|
|
||||||
qCoreProgT :: String -> Q Exp
|
|
||||||
qCoreProgT s = undefined
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,9 +38,13 @@ spec = do
|
|||||||
let e = [coreExpr|3|]
|
let e = [coreExpr|3|]
|
||||||
in check' [] (TyCon "Bool") e `shouldSatisfy` isLeft
|
in check' [] (TyCon "Bool") e `shouldSatisfy` isLeft
|
||||||
|
|
||||||
infer' :: Context' -> Expr' -> Either TypeError Type
|
infer' :: Context' -> Expr' -> Either [TypeError] Type
|
||||||
infer' g e = fmap fst . runErrorful $ infer g e
|
infer' g e = case runErrorful $ infer g e of
|
||||||
|
(Just t, _) -> Right t
|
||||||
|
(Nothing, es) -> Left es
|
||||||
|
|
||||||
check' :: Context' -> Type -> Expr' -> Either TypeError ()
|
check' :: Context' -> Type -> Expr' -> Either [TypeError] ()
|
||||||
check' g t e = fmap fst . runErrorful $ check g t e
|
check' g t e = case runErrorful $ check g t e of
|
||||||
|
(Just t, _) -> Right ()
|
||||||
|
(Nothing, es) -> Left es
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user