diff --git a/tests b/tests index 6a3ca209213ac435da5564d6f9da217876ea1ca0..1218b5e953db2506b63817a39b53b16d4e2695de 100644 --- a/tests +++ b/tests @@ -329,6 +329,9 @@ int main() { assert(0, (long)&*(int *)0, "(long)&*(int *)0"); assert(5, ({ int x=5; long y=(long)&x; *(int*)y; }), "int x=5; long y=(long)&x; *(int*)y"); + assert(97, 'a', "'a'"); + assert(10, '\n', "\'\\n\'"); + printf("OK\n"); return 0; } diff --git a/tokenize.c b/tokenize.c index 573c3a20a2fc4f9584829f8043f8e94dda2fd337..7fcdcce827fbac5d711ef9a34bc09d36c74e869e 100644 --- a/tokenize.c +++ b/tokenize.c @@ -211,6 +211,28 @@ static Token *read_string_literal(Token *cur, char *start) { return tok; } +static Token *read_char_literal(Token *cur, char *start) { + char *p = start + 1; + if (*p == '\0') + error_at(start, "unclosed char literal"); + + char c; + if (*p == '\\') { + p++; + c = get_escape_char(*p++); + } else { + c = *p++; + } + + if (*p != '\'') + error_at(start, "char literal too long"); + p++; + + Token *tok = new_token(TK_NUM, cur, start, p - start); + tok->val = c; + return tok; +} + // Tokenize `user_input` and returns new tokens. Token *tokenize(void) { char *p = user_input; @@ -248,6 +270,13 @@ Token *tokenize(void) { continue; } + // Character literal + if (*p == '\'') { + cur = read_char_literal(cur, p); + p += cur->len; + continue; + } + // Keywords or multi-letter punctuators char *kw = starts_with_reserved(p); if (kw) {