X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=sem.icl;h=ab7aa9c005ef0722e7ab5449df484f477a4a144c;hb=fa73f7e0d251020e47185a94699c41d9575f4052;hp=6e177ecce6b3b06c7eee6ccdfa2a108c32d3d821;hpb=a9c9d183b4bd43472ca0e40ec8b5f044a398c327;p=cc1516.git diff --git a/sem.icl b/sem.icl index 6e177ec..ab7aa9c 100644 --- a/sem.icl +++ b/sem.icl @@ -24,6 +24,7 @@ from parse import :: ParserOutput, :: Error :: Gamma :== ('Map'.Map String Type, [String]) :: Env a :== StateT Gamma (Either SemError) a +//StateT (Gamma -> Either SemError (a, Gamma)) //we need to redefine this even though it is in Control.Monad.State instance MonadTrans (StateT Gamma) where @@ -34,12 +35,13 @@ get = gets id getRandomStream :: Int -> [String] getRandomStream i = genIdents $ filter (isAlpha o toChar) (genRandInt i) where - genIdents r = let (ic, r) = splitAt 5 r in [toString ic: genIdents r] + genIdents r = let (ic, r2) = splitAt 5 r in [toString ic: genIdents r2] -freshIdent :: Gamma -> (String, Gamma) -freshIdent (st, [ident:rest]) = case 'Map'.get ident st of - Nothing = (ident, (st, rest)) - _ = freshIdent (st, rest) +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 @@ -57,22 +59,15 @@ instance toString SemError where toString t1, ". Given: ", toString t2] sem :: AST -> SemOutput -sem (AST vd fd) = case evalStateT m ('Map'.newMap, getRandomStream 0) 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) - - -splitEithers :: [Either a b] -> Either [a] [b] -splitEithers [] = Right [] -splitEithers [Right x:xs] = splitEithers xs >>= \rest->Right [x:rest] -splitEithers xs = Left $ [x\\(Left x)<-xs] - semFunDecl :: FunDecl -> Env FunDecl semFunDecl f = pure f @@ -110,8 +105,9 @@ typeExpr (Op2Expr p e1 BiOr e2) = unify BoolType e1 >>| unify BoolType e2 //a typeExpr (Op2Expr p e1 BiCons e2) = typeExpr e1 >>= \t1-> typeExpr e2 >>= \t2-> unify (ListType t1) t2 +typeExpr (EmptyListExpr p) = freshIdent >>= \frsh-> let t = IdType frsh in + putIdent frsh t >>| pure t //typeExpr (FunExpr p FunCall) = undef -typeExpr (EmptyListExpr p) = pure $ ListType IntType //we'll need quantified types //typeExpr (VarExpr Pos VarDef) = undef //when checking var-expr, be sure to //put the infered type in the context @@ -125,17 +121,24 @@ 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 +replace :: String Type -> Env Void +replace _ _ = undef + instance unify Type where unify IntType IntType = pure IntType unify BoolType BoolType = pure BoolType unify CharType CharType = pure CharType - unify (ListType t1) (ListType t2) = unify t1 t2 + 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 instance zero Pos where @@ -159,4 +162,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]