:: Gamma :== ('Map'.Map String Type, [String])
:: Env a :== StateT Gamma (Either SemError) a
+//StateT (Gamma -> Either SemError (a, Gamma))
//we need to redefine this even though it is in Control.Monad.State
instance MonadTrans (StateT Gamma) where
where
genIdents r = let (ic, r) = splitAt 5 r in [toString ic: genIdents r]
-freshIdent :: Gamma -> (String, Gamma)
-freshIdent (st, [ident:rest]) = case 'Map'.get ident st of
- Nothing = (ident, (st, rest))
- _ = freshIdent (st, rest)
+freshIdent :: Env String
+freshIdent = get >>= \(st, [ident:rest])-> put (st, rest)
+ >>| case 'Map'.get ident st of
+ Nothing = pure ident
+ _ = freshIdent
putIdent :: String Type -> Env Void
putIdent i t = gets (\(st, r)->'Map'.get i st) >>= \mt -> case mt of
mapM semFunDecl fd >>= \fds ->
pure (vds, fds)
-
-
-splitEithers :: [Either a b] -> Either [a] [b]
-splitEithers [] = Right []
-splitEithers [Right x:xs] = splitEithers xs >>= \rest->Right [x:rest]
-splitEithers xs = Left $ [x\\(Left x)<-xs]
-
semFunDecl :: FunDecl -> Env FunDecl
semFunDecl f = pure f
typeExpr (Op2Expr p e1 BiDivide e2) = unify IntType e1 >>| unify IntType e2
typeExpr (Op2Expr p e1 BiMod e2) = unify IntType e1 >>| unify IntType e2
//bool, char of int
-typeExpr (Op2Expr p e1 BiEquals e2) = undef
-typeExpr (Op2Expr p e1 BiUnEqual e2) = undef
+typeExpr (Op2Expr p e1 BiEquals e2) = typeExpr e1 >>= \t1 -> unify t1 e2
+ >>| pure BoolType //todo, actually check t1 in Char,Bool,Int
+typeExpr (Op2Expr p e1 BiUnEqual e2) = typeExpr (Op2Expr p e1 BiEquals e2)
//char of int
-typeExpr (Op2Expr p e1 BiLesser e2) = undef
-typeExpr (Op2Expr p e1 BiGreater e2) = undef
-typeExpr (Op2Expr p e1 BiLesserEq e2) = undef
-typeExpr (Op2Expr p e1 BiGreaterEq e2) = undef
+typeExpr (Op2Expr p e1 BiLesser e2) = typeExpr e1 >>= \t1 -> unify t1 e2
+ >>| pure BoolType //todo, actually check t1 in Char, Int
+typeExpr (Op2Expr p e1 BiGreater e2) = typeExpr (Op2Expr p e1 BiLesser e2)
+typeExpr (Op2Expr p e1 BiLesserEq e2) = typeExpr (Op2Expr p e1 BiLesser e2)
+typeExpr (Op2Expr p e1 BiGreaterEq e2) = typeExpr (Op2Expr p e1 BiLesser e2)
//bool
-typeExpr (Op2Expr p e1 BiAnd e2) = undef
-typeExpr (Op2Expr p e1 BiOr e2) = undef
+typeExpr (Op2Expr p e1 BiAnd e2) = unify BoolType e1 >>| unify BoolType e2
+typeExpr (Op2Expr p e1 BiOr e2) = unify BoolType e1 >>| unify BoolType e2
//a
-typeExpr (Op2Expr p e1 BiCons e2) = undef
-//typeExpr (FunExpr Pos FunCall) = undef
-//typeExpr (EmptyListExpr Pos) = undef
+typeExpr (Op2Expr p e1 BiCons e2) = typeExpr e1 >>= \t1-> typeExpr e2
+ >>= \t2-> unify (ListType t1) t2
+//typeExpr (FunExpr p FunCall) = undef
+typeExpr (EmptyListExpr p) = freshIdent >>= \frsh-> let t = IdType frsh in
+ putIdent frsh t >>| pure t
//typeExpr (VarExpr Pos VarDef) = undef //when checking var-expr, be sure to
-//put the infered type
- //in the context
+ //put the infered type in the context
class unify a :: Type a -> Env Type
unify IntType IntType = pure IntType
unify BoolType BoolType = pure BoolType
unify CharType CharType = pure CharType
+ unify (ListType t1) (ListType t2) = unify t1 t2
unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2
instance zero Pos where
extrPos (BoolExpr p _) = p
extrPos (FunExpr p _) = p
extrPos (EmptyListExpr p) = p
-extrPos (TupleExpr p _) = p
+extrPos (TupleExpr p _) = p
\ No newline at end of file