Added an initial crude implementation of name mangling for the main function
This commit is contained in:
parent
1e06768c20
commit
0c28f6255c
|
@ -261,11 +261,20 @@ testRecordInfNames3 = testPassShouldFail "testRecordInfNames3" (recordInfNameTyp
|
|||
(>>>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
|
||||
(>>>) f0 f1 x = (f0 x) >>= f1
|
||||
|
||||
--Normally, process names in Rain are not mangled. And this should be fine in all cases - but not for the main process (which would
|
||||
--result in a function called main. Therefore we must mangle main. Ideally into a nonce, but for now into ____main
|
||||
|
||||
--TODO check recursive main function works
|
||||
|
||||
testFindMain0 :: Test
|
||||
testFindMain0 = testPassWithStateCheck "testFindMain0" orig ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
testFindMain0 = testPassWithStateCheck "testFindMain0" exp ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
where
|
||||
orig = A.Spec m (A.Specification m (A.Name m A.ProcName "main") $ A.Proc m A.PlainSpec [] (A.Skip m)) $ A.Several m []
|
||||
check state = assertEqual "testFindMain0" [("main",(A.Name m A.ProcName "main"))] (csMainLocals state)
|
||||
proc name = A.Spec m (A.Specification m (A.Name m A.ProcName name) $ A.Proc m A.PlainSpec [] (A.Skip m)) $ A.Several m []
|
||||
orig = proc "main"
|
||||
exp = proc "____main"
|
||||
check state = do assertEqual "testFindMain0 A" [("____main",(A.Name m A.ProcName "____main"))] (csMainLocals state)
|
||||
assertVarDef "testFindMain0 B" state "____main"
|
||||
(tag7 A.NameDef DontCare "____main" "main" A.ProcName DontCare A.Original A.Unplaced)
|
||||
|
||||
testFindMain1 :: Test
|
||||
testFindMain1 = testPassWithStateCheck "testFindMain1" orig ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
|
@ -274,20 +283,24 @@ testFindMain1 = testPassWithStateCheck "testFindMain1" orig ((uniquifyAndResolve
|
|||
check state = assertEqual "testFindMain1" [] (csMainLocals state)
|
||||
|
||||
testFindMain2 :: Test
|
||||
testFindMain2 = testPassWithStateCheck "testFindMain2" orig ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
testFindMain2 = testPassWithStateCheck "testFindMain2" exp ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
where
|
||||
orig = A.Spec m (A.Specification m (A.Name m A.ProcName "main") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Spec m (A.Specification m (A.Name m A.ProcName "foo") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Several m []
|
||||
check state = assertEqual "testFindMain2" [("main",(A.Name m A.ProcName "main"))] (csMainLocals state)
|
||||
proc name = A.Spec m (A.Specification m (A.Name m A.ProcName name) $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Spec m (A.Specification m (A.Name m A.ProcName "foo") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Several m []
|
||||
orig = proc "main"
|
||||
exp = proc "____main"
|
||||
check state = assertEqual "testFindMain2" [("____main",(A.Name m A.ProcName "____main"))] (csMainLocals state)
|
||||
|
||||
testFindMain3 :: Test
|
||||
testFindMain3 = testPassWithStateCheck "testFindMain3" orig ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
testFindMain3 = testPassWithStateCheck "testFindMain3" exp ((uniquifyAndResolveVars >>> findMain) orig) (return ()) check
|
||||
where
|
||||
orig = A.Spec m (A.Specification m (A.Name m A.ProcName "foo") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Spec m (A.Specification m (A.Name m A.ProcName "main") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Several m []
|
||||
check state = assertEqual "testFindMain3" [("main",(A.Name m A.ProcName "main"))] (csMainLocals state)
|
||||
proc name = A.Spec m (A.Specification m (A.Name m A.ProcName "foo") $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Spec m (A.Specification m (A.Name m A.ProcName name) $ A.Proc m A.PlainSpec [] (A.Skip m)) $
|
||||
A.Several m []
|
||||
orig = proc "main"
|
||||
exp = proc "____main"
|
||||
check state = assertEqual "testFindMain3" [("____main",(A.Name m A.ProcName "____main"))] (csMainLocals state)
|
||||
|
||||
|
||||
--Returns the list of tests:
|
||||
|
|
|
@ -96,8 +96,9 @@ uniquifyAndResolveVars = everywhereM (mkM uniquifyAndResolveVars')
|
|||
--Other:
|
||||
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
|
||||
--Helper function for a few of the passes:
|
||||
replaceNameName :: String -> String -> A.Name -> A.Name
|
||||
replaceNameName find replace n = if (A.nameName n) == find then n {A.nameName = replace} else n
|
||||
|
||||
recordInfNameTypes :: Data t => t -> PassM t
|
||||
recordInfNameTypes = everywhereM (mkM recordInfNameTypes')
|
||||
|
@ -121,14 +122,19 @@ findMain :: Data t => t -> PassM t
|
|||
--Because findMain runs after uniquifyAndResolveVars, the types of all the process will have been recorded
|
||||
--Therefore this pass doesn't actually need to walk the tree, it just has to look for a process named "main"
|
||||
--in the CompState, and pull it out into csMainLocals
|
||||
findMain x = do st <- get
|
||||
put (findMain' st)
|
||||
return x
|
||||
findMain x = do modify findMain'
|
||||
everywhereM (mkM $ return . (replaceNameName "main" "____main")) x
|
||||
where
|
||||
--We have to mangle the main name because otherwise it will cause problems on some backends (including C and C++)
|
||||
findMain' :: CompState -> CompState
|
||||
findMain' st = case (Map.lookup "main" (csNames st)) of
|
||||
Just n -> st {csMainLocals = [("main",A.Name {A.nameName = "main", A.nameMeta = A.ndMeta n, A.nameType = A.ndNameType n})]}
|
||||
Just n -> st {csNames = changeMainName (csNames st) , csMainLocals = [("____main",A.Name {A.nameName = "____main", A.nameMeta = A.ndMeta n, A.nameType = A.ndNameType n})]}
|
||||
Nothing -> st
|
||||
changeMainName :: Map.Map String A.NameDef -> Map.Map String A.NameDef
|
||||
changeMainName m = case (Map.lookup "main" m) of
|
||||
Nothing -> m
|
||||
Just nd -> ((Map.insert "____main" (nd {A.ndName = "____main"})) . (Map.delete "main")) m
|
||||
|
||||
|
||||
transformEach :: Data t => t -> PassM t
|
||||
transformEach = everywhereM (mkM transformEach')
|
||||
|
|
Loading…
Reference in New Issue
Block a user