Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r106:808cb0b998ee
Date: 2014-11-29 09:21 +0100
http://bitbucket.org/cffi/creflect/changeset/808cb0b998ee/

Log:    simple function types

diff --git a/creflect/src/c_decl_parser.c b/creflect/src/c_decl_parser.c
--- a/creflect/src/c_decl_parser.c
+++ b/creflect/src/c_decl_parser.c
@@ -68,6 +68,16 @@
     return (is_ident_first(x) || is_digit(x));
 }
 
+static int is_following_token_this_char(crxp_token_t *tok, char expected)
+{
+    const char *p = tok->p + tok->size;
+    if (tok->kind == TOK_ERROR)
+        return 0;
+    while (is_space(*p))
+        p++;
+    return *p == expected;
+}
+
 static void next_token(crxp_token_t *tok)
 {
     const char *p = tok->p + tok->size;
@@ -148,6 +158,8 @@
     return result;
 }
 
+static crx_type_t *parse_complete(crxp_token_t *tok);
+
 static void parse_sequel(crxp_token_t *tok, intptr_t ds_end)
 {
     while (tok->kind == TOK_STAR || tok->kind == TOK_CONST) {
@@ -162,12 +174,42 @@
     switch (tok->kind) {
 
     case TOK_OPEN_PAREN:
-        /* just parentheses for grouping */
         next_token(tok);
 
-        ds = tok->delay_slots;
-        parse_sequel(tok, *jump_slot);
-        *jump_slot = -(ds - tok->all_delay_slots);
+        if (tok->kind == TOK_STAR ||
+            tok->kind == TOK_CONST ||
+            tok->kind == TOK_OPEN_BRACKET) {
+            /* just parentheses for grouping */
+            ds = tok->delay_slots;
+            parse_sequel(tok, *jump_slot);
+            *jump_slot = -(ds - tok->all_delay_slots);
+        }
+        else {
+            /* function type */
+            ds = alloc_ds(tok, 2);
+            ds[0] = TOK_OPEN_PAREN;
+            ds[1] = 0;
+            if (tok->kind == TOK_VOID &&
+                    is_following_token_this_char(tok, ')')) {
+                next_token(tok);
+            }
+            if (tok->kind != TOK_CLOSE_PAREN) {
+                while (1) {
+                    crx_type_t *t1 = parse_complete(tok);
+                    intptr_t *ds_type = alloc_ds(tok, 1);
+                    assert(ds_type == ds + 2 + ds[1]);
+                    *ds_type = (intptr_t)t1;
+                    ds[1]++;
+                    if (tok->kind != TOK_COMMA)
+                        break;
+                    next_token(tok);
+                }
+            }
+            intptr_t *ds_next = alloc_ds(tok, 1);
+            assert(ds_next == ds + 2 + ds[1]);
+            *ds_next = *jump_slot;
+            *jump_slot = -(ds - tok->all_delay_slots);
+        }
 
         assert(tok->kind == TOK_CLOSE_PAREN);  // XXX
         next_token(tok);
@@ -221,6 +263,15 @@
                 t1 = tok->cb->get_array_type(tok->cb, t1, length);
                 break;
             }
+            case TOK_OPEN_PAREN:   /* function */
+            {
+                intptr_t nbargs = *delay_slot++;
+                crx_type_t **argtypes = (crx_type_t **)delay_slot;
+                delay_slot += nbargs;
+                t1 = tok->cb->get_function_type(tok->cb, t1, argtypes,
+                                                nbargs, NULL);
+                break;
+            }
             default:
                 abort();
             }
@@ -242,6 +293,9 @@
     case TOK_INT:
         t1 = tok->cb->get_signed_type(tok->cb, sizeof(int), "int");
         break;
+    case TOK_VOID:
+        t1 = tok->cb->get_void_type(tok->cb);
+        break;
     default:
         tok->kind = TOK_ERROR;
         return;
diff --git a/test/test_c_decl_parser.py b/test/test_c_decl_parser.py
--- a/test/test_c_decl_parser.py
+++ b/test/test_c_decl_parser.py
@@ -37,10 +37,10 @@
     mod.executable = executable
 
 
-def parse(input, expected_output):
+def parse(input, expected_output='???'):
     global executable
+    print repr(input)
     got = subprocess.check_output([executable, input])
-    print repr(input)
     print got.rstrip()
     assert got == expected_output + '\n'
 
@@ -57,18 +57,21 @@
     parse("int*[2][3]", "ARRAY[2] ARRAY[3] PTR int")
     parse("int(*)[2][3]", "PTR ARRAY[2] ARRAY[3] int")
     parse("int(*[2])[3]", "ARRAY[2] PTR ARRAY[3] int")
+    parse("int()", "FUNC( int )")
+    parse("int(void)", "FUNC( int )")
+    parse("int(int)", "FUNC( int -> int )")
+    parse("int(int *, int const *)", "FUNC( PTR int -> PTR CONST int -> int )")
+    parse("int(*)(int)", "PTR FUNC( int -> int )")
     import py; py.test.skip("in-progress")
-    parse("int()")
-    parse("int(void)")
-    parse("int(int)")
-    parse("int(int *, int const *)")
-    parse("int(*)(int)")
     parse("unsigned int")
     parse("unsigned long long *")
     parse("const unsigned long long *")
     parse("unsigned long long const *")
     parse("char(*(*)(long))(int)")
     parse("foo_t[]")
+    parse("int(int, ...)")
+    parse("int(int[])")
+    parse("int(long(char))")
 
 def test_c_decl_error():
     parse_error("*", 0)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to