using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics.Contracts; using Microsoft.Boogie; namespace Microsoft.Dafny { class Util { public static string Comma(IEnumerable l, Func f) { return Comma(",", l, f); } public static string Comma(string comma, IEnumerable l, Func f) { string res = ""; string c = ""; foreach(var t in l) { res += c + f(t); c = comma; } return res; } public static List Map(IEnumerable xs, Func f) { List ys = new List(); foreach (A x in xs) { ys.Add(f(x)); } return ys; } public static List Nil() { return new List(); } public static List Singleton(A x) { return new List { x }; } public static List Cons(A x, List xs) { return Concat(Singleton(x), xs); } public static List Snoc(List xs, A x) { return Concat(xs, Singleton(x)); } public static List Concat(List xs, List ys) { List cpy = new List(xs); cpy.AddRange(ys); return cpy; } public static Dictionary Dict(IEnumerable xs, IEnumerable ys) { return Dict(xs.Zip(ys)); } public static Dictionary Dict(IEnumerable> xys) { Dictionary res = new Dictionary(); foreach (var p in xys) { res[p.Item1] = p.Item2; } return res; } /// /// Returns s but with all occurrences of '_' removed. /// public static string RemoveUnderscores(string s) { Contract.Requires(s != null); while (true) { var j = s.IndexOf('_'); if (j == -1) { return s; } s = s.Substring(0, j) + s.Substring(j + 1); } } /// /// For "S" returns S and false. /// For @"S" return S and true. /// Assumes that s has one of these forms. /// public static string RemoveParsedStringQuotes(string s, out bool isVerbatimString) { Contract.Requires(s != null); var len = s.Length; if (s[0] == '@') { isVerbatimString = true; return s.Substring(2, len - 3); } else { isVerbatimString = false; return s.Substring(1, len - 2); } } /// /// Replaced any escaped characters in s by the actual character that the escaping represents. /// Assumes s to be a well-parsed string. /// public static string RemoveEscaping(string s, bool isVerbatimString) { Contract.Requires(s != null); var sb = new StringBuilder(); UnescapedCharacters(s, isVerbatimString).Iter(ch => sb.Append(ch)); return sb.ToString(); } /// /// Returns the characters of the well-parsed string p, replacing any /// escaped characters by the actual characters. /// public static IEnumerable UnescapedCharacters(string p, bool isVerbatimString) { Contract.Requires(p != null); if (isVerbatimString) { var skipNext = false; foreach (var ch in p) { if (skipNext) { skipNext = false; } else { yield return ch; if (ch == '"') { skipNext = true; } } } } else { var i = 0; while (i < p.Length) { char special = ' '; // ' ' indicates not special if (p[i] == '\\') { switch (p[i + 1]) { case '\'': special = '\''; break; case '\"': special = '\"'; break; case '\\': special = '\\'; break; case '\0': special = '\0'; break; case 'n': special = '\n'; break; case 'r': special = '\r'; break; case 't': special = '\t'; break; case 'u': int ch = HexValue(p[i + 2]); ch = 16 * ch + HexValue(p[i + 3]); ch = 16 * ch + HexValue(p[i + 4]); ch = 16 * ch + HexValue(p[i + 5]); yield return (char)ch; i += 6; continue; default: break; } } if (special != ' ') { yield return special; i += 2; } else { yield return p[i]; i++; } } } } /// /// Converts a hexadecimal digit to an integer. /// Assumes ch does represent a hexadecimal digit; alphabetic digits can be in either case. /// public static int HexValue(char ch) { if ('a' <= ch && ch <= 'f') { return ch - 'a' + 10; } else if ('A' <= ch && ch <= 'F') { return ch - 'A' + 10; } else { return ch - '0'; } } } }