summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-30 02:24:10 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-30 02:24:10 +0000
commit0427d254207a69e394499d1abaea768f484f1cb5 (patch)
treef16b97f798a6e4995ffe467b046efe70bb66904e
parentb27b128f97596236a4ce6a3d9b40ef3dfad84d06 (diff)
Improvements related to C23 (#112)
-rw-r--r--README.md12
-rw-r--r--README_ES.md11
-rw-r--r--README_ZH_CN.md11
-rw-r--r--README_ZH_TW.md11
-rw-r--r--src/ast/ast.c25
-rw-r--r--src/ast/ast.h4
-rw-r--r--src/codegen/codegen_decl.c4
-rw-r--r--src/codegen/compat.h6
-rw-r--r--src/parser/parser_expr.c2
-rw-r--r--src/parser/parser_type.c84
10 files changed, 168 insertions, 2 deletions
diff --git a/README.md b/README.md
index 75c4624..f03f605 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,7 @@ Join the discussion, share demos, ask questions, or report bugs in the official
- [C++ Interop](#c-interop)
- [CUDA Interop](#cuda-interop)
- [Objective-C Interop](#objective-c-interop)
+ - [C23 Support](#c23-support)
- [Contributing](#contributing)
- [Attributions](#attributions)
@@ -197,6 +198,8 @@ let y: const int = 10; // Read-only (Type qualified)
// y = 20; // Error: cannot assign to const
```
+> **Type Inference**: Zen C automatically infers types for initialized variables. It compiles to C23 `auto` on supported compilers, or GCC's `__auto_type` extension otherwise.
+
### 2. Primitive Types
| Type | C Equivalent | Description |
@@ -211,6 +214,8 @@ let y: const int = 10; // Read-only (Type qualified)
| `char` | `char` | Single character |
| `string` | `char*` | C-string (null-terminated) |
| `U0`, `u0`, `void` | `void` | Empty type |
+| `iN` (for example, `i256`) | `_BitInt(N)` | Arbitrary bit-width signed integer (C23) |
+| `uN` (for example, `u42`) | `unsigned _BitInt(N)` | Arbitrary bit-width unsigned integer (C23) |
### 3. Aggregate Types
@@ -1337,6 +1342,13 @@ let tid = local_id();
> **Note:** The `--cuda` flag sets `nvcc` as the compiler and implies `--cpp` mode. Requires the NVIDIA CUDA Toolkit.
+### C23 Support
+
+Zen C supports modern C23 features when using a compatible backend compiler (GCC 14+, Clang 14+, TCC (partial)).
+
+- **`auto`**: Zen C automatically maps type inference to standard C23 `auto` if `__STDC_VERSION__ >= 202300L`.
+- **`_BitInt(N)`**: Use `iN` and `uN` types (e.g., `i256`, `u12`, `i24`) to access C23 arbitrary-width integers.
+
### Objective-C Interop
Zen C can compile to Objective-C (`.m`) using the `--objc` flag, allowing you to use Objective-C frameworks (like Cocoa/Foundation) and syntax.
diff --git a/README_ES.md b/README_ES.md
index c5655e3..9040ea8 100644
--- a/README_ES.md
+++ b/README_ES.md
@@ -197,6 +197,8 @@ let y: const int = 10; // Solo lectura (Calificado por tipo)
// y = 20; // Error: no se puede asignar a una constante
```
+> **Inferencia de tipos**: Zen C infiere automáticamente los tipos para variables inicializadas. Se compila a `auto` de C23 en compiladores compatibles, o a la extensión `__auto_type` de GCC en otros casos.
+
### 2. Tipos Primitivos
| Tipo | Equivalente en C | Descripción |
@@ -211,6 +213,8 @@ let y: const int = 10; // Solo lectura (Calificado por tipo)
| `char` | `char` | Carácter único |
| `string` | `char*` | Cadena de C (terminada en null) |
| `U0`, `u0`, `void` | `void` | Tipo vacío |
+| `iN` (ej. `i256`) | `_BitInt(N)` | Entero con signo de ancho arbitrario (C23) |
+| `uN` (ej. `u42`) | `unsigned _BitInt(N)` | Entero sin signo de ancho arbitrario (C23) |
### 3. Tipos Agregados
@@ -1337,6 +1341,13 @@ let tid = local_id();
> **Nota:** La flag `--cuda` establece `nvcc` como el compilador e implica el modo `--cpp`. Requiere el NVIDIA CUDA Toolkit.
+### Soporte C23
+
+Zen C soporta características modernas de C23 cuando se utiliza un compilador backend compatible (GCC 14+, Clang 14+).
+
+- **`auto`**: Zen C mapea automáticamente la inferencia de tipos a `auto` estándar de C23 si `__STDC_VERSION__ >= 202300L`.
+- **`_BitInt(N)`**: Use tipos `iN` y `uN` (ej. `i256`, `u12`, `i24`) para acceder a enteros de ancho arbitrario de C23.
+
### Interop con Objective-C
Zen C puede compilarse a Objective-C (`.m`) usando la flag `--objc`, permitiéndote usar frameworks de Objective-C (como Cocoa/Foundation) y su sintaxis.
diff --git a/README_ZH_CN.md b/README_ZH_CN.md
index 6fce2d2..217e9ec 100644
--- a/README_ZH_CN.md
+++ b/README_ZH_CN.md
@@ -197,6 +197,8 @@ let y: const int = 10; // 只读 (类型修饰)
// y = 20; // 错误:无法赋值给 const 变量
```
+> **类型推导**:Zen C 自动推导初始化变量的类型。在支持的编译器上编译为 C23 的 `auto`,否则使用 GCC 的 `__auto_type` 扩展。
+
### 2. 原始类型
| 类型 | C 等效类型 | 描述 |
@@ -211,6 +213,8 @@ let y: const int = 10; // 只读 (类型修饰)
| `char` | `char` | 单个字符 |
| `string` | `char*` | C-string (以 null 结尾) |
| `U0`, `u0`, `void` | `void` | 空类型 |
+| `iN` (例 `i256`) | `_BitInt(N)` | 任意位宽有符号整数 (C23) |
+| `uN` (例 `u42`) | `unsigned _BitInt(N)` | 任意位宽无符号整数 (C23) |
### 3. 复合类型
@@ -1337,6 +1341,13 @@ let tid = local_id();
> **注意:** `--cuda` 标志设置 `nvcc` 为编译器并隐含 `--cpp` 模式。需要安装 NVIDIA CUDA Toolkit。
+### C23 支持
+
+当使用兼容的后端编译器(GCC 14+, Clang 14+)时,Zen C 支持现代 C23特性。
+
+- **`auto`**: 如果 `__STDC_VERSION__ >= 202300L`,Zen C 会自动将类型推导映射到标准 C23 `auto`。
+- **`_BitInt(N)`**: 使用 `iN` 和 `uN` 类型(例如 `i256`, `u12`, `i24`)访问 C23 任意位宽整数。
+
### Objective-C 互操作
Zen C 可以通过 `--objc` 标志编译为 Objective-C (`.m`),允许你使用 Objective-C 框架(如 Cocoa/Foundation)和语法。
diff --git a/README_ZH_TW.md b/README_ZH_TW.md
index fc9cef5..8618540 100644
--- a/README_ZH_TW.md
+++ b/README_ZH_TW.md
@@ -197,6 +197,8 @@ let y: const int = 10; // 只讀 (類型修飾)
// y = 20; // 錯誤:無法賦值給 const 變量
```
+> **型別推導**:Zen C 自動推導初始化變數的型別。在支援的編譯器上編譯為 C23 的 `auto`,否則使用 GCC 的 `__auto_type` 擴充功能。
+
### 2. 原始類型
| 類型 | C 等效類型 | 描述 |
@@ -211,6 +213,8 @@ let y: const int = 10; // 只讀 (類型修飾)
| `char` | `char` | 單個字符 |
| `string` | `char*` | C-string (以 null 結尾) |
| `U0`, `u0`, `void` | `void` | 空類型 |
+| `iN` (例 `i256`) | `_BitInt(N)` | 任意位元寬度有號整數 (C23) |
+| `uN` (例 `u42`) | `unsigned _BitInt(N)` | 任意位元寬度無號整數 (C23) |
### 3. 複合類型
@@ -1337,6 +1341,13 @@ let tid = local_id();
> **注意:** `--cuda` 標誌設置 `nvcc` 為編譯器並隱含 `--cpp` 模式。需要安裝 NVIDIA CUDA Toolkit。
+### C23 支援
+
+當使用相容的後端編譯器(GCC 14+, Clang 14+)時,Zen C 支援現代 C23 特性。
+
+- **`auto`**: 如果 `__STDC_VERSION__ >= 202300L`,Zen C 會自動將型別推導映射到標準 C23 `auto`。
+- **`_BitInt(N)`**: 使用 `iN` 和 `uN` 型別(例如 `i256`, `u12`, `i24`)存取 C23 任意位元寬度整數。
+
### Objective-C 互操作
Zen C 可以通過 `--objc` 標誌編譯為 Objective-C (`.m`),允許你使用 Objective-C 框架(如 Cocoa/Foundation)和語法。
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);