Skip to content
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

MetaOCaml: support for .<e>. and .~e #11871

Open
wants to merge 12 commits into
base: trunk
Choose a base branch
from

Conversation

johnyob
Copy link
Contributor

@johnyob johnyob commented Jan 5, 2023

A follow on PR from #10131, cc @Octachron.

This PR adds MetaOCaml brackets and escapes to the OCaml parser and Parsetree.

  • .<e>. is parsed as Pexp_bracket e
  • .~e is parsed as Pexp_escape e

In the type checker, these MetaOCaml nodes are handled as extensions, reporting a 'Uninterpreted MetaOCaml expression' error. For instance:

# let one = .<1>.;;
Error: Uninterpreted MetaOCaml expression.

Copy link
Contributor

@nojb nojb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! You can add a parsing test for the new constructions in testsuite/tests/parsetree/source.ml.

@@ -340,6 +340,8 @@ let identchar_latin1 =

let symbolchar =
['!' '$' '%' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~']
let symbolcharnodot =
['!' '$' '%' '&' '*' '+' '-' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can define

let symbolchar = symbolcharnodot | '.'

or

let symbolcharnodot = symbolchar # '.'

@@ -228,6 +228,11 @@ module Exp = struct
pbop_exp = exp;
pbop_loc = loc;
}

(* NNN begin *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does NNN stand for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe it stands for anything. It seems to be a convention in the other MetaOCaml PRs (#10130, #10131, #10132) to prefix / annotate MetaOCaml specific changes with NNN.

I have no strong opinions regarding it, so I'm more than happy to remove the NNN comments.

Comment on lines +761 to +763
(match e.pexp_desc with
| Pexp_ident li -> pp f ".~%a" longident_loc li
| _ -> pp f ".~%a" (paren true (expression ctxt)) e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use simple_expr here?

Suggested change
(match e.pexp_desc with
| Pexp_ident li -> pp f ".~%a" longident_loc li
| _ -> pp f ".~%a" (paren true (expression ctxt)) e)
pp f ".~%a" (simple_expr ctxt) e

@@ -754,6 +754,14 @@ and expression ctxt f x =
(expression ctxt) body
| Pexp_extension e -> extension ctxt f e
| Pexp_unreachable -> pp f "."
(* NNN begin *)
| Pexp_bracket e ->
pp f "@[<hov2>.<@ %a @ >.@]" (expression ctxt) e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for the extra (breaking) space?

Suggested change
pp f "@[<hov2>.<@ %a @ >.@]" (expression ctxt) e
pp f "@[<hov2>.<%a>.@]" (expression ctxt) e

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spaces are useful for when e is a 'larger' expression. For instance: I find

.< let foo = bar () in baz foo foo >.

more readable compared to:

.<let foo = bar () in baz foo foo>.

But this is rather subjective, so I'm happy to implement the suggestion if you disagree.

@@ -754,6 +754,14 @@ and expression ctxt f x =
(expression ctxt) body
| Pexp_extension e -> extension ctxt f e
| Pexp_unreachable -> pp f "."
(* NNN begin *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments do not seem very useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I concur. See above comment regarding NNN.

@hhugo
Copy link
Contributor

hhugo commented Jan 6, 2023

The comment from #10130 still holds #10130 (comment)

@Kakadu
Copy link
Contributor

Kakadu commented Jan 7, 2023

I looked a bit into metaocaml patches, and it seems that new syntax constructions are encoded using attibutes.
Maybe we shouldn't push changes in parser related to metaocaml? Maybe two extra parsetree nodes is already good enough?

@johnyob
Copy link
Contributor Author

johnyob commented Jan 7, 2023

The comment from #10130 still holds #10130 (comment)

@hhugo once #10130 is merged (having implemented a satisfactory solution) I'll rebase on top of it

@gasche
Copy link
Member

gasche commented Jan 13, 2023

Semi-related: as far as we know, MetaOCaml has not been released upstream in version 4.14 and 5.0. This is something that people interested in contributing could consider helping with.

@yallop
Copy link
Member

yallop commented Jan 13, 2023

@gasche: what do you have in mind? MetaOCaml development doesn't take place in public, so I'm not sure what you're proposing.

@Octachron
Copy link
Member

@yallop , would it not be possible for an external contributor to update the last released version of MetaOCaml to either 4.14 or 5.0 ? That might help people working on the upstreaming patches to build some intuitions of what changes are required to reduce MetaOCaml maintenance burden in its current incarnation.

@yallop
Copy link
Member

yallop commented Jan 13, 2023

@Octachron: each new release of BER MetaOCaml typically has various non-trivial changes.

Some changes arise from interactions with new features in the underlying OCaml release. For example, the detection of scope extrusion in BER MetaOCaml relies on various assumptions about the stack, as the notes in the source code explain:

We use a different method: we mark each piece of the generated code with the list of free variable the code contains. Each variable is associated with a `stackmark', which identifiers the region with which the variable is associated. All valid stackmarks form a total order. Alas, delimited control can reshuffle that order.

It may be that design and implementation decisions are needed to handle the changes to stacks in OCaml 5 (or perhaps the existing care taken to properly handle delimited control is already sufficient; I don't know offhand).

Other changes involve updates to the design or implementation of MetaOCaml itself. For example, the changelog for MetaOCaml 111 (based on OCaml 4.11) describes new features for let rec generation:

Added generation (mutually) recursive let. See more detailed explanation in PEPM 2019 and ML 2019. Examples in those papers work (see test/genletrec.ml)

In other words, MetaOCaml isn't just a fairly fixed patchset that needs to be updated/rebased when new OCaml releases are made; each new release has significant changes that require design and implementation decisions by the maintainer. Helping with the next MetaOCaml release consequently requires interacting with the maintainer.

@gasche
Copy link
Member

gasche commented Aug 5, 2023

It may be interesting to rebase this PR on top of #12470, which is our new attempt at upstream-friendly patches for lexer+parser MetaOCaml support. (But: we could also make a better job of providing @johnyob on feedback on the current PR, before we ask for more work on his side.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants