diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-30 02:24:10 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-30 02:24:10 +0000 |
| commit | 0427d254207a69e394499d1abaea768f484f1cb5 (patch) | |
| tree | f16b97f798a6e4995ffe467b046efe70bb66904e /src | |
| parent | b27b128f97596236a4ce6a3d9b40ef3dfad84d06 (diff) | |
Improvements related to C23 (#112)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast/ast.c | 25 | ||||
| -rw-r--r-- | src/ast/ast.h | 4 | ||||
| -rw-r--r-- | src/codegen/codegen_decl.c | 4 | ||||
| -rw-r--r-- | src/codegen/compat.h | 6 | ||||
| -rw-r--r-- | src/parser/parser_expr.c | 2 | ||||
| -rw-r--r-- | src/parser/parser_type.c | 84 |
6 files changed, 123 insertions, 2 deletions
diff --git a/src/ast/ast.c b/src/ast/ast.c index f4922a6..439a9f5 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -100,6 +100,7 @@ int is_integer_type(Type *t) t->kind == TYPE_I64 || t->kind == TYPE_U64 || t->kind == TYPE_USIZE || t->kind == TYPE_ISIZE || t->kind == TYPE_BYTE || t->kind == TYPE_RUNE || t->kind == TYPE_UINT || t->kind == TYPE_I128 || t->kind == TYPE_U128 || + t->kind == TYPE_BITINT || t->kind == TYPE_UBITINT || (t->kind == TYPE_STRUCT && t->name && (0 == strcmp(t->name, "int8_t") || 0 == strcmp(t->name, "uint8_t") || 0 == strcmp(t->name, "int16_t") || 0 == strcmp(t->name, "uint16_t") || @@ -262,6 +263,18 @@ static char *type_to_string_impl(Type *t) return xstrdup("int"); case TYPE_FLOAT: return xstrdup("float"); + case TYPE_BITINT: + { + char *res = xmalloc(32); + sprintf(res, "i%d", t->array_size); + return res; + } + case TYPE_UBITINT: + { + char *res = xmalloc(32); + sprintf(res, "u%d", t->array_size); + return res; + } case TYPE_POINTER: { @@ -452,6 +465,18 @@ static char *type_to_c_string_impl(Type *t) return xstrdup("int"); case TYPE_FLOAT: return xstrdup("float"); + case TYPE_BITINT: + { + char *res = xmalloc(32); + sprintf(res, "_BitInt(%d)", t->array_size); + return res; + } + case TYPE_UBITINT: + { + char *res = xmalloc(40); + sprintf(res, "unsigned _BitInt(%d)", t->array_size); + return res; + } case TYPE_POINTER: { diff --git a/src/ast/ast.h b/src/ast/ast.h index a868bf0..71d9943 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -59,6 +59,8 @@ typedef enum TYPE_FUNCTION, ///< Function pointer or reference. TYPE_GENERIC, ///< Generic type parameter (T). TYPE_ALIAS, ///< Opaque type alias. + TYPE_BITINT, ///< C23 _BitInt(N). + TYPE_UBITINT, ///< C23 unsigned _BitInt(N). TYPE_UNKNOWN ///< Unknown/unresolved type. } TypeKind; @@ -75,7 +77,7 @@ typedef struct Type int is_const; ///< 1 if const-qualified. int is_explicit_struct; ///< 1 if defined with "struct" keyword explicitly. int is_raw; // Raw function pointer (fn*) - int array_size; ///< Size for fixed-size arrays. + int array_size; ///< Size for fixed-size arrays. For TYPE_BITINT, this is the bit width. union { int is_varargs; ///< 1 if function type is variadic. diff --git a/src/codegen/codegen_decl.c b/src/codegen/codegen_decl.c index 31513ef..0b78676 100644 --- a/src/codegen/codegen_decl.c +++ b/src/codegen/codegen_decl.c @@ -85,7 +85,11 @@ void emit_preamble(ParserContext *ctx, FILE *out) else { // C mode + fputs("#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202300L\n", out); + fputs("#define ZC_AUTO auto\n", out); + fputs("#else\n", out); fputs("#define ZC_AUTO __auto_type\n", out); + fputs("#endif\n", out); fputs("#define ZC_CAST(T, x) ((T)(x))\n", out); fputs(ZC_TCC_COMPAT_STR, out); fputs("static inline const char* _z_bool_str(_Bool b) { return b ? \"true\" : " diff --git a/src/codegen/compat.h b/src/codegen/compat.h index 63a5af5..f8d9a4e 100644 --- a/src/codegen/compat.h +++ b/src/codegen/compat.h @@ -14,7 +14,11 @@ #define ZC_EXTERN_C_END } #else /* C mode */ -#define ZC_AUTO __auto_type ///< Auto type inference. +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202300L +#define ZC_AUTO auto ///< C23 standard auto. +#else +#define ZC_AUTO __auto_type ///< GCC/Clang extension. +#endif #define ZC_CAST(T, x) ((T)(x)) ///< Explicit cast. #define ZC_REINTERPRET(T, x) ((T)(x)) ///< Reinterpret cast. #define ZC_EXTERN_C ///< Extern "C" (no-op in C). diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index 51d2baa..6156cc0 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -148,6 +148,8 @@ int is_type_copy(ParserContext *ctx, Type *t) case TYPE_POINTER: // Pointers are Copy case TYPE_FUNCTION: case TYPE_ENUM: // Enums are integers + case TYPE_BITINT: + case TYPE_UBITINT: return 1; case TYPE_STRUCT: diff --git a/src/parser/parser_type.c b/src/parser/parser_type.c index 65f2848..49e961c 100644 --- a/src/parser/parser_type.c +++ b/src/parser/parser_type.c @@ -300,6 +300,90 @@ Type *parse_type_base(ParserContext *ctx, Lexer *l) free(name); return type_new(TYPE_I16); } + + // C23 BitInt Support (i42, u256, etc.) + if ((name[0] == 'i' || name[0] == 'u') && isdigit(name[1])) + { + // Verify it is a purely numeric suffix + int valid = 1; + for (size_t k = 1; k < strlen(name); k++) + { + if (!isdigit(name[k])) + { + valid = 0; + break; + } + } + if (valid) + { + int width = atoi(name + 1); + if (width > 0) + { + // Map standard widths to standard types for standard ABI/C compabitility + if (name[0] == 'i') + { + if (width == 8) + { + free(name); + return type_new(TYPE_I8); + } + if (width == 16) + { + free(name); + return type_new(TYPE_I16); + } + if (width == 32) + { + free(name); + return type_new(TYPE_I32); + } + if (width == 64) + { + free(name); + return type_new(TYPE_I64); + } + if (width == 128) + { + free(name); + return type_new(TYPE_I128); + } + } + else + { + if (width == 8) + { + free(name); + return type_new(TYPE_U8); + } + if (width == 16) + { + free(name); + return type_new(TYPE_U16); + } + if (width == 32) + { + free(name); + return type_new(TYPE_U32); + } + if (width == 64) + { + free(name); + return type_new(TYPE_U64); + } + if (width == 128) + { + free(name); + return type_new(TYPE_U128); + } + } + + Type *t = type_new(name[0] == 'u' ? TYPE_UBITINT : TYPE_BITINT); + t->array_size = width; + free(name); + return t; + } + } + } if (strcmp(name, "u16") == 0) { free(name); |
