[metapost] accessing variables in nested macros

Ryan Van Wagoner whiteviz at gmail.com
Fri Feb 9 22:01:18 CET 2007


>>>>> "Stephen Hennig" == Stephan Hennig <mailing_list at arcor.de> writes:

 Stephen Hennig> def init=
 Stephen Hennig>  calculation;
 Stephen Hennig> enddef;

 Stephen Hennig> vardef calcA(expr parameters)=
 Stephen Hennig>   init;
 Stephen Hennig> enddef;

 Stephen Hennig> when called, more or less to literally replace "init;" by "calculation;"
 Stephen Hennig> and therefore accessing variables from "calcA" in "init" should be ok.
 Stephen Hennig> However, in the example below I can't access variables from the calling
 Stephen Hennig> macro.  What's wrong with my definition?

Your problem appears to be related to scoping, although I am not
familiar with how scope works in MetaPost.  Since "def" is supposed to
act like a macro, i.e. direct replacement of "init" with the text in
your definition prior to evaluation, I agree that your approach should
work.  Especially given that the "vardef" wraps things with begingroup
and endgroup.  However, if you change your definition of "init" slightly
to something that should behave identically, it highlights that the
problem is that the variable "a" is not available to the expansion of
"init".

def init =
save b;
numeric b;
scantokens("b := " & decimal a & " + 1;");
enddef;

gives the error:

>> a
! Not implemented: decimal(unknown numeric).
<to be read again> 
                   &
init->...b;numeric.b;scantokens("b := "&decimal.a&
                                                  " + 1;");
calcA->begingroup.init
                      ;show"a = "&decimal(EXPR2);show"b = "&decimal.b;endgroup
l.14 calcA(163)
               ;

So even though your expanded "init" macro should be parsed and digested
in the scope of the vardef where "a" is bound to the argument of the
macro, it is not.  Note that if you move the scantokens line into the
definition of calcA, it works as expected.  However, if you use instead:

scantokens("b := a + 1;");

inside your calcA definition, you get the same error as shown above.
This suggests that the binding of "a" in the vardef is not available
either to scantokens or to the macro expansion/evaluation machinery (how
similar are these two mechanisms?).

I'm sorry that this does not provide an answer to your question, but it
might prompt someone else to provide some clarification on how scope and
evaluation are handled in MetaPost.  I also apologize if my terminology
is a bit lispish, but that's where my head is these days.

Regards,

-- 

Ryan Van Wagoner


More information about the metapost mailing list