Moved variant.d to dyaml/std/variant. Profile build doesn't inline anymore (made profiling too difficult). More optimizations, speedup (parsing only).
This commit is contained in:
parent
be5664a24d
commit
0e0113ef0e
4
cdc.d
4
cdc.d
|
@ -155,8 +155,8 @@ void main(string[] args)
|
||||||
if(args.length > 0 && args[$ - 1][0] != '-'){target = args[$ - 1];}
|
if(args.length > 0 && args[$ - 1][0] != '-'){target = args[$ - 1];}
|
||||||
|
|
||||||
string[] dbg = ["-debug", "-gc"];
|
string[] dbg = ["-debug", "-gc"];
|
||||||
string[] optimize = ["-O", "-inline", "-release"];
|
string[] optimize = ["-O", "-inline", "-release", "-noboundscheck"];
|
||||||
string[] profile = ["-O", "-inline", "-release", "-gc"];
|
string[] profile = ["-O", "-release", "-noboundscheck", "-gc"];
|
||||||
string[] lib_src = ["dyaml/", "yaml.d"];
|
string[] lib_src = ["dyaml/", "yaml.d"];
|
||||||
|
|
||||||
void compile_(string[] args, string[] files)
|
void compile_(string[] args, string[] files)
|
||||||
|
|
|
@ -219,7 +219,7 @@ final class Parser
|
||||||
if(!currentEvent_.isNull)
|
if(!currentEvent_.isNull)
|
||||||
{
|
{
|
||||||
immutable Event result = currentEvent_;
|
immutable Event result = currentEvent_;
|
||||||
clear(currentEvent_);
|
currentEvent_.id = EventID.Invalid;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
assert(false, "No event left to get");
|
assert(false, "No event left to get");
|
||||||
|
|
|
@ -185,7 +185,7 @@ T* allocate(T, Args...)(Args args)
|
||||||
T* ptr = cast(T*)malloc(T.sizeof);
|
T* ptr = cast(T*)malloc(T.sizeof);
|
||||||
*ptr = T(args);
|
*ptr = T(args);
|
||||||
//The struct might contain references to GC-allocated memory, so tell the GC about it.
|
//The struct might contain references to GC-allocated memory, so tell the GC about it.
|
||||||
if(hasIndirections!T){GC.addRange(cast(void*)ptr, T.sizeof);}
|
static if(hasIndirections!T){GC.addRange(cast(void*)ptr, T.sizeof);}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,8 +193,8 @@ T* allocate(T, Args...)(Args args)
|
||||||
void free(T)(T* ptr)
|
void free(T)(T* ptr)
|
||||||
{
|
{
|
||||||
//GC doesn't need to care about any references in this struct anymore.
|
//GC doesn't need to care about any references in this struct anymore.
|
||||||
if(hasIndirections!T){GC.removeRange(cast(void*)ptr);}
|
static if(hasIndirections!T){GC.removeRange(cast(void*)ptr);}
|
||||||
clear(*ptr);
|
static if(hasMember!(T, "__dtor")){clear(*ptr);}
|
||||||
std.c.stdlib.free(ptr);
|
std.c.stdlib.free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,22 +170,36 @@ final class Reader
|
||||||
*
|
*
|
||||||
* Params: length = Number of characters to get.
|
* Params: length = Number of characters to get.
|
||||||
*
|
*
|
||||||
* Returns: Characters starting at current position.
|
* Returns: Characters starting at current position or an empty slice if out of bounds.
|
||||||
*
|
|
||||||
* Throws: ReaderException if trying to read past the end of the stream
|
|
||||||
* or if invalid data is read.
|
|
||||||
*/
|
*/
|
||||||
dstring prefix(in size_t length)
|
const(dstring) prefix(in size_t length)
|
||||||
{
|
{
|
||||||
if(length == 0){return "";}
|
return slice(0, length);
|
||||||
if(buffer_.length <= bufferOffset_ + length)
|
|
||||||
{
|
|
||||||
updateBuffer(length);
|
|
||||||
}
|
}
|
||||||
const end = min(buffer_.length, bufferOffset_ + length);
|
|
||||||
//need to duplicate as we change buffer content with C functions
|
/**
|
||||||
//and could end up with returned string referencing changed data
|
* Get a slice view of the internal buffer.
|
||||||
return cast(dstring)buffer_[bufferOffset_ .. end];
|
*
|
||||||
|
* Note: This gets only a "view" into the internal buffer,
|
||||||
|
* which WILL get invalidated after other Reader calls.
|
||||||
|
*
|
||||||
|
* Params: start = Start of the slice relative to current position.
|
||||||
|
* end = End of the slice relative to current position.
|
||||||
|
*
|
||||||
|
* Returns: Slice into the internal buffer or an empty slice if out of bounds.
|
||||||
|
*/
|
||||||
|
const(dstring) slice(size_t start, size_t end)
|
||||||
|
{
|
||||||
|
if(buffer_.length <= bufferOffset_ + end)
|
||||||
|
{
|
||||||
|
updateBuffer(end);
|
||||||
|
}
|
||||||
|
end += bufferOffset_;
|
||||||
|
start += bufferOffset_;
|
||||||
|
end = min(buffer_.length, end);
|
||||||
|
if(end <= start){return "";}
|
||||||
|
|
||||||
|
return cast(dstring)buffer_[start .. end];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,7 +289,7 @@ final class Reader
|
||||||
* If there are not enough characters in the stream, it will get
|
* If there are not enough characters in the stream, it will get
|
||||||
* as many as possible.
|
* as many as possible.
|
||||||
*
|
*
|
||||||
* Params: length = Mimimum number of characters we need to read.
|
* Params: length = Number of characters we need to read.
|
||||||
*
|
*
|
||||||
* Throws: ReaderException if trying to read past the end of the stream
|
* Throws: ReaderException if trying to read past the end of the stream
|
||||||
* or if invalid data is read.
|
* or if invalid data is read.
|
||||||
|
@ -324,7 +338,7 @@ final class Reader
|
||||||
///Get next character from the stream.
|
///Get next character from the stream.
|
||||||
dchar getDChar()
|
dchar getDChar()
|
||||||
{
|
{
|
||||||
switch(encoding_)
|
final switch(encoding_)
|
||||||
{
|
{
|
||||||
case Encoding.UTF_8:
|
case Encoding.UTF_8:
|
||||||
//Temp buffer for moving data in rawBuffer8_.
|
//Temp buffer for moving data in rawBuffer8_.
|
||||||
|
@ -389,7 +403,6 @@ final class Reader
|
||||||
available_ -= 4;
|
available_ -= 4;
|
||||||
stream_.read(result);
|
stream_.read(result);
|
||||||
return result;
|
return result;
|
||||||
default: assert(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import core.stdc.string;
|
||||||
|
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
|
import std.container;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.ascii : isAlphaNum, isDigit, isHexDigit;
|
import std.ascii : isAlphaNum, isDigit, isHexDigit;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
|
@ -123,7 +124,7 @@ final class Scanner
|
||||||
///Current indentation level.
|
///Current indentation level.
|
||||||
int indent_ = -1;
|
int indent_ = -1;
|
||||||
///Past indentation levels. Used as a stack.
|
///Past indentation levels. Used as a stack.
|
||||||
int[] indents_;
|
Array!int indents_;
|
||||||
|
|
||||||
///Processed tokens not yet emitted. Used as a queue.
|
///Processed tokens not yet emitted. Used as a queue.
|
||||||
Queue!Token tokens_;
|
Queue!Token tokens_;
|
||||||
|
@ -164,7 +165,6 @@ final class Scanner
|
||||||
{
|
{
|
||||||
clear(tokens_);
|
clear(tokens_);
|
||||||
clear(indents_);
|
clear(indents_);
|
||||||
indents_ = null;
|
|
||||||
clear(possibleSimpleKeys_);
|
clear(possibleSimpleKeys_);
|
||||||
possibleSimpleKeys_ = null;
|
possibleSimpleKeys_ = null;
|
||||||
clear(appender_);
|
clear(appender_);
|
||||||
|
@ -404,7 +404,7 @@ final class Scanner
|
||||||
while(indent_ > column)
|
while(indent_ > column)
|
||||||
{
|
{
|
||||||
indent_ = indents_.back;
|
indent_ = indents_.back;
|
||||||
indents_.popBack();
|
indents_.length = indents_.length - 1;
|
||||||
tokens_.push(blockEndToken(reader_.mark, reader_.mark));
|
tokens_.push(blockEndToken(reader_.mark, reader_.mark));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,7 +779,6 @@ final class Scanner
|
||||||
(c == '-' || (flowLevel_ == 0 && "?:"d.canFind(c))));
|
(c == '-' || (flowLevel_ == 0 && "?:"d.canFind(c))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///Move to the next non-space character.
|
///Move to the next non-space character.
|
||||||
void findNextNonSpace()
|
void findNextNonSpace()
|
||||||
{
|
{
|
||||||
|
@ -1266,13 +1265,23 @@ final class Scanner
|
||||||
|
|
||||||
mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029\'\"\\"d search;
|
mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029\'\"\\"d search;
|
||||||
|
|
||||||
while(!search.canFind(c))
|
//This is an optimized way of writing:
|
||||||
|
//while(!search.canFind(reader_.peek(length))){++length;}
|
||||||
|
outer: for(;;)
|
||||||
{
|
{
|
||||||
|
const slice = reader_.slice(length, length + 32);
|
||||||
|
enforce(slice.length > 0,
|
||||||
|
new Error("While reading a flow scalar", startMark,
|
||||||
|
"reached end of file", reader_.mark));
|
||||||
|
foreach(ch; slice)
|
||||||
|
{
|
||||||
|
if(search.canFind(ch)){break outer;}
|
||||||
++length;
|
++length;
|
||||||
c = reader_.peek(length);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(length > 0){appender_.put(reader_.get(length));}
|
appender_.put(reader_.prefix(length));
|
||||||
|
reader_.forward(length);
|
||||||
|
|
||||||
c = reader_.peek();
|
c = reader_.peek();
|
||||||
if(quotes == ScalarStyle.SingleQuoted &&
|
if(quotes == ScalarStyle.SingleQuoted &&
|
||||||
|
@ -1338,14 +1347,15 @@ final class Scanner
|
||||||
{
|
{
|
||||||
uint length = 0;
|
uint length = 0;
|
||||||
while(" \t"d.canFind(reader_.peek(length))){++length;}
|
while(" \t"d.canFind(reader_.peek(length))){++length;}
|
||||||
const whitespaces = reader_.get(length);
|
const whitespaces = reader_.prefix(length + 1);
|
||||||
|
|
||||||
dchar c = reader_.peek();
|
const c = whitespaces[$ - 1];
|
||||||
enforce(c != '\0', new Error("While scanning a quoted scalar", startMark,
|
enforce(c != '\0', new Error("While scanning a quoted scalar", startMark,
|
||||||
"found unexpected end of stream", reader_.mark));
|
"found unexpected end of stream", reader_.mark));
|
||||||
|
|
||||||
if("\n\r\u0085\u2028\u2029"d.canFind(c))
|
if("\n\r\u0085\u2028\u2029"d.canFind(c))
|
||||||
{
|
{
|
||||||
|
reader_.forward(length);
|
||||||
const lineBreak = scanLineBreak();
|
const lineBreak = scanLineBreak();
|
||||||
const breaks = scanFlowScalarBreaks(startMark);
|
const breaks = scanFlowScalarBreaks(startMark);
|
||||||
|
|
||||||
|
@ -1353,7 +1363,11 @@ final class Scanner
|
||||||
else if(breaks.length == 0){appender_.put(' ');}
|
else if(breaks.length == 0){appender_.put(' ');}
|
||||||
appender_.put(breaks);
|
appender_.put(breaks);
|
||||||
}
|
}
|
||||||
else{appender_.put(whitespaces);}
|
else
|
||||||
|
{
|
||||||
|
appender_.put(whitespaces[0 .. $ - 1]);
|
||||||
|
reader_.forward(length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan line breaks in a flow scalar.
|
///Scan line breaks in a flow scalar.
|
||||||
|
|
Loading…
Reference in a new issue