External Stages

fud supports using stages that aren't defined in its main source tree. These are known as 'external stages' and the provide a mechanism for projects using Calyx to take advantage of fud. You can register an external stage with:

fud register stage_name -p /path/to/stage.py

Once an external stage is registered, it behaves exactly like any other stage.

You can remove an external stage with:

fud register stage_name --delete

The following defines a stage that transforms MrXL programs to Calyx programs.

from fud.stages import Stage, SourceType
from fud.utils import shell


class MrXLStage(Stage):
    """
    Stage that invokes the MrXL frontend.
    """

    def __init__(self, config):
        super().__init__(
            name="mrxl",
            target_stage="futil",
            input_type=SourceType.Path,
            output_type=SourceType.Stream,
            config=config,
            description="Compiles MrXL to Calyx.",
        )
        self.setup()

    @staticmethod
    def defaults():
        return {"exec": "mrxl"}

    def _define_steps(self, input_path):
        @self.step(description=self.cmd)
        def run_mrxl(mrxl_prog: SourceType.Path) -> SourceType.Stream:
            return shell(f"{self.cmd} {str(mrxl_prog)}")

        return run_mrxl(input_path)


# Export the defined stages to fud
__STAGES__ = [MrXLStage]

External stages must define default values for configuration keys using the Stage.defaults() static method.

Stage Configuration

Like normal stages, external stages can have persistent configuration information saved using fud config.

To add persistent stage configuration, run:

fud config stages.<stage-name>.<key> <value>

To dynamically override the value of a field during execution, use the -s flag:

fud e -s <stage-name>.<key> <value> ...

The override order for stage configuration is:

  1. Dynamic values provided by -s.
  2. Configuration value in the fud config.
  3. Default value provided by Stage.defaults()