diff --git a/RainPassTest.hs b/RainPassTest.hs index 848859f..b322c99 100644 --- a/RainPassTest.hs +++ b/RainPassTest.hs @@ -116,15 +116,16 @@ testEachPass1 = testPass "testEachPass0" exp (transformEach orig) startState' -- | Test variable is made unique in a declaration: testUnique0 :: Test -testUnique0 = testPassWithCheck "testUnique0" exp (uniquifyVars orig) (return ()) check +testUnique0 = testPassWithCheck "testUnique0" exp (uniquifyAndResolveVars orig) (return ()) check where - orig = A.Specification m (simpleName "c") $ A.Declaration m $ A.Byte - exp = tag3 A.Specification DontCare (Named "newc" DontCare) $ A.Declaration m $ A.Byte + orig = A.Spec m (A.Specification m (simpleName "c") $ A.Declaration m $ A.Byte) skipP + exp = tag3 A.Spec DontCare (tag3 A.Specification DontCare (Named "newc" DontCare) $ A.Declaration m $ A.Byte) skipP + skipP = A.OnlyP m (A.Skip m) check items = assertItemNotEqual "testUnique0: Variable was not made unique" (simpleName "c") (Map.lookup "newc" items) -- | Tests that two declarations of a variable with the same name are indeed made unique: testUnique1 :: Test -testUnique1 = testPassWithCheck "testUnique1" exp (uniquifyVars orig) (return ()) check +testUnique1 = testPassWithCheck "testUnique1" exp (uniquifyAndResolveVars orig) (return ()) check where orig = A.Several m [A.Spec m (A.Specification m (simpleName "c") $ A.Declaration m $ A.Byte) skipP, A.Spec m (A.Specification m (simpleName "c") $ A.Declaration m $ A.Int) skipP] @@ -135,12 +136,13 @@ testUnique1 = testPassWithCheck "testUnique1" exp (uniquifyVars orig) (return () assertItemNotEqual "testUnique1: Variable was not made unique" (simpleName "c") (Map.lookup "newc1" items) assertItemNotSame "testUnique1: Variables were not made unique" items "newc0" "newc1" --- | Tests that the unique pass does not change variables that are not in declarations +-- | Tests that the unique pass does resolve the variables that are in scope testUnique2 :: Test -testUnique2 = testPassWithCheck "testUnique2" exp (uniquifyVars orig) (return ()) check +testUnique2 = testPassWithCheck "testUnique2" exp (uniquifyAndResolveVars orig) (return ()) check where orig = A.Spec m (A.Specification m (simpleName "c") $ A.Declaration m $ A.Byte) (A.OnlyP m $ makeSimpleAssign "c" "d") - exp = tag3 A.Spec DontCare (tag3 A.Specification DontCare (Named "newc" DontCare) $ A.Declaration m $ A.Byte) (A.OnlyP m $ makeSimpleAssign "c" "d") + exp = tag3 A.Spec DontCare (tag3 A.Specification DontCare (Named "newc" DontCare) $ A.Declaration m $ A.Byte) + (tag2 A.OnlyP m $ tag3 A.Assign DontCare [tag2 A.Variable DontCare (Named "newc" DontCare)] (tag2 A.ExpressionList DontCare [(exprVariable "d")])) check items = assertItemNotEqual "testUnique2: Variable was not made unique" (simpleName "c") (Map.lookup "newc" items) diff --git a/RainPasses.hs b/RainPasses.hs index 7ce06c1..5e3b76b 100644 --- a/RainPasses.hs +++ b/RainPasses.hs @@ -9,25 +9,30 @@ import CompState --TODO add passes for: -- Typing the variables --- Resolving (and uniquifying) names rainPasses :: A.Process -> PassM A.Process rainPasses = runPasses passes where passes = - [ ("Uniquify variable declarations",uniquifyVars) + [ ("Uniquify variable declarations and resolve variable names",uniquifyAndResolveVars) ,("Convert seqeach/pareach loops into classic replicated SEQ/PAR",transformEach) ] -uniquifyVars :: Data t => t -> PassM t -uniquifyVars = everywhereM (mkM uniquifyVars') +uniquifyAndResolveVars :: Data t => t -> PassM t +uniquifyAndResolveVars = everywhereM (mkM uniquifyAndResolveVars') where - uniquifyVars' :: A.Specification -> PassM A.Specification - uniquifyVars' (A.Specification m n decl@(A.Declaration _ _)) + uniquifyAndResolveVars' :: A.Structured -> PassM A.Structured + uniquifyAndResolveVars' (A.Spec m (A.Specification m' n decl@(A.Declaration _ _)) scope) = do n' <- makeNonce $ A.nameName n - return (A.Specification m n {A.nameName = n'} decl) - uniquifyVars' s = return s + let scope' = everywhere (mkT $ replaceNameName (A.nameName n) n') scope + return $ A.Spec m (A.Specification m' n {A.nameName = n'} decl) scope' + uniquifyAndResolveVars' s = return s + + replaceNameName :: String -> String -> A.Name -> A.Name + replaceNameName find replace n = if (A.nameName n) == find then n {A.nameName = replace} else n + + transformEach :: Data t => t -> PassM t transformEach = everywhereM (mkM transformEach')