diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 11:14:32 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 11:14:32 -0500 |
commit | 7432b0a64761aa07f95ad19761c61bf11db428e9 (patch) | |
tree | d5ab002a15bab9b985c7f070e2c2a91a1491d66b | |
parent | e80252a52bf25f762bc986ce6e4e0d17fbb130d0 (diff) | |
download | roux-7432b0a64761aa07f95ad19761c61bf11db428e9.tar.gz |
fix int parsing
The spec says that numbers can be arbitrarily big, and only the last 64 bits will be taken into consideration. Calling sscanf does not implement this, so I wrote an ad-hoc function.
-rw-r--r-- | parse.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/parse.c b/parse.c index 38481aa..edb6c29 100644 --- a/parse.c +++ b/parse.c @@ -254,6 +254,29 @@ lexinit() done = 1; } +static int64_t +getint() +{ + uint64_t n; + int c, m; + + n = 0; + c = fgetc(inf); + m = 0; + switch (c) { + case '-': m = 1; + case '+': c = fgetc(inf); + } + do { + n = 10*n + (c - '0'); + c = fgetc(inf); + } while ('0' <= c && c <= '9'); + ungetc(c, inf); + if (m) + n = 1 + ~n; + return *(int64_t *)&n; +} + static int lex() { @@ -312,8 +335,7 @@ lex() } if (isdigit(c) || c == '-' || c == '+') { ungetc(c, inf); - if (fscanf(inf, "%"SCNd64, &tokval.num) != 1) - err("invalid integer literal"); + tokval.num = getint(); return Tint; } if (c == '"') { |