The sample file
blank.nano is, as its name suggests, a completely empty file. This is the simplest possible Nanoverse project. When run, it nothing seems to happen. But Nanoverse ran all the way through its compilation and runtime routines.
Since this simulation is trivially simple, it can be informative to follow the project's progress through the codebase.
When you run
java -jar nanoverse.jar samples/blank.nano, you are invoking the
nanoverse.Nanoverse entry point. The entry point constructs a compiler, and passes control to it.
Inside the compiler, an ANTLR-generated parser reads the file. This process completes immediately, resulting in a syntax tree consisting of an empty root node.
The trivial syntax tree is then passed to the translator. The translator matches the root node to the root symbol table and translates it into an “object tree” node that describes a future Java object and its constructor arguments. Once built, no children get loaded into the node, because no information has been supplied. This container will eventually be instantiated into the top-level runtime object, the
Project object (called
Runner in Nanoverse v1.0.0-a1).
The object tree node is then passed to the instantiation stage of the [codebase#nanoversecompilerpipeline|compilation pipeline]]. The top node of the instantiation pipeline is the
ProjectLoader. It attempts to instantiate the
Runner object by first trying to instantiate each of its children. With each of the children instantiated, the
ProjectLoader will instantiate the
Runner object itself.
The ProjectLoader delegates child instantiation to the
ProjectInterpolator finds that each of the children is missing. It therefore turns to the
ProjectDefaults object to construct these objects. Sometimes,
ProjectLoader passes previously instantiated children to the
ProjectInterpolator as arguments for subsequent children.
When all of the
Runner's arguments have been instantiated, the
Runner itself is built and passed back to the
Compiler pipeline, which returns it to the
Nanoverse entry point.
Runtime is initiated by calling the
run() method on the
Runner has two arguments:
GeneralParameters, which contains system-level arguments and state, and
Integrator, which is responsible for stepping through simulations.
GeneralParameters how many instances of the simulation to run. The default is one instance, so it loops through one instance of the simulation. For each instance (in this case, only one), the
Runner asks the
Integrator to run the simulation through to completion by calling its
doNext() sets all state objects to their initial state, and then causes the simulation to run until it is caused to stop by a
HaltCondition. Once halted, it reports the
HaltCondition to any output systems specified by the user, which may use the information.
Blank.nano has no output modes, so nothing happens at that time.
To run the simulation, the
Integrator cycles through all of the user-defined processes until one of them halts the simulation, or the simulation reaches its maximum number of logical cycles. The default number of logical cycles is 100, so this simulation will run through its main loop 100 times.
At each pass through the main loop, the
Integrator will ask a helper object (
ProcessManager) to execute any user-specified
processes that are eligible for execution in this cycle. Since there are no user-defined processes, the helper does nothing in any of these cycles.
After 100 passes through this loop, the simulation ends with a
Integrator passes this information to the (empty) output manager, and returns control to the
Runner returns control to the entry point, and the entry point exits.