Given this type:
type 'a variable = { name: string; mutable value: 'a }
I'm trying to create a syntax extension that would accept this syntax:
var foo = true
...and convert it to:
let foo = { name = "foo"; value = true }
Here's my attempt:
open Camlp4.PreCast
open Syntax
type 'a variable = { name: string; mutable value: 'a }
EXTEND Gram
expr: LEVEL "top"
[ [ "var"; v = a_LIDENT; "="; e = expr ->
<:expr< let $lid:v$ = { name= $`str:v$ ; value = $e$ } in $e$ >>
] ]
;
END
(I'm pretty sure it needs that $e$ at the end of the substitution as a way of saying "the rest", but it also looks kind of suspect given that we want the value field of the record to have the value of the expression on the right - initially I did not have the ending $e$ there and got the same error)
I try compiling with:
ocamlc -I +camlp4 camlp4lib.cma -pp camlp4orf -c pa_var.ml
Which results in:
File "pa_var.ml", line 10, characters 50-51:
While expanding quotation "expr" in a position of "expr":
Parse error: "}" expected after [label_expr_list] (in [expr])
File "pa_var.ml", line 1, characters 0-1:
Error: Preprocessor error
I do not know know why it seems to want to have a "}" after the name field of the record. (Otherwise, am I on the right track here?)
The error is that you use
camlp4orf
, which uses standard syntax for the code, but revised syntax for the quotations, along with a field namevalue
, which is a keyword in OCaml revised syntax. The simplest fix is to usescamlp4oof
to use standard syntax everywhere, but you could also rename that field.PS: I really don't think it is necessary to write a Camlp4 extension to do this. I would suggest living with the redundancy and using
let foo = var "foo" true
instead. That would simplify maintenance, interaction with other codebases, etc.PPS: A couple more comments :
you don't want to implement it that way; if you want to catch toplevel declaration phrases
let x = foo;;
, you must live instruct_item
, notexpr
, and inexpr
you may want to catch local declarations of the formvar <lid> = <expr> in <expr>
.If you insist on using Camlp4, you should avoid grammar modification using
EXTEND
, as you are doing right now. Instead chooselet foo = VAR true
as your concrete syntax, and use theCamlp4Filters
mechanism to transform this into what you want. This will be much more robust and simple to implement.