Fixed EId, more work on other expressions needed

This commit is contained in:
sebastianselander 2023-02-14 10:12:38 +01:00
parent c10d7703ad
commit 200a9e57ed
4 changed files with 55 additions and 28 deletions

View file

@ -1,15 +1,15 @@
Program. Program ::= [Bind]; Program. Program ::= [Bind] ;
Bind. Bind ::= Ident [Ident] "=" Exp; Bind. Bind ::= Ident [Ident] "=" Exp ;
EAnn. Exp5 ::= Exp5 ":" Type ; EAnn. Exp5 ::= Exp5 ":" Type ;
EId. Exp4 ::= Ident; EId. Exp4 ::= Ident ;
EConst. Exp4 ::= Const; EConst. Exp4 ::= Const ;
EApp. Exp3 ::= Exp3 Exp4; EApp. Exp3 ::= Exp3 Exp4 ;
EAdd. Exp1 ::= Exp1 "+" Exp2; EAdd. Exp1 ::= Exp1 "+" Exp2 ;
ELet. Exp ::= "let" Ident "=" Exp "in" Exp; ELet. Exp ::= "let" Ident "=" Exp "in" Exp ;
EAbs. Exp ::= "\\" Ident "." Exp; EAbs. Exp ::= "\\" Ident "." Exp ;
CInt. Const ::= Integer ; CInt. Const ::= Integer ;
CStr. Const ::= String ; CStr. Const ::= String ;
@ -21,11 +21,11 @@ TArrow. Type ::= Type "->" Type1 ;
token UIdent (upper (letter | digit | '_')*) ; token UIdent (upper (letter | digit | '_')*) ;
token LIdent (lower (letter | digit | '_')*) ; token LIdent (lower (letter | digit | '_')*) ;
separator Bind ";"; separator Bind ";" ;
separator Ident " "; separator Ident " ";
coercions Type 1 ; coercions Type 1 ;
coercions Exp 5; coercions Exp 5 ;
comment "--"; comment "--" ;
comment "{-" "-}"; comment "{-" "-}" ;

View file

@ -17,7 +17,7 @@ extra-source-files:
common warnings common warnings
ghc-options: -W ghc-options: -Wdefault
executable language executable language
import: warnings import: warnings

View file

