- unify IntType IntType = pure $ Right IntType
- unify BoolType BoolType = pure $ Right BoolType
- unify CharType CharType = pure $ Right CharType
- unify _ _ = undef
-//
-//instance unify Expr where
-// unify type expr = case type of
-// _ ->> _ = Left $ ParseError (extrPos expr)
-// "Expression cannot be a higher order function. Yet..."
-// VoidType = Left $ ParseError (extrPos expr)
-// "Expression cannot be a Void type."
-// IdType _ = Left $ ParseError (extrPos expr)
-// "Expression cannot be an polymorf type."
-// TupleType (_, _) = undef
-// ListType _ = undef
-// IntType = undef
-// BoolType = undef
-// CharType = undef
-// VarType = undef
-//
-//extrPos :: Expr -> Pos
-//extrPos (VarExpr p _) = p
-//extrPos (Op2Expr p _ _ _) = p
-//extrPos (Op1Expr p _ _) = p
-//extrPos (IntExpr p _) = p
-//extrPos (CharExpr p _) = p
-//extrPos (BoolExpr p _) = p
-//extrPos (FunExpr p _) = p
-//extrPos (EmptyListExpr p) = p
-//extrPos (TupleExpr p _) = p
+ unify IntType IntType = pure IntType
+ unify BoolType BoolType = pure BoolType
+ unify CharType CharType = pure CharType
+ unify (IdType i) t=:(IdType j) = replace i t >>| pure t
+ unify t (IdType i) = unify (IdType i) t
+ unify (IdType i) t = replace i t >>| pure t
+ unify (ListType t1) (ListType t2) = unify t1 t2 >>| (pure $ ListType t1)
+ unify (ta1 ->> ta2) (tb1 ->> tb2) = unify ta1 tb1 >>= \ta-> unify ta2 tb2
+ >>= \tb-> pure (ta ->> tb)
+ unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2
+
+instance zero Pos where
+ zero = {line=0,col=0}
+
+decErr :: Expr SemError -> SemError
+decErr e (UnifyError _ t1 t2) = UnifyError (extrPos e) t1 t2
+decErr e (FieldSelectorError _ t fs) = FieldSelectorError (extrPos e) t fs
+decErr e (ParseError _ s) = ParseError (extrPos e) s
+decErr e err = err
+
+dc2 :: Expr (Either SemError a) -> Either SemError a
+dc2 e (Right t) = Right t
+dc2 e (Left err) = Left err
+
+extrPos :: Expr -> Pos
+extrPos (VarExpr p _) = p
+extrPos (Op2Expr p _ _ _) = p
+extrPos (Op1Expr p _ _) = p
+extrPos (IntExpr p _) = p
+extrPos (CharExpr p _) = p
+extrPos (BoolExpr p _) = p
+extrPos (FunExpr p _) = p
+extrPos (EmptyListExpr p) = p
+extrPos (TupleExpr p _) = p
+
+instance toString Gamma where
+ toString (mp, _) = concat
+ [concat [k, ": ", toString v, "\n"]\\(k, v) <- 'Map'.toList mp]
+
+getRandomStream :: Int -> [String]
+getRandomStream i = genIdents $ filter (isAlpha o toChar) (genRandInt i)
+ where
+ genIdents r = let (ic, r2) = splitAt 5 r in [toString ic: genIdents r2]
+
+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
+ Nothing = modify (\(st, r)->('Map'.put i t st, r))
+ Just t2 = unify t t2 >>= \t3-> modify (\(st, r)->('Map'.put i t3 st, r))
+
+replace :: String Type -> Env Void
+replace ident type = get >>= \(st, fr)->put ('Map'.fromList $
+ map (itupdate ident type) ('Map'.toList st), fr)
+ where
+ itupdate :: String Type (String, Type) -> (String, Type)
+ itupdate ident newtype ov=:(key, IdType type) = if (ident == type)
+ (key, newtype) ov
+ itupdate ident newtype (key, TupleType (t1, t2))
+ # (_, t1) = itupdate ident newtype (key, t1)
+ # (_, t2) = itupdate ident newtype (key, t2)
+ = (key, TupleType (t1, t2))
+ itupdate ident newtype (key, ListType t1)
+ # (_, t1) = itupdate ident newtype (key, t1)
+ = (key, ListType t1)
+ itupdate _ _ k = k
+
+instance toString SemError where
+ toString (ParseError p e) = concat [
+ toString p,"SemError: ParseError: ", e]
+ toString (Error e) = "SemError: " +++ e
+ toString (UnifyError p t1 t2) = concat [
+ toString p,
+ "SemError: Cannot unify types. Expected: ",
+ toString t1, ". Given: ", toString t2]
+ toString (FieldSelectorError p t fs) = concat [
+ toString p,
+ "SemError: Cannot select ", toString fs, " from type: ",
+ toString t]
+ toString (OperatorError p o t) = concat [
+ toString p,
+ "SemError: No ", toString o, " for type ",
+ toString t]
+ toString (UndeclaredVariableError p ident) = concat [
+ toString p, "SemError: identifier: ", ident, " undefined."]
+
+saveGamma :: Env Gamma
+saveGamma = get
+
+restoreGamma :: Gamma -> Env Void
+restoreGamma g = put g