diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-07 19:06:29 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-07 19:06:38 +0900 |
| commit | 0ae64ed2c00f66c7f3ddec8689169bacafff87ea (patch) | |
| tree | c72db385bca5de58910f2769168a7b0918309c21 | |
| parent | 7ba8a506a215846d14d71487807f5e525e9e5c16 (diff) | |
| download | ducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.tar.gz ducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.tar.zst ducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.zip | |
feat: partially support float/double
| -rw-r--r-- | src/ast.c | 18 | ||||
| -rw-r--r-- | src/ast.h | 7 | ||||
| -rw-r--r-- | src/io.c | 10 | ||||
| -rw-r--r-- | src/io.h | 1 | ||||
| -rw-r--r-- | src/parse.c | 2 | ||||
| -rw-r--r-- | src/token.c | 6 | ||||
| -rw-r--r-- | src/token.h | 2 | ||||
| -rw-r--r-- | src/tokenize.c | 15 |
8 files changed, 55 insertions, 6 deletions
@@ -130,10 +130,10 @@ int type_sizeof(Type* ty) { return 1; else if (ty->kind == TypeKind_short || ty->kind == TypeKind_ushort) return 2; - else if (ty->kind == TypeKind_int || ty->kind == TypeKind_uint) + else if (ty->kind == TypeKind_int || ty->kind == TypeKind_uint || ty->kind == TypeKind_float) return 4; else if (ty->kind == TypeKind_long || ty->kind == TypeKind_ulong || ty->kind == TypeKind_llong || - ty->kind == TypeKind_ullong) + ty->kind == TypeKind_ullong || ty->kind == TypeKind_double) return 8; else if (ty->kind == TypeKind_struct) return type_sizeof_struct(ty); @@ -161,10 +161,10 @@ int type_alignof(Type* ty) { return 1; else if (ty->kind == TypeKind_short || ty->kind == TypeKind_ushort) return 2; - else if (ty->kind == TypeKind_int || ty->kind == TypeKind_uint) + else if (ty->kind == TypeKind_int || ty->kind == TypeKind_uint || ty->kind == TypeKind_float) return 4; else if (ty->kind == TypeKind_long || ty->kind == TypeKind_ulong || ty->kind == TypeKind_llong || - ty->kind == TypeKind_ullong) + ty->kind == TypeKind_ullong || ty->kind == TypeKind_double) return 8; else if (ty->kind == TypeKind_struct) return type_alignof_struct(ty); @@ -240,6 +240,8 @@ const char* astnode_kind_stringify(AstNodeKind k) { return "if_stmt"; case AstNodeKind_int_expr: return "int_expr"; + case AstNodeKind_double_expr: + return "double_expr"; case AstNodeKind_label_stmt: return "label_stmt"; case AstNodeKind_list: @@ -325,6 +327,14 @@ AstNode* ast_new_int(int v) { return e; } +AstNode* ast_new_double(double v) { + AstNode* e = ast_new(AstNodeKind_double_expr); + e->as.double_expr = calloc(1, sizeof(DoubleExprNode)); + e->as.double_expr->value = v; + e->ty = type_new(TypeKind_double); + return e; +} + AstNode* ast_new_unary_expr(int op, AstNode* operand) { AstNode* e = ast_new(AstNodeKind_unary_expr); e->as.unary_expr = calloc(1, sizeof(UnaryExprNode)); @@ -112,6 +112,7 @@ typedef enum { AstNodeKind_gvar_decl, AstNodeKind_if_stmt, AstNodeKind_int_expr, + AstNodeKind_double_expr, AstNodeKind_label_stmt, AstNodeKind_list, AstNodeKind_logical_expr, @@ -143,6 +144,10 @@ typedef struct { } IntExprNode; typedef struct { + double value; +} DoubleExprNode; + +typedef struct { int idx; } StrExprNode; @@ -325,6 +330,7 @@ struct AstNode { Type* ty; union { IntExprNode* int_expr; + DoubleExprNode* double_expr; StrExprNode* str_expr; UnaryExprNode* unary_expr; BinaryExprNode* binary_expr; @@ -374,6 +380,7 @@ AstNode* ast_new(AstNodeKind kind); AstNode* ast_new_list(int capacity); void ast_append(AstNode* list, AstNode* item); AstNode* ast_new_int(int v); +AstNode* ast_new_double(double v); AstNode* ast_new_unary_expr(int op, AstNode* operand); AstNode* ast_new_binary_expr(int op, AstNode* lhs, AstNode* rhs); @@ -107,6 +107,16 @@ char infile_next_char(InFile* f) { return c; } +char infile_peek_char2(InFile* f) { + int saved_pos = f->pos; + int saved_line = f->loc.line; + infile_next_char(f); + char c = infile_peek_char(f); + f->pos = saved_pos; + f->loc.line = saved_line; + return c; +} + bool infile_consume_if(InFile* f, char expected) { if (infile_peek_char(f) == expected) { infile_next_char(f); @@ -19,6 +19,7 @@ typedef struct { InFile* infile_open(const char* filename); bool infile_eof(InFile* f); char infile_peek_char(InFile* f); +char infile_peek_char2(InFile* f); char infile_next_char(InFile* f); bool infile_consume_if(InFile* f, char expected); diff --git a/src/parse.c b/src/parse.c index 3f55a51..51a85ff 100644 --- a/src/parse.c +++ b/src/parse.c @@ -623,6 +623,8 @@ static AstNode* parse_primary_expr(Parser* p) { Token* t = next_token(p); if (t->kind == TokenKind_literal_int) { return ast_new_int(t->value.integer); + } else if (t->kind == TokenKind_literal_double) { + return ast_new_double(t->value.floating); } else if (t->kind == TokenKind_keyword_true) { return ast_new_int(1); } else if (t->kind == TokenKind_keyword_false) { diff --git a/src/token.c b/src/token.c index a7b2afd..726a912 100644 --- a/src/token.c +++ b/src/token.c @@ -233,6 +233,8 @@ const char* token_kind_stringify(TokenKind k) { return "<="; else if (k == TokenKind_literal_int) return "<integer>"; + else if (k == TokenKind_literal_double) + return "<double>"; else if (k == TokenKind_literal_str) return "<string>"; else if (k == TokenKind_lshift) @@ -301,6 +303,10 @@ const char* token_stringify(Token* tok) { char* buf = calloc(10, sizeof(char)); sprintf(buf, "%d", tok->value.integer); return buf; + } else if (k == TokenKind_literal_double) { + char* buf = calloc(32, sizeof(char)); + sprintf(buf, "%g", tok->value.floating); + return buf; } else if (k == TokenKind_other || k == TokenKind_character_constant || k == TokenKind_ident || k == TokenKind_literal_str || k == TokenKind_header_name) { return tok->value.string; diff --git a/src/token.h b/src/token.h index b81c10a..6c4f20b 100644 --- a/src/token.h +++ b/src/token.h @@ -125,6 +125,7 @@ typedef enum { TokenKind_ident, TokenKind_le, TokenKind_literal_int, + TokenKind_literal_double, TokenKind_literal_str, TokenKind_lshift, TokenKind_lt, @@ -155,6 +156,7 @@ bool is_pp_directive(TokenKind k); typedef union { const char* string; int integer; + double floating; } TokenValue; typedef struct { diff --git a/src/tokenize.c b/src/tokenize.c index ceba12d..6e9ad43 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -350,8 +350,19 @@ static void do_tokenize_all(Lexer* l) { strbuilder_append_char(&builder, infile_peek_char(l->src)); infile_next_char(l->src); } - tok->kind = TokenKind_literal_int; - tok->value.integer = strtol(builder.buf, NULL, 0); + if (infile_peek_char(l->src) == '.' && isdigit(infile_peek_char2(l->src))) { + strbuilder_append_char(&builder, infile_peek_char(l->src)); + infile_next_char(l->src); + while (isdigit(infile_peek_char(l->src))) { + strbuilder_append_char(&builder, infile_peek_char(l->src)); + infile_next_char(l->src); + } + tok->kind = TokenKind_literal_double; + tok->value.floating = strtod(builder.buf, NULL); + } else { + tok->kind = TokenKind_literal_int; + tok->value.integer = strtol(builder.buf, NULL, 0); + } } else if (isalpha(c) || c == '_') { StrBuilder builder; strbuilder_init(&builder); |
