Skip to content

Commit 011309a

Browse files
committed
Reduce tiny allocations & reduce trivia size
1 parent 776ca6b commit 011309a

4 files changed

Lines changed: 73 additions & 11 deletions

File tree

src/dparse/lexer.d

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ mixin template TokenTriviaFields()
134134
*
135135
* Contains: `comment`, `whitespace`, `specialTokenSequence`
136136
*/
137-
immutable(typeof(this))[] leadingTrivia;
137+
immutable(TriviaToken)[] leadingTrivia;
138138
/// ditto
139-
immutable(typeof(this))[] trailingTrivia;
139+
immutable(TriviaToken)[] trailingTrivia;
140140

141141
string memoizedLeadingComment = null;
142142
string memoizedTrailingComment = null;
@@ -171,11 +171,31 @@ mixin template TokenTriviaFields()
171171

172172
// mixin in from dparse.lexer to make error messages more managable size as the
173173
// entire string is dumped when there is a type mismatch.
174-
private enum extraFields = "import dparse.lexer:TokenTriviaFields; mixin TokenTriviaFields;";
174+
private enum extraFields = "import dparse.lexer:TokenTriviaFields,TriviaToken; mixin TokenTriviaFields;";
175+
private enum extraFieldsBare = "
176+
import dparse.lexer : Token;
177+
178+
this(Token token) pure nothrow @safe @nogc {
179+
this(token.type, token.text, token.line, token.column, token.index);
180+
}
181+
182+
int opCmp(size_t i) const pure nothrow @safe @nogc {
183+
if (index < i) return -1;
184+
if (index > i) return 1;
185+
return 0;
186+
}
187+
188+
int opCmp(ref const typeof(this) other) const pure nothrow @safe @nogc {
189+
return opCmp(other.index);
190+
}
191+
";
175192

176193
/// The token type in the D lexer
177194
public alias Token = std.experimental.lexer.TokenStructure!(IdType, extraFields);
178195

196+
/// Same as Token, but doesn't contain child TriviaTokens
197+
public alias TriviaToken = std.experimental.lexer.TokenStructure!(IdType, extraFieldsBare);
198+
179199
/**
180200
* Configure whitespace handling
181201
*/
@@ -472,9 +492,9 @@ if (is(Unqual!(ElementEncodingType!R) : ubyte) && isDynamicArray!R)
472492
config.whitespaceBehavior = WhitespaceBehavior.include;
473493
config.commentBehavior = CommentBehavior.noIntern;
474494

475-
auto leadingTriviaAppender = appender!(Token[])();
495+
auto leadingTriviaAppender = appender!(TriviaToken[])();
476496
leadingTriviaAppender.reserve(128);
477-
auto trailingTriviaAppender = appender!(Token[])();
497+
auto trailingTriviaAppender = appender!(TriviaToken[])();
478498
trailingTriviaAppender.reserve(128);
479499

480500
auto output = appender!(typeof(return))();
@@ -485,9 +505,9 @@ if (is(Unqual!(ElementEncodingType!R) : ubyte) && isDynamicArray!R)
485505
case tok!"whitespace":
486506
case tok!"comment":
487507
if (!output.data.empty && lexer.front.line == output.data[$ - 1].line)
488-
trailingTriviaAppender.put(lexer.front);
508+
trailingTriviaAppender.put(TriviaToken(lexer.front));
489509
else
490-
leadingTriviaAppender.put(lexer.front);
510+
leadingTriviaAppender.put(TriviaToken(lexer.front));
491511
lexer.popFront();
492512
break;
493513
case tok!"__EOF__":

src/dparse/parser.d

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8651,7 +8651,11 @@ protected: final:
86518651
stderr.writefln("%s(%d:%d)[error]: %s", fileName, line, column, message);
86528652
}
86538653
else
8654-
++suppressMessages[$ - 1];
8654+
{
8655+
import std.checkedint;
8656+
8657+
++suppressMessages.back.checked;
8658+
}
86558659
while (shouldAdvance && moreTokens())
86568660
{
86578661
if (currentIsOneOf(tok!";", tok!"}",
@@ -9160,7 +9164,7 @@ protected: final:
91609164
return suppressMessages.empty ? 0 : suppressMessages.back();
91619165
}
91629166

9163-
uint[] suppressMessages;
9167+
TypedStackBuffer!uint suppressMessages;
91649168
size_t index;
91659169
int _traceDepth;
91669170
string comment;

src/dparse/stack_buffer.d

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct StackBuffer
7070
}
7171
}
7272

73-
void[] opSlice()
73+
inout(void[]) opSlice() inout pure nothrow @nogc @safe return scope
7474
{
7575
return arr[0 .. _length];
7676
}
@@ -121,3 +121,41 @@ unittest
121121
B d = new D;
122122
sb.put(d);
123123
}
124+
125+
package struct TypedStackBuffer(T)
126+
if (__traits(isPOD, T))
127+
{
128+
void push(T value) @trusted
129+
{
130+
sb.put(value);
131+
}
132+
133+
void opOpAssign(string op : "~")(T value)
134+
{
135+
push(value);
136+
}
137+
138+
ref inout(T) back() inout pure nothrow @nogc @safe @property
139+
{
140+
return (cast(inout(T)[])sb.opSlice[$ - T.sizeof .. $])[0];
141+
}
142+
143+
void popBack() pure nothrow @nogc @safe @property
144+
{
145+
assert(!empty);
146+
sb._length -= T.sizeof;
147+
}
148+
149+
bool empty() const pure nothrow @nogc @safe @property
150+
{
151+
return sb.length == 0;
152+
}
153+
154+
uint length() const pure nothrow @nogc @safe @property
155+
{
156+
return sb.length / T.sizeof;
157+
}
158+
159+
private:
160+
StackBuffer sb;
161+
}

src/dparse/trivia.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ unittest
516516

517517
/// Extracts and combines ddoc comments from trivia comments.
518518
string extractDdocFromTrivia(Tokens)(Tokens tokens) pure nothrow @safe
519-
if (isInputRange!Tokens && is(ElementType!Tokens : Token))
519+
if (isInputRange!Tokens && (is(ElementType!Tokens : Token) || is(ElementType!Tokens : TriviaToken)))
520520
{
521521
bool hasDoc;
522522
auto ret = appender!string;

0 commit comments

Comments
 (0)