3 source/interpret.c | 30 ++++++++++++++++++++++++++++++
5 source/parse.y | 38 ++++++++++++++++++++++++++++++++++++--
6 3 files changed, 67 insertions(+), 2 deletions(-)
8 diff --quilt old/source/parse.y new/source/parse.y
10 +++ new/source/parse.y
11 @@ -96,6 +96,7 @@ static int follow2(char expect1, int yes
12 static int follow_non_whitespace(char expect, int yes, int no);
13 static int eq_look_ahead(void);
14 static int comma_look_ahead(void);
15 +static int te_look_ahead(void);
16 static Symbol *matchesActionRoutine(char **inPtr);
17 static int scanString(void);
19 @@ -134,7 +135,7 @@ static int nextSymIsField = 0;
23 -%type <inst> thenx elsex
24 +%type <inst> thenx elsex thenelsex
28 @@ -142,7 +143,7 @@ static int nextSymIsField = 0;
30 %nonassoc SYMBOL ARG_LOOKUP
31 %right '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
37 @@ -676,6 +677,9 @@ numexpr: '(' blank expr blank ')'
38 SET_BR_OFF($2, $5 + 1); /* thenx limb ends at $5+1 */
39 SET_BR_OFF($5, GetPC()); /* elsex limb ends here */
41 + | numexpr thenelsex blank numexpr %prec '?' {
42 + SET_BR_OFF($2, GetPC());
44 | incrdecr blank SYMBOL %prec INCR {
45 ADD_OP(OP_PUSH_SYM); ADD_SYM($3); ADD_OP($1);
46 ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($3);
47 @@ -738,13 +742,24 @@ or: OR {
51 + ADD_OP(OP_BOOLEANIZE);
52 ADD_OP(OP_BRANCH_FALSE); $$ = GetPC();
57 ADD_OP(OP_BRANCH); $$ = GetPC();
63 + ADD_OP(OP_BOOLEANIZE);
64 + ADD_OP(OP_BRANCH_TRUE); $$ = GetPC();
72 @@ -936,6 +951,7 @@ static int yylex(void)
73 return result; /* but return what we started with */
75 case ',': return comma_look_ahead();
76 + case '?': return te_look_ahead();
77 default: return *(InPtr-1);
80 @@ -1037,6 +1053,24 @@ static int comma_look_ahead(void)
84 +/* look ahead fo ternary operator without second operand, ie ?: */
85 +static int te_look_ahead(void)
87 + char *savedInPtr = InPtr;
89 + /* skip any whitespace */
92 + if (*InPtr == ':') {
103 ** Look (way) ahead for hyphenated routine names which begin at inPtr. A
104 ** hyphenated name is allowed if it is pre-defined in the global symbol
105 diff --quilt old/source/interpret.c new/source/interpret.c
106 --- old/source/interpret.c
107 +++ new/source/interpret.c
108 @@ -2460,6 +2460,36 @@ static int power(void)
109 return errCheck("exponentiation");
112 +static int booleanize(void)
123 + case INT_TAG: res = !!dv.val.n; break;
125 + if (StringToNum(dv.val.str.rep, &res)) {
129 + res = !!dv.val.str.len;
132 + case ARRAY_TAG: res = !!ArraySize(&dv); break;
133 + default: EXEC_ERROR("incompatible type in booleanize context: <%s>",
143 ** A helper routine used in concat(), and makeArrayKeyFromArgs(). Concatenate a
144 ** number of values from the stack and return the result as a character pointer
145 diff --quilt old/source/ops.h new/source/ops.h
148 @@ -30,6 +30,7 @@ OP(BIT_OR, bitOr)
149 OP(AND, and) /* pop(v2,v1), push(v1 && v2) */
150 OP(OR, or) /* pop(v2,v1), push(v1 || v2) */
151 OP(NOT, not) /* pop(v), push(!v) */
152 +OP(BOOLEANIZE, booleanize) /* pop(v), push(!!v) */
153 OP(POWER, power) /* pop(v2,v1), push(v1 ** v2) */
154 OP(CONCAT, concat) /* pop(s2,s1), push(s1 s2) */
155 OP(ASSIGN, assign) /* sym */ /* pop(v), sym.v = v */