diff --git a/src/Semantic/ExpressionChecker.hs b/src/Semantic/ExpressionChecker.hs index 83e147a..fb3d1f6 100644 --- a/src/Semantic/ExpressionChecker.hs +++ b/src/Semantic/ExpressionChecker.hs @@ -52,12 +52,12 @@ defaultMap = [ Func "count" [BasicType "Any"] (BasicType "Integer") ] -checkExpression :: [Symbol] -> Expression -> Either Type TypeCheckError +checkExpression :: [Symbol] -> Expression -> Either TypeCheckError Type checkExpression symbolMap (Variable var) = findVarType var symbolMap -checkExpression _ (Int _) = Left $ BasicType "Integer" -checkExpression _ (Real _) = Left $ BasicType "Double" -checkExpression _ (Boolean _) = Left $ BasicType "Boolean" -checkExpression _ Empty = Left $ BasicType "Empty" +checkExpression _ (Int _) = Right $ BasicType "Integer" +checkExpression _ (Real _) = Right $ BasicType "Double" +checkExpression _ (Boolean _) = Right $ BasicType "Boolean" +checkExpression _ Empty = Right $ BasicType "Empty" checkExpression symbolMap (Parens ex) = checkExpression symbolMap ex checkExpression symbolMap (List lst) = checkList symbolMap lst checkExpression symbolMap (PrefixExp name ex) = checkFunctionCall symbolMap name [checkExpression symbolMap ex] @@ -65,58 +65,58 @@ checkExpression symbolMap (Function name exps) = checkFunctionCall symbolMap nam checkExpression symbolMap (PostfixExp name ex) = checkFunctionCall symbolMap name [checkExpression symbolMap ex] checkExpression symbolMap (InfixExp name ex1 ex2) = checkFunctionCall symbolMap name (checkExpression symbolMap ex1: [checkExpression symbolMap ex2]) checkExpression symbolMap (IfSimple cond ex) - | isLeft condType && isLeft (typeMatch (fromLeftUnsafe condType) (BasicType "Boolean")) = checkExpression symbolMap ex - | otherwise = Right IfConditionNotBoolean + | isLeft condType && isLeft (typeMatch (fromRightUnsafe condType) (BasicType "Boolean")) = checkExpression symbolMap ex + | otherwise = Left IfConditionNotBoolean where condType = checkExpression symbolMap cond checkExpression symbolMap (IfElse cond ex1 ex2) - | isRight condType || isRight (typeMatch (fromLeftUnsafe condType) (BasicType "Boolean")) = Right IfConditionNotBoolean - | isRight ex1Type || isRight ex2Type || isRight (typeMatch (fromLeftUnsafe ex1Type) (fromLeftUnsafe ex2Type)) = Right IfExpressionsDifferentTypes + | isRight condType || isRight (typeMatch (fromRightUnsafe condType) (BasicType "Boolean")) = Left IfConditionNotBoolean + | isRight ex1Type || isRight ex2Type || isRight (typeMatch (fromRightUnsafe ex1Type) (fromRightUnsafe ex2Type)) = Left IfExpressionsDifferentTypes | otherwise = ex1Type where condType = checkExpression symbolMap cond ex1Type = checkExpression symbolMap ex1 ex2Type = checkExpression symbolMap ex2 -checkList :: [Symbol] -> [Expression] -> Either Type TypeCheckError +checkList :: [Symbol] -> [Expression] -> Either TypeCheckError Type checkList symbs exps - | isLeft typ && fromLeftUnsafe typ == BasicType "Any" = Left $ BasicType "Empty" + | isRight typ && fromRightUnsafe typ == BasicType "Any" = Right $ BasicType "Empty" | otherwise = typ where typ = checkList1 symbs exps (BasicType "Any") -checkList1 :: [Symbol] -> [Expression] -> Type -> Either Type TypeCheckError -checkList1 _ [] typ = Left typ +checkList1 :: [Symbol] -> [Expression] -> Type -> Either TypeCheckError Type +checkList1 _ [] typ = Right typ checkList1 symbs (ex : exps) typ | isRight exTyp = exTyp | isRight match = match - | otherwise = checkList1 symbs exps (fromLeftUnsafe match) + | otherwise = checkList1 symbs exps (fromRightUnsafe match) where exTyp = checkExpression symbs ex - match = typeMatch typ (fromLeftUnsafe exTyp) + match = typeMatch typ (fromRightUnsafe exTyp) -checkFunctionCall :: [Symbol] -> String -> [Either Type TypeCheckError] -> Either Type TypeCheckError -checkFunctionCall [] fun args = Right $ UndefinedFunction $ "Undefined function: \"" ++ fun ++ "\" [" ++ concatMap typeName (lefts args) ++ "]" +checkFunctionCall :: [Symbol] -> String -> [Either TypeCheckError Type] -> Either TypeCheckError Type +checkFunctionCall [] fun args = Left $ UndefinedFunction $ "Undefined function: \"" ++ fun ++ "\" [" ++ concatMap typeName (rights args) ++ "]" checkFunctionCall ((Func n a r):symbolMap) name args - | length left /= length args = Right ErrorInsideFunction - | name == n && all isLeft (zipWith typeMatch a left) = Left r + | length right /= length args = Left ErrorInsideFunction + | name == n && all isRight (zipWith typeMatch a right) = Right r | otherwise = checkFunctionCall symbolMap name args - where left = lefts args + where right = rights args checkFunctionCall (_:symbolMap) name args = checkFunctionCall symbolMap name args --Try to match 2nd type to first type -typeMatch :: Type -> Type -> Either Type TypeCheckError -typeMatch (BasicType "Any") x = Left x -typeMatch (BasicType "Double") (BasicType "Integer") = Left $ BasicType "Dobule" +typeMatch :: Type -> Type -> Either TypeCheckError Type +typeMatch (BasicType "Any") x = Right x +typeMatch (BasicType "Double") (BasicType "Integer") = Right $ BasicType "Dobule" typeMatch s (BasicType s2) - | s == BasicType s2 = Left s - | otherwise = Right $ TypeMismatch (typeName s) s2 + | s == BasicType s2 = Right s + | otherwise = Left $ TypeMismatch (typeName s) s2 typeMatch s s2 - | s == s2 = Left s + | s == s2 = Right s | isJust $ superType s2 = typeMatch s (fromJust $ superType s2) - | otherwise = Right $ TypeMismatch (typeName s) (typeName s2) + | otherwise = Left $ TypeMismatch (typeName s) (typeName s2) -findVarType :: String -> [Symbol] -> Either Type TypeCheckError -findVarType var [] = Right $ UndefinedVariable var +findVarType :: String -> [Symbol] -> Either TypeCheckError Type +findVarType var [] = Left $ UndefinedVariable var findVarType x ((Var name typ):symbols) - | x == name = Left typ + | x == name = Right typ | otherwise = findVarType x symbols findVarType x (_:symbols) = findVarType x symbols diff --git a/src/Semantic/TypeChecker.hs b/src/Semantic/TypeChecker.hs index 402943d..efd8f45 100644 --- a/src/Semantic/TypeChecker.hs +++ b/src/Semantic/TypeChecker.hs @@ -12,19 +12,19 @@ data TypeCheckError = | TypeMismatch String String deriving (Show) -checkAttributes :: [Type] -> [TypeAttribute] -> [Either Type TypeCheckError] +checkAttributes :: [Type] -> [TypeAttribute] -> [Either TypeCheckError Type] checkAttributes _ [] = [] checkAttributes definedTypes ((MakeTypeAttribute _ name _ _):as) = checkType definedTypes name : checkAttributes definedTypes as -checkType :: [Type] -> Type -> Either Type TypeCheckError -checkType _ (MakeType "int" _ _ _) = Left $ BasicType "Integer" -checkType _ (MakeType "string" _ _ _) = Left $ BasicType "String" -checkType _ (MakeType "number" _ _ _) = Left $ BasicType "Double" -checkType _ (MakeType "boolean" _ _ _) = Left $ BasicType "Bool" -checkType _ (MakeType "time" _ _ _) = Left $ BasicType "Time" +checkType :: [Type] -> Type -> Either TypeCheckError Type +checkType _ (MakeType "int" _ _ _) = Right $ BasicType "Integer" +checkType _ (MakeType "string" _ _ _) = Right $ BasicType "String" +checkType _ (MakeType "number" _ _ _) = Right $ BasicType "Double" +checkType _ (MakeType "boolean" _ _ _) = Right $ BasicType "Bool" +checkType _ (MakeType "time" _ _ _) = Right $ BasicType "Time" checkType definedTypes name - | name `elem` definedTypes = Left name - | otherwise = Right $ UndefinedType (typeName name) + | name `elem` definedTypes = Right name + | otherwise = Left $ UndefinedType (typeName name) addDefinedTypes :: [Type] -> [Type] -> [Type] addDefinedTypes l [] = l