[add lint routine to traverse an E and ensure every occurance of a variable exactly matches its declaration
John Meacham <john@repetae.net>**20070302094028] hunk ./E/Traverse.hs 10
+    scopeCheck,
hunk ./E/Traverse.hs 19
-import E.Type
+import E.E
hunk ./E/Traverse.hs 21
+import E.Type
hunk ./E/Traverse.hs 23
-import Name.Name
-import Support.FreeVars
hunk ./E/Traverse.hs 24
-import Util.Graph
hunk ./E/Traverse.hs 163
+
+scopeCheck :: Monad m => Bool -> IdMap TVr -> E -> m ()
+scopeCheck checkFvs initMap e = runReaderT (f e) initMap  where
+    f (ELam tvr e) = f (tvrType tvr) >> local (minsert (tvrIdent tvr) tvr) (f e)
+    f (EPi tvr e) = f (tvrType tvr) >> local (minsert (tvrIdent tvr) tvr) (f e)
+    f (EVar t) = do
+        m <- ask
+        case mlookup (tvrIdent t) m of
+            Nothing | checkFvs -> fail $ "scopeCheck: found variable not in scope " ++ tvrShowName t
+            Just t' | tvrType t /= tvrType t' -> fail $ "scopeCheck: found variable whose type does not match " ++ tvrShowName t
+            _ -> return ()
+    f ec@ECase { eCaseBind = b } = do
+        f (eCaseScrutinee e)
+        f (eCaseType ec)
+        f (tvrType b)
+        local (minsert (tvrIdent b) b) $ mapM_ doAlt (eCaseAlts ec)
+    f ELetRec { eDefs = ds, eBody = e } = do
+        mapM_ (f . tvrType . fst) ds
+        local (fromList [ (tvrIdent t,t) | (t,_) <- ds ] `mappend`) (f e)
+    f e = emapE_ f e
+    doAlt (Alt LitCons { litArgs = xs, litType = t } e) = do
+        f t >> local (fromList [ (tvrIdent t,t) | t <- xs] `mappend`) (f e)
+    doAlt (Alt (LitInt _ t) e) = f t >> f e
+
+