Skip to content

Commit

Permalink
Improve the build times of dyaml.node
Browse files Browse the repository at this point in the history
  • Loading branch information
rikkimax committed Mar 2, 2023
1 parent 2c915b3 commit efda074
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 37 deletions.
64 changes: 61 additions & 3 deletions source/dyaml/node.d
Original file line number Diff line number Diff line change
Expand Up @@ -2477,7 +2477,28 @@ struct Node
return this.value_.tryMatch!(
(inout bool v) @safe => v.to!TType,
(inout long v) @safe => v.to!TType,
(inout Node[] v) @trusted => v.to!TType,
(inout Node[] v) @trusted
{
static if (is(TType == string))
{
auto sink = appender!string();
sink ~= "[";

foreach(i, ref node; v)
{
if (i > 0)
sink ~= ", ";
node.toString(sink);
}

sink ~= "]";
return sink.data;
}
else
{
return v.to!TType;
}
},
(inout ubyte[] v) @safe => v.to!TType,
(inout string v) @safe => v.to!TType,
(inout Node.Pair[] v) @trusted => v.to!TType,
Expand Down Expand Up @@ -2510,17 +2531,54 @@ struct Node
this.value_.match!(
(const bool v) => formattedWrite(sink, v ? "true" : "false"),
(const long v) => formattedWrite(sink, "%s", v),
(const Node[] v) => formattedWrite(sink, "[%(%s, %)]", v),
(scope const Node[] v) @trusted
{
sink ~= "[";

foreach(i, ref node; v)
{
if (i > 0)
sink ~= ", ";
node.toString(sink);
}

sink ~= "]";
return 0;
},
(const ubyte[] v) => formattedWrite(sink, "%s", v),
(const string v) => formattedWrite(sink, `"%s"`, v),
(const Node.Pair[] v) => formattedWrite(sink, "{%(%s, %)}", v),
(const SysTime v) => formattedWrite(sink, "%s", v),
(const SysTime v)
{
v.toString(sink);
return 0;
},
(const YAMLNull v) => formattedWrite(sink, "%s", v),
(const YAMLMerge v) => formattedWrite(sink, "%s", v),
(const real v) => formattedWrite(sink, "%s", v),
(const YAMLInvalid v) => formattedWrite(sink, "%s", v),
);
}

@safe unittest
{
import std.array : appender;
auto output = appender!string();
auto seq1 = Node([1, 2, 3, 4, 5]);

seq1.toString(output);
assert(output.data.length > 0);
}

@safe unittest
{
import std.array : appender;
auto output = appender!string();
auto node = Node(SysTime(DateTime(2005, 6, 15, 20, 0, 0), UTC()));

node.toString(output);
assert(output.data.length > 0);
}
}

package:
Expand Down
67 changes: 33 additions & 34 deletions source/dyaml/resolver.d
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,42 @@ import dyaml.exception;
/// Type of `regexes`
private alias RegexType = Tuple!(string, "tag", const Regex!char, "regexp", string, "chars");

