-
Notifications
You must be signed in to change notification settings - Fork 16
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
Allow --prefix
, --infix
and --postfix
pragmas to refer to later constant declarations
#270
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This ensures that we can print pragmas without applying their effect. This is useful for postponed fixity pragmas.
…otation` The verb `add` is more indicative of a side effect on the pretty-printing state.
This test case is derived from `./t/code/success/infix/alternate.bel`. The difference is that the new style of LF declarations is used, along with infix pragmas that precedence the type family declaration. Those pragmas are postponed, in the sense that they apply to constants declared after it as opposed to constants already in scope.
This removes some of the duplicated code for determining whether a fixity pragma is postponed or not.
MartyO256
added a commit
that referenced
this pull request
Oct 24, 2023
PR #270 did not include the necessary changes to support postponed fixity pragmas in Harpoon sessions. When a reconstructed Beluga signature is revisited to create snapshots of the disambiguation state, Harpoon would raise an unbound identifier exception for postponed fixity pragmas.
MartyO256
added a commit
that referenced
this pull request
May 7, 2024
This updates the disambiguation algorithm for module entries to support postponed fixity pragmas (#270).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
Before v1.1, it was possible to declare an identifier as an operator before any constant declaration was attached to that identifier.
For instance, the following snippet first defines
~
as an infix operator, then declares an LF type-level constant with identifier~
. This made it possible to use that infix notation in the definition of LF term-level constants.The re-write of the parser in #266 to support shadowing of constants and the definition of namespaces broke that feature. Indeed, it became necessary for fixity pragmas to refer to constants that are already bound. This meant that parsing the pragma
--infix ~ 1 right.
would result in an "Unbound identifier ~" exception to be thrown.The reason why this breaking change occurred is because in the disambiguation state, the notation for an identifier has to be attached to the constant it is meant to affect. This is necessary because opening a module with the
--open
pragma has to bring that notation back in scope.Changes
This PR re-introduces the feature of having a
--prefix
,--infix
or--postfix
pragma before the declaration it is meant to affect. During the disambiguation of Beluga signatures, when a fixity pragma is encountered, a lookahead is performed to determine if the closest declaration that follows the pragma introduces a constant with the same identifier as the target of the pragma. If it is the case that this next declaration introduces the pragma's target, then the fixity pragma is said to be postponed, in the sense that it is applied once that constant is added to the disambiguation state.Put more precisely, if
P
is a fixity pragma with target identifierc
, andD
is a declaration that introduces a constant with identifierc
, thenP
is a postponed fixity pragma if we have the following in a Beluga signature file:This makes it possible to write snippets like the following:
The
./t/code/success/infix/postponed.bel
test case is added to showcase this feature.If a fixity pragma is found not to be postponed, then it affects a constant declared earlier in the signature, like it did in v1.1. The proposed lookahead solution does not introduce ambiguity in the placement of fixity pragmas. If the pragma is between two declarations that use the same identifier, then the pragma is postponed. Attaching the pragma to the earlier declaration would not be useful since that constant is immediately shadowed by the other declaration.
This change affects all the areas where fixity pragmas are involved, namely:
OpPragmas
store, which is constructed during signature reconstruction)