ttyname: use precomputed lengths
[nedit-bw.git] / ARYITER_TAG.patch
blob19552d11cf7a85b955ba16e45657df14a236973c
1 ---
3 source/interpret.c | 120 +++++++++++++++++++++++++++++++++--------------------
4 source/interpret.h | 9 +++
5 source/ops.h | 1
6 source/parse.y | 12 +++--
7 4 files changed, 93 insertions(+), 49 deletions(-)
9 diff --quilt old/source/interpret.c new/source/interpret.c
10 --- old/source/interpret.c
11 +++ new/source/interpret.c
12 @@ -569,8 +569,15 @@ static void rewindFrame(RestartData *con
13 Symbol *symList = FP_GET_SYM_TAB(context->frameP);
14 int isNestedFrame = prog->nested;
16 - /* pop past local variables */
17 - context->stackP = context->frameP;
18 + /* pop remaining vars on the stack and free any array iterators */
19 + while (context->stackP != context->frameP) {
20 + --context->stackP;
21 + if (context->stackP->tag == ARYITER_TAG) {
22 + XtFree((char *)context->stackP->val.aryiter);
23 + context->stackP->tag = NO_TAG;
24 + }
25 + }
27 /* pop past arguments */
28 context->stackP -= (FP_TO_ARGS_DIST + nArgs);
30 @@ -3611,34 +3618,40 @@ static int arrayRefAndAssignSetup(void)
34 -** setup symbol values for array iteration in interpreter
36 -** Before: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
37 -** TheStack-> [arrayVal], next, ...
38 -** After: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
39 -** TheStack-> [iter], next, ...
40 -** Where:
41 -** iter is a symbol which gives the position of the iterator value in
42 -** the stack frame
43 -** arrayVal is the data value holding the array in question
45 -static int beginArrayIter(void)
46 +static int beginArrayIterCheckDim(int checkDim)
48 DataValue iterator;
49 DataValue arrayVal;
50 + int errNum;
52 DISASM_RT();
53 - STACKDUMP(1, 3);
54 + STACKDUMP(1 + !!checkDim, 3);
56 POP(arrayVal);
59 + if (checkDim) {
60 + int nDims;
61 + PEEK_INT(nDims, 0);
63 + if (nDims < 0) {
64 + EXEC_ERROR("bad multi dimension", NULL);
65 + }
66 + }
68 if (arrayVal.tag != ARRAY_TAG) {
69 EXEC_ERROR("can't iterate non-array", NULL);
72 - /* maybe a new ARYITER_TAG */
73 - iterator.tag = NO_TAG;
74 - iterator.val.arrayPtr = arrayIterateFirst(&arrayVal);
75 + iterator.tag = ARYITER_TAG;
76 + iterator.val.aryiter = XtNew(SparseAryiter);
77 + errNum = ArrayCopy(&iterator.val.aryiter->array, &arrayVal);
78 + if (errNum != STAT_OK) {
79 + XtFree((char *)iterator.val.aryiter);
80 + return errNum;
81 + }
82 + iterator.val.aryiter->next = arrayIterateFirst(&iterator.val.aryiter->array);
84 PUSH(iterator);
86 @@ -3646,6 +3659,23 @@ static int beginArrayIter(void)
90 +** setup symbol values for array iteration in interpreter
91 +**
92 +** Before: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
93 +** TheStack-> [arrayVal], next, ...
94 +** After: Prog-> [ARRAY_ITER], withVal, iterVarKey(, iterVarVal), endLoopBranch, next, ...
95 +** TheStack-> [iter], next, ...
96 +** Where:
97 +** iter is a symbol which gives the position of the iterator value in
98 +** the stack frame
99 +** arrayVal is the data value holding the array in question
101 +static int beginArrayIter(void)
103 + return beginArrayIterCheckDim(False);
107 ** copy key and value to symbols if node is still valid, marked bad by a color
108 ** of -1 then move iterator to next node
109 ** this allows iterators to progress even if you delete any node in the array
110 @@ -3706,7 +3736,7 @@ static int arrayIter(void)
111 valPtr->tag = NO_TAG;
114 - thisEntry = iterator.val.arrayPtr;
115 + thisEntry = iterator.val.aryiter->next;
116 if (thisEntry && thisEntry->nodePtrs.color != -1) {
117 /* set key */
118 keyValPtr->tag = STRING_TAG;
119 @@ -3719,7 +3749,7 @@ static int arrayIter(void)
122 /* advance iterator */
123 - iterator.val.arrayPtr = arrayIterateNext(thisEntry);
124 + iterator.val.aryiter->next = arrayIterateNext(thisEntry);
126 else {
127 JUMP(branchAddr);
128 @@ -3730,41 +3760,35 @@ static int arrayIter(void)
129 return STAT_OK;
133 -** Before: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
134 -** TheStack-> [arrayVal], nDims, next, ...
135 -** After: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
136 -** TheStack-> [iter], nDims, next, ...
138 -static int beginArrayIterArray(void)
139 +static int endArrayIter(void)
141 DataValue iterator;
142 - DataValue arrayVal;
143 - int nDims;
145 DISASM_RT();
146 - STACKDUMP(2, 3);
148 - POP(arrayVal);
149 - PEEK_INT(nDims, 0);
150 + STACKDUMP(1, 3);
152 - if (nDims < 0) {
153 - EXEC_ERROR("bad multi dimension", NULL);
155 + POP(iterator);
157 - if (arrayVal.tag != ARRAY_TAG) {
158 - EXEC_ERROR("can't iterate non-array", NULL);
159 + if (iterator.tag != ARYITER_TAG) {
160 + EXEC_ERROR("array iterator expected", NULL);
163 - /* maybe a new ARYITER_TAG */
164 - iterator.tag = NO_TAG;
165 - iterator.val.arrayPtr = arrayIterateFirst(&arrayVal);
167 - PUSH(iterator);
168 + XtFree((char *)iterator.val.aryiter);
170 return STAT_OK;
174 +** Before: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
175 +** TheStack-> [arrayVal], nDims, next, ...
176 +** After: Prog-> [ARRAY_ITER_ARRAY], withVal, keyArraySym(, valSym), endLoopBranch, next, ...
177 +** TheStack-> [iter], nDims, next, ...
179 +static int beginArrayIterArray(void)
181 + return beginArrayIterCheckDim(True);
184 static int countDim(const char *key)
186 int nDims = 0;
187 @@ -3865,7 +3889,7 @@ static int arrayIterArray(void)
188 valPtr->tag = NO_TAG;
191 - thisEntry = iterator.val.arrayPtr;
192 + thisEntry = iterator.val.aryiter->next;
193 while (thisEntry && thisEntry->nodePtrs.color != -1) {
195 /* check if this is an nDims key, but only if requested */
196 @@ -3895,7 +3919,7 @@ static int arrayIterArray(void)
197 thisEntry = arrayIterateNext(thisEntry);
198 break;
200 - iterator.val.arrayPtr = thisEntry;
201 + iterator.val.aryiter->next = thisEntry;
203 if (!keyFound && (!thisEntry || thisEntry->nodePtrs.color == -1)) {
204 JUMP(branchAddr);
205 @@ -4539,6 +4563,8 @@ static const char *tagToStr(enum typeTag
206 return "string";
207 case ARRAY_TAG:
208 return "array";
209 + case ARYITER_TAG:
210 + return "aryiter";
211 case NO_TAG:
212 default:
213 return "no value";
214 @@ -4697,6 +4723,12 @@ static void dumpVal(DataValue dv)
215 printd(" <%s %u:%p>", tagToStr(ARRAY_TAG), ArraySize(&dv),
216 dv.val.arrayPtr);
217 break;
218 + case ARYITER_TAG:
219 + printd(" <%s %p[%s]>", tagToStr(ARYITER_TAG),
220 + dv.val.aryiter->array.val.arrayPtr,
221 + dv.val.aryiter->next ? dv.val.aryiter->next->key
222 + : "");
223 + break;
224 case NO_TAG:
225 if (!*(void **)&dv.val) {
226 printd(" <%s>", tagToStr(NO_TAG));
227 diff --quilt old/source/interpret.h new/source/interpret.h
228 --- old/source/interpret.h
229 +++ new/source/interpret.h
230 @@ -56,7 +56,7 @@ enum operations {
231 /* C_FUNCTION_SYM -> BUILT_IN_SUBR_TAG */
232 /* PROC_VALUE_SYM -> BUILT_IN_VAR_TAG */
233 /* ACTION_ROUTINE_SYM -> ACTION_SUBR_TAG */
234 -enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG, ARG_VAR_TAG,
235 +enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG, ARYITER_TAG, ARG_VAR_TAG,
236 BUILT_IN_VAR_TAG, BUILT_IN_SUBR_TAG, MACRO_SUBR_TAG,
237 ACTION_SUBR_TAG};
239 @@ -68,6 +68,7 @@ enum instTypes {NO_INST, OP_INST, IMMED_
241 struct DataValueTag;
242 struct SparseArrayEntryTag;
243 +struct SparseAryiterTag;
244 struct ProgramTag;
245 struct SymbolRec;
247 @@ -101,6 +102,7 @@ typedef struct DataValueTag {
248 Inst **instp;
249 struct DataValueTag* dataval;
250 struct SparseArrayEntryTag *arrayPtr;
251 + struct SparseAryiterTag *aryiter;
252 struct SymbolRec *sym;
253 } val;
254 } DataValue;
255 @@ -111,6 +113,11 @@ typedef struct SparseArrayEntryTag {
256 DataValue value;
257 } SparseArrayEntry;
259 +typedef struct SparseAryiterTag {
260 + DataValue array;
261 + SparseArrayEntry *next;
262 +} SparseAryiter;
264 /* symbol table entry */
265 typedef struct SymbolRec {
266 const char *name;
267 diff --quilt old/source/ops.h new/source/ops.h
268 --- old/source/ops.h
269 +++ new/source/ops.h
270 @@ -47,6 +47,7 @@ OP(ARRAY_ASSIGN, arrayAssign)
271 OP(ARRAY_ASSIGN_NEXT, arrayAssignNext) /* pop(v, a), a[a.nextidx] = v */
272 OP(BEGIN_ARRAY_ITER, beginArrayIter) /* pop(a), it=a.begin, push(it) */
273 OP(ARRAY_ITER, arrayIter) /*w,k[,v],pc*/ /* it?(k.v=it.k,(w?v.v=it.v:),it++):PC=pc */
274 +OP(END_ARRAY_ITER, endArrayIter) /* pop(it) */
275 OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIterArray) /* pop(a), it=a.begin, push(it) */
276 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 */
277 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
278 diff --quilt old/source/parse.y new/source/parse.y
279 --- old/source/parse.y
280 +++ new/source/parse.y
281 @@ -414,7 +414,8 @@ loops: while '(' mark cond ')' bl
282 SwapCode($10, here, GetPC());
283 END_LOOP($1, $10 + 4, $10 + 1);
284 /* remove iter from stack */
285 - ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
286 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
287 + ADD_OP(OP_END_ARRAY_ITER);
289 | for '(' blank SYMBOL KEYVAL SYMBOL IN
290 blank numexpr blank ')' mark blank block {
291 @@ -428,7 +429,8 @@ loops: while '(' mark cond ')' bl
292 SwapCode($12, here, GetPC());
293 END_LOOP($1, $12 + 5, $12 + 1);
294 /* remove iter from stack */
295 - ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
296 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
297 + ADD_OP(OP_END_ARRAY_ITER);
300 | for '(' blank SYMBOL '[' numexpropt ']' IN
301 @@ -442,7 +444,8 @@ loops: while '(' mark cond ')' bl
302 SwapCode($13, here, GetPC());
303 END_LOOP($1, $13 + 4, $13 + 1);
304 /* remove iter from stack */
305 - ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
306 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
307 + ADD_OP(OP_END_ARRAY_ITER);
308 /* remove nDim from stack */
309 ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
311 @@ -458,7 +461,8 @@ loops: while '(' mark cond ')' bl
312 SwapCode($15, here, GetPC());
313 END_LOOP($1, $15 + 5, $15 + 1);
314 /* remove iter from stack */
315 - ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
316 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
317 + ADD_OP(OP_END_ARRAY_ITER);
318 /* remove nDim from stack */
319 ADD_OP(OP_PEEK_POP); ADD_IMMED(2);