`type name = string`

The type `word` is a description of words in Shell. See POSIX, 2 Shell & Utilities, 2.3 Token Recognition

`and character_range = char list`
`and attribute =`

1. `| NoAttribute`
2. `| ParameterLength`
3. `| UseDefaultValues of word * bool`
4. `| AssignDefaultValues of word * bool`
5. `| IndicateErrorifNullorUnset of word * bool`
6. `| UseAlternativeValue of word * bool`
7. `| RemoveSmallestSuffixPattern of word`
8. `| RemoveLargestSuffixPattern of word`
9. `| RemoveSmallestPrefixPattern of word`
10. `| RemoveLargestPrefixPattern of word`

`and word_component =`

1. `| WTildePrefix of string`
2. `| WLiteral of string`
3. `| WDoubleQuoted of word`
4. `| WVariable of name * attribute`
5. `| WSubshell of program`
6. `| WGlobAll`
7. `| WGlobAny`
8. `| WBracketExpression of Morbig.CST.bracket_expression`

`and word = word_component list`
`and word' = word Location.located`

For now, a `pattern` is just a `word`.

`and pattern = word list`
`and pattern' = pattern Location.located`

An assignment is just a pair of a `name` and a `word`.

`and assignment = name * word`
`and assignment' = assignment Location.located`

A file descriptor `descr` is an integer.

`and descr = int`

The following description does contain all the semantic subtleties of POSIX Shell. Such a description can be found in the document IEEE Std 1003.1™-2008, 2016 Edition. In the following, we will refer to it simple as POSIX.

The type `command` contains the definition of a Shell command in Morsmall. Compared to what can be found in the POSIX standard or in Morbig, this type is rather small. This is because a lot of syntactically distinct scripts that are semantically equivalent are identified in here. For instance, all the following scripts are equivalent and identified as such:

        if t1; then c1; elif t2; then c2; fi
        if { t1; }; then c1; elif { { t2; }; }; fi
        if t1; then c1; else if t2; then c2; fi; fi

### Simple Command

See POSIX, 2 Shell & Utilities, 2.9.1 Simple Command

### Lists and Pipelines

See POSIX, 2 Shell & Utilities, 2.9.2 Pipelines and 2.9.3 Lists

- Asynchronous Lists. When encountering `Async c`, the Shell shall execute `c` asynchronously in a subshell. This means that the shell shall not wait for the command to finish before executing the next command.

- Sequential Lists. A contrario, the commands `c1` and `c2` in `Seq (c1, c2)` shall be executed sequentially.

- AND Lists. In `And (c1, c2)`, `c1` shall be executed first. If its exit status is zero, `c2` shall be executed. The commands are expanded only if they are executed.

- OR Lists. In `Or (c1, c2)`, `c1` shall be executed first. If its exit status is non-zero, `c2` shall be executed.

- Pipeline. In `Pipe (c1, c2)`, the standard output of `c1` shall be connected to the standard input of `c2`. The standard input, standard output, or both of a command shall be considered to be assigned by the pipeline before any redirection specified by redirection operators that are part of the command.

- Negation. The command `Not c` has the same behaviour as `c`, except for the exit status that shall be the logical NOT of the exit status of `c`.

### Compound Commands

See POSIX, 2 Shell & Utilities, 2.9.4 Compound Commands

- The Subshell Environment. `Subshell c` shall execute `c` a subshell environment. Variable assignments and built-in commands that affect the environment shall not remain in effect after the list finishes.

- The for Loop. `For (x, l, c)` shall execute a sequence of commands `c` for each member in a list of items. It is to be noted that `l` is non-mandatory and is thus an option. Besides, there is an important semantic difference between `None` and `Some []`. The former appears in a for loop where the list of words appear but is empty. In that case, the for loops through the empty list. The latter appears in a for loop where the list of words has been omitted. In that case, the for loops through the positional parameters.

