User Tools

Site Tools


codebase

The Nanoverse Codebase

This page is accurate as of Nanoverse v1.0.0-a6. If you are using a later version, some aspects may have changed.

The Nanoverse codebase is, in a word, huge. It got a little smaller with the removal of legacy code in September 2015, but it's still a challenge for anyone to navigate (including its inventor). Fortunately, it is reasonably well-organized, meaning that a decent map should help you get your bearings.

Java allows developers to organize code into packages. The following skeleton does not mention every Nanoverse package, but it does mention enough of the important ones to let you find your way around.

The Nanoverse entry point

Nanoverse's main class is nanoverse.Nanoverse. It takes a exactly one argument: namely, the path to the project file to be executed. The class constructs a compiler, compiled the project into a Nanoverse project, and then simulates the project.

The most important packages

We are currently interviewing research assistants to help develop an interactive object dictionary. Until then, the user must identify objects by viewing the Nanoverse source code. Perhaps the most important package for doing this is the symbol table hierarchy, which is located at

nanoverse.compiler.pipeline.translate.symbol

These symbol tables contain plain-text descriptions of objects and their properties. Starting at the project symbol table, you can actually crawl through the hierarchy of symbol tables to learn about any object desired. The symbol table hierarchy is a nearly exact mirror of the runtime hierarchy.

nanoverse.compiler.pipeline.translate.symbol.control.run.ProjectSymbolTable

The next most important package is the the hierarchy of loaders, which build Java objects from internal representation of user code. The loader hierarchy contains information about which parameters are optional, and if so, what defaults are used. This information can be found at:

nanoverse.compiler.pipeline.instantiate.loader

Like the symbol table hierarchy, the loader hierarchy basically mirrors the runtime hierarchy. (It should mirror it exactly, but it must be maintained manually, so it gets messed up sometimes.) The project loader is found at

nanoverse.compiler.pipeline.instantiate.loader.control.ProjectLoader

Compiler

The nanoverse.compiler package contains all of the logic necessary to read user source code, check it for errors, convert it to an internal representation (with defaults as needed), and translate it into an execution plan.

Nanosyntax.g4

Nanosyntax.g4 is the Nanoverse language specification. It is written in ANTLR v4, a program for generating parsers from grammars. This file is used to generate the backbone of the interpreter, found in nanoverse.compiler.pipeline.interpret.nanosyntax.*. You can peruse the Nanosyntax.g4 file to study the grammar of the language directly.

nanoverse.compiler.error

The package nanoverse.compiler.error contains error messages supplied to the user during compile time, typically as a result of syntax errors or illegal definitions.

nanoverse.compiler.pipeline

The package nanoverse.compiler.pipeline contains the sequence of steps involved in converting human-readable Nanoverse source code into a simulation. The compilation pipeline consists of three steps: interpretation, translation, and instantiation. The instantiation step is further divided into two sub-steps: interpolation and loading.

nanoverse.compiler.pipeline.interpret

This package contains the logic involved in reading Nanoverse source code and turning into an internal representation known as an abstract syntax tree. The abstract syntax tree has only structural information about the program; semantic information is added in the next step, Translate.

Much of the code in this package is computer-generated, and is therefore not subjected to automated tests.

nanoverse.compiler.pipeline.translate

This package contains the logic involved in understanding the user's specifications in the context of agent-based models. In technical terms, the Translate step decorates the abstract syntax tree with semantic information. This is accomplished by matching each token to a corresponding symbol table. If the token is not recognized as a well-defined symbol in the current context in which it is used, the compiler halts with an error.

The symbol table hierarchy is an extremely helpful source of information for the user: it can be used as a dictionary for types and their associated classes, as well as for the arguments of each particular class. The symbol table hierarchy can be found at nanoverse.compiler.pipeline.translate.symbol.

nanoverse.compiler.pipeline.instantiate

The last stage of the compilation pipeline is the Instantiate stage. During this stage, well-defined symbols are converted to Java objects. This process is completed recursively: before an object can be instantiated, its properties must first be instantiated as well.

