use StringToNumEnd() for check of numeric keys
[nedit-bw.git] / aryiter-on-stack.patch
blob456e89de366f8b37adcdfd7074fd879bc191b7fa
1 ---
3 source/interpret.c | 181 +++++++++++++++++------------------------------------
4 source/ops.h | 8 +-
5 source/parse.y | 40 ++++-------
6 3 files changed, 81 insertions(+), 148 deletions(-)
8 diff --quilt old/source/interpret.c new/source/interpret.c
9 --- old/source/interpret.c
10 +++ new/source/interpret.c
11 @@ -835,24 +835,6 @@ Symbol *InstallMultiAssignExpr(void)
15 -** install an array iteration symbol
16 -** it is tagged as an integer but holds an array node pointer
17 -*/
18 -#define ARRAY_ITER_SYM_PREFIX "aryiter #"
19 -Symbol *InstallIteratorSymbol(void)
21 - char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
22 - DataValue value;
23 - static int interatorNameIndex;
25 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
26 - ++interatorNameIndex;
27 - value.tag = INT_TAG;
28 - value.val.arrayPtr = NULL;
29 - return(InstallSymbol(symbolName, LOCAL_SYM, value));
32 -/*
33 ** Lookup a constant string by its value. This allows reuse of string
34 ** constants and fixing a leak in the interpreter.
36 @@ -3576,10 +3558,10 @@ static int arrayRefAndAssignSetup(void)
38 ** setup symbol values for array iteration in interpreter
40 -** Before: Prog-> [iter], ARRAY_ITER, withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
41 +** Before: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
42 ** TheStack-> [arrayVal], next, ...
43 -** After: Prog-> iter, [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
44 -** TheStack-> [next], ...
45 +** After: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
46 +** TheStack-> [iter], next, ...
47 ** Where:
48 ** iter is a symbol which gives the position of the iterator value in
49 ** the stack frame
50 @@ -3587,30 +3569,24 @@ static int arrayRefAndAssignSetup(void)
52 static int beginArrayIter(void)
54 - Symbol *iterator;
55 - DataValue *iteratorValPtr;
56 + DataValue iterator;
57 DataValue arrayVal;
59 DISASM_RT();
60 STACKDUMP(1, 3);
62 - GET_SYM(iterator);
64 POP(arrayVal);
66 - if (iterator->type == LOCAL_SYM) {
67 - iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
68 - }
69 - else {
70 - EXEC_ERROR("bad temporary iterator: %s", iterator->name);
71 - }
73 - iteratorValPtr->tag = INT_TAG;
74 if (arrayVal.tag != ARRAY_TAG) {
75 EXEC_ERROR("can't iterate non-array", NULL);
78 - iteratorValPtr->val.arrayPtr = arrayIterateFirst(&arrayVal);
79 + /* maybe a new ARYITER_TAG */
80 + iterator.tag = NO_TAG;
81 + iterator.val.arrayPtr = arrayIterateFirst(&arrayVal);
83 + PUSH(iterator);
85 return STAT_OK;
88 @@ -3620,10 +3596,10 @@ static int beginArrayIter(void)
89 ** this allows iterators to progress even if you delete any node in the array
90 ** except the item just after the current key
92 -** Before: Prog-> iter, ARRAY_ITER, [withVal], iterVarKey(, iterVarVal), iter, endLoopBranch, next, ...
93 -** TheStack-> [next], ...
94 -** After: Prog-> iter, ARRAY_ITER, withVal, iterVarKey(, iterVarVal), iter, endLoopBranch, [next], ...
95 -** TheStack-> [next], ... (unchanged)
96 +** Before: Prog-> ARRAY_ITER, [withVal], iterVarKey(, iterVarVal), endLoopBranch, next, ...
97 +** TheStack-> [iter], ...
98 +** After: Prog-> ARRAY_ITER, withVal, iterVarKey(, iterVarVal), endLoopBranch, [next], ...
99 +** TheStack-> [iter], ... (unchanged)
100 ** Where:
101 ** iter is a symbol which gives the position of the iterator value in
102 ** the stack frame (set up by OP_BEGIN_ARRAY_ITER); that value refers
103 @@ -3640,10 +3616,9 @@ static int beginArrayIter(void)
105 static int arrayIter(void)
107 - Symbol *iterator;
108 Symbol *keySym;
109 Symbol *valSym;
110 - DataValue *iteratorValPtr;
111 + DataValue iterator;
112 DataValue *keyValPtr;
113 DataValue *valPtr;
114 SparseArrayEntry *thisEntry;
115 @@ -3651,16 +3626,17 @@ static int arrayIter(void)
116 int withVal;
118 DISASM_RT();
119 - STACKDUMP(0, 4);
120 + STACKDUMP(1, 4);
122 GET_IMMED(withVal);
123 GET_SYM(keySym);
124 if (withVal) {
125 GET_SYM(valSym);
127 - GET_SYM(iterator);
128 GET_BRANCH(branchAddr);
130 + POP(iterator);
132 if (keySym->type == LOCAL_SYM) {
133 keyValPtr = &FP_GET_SYM_VAL(FrameP, keySym);
135 @@ -3685,14 +3661,7 @@ static int arrayIter(void)
136 valPtr->tag = NO_TAG;
139 - if (iterator->type == LOCAL_SYM) {
140 - iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
142 - else {
143 - EXEC_ERROR("bad temporary iterator: %s", iterator->name);
146 - thisEntry = iteratorValPtr->val.arrayPtr;
147 + thisEntry = iterator.val.arrayPtr;
148 if (thisEntry && thisEntry->nodePtrs.color != -1) {
149 /* set key */
150 keyValPtr->tag = STRING_TAG;
151 @@ -3705,52 +3674,48 @@ static int arrayIter(void)
154 /* advance iterator */
155 - iteratorValPtr->val.arrayPtr = arrayIterateNext(thisEntry);
156 + iterator.val.arrayPtr = arrayIterateNext(thisEntry);
158 else {
159 JUMP(branchAddr);
162 + PUSH(iterator);
164 return STAT_OK;
168 -** Before: Prog-> [iter], ARRAY_ITER_ARRAY, withVal, keyArraySym(, valSym), iter, endLoopBranch, next, ...
169 +** Before: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
170 ** TheStack-> [arrayVal], nDims, next, ...
171 -** After: Prog-> iter, [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), iter, endLoopBranch, next, ...
172 -** TheStack-> [nDims], next, ...
173 +** After: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
174 +** TheStack-> [iter], nDims, next, ...
176 static int beginArrayIterArray(void)
178 - Symbol *iterator;
179 - DataValue *iteratorValPtr;
180 + DataValue iterator;
181 DataValue arrayVal;
182 int nDims;
184 DISASM_RT();
185 STACKDUMP(2, 3);
187 - GET_SYM(iterator);
189 POP(arrayVal);
190 PEEK_INT(nDims, 0);
192 - if (iterator->type == LOCAL_SYM) {
193 - iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
195 - else {
196 - EXEC_ERROR("bad temporary iterator: %s", iterator->name);
199 if (nDims < 0) {
200 EXEC_ERROR("bad multi dimension", NULL);
203 - iteratorValPtr->tag = INT_TAG;
204 if (arrayVal.tag != ARRAY_TAG) {
205 EXEC_ERROR("can't iterate non-array", NULL);
208 - iteratorValPtr->val.arrayPtr = arrayIterateFirst(&arrayVal);
209 + /* maybe a new ARYITER_TAG */
210 + iterator.tag = NO_TAG;
211 + iterator.val.arrayPtr = arrayIterateFirst(&arrayVal);
213 + PUSH(iterator);
215 return STAT_OK;
217 @@ -3809,17 +3774,16 @@ static Boolean splitKeyIntoArray(const c
221 -** Before: Prog-> iter, ARRAY_ITER_ARRAY, [withVal], keyArraySym, (, valSym), iter, endLoopBranch, next, ...
222 -** TheStack-> [nDims], next, ...
223 -** After: Prog-> iter, ARRAY_ITER_ARRAY, withVal, keyArraySym, (, valSym), iter, endLoopBranch, [next], ...
224 -** TheStack-> [nDims], next, ... (unchanged)
225 +** Before: Prog-> ARRAY_ITER_ARRAY, [withVal], keyArraySym, (, valSym), endLoopBranch, next, ...
226 +** TheStack-> [iter], nDims, next, ...
227 +** After: Prog-> ARRAY_ITER_ARRAY, withVal, keyArraySym, (, valSym), endLoopBranch, [next], ...
228 +** TheStack-> [iter], nDims, next, ... (unchanged)
230 static int arrayIterArray(void)
232 - Symbol *iterator;
233 Symbol *keyArraySym;
234 Symbol *valSym;
235 - DataValue *iteratorValPtr;
236 + DataValue iterator;
237 DataValue *keyArrayPtr;
238 DataValue *valPtr;
239 SparseArrayEntry *thisEntry;
240 @@ -3829,16 +3793,16 @@ static int arrayIterArray(void)
241 Boolean keyFound = False;
243 DISASM_RT();
244 - STACKDUMP(1, 4);
245 + STACKDUMP(2, 4);
247 GET_IMMED(withVal);
248 GET_SYM(keyArraySym);
249 if (withVal) {
250 GET_SYM(valSym);
252 - GET_SYM(iterator);
253 GET_BRANCH(branchAddr);
255 + POP(iterator);
256 PEEK_INT(nDims, 0);
258 if (keyArraySym->type == LOCAL_SYM) {
259 @@ -3866,14 +3830,7 @@ static int arrayIterArray(void)
260 valPtr->tag = NO_TAG;
263 - if (iterator->type == LOCAL_SYM) {
264 - iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
266 - else {
267 - EXEC_ERROR("bad temporary iterator: %s", iterator->name);
270 - thisEntry = iteratorValPtr->val.arrayPtr;
271 + thisEntry = iterator.val.arrayPtr;
272 while (thisEntry && thisEntry->nodePtrs.color != -1) {
274 /* check if this is an nDims key, but only if requested */
275 @@ -3903,12 +3860,14 @@ static int arrayIterArray(void)
276 thisEntry = arrayIterateNext(thisEntry);
277 break;
279 - iteratorValPtr->val.arrayPtr = thisEntry;
280 + iterator.val.arrayPtr = thisEntry;
282 if (!keyFound && (!thisEntry || thisEntry->nodePtrs.color == -1)) {
283 JUMP(branchAddr);
286 + PUSH(iterator);
288 return STAT_OK;
291 @@ -4608,39 +4567,26 @@ static void disasmInternal(Inst *inst, i
293 break;
295 - case OP_BEGIN_ARRAY_ITER:
296 - case OP_BEGIN_ARRAY_ITER_ARRAY:
297 - CHECK_OPERANDS(1, SYM_INST);
298 - printd(" in");
299 - dumpInst(&inst[i+1], "aryIter");
300 - ++i;
301 - break;
303 case OP_ARRAY_ITER:
304 CHECK_OPERANDS(1, IMMED_INST);
305 if (!inst[i+1].val.immed) {
306 /* without val */
307 - CHECK_OPERANDS(4, IMMED_INST,
308 - SYM_INST, SYM_INST, BRANCH_INST);
309 + CHECK_OPERANDS(3, IMMED_INST, SYM_INST, BRANCH_INST);
310 dumpInst(&inst[i+2], "key");
311 - printd(" :=");
312 - dumpInst(&inst[i+3], "aryIter");
313 - printd("++");
314 - dumpInst(&inst[i+4], "end-loop");
315 - i += 4;
316 + printd(" := aryIter++");
317 + dumpInst(&inst[i+3], "end-loop");
318 + i += 3;
320 else {
321 /* with val */
322 - CHECK_OPERANDS(5, IMMED_INST,
323 - SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
324 + CHECK_OPERANDS(4, IMMED_INST,
325 + SYM_INST, SYM_INST, BRANCH_INST);
326 dumpInst(&inst[i+2], "key");
327 printd(" =");
328 dumpInst(&inst[i+3], "val");
329 - printd(" :=");
330 - dumpInst(&inst[i+4], "aryIter");
331 - printd("++");
332 - dumpInst(&inst[i+5], "end-loop");
333 - i += 5;
334 + printd(" := aryIter++");
335 + dumpInst(&inst[i+4], "end-loop");
336 + i += 4;
338 break;
340 @@ -4648,27 +4594,22 @@ static void disasmInternal(Inst *inst, i
341 CHECK_OPERANDS(1, IMMED_INST);
342 if (!inst[i+1].val.immed) {
343 /* without val */
344 - CHECK_OPERANDS(4, IMMED_INST,
345 - SYM_INST, SYM_INST, BRANCH_INST);
346 + CHECK_OPERANDS(3, IMMED_INST, SYM_INST, BRANCH_INST);
347 dumpInst(&inst[i+2], "keyArr");
348 - printd(" :=");
349 - dumpInst(&inst[i+3], "aryIter");
350 - printd("++");
351 - dumpInst(&inst[i+4], "end-loop");
352 - i += 4;
353 + printd(" := aryIter++");
354 + dumpInst(&inst[i+3], "end-loop");
355 + i += 3;
357 else {
358 /* with val */
359 - CHECK_OPERANDS(5, IMMED_INST,
360 - SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
361 + CHECK_OPERANDS(4, IMMED_INST,
362 + SYM_INST, SYM_INST, BRANCH_INST);
363 dumpInst(&inst[i+2], "keyArr");
364 printd("[] =");
365 dumpInst(&inst[i+3], "val");
366 - printd(" :=");
367 - dumpInst(&inst[i+4], "aryIter");
368 - printd("++");
369 - dumpInst(&inst[i+5], "end-loop");
370 - i += 5;
371 + printd(" := aryIter++");
372 + dumpInst(&inst[i+4], "end-loop");
373 + i += 4;
375 break;
377 diff --quilt old/source/parse.y new/source/parse.y
378 --- old/source/parse.y
379 +++ new/source/parse.y
380 @@ -256,71 +256,63 @@ stmt: ';' blank
381 ADD_OP(OP_BRANCH); ADD_BR_OFF($3); SET_BR_OFF($5, GetPC());
383 | for '(' blank SYMBOL IN blank arrayexpr blank ')' {
384 - Symbol *iterSym = InstallIteratorSymbol();
385 ADD_OP(OP_BEGIN_ARRAY_ITER);
386 - ADD_SYM(iterSym);
387 ADD_OP(OP_ARRAY_ITER);
388 ADD_IMMED(0); /* without val symbol */
389 ADD_SYM($4);
390 - ADD_SYM(iterSym);
391 ADD_BR_OFF(0);
393 blank block {
394 ADD_OP(OP_BRANCH);
395 - ADD_BR_OFF($7+2);
396 - SET_BR_OFF($7+6, GetPC());
397 - FillLoopAddrs(GetPC(), $7+2);
398 + ADD_BR_OFF($7+1);
399 + SET_BR_OFF($7+4, GetPC());
400 + FillLoopAddrs(GetPC(), $7+1);
401 + ADD_OP(OP_POP); /* remove iter from stack */
403 | for '(' blank SYMBOL KEYVAL SYMBOL IN blank arrayexpr blank ')' {
404 - Symbol *iterSym = InstallIteratorSymbol();
405 ADD_OP(OP_BEGIN_ARRAY_ITER);
406 - ADD_SYM(iterSym);
407 ADD_OP(OP_ARRAY_ITER);
408 ADD_IMMED(1); /* with val symbol */
409 ADD_SYM($4);
410 ADD_SYM($6);
411 - ADD_SYM(iterSym);
412 ADD_BR_OFF(0);
414 blank block {
415 ADD_OP(OP_BRANCH);
416 - ADD_BR_OFF($9+2);
417 - SET_BR_OFF($9+7, GetPC());
418 - FillLoopAddrs(GetPC(), $9+2);
419 + ADD_BR_OFF($9+1);
420 + SET_BR_OFF($9+5, GetPC());
421 + FillLoopAddrs(GetPC(), $9+1);
422 + ADD_OP(OP_POP); /* remove iter from stack */
424 | for '(' blank SYMBOL '[' numexpropt ']' IN blank arrayexpr blank ')' {
425 - Symbol *iterSym = InstallIteratorSymbol();
426 ADD_OP(OP_BEGIN_ARRAY_ITER_ARRAY);
427 - ADD_SYM(iterSym);
428 ADD_OP(OP_ARRAY_ITER_ARRAY);
429 ADD_IMMED(0); /* without val symbol */
430 ADD_SYM($4);
431 - ADD_SYM(iterSym);
432 ADD_BR_OFF(0);
434 blank block {
435 ADD_OP(OP_BRANCH);
436 - ADD_BR_OFF($10+2);
437 - SET_BR_OFF($10+6, GetPC());
438 - FillLoopAddrs(GetPC(), $10+2);
439 + ADD_BR_OFF($10+1);
440 + SET_BR_OFF($10+4, GetPC());
441 + FillLoopAddrs(GetPC(), $10+1);
442 + ADD_OP(OP_POP); /* remove iter from stack */
443 ADD_OP(OP_POP); /* remove nDim from stack */
445 | for '(' blank SYMBOL '[' numexpropt ']' KEYVAL SYMBOL IN blank arrayexpr blank ')' {
446 - Symbol *iterSym = InstallIteratorSymbol();
447 ADD_OP(OP_BEGIN_ARRAY_ITER_ARRAY);
448 - ADD_SYM(iterSym);
449 ADD_OP(OP_ARRAY_ITER_ARRAY);
450 ADD_IMMED(1); /* with val symbol */
451 ADD_SYM($4);
452 ADD_SYM($9);
453 - ADD_SYM(iterSym);
454 ADD_BR_OFF(0);
456 blank block {
457 ADD_OP(OP_BRANCH);
458 - ADD_BR_OFF($12+2);
459 - SET_BR_OFF($12+7, GetPC());
460 - FillLoopAddrs(GetPC(), $12+2);
461 + ADD_BR_OFF($12+1);
462 + SET_BR_OFF($12+5, GetPC());
463 + FillLoopAddrs(GetPC(), $12+1);
464 + ADD_OP(OP_POP); /* remove iter from stack */
465 ADD_OP(OP_POP); /* remove nDim from stack */
467 | BREAK stmtend blank {
468 diff --quilt old/source/ops.h new/source/ops.h
469 --- old/source/ops.h
470 +++ new/source/ops.h
471 @@ -40,10 +40,10 @@ OP(BRANCH_NEVER, branchNever)
472 OP(ARRAY_REF, arrayRef) /* N */ /* pop(kN..k1,a), push(a[k1..kN]) */
473 OP(ARRAY_ASSIGN, arrayAssign) /* N */ /* pop(v,kN..k1,a), a[k1..kN]=v */
474 OP(ARRAY_ASSIGN_NEXT, arrayAssignNext) /* pop(v, a), a[a.nextidx] = v */
475 -OP(BEGIN_ARRAY_ITER, beginArrayIter) /* it */ /* pop(a), it=a.begin */
476 -OP(ARRAY_ITER, arrayIter) /*w,k[,v],it,pc*/ /* it?(k.v=it.k,(w?v.v=it.v:),it++):PC=pc */
477 -OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIterArray) /*it*/ /* */
478 -OP(ARRAY_ITER_ARRAY, arrayIterArray) /*w,ka[,v],it,pc*/ /* top(N),while it: (if dim(it.k)==N: (ka.v=split(it.k),(w?v.v=it.v:),return),it++), PC=pc */
479 +OP(BEGIN_ARRAY_ITER, beginArrayIter) /* pop(a), it=a.begin, push(it) */
480 +OP(ARRAY_ITER, arrayIter) /*w,k[,v],pc*/ /* it?(k.v=it.k,(w?v.v=it.v:),it++):PC=pc */
481 +OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIterArray) /* pop(a), it=a.begin, push(it) */
482 +OP(ARRAY_ITER_ARRAY, arrayIterArray) /*w,ka[,v],pc*/ /* top(N),while it: (if dim(it.k)==N: (ka.v=split(it.k),(w?v.v=it.v:),return),it++), PC=pc */
483 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
484 OP(ARRAY_DELETE, deleteArrayElement) /*N*/ /* N>0 ? (pop(kN..k1,a), del(a[k])) : (pop(a), delall(a)) */
485 OP(PUSH_ARRAY_SYM, pushArraySymVal) /*s,i*/ /* if i: s.v=ary()), push(s.v) */