aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ast.c5
-rw-r--r--codegen.c8
-rw-r--r--parse.c16
-rw-r--r--tests/081.sh18
-rw-r--r--tokenize.c5
5 files changed, 44 insertions, 8 deletions
diff --git a/ast.c b/ast.c
index 3bcc9c7..e1c9ba6 100644
--- a/ast.c
+++ b/ast.c
@@ -3,6 +3,7 @@ enum TypeKind {
TypeKind_char,
TypeKind_int,
+ TypeKind_short,
TypeKind_long,
TypeKind_void,
TypeKind_ptr,
@@ -70,6 +71,8 @@ int type_sizeof(Type* ty) {
return 8;
} else if (ty->kind == TypeKind_char) {
return 1;
+ } else if (ty->kind == TypeKind_short) {
+ return 2;
} else if (ty->kind == TypeKind_int) {
return 4;
} else if (ty->kind == TypeKind_long) {
@@ -92,6 +95,8 @@ int type_alignof(Type* ty) {
return 8;
} else if (ty->kind == TypeKind_char) {
return 1;
+ } else if (ty->kind == TypeKind_short) {
+ return 2;
} else if (ty->kind == TypeKind_int) {
return 4;
} else if (ty->kind == TypeKind_long) {
diff --git a/codegen.c b/codegen.c
index 51254dc..7ca5fe7 100644
--- a/codegen.c
+++ b/codegen.c
@@ -93,7 +93,8 @@ void codegen_push_expr(const char* reg, int size) {
printf(" movsx %s, BYTE PTR [%s]\n", reg, reg);
printf(" push %s\n", reg);
} else if (size == 2) {
- unimplemented();
+ printf(" movsx %s, WORD PTR [%s]\n", reg, reg);
+ printf(" push %s\n", reg);
} else if (size == 4) {
printf(" movsxd %s, DWORD PTR [%s]\n", reg, reg);
printf(" push %s\n", reg);
@@ -226,6 +227,11 @@ void codegen_assign_expr(CodeGen* g, AstNode* ast) {
printf(" pop rax\n");
printf(" mov BYTE PTR [rax], dil\n");
printf(" push rdi\n");
+ } else if (sizeof_lhs == 2) {
+ printf(" pop rdi\n");
+ printf(" pop rax\n");
+ printf(" mov WORD PTR [rax], di\n");
+ printf(" push rdi\n");
} else if (sizeof_lhs == 4) {
printf(" pop rdi\n");
printf(" pop rax\n");
diff --git a/parse.c b/parse.c
index b9b8700..9c05519 100644
--- a/parse.c
+++ b/parse.c
@@ -358,10 +358,10 @@ AstNode* parse_postfix_expr(Parser* p) {
}
int is_type_token(Parser* p, Token* token) {
- if (token->kind == TokenKind_keyword_int || token->kind == TokenKind_keyword_long ||
- token->kind == TokenKind_keyword_char || token->kind == TokenKind_keyword_void ||
- token->kind == TokenKind_keyword_enum || token->kind == TokenKind_keyword_struct ||
- token->kind == TokenKind_keyword_const) {
+ if (token->kind == TokenKind_keyword_int || token->kind == TokenKind_keyword_short ||
+ token->kind == TokenKind_keyword_long || token->kind == TokenKind_keyword_char ||
+ token->kind == TokenKind_keyword_void || token->kind == TokenKind_keyword_enum ||
+ token->kind == TokenKind_keyword_struct || token->kind == TokenKind_keyword_const) {
return 1;
}
if (token->kind != TokenKind_ident) {
@@ -388,12 +388,14 @@ Type* parse_type(Parser* p) {
ty = p->typedefs[typedef_idx].ty;
} else {
ty = type_new(TypeKind_unknown);
- if (t->kind == TokenKind_keyword_int) {
+ if (t->kind == TokenKind_keyword_char) {
+ ty->kind = TypeKind_char;
+ } else if (t->kind == TokenKind_keyword_short) {
+ ty->kind = TypeKind_short;
+ } else if (t->kind == TokenKind_keyword_int) {
ty->kind = TypeKind_int;
} else if (t->kind == TokenKind_keyword_long) {
ty->kind = TypeKind_long;
- } else if (t->kind == TokenKind_keyword_char) {
- ty->kind = TypeKind_char;
} else if (t->kind == TokenKind_keyword_void) {
ty->kind = TypeKind_void;
} else if (t->kind == TokenKind_keyword_enum) {
diff --git a/tests/081.sh b/tests/081.sh
new file mode 100644
index 0000000..03239bc
--- /dev/null
+++ b/tests/081.sh
@@ -0,0 +1,18 @@
+set -e
+
+cat <<'EOF' > expected
+2 42
+8 123
+EOF
+
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ short a = 42;
+ printf("%zu %hd\n", sizeof(a), a);
+ short* b = &a;
+ *b = 123;
+ printf("%zu %hd\n", sizeof(b), *b);
+}
+EOF
diff --git a/tokenize.c b/tokenize.c
index 2642b5a..9bc14d6 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -31,6 +31,7 @@ enum TokenKind {
TokenKind_keyword_int,
TokenKind_keyword_long,
TokenKind_keyword_return,
+ TokenKind_keyword_short,
TokenKind_keyword_sizeof,
TokenKind_keyword_struct,
TokenKind_keyword_typeof,
@@ -129,6 +130,8 @@ const char* token_kind_stringify(TokenKind k) {
return "long";
else if (k == TokenKind_keyword_return)
return "return";
+ else if (k == TokenKind_keyword_short)
+ return "short";
else if (k == TokenKind_keyword_sizeof)
return "sizeof";
else if (k == TokenKind_keyword_struct)
@@ -245,6 +248,8 @@ void tokenize_all(Lexer* l) {
tok->kind = TokenKind_keyword_long;
} else if (string_equals_cstr(&pp_tok->raw, "return")) {
tok->kind = TokenKind_keyword_return;
+ } else if (string_equals_cstr(&pp_tok->raw, "short")) {
+ tok->kind = TokenKind_keyword_short;
} else if (string_equals_cstr(&pp_tok->raw, "sizeof")) {
tok->kind = TokenKind_keyword_sizeof;
} else if (string_equals_cstr(&pp_tok->raw, "struct")) {