diff --git a/parse.c b/parse.c index 1cc339e..63a0199 100644 --- a/parse.c +++ b/parse.c @@ -4345,19 +4345,9 @@ static Node *primary(Token **rest, Token *tok) { return new_boolean(1, tok); } - if (tok->kind == TK_PP_NUM) - convert_pp_number(tok); - - if (tok->kind == TK_NUM) { - Node *node; - if (is_flonum(tok->ty)) { - node = new_node(ND_NUM, tok); - node->fval = tok->fval; - } else { - node = new_num(tok->val, tok); - } - - node->ty = tok->ty; + if (tok->kind == TK_INT_NUM || tok->kind == TK_PP_NUM) { + Node *node = new_node(ND_NUM, tok); + node->ty = convert_pp_number(tok, &node->val, &node->fval); *rest = tok->next; return node; } diff --git a/preprocess.c b/preprocess.c index 4539588..7bc429e 100644 --- a/preprocess.c +++ b/preprocess.c @@ -329,8 +329,8 @@ static Token *new_comma_token(Token *tmpl) { } static Token *to_int_token(Token *tok, int64_t val) { - tok->kind = TK_NUM; - tok->val = val; + tok->kind = TK_INT_NUM; + tok->ival = val; tok->ty = ty_int; return tok; } @@ -1119,11 +1119,12 @@ static Token *embed_file(Token *cont, Token *tok, char *path, Token *start) { static void read_line_marker(Token **rest, Token *tok) { Token *start = tok; tok = expand_tok(split_line(rest, tok)); - convert_pp_number(tok); - if (tok->kind != TK_NUM || tok->ty->kind != TY_INT) + int64_t val; + if (convert_pp_number(tok, &val, &(long double){0})->kind != TY_INT) error_tok(tok, "invalid line marker"); - start->file->line_delta = tok->val - start->line_no - 1; + + start->file->line_delta = val - start->line_no - 1; tok = tok->next; if (tok->kind == TK_EOF) diff --git a/slimcc.h b/slimcc.h index be6bbcb..c944a63 100644 --- a/slimcc.h +++ b/slimcc.h @@ -131,7 +131,7 @@ typedef enum { TK_KEYWORD, // Keywords TK_TYPEKW, // Keywords TK_STR, // String literals - TK_NUM, // Numeric literals + TK_INT_NUM, // Integer Numeric literals TK_PP_NUM, // Preprocessing numbers TK_PMARK, // Placermarkers TK_ATTR, // GNU attribute @@ -157,11 +157,10 @@ typedef struct Token Token; struct Token { TokenKind kind; // Token kind Token *next; // Next token - int64_t val; // If kind is TK_NUM, its value - long double fval; // If kind is TK_NUM, its value + int64_t ival; // If kind is TK_INT_NUM, its value char *loc; // Token location int len; // Token length - Type *ty; // Used if TK_NUM or TK_STR + Type *ty; // Used if TK_INT_NUM or TK_STR char *str; // String literal contents including terminating '\0' File *file; // Source location @@ -194,7 +193,7 @@ Token *tokenize_string_literal(Token *tok, Type *basety); Token *tokenize(File *file, Token **end); Token *tokenize_file(char *filename, Token **end, int *incl_no); File *add_input_file(char *path, char *content, int *incl_no); -void convert_pp_number(Token *tok); +Type *convert_pp_number(Token *tok, int64_t *res_val, long double *res_fval); TokenKind ident_keyword(Token *tok); #define internal_error() \ diff --git a/tokenize.c b/tokenize.c index 97c861d..e403da8 100644 --- a/tokenize.c +++ b/tokenize.c @@ -410,8 +410,8 @@ static Token *read_char_literal(char *start, char *quote, Type *ty) { if (!end) error_at(p, "unclosed char literal"); - Token *tok = new_token(TK_NUM, start, end + 1); - tok->val = c; + Token *tok = new_token(TK_INT_NUM, start, end + 1); + tok->ival = c; tok->ty = ty; return tok; } @@ -448,7 +448,7 @@ static Token *new_pp_number(char *start, char *p) { } } -static bool convert_pp_int(Token *tok, char *loc, int len) { +static bool convert_pp_int(char *loc, int len, Type **res_ty, int64_t *res_val) { char *p = loc; // Read a binary, octal, decimal or hexadecimal number. @@ -522,14 +522,18 @@ static bool convert_pp_int(Token *tok, char *loc, int len) { ty = ty_int; } - tok->kind = TK_NUM; - tok->val = val; - tok->ty = ty; + *res_val = val; + *res_ty = ty; return true; } // Converts a pp-number token to a regular number token. -void convert_pp_number(Token *tok) { +Type *convert_pp_number(Token *tok, int64_t *res_val, long double *res_fval) { + if (tok->kind == TK_INT_NUM) { + *res_val = tok->ival; + return tok->ty; + } + // Remove digit seperators int len = 0; char buf[227]; @@ -546,15 +550,15 @@ void convert_pp_number(Token *tok) { buf[len] = '\0'; + Type *ty; // Try to parse as an integer constant. - if (convert_pp_int(tok, buf, len)) - return; + if (convert_pp_int(buf, len, &ty, res_val)) + return ty; // If it's not an integer, it must be a floating point constant. char *end; long double val = strtold(buf, &end); - Type *ty; if (*end == 'f' || *end == 'F') { val = (float)val; ty = ty_float; @@ -570,9 +574,8 @@ void convert_pp_number(Token *tok) { if (&buf[len] != end) error_tok(tok, "invalid numeric constant"); - tok->kind = TK_NUM; - tok->fval = val; - tok->ty = ty; + *res_fval = val; + return ty; } // Initialize line info for all tokens. @@ -700,7 +703,7 @@ Token *tokenize(File *file, Token **end) { // Character literal if (*p == '\'') { cur = cur->next = read_char_literal(p, p, ty_int); - cur->val = (char)cur->val; + cur->ival = (char)cur->ival; p += cur->len; continue; } @@ -708,7 +711,7 @@ Token *tokenize(File *file, Token **end) { // UTF-16 character literal if (startswith2(p, 'u', '\'')) { cur = cur->next = read_char_literal(p, p + 1, ty_ushort); - cur->val &= 0xffff; + cur->ival &= 0xffff; p += cur->len; continue; }