implementation module sem
import qualified Data.Map as Map
+
from Data.Func import $
-import Data.Maybe
-import Data.Either
-import Data.Functor
-import Control.Applicative
+from StdFunc import o
+
import Control.Monad
-import Control.Monad.State
-import Control.Monad.Identity
-import StdMisc
-from StdFunc import id, const
+import Data.Either
+import Data.Monoid
+
import StdString
import StdList
+import StdMisc
+import StdEnum
+import RWST
+import GenEq
from Text import class Text(concat), instance Text String
import AST
-from parse import :: ParserOutput, :: Error
-:: Gamma :== 'Map'.Map String Type
-:: Env a :== (State Gamma (Either SemError a))
+:: Scheme = Forall [String] Type
+:: Gamma :== 'Map'.Map String Scheme
+:: Constraints :== [(Type, Type)]
+:: Infer a :== RWST Gamma Constraints [String] (Either SemError) a
+:: SemError
+ = ParseError Pos String
+ | UnifyError Pos Type Type
+ | FieldSelectorError Pos Type FieldSelector
+ | OperatorError Pos Op2 Type
+ | UndeclaredVariableError Pos String
+ | ArgumentMisMatchError Pos String
+ | Error String
+
+variableStream :: [String]
+variableStream = map toString [1..]
-get = state $ \s -> (s,s)
+sem :: AST -> SemOutput
+sem (AST fd) = Right (AST fd, 'Map'.newMap)
-putIdent :: String Type -> Env Void
-putIdent i t = gets ('Map'.get i) >>= \mt -> case mt of
- Nothing = pure <$> modify ('Map'.put i t)
- Just t2 = unify t t2 >>= \r -> case r of
- Left e = pure $ Left e
- Right t3 = pure <$> modify ('Map'.put i t3)
+instance toString Scheme where
+ toString (Forall x t) =
+ concat ["Forall ": map ((+++) "\n") x] +++ toString t
-instance toString SemError where
- toString (ParseError p e) = concat [
- toString p,"SemError: ParseError: ", e]
- toString (Error e) = "SemError: " +++ e
- toString (UnifyErrorStub t1 t2) = toString (UnifyError {line=0,col=0} t1 t2)
- toString (UnifyError p t1 t2) = concat [
- toString p,
- "SemError: Cannot unify types. Expected: ",
- toString t1, ". Given: ", toString t2]
+instance toString Gamma where
+ toString mp =
+ concat [concat [k, ": ", toString v, "\n"]\\(k, v)<-'Map'.toList mp]
-sem :: AST -> SemOutput
-sem (AST vd fd)
-# (eithervds, gamma) = runState (mapM semVarDecl vd) 'Map'.newMap
-# (eitherfds, gamma) = runState (mapM semFunDecl fd) gamma
-= case splitEithers eithervds of
- (Left errs) = Left $ errs ++ [x\\(Left x)<-eitherfds]
- (Right vds) = case splitEithers eitherfds of
- (Left errs) = Left errs
- (Right fds) = Right $ AST 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 $ Right f
-
-semVarDecl :: VarDecl -> Env VarDecl
-semVarDecl vd=:(VarDecl pos type ident ex) = unify type ex
- >>= \et->pure (
- et >>= \t->pure $ VarDecl pos t ident ex)
-//Right v
-// //TODO ident in de environment
-// Right e = Right $ pure vd
-
-typeOp1 :: Pos Expr Type -> Env Type
-typeOp1 p expr rtype = unify rtype expr
-
-typeExpr :: Expr -> Env Type
-typeExpr (IntExpr _ _) = pure $ Right IntType
-typeExpr (CharExpr _ _) = pure $ Right CharType
-typeExpr (BoolExpr _ _) = pure $ Right BoolType
-typeExpr (Op1Expr p UnNegation expr) = typeOp1 p expr BoolType
-typeExpr (Op1Expr p UnMinus expr) = typeOp1 p expr IntType
-typeExpr (TupleExpr p (e1, e2)) = typeExpr e1
- >>= \ete1->typeExpr e2 >>= \ete2->pure (
- ete1 >>= \te1->ete2 >>= \te2->Right $ TupleType (te1, te2))
-//typeExpr (Op2Expr Pos Expr Op2 Expr) = undef
-//typeExpr (FunExpr Pos FunCall) = undef
-//typeExpr (EmptyListExpr Pos) = undef
-//typeExpr (VarExpr Pos VarDef) = undef
-
-class unify a :: Type a -> Env Type
-
-instance unify Expr where
- unify (_ ->> _) e = pure $ Left $ ParseError (extrPos e)
- "Expression cannot be a higher order function. Yet..."
- unify VoidType e = pure $ Left $ ParseError (extrPos e)
- "Expression cannot be a Void type."
- unify (IdType _) e = pure $ Left $ ParseError (extrPos e)
- "Expression cannot be an polymorf type."
- unify t e = typeExpr e
- >>= \eithertype->case eithertype of
- Left e = pure $ Left e
- Right tex = unify t tex >>= \eitherun->case eitherun of
- Left err = pure $ Left $ decErr e err
- Right t = pure $ Right t
-
-instance unify Type where
- unify IntType IntType = pure $ Right IntType
- unify BoolType BoolType = pure $ Right BoolType
- unify CharType CharType = pure $ Right CharType
- unify t1 t2 = pure $ Left $ UnifyError zero t1 t2
-
-instance zero Pos where
- zero = {line=0,col=0}
-
-decErr :: Expr SemError -> SemError
-decErr e (UnifyError _ t1 t2) = UnifyError (extrPos e) t1 t2
-decErr e (ParseError _ s) = ParseError (extrPos e) s
-decErr e err = err
-
-extrPos :: Expr -> Pos
-extrPos (VarExpr p _) = p
-extrPos (Op2Expr p _ _ _) = p
-extrPos (Op1Expr p _ _) = p
-extrPos (IntExpr p _) = p
-extrPos (CharExpr p _) = p
-extrPos (BoolExpr p _) = p
-extrPos (FunExpr p _) = p
-extrPos (EmptyListExpr p) = p
-extrPos (TupleExpr p _) = p
+instance toString SemError where
+ toString se = "SemError: "
+
+uni :: Type Type -> Infer ()
+uni t1 t2 = tell [(t1, t2)]
+
+inEnv :: (String, Scheme) (Infer a) -> (Infer a)
+inEnv (x, sc) m = local scope m
+ where
+ scope e = 'Map'.put x sc ('Map'.del x e )
+
+class infer a :: a -> Infer Type
+
+instance infer Expr where
+ infer (VarExpr _ vd) = undef
+ infer (Op2Expr _ e1 op e2) = case op of
+ BiPlus = pure IntType
+ BiMinus = pure IntType
+ BiTimes = pure IntType
+ BiDivide = pure IntType
+ BiMod = pure IntType
+ BiLesser = pure IntType
+ BiGreater = pure IntType
+ BiLesserEq = pure IntType
+ BiGreaterEq = pure IntType
+ BiAnd = pure BoolType
+ BiOr = pure BoolType
+ BiEquals = infer e1
+ BiUnEqual = infer e1 // maybe check e2?
+ BiCons = infer e1 >>= \it1->pure $ ListType it1
+ infer (Op1Expr _ op e) = case op of
+ UnMinus = pure IntType
+ UnNegation = pure BoolType
+ infer (IntExpr _ _) = pure IntType
+ infer (CharExpr _ _) = pure CharType
+ infer (BoolExpr _ _) = pure BoolType
+ infer (FunExpr _ _ _ _) = undef
+ infer (EmptyListExpr _) = undef
+ infer (TupleExpr _ (e1, e2)) =
+ infer e1 >>= \et1->infer e2 >>= \et2->pure $ TupleType (et1, et2)
+
+//:: VarDef = VarDef String [FieldSelector]
+//:: FieldSelector = FieldHd | FieldTl | FieldFst | FieldSnd
+//:: Op1 = UnNegation | UnMinus
+//:: Op2 = BiPlus | BiMinus | BiTimes | BiDivide | BiMod | BiEquals | BiLesser |
+// BiGreater | BiLesserEq | BiGreaterEq | BiUnEqual | BiAnd | BiOr | BiCons
+//:: FunDecl = FunDecl Pos String [String] (Maybe Type) [VarDecl] [Stmt]
+//:: FunCall = FunCall String [Expr]
+//:: Stmt
+// = IfStmt Expr [Stmt] [Stmt]
+// | WhileStmt Expr [Stmt]
+// | AssStmt VarDef Expr
+// | FunStmt FunCall
+// | ReturnStmt (Maybe Expr)
+//:: Pos = {line :: Int, col :: Int}
+//:: AST = AST [VarDecl] [FunDecl]
+//:: VarDecl = VarDecl Pos Type String Expr
+//:: Type
+// = TupleType (Type, Type)
+// | ListType Type
+// | IdType String
+// | IntType
+// | BoolType
+// | CharType
+// | VarType
+// | VoidType
+// | (->>) infixl 7 Type Type