-
Notifications
You must be signed in to change notification settings - Fork 87
Modules Notes
-
We conflate modules and compilation units. That is, each file
f.p4
is module. -
Files are searched in a standard order -- e.g., according to an environment variable like
$P4PATH
and/or command-line arguments to thep4c
compiler.- It would be simplest to restrict that for every name
foo
, importing modulefoo
will always correspond to the filefoo.p4
in the first directory of$P4PATH
that contains such a file, ignoring any identically named files in later directories of$P4PATH
. Also, for a single execution of the compiler, there is only one value for$P4PATH
, i.e. no way to temporarily modify$P4PATH
for part of the compilation run, or when compiling some modules vs. other modules.
- It would be simplest to restrict that for every name
-
We still run
cpp
over each file before loading. However, this will be discouraged, and we hope soon become unnecessary. -
We import modules by name in a P4 Program.
import f; // can now reference f.x and f.y
import f as g; // can now reference g.x and g.y
from f import x,y; // can now reference x and y
from f import *; // @jafingerhut argues against this. // However, this would let us say that the compiler automagically does `from core import *` // We could consider making core, and perhaps also one architecture per program, as a special // case that behaves like `from core import *`, but still not let the P4 developer write // `from foo import *` for any other modules.
-
A few issues to think about:
-
Do we write
import core
? Or do we just automatically import and open that module? -
Do we write
import v1model
?- Could specify architecture on the command-line and automagically import, like
core
?
... counter(1024) c; ... switch( ... ) main;
- Could specify the architecture on the command-line but manually import architecture
import psa ... psa.counter(1024) c; ... psa.switch( ... ) main;
- Could specify the architecture on the command-line but automagically import with a wildcard
from psa import * ... counter(1024) c; ... switch( ... ) main;
- Could include using
cpp
directives
#include<psa.p4> ... counter(1024) c; ... switch( ... ) main;
- Could specify architecture on the command-line and automagically import, like
-
-
Circular dependencies between compilation units not allowed
-
import statements are definitely supported at the top level of the code. Proposal: It seems reasonable to disallow them anywhere except at the top level of a program, e.g. they are not permitted inside the body of a parser or control.
-
Proposal: Explicitly support an arbitrary directed acyclic graph structure of imports between modules in a single compilation run, i.e. compiling A, which imports B, C, and D, and all of B, C, and D import E (perhaps with different aliases for each) should be allowed.
- Does it ever make sense for the instantiation of
main
to be anywhere other than A, the file name / module that one directly invokes the compiler on? Anything after that instantiation seems like it cannot affect the behavior of earlier code, so seems like it must be dead code to me. P4 has no forward declarations. - Should a module that is imported be allowed to have top level instantiations of extern objects, parsers, controls, or packages? Proposal: Yes. If yes, and if a module like E in the example above is imported from multiple other places has such instantiations, should that imply exactly one instantiation of each of those objects, or once for each time that E is imported (3 in the example above)? Proposal: Exactly one instantiation seems simpler to implement and reason about, and still useful.
- Does it ever make sense for the instantiation of
-
Should A be allowed to have multiple import statements for the same module B? If so, what does that mean? Proposal: It is allowed, and simply creates more aliases for the same objects of B inside of A. In the directed acyclic graph described in the issue above, it is simply multiple edges from A to B.