From b56b655f0bea1922999305d8e88bf16e874098a3 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 20 Jul 2017 08:24:33 +0000 Subject: Add checks for locals with type Void --- Sil/Check.dcl | 1 + Sil/Check.icl | 16 ++++++++++++---- Sil/Syntax.dcl | 9 +++++++++ Sil/Syntax.icl | 20 ++++++++++++++++++++ examples/errors.sil | 4 ++++ 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; +} -- cgit v1.2.3