From 90a8f16e5f1d852f21fbbaf2b0631d348973152a Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 30 Aug 2022 23:21:50 +0100 Subject: Check undefined types --- src/Compiler.hs | 26 ++++++++++++++++++++++++++ src/Error.hs | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Compiler.hs b/src/Compiler.hs index f788c11..785efab 100644 --- a/src/Compiler.hs +++ b/src/Compiler.hs @@ -3,6 +3,7 @@ module Compiler where import qualified Ast as A import Control.Monad.State import Data.Either (rights) +import Data.Maybe (catMaybes, fromMaybe) import Env import Error import System.Environment (getEnv, getEnvironment) @@ -77,6 +78,29 @@ typecheckReturn (Just value) fret = do else return $ Just $ "invalid return value\n found: " ++ showMaybet r ++ "\n expected: " ++ showMaybet fret Left _ -> return $ Nothing -- error resolving return value +-- built-in types +types = ["bool", "u8", "s8", "u16", "s16"] + +definedType :: A.Type -> Bool +definedType (A.Type t) = t `elem` types +definedType (A.FuncType ts r) = + all definedType ts && fromMaybe False (fmap definedType r) + +verifyFuncTypes :: String -> [A.FuncParam] -> Maybe A.Type -> SourcePos -> [Error] +verifyFuncTypes ident params ret pos = do + ( catMaybes $ + map + ( \(id, t, pos) -> + if not (definedType t) + then Just $ Error UndefinedType ("undefined type in \"" ++ id ++ "\"") pos + else Nothing + ) + params + ) + ++ if not (fromMaybe True (fmap definedType ret)) + then [Error UndefinedType ("undefined return type in \"" ++ ident ++ "\"") pos] + else [] + compile :: A.Expr -> State CompState CompResult compile x = do case x of @@ -90,6 +114,8 @@ compile x = do (A.Func ident params ret body priv anon pos) -> do -- current env (ev, errs) <- get + -- check for undefined types + (ev, errs) <- return $ (ev, (verifyFuncTypes ident params ret pos) ++ errs) -- updated with the function (ev, errs) <- return $ case addSymUniq ev (ident, ftype, pos) of diff --git a/src/Error.hs b/src/Error.hs index 40bb046..9aad85d 100644 --- a/src/Error.hs +++ b/src/Error.hs @@ -4,7 +4,7 @@ import Data.List (sort) import Text.Parsec (SourcePos, errorPos) import Text.Parsec.Error (ParseError, errorMessages, showErrorMessages) -data ErrorType = GenericError | TypeError | UnexpectedReturn | AlreadyDefined | NonCallable | Undefined deriving (Show) +data ErrorType = GenericError | TypeError | UnexpectedReturn | AlreadyDefined | NonCallable | Undefined | UndefinedType deriving (Show) instance Enum ErrorType where fromEnum GenericError = 0 @@ -13,6 +13,7 @@ instance Enum ErrorType where fromEnum AlreadyDefined = 3 fromEnum NonCallable = 4 fromEnum Undefined = 5 + fromEnum UndefinedType = 6 toEnum _ = error "toEnum is undefined for Error" data Error = Error ErrorType String SourcePos -- cgit v1.2.3