1 Subject: multi-dimension in operator
3 It is currently not possible to use the in operator directly with
4 multi-dimensional keys, you need to workaround like this:
6 if (("1" $sub_sep "2") in myArray)
11 if ([1, 2] in myArray)
16 doc/help.etx | 13 +++----------
17 source/interpret.c | 38 +++++++++++++++++++++++++++++++++++++-
19 source/parse.y | 13 +++++++++++--
20 4 files changed, 52 insertions(+), 13 deletions(-)
22 diff --quilt old/source/interpret.c new/source/interpret.c
23 --- old/source/interpret.c
24 +++ new/source/interpret.c
25 @@ -1876,6 +1876,41 @@ static int assign(void)
30 +** Before: Prog-> [nDim], next, ...
31 +** TheStack-> [indnDim, ... ind1], next, ...
32 +** After: Prog-> nDim, [next], ...
33 +** TheStack-> kayValue, next, ...
35 +static int arrayIndex(void)
38 + char *keyString = NULL;
46 + STACKDUMP(nDim+3, 3);
48 + /* the next nDim stack entries form the index */
49 + errNum = makeArrayKeyFromArgs(nDim, &keyString, False);
50 + if (errNum != STAT_OK) {
54 + keyData.tag = STRING_TAG;
55 + keyData.val.str.rep = keyString;
56 + keyData.val.str.len = strlen(keyString);
64 ** copy the top value of the stack
65 ** Before: TheStack-> value, next, ...
66 ** After: TheStack-> value, value, next, ...
67 @@ -3966,7 +4001,8 @@ static void disasmInternal(Inst *inst, i
68 j == OP_ARRAY_ASSIGN ||
69 j == OP_ANONARRAY_INDEX_VAL ||
71 - j == OP_NAMED_ARGN) {
72 + j == OP_NAMED_ARGN ||
73 + j == OP_ARRAY_INDEX) {
74 printd(" nDim=%d", inst[i+1].value);
77 diff --quilt old/source/parse.y new/source/parse.y
78 --- old/source/parse.y
79 +++ new/source/parse.y
80 @@ -680,16 +680,25 @@ numexpr: '(' blank expr blank ')'
81 ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DUP);
82 ADD_OP($2); ADD_OP(OP_ASSIGN); ADD_SYM($1);
84 - | numexpr IN blank numexpr {
85 + | keyinexpr IN blank numexpr {
88 - | numexpr NOT IN blank numexpr %prec IN {
89 + | keyinexpr NOT IN blank numexpr %prec IN {
96 +/* array key expression for in operator */
98 + | blank '[' arglist ']' blank {
99 + /* build the index from arglist and push to stack */
100 + ADD_OP(OP_ARRAY_INDEX);
106 $$ = GetPC(); StartLoopAddrList();
108 diff --quilt old/doc/help.etx new/doc/help.etx
111 @@ -2328,17 +2328,10 @@ Macro Language
112 You can also check for the existence of multi-dimensional array by
113 looking for $sub_sep in the key.
115 - Last, you need $sub_sep if you want to use the 'in' keyword.
116 + If you want to use the 'in' keyword, use this syntax:
118 - if ((1,2) in myArray)
123 - if (("1" $sub_sep "2") in myArray)
127 + if ([1,2] in myArray)
130 Note that if an array contains a value that is itself an array, you can
131 apply the index operator more than once. For example
132 diff --quilt old/source/ops.h new/source/ops.h
135 @@ -41,6 +41,7 @@ OP(ARRAY_ASSIGN, arrayAssign)
136 OP(BEGIN_ARRAY_ITER, beginArrayIter) /* it */ /* pop(a), it=a.begin */
137 OP(ARRAY_ITER, arrayIter) /* k,it,pc */ /* it ? (k.v=it.k, it++) : PC = pc */
138 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
139 +OP(ARRAY_INDEX, arrayIndex) /* N */ /* pop(kN..k1), push([kN..k1]) */
140 OP(ARRAY_DELETE, deleteArrayElement) /*N*/ /* N>0 ? (pop(kN..k1,a), del(a[k])) : (pop(a), delall(a)) */
141 OP(PUSH_ARRAY_SYM, pushArraySymVal) /*s,i*/ /* if i: s.v=ary()), push(s.v) */
142 OP(ARRAY_REF_ASSIGN_SETUP, arrayRefAndAssignSetup) /*op,N*/ /* pop(v,kN..a), a[k1..kN] op= v */