nasa / fpp

F Prime Prime: A modeling language for F Prime
https://fprime.jpl.nasa.gov
Apache License 2.0
49 stars 31 forks source link

Add a location symbol for include specifiers #354

Open bocchino opened 11 months ago

bocchino commented 11 months ago

Currently the path in an include specifier is resolved relative to the location of the include specifier. This makes it hard to "drop in" library code that uses include specifiers, because the location of the specifier may not be known by the author of the specifier. For example, a file that says include "../../foo/bar.fppi" must be two directories down from the start of the relative path foo/bar.fppi. But a user may want to put the file in a different place.

The proposal is as follows:

  1. Add a new kind of symbol called a location symbol. For example

    location L
  2. Add a new location specifier for location symbols:

    locate L at foo.fpp
  3. In an include specifier, allow a location symbol to be specified. For example:

    include L "bar/baz.fppi"

In item 1, L is the name of a location definition. To simplify the name resolution, location definitions may occur only at the top level (not inside a module or any other scoped construct). The name may be a qualified name, e.g., A.B.C, and the qualification is unrelated to the qualification implied by the nesting of scoped constructs. This approach is similar to Java and Scala package names.

In item 2, the location specifier says that the definition of location L is located in the file [absolute path]/foo.fpp, where [absolute path] is the absolute path of the directory containing the file containing the specifier.

In item 3, the include path bar/baz.fppi is relative to the location of the symbol L. The user can put the file with the include specifier anywhere; the location specifier for L will say where the root of the path bar/baz.fppi is. In the example in item 2, the root is [absolute path].

The at construct for instance definitions could work similarly:

instance i: C base id 0x100 at L "bar/baz.hpp"

To make the analysis deterministic, we can use the following algorithm:

  1. While there are any include specifiers in the model
    1. Non-recursively resolve all include specifiers that have no location specifier.
    2. Resolve all uses of location specifier symbols.
    3. Non-recursively resolve all include specifiers that have location specifiers.

For example, consider the following input:

We would resolve include b.fppi; then we would resolve the use of L in include L d.fppi; then we would resolve include L d.fppi.

An attempt to include a location specifier through another location specifier would fail. For example, this input would fail, because the symbols L and M would be undefined in step 2: