From 1cc6a04b8bce82fa83b62d919bf8bdf14cad0b92 Mon Sep 17 00:00:00 2001 From: Ralph Amissah Date: Sat, 1 Oct 2016 13:54:14 -0400 Subject: update sdlang, start looking to using dub remote dependencies --- src/sdlang/util.d | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 5 deletions(-) (limited to 'src/sdlang/util.d') diff --git a/src/sdlang/util.d b/src/sdlang/util.d index 329e387..d192ea2 100644 --- a/src/sdlang/util.d +++ b/src/sdlang/util.d @@ -4,10 +4,14 @@ module sdlang.util; import std.algorithm; +import std.array; +import std.conv; import std.datetime; +import std.range; import std.stdio; import std.string; +import sdlang.exception; import sdlang.token; enum sdlangVersion = "0.9.1"; @@ -26,14 +30,14 @@ struct Location int line; /// Zero-indexed int col; /// Zero-indexed, Tab counts as 1 size_t index; /// Index into the source - + this(int line, int col, int index) { this.line = line; this.col = col; this.index = index; } - + this(string file, int line, int col, int index) { this.file = file; @@ -41,12 +45,106 @@ struct Location this.col = col; this.index = index; } - + + /// Convert to string. Optionally takes output range as a sink. + string toString() + { + Appender!string sink; + this.toString(sink); + return sink.data; + } + + ///ditto + void toString(Sink)(ref Sink sink) if(isOutputRange!(Sink,char)) + { + sink.put(file); + sink.put("("); + sink.put(to!string(line+1)); + sink.put(":"); + sink.put(to!string(col+1)); + sink.put(")"); + } +} + +struct FullName +{ + string namespace; + string name; + + /// Convert to string. Optionally takes output range as a sink. string toString() { - return "%s(%s:%s)".format(file, line+1, col+1); + if(namespace == "") + return name; + + Appender!string sink; + this.toString(sink); + return sink.data; + } + + ///ditto + void toString(Sink)(ref Sink sink) if(isOutputRange!(Sink,char)) + { + if(namespace != "") + { + sink.put(namespace); + sink.put(":"); + } + + sink.put(name); + } + + /// + static string combine(string namespace, string name) + { + return FullName(namespace, name).toString(); + } + /// + @("FullName.combine example") + unittest + { + assert(FullName.combine("", "name") == "name"); + assert(FullName.combine("*", "name") == "*:name"); + assert(FullName.combine("namespace", "name") == "namespace:name"); + } + + /// + static FullName parse(string fullName) + { + FullName result; + + auto parts = fullName.findSplit(":"); + if(parts[1] == "") // No colon + { + result.namespace = ""; + result.name = parts[0]; + } + else + { + result.namespace = parts[0]; + result.name = parts[2]; + } + + return result; + } + /// + @("FullName.parse example") + unittest + { + assert(FullName.parse("name") == FullName("", "name")); + assert(FullName.parse("*:name") == FullName("*", "name")); + assert(FullName.parse("namespace:name") == FullName("namespace", "name")); + } + + /// Throws with appropriate message if this.name is "*". + /// Wildcards are only supported for namespaces, not names. + void ensureNoWildcardName(string extaMsg = null) + { + if(name == "*") + throw new ArgumentException(`Wildcards ("*") only allowed for namespaces, not names. `~extaMsg); } } +struct Foo { string foo; } void removeIndex(E)(ref E[] arr, ptrdiff_t index) { @@ -79,6 +177,24 @@ string toString(TypeInfo ti) else if(ti == typeid( Duration )) return "Duration"; else if(ti == typeid( ubyte[] )) return "ubyte[]"; else if(ti == typeid( typeof(null) )) return "null"; - + return "{unknown}"; } + +enum BOM { + UTF8, /// UTF-8 + UTF16LE, /// UTF-16 (little-endian) + UTF16BE, /// UTF-16 (big-endian) + UTF32LE, /// UTF-32 (little-endian) + UTF32BE, /// UTF-32 (big-endian) +} + +enum NBOM = __traits(allMembers, BOM).length; +immutable ubyte[][NBOM] ByteOrderMarks = +[ + [0xEF, 0xBB, 0xBF], //UTF8 + [0xFF, 0xFE], //UTF16LE + [0xFE, 0xFF], //UTF16BE + [0xFF, 0xFE, 0x00, 0x00], //UTF32LE + [0x00, 0x00, 0xFE, 0xFF] //UTF32BE +]; -- cgit v1.2.3