Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit