Skip to content

Commit

Permalink
[osh] Implement SparseArray $sp as ${sp[0]} (#2222)
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga authored Jan 4, 2025
1 parent 25161ff commit f4f49ac
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
19 changes: 14 additions & 5 deletions osh/word_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,16 @@ def ShouldArrayDecay(var_name, exec_opts, is_plain_var_sub=True):
def DecayArray(val):
# type: (value_t) -> value_t
"""Resolve ${array} to ${array[0]}."""
if val.tag() == value_e.BashArray:
array_val = cast(value.BashArray, val)
s, error_code = bash_impl.BashArray_GetElement(array_val, 0)
if val.tag() in (value_e.BashArray, value_e.SparseArray):
if val.tag() == value_e.BashArray:
array_val = cast(value.BashArray, val)
s, error_code = bash_impl.BashArray_GetElement(array_val, 0)
elif val.tag() == value_e.SparseArray:
sparse_val = cast(value.SparseArray, val)
s, error_code = bash_impl.SparseArray_GetElement(
sparse_val, mops.ZERO)
else:
raise AssertionError(val.tag())

# Note: index 0 should never cause the out-of-bound index error.
assert error_code == error_code_e.OK
Expand Down Expand Up @@ -1419,7 +1426,8 @@ def _EvalBracketOp(self, val, part, quoted, vsub_state, vtest_place):
else: # no bracket op
var_name = vtest_place.name
if (var_name is not None and
val.tag() in (value_e.BashArray, value_e.BashAssoc)):
val.tag() in (value_e.BashArray, value_e.SparseArray,
value_e.BashAssoc)):
if ShouldArrayDecay(var_name, self.exec_opts,
not (part.prefix_op or part.suffix_op)):
# for ${BASH_SOURCE}, etc.
Expand Down Expand Up @@ -1698,7 +1706,8 @@ def _EvalSimpleVarSub(self, part, part_vals, quoted):
var_name = lexer.LazyStr(token)
# TODO: Special case for LINENO
val = self.mem.GetValue(var_name)
if val.tag() in (value_e.BashArray, value_e.BashAssoc):
if val.tag() in (value_e.BashArray, value_e.SparseArray,
value_e.BashAssoc):
if ShouldArrayDecay(var_name, self.exec_opts):
# for $BASH_SOURCE, etc.
val = DecayArray(val)
Expand Down
23 changes: 23 additions & 0 deletions spec/ble-idioms.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,29 @@ a3 empty: [ ]
## END


#### SparseArray: ${a-}
case $SH in zsh|mksh|ash) exit ;; esac

a1=()
a2=("" "")
a3=(foo bar)

case ${SH##*/} in osh) eval 'var a1 = _a2sp(a1); var a2 = _a2sp(a2); var a3 = _a2sp(a3)' ;; esac

echo "$a1, ${a1-(unset)}, ${a1:-(empty)};"
echo "$a2, ${a2-(unset)}, ${a2:-(empty)};"
echo "$a3, ${a3-(unset)}, ${a3:-(empty)};"

## STDOUT:
, (unset), (empty);
, , (empty);
foo, foo, foo;
## END

## N-I zsh/mksh/ash STDOUT:
## END


#### SparseArray: compgen -F _set_COMPREPLY
case $SH in zsh|mksh|ash) exit ;; esac

Expand Down

0 comments on commit f4f49ac

Please sign in to comment.