mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-18 21:29:19 +02:00
fix inexact json parsing
This commit is contained in:
parent
72971fd4f4
commit
eaf8e90e8c
2 changed files with 26 additions and 3 deletions
|
@ -5,6 +5,9 @@
|
||||||
(begin
|
(begin
|
||||||
(define (run-tests)
|
(define (run-tests)
|
||||||
(test-begin "json")
|
(test-begin "json")
|
||||||
|
(test 1 (parse-json "1"))
|
||||||
|
(test 1.5 (parse-json "1.5"))
|
||||||
|
(test 1000.0 (parse-json "1e3"))
|
||||||
(test '((glossary
|
(test '((glossary
|
||||||
(title . "example glossary")
|
(title . "example glossary")
|
||||||
(GlossDiv
|
(GlossDiv
|
||||||
|
|
|
@ -16,12 +16,31 @@ sexp sexp_json_exception (sexp ctx, sexp self, const char* msg, sexp str, const
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp parse_json_number (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len) {
|
sexp parse_json_number (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len) {
|
||||||
sexp_sint_t res = 0;
|
double res = 0, scale = 1;
|
||||||
int j = *i;
|
int j = *i, sign = 1, inexactp = 0;
|
||||||
|
if (s[j] == '+') {
|
||||||
|
++j;
|
||||||
|
} else if (s[j] == '-') {
|
||||||
|
++j;
|
||||||
|
sign = -1;
|
||||||
|
}
|
||||||
while (j < len && isdigit(s[j]))
|
while (j < len && isdigit(s[j]))
|
||||||
res = res * 10 + s[j++] - '0';
|
res = res * 10 + s[j++] - '0';
|
||||||
|
if (j < len && s[j] == '.') {
|
||||||
|
inexactp = 1;
|
||||||
|
for (++j; j < len && isdigit(s[j]); scale *= 10)
|
||||||
|
res = res * 10 + s[j++] - '0';
|
||||||
|
res /= scale;
|
||||||
|
} else if (j < len && sexp_tolower(s[j]) == 'e') {
|
||||||
|
inexactp = 1;
|
||||||
|
for (++j, scale=0; j < len && isdigit(s[j]); )
|
||||||
|
scale = scale * 10 + s[j++] - '0';
|
||||||
|
res *= pow(10.0, scale);
|
||||||
|
}
|
||||||
*i = j;
|
*i = j;
|
||||||
return sexp_make_fixnum(res);
|
return (inexactp || fabs(res) > SEXP_MAX_FIXNUM) ?
|
||||||
|
sexp_make_flonum(ctx, sign * res) :
|
||||||
|
sexp_make_fixnum(sign * res); /* always return inexact? */
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp parse_json_literal (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len, const char* name, int namelen, sexp value) {
|
sexp parse_json_literal (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len, const char* name, int namelen, sexp value) {
|
||||||
|
@ -206,6 +225,7 @@ sexp parse_json (sexp ctx, sexp self, sexp str, const char* s, int* i, const int
|
||||||
++j;
|
++j;
|
||||||
res = parse_json_string(ctx, self, str, s, &j, len);
|
res = parse_json_string(ctx, self, str, s, &j, len);
|
||||||
break;
|
break;
|
||||||
|
case '-': case '+':
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
res = parse_json_number(ctx, self, str, s, &j, len);
|
res = parse_json_number(ctx, self, str, s, &j, len);
|
||||||
|
|
Loading…
Add table
Reference in a new issue