Branch ast-stage-c. L6 = "classes/vtables, imports, nested modules".
Nested modules (f82f72b, tag v3-lower6-nested)
CanDecl accepts a nested NkUnit (with no imports).LowerDecls emits the nested unit's declarations and, when it has a
BEGIN body, BeginInit/body/EndInit (registering <nested>_init
so the enclosing BeginBody calls it).ReenterGlobals re-registers a nested module's non-exported globals in
the still-open enclosing module scope, so QbeGen.GlobalRef resolves
their "<outer>_<name>" symbols after the nested scope has been popped.lower_ok t_nestedmod.mod byte-matches. Suite 194/194; FIXPOINT OK
(3,328,857 bytes).-lower is invoked only from ProgModule's END (M2.atg), so Lower
re-emits only the last unit. But a session's image is accumulated
across all units (sessBuf): a program that IMPORTs a module pulls
that module's procs/init/globals into the same gen_ssa/<Prog>.ssa.
So re-emitting just the program cannot byte-match.
Supporting imports therefore needs a mechanism change: lower every
unit (definition/implementation/program) and accumulate a session image
(mirroring sessBuf), or otherwise compare per unit. That is the same
mechanism the L7 flip needs, so it is the natural next structural
step. Qualified names (M.x) additionally need SymTab.MaterializeAlias
at lowering time (module scope is open — workable) and qualified-call
resolution in LowerCall (currently CalleeName reads only the base
ident).
Surface: NkClassDecl/NkFieldDecl, CLASS IMPLEMENTATION, method
binding (obj.Method + ArmRecv), virtual dispatch, inheritance, NEW
for classes, vtables (QbeGen.EmitVTables), THIS. Independent of
imports, so it can be byte-verified with lower_ok on a self-contained
class program.