JustBash.Interpreter.Expansion (JustBash v0.4.0)
View SourceHandles shell expansion: variables, command substitution, arithmetic.
Delegates to specialized submodules:
Parameter- Parameter expansion operations (${VAR:-default}, etc.)Glob- Glob expansion and pattern matchingBrace- Brace expansion ({a,b,c}, {1..10})
Summary
Types
A variable assignment from an expansion like ${VAR:=default} or $((x++))
Side effects an expansion hands back to the enclosing command.
What a command substitution did, on its way out to the enclosing command.
Functions
Expand a single array element word, applying IFS splitting to unquoted expansions.
Expand words for a for-loop, applying IFS splitting to unquoted expansions.
Expand a parameter with optional operations. Returns {expanded_value, pending_assignments}.
Expand redirection target.
Expand word parts into a string, handling all substitution types.
Returns the expanded string and any side effects — see pending_assignments/0
and take_substitutions/1.
Expand word parts into a string, discarding pending assignments. Use this when you don't need to track variable assignments (e.g., in pattern matching).
Expand word parts with brace and glob expansion, returning a list of strings. Used for command arguments where globs should expand to multiple files.
Split the command-substitution traces out of a list of expansion side effects.
Types
A variable assignment from an expansion like ${VAR:=default} or $((x++))
@type pending_assignments() :: [assignment() | substitution()]
Side effects an expansion hands back to the enclosing command.
@type substitution() :: {:substitution, String.t(), non_neg_integer()}
What a command substitution did, on its way out to the enclosing command.
Its diagnostic belongs on the shell's stderr — bash writes it there even when
the enclosing command redirects stderr, since the expansion happens before
the redirection is performed — and its exit status is what a bare assignment
reports as $?.
Functions
@spec expand_array_element(JustBash.t(), JustBash.AST.Word.t()) :: [String.t()]
Expand a single array element word, applying IFS splitting to unquoted expansions.
Used for array assignment like arr=($(echo "a b c")) where command substitution
output should be word-split into multiple array elements.
Returns a list of expanded strings (may be multiple due to IFS splitting or brace expansion).
@spec expand_for_loop_words(JustBash.t(), [JustBash.AST.Word.t()]) :: [String.t()]
Expand words for a for-loop, applying IFS splitting to unquoted expansions.
In bash, IFS splitting only happens on unquoted variable/command substitution results. Quoted strings (single or double) are not split. Brace expansion produces multiple words directly.
@spec expand_parameter(JustBash.t(), JustBash.AST.ParameterExpansion.t()) :: {String.t(), pending_assignments()}
Expand a parameter with optional operations. Returns {expanded_value, pending_assignments}.
Delegates to JustBash.Interpreter.Expansion.Parameter.
@spec expand_redirect_target(JustBash.t(), JustBash.AST.Word.t() | String.t() | any()) :: String.t()
Expand redirection target.
@spec expand_word_parts(JustBash.t(), [JustBash.AST.word_part()]) :: {String.t(), pending_assignments()}
Expand word parts into a string, handling all substitution types.
Returns the expanded string and any side effects — see pending_assignments/0
and take_substitutions/1.
Examples
iex> expand_word_parts(bash, [%AST.Literal{value: "hello"}])
{"hello", []}
iex> expand_word_parts(bash, [%AST.ParameterExpansion{parameter: "x", operation: %AST.AssignDefault{...}}])
{"default", [{"x", "default"}]}
@spec expand_word_parts_simple(JustBash.t(), [JustBash.AST.word_part()]) :: String.t()
Expand word parts into a string, discarding pending assignments. Use this when you don't need to track variable assignments (e.g., in pattern matching).
@spec expand_word_with_glob(JustBash.t(), [JustBash.AST.word_part()]) :: {[String.t()], pending_assignments()}
Expand word parts with brace and glob expansion, returning a list of strings. Used for command arguments where globs should expand to multiple files.
Expansion order: brace -> parameter/command -> word splitting (IFS) -> glob
@spec take_substitutions(pending_assignments()) :: {String.t(), non_neg_integer() | nil, [assignment()]}
Split the command-substitution traces out of a list of expansion side effects.
Returns the accumulated stderr, the exit status of the last substitution
that ran (nil when none did — bash reports the last one as $? for a bare
assignment), and the assignments left over.