Commit graph

102 commits

Author SHA1 Message Date
Carl Worth
0197e9b64f Change macro expansion to append onto token lists rather than printing directly.
This doesn't change any functionality here, but will allow us to make
future changes that were not possible with direct printing.
Specifically, we need to expand macros within macro arguments before
performing argument substitution. And *that* expansion cannot result
in immediate printing.
2010-05-26 08:05:55 -07:00
Carl Worth
c0607d573e Check active expansions before expanding a function-like macro invocation.
With this fix, test 32 no longer recurses infinitely, but now passes.
2010-05-26 08:01:42 -07:00
Carl Worth
039739b2da Defer test 26 until much later (to test 55).
Supporting embedded newlines in a macro invocation is going to be
tricky with our current approach to lexing and parsing. Since this
isn't really an important feature for us, we can defer this until more
important things are resolved.

With this test out of the way, tests 27 through 31 are passing.
2010-05-26 08:00:43 -07:00
Carl Worth
10ae438399 Avoid getting extra trailing whitespace from macros.
This trailing whitespace was coming from macro definitions and from
macro arguments. We fix this with a little extra state in the
token_list. It now remembers the last non-space token added, so that
these can be trimmed off just before printing the list.

With this fix test 23 now passes. Tests 24 and 25 are also passing,
but they probbably would ahve before this fix---just that they weren't
being run earlier.
2010-05-25 20:39:33 -07:00
Carl Worth
5aa7ea0809 Remove a bunch of old code and give the static treatment to what's left.
We're no longer using the expansion stack, so its functions can go
along with most of the body of glcpp_parser_lex that was using it.
2010-05-25 18:39:43 -07:00
Carl Worth
652fa272ea Avoid swallowing initial left parenthesis from nested macro invocation.
We weren't including this left parenthesis in the argument's token
list so the nested function invocation wasn not being recognized.

With this fix, tests 21 and 22 now pass.
2010-05-25 17:45:22 -07:00
Carl Worth
c7581c2e6e Ignore separating whitespace at the beginning of a macro argument.
This causes test 16 to pass. Tests 17-20 are also passing now, (though
they would probably have passed before this change and simply weren't
being run yet).
2010-05-25 17:41:07 -07:00
Carl Worth
9ce18cf983 Implement substitution of function parameters in macro calls.
This makes tests 16 - 19 pass.
2010-05-25 17:32:21 -07:00
Carl Worth
e9397867dd Collapse multiple spaces in input down to a single space.
This is what gcc does, and it's actually less work to do
this. Previously we were having to save the contents of space tokens
as a string, but we don't need to do that now.

We extend test #0 to exercise this feature here.
2010-05-25 17:08:07 -07:00
Carl Worth
f8ec4e0be8 Add a test #0 to ensure that we don't do any inadvertent token pasting.
This simply ensures that spaces in input line are preserved.
2010-05-25 17:06:17 -07:00
Carl Worth
f34a0009dd Pass through literal space values from replacement lists.
This makes test 15 pass and also dramatically simplifies the lexer.

We were previously using a CONTROL state in the lexer to only emit
SPACE tokens when on text lines. But that's not actually what we
want. We need SPACE tokens in the replacement lists as well. Instead
of a lexer state for this, we now simply set a "space_tokens" flag
whenever we start constructing a pp_tokens list and clear the flag
whenever we see a '#' introducing a directive.

Much cleaner this way.
2010-05-25 17:06:08 -07:00
Carl Worth
b1854fdfb6 Implement simplified substitution for function-like macro invocation.
This supports function-like macro invocation but without any argument
substitution. This now makes test 11 through 14 pass.
2010-05-25 16:28:26 -07:00
Carl Worth
e6fb7827c9 Implement #undef.
Which is as simple as copying the former action back from the git
history.

Now all tests through test 11 pass.
2010-05-25 15:28:58 -07:00
Carl Worth
ae6517f4a8 Implement expansion of object-like macros.
For this we add an "active" string_list_t to the parser. This makes
the current expansion_list_t in the parser obsolete, but we don't
remove that yet.

With this change we can now start passing some actual tests, so we
turn on real testing in the test suite again. I expect to implement
things more or less in the same order as before, so the test suite now
halts on first error.

