type-checked quasiquoters
This commit is contained in:
@@ -13,10 +13,12 @@ errors and the family of RLPC monads.
|
|||||||
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
|
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
|
||||||
module Compiler.RLPC
|
module Compiler.RLPC
|
||||||
( RLPC
|
( RLPC
|
||||||
, RLPCT
|
, RLPCT(..)
|
||||||
, RLPCIO
|
, RLPCIO
|
||||||
, RLPCOptions(RLPCOptions)
|
, RLPCOptions(RLPCOptions)
|
||||||
, RlpcError(..)
|
, RlpcError(..)
|
||||||
|
, IsRlpcError(..)
|
||||||
|
, rlpc
|
||||||
, addFatal
|
, addFatal
|
||||||
, addWound
|
, addWound
|
||||||
, MonadErrorful
|
, MonadErrorful
|
||||||
@@ -135,6 +137,9 @@ addRlpcWound = addWound . liftRlpcErr
|
|||||||
addRlpcFatal :: (IsRlpcError e, Monad m) => e -> RLPCT RlpcError m ()
|
addRlpcFatal :: (IsRlpcError e, Monad m) => e -> RLPCT RlpcError m ()
|
||||||
addRlpcFatal = addWound . liftRlpcErr
|
addRlpcFatal = addWound . liftRlpcErr
|
||||||
|
|
||||||
|
rlpc :: (Monad m) => ErrorfulT e m a -> RLPCT e m a
|
||||||
|
rlpc = RLPCT . ReaderT . const
|
||||||
|
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
instance Default RLPCOptions where
|
instance Default RLPCOptions where
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ module Core.HindleyMilner
|
|||||||
( Context'
|
( Context'
|
||||||
, infer
|
, infer
|
||||||
, check
|
, check
|
||||||
, checkProg
|
, checkCoreProg
|
||||||
|
, checkCoreProgR
|
||||||
, TypeError(..)
|
, TypeError(..)
|
||||||
, HMError
|
, HMError
|
||||||
)
|
)
|
||||||
@@ -47,6 +48,10 @@ data TypeError
|
|||||||
| TyErrMissingTypeSig Name
|
| TyErrMissingTypeSig Name
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- TODO:
|
||||||
|
instance IsRlpcError TypeError where
|
||||||
|
liftRlpcErr = RlpcErr . 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@.
|
||||||
type HMError = Errorful TypeError
|
type HMError = Errorful TypeError
|
||||||
@@ -69,8 +74,8 @@ check g t1 e = do
|
|||||||
|
|
||||||
-- | Typecheck program. I plan to allow for *some* inference in the future, but
|
-- | Typecheck program. I plan to allow for *some* inference in the future, but
|
||||||
-- in the mean time all top-level binders must have a type annotation.
|
-- in the mean time all top-level binders must have a type annotation.
|
||||||
checkProg :: Program' -> HMError ()
|
checkCoreProg :: Program' -> HMError ()
|
||||||
checkProg p = scDefs
|
checkCoreProg p = scDefs
|
||||||
& traverse_ k
|
& traverse_ k
|
||||||
where
|
where
|
||||||
scDefs = p ^. programScDefs
|
scDefs = p ^. programScDefs
|
||||||
@@ -82,8 +87,11 @@ checkProg p = scDefs
|
|||||||
Nothing -> addFatal $ TyErrMissingTypeSig scname
|
Nothing -> addFatal $ TyErrMissingTypeSig scname
|
||||||
where scname = sc ^. _lhs._1
|
where scname = sc ^. _lhs._1
|
||||||
|
|
||||||
checkRlpcProg :: Program' -> RLPC TypeError ()
|
-- | @checkCoreProgR p@ returns @p@ if @p@ successfully typechecks.
|
||||||
checkRlpcProg = undefined
|
checkCoreProgR :: Program' -> RLPC RlpcError Program'
|
||||||
|
checkCoreProgR p = do
|
||||||
|
liftRlpcErrs . rlpc . checkCoreProg $ p
|
||||||
|
pure p
|
||||||
|
|
||||||
-- | Infer the type of an expression under some context.
|
-- | Infer the type of an expression under some context.
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ Description : Core quasiquoters
|
|||||||
module Core.TH
|
module Core.TH
|
||||||
( coreExpr
|
( coreExpr
|
||||||
, coreProg
|
, coreProg
|
||||||
|
, coreProgT
|
||||||
, core
|
, core
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
@@ -18,8 +19,11 @@ import Data.Default.Class (def)
|
|||||||
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.HindleyMilner (checkCoreProgR)
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: write in terms of a String -> QuasiQuoter
|
||||||
|
|
||||||
core :: QuasiQuoter
|
core :: QuasiQuoter
|
||||||
core = QuasiQuoter
|
core = QuasiQuoter
|
||||||
{ quoteExp = qCore
|
{ quoteExp = qCore
|
||||||
@@ -44,6 +48,15 @@ coreExpr = QuasiQuoter
|
|||||||
, quoteDec = error "core quasiquotes may only be used in expressions"
|
, quoteDec = error "core quasiquotes may only be used in expressions"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- | Type-checked @coreProg@
|
||||||
|
coreProgT :: QuasiQuoter
|
||||||
|
coreProgT = QuasiQuoter
|
||||||
|
{ quoteExp = qCoreProgT
|
||||||
|
, 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"
|
||||||
|
}
|
||||||
|
|
||||||
qCore :: String -> Q Exp
|
qCore :: String -> Q Exp
|
||||||
qCore s = case parse (T.pack s) of
|
qCore s = case parse (T.pack s) of
|
||||||
Left e -> error (show e)
|
Left e -> error (show e)
|
||||||
@@ -59,9 +72,16 @@ qCoreExpr s = case parseExpr (T.pack s) of
|
|||||||
parseExpr = evalRLPC def . (lexCore >=> parseCoreExpr)
|
parseExpr = evalRLPC def . (lexCore >=> parseCoreExpr)
|
||||||
|
|
||||||
qCoreProg :: String -> Q Exp
|
qCoreProg :: String -> Q Exp
|
||||||
qCoreProg s = case parseProg (T.pack s) of
|
qCoreProg s = case parse (T.pack s) of
|
||||||
Left e -> error (show e)
|
Left e -> error (show e)
|
||||||
Right (m,ts) -> lift m
|
Right (m,ts) -> lift m
|
||||||
where
|
where
|
||||||
parseProg = evalRLPC def . (lexCoreR >=> parseCoreProgR)
|
parse = evalRLPC def . (lexCoreR >=> parseCoreProgR)
|
||||||
|
|
||||||
|
qCoreProgT :: String -> Q Exp
|
||||||
|
qCoreProgT s = case parse (T.pack s) of
|
||||||
|
Left e -> error (show e)
|
||||||
|
Right (m,_) -> lift m
|
||||||
|
where
|
||||||
|
parse = evalRLPC def . (lexCoreR >=> parseCoreProgR >=> checkCoreProgR)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user