summaryrefslogtreecommitdiff
path: root/parse/tok.c
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-10-29 00:18:54 -0700
committerOri Bernstein <ori@eigenstate.org>2016-10-29 00:18:54 -0700
commit018b5d47a594fff5e29361b9722160f11fdcd0f2 (patch)
treea3247099aefbb7000a6ea93e8903081e1dd86285 /parse/tok.c
parent4d472fe09784b047964fa3c7aad197c0f7ef5480 (diff)
downloadmc-018b5d47a594fff5e29361b9722160f11fdcd0f2.tar.gz
Add support for exponential notation for floats.
Diffstat (limited to 'parse/tok.c')
-rw-r--r--parse/tok.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/parse/tok.c b/parse/tok.c
index 7ab2874..76756cb 100644
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -635,6 +635,7 @@ static Tok *number(int base)
* need a buffer that holds the number without '_'.
*/
char buf[2048];
+ char *endp;
size_t nbuf;
t = NULL;
@@ -645,27 +646,47 @@ static Tok *number(int base)
next();
if (c == '_')
continue;
- if (c == '.')
- isfloat = 1;
- else if (hexval(c) < 0 || hexval(c) >= base)
- lfatal(curloc, "Integer digit '%c' outside of base %d", c, base);
if (nbuf >= sizeof buf - 1) {
buf[nbuf - 1] = '\0';
lfatal(curloc, "number %s... too long to represent", buf);
}
- buf[nbuf++] = c;
+
+ /* float radix */
+ if (c == '.') {
+ isfloat = 1;
+ buf[nbuf++] = c;
+ /* exponential notation */
+ } else if (base == 10 && (c == 'e' || c == 'E')) {
+ isfloat = 1;
+ buf[nbuf++] = c;
+ if ((peek() == '+' || peek() == '-') && nbuf < sizeof buf - 1)
+ buf[nbuf++] = next();
+ /* out of range */
+ } else if (hexval(c) < 0 || hexval(c) >= base) {
+ lfatal(curloc, "Integer digit '%c' outside of base %d", c, base);
+ /* just a number */
+ } else {
+ buf[nbuf++] = c;
+ }
}
buf[nbuf] = '\0';
/* we only support base 10 floats */
- if (isfloat && base == 10) {
+ if (isfloat) {
+ if (base != 10)
+ lfatal(curloc, "%s is not a valid floating point value", buf);
t = mktok(Tfloatlit);
t->id = strdupn(&fbuf[start], fidx - start);
- t->fltval = strtod(buf, NULL);
+ t->fltval = strtod(buf, &endp);
+ if (endp == buf)
+ lfatal(curloc, "%s is not a valid floating point value", buf);
} else {
t = mktok(Tintlit);
t->id = strdupn(&fbuf[start], fidx - start);
- t->intval = strtoull(buf, NULL, base);
+ t->intval = strtoull(buf, &endp, base);
+ if (endp == buf)
+ lfatal(curloc, "%s is not a valid integer value", buf);
+
/* check suffixes:
* u -> unsigned
* l -> 64 bit
@@ -733,8 +754,10 @@ static Tok *numlit(void)
t = number(2);
else if (match('o'))
t = number(8);
- else
+ else {
+ unget();
t = number(10);
+ }
} else {
t = number(10);
}