summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c14
-rw-r--r--ffi.h2
-rw-r--r--txr.126
3 files changed, 40 insertions, 2 deletions
diff --git a/ffi.c b/ffi.c
index ca8ab24b..c4f5bcd1 100644
--- a/ffi.c
+++ b/ffi.c
@@ -123,7 +123,7 @@ val closure_s;
val sbit_s, ubit_s, bit_s;
-val enum_s;
+val enum_s, enumed_s;
val align_s;
@@ -3487,6 +3487,17 @@ val ffi_type_compile(val syntax)
lit("~a: enum name ~s must be bindable symbol or nil"),
self, name, nao);
return make_ffi_type_enum(xsyntax, enums, ffi_type_lookup(int_s), self);
+ } else if (sym == enumed_s) {
+ val base_type_syntax = cadr(syntax);
+ val name = caddr(syntax);
+ val enums = cdddr(syntax);
+ val xsyntax = list(enumed_s, base_type_syntax, name, nao);
+ val base_type = ffi_type_compile(base_type_syntax);
+ if (name && !bindable(name))
+ uw_throwf(error_s,
+ lit("~a: enum name ~s must be bindable symbol or nil"),
+ self, name, nao);
+ return make_ffi_type_enum(xsyntax, enums, base_type, self);
} else if (sym == align_s) {
val align = ffi_eval_expr(cadr(syntax), nil, nil);
ucnum al = c_num(align);
@@ -5339,6 +5350,7 @@ void ffi_init(void)
ubit_s = intern(lit("ubit"), user_package);
bit_s = intern(lit("bit"), user_package);
enum_s = intern(lit("enum"), user_package);
+ enumed_s = intern(lit("enumed"), user_package);
align_s = intern(lit("align"), user_package);
bool_s = intern(lit("bool"), user_package);
ffi_type_s = intern(lit("ffi-type"), user_package);
diff --git a/ffi.h b/ffi.h
index 34aca3c6..351dedb5 100644
--- a/ffi.h
+++ b/ffi.h
@@ -63,7 +63,7 @@ extern val closure_s;
extern val sbit_s, ubit_s, bit_s;
-extern val enum_s;
+extern val enum_s, enumed_s;
extern val align_s;
diff --git a/txr.1 b/txr.1
index 42c6bb0f..5cc0d178 100644
--- a/txr.1
+++ b/txr.1
@@ -54492,6 +54492,32 @@ that integer value itself rather than a symbol. If an integer value occurs
which is assigned to multiple enumeration symbols, it is not specified which
of those symbols is produced.
+.meIP (enumed < type < name >> {( sym << value ) | << sym }*)
+The
+.code enumed
+type operator is a generalization of
+.code enum
+which allows the base integer type of the enumeration to be specified.
+The following equivalence holds:
+
+.cblk
+ (enum n a b c ...) <--> (enumed int n a b c ...)
+.cble
+
+Any integer type or
+.meta typedef
+name may be specified for
+.metn type ,
+including any one of the endian types. The enumeration inherits its
+size, alignment and other foreign representation details from
+.metn type .
+
+The values associated with the enumeration symbols must be in
+the representation range of
+.metn type ,
+which is not checked until the conversion of a symbol
+through the enumeration is is attempted at run time.
+
.meIP (struct < name >> {( slot << type )}*)
The FFI
.code struct