summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-20 15:15:26 -0700
committerCarl Worth <cworth@cworth.org>2010-05-20 15:15:26 -0700
commitc10a51ba13272dc48407b885d8684be99bba120d (patch)
treec5e9be684befb68e37723eec73cc0ddc4ad4f9b2
parentb894583fd0246060d908a0cc7b5f3ef72a5a2112 (diff)
Pre-expand macro arguments at time of invocation.
Previously, we were using the same lexing stack as we use for macro expansion to also expand macro arguments. Instead, we now do this earlier by simply recursing over the macro-invocations replacement list and constructing a new expanded list, (and pushing only *that* onto the stack). This is simpler, and also allows us to more easily implement token pasting in the future.
-rw-r--r--glcpp-lex.l8
-rw-r--r--glcpp-parse.y88
-rw-r--r--glcpp.h2
3 files changed, 28 insertions, 70 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l
index 114b59f045..6138a9de12 100644
--- a/glcpp-lex.l
+++ b/glcpp-lex.l
@@ -138,14 +138,6 @@ TOKEN [^[:space:](),]+
switch (glcpp_parser_classify_token (yyextra, yylval.str,
&parameter_index))
{
- case TOKEN_CLASS_ARGUMENT:
- talloc_free (yylval.str);
- /* We don't return a value here since the
- * current token will be replaced by new
- * tokens. */
- glcpp_parser_push_expansion_argument (yyextra,
- parameter_index);
- break;
case TOKEN_CLASS_IDENTIFIER:
return IDENTIFIER;
break;
diff --git a/glcpp-parse.y b/glcpp-parse.y
index ddc2a258cd..0691619acf 100644
--- a/glcpp-parse.y
+++ b/glcpp-parse.y
@@ -87,11 +87,6 @@ void
_token_list_append_list (token_list_t *list, token_list_t *tail);
static void
-glcpp_parser_push_expansion_macro (glcpp_parser_t *parser,
- macro_t *macro,
- argument_list_t *arguments);
-
-static void
glcpp_parser_pop_expansion (glcpp_parser_t *parser);
#define yylex glcpp_parser_lex
@@ -614,24 +609,7 @@ glcpp_parser_classify_token (glcpp_parser_t *parser,
{
macro_t *macro;
- /* First we check if we are currently expanding a
- * function-like macro, and if so, whether the parameter list
- * contains a parameter matching this token name. */
- if (parser->expansions &&
- parser->expansions->macro &&
- parser->expansions->macro->parameters)
- {
- string_list_t *list;
-
- list = parser->expansions->macro->parameters;
-
- if (_string_list_contains (list, identifier, parameter_index))
- return TOKEN_CLASS_ARGUMENT;
- }
-
- /* If not a function-like macro parameter, we next check if
- * this token is a macro itself. */
-
+ /* Is this token a defined macro? */
macro = hash_table_find (parser->defines, identifier);
if (macro == NULL)
@@ -685,17 +663,15 @@ _define_function_macro (glcpp_parser_t *parser,
}
static void
-_glcpp_parser_push_expansion_internal (glcpp_parser_t *parser,
- macro_t *macro,
- argument_list_t *arguments,
- token_node_t *replacements)
+_glcpp_parser_push_expansion (glcpp_parser_t *parser,
+ macro_t *macro,
+ token_node_t *replacements)
{
expansion_node_t *node;
node = xtalloc (parser, expansion_node_t);
node->macro = macro;
- node->arguments = arguments;
node->replacements = replacements;
node->next = parser->expansions;
@@ -703,30 +679,6 @@ _glcpp_parser_push_expansion_internal (glcpp_parser_t *parser,
}
static void
-glcpp_parser_push_expansion_macro (glcpp_parser_t *parser,
- macro_t *macro,
- argument_list_t *arguments)
-{
- _glcpp_parser_push_expansion_internal (parser, macro, arguments,
- macro->replacements->head);
-}
-
-void
-glcpp_parser_push_expansion_argument (glcpp_parser_t *parser,
- int argument_index)
-{
- argument_list_t *arguments;
- token_list_t *argument;
-
- arguments = parser->expansions->arguments;
-
- argument = _argument_list_member_at (arguments, argument_index);
-
- _glcpp_parser_push_expansion_internal (parser, NULL, NULL,
- argument->head);
-}
-
-static void
glcpp_parser_pop_expansion (glcpp_parser_t *parser)
{
expansion_node_t *node;
@@ -752,7 +704,7 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier)
assert (! macro->is_function);
assert (! glcpp_parser_is_expanding (parser, identifier));
- glcpp_parser_push_expansion_macro (parser, macro, NULL);
+ _glcpp_parser_push_expansion (parser, macro, macro->replacements->head);
}
void
@@ -761,6 +713,9 @@ _expand_function_macro (glcpp_parser_t *parser,
argument_list_t *arguments)
{
macro_t *macro;
+ token_list_t *expanded;
+ token_node_t *i, *j;
+ int parameter_index;
macro = hash_table_find (parser->defines, identifier);
assert (macro->is_function);
@@ -777,7 +732,26 @@ _expand_function_macro (glcpp_parser_t *parser,
return;
}
- glcpp_parser_push_expansion_macro (parser, macro, arguments);
+ expanded = _token_list_create (macro);
+
+ for (i = macro->replacements->head; i; i = i->next) {
+ if (_string_list_contains (macro->parameters, i->value,
+ &parameter_index))
+ {
+ token_list_t *argument;
+ argument = _argument_list_member_at (arguments,
+ parameter_index);
+ for (j = argument->head; j; j = j->next)
+ {
+ _token_list_append (expanded, j->type,
+ j->value);
+ }
+ } else {
+ _token_list_append (expanded, i->type, i->value);
+ }
+ }
+
+ _glcpp_parser_push_expansion (parser, macro, expanded->head);
}
static int
@@ -819,12 +793,6 @@ glcpp_parser_lex (glcpp_parser_t *parser)
switch (glcpp_parser_classify_token (parser, yylval.str,
&parameter_index))
{
- case TOKEN_CLASS_ARGUMENT:
- talloc_free (yylval.str);
- glcpp_parser_push_expansion_argument (parser,
- parameter_index);
- goto RECURSE;
- break;
case TOKEN_CLASS_IDENTIFIER:
return IDENTIFIER;
break;
diff --git a/glcpp.h b/glcpp.h
index 048a9be76b..1537109ada 100644
--- a/glcpp.h
+++ b/glcpp.h
@@ -71,7 +71,6 @@ typedef struct argument_list {
typedef struct glcpp_parser glcpp_parser_t;
typedef enum {
- TOKEN_CLASS_ARGUMENT,
TOKEN_CLASS_IDENTIFIER,
TOKEN_CLASS_IDENTIFIER_FINALIZED,
TOKEN_CLASS_FUNC_MACRO,
@@ -92,7 +91,6 @@ typedef struct {
typedef struct expansion_node {
macro_t *macro;
- argument_list_t *arguments;
token_node_t *replacements;
struct expansion_node *next;
} expansion_node_t;