Thus, at the outset of the Instantiation stage, the compiler begins to instantiate the simulation itself. In order to do this, the compiler must first instantiate each of the simulation's properties. Why? These properties are used to define the simulation itself. (On the Java side of things, these properties are arguments to the constructors of the simulation's foundational objects.) So these must be instantiated first.

The build sequence for an object called MyObject is defined in a Loader object called MyObjectLoader, in a method called instantiate(…). This Loader object should be in a package that mirrors the nanoverse.runtime hierarchy, rooted in nanoverse.compiler.pipeline.instantiate.loader.

The first Loader visited is the ProjectLoader, located at nanoverse.compiler.pipeline.instantiate.loader.control.ProjectLoader.

Interpolation

The user may omit essential properties from the project definition. If there is a default for that property, Nanoverse attempts to use it automatically. Some defaults are “smart”, in that they attempt to interpolate the most reasonable value based on the user's other input. For an object called MyObject with loader MyObjectLoader, interpolation will occur in an object called MyObjectInterpolator. Defaults are specified in MyObjectDefaults. The loader, interpolator and defaults are all in the same package.

Runtime

The nanoverse.runtime package contains all of the logic that will be used to actually execute a simulation. The first runtime object, nanoverse.runtime.control.Runner, is returned by the last step of the compiler. Executing its run() method begins simulation execution.

nanoverse.runtime.agent

The nanoverse.runtime.agent package contains classes involved in creating and controlling agents, including agent actions and action targets. the contents of nanoverse.runtime.cells will soon by migrated to this package as well.

nanoverse.runtime.agent.action

The nanoverse.runtime.agent.action package contains the definitions of all actions that can be performed by agents. The ActionClassSymbolTable (in the translate package of the compiler) provides human-readable descriptions actions, as well as their names in the Nanoverse language.

nanoverse.runtime.agent.target

The nanoverse.runtime.agent.target package contains methods used to specify the affected site(s) of transitive actions relative to the acting agent.

nanoverse.runtime.control

This package contains the control logic for the simulation engine itself, such as the simulation integrator (which moves the simulation forward through time) and halt events (which signal that the simulation is over).

nanoverse.runtime.control.halt

This package contains the so-called “Halt conditions” that cause the simulation to stop running. These are triggered by corresponding Check processes. There are two special cases: StepMaxReachedEvent, which occurs when the simulation has reached the maximum time specified in the parameters section of the project, and BoundaryReachedEvent, which occurs if an agent touches or passes the boundary while its agent layer is using a HaltBoundary.

nanoverse.runtime.geometry

This package contains the lattices, shapes and boundaries that make up the geometry of a simulation. This includes both simulation-wide geometric properties (lattice, shape) and the layer-specific boundary. This package also includes Coordinate objects and coordinate sets, which are used to specify areas of effect.

nanoverse.runtime.io

This package contains all serializers (output classes), deserializers (input classes), and visualizations for simulations.

nanoverse.runtime.layers

This package contains all of the logic for agent and continuum layers, as well as for the linkages between them.

nanoverse.runtime.layers.continuum

This package contains all classes concerned with managing and updating continuum layers. It includes the Java linkages to the PETSc numerical simulation library, which is used on Mac and UNIX computers to update simulation state quickly. (Windows users must content themselves with Matrix Toolkit Java).

nanoverse.runtime.layers.cell

This package contains all classes concerned with managing and updating agent layers. The biology-specific name is a holdover from earlier versions of Nanoverse; expect this to change soon.

nanoverse.runtime.processes

This package contains all of the global processes that can take place in a simulation. The ProcessClassSymbolTable (in the translate package of the compiler) provides plain-text descriptions of each process, as well as the word used to invoke the process in the Nanoverse programming language.

nanoverse.runtime.structural

This package contains utility methods that are used throughout the code base.

codebase.txt · Last modified: 2015/11/17 11:45 by david