commit 2056f41feb1c0e2b22fe954212c7da0ab7ecde44
parent 81145f1d272b6184f70ce4c393882dc34de3fbe3
Author: Sebastian <sebastian@sebsite.pw>
Date: Tue, 9 May 2023 21:59:04 -0400
types::c: initial commit
Adds new module with type aliases for C builtin types and commonly used
standard typedefs.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
8 files changed, 318 insertions(+), 0 deletions(-)
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -1397,6 +1397,16 @@ types() {
gen_ssa types
}
+types_c() {
+ if [ $testing -eq 1 ]
+ then
+ gen_srcs types::c +test.ha types.ha 'arch+$(ARCH).ha'
+ else
+ gen_srcs types::c types.ha 'arch+$(ARCH).ha'
+ fi
+ gen_ssa types::c types
+}
+
unix() {
gen_srcs -plinux unix \
+linux/nice.ha \
@@ -1584,6 +1594,7 @@ temp linux freebsd
time linux freebsd
time::chrono linux freebsd
types
+types::c
unix linux freebsd
unix::hosts linux freebsd
unix::passwd
diff --git a/stdlib.mk b/stdlib.mk
@@ -691,6 +691,12 @@ stdlib_deps_any += $(stdlib_types_any)
stdlib_types_linux = $(stdlib_types_any)
stdlib_types_freebsd = $(stdlib_types_any)
+# gen_lib types::c (any)
+stdlib_types_c_any = $(HARECACHE)/types/c/types_c-any.o
+stdlib_deps_any += $(stdlib_types_c_any)
+stdlib_types_c_linux = $(stdlib_types_c_any)
+stdlib_types_c_freebsd = $(stdlib_types_c_any)
+
# gen_lib unix (linux)
stdlib_unix_linux = $(HARECACHE)/unix/unix-linux.o
stdlib_deps_linux += $(stdlib_unix_linux)
@@ -2058,6 +2064,17 @@ $(HARECACHE)/types/types-any.ssa: $(stdlib_types_any_srcs) $(stdlib_rt)
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntypes \
-t$(HARECACHE)/types/types.td $(stdlib_types_any_srcs)
+# types::c (+any)
+stdlib_types_c_any_srcs = \
+ $(STDLIB)/types/c/types.ha \
+ $(STDLIB)/types/c/arch+$(ARCH).ha
+
+$(HARECACHE)/types/c/types_c-any.ssa: $(stdlib_types_c_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM))
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(HARECACHE)/types/c
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntypes::c \
+ -t$(HARECACHE)/types/c/types_c.td $(stdlib_types_c_any_srcs)
+
# unix (+linux)
stdlib_unix_linux_srcs = \
$(STDLIB)/unix/+linux/nice.ha \
@@ -2918,6 +2935,12 @@ testlib_deps_any += $(testlib_types_any)
testlib_types_linux = $(testlib_types_any)
testlib_types_freebsd = $(testlib_types_any)
+# gen_lib types::c (any)
+testlib_types_c_any = $(TESTCACHE)/types/c/types_c-any.o
+testlib_deps_any += $(testlib_types_c_any)
+testlib_types_c_linux = $(testlib_types_c_any)
+testlib_types_c_freebsd = $(testlib_types_c_any)
+
# gen_lib unix (linux)
testlib_unix_linux = $(TESTCACHE)/unix/unix-linux.o
testlib_deps_linux += $(testlib_unix_linux)
@@ -4346,6 +4369,18 @@ $(TESTCACHE)/types/types-any.ssa: $(testlib_types_any_srcs) $(testlib_rt)
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntypes \
-t$(TESTCACHE)/types/types.td $(testlib_types_any_srcs)
+# types::c (+any)
+testlib_types_c_any_srcs = \
+ $(STDLIB)/types/c/+test.ha \
+ $(STDLIB)/types/c/types.ha \
+ $(STDLIB)/types/c/arch+$(ARCH).ha
+
+$(TESTCACHE)/types/c/types_c-any.ssa: $(testlib_types_c_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM))
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/types/c
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntypes::c \
+ -t$(TESTCACHE)/types/c/types_c.td $(testlib_types_c_any_srcs)
+
# unix (+linux)
testlib_unix_linux_srcs = \
$(STDLIB)/unix/+linux/nice.ha \
diff --git a/types/c/+test.ha b/types/c/+test.ha
@@ -0,0 +1,18 @@
+@test fn sizes() void = {
+ static assert(size(short) == size(ushort));
+ static assert(size(long) == size(ulong));
+ static assert(size(longlong) == size(ulonglong));
+ static assert(size(intmax) == size(uintmax));
+ static assert(size(intptr) == size(uintptr));
+ static assert(size(ssize) == size(size));
+ static assert(size(short) <= size(int));
+ static assert(size(long) >= 4);
+ static assert(size(longlong) >= 8);
+
+ static assert(align(short) == align(ushort));
+ static assert(align(long) == align(ulong));
+ static assert(align(longlong) == align(ulonglong));
+ static assert(align(intmax) == align(uintmax));
+ static assert(align(intptr) == align(uintptr));
+ static assert(align(ssize) == align(size));
+};
diff --git a/types/c/README b/types/c/README
@@ -0,0 +1,44 @@
+types::c provides type aliases that are compatible with standard C builtin types
+and typedefs, as specified ISO/IEC 9899 and POSIX, as well as convenience
+functions for working with C types. This module is useful for C interop, for
+instance if an external function returns a [[long]] or a [[ssize]], or if you
+need to convert between a C string and a Hare string. The types provided here
+shouldn't be used for most Hare code.
+
+Some C types aren't provided by this module, since they are provided by the Hare
+language itself:
+
+--------------------------------------------------
+| Hare type | C type | C header |
+|===========|==============|=====================|
+| bool | _Bool, bool | stdbool.h (C99-C17) |
+|-----------|--------------|---------------------|
+| int | (signed) int | - |
+|-----------|--------------|---------------------|
+| size | size_t | stddef.h |
+|-----------|--------------|---------------------|
+| uint | unsigned int | - |
+|-----------|--------------|---------------------|
+| uintptr | uintptr_t | stdint.h |
+|-----------|--------------|---------------------|
+| valist | va_list | stdarg.h |
+--------------------------------------------------
+
+Some C types are mostly compatible with Hare types, with minor differences:
+
+--------------------------------------------------------------------------------
+| Hare type | C type | Differences |
+|===========|===================|==============================================|
+| void | void | Hare's void is a zero-size type; C's void is |
+| | | an incomplete opaque type. This distinction |
+| | | isn't relevant for C interop. In both |
+| | | languages, void pointers are used as generic |
+| | | pointers. |
+|-----------|-------------------|----------------------------------------------|
+| f32 | float _Imaginary | The types are equivalent in representation, |
+| f64 | double _Imaginary | but behavior differs when casting between |
+| [2]f32 | float _Complex | real, imaginary, and complex types. |
+| [2]f64 | double _Complex | |
+--------------------------------------------------------------------------------
+
+Additional low-level or implementation-specific types may be defined in [[rt]].
diff --git a/types/c/arch+aarch64.ha b/types/c/arch+aarch64.ha
@@ -0,0 +1,37 @@
+// Integer type compatible with `signed char`, as specified by ISO/IEC 9899.
+export type schar = i8;
+
+// Integer type compatible with `unsigned char`, as specified by ISO/IEC 9899.
+export type uchar = u8;
+
+// Integer type compatible with `signed short`, as specified by ISO/IEC 9899.
+export type short = i16;
+
+// Integer type compatible with `unsigned short`, as specified by ISO/IEC 9899.
+export type ushort = u16;
+
+// Integer type compatible with `signed long`, as specified by ISO/IEC 9899.
+export type long = i64;
+
+// Integer type compatible with `unsigned long`, as specified by ISO/IEC 9899.
+export type ulong = u64;
+
+// Integer type compatible with `signed long long`, as specified by ISO/IEC
+// 9899:1999.
+export type longlong = i64;
+
+// Integer type compatible with `unsigned long long`, as specified by ISO/IEC
+// 9899:1999.
+export type ulonglong = u64;
+
+// Integer type compatible with `intptr_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899.
+export type intptr = i64;
+
+// Integer type compatible with `ptrdiff_t`, as defined in <stddef.h> and
+// specified by ISO/IEC 9899.
+export type ptrdiff = i64;
+
+// Integer type compatible with `ssize_t`, as defined in <sys/types.h> and
+// specified by POSIX.
+export type ssize = i64;
diff --git a/types/c/arch+riscv64.ha b/types/c/arch+riscv64.ha
@@ -0,0 +1,37 @@
+// Integer type compatible with `signed char`, as specified by ISO/IEC 9899.
+export type schar = i8;
+
+// Integer type compatible with `unsigned char`, as specified by ISO/IEC 9899.
+export type uchar = u8;
+
+// Integer type compatible with `signed short`, as specified by ISO/IEC 9899.
+export type short = i16;
+
+// Integer type compatible with `unsigned short`, as specified by ISO/IEC 9899.
+export type ushort = u16;
+
+// Integer type compatible with `signed long`, as specified by ISO/IEC 9899.
+export type long = i64;
+
+// Integer type compatible with `unsigned long`, as specified by ISO/IEC 9899.
+export type ulong = u64;
+
+// Integer type compatible with `signed long long`, as specified by ISO/IEC
+// 9899:1999.
+export type longlong = i64;
+
+// Integer type compatible with `unsigned long long`, as specified by ISO/IEC
+// 9899:1999.
+export type ulonglong = u64;
+
+// Integer type compatible with `intptr_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899.
+export type intptr = i64;
+
+// Integer type compatible with `ptrdiff_t`, as defined in <stddef.h> and
+// specified by ISO/IEC 9899.
+export type ptrdiff = i64;
+
+// Integer type compatible with `ssize_t`, as defined in <sys/types.h> and
+// specified by POSIX.
+export type ssize = i64;
diff --git a/types/c/arch+x86_64.ha b/types/c/arch+x86_64.ha
@@ -0,0 +1,37 @@
+// Integer type compatible with `signed char`, as specified by ISO/IEC 9899.
+export type schar = i8;
+
+// Integer type compatible with `unsigned char`, as specified by ISO/IEC 9899.
+export type uchar = u8;
+
+// Integer type compatible with `signed short`, as specified by ISO/IEC 9899.
+export type short = i16;
+
+// Integer type compatible with `unsigned short`, as specified by ISO/IEC 9899.
+export type ushort = u16;
+
+// Integer type compatible with `signed long`, as specified by ISO/IEC 9899.
+export type long = i64;
+
+// Integer type compatible with `unsigned long`, as specified by ISO/IEC 9899.
+export type ulong = u64;
+
+// Integer type compatible with `signed long long`, as specified by ISO/IEC
+// 9899:1999.
+export type longlong = i64;
+
+// Integer type compatible with `unsigned long long`, as specified by ISO/IEC
+// 9899:1999.
+export type ulonglong = u64;
+
+// Integer type compatible with `intptr_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899.
+export type intptr = i64;
+
+// Integer type compatible with `ptrdiff_t`, as defined in <stddef.h> and
+// specified by ISO/IEC 9899.
+export type ptrdiff = i64;
+
+// Integer type compatible with `ssize_t`, as defined in <sys/types.h> and
+// specified by POSIX.
+export type ssize = i64;
diff --git a/types/c/types.ha b/types/c/types.ha
@@ -0,0 +1,99 @@
+use types;
+
+// Integer type compatible with `char8_t`, as defined in <uchar.h> and specified
+// by ISO/IEC 9899:2023.
+export type char8 = uchar;
+
+// Integer type compatible with `char16_t`, as defined in <uchar.h> and
+// specified by ISO/IEC 9899:2011.
+export type char16 = uint_least16;
+
+// Integer type compatible with `char32_t`, as defined in <uchar.h> and
+// specified by ISO/IEC 9899:2011.
+export type char32 = uint_least32;
+
+// Integer type compatible with `intmax_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+//
+// Note that this type isn't necessarily the actual maximum integer type. This
+// type should only be used when required for C interop.
+export type intmax = i64;
+
+// Integer type compatible with `uintmax_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+//
+// Note that this type isn't necessarily the actual maximum integer type. This
+// type should only be used when required for C interop.
+export type uintmax = u64;
+
+// Integer type compatible with `int_least8_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_least8 = i8;
+
+// Integer type compatible with `int_least16_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_least16 = i16;
+
+// Integer type compatible with `int_least32_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_least32 = i32;
+
+// Integer type compatible with `int_least64_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_least64 = i64;
+
+// Integer type compatible with `uint_least8_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_least8 = u8;
+
+// Integer type compatible with `uint_least16_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_least16 = u16;
+
+// Integer type compatible with `uint_least32_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_least32 = u32;
+
+// Integer type compatible with `uint_least64_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_least64 = u64;
+
+// Integer type compatible with `int_fast8_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_fast8 = i8;
+
+// Integer type compatible with `int_fast16_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_fast16 = i16;
+
+// Integer type compatible with `int_fast32_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_fast32 = i32;
+
+// Integer type compatible with `int_fast64_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type int_fast64 = i64;
+
+// Integer type compatible with `uint_fast8_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_fast8 = u8;
+
+// Integer type compatible with `uint_fast16_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_fast16 = u16;
+
+// Integer type compatible with `uint_fast32_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_fast32 = u32;
+
+// Integer type compatible with `uint_fast64_t`, as defined in <stdint.h> and
+// specified by ISO/IEC 9899:1999.
+export type uint_fast64 = u64;
+
+// Integer type compatible with `wchar_t`, as defined in <stddef.h> and
+// specified by ISO/IEC 9899.
+export type wchar = i32;
+
+// Integer type compatible with `wint_t`, as defined in <stdint.h> and specified
+// by ISO/IEC 9899:1994.
+export type wint = u32;