aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-07 19:06:29 +0900
committernsfisis <nsfisis@gmail.com>2026-02-07 19:06:38 +0900
commit0ae64ed2c00f66c7f3ddec8689169bacafff87ea (patch)
treec72db385bca5de58910f2769168a7b0918309c21
parent7ba8a506a215846d14d71487807f5e525e9e5c16 (diff)
downloadducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.tar.gz
ducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.tar.zst
ducc-0ae64ed2c00f66c7f3ddec8689169bacafff87ea.zip
feat: partially support float/double
-rw-r--r--src/ast.c18
-rw-r--r--src/ast.h7
-rw-r--r--src/io.c10
-rw-r--r--src/io.h1
-rw-r--r--src/parse.c2
-rw-r--r--src/token.c6
-rw-r--r--src/token.h2
-rw-r--r--src/tokenize.c15
8 files changed, 55 insertions, 6 deletions
diff --git a/src/ast.c b/src/ast.c
index eb478c5..89c8aea 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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));
diff --git a/src/ast.h b/src/ast.h
index fe2f720..79d58d0 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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);
diff --git a/src/io.c b/src/io.c
index 897f1a3..469c868 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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);
diff --git a/src/io.h b/src/io.h
index 67bf055..71e25b0 100644
--- a/src/io.h
+++ b/src/io.h
@@ -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);