[rfc][env] Hook, object, and function types for Environment globals
Adds `GlobalRegistry`, which holds the names and types of known global objects, i.e. ```js type GlobalRegistry = Map<string, PrimitiveType | ObjectType | FunctionType | HookType | PolyType>; // ... globalRegistry.get("NaN"); // {kind: "Primitive"} globalRegistry.get("parseInt"); // {kind: "Function", shapeId: "..."} globalRegistry.get("Math"); // {kind: "Object", shapeId: "..."} ``` Since we currently do not track module imports and module-level declarations, builtin and custom hooks currently also live in GlobalRegistry. ```js globalRegistry.get("useState"); // {kind: "Hook", definition: {...}} globalRegistry.get("useFreeze"); // {kind: Hook, definition: {...}} ``` This PR does not allow Forget users to define their own globals. When we add this as a configuration, we should not expose `ShapeRegistry` to the user, as a user-provided ShapeRegistry may accidentally be not well formed. (i.e. missing (1) required shapes (BuiltInArray for [] and BuiltInObject for {}) or (2) some recursive shapeIds) ```js export type UserType = UserObject | UserFunction | "Primitive" | "BuiltinObject" | ...; export type UserObject = { kind: "Object", properties: Map<string, UserType> } export type UserFunction = { kind: "Function", properties: Map<string, UserType>, signature: ... } export type UserGlobals = Map<string, UserType>; class Environment { constructor(globals: Map<string, UserType>, ...) { // ... addUserDefinedGlobals(this.#globals, this.#shapes); ```