1 implementation module sem
3 import qualified Data.Map as Map
4 from Data.Func import $
8 import Control.Applicative
10 import Control.Monad.State
11 import Control.Monad.Identity
12 import Control.Monad.Trans
14 from StdFunc import id, const
18 from Text import class Text(concat), instance Text String
21 from parse import :: ParserOutput, :: Error
23 :: Gamma :== 'Map'.Map String Type
24 :: Env a :== StateT Gamma (Either SemError) a
26 //we need to redefine this even though it is in Control.Monad.State
27 instance MonadTrans (StateT Gamma) where
28 liftT m = StateT \s-> m >>= \a-> return (a, s)
32 instance toString SemError where
33 toString (ParseError p e) = concat [
34 toString p,"SemError: ParseError: ", e]
35 toString (Error e) = "SemError: " +++ e
36 toString (UnifyErrorStub t1 t2) = toString (UnifyError {line=0,col=0} t1 t2)
37 toString (UnifyError p t1 t2) = concat [
39 "SemError: Cannot unify types. Expected: ",
40 toString t1, ". Given: ", toString t2]
42 putIdent :: String Type -> Env Void
43 putIdent i t = gets ('Map'.get i) >>= \mt -> case mt of
44 Nothing = modify ('Map'.put i t)
45 Just t2 = unify t t2 >>= \t3-> modify ('Map'.put i t3)
47 sem :: AST -> SemOutput
48 sem (AST vd fd) = case evalStateT m 'Map'.newMap of
50 Right (vds, fds) = Right (AST vds fds)
52 m :: Env (([VarDecl], [FunDecl]))
53 m = (mapM semVarDecl vd) >>= \vds ->
54 mapM semFunDecl fd >>= \fds ->
57 splitEithers :: [Either a b] -> Either [a] [b]
58 splitEithers [] = Right []
59 splitEithers [Right x:xs] = splitEithers xs >>= \rest->Right [x:rest]
60 splitEithers xs = Left $ [x\\(Left x)<-xs]
62 semFunDecl :: FunDecl -> Env FunDecl
65 semVarDecl :: VarDecl -> Env VarDecl
66 semVarDecl (VarDecl pos type ident ex) = unify type ex
67 >>= \t-> putIdent ident t >>| (pure $ VarDecl pos t ident ex)
69 typeExpr :: Expr -> Env Type
70 typeExpr (IntExpr _ _) = pure IntType
71 typeExpr (CharExpr _ _) = pure CharType
72 typeExpr (BoolExpr _ _) = pure BoolType
73 typeExpr (Op1Expr p UnNegation expr) = unify BoolType expr
74 typeExpr (Op1Expr p UnMinus expr) = unify IntType expr
75 typeExpr (TupleExpr p (e1, e2)) = typeExpr e1
76 >>= \t1-> typeExpr e2 >>= \t2-> pure $ TupleType (t1, t2)
78 typeExpr (Op2Expr p e1 BiPlus e2) = unify IntType e1 >>| unify IntType e2
79 typeExpr (Op2Expr p e1 BiMinus e2) = unify IntType e1 >>| unify IntType e2
80 typeExpr (Op2Expr p e1 BiTimes e2) = unify IntType e1 >>| unify IntType e2
81 typeExpr (Op2Expr p e1 BiDivide e2) = unify IntType e1 >>| unify IntType e2
82 typeExpr (Op2Expr p e1 BiMod e2) = unify IntType e1 >>| unify IntType e2
84 typeExpr (Op2Expr p e1 BiEquals e2) = undef
85 typeExpr (Op2Expr p e1 BiUnEqual e2) = undef
87 typeExpr (Op2Expr p e1 BiLesser e2) = undef
88 typeExpr (Op2Expr p e1 BiGreater e2) = undef
89 typeExpr (Op2Expr p e1 BiLesserEq e2) = undef
90 typeExpr (Op2Expr p e1 BiGreaterEq e2) = undef
92 typeExpr (Op2Expr p e1 BiAnd e2) = undef
93 typeExpr (Op2Expr p e1 BiOr e2) = undef
95 typeExpr (Op2Expr p e1 BiCons e2) = undef
96 //typeExpr (FunExpr Pos FunCall) = undef
97 //typeExpr (EmptyListExpr Pos) = undef
98 //typeExpr (VarExpr Pos VarDef) = undef //when checking var-expr, be sure to put the infered type
101 class unify a :: Type a -> Env Type
103 instance unify Expr where
104 unify (_ ->> _) e = liftT $ Left $ ParseError (extrPos e)
105 "Expression cannot be a higher order function. Yet..."
106 unify VoidType e = liftT $ Left $ ParseError (extrPos e)
107 "Expression cannot be a Void type."
108 unify (IdType _) e = liftT $ Left $ ParseError (extrPos e)
109 "Expression cannot be an polymorf type."
110 unify VarType e = typeExpr e
111 //we have to cheat to decorate the error, can be done nicer?
112 unify t e = StateT $ \s0 -> let res = runStateT m s0 in case res of
113 Left err = Left $ decErr e err
114 Right t = Right t //note, t :: (Type, Gamma)
115 where m = typeExpr e >>= \tex-> unify t tex
117 instance unify Type where
118 unify IntType IntType = pure IntType
119 unify BoolType BoolType = pure BoolType
120 unify CharType CharType = pure CharType
121 unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2
123 instance zero Pos where
124 zero = {line=0,col=0}
126 decErr :: Expr SemError -> SemError
127 decErr e (UnifyError _ t1 t2) = UnifyError (extrPos e) t1 t2
128 decErr e (ParseError _ s) = ParseError (extrPos e) s
131 dc2 :: Expr (Either SemError a) -> Either SemError a
132 dc2 e (Right t) = Right t
133 dc2 e (Left err) = Left err
135 extrPos :: Expr -> Pos
136 extrPos (VarExpr p _) = p
137 extrPos (Op2Expr p _ _ _) = p
138 extrPos (Op1Expr p _ _) = p
139 extrPos (IntExpr p _) = p
140 extrPos (CharExpr p _) = p
141 extrPos (BoolExpr p _) = p
142 extrPos (FunExpr p _) = p
143 extrPos (EmptyListExpr p) = p
144 extrPos (TupleExpr p _) = p