[Forensics-changes] [yara] 265/407: Add new instructions for working with doubles.
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:28:33 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.3.0
in repository yara.
commit 86d991e105b74f50636fef8152f0fc021033432b
Author: Wesley Shields <wxs at atarininja.org>
Date: Mon Dec 29 14:02:30 2014 -0500
Add new instructions for working with doubles.
---
libyara/exec.c | 132 ++++++++-
libyara/grammar.c | 696 +++++++++++++++++++++++++++++++++-----------
libyara/grammar.y | 509 +++++++++++++++++++++++++++-----
libyara/include/yara/exec.h | 11 +
4 files changed, 1094 insertions(+), 254 deletions(-)
diff --git a/libyara/exec.c b/libyara/exec.c
index 2e5f6c4..03ab59b 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -43,9 +43,57 @@ limitations under the License.
} while(0)
+// Used when pushing a double to the stack, which looses precision when
+// using push().
+#define push_dbl(x) \
+ do { \
+ if (sp < STACK_SIZE) \
+ { \
+ dsp = (double*) (stack + sp); \
+ *dsp = (x); \
+ sp++; \
+ } \
+ else return ERROR_EXEC_STACK_OVERFLOW; \
+ } while(0)
+
+
#define pop(x) x = stack[--sp]
+#define pop_dbl(x) x = *(double*) &stack[--sp]
+
+
+// The _rel() variants are used to push or pop at specific offsets from sp.
+// This is useful when you need have a stack with an integer that needs to be
+// converted to a double at stack[0] and a double at stack[1]. In this case
+// sp would be 2, so you can do:
+//
+// pop_rel(2, r1)
+// push_dbl_rel(2, r1)
+#define push_rel(offset, x) \
+ do { \
+ if (offset <= 0 || sp - offset < 0) return ERROR_EXEC_STACK_OVERFLOW; \
+ else stack[sp - offset] = (x); \
+ } while(0)
+
+
+#define push_dbl_rel(offset, x) \
+ do { \
+ if (offset <= 0 || sp - offset < 0) return ERROR_EXEC_STACK_OVERFLOW; \
+ else \
+ { \
+ dsp = (double *) ((stack + sp) - offset); \
+ *dsp = (x); \
+ } \
+ } while(0)
+
+#define pop_rel(offset, x) \
+ do { \
+ if (offset < 0 || sp - offset < 0) return ERROR_EXEC_STACK_OVERFLOW; \
+ else x = stack[sp - offset]; \
+ } while(0)
+
+
#define little_endian_uint8_t(x) (x)
#define little_endian_uint16_t(x) (x)
#define little_endian_uint32_t(x) (x)
@@ -112,8 +160,11 @@ int yr_execute_code(
int64_t r1;
int64_t r2;
int64_t r3;
+ double dr1;
+ double dr2;
int64_t mem[MEM_SIZE];
int64_t stack[STACK_SIZE];
+ double* dsp = 0;
int64_t args[MAX_FUNCTION_ARGS];
int32_t sp = 0;
uint8_t* ip = rules->code_start;
@@ -499,7 +550,7 @@ int yr_execute_code(
break;
case OBJECT_TYPE_DOUBLE:
- push(((YR_OBJECT_DOUBLE*) object)->value);
+ push_dbl(((YR_OBJECT_DOUBLE*) object)->value);
break;
case OBJECT_TYPE_STRING:
@@ -864,6 +915,85 @@ int yr_execute_code(
push(result >= 0);
break;
+ case OP_ITD:
+ r1 = *(uint64_t*)(ip + 1);
+ ip += sizeof(uint64_t);
+
+ pop_rel(r1, r2);
+
+ if (IS_UNDEFINED(r2))
+ {
+ push(UNDEFINED);
+ }
+ else
+ {
+ push_dbl_rel(r1, r2);
+ }
+ break;
+
+ // Double comparisons do not use push_dbl because the result is just
+ // an integer.
+ case OP_LTD:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(<, dr1, dr2));
+ break;
+
+ case OP_GTD:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(>, dr1, dr2));
+ break;
+
+ case OP_LED:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(<=, dr1, dr2));
+ break;
+
+ case OP_GED:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(>=, dr1, dr2));
+ break;
+
+ case OP_EQD:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(==, dr1, dr2));
+ break;
+
+ case OP_NEQD:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push(COMPARISON(!=, dr1, dr2));
+ break;
+
+ // Double operations do use push_dbl because the result is a double.
+ case OP_ADD_DBL:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push_dbl(OPERATION(+, dr1, dr2));
+ break;
+
+ case OP_SUB_DBL:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push_dbl(OPERATION(-, dr1, dr2));
+ break;
+
+ case OP_MUL_DBL:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push_dbl(OPERATION(*, dr1, dr2));
+ break;
+
+ case OP_DIV_DBL:
+ pop_dbl(dr2);
+ pop_dbl(dr1);
+ push_dbl(OPERATION(/, dr1, dr2));
+ break;
+
default:
// Unknown instruction, this shouldn't happen.
assert(FALSE);
diff --git a/libyara/grammar.c b/libyara/grammar.c
index 1494f21..22f3e3c 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -640,12 +640,12 @@ static const yytype_uint16 yyrline[] =
488, 493, 507, 506, 525, 542, 543, 548, 549, 550,
551, 556, 644, 692, 752, 799, 802, 827, 863, 908,
925, 934, 943, 958, 972, 986, 1002, 1017, 1052, 1016,
- 1166, 1165, 1244, 1250, 1256, 1262, 1270, 1288, 1306, 1324,
- 1342, 1369, 1396, 1423, 1427, 1435, 1436, 1441, 1463, 1475,
- 1491, 1490, 1496, 1505, 1506, 1511, 1516, 1525, 1526, 1530,
- 1538, 1542, 1552, 1565, 1581, 1591, 1601, 1624, 1639, 1654,
- 1676, 1718, 1728, 1738, 1748, 1758, 1768, 1778, 1788, 1798,
- 1808, 1818, 1828
+ 1166, 1165, 1244, 1250, 1256, 1262, 1270, 1324, 1377, 1431,
+ 1485, 1543, 1571, 1629, 1633, 1641, 1642, 1647, 1669, 1681,
+ 1697, 1696, 1702, 1711, 1712, 1717, 1722, 1731, 1732, 1736,
+ 1744, 1748, 1758, 1771, 1787, 1797, 1807, 1830, 1845, 1860,
+ 1882, 1924, 1970, 2016, 2062, 2108, 2118, 2128, 2138, 2148,
+ 2158, 2168, 2178
};
#endif
@@ -2840,125 +2840,300 @@ yyreduce:
case 66:
#line 1271 "grammar.y" /* yacc.c:1661 */
{
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_DOUBLE))
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- CLEANUP("<", (yyvsp[-2].expression));
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for < operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LTD, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_DOUBLE))
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
{
- CLEANUP("<", (yyvsp[0].expression));
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LT, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LTD, NULL);
+ }
+ else
+ {
+ CLEANUP("<", (yyvsp[-2].expression));
}
- TYPE_INEQUALITY((yyvsp[-2].expression), (yyvsp[0].expression), "<")
- yr_parser_emit(yyscanner, OP_LT, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2860 "grammar.c" /* yacc.c:1661 */
+#line 2896 "grammar.c" /* yacc.c:1661 */
break;
case 67:
-#line 1289 "grammar.y" /* yacc.c:1661 */
+#line 1325 "grammar.y" /* yacc.c:1661 */
{
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_DOUBLE))
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- CLEANUP(">", (yyvsp[-2].expression));
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for > operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GTD, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_DOUBLE))
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
{
- CLEANUP(">", (yyvsp[0].expression));
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GT, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GTD, NULL);
+ }
+ else
+ {
+ CLEANUP(">", (yyvsp[-2].expression));
}
- TYPE_INEQUALITY((yyvsp[-2].expression), (yyvsp[0].expression), ">")
-
- yr_parser_emit(yyscanner, OP_GT, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2882 "grammar.c" /* yacc.c:1661 */
+#line 2953 "grammar.c" /* yacc.c:1661 */
break;
case 68:
-#line 1307 "grammar.y" /* yacc.c:1661 */
+#line 1378 "grammar.y" /* yacc.c:1661 */
{
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_DOUBLE))
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- CLEANUP("<=", (yyvsp[-2].expression));
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for <= operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LED, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LE, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_DOUBLE))
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
{
- CLEANUP("<=", (yyvsp[0].expression));
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LED, NULL);
+ }
+ else
+ {
+ CLEANUP("<=", (yyvsp[-2].expression));
}
- TYPE_INEQUALITY((yyvsp[-2].expression), (yyvsp[0].expression), "<=")
- yr_parser_emit(yyscanner, OP_LE, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2904 "grammar.c" /* yacc.c:1661 */
+#line 3011 "grammar.c" /* yacc.c:1661 */
break;
case 69:
-#line 1325 "grammar.y" /* yacc.c:1661 */
+#line 1432 "grammar.y" /* yacc.c:1661 */
{
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[-2].expression), EXPRESSION_TYPE_DOUBLE))
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- CLEANUP(">=", (yyvsp[-2].expression));
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for >= operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GED, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GE, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GED, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP((yyvsp[0].expression), EXPRESSION_TYPE_DOUBLE))
+ else
{
- CLEANUP(">=", (yyvsp[0].expression));
+ CLEANUP(">=", (yyvsp[-2].expression));
}
- TYPE_INEQUALITY((yyvsp[-2].expression), (yyvsp[0].expression), ">=")
- yr_parser_emit(yyscanner, OP_GE, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2926 "grammar.c" /* yacc.c:1661 */
+#line 3069 "grammar.c" /* yacc.c:1661 */
break;
case 70:
-#line 1343 "grammar.y" /* yacc.c:1661 */
+#line 1486 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- yr_compiler_set_error_extra_info(
- compiler, "mismatching types for == operator");
- compiler->last_result = ERROR_WRONG_TYPE;
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for == operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQD, NULL);
}
else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_STRING)
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_STR_EQ,
- NULL);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_STR_EQ, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQ, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQD, NULL);
}
else
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_EQ,
- NULL);
+ CLEANUP("==", (yyvsp[-2].expression));
}
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2957 "grammar.c" /* yacc.c:1661 */
+#line 3131 "grammar.c" /* yacc.c:1661 */
break;
case 71:
-#line 1370 "grammar.y" /* yacc.c:1661 */
+#line 1544 "grammar.y" /* yacc.c:1661 */
{
+ // XXX: What is _IS_? Dead code?
if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
yr_compiler_set_error_extra_info(
@@ -2984,70 +3159,101 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 2988 "grammar.c" /* yacc.c:1661 */
+#line 3163 "grammar.c" /* yacc.c:1661 */
break;
case 72:
-#line 1397 "grammar.y" /* yacc.c:1661 */
+#line 1572 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
{
- yr_compiler_set_error_extra_info(
- compiler, "mismatching types for != operator");
- compiler->last_result = ERROR_WRONG_TYPE;
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for != operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQD, NULL);
}
else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_STRING)
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_STR_NEQ,
- NULL);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_STR_NEQ, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQ, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQD, NULL);
}
else
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_NEQ,
- NULL);
+ CLEANUP("!=", (yyvsp[-2].expression));
}
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
(yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
-#line 3019 "grammar.c" /* yacc.c:1661 */
+#line 3225 "grammar.c" /* yacc.c:1661 */
break;
case 73:
-#line 1424 "grammar.y" /* yacc.c:1661 */
+#line 1630 "grammar.y" /* yacc.c:1661 */
{
(yyval.expression) = (yyvsp[0].expression);
}
-#line 3027 "grammar.c" /* yacc.c:1661 */
+#line 3233 "grammar.c" /* yacc.c:1661 */
break;
case 74:
-#line 1428 "grammar.y" /* yacc.c:1661 */
+#line 1634 "grammar.y" /* yacc.c:1661 */
{
(yyval.expression) = (yyvsp[-1].expression);
}
-#line 3035 "grammar.c" /* yacc.c:1661 */
+#line 3241 "grammar.c" /* yacc.c:1661 */
break;
case 75:
-#line 1435 "grammar.y" /* yacc.c:1661 */
+#line 1641 "grammar.y" /* yacc.c:1661 */
{ (yyval.integer) = INTEGER_SET_ENUMERATION; }
-#line 3041 "grammar.c" /* yacc.c:1661 */
+#line 3247 "grammar.c" /* yacc.c:1661 */
break;
case 76:
-#line 1436 "grammar.y" /* yacc.c:1661 */
+#line 1642 "grammar.y" /* yacc.c:1661 */
{ (yyval.integer) = INTEGER_SET_RANGE; }
-#line 3047 "grammar.c" /* yacc.c:1661 */
+#line 3253 "grammar.c" /* yacc.c:1661 */
break;
case 77:
-#line 1442 "grammar.y" /* yacc.c:1661 */
+#line 1648 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[-4].expression).type != EXPRESSION_TYPE_INTEGER)
{
@@ -3065,11 +3271,11 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-#line 3069 "grammar.c" /* yacc.c:1661 */
+#line 3275 "grammar.c" /* yacc.c:1661 */
break;
case 78:
-#line 1464 "grammar.y" /* yacc.c:1661 */
+#line 1670 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
{
@@ -3081,11 +3287,11 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-#line 3085 "grammar.c" /* yacc.c:1661 */
+#line 3291 "grammar.c" /* yacc.c:1661 */
break;
case 79:
-#line 1476 "grammar.y" /* yacc.c:1661 */
+#line 1682 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
{
@@ -3096,71 +3302,71 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-#line 3100 "grammar.c" /* yacc.c:1661 */
+#line 3306 "grammar.c" /* yacc.c:1661 */
break;
case 80:
-#line 1491 "grammar.y" /* yacc.c:1661 */
+#line 1697 "grammar.y" /* yacc.c:1661 */
{
// Push end-of-list marker
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
}
-#line 3109 "grammar.c" /* yacc.c:1661 */
+#line 3315 "grammar.c" /* yacc.c:1661 */
break;
case 82:
-#line 1497 "grammar.y" /* yacc.c:1661 */
+#line 1703 "grammar.y" /* yacc.c:1661 */
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
yr_parser_emit_pushes_for_strings(yyscanner, "$*");
}
-#line 3118 "grammar.c" /* yacc.c:1661 */
+#line 3324 "grammar.c" /* yacc.c:1661 */
break;
case 85:
-#line 1512 "grammar.y" /* yacc.c:1661 */
+#line 1718 "grammar.y" /* yacc.c:1661 */
{
yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
yr_free((yyvsp[0].c_string));
}
-#line 3127 "grammar.c" /* yacc.c:1661 */
+#line 3333 "grammar.c" /* yacc.c:1661 */
break;
case 86:
-#line 1517 "grammar.y" /* yacc.c:1661 */
+#line 1723 "grammar.y" /* yacc.c:1661 */
{
yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
yr_free((yyvsp[0].c_string));
}
-#line 3136 "grammar.c" /* yacc.c:1661 */
+#line 3342 "grammar.c" /* yacc.c:1661 */
break;
case 88:
-#line 1527 "grammar.y" /* yacc.c:1661 */
+#line 1733 "grammar.y" /* yacc.c:1661 */
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
}
-#line 3144 "grammar.c" /* yacc.c:1661 */
+#line 3350 "grammar.c" /* yacc.c:1661 */
break;
case 89:
-#line 1531 "grammar.y" /* yacc.c:1661 */
+#line 1737 "grammar.y" /* yacc.c:1661 */
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
}
-#line 3152 "grammar.c" /* yacc.c:1661 */
+#line 3358 "grammar.c" /* yacc.c:1661 */
break;
case 90:
-#line 1539 "grammar.y" /* yacc.c:1661 */
+#line 1745 "grammar.y" /* yacc.c:1661 */
{
(yyval.expression) = (yyvsp[-1].expression);
}
-#line 3160 "grammar.c" /* yacc.c:1661 */
+#line 3366 "grammar.c" /* yacc.c:1661 */
break;
case 91:
-#line 1543 "grammar.y" /* yacc.c:1661 */
+#line 1749 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_emit(
yyscanner, OP_FILESIZE, NULL);
@@ -3170,11 +3376,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3174 "grammar.c" /* yacc.c:1661 */
+#line 3380 "grammar.c" /* yacc.c:1661 */
break;
case 92:
-#line 1553 "grammar.y" /* yacc.c:1661 */
+#line 1759 "grammar.y" /* yacc.c:1661 */
{
yywarning(yyscanner,
"Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " "function from PE module instead.");
@@ -3187,11 +3393,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3191 "grammar.c" /* yacc.c:1661 */
+#line 3397 "grammar.c" /* yacc.c:1661 */
break;
case 93:
-#line 1566 "grammar.y" /* yacc.c:1661 */
+#line 1772 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
@@ -3207,11 +3413,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3211 "grammar.c" /* yacc.c:1661 */
+#line 3417 "grammar.c" /* yacc.c:1661 */
break;
case 94:
-#line 1582 "grammar.y" /* yacc.c:1661 */
+#line 1788 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_emit_with_arg(
yyscanner, OP_PUSH, (yyvsp[0].integer), NULL);
@@ -3221,11 +3427,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = (yyvsp[0].integer);
}
-#line 3225 "grammar.c" /* yacc.c:1661 */
+#line 3431 "grammar.c" /* yacc.c:1661 */
break;
case 95:
-#line 1592 "grammar.y" /* yacc.c:1661 */
+#line 1798 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_emit_with_arg_double(
yyscanner, OP_PUSH, (yyvsp[0].double_), NULL);
@@ -3235,11 +3441,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
(yyval.expression).value.double_ = (yyvsp[0].double_);
}
-#line 3239 "grammar.c" /* yacc.c:1661 */
+#line 3445 "grammar.c" /* yacc.c:1661 */
break;
case 96:
-#line 1602 "grammar.y" /* yacc.c:1661 */
+#line 1808 "grammar.y" /* yacc.c:1661 */
{
SIZED_STRING* sized_string;
@@ -3262,11 +3468,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_STRING;
}
-#line 3266 "grammar.c" /* yacc.c:1661 */
+#line 3472 "grammar.c" /* yacc.c:1661 */
break;
case 97:
-#line 1625 "grammar.y" /* yacc.c:1661 */
+#line 1831 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
@@ -3281,11 +3487,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3285 "grammar.c" /* yacc.c:1661 */
+#line 3491 "grammar.c" /* yacc.c:1661 */
break;
case 98:
-#line 1640 "grammar.y" /* yacc.c:1661 */
+#line 1846 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
@@ -3300,11 +3506,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3304 "grammar.c" /* yacc.c:1661 */
+#line 3510 "grammar.c" /* yacc.c:1661 */
break;
case 99:
-#line 1655 "grammar.y" /* yacc.c:1661 */
+#line 1861 "grammar.y" /* yacc.c:1661 */
{
compiler->last_result = yr_parser_emit_with_arg(
yyscanner,
@@ -3326,11 +3532,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = UNDEFINED;
}
-#line 3330 "grammar.c" /* yacc.c:1661 */
+#line 3536 "grammar.c" /* yacc.c:1661 */
break;
case 100:
-#line 1677 "grammar.y" /* yacc.c:1661 */
+#line 1883 "grammar.y" /* yacc.c:1661 */
{
if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) // loop identifier
{
@@ -3355,7 +3561,7 @@ yyreduce:
break;
case OBJECT_TYPE_DOUBLE:
(yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
- (yyval.expression).value.integer = UNDEFINED;
+ (yyval.expression).value.double_ = UNDEFINED;
break;
case OBJECT_TYPE_STRING:
(yyval.expression).type = EXPRESSION_TYPE_STRING;
@@ -3372,67 +3578,211 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-#line 3376 "grammar.c" /* yacc.c:1661 */
+#line 3582 "grammar.c" /* yacc.c:1661 */
break;
case 101:
-#line 1719 "grammar.y" /* yacc.c:1661 */
+#line 1925 "grammar.y" /* yacc.c:1661 */
{
- CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "+");
- CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "+");
-
- yr_parser_emit(yyscanner, OP_ADD, NULL);
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
+ {
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for + operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
- (yyval.expression).value.integer = OPERATION(+, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ yr_parser_emit(yyscanner, OP_ADD_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(+, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_ADD, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(+, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_ADD_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(+, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else
+ {
+ CLEANUP("+", (yyvsp[-2].expression));
+ }
}
-#line 3390 "grammar.c" /* yacc.c:1661 */
+#line 3632 "grammar.c" /* yacc.c:1661 */
break;
case 102:
-#line 1729 "grammar.y" /* yacc.c:1661 */
+#line 1971 "grammar.y" /* yacc.c:1661 */
{
- CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "-");
- CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "-");
-
- yr_parser_emit(yyscanner, OP_SUB, NULL);
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
+ {
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for - operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
- (yyval.expression).value.integer = OPERATION(-, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ yr_parser_emit(yyscanner, OP_SUB_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(-, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_SUB, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(-, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_SUB_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(-, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else
+ {
+ CLEANUP("-", (yyvsp[-2].expression));
+ }
}
-#line 3404 "grammar.c" /* yacc.c:1661 */
+#line 3682 "grammar.c" /* yacc.c:1661 */
break;
case 103:
-#line 1739 "grammar.y" /* yacc.c:1661 */
+#line 2017 "grammar.y" /* yacc.c:1661 */
{
- CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "*");
- CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "*");
-
- yr_parser_emit(yyscanner, OP_MUL, NULL);
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
+ {
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for * operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
- (yyval.expression).value.integer = OPERATION(*, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ yr_parser_emit(yyscanner, OP_MUL_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(*, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_MUL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(*, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_MUL_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(*, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else
+ {
+ CLEANUP("*", (yyvsp[-2].expression));
+ }
}
-#line 3418 "grammar.c" /* yacc.c:1661 */
+#line 3732 "grammar.c" /* yacc.c:1661 */
break;
case 104:
-#line 1749 "grammar.y" /* yacc.c:1661 */
+#line 2063 "grammar.y" /* yacc.c:1661 */
{
- CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "\\");
- CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "\\");
-
- yr_parser_emit(yyscanner, OP_DIV, NULL);
+ if ((yyvsp[-2].expression).type != (yyvsp[0].expression).type)
+ {
+ if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE &&
+ (yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for \\ operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
- (yyval.expression).value.integer = OPERATION(/, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ yr_parser_emit(yyscanner, OP_DIV_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(/, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_DIV, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(*, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
+ }
+ else if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_DIV_DBL, NULL);
+ (yyval.expression).type = EXPRESSION_TYPE_DOUBLE;
+ (yyval.expression).value.double_ = OPERATION(/, (yyvsp[-2].expression).value.double_, (yyvsp[0].expression).value.double_);
+ }
+ else
+ {
+ CLEANUP("\\", (yyvsp[-2].expression));
+ }
}
-#line 3432 "grammar.c" /* yacc.c:1661 */
+#line 3782 "grammar.c" /* yacc.c:1661 */
break;
case 105:
-#line 1759 "grammar.y" /* yacc.c:1661 */
+#line 2109 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3442,11 +3792,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(%, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3446 "grammar.c" /* yacc.c:1661 */
+#line 3796 "grammar.c" /* yacc.c:1661 */
break;
case 106:
-#line 1769 "grammar.y" /* yacc.c:1661 */
+#line 2119 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3456,11 +3806,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3460 "grammar.c" /* yacc.c:1661 */
+#line 3810 "grammar.c" /* yacc.c:1661 */
break;
case 107:
-#line 1779 "grammar.y" /* yacc.c:1661 */
+#line 2129 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3470,11 +3820,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3474 "grammar.c" /* yacc.c:1661 */
+#line 3824 "grammar.c" /* yacc.c:1661 */
break;
case 108:
-#line 1789 "grammar.y" /* yacc.c:1661 */
+#line 2139 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3484,11 +3834,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3488 "grammar.c" /* yacc.c:1661 */
+#line 3838 "grammar.c" /* yacc.c:1661 */
break;
case 109:
-#line 1799 "grammar.y" /* yacc.c:1661 */
+#line 2149 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~");
@@ -3498,11 +3848,11 @@ yyreduce:
(yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ?
UNDEFINED : (yyvsp[0].expression).value.integer;
}
-#line 3502 "grammar.c" /* yacc.c:1661 */
+#line 3852 "grammar.c" /* yacc.c:1661 */
break;
case 110:
-#line 1809 "grammar.y" /* yacc.c:1661 */
+#line 2159 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3512,11 +3862,11 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3516 "grammar.c" /* yacc.c:1661 */
+#line 3866 "grammar.c" /* yacc.c:1661 */
break;
case 111:
-#line 1819 "grammar.y" /* yacc.c:1661 */
+#line 2169 "grammar.y" /* yacc.c:1661 */
{
CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>");
CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3526,19 +3876,19 @@ yyreduce:
(yyval.expression).type = EXPRESSION_TYPE_INTEGER;
(yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
}
-#line 3530 "grammar.c" /* yacc.c:1661 */
+#line 3880 "grammar.c" /* yacc.c:1661 */
break;
case 112:
-#line 1829 "grammar.y" /* yacc.c:1661 */
+#line 2179 "grammar.y" /* yacc.c:1661 */
{
(yyval.expression) = (yyvsp[0].expression);
}
-#line 3538 "grammar.c" /* yacc.c:1661 */
+#line 3888 "grammar.c" /* yacc.c:1661 */
break;
-#line 3542 "grammar.c" /* yacc.c:1661 */
+#line 3892 "grammar.c" /* yacc.c:1661 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3766,5 +4116,5 @@ yyreturn:
#endif
return yyresult;
}
-#line 1834 "grammar.y" /* yacc.c:1906 */
+#line 2184 "grammar.y" /* yacc.c:1906 */
diff --git a/libyara/grammar.y b/libyara/grammar.y
index 340d591..941ff9b 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -1269,73 +1269,216 @@ expression
}
| primary_expression _LT_ primary_expression
{
- if (CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_DOUBLE))
+ if ($1.type != $3.type)
{
- CLEANUP("<", $1);
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for < operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LTD, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LT, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LTD, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_DOUBLE))
+ else
{
- CLEANUP("<", $3);
+ CLEANUP("<", $1);
}
- TYPE_INEQUALITY($1, $3, "<")
- yr_parser_emit(yyscanner, OP_LT, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _GT_ primary_expression
{
- if (CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_DOUBLE))
+ if ($1.type != $3.type)
{
- CLEANUP(">", $1);
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for > operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GTD, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_DOUBLE))
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
{
- CLEANUP(">", $3);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GT, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GTD, NULL);
+ }
+ else
+ {
+ CLEANUP(">", $1);
}
- TYPE_INEQUALITY($1, $3, ">")
-
- yr_parser_emit(yyscanner, OP_GT, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _LE_ primary_expression
{
- if (CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_DOUBLE))
+ if ($1.type != $3.type)
{
- CLEANUP("<=", $1);
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for <= operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LED, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LE, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_DOUBLE))
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
{
- CLEANUP("<=", $3);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_LED, NULL);
+ }
+ else
+ {
+ CLEANUP("<=", $1);
}
- TYPE_INEQUALITY($1, $3, "<=")
- yr_parser_emit(yyscanner, OP_LE, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _GE_ primary_expression
{
- if (CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($1, EXPRESSION_TYPE_DOUBLE))
+ if ($1.type != $3.type)
{
- CLEANUP(">=", $1);
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for >= operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GED, NULL);
}
- if (CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_INTEGER) &&
- CHECK_TYPE_NO_CLEANUP($3, EXPRESSION_TYPE_DOUBLE))
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
{
- CLEANUP(">=", $3);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GE, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_GED, NULL);
+ }
+ else
+ {
+ CLEANUP(">=", $1);
}
- TYPE_INEQUALITY($1, $3, ">=")
- yr_parser_emit(yyscanner, OP_GE, NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
@@ -1343,23 +1486,54 @@ expression
{
if ($1.type != $3.type)
{
- yr_compiler_set_error_extra_info(
- compiler, "mismatching types for == operator");
- compiler->last_result = ERROR_WRONG_TYPE;
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for == operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQD, NULL);
}
else if ($1.type == EXPRESSION_TYPE_STRING)
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_STR_EQ,
- NULL);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_STR_EQ, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQ, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_EQD, NULL);
}
else
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_EQ,
- NULL);
+ CLEANUP("==", $1);
}
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -1397,23 +1571,54 @@ expression
{
if ($1.type != $3.type)
{
- yr_compiler_set_error_extra_info(
- compiler, "mismatching types for != operator");
- compiler->last_result = ERROR_WRONG_TYPE;
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 2,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ compiler->last_result = yr_parser_emit_with_arg(
+ yyscanner,
+ OP_ITD,
+ 1,
+ NULL);
+ ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for != operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
+
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQD, NULL);
}
else if ($1.type == EXPRESSION_TYPE_STRING)
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_STR_NEQ,
- NULL);
+ compiler->last_result = yr_parser_emit(yyscanner, OP_STR_NEQ, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQ, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ compiler->last_result = yr_parser_emit(yyscanner, OP_NEQD, NULL);
}
else
{
- compiler->last_result = yr_parser_emit(
- yyscanner,
- OP_NEQ,
- NULL);
+ CLEANUP("!=", $1);
}
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -1698,7 +1903,7 @@ primary_expression
break;
case OBJECT_TYPE_DOUBLE:
$$.type = EXPRESSION_TYPE_DOUBLE;
- $$.value.integer = UNDEFINED;
+ $$.value.double_ = UNDEFINED;
break;
case OBJECT_TYPE_STRING:
$$.type = EXPRESSION_TYPE_STRING;
@@ -1717,43 +1922,187 @@ primary_expression
}
| primary_expression '+' primary_expression
{
- CHECK_TYPE($1, EXPRESSION_TYPE_INTEGER, "+");
- CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "+");
-
- yr_parser_emit(yyscanner, OP_ADD, NULL);
+ if ($1.type != $3.type)
+ {
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for + operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- $$.type = EXPRESSION_TYPE_INTEGER;
- $$.value.integer = OPERATION(+, $1.value.integer, $3.value.integer);
+ yr_parser_emit(yyscanner, OP_ADD_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(+, $1.value.double_, $3.value.double_);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_ADD, NULL);
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(+, $1.value.integer, $3.value.integer);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_ADD_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(+, $1.value.double_, $3.value.double_);
+ }
+ else
+ {
+ CLEANUP("+", $1);
+ }
}
| primary_expression '-' primary_expression
{
- CHECK_TYPE($1, EXPRESSION_TYPE_INTEGER, "-");
- CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "-");
-
- yr_parser_emit(yyscanner, OP_SUB, NULL);
+ if ($1.type != $3.type)
+ {
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for - operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- $$.type = EXPRESSION_TYPE_INTEGER;
- $$.value.integer = OPERATION(-, $1.value.integer, $3.value.integer);
+ yr_parser_emit(yyscanner, OP_SUB_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(-, $1.value.double_, $3.value.double_);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_SUB, NULL);
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(-, $1.value.integer, $3.value.integer);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_SUB_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(-, $1.value.double_, $3.value.double_);
+ }
+ else
+ {
+ CLEANUP("-", $1);
+ }
}
| primary_expression '*' primary_expression
{
- CHECK_TYPE($1, EXPRESSION_TYPE_INTEGER, "*");
- CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "*");
-
- yr_parser_emit(yyscanner, OP_MUL, NULL);
+ if ($1.type != $3.type)
+ {
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for * operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- $$.type = EXPRESSION_TYPE_INTEGER;
- $$.value.integer = OPERATION(*, $1.value.integer, $3.value.integer);
+ yr_parser_emit(yyscanner, OP_MUL_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(*, $1.value.double_, $3.value.double_);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_MUL, NULL);
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(*, $1.value.integer, $3.value.integer);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_MUL_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(*, $1.value.double_, $3.value.double_);
+ }
+ else
+ {
+ CLEANUP("*", $1);
+ }
}
| primary_expression '\\' primary_expression
{
- CHECK_TYPE($1, EXPRESSION_TYPE_INTEGER, "\\");
- CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "\\");
-
- yr_parser_emit(yyscanner, OP_DIV, NULL);
+ if ($1.type != $3.type)
+ {
+ if ($1.type == EXPRESSION_TYPE_INTEGER &&
+ $3.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ // Cast left side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 2, NULL);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE &&
+ $3.type == EXPRESSION_TYPE_INTEGER)
+ {
+ // Cast right side to double.
+ yr_parser_emit_with_arg(yyscanner, OP_ITD, 1, NULL);
+ }
+ else
+ {
+ yr_compiler_set_error_extra_info(
+ compiler, "mismatching types for \\ operator");
+ compiler->last_result = ERROR_WRONG_TYPE;
+ yyerror(yyscanner, compiler, NULL);
+ YYERROR;
+ }
- $$.type = EXPRESSION_TYPE_INTEGER;
- $$.value.integer = OPERATION(/, $1.value.integer, $3.value.integer);
+ yr_parser_emit(yyscanner, OP_DIV_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(/, $1.value.double_, $3.value.double_);
+ }
+ else if ($1.type == EXPRESSION_TYPE_INTEGER)
+ {
+ yr_parser_emit(yyscanner, OP_DIV, NULL);
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(*, $1.value.integer, $3.value.integer);
+ }
+ else if ($1.type == EXPRESSION_TYPE_DOUBLE)
+ {
+ yr_parser_emit(yyscanner, OP_DIV_DBL, NULL);
+ $$.type = EXPRESSION_TYPE_DOUBLE;
+ $$.value.double_ = OPERATION(/, $1.value.double_, $3.value.double_);
+ }
+ else
+ {
+ CLEANUP("\\", $1);
+ }
}
| primary_expression '%' primary_expression
{
diff --git a/libyara/include/yara/exec.h b/libyara/include/yara/exec.h
index 37ee034..7799a6f 100644
--- a/libyara/include/yara/exec.h
+++ b/libyara/include/yara/exec.h
@@ -80,6 +80,17 @@ limitations under the License.
#define OP_MATCHES 50
#define OP_IMPORT 51
#define OP_LOOKUP_DICT 52
+#define OP_ITD 53
+#define OP_LTD 54
+#define OP_GTD 55
+#define OP_LED 56
+#define OP_GED 57
+#define OP_EQD 58
+#define OP_NEQD 59
+#define OP_ADD_DBL 60
+#define OP_SUB_DBL 61
+#define OP_MUL_DBL 62
+#define OP_DIV_DBL 63
#define OP_INT 100
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list