caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* 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;
as well as URLs for NNTP newsgroup(s).