From 62c9c126ed3eedf981cc087938fd98f7afb17506 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 20 Jul 2017 20:40:38 +0000 Subject: Check the type of the main function (should be Void) --- Sil/Check.icl | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'Sil/Check.icl') diff --git a/Sil/Check.icl b/Sil/Check.icl index 61f5ac7..9b24f50 100644 --- a/Sil/Check.icl +++ b/Sil/Check.icl @@ -8,6 +8,7 @@ import StdOverloaded import StdString import StdTuple +import Data.Error from Data.Func import $, mapSt, seqSt import Data.List import Data.Maybe @@ -21,13 +22,15 @@ instance toString CheckError where toString NoMainFunction = "Error: no main function." + toString (MainFunctionInvalidType t) + = "Error: function 'main' should have type Void but has type " <+ t <+ "." toString (DuplicateFunctionName n) = "Error: multiply defined: '" <+ n <+ "'." toString (DuplicateLocalName f arg) = "Error: multiply defined: '" <+ arg <+ "' in '" <+ f <+ "'." - toString (ReturnExpressionFromVoidError f) + toString (ReturnExpressionFromVoid f) = "Type error: an expression was returned from void function '" <+ f <+ "'." - toString (NoReturnFromNonVoidError f) + toString (NoReturnFromNonVoid f) = "Type error: no return from non-void function '" <+ f <+ "'." toString (LocalVoid f l) = "Type error: local variable '" <+ l <+ "' in '" <+ f <+ "' cannot have type Void." @@ -36,7 +39,10 @@ instance <<< CheckError where <<< f e = f <<< toString e <<< "\r\n" checkProgram :: *(Maybe *File) Program -> *([CheckError], *Maybe *File) checkProgram err prog - = checkErrors [checkFunctionNames, checkMainFunction] prog + = checkErrors + [ checkFunctionNames + , checkMainFunction + ] prog $ appFst flatten $ mapSt (flip checkFunction) prog.p_funs err where checkMainFunction :: Program -> [CheckError] @@ -51,14 +57,18 @@ where | not (isEmpty fs) && isMember (hd fs) (tl fs)] checkFunction :: *(Maybe *File) Function -> *([CheckError], *Maybe *File) -checkFunction err f = checkErrors [checkLocals, checkReturnAndVoid] f $ noErrors err +checkFunction err f = checkErrors + [ checkLocals + , checkReturnAndVoid + , checkMainFunctionType + ] f $ noErrors err where checkReturnAndVoid :: Function -> [CheckError] checkReturnAndVoid f = case f.f_type of TVoid -> case [st \\ st=:(Return (Just _)) <- allStatements f] of [] -> [] - _ -> [ReturnExpressionFromVoidError f.f_name] - _ -> if (sureToReturn f.f_code) [] [NoReturnFromNonVoidError f.f_name] + _ -> [ReturnExpressionFromVoid f.f_name] + _ -> if (sureToReturn f.f_code) [] [NoReturnFromNonVoid f.f_name] where sureToReturn :: CodeBlock -> Bool sureToReturn cb = case cb.cb_content of @@ -70,6 +80,11 @@ where If bs Nothing -> all (sureToReturn o snd) bs _ -> False + checkMainFunctionType :: Function -> [CheckError] + checkMainFunctionType f=:{f_name="main",f_type=TVoid,f_args=[]} = [] + checkMainFunctionType f=:{f_name="main"} = [MainFunctionInvalidType $ fromOk $ fromJust $ type zero f] + checkMainFunctionType _ = [] + checkLocals :: Function -> [CheckError] checkLocals f = checkDupName [a.arg_name \\ a <- f.f_args] f.f_code ++ -- cgit v1.2.3