d: Merge dmd. druntime e770945277, phobos 6d6e0b9b9
[official-gcc.git] / libphobos / libdruntime / core / interpolation.d
blob0d45fe79088e0174a34d3e69832c0f6b4a9e5819
1 /++
2 This module provides definitions to support D's
3 interpolated expression sequence literal, sometimes
4 called string interpolation.
7 ---
8 string str;
9 int num;
10 // the compiler uses this module to implement the
11 // i"..." literal used here.
12 auto a = i"$​(str) has $​(num) items.";
13 ---
15 The variable `a` is a sequence of expressions:
17 ---
18 a[0] == InterpolationHeader()
19 a[$-1] == InterpolationFooter()
20 ---
22 First and last, you see the header and footer, to
23 clearly indicate where interpolation begins and ends.
24 Note that there may be nested interpolated sequences too,
25 each with their own header and footer. Think of them
26 as a set of balanced parenthesis around the contents.
28 Inside, you will find three general categories of
29 content: `InterpolatedLiteral!"string"` for string
30 expressions, `InterpolatedExpression!"code"` for code
31 expressions, and then the values themselves as their
32 own type.
34 In the example:
35 ---
36 auto a = i"$​(str) has $​(num) items.";
37 ---
39 We will find:
40 ---
41 a[0] == InterpolationHeader()
42 a[1] == InterpolatedExpression!"str"
43 a[2] == str
44 a[3] == InterpolatedLiteral!" has ";
45 a[4] == InterpolatedExpression!"num";
46 a[5] == num
47 a[6] == InterpolatedLiteral!" items.";
48 a[7] == InterpolationFooter()
49 a.length == 8;
50 ---
52 You can see the correspondence with the original
53 input: when you write `$​(expression)`, the string of the
54 expression is passed as `InterpolatedExpression!ThatString`,
55 (excluding any parenthesis around the expression),
56 and everything else is passed as `InterpolatedLiteral!str`,
57 in the same sequence as they appeared in the source.
59 After an `InterpolatedExpression!...`, you will find the
60 actual value(s) in the tuple. (If the expression expanded
61 to multiple values - for example, if it was itself a tuple,
62 there will be multiple values for a single expression.)
64 Library functions should NOT attempt to mixin the code
65 from an `InterpolatedExpression` themselves. Doing so
66 will fail, since it is coming from a different scope anyway.
67 The string is provided to you only for informational purposes
68 and as a sentinel to separate things the user wrote.
70 Your code should be able to handle an empty code string
71 in `InterpolatedExpression` or even an entirely missing
72 `InterpolatedExpression`, in case an implementation decides to
73 not emit these.
75 The `toString` members on these return `null`, except for
76 the `InterpolatedLiteral`, which returns the literal string.
77 This is to ease processing by generic functions like
78 `std.stdio.write` or `std.conv.text`, making them effectively
79 transparently skipped.
81 To extract the string from an `InterpolatedLiteral`, you can
82 use an `is` expression or the `.toString` method.
84 To extract the string from a `InterpolatedExpression`, you can
85 use an `is` expression or the `.expression` member.
87 None of these structures have runtime state.
89 History:
90 Added in dmd 2.10x frontend, released in late 2023.
92 module core.interpolation;
94 /++
95 Sentinel values to indicate the beginning and end of an
96 interpolated expression sequence.
98 Note that these can nest, so while processing a sequence,
99 it may be helpful to keep a nesting count if that knowledge
100 is important to your application.
102 struct InterpolationHeader {
104 Returns `null` for easy compatibility with existing functions
105 like `std.stdio.writeln` and `std.conv.text`.
107 string toString() const @nogc pure nothrow @safe {
108 return null;
112 /// ditto
113 struct InterpolationFooter {
115 Returns `null` for easy compatibility with existing functions
116 like `std.stdio.writeln` and `std.conv.text`.
118 string toString() const @nogc pure nothrow @safe {
119 return null;
124 Represents a fragment of a string literal in between expressions
125 passed as part of an interpolated expression sequence.
127 struct InterpolatedLiteral(string text) {
129 Returns the text of the interpolated string literal for this
130 segment of the tuple, for easy access and compatibility with
131 existing functions like `std.stdio.writeln` and `std.conv.text`.
133 string toString() const @nogc pure nothrow @safe {
134 return text;
139 Represents the source code of an expression passed as part of an
140 interpolated expression sequence.
142 struct InterpolatedExpression(string text) {
144 Returns the text of an interpolated expression used in the
145 original literal, if provided by the implementation.
147 enum expression = text;
150 Returns `null` for easy compatibility with existing functions
151 like `std.stdio.writeln` and `std.conv.text`.
153 string toString() const @nogc pure nothrow @safe {
154 return null;