When we resolve an undfined name we record error, but we continue
processing things, so that we can report multiple errors. As a result
we need to generate some sort of fake "real" name for the undefined entity.
Previously we used to generate a fake local name, but that confused parts
of the code that expected certain things to always be defined at the top
level. So now we generate a fake name in the Cryptol prelude instead.
* Limitations:
Does not work in combination parameterized modules, as I am
about to redo how that works.
* General refeactorings:
* Namespaces:
- We have an explicit type for namespaces, see `Cryptol.Util.Ident`
- Display environments should now be aware of the namespace of the
name being displayed.
* Renamer:
- Factor out the renamer monad and error type into separate modules
- All name resultion is done through a single function `resolveName`
- The renamer now computes the dependencies between declarations,
orders things in dependency order, and checks for bad recursion.
* Typechecker: Redo checking of declarations (both top-level and local).
Previously we used a sort of CPS to add things in scope. Now we use
a state monad and add things to the state. We assume that the renamer
has been run, which means that declarations are ordered in dependency
order, and things have unique name, so we don't need to worry about
scoping too much.
* Change specific to nested modules:
- We have a new namespace for module names
- The interface file of a module contains the interfaces for nested modules
- Most of the changes related to nested modules in the renamer are
in `ModuleSystem.NamingEnv` and `ModuleSystem.Rename`
- There is some trickiness when resolving module names when importing
submodules (seed `processOpen` and `openLoop`)
- There are some changes to the representation of modules in the typechecked
syntax, in particular:
- During type-checking we "flatten" nested module declarations into
a single big declaration. Hopefully, this means that passes after
the type checker don't need to worry about nested modules
- There is a new field containing the interfaces of the nested modules,
this is needed so that when we import the module we know we have the
nested structure
- Declarations in functor/parameterzied modules do not appear in the
flattened list of declarations. Instead thouse modules are collected
in a separate field, and the plan is that they would be used from
there when we implmenet functor instantiation.
More precisely, in both cases we unload all modules and then reload
everything (this is what `:l` used to do, while `:m` only reloaded
the current module). This fixes#668.
There are opportunities to be smarter here: in particular when we
reload modules, we do need to parse them so that we can find out what
their dependencies are, and if needed to reload those. However, if
none of the dependencies have changed, and we didn't change, then we
could reuse the current module. This could be quite useful for modules
that take a long time to load.
Previously, "include" used locale-dependent decoding of source files,
while the rest of Cryptol uses UTF8. This change makes "include"
consistent with the rest of Cryptol, and adds a test that checks for
malformed UTF8.