- The case Conditional Construct. `Case (w, [([p11;...],c1); ...])` shall execute the compound-list corresponding to the first one of several patterns that is matched by the string resulting from the expansion of the given word `w`. In order from the beginning to the end of the case statement, each pattern `p*` shall be subjected to expansion, and the result of these expansions shall be compared against the expansion of `w`. After the first match, no more patterns shall be expanded, and the corresponding `c*` shall be executed. The order of expansion and comparison of multiple patterns that label the same statement is unspecified.

- The if Conditional Construct. `If (c1, c2, c3)` shall execute `c1` and use its exit status to determine whether to execute `c2` or `c3`. In fact, `c3` is not mandatory and is thus an option.

- The while Loop. `While (c1, c2)` shall continuously execute `c2` as long as `c1` has a zero exit status.

- The until Loop. `Until (c1, c2)` shall continuously execute `c2` as long as `c1` has a non-zero exit status.

### Function Definition Command

See POSIX, 2 Shell & Utilities, 2.9.5 Function Definition Command

A function is a user-defined name that is used as a simple command to call a compound command with new positional parameters. A function is defined with a function definition command, `Function (name, body)`.

This function definition command defines a function named `name: string` and with body `body: command`. The `body` shall be executed whenever `name` is specified as the name of a simple command.

### Redirection

See POSIX, 2 Shell & Utilities, 2.7 Redirections

## Type Definitions

The type `command` describes a command in the AST. All the command semantics are described at the top of this document.

`and program = command' list`
`and command =`

1. `| Simple of assignment' list * word' list`
2. `| Async of command'`
3. `| Seq of command' * command'`
4. `| And of command' * command'`
5. `| Or of command' * command'`
6. `| Not of command'`
7. `| Pipe of command' * command'`
8. `| Subshell of command'`
9. `| For of name * word' list option * command'`
10. `| Case of word' * case_item' list`
11. `| If of command' * command' * command' option`
12. `| While of command' * command'`
13. `| Until of command' * command'`
14. `| Function of name * command'`
15. `| Redirection of command' * descr * kind * word'`
16. `| HereDocument of command' * descr * word'`

`and command' = command Location.located`
`and case_item = pattern' * command' option`
`and case_item' = case_item Location.located`
`and kind =`

1. `| Output`
2. `| OutputDuplicate`
3. `| OutputAppend`
4. `| OutputClobber`
5. `| Input`
6. `| InputDuplicate`
7. `| InputOutput`

