diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-08-03 13:19:40 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-08-15 10:06:21 +0900 |
| commit | e1de8fc36f11ac932707c7113eb4bf3ebc4b1f74 (patch) | |
| tree | 65c0a362dc9343b09a6e452d5526e39da834b986 | |
| parent | 185778aa3ae35252ae992f12a9dfc39a4eab5758 (diff) | |
| download | ducc-e1de8fc36f11ac932707c7113eb4bf3ebc4b1f74.tar.gz ducc-e1de8fc36f11ac932707c7113eb4bf3ebc4b1f74.tar.zst ducc-e1de8fc36f11ac932707c7113eb4bf3ebc4b1f74.zip | |
feat: support short type
| -rw-r--r-- | ast.c | 5 | ||||
| -rw-r--r-- | codegen.c | 8 | ||||
| -rw-r--r-- | parse.c | 16 | ||||
| -rw-r--r-- | tests/081.sh | 18 | ||||
| -rw-r--r-- | tokenize.c | 5 |
5 files changed, 44 insertions, 8 deletions
@@ -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) { @@ -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"); @@ -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 @@ -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")) { |
