let all function types return NO_TAG
[nedit-bw.git] / extend-for-key-in-array-syntax.patch
blob32d7eaa9060e596b3d84de2bdbafdef1b1fd59bd
1 ---
3 doc/help.etx | 5 ++
4 source/interpret.c | 102 +++++++++++++++++++++++++++++++++++++----------------
5 source/parse.y | 31 ++++++++++++++--
6 3 files changed, 105 insertions(+), 33 deletions(-)
8 diff --quilt old/source/interpret.c new/source/interpret.c
9 --- old/source/interpret.c
10 +++ new/source/interpret.c
11 @@ -3256,13 +3256,13 @@ static int arrayRefAndAssignSetup(void)
15 ** setup symbol values for array iteration in interpreter
17 -** Before: Prog-> [iter], ARRAY_ITER, iterVar, iter, endLoopBranch, next, ...
18 +** Before: Prog-> [iter], ARRAY_ITER, withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
19 ** TheStack-> [arrayVal], next, ...
20 -** After: Prog-> iter, [ARRAY_ITER], iterVar, iter, endLoopBranch, next, ...
21 +** After: Prog-> iter, [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
22 ** TheStack-> [next], ...
23 ** Where:
24 ** iter is a symbol which gives the position of the iterator value in
25 ** the stack frame
26 ** arrayVal is the data value holding the array in question
27 @@ -3296,74 +3296,105 @@ static int beginArrayIter(void)
28 iteratorValPtr->val.arrayPtr = arrayIterateFirst(&arrayVal);
29 return(STAT_OK);
33 -** copy key to symbol if node is still valid, marked bad by a color of -1
34 -** then move iterator to next node
35 +** copy key and value to symbols if node is still valid, marked bad by a color
36 +** of -1 then move iterator to next node
37 ** this allows iterators to progress even if you delete any node in the array
38 ** except the item just after the current key
40 -** Before: Prog-> iter, ARRAY_ITER, [iterVar], iter, endLoopBranch, next, ...
41 +** Before: Prog-> iter, ARRAY_ITER, [withVal], iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
42 ** TheStack-> [next], ...
43 -** After: Prog-> iter, ARRAY_ITER, iterVar, iter, endLoopBranch, [next], ...
44 +** After: Prog-> iter, ARRAY_ITER, withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, [next], ...
45 ** TheStack-> [next], ... (unchanged)
46 -** Where:
47 +** Where:
48 ** iter is a symbol which gives the position of the iterator value in
49 -** the stack frame (set up by BEGIN_ARRAY_ITER); that value refers
50 +** the stack frame (set up by OP_BEGIN_ARRAY_ITER); that value refers
51 ** to the array and a position within it
52 -** iterVal is the programmer-visible symbol which will take the current
53 +** iterVarKey is the programmer-visible symbol which will take the current
54 ** key value
55 +** iterVarVal is the programmer-visible symbol which will take the current
56 +** entry value (only if withVal is true)
57 ** endLoopBranch is the instruction offset to the instruction following the
58 ** loop (measured from itself)
59 ** arrayVal is the data value holding the array in question
60 ** The return-to-start-of-loop branch (at the end of the loop) should address
61 ** the ARRAY_ITER instruction
63 static int arrayIter(void)
65 Symbol *iterator;
66 - Symbol *item;
67 + Symbol *itemKey;
68 + Symbol *itemVal;
69 DataValue *iteratorValPtr;
70 - DataValue *itemValPtr;
71 + DataValue *itemVarKeyPtr;
72 + DataValue *itemVarValPtr;
73 SparseArrayEntry *thisEntry;
74 Inst *branchAddr;
75 + int withVal;
77 DISASM_RT(PC-1, 4);
78 - STACKDUMP(0, 3);
79 + STACKDUMP(0, 4);
81 - item = PC->sym;
82 + withVal = PC->value;
83 + PC++;
84 + itemKey = PC->sym;
85 PC++;
86 + if (withVal) {
87 + itemVal = PC->sym;
88 + PC++;
89 + }
90 iterator = PC->sym;
91 PC++;
92 branchAddr = PC + PC->value;
93 PC++;
95 - if (item->type == LOCAL_SYM) {
96 - itemValPtr = &FP_GET_SYM_VAL(FrameP, item);
97 + if (itemKey->type == LOCAL_SYM) {
98 + itemVarKeyPtr = &FP_GET_SYM_VAL(FrameP, itemKey);
100 - else if (item->type == GLOBAL_SYM) {
101 - itemValPtr = &(item->value);
102 + else if (itemKey->type == GLOBAL_SYM) {
103 + itemVarKeyPtr = &(itemKey->value);
105 else {
106 - return(execError("can't assign to: %s", item->name));
107 + return(execError("can't assign to: %s", itemKey->name));
109 + itemVarKeyPtr->tag = NO_TAG;
111 + if (withVal) {
112 + if (itemVal->type == LOCAL_SYM) {
113 + itemVarValPtr = &FP_GET_SYM_VAL(FrameP, itemVal);
115 + else if (itemVal->type == GLOBAL_SYM) {
116 + itemVarValPtr = &(itemVal->value);
118 + else {
119 + return(execError("can't assign to: %s", itemVal->name));
121 + itemVarValPtr->tag = NO_TAG;
123 - itemValPtr->tag = NO_TAG;
125 if (iterator->type == LOCAL_SYM) {
126 iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
128 else {
129 return(execError("bad temporary iterator: %s", iterator->name));
132 thisEntry = iteratorValPtr->val.arrayPtr;
133 if (thisEntry && thisEntry->nodePtrs.color != -1) {
134 - itemValPtr->tag = STRING_TAG;
135 - itemValPtr->val.str.rep = thisEntry->key;
136 - itemValPtr->val.str.len = strlen(thisEntry->key);
138 + /* set key */
139 + itemVarKeyPtr->tag = STRING_TAG;
140 + itemVarKeyPtr->val.str.rep = thisEntry->key;
141 + itemVarKeyPtr->val.str.len = strlen(thisEntry->key);
143 + if (withVal) {
144 + /* set value */
145 + *itemVarValPtr = thisEntry->value;
148 + /* advance iterator */
149 iteratorValPtr->val.arrayPtr = arrayIterateNext(thisEntry);
151 else {
152 PC = branchAddr;
154 @@ -3872,16 +3903,29 @@ static void disasmInternal(Inst *inst, i
155 else if (j == OP_BEGIN_ARRAY_ITER) {
156 printd(" %s in", inst[i+1].sym->name);
157 ++i;
159 else if (j == OP_ARRAY_ITER) {
160 - printd(" %s = %s++ end-loop=(%+d) %8p",
161 - inst[i+1].sym->name,
162 - inst[i+2].sym->name,
163 - inst[i+3].value,
164 - &inst[i+3] + inst[i+3].value);
165 - i += 3;
166 + if (!inst[i+1].value) {
167 + /* without val */
168 + printd(" %s = %s++ end-loop=(%+d) %8p",
169 + inst[i+2].sym->name,
170 + inst[i+3].sym->name,
171 + inst[i+4].value,
172 + &inst[i+4] + inst[i+4].value);
173 + i += 4;
175 + else {
176 + /* with val */
177 + printd(" %s=%s = %s++ end-loop=(%+d) %8p",
178 + inst[i+2].sym->name,
179 + inst[i+3].sym->name,
180 + inst[i+4].sym->name,
181 + inst[i+5].value,
182 + &inst[i+5] + inst[i+5].value);
183 + i += 5;
186 else if (j == OP_ARRAY_REF ||
187 j == OP_ARRAY_DELETE ||
188 j == OP_ARRAY_ASSIGN ||
189 j == OP_ANONARRAY_INDEX_VAL ||
190 diff --quilt old/source/parse.y new/source/parse.y
191 --- old/source/parse.y
192 +++ new/source/parse.y
193 @@ -145,18 +145,41 @@ stmt: ';' blank
194 SwapCode($5+1, $7, GetPC());
195 ADD_OP(OP_BRANCH); ADD_BR_OFF($3); SET_BR_OFF($5, GetPC());
197 | for '(' blank SYMBOL IN blank arrayexpr blank ')' {
198 Symbol *iterSym = InstallIteratorSymbol();
199 - ADD_OP(OP_BEGIN_ARRAY_ITER); ADD_SYM(iterSym);
200 - ADD_OP(OP_ARRAY_ITER); ADD_SYM($4); ADD_SYM(iterSym); ADD_BR_OFF(0);
201 + ADD_OP(OP_BEGIN_ARRAY_ITER);
202 + ADD_SYM(iterSym);
203 + ADD_OP(OP_ARRAY_ITER);
204 + ADD_IMMED(0); /* without val symbol */
205 + ADD_SYM($4);
206 + ADD_SYM(iterSym);
207 + ADD_BR_OFF(0);
209 blank block {
210 - ADD_OP(OP_BRANCH); ADD_BR_OFF($7+2);
211 - SET_BR_OFF($7+5, GetPC());
212 + ADD_OP(OP_BRANCH);
213 + ADD_BR_OFF($7+2);
214 + SET_BR_OFF($7+6, GetPC());
215 FillLoopAddrs(GetPC(), $7+2);
217 + | for '(' blank SYMBOL ':' SYMBOL IN blank arrayexpr blank ')' {
218 + Symbol *iterSym = InstallIteratorSymbol();
219 + ADD_OP(OP_BEGIN_ARRAY_ITER);
220 + ADD_SYM(iterSym);
221 + ADD_OP(OP_ARRAY_ITER);
222 + ADD_IMMED(1); /* with val symbol */
223 + ADD_SYM($4);
224 + ADD_SYM($6);
225 + ADD_SYM(iterSym);
226 + ADD_BR_OFF(0);
228 + blank block {
229 + ADD_OP(OP_BRANCH);
230 + ADD_BR_OFF($9+2);
231 + SET_BR_OFF($9+7, GetPC());
232 + FillLoopAddrs(GetPC(), $9+2);
234 | BREAK stmtend blank {
235 ADD_OP(OP_BRANCH); ADD_BR_OFF(0);
236 if (AddBreakAddr(GetPC()-1)) {
237 yyerror("break outside loop"); YYERROR;
239 diff --quilt old/doc/help.etx new/doc/help.etx
240 --- old/doc/help.etx
241 +++ new/doc/help.etx
242 @@ -2259,10 +2259,15 @@ Macro Language
243 Keys are not guaranteed in any particular order:
245 for (aKey in x)
246 <body>
248 + Or, to get also the corresponding value for the key:
250 + for (aKey=theVal in x)
251 + <body>
253 Elements can be removed from an array using the delete command:
255 delete x[3] # deletes element with key 3
256 delete x[] # deletes all elements