Incorrect. If that was an aggregate type, no rewinding happens.
The rewinding happens if the type is a simple type, like int, boolean, string, buffer, location, bounty, etc.
It most likely is always only going to be a single "word".
This code is weird.
The only non-erroring test case I could come up with to exercise rewinding was creating a typedef with the same name as a variable, then using that variable in a parenthesized expression.
In general, we can't get very far in Parser.parseValue except from places like parseCommand that don't normally expect types. Even an ordinary aggregate literal expression ("int[5] { 1, 2, 3, 4, 5}") follows a completely different codepath; ditto with an assignment or variable initialization. But suddenly when I wrap it in parentheses, Parser decides to use this path. (I then looked at the blame to see when this crazy logic was added... and saw it was part of the aggregate literals change I added 5 years ago...)
(I think this is an opportunity in the future for some cleanup / refactoring for how this logic works. Not now, though.)
Anyways. I'm getting close to a place where I'm happy with test coverage, after some amount of additional tweaking.
One case that comes to mind is multiline comment handling in nextToken. Apparently there's support for something like
. I'm not sure why you'd ever want to do that, though, although it is valid in other languages like C++ (probably because it's applying the unary minus in that case).
Even weirder is the quiet support for
This isn't valid in other languages...
I'm noting there are a lot of similarities in Parser.currentToken() vs Parser.nextToken(), but one notable difference is that currentToken creates explicit tokens for skipped comments (even though neither method returns them).
Token() doesn't have the same indexOf trick that we use in Line().
Either way, I'll try to post a patch later today with my edits and tests, and then hopefully we can get this behemoth merged if you think everything checks out.