Tree checking

Once the tree is generated, it's useful to check it for redundant arms and for arms that never match. These checks will help users catch mistakes in their specifications. Note that I must check the ``original'' arms; that's why they're there. «*»= procedure checktree(n) originals := set() every insert(originals, (!n.cs.arms).original) deletematching(n, originals) every a := !originals do warning("No word matches pattern at ", image(a.file), ", line ", a.line) if hasnomatch(n) then warning("Case statement at ", image(n.cs.arms[1].file), ", line ", n.cs.arms[1].line - 1, " doesn't cover all cases") return n end procedure deletematching(n, originals) if *originals = 0 then return else if *n.children > 0 then every deletematching((!n.children).node, originals) else every delete(originals, (!n.cs.arms).original) end procedure hasnomatch(n) if *n.children > 0 then return hasnomatch((!n.children).node) else if *n.cs.arms = 0 then return # found it end @