Monadic shenanigans beginning.
This commit is contained in:
@@ -32,11 +32,13 @@ executable bang
|
|||||||
other-extensions: CPP,
|
other-extensions: CPP,
|
||||||
DeriveDataTypeable,
|
DeriveDataTypeable,
|
||||||
DeriveFunctor,
|
DeriveFunctor,
|
||||||
|
FlexibleInstances,
|
||||||
GeneralizedNewtypeDeriving,
|
GeneralizedNewtypeDeriving,
|
||||||
MagicHash,
|
MagicHash,
|
||||||
MultiParamTypeClasses,
|
MultiParamTypeClasses,
|
||||||
OverloadedStrings,
|
OverloadedStrings,
|
||||||
TemplateHaskell
|
TemplateHaskell,
|
||||||
|
UndecidableInstances
|
||||||
other-modules:
|
other-modules:
|
||||||
Bang.CommandLine,
|
Bang.CommandLine,
|
||||||
Bang.Syntax.Lexer,
|
Bang.Syntax.Lexer,
|
||||||
|
|||||||
107
src/Bang/Monad.hs
Normal file
107
src/Bang/Monad.hs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
{-# LANGUAGE DeriveFunctor #-}
|
||||||
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
module Bang.Monad(
|
||||||
|
Compiler
|
||||||
|
, (==>), (==>|)
|
||||||
|
, genName, genTypeRef, genVarRef
|
||||||
|
, warn, err
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Bang.Syntax.AST
|
||||||
|
import Bang.Syntax.Location(unknownLocation)
|
||||||
|
import Bang.Utils.Pretty(BangDoc)
|
||||||
|
import Data.Text.Lazy(pack)
|
||||||
|
import MonadLib
|
||||||
|
import Text.PrettyPrint.Annotated(Doc)
|
||||||
|
|
||||||
|
class BangError e where
|
||||||
|
ppError :: e -> BangDoc
|
||||||
|
|
||||||
|
class BangWarning w where
|
||||||
|
ppWarning :: w -> BangDoc
|
||||||
|
|
||||||
|
instance BangWarning w => BangError w where
|
||||||
|
ppError = ppWarning
|
||||||
|
|
||||||
|
data CompilerState state = CompilerState {
|
||||||
|
csNextIdent :: Word
|
||||||
|
, csPromoteWarnings :: Bool
|
||||||
|
, csWarnings :: [BangDoc]
|
||||||
|
, csPassState :: state
|
||||||
|
}
|
||||||
|
|
||||||
|
initialState :: CompilerState ()
|
||||||
|
initialState = CompilerState 1 False [] ()
|
||||||
|
|
||||||
|
newtype Compiler s a =
|
||||||
|
Compiler { unCompiler :: CompilerState s -> IO (CompilerState s, a) }
|
||||||
|
|
||||||
|
instance Applicative (Compiler s) where
|
||||||
|
pure a = Compiler (\ st -> return (st, a))
|
||||||
|
mf <*> ma = Compiler (\ st ->
|
||||||
|
do (st', f) <- unCompiler mf st
|
||||||
|
(st'', a) <- unCompiler ma st'
|
||||||
|
return (st'', f a))
|
||||||
|
|
||||||
|
instance Functor (Compiler s) where
|
||||||
|
fmap f m = return f <*> m
|
||||||
|
|
||||||
|
instance Monad (Compiler s) where
|
||||||
|
return a = Compiler (\ st -> return (st, a))
|
||||||
|
m >>= k = Compiler (\ st ->
|
||||||
|
do (st', a) <- unCompiler m st
|
||||||
|
unCompiler (k a) st')
|
||||||
|
|
||||||
|
class PassTransition s1 s2 where
|
||||||
|
transition :: s1 -> s2
|
||||||
|
|
||||||
|
(==>) :: PassTransition s1 s2 =>
|
||||||
|
Compiler s1 a ->
|
||||||
|
(a -> Compiler s2 b) ->
|
||||||
|
Compiler s1 b
|
||||||
|
m1 ==> k = Compiler (\ st ->
|
||||||
|
do (st', a) <- unCompiler m1 st
|
||||||
|
let next = k a
|
||||||
|
ps' = transition (csPassState st')
|
||||||
|
st'' = st'{ csPassState = ps' }
|
||||||
|
(_, b) <- unCompiler next st''
|
||||||
|
return (st', b))
|
||||||
|
|
||||||
|
(==>|) :: PassTransition s1 s2 =>
|
||||||
|
Compiler s1 a ->
|
||||||
|
Compiler s2 b ->
|
||||||
|
Compiler s1 b
|
||||||
|
m1 ==>| m2 = m1 ==> (const m2)
|
||||||
|
|
||||||
|
genName :: NameEnvironment -> Compiler s Name
|
||||||
|
genName env = Compiler (\ st ->
|
||||||
|
do let current = csNextIdent st
|
||||||
|
str = "gen:" ++ show current
|
||||||
|
res = Name unknownLocation env current (pack str)
|
||||||
|
return (st{ csNextIdent = current + 1 }, res))
|
||||||
|
|
||||||
|
genTypeRef :: Kind -> Compiler s Type
|
||||||
|
genTypeRef k = TypeRef unknownLocation k `fmap` genName TypeEnv
|
||||||
|
|
||||||
|
genVarRef :: Compiler s Expression
|
||||||
|
genVarRef = ReferenceExp unknownLocation `fmap` genName VarEnv
|
||||||
|
|
||||||
|
warn :: BangWarning w => w -> Compiler s ()
|
||||||
|
warn w = Compiler (\ st ->
|
||||||
|
if csPromoteWarnings st
|
||||||
|
then runError w
|
||||||
|
else runWarning w >> return (st, ()))
|
||||||
|
|
||||||
|
err :: BangError w => w -> Compiler s a
|
||||||
|
err w = Compiler (\ _ -> runError w)
|
||||||
|
|
||||||
|
runWarning :: BangWarning w => w -> IO ()
|
||||||
|
runWarning = undefined
|
||||||
|
|
||||||
|
runError :: BangError w => w -> IO a
|
||||||
|
runError = undefined
|
||||||
|
|
||||||
@@ -302,7 +302,6 @@ initialState tokenStream = ParserState {
|
|||||||
, psNextIdent = 1
|
, psNextIdent = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
instance StateM Parser ParserState where
|
instance StateM Parser ParserState where
|
||||||
get = Parser get
|
get = Parser get
|
||||||
set = Parser . set
|
set = Parser . set
|
||||||
|
|||||||
@@ -180,7 +180,12 @@ inferConstant c =
|
|||||||
| ConstantFloat _ <- c = IsIn "FloatLike" v
|
| ConstantFloat _ <- c = IsIn "FloatLike" v
|
||||||
return ([constraint], v)
|
return ([constraint], v)
|
||||||
|
|
||||||
inferExpression :: ClassEnvironment -> [Assumptions] ->
|
data ClassEnvironment = [Predicate] :=> Type
|
||||||
|
|
||||||
|
freshInst :: Scheme -> Infer ClassEnvironment
|
||||||
|
freshInst = undefined
|
||||||
|
|
||||||
|
inferExpression :: ClassEnvironment -> [Assumption] ->
|
||||||
Expression ->
|
Expression ->
|
||||||
Infer ([Predicate], Type)
|
Infer ([Predicate], Type)
|
||||||
inferExpression classEnv assumpts expr =
|
inferExpression classEnv assumpts expr =
|
||||||
|
|||||||
12
src/Bang/Utils/Pretty.hs
Normal file
12
src/Bang/Utils/Pretty.hs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module Bang.Utils.Pretty(
|
||||||
|
BangDoc
|
||||||
|
, Annotation(..)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Text.PrettyPrint.Annotated(Doc)
|
||||||
|
|
||||||
|
type BangDoc = Doc Annotation
|
||||||
|
|
||||||
|
data Annotation = KeywordAnnotation
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import Bang.CommandLine
|
import Bang.CommandLine
|
||||||
import Bang.Error(exit)
|
import Bang.Error(exit)
|
||||||
|
import Bang.Monad
|
||||||
import Bang.Syntax.AST(Module)
|
import Bang.Syntax.AST(Module)
|
||||||
import Bang.Syntax.Lexer(lexer)
|
import Bang.Syntax.Lexer(lexer)
|
||||||
import Bang.Syntax.Location
|
import Bang.Syntax.Location
|
||||||
|
|||||||
Reference in New Issue
Block a user