new grammar and adapted renamer

This commit is contained in:
sebastianselander 2023-03-22 12:45:51 +01:00
parent 88a4a934b8
commit 936cb1301f
15 changed files with 858 additions and 821 deletions

View file

@ -1,50 +1,91 @@
--------------------------------------------------------------------------------
-- * PROGRAM
--------------------------------------------------------------------------------
Program. Program ::= [Def] ;
--------------------------------------------------------------------------------
-- * TOP-LEVEL
--------------------------------------------------------------------------------
DBind. Def ::= Bind ;
DSig. Def ::= Sig ;
DData. Def ::= Data ;
separator Def ";" ;
Bind. Bind ::= Ident ":" Type ";"
Ident [Ident] "=" Exp ;
Sig. Sig ::= LIdent ":" Type ;
Data. Data ::= "data" Constr "where" "{" [Constructor] "}" ;
Bind. Bind ::= LIdent [LIdent] "=" Exp ;
Constructor. Constructor ::= Ident ":" Type ;
separator nonempty Constructor "" ;
--------------------------------------------------------------------------------
-- * TYPES
--------------------------------------------------------------------------------
TMono. Type1 ::= "_" Ident ;
TPol. Type1 ::= "'" Ident ;
TConstr. Type1 ::= Constr ;
TArr. Type ::= Type1 "->" Type ;
TLit. Type2 ::= UIdent ;
TVar. Type2 ::= TVar ;
TAll. Type1 ::= "forall" TVar "." Type ;
TIndexed. Type1 ::= Indexed ;
internal TEVar. Type1 ::= TEVar ;
TFun. Type ::= Type1 "->" Type ;
Constr. Constr ::= Ident "(" [Type] ")" ;
MkTVar. TVar ::= LIdent ;
internal MkTEVar. TEVar ::= LIdent ;
--------------------------------------------------------------------------------
-- * DATA TYPES
--------------------------------------------------------------------------------
Constructor. Constructor ::= UIdent ":" Type ;
Indexed. Indexed ::= UIdent "(" [Type] ")" ;
Data. Data ::= "data" Indexed "where" "{" [Constructor] "}" ;
--------------------------------------------------------------------------------
-- * EXPRESSIONS
--------------------------------------------------------------------------------
-- TODO: Move literal to its own thing since it's reused in Init as well.
EAnn. Exp5 ::= "(" Exp ":" Type ")" ;
EId. Exp4 ::= Ident ;
ELit. Exp4 ::= Literal ;
EId. Exp4 ::= LIdent ;
ELit. Exp4 ::= Lit ;
EApp. Exp3 ::= Exp3 Exp4 ;
EAdd. Exp1 ::= Exp1 "+" Exp2 ;
ELet. Exp ::= "let" Ident "=" Exp "in" Exp ;
EAbs. Exp ::= "\\" Ident "." Exp ;
ELet. Exp ::= "let" LIdent "=" Exp "in" Exp ;
EAbs. Exp ::= "\\" LIdent "." Exp ;
ECase. Exp ::= "case" Exp "of" "{" [Inj] "}";
LInt. Literal ::= Integer ;
--------------------------------------------------------------------------------
-- * LITERALS
--------------------------------------------------------------------------------
LInt. Lit ::= Integer ;
LChar. Lit ::= Char ;
--------------------------------------------------------------------------------
-- * CASE
--------------------------------------------------------------------------------
Inj. Inj ::= Init "=>" Exp ;
separator nonempty Inj ";" ;
InitLit. Init ::= Literal ;
InitConstr. Init ::= Ident [Ident] ;
InitCatch. Init ::= "_" ;
InitLit. Init ::= Lit ;
InitConstructor. Init ::= UIdent [LIdent] ;
InitCatch. Init ::= "_" ;
--------------------------------------------------------------------------------
-- * AUX
--------------------------------------------------------------------------------
separator Def ";" ;
separator nonempty Constructor "" ;
separator Type " " ;
coercions Type 2 ;
separator nonempty Inj ";" ;
separator Ident " ";
separator LIdent " ";
coercions Exp 5 ;
coercions Type 2 ;
token UIdent (upper (letter | digit | '_')*) ;
token LIdent (lower (letter | digit | '_')*) ;
comment "--" ;
comment "{-" "-}" ;

