replace ding in map'
[cc1516.git] / sem.icl
diff --git a/sem.icl b/sem.icl
index f0241e1..1bedd62 100644 (file)
--- a/sem.icl
+++ b/sem.icl
@@ -59,11 +59,11 @@ instance toString SemError where
                toString t1, ". Given: ", toString t2]
 
 sem :: AST -> SemOutput
-sem (AST vd fd) = case evalStateT m ('Map'.newMap, getRandomStream 1) of
+sem (AST vd fd) = case runStateT m ('Map'.newMap, getRandomStream 1) of
     Left e = Left [e]
-    Right (vds, fds) = Right (AST vds fds)
+    Right ((vds, fds), gamma) = Right ((AST vds fds), gamma)
 where 
-    m :: Env (([VarDecl], [FunDecl]))
+    m :: Env ([VarDecl], [FunDecl])
     m = (mapM semVarDecl vd) >>= \vds -> 
         mapM semFunDecl fd >>= \fds -> 
         pure (vds, fds)
@@ -121,20 +121,36 @@ instance unify Expr where
        unify (IdType _) e = liftT $ Left $ ParseError (extrPos e)
                        "Expression cannot be an polymorf type."
     unify VarType e = typeExpr e
+    unify (IdType i) e = undef
     //we have to cheat to decorate the error, can be done nicer?
     unify t e = StateT $ \s0 -> let res = runStateT m s0 in case res of
         Left err = Left $ decErr e err
         Right t = Right t //note, t :: (Type, Gamma) 
     where m = typeExpr e >>= \tex-> unify t tex 
 
-//unify e (IdType i) = unify (IdType i) e
-    //note, don't use putIdent as that will call unify again
-    //unify (IdType i) e=:(IdType j) = modify (\(st, r)->('Map'.put j e 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 unify Type where
        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
        unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2
 
@@ -159,4 +175,8 @@ extrPos (CharExpr p _) = p
 extrPos (BoolExpr p _) = p
 extrPos (FunExpr p _) = p
 extrPos (EmptyListExpr p) = p
-extrPos (TupleExpr p _) = p
\ No newline at end of file
+extrPos (TupleExpr p _) = p
+
+instance toString Gamma where
+       toString (mp, _) = concat
+               [concat [k, ": ", toString v, "\n"]\\(k, v) <- 'Map'.toList mp]