@ -1,4 +1,4 @@
{-# LANGUAGE LambdaCase, OverloadedStrings #-} {-# LANGUAGE LambdaCase, OverloadedStrings, OverloadedRecordDot #-}
module TypeChecker.TypeChecker (typecheck) where module TypeChecker.TypeChecker (typecheck) where
@ -18,6 +18,8 @@ import qualified Data.Map as M
import Data.Set (Set) import Data.Set (Set)
import qualified Data.Set as S import qualified Data.Set as S
import Data.Bool (bool)
import qualified Grammar.Abs as Old import qualified Grammar.Abs as Old
import Grammar.ErrM (Err) import Grammar.ErrM (Err)
@ -25,7 +27,7 @@ import TypeChecker.TypeCheckerIr
data Ctx = Ctx data Ctx = Ctx
{ env :: [Map Ident Type] { env :: [Map Ident Type]
, sig :: Map Ident Bind , sigs :: Map Ident Type
, typs :: Set Ident , typs :: Set Ident
} }
deriving Show deriving Show
@ -35,7 +37,7 @@ type Check = ReaderT Ctx (ExceptT Error Identity)
initEnv :: Ctx initEnv :: Ctx
initEnv = initEnv =
Ctx { env = mempty Ctx { env = mempty
, sig = mempty , sigs = mempty
, typs = mempty , typs = mempty
} }
@ -54,7 +56,14 @@ inferBind (Bind _ _ e) = void $ inferExp e
inferExp :: Old.Exp -> Check Type inferExp :: Old.Exp -> Check Type
inferExp = \case inferExp = \case
Old.EId i -> undefined Old.EId i -> do
ctx <- R.ask
case lookupEnv i ctx of
Just t -> return t
Nothing -> case lookupSigs i ctx of
Just t -> return t
Nothing -> throwError UnboundVar
Old.EAnn e t -> do Old.EAnn e t -> do
infT <- inferExp e infT <- inferExp e
@ -68,8 +77,12 @@ inferExp = \case
Old.EAdd e1 e2 -> do Old.EAdd e1 e2 -> do
t1 <- inferExp e1 t1 <- inferExp e1
t2 <- inferExp e2 t2 <- inferExp e2
let int = TMono (UIdent "Int")
case (t1, t2) of case (t1, t2) of
(TMono (UIdent "Int"), TMono (UIdent "Int")) -> return t1 (TMono (UIdent "Int"), TMono (UIdent "Int")) -> return int
(_, TMono (UIdent "Int")) -> return int
(TMono (UIdent "Int"), _) -> return int
(TPoly (LIdent x), TPoly (LIdent y)) -> bool (throwError TypeMismatch) (return int) (x==y)
_ -> throwError NotNumber _ -> throwError NotNumber
return t1 return t1
@ -95,27 +108,39 @@ inferExp = \case
-- Aux -- Aux
-- Double check this function. It's bad and maybe wrong
subtype :: Type -> Type -> Bool subtype :: Type -> Type -> Bool
subtype (TMono t1) (TMono t2) = t1 == t2 subtype (TMono t1) (TMono t2) = t1 == t2
subtype (TMono t1) (TPoly t2) = True subtype (TMono t1) (TPoly t2) = True
subtype (TPoly t2) (TMono t1) = False subtype (TPoly t2) (TMono t1) = False
subtype (TArrow t1 t2) (TArrow t3 t4) = t1 `subtype` t3 && t2 `subtype` t4 subtype (TArrow t1 t2) (TArrow t3 t4) = t1 `subtype` t3 && t2 `subtype` t4
subtype _ _ = False
lookupEnv :: Ident -> Ctx -> Maybe Type lookupEnv :: Ident -> Ctx -> Maybe Type
lookupEnv i c = case env c of lookupEnv i c = case env c of
[] -> Nothing [] -> Nothing
x : xs -> case M.lookup i x of x : xs -> case M.lookup i x of
Nothing -> lookupEnv i (Ctx { env = xs }) Nothing -> lookupEnv i (Ctx { env = xs
, sigs = c.sigs
, typs = c.typs
})
Just x -> Just x Just x -> Just x
lookupSig :: Ident -> Ctx -> Maybe Bind lookupSigs :: Ident -> Ctx -> Maybe Type
lookupSig i = M.lookup i . sig lookupSigs i = M.lookup i . sigs
insertEnv :: Ident -> Type -> Ctx -> Ctx insertEnv :: Ident -> Type -> Ctx -> Ctx
insertEnv i t c = insertEnv i t c =
case env c of case env c of
[] -> Ctx{env = [M.insert i t mempty]} [] -> Ctx { env = [M.insert i t mempty]
(x : xs) -> Ctx{env = M.insert i t x : xs} , sigs = c.sigs
, typs = c.typs
}
(x : xs) -> Ctx { env = M.insert i t x : xs
, sigs = c.sigs
, typs = c.typs
}
data Error data Error
= TypeMismatch = TypeMismatch
@ -145,17 +170,19 @@ data Error
-- ] -- ]
-- Default mess -> mess -- Default mess -> mess
-- Tests -- Tests
number :: Old.Exp number :: Old.Exp
number = Old.EConst (CInt 3) number = Old.EConst (CInt 3)
lambda :: Old.Exp aToInt :: Old.Exp
lambda = Old.EAbs (Old.Ident "x") (Old.EAdd (Old.EConst (Old.CInt 3)) (Old.EConst (Old.CInt 3))) aToInt = Old.EAbs (Old.Ident "x") (Old.EAdd (Old.EConst (Old.CInt 3)) (Old.EConst (Old.CInt 3)))
intToInt :: Old.Exp
intToInt = Old.EAbs (Old.Ident "x") (Old.EAdd (Old.EId $ Ident "x") (Old.EConst (Old.CInt 3)))
apply :: Old.Exp apply :: Old.Exp
apply = Old.EApp lambda (Old.EConst (Old.CInt 3)) apply = Old.EApp aToInt (Old.EConst (Old.CInt 3))
{-# WARNING todo "TODO IN CODE" #-} {-# WARNING todo "TODO IN CODE" #-}
todo :: a todo :: a

View file

@ -1 +1 @@
test y = y main = 3;