* camlp4 pa_macro
@ 2005-09-06 8:07 Dmitry Bely
2005-09-06 19:35 ` [Caml-list] camlp4 pa_macro (doc request) Martin Jambon
2005-09-07 12:03 ` Peter Jolly
0 siblings, 2 replies; 10+ messages in thread
From: Dmitry Bely @ 2005-09-06 8:07 UTC (permalink / raw)
To: caml-list
Is it possible to achieve with pa_macro something like this:
IFDEF NDEBUG THEN
DEFINE LOG(expr) = ()
ELSE
DEFINE LOG(expr) = Printf.printf expr
ENDIF
...
LOG("x=%d,y=%d" x y);
Unfortunately the code above does not work: debug version is OK, but then
NDEBUG is turned on I have
"This expression is not a function, it cannot be applied" on LOG()
expression.
If I use
LOG "x=%d,y=%d" x y;
then the release version surprisingly works, but the debug one gives
"Parse error: currified constructor"
How to overcome this? Another question: is there an up-to-date Camlp4
manual with all standard extensions (like pa_macro) properly documented?
- Dmitry Bely
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro (doc request)
2005-09-06 8:07 camlp4 pa_macro Dmitry Bely
@ 2005-09-06 19:35 ` Martin Jambon
2005-09-06 21:55 ` Remi Vanicat
2005-09-07 12:03 ` Peter Jolly
1 sibling, 1 reply; 10+ messages in thread
From: Martin Jambon @ 2005-09-06 19:35 UTC (permalink / raw)
To: Dmitry Bely; +Cc: caml-list
On Tue, 6 Sep 2005, Dmitry Bely wrote:
> Another question: is there an up-to-date Camlp4
> manual with all standard extensions (like pa_macro) properly documented?
I copy-pasted what the source file says.
I guess I could setup a web page with examples. Of course, it would be
better if it were included in the official documentation.
Thanks,
Martin
>From camlp4/meta/pa_macro.ml:
(*
Added statements:
At toplevel (structure item):
DEFINE <uident>
DEFINE <uident> = <expression>
DEFINE <uident> (<parameters>) = <expression>
IFDEF <uident> THEN <structure_items> (END | ENDIF)
IFDEF <uident> THEN <structure_items> ELSE <structure_items> (END | ENDIF)
IFNDEF <uident> THEN <structure_items> (END | ENDIF)
IFNDEF <uident> THEN <structure_items> ELSE <structure_items> (END | ENDIF)
INCLUDE <string>
In expressions:
IFDEF <uident> THEN <expression> ELSE <expression> (END | ENDIF)
IFNDEF <uident> THEN <expression> ELSE <expression> (END | ENDIF)
__FILE__
__LOCATION__
In patterns:
IFDEF <uident> THEN <pattern> ELSE <pattern> (END | ENDIF)
IFNDEF <uident> THEN <pattern> ELSE <pattern> (END | ENDIF)
As Camlp4 options:
-D<uident> define <uident>
-U<uident> undefine it
-I<dir> add <dir> to the search path for INCLUDE'd
files
After having used a DEFINE <uident> followed by "= <expression>", you
can use it in expressions *and* in patterns. If the expression defining
the macro cannot be used as a pattern, there is an error message if
it is used in a pattern.
The toplevel statement INCLUDE <string> can be used to include a
file containing macro definitions; note that files included in such
a way can not have any non-macro toplevel items. The included files
are looked up in directories passed in via the -I option, falling
back to the current directory.
The expression __FILE__ returns the current compiled file name.
The expression __LOCATION__ returns the current location of itself.
*)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro (doc request)
2005-09-06 19:35 ` [Caml-list] camlp4 pa_macro (doc request) Martin Jambon
@ 2005-09-06 21:55 ` Remi Vanicat
2005-09-07 8:29 ` [Caml-list] camlp4 pa_macro Dmitry Bely
0 siblings, 1 reply; 10+ messages in thread
From: Remi Vanicat @ 2005-09-06 21:55 UTC (permalink / raw)
To: Martin Jambon; +Cc: Dmitry Bely, caml-list
2005/9/6, Martin Jambon <martin_jambon@emailuser.net>:
> On Tue, 6 Sep 2005, Dmitry Bely wrote:
>
> > Another question: is there an up-to-date Camlp4
> > manual with all standard extensions (like pa_macro) properly documented?
>
> I copy-pasted what the source file says.
> I guess I could setup a web page with examples. Of course, it would be
> better if it were included in the official documentation.
Well, the camlp4 documentation is outdated, it contain, so may be some
documentation for those extension will be added when the new version
of the documentaion will be out.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-06 21:55 ` Remi Vanicat
@ 2005-09-07 8:29 ` Dmitry Bely
2005-09-07 8:40 ` Remi Vanicat
0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Bely @ 2005-09-07 8:29 UTC (permalink / raw)
To: caml-list
On Tue, 6 Sep 2005 Remi Vanicat wrote:
> > > Another question: is there an up-to-date Camlp4
> > > manual with all standard extensions (like pa_macro) properly documented?
> >
> > I copy-pasted what the source file says.
> > I guess I could setup a web page with examples. Of course, it would be
> > better if it were included in the official documentation.
>
> Well, the camlp4 documentation is outdated, it contain, so may be some
> documentation for those extension will be added when the new version
> of the documentaion will be out.
Where is that (even outdated) camlp4 documentation? The current ocaml docs do not containt anything related to camlp4 (except maybe streams).
Also camlp4 doc request was just the second question in my original message - I was able to read the comments in pa_macro.ml. But I was not able to make LOG() macro work. Does anybody have an idea how to achieve that? I think that's not something extraordinary - just the very basic usage.
- Dmitry Bely
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-07 8:29 ` [Caml-list] camlp4 pa_macro Dmitry Bely
@ 2005-09-07 8:40 ` Remi Vanicat
0 siblings, 0 replies; 10+ messages in thread
From: Remi Vanicat @ 2005-09-07 8:40 UTC (permalink / raw)
To: Dmitry Bely; +Cc: caml-list
2005/9/7, Dmitry Bely <dbely@mail.ru>:
> Where is that (even outdated) camlp4 documentation? The current ocaml docs do
> not containt anything related to camlp4 (except maybe streams).
http://www.google.com/search?hl=fr&q=camlp4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-06 8:07 camlp4 pa_macro Dmitry Bely
2005-09-06 19:35 ` [Caml-list] camlp4 pa_macro (doc request) Martin Jambon
@ 2005-09-07 12:03 ` Peter Jolly
2005-09-07 12:28 ` Basile STARYNKEVITCH
2005-09-08 8:47 ` Dmitry Bely
1 sibling, 2 replies; 10+ messages in thread
From: Peter Jolly @ 2005-09-07 12:03 UTC (permalink / raw)
To: Dmitry Bely; +Cc: caml-list
Dmitry Bely wrote:
> Is it possible to achieve with pa_macro something like this:
>
> IFDEF NDEBUG THEN
> DEFINE LOG(expr) = ()
> ELSE
> DEFINE LOG(expr) = Printf.printf expr
> ENDIF
> ...
> LOG("x=%d,y=%d" x y);
>
> Unfortunately the code above does not work: debug version is OK, but then
> NDEBUG is turned on I have
>
> "This expression is not a function, it cannot be applied" on LOG()
> expression.
Getting camlp4 to pretty-print the code after macro expansion is a
useful technique for debugging this sort of problem:
$ camlp4 pa_o.cmo pa_op.cmo pr_o.cmo pa_macro.cmo test.ml
...
Printf.printf ("x=%d,y=%d" x y)
It should be clear why that isn't working.
> If I use
>
> LOG "x=%d,y=%d" x y;
>
> then the release version surprisingly works, but the debug one gives
>
> "Parse error: currified constructor"
Yes, because this does not pass any arguments to the LOG macro - it
expands it with an empty <expr>. So this works in the latter case,
because LOG just expands to "Printf.printf", but in the former case you
end up with
() "x=%d,y=%d" x y
which is a syntax error as reported.
> How to overcome this?
IFDEF NDEBUG THEN
DEFINE LOG = Printf.kprintf ignore
ELSE
DEFINE LOG = Printf.printf
ENDIF
Or just replace all instances of LOG with "if debug then Printf.printf",
on the grounds that the compiler is probably clever enough to prune
conditions that always evaluate to false, and you probably won't notice
any significant difference in speed even if it isn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-07 12:03 ` Peter Jolly
@ 2005-09-07 12:28 ` Basile STARYNKEVITCH
2005-09-07 19:46 ` Jonathan Roewen
2005-09-08 8:47 ` Dmitry Bely
1 sibling, 1 reply; 10+ messages in thread
From: Basile STARYNKEVITCH @ 2005-09-07 12:28 UTC (permalink / raw)
To: Peter Jolly; +Cc: caml-list
Le Wed, Sep 07, 2005 at 01:03:07PM +0100, Peter Jolly écrivait/wrote:
> Dmitry Bely wrote:
> > Is it possible to achieve with pa_macro something like this:
> >
> > IFDEF NDEBUG THEN
> > DEFINE LOG(expr) = ()
> > ELSE
> > DEFINE LOG(expr) = Printf.printf expr
> > ENDIF
> > ...
> > LOG("x=%d,y=%d" x y);
> >
> > Unfortunately the code above does not work: debug version is OK, but then
> > NDEBUG is turned on I have
> >
> > "This expression is not a function, it cannot be applied" on LOG()
> > expression.
>
For information the pa_trace.ml file (for camlp4 for a pre 3.08
version of ocaml) did exactly what you want to achieve
you might look for POESIA on sourceforge at
http://sourceforge.net/project/showfiles.php?group_id=79887&release_id=1
download the source package http://prdownloads.sourceforge.net/poesia/poesiasoft_snapshot_20july2005.tar.gz?download
and look for the pa_trace.ml inside PoesiaMonIcap
this is orphaned software (GPL). I don't maintain it anymore, and I
believe it don't compile as-is on 3.08 because of the location change
in camlp4 since 3.06. Feel free to patch it for your needs.
Regards
--
Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basile(at)starynkevitch(dot)net
8, rue de la Faïencerie, 92340 Bourg La Reine, France
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-07 12:28 ` Basile STARYNKEVITCH
@ 2005-09-07 19:46 ` Jonathan Roewen
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Roewen @ 2005-09-07 19:46 UTC (permalink / raw)
To: Basile STARYNKEVITCH; +Cc: Peter Jolly, caml-list
> > > IFDEF NDEBUG THEN
> > > DEFINE LOG(expr) = ()
> > > ELSE
> > > DEFINE LOG(expr) = Printf.printf expr
> > > ENDIF
> > > ...
> > > LOG("x=%d,y=%d" x y);
I don't see anything that says the DEFINEs have to be symmetric.
Maybe this doesn't handle parameters like I assume it would, but how about:
IFDEF NDEBUG THEN
DEFINE LOG(expr) = ()
ELSE
DEFINE LOG = Printf.printf
ENDIF
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-07 12:03 ` Peter Jolly
2005-09-07 12:28 ` Basile STARYNKEVITCH
@ 2005-09-08 8:47 ` Dmitry Bely
2005-09-08 12:48 ` David MENTRE
1 sibling, 1 reply; 10+ messages in thread
From: Dmitry Bely @ 2005-09-08 8:47 UTC (permalink / raw)
To: Peter Jolly; +Cc: caml-list
Peter Jolly <peter@jollys.org> writes:
>> Is it possible to achieve with pa_macro something like this:
>>
>> IFDEF NDEBUG THEN
>> DEFINE LOG(expr) = ()
>> ELSE
>> DEFINE LOG(expr) = Printf.printf expr
>> ENDIF
>> ...
>> LOG("x=%d,y=%d" x y);
>>
>> Unfortunately the code above does not work: debug version is OK, but then
>> NDEBUG is turned on I have
>>
>> "This expression is not a function, it cannot be applied" on LOG()
>> expression.
>
> Getting camlp4 to pretty-print the code after macro expansion is a
> useful technique for debugging this sort of problem:
>
> $ camlp4 pa_o.cmo pa_op.cmo pr_o.cmo pa_macro.cmo test.ml
> ...
> Printf.printf ("x=%d,y=%d" x y)
>
> It should be clear why that isn't working.
I see. Thank you very much for the info.
>
>> If I use
>>
>> LOG "x=%d,y=%d" x y;
>>
>> then the release version surprisingly works, but the debug one gives
>>
>> "Parse error: currified constructor"
>
> Yes, because this does not pass any arguments to the LOG macro - it
> expands it with an empty <expr>. So this works in the latter case,
> because LOG just expands to "Printf.printf", but in the former case you
> end up with
>
> () "x=%d,y=%d" x y
>
> which is a syntax error as reported.
>
>> How to overcome this?
>
> IFDEF NDEBUG THEN
> DEFINE LOG = Printf.kprintf ignore
> ELSE
> DEFINE LOG = Printf.printf
> ENDIF
It's quite useless -
let debug = ref true
let log fmt =
if !debug then
Printf.kprintf print_string fmt
else
Printf.kprintf ignore fmt
will in fact give the same result. It does not solve the initial problem -
completely remove the debugging code from the release binary.
> Or just replace all instances of LOG with "if debug then Printf.printf",
> on the grounds that the compiler is probably clever enough to prune
> conditions that always evaluate to false, and you probably won't notice
> any significant difference in speed even if it isn't.
But the debugging code (format strings etc.) will be there. OK, the best I
can get now is
IFDEF NDEBUG THEN
DEFINE LOG(expr) = ()
ELSE
let dprintf = Printf.printf
DEFINE LOG(expr) = expr
ENDIF
...
LOG(dprintf "x=%d,y=%d" x y);
Not very elegant, but works.
- Dmitry Bely
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Caml-list] camlp4 pa_macro
2005-09-08 8:47 ` Dmitry Bely
@ 2005-09-08 12:48 ` David MENTRE
0 siblings, 0 replies; 10+ messages in thread
From: David MENTRE @ 2005-09-08 12:48 UTC (permalink / raw)
To: Dmitry Bely; +Cc: Peter Jolly, caml-list
Hello,
2005/9/8, Dmitry Bely <dbely@mail.ru>:
> let debug = ref true
>
> let log fmt =
> if !debug then
> Printf.kprintf print_string fmt
> else
> Printf.kprintf ignore fmt
>
> will in fact give the same result. It does not solve the initial problem -
> completely remove the debugging code from the release binary.
If you use "let debug = true", i.e. remove the reference, the
debugging code is indeed removed for *native* compilation. See this
answer by Xavier Leroy:
http://groups.google.com/group/fa.caml/browse_frm/thread/e80a6b8cf550a9cc/f3bb4fc08274512d?tvc=1&q=mentre+leroy+avoid+compiling#f3bb4fc08274512d
BTW, the above old thread is very similar to this one, with different
techniques to have optional debug code.
Yours,
d.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2005-09-08 12:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-06 8:07 camlp4 pa_macro Dmitry Bely
2005-09-06 19:35 ` [Caml-list] camlp4 pa_macro (doc request) Martin Jambon
2005-09-06 21:55 ` Remi Vanicat
2005-09-07 8:29 ` [Caml-list] camlp4 pa_macro Dmitry Bely
2005-09-07 8:40 ` Remi Vanicat
2005-09-07 12:03 ` Peter Jolly
2005-09-07 12:28 ` Basile STARYNKEVITCH
2005-09-07 19:46 ` Jonathan Roewen
2005-09-08 8:47 ` Dmitry Bely
2005-09-08 12:48 ` David MENTRE
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox