[TIR] Generalize implementation of T.macro to work with other dialects #15432
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As a background info---the script parser works by visiting a "statement" (or top-level expression) at a time. The expression parts of the statement are evaluated, and then the IR corresponding to the statement is constructed if necessary.
In TIR, macro calls can only occur at the statement level, and they don't produce any values. This means that the statement visitor (
visit_expr_stmt
) can see these calls directly in its node parameter. At this point it could simply visit the body of the macro instead, which is the basis of the existing implementation.In other dialects there may be a need for macros to produce values. This means that macro calls can occur in the middle of complex expressions. As a result, these calls will not be present at the statement level, and the TIR approach by intercepting them in
visit_expr_stmt
will no longer work. Instead, these macros delay the visiting of the macro body to the evaluation time. A macro is represented by anScriptMacro
(TIRMacro
in the current implementation) object (created via macro decorator). When the evaluator evaluates an expression with a macro call, it will call the macro object (since macro calls use function call syntax). It is in the macro object's__call__
function where the macro parsing picks up. The remaining issue was to pass the Parser object to the__call__
function. This is done by injecting it into the global dictionary under a reserved name.It turns out that the same approach also works for TIR, and the macro processing can be generalized, leaving only language-specific details to the language-specific language macro objects.