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