-
Notifications
You must be signed in to change notification settings - Fork 26
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
Higher-order macros and macro definitions with explicit delimiters #90
Conversation
The lexer rule [formals] is new. The token [DEFUN] disappears. The non-terminal symbols [def_args1] and [arg_blank] disappear. The locations of a few error messages change slightly. The expected test output is adjusted in a separate commit.
The expected test output is adjusted in a separate commit.
The new way is more verbose but should be more modular (extensible).
For the moment, this shape information is carried around, but unused.
…hape], [check_shape].
This actually enables support for higher-order macros.
This is slightly less redundant and allows extracting a location out of an actual argument even if this is argument is empty. This improves the location of the error message in [test/expect_ident_empty]. The expected test output is updated in the next commit.
This is not a deep change; this way seems slightly preferable. Also, isolate the auxiliary functions [int_expansion_error] and [int_expansion].
In particular, explain when parentheses must be used and must not be used. Give examples.
This clarifies the fact that [line] is the entry point of the lexer.
These macros can span several lines (without backslashes) and can be nested.
…ax error. This produces better syntax error locations in some situations. The expected test output is adjusted in the next commit.
A minor comment:
Not that C has much to do with this, but I'll note that in C, a translation unit (aka a file) without a terminating newline is documented as UB. |
Also, not that Lisp is a precedent we need to care about...
In Lisp, this would be a |
So a lot of this looks neat. I am obligated to ask, of course, what the anticipated use case is. I've traditionally viewed cppo as a sometimes needed hack that one generally wants to avoid. Also, since I started doing a lot of work on refactoring C code I've come to hate cpp in that context because it makes it harder to automate refactoring. However, some of this seems like a very cool experiment. |
Good question! I don't really have a clear use case at this point. Lately, for performance reasons, I have been playing with unrolling loops and specializing higher-order functions (which the OCaml compiler does not do), so |
Sure. I would be happy to use whatever syntax you think is most convenient or elegant. |
I have never used metaocaml, but I understand it is also useful for such things. Would this serve a distinct need? Also, I have no particular brief for |
What do we need to do next to move this pull request forward? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propose merging if no concerns arise by Tuesday 20 Aug AoE.
Seems fine by me. |
Is there something I can/should do? In particular, I haven't written an entry in |
Given the time length for re-running the CI, maybe worth editting the changelog in a separate commit. |
I have pushed two commits to fix a couple typos and add an entry in |
I believe that the CI has succeeded. Is it OK if I release by running |
Please fire at will. You might need to create a tag for v1.7.0 before running the Makefile script. |
@fpottier Just FYI, you're as much a maintainer now as the rest of us. :) |
It's an honor :-) |
Hello,
This PR proposes:
Higher-order macros. This does not break any existing code: the formal parameters of a higher-order macro must be annotated with their types, and there is a new syntax for this purpose.
Macro definitions with explicit delimiters,
#def
and#enddef
. This allows multi-line macros (without backslashes) and nested macros. This is unlikely to break any existing code, but it does introduce two new directives.(minor)
#define
on the last line of a file, without a newline, is now accepted. (It used to be an error. Accepting it allows me to produce a reliable error message when#def
does not have a matching#enddef
.)(minor) Better locations for some syntax error messages, by systematically using
long_loc
instead ofloc
.The new features are documented in README.md.
Some examples of the use of higher-order macros appear in the example file test/higher_order_macros.cppo. Similar examples, which also take advantage of
#def ... #enddef
, appear in test/def.cppo.Here are some more ideas, about which I would welcome the opinion of the
cppo
maintainers. I believe that each of these ideas would be easy to implement:I am tempted to introduce
#scope
and#endscope
delimiters, so as to allow limiting the scope of a macro definition. I believe that this would often remove the need to use#undef
, which is quite painful.The use of higher-order macros is currently somewhat heavy, because the actual argument must be a named macro, so, at the call site, it must be locally defined (and possibly undefined). I am tempted to introduce a syntax for macro-abstractions, which would be allowed to appear as actual arguments to higher-order macros. The syntax would be
#lambda(formals) ... #endlambda
. Perhaps, for greater conciseness, it would be necessary to allow#lambda
and#endlambda
to be recognized as directives even if they are not placed at the beginning of a line.In order to improve hygiene in higher-order macros, I would like to introduce a new directive
#fresh x y
, which behaves like#define x <some fresh name based on y>
. A globally fresh name would be obtained by combining the prefixy
with a numeric suffix obtained by reading and incrementing a global counter.Because
#undef
is heavy, I have been tempted to add a command-line switch--allow-shadowing
, which allows a new macro definition to shadow an existing definition. That said, perhaps#scope ... #endscope
would lessen the need for this feature.