Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix preprocessor expansion strategy #33

Merged
merged 13 commits into from
Oct 10, 2021

Conversation

doppioandante
Copy link
Contributor

@doppioandante doppioandante commented Sep 26, 2021

Fixes #31
Fixes #30
Supersedes #29
Still WIP, I need to reintegrate the logic needed to handle __VA_ARGS__ and some other things, but overall it works.

I will tidy up the commits when done.

@doppioandante
Copy link
Contributor Author

@Vexu this is still not ready for a full review, but I have to suspend working on this for a week or so. Could you give it a quick skim regarding structure and memory handling? It's practically the first real piece of zig code I write, and I felt it was rough a lot of times.

The entry point is expandMacro2(), if one substitutes it to expandMacro() in the two occurrences in the source, the new code will be used. I have added new test cases and everything passes now, but I have some regressions which aren't being tested and a lot of things I want to fix first.

Copy link
Owner

@Vexu Vexu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far this seems mostly fine, I tried answering most of the questions in the TODOs.
I'd be nice if more allocations could be avoided but correctness comes first.

test/cases/unspecified expansion.c Show resolved Hide resolved
src/Preprocessor.zig Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
@doppioandante
Copy link
Contributor Author

Small status update, don't review yet because the commits are a mess right now, It seems that the preprocessor is working ok. I've tested it with libpp and it passes all its tests. I also tested it with cloak, but that didn't work completely, I suspect it relies on the undefined behaviour that arocc does differently respect to gcc/clang.

I will test it with more libraries from awesome-c-preprocessor

A note about commit cf776f3 . That commit deals with the following:

#define h(s) 30
#define H h
#define SS (s)

H SS // should this be h(s) or 30?

gcc/clang expand as h(s), while arocc before cf776f3 expands to 30, after it does like gcc. What gcc does is reasonable, but I'm not sure it is strictly mandated by the standard

@doppioandante
Copy link
Contributor Author

@Vexu I'm stopping here with the fixes and enhancements, this is getting a bit out of hand already.
Can you please tell me if you prefer to review this after I have rebased/reordered the commits or if you want to review now? Being this big, it is a bit easier to be able to see the timeline of the changes, but it's the same for me.

After the rebasing, I will add documentation to all the parts I touched, and I will do following development in future PR:

  • remove .empty from the Macro enum and rework the func/simple distinction
  • make the location linked list a vector
  • FIx the commented parts of test test/cases/standard-concatenation-strings-example.c
    A bit of explanation on the last one: this is what fails now
#define str(x) #x
str(f(x)+1)
str(f(x) + 1)

This should expand to "str(f(x)+1)" and "str(f(x) + 1)" respectively. The previous implementation always did the second, the current always does the former.
As far as I can tell, the current preprocessor completely deletes simple spaces between token, is that correct? Unfortunately I think those must be kept track of, what do you think about this?

src/Preprocessor.zig Outdated Show resolved Hide resolved
@Vexu
Copy link
Owner

Vexu commented Oct 3, 2021

Can you please tell me if you prefer to review this after I have rebased/reordered the commits or if you want to review now?

I can review it now, should make squashing any fixups easier too.

Unfortunately I think those must be kept track of, what do you think about this?

Yes that seems to be the case, it should also make properly implementing the -E command easier and shouldn't add too much memory usage as we don't have to pass the whitespace tokens out of the preprocessor and they don't need proper source locations.

src/Preprocessor.zig Outdated Show resolved Hide resolved
Copy link
Owner

@Vexu Vexu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good and removes some of the ugliest parts of the entire codebase.

I didn't make notes about all the debug comments and prints since you'll probably remove them as part of the rebasing.

test/cases/macro re-expansion.c Outdated Show resolved Hide resolved
test/cases/unspecified expansion.c Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
src/Preprocessor.zig Outdated Show resolved Hide resolved
@doppioandante doppioandante force-pushed the preprocessor-fix-2 branch 3 times, most recently from 31da779 to 8083895 Compare October 3, 2021 13:29
The previous macro expansion implementation had several flaws regarding
order and re-expansion logic. Those were fixed by a complete rewrite
of the expandMacro() and its nested code paths.
Also remove special handling for 'self' macros. In the future, the 'empty'
macro will be removed as well.
try buf.replaceRange(idx, macro_scan_idx-idx+1, res.items);
// TODO: moving_end_idx += res.items.len - (macro_scan_idx-idx+1)
// doesn't work when the RHS is negative (unsigned!)
moving_end_idx = moving_end_idx + res.items.len - (macro_scan_idx-idx+1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any suggestion about this? It was moving_end_idx -= res.items.len - (macro_scan_idx-idx+1);
But the rhs can become negative, which is harmless but zig doesn't like it. It works right now, but I don't know if this is the zig way

@@ -70,11 +70,7 @@ defines: DefineMap,
tokens: Token.List = .{},
generated: std.ArrayList(u8),
token_buf: RawTokenList,
char_buf: std.ArrayList(u8),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was only used during stringification, so I moved it there locally, is that okay?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason it was in the PreProcessor was so that the buffer could be reused between stringifications redusing redundant allocations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reintroduced the global pp.char_buf

@doppioandante
Copy link
Contributor Author

Rebased and applied zig fmt. I originally wanted to also add some docs to this PR, but maybe I'll leave that for another one if that's okay for you?
I left another couple of comments, but other than that I think it's good to go.

@doppioandante doppioandante marked this pull request as ready for review October 3, 2021 14:27
doppioandante and others added 3 commits October 6, 2021 20:51
Mainly changes to the control flow of the macro expansion/rescan loop

Co-authored-by: Veikka Tuominen <git@vexu.eu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants