diff --git a/chibicc.h b/chibicc.h index 2b8883b..9ec8887 100644 --- a/chibicc.h +++ b/chibicc.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ typedef struct Token Token; struct Token { TokenKind kind; // Token kind Token *next; // Next token - int val; // If kind is TK_NUM, its value + int64_t val; // If kind is TK_NUM, its value char *loc; // Token location int len; // Token length Type *ty; // Used if TK_STR @@ -140,7 +141,7 @@ struct Node { Node *args; Obj *var; // Used if kind == ND_VAR - int val; // Used if kind == ND_NUM + int64_t val; // Used if kind == ND_NUM }; Obj *parse(Token *tok); @@ -152,6 +153,7 @@ Obj *parse(Token *tok); typedef enum { TY_CHAR, TY_INT, + TY_LONG, TY_PTR, TY_FUNC, TY_ARRAY, @@ -199,6 +201,7 @@ struct Member { extern Type *ty_char; extern Type *ty_int; +extern Type *ty_long; bool is_integer(Type *ty); Type *copy_type(Type *ty); diff --git a/codegen.c b/codegen.c index 30574ab..d77dfda 100644 --- a/codegen.c +++ b/codegen.c @@ -114,7 +114,7 @@ static void gen_expr(Node *node) { switch (node->kind) { case ND_NUM: - println(" mov $%d, %%rax", node->val); + println(" mov $%ld, %%rax", node->val); return; case ND_NEG: gen_expr(node->lhs); diff --git a/parse.c b/parse.c index f1c4b20..bfe5f4d 100644 --- a/parse.c +++ b/parse.c @@ -119,7 +119,7 @@ static Node *new_unary(NodeKind kind, Node *expr, Token *tok) { return node; } -static Node *new_num(int val, Token *tok) { +static Node *new_num(int64_t val, Token *tok) { Node *node = new_node(ND_NUM, tok); node->val = val; return node; @@ -198,7 +198,7 @@ static void push_tag_scope(Token *tok, Type *ty) { scope->tags = sc; } -// declspec = "char" | "int" | struct-decl +// declspec = "char" | "short" | "int" | "long" | struct-decl | union-decl static Type *declspec(Token **rest, Token *tok) { if (equal(tok, "char")) { *rest = tok->next; @@ -210,6 +210,11 @@ static Type *declspec(Token **rest, Token *tok) { return ty_int; } + if (equal(tok, "long")) { + *rest = tok->next; + return ty_long; + } + if (equal(tok, "struct")) return struct_decl(rest, tok->next); @@ -301,8 +306,8 @@ static Node *declaration(Token **rest, Token *tok) { // Returns true if a given token represents a type. static bool is_typename(Token *tok) { - return equal(tok, "char") || equal(tok, "int") || equal(tok, "struct") || - equal(tok, "union"); + return equal(tok, "char") || equal(tok, "short") || equal(tok, "int") || + equal(tok, "long") || equal(tok, "struct") || equal(tok, "union"); } // stmt = "return" expr ";" diff --git a/test/function.c b/test/function.c index 39fff11..951a281 100644 --- a/test/function.c +++ b/test/function.c @@ -31,6 +31,10 @@ int fib(int x) { return fib(x-1) + fib(x-2); } +int sub_long(long a, long b, long c) { + return a - b - c; +} + int main() { ASSERT(3, ret3()); ASSERT(8, add2(3, 5)); @@ -45,6 +49,8 @@ int main() { ASSERT(1, ({ sub_char(7, 3, 3); })); + ASSERT(1, sub_long(7, 3, 3)); + printf("OK\n"); return 0; } diff --git a/test/struct.c b/test/struct.c index 8975f43..7ca0374 100644 --- a/test/struct.c +++ b/test/struct.c @@ -49,6 +49,8 @@ int main() { ASSERT(8, ({ struct t {int a; int b;} x; struct t y; sizeof(y); })); ASSERT(8, ({ struct t {int a; int b;}; struct t y; sizeof(y); })); + ASSERT(16, ({ struct {char a; long b;} x; sizeof(x); })); + printf("OK\n"); return 0; } diff --git a/test/variable.c b/test/variable.c index ee8e4ee..a329a9a 100644 --- a/test/variable.c +++ b/test/variable.c @@ -50,6 +50,8 @@ int main() { ASSERT(7, ({ int x; int y; char z; char *a=&y; char *b=&z; b-a; })); ASSERT(1, ({ int x; char y; int z; char *a=&y; char *b=&z; b-a; })); + ASSERT(8, ({ long x; sizeof(x); })); + printf("OK\n"); return 0; } diff --git a/tokenize.c b/tokenize.c index 4c29bc2..3224369 100644 --- a/tokenize.c +++ b/tokenize.c @@ -126,7 +126,7 @@ static int read_punct(char *p) { static bool is_keyword(Token *tok) { static char *kw[] = { "return", "if", "else", "for", "while", "int", "sizeof", "char", - "struct", "union", + "struct", "union", "short", "long", }; for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++) diff --git a/type.c b/type.c index e5baf1f..18c6e9d 100644 --- a/type.c +++ b/type.c @@ -2,6 +2,7 @@ Type *ty_char = &(Type){TY_CHAR, 1, 1}; Type *ty_int = &(Type){TY_INT, 4, 4}; +Type *ty_long = &(Type){TY_LONG, 8, 8}; static Type *new_type(TypeKind kind, int size, int align) { Type *ty = calloc(1, sizeof(Type)); @@ -12,7 +13,8 @@ static Type *new_type(TypeKind kind, int size, int align) { } bool is_integer(Type *ty) { - return ty->kind == TY_CHAR || ty->kind == TY_INT; + TypeKind k = ty->kind; + return k == TY_CHAR || k == TY_INT || k == TY_LONG; } Type *copy_type(Type *ty) { @@ -77,7 +79,7 @@ void add_type(Node *node) { case ND_LE: case ND_NUM: case ND_FUNCALL: - node->ty = ty_int; + node->ty = ty_long; return; case ND_VAR: node->ty = node->var->ty;