`include sig ... end`
`class virtual +'a iter : object ... end`
`include sig ... end`
`class virtual +'a map : object ... end`
`include sig ... end`
`class virtual +'a reduce : object ... end`
`include sig ... end`
`class virtual +'a mapreduce : object ... end`
`include sig ... end`
`class virtual +'a iter2 : object ... end`
`include sig ... end`
`class virtual +'a map2 : object ... end`
`include sig ... end`
`class virtual +'a reduce2 : object ... end`
`val equal_name : name -> name -> Ppx_deriving_runtime.bool`
`val equal_character_range : character_range -> character_range -> Ppx_deriving_runtime.bool`
`val equal_attribute : attribute -> attribute -> Ppx_deriving_runtime.bool`
`val equal_word_component : word_component -> word_component -> Ppx_deriving_runtime.bool`
`val equal_word : word -> word -> Ppx_deriving_runtime.bool`
`val equal_word' : word' -> word' -> Ppx_deriving_runtime.bool`
`val equal_pattern : pattern -> pattern -> Ppx_deriving_runtime.bool`
`val equal_pattern' : pattern' -> pattern' -> Ppx_deriving_runtime.bool`
`val equal_assignment : assignment -> assignment -> Ppx_deriving_runtime.bool`
`val equal_assignment' : assignment' -> assignment' -> Ppx_deriving_runtime.bool`
`val equal_descr : descr -> descr -> Ppx_deriving_runtime.bool`
`val equal_program : program -> program -> Ppx_deriving_runtime.bool`
`val equal_command : command -> command -> Ppx_deriving_runtime.bool`
`val equal_command' : command' -> command' -> Ppx_deriving_runtime.bool`
`val equal_case_item : case_item -> case_item -> Ppx_deriving_runtime.bool`
`val equal_case_item' : case_item' -> case_item' -> Ppx_deriving_runtime.bool`
`val equal_kind : kind -> kind -> Ppx_deriving_runtime.bool`
`val pp_name : Ppx_deriving_runtime.Format.formatter -> name -> Ppx_deriving_runtime.unit`
`val show_name : name -> Ppx_deriving_runtime.string`
`val pp_character_range : Ppx_deriving_runtime.Format.formatter -> character_range -> Ppx_deriving_runtime.unit`
`val show_character_range : character_range -> Ppx_deriving_runtime.string`
`val pp_attribute : Ppx_deriving_runtime.Format.formatter -> attribute -> Ppx_deriving_runtime.unit`
`val show_attribute : attribute -> Ppx_deriving_runtime.string`
`val pp_word_component : Ppx_deriving_runtime.Format.formatter -> word_component -> Ppx_deriving_runtime.unit`
`val show_word_component : word_component -> Ppx_deriving_runtime.string`
`val pp_word : Ppx_deriving_runtime.Format.formatter -> word -> Ppx_deriving_runtime.unit`
`val show_word : word -> Ppx_deriving_runtime.string`
`val pp_word' : Ppx_deriving_runtime.Format.formatter -> word' -> Ppx_deriving_runtime.unit`
`val show_word' : word' -> Ppx_deriving_runtime.string`
`val pp_pattern : Ppx_deriving_runtime.Format.formatter -> pattern -> Ppx_deriving_runtime.unit`
`val show_pattern : pattern -> Ppx_deriving_runtime.string`
`val pp_pattern' : Ppx_deriving_runtime.Format.formatter -> pattern' -> Ppx_deriving_runtime.unit`
`val show_pattern' : pattern' -> Ppx_deriving_runtime.string`
`val pp_assignment : Ppx_deriving_runtime.Format.formatter -> assignment -> Ppx_deriving_runtime.unit`
`val show_assignment : assignment -> Ppx_deriving_runtime.string`
`val pp_assignment' : Ppx_deriving_runtime.Format.formatter -> assignment' -> Ppx_deriving_runtime.unit`
`val show_assignment' : assignment' -> Ppx_deriving_runtime.string`
`val pp_descr : Ppx_deriving_runtime.Format.formatter -> descr -> Ppx_deriving_runtime.unit`
`val show_descr : descr -> Ppx_deriving_runtime.string`
`val pp_program : Ppx_deriving_runtime.Format.formatter -> program -> Ppx_deriving_runtime.unit`
`val show_program : program -> Ppx_deriving_runtime.string`
`val pp_command : Ppx_deriving_runtime.Format.formatter -> command -> Ppx_deriving_runtime.unit`
`val show_command : command -> Ppx_deriving_runtime.string`
`val pp_command' : Ppx_deriving_runtime.Format.formatter -> command' -> Ppx_deriving_runtime.unit`
`val show_command' : command' -> Ppx_deriving_runtime.string`
`val pp_case_item : Ppx_deriving_runtime.Format.formatter -> case_item -> Ppx_deriving_runtime.unit`
`val show_case_item : case_item -> Ppx_deriving_runtime.string`
`val pp_case_item' : Ppx_deriving_runtime.Format.formatter -> case_item' -> Ppx_deriving_runtime.unit`
`val show_case_item' : case_item' -> Ppx_deriving_runtime.string`
`val pp_kind : Ppx_deriving_runtime.Format.formatter -> kind -> Ppx_deriving_runtime.unit`
`val show_kind : kind -> Ppx_deriving_runtime.string`
`val name_to_yojson : name -> Yojson.Safe.t`
`val name_of_yojson : Yojson.Safe.t -> name Ppx_deriving_yojson_runtime.error_or`
`val character_range_to_yojson : character_range -> Yojson.Safe.t`
`val character_range_of_yojson : Yojson.Safe.t -> character_range Ppx_deriving_yojson_runtime.error_or`
`val attribute_to_yojson : attribute -> Yojson.Safe.t`
`val attribute_of_yojson : Yojson.Safe.t -> attribute Ppx_deriving_yojson_runtime.error_or`
`val word_component_to_yojson : word_component -> Yojson.Safe.t`
`val word_component_of_yojson : Yojson.Safe.t -> word_component Ppx_deriving_yojson_runtime.error_or`
`val word_to_yojson : word -> Yojson.Safe.t`
`val word_of_yojson : Yojson.Safe.t -> word Ppx_deriving_yojson_runtime.error_or`
`val word'_to_yojson : word' -> Yojson.Safe.t`
`val word'_of_yojson : Yojson.Safe.t -> word' Ppx_deriving_yojson_runtime.error_or`
`val pattern_to_yojson : pattern -> Yojson.Safe.t`
`val pattern_of_yojson : Yojson.Safe.t -> pattern Ppx_deriving_yojson_runtime.error_or`
`val pattern'_to_yojson : pattern' -> Yojson.Safe.t`
`val pattern'_of_yojson : Yojson.Safe.t -> pattern' Ppx_deriving_yojson_runtime.error_or`
`val assignment_to_yojson : assignment -> Yojson.Safe.t`
`val assignment_of_yojson : Yojson.Safe.t -> assignment Ppx_deriving_yojson_runtime.error_or`
`val assignment'_to_yojson : assignment' -> Yojson.Safe.t`
`val assignment'_of_yojson : Yojson.Safe.t -> assignment' Ppx_deriving_yojson_runtime.error_or`
`val descr_to_yojson : descr -> Yojson.Safe.t`
`val descr_of_yojson : Yojson.Safe.t -> descr Ppx_deriving_yojson_runtime.error_or`
`val program_to_yojson : program -> Yojson.Safe.t`
`val program_of_yojson : Yojson.Safe.t -> program Ppx_deriving_yojson_runtime.error_or`
`val command_to_yojson : command -> Yojson.Safe.t`
`val command_of_yojson : Yojson.Safe.t -> command Ppx_deriving_yojson_runtime.error_or`
`val command'_to_yojson : command' -> Yojson.Safe.t`
`val command'_of_yojson : Yojson.Safe.t -> command' Ppx_deriving_yojson_runtime.error_or`
`val case_item_to_yojson : case_item -> Yojson.Safe.t`
`val case_item_of_yojson : Yojson.Safe.t -> case_item Ppx_deriving_yojson_runtime.error_or`
`val case_item'_to_yojson : case_item' -> Yojson.Safe.t`
`val case_item'_of_yojson : Yojson.Safe.t -> case_item' Ppx_deriving_yojson_runtime.error_or`
`val kind_to_yojson : kind -> Yojson.Safe.t`
`val kind_of_yojson : Yojson.Safe.t -> kind Ppx_deriving_yojson_runtime.error_or`
`val name_of_yojson_exn : Yojson.Safe.t -> name`
`val character_range_of_yojson_exn : Yojson.Safe.t -> character_range`
`val attribute_of_yojson_exn : Yojson.Safe.t -> attribute`
`val word_component_of_yojson_exn : Yojson.Safe.t -> word_component`
`val word_of_yojson_exn : Yojson.Safe.t -> word`
`val word'_of_yojson_exn : Yojson.Safe.t -> word'`
`val pattern_of_yojson_exn : Yojson.Safe.t -> pattern`
`val pattern'_of_yojson_exn : Yojson.Safe.t -> pattern'`
`val assignment_of_yojson_exn : Yojson.Safe.t -> assignment`
`val assignment'_of_yojson_exn : Yojson.Safe.t -> assignment'`
`val descr_of_yojson_exn : Yojson.Safe.t -> descr`
`val program_of_yojson_exn : Yojson.Safe.t -> program`
`val command_of_yojson_exn : Yojson.Safe.t -> command`
`val command'_of_yojson_exn : Yojson.Safe.t -> command'`
`val case_item_of_yojson_exn : Yojson.Safe.t -> case_item`
`val case_item'_of_yojson_exn : Yojson.Safe.t -> case_item'`
`val kind_of_yojson_exn : Yojson.Safe.t -> kind`
`val _ : Yojson.Safe.t -> kind`
`val default_redirection_descriptor : kind -> int`