Ontwerpbesluit toegevoegd dat functies pas na decla beschikbaar zijn
[cc1516.git] / sem.icl
diff --git a/sem.icl b/sem.icl
index addadad..eb626f6 100644 (file)
--- a/sem.icl
+++ b/sem.icl
@@ -3,6 +3,7 @@ implementation module sem
 import qualified Data.Map as Map
 from Data.Func import $
 import Data.Maybe
+import Data.Void
 import Data.Either
 import Data.Functor
 import Control.Applicative
@@ -49,10 +50,17 @@ semFunDecl fd=:(FunDecl p f args mt vds stmts) =
     (case mt of
         Nothing = let t = IdType f in putIdent f t >>| pure t
         Just t = putIdent f t >>| pure t) >>= \ft ->
-    mapM_ (\a-> putIdent a (IdType <$> freshIdent)) args >>|
-    mapM_ semVarDecl vds >>| 
+       matchFunctions args ft >>|
+    mapM semVarDecl vds >>= \newvds->
     mapM_ (checkStmt $ resultType ft) stmts >>| 
-    restoreGamma gamma >>| pure fd 
+    restoreGamma gamma >>| 
+       pure (FunDecl p f args mt newvds stmts) 
+
+matchFunctions :: [String] Type -> Env Void
+matchFunctions [] (_ ->> _) = liftT $ Left $ Error "Niet genoeg argumentenerror"
+matchFunctions [] t = pure Void
+matchFunctions [x:xs] (t1 ->> t2) = 
+       modify (\(st, r)->('Map'.put x t1 st, r)) >>| matchFunctions xs t2
 
 semVarDecl :: VarDecl -> Env VarDecl
 semVarDecl (VarDecl pos type ident ex) = unify type ex
@@ -63,7 +71,10 @@ checkStmt t (IfStmt c st se) = unify BoolType c >>| mapM (checkStmt t) st
     >>= \st1-> mapM (checkStmt t) se >>= \se1-> pure (IfStmt c st1 se1)
 checkStmt t w=:(WhileStmt c et) = unify BoolType c >>| mapM (checkStmt t) et
     >>= \et1-> pure w
-checkStmt t (AssStmt (VarDef ident fs) e) = undef
+checkStmt t a=:(AssStmt (VarDef ident fs) e) = gets (\(st, r)->'Map'.get ident st)
+    >>= \mt->case mt of
+        Nothing = liftT $ Left $ UndeclaredVariableError zero ident
+        Just t = unify t fs >>= \t1 -> unify t1 e >>| pure a
 checkStmt t r=:(FunStmt (FunCall f es)) = typeFun f es >>| pure r
 checkStmt VoidType r=:(ReturnStmt Nothing) = pure r
 checkStmt t r=:(ReturnStmt (Just e)) = unify t e >>| pure r
@@ -94,7 +105,6 @@ typeExpr (VarExpr p (VarDef ident fs)) = gets (\(st, r)->'Map'.get ident st)
     >>= \mt->case mt of
         Nothing = liftT $ Left $ UndeclaredVariableError p ident
         Just t = unify t fs
-
 typeOp2 :: Expr Expr Op2 [Type] Type -> Env Type
 typeOp2 e1 e2 op ts ret = typeExpr e1 >>= \t1-> typeExpr e2 >>= \t2->
     unify t1 t2 >>= \t3->if (isMember t3 ts) (pure ret)
@@ -238,4 +248,4 @@ saveGamma :: Env Gamma
 saveGamma = get
 
 restoreGamma :: Gamma -> Env Void
-restoreGamma g = put g
\ No newline at end of file
+restoreGamma g = put g