aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-10-21 13:14:44 -0700
committerMichael Forney <mforney@mforney.org>2021-10-21 13:15:11 -0700
commit8fac505536f69b3f3864dcd09979bfc9cc3ce471 (patch)
tree432855fd676b478d6899dd1cf04458c11bd27c2d
parent9f21e00b458858198381d8e4ab4141ecf2fa2bbe (diff)
expr: Implement binary integer constants
These are in the latest C23 draft.
-rw-r--r--expr.c17
-rw-r--r--test/binary-constant.c1
-rw-r--r--test/binary-constant.qbe1
3 files changed, 16 insertions, 3 deletions
diff --git a/expr.c b/expr.c
index 66ffd29..27acbcf 100644
--- a/expr.c
+++ b/expr.c
@@ -612,7 +612,15 @@ primaryexpr(struct scope *s)
break;
case TNUMBER:
e = mkexpr(EXPRCONST, NULL, NULL);
- base = tok.lit[0] != '0' ? 10 : tolower(tok.lit[1]) == 'x' ? 16 : 8;
+ if (tok.lit[0] == '0') {
+ switch (tolower(tok.lit[1])) {
+ case 'x': base = 16; break;
+ case 'b': base = 2; break;
+ default: base = 8; break;
+ }
+ } else {
+ base = 10;
+ }
if (strpbrk(tok.lit, base == 16 ? ".pP" : ".eE")) {
/* floating constant */
e->constant.f = strtod(tok.lit, &end);
@@ -627,9 +635,12 @@ primaryexpr(struct scope *s)
else
error(&tok.loc, "invalid floating constant suffix '%s'", end);
} else {
+ src = tok.lit;
+ if (base == 2)
+ src += 2;
/* integer constant */
- e->constant.u = strtoull(tok.lit, &end, 0);
- if (end == tok.lit)
+ e->constant.u = strtoull(src, &end, base);
+ if (end == src)
error(&tok.loc, "invalid integer constant '%s'", tok.lit);
e->type = inttype(e->constant.u, base == 10, end);
}
diff --git a/test/binary-constant.c b/test/binary-constant.c
new file mode 100644
index 0000000..234e116
--- /dev/null
+++ b/test/binary-constant.c
@@ -0,0 +1 @@
+int x = 0b11100100;
diff --git a/test/binary-constant.qbe b/test/binary-constant.qbe
new file mode 100644
index 0000000..d72a76c
--- /dev/null
+++ b/test/binary-constant.qbe
@@ -0,0 +1 @@
+export data $x = align 4 { w 228, }