Add `signed` keyword

This commit is contained in:
Rui Ueyama 2019-08-27 00:21:23 +09:00
parent d1e7d1e88d
commit 06d3190515
3 changed files with 47 additions and 10 deletions

32
parse.c
View File

@ -260,18 +260,20 @@ Program *program(void) {
//
// Note that "typedef" and "static" can appear anywhere in a basetype.
// "int" can appear anywhere if type is short, long or long long.
// "signed" can appear anywhere if type is short, int, long or long long.
static Type *basetype(StorageClass *sclass) {
if (!is_typename())
error_tok(token, "typename expected");
enum {
VOID = 1 << 0,
BOOL = 1 << 2,
CHAR = 1 << 4,
SHORT = 1 << 6,
INT = 1 << 8,
LONG = 1 << 10,
OTHER = 1 << 12,
VOID = 1 << 0,
BOOL = 1 << 2,
CHAR = 1 << 4,
SHORT = 1 << 6,
INT = 1 << 8,
LONG = 1 << 10,
OTHER = 1 << 12,
SIGNED = 1 << 13,
};
Type *ty = int_type;
@ -302,7 +304,8 @@ static Type *basetype(StorageClass *sclass) {
// Handle user-defined types.
if (!peek("void") && !peek("_Bool") && !peek("char") &&
!peek("short") && !peek("int") && !peek("long")) {
!peek("short") && !peek("int") && !peek("long") &&
!peek("signed")) {
if (counter)
break;
@ -333,6 +336,8 @@ static Type *basetype(StorageClass *sclass) {
counter += INT;
else if (consume("long"))
counter += LONG;
else if (consume("signed"))
counter |= SIGNED;
switch (counter) {
case VOID:
@ -342,19 +347,28 @@ static Type *basetype(StorageClass *sclass) {
ty = bool_type;
break;
case CHAR:
case SIGNED + CHAR:
ty = char_type;
break;
case SHORT:
case SHORT + INT:
case SIGNED + SHORT:
case SIGNED + SHORT + INT:
ty = short_type;
break;
case INT:
case SIGNED:
case SIGNED + INT:
ty = int_type;
break;
case LONG:
case LONG + INT:
case LONG + LONG:
case LONG + LONG + INT:
case SIGNED + LONG:
case SIGNED + LONG + INT:
case SIGNED + LONG + LONG:
case SIGNED + LONG + LONG + INT:
ty = long_type;
break;
default:
@ -1118,7 +1132,7 @@ static bool is_typename(void) {
return peek("void") || peek("_Bool") || peek("char") || peek("short") ||
peek("int") || peek("long") || peek("enum") || peek("struct") ||
peek("typedef") || peek("static") || peek("extern") ||
find_typedef(token);
peek("signed") || find_typedef(token);
}
static Node *stmt(void) {

23
tests
View File

@ -709,6 +709,29 @@ int main() {
assert(6, add_all3(1,2,3,0), "add_all3(1,2,3,0)");
assert(5, add_all3(1,2,3,-1,0), "add_all3(1,2,3,-1,0)");
assert(1, sizeof(char), "sizeof(char)");
assert(1, sizeof(signed char), "sizeof(signed char)");
assert(1, sizeof(signed char signed), "sizeof(signed char signed)");
assert(2, sizeof(short), "sizeof(short)");
assert(2, sizeof(int short), "sizeof(int short)");
assert(2, sizeof(short int), "sizeof(short int)");
assert(2, sizeof(signed short), "sizeof(signed short)");
assert(2, sizeof(int short signed), "sizeof(int short signed)");
assert(4, sizeof(int), "sizeof(int)");
assert(4, sizeof(signed int), "sizeof(signed int)");
assert(4, sizeof(signed), "sizeof(signed)");
assert(4, sizeof(signed signed), "sizeof(signed signed)");
assert(8, sizeof(long), "sizeof(long)");
assert(8, sizeof(signed long), "sizeof(signed long)");
assert(8, sizeof(signed long int), "sizeof(signed long int)");
assert(8, sizeof(long long), "sizeof(long long)");
assert(8, sizeof(signed long long), "sizeof(signed long long)");
assert(8, sizeof(signed long long int), "sizeof(signed long long int)");
printf("OK\n");
return 0;
}

View File

@ -151,7 +151,7 @@ static char *starts_with_reserved(char *p) {
"char", "sizeof", "struct", "typedef", "short",
"long", "void", "_Bool", "enum", "static", "break",
"continue", "goto", "switch", "case", "default",
"extern", "_Alignof", "do"};
"extern", "_Alignof", "do", "signed"};
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++) {
int len = strlen(kw[i]);