aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2017-07-20 08:24:33 +0000
committerCamil Staps2017-07-20 08:24:33 +0000
commitb56b655f0bea1922999305d8e88bf16e874098a3 (patch)
tree8e236349c9325cd70664c09809a58ad9f1bcd46c
parentAdd checks: no main, duplicate function, duplicate local (diff)
Add checks for locals with type Void
-rw-r--r--Sil/Check.dcl1
-rw-r--r--Sil/Check.icl16
-rw-r--r--Sil/Syntax.dcl9
-rw-r--r--Sil/Syntax.icl20
-rw-r--r--examples/errors.sil4
5 files changed, 46 insertions, 4 deletions
diff --git a/Sil/Check.dcl b/Sil/Check.dcl
index 1d5929d..e71448f 100644
--- a/Sil/Check.dcl
+++ b/Sil/Check.dcl
@@ -12,6 +12,7 @@ from Sil.Syntax import :: Program, :: Name
| DuplicateLocalName Name Name
| ReturnExpressionFromVoidError Name
| NoReturnFromNonVoidError Name
+ | LocalVoid Name Name
instance toString CheckError
diff --git a/Sil/Check.icl b/Sil/Check.icl
index fc80324..37ee282 100644
--- a/Sil/Check.icl
+++ b/Sil/Check.icl
@@ -28,6 +28,8 @@ where
= "Type error: an expression was returned from void function '" <+ f <+ "'."
toString (NoReturnFromNonVoidError 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."
instance <<< CheckError where <<< f e = f <<< toString e <<< "\r\n"
@@ -68,12 +70,14 @@ where
_ -> False
checkLocals :: Function -> [CheckError]
- checkLocals f = check [a.arg_name \\ a <- f.f_args] f.f_code
+ checkLocals f =
+ checkDupName [a.arg_name \\ a <- f.f_args] f.f_code ++
+ concatMap checkVoid (allLocals f)
where
- check :: [Name] CodeBlock -> [CheckError]
- check defined cb =
+ checkDupName :: [Name] CodeBlock -> [CheckError]
+ checkDupName defined cb =
[DuplicateLocalName f.f_name l \\ l <- defined | isMember l locals] ++
- concatMap (check (locals ++ defined)) (underlyingCBs cb)
+ concatMap (checkDupName (locals ++ defined)) (underlyingCBs cb)
where locals = [i.init_name \\ i <- cb.cb_init]
underlyingCBs :: CodeBlock -> [CodeBlock]
@@ -87,6 +91,10 @@ where
findCBs (While _ cb) = [cb]
findCBs (MachineStm _) = []
+ checkVoid :: (Type, Name) -> [CheckError]
+ checkVoid (TVoid, n) = [LocalVoid f.f_name n]
+ checkVoid _ = []
+
checkErrors :: [(a -> [CheckError])] a *([CheckError], Maybe *File) -> *([CheckError], *Maybe *File)
checkErrors cks x st = seqSt error (concatMap (flip ($) x) cks) st
diff --git a/Sil/Syntax.dcl b/Sil/Syntax.dcl
index 42097c5..1aa0c8b 100644
--- a/Sil/Syntax.dcl
+++ b/Sil/Syntax.dcl
@@ -84,6 +84,15 @@ instance allStatements Function
instance allStatements CodeBlock
instance allStatements Statement
+class allCodeBlocks a :: a -> [CodeBlock]
+instance allCodeBlocks Function
+instance allCodeBlocks CodeBlock
+instance allCodeBlocks Statement
+
+class allLocals a :: a -> [(Type, Name)]
+instance allLocals Function
+instance allLocals CodeBlock
+
/**
* Size of an expression on the stack
*/
diff --git a/Sil/Syntax.icl b/Sil/Syntax.icl
index f78ba83..8083eba 100644
--- a/Sil/Syntax.icl
+++ b/Sil/Syntax.icl
@@ -77,6 +77,26 @@ where
allStatements st=:(While _ cb) = [st:allStatements cb]
allStatements st=:(MachineStm _) = [st]
+instance allCodeBlocks Function where allCodeBlocks f = allCodeBlocks f.f_code
+
+instance allCodeBlocks CodeBlock
+where allCodeBlocks cb = [cb:concatMap allCodeBlocks cb.cb_content]
+
+instance allCodeBlocks Statement
+where
+ allCodeBlocks (If bs Nothing) = concatMap (allCodeBlocks o snd) bs
+ allCodeBlocks (If bs (Just e)) = [e:concatMap (allCodeBlocks o snd) bs]
+ allCodeBlocks (While _ cb) = [cb]
+ allCodeBlocks _ = []
+
+instance allLocals Function
+where
+ allLocals f = [(a.arg_type, a.arg_name) \\ a <- f.f_args] ++
+ allLocals f.f_code
+
+instance allLocals CodeBlock
+where allLocals cb = [(i.init_type, i.init_name) \\ i <- cb.cb_init]
+
typeSize :: Type -> Int
typeSize TVoid = 0
typeSize TBool = 1
diff --git a/examples/errors.sil b/examples/errors.sil
index 4507097..8bad357 100644
--- a/examples/errors.sil
+++ b/examples/errors.sil
@@ -16,3 +16,7 @@ Void duplicateFunction() {
Void duplicateLocals(Int a) {
Int a;
}
+
+Void localVoid(Void x) {
+ Void y;
+}