Add hexadecimal, octal and binary number literals

This commit is contained in:
Rui Ueyama 2019-08-13 18:39:56 +09:00
parent 05e907d2b8
commit f78c409856
3 changed files with 40 additions and 4 deletions

View File

@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
typedef struct Type Type;
typedef struct Member Member;

12
tests
View File

@ -378,6 +378,18 @@ int main() {
assert(3, ({ int i=6; i/=2; i; }), "int i=6; i/=2; i;");
assert(3, ({ int i=6; i/=2; }), "int i=6; i/=2;");
assert(511, 0777, "0777");
assert(0, 0x0, "0x0");
assert(10, 0xa, "0xa");
assert(10, 0XA, "0XA");
assert(48879, 0xbeef, "0xbeef");
assert(48879, 0xBEEF, "0xBEEF");
assert(48879, 0XBEEF, "0XBEEF");
assert(0, 0b0, "0b0");
assert(1, 0b1, "0b1");
assert(47, 0b101111, "0b101111");
assert(47, 0B101111, "0B101111");
printf("OK\n");
return 0;
}

View File

@ -234,6 +234,31 @@ static Token *read_char_literal(Token *cur, char *start) {
return tok;
}
static Token *read_int_literal(Token *cur, char *start) {
char *p = start;
int base;
if (!strncasecmp(p, "0x", 2) && is_alnum(p[2])) {
p += 2;
base = 16;
} else if (!strncasecmp(p, "0b", 2) && is_alnum(p[2])) {
p += 2;
base = 2;
} else if (*p == '0') {
base = 8;
} else {
base = 10;
}
long val = strtol(p, &p, base);
if (is_alnum(*p))
error_at(p, "invalid digit");
Token *tok = new_token(TK_NUM, cur, start, p - start);
tok->val = val;
return tok;
}
// Tokenize `user_input` and returns new tokens.
Token *tokenize(void) {
char *p = user_input;
@ -304,10 +329,8 @@ Token *tokenize(void) {
// Integer literal
if (isdigit(*p)) {
cur = new_token(TK_NUM, cur, p, 0);
char *q = p;
cur->val = strtol(p, &p, 10);
cur->len = p - q;
cur = read_int_literal(cur, p);
p += cur->len;
continue;
}