Better performance
This commit is contained in:
parent
ccb4023ec0
commit
4adaae9e06
|
@ -17,13 +17,15 @@ void writeSpan(string cssClass, string value)
|
||||||
|
|
||||||
|
|
||||||
// http://ethanschoonover.com/solarized
|
// http://ethanschoonover.com/solarized
|
||||||
void highlight(R)(R tokens)
|
void highlight(R)(TokenRange!R tokens, string fileName)
|
||||||
{
|
{
|
||||||
stdout.writeln(q"EOS
|
stdout.writeln(q"[
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>]");
|
||||||
|
stdout.writeln("<title>", fileName, "</title>");
|
||||||
|
stdout.writeln(q"[</head>
|
||||||
<body>
|
<body>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
html { background-color: #fdf6e3; color: #002b36; }
|
html { background-color: #fdf6e3; color: #002b36; }
|
||||||
|
@ -35,8 +37,7 @@ html { background-color: #fdf6e3; color: #002b36; }
|
||||||
.type { color: #268bd2; font-weight: bold; }
|
.type { color: #268bd2; font-weight: bold; }
|
||||||
.cons { color: #859900; font-weight: bold; }
|
.cons { color: #859900; font-weight: bold; }
|
||||||
</style>
|
</style>
|
||||||
<pre>
|
<pre>]");
|
||||||
EOS");
|
|
||||||
|
|
||||||
foreach (Token t; tokens)
|
foreach (Token t; tokens)
|
||||||
{
|
{
|
||||||
|
|
7
main.d
7
main.d
|
@ -140,6 +140,7 @@ int main(string[] args)
|
||||||
|
|
||||||
if (tokenCount)
|
if (tokenCount)
|
||||||
{
|
{
|
||||||
|
import core.memory;
|
||||||
/+if (args.length == 1)
|
/+if (args.length == 1)
|
||||||
{
|
{
|
||||||
writeln((cast (ubyte[]) stdin.byLine(KeepTerminator.yes).join()).byToken().walkLength());
|
writeln((cast (ubyte[]) stdin.byLine(KeepTerminator.yes).join()).byToken().walkLength());
|
||||||
|
@ -151,11 +152,12 @@ int main(string[] args)
|
||||||
{
|
{
|
||||||
config.fileName = arg;
|
config.fileName = arg;
|
||||||
uint count;
|
uint count;
|
||||||
|
//GC.disable();
|
||||||
foreach(t; byToken(cast(ubyte[]) File(arg).byLine(KeepTerminator.yes).join(), config))
|
foreach(t; byToken(cast(ubyte[]) File(arg).byLine(KeepTerminator.yes).join(), config))
|
||||||
{
|
{
|
||||||
writeln(t);
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
//GC.enable();
|
||||||
writefln("%s: %d", arg, count);
|
writefln("%s: %d", arg, count);
|
||||||
}
|
}
|
||||||
/+}+/
|
/+}+/
|
||||||
|
@ -193,7 +195,8 @@ int main(string[] args)
|
||||||
config.iterStyle = IterationStyle.everything;
|
config.iterStyle = IterationStyle.everything;
|
||||||
config.tokenStyle = TokenStyle.source;
|
config.tokenStyle = TokenStyle.source;
|
||||||
File f = args.length == 1 ? stdin : File(args[1]);
|
File f = args.length == 1 ? stdin : File(args[1]);
|
||||||
highlighter.highlight((cast(ubyte[]) f.byLine(KeepTerminator.yes).join()).byToken(config));
|
highlighter.highlight((cast(ubyte[]) f.byLine(KeepTerminator.yes).join()).byToken(config),
|
||||||
|
args.length == 1 ? "stdin" : args[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
544
std/d/lexer.d
544
std/d/lexer.d
|
@ -119,8 +119,7 @@ import std.traits;
|
||||||
import std.uni;
|
import std.uni;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
import std.regex;
|
import std.regex;
|
||||||
|
import std.container;
|
||||||
import std.stdio;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -268,7 +267,7 @@ struct LexerConfig
|
||||||
/**
|
/**
|
||||||
* Replacement for the ___VERSION__ token. Defaults to 1.
|
* Replacement for the ___VERSION__ token. Defaults to 1.
|
||||||
*/
|
*/
|
||||||
uint versionNumber = 1;
|
uint versionNumber = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replacement for the ___VENDOR__ token. Defaults to $(D_STRING "std.d.lexer")
|
* Replacement for the ___VENDOR__ token. Defaults to $(D_STRING "std.d.lexer")
|
||||||
|
@ -415,6 +414,7 @@ private:
|
||||||
{
|
{
|
||||||
this.range = range;
|
this.range = range;
|
||||||
buffer = new ubyte[config.bufferSize];
|
buffer = new ubyte[config.bufferSize];
|
||||||
|
cache.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -631,7 +631,7 @@ private:
|
||||||
current.type = lookupTokenType(cast(char[]) buffer[0 .. bufferIndex]);
|
current.type = lookupTokenType(cast(char[]) buffer[0 .. bufferIndex]);
|
||||||
current.value = getTokenValue(current.type);
|
current.value = getTokenValue(current.type);
|
||||||
if (current.value is null)
|
if (current.value is null)
|
||||||
current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
setTokenValue();
|
||||||
|
|
||||||
if (!(config.iterStyle & IterationStyle.ignoreEOF) && current.type == TokenType.eof)
|
if (!(config.iterStyle & IterationStyle.ignoreEOF) && current.type == TokenType.eof)
|
||||||
{
|
{
|
||||||
|
@ -693,7 +693,7 @@ private:
|
||||||
keepChar();
|
keepChar();
|
||||||
}
|
}
|
||||||
if (config.iterStyle & IterationStyle.includeWhitespace)
|
if (config.iterStyle & IterationStyle.includeWhitespace)
|
||||||
current.value = (cast(char[]) buffer[0..bufferIndex]).idup;
|
setTokenValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexComment()
|
void lexComment()
|
||||||
|
@ -759,7 +759,7 @@ private:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
if (config.iterStyle & IterationStyle.includeComments)
|
if (config.iterStyle & IterationStyle.includeComments)
|
||||||
current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
setTokenValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexHexString()
|
void lexHexString()
|
||||||
|
@ -770,20 +770,13 @@ private:
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
current.type = TokenType.stringLiteral;
|
current.type = TokenType.stringLiteral;
|
||||||
size_t i;
|
keepChar();
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
keepChar();
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
buffer[i++] = 'x';
|
if (range.isEoF())
|
||||||
buffer[i++] = '"';
|
|
||||||
}
|
|
||||||
range.popFront();
|
|
||||||
range.popFront();
|
|
||||||
index += 2;
|
|
||||||
while (!range.isEoF())
|
|
||||||
{
|
|
||||||
if (i >= buffer.length)
|
|
||||||
{
|
{
|
||||||
errorMessage("Hex string constant exceeded buffer size");
|
errorMessage("Unterminated hex string literal");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (isHexDigit(range.front))
|
else if (isHexDigit(range.front))
|
||||||
|
@ -796,44 +789,28 @@ private:
|
||||||
}
|
}
|
||||||
else if (range.front == '"')
|
else if (range.front == '"')
|
||||||
{
|
{
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
keepChar();
|
||||||
buffer[i++] = '"';
|
|
||||||
range.popFront();
|
|
||||||
++index;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errorMessage(format("Invalid character '%s' in hex string literal",
|
errorMessage(format("Invalid character '%s' in hex string literal",
|
||||||
cast(char) range.front));
|
cast(char) range.front));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!range.isEoF())
|
lexStringSuffix();
|
||||||
{
|
|
||||||
switch (range.front)
|
|
||||||
{
|
|
||||||
case 'w':
|
|
||||||
current.type = TokenType.wstringLiteral;
|
|
||||||
goto case 'c';
|
|
||||||
case 'd':
|
|
||||||
current.type = TokenType.dstringLiteral;
|
|
||||||
goto case 'c';
|
|
||||||
case 'c':
|
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
|
||||||
buffer[i++] = range.front;
|
|
||||||
range.popFront();
|
|
||||||
++index;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.tokenStyle & TokenStyle.notEscaped)
|
if (config.tokenStyle & TokenStyle.notEscaped)
|
||||||
current.value = (cast(char[]) buffer[0 .. i]).idup;
|
{
|
||||||
|
if (config.tokenStyle & TokenStyle.includeQuotes)
|
||||||
|
setTokenValue();
|
||||||
|
else
|
||||||
|
setTokenValue(bufferIndex - 1, 2);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto a = appender!(ubyte[])();
|
auto a = appender!(ubyte[])();
|
||||||
foreach (b; std.range.chunks(buffer[0 .. i], 2))
|
foreach (b; std.range.chunks(buffer[2 .. bufferIndex - 1], 2))
|
||||||
{
|
{
|
||||||
string s = to!string(cast(char[]) b);
|
string s = to!string(cast(char[]) b);
|
||||||
a.put(cast(ubyte[]) to!string(cast(dchar) parse!uint(s, 16)));
|
a.put(cast(ubyte[]) to!string(cast(dchar) parse!uint(s, 16)));
|
||||||
|
@ -999,7 +976,7 @@ private:
|
||||||
{
|
{
|
||||||
bool foundDot = false;
|
bool foundDot = false;
|
||||||
current.type = TokenType.intLiteral;
|
current.type = TokenType.intLiteral;
|
||||||
scope(exit) current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
scope(exit) setTokenValue();
|
||||||
decimalLoop: while (!range.isEoF())
|
decimalLoop: while (!range.isEoF())
|
||||||
{
|
{
|
||||||
switch (range.front)
|
switch (range.front)
|
||||||
|
@ -1049,7 +1026,7 @@ private:
|
||||||
void lexBinary()
|
void lexBinary()
|
||||||
{
|
{
|
||||||
current.type = TokenType.intLiteral;
|
current.type = TokenType.intLiteral;
|
||||||
scope(exit) current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
scope(exit) setTokenValue();
|
||||||
binaryLoop: while (!range.isEoF())
|
binaryLoop: while (!range.isEoF())
|
||||||
{
|
{
|
||||||
switch (range.front)
|
switch (range.front)
|
||||||
|
@ -1073,7 +1050,7 @@ private:
|
||||||
void lexHex()
|
void lexHex()
|
||||||
{
|
{
|
||||||
current.type = TokenType.intLiteral;
|
current.type = TokenType.intLiteral;
|
||||||
scope(exit) current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
scope(exit) setTokenValue();
|
||||||
bool foundDot;
|
bool foundDot;
|
||||||
hexLoop: while (!range.isEoF())
|
hexLoop: while (!range.isEoF())
|
||||||
{
|
{
|
||||||
|
@ -1155,13 +1132,13 @@ private:
|
||||||
scope (exit)
|
scope (exit)
|
||||||
{
|
{
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
if (config.tokenStyle & TokenStyle.includeQuotes)
|
||||||
current.value = (cast(char[]) buffer[0..bufferIndex]).idup;
|
setTokenValue();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (buffer[0] == 'r')
|
if (buffer[0] == 'r')
|
||||||
current.value = (cast(char[]) buffer[2..bufferIndex - 1]).idup;
|
setTokenValue(bufferIndex - 1, 2);
|
||||||
else
|
else
|
||||||
current.value = (cast(char[]) buffer[1..bufferIndex - 1]).idup;
|
setTokenValue(bufferIndex - 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1250,9 +1227,9 @@ private:
|
||||||
scope (exit)
|
scope (exit)
|
||||||
{
|
{
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
if (config.tokenStyle & TokenStyle.includeQuotes)
|
||||||
current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
setTokenValue();
|
||||||
else
|
else
|
||||||
current.value = (cast(char[]) buffer[3 .. bufferIndex - 2]).idup;
|
setTokenValue(bufferIndex - 2, 3);
|
||||||
}
|
}
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -1323,7 +1300,7 @@ private:
|
||||||
scope(exit)
|
scope(exit)
|
||||||
{
|
{
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
if (config.tokenStyle & TokenStyle.includeQuotes)
|
||||||
current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
setTokenValue();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t b = 2 + ident.length;
|
size_t b = 2 + ident.length;
|
||||||
|
@ -1332,8 +1309,7 @@ private:
|
||||||
size_t e = bufferIndex;
|
size_t e = bufferIndex;
|
||||||
if (buffer[e - 1] == 'c' || buffer[e - 1] == 'd' || buffer[e - 1] == 'w')
|
if (buffer[e - 1] == 'c' || buffer[e - 1] == 'd' || buffer[e - 1] == 'w')
|
||||||
--e;
|
--e;
|
||||||
stderr.writeln("b = ", b, " e = ", e);
|
setTokenValue(e, b);
|
||||||
current.value = (cast(char[]) buffer[b .. e]).idup;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,9 +1352,9 @@ private:
|
||||||
scope (exit)
|
scope (exit)
|
||||||
{
|
{
|
||||||
if (config.tokenStyle & TokenStyle.includeQuotes)
|
if (config.tokenStyle & TokenStyle.includeQuotes)
|
||||||
current.value = (cast(char[]) buffer[0 .. bufferIndex]).idup;
|
setTokenValue();
|
||||||
else
|
else
|
||||||
current.value = (cast(char[]) buffer[2 .. bufferIndex - 1]).idup;
|
setTokenValue(bufferIndex - 1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
keepChar();
|
keepChar();
|
||||||
|
@ -1514,6 +1490,13 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTokenValue(size_t endIndex = 0, size_t startIndex = 0)
|
||||||
|
{
|
||||||
|
if (endIndex == 0)
|
||||||
|
endIndex = bufferIndex;
|
||||||
|
current.value = cache.get(buffer[startIndex .. endIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
Token current;
|
Token current;
|
||||||
uint lineNumber;
|
uint lineNumber;
|
||||||
uint index;
|
uint index;
|
||||||
|
@ -1523,6 +1506,7 @@ private:
|
||||||
ubyte[] buffer;
|
ubyte[] buffer;
|
||||||
size_t bufferIndex;
|
size_t bufferIndex;
|
||||||
LexerConfig config;
|
LexerConfig config;
|
||||||
|
StringCache cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1822,207 +1806,207 @@ private:
|
||||||
* To avoid memory allocations Token.value is set to a slice of this string
|
* To avoid memory allocations Token.value is set to a slice of this string
|
||||||
* for operators and keywords.
|
* for operators and keywords.
|
||||||
*/
|
*/
|
||||||
immutable string opKwdValues =
|
//immutable string opKwdValues =
|
||||||
"#/=*=+=++-=--^^=~=<<=%==>>>=||=&&=,;:!<=!<>=!=!>=?...()[]{}@$"
|
// "#/=*=+=++-=--^^=~=<<=%==>>>=||=&&=,;:!<=!<>=!=!>=?...()[]{}@$"
|
||||||
~ "boolcdoublecentcfloatcrealdchardstringfunctionidoubleifloatirealubyte"
|
// ~ "boolcdoublecentcfloatcrealdchardstringfunctionidoubleifloatirealubyte"
|
||||||
~ "ucentuintulongushortvoidwcharwstringaligndeprecatedexternpragmaexport"
|
// ~ "ucentuintulongushortvoidwcharwstringaligndeprecatedexternpragmaexport"
|
||||||
~ "packageprivateprotectedpublicabstractautoconstfinal__gsharedimmutable"
|
// ~ "packageprivateprotectedpublicabstractautoconstfinal__gsharedimmutable"
|
||||||
~ "inoutscopesharedstaticsynchronizedaliasasmassertbodybreakcasecastcatch"
|
// ~ "inoutscopesharedstaticsynchronizedaliasasmassertbodybreakcasecastcatch"
|
||||||
~ "classcontinuedebugdefaultdelegatedeleteelseenumfalsefinally"
|
// ~ "classcontinuedebugdefaultdelegatedeleteelseenumfalsefinally"
|
||||||
~ "foreach_reversegotoimportinterfaceinvariantlazymacromixinmodule"
|
// ~ "foreach_reversegotoimportinterfaceinvariantlazymacromixinmodule"
|
||||||
~ "newnothrownulloverridepurerefreturnstructsuperswitchtemplatethistruetry"
|
// ~ "newnothrownulloverridepurerefreturnstructsuperswitchtemplatethistruetry"
|
||||||
~ "typedeftypeidtypeofunionunittestversionvolatilewhilewith__traits"
|
// ~ "typedeftypeidtypeofunionunittestversionvolatilewhilewith__traits"
|
||||||
~ "__vector__parameters__DATE__EOF__TIME__TIMESTAMP__VENDOR__VERSION__"
|
// ~ "__vector__parameters__DATE__EOF__TIME__TIMESTAMP__VENDOR__VERSION__"
|
||||||
~ "FILE__LINE__";
|
// ~ "FILE__LINE__";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Slices of the above string to save memory. This array is automatically
|
* Slices of the above string to save memory. This array is automatically
|
||||||
* generated.
|
* generated.
|
||||||
*/
|
*/
|
||||||
immutable(string[]) tokenValues = [
|
immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
opKwdValues[2 .. 3], // =
|
"=",
|
||||||
opKwdValues[59 .. 60], // @
|
"@",
|
||||||
opKwdValues[31 .. 32], // &
|
"&",
|
||||||
opKwdValues[32 .. 34], // &=
|
"&=",
|
||||||
opKwdValues[28 .. 29], // |
|
"|",
|
||||||
opKwdValues[29 .. 31], // |=
|
"|=",
|
||||||
opKwdValues[16 .. 18], // ~=
|
"~=",
|
||||||
opKwdValues[36 .. 37], // :
|
":",
|
||||||
opKwdValues[34 .. 35], // ,
|
",",
|
||||||
opKwdValues[11 .. 13], // --
|
"--",
|
||||||
opKwdValues[1 .. 2], // /
|
"/",
|
||||||
opKwdValues[1 .. 3], // /=
|
"/=",
|
||||||
opKwdValues[60 .. 61], // $
|
"$",
|
||||||
opKwdValues[50 .. 51], // .
|
".",
|
||||||
opKwdValues[22 .. 24], // ==
|
"==",
|
||||||
opKwdValues[23 .. 25], // =>
|
"=>",
|
||||||
opKwdValues[24 .. 25], // >
|
">",
|
||||||
opKwdValues[26 .. 28], // >=
|
">=",
|
||||||
opKwdValues[0 .. 1], // #
|
"#",
|
||||||
opKwdValues[7 .. 9], // ++
|
"++",
|
||||||
opKwdValues[57 .. 58], // {
|
"{",
|
||||||
opKwdValues[55 .. 56], // [
|
"[",
|
||||||
opKwdValues[18 .. 19], // <
|
"<",
|
||||||
opKwdValues[19 .. 21], // <=
|
"<=",
|
||||||
opKwdValues[41 .. 44], // <>=
|
"<>=",
|
||||||
opKwdValues[41 .. 43], // <>
|
"<>",
|
||||||
opKwdValues[31 .. 33], // &&
|
"&&",
|
||||||
opKwdValues[28 .. 30], // ||
|
"||",
|
||||||
opKwdValues[53 .. 54], // (
|
"(",
|
||||||
opKwdValues[9 .. 10], // -
|
"-",
|
||||||
opKwdValues[9 .. 11], // -=
|
"-=",
|
||||||
opKwdValues[21 .. 22], // %
|
"%",
|
||||||
opKwdValues[21 .. 23], // %=
|
"%=",
|
||||||
opKwdValues[3 .. 5], // *=
|
"*=",
|
||||||
opKwdValues[37 .. 38], // !
|
"!",
|
||||||
opKwdValues[44 .. 46], // !=
|
"!=",
|
||||||
opKwdValues[46 .. 48], // !>
|
"!>",
|
||||||
opKwdValues[46 .. 49], // !>=
|
"!>=",
|
||||||
opKwdValues[37 .. 39], // !<
|
"!<",
|
||||||
opKwdValues[37 .. 40], // !<=
|
"!<=",
|
||||||
opKwdValues[40 .. 43], // !<>
|
"!<>",
|
||||||
opKwdValues[5 .. 6], // +
|
"+",
|
||||||
opKwdValues[5 .. 7], // +=
|
"+=",
|
||||||
opKwdValues[13 .. 15], // ^^
|
"^^",
|
||||||
opKwdValues[13 .. 16], // ^^=
|
"^^=",
|
||||||
opKwdValues[58 .. 59], // }
|
"}",
|
||||||
opKwdValues[56 .. 57], // ]
|
"]",
|
||||||
opKwdValues[54 .. 55], // )
|
")",
|
||||||
opKwdValues[35 .. 36], // ;
|
";",
|
||||||
opKwdValues[18 .. 20], // <<
|
"<<",
|
||||||
opKwdValues[18 .. 21], // <<=
|
"<<=",
|
||||||
opKwdValues[24 .. 26], // >>
|
">>",
|
||||||
opKwdValues[25 .. 28], // >>=
|
">>=",
|
||||||
opKwdValues[50 .. 52], // ..
|
"..",
|
||||||
opKwdValues[3 .. 4], // *
|
"*",
|
||||||
opKwdValues[49 .. 50], // ?
|
"?",
|
||||||
opKwdValues[16 .. 17], // ~
|
"~",
|
||||||
opKwdValues[40 .. 44], // !<>=
|
"!<>=",
|
||||||
opKwdValues[24 .. 27], // >>>
|
">>>",
|
||||||
opKwdValues[24 .. 28], // >>>=
|
">>>=",
|
||||||
opKwdValues[50 .. 53], // ...
|
"...",
|
||||||
opKwdValues[13 .. 14], // ^
|
"^",
|
||||||
opKwdValues[14 .. 16], // ^=
|
"^=",
|
||||||
opKwdValues[61 .. 65], // bool
|
"bool",
|
||||||
opKwdValues[126 .. 130], // byte
|
"byte",
|
||||||
opKwdValues[65 .. 72], // cdouble
|
"cdouble",
|
||||||
opKwdValues[72 .. 76], // cent
|
"cent",
|
||||||
opKwdValues[76 .. 82], // cfloat
|
"cfloat",
|
||||||
opKwdValues[88 .. 92], // char
|
"char",
|
||||||
opKwdValues[82 .. 87], // creal
|
"creal",
|
||||||
opKwdValues[87 .. 92], // dchar
|
"dchar",
|
||||||
opKwdValues[66 .. 72], // double
|
"double",
|
||||||
opKwdValues[92 .. 99], // dstring
|
"dstring",
|
||||||
opKwdValues[77 .. 82], // float
|
"float",
|
||||||
opKwdValues[99 .. 107], // function
|
"function",
|
||||||
opKwdValues[107 .. 114], // idouble
|
"idouble",
|
||||||
opKwdValues[114 .. 120], // ifloat
|
"ifloat",
|
||||||
opKwdValues[136 .. 139], // int
|
"int",
|
||||||
opKwdValues[120 .. 125], // ireal
|
"ireal",
|
||||||
opKwdValues[140 .. 144], // long
|
"long",
|
||||||
opKwdValues[83 .. 87], // real
|
"real",
|
||||||
opKwdValues[145 .. 150], // short
|
"short",
|
||||||
opKwdValues[93 .. 99], // string
|
"string",
|
||||||
opKwdValues[125 .. 130], // ubyte
|
"ubyte",
|
||||||
opKwdValues[130 .. 135], // ucent
|
"ucent",
|
||||||
opKwdValues[135 .. 139], // uint
|
"uint",
|
||||||
opKwdValues[139 .. 144], // ulong
|
"ulong",
|
||||||
opKwdValues[144 .. 150], // ushort
|
"ushort",
|
||||||
opKwdValues[150 .. 154], // void
|
"void",
|
||||||
opKwdValues[154 .. 159], // wchar
|
"wchar",
|
||||||
opKwdValues[159 .. 166], // wstring
|
"wstring",
|
||||||
opKwdValues[166 .. 171], // align
|
"align",
|
||||||
opKwdValues[171 .. 181], // deprecated
|
"deprecated",
|
||||||
opKwdValues[181 .. 187], // extern
|
"extern",
|
||||||
opKwdValues[187 .. 193], // pragma
|
"pragma",
|
||||||
opKwdValues[193 .. 199], // export
|
"export",
|
||||||
opKwdValues[199 .. 206], // package
|
"package",
|
||||||
opKwdValues[206 .. 213], // private
|
"private",
|
||||||
opKwdValues[213 .. 222], // protected
|
"protected",
|
||||||
opKwdValues[222 .. 228], // public
|
"public",
|
||||||
opKwdValues[228 .. 236], // abstract
|
"abstract",
|
||||||
opKwdValues[236 .. 240], // auto
|
"auto",
|
||||||
opKwdValues[240 .. 245], // const
|
"const",
|
||||||
opKwdValues[245 .. 250], // final
|
"final",
|
||||||
opKwdValues[250 .. 259], // __gshared
|
"__gshared",
|
||||||
opKwdValues[259 .. 268], // immutable
|
"immutable",
|
||||||
opKwdValues[268 .. 273], // inout
|
"inout",
|
||||||
opKwdValues[273 .. 278], // scope
|
"scope",
|
||||||
opKwdValues[253 .. 259], // shared
|
"shared",
|
||||||
opKwdValues[284 .. 290], // static
|
"static",
|
||||||
opKwdValues[290 .. 302], // synchronized
|
"synchronized",
|
||||||
opKwdValues[302 .. 307], // alias
|
"alias",
|
||||||
opKwdValues[307 .. 310], // asm
|
"asm",
|
||||||
opKwdValues[310 .. 316], // assert
|
"assert",
|
||||||
opKwdValues[316 .. 320], // body
|
"body",
|
||||||
opKwdValues[320 .. 325], // break
|
"break",
|
||||||
opKwdValues[325 .. 329], // case
|
"case",
|
||||||
opKwdValues[329 .. 333], // cast
|
"cast",
|
||||||
opKwdValues[333 .. 338], // catch
|
"catch",
|
||||||
opKwdValues[338 .. 343], // class
|
"class",
|
||||||
opKwdValues[343 .. 351], // continue
|
"continue",
|
||||||
opKwdValues[351 .. 356], // debug
|
"debug",
|
||||||
opKwdValues[356 .. 363], // default
|
"default",
|
||||||
opKwdValues[363 .. 371], // delegate
|
"delegate",
|
||||||
opKwdValues[371 .. 377], // delete
|
"delete",
|
||||||
opKwdValues[66 .. 68], // do
|
"do",
|
||||||
opKwdValues[377 .. 381], // else
|
"else",
|
||||||
opKwdValues[381 .. 385], // enum
|
"enum",
|
||||||
opKwdValues[385 .. 390], // false
|
"false",
|
||||||
opKwdValues[390 .. 397], // finally
|
"finally",
|
||||||
opKwdValues[397 .. 404], // foreach
|
"foreach",
|
||||||
opKwdValues[397 .. 412], // foreach_reverse
|
"foreach_reverse",
|
||||||
opKwdValues[397 .. 400], // for
|
"for",
|
||||||
opKwdValues[412 .. 416], // goto
|
"goto",
|
||||||
opKwdValues[114 .. 116], // if
|
"if",
|
||||||
opKwdValues[416 .. 422], // import
|
"import",
|
||||||
opKwdValues[96 .. 98], // in
|
"in",
|
||||||
opKwdValues[422 .. 431], // interface
|
"interface",
|
||||||
opKwdValues[431 .. 440], // invariant
|
"invariant",
|
||||||
opKwdValues[522 .. 524], // is
|
"is",
|
||||||
opKwdValues[440 .. 444], // lazy
|
"lazy",
|
||||||
opKwdValues[444 .. 449], // macro
|
"macro",
|
||||||
opKwdValues[449 .. 454], // mixin
|
"mixin",
|
||||||
opKwdValues[454 .. 460], // module
|
"module",
|
||||||
opKwdValues[460 .. 463], // new
|
"new",
|
||||||
opKwdValues[463 .. 470], // nothrow
|
"nothrow",
|
||||||
opKwdValues[470 .. 474], // null
|
"null",
|
||||||
opKwdValues[270 .. 273], // out
|
"out",
|
||||||
opKwdValues[474 .. 482], // override
|
"override",
|
||||||
opKwdValues[482 .. 486], // pure
|
"pure",
|
||||||
opKwdValues[486 .. 489], // ref
|
"ref",
|
||||||
opKwdValues[489 .. 495], // return
|
"return",
|
||||||
opKwdValues[495 .. 501], // struct
|
"struct",
|
||||||
opKwdValues[501 .. 506], // super
|
"super",
|
||||||
opKwdValues[506 .. 512], // switch
|
"switch",
|
||||||
opKwdValues[512 .. 520], // template
|
"template",
|
||||||
opKwdValues[520 .. 524], // this
|
"this",
|
||||||
opKwdValues[465 .. 470], // throw
|
"throw",
|
||||||
opKwdValues[524 .. 528], // true
|
"true",
|
||||||
opKwdValues[528 .. 531], // try
|
"try",
|
||||||
opKwdValues[531 .. 538], // typedef
|
"typedef",
|
||||||
opKwdValues[538 .. 544], // typeid
|
"typeid",
|
||||||
opKwdValues[544 .. 550], // typeof
|
"typeof",
|
||||||
opKwdValues[550 .. 555], // union
|
"union",
|
||||||
opKwdValues[555 .. 563], // unittest
|
"unittest",
|
||||||
opKwdValues[563 .. 570], // version
|
"version",
|
||||||
opKwdValues[570 .. 578], // volatile
|
"volatile",
|
||||||
opKwdValues[578 .. 583], // while
|
"while",
|
||||||
opKwdValues[583 .. 587], // with
|
"with",
|
||||||
opKwdValues[615 .. 623], // __DATE__
|
"__DATE__",
|
||||||
opKwdValues[621 .. 628], // __EOF__
|
"__EOF__",
|
||||||
opKwdValues[626 .. 634], // __TIME__
|
"__TIME__",
|
||||||
opKwdValues[632 .. 645], // __TIMESTAMP__
|
"__TIMESTAMP__",
|
||||||
opKwdValues[643 .. 653], // __VENDOR__
|
"__VENDOR__",
|
||||||
opKwdValues[651 .. 662], // __VERSION__
|
"__VERSION__",
|
||||||
opKwdValues[660 .. 668], // __FILE__
|
"__FILE__",
|
||||||
opKwdValues[666 .. 674], // __LINE__
|
"__LINE__",
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
opKwdValues[587 .. 595], // __traits
|
"__traits",
|
||||||
opKwdValues[603 .. 615], // __parameters
|
"__parameters",
|
||||||
opKwdValues[595 .. 603], // __vector
|
"__vector",
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
@ -2477,4 +2461,64 @@ string generateCaseTrie(string[] args ...)
|
||||||
return printCaseStatements(t, "");
|
return printCaseStatements(t, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StringCache
|
||||||
|
{
|
||||||
|
|
||||||
|
void initialize()
|
||||||
|
{
|
||||||
|
pages.length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string get(ubyte[] bytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
string* val = (cast(string) bytes) in index;
|
||||||
|
if (val !is null)
|
||||||
|
{
|
||||||
|
return *val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto s = insert(bytes);
|
||||||
|
index[s] = s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
immutable pageSize = 1024 * 1024;
|
||||||
|
|
||||||
|
string insert(ubyte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes.length >= pageSize)
|
||||||
|
assert(false);
|
||||||
|
size_t last = pages.length - 1;
|
||||||
|
Page* p = &(pages[last]);
|
||||||
|
size_t free = p.data.length - p.lastUsed;
|
||||||
|
if (free >= bytes.length)
|
||||||
|
{
|
||||||
|
p.data[p.lastUsed .. (p.lastUsed + bytes.length)] = bytes;
|
||||||
|
p.lastUsed += bytes.length;
|
||||||
|
return cast(immutable(char)[]) p.data[p.lastUsed - bytes.length .. p.lastUsed];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pages.length++;
|
||||||
|
pages[pages.length - 1].data[0 .. bytes.length] = bytes;
|
||||||
|
pages[pages.length - 1].lastUsed = bytes.length;
|
||||||
|
return cast(immutable(char)[]) pages[pages.length - 1].data[0 .. bytes.length];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Page
|
||||||
|
{
|
||||||
|
ubyte[pageSize] data;
|
||||||
|
size_t lastUsed;
|
||||||
|
}
|
||||||
|
Page[] pages;
|
||||||
|
string[string] index;
|
||||||
|
}
|
||||||
|
|
||||||
//void main(string[] args) {}
|
//void main(string[] args) {}
|
||||||
|
|
Loading…
Reference in New Issue