1.1 --- a/generator.py Thu Nov 17 21:45:25 2016 +0100
1.2 +++ b/generator.py Thu Nov 17 21:48:26 2016 +0100
1.3 @@ -910,19 +910,17 @@
1.4 __Try
1.5 {"""
1.6
1.7 - for name in self.importer.modules.keys():
1.8 + for name in self.importer.order_modules():
1.9 function_name = "__main_%s" % encode_path(name)
1.10 print >>f_signatures, "void %s();" % function_name
1.11
1.12 - # Emit the main module's function last.
1.13 # Omit the native module.
1.14
1.15 - if name not in ("__main__", "native"):
1.16 + if name != "native":
1.17 print >>f_code, """\
1.18 %s();""" % function_name
1.19
1.20 print >>f_code, """\
1.21 - __main___main__();
1.22 return 0;
1.23 }
1.24 __Catch_anonymous
2.1 --- a/importer.py Thu Nov 17 21:45:25 2016 +0100
2.2 +++ b/importer.py Thu Nov 17 21:48:26 2016 +0100
2.3 @@ -397,6 +397,7 @@
2.4 "Resolve dependencies between modules."
2.5
2.6 self.waiting = {}
2.7 + self.depends = {}
2.8
2.9 for module in self.modules.values():
2.10
2.11 @@ -418,7 +419,11 @@
2.12 provider = self.get_module_provider(found.unresolved() and ref or found)
2.13 ref.mutate(found)
2.14
2.15 - if provider:
2.16 + # Record any external dependency.
2.17 +
2.18 + if provider and provider != module.name:
2.19 +
2.20 + # Record the provider dependency.
2.21
2.22 module.required.add(provider)
2.23 self.accessing_modules[provider].add(module.name)
2.24 @@ -437,6 +442,12 @@
2.25 if self.verbose:
2.26 print >>sys.stderr, "Requiring", provider, "for", ref
2.27
2.28 + # Record a module ordering dependency.
2.29 +
2.30 + if not found.static():
2.31 + init_item(self.depends, module.name, set)
2.32 + self.depends[module.name].add(provider)
2.33 +
2.34 # Check modules again to see if they are now required and should now
2.35 # cause the inclusion of other modules providing objects to the program.
2.36
2.37 @@ -458,6 +469,43 @@
2.38 print >>sys.stderr, "Requiring", provider
2.39 self.require_providers(provider)
2.40
2.41 + def order_modules(self):
2.42 +
2.43 + "Produce a module initialisation ordering."
2.44 +
2.45 + self.check_ordering()
2.46 + return self.order_modules_for_module("__main__", set())
2.47 +
2.48 + def order_modules_for_module(self, module_name, visited):
2.49 +
2.50 + """
2.51 + Order the modules required by 'module_name', using 'visited' to track
2.52 + visited modules.
2.53 + """
2.54 +
2.55 + if module_name in visited:
2.56 + return []
2.57 +
2.58 + module = self.modules[module_name]
2.59 + visited.add(module_name)
2.60 + ordered = [module_name]
2.61 +
2.62 + for module_name in module.required:
2.63 + modules = self.order_modules_for_module(module_name, visited)
2.64 + ordered[:0] = modules
2.65 + visited.update(modules)
2.66 +
2.67 + return ordered
2.68 +
2.69 + def check_ordering(self):
2.70 +
2.71 + "Check the ordering dependencies."
2.72 +
2.73 + for module_name, modules in self.depends.items():
2.74 + for provider in modules:
2.75 + if self.depends.has_key(provider) and module_name in self.depends[provider]:
2.76 + raise ProgramError, "Modules %s and %s may not depend on each other for non-static objects." % (module_name, provider)
2.77 +
2.78 def find_dependency(self, ref):
2.79
2.80 "Find the ultimate dependency for 'ref'."
3.1 --- a/lib/__builtins__/io.py Thu Nov 17 21:45:25 2016 +0100
3.2 +++ b/lib/__builtins__/io.py Thu Nov 17 21:48:26 2016 +0100
3.3 @@ -61,9 +61,9 @@
3.4 'nl' is given as a true value.
3.5 """
3.6
3.7 - # Import locally to ensure that the object is initialised.
3.8 - # Otherwise, if imported at the module level, the sys module may not have
3.9 - # been set up.
3.10 + # If imported at the module level, the sys module must be set up first,
3.11 + # which should be ensured by the module ordering activity, and a module
3.12 + # attribute will be employed to hold a reference to sys.stdout.
3.13
3.14 from sys import stdout
3.15