[hack] Pretty printing of environments
[hack] Pretty printing of environments

Summary:
The `hh_show` pseudo-function is very useful for debugging Hack type inference: it displays on the terminal the type that Hack believes an expression to have at the point that it type checks the line in which it occurs. (So, for example, it will show multiple times in a loop as Hack seeks a fixed point.)

But there is currently no way to dump any other aspect of Hack internals such as the type parameter environment. This diff rectifies this situation. It introduces a new nullary pseudo-function `hh_show_env` that causes Hack to dump information about its environment, including:

* The types of all locals (`local_types`)
* The lower and upper bounds on all type parameters in scope (`tpenv`)
* The state of the type-variable-to-type variable substitution (`subst`)
* The state of the type-variable-to-type environment (`tenv`)

The last two aren't shown in full but instead as a delta from the previous time that `hh_show_env` was called.

Some other aspects:
* Colour display, with indentation!
* The position information of the `hh_show_env` command is shown above the environment information, with an iteration number in square brackets (because it might be invoked more than once e.g. round a loop).

The `hh_show` command is also improved, to display this position information.

Finally, type variable numbers are shown in types so that the `subst` and `tpenv` parts of the environment can be debugged.

Here is an example: the test `erling_loop5.php` with `hh_show_env()` inserted at the end of the inner loop. The output from `hh_single_type_check` is as follows:
```
File "erling_loop5.php", line 34, characters 5-17:[1]
  local_types
    $obj: X as X<#216(int | string)>
    $x: (int)
    $y: (int)
    $z: (int | string)
    $i: int
  subst(changes)
    #199: #216; #201: #212; #212: #214; #214: #216;
  tenv(changes)
    #198: [unresolved]; #199: [unresolved]; #200: [unresolved]; #201: int; #212: int;
    #214: int; #216: (int | string);
File "erling_loop5.php", line 34, characters 5-17:[2]
  local_types
    $obj: X as X<#223(int | string)>
    $x: (string | int)
    $y: (int | string)
    $z: (int | string)
    $i: int
  subst(changes)
    #223: #223; #216: #219; #219: #221; #221: #223;
  tenv(changes)
    #219: (string | int); #221: (int | string); #223: (int | string);
```

Reviewed By: dabek

Differential Revision: D4068570

fbshipit-source-id: cb96d5178bc41f73a8ddd8776ab7f91f69de2b71

gabro/flow,gabelevi/flow,JonathanUsername/flow,samwgoldman/flow,gabro/flow,samwgoldman/flow,fletcherw/flow,facebook/flow,popham/flow,nmote/flow,JonathanUsername/flow,JonathanUsername/flow,claudiopro/flow,TiddoLangerak/flow,AgentME/flow,mroch/flow,mroch/flow,JonathanUsername/flow,claudiopro/flow,facebook/flow,gabelevi/flow,jamesgpearce/flow,samwgoldman/flow,gabro/flow,ForbesLindesay/flow,AgentME/flow,fletcherw/flow,mroch/flow,popham/flow,MichaelDeBoey/flow,JonathanUsername/flow,facebook/flow,mroch/flow,samwgoldman/flow,gabelevi/flow,nmote/flow,AgentME/flow,ylu1317/flow,jamesgpearce/flow,popham/flow,claudiopro/flow,nmote/flow,samwgoldman/flow,fletcherw/flow,jamesgpearce/flow,jamesgpearce/flow,popham/flow,ForbesLindesay/flow,ylu1317/flow,facebook/flow,gabro/flow,TiddoLangerak/flow,JonathanUsername/flow,facebook/flow,gabelevi/flow,mroch/flow,AgentME/flow,JonathanUsername/flow,nmote/flow,ylu1317/flow,gabro/flow,facebook/flow,popham/flow,ForbesLindesay/flow,TiddoLangerak/flow,TiddoLangerak/flow,gabro/flow,ForbesLindesay/flow,ylu1317/flow,samwgoldman/flow,nmote/flow,fletcherw/flow,samwgoldman/flow,AgentME/flow,fletcherw/flow,gabelevi/flow,ForbesLindesay/flow,MichaelDeBoey/flow,facebook/flow,nmote/flow,TiddoLangerak/flow,claudiopro/flow,jamesgpearce/flow,ForbesLindesay/flow,gabelevi/flow,ylu1317/flow,jamesgpearce/flow,popham/flow,fletcherw/flow,MichaelDeBoey/flow,mroch/flow,claudiopro/flow,jamesgpearce/flow,gabelevi/flow,popham/flow,nmote/flow,MichaelDeBoey/flow,mroch/flow,MichaelDeBoey/flow