Request: (expression).stringof should return a textual AST

Don Clugston dac at nospam.com.au
Thu May 3 07:47:00 PDT 2007


Don Clugston wrote:
> Many uses of textual macros involve D expression syntax.
> For example,
> 
> int x;
> mixin(println("The value of x is $x and the next value is ${x+1}"));
> 
> If these embedded expressions are evaluated by manually parsing the 
> string, we need to be able to be able to identify D literals, such as
> floating-point literals (-0x1.2_5p-38, 1e80, etc). Also, we need to 
> enforce the precedence rules. This is quite a lot of code that is 
> difficult to get right.
> 
> Almost all the difficulty could be avoided by standardizing the 
> behaviour of (expression).stringof.
> 
> The behaviour of .stringof when presented with an expression has changed 
> a couple of times already. According to the spec, (expression).stringof 
> is not supposed to perform semantic analysis, but it currently does (bug 
> #1142). It seems that it parses the expression, performs type checking, 
> and returns a slightly modified string.
> 
> For use in metaprogramming, it would extremely useful if instead, it 
> parsed the string, without reference to types, removed unnecessary 
> spaces and parentheses, and inserted parentheses to indicate precedence.
> 
> Under this proposal, with an expression, .stringof would return a value 
> which was a standardised equivalent to the original string:
> 
> (1.2e+58+2*3).stringof --> (1.2e+58)+((2)*(3))
> (func(var, var1*3.6)--> ((func)((var),((var1)*(3.6))))
> 
> This would allow code generators to accept D expressions embedded in 
> strings, without needing to implement a lexer or precedence of 
> operators; it only needs to count the number of ( and ).
> 
> All terminal expressions would be wrapped in () (or alternatively, they 
> could be terminated with a space -- doesn't matter as long as it is 
> consistent).
 >
 > If there is a mixin in the expression, it should be evaluated before
 > .stringof is invoked. (It's not possible to know the precedence until
 > you have the complete string).


After experimenting with this a bit more, wrapping everything in () is 
not necessary or even desirable -- it does look pretty ugly.
It would be enough to ensure all terminal expressions are 
space-terminated, and () is only required when the order of evaluation 
should not be left-to-right, due to precedence or associativity. So my 
examples would be:

(1.2e+58+2*3).stringof --> "1.2e+58 + ( 2 * 3 )"
(func(var, var1*3.6).stringof --> "func ( var , var1 * 3.6 )"
and
(2*3+1.2e+58).stringof --> "2 * 3 + 1.2e+58"

Bug #1142 gets us most of the way there.





More information about the Digitalmars-d mailing list