diff options
author | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2012-10-04 19:08:39 +0100 |
---|---|---|
committer | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2012-10-04 19:08:39 +0100 |
commit | f09b0cb293c034df8efccdce12235e74a5ae6d13 (patch) | |
tree | 901617e8dd7aabe512aa0eb4d12c3c13c618dbbb /src/webidl-parser.y | |
parent | 35f2b9fc8120776bbd5e6f2aa3ddf68ddb46bf33 (diff) | |
download | nsgenbind-f09b0cb293c034df8efccdce12235e74a5ae6d13.tar.gz nsgenbind-f09b0cb293c034df8efccdce12235e74a5ae6d13.tar.bz2 |
fix polymorphism in teh AST generation
Diffstat (limited to 'src/webidl-parser.y')
-rw-r--r-- | src/webidl-parser.y | 144 |
1 files changed, 94 insertions, 50 deletions
diff --git a/src/webidl-parser.y b/src/webidl-parser.y index 81f0dfc..7d93a4e 100644 --- a/src/webidl-parser.y +++ b/src/webidl-parser.y @@ -236,40 +236,30 @@ Interface: { /* extend interface with additional members */ struct webidl_node *interface_node; + struct webidl_node *members = NULL; + + if ($3 != NULL) { + members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, members, $3); + } + + members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5); + + interface_node = webidl_node_find_type_ident(*webidl_ast, WEBIDL_NODE_TYPE_INTERFACE, $2); if (interface_node == NULL) { - struct webidl_node *members; - struct webidl_node *ident; - struct webidl_node *inheritance = NULL; - - if ($3 != NULL) { - inheritance = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, NULL, $3); - } - - members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, inheritance, $5); + /* no existing interface - create one with ident */ + members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); - ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); - - $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, ident); + $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, members); } else { - struct webidl_node *members; - struct webidl_node *inheritance = webidl_node_getnode(interface_node); - - if ($3 != NULL) { - inheritance = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, inheritance, $3); - } - - members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, - inheritance, - $5); + /* update the existing interface */ /* link member node into interfaces_node */ - webidl_node_set(interface_node, - WEBIDL_NODE_TYPE_INTERFACE, - members); - $$ = NULL; /* updated existing interface do not add it again */ + webidl_node_add(interface_node, members); + + $$ = NULL; /* updating so no need to add a new node */ } } ; @@ -294,33 +284,28 @@ PartialInterface: TOK_INTERFACE TOK_IDENTIFIER '{' InterfaceMembers '}' ';' { /* extend interface with additional members */ + struct webidl_node *members; struct webidl_node *interface_node; + interface_node = webidl_node_find_type_ident(*webidl_ast, WEBIDL_NODE_TYPE_INTERFACE, $2); - if (interface_node == NULL) { - /* doesnt already exist so create it */ - struct webidl_node *members; - struct webidl_node *ident; - members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $4); + members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $4); - ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); + if (interface_node == NULL) { + /* doesnt already exist so create it */ - $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, ident); + members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); + $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, members); } else { - struct webidl_node *members; - members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, - webidl_node_getnode(interface_node), - $4); + /* update the existing interface */ /* link member node into interfaces_node */ - webidl_node_set(interface_node, - WEBIDL_NODE_TYPE_INTERFACE, - members); + webidl_node_add(interface_node, members); - $$ = NULL; /* updated existing interface do not add it again */ + $$ = NULL; /* updating so no need to add a new node */ } } ; @@ -333,8 +318,54 @@ InterfaceMembers: } | InterfaceMembers ExtendedAttributeList InterfaceMember - { - $$ = webidl_add_interface_member($1, $3); + /* This needs to deal with members with the same identifier which + * indicate polymorphism. this is handled in the AST by adding the + * argument lists for each polymorphism to the same + * WEBIDL_NODE_TYPE_OPERATION + * + * @todo need to consider qualifer/stringifier compatibility + */ + { + struct webidl_node *member_node; + struct webidl_node *ident_node; + struct webidl_node *list_node; + + ident_node = webidl_node_find(webidl_node_getnode($3), + NULL, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_IDENT); + + list_node = webidl_node_find(webidl_node_getnode($3), + NULL, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_LIST); + + if (ident_node == NULL) { + /* something with no ident - possibly constructors? */ + /* @todo understand this abtter */ + + $$ = webidl_node_prepend($1, $3); + } else if (list_node == NULL) { + /* something with no argument list - cannot be polymorphic */ + $$ = webidl_node_prepend($1, $3); + } else { + /* has an arguemnt list so can be polymorphic */ + member_node = webidl_node_find_type_ident($1, + webidl_node_gettype($3), + webidl_node_gettext(ident_node)); + if (member_node == NULL) { + /* not a member with that ident already present */ + $$ = webidl_node_prepend($1, $3); + } else { + + fprintf(stderr, + "HERE: New polymorphic member %p, ident node %p (%s), list node %p\n", + (void *)$3, (void *)ident_node, webidl_node_gettext(ident_node), (void *)list_node); + + webidl_node_add(member_node, list_node); + $$ = $1; /* updated existing node do not add new one */ + } + } } ; @@ -462,7 +493,18 @@ ImplementsStatement: Const: TOK_CONST ConstType TOK_IDENTIFIER '=' ConstValue ';' { - $$ = NULL; + struct webidl_node *constant; + + constant = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3); + + /* add constant type */ + //constant = webidl_node_prepend(constant, $2); + + /* add constant value */ + //constant = webidl_node_prepend(constant, $5); + + $$ = webidl_node_new(WEBIDL_NODE_TYPE_CONST, NULL, constant); + } ; @@ -512,6 +554,10 @@ StringifierAttributeOrOperation: Attribute | OperationRest + { + /* @todo deal with stringifier */ + $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, $1); + } | ';' { @@ -570,7 +616,8 @@ ReadOnly: Operation: Qualifiers OperationRest { - $$=$2; + /* @todo fix qualifiers */ + $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, $2); } ; @@ -605,18 +652,15 @@ Special: OperationRest: ReturnType OptionalIdentifier '(' ArgumentList ')' ';' { - struct webidl_node *operation; struct webidl_node *arglist; /* put return type in argument list */ arglist = webidl_node_prepend($4, $1); /* argument list */ - operation = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, arglist); - - operation = webidl_node_prepend(operation, $2); /* identifier */ + $$ = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, arglist); - $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, operation); + $$ = webidl_node_prepend($$, $2); /* identifier */ } ; |