@@ -73,6 +73,9 @@ shared static this()
7373 typeMap[typeid (TypeofExpression)] = 46 ;
7474 typeMap[typeid (UnaryExpression)] = 47 ;
7575 typeMap[typeid (XorExpression)] = 48 ;
76+ typeMap[typeid (InterpolatedStringExpression)] = 49 ;
77+ typeMap[typeid (InterpolatedStringText)] = 50 ;
78+ typeMap[typeid (InterpolatedStringVariable)] = 51 ;
7679}
7780
7881// / Describes which syntax was used in a list of declarations in the containing AST node
@@ -167,6 +170,19 @@ abstract class ASTVisitor
167170 case 46 : visit(cast (TypeofExpression) n); break ;
168171 case 47 : visit(cast (UnaryExpression) n); break ;
169172 case 48 : visit(cast (XorExpression) n); break ;
173+ // skip 49, 50, 51 (used for InterpolatedStringPart)
174+ default : assert (false , __MODULE__ ~ " has a bug" );
175+ }
176+ }
177+
178+ // / ditto
179+ void dynamicDispatch (const InterpolatedStringPart n)
180+ {
181+ switch (typeMap.get (typeid (n), 0 ))
182+ {
183+ case 49 : visit(cast (InterpolatedStringExpression) n); break ;
184+ case 50 : visit(cast (InterpolatedStringText) n); break ;
185+ case 51 : visit(cast (InterpolatedStringVariable) n); break ;
170186 default : assert (false , __MODULE__ ~ " has a bug" );
171187 }
172188 }
@@ -289,6 +305,10 @@ abstract class ASTVisitor
289305 /* * */ void visit(const Initialize initialize) { initialize.accept(this ); }
290306 /* * */ void visit(const Initializer initializer) { initializer.accept(this ); }
291307 /* * */ void visit(const InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this ); }
308+ /* * */ void visit(const InterpolatedString interpolatedString) { interpolatedString.accept(this ); }
309+ /* * */ void visit(const InterpolatedStringExpression interpolatedStringExpression) { interpolatedStringExpression.accept(this ); }
310+ /* * */ void visit(const InterpolatedStringText interpolatedStringText) { interpolatedStringText.accept(this ); }
311+ /* * */ void visit(const InterpolatedStringVariable interpolatedStringVariable) { interpolatedStringVariable.accept(this ); }
292312 /* * */ void visit(const Invariant invariant_) { invariant_.accept(this ); }
293313 /* * */ void visit(const IsExpression isExpression) { isExpression.accept(this ); }
294314 /* * */ void visit(const KeyValuePair keyValuePair) { keyValuePair.accept(this ); }
@@ -426,7 +446,7 @@ template visitIfNotNull(fields ...)
426446 }
427447}
428448
429- mixin template OpEquals(bool print = false )
449+ private mixin template OpEquals(extraFields ... )
430450{
431451 override bool opEquals (Object other) const
432452 {
@@ -443,6 +463,9 @@ mixin template OpEquals(bool print = false)
443463 if (field != obj.tupleof[i])
444464 return false ;
445465 }
466+ static foreach (field; extraFields)
467+ if (mixin (" this." ~ field ~ " != obj." ~ field))
468+ return false ;
446469 return true ;
447470 }
448471 return false ;
@@ -2318,6 +2341,109 @@ final class InterfaceDeclaration : BaseNode
23182341 mixin OpEquals;
23192342}
23202343
2344+ // /
2345+ final class InterpolatedString : BaseNode
2346+ {
2347+ override void accept (ASTVisitor visitor) const
2348+ {
2349+ mixin (visitIfNotNull! (parts));
2350+ }
2351+
2352+ /* * */ InterpolatedStringPart[] parts;
2353+
2354+ inout (Token ) startQuote () inout pure nothrow @nogc @safe scope
2355+ {
2356+ return tokens.length ? tokens[0 ] : Token .init;
2357+ }
2358+
2359+ inout (Token ) endQuote () inout pure nothrow @nogc @safe scope
2360+ {
2361+ return tokens.length && tokens[$ - 1 ].type == tok! " istringLiteralEnd"
2362+ ? tokens[$ - 1 ]
2363+ : Token .init;
2364+ }
2365+
2366+ // / '\0'/'c'/'w'/'d' for `i""`, `i""c`, `i""w` and `i""d` respectively.
2367+ char postfixType () inout pure nothrow @nogc @safe scope
2368+ {
2369+ auto end = endQuote.text;
2370+ auto endChar = end.length ? end[$ - 1 ] : ' ' ;
2371+ switch (endChar)
2372+ {
2373+ case ' c' :
2374+ case ' w' :
2375+ case ' d' :
2376+ return endChar;
2377+ default :
2378+ return ' \0 ' ;
2379+ }
2380+ }
2381+
2382+ mixin OpEquals! (" startQuote.text" , " postfixType" );
2383+ }
2384+
2385+ // /
2386+ abstract class InterpolatedStringPart : BaseNode
2387+ {
2388+ }
2389+
2390+ // /
2391+ final class InterpolatedStringText : InterpolatedStringPart
2392+ {
2393+ override void accept (ASTVisitor visitor) const
2394+ {
2395+ }
2396+
2397+ // / The token containing the plain text part in its `.text` property.
2398+ inout (Token ) text () inout pure nothrow @nogc @safe scope
2399+ {
2400+ return tokens.length ? tokens[0 ] : Token .init;
2401+ }
2402+
2403+ mixin OpEquals! (" text.text" );
2404+ }
2405+
2406+ // /
2407+ final class InterpolatedStringVariable : InterpolatedStringPart
2408+ {
2409+ override void accept (ASTVisitor visitor) const
2410+ {
2411+ }
2412+
2413+ // / The dollar token.
2414+ inout (Token ) dollar () inout pure nothrow @nogc @safe scope
2415+ {
2416+ return tokens.length == 2 ? tokens[0 ] : Token .init;
2417+ }
2418+
2419+ // / The variable name token.
2420+ inout (Token ) name () inout pure nothrow @nogc @safe scope
2421+ {
2422+ return tokens.length == 2 ? tokens[1 ] : Token .init;
2423+ }
2424+
2425+ mixin OpEquals! (" name.text" );
2426+ }
2427+
2428+ // /
2429+ final class InterpolatedStringExpression : InterpolatedStringPart
2430+ {
2431+ override void accept (ASTVisitor visitor) const
2432+ {
2433+ mixin (visitIfNotNull! (expression));
2434+ }
2435+
2436+ /* * */ Expression expression;
2437+
2438+ // / The dollar token.
2439+ inout (Token ) dollar () inout pure nothrow @nogc @safe scope
2440+ {
2441+ return tokens.length ? tokens[0 ] : Token .init;
2442+ }
2443+
2444+ mixin OpEquals;
2445+ }
2446+
23212447// /
23222448final class Invariant : BaseNode
23232449{
@@ -2798,7 +2924,7 @@ final class PrimaryExpression : ExpressionNode
27982924 typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
27992925 expression, dot, identifierOrTemplateInstance, isExpression,
28002926 functionLiteralExpression,traitsExpression, mixinExpression,
2801- importExpression, vector, arguments));
2927+ importExpression, vector, arguments, interpolatedString ));
28022928 }
28032929 /* * */ Token dot;
28042930 /* * */ Token primary;
@@ -2818,6 +2944,7 @@ final class PrimaryExpression : ExpressionNode
28182944 /* * */ Type type;
28192945 /* * */ Token typeConstructor;
28202946 /* * */ Arguments arguments;
2947+ /* * */ InterpolatedString interpolatedString;
28212948 mixin OpEquals;
28222949}
28232950
0 commit comments