View file

@ -1,2 +1,2 @@
f : _Int -> _Int ;
f : Int -> Int ;
f = \x. x+1 ;

View file

@ -1,5 +1,5 @@
add : _Int -> _Int -> _Int ;
add : Int -> Int -> Int ;
add x = \y. x+y;
main : _Int ;
main : Int ;
main = (\z. z+z) ((add 4) 6) ;

View file

@ -1,2 +1,2 @@
main : _Int ;
main : Int ;
main = (\x. x+x+3) ((\x. x) 2) ;

View file

@ -1,2 +1,2 @@
f : _Int -> _Int ;
f : Int -> Int ;
f x = let g = (\y. y+1) in g (g x)

View file

@ -1,8 +1,8 @@
double : _Int -> _Int ;
double : Int -> Int ;
double n = n + n;
id : 'a -> 'a ;
id : forall a. a -> a ;
id x = x ;
main : _Int ;
main : Int ;
main = id double 5;

View file

@ -3,7 +3,7 @@ data Bool () where {
False : Bool ()
};
main : Bool () -> _Int ;
main : Bool () -> Int ;
main b = case b of {
False => 0;
True => 0

View file

@ -3,7 +3,7 @@ data Bool () where {
False : Bool ()
};
ifThenElse : Bool () -> 'a -> 'a -> 'a;
ifThenElse : forall a. Bool () -> a -> a -> a;
ifThenElse b if else = case b of {
True => if;
False => else

View file

@ -1,22 +1,22 @@
data Maybe ('a) where {
Nothing : Maybe ('a)
Just : 'a -> Maybe ('a)
data Maybe (a) where {
Nothing : Maybe (a)
Just : forall a. a -> Maybe (a)
};
fromJust : Maybe ('a) -> 'a ;
fromJust : Maybe (a) -> a ;
fromJust a =
case a of {
Just a => a
};
fromMaybe : 'a -> Maybe ('a) -> 'a ;
fromMaybe : a -> Maybe (a) -> a ;
fromMaybe a b =
case b of {
Just a => a;
Nothing => a
};
maybe : 'b -> ('a -> 'b) -> Maybe ('a) -> 'b;
maybe : b -> (a -> b) -> Maybe (a) -> b;
maybe b f ma =
case ma of {
Just a => f a;

View file

@ -11,7 +11,8 @@ import Grammar.Print (printTree)
import Renamer.Renamer (rename)
import System.Environment (getArgs)
import System.Exit (exitFailure, exitSuccess)
import TypeChecker.TypeChecker (typecheck)
-- import TypeChecker.TypeChecker (typecheck)
main :: IO ()
main =
@ -28,12 +29,12 @@ main' s = do
putStrLn $ printTree parsed
putStrLn "\n-- Renamer --"
let renamed = rename parsed
renamed <- fromRenamerErr . rename $ parsed
putStrLn $ printTree renamed
putStrLn "\n-- TypeChecker --"
typechecked <- fromTypeCheckerErr $ typecheck renamed
putStrLn $ show typechecked
-- putStrLn "\n-- TypeChecker --"
-- typechecked <- fromTypeCheckerErr $ typecheck renamed
-- putStrLn $ show typechecked
-- putStrLn "\n-- Lambda Lifter --"
-- let lifted = lambdaLift typechecked
@ -55,6 +56,16 @@ fromCompilerErr =
)
pure
fromRenamerErr :: Err a -> IO a
fromRenamerErr =
either
( \err -> do
putStrLn "\nRENAME ERROR"
putStrLn err
exitFailure
)
pure
fromSyntaxErr :: Err a -> IO a
fromSyntaxErr =
either

View file

@ -1,56 +1,101 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
module Renamer.Renamer where
module Renamer.Renamer (rename) where
import Auxiliary (mapAccumM)
import Control.Applicative (Applicative (liftA2))
import Control.Monad.Except (ExceptT, runExceptT)
import Control.Monad.Identity (Identity, runIdentity)
import Control.Monad.State (
MonadState,
State,
evalState,
StateT,
evalStateT,
gets,
modify,
)
import Data.List (foldl')
import Data.Function (on)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe (fromMaybe)
import Data.Tuple.Extra (dupe)
import Debug.Trace (trace)
import Grammar.Abs
-- | Rename all variables and local binds
rename :: Program -> Program
rename (Program bs) = Program $ evalState (runRn $ mapM (renameSc initNames) bs) 0
rename :: Program -> Either String Program
rename (Program defs) = Program <$> renameDefs defs
renameDefs :: [Def] -> Either String [Def]
renameDefs defs = runIdentity $ runExceptT $ evalStateT (runRn $ mapM renameDef defs) initCxt
where
-- initNames = Map.fromList $ map (\(Bind name _ _ _ _) -> dupe name) bs
initNames = Map.fromList $ foldl' saveIfBind [] bs
saveIfBind acc (DBind (Bind name _ _ _ _)) = dupe name : acc
saveIfBind acc _ = acc
renameSc :: Names -> Def -> Rn Def
renameSc old_names (DBind (Bind name t _ parms rhs)) = do
(new_names, parms') <- newNames old_names parms
rhs' <- snd <$> renameExp new_names rhs
pure . DBind $ Bind name t name parms' rhs'
renameSc _ def = pure def
initNames = Map.fromList [dupe name | DBind (Bind name _ _) <- defs]
renameDef :: Def -> Rn Def
renameDef = \case
DSig (Sig name typ) -> DSig . Sig name <$> renameTVars typ
DBind (Bind name vars rhs) -> do
(new_names, vars') <- newNames initNames vars
rhs' <- snd <$> renameExp new_names rhs
pure . DBind $ Bind name vars' rhs'
DData (Data (Indexed cname types) constrs) -> do
tvars' <- mapM nextNameTVar tvars
let tvars_lt = zip tvars tvars'
typ' = map (substituteTVar tvars_lt) types
constrs' = map (renameConstr tvars_lt) constrs
pure . DData $ Data (Indexed cname typ') constrs'
where
tvars = concatMap (collectTVars []) types
collectTVars tvars = \case
TAll tvar t -> collectTVars (tvar : tvars) t
TIndexed _ -> tvars
-- Should be monad error
TVar v -> [v]
_ -> error ("Bad data type definition: " ++ show types)
renameConstr :: [(TVar, TVar)] -> Constructor -> Constructor
renameConstr new_types (Constructor name typ) =
Constructor name $ substituteTVar new_types typ
substituteTVar :: [(TVar, TVar)] -> Type -> Type
substituteTVar new_names typ = case typ of
TLit _ -> typ
TVar tvar
| Just tvar' <- lookup tvar new_names ->
TVar tvar'
| otherwise ->
typ
TFun t1 t2 -> on TFun substitute' t1 t2
TAll tvar t
| Just tvar' <- lookup tvar new_names ->
TAll tvar' $ substitute' t
| otherwise ->
TAll tvar $ substitute' t
TIndexed (Indexed name typs) -> TIndexed . Indexed name $ map substitute' typs
_ -> error ("Impossible " ++ show typ)
where
substitute' = substituteTVar new_names
initCxt :: Cxt
initCxt = Cxt 0 0
data Cxt = Cxt
{ var_counter :: Int
, tvar_counter :: Int
}
-- | Rename monad. State holds the number of renamed names.
newtype Rn a = Rn {runRn :: State Int a}
deriving (Functor, Applicative, Monad, MonadState Int)
newtype Rn a = Rn {runRn :: StateT Cxt (ExceptT String Identity) a}
deriving (Functor, Applicative, Monad, MonadState Cxt)
-- | Maps old to new name
type Names = Map Ident Ident
renameLocalBind :: Names -> Bind -> Rn (Names, Bind)
renameLocalBind old_names (Bind name t _ parms rhs) = do
(new_names, name') <- newName old_names name
(new_names', parms') <- newNames new_names parms
(new_names'', rhs') <- renameExp new_names' rhs
pure (new_names'', Bind name' t name' parms' rhs')
type Names = Map LIdent LIdent
renameExp :: Names -> Exp -> Rn (Names, Exp)
renameExp old_names = \case
EId n -> pure (old_names, EId . fromMaybe n $ Map.lookup n old_names)
ELit (LInt i1) -> pure (old_names, ELit (LInt i1))
ELit lit -> pure (old_names, ELit lit)
EApp e1 e2 -> do
(env1, e1') <- renameExp old_names e1
(env2, e2') <- renameExp old_names e2
@ -59,17 +104,21 @@ renameExp old_names = \case
(env1, e1') <- renameExp old_names e1
(env2, e2') <- renameExp old_names e2
pure (Map.union env1 env2, EAdd e1' e2')
ELet i e1 e2 -> do
(new_names, e1') <- renameExp old_names e1
(new_names', e2') <- renameExp new_names e2
pure (new_names', ELet i e1' e2')
-- TODO fix shadowing
ELet name rhs e -> do
(new_names, name') <- newName old_names name
(new_names', rhs') <- renameExp new_names rhs
(new_names'', e') <- renameExp new_names' e
pure (new_names'', ELet name' rhs' e')
EAbs par e -> do
(new_names, par') <- newName old_names par
(new_names', e') <- renameExp new_names e
pure (new_names', EAbs par' e')
EAnn e t -> do
(new_names, e') <- renameExp old_names e
pure (new_names, EAnn e' t)
t' <- renameTVars t
pure (new_names, EAnn e' t')
ECase e injs -> do
(new_names, e') <- renameExp old_names e
(new_names', injs') <- renameInjs new_names injs
@ -88,21 +137,58 @@ renameInj ns (Inj init e) = do
renameInit :: Names -> Init -> Rn (Names, Init)
renameInit ns i = case i of
InitConstr cs vars -> do
InitConstructor cs vars -> do
(ns_new, vars') <- newNames ns vars
return (ns_new, InitConstr cs vars')
return (ns_new, InitConstructor cs vars')
rest -> return (ns, rest)
renameTVars :: Type -> Rn Type
renameTVars typ = case typ of
TAll tvar t -> do
tvar' <- nextNameTVar tvar
t' <- renameTVars $ substitute tvar tvar' t
pure $ TAll tvar' t'
TFun t1 t2 -> liftA2 TFun (renameTVars t1) (renameTVars t2)
_ -> pure typ
substitute ::
TVar -> -- α
TVar -> -- α_n
Type -> -- A
Type -- [α_n/α]A
substitute tvar1 tvar2 typ = case typ of
TLit _ -> typ
TVar tvar'
| tvar' == tvar1 -> TVar tvar2
| otherwise -> typ
TFun t1 t2 -> on TFun substitute' t1 t2
TAll tvar t -> TAll tvar $ substitute' t
TIndexed (Indexed name typs) -> TIndexed . Indexed name $ map substitute' typs
_ -> error "Impossible"
where
substitute' = substitute tvar1 tvar2
-- | Create a new name and add it to name environment.
newName :: Names -> Ident -> Rn (Names, Ident)
newName :: Names -> LIdent -> Rn (Names, LIdent)
newName env old_name = do
new_name <- makeName old_name
pure (Map.insert old_name new_name env, new_name)
-- | Create multiple names and add them to the name environment
newNames :: Names -> [Ident] -> Rn (Names, [Ident])
newNames :: Names -> [LIdent] -> Rn (Names, [LIdent])
newNames = mapAccumM newName
-- | Annotate name with number and increment the number @prefix ⇒ prefix_number@.
makeName :: Ident -> Rn Ident
makeName (Ident prefix) = gets (\i -> Ident $ prefix ++ "_" ++ show i) <* modify succ
makeName :: LIdent -> Rn LIdent
makeName (LIdent prefix) = do
i <- gets var_counter
let name = LIdent $ prefix ++ "_" ++ show i
modify $ \cxt -> cxt{var_counter = succ cxt.var_counter}
pure name
nextNameTVar :: TVar -> Rn TVar
nextNameTVar (MkTVar (LIdent s)) = do
i <- gets tvar_counter
let tvar = MkTVar . LIdent $ s ++ "_" ++ show i
modify $ \cxt -> cxt{tvar_counter = succ cxt.tvar_counter}
pure tvar

View file

@ -1,83 +0,0 @@
## Bugs
None known at this moment
main\_bug should not typecheck
```hs
apply : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c ;
apply f x = \y. f x y ;
id : 'a -> 'a ;
id x = x ;
add : _Int -> _Int -> _Int ;
add x y = x + y ;
main_bug : _Int -> _Int -> _Int ;
main_bug= (apply id) add ;
idadd : _Int -> _Int -> _Int ;
idadd = id add ;
```
main\_bug should typecheck
```hs
apply : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c ;
apply f x = \y. f x y ;
id : 'a -> 'a ;
id x = x ;
add : _Int -> _Int -> _Int ;
add x y = x + y ;
main_bug : _Int -> _Int -> _Int ;
main_bug = apply (id add) ;
idadd : _Int -> _Int -> _Int ;
idadd = id add ;
```
## Fixed bugs
* 1
```hs
fmap : ('a -> 'b) -> Maybe ('a) -> Maybe ('b) ;
fmap f x =
case x of {
Just x => Just (f x) ;
Nothing => Nothing
}
```
* 2
```hs
data Maybe ('a) where {
Nothing : Maybe ('a)
Just : 'a -> Maybe ('a)
};
id : 'a -> 'a ;
id x = x ;
main : Maybe ('a -> 'a) ;
main = Just id;
```
But this does
```hs
data Maybe ('a) where {
Nothing : Maybe ('a)
Just : 'a -> Maybe ('a)
};
id : 'b -> 'b ;
id x = x ;
main : Maybe ('a -> 'a) ;
main = Just id;
```

File diff suppressed because it is too large Load diff

View file

@ -2,178 +2,178 @@
module TypeChecker.TypeCheckerIr where
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.State
import Data.Functor.Identity (Identity)
import Data.Map (Map)
import Grammar.Abs (
Data (..),
Ident (..),
Init (..),
Literal (..),
Type (..),
)
import Grammar.Print
import Prelude
import Prelude qualified as C (Eq, Ord, Read, Show)
-- import Control.Monad.Except
-- import Control.Monad.Reader
-- import Control.Monad.State
-- import Data.Functor.Identity (Identity)
-- import Data.Map (Map)
-- import Grammar.Abs (
-- Data (..),
-- Ident (..),
-- Init (..),
-- Literal (..),
-- Type (..),
-- )
-- import Grammar.Print
-- import Prelude
-- import Prelude qualified as C (Eq, Ord, Read, Show)
-- | A data type representing type variables
data Poly = Forall [Ident] Type
deriving (Show)
-- -- | A data type representing type variables
-- data Poly = Forall [Ident] Type
-- deriving (Show)
newtype Ctx = Ctx {vars :: Map Ident Poly}
deriving Show
-- newtype Ctx = Ctx {vars :: Map Ident Poly}
-- deriving Show
data Env = Env
{ count :: Int
, sigs :: Map Ident Type
, constructors :: Map Ident Type
} deriving Show
-- data Env = Env
-- { count :: Int
-- , sigs :: Map Ident Type
-- , constructors :: Map Ident Type
-- } deriving Show
type Error = String
type Subst = Map Ident Type
-- type Error = String
-- type Subst = Map Ident Type
type Infer = StateT Env (ReaderT Ctx (ExceptT Error Identity))
-- type Infer = StateT Env (ReaderT Ctx (ExceptT Error Identity))
newtype Program = Program [Def]
deriving (C.Eq, C.Ord, C.Show, C.Read)
-- newtype Program = Program [Def]
-- deriving (C.Eq, C.Ord, C.Show, C.Read)
data Exp
= EId Id
| ELit Type Literal
| ELet Bind Exp
| EApp Type Exp Exp
| EAdd Type Exp Exp
| EAbs Type Id Exp
| ECase Type Exp [Inj]
deriving (C.Eq, C.Ord, C.Read, C.Show)
-- data Exp
-- = EId Id
-- | ELit Type Literal
-- | ELet Bind Exp
-- | EApp Type Exp Exp
-- | EAdd Type Exp Exp
-- | EAbs Type Id Exp
-- | ECase Type Exp [Inj]
-- deriving (C.Eq, C.Ord, C.Read, C.Show)
data Inj = Inj (Init, Type) Exp
deriving (C.Eq, C.Ord, C.Read, C.Show)
-- data Inj = Inj (Init, Type) Exp
-- deriving (C.Eq, C.Ord, C.Read, C.Show)
data Def = DBind Bind | DData Data
deriving (C.Eq, C.Ord, C.Read, C.Show)
-- data Def = DBind Bind | DData Data
-- deriving (C.Eq, C.Ord, C.Read, C.Show)
type Id = (Ident, Type)
-- type Id = (Ident, Type)
data Bind = Bind Id Exp
deriving (C.Eq, C.Ord, C.Show, C.Read)
-- data Bind = Bind Id Exp
-- deriving (C.Eq, C.Ord, C.Show, C.Read)
instance Print [Def] where
prt _ [] = concatD []
prt _ (x : xs) = concatD [prt 0 x, doc (showString "\n"), prt 0 xs]
-- instance Print [Def] where
-- prt _ [] = concatD []
-- prt _ (x : xs) = concatD [prt 0 x, doc (showString "\n"), prt 0 xs]
instance Print Def where
prt i (DBind bind) = prt i bind
prt i (DData d) = prt i d
-- instance Print Def where
-- prt i (DBind bind) = prt i bind
-- prt i (DData d) = prt i d
instance Print Program where
prt i (Program sc) = prPrec i 0 $ prt 0 sc
-- instance Print Program where
-- prt i (Program sc) = prPrec i 0 $ prt 0 sc
instance Print Bind where
prt i (Bind (t, name) rhs) =
prPrec i 0 $
concatD
[ prt 0 name
, doc $ showString ":"
, prt 0 t
, doc $ showString "\n"
, prt 0 name
, doc $ showString "="
, prt 0 rhs
]
-- instance Print Bind where
-- prt i (Bind (t, name) rhs) =
-- prPrec i 0 $
-- concatD
-- [ prt 0 name
-- , doc $ showString ":"
-- , prt 0 t
-- , doc $ showString "\n"
-- , prt 0 name
-- , doc $ showString "="
-- , prt 0 rhs
-- ]
instance Print [Bind] where
prt _ [] = concatD []
prt _ [x] = concatD [prt 0 x]
prt _ (x : xs) = concatD [prt 0 x, doc (showString ";"), doc (showString "\n"), prt 0 xs]
-- instance Print [Bind] where
-- prt _ [] = concatD []
-- prt _ [x] = concatD [prt 0 x]
-- prt _ (x : xs) = concatD [prt 0 x, doc (showString ";"), doc (showString "\n"), prt 0 xs]
prtIdPs :: Int -> [Id] -> Doc
prtIdPs i = prPrec i 0 . concatD . map (prtIdP i)
-- prtIdPs :: Int -> [Id] -> Doc
-- prtIdPs i = prPrec i 0 . concatD . map (prtIdP i)
prtId :: Int -> Id -> Doc
prtId i (name, t) =
prPrec i 0 $
concatD
[ prt 0 name
, doc $ showString ":"
, prt 0 t
]
-- prtId :: Int -> Id -> Doc
-- prtId i (name, t) =
-- prPrec i 0 $
-- concatD
-- [ prt 0 name
-- , doc $ showString ":"
-- , prt 0 t
-- ]
prtIdP :: Int -> Id -> Doc
prtIdP i (name, t) =
prPrec i 0 $
concatD
[ doc $ showString "("
, prt 0 name
, doc $ showString ":"
, prt 0 t
, doc $ showString ")"
]
-- prtIdP :: Int -> Id -> Doc
-- prtIdP i (name, t) =
-- prPrec i 0 $
-- concatD
-- [ doc $ showString "("
-- , prt 0 name
-- , doc $ showString ":"
-- , prt 0 t
-- , doc $ showString ")"
-- ]
instance Print Exp where
prt i = \case
EId n -> prPrec i 3 $ concatD [prtId 0 n, doc $ showString "\n"]
ELit _ (LInt i1) -> prPrec i 3 $ concatD [prt 0 i1, doc $ showString "\n"]
ELet bs e ->
prPrec i 3 $
concatD
[ doc $ showString "let"
, prt 0 bs
, doc $ showString "in"
, prt 0 e
, doc $ showString "\n"
]
EApp _ e1 e2 ->
prPrec i 2 $
concatD
[ prt 2 e1
, prt 3 e2
]
EAdd t e1 e2 ->
prPrec i 1 $
concatD
[ doc $ showString "@"
, prt 0 t
, prt 1 e1
, doc $ showString "+"
, prt 2 e2
, doc $ showString "\n"
]
EAbs t n e ->
prPrec i 0 $
concatD
[ doc $ showString "@"
, prt 0 t
, doc $ showString "\\"
, prtId 0 n
, doc $ showString "."
, prt 0 e
, doc $ showString "\n"
]
ECase t exp injs ->
prPrec
i
0
( concatD
[ doc (showString "case")
, prt 0 exp
, doc (showString "of")
, doc (showString "{")
, prt 0 injs
, doc (showString "}")
, doc (showString ":")
, prt 0 t
, doc $ showString "\n"
]
)
-- instance Print Exp where
-- prt i = \case
-- EId n -> prPrec i 3 $ concatD [prtId 0 n, doc $ showString "\n"]
-- ELit _ (LInt i1) -> prPrec i 3 $ concatD [prt 0 i1, doc $ showString "\n"]
-- ELet bs e ->
-- prPrec i 3 $
-- concatD
-- [ doc $ showString "let"
-- , prt 0 bs
-- , doc $ showString "in"
-- , prt 0 e
-- , doc $ showString "\n"
-- ]
-- EApp _ e1 e2 ->
-- prPrec i 2 $
-- concatD
-- [ prt 2 e1
-- , prt 3 e2
-- ]
-- EAdd t e1 e2 ->
-- prPrec i 1 $
-- concatD
-- [ doc $ showString "@"
-- , prt 0 t
-- , prt 1 e1
-- , doc $ showString "+"
-- , prt 2 e2
-- , doc $ showString "\n"
-- ]
-- EAbs t n e ->
-- prPrec i 0 $
-- concatD
-- [ doc $ showString "@"
-- , prt 0 t
-- , doc $ showString "\\"
-- , prtId 0 n
-- , doc $ showString "."
-- , prt 0 e
-- , doc $ showString "\n"
-- ]
-- ECase t exp injs ->
-- prPrec
-- i
-- 0
-- ( concatD
-- [ doc (showString "case")
-- , prt 0 exp
-- , doc (showString "of")
-- , doc (showString "{")
-- , prt 0 injs
-- , doc (showString "}")
-- , doc (showString ":")
-- , prt 0 t
-- , doc $ showString "\n"
-- ]
-- )
instance Print Inj where
prt i = \case
Inj (init, t) exp -> prPrec i 0 (concatD [prt 0 init, doc (showString ":"), prt 0 t, doc (showString "=>"), prt 0 exp])
-- instance Print Inj where
-- prt i = \case
-- Inj (init, t) exp -> prPrec i 0 (concatD [prt 0 init, doc (showString ":"), prt 0 t, doc (showString "=>"), prt 0 exp])
instance Print [Inj] where
prt _ [] = concatD []
prt _ [x] = concatD [prt 0 x]
prt _ (x : xs) = concatD [prt 0 x, doc (showString ";"), prt 0 xs]
-- instance Print [Inj] where
-- prt _ [] = concatD []
-- prt _ [x] = concatD [prt 0 x]
-- prt _ (x : xs) = concatD [prt 0 x, doc (showString ";"), prt 0 xs]

View file

@ -1,24 +1,4 @@
data Maybe ('a) where {
Nothing : Maybe ('a)
Just : 'a -> Maybe ('a)
};
fromJust : Maybe ('a) -> 'a ;
fromJust a =
case a of {
Just a => a
};
fromMaybe : 'a -> Maybe ('a) -> 'a ;
fromMaybe a b =
case b of {
Just a => a;
Nothing => a
};
maybe : 'b -> ('a -> 'b) -> Maybe ('a) -> 'b;
maybe b f ma =
case ma of {
Just a => f a;
Nothing => b
}
data Maybe (a) where {
Nothing : Maybe (a)
Just : a -> Maybe (a)
}