From a17ddcf8acbeff99d928be60e903fe46929e548b Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 1 Jan 2025 01:21:19 +0900 Subject: [PATCH] [doc] Introduce concepts "h-value" and "r-value" of the expansion ${x} --- core/runtime.asdl | 5 +++-- doc/ref/chap-word-lang.md | 31 +++++++++++++++++++------------ osh/word_eval.py | 8 ++++---- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/core/runtime.asdl b/core/runtime.asdl index 2917b6caf..80e43633a 100644 --- a/core/runtime.asdl +++ b/core/runtime.asdl @@ -58,8 +58,9 @@ module runtime coerced = Int | Float | Neither - # evaluation state for BracedVarSub - VarSubState = (bool join_array, value holder_val, Token array_ref) + # evaluation state for BracedVarSub. See "doc/ref/chap-word-lang.md" for + # the description of h-value of a variable substitution. + VarSubState = (bool join_array, value h_value, Token array_ref) # A Cell is a wrapper for a value. # TODO: add location for declaration for 'assigning const' error diff --git a/doc/ref/chap-word-lang.md b/doc/ref/chap-word-lang.md index 5ffbab89f..cecdb0839 100644 --- a/doc/ref/chap-word-lang.md +++ b/doc/ref/chap-word-lang.md @@ -300,8 +300,15 @@ string: --- -`${x@a}` returns the set of characters that represent the attributes of the -variable in which each resulting string is stored. +`${x@a}` returns the set of characters that represent the attributes of +*h-value* of the expansion `$x`. + +Here, *h-value* is the variable (or the object that the variable directly +points) from which the result of `$x` would originally come. This is different +from the *r-value* of the expansion `$x`, namely the result of the expansion +`$x`. + +The characters representing attributes are listed below: - `a`: The value of `$x` would be obtained from an indexed array element. - `A`: The value of `$x` would be obtained from an associative array element. @@ -309,18 +316,18 @@ variable in which each resulting string is stored. - `x`: The value of `$x` would be obtained from a container with the export attribute. - `n`: `x` is a name reference (OSH extension) -It should be noted that `${x@a}` does not return the attributes of the obtained -value. For example, `${a[0]@a}` returns `a` because the string `${a[0]}` would -be obtained from an array although the resulting value of `${a[0]}` is a scalar -string. +It should be noted that `${x@a}` does not return the attributes of the +*r-value* of the expansion `$x`. For example, although the *r-value* of +`${arr[0]}` is arr scalar string, `${arr[0]@a}` returns `a` because the +*h-value* is array `arr`, which stores the element `arr[0]`. - $ echo ${a[0]@a} + $ echo ${arr[0]@a} a -When `$x` would result in a word list (such as `${a[@]}` and `${!ref}` with -`ref="a[@]"`), `${x@a}` returns a word list containing the attributes for each -word. +When `$x` would result in a word list (such as `${arr[@]}` and `${!ref}` with +`ref="arr[@]"`), `${x@a}` returns a word list containing the attributes of the +*h-value* of each word. - $ a=(1 2 3) - $ echo "${a[@]@a}" + $ arr=(1 2 3) + $ echo "${arr[@]@a}" a a a diff --git a/osh/word_eval.py b/osh/word_eval.py index a788681c2..5007f5070 100644 --- a/osh/word_eval.py +++ b/osh/word_eval.py @@ -1104,7 +1104,7 @@ def _Nullary(self, val, op, var_name, vsub_token, vsub_state): # We're ONLY simluating -a and -A, not -r -x -n for now. See # spec/ble-idioms.test.sh. chars = [] # type: List[str] - with tagswitch(vsub_state.holder_val) as case: + with tagswitch(vsub_state.h_value) as case: if case(value_e.BashArray): chars.append('a') elif case(value_e.BashAssoc): @@ -1353,8 +1353,8 @@ def _VarRefValue(self, part, quoted, vsub_state, vtest_place): # $* decays val = self._EvalSpecialVar(part.name_tok.id, quoted, vsub_state) - # update the holder of the current value - vsub_state.holder_val = val + # update h-value (i.e., the holder of the current value) + vsub_state.h_value = val # We don't need var_index because it's only for L-Values of test ops? if self.exec_opts.eval_unsafe_arith(): @@ -1448,7 +1448,7 @@ def _EvalBracedVarSub(self, part, part_vals, quoted): suffix_op_ = part.suffix_op if suffix_op_: UP_op = suffix_op_ - vsub_state.holder_val = val + vsub_state.h_value = val # 2. Bracket Op val = self._EvalBracketOp(val, part, quoted, vsub_state, vtest_place)