def _EvalLhsAndLookupArith(self, node):
        # type: (arith_expr_t) -> Tuple[int, lvalue_t]
        """ For x = y  and   x += y  and  ++x """

        lval = self.EvalArithLhs(node, runtime.NO_SPID)
        val = OldValue(lval, self.mem, self.exec_opts)

        # BASH_LINENO, arr (array name with shopt -s compat_array), etc.
        if val.tag_() in (value_e.MaybeStrArray, value_e.AssocArray
                          ) and lval.tag_() == lvalue_e.Named:
            named_lval = cast(lvalue__Named, lval)
            if word_eval.CheckCompatArray(named_lval.name, self.exec_opts):
                if val.tag_() == value_e.MaybeStrArray:
                    lval = lvalue.Indexed(named_lval.name, 0)
                elif val.tag_() == value_e.AssocArray:
                    lval = lvalue.Keyed(named_lval.name, '0')
                val = word_eval.ResolveCompatArray(val)

        # This error message could be better, but we already have one
        #if val.tag_() == value_e.MaybeStrArray:
        #  e_die("Can't use assignment like ++ or += on arrays")

        span_id = location.SpanForArithExpr(node)
        i = self._ValToIntOrError(val, span_id=span_id)
        return i, lval
Ejemplo n.º 2
0
  def EvalToInt(self, node):
    # type: (arith_expr_t) -> int
    """Used externally by ${a[i+1]} and ${a:start:len}.

    Also used internally.
    """
    val = self.Eval(node)

    # BASH_LINENO, arr (array name with shopt -s compat_array), etc.
    if val.tag_() in (value_e.MaybeStrArray, value_e.AssocArray) and node.tag_() == arith_expr_e.VarRef:
      tok = cast(Token, node)
      if word_eval.CheckCompatArray(tok.val, self.exec_opts):
        val = word_eval.ResolveCompatArray(val)

    # TODO: Can we avoid the runtime cost of adding location info?
    span_id = location.SpanForArithExpr(node)
    i = self._ValToIntOrError(val, span_id=span_id)
    return i