With this change the first 8 tests in the suite pass, (object-like
macros with chaining and recursion).
2010-05-25 15:24:59 -07:00
Carl Worth
9fb8b7a495 Make the lexer pass whitespace through (as OTHER tokens) for text lines.
With this change, we can recreate the original text-line input
exactly. Previously we were inserting a space between every pair of
tokens so our output had a lot more whitespace than our input.

With this change, we can drop the "-b" option to diff and match the
input exactly.
2010-05-25 15:04:32 -07:00
Carl Worth
808401fd79 Store parsed tokens as token list and print all text lines.
Still not doing any macro expansion just yet. But it should be fairly
easy from here.
2010-05-25 14:52:43 -07:00
Carl Worth
80dc60b9c3 Delete some trailing whitespace.
This pernicious stuff managed to sneak in on us.
2010-05-25 14:42:00 -07:00
Carl Worth
9bb796f33a Add xtalloc_reference.
Yet another talloc wrapper that should come in handy.
2010-05-25 14:40:47 -07:00
Carl Worth
3ff8167084 Starting over with the C99 grammar for the preprocessor.
This is a fresh start with a much simpler approach for the flex/bison
portions of the preprocessor. This isn't functional yet, (produces no
output), but can at least read all of our test cases without any parse
errors.

The grammar here is based on the grammar provided for the preprocessor
in the C99 specification.
2010-05-25 14:38:15 -07:00
Carl Worth
00f1ec421e Add test for '/', '<<', and '>>' in #if expressions.
These operators have been supported already, but were not covered in
existing tests yet. So this test passes already.
2010-05-24 11:41:36 -07:00
Carl Worth
bb9315f804 Add test of bitwise operators and octal/hexadecimal literals.
This new test covers several features from the last few commits.

This test passes already.
2010-05-24 11:33:07 -07:00
Carl Worth
03f6d5d2d4 Add support for octal and hexadecimal integer literals.
In addition to the decimal literals which we already support. Note
that we use strtoll here to get the large-width integers demanded by
the specification.
2010-05-24 11:29:02 -07:00
Carl Worth
35419095f8 Switch to intmax_t (rather than int) for #if expressions
This is what the C99 specification demands. And the GLSL specification
says that we should follow the "standard C++" rules for #if condition
expressions rather than the GLSL rules, (which only support a 32-bit
integer).
2010-05-24 11:27:23 -07:00
Carl Worth
89b933a243 Add the '~' operator to the lexer.
This was simply missing before, (and unnoticed since we had no test of
the '~' operator).
2010-05-24 11:26:42 -07:00
Carl Worth
bcbd587b0f Implement all operators specified for GLSL #if expressions (with tests).
The operator coverage here is quite complete. The one big thing
missing is that we are not yet doing macro expansion in #if
lines. This makes the whole support fairly useless, so we plan to fix
that shortcoming right away.
2010-05-24 10:37:38 -07:00
Carl Worth
b20d33c5c6 Implement #if, #else, #elif, and #endif with tests.
So far the only expression implemented is a single integer literal,
but obviously that's easy to extend. Various things including nesting
are tested here.
2010-05-20 22:27:07 -07:00
Carl Worth
d8327e575d Implement (and add test) for token pasting.
This is *very* easy to implement now that macro arguments are pre-expanded.
2010-05-20 15:18:54 -07:00
Carl Worth
c10a51ba13 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.
2010-05-20 15:15:26 -07:00
Carl Worth
b894583fd0 Add xtalloc_asprintf
I expect this to be useful in the upcoming implementation of token pasting.
2010-05-20 15:02:03 -07:00
Carl Worth
876e510bda Finish cleaning up whitespace differences.
The last remaining thing here was that when a line ended with a macro,
and the parser looked ahead to the newline token, the lexer was
printing that newline before the parser printed the expansion of the
macro.

The fix is simple, just make the lexer tell the parser that a newline
is needed, and the parser can wait until reducing a production to
print that newline.

