Skip to content

Commit

Permalink
[expr_eval] Add type checking for list indexing.
Browse files Browse the repository at this point in the history
Fixes a spec test.
  • Loading branch information
Andy Chu committed Jul 14, 2019
1 parent 74d6d24 commit d5066c5
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 4 deletions.
12 changes: 10 additions & 2 deletions osh/expr_eval.py
Expand Up @@ -380,6 +380,10 @@ def Eval(self, node, int_coerce=True):
int for Str
List[int] for StrArray
Dict[str, str] for AssocArray (TODO: Should we support this?)
NOTE: (( A['x'] = 'x' )) and (( x = A['x'] )) are syntactically valid in
bash, but don't do what you'd think. 'x' sometimes a variable name and
sometimes a key.
"""
# OSH semantics: Variable NAMES cannot be formed dynamically; but INTEGERS
# can. ${foo:-3}4 is OK. $? will be a compound word too, so we don't have
Expand Down Expand Up @@ -508,13 +512,16 @@ def Eval(self, node, int_coerce=True):
if op_id == Id.Arith_LBracket:
# StrArray or AssocArray
if isinstance(lhs, list):
if not isinstance(rhs, int):
e_die('Expected index to be an integer, got %r', rhs)
try:
item = lhs[rhs]
except IndexError:
if self.exec_opts.nounset:
e_die('Index out of bounds')
else:
return 0 # If not fatal, return 0
# TODO: Should be None for Undef instead? Or ''?
return 0

elif isinstance(lhs, dict):
try:
Expand All @@ -523,7 +530,8 @@ def Eval(self, node, int_coerce=True):
if self.exec_opts.nounset:
e_die('Invalid key %r' % rhs)
else:
return 0 # If not fatal, return 0
# TODO: Should be None for Undef instead? Or ''?
return 0
else:
# TODO: Add error context
e_die('Expected array in index expression, got %s', lhs)
Expand Down
1 change: 1 addition & 0 deletions osh/runtime.asdl
Expand Up @@ -53,6 +53,7 @@ module runtime
lvalue =
LhsName(string name)
| LhsIndexedName(string name, int index)
| LhsStringKey(string name, string key)

-- evaluated version of syntax.redir
redirect =
Expand Down
2 changes: 2 additions & 0 deletions spec/array.test.sh
Expand Up @@ -488,7 +488,9 @@ shopt -u strict-arith
a=(1 2 3)
(( x = a[a] ))
echo $x
## status: 1
## stdout-json: ""
## BUG bash/mksh status: 0
## BUG bash/mksh STDOUT:
2
## END
Expand Down
13 changes: 13 additions & 0 deletions spec/dparen.test.sh
Expand Up @@ -119,3 +119,16 @@ values = 0
## N-I zsh status: 1
## N-I mksh stdout-json: ""
## N-I mksh status: 1

#### literal strings not properly supported
declare -A A
A['x']=x
(( x = A['x'] ))
(( A['y'] = 'y' )) # y is a variable, gets coerced to 0
echo $x ${A['y']}
## STDOUT:
0 0
## END
## N-I zsh/mksh STDOUT:
0
## END
4 changes: 2 additions & 2 deletions test/spec.sh
Expand Up @@ -554,7 +554,7 @@ arith-context() {
}

array() {
sh-spec spec/array.test.sh --osh-failures-allowed 3 \
sh-spec spec/array.test.sh --osh-failures-allowed 2 \
$BASH $MKSH $OSH_LIST "$@"
}

Expand Down Expand Up @@ -593,7 +593,7 @@ dbracket() {
}

dparen() {
sh-spec spec/dparen.test.sh --osh-failures-allowed 4 \
sh-spec spec/dparen.test.sh --osh-failures-allowed 5 \
$BASH $MKSH $ZSH $OSH_LIST "$@"
}

Expand Down

0 comments on commit d5066c5

Please sign in to comment.