private immutable RegexType[] regexes = [
RegexType("tag:yaml.org,2002:bool",
regex(r"^(?:yes|Yes|YES|no|No|NO|true|True|TRUE" ~
"|false|False|FALSE|on|On|ON|off|Off|OFF)$"),
"yYnNtTfFoO"),
RegexType("tag:yaml.org,2002:float",
regex(r"^(?:[-+]?([0-9][0-9_]*)\\.[0-9_]*" ~
"(?:[eE][-+][0-9]+)?|[-+]?(?:[0-9][0-9_]" ~
"*)?\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?" ~
"[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]" ~
"*|[-+]?\\.(?:inf|Inf|INF)|\\." ~
"(?:nan|NaN|NAN))$"),
"-+0123456789."),
RegexType("tag:yaml.org,2002:int",
regex(r"^(?:[-+]?0b[0-1_]+" ~
"|[-+]?0[0-7_]+" ~
"|[-+]?(?:0|[1-9][0-9_]*)" ~
"|[-+]?0x[0-9a-fA-F_]+" ~
"|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$"),
"-+0123456789"),
RegexType("tag:yaml.org,2002:merge", regex(r"^<<$"), "<"),
RegexType("tag:yaml.org,2002:null",
regex(r"^$|^(?:~|null|Null|NULL)$"), "~nN\0"),
RegexType("tag:yaml.org,2002:timestamp",
regex(r"^[0-9][0-9][0-9][0-9]-[0-9][0-9]-" ~
"[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9]" ~
"[0-9]?-[0-9][0-9]?[Tt]|[ \t]+[0-9]" ~
"[0-9]?:[0-9][0-9]:[0-9][0-9]" ~
"(?:\\.[0-9]*)?(?:[ \t]*Z|[-+][0-9]" ~
"[0-9]?(?::[0-9][0-9])?)?$"),
"0123456789"),
RegexType("tag:yaml.org,2002:value", regex(r"^=$"), "="),
// build this at runtime, to prevent build time costs
private __gshared immutable RegexType[] regexes;

shared static this() {
__gshared string forceRT;
RegexType[] regexArray;
Regex!char toBuild;

toBuild = regex(r"^(?:yes|Yes|YES|no|No|NO|true|True|TRUE" ~ "|false|False|FALSE|on|On|ON|off|Off|OFF)$" ~ forceRT);
regexArray ~= RegexType("tag:yaml.org,2002:bool", toBuild, "yYnNtTfFoO");

toBuild = regex(r"^(?:[-+]?([0-9][0-9_]*)\\.[0-9_]*" ~ "(?:[eE][-+][0-9]+)?|[-+]?(?:[0-9][0-9_]" ~ "*)?\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?" ~ "[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]" ~ "*|[-+]?\\.(?:inf|Inf|INF)|\\." ~ "(?:nan|NaN|NAN))$" ~ forceRT);
regexArray ~= RegexType("tag:yaml.org,2002:float", toBuild, "-+0123456789.");

toBuild = regex(r"^(?:[-+]?0b[0-1_]+" ~ "|[-+]?0[0-7_]+" ~ "|[-+]?(?:0|[1-9][0-9_]*)" ~ "|[-+]?0x[0-9a-fA-F_]+" ~ "|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$" ~ forceRT);
regexArray ~= RegexType("tag:yaml.org,2002:int", toBuild, "-+0123456789");

toBuild = regex(r"^<<$" ~ forceRT);
regexArray ~= RegexType("tag:yaml.org,2002:merge", toBuild, "<");

toBuild = regex(r"^$|^(?:~|null|Null|NULL)$" ~ forceRT);
regexArray ~= RegexType("tag:yaml.org,2002:null", toBuild, "~nN\0");

toBuild = regex(r"^[0-9][0-9][0-9][0-9]-[0-9][0-9]-" ~ "[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9]" ~ "[0-9]?-[0-9][0-9]?[Tt]|[ \t]+[0-9]" ~ "[0-9]?:[0-9][0-9]:[0-9][0-9]" ~ "(?:\\.[0-9]*)?(?:[ \t]*Z|[-+][0-9]" ~ "[0-9]?(?::[0-9][0-9])?)?$");
regexArray ~= RegexType("tag:yaml.org,2002:timestamp", toBuild, "0123456789");

toBuild = regex(r"^=$");
regexArray ~= RegexType("tag:yaml.org,2002:value", toBuild, "=");

//The following resolver is only for documentation purposes. It cannot work
//because plain scalars cannot start with '!', '&', or '*'.
RegexType("tag:yaml.org,2002:yaml", regex(r"^(?:!|&|\*)$"), "!&*"),
];
toBuild = regex(r"^(?:!|&|\*)$");
regexArray ~= RegexType("tag:yaml.org,2002:yaml", toBuild, "!&*");

regexes = cast(immutable)regexArray;
}

/**
* Resolves YAML tags (data types).
Expand Down

0 comments on commit efda074

Please sign in to comment.