summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-24 20:17:03 +0100
committerVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-24 20:17:03 +0100
commitb5c59d1138c704afd09c4716faabe79f04a80616 (patch)
tree6a850ca46c373636dd8d8911665ac6cad94f7bef /src
parent20f9ab6b2c89a9a9edf00f052c912f139e7c4a38 (diff)
downloadnsgenbind-b5c59d1138c704afd09c4716faabe79f04a80616.tar.gz
nsgenbind-b5c59d1138c704afd09c4716faabe79f04a80616.tar.bz2
add interface function argument and type processing
Diffstat (limited to 'src')
-rw-r--r--src/webidl-ast.c54
-rw-r--r--src/webidl-ast.h30
-rw-r--r--src/webidl-parser.y219
3 files changed, 281 insertions, 22 deletions
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index d698fff..53ba7e6 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -30,21 +30,40 @@ struct webidl_node {
} r;
};
+/* insert node at beginning of a list */
+struct webidl_node *
+webidl_node_prepend(struct webidl_node *list, struct webidl_node *node)
+{
+ if (node == NULL) {
+ return list; /* no node to prepend - return existing list */
+ }
+ node->l = list;
+ return node;
+}
+
+/* append node at end of a list */
struct webidl_node *
-webidl_node_link(struct webidl_node *tgt, struct webidl_node *src)
+webidl_node_append(struct webidl_node *list, struct webidl_node *node)
{
- if (tgt != NULL) {
- tgt->l = src;
- return tgt;
- }
- return src;
+ struct webidl_node *cur = list;
+
+ if (cur == NULL) {
+ return node; /* no existing list so just return node */
+ }
+
+ while (cur->l != NULL) {
+ cur = cur->l;
+ }
+ cur->l = node;
+
+ return list;
}
struct webidl_node *
webidl_add_interface_member(struct webidl_node *list, struct webidl_node *new)
{
- return webidl_node_link(new, list);
+ return webidl_node_prepend(list, new);
}
struct webidl_node *webidl_node_new(enum webidl_node_type type, struct webidl_node *l, void *r)
@@ -178,6 +197,9 @@ struct webidl_node *webidl_node_getnode(struct webidl_node *node)
case WEBIDL_NODE_TYPE_INTERFACE_MEMBERS:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
case WEBIDL_NODE_TYPE_OPERATION:
+ case WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT:
+ case WEBIDL_NODE_TYPE_ARGUMENT:
+ case WEBIDL_NODE_TYPE_TYPE:
return node->r.node;
default:
break;
@@ -211,6 +233,24 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_OPERATION:
return "Operation";
+ case WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT:
+ return "Argument(opt)";
+
+ case WEBIDL_NODE_TYPE_ARGUMENT:
+ return "Argument";
+
+ case WEBIDL_NODE_TYPE_ELLIPSIS:
+ return "Ellipsis";
+
+ case WEBIDL_NODE_TYPE_TYPE:
+ return "Type";
+
+ case WEBIDL_NODE_TYPE_TYPE_BASE:
+ return "Base";
+
+ case WEBIDL_NODE_TYPE_TYPE_MODIFIER:
+ return "Modifier";
+
default:
return "Unknown";
}
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index c86d59b..7c32d82 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -17,6 +17,33 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
+ WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT,
+ WEBIDL_NODE_TYPE_ARGUMENT,
+ WEBIDL_NODE_TYPE_ELLIPSIS,
+ WEBIDL_NODE_TYPE_TYPE,
+ WEBIDL_NODE_TYPE_TYPE_BASE,
+ WEBIDL_NODE_TYPE_TYPE_MODIFIER,
+};
+
+enum webidl_type {
+ WEBIDL_TYPE_BOOL,
+ WEBIDL_TYPE_BYTE,
+ WEBIDL_TYPE_OCTET,
+ WEBIDL_TYPE_FLOAT,
+ WEBIDL_TYPE_DOUBLE,
+ WEBIDL_TYPE_SHORT,
+ WEBIDL_TYPE_LONG,
+ WEBIDL_TYPE_LONGLONG,
+ WEBIDL_TYPE_STRING,
+ WEBIDL_TYPE_SEQUENCE,
+ WEBIDL_TYPE_OBJECT,
+ WEBIDL_TYPE_DATE,
+ WEBIDL_TYPE_USER,
+};
+
+enum webidl_type_modifier {
+ WEBIDL_TYPE_MODIFIER_UNSIGNED,
+ WEBIDL_TYPE_MODIFIER_UNRESTRICTED,
};
struct webidl_node;
@@ -30,7 +57,8 @@ struct webidl_node *webidl_node_new(enum webidl_node_type, struct webidl_node *l
void webidl_node_set(struct webidl_node *node, enum webidl_node_type type, void *r);
-struct webidl_node *webidl_node_link(struct webidl_node *tgt, struct webidl_node *src);
+struct webidl_node *webidl_node_prepend(struct webidl_node *list, struct webidl_node *node);
+struct webidl_node *webidl_node_append(struct webidl_node *list, struct webidl_node *node);
struct webidl_node *webidl_add_interface_member(struct webidl_node *list, struct webidl_node *new);
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 9b3eb12..c3bb609 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -13,6 +13,8 @@
#include <stdio.h>
#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
#include "webidl-ast.h"
@@ -39,9 +41,9 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%union
{
int attr;
- char* text;
long value;
- struct ifmember_s **ifmember;
+ bool isit;
+ char* text;
struct webidl_node *node;
}
@@ -138,14 +140,36 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <node> Operation
%type <node> OperationRest
-%type <text> OptionalIdentifier
+%type <node> OptionalIdentifier
+
+%type <node> ArgumentList
+%type <node> Arguments
+%type <node> Argument
+%type <node> OptionalOrRequiredArgument
+%type <text> ArgumentName
+%type <text> ArgumentNameKeyword
+%type <node> Ellipsis
+
+%type <node> Type
+%type <node> SingleType
+%type <node> UnionType
+%type <node> NonAnyType
+%type <node> PrimitiveType
+%type <node> UnrestrictedFloatType
+%type <node> FloatType
+%type <node> UnsignedIntegerType
+%type <node> IntegerType
+
+%type <isit> OptionalLong
%%
/* default rule to add built AST to passed in one */
Input:
Definitions
- { *webidl_ast = webidl_node_link($1, *webidl_ast); }
+ {
+ *webidl_ast = webidl_node_prepend(*webidl_ast, $1);
+ }
|
error
{
@@ -164,7 +188,7 @@ Definitions:
|
Definitions ExtendedAttributeList Definition
{
- $$ = webidl_node_link($1, $3);
+ $$ = webidl_node_prepend($1, $3);
}
;
@@ -496,9 +520,9 @@ StringifierAttributeOrOperation:
Attribute:
Inherit ReadOnly TOK_ATTRIBUTE Type TOK_IDENTIFIER ';'
{
- struct webidl_node *ident;
- ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $5);
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE, NULL, ident);;
+ struct webidl_node *attribute;
+ attribute = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $5);
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE, NULL, attribute);
}
;
@@ -555,11 +579,11 @@ Special:
OperationRest:
ReturnType OptionalIdentifier '(' ArgumentList ')' ';'
{
- struct webidl_node *ident = NULL;
- if ($2 != NULL) {
- ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $2);
- }
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, ident);
+ struct webidl_node *operation = $4; /* argument list */
+
+ operation = webidl_node_prepend(operation, $2); /* identifier */
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, operation);
}
;
@@ -571,34 +595,67 @@ OptionalIdentifier:
}
|
TOK_IDENTIFIER
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $1);
+ }
;
- /* [41] */
+ /* [41] an empty list or a list of non empty comma separated arguments, note
+ * this is right associative so the tree build is ass backwards
+ */
ArgumentList:
/* empty */
+ {
+ $$ = NULL;
+ }
|
Argument Arguments
+ {
+ $$ = webidl_node_append($2, $1);
+ }
;
/* [42] */
Arguments:
/* empty */
+ {
+ $$ = NULL;
+ }
|
',' Argument Arguments
+ {
+ $$ = webidl_node_append($3, $2);
+ }
;
/* [43] */
Argument:
ExtendedAttributeList OptionalOrRequiredArgument
+ {
+ $$ = $2;
+ }
;
/* [44] */
OptionalOrRequiredArgument:
TOK_OPTIONAL Type ArgumentName Default
+ {
+ struct webidl_node *argument;
+ argument = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3);
+ argument = webidl_node_prepend(argument, $2); /* add type node */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT, NULL, argument);
+ }
|
Type Ellipsis ArgumentName
+ {
+ struct webidl_node *argument;
+ argument = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3);
+ argument = webidl_node_prepend(argument, $2); /* ellipsis node */
+ argument = webidl_node_prepend(argument, $1); /* add type node */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, argument);
+ }
;
/* [45] */
@@ -611,8 +668,14 @@ ArgumentName:
/* [46] */
Ellipsis:
/* empty */
+ {
+ $$ = NULL;
+ }
|
TOK_ELLIPSIS
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ELLIPSIS, NULL, NULL);
+ }
;
/* [47] */
@@ -750,42 +813,99 @@ Other:
/* [55] */
ArgumentNameKeyword:
TOK_ATTRIBUTE
+ {
+ $$ = strdup("attribute");
+ }
|
TOK_CALLBACK
+ {
+ $$ = strdup("callback");
+ }
|
TOK_CONST
+ {
+ $$ = strdup("const");
+ }
|
TOK_CREATOR
+ {
+ $$ = strdup("creator");
+ }
|
TOK_DELETER
+ {
+ $$ = strdup("deleter");
+ }
|
TOK_DICTIONARY
+ {
+ $$ = strdup("dictionary");
+ }
|
TOK_ENUM
+ {
+ $$ = strdup("enum");
+ }
|
TOK_EXCEPTION
+ {
+ $$ = strdup("exception");
+ }
|
TOK_GETTER
+ {
+ $$ = strdup("getter");
+ }
|
TOK_IMPLEMENTS
+ {
+ $$ = strdup("implements");
+ }
|
TOK_INHERIT
+ {
+ $$ = strdup("inherit");
+ }
|
TOK_INTERFACE
+ {
+ $$ = strdup("interface");
+ }
|
TOK_LEGACYCALLER
+ {
+ $$ = strdup("legacycaller");
+ }
|
TOK_PARTIAL
+ {
+ $$ = strdup("partial");
+ }
|
TOK_SETTER
+ {
+ $$ = strdup("setter");
+ }
|
TOK_STATIC
+ {
+ $$ = strdup("static");
+ }
|
TOK_STRINGIFIER
+ {
+ $$ = strdup("stringifier");
+ }
|
TOK_TYPEDEF
+ {
+ $$ = strdup("typedef");
+ }
|
TOK_UNRESTRICTED
+ {
+ $$ = strdup("unrestricted");
+ }
;
/* [56] as it says an other element or a comma */
@@ -798,8 +918,15 @@ OtherOrComma:
/* [57] */
Type:
SingleType
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE, NULL, $1);
+ }
|
UnionType TypeSuffix
+ {
+ /* todo handle suffix */
+ $$ = $1;
+ }
;
/* [58] */
@@ -807,11 +934,17 @@ SingleType:
NonAnyType
|
TOK_ANY TypeSuffixStartingWithArray
+ {
+ $$ = NULL; /* todo implement */
+ }
;
/* [59] */
UnionType:
'(' UnionMemberType TOK_OR UnionMemberType UnionMemberTypes ')'
+ {
+ $$ = NULL;
+ }
;
/* [60] */
@@ -835,14 +968,31 @@ NonAnyType:
PrimitiveType TypeSuffix
|
TOK_STRING TypeSuffix
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_STRING);
+ }
|
TOK_IDENTIFIER TypeSuffix
+ {
+ struct webidl_node *type;
+ type = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_USER);
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, type, $1);
+ }
|
TOK_SEQUENCE '<' Type '>' Null
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $3, (void *)WEBIDL_TYPE_SEQUENCE);
+ }
|
TOK_OBJECT TypeSuffix
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_OBJECT);
+ }
|
TOK_DATE TypeSuffix
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_DATE);
+ }
;
/* [63] */
@@ -859,15 +1009,29 @@ PrimitiveType:
UnrestrictedFloatType
|
TOK_BOOLEAN
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_BOOL);
+ }
|
TOK_BYTE
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_BYTE);
+ }
|
TOK_OCTET
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_OCTET);
+ }
;
/* [65] */
UnrestrictedFloatType:
TOK_UNRESTRICTED FloatType
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_MODIFIER,
+ $2,
+ (void *)WEBIDL_TYPE_MODIFIER_UNRESTRICTED);
+ }
|
FloatType
;
@@ -875,13 +1039,24 @@ UnrestrictedFloatType:
/* [66] */
FloatType:
TOK_FLOAT
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_FLOAT);
+ }
|
TOK_DOUBLE
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_DOUBLE);
+ }
;
/* [67] */
UnsignedIntegerType:
TOK_UNSIGNED IntegerType
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_MODIFIER,
+ $2,
+ (void *)WEBIDL_TYPE_MODIFIER_UNSIGNED);
+ }
|
IntegerType
;
@@ -889,15 +1064,31 @@ UnsignedIntegerType:
/* [68] */
IntegerType:
TOK_SHORT
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_SHORT);
+ }
|
TOK_LONG OptionalLong
+ {
+ if ($2) {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_LONGLONG);
+ } else {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_LONG);
+ }
+ }
;
/* [69] */
OptionalLong:
/* empty */
+ {
+ $$ = false;
+ }
|
TOK_LONG
+ {
+ $$ = true;
+ }
;
/* [70] */