From f130eea047e092a9b8c70ac06e39de026c2f212e Mon Sep 17 00:00:00 2001 From: treeform Date: Mon, 25 May 2026 10:08:13 -0700 Subject: [PATCH] Add C ergonomics --- src/genny/languages/c.nim | 54 +++++++++++++++++++----------- tests/generated/test.h | 70 ++++++++++++++++++++++----------------- 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/src/genny/languages/c.nim b/src/genny/languages/c.nim index d820fe5..6ee30df 100644 --- a/src/genny/languages/c.nim +++ b/src/genny/languages/c.nim @@ -31,23 +31,23 @@ proc exportTypeC(sym: NimNode): string = else: result = case typ.repr: - of "string": "char*" + of "string", "cstring": "const char*" of "bool": "char" - of "byte": "char" - of "int8": "char" - of "int16": "short" - of "int32": "int" - of "int64": "long long" - of "int": "long long" - of "uint8": "unsigned char" - of "uint16": "unsigned short" - of "uint32": "unsigned int" - of "uint64": "unsigned long long" - of "uint": "unsigned long long" + of "byte": "uint8_t" + of "int8": "int8_t" + of "int16": "int16_t" + of "int32": "int32_t" + of "int64": "int64_t" + of "int": "intptr_t" + of "uint8": "uint8_t" + of "uint16": "uint16_t" + of "uint32": "uint32_t" + of "uint64": "uint64_t" + of "uint": "uintptr_t" of "float32": "float" of "float64": "double" of "float": "double" - of "Rune": "int" + of "Rune": "int32_t" of "Vec2": "Vector2" of "Mat3": "Matrix3" of "", "nil": "void" @@ -166,7 +166,7 @@ proc exportObjectC*(sym: NimNode, constructor: NimNode) = dllProc(&"$lib_{toSnakeCase(objName)}_eq", [&"{objName} a", &"{objName} b"], "char") proc genRefObject(objName: string) = - types.add &"typedef long long {objName};\n\n" + types.add &"typedef struct {objName}Handle* {objName};\n\n" let unrefLibProc = &"$lib_{toSnakeCase(objName)}_unref" @@ -174,10 +174,10 @@ proc genRefObject(objName: string) = proc genSeqProcs(objName, procPrefix, selfSuffix: string, entryType: NimNode) = let objArg = objName & " " & toSnakeCase(objName) - dllProc(&"{procPrefix}_len", [objArg], "long long") - dllProc(&"{procPrefix}_get", [objArg, "long long index"], exportTypeC(entryType)) - dllProc(&"{procPrefix}_set", [objArg, "long long index", exportTypeC(entryType, "value")], "void") - dllProc(&"{procPrefix}_delete", [objArg, "long long index"], "void") + dllProc(&"{procPrefix}_len", [objArg], "intptr_t") + dllProc(&"{procPrefix}_get", [objArg, "intptr_t index"], exportTypeC(entryType)) + dllProc(&"{procPrefix}_set", [objArg, "intptr_t index", exportTypeC(entryType, "value")], "void") + dllProc(&"{procPrefix}_delete", [objArg, "intptr_t index"], "void") dllProc(&"{procPrefix}_add", [objArg, exportTypeC(entryType, "value")], "void") dllProc(&"{procPrefix}_clear", [objArg], "void") @@ -249,6 +249,22 @@ const header = """ #ifndef INCLUDE_$LIB_H #define INCLUDE_$LIB_H +#include + +""" + +const externCStart = """ +#ifdef __cplusplus +extern "C" { +#endif + +""" + +const externCEnd = """ +#ifdef __cplusplus +} +#endif + """ const footer = """ @@ -257,6 +273,6 @@ const footer = """ proc writeC*(dir, lib: string) = createDir(dir) - writeFile(&"{dir}/{toSnakeCase(lib)}.h", (header & types & procs & footer) + writeFile(&"{dir}/{toSnakeCase(lib)}.h", (header & types & externCStart & procs & externCEnd & footer) .replace("$lib", toSnakeCase(lib)).replace("$LIB", lib.toUpperAscii()) ) diff --git a/tests/generated/test.h b/tests/generated/test.h index 13b6c3e..d6e3909 100644 --- a/tests/generated/test.h +++ b/tests/generated/test.h @@ -1,6 +1,8 @@ #ifndef INCLUDE_TEST_H #define INCLUDE_TEST_H +#include + #define SIMPLE_CONST 123 typedef char SimpleEnum; @@ -9,31 +11,35 @@ typedef char SimpleEnum; #define THIRD 2 typedef struct SimpleObj { - long long simple_a; - char simple_b; + intptr_t simple_a; + uint8_t simple_b; char simple_c; } SimpleObj; -typedef long long SimpleRefObj; +typedef struct SimpleRefObjHandle* SimpleRefObj; -typedef long long SeqInt; +typedef struct SeqIntHandle* SeqInt; -typedef long long RefObjWithSeq; +typedef struct RefObjWithSeqHandle* RefObjWithSeq; typedef struct SimpleObjWithProc { - long long simple_a; - char simple_b; + intptr_t simple_a; + uint8_t simple_b; char simple_c; } SimpleObjWithProc; -typedef long long SeqString; +typedef struct SeqStringHandle* SeqString; + +#ifdef __cplusplus +extern "C" { +#endif /** * Returns the integer passed in. */ -long long test_simple_call(long long a); +intptr_t test_simple_call(intptr_t a); -SimpleObj test_simple_obj(long long simple_a, char simple_b, char simple_c); +SimpleObj test_simple_obj(intptr_t simple_a, uint8_t simple_b, char simple_c); char test_simple_obj_eq(SimpleObj a, SimpleObj b); @@ -41,13 +47,13 @@ void test_simple_ref_obj_unref(SimpleRefObj simple_ref_obj); SimpleRefObj test_new_simple_ref_obj(); -long long test_simple_ref_obj_get_simple_ref_a(SimpleRefObj simple_ref_obj); +intptr_t test_simple_ref_obj_get_simple_ref_a(SimpleRefObj simple_ref_obj); -void test_simple_ref_obj_set_simple_ref_a(SimpleRefObj simple_ref_obj, long long value); +void test_simple_ref_obj_set_simple_ref_a(SimpleRefObj simple_ref_obj, intptr_t value); -char test_simple_ref_obj_get_simple_ref_b(SimpleRefObj simple_ref_obj); +uint8_t test_simple_ref_obj_get_simple_ref_b(SimpleRefObj simple_ref_obj); -void test_simple_ref_obj_set_simple_ref_b(SimpleRefObj simple_ref_obj, char value); +void test_simple_ref_obj_set_simple_ref_b(SimpleRefObj simple_ref_obj, uint8_t value); /** * Does some thing with SimpleRefObj. @@ -58,15 +64,15 @@ void test_seq_int_unref(SeqInt seq_int); SeqInt test_new_seq_int(); -long long test_seq_int_len(SeqInt seq_int); +intptr_t test_seq_int_len(SeqInt seq_int); -long long test_seq_int_get(SeqInt seq_int, long long index); +intptr_t test_seq_int_get(SeqInt seq_int, intptr_t index); -void test_seq_int_set(SeqInt seq_int, long long index, long long value); +void test_seq_int_set(SeqInt seq_int, intptr_t index, intptr_t value); -void test_seq_int_delete(SeqInt seq_int, long long index); +void test_seq_int_delete(SeqInt seq_int, intptr_t index); -void test_seq_int_add(SeqInt seq_int, long long value); +void test_seq_int_add(SeqInt seq_int, intptr_t value); void test_seq_int_clear(SeqInt seq_int); @@ -74,19 +80,19 @@ void test_ref_obj_with_seq_unref(RefObjWithSeq ref_obj_with_seq); RefObjWithSeq test_new_ref_obj_with_seq(); -long long test_ref_obj_with_seq_data_len(RefObjWithSeq ref_obj_with_seq); +intptr_t test_ref_obj_with_seq_data_len(RefObjWithSeq ref_obj_with_seq); -char test_ref_obj_with_seq_data_get(RefObjWithSeq ref_obj_with_seq, long long index); +uint8_t test_ref_obj_with_seq_data_get(RefObjWithSeq ref_obj_with_seq, intptr_t index); -void test_ref_obj_with_seq_data_set(RefObjWithSeq ref_obj_with_seq, long long index, char value); +void test_ref_obj_with_seq_data_set(RefObjWithSeq ref_obj_with_seq, intptr_t index, uint8_t value); -void test_ref_obj_with_seq_data_delete(RefObjWithSeq ref_obj_with_seq, long long index); +void test_ref_obj_with_seq_data_delete(RefObjWithSeq ref_obj_with_seq, intptr_t index); -void test_ref_obj_with_seq_data_add(RefObjWithSeq ref_obj_with_seq, char value); +void test_ref_obj_with_seq_data_add(RefObjWithSeq ref_obj_with_seq, uint8_t value); void test_ref_obj_with_seq_data_clear(RefObjWithSeq ref_obj_with_seq); -SimpleObjWithProc test_simple_obj_with_proc(long long simple_a, char simple_b, char simple_c); +SimpleObjWithProc test_simple_obj_with_proc(intptr_t simple_a, uint8_t simple_b, char simple_c); char test_simple_obj_with_proc_eq(SimpleObjWithProc a, SimpleObjWithProc b); @@ -96,18 +102,22 @@ void test_seq_string_unref(SeqString seq_string); SeqString test_new_seq_string(); -long long test_seq_string_len(SeqString seq_string); +intptr_t test_seq_string_len(SeqString seq_string); -char* test_seq_string_get(SeqString seq_string, long long index); +const char* test_seq_string_get(SeqString seq_string, intptr_t index); -void test_seq_string_set(SeqString seq_string, long long index, char* value); +void test_seq_string_set(SeqString seq_string, intptr_t index, const char* value); -void test_seq_string_delete(SeqString seq_string, long long index); +void test_seq_string_delete(SeqString seq_string, intptr_t index); -void test_seq_string_add(SeqString seq_string, char* value); +void test_seq_string_add(SeqString seq_string, const char* value); void test_seq_string_clear(SeqString seq_string); SeqString test_get_datas(); +#ifdef __cplusplus +} +#endif + #endif