Exobiont Systems

⌂ Home

Shell Command Type DSL

To overcome the limitations of our initial grep-based command-type database, we propose a new DSL to declare the typing of shell commands more intuitively and precisely. Our goal is to match specific command invocation patterns and assign them a type, such that variations on input/output types which depend on the configuration of the process arguments, can be captured in a clean and non-repetetive way.

The DSL is made up of two essential objectives: to define Command Patterns and Type Statements.

Command Patterns

The first aspect of the DSL is to match command invocations. Each command pattern must be opened with the :: prefix. Then we follow a syntax which resembles that of the SYNOPSIS section in manpages.

Example 1: Command pattern for a regular stat invocation

::stat [OPTION]... FILE...

Example 2: Command pattern for a regular find invocation

::find [START-DIR]... [EXPRESSION]

Example 3: Command pattern for invocation of version info

::find --version

(Uppercase names will be interpreted as variables, whereas all other strings are counted as literal)

Command Types

Given a Command Pattern, we can now define the Command Type for the case that the command invocation matches the pattern.

Therefore, a Command Pattern is always followed by a Command Type, given as a collection of type assignments inside a { ... }-block.

A Command Type is a collection of type assignments, where all kinds of input/output streams — such as arguments, pipes and files — of a process can be selected.

The general syntax for a Type Statement is

    SELECTOR : TYPE ;

Where TYPE is a Ladder-Type and SELECTOR can be any of:

SELECTOR Function
>0 Stdin
<1 Stdout
<2 Stderr
>FD Select input pipe on filedescriptor FD
<FD Select output pipe on filedescriptor FD
PATTERN-VARIABLE Select a matched sub-pattern
$VAR Environment Variable
$1 First Process Argument
@FILE Content of a file

Example 4: (simplified) Command type definition for the regular invocation pattern of find

::find [START-DIR]... [EXPRESSION] {

    # The each of the arguments matched by START-DIR must be of type `Path`
    START-DIR : Path ;

    # The data written to stdout is a newline-separated sequence of paths
    <1 : [ Path ~ [Char] ] ~ <SepSeq '\n' Char> ~ [Char] ;
}

A command type file may contain multiple command patterns. They will be tested in order where the first successful match will return.

Example 5: Multiple patterns in one file

::find --help { <1: Help~[Char]; }
::find -version--version { <1: VersionInfo~[Char]; }
::find [START-DIR]... [EXPRESSION] {

    # The each of the arguments matched by START-DIR must be of type `Path`
    START-DIR : Path ;

    # The data written to stdout is a newline-separated sequence of paths
    <1 : [ Path ~ [Char] ] ~ <SepSeq '\n' Char> ~ [Char] ;
}

Match Statement

Inside a block of Type Statements , any VARIABLE from the Command Pattern can be refined to match against a specific set of sub-patterns, where each case may add extra Type Statements to the resulting Process Type.

Example 6: Match inside Type-Block

::find [START-DIR]... [EXPRESSION] {

    # The each of the arguments matched by START-DIR must be of type `Path`
    START-DIR : Path ;

    match EXPRESSION {
        # In case the `-print0` option is enabled, change the output type
        ::-print0 {
            # The data written to stdout is a null-separated sequence of paths
            <1 : [ Path ~ [Char] ] ~ <SepSeq '\0' Char> ~ [Char] ;
        }

        # default
        ::{
            # The data written to stdout is a newline-separated sequence of paths
            <1 : [ Path ~ [Char] ] ~ <SepSeq '\n' Char> ~ [Char] ;
        }
    }
}

Questions

Format Strings

Parameter Packs

Pattern options are intricate

date has format string AND -R/-I options, which exclude each other..

xargs ??