X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=sem.icl;h=66d9024ab292dd45b00576485b912069a35d7fe1;hb=302891ef956bd735780714742850947bf7588ce5;hp=7af3b20316a292d89e8e4205ff760d862808fd62;hpb=79bfc0933c6ce1f97930053d7a1090e90dd618f1;p=cc1516.git diff --git a/sem.icl b/sem.icl index 7af3b20..66d9024 100644 --- a/sem.icl +++ b/sem.icl @@ -18,6 +18,7 @@ import StdString import StdTuple import StdList import StdBool +import GenEq from Text import class Text(concat), instance Text String @@ -32,7 +33,7 @@ from parse import :: ParserOutput, :: Error instance MonadTrans (StateT Gamma) where liftT m = StateT \s-> m >>= \a-> return (a, s) -get = gets id +get :== gets id sem :: AST -> SemOutput sem (AST vd fd) = case runStateT m ('Map'.newMap, getRandomStream 1) of @@ -41,26 +42,53 @@ sem (AST vd fd) = case runStateT m ('Map'.newMap, getRandomStream 1) of where m :: Env ([VarDecl], [FunDecl]) m = mapM semVarDecl vd >>= \vds -> - mapM semFunDecl fd >>= \fds -> - pure (vds, fds) + mapM semFunDecl fd >>= \fds1 -> + mapM semFunDecl fds1 >>= \fds2 -> + pure (vds, fds2) semFunDecl :: FunDecl -> Env FunDecl semFunDecl fd=:(FunDecl p f args mt vds stmts) = - saveGamma >>= \gamma -> (case mt of - Nothing = let t = IdType f in putIdent f t >>| pure t + Nothing = genType args >>= \infft->putIdent f infft >>| pure infft Just t = putIdent f t >>| pure t) >>= \ft -> - matchFunctions args ft >>| + saveGamma >>= \gamma -> + matchFunctions args ft >>= \tres-> mapM semVarDecl vds >>= \newvds-> - mapM_ (checkStmt $ resultType ft) stmts >>| - 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 + mapM (checkStmt tres) stmts >>= \newstmts-> + case mt of + Nothing = inferReturnType stmts + >>= \returntype->reconstructType args returntype + >>= \ftype->restoreGamma gamma + >>| putIdent f ftype >>| pure ( + FunDecl p f args (Just ftype) newvds newstmts) + Just t = restoreGamma gamma + >>| pure (FunDecl p f args mt newvds newstmts) + +inferReturnType :: [Stmt] -> Env Type +inferReturnType [] = pure VoidType +inferReturnType [ReturnStmt (Just t):rest] = typeExpr t +inferReturnType [ReturnStmt _:rest] = pure VoidType +inferReturnType [_:rest] = inferReturnType rest + +reconstructType :: [String] Type -> Env Type +reconstructType [] t = pure t +reconstructType [x:xs] t = gets (\(st, r)->'Map'.get x st) + >>= \mtype->case mtype of + Nothing = liftT $ Left $ Error "Not used ????" + Just type = reconstructType xs t >>= \resttype->pure (type ->> resttype) + +genType :: [String] -> Env Type +genType [] = freshIdent >>= \fi->pure $ IdType fi +genType [x:xs] = liftM2 (->>) (freshIdent >>= \fi->pure $ IdType fi) + (genType xs) + +matchFunctions :: [String] Type -> Env Type +matchFunctions [] (_ ->> _) = liftT $ Left $ Error "Not enough arguments" +matchFunctions _ (VoidType ->> _) = liftT $ Left $ Error "Cannot have a void type in the middle of the function definition" matchFunctions [x:xs] (t1 ->> t2) = modify (\(st, r)->('Map'.put x t1 st, r)) >>| matchFunctions xs t2 +matchFunctions [] t = pure t +matchFunctions _ t = liftT $ Left $ Error "Too much argumnts" semVarDecl :: VarDecl -> Env VarDecl semVarDecl (VarDecl pos type ident ex) = unify type ex @@ -105,7 +133,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) @@ -145,8 +172,8 @@ instance unify Expr where "Expression cannot be a higher order function. Yet..." unify VoidType e = liftT $ Left $ ParseError (extrPos e) "Expression cannot be a Void type." - unify (IdType _) e = liftT $ Left $ ParseError (extrPos e) - "Expression cannot be an polymorf type." +// unify (IdType _) e = liftT $ Left $ ParseError (extrPos e) +// "Expression cannot be an polymorf type." unify VarType e = typeExpr e //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 @@ -249,4 +276,9 @@ saveGamma :: Env Gamma saveGamma = get restoreGamma :: Gamma -> Env Void -restoreGamma g = put g +restoreGamma (oldstate, _) = gets snd >>= \newr->put (oldstate, newr) + +derive gEq Type +instance == Type where + (==) (IdType _) (IdType _) = True + (==) o1 o2 = gEq{|*|} o1 o2