rc #13

Merged
crumbtoo merged 196 commits from dev into main 2024-02-13 13:22:23 -07:00
11 changed files with 112 additions and 79 deletions
Showing only changes of commit 1a881399ab - Show all commits

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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|

View File

@@ -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.
-- --

View File

@@ -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 }) ->

View File

@@ -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

View File

@@ -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

View File

@@ -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