3 source/interpret.c | 488 +++++++++++++++++++++++++++++------------------------
5 source/parse.y | 33 +++
6 3 files changed, 317 insertions(+), 219 deletions(-)
8 diff --quilt old/source/macro.c new/source/macro.c
10 +++ new/source/macro.c
11 @@ -112,8 +112,19 @@ static const char CVSID[] = "$Id: macro.
13 /* The following definitions cause an exit from the macro with a message */
14 /* added if (1) to remove compiler warnings on solaris */
15 -#define M_FAILURE(s) do { *errMsg = s; if (1) return False; } while (0)
16 -#define M_STR_ALLOC_ASSERT(xDV) do { if (xDV.tag == STRING_TAG && !xDV.val.str.rep) { *errMsg = "Failed to allocate value: %s"; return(False); } } while (0)
17 +#define M_FAILURE(s) \
23 +#define M_STR_ALLOC_ASSERT(xDV) \
25 + if (xDV.tag == STRING_TAG && !xDV.val.str.rep) { \
26 + *errMsg = "Failed to allocate value: %s"; \
30 #define M_ARRAY_INSERT_FAILURE() M_FAILURE("array element failed to insert: %s")
32 /* Data attached to window during shell command execution with
33 diff --quilt old/source/parse.y new/source/parse.y
34 --- old/source/parse.y
35 +++ new/source/parse.y
39 /* Macros to add error processing to AddOp and AddSym calls */
40 -#define ADD_OP(op) if (!AddOp(op, &ErrMsg)) return 1
41 -#define ADD_SYM(sym) if (!AddSym(sym, &ErrMsg)) return 1
42 -#define ADD_IMMED(val) if (!AddImmediate(val, &ErrMsg)) return 1
43 -#define ADD_BR_OFF(to) if (!AddBranchOffset(to, &ErrMsg)) return 1
44 -#define SET_BR_OFF(from, to) ((from)->value) = ((Inst *)(to)) - ((Inst *)(from))
47 + if (!AddOp(op, &ErrMsg)) { \
51 +#define ADD_SYM(sym) \
53 + if (!AddSym(sym, &ErrMsg)) { \
57 +#define ADD_IMMED(val) \
59 + if (!AddImmediate(val, &ErrMsg)) { \
63 +#define ADD_BR_OFF(to) \
65 + if (!AddBranchOffset(to, &ErrMsg)) { \
69 +#define SET_BR_OFF(from, to) \
71 + ((from)->value) = ((Inst *)(to)) - ((Inst *)(from)); \
74 /* Max. length for a string constant (... there shouldn't be a maximum) */
75 #define MAX_STRING_CONST_LEN 5000
76 diff --quilt old/source/interpret.c new/source/interpret.c
77 --- old/source/interpret.c
78 +++ new/source/interpret.c
79 @@ -68,7 +68,7 @@ static const char CVSID[] = "$Id: interp
81 #define PROGRAM_SIZE 4096 /* Maximum program size */
82 #define MAX_ERR_MSG_LEN 256 /* Max. length for error messages */
83 -#define LOOP_STACK_SIZE 200 /* (Approx.) Number of break/continue stmts
84 +#define LOOP_STACK_SIZE 256 /* (Approx.) Number of break/continue stmts
85 allowed per program */
86 #define INSTRUCTION_LIMIT 100 /* Number of instructions the interpreter is
87 allowed to execute before preempting and
88 @@ -211,7 +211,7 @@ static SparseArrayEntryWrapper *Allocate
89 the macros are used */
90 static const char *StackOverflowMsg = "macro stack overflow";
91 static const char *StackUnderflowMsg = "macro stack underflow";
92 -static const char *StringToNumberMsg = "string could not be converted to number";
93 +static const char *StringToNumberMsg = "string '%s' could not be converted to number";
95 /* Temporary global data for use while accumulating programs */
96 static Symbol *LocalSymList = NULL; /* symbols local to the program */
97 @@ -273,12 +273,39 @@ static int (*OpFns[N_OPS])() = {returnNo
98 #define FP_GET_SYM_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN))
99 #define FP_GET_SYM_VAL(xFrameP,xSym) (FP_GET_SYM_N(xFrameP, xSym->value.val.n))
101 -#define PUSH_CHECK_TOO_MUCH(n) \
102 - (StackP + (n) > &TheStack[STACK_SIZE])
103 +/* true, if you can pop n values */
104 +#define OK_TO_POP(n) \
105 + ((StackP - (n)) >= TheStack)
107 +#define POP_CHECK(n) \
109 + if (!OK_TO_POP(n)) { \
110 + return execError(StackUnderflowMsg, ""); \
114 +/* true, if you can push n values */
115 +#define OK_TO_PUSH(n) \
116 + (StackP + (n) <= &TheStack[STACK_SIZE])
118 #define PUSH_CHECK(n) \
119 - if (PUSH_CHECK_TOO_MUCH(n)) \
120 - return execError(StackOverflowMsg, "");
122 + if (!OK_TO_PUSH(n)) { \
123 + return execError(StackOverflowMsg, ""); \
127 +#define PEEK_CHECK(n) \
129 + if (!OK_TO_POP((n) + 1)) { \
130 + return execError(StackUnderflowMsg, ""); \
132 + if (!OK_TO_PUSH(-(n))) { \
133 + return execError(StackOverflowMsg, ""); \
137 +static const char *tagToStr(enum typeTags tag);
140 ** Initialize macro language global variables. Must be called before
141 @@ -493,7 +520,7 @@ int AddContinueAddr(Inst *addr)
143 static void addLoopAddr(Inst *addr)
145 - if (LoopStackPtr > &LoopStack[LOOP_STACK_SIZE-1]) {
146 + if (LoopStackPtr >= &LoopStack[LOOP_STACK_SIZE]) {
147 fprintf(stderr, "NEdit: loop stack overflow in macro parser");
150 @@ -665,7 +692,7 @@ void RunMacroAsSubrCall(Program *prog)
152 /* See subroutine "callSubroutine" for a description of the stack frame
153 for a subroutine call */
154 - /* if (PUSH_CHECK_TOO_MUCH(4)) return MACRO_ERROR; */
155 + /* if (!OK_TO_PUSH(4)) return MACRO_ERROR; */
157 *(StackP++) = noValue; /* cached arg array */
159 @@ -693,7 +720,7 @@ void RunMacroAsSubrCall(Program *prog)
162 for (s = prog->localSymList; s != NULL; s = s->next) {
163 - /* if (PUSH_CHECK_TOO_MUCH(1)) return MACRO_ERROR; */
164 + /* if (!OK_TO_PUSH(1)) return MACRO_ERROR; */
165 FP_GET_SYM_VAL(FrameP, s) = noValue;
168 @@ -1232,95 +1259,118 @@ static void freeSymbolTable(Symbol *symT
171 #define POP(dataVal) \
172 - if (StackP == TheStack) \
173 - return execError(StackUnderflowMsg, ""); \
174 - dataVal = *--StackP;
177 + dataVal = *--StackP; \
180 #define PUSH(dataVal) \
181 - if (StackP >= &TheStack[STACK_SIZE]) \
182 - return execError(StackOverflowMsg, ""); \
183 - *StackP++ = dataVal;
186 + *StackP++ = dataVal; \
189 #define PEEK(dataVal, peekIndex) \
190 - dataVal = *(StackP - peekIndex - 1);
192 + PEEK_CHECK(peekIndex); \
193 + dataVal = *(StackP - peekIndex - 1); \
196 +#define TO_INT(dataVal, number) \
199 + if (dataVal.tag == INT_TAG) { \
200 + __int = dataVal.val.n; \
201 + } else if (dataVal.tag == STRING_TAG) { \
202 + if (!StringToNum(dataVal.val.str.rep, &__int)) {\
203 + return execError(StringToNumberMsg, dataVal.val.str.rep); \
206 + return(execError("incompatible type in integer context: %s", \
207 + tagToStr(dataVal.tag))); \
212 +#define TO_STRING(dataVal, string) \
215 + if (dataVal.tag == STRING_TAG) { \
216 + __str = dataVal.val.str.rep; \
217 + } else if (dataVal.tag == INT_TAG) { \
218 + __str = AllocStringOfNumber(dataVal.val.n); \
220 + return(execError("incompatible type in string context: %s", \
221 + tagToStr(dataVal.tag))); \
226 #define POP_INT(number) \
227 - if (StackP == TheStack) \
228 - return execError(StackUnderflowMsg, ""); \
230 - if (StackP->tag == STRING_TAG) { \
231 - if (!StringToNum(StackP->val.str.rep, &number)) \
232 - return execError(StringToNumberMsg, ""); \
233 - } else if (StackP->tag == INT_TAG) \
234 - number = StackP->val.n; \
236 - return(execError("can't convert array to integer", NULL));
240 + TO_INT(dv, number); \
243 #define POP_STRING(string) \
244 - if (StackP == TheStack) \
245 - return execError(StackUnderflowMsg, ""); \
247 - if (StackP->tag == INT_TAG) { \
248 - string = AllocStringOfNumber(StackP->val.n); \
249 - } else if (StackP->tag == STRING_TAG) \
250 - string = StackP->val.str.rep; \
252 - return(execError("can't convert array to string", NULL));
254 -#define PEEK_STRING(string, peekIndex) \
255 - if ((StackP - peekIndex - 1)->tag == INT_TAG) { \
256 - string = AllocStringOfNumber((StackP - peekIndex - 1)->val.n); \
258 - else if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \
259 - string = (StackP - peekIndex - 1)->val.str.rep; \
262 - return(execError("can't convert array to string", NULL)); \
267 + TO_STRING(dv, string); \
270 #define PEEK_INT(number, peekIndex) \
271 - if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \
272 - if (!StringToNum((StackP - peekIndex - 1)->val.str.rep, &number)) { \
273 - return execError(StringToNumberMsg, ""); \
275 - } else if ((StackP - peekIndex - 1)->tag == INT_TAG) { \
276 - number = (StackP - peekIndex - 1)->val.n; \
279 - return(execError("can't convert array to string", NULL)); \
283 + PEEK(dv, peekIndex); \
284 + TO_INT(dv, number); \
287 +#define PEEK_STRING(string, peekIndex) \
291 + TO_STRING(dv, string); \
294 #define PUSH_INT(number) \
295 - if (StackP >= &TheStack[STACK_SIZE]) \
296 - return execError(StackOverflowMsg, ""); \
297 - StackP->tag = INT_TAG; \
298 - StackP->val.n = number; \
303 + dv.tag = INT_TAG; \
304 + dv.val.n = (number); \
308 #define PUSH_STRING(string, length) \
309 - if (StackP >= &TheStack[STACK_SIZE]) \
310 - return execError(StackOverflowMsg, ""); \
311 - StackP->tag = STRING_TAG; \
312 - StackP->val.str.rep = string; \
313 - StackP->val.str.len = length; \
317 + dv.tag = STRING_TAG; \
318 + dv.val.str.rep = string; \
319 + dv.val.str.len = length; \
323 #define BINARY_NUMERIC_OPERATION(operator) \
325 - DISASM_RT(PC-1, 1); \
329 - PUSH_INT(n1 operator n2) \
333 + DISASM_RT(PC-1, 1); \
337 + PUSH_INT(n1 operator n2); \
341 #define UNARY_NUMERIC_OPERATION(operator) \
343 - DISASM_RT(PC-1, 1); \
346 - PUSH_INT(operator n) \
350 + DISASM_RT(PC-1, 1); \
353 + PUSH_INT(operator n); \
358 ** copy a symbol's value onto the stack
359 @@ -1370,7 +1420,7 @@ static int pushSymVal(void)
360 return execError("variable not set: %s", s->name);
368 @@ -1382,7 +1432,7 @@ static int pushArgVal(void)
375 nArgs = FP_GET_ARG_COUNT(FrameP);
376 if (argNum >= nArgs || argNum < 0) {
377 @@ -1458,13 +1508,11 @@ static int pushArraySymVal(void)
380 if (sym->type == LOCAL_SYM) {
381 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
383 - else if (sym->type == GLOBAL_SYM) {
384 - dataPtr = &sym->value;
387 - return execError("assigning to non-lvalue array or non-array: %s", sym->name);
388 + dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
389 + } else if (sym->type == GLOBAL_SYM) {
390 + dataPtr = &sym->value;
392 + return execError("assigning to non-lvalue array or non-array: %s", sym->name);
395 if (initEmpty && dataPtr->tag == NO_TAG) {
396 @@ -1476,7 +1524,7 @@ static int pushArraySymVal(void)
397 return execError("variable not set: %s", sym->name);
405 @@ -1502,10 +1550,10 @@ static int anonArrayOpen(void)
406 dataVal.val.arrayPtr = ArrayNew();
408 /* push the default next index value first */
412 /* and the empty array */
418 @@ -1528,15 +1576,15 @@ static int anonArraySkip(void)
425 + POP_INT(nextIndex);
427 /* we need to increment the index for next time */
430 /* push the default next index value first, then the array */
431 - PUSH_INT(nextIndex)
433 + PUSH_INT(nextIndex);
438 @@ -1560,9 +1608,9 @@ static int anonArrayNextVal(void)
447 + POP_INT(nextIndex);
449 sprintf(numString, "%d", nextIndex);
450 if (!ArrayInsert(&anonArray, AllocStringCpy(numString), &exprVal)) {
451 @@ -1573,8 +1621,8 @@ static int anonArrayNextVal(void)
454 /* push the default next index value first, then the array */
455 - PUSH_INT(nextIndex)
457 + PUSH_INT(nextIndex);
462 @@ -1600,7 +1648,7 @@ static int anonArrayIndexVal(void)
464 STACKDUMP(nDim+3, 3);
469 /* the next nDim stack entries form the index */
470 errNum = makeArrayKeyFromArgs(nDim, &keyString, 0);
471 @@ -1608,8 +1656,8 @@ static int anonArrayIndexVal(void)
478 + POP_INT(nextIndex);
480 /* if our index is numeric (or can be converted to a number) we must
481 change the next index value */
482 @@ -1622,8 +1670,8 @@ static int anonArrayIndexVal(void)
485 /* push the default next index value first, then the array */
486 - PUSH_INT(nextIndex)
488 + PUSH_INT(nextIndex);
493 @@ -1646,10 +1694,10 @@ static int anonArrayClose(void)
496 /* remove top two elements */
501 /* put back the array content */
507 @@ -1692,12 +1740,13 @@ static int namedArg1orN(Boolean isFirst)
508 DataValue exprVal, argsArray;
511 - nDim = (PC++)->value;
516 STACKDUMP(nDim + (isFirst ? 2 : 1), 3);
521 /* the next nDim stack entries form the index */
522 errNum = makeArrayKeyFromArgs(nDim, &keyString, 0);
523 @@ -1718,7 +1767,7 @@ static int namedArg1orN(Boolean isFirst)
526 /* use the array at the top of the stack */
531 if (!ArrayInsert(&argsArray, keyString, &exprVal)) {
532 @@ -1726,7 +1775,7 @@ static int namedArg1orN(Boolean isFirst)
535 /* and (re)push the array */
541 @@ -1741,10 +1790,10 @@ static int swapTop2(void)
556 @@ -1788,7 +1837,7 @@ static int assign(void)
557 dataPtr = &sym->value;
563 if (value.tag == ARRAY_TAG) {
564 ArrayCopy(dataPtr, &value);
565 @@ -1829,7 +1878,7 @@ static int arrayIndex(void)
566 keyData.val.str.rep = keyString;
567 keyData.val.str.len = strlen(keyString);
574 @@ -1846,8 +1895,8 @@ static int dupStack(void)
585 @@ -1868,16 +1917,16 @@ static int add(void)
591 if (rightVal.tag == ARRAY_TAG) {
594 if (leftVal.tag == ARRAY_TAG) {
595 SparseArrayEntry *leftIter, *rightIter;
596 resultArray.tag = ARRAY_TAG;
597 resultArray.val.arrayPtr = ArrayNew();
603 leftIter = arrayIterateFirst(&leftVal);
604 rightIter = arrayIterateFirst(&rightVal);
605 while (leftIter || rightIter) {
606 @@ -1911,16 +1960,16 @@ static int add(void)
607 return(execError("array insertion failure", NULL));
614 return(execError("can't mix math with arrays and non-arrays", NULL));
627 @@ -1940,16 +1989,16 @@ static int subtract(void)
633 if (rightVal.tag == ARRAY_TAG) {
636 if (leftVal.tag == ARRAY_TAG) {
637 SparseArrayEntry *leftIter, *rightIter;
638 resultArray.tag = ARRAY_TAG;
639 resultArray.val.arrayPtr = ArrayNew();
645 leftIter = arrayIterateFirst(&leftVal);
646 rightIter = arrayIterateFirst(&rightVal);
648 @@ -1977,16 +2026,16 @@ static int subtract(void)
649 return(execError("array insertion failure", NULL));
656 return(execError("can't mix math with arrays and non-arrays", NULL));
669 @@ -2002,7 +2051,7 @@ static int subtract(void)
671 static int multiply(void)
673 - BINARY_NUMERIC_OPERATION(*)
674 + BINARY_NUMERIC_OPERATION(*);
677 static int divide(void)
678 @@ -2012,12 +2061,12 @@ static int divide(void)
687 return execError("division by zero", "");
694 @@ -2028,48 +2077,48 @@ static int modulo(void)
703 return execError("modulo by zero", "");
710 static int negate(void)
712 - UNARY_NUMERIC_OPERATION(-)
713 + UNARY_NUMERIC_OPERATION(-);
716 static int increment(void)
718 - UNARY_NUMERIC_OPERATION(++)
719 + UNARY_NUMERIC_OPERATION(++);
722 static int decrement(void)
724 - UNARY_NUMERIC_OPERATION(--)
725 + UNARY_NUMERIC_OPERATION(--);
730 - BINARY_NUMERIC_OPERATION(>)
731 + BINARY_NUMERIC_OPERATION(>);
736 - BINARY_NUMERIC_OPERATION(<)
737 + BINARY_NUMERIC_OPERATION(<);
742 - BINARY_NUMERIC_OPERATION(>=)
743 + BINARY_NUMERIC_OPERATION(>=);
748 - BINARY_NUMERIC_OPERATION(<=)
749 + BINARY_NUMERIC_OPERATION(<=);
753 @@ -2085,8 +2134,8 @@ static int eq(void)
761 if (v1.tag == INT_TAG && v2.tag == INT_TAG) {
762 v1.val.n = v1.val.n == v2.val.n;
764 @@ -2115,7 +2164,7 @@ static int eq(void)
765 return(execError("incompatible types to compare", NULL));
773 @@ -2141,16 +2190,16 @@ static int bitAnd(void)
779 if (rightVal.tag == ARRAY_TAG) {
782 if (leftVal.tag == ARRAY_TAG) {
783 SparseArrayEntry *leftIter, *rightIter;
784 resultArray.tag = ARRAY_TAG;
785 resultArray.val.arrayPtr = ArrayNew();
791 leftIter = arrayIterateFirst(&leftVal);
792 rightIter = arrayIterateFirst(&rightVal);
793 while (leftIter && rightIter) {
794 @@ -2172,16 +2221,16 @@ static int bitAnd(void)
795 return(execError("array insertion failure", NULL));
802 return(execError("can't mix math with arrays and non-arrays", NULL));
815 @@ -2201,16 +2250,16 @@ static int bitOr(void)
821 if (rightVal.tag == ARRAY_TAG) {
824 if (leftVal.tag == ARRAY_TAG) {
825 SparseArrayEntry *leftIter, *rightIter;
826 resultArray.tag = ARRAY_TAG;
827 resultArray.val.arrayPtr = ArrayNew();
833 leftIter = arrayIterateFirst(&leftVal);
834 rightIter = arrayIterateFirst(&rightVal);
835 while (leftIter || rightIter) {
836 @@ -2243,33 +2292,33 @@ static int bitOr(void)
837 return(execError("array insertion failure", NULL));
844 return(execError("can't mix math with arrays and non-arrays", NULL));
860 - BINARY_NUMERIC_OPERATION(&&)
861 + BINARY_NUMERIC_OPERATION(&&);
866 - BINARY_NUMERIC_OPERATION(||)
867 + BINARY_NUMERIC_OPERATION(||);
872 - UNARY_NUMERIC_OPERATION(!)
873 + UNARY_NUMERIC_OPERATION(!);
877 @@ -2284,8 +2333,8 @@ static int power(void)
885 /* We need to round to deal with pow() giving results slightly above
886 or below the real result since it deals with floating point numbers.
887 Note: We're not really wanting rounded results, we merely
888 @@ -2313,7 +2362,7 @@ static int power(void)
889 n3 = (int)(pow((double)n1, (double)n2) + (double)0.5);
894 return errCheck("exponentiation");
897 @@ -2345,7 +2394,7 @@ static int concatenateNwithSep(int nVals
898 /* evaluate total length (upper limit) */
899 len = sepLen * (nVals - 1);
900 for (i = nVals - 1; i >= 0; --i) {
903 if (value.tag == INT_TAG) {
904 len += lenLongAsStr(value.val.n);
906 @@ -2362,7 +2411,7 @@ static int concatenateNwithSep(int nVals
908 /* write everything into the result */
909 for (i = nVals - 1; i >= 0; --i) {
912 if (value.tag == INT_TAG) {
913 pos += strlen(strcpy(pos, longAsStr(value.val.n)));
915 @@ -2379,7 +2428,7 @@ static int concatenateNwithSep(int nVals
916 /* remove the source expression values */
924 @@ -2413,7 +2462,7 @@ static int concat(void)
926 return(execError("can only concatenate with string or integer", NULL));
928 - PUSH_STRING(out, len)
929 + PUSH_STRING(out, len);
933 @@ -2462,7 +2511,7 @@ static int callSubroutineFromSymbol(Symb
936 if (!haveNamedArgs) {
937 - PUSH(noValue) /* push dummy named arg array */
938 + PUSH(noValue); /* push dummy named arg array */
941 /* "pop" stack back to the first argument in the call stack */
942 @@ -2488,7 +2537,7 @@ static int callSubroutineFromSymbol(Symb
943 ** values which are already there.
945 if (sym->type == MACRO_FUNCTION_SYM) {
946 - PUSH_CHECK(3 + !haveNamedArgs)
947 + PUSH_CHECK(3 + !haveNamedArgs);
949 prog = sym->value.val.prog;
951 @@ -2519,7 +2568,7 @@ static int callSubroutineFromSymbol(Symb
954 for (s = prog->localSymList; s != NULL; s = s->next) {
957 FP_GET_SYM_VAL(FrameP, s) = noValue;
960 @@ -2560,7 +2609,7 @@ static int callSubroutineFromSymbol(Symb
962 /* pop arguments off the stack and put them in the argument list */
963 for (i=nArgs-1; i>=0; i--) {
964 - POP_STRING(argList[i])
965 + POP_STRING(argList[i]);
968 /* Call the action routine and check for preemption */
969 @@ -2619,11 +2668,11 @@ static int callSubroutineStackedN(void)
974 + PEEK_INT(nArgs, 0);
976 STACKDUMP(-nArgs + 1, 3); /* +1 for stacked nArgs */
983 @@ -2720,7 +2769,7 @@ static int unpackArrayToArgs(void)
990 if (dvEntry.tag != ARRAY_TAG) {
991 return execError("argument array call made with non-array value", NULL);
992 @@ -2737,10 +2786,10 @@ static int unpackArrayToArgs(void)
994 /* remove them from remaining array */
995 ArrayDelete(&dvArray, ind);
1006 @@ -2856,7 +2905,7 @@ static int branchIf(Boolean trueOrFalse)
1012 addr = PC + PC->value;
1015 @@ -3155,12 +3204,12 @@ static int arrayRef(void)
1021 if (srcArray.tag == ARRAY_TAG) {
1022 if (!ArrayGet(&srcArray, keyString, &valueItem)) {
1023 return(execError("referenced array value not in array: %s", keyString));
1030 @@ -3168,9 +3217,9 @@ static int arrayRef(void)
1036 if (srcArray.tag == ARRAY_TAG) {
1037 - PUSH_INT(ArraySize(&srcArray))
1038 + PUSH_INT(ArraySize(&srcArray));
1042 @@ -3201,14 +3250,14 @@ static int arrayAssign(void)
1043 STACKDUMP(nDim+2, 3);
1049 errNum = makeArrayKeyFromArgs(nDim, &keyString, 0);
1050 if (errNum != STAT_OK) {
1057 if (dstArray.tag != ARRAY_TAG && dstArray.tag != NO_TAG) {
1058 return(execError("cannot assign array element of non-array", NULL));
1059 @@ -3256,7 +3305,7 @@ static int arrayRefAndAssignSetup(void)
1060 STACKDUMP(nDim + (binaryOp ? 2 : 1), 3);
1068 @@ -3265,14 +3314,14 @@ static int arrayRefAndAssignSetup(void)
1072 - PEEK(srcArray, nDim)
1073 + PEEK(srcArray, nDim);
1074 if (srcArray.tag == ARRAY_TAG) {
1075 if (!ArrayGet(&srcArray, keyString, &valueItem)) {
1076 return(execError("referenced array value not in array: %s", keyString));
1086 @@ -3309,7 +3358,7 @@ static int beginArrayIter(void)
1093 if (iterator->type == LOCAL_SYM) {
1094 iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
1095 @@ -3641,8 +3690,8 @@ static int beginArrayMultiIterArray(void
1100 - PEEK_INT(nDims, 0)
1102 + PEEK_INT(nDims, 0);
1104 if (iterator->type == LOCAL_SYM) {
1105 iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
1106 @@ -3850,15 +3899,15 @@ static int inArray(void)
1112 if (theArray.tag != ARRAY_TAG) {
1113 return(execError("operator in on non-array", NULL));
1115 - PEEK(leftArray, 0)
1116 + PEEK(leftArray, 0);
1117 if (leftArray.tag == ARRAY_TAG) {
1118 SparseArrayEntry *iter;
1123 iter = arrayIterateFirst(&leftArray);
1124 while (inResult && iter) {
1125 @@ -3867,12 +3916,12 @@ static int inArray(void)
1129 - POP_STRING(keyStr)
1130 + POP_STRING(keyStr);
1131 if (ArrayGet(&theArray, keyStr, &theValue)) {
1135 - PUSH_INT(inResult)
1136 + PUSH_INT(inResult);
1140 @@ -3906,7 +3955,7 @@ static int deleteArrayElement(void)
1146 if (theArray.tag == ARRAY_TAG) {
1148 ArrayDelete(&theArray, keyString);
1149 @@ -3943,7 +3992,7 @@ static int typeOfOut(void)
1156 retVal.tag = STRING_TAG;
1158 @@ -4101,6 +4150,21 @@ int StringToNum(const char *string, int
1162 +static const char *tagToStr(enum typeTags tag)
1166 + return "<integer>";
1168 + return "<string>";
1173 + return "<no value>";
1177 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
1178 static char *printdBuffer = NULL;
1179 static int printdPos = 0;