aboutsummaryrefslogtreecommitdiff
path: root/Sil
diff options
context:
space:
mode:
authorCamil Staps2017-07-20 20:40:38 +0000
committerCamil Staps2017-07-20 20:40:38 +0000
commit62c9c126ed3eedf981cc087938fd98f7afb17506 (patch)
treebdab83683ff75ab915d3d8af612235c55812d772 /Sil
parentCleanup (diff)
Check the type of the main function (should be Void)
Diffstat (limited to 'Sil')
-rw-r--r--Sil/Check.dcl6
-rw-r--r--Sil/Check.icl27
-rw-r--r--Sil/Compile.icl2
-rw-r--r--Sil/Types.dcl4
-rw-r--r--Sil/Types.icl3
5 files changed, 32 insertions, 10 deletions
diff --git a/Sil/Check.dcl b/Sil/Check.dcl
index e71448f..a34eb99 100644
--- a/Sil/Check.dcl
+++ b/Sil/Check.dcl
@@ -5,13 +5,15 @@ from StdOverloaded import class toString
from Data.Maybe import :: Maybe
from Sil.Syntax import :: Program, :: Name
+from Sil.Types import :: Type
:: CheckError
= NoMainFunction
+ | MainFunctionInvalidType Type
| DuplicateFunctionName Name
| DuplicateLocalName Name Name
- | ReturnExpressionFromVoidError Name
- | NoReturnFromNonVoidError Name
+ | ReturnExpressionFromVoid Name
+ | NoReturnFromNonVoid Name
| LocalVoid Name Name
instance toString CheckError
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 ++
diff --git a/Sil/Compile.icl b/Sil/Compile.icl
index af82f3e..50cc86b 100644
--- a/Sil/Compile.icl
+++ b/Sil/Compile.icl
@@ -181,7 +181,7 @@ where
typeresolver :: Name -> Maybe (MaybeError TypeError Type)
typeresolver n = case [f \\ f <- p.p_funs | f.f_name == n] of
[] -> Nothing
- [f:_] -> type (const Nothing) f
+ [f:_] -> type zero f
instance gen Function
where
diff --git a/Sil/Types.dcl b/Sil/Types.dcl
index 1659436..5fd159e 100644
--- a/Sil/Types.dcl
+++ b/Sil/Types.dcl
@@ -1,6 +1,6 @@
definition module Sil.Types
-from StdOverloaded import class ==, class toString
+from StdOverloaded import class ==, class toString, class zero
from Data.Error import :: MaybeError
from Data.Maybe import :: Maybe
@@ -28,6 +28,8 @@ typeSize :: Type -> Int
:: TypeResolver :== Name -> Maybe (MaybeError TypeError Type)
+instance zero TypeResolver
+
class type a :: TypeResolver a -> Maybe (MaybeError TypeError Type)
instance type Function
instance type Expression
diff --git a/Sil/Types.icl b/Sil/Types.icl
index 5f17956..40fc0cb 100644
--- a/Sil/Types.icl
+++ b/Sil/Types.icl
@@ -1,5 +1,6 @@
implementation module Sil.Types
+from StdFunc import const
import StdList
import StdOverloaded
import StdString
@@ -34,6 +35,8 @@ typeSize TVoid = 0
typeSize TBool = 1
typeSize TInt = 1
+instance zero TypeResolver where zero = const Nothing
+
instance type Function
where
type res f = Just $ Ok $ foldr (-->) f.f_type [a.arg_type \\ a <- f.f_args]