[mcs] Codegen for optimized new with valuetype load and awaited arguments. Fixes...
[mono-project.git] / mcs / ilasm / scanner / StringHelper.cs
blob32d0fc69765cdf6263ac1e17a00e374baccbdd12
1 // StringHelper.cs
2 // Author: Sergey Chaban (serge@wildwestsoftware.com)
4 using System;
5 using System.Text;
7 namespace Mono.ILASM {
9 /// <summary>
10 /// </summary>
11 internal class StringHelper : StringHelperBase {
13 private static readonly string startIdChars = "#$@_";
14 private static readonly string idChars = "_$@?`";
16 /// <summary>
17 /// </summary>
18 /// <param name="host"></param>
19 public StringHelper (ILTokenizer host) : base (host)
24 /// <summary>
25 /// </summary>
26 /// <returns></returns>
27 public override bool Start (char ch)
29 mode = Token.UNKNOWN;
31 if (Char.IsLetter (ch) || startIdChars.IndexOf (ch) != -1) {
32 mode = Token.ID;
33 } else if (ch == '\'') {
34 mode = Token.SQSTRING;
35 } else if (ch == '"') {
36 mode = Token.QSTRING;
39 return (mode != Token.UNKNOWN);
43 private static bool IsIdChar (int c)
45 char ch = (char) c;
46 return (Char.IsLetterOrDigit(ch) || idChars.IndexOf (ch) != -1);
49 /// <summary>
50 /// </summary>
51 /// <returns></returns>
52 public override string Build ()
54 if (mode == Token.UNKNOWN) return String.Empty;
55 int ch = 0;
57 ILReader reader = host.Reader;
59 StringBuilder idsb = new StringBuilder ();
60 if (mode == Token.SQSTRING || mode == Token.QSTRING) {
61 int term = (mode == Token.SQSTRING) ? '\'' : '"';
62 reader.Read (); // skip quote
63 for (ch = reader.Read (); ch != -1; ch = reader.Read ()) {
64 if (ch == term) {
65 break;
68 if (ch == '\\') {
69 ch = reader.Read ();
72 * Long string can be broken across multiple lines
73 * by using '\' as the last char in line.
74 * Any white space chars between '\' and the first
75 * char on the next line are ignored.
77 if (ch == '\n') {
78 reader.SkipWhitespace ();
79 continue;
82 int escaped = Escape (reader, ch);
83 if (escaped == -1) {
84 reader.Unread (ch);
85 ch = '\\';
86 } else {
87 ch = escaped;
91 idsb.Append((char)ch);
93 } else { // ID
94 while ((ch = reader.Read ()) != -1) {
95 if (IsIdChar (ch)) {
96 idsb.Append ((char) ch);
97 } else {
98 reader.Unread (ch);
99 break;
103 return idsb.ToString ();
109 /// <summary>
110 /// </summary>
111 /// <param name="ch"></param>
112 /// <returns></returns>
113 public static int Escape (ILReader reader, int ch)
115 int res = -1;
117 if (ch >= '0' && ch <='7') {
118 StringBuilder octal = new StringBuilder ();
119 octal.Append ((char)ch);
120 int possibleOctalChar = reader.Peek ();
121 if (possibleOctalChar >= '0' && possibleOctalChar <='7') {
122 octal.Append ((char)reader.Read ());
123 possibleOctalChar = reader.Peek ();
124 if (possibleOctalChar >= '0' && possibleOctalChar <='7')
125 octal.Append ((char)reader.Read ());
127 res = Convert.ToInt32(octal.ToString (), 8);
128 } else {
129 int id = "abfnrtv\"'\\".IndexOf ((char)ch);
130 if (id != -1) {
131 res = "\a\b\f\n\r\t\v\"'\\" [id];
135 return res;