@@ -64,6 +64,7 @@ import Data.Generics.Extras.Schemes
64
64
import Data.Data (Data ,Typeable )
65
65
import Data.List (find ,sort ,sortBy ,nub ,foldl' ,nubBy ,deleteFirstsBy )
66
66
import qualified Data.Map as M
67
+ import qualified Data.Set as DS
67
68
import Data.Maybe (isJust ,isNothing )
68
69
import Language.Lsl.Internal.Util (ctx ,findM ,lookupM ,filtMap ,throwStrError )
69
70
import Control.Monad (when ,foldM ,MonadPlus (.. ))
@@ -288,7 +289,7 @@ data ValidationState = ValidationState {
288
289
vsFuncs :: ! [Ctx Func ],
289
290
vsErr :: ! CodeErrs ,
290
291
vsWarn :: ! CodeErrs ,
291
- vsNamesUsed :: [ String ] ,
292
+ vsNamesUsed :: ! ( DS. Set String ) ,
292
293
vsGVs :: ! [Var ],
293
294
vsGFs :: ! [FuncDec ],
294
295
vsStateNames :: ! [String ],
@@ -298,7 +299,7 @@ data ValidationState = ValidationState {
298
299
vsImports :: ! [(String ,[(String ,String )],String )],
299
300
vsContext :: [Maybe SourceContext ]
300
301
}
301
-
302
+
302
303
emptyValidationState = ValidationState {
303
304
vsLib = [] ,
304
305
vsGlobalRegistry = M. empty,
@@ -312,7 +313,7 @@ emptyValidationState = ValidationState {
312
313
vsFuncs = [] ,
313
314
vsErr = CodeErrs [] ,
314
315
vsWarn = CodeErrs [] ,
315
- vsNamesUsed = [] ,
316
+ vsNamesUsed = DS. fromList ( map ( \ (name, t, ts) -> name) funcSigs) ,
316
317
vsGVs = [] ,
317
318
vsGFs = [] ,
318
319
vsStateNames = [] ,
@@ -395,7 +396,7 @@ vsmAddLocal ctx v@(Var name _) = do
395
396
vsmAddImport imp = get'vsImports >>= put'vsImports . (imp: )
396
397
397
398
vsmAddToNamesUsed :: String -> VState ()
398
- vsmAddToNamesUsed name = get'vsNamesUsed >>= put'vsNamesUsed . (name : )
399
+ vsmAddToNamesUsed name = get'vsNamesUsed >>= put'vsNamesUsed . (DS. insert name )
399
400
400
401
vsmWithNewScope :: VState a -> VState a
401
402
vsmWithNewScope action = do
@@ -535,7 +536,7 @@ compileGlob (GV v mexpr) = do
535
536
when (isConstant $ varName v') (vsmAddErr (srcCtx v, varName v' ++ " is a predefined constant" ))
536
537
namesUsed <- get'vsNamesUsed
537
538
gvs <- get'vsGVs
538
- when (varName v' `elem ` namesUsed) (vsmAddErr (srcCtx v, varName v' ++ " is already defined" ))
539
+ when (varName v' `DS.member ` namesUsed) (vsmAddErr (srcCtx v, varName v' ++ " is already defined" ))
539
540
whenJust mexpr $ \ expr -> do
540
541
let (_,gvs') = break (\ var -> varName var == varName v') gvs
541
542
mt <- compileCtxSimple (drop 1 gvs') expr
@@ -547,7 +548,7 @@ compileGlob (GF cf@(Ctx ctx f@(Func (FuncDec name t params) statements))) =
547
548
vsmWithNewScope $ do
548
549
compileParams params
549
550
vsmInEntryPoint t False $ do
550
- whenM ((return elem ) `ap` (return $ ctxItem name) `ap` get'vsNamesUsed) (vsmAddErr (srcCtx name, ctxItem name ++ " is already defined" ))
551
+ whenM ((return DS. member ) `ap` (return $ ctxItem name) `ap` get'vsNamesUsed) (vsmAddErr (srcCtx name, ctxItem name ++ " is already defined" ))
551
552
returns <- compileStatements statements
552
553
when (not returns && t /= LLVoid ) (vsmAddErr (srcCtx name, ctxItem name ++ " : not all code paths return a value" ))
553
554
vsmRegisterFunc f
@@ -576,9 +577,9 @@ rewriteGlob' prefix renames vars (GF (Ctx ctx (Func (FuncDec name t params) stat
576
577
Nothing -> vsmAddErr (srcCtx name, " can't rename " ++ ctxItem name ++ " : not found" )
577
578
Just name' -> do
578
579
namesUsed <- get'vsNamesUsed
579
- if name' `elem ` namesUsed
580
+ if name' `DS.member ` namesUsed
580
581
then vsmAddErr (srcCtx name, name' ++ " imported from module is already defined" )
581
- else let rewrittenFunc = (Func (FuncDec (Ctx (srcCtx name) name') t params) $ rewriteStatements 0 renames statements)
582
+ else let rewrittenFunc = (Func (FuncDec (Ctx (srcCtx name) name') t params) $ rewriteStatements 0 (removeLocals params renames) statements)
582
583
in do vsmAddToNamesUsed name'
583
584
vsmRegisterFunc rewrittenFunc
584
585
vsmAddFunc (Ctx ctx rewrittenFunc)
@@ -587,7 +588,7 @@ rewriteGlob' prefix renames vars (GV (Ctx ctx (Var name t)) mexpr) =
587
588
Nothing -> vsmAddErr (ctx, " can't rename " ++ name ++ " : not found" )
588
589
Just name' -> do
589
590
namesUsed <- get'vsNamesUsed
590
- if name' `elem ` namesUsed
591
+ if name' `DS.member ` namesUsed
591
592
then vsmAddErr (ctx, name' ++ " imported from module is already defined" )
592
593
else let rewrittenGlobVar = GDecl (nullCtx (Var name' t)) (fmap (ctxItem . (rewriteCtxExpr renames)) mexpr)
593
594
in do vsmAddToNamesUsed name'
@@ -613,6 +614,10 @@ rewriteGlob' prefix0 renames vars (GI (Ctx ctx mName) bindings prefix) =
613
614
Nothing -> vsmAddErr (ctx, rn ++ " : not found" ) >> return (fv,rn)
614
615
Just rn' -> return (fv,rn')
615
616
617
+ removeLocals :: [CtxVar ] -> [(String , String )] -> [(String , String )]
618
+ removeLocals locals globals =
619
+ filter (\ (gName, _) -> (all (\ (Ctx _ (Var localName _)) -> localName /= gName)) locals) globals
620
+
616
621
compileState :: Ctx State -> VState ()
617
622
compileState state@ (Ctx _ (State nm handlers)) =
618
623
vsmWithinState $ do
@@ -693,22 +698,22 @@ compileStatement (Ctx ctx (Decl var@(Var name t) expr)) = do
693
698
get'vsBranchReturns
694
699
compileStatement (Ctx ctx (While expr statement)) = do
695
700
t <- compileCtxExpr expr
696
- vsmInBranch $ compileStatement statement
701
+ compileBranchStatement statement
697
702
get'vsBranchReturns
698
703
compileStatement (Ctx ctx(DoWhile statement expr)) = do
699
704
t <- compileCtxExpr expr
700
- vsmInBranch $ compileStatement statement
705
+ compileBranchStatement statement
701
706
get'vsBranchReturns
702
707
compileStatement (Ctx ctx (For mexpr1 mexpr2 mexpr3 statement)) = do
703
708
compileExpressions mexpr1
704
709
compileExpressions mexpr3
705
710
t <- compileMExpression mexpr2
706
- vsmInBranch $ compileStatement statement
711
+ compileBranchStatement statement
707
712
get'vsBranchReturns
708
713
compileStatement (Ctx ctx (If expr thenStmt elseStmt)) = do
709
714
t <- compileCtxExpr expr
710
- ret1 <- vsmInBranch $ compileStatement thenStmt
711
- ret2 <- vsmInBranch $ compileStatement elseStmt
715
+ ret1 <- compileBranchStatement thenStmt
716
+ ret2 <- compileBranchStatement elseStmt
712
717
returns <- get'vsBranchReturns
713
718
put'vsBranchReturns (returns || (ret1 && ret2))
714
719
get'vsBranchReturns
@@ -744,6 +749,13 @@ compileStatement (Ctx ctx (Jump s)) = do
744
749
when (s `notElem` concat labels) $ vsmAddErr (ctx, " no such label to jump to: " ++ s)
745
750
get'vsBranchReturns
746
751
752
+ compileBranchStatement :: CtxStmt -> VState Bool
753
+ compileBranchStatement ctxStmt@ (Ctx _ (Decl _ _)) = do
754
+ vsmAddErr (srcCtx ctxStmt, " Declaration requires a new scope - - use { and }" )
755
+ return False
756
+ -- get'vsBranchReturns
757
+ compileBranchStatement ctxStmt = vsmInBranch $ compileStatement ctxStmt
758
+
747
759
748
760
compileStatements :: [CtxStmt ] -> VState Bool
749
761
compileStatements stmts = do
0 commit comments