Expand expr's support for numeric literals
- Support hex prefix 0x or OX - Support scientific notation Also, reconcile the bitwise complement operator with C (use ~ instead of ^).
This commit is contained in:
parent
7842f9a715
commit
11851a01e6
|
@ -160,10 +160,10 @@ static int expr_prec(enum expr_type a, enum expr_type b) {
|
||||||
return (left && prec[a] >= prec[b]) || (prec[a] > prec[b]);
|
return (left && prec[a] >= prec[b]) || (prec[a] > prec[b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define isfirstvarchr(c) \
|
#define isfirstvarchr(c) \
|
||||||
(((unsigned char)c >= '@' && c != '^' && c != '|') || c == '$')
|
(((unsigned char)c >= '@' && c != '^' && c != '|' && c != '~') || c == '$')
|
||||||
#define isvarchr(c) \
|
#define isvarchr(c) \
|
||||||
(((unsigned char)c >= '@' && c != '^' && c != '|') || c == '$' || \
|
(((unsigned char)c >= '@' && c != '^' && c != '|' && c != '~') || c == '$' || \
|
||||||
c == '#' || (c >= '0' && c <= '9'))
|
c == '#' || (c >= '0' && c <= '9'))
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -172,7 +172,7 @@ static struct {
|
||||||
} OPS[] = {
|
} OPS[] = {
|
||||||
{"-u", OP_UNARY_MINUS},
|
{"-u", OP_UNARY_MINUS},
|
||||||
{"!u", OP_UNARY_LOGICAL_NOT},
|
{"!u", OP_UNARY_LOGICAL_NOT},
|
||||||
{"^u", OP_UNARY_BITWISE_NOT},
|
{"~u", OP_UNARY_BITWISE_NOT},
|
||||||
{"**", OP_POWER},
|
{"**", OP_POWER},
|
||||||
{"*", OP_MULTIPLY},
|
{"*", OP_MULTIPLY},
|
||||||
{"/", OP_DIVIDE},
|
{"/", OP_DIVIDE},
|
||||||
|
@ -199,7 +199,7 @@ static struct {
|
||||||
them at the end */
|
them at the end */
|
||||||
{"-", OP_UNARY_MINUS},
|
{"-", OP_UNARY_MINUS},
|
||||||
{"!", OP_UNARY_LOGICAL_NOT},
|
{"!", OP_UNARY_LOGICAL_NOT},
|
||||||
{"^", OP_UNARY_BITWISE_NOT},
|
{"~", OP_UNARY_BITWISE_NOT},
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum expr_type expr_op(const char *s, size_t len, int unary) {
|
static enum expr_type expr_op(const char *s, size_t len, int unary) {
|
||||||
|
@ -212,30 +212,24 @@ static enum expr_type expr_op(const char *s, size_t len, int unary) {
|
||||||
return OP_UNKNOWN;
|
return OP_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double expr_parse_number(const char *s, size_t len) {
|
static double expr_parse_number(const char* s, size_t len) {
|
||||||
double num = 0;
|
double num = 0;
|
||||||
unsigned int frac = 0;
|
char buf[32];
|
||||||
unsigned int digits = 0;
|
char* sz = buf;
|
||||||
for (unsigned int i = 0; i < len; i++) {
|
char* end = NULL;
|
||||||
if (s[i] == '.' && frac == 0) {
|
if (len >= sizeof(buf)) {
|
||||||
frac++;
|
sz = (char*)calloc(1, len + 1);
|
||||||
continue;
|
if (sz == NULL) {
|
||||||
}
|
|
||||||
if (isdigit(s[i])) {
|
|
||||||
digits++;
|
|
||||||
if (frac > 0) {
|
|
||||||
frac++;
|
|
||||||
}
|
|
||||||
num = num * 10 + (s[i] - '0');
|
|
||||||
} else {
|
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (frac > 1) {
|
strncpy(sz, s, len);
|
||||||
num = num / 10;
|
sz[len] = '\0';
|
||||||
frac--;
|
num = strtod(sz, &end);
|
||||||
|
if (sz != buf) {
|
||||||
|
free(sz);
|
||||||
}
|
}
|
||||||
return (digits > 0 ? num : NAN);
|
return (end == sz + len ? num : NAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -446,9 +440,23 @@ static int expr_next_token(const char *s, size_t len, int *flags) {
|
||||||
return -1; // unexpected number
|
return -1; // unexpected number
|
||||||
}
|
}
|
||||||
*flags = EXPR_TOP | EXPR_TCLOSE;
|
*flags = EXPR_TOP | EXPR_TCLOSE;
|
||||||
while ((c == '.' || isdigit(c)) && i < len) {
|
if (c == '0') {
|
||||||
i++;
|
i++;
|
||||||
c = s[i];
|
if (i < len && (s[i] == 'x' || s[i] == 'X')) {
|
||||||
|
i++;
|
||||||
|
for (; i < len && isxdigit(s[i]); i++)
|
||||||
|
;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; i < len && (s[i] == '.' || isdigit(s[i])); i++)
|
||||||
|
;
|
||||||
|
if (i < len && (s[i] == 'e' || s[i] == 'E')) {
|
||||||
|
i++;
|
||||||
|
if (i < len && (s[i] == '+' || s[i] == '-'))
|
||||||
|
i++;
|
||||||
|
for (; i < len && isdigit(s[i]); i++)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
} else if (isfirstvarchr(c)) {
|
} else if (isfirstvarchr(c)) {
|
||||||
|
@ -626,8 +634,8 @@ static struct expr *expr_create(const char *s, size_t len,
|
||||||
case '-':
|
case '-':
|
||||||
tok = "-u";
|
tok = "-u";
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '~':
|
||||||
tok = "^u";
|
tok = "~u";
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
tok = "!u";
|
tok = "!u";
|
||||||
|
|
Loading…
Reference in New Issue