1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-24 07:20:27 +00:00

Fix some behavior with parsing integers.

This commit is contained in:
Calvin Rose 2018-03-24 00:25:59 -04:00
parent 0b25284aa9
commit 41d5b5cb90
2 changed files with 40 additions and 4 deletions

View File

@ -703,6 +703,35 @@ static int cfun_parsenumber(DstArgs args) {
return dst_return(args, x); return dst_return(args, x);
} }
static int cfun_parseint(DstArgs args) {
const uint8_t *data;
int32_t len, ret;
int err = 0;
if (args.n != 1) return dst_throw(args, "expected string or buffer");
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected string or buffer");
ret = dst_scan_integer(data, len, &err);
if (err) {
return dst_throw(args, "error parsing integer");
}
return dst_return(args, dst_wrap_integer(ret));
}
static int cfun_parsereal(DstArgs args) {
const uint8_t *data;
int32_t len;
double ret;
int err = 0;
if (args.n != 1) return dst_throw(args, "expected string or buffer");
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected string or buffer");
ret = dst_scan_real(data, len, &err);
if (err) {
return dst_throw(args, "error parsing real");
}
return dst_return(args, dst_wrap_real(ret));
}
static const DstReg cfuns[] = { static const DstReg cfuns[] = {
{"parser", cfun_parser}, {"parser", cfun_parser},
{"parser-produce", cfun_produce}, {"parser-produce", cfun_produce},
@ -715,6 +744,8 @@ static const DstReg cfuns[] = {
{"ast-wrap", cfun_wrap}, {"ast-wrap", cfun_wrap},
{"ast-node", cfun_node}, {"ast-node", cfun_node},
{"parse-number", cfun_parsenumber}, {"parse-number", cfun_parsenumber},
{"parse-int", cfun_parseint},
{"parse-real", cfun_parsereal},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -268,11 +268,16 @@ int32_t dst_scan_integer(
int *err) { int *err) {
struct DstScanRes res = dst_scan_impl(str, len); struct DstScanRes res = dst_scan_impl(str, len);
int64_t i64; int64_t i64;
if (res.error) if (res.error) goto error;
goto error; if (res.seenpoint) goto error;
if (res.ex < 0) goto error;
i64 = res.neg ? -res.mant : res.mant; i64 = res.neg ? -res.mant : res.mant;
if (i64 > INT32_MAX || i64 < INT32_MIN) while (res.ex > 0) {
goto error; i64 *= res.base;
if (i64 > INT32_MAX || i64 < INT32_MIN) goto error;
res.ex--;
}
if (i64 > INT32_MAX || i64 < INT32_MIN) goto error;
if (NULL != err) if (NULL != err)
*err = 0; *err = 0;
return (int32_t) i64; return (int32_t) i64;