[stringtemplate-interest] [ST4 Beta4] Default args are not always evaluated in the context of their template

Sam Harwell sharwell at pixelminegames.com
Thu Feb 17 06:45:18 PST 2011


That's correct. Remember you are passing the template and not its evaluated
result to t2. If you want to pass the evaluated result to t2, you need to
use parentheses (the "tostring" operator) as follows:

t1(p1,p2={<p1>}) ::= <<
  inside t1: p1=<p1>, p2=<p2>
<t2(p1="B",p2=(p2))>
>>

Sam

-----Original Message-----
From: stringtemplate-interest-bounces at antlr.org
[mailto:stringtemplate-interest-bounces at antlr.org] On Behalf Of Udo
Borkowski
Sent: Thursday, February 17, 2011 5:04 AM
To: stringtemplate-interest List
Subject: [stringtemplate-interest] [ST4 Beta4] Default args are not always
evaluated in the context of their template

Ter wrote in a recent mail:

> In ST v4, the default args are formally defined to have the same context
as the template itself, hence, default arguments can see the other
arguments.
> 


Based on this I expected the default args are also evaluated in the context
of the template, e.g. if t1 is defined as

	t1(p1,p2={<p1>}) ::= <<.>>

and I call

	<t1(p1="A")>

p1 and p2 both will have the value "A". 

As it turns out this is not always the case.


When the name "p1" is later used in a different template called inside of t1
the new value of p1 is also applied to the default arg (and not the value
defined in the context of t1). 

Here a complete example:

-----------
t1(p1,p2={<p1>}) ::= <<
  inside t1: p1=<p1>, p2=<p2>
<t2(p1="B",p2=p2)>
>>

t2(p1,p2) ::= <<
  inside t2: p1=<p1>, p2=<p2>
>>

main() ::= <<
Use default value for p2
<t1(p1="A")>
>> 
------------

This will output:
-------------
Use default value for p2
  inside t1: p1=A, p2=A
  inside t2: p1=B, p2=B
----------

However I had expected:
-------------
Use default value for p2
  inside t1: p1=A, p2=A
  inside t2: p1=B, p2=A
----------

i.e. I expected p2 to be "A" in the template t2, too, as this is the default
value defined in the context of t1.

It looks like the names in a default value expression/subtemplate are
resolved the "normal" way by dynamically looking up the call chain for the
name, starting "at the current scope", i.e. "the point when the default
value template is currently expanded". I expected the lookup starts with the
template argument definition in t1(p1,p2={<p1>}). If this fails a "normal"
lookup may be performed.

I know one could "fix" the above example by changing the definition of t1
from

	t1(p1,p2={<p1>}) ::= <<.>>
to 
	t1(p1,p2={<(p1)>}) ::= <<.>>

i.e. force to "stringify" the default value in the argument definition. 

However 
a) I am not sure if this is obvious for the "casual user".  (BTW: is this
"{<(p1)>}" behavior documented somewhere? I learned this by reading the
source code.)

b) this does not work in all cases. E.g. the template definition

	t3(p1,p2={<p1>x}) ::= <<.>>

(i.e. append an "x" to the value of p1 to create p2) could not be fixed this
way.


To fix the issue I assume one needs to remember the context of the default
value subtemplate (i.e. the argument list) with the subtemplate instance and
check this context first before doing the normal dynamic name lookup.


Udo

_______________________________________________
stringtemplate-interest mailing list
stringtemplate-interest at antlr.org
http://www.antlr.org/mailman/listinfo/stringtemplate-interest



More information about the stringtemplate-interest mailing list