icerpc / slicec

The Slice compiler library
Apache License 2.0
13 stars 5 forks source link

Fixed Preprocessor Executing Directives in Skipped Blocks #655

Closed InsertCreativityHere closed 1 year ago

InsertCreativityHere commented 1 year ago

LALR parsers works from inner-to-outer. So, in this example, the field is constructed before the struct is:

struct S {
    inner: bool,
}

This is great for Slice definitions, where we don't want to null-initialize a bunch of data, then set it later.

But, it's a problem for the preprocessor, because it means that inner directives (that should be skipped) are still executed:

#if UNDEFINED
    #define FOO // This is defined when it shouldn't be!
#endif

Because the inner expressions are run first, before the preprocessor even checks the outer condition.


This PR fixes this by no longer performing actions during parsing. Instead, the preprocessor works more like the Slice parser. It builds up a mini-AST for itself, then we traverse the AST once we have complete information. During traversal we evaluate these conditionals, and only visit the contents of those that are true.