1 Subject: interpret.c: macro cleanup
3 Use 'do { } while (0)' syntax for macros and consolidate num/string conversion.
7 source/interpret.c | 410 +++++++++++++++++++++++++++++++----------------------
8 1 file changed, 241 insertions(+), 169 deletions(-)
10 diff --quilt old/source/interpret.c new/source/interpret.c
11 --- old/source/interpret.c
12 +++ new/source/interpret.c
13 @@ -136,6 +136,8 @@ static int arrayEntryCompare(rbTreeNode
14 static void arrayDisposeNode(rbTreeNode *src);
15 static SparseArrayEntry *allocateSparseArrayEntry(void);
17 +static const char *tagToStr(enum typeTags tag);
19 /*#define DEBUG_ASSEMBLY*/
20 /*#define DEBUG_STACK*/
22 @@ -177,7 +179,7 @@ static SparseArrayEntryWrapper *Allocate
23 the macros are used */
24 static const char *StackOverflowMsg = "macro stack overflow";
25 static const char *StackUnderflowMsg = "macro stack underflow";
26 -static const char *StringToNumberMsg = "string could not be converted to number";
27 +static const char *StringToNumberMsg = "string '%s' could not be converted to number";
29 /* Temporary global data for use while accumulating programs */
30 static Symbol *LocalSymList = NULL; /* symbols local to the program */
31 @@ -1128,98 +1130,152 @@ static void freeSymbolTable(Symbol *symT
35 +/* true, if you can pop n values */
36 +#define OK_TO_POP(n) \
37 + ((StackP - (n)) >= TheStack)
39 +#define POP_CHECK(n) \
41 + if (!OK_TO_POP(n)) { \
42 + return execError(StackUnderflowMsg, ""); \
46 +/* true, if you can push n values */
47 +#define OK_TO_PUSH(n) \
48 + (StackP + (n) <= &TheStack[STACK_SIZE])
50 + #define PUSH_CHECK(n) \
52 + if (!OK_TO_PUSH(n)) { \
53 + return execError(StackOverflowMsg, ""); \
57 +#define PEEK_CHECK(n) \
59 + if (!OK_TO_POP((n) + 1)) { \
60 + return execError(StackUnderflowMsg, ""); \
62 + if (!OK_TO_PUSH(-(n))) { \
63 + return execError(StackOverflowMsg, ""); \
67 #define POP(dataVal) \
68 - if (StackP == TheStack) \
69 - return execError(StackUnderflowMsg, ""); \
70 - dataVal = *--StackP;
73 + dataVal = *--StackP; \
76 #define PUSH(dataVal) \
77 - if (StackP >= &TheStack[STACK_SIZE]) \
78 - return execError(StackOverflowMsg, ""); \
79 - *StackP++ = dataVal;
82 + *StackP++ = dataVal; \
85 #define PEEK(dataVal, peekIndex) \
86 - dataVal = *(StackP - peekIndex - 1);
88 + PEEK_CHECK(peekIndex); \
89 + dataVal = *(StackP - peekIndex - 1); \
92 +#define TO_INT(dataVal, number) \
95 + if (dataVal.tag == INT_TAG) { \
96 + __int = dataVal.val.n; \
97 + } else if (dataVal.tag == STRING_TAG) { \
98 + if (!StringToNum(dataVal.val.str.rep, &__int)) {\
99 + return execError(StringToNumberMsg, dataVal.val.str.rep); \
102 + return execError("incompatible type in integer context: <%s>", \
103 + tagToStr(dataVal.tag)); \
108 +#define TO_STRING(dataVal, string) \
111 + if (dataVal.tag == STRING_TAG) { \
112 + __str = dataVal.val.str.rep; \
113 + } else if (dataVal.tag == INT_TAG) { \
114 + __str = AllocString(TYPE_INT_STR_SIZE(int)); \
115 + sprintf(__str, "%d", dataVal.val.n); \
117 + return execError("incompatible type in string context: <%s>", \
118 + tagToStr(dataVal.tag)); \
123 #define POP_INT(number) \
124 - if (StackP == TheStack) \
125 - return execError(StackUnderflowMsg, ""); \
127 - if (StackP->tag == STRING_TAG) { \
128 - if (!StringToNum(StackP->val.str.rep, &number)) \
129 - return execError(StringToNumberMsg, ""); \
130 - } else if (StackP->tag == INT_TAG) \
131 - number = StackP->val.n; \
133 - return(execError("can't convert array to integer", NULL));
137 + TO_INT(dv, number); \
140 #define POP_STRING(string) \
141 - if (StackP == TheStack) \
142 - return execError(StackUnderflowMsg, ""); \
144 - if (StackP->tag == INT_TAG) { \
145 - string = AllocString(TYPE_INT_STR_SIZE(int)); \
146 - sprintf(string, "%d", StackP->val.n); \
147 - } else if (StackP->tag == STRING_TAG) \
148 - string = StackP->val.str.rep; \
150 - return(execError("can't convert array to string", NULL));
152 -#define PEEK_STRING(string, peekIndex) \
153 - if ((StackP - peekIndex - 1)->tag == INT_TAG) { \
154 - string = AllocString(TYPE_INT_STR_SIZE(int)); \
155 - sprintf(string, "%d", (StackP - peekIndex - 1)->val.n); \
157 - else if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \
158 - string = (StackP - peekIndex - 1)->val.str.rep; \
161 - return(execError("can't convert array to string", NULL)); \
166 + TO_STRING(dv, string); \
169 #define PEEK_INT(number, peekIndex) \
170 - if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \
171 - if (!StringToNum((StackP - peekIndex - 1)->val.str.rep, &number)) { \
172 - return execError(StringToNumberMsg, ""); \
174 - } else if ((StackP - peekIndex - 1)->tag == INT_TAG) { \
175 - number = (StackP - peekIndex - 1)->val.n; \
178 - return(execError("can't convert array to string", NULL)); \
182 + PEEK(dv, peekIndex); \
183 + TO_INT(dv, number); \
186 +#define PEEK_STRING(string, peekIndex) \
190 + TO_STRING(dv, string); \
193 #define PUSH_INT(number) \
194 - if (StackP >= &TheStack[STACK_SIZE]) \
195 - return execError(StackOverflowMsg, ""); \
196 - StackP->tag = INT_TAG; \
197 - StackP->val.n = number; \
202 + dv.tag = INT_TAG; \
203 + dv.val.n = (number); \
207 #define PUSH_STRING(string, length) \
208 - if (StackP >= &TheStack[STACK_SIZE]) \
209 - return execError(StackOverflowMsg, ""); \
210 - StackP->tag = STRING_TAG; \
211 - StackP->val.str.rep = string; \
212 - StackP->val.str.len = length; \
216 + dv.tag = STRING_TAG; \
217 + dv.val.str.rep = (string); \
218 + dv.val.str.len = (length); \
222 #define BINARY_NUMERIC_OPERATION(operator) \
224 - DISASM_RT(PC-1, 1); \
228 - PUSH_INT(n1 operator n2) \
232 + DISASM_RT(PC-1, 1); \
236 + PUSH_INT(n1 operator n2); \
240 #define UNARY_NUMERIC_OPERATION(operator) \
242 - DISASM_RT(PC-1, 1); \
245 - PUSH_INT(operator n) \
249 + DISASM_RT(PC-1, 1); \
252 + PUSH_INT(operator n); \
257 ** copy a symbol's value onto the stack
258 @@ -1269,7 +1325,7 @@ static int pushSymVal(void)
259 return execError("variable not set: %s", s->name);
267 @@ -1281,7 +1337,7 @@ static int pushArgVal(void)
274 nArgs = FP_GET_ARG_COUNT(FrameP);
275 if (argNum >= nArgs || argNum < 0) {
276 @@ -1372,7 +1428,7 @@ static int pushArraySymVal(void)
277 return execError("variable not set: %s", sym->name);
285 @@ -1416,7 +1472,7 @@ static int assign(void)
286 dataPtr = &sym->value;
292 if (value.tag == ARRAY_TAG) {
293 ArrayCopy(dataPtr, &value);
294 @@ -1439,8 +1495,8 @@ static int dupStack(void)
305 @@ -1461,16 +1517,16 @@ static int add(void)
311 if (rightVal.tag == ARRAY_TAG) {
314 if (leftVal.tag == ARRAY_TAG) {
315 SparseArrayEntry *leftIter, *rightIter;
316 resultArray.tag = ARRAY_TAG;
317 resultArray.val.arrayPtr = ArrayNew();
323 leftIter = arrayIterateFirst(&leftVal);
324 rightIter = arrayIterateFirst(&rightVal);
325 while (leftIter || rightIter) {
326 @@ -1504,16 +1560,16 @@ static int add(void)
327 return(execError("array insertion failure", NULL));
334 return(execError("can't mix math with arrays and non-arrays", NULL));
347 @@ -1533,16 +1589,16 @@ static int subtract(void)
353 if (rightVal.tag == ARRAY_TAG) {
356 if (leftVal.tag == ARRAY_TAG) {
357 SparseArrayEntry *leftIter, *rightIter;
358 resultArray.tag = ARRAY_TAG;
359 resultArray.val.arrayPtr = ArrayNew();
365 leftIter = arrayIterateFirst(&leftVal);
366 rightIter = arrayIterateFirst(&rightVal);
368 @@ -1570,16 +1626,16 @@ static int subtract(void)
369 return(execError("array insertion failure", NULL));
376 return(execError("can't mix math with arrays and non-arrays", NULL));
389 @@ -1595,7 +1651,7 @@ static int subtract(void)
391 static int multiply(void)
393 - BINARY_NUMERIC_OPERATION(*)
394 + BINARY_NUMERIC_OPERATION(*);
397 static int divide(void)
398 @@ -1605,12 +1661,12 @@ static int divide(void)
407 return execError("division by zero", "");
414 @@ -1621,48 +1677,48 @@ static int modulo(void)
423 return execError("modulo by zero", "");
430 static int negate(void)
432 - UNARY_NUMERIC_OPERATION(-)
433 + UNARY_NUMERIC_OPERATION(-);
436 static int increment(void)
438 - UNARY_NUMERIC_OPERATION(++)
439 + UNARY_NUMERIC_OPERATION(++);
442 static int decrement(void)
444 - UNARY_NUMERIC_OPERATION(--)
445 + UNARY_NUMERIC_OPERATION(--);
450 - BINARY_NUMERIC_OPERATION(>)
451 + BINARY_NUMERIC_OPERATION(>);
456 - BINARY_NUMERIC_OPERATION(<)
457 + BINARY_NUMERIC_OPERATION(<);
462 - BINARY_NUMERIC_OPERATION(>=)
463 + BINARY_NUMERIC_OPERATION(>=);
468 - BINARY_NUMERIC_OPERATION(<=)
469 + BINARY_NUMERIC_OPERATION(<=);
473 @@ -1678,8 +1734,8 @@ static int eq(void)
481 if (v1.tag == INT_TAG && v2.tag == INT_TAG) {
482 v1.val.n = v1.val.n == v2.val.n;
484 @@ -1708,7 +1764,7 @@ static int eq(void)
485 return(execError("incompatible types to compare", NULL));
493 @@ -1734,16 +1790,16 @@ static int bitAnd(void)
499 if (rightVal.tag == ARRAY_TAG) {
502 if (leftVal.tag == ARRAY_TAG) {
503 SparseArrayEntry *leftIter, *rightIter;
504 resultArray.tag = ARRAY_TAG;
505 resultArray.val.arrayPtr = ArrayNew();
511 leftIter = arrayIterateFirst(&leftVal);
512 rightIter = arrayIterateFirst(&rightVal);
513 while (leftIter && rightIter) {
514 @@ -1765,16 +1821,16 @@ static int bitAnd(void)
515 return(execError("array insertion failure", NULL));
522 return(execError("can't mix math with arrays and non-arrays", NULL));
535 @@ -1794,16 +1850,16 @@ static int bitOr(void)
541 if (rightVal.tag == ARRAY_TAG) {
544 if (leftVal.tag == ARRAY_TAG) {
545 SparseArrayEntry *leftIter, *rightIter;
546 resultArray.tag = ARRAY_TAG;
547 resultArray.val.arrayPtr = ArrayNew();
553 leftIter = arrayIterateFirst(&leftVal);
554 rightIter = arrayIterateFirst(&rightVal);
555 while (leftIter || rightIter) {
556 @@ -1836,33 +1892,33 @@ static int bitOr(void)
557 return(execError("array insertion failure", NULL));
564 return(execError("can't mix math with arrays and non-arrays", NULL));
580 - BINARY_NUMERIC_OPERATION(&&)
581 + BINARY_NUMERIC_OPERATION(&&);
586 - BINARY_NUMERIC_OPERATION(||)
587 + BINARY_NUMERIC_OPERATION(||);
592 - UNARY_NUMERIC_OPERATION(!)
593 + UNARY_NUMERIC_OPERATION(!);
597 @@ -1877,8 +1933,8 @@ static int power(void)
605 /* We need to round to deal with pow() giving results slightly above
606 or below the real result since it deals with floating point numbers.
607 Note: We're not really wanting rounded results, we merely
608 @@ -1906,7 +1962,7 @@ static int power(void)
609 n3 = (int)(pow((double)n1, (double)n2) + (double)0.5);
614 return errCheck("exponentiation");
617 @@ -1923,14 +1979,14 @@ static int concat(void)
627 out = AllocString(len1 + len2 + 1);
628 strncpy(out, s1, len1);
629 strcpy(&out[len1], s2);
630 - PUSH_STRING(out, len1 + len2)
631 + PUSH_STRING(out, len1 + len2);
635 @@ -1985,7 +2041,7 @@ static int callSubroutine(void)
636 if (result.tag == NO_TAG) {
637 return execError("%s does not return a value", sym->name);
643 return PreemptRequest ? STAT_PREEMPT : STAT_OK;
644 @@ -2035,7 +2091,7 @@ static int callSubroutine(void)
645 argList = (String *)XtCalloc(nArgs, sizeof(*argList));
646 /* pop arguments off the stack and put them in the argument list */
647 for (i=nArgs-1; i>=0; i--) {
648 - POP_STRING(argList[i])
649 + POP_STRING(argList[i]);
652 /* Call the action routine and check for preemption */
653 @@ -2090,7 +2146,7 @@ static int returnValOrNone(int valOnStac
655 /* return value is on the stack */
661 PC = rewindFrame(&FrameP, &StackP);
662 @@ -2098,13 +2154,13 @@ static int returnValOrNone(int valOnStac
663 /* push returned value, if requsted */
672 } else if (PC->func == fetchRetVal) {
679 @@ -2148,7 +2204,7 @@ static int branchTrue(void)
685 addr = PC + PC->value;
688 @@ -2164,7 +2220,7 @@ static int branchFalse(void)
694 addr = PC + PC->value;
697 @@ -2243,7 +2299,7 @@ static int makeArrayKeyFromArgs(int nArg
699 keyLength = sepLen * (nArgs - 1);
700 for (i = nArgs - 1; i >= 0; --i) {
703 if (tmpVal.tag == INT_TAG) {
704 keyLength += TYPE_INT_STR_SIZE(tmpVal.val.n);
706 @@ -2260,7 +2316,7 @@ static int makeArrayKeyFromArgs(int nArg
707 if (i != nArgs - 1) {
708 strcat(*keyString, ARRAY_DIM_SEP);
712 if (tmpVal.tag == INT_TAG) {
713 sprintf(&((*keyString)[strlen(*keyString)]), "%d", tmpVal.val.n);
715 @@ -2273,7 +2329,7 @@ static int makeArrayKeyFromArgs(int nArg
718 for (i = nArgs - 1; i >= 0; --i) {
724 @@ -2497,12 +2553,12 @@ static int arrayRef(void)
730 if (srcArray.tag == ARRAY_TAG) {
731 if (!ArrayGet(&srcArray, keyString, &valueItem)) {
732 return(execError("referenced array value not in array: %s", keyString));
739 @@ -2510,9 +2566,9 @@ static int arrayRef(void)
745 if (srcArray.tag == ARRAY_TAG) {
746 - PUSH_INT(ArraySize(&srcArray))
747 + PUSH_INT(ArraySize(&srcArray));
751 @@ -2543,14 +2599,14 @@ static int arrayAssign(void)
758 errNum = makeArrayKeyFromArgs(nDim, &keyString, 0);
759 if (errNum != STAT_OK) {
766 if (dstArray.tag != ARRAY_TAG && dstArray.tag != NO_TAG) {
767 return(execError("cannot assign array element of non-array", NULL));
768 @@ -2598,7 +2654,7 @@ static int arrayRefAndAssignSetup(void)
769 STACKDUMP(nDim + 1, 3);
777 @@ -2607,14 +2663,14 @@ static int arrayRefAndAssignSetup(void)
781 - PEEK(srcArray, nDim)
782 + PEEK(srcArray, nDim);
783 if (srcArray.tag == ARRAY_TAG) {
784 if (!ArrayGet(&srcArray, keyString, &valueItem)) {
785 return(execError("referenced array value not in array: %s", keyString));
795 @@ -2651,7 +2707,7 @@ static int beginArrayIter(void)
802 if (iterator->type == LOCAL_SYM) {
803 iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
804 @@ -2763,15 +2819,15 @@ static int inArray(void)
810 if (theArray.tag != ARRAY_TAG) {
811 return(execError("operator in on non-array", NULL));
814 + PEEK(leftArray, 0);
815 if (leftArray.tag == ARRAY_TAG) {
816 SparseArrayEntry *iter;
821 iter = arrayIterateFirst(&leftArray);
822 while (inResult && iter) {
823 @@ -2780,12 +2836,12 @@ static int inArray(void)
828 + POP_STRING(keyStr);
829 if (ArrayGet(&theArray, keyStr, &theValue)) {
834 + PUSH_INT(inResult);
838 @@ -2819,7 +2875,7 @@ static int deleteArrayElement(void)
844 if (theArray.tag == ARRAY_TAG) {
846 ArrayDelete(&theArray, keyString);
847 @@ -2891,6 +2947,22 @@ int StringToNum(const char *string, int
852 +static const char *tagToStr(enum typeTags tag)
867 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
868 static void dumpVal(DataValue dv)
870 @@ -2917,11 +2989,11 @@ static void dumpVal(DataValue dv)
875 + printf("<%s>", tagToStr(ARRAY_TAG));
879 - printf("<no value>");
880 + printf("<%s>", tagToStr(NO_TAG));
883 printf("?%8p", dv.val.inst);