-
Notifications
You must be signed in to change notification settings - Fork 63
Import System
The following topics are meant as collections of design ideas, with the purpose of refining them into concrete design proposals.
The import functionality in Lingua Franca is limited to:
import HelloWorld.lf
This can be useful if the .lf
file is located in the same directory as the file containing the main reactor.
However, several shortcomings exist in this current system which we shall discuss next.
Reactors with the same name can cause issues. For example:
import CatsAndPuppies.lf // Contains a Puppy reactor
import MeanPuppies.lf // Contains another Puppy reactor
There is no way for the LF program to distinguish between the two Puppy
reactors.
Note. With a relatively trivial extension to the current LF import mechanism, it is possible to detect duplicates, but there is no way to circumvent them in the current LF program (i.e., the original names might have to be changed).
Selective importing is not possible. For example, using
import CatsAndPuppies.lf
will import all the reactors contained in the .lf
file. It would be desirable to selectively import a subset of reactors in another .lf
file.
Currently, there is no elegant way of importing modules that are not in the same directory.
All the reactors imported will have the name originally given to them by the original programmer. It might make sense to rename them for the current LF program.
With the current import solution that only uses files, implementing packages in Lingua Franca is not feasible.
With inspirations from Python, we propose the following import mechanism:
"import" LF_Trunc_File/module ("," LF_Trunc_File/module)*
| "from" LFTruncFile/module "import" reactor ["as" name]
("," reactor ["as" name] )*
| "from" LF_Trunc_File/module "import" "*"
Before discussing some examples, let's discuss LF_Trunc_File/module
. First and foremost, LF_Truc_File
stands for Lingua Franca Truncated File, which is a name.lf
file with the .lf
removed. Therefore, the legacy support for import can be carried over as:
import HelloWorld
Second, the module
would introduce the notion of packages to Lingua Franca. The content of a module can be located in any path. To enable this facility, modules provide a Lingua Franca Meta file (LFM) that introduces the package name, and the absolute or relative paths of all the LF files that are included in that package. For example:
// CatsAndPuppies.LFM
package CatsAndPuppies // Optional. The file name would be interpreted as the package name.
import /home/user/linguafranca/pets/Cats.lf // Absolute paths
import pets/Puppies.lf // Relative paths
For a package to be accessible, the LFM
file needs to be discoverable. For example, it can be automatically added to the current directory or "installed" in a known Lingua Franca path (e.g., /usr/local/LF/packages
or /home/user/linguafranca/packages
).
With that in mind, let's discuss some examples on how this might work next.
The content of the HelloWorld.lf
example is as follows:
target C;
reactor SayHello {
timer t;
reaction(t) {=
printf("Hello World.\n");
=}
}
main reactor HelloWorldTest {
a = new HelloWorld();
}
Let us create a Greetings.lf
program based on HelloWorld.
target C;
import HelloWorld
main reactor Greetings {
a = new SayHello();
}
To generate code for Greetings.lf
, Lingua Franca first searches for a HelloWorld.lf
file in the same directory as Greetings.lf
. If not found, it will look for a HelloWorld.LFM
in the known paths. If none is found, an error is raised.
Now we can demonstrate selective import. For example:
target C;
from HelloWorld import SayHello
main reactor Greetings {
a = new SayHello();
}
Finally, renaming can be done by using the as
predicate:
target C;
from HelloWorld import SayHello as SayGreetings
main reactor Greetings {
a = new SayHeGreetings();
}