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

Reply via email to