X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=sem.icl;h=e2227d168fde2b92938604d92724d623d646070c;hb=a8348a333a567e5a469d1e5f8ec6c3dafc051c91;hp=a041cee3215065f1210481973b65b49cf02dff12;hpb=8259ed46f53f70bc732ce8756ddf2b6f000df6a4;p=cc1516.git diff --git a/sem.icl b/sem.icl index a041cee..e2227d1 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 @@ -40,10 +41,15 @@ sem (AST vd fd) = case runStateT m ('Map'.newMap, getRandomStream 1) of Right ((vds, fds), gamma) = Right ((AST vds fds), gamma) where m :: Env ([VarDecl], [FunDecl]) - m = mapM semVarDecl vd >>= \vds -> - mapM semFunDecl fd >>= \fds1 -> - mapM semFunDecl fds1 >>= \fds2 -> - pure (vds, fds2) + m = mapM semVarDecl vd >>= \vd1 -> + mapM semFunDecl fd >>= \fd1 -> + mapM semVarDecl vd1 >>= \vd2 -> + mapM semFunDecl fd1 >>= \fd2 -> + mapM semVarDecl vd2 >>= \vd3 -> + mapM semFunDecl fd2 >>= \fd3 -> + mapM semVarDecl vd3 >>= \vd4 -> + mapM semFunDecl fd3 >>= \fd4 -> //Dit is puur om te proberen + pure (vd4, fd4) semFunDecl :: FunDecl -> Env FunDecl semFunDecl fd=:(FunDecl p f args mt vds stmts) = @@ -54,15 +60,21 @@ semFunDecl fd=:(FunDecl p f args mt vds stmts) = matchFunctions args ft >>= \tres-> mapM semVarDecl vds >>= \newvds-> mapM (checkStmt tres) stmts >>= \newstmts-> - pure IntType >>= \returntype-> case mt of - Nothing = reconstructType args returntype - >>= \ftype->restoreGamma gamma + Nothing = inferReturnType stmts + >>= \returntype->reconstructType args tres + >>= \ftype->restoreGamma gamma >>| putIdent f ftype >>| pure ( - FunDecl p f args (Just ftype) newvds newstmts) + 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) @@ -126,10 +138,9 @@ 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) + unify t1 t2 >>= \t3->if (isMember t3 [IdType "":ts]) (pure ret) (liftT $ Left $ OperatorError (extrPos e1) op t3) buildFunctionType :: String [Expr] -> Env Type @@ -170,6 +181,8 @@ instance unify Expr where // "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=:(IdType id) e = typeExpr e >>= \tex->unify t tex + >>= \type->putIdent id type >>| pure type 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) @@ -185,6 +198,7 @@ instance unify Type where 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 VoidType VoidType = pure VoidType unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2 instance zero Pos where @@ -271,3 +285,8 @@ saveGamma = get restoreGamma :: Gamma -> Env Void restoreGamma (oldstate, _) = gets snd >>= \newr->put (oldstate, newr) + +derive gEq Type +instance == Type where + (==) (IdType _) (IdType _) = True + (==) o1 o2 = gEq{|*|} o1 o2