With this, we now pass the entire test suite with simply "diff -u", so
we no longer have any diff options hiding whitespace bugs from
us. Hurrah!
2010-05-20 14:38:06 -07:00
Carl Worth
5a6b9a27fd Avoid printing a space at the beginning of lines in the output.
This fixes more differences compared to "gcc -E" so removes several
cases of erroneously failing test cases. The implementation isn't very
elegant, but it is functional.
2010-05-20 14:29:43 -07:00
Carl Worth
005b32061f Fix bug of consuming excess whitespace.
We fix this by moving printing up to the top-level "input" action and
tracking whether a space is needed between one token and the next.

This fixes all actual bugs in test-suite output, but does leave some
tests failing due to differences in the amount of whitespace produced,
(which aren't actual bugs per se).
2010-05-20 14:19:57 -07:00
Carl Worth
ff13cfed81 Remove unused function _print_string_list
The only good dead code is non-existing dead code.
2010-05-20 14:08:19 -07:00
Carl Worth
323421db65 Remove "unnecessary" whitespace from some tests.
This whitespace was not part of anything being tested, and it
introduces differences (that we don't actually care about) between the
output of "gcc -E" and glcpp.

Just eliminate this extra whitespace to reduce spurious test-case
failures.
2010-05-20 14:05:37 -07:00
Carl Worth
660bda057a Stop ignoring whitespace while testing.
Sometime back the output of glcpp started differing from the output of
"gcc -E" in the amount of whitespace in emitted. At the time, I
switched the test suite to use "diff -w" to ignore this. This was a
mistake since it ignores whitespace entirely. (I meant to use "diff
-b" which ignores only changes in the amount of whitespace.)

So bugs have since been introduced that the test suite doesn't
notice. For example, glcpp is producing "twotokens" where it should be
producing "two tokens".

Let's stop ignoring whitespace in the test suite, which currently
introduces lots of failures---some real and some spurious.
2010-05-20 14:01:59 -07:00
Carl Worth
805ea6afe6 Add test (and fix) for a function argument of a macro that expands with a comma.
The fix here is quite simple (and actually only deletes code). When
expanding a macro, we don't return a ',' as a unique token type, but
simply let it fall through to the generic case.
2010-05-20 12:06:33 -07:00
Carl Worth
9f3d2c4e3d Add support for commas within parenthesized groups in function arguments.
The specification says that commas within a parenthesized group,
(that's not a function-like macro invocation), are passed through
literally and not considered argument separators in any outer macro
invocation.

Add support and a test for this case. This support makes a third
occurrence of the same "FUNC_MACRO (" shift/reduce conflict appear, so
expect that.

This change does introduce a fairly large copy/paste block in the
grammar which is unfortunate. Perhaps if I were more clever I'd find a
way to share the common pieces between argument and argument_or_comma.
2010-05-20 08:46:54 -07:00
Carl Worth
b569383bbd Avoid re-expanding a macro name that has once been rejected from expansion.
The specification of the preprocessor in C99 says that when we see a
macro name that we are already expanding that we refuse to expand it
now, (which we've done for a while), but also that we refuse to ever
expand it later if seen in other contexts at which it would be
legitimate to expand.

We add a test case for that here, and fix it to work. The fix takes
advantage of a new token_t value for tokens and argument words along
with the recently added IDENTIFIER_FINALIZED token type which
instructs the parser to not even look for another expansion.
2010-05-20 08:01:44 -07:00
Carl Worth
472524413d Use new token_list_t rather than string_list_t for macro values.
There's not yet any change in functionality here, (at least according
to the test suite). But we now have the option of specifying a type
for each string in the token list. This will allow us to finalize an
unexpanded macro name so that it won't be subjected to excess
expansion later.
2010-05-19 13:54:37 -07:00
Carl Worth
aaa9acbf10 Perform "re lexing" on string list values rathern than on text.
Previously, we would pass original strings back to the original lexer
whenever we needed to re-lex something, (such as an expanded macro or
a macro argument). Now, we instead parse the macro or argument
originally to a string list, and then re-lex by simply returning each
string from this list in turn.

We do this in the recently added glcpp_parser_lex function that sits
on top of the lower-level glcpp_lex that only deals with text.

This doesn't change any behavior (at least according to the existing
test suite which all still passes) but it brings us much closer to
being able to "finalize" an unexpanded macro as required by the
specification.
2010-05-19 13:28:24 -07:00
Carl Worth
71c59ec66b Remove unused NEWLINE token.
We fixed the lexer a while back to never return a NEWLINE token, but
negelcted to clean up this declaration.
2010-05-19 10:07:31 -07:00
Carl Worth
66df1c262a Remove unneeded YYLEX_PARAM define.
I'm not sure where this came from, but it's clearly not needed.
2010-05-19 10:06:56 -07:00
Carl Worth
0293b2e2dd Rename yylex to glcpp_parser_lex and give it a glcpp_parser_t* argument.
Much cleaner this way, (and now our custom lex function has access to
all the parser state which it will need).
2010-05-19 10:05:40 -07:00
Carl Worth
8f38aff9b5 Add a wrapper function around the lexer.
We rename the generated lexer from yylex to glcpp_lex. Then we
implement our own yylex function in glcpp-parse.y that calls
glcpp_lex. This doesn't change the behavior at all yet, but gives us a
place where we can do implement alternate lexing in the future.

(We want this because instead of re-lexing from strings for macro
expansion, we want to lex from pre-parsed token lists. We need this so
that when we terminate recursion due to an already active macro
expansion, we can ensure that that symbol never gets expanded again
later.)
2010-05-19 10:01:29 -07:00
Carl Worth
5d21142545 Like previous fix, but for object-like macros (and add a test).
The support for an object-like amcro within a macro-invocation
argument was also implemented at one level too high in the
grammar. Fortunately, this is a very simple fix.
2010-05-19 07:57:03 -07:00
Carl Worth
59ca98990f Fix bug as in previous fix, but with multi-token argument.
The previous fix added FUNC_MACRO to a production one higher in teh
grammar than it should have. So it prevented a FUNC_MACRO from
appearing as part of a mutli-token argument rather than just alone as
an argument. Fix this (and add a test).
2010-05-19 07:49:47 -07:00
Carl Worth
69f390d609 Fix bug (and test) for an invocation using macro name as a non-macro argument
This adds a second shift/reduce conflict to our grammar. It's basically the
same conflict we had previously, (deciding to shift a '(' after a FUNC_MACRO)
but this time in the "argument" context rather than the "content" context.

It would be nice to not have these, but I think they are unavoidable
(withotu a lot of pain at least) given the preprocessor specification.
2010-05-19 07:42:42 -07:00
Carl Worth
be0e2e9b2a Fix bug (and add tests) for a function-like macro defined as itself.
This case worked previously, but broke in the recent rewrite of
function- like macro expansion. The recursion was still terminated
correctly, but any parenthesized expression after the macro name was
still being swallowed even though the identifier was not being
expanded as a macro.

The fix is to notice earlier that the identifier is an
already-expanding macro. We let the lexer know this through the
classify_token function so that an already-expanding macro is lexed as
an identifier, not a FUNC_MACRO.
2010-05-19 07:29:22 -07:00
Carl Worth
a807fb72c4 Rewrite macro handling to support function-like macro invocation in macro values
The rewrite her discards the functions that did direct, recursive
expansion of macro values. Instead, the parser now pushes the macro
definition string over to a stack of buffers for the lexer. This way,
macro expansion gets access to all parsing machinery.

This isn't a small change, but the result is simpler than before (I
think). It passes the entire test suite, including the four tests
added with the previous commit that were failing before.
2010-05-18 22:10:04 -07:00
Carl Worth
d476db38fe Add several tests where the defined value of a macro is (or looks like) a macro
Many of these look quite similar to existing tests that are handled
correctly, yet none of these work. For example, in test 30 we have a
simple non-function macro "foo" that is defined as "bar(baz(success))"
and obviously non-function macro expansion has been working for a long
time.  Similarly, if we had text of "bar(baz(success))" it would be
expanded correctly as well.

But when this otherwise functioning text appears as the body of a
macro, things don't work at all.

This is pointing out a fundamental problem with the current
approach. The current code does a recursive expansion of a macro
definition, but this doesn't involve the parsing machinery, so it
can't actually handle things like an arbitrary nesting of parentheses.

The fix will require the parser to stuff macro values back into the
lexer to get at all of the existing machinery when expanding macros.
2010-05-18 22:09:57 -07:00