Author: Armin Rigo <[email protected]>
Branch:
Changeset: r70:9af295178841
Date: 2014-11-18 17:16 +0100
http://bitbucket.org/cffi/creflect/changeset/9af295178841/
Log: First part of glob-003
diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -13,6 +13,15 @@
typedef void (*crx_trampoline0_fn)(void *args[], void *res);
typedef void (*crx_trampoline1_fn)(void *fn, void *args[], void *res);
+typedef union {
+ int as_int;
+ long as_long;
+ long long as_long_long;
+ unsigned int as_unsigned_int;
+ unsigned long as_unsigned_long;
+ unsigned long long as_unsigned_long_long;
+} crx_int_const_t;
+
#define CRX_SELF struct _crx_builder_s *
typedef struct _crx_builder_s {
crx_type_t *(*get_void_type)(CRX_SELF);
@@ -43,6 +52,8 @@
void *);
void (*define_func)(CRX_SELF, const char *, crx_type_t *,
crx_type_t *[], int, crx_trampoline0_fn, void *);
+ void (*define_int_const)(CRX_SELF, const char *, crx_type_t *,
+ crx_int_const_t *);
void (*error)(CRX_SELF, const char *);
} crx_builder_t;
#undef CRX_SELF
@@ -51,6 +62,16 @@
#define CRX_INT_TYPE(cb, expr, guessname) \
_creflect__int_type(cb, expr > 0, sizeof(expr), expr == 1, guessname)
+#define CRX_INT_CONST(cb, expr, vp) \
+ _creflect__int_expr(cb, vp, \
+ "integer constant '" #expr "' is too large", \
+ !(((expr) * 0 + 4) << (sizeof(int)*8-2)), \
+ !(((expr) * 0L + 4L) << (sizeof(long)*8-2)), \
+ ((expr) * 0 - 1) > 0, \
+ (expr) == (unsigned long long)(expr), \
+ (expr) == (long long)(expr), \
+ (unsigned long long)(expr))
+
__attribute__((unused))
static crx_type_t *_creflect__int_type(crx_builder_t *cb, int expr_positive,
size_t size_of_expr, int expr_equal_one,
@@ -63,3 +84,61 @@
else
return cb->get_unsigned_type(cb, size_of_expr, guessname);
}
+
+__attribute__((unused))
+static crx_type_t *_creflect__int_expr(crx_builder_t *cb, crx_int_const_t *vp,
+ const char *toobig,
+ int fits_int, int fits_long,
+ int unsign, int fits_ull, int fits_ll,
+ unsigned long long value)
+{
+ size_t size;
+ const char *name;
+
+ if (unsign) {
+ if (!fits_ull) {
+ goto overflow;
+ }
+ else if (fits_int) {
+ vp->as_unsigned_int = (unsigned int)value;
+ size = sizeof(unsigned int);
+ name = "unsigned int";
+ }
+ else if (fits_long) {
+ vp->as_unsigned_long = (unsigned long)value;
+ size = sizeof(unsigned long);
+ name = "unsigned long";
+ }
+ else {
+ vp->as_unsigned_long_long = (unsigned long long)value;
+ size = sizeof(unsigned long long);
+ name = "unsigned long long";
+ }
+ return cb->get_unsigned_type(cb, size, name);
+ }
+ else { /* signed */
+ if (!fits_ll) {
+ goto overflow;
+ }
+ else if (fits_int) {
+ vp->as_int = (int)value;
+ size = sizeof(int);
+ name = "int";
+ }
+ else if (fits_long) {
+ vp->as_long = (long)value;
+ size = sizeof(long);
+ name = "long";
+ }
+ else {
+ vp->as_long_long = (long long)value;
+ size = sizeof(long long);
+ name = "long long";
+ }
+ return cb->get_signed_type(cb, size, name);
+ }
+
+ overflow:
+ cb->error(cb, toobig);
+ return 0;
+}
diff --git a/test/cgcompile.c b/test/cgcompile.c
--- a/test/cgcompile.c
+++ b/test/cgcompile.c
@@ -174,6 +174,28 @@
printf("%s\n", ret->text);
}
+static void tst_define_int_const(crx_builder_t *cb, const char *name,
+ crx_type_t *t, crx_int_const_t *value)
+{
+ printf("INTCONST %s = %s ", name, t->text);
+ if (strcmp(t->text, "int") == 0)
+ printf("%d\n", value->as_int);
+ else if (strcmp(t->text, "long") == 0)
+ printf("%ld\n", value->as_long);
+ else if (strcmp(t->text, "long long") == 0)
+ printf("%lld\n", value->as_long_long);
+ else if (strcmp(t->text, "unsigned int") == 0)
+ printf("%u\n", value->as_unsigned_int);
+ else if (strcmp(t->text, "unsigned long") == 0)
+ printf("%lu\n", value->as_unsigned_long);
+ else if (strcmp(t->text, "unsigned long long") == 0)
+ printf("%llu\n", value->as_unsigned_long_long);
+ else {
+ printf("???\n");
+ abort();
+ }
+}
+
static void tst_error(crx_builder_t *cb, const char *msg)
{
printf("ERROR: %s\n", msg);
@@ -200,6 +222,7 @@
tst_define_type,
tst_define_var,
tst_define_func,
+ tst_define_int_const,
tst_error,
};
diff --git a/test/codegen/glob-003.c b/test/codegen/glob-003.c
--- a/test/codegen/glob-003.c
+++ b/test/codegen/glob-003.c
@@ -2,57 +2,14 @@
# ____________________________________________________________
-int testglob_003(char *r)
+void testglob_003(crx_builder_t *cb)
{
- int e = 0;
- char v[32];
- if (!r)
- return 64 + 1;
+ crx_type_t *t1;
{
- int z1, z2;
- (void)(ab << 1); /* check that 'ab' is an integer */
- z1 = !((ab * 0 + 4) << (sizeof(int)*8-2));
- z2 = !((ab * 0L + 4L) << (sizeof(long)*8-2));
- if ((ab * 0 - 1) > 0) { /* unsigned */
- if (ab != (unsigned long long)ab) {
- r += sprintf(r, "#error unsigned integer constant 'ab' is too
large\n");
- e = -1;
- goto f1;
- }
- if (z1) {
- r += sprintf(r, "unsigned int");
- sprintf(v, "%u", (unsigned int)ab);
- }
- else if (z2) {
- r += sprintf(r, "unsigned long");
- sprintf(v, "%lu", (unsigned long)ab);
- }
- else {
- r += sprintf(r, "unsigned long long");
- sprintf(v, "%llu", (unsigned long long)ab);
- }
- }
- else { /* signed */
- if (ab != (long long)ab) {
- r += sprintf(r, "#error integer constant 'ab' is too large\n");
- e = -1;
- goto f1;
- }
- if (z1) {
- r += sprintf(r, "int");
- sprintf(v, "%d", (int)ab);
- }
- else if (z2) {
- r += sprintf(r, "long");
- sprintf(v, "%ld", (long)ab);
- }
- else {
- r += sprintf(r, "long long");
- sprintf(v, "%lld", (long long)ab);
- }
- }
+ crx_int_const_t v;
+ (void)((ab) << 1); /* check that 'ab' is an integer */
+ t1 = CRX_INT_CONST(cb, ab, &v);
+ cb->define_int_const(cb, "ab", t1, &v);
+#expect INTCONST ab = int -42
}
- r += sprintf(r, " const ab = %s;\n", v);
- f1:
- return e;
}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit