Skip to content

Initial support for metaocaml#2630

Open
hhugo wants to merge 1 commit intomainfrom
metaocaml
Open

Initial support for metaocaml#2630
hhugo wants to merge 1 commit intomainfrom
metaocaml

Conversation

@hhugo
Copy link
Copy Markdown
Collaborator

@hhugo hhugo commented Nov 26, 2024

This PR is the result of a quick experiment to add support for metaocaml.
You should feel free to take over it and push it through.

Fix #1211

This PR

  • The parser rules are already present (here and upstream)
  • This PR patches lexers to emit metaocaml tokens if requested (inspired from MetaOCaml parsing mode ocaml/ocaml#12470)
  • The metaocaml syntax is preserved. The corresponding extension points are not automatically converted to metaocaml syntax.
  • This PR introduce a new config flag to switch metaocaml mode on

Testing

I've not added tests yet.

This PR was manually tested with the following example

$ cat meta.ml

   let rec spower n x =
      if n = 0 then .<1>.
      else if n mod 2 = 0 then .<square .~(spower (n/2) x)>.
      else .<.~x * .~(spower (n-1) x)>.
    (* val spower : int -> int code -> int code = <fun> *)

$ dune exec ocamlformat -- --metaocaml meta.ml

let rec spower n x =                   
  if n = 0 then .< 1 >.
  else if n mod 2 = 0 then .< square .~(spower (n / 2) x) >.
  else .< .~x * .~(spower (n - 1) x) >.
(* val spower : int -> int code -> int code = <fun> *)

Add a --metaocaml flag to enable MetaOCaml syntax (brackets .< >.,
escape .~, run .!) in the lexer and formatter.

Lexer changes:
- Split symbolchar into symbolcharnodot/symbolchar to avoid
  capturing MetaOCaml tokens as operator characters
- Gate .~ (escape) and >. (bracket close) behind the metaocaml flag;
  .< (bracket open) is always lexed as METAOCAML_BRACKET_OPEN
- Add symbolchars sub-lexer for consuming remaining operator chars
  after >. when metaocaml is disabled
- Thread ~metaocaml through parse.ml to set lex_metaocaml ref

Formatter changes:
- Detect metaocaml.bracket and metaocaml.escape extension nodes
  (synthetic, with ghost loc) and render them with sugar syntax
  (.< expr >. and .~expr) instead of [%metaocaml.bracket ...]
- Parenthesize .~ argument unless it is a simple identifier
- Skip comment relocation for metaocaml extension nodes in Cmts

Configuration:
- Add metaocaml boolean to opr_opts (Conf_t), default false
- Wire --metaocaml/--no-metaocaml flag through Conf and CLI
- Thread ~metaocaml through Extended_ast, Std_ast,
  Parse_with_comments, Toplevel_lexer
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.

Feature request: support BER MetaOCaml

1 participant