https://github.com/shader-slang/slang
Revision 0389546b0b065303d3c6874891a9fab4428910b9 authored by T. Foley on 21 May 2021, 22:07:21 UTC, committed by GitHub on 21 May 2021, 22:07:21 UTC
* Overhaul the preprocessor

The old Slang preprocessor was based on a simple mental model that tried to unify two parts of macro expansion:

* Scanning for macro invocations in a sequence of tokens

* Producing the expanded tokens for a macro expansion by substituting arguments into its body

The basic was that substitution of macro arguments into a macro definition is superficially similar to top-level macro expansion, just with an environment where the macro arguments act like `#define`s for the corresponding parameter names. That approach was "clever" and could conceivably have been extended to include a lot of advanced preprocessor features (e.g., a preprocessor-level `lambda` would be easy to support!), but it was basically impossible to make it correctly handle all the corner cases of the full C/C++ preprocessor.

The fundamental problem with the old approach was that it conflated the two parts of expansion listed above into one implementation, while the various special cases of the C/C++ preprocessor rely on treating the two cases very differently. The new approach here (which is somewhere between a refactor and a full rewrite of the preprocessor) changes things up in a few key ways:

* The abstraction still cares a lot about streams of tokens, but it now treats the top level streams (`InputFile`s) as fairly different from the lower-level streams (`InputStream`s)

* Macro expansion is handled as a dedicated type of stream that wraps another stream. This allows macro expansion to be applied to anything, and supports cases where multiple rounds of macro expansion are required by the spec.

* Macro *invocations* and the substitution of their arguments are now handled by a completely new system.

    * Macro arguments are no longer treated as if they were `#define`s

    * The macro body/definition is analyzed at definition time to detect various kinds of issues, and to derive a list of "ops" that make it easier to "play back" the definition at substitution time

* Token pasting and stringizing are now only handled in macro definitions (rather than being allowed anywhere), and their use cases are restricted to only those that make sense (e.g., you can't stringize anythign except a macro parameter, because anything else wouldn't make sense)

The key new types here are the `ExpansionInputStream` which handles scanning for macro invocations, and the `MacroInvocation` type, which handles playing back the macro body with substitutions.

The `ExpansionInputStream` is the easier of the two to understand. By refactoring it to use a single token of lookahead, the one major detail it had to deal with before (abandoning expansion of a function-like macro if the macro name was not followed by `(`) is significantly easier to manage.

The more subtle part is the `MacroInvocation` type, and most of the complexity there is around handling of token pasting, and the fact that either or both of the operands to a token paste might be empty.

Many of the test cases that exposed the problems in the preprocessor have been moved from `current-bugs` to `preprocessor` since they now work correctly.

* debugging: enable extractor command line dump

* fixup

* fixup
1 parent c4c90f5
History
Tip revision: 0389546b0b065303d3c6874891a9fab4428910b9 authored by T. Foley on 21 May 2021, 22:07:21 UTC
Overhaul the preprocessor (#1849)
Tip revision: 0389546
File Mode Size
.github
build
docs
examples
external
extras
prelude
source
tests
tools
.editorconfig -rw-r--r-- 937 bytes
.gitattributes -rw-r--r-- 95 bytes
.gitignore -rw-r--r-- 1.1 KB
.gitmodules -rw-r--r-- 951 bytes
CODE_OF_CONDUCT.md -rw-r--r-- 3.1 KB
LICENSE -rw-r--r-- 1.1 KB
README.md -rw-r--r-- 6.1 KB
github_build.sh -rw-r--r-- 495 bytes
github_test.sh -rw-r--r-- 546 bytes
premake.bat -rw-r--r-- 120 bytes
premake5.lua -rw-r--r-- 49.0 KB
slang-com-helper.h -rw-r--r-- 4.9 KB
slang-com-ptr.h -rw-r--r-- 4.9 KB
slang-gfx.h -rw-r--r-- 43.9 KB
slang-tag-version.h -rw-r--r-- 36 bytes
slang.h -rw-r--r-- 172.9 KB
slang.sln -rw-r--r-- 21.2 KB
test.bat -rw-r--r-- 1.4 KB

README.md

back to top