public int parsing_generic_less_than;
public int current_token;
public object val;
+ public int parsing_string_interpolation;
public Position (Tokenizer t)
{
ifstack = new Stack<int> (clone);
}
parsing_generic_less_than = t.parsing_generic_less_than;
+ parsing_string_interpolation = t.parsing_string_interpolation;
current_token = t.current_token;
val = t.val;
}
previous_col = p.previous_col;
ifstack = p.ifstack;
parsing_generic_less_than = p.parsing_generic_less_than;
+ parsing_string_interpolation = p.parsing_string_interpolation;
current_token = p.current_token;
val = p.val;
}
static bool is_identifier_start_character (int c)
{
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Char.IsLetter ((char)c);
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')
+ return true;
+
+ if (c < 0x80)
+ return false;
+
+ return is_identifier_start_character_slow_part ((char) c);
}
static bool is_identifier_part_character (char c)
return is_identifier_part_character_slow_part (c);
}
- static bool is_identifier_part_character_slow_part (char c)
+ static bool is_identifier_start_character_slow_part (char c)
{
- if (Char.IsLetter (c))
+ switch (Char.GetUnicodeCategory (c)) {
+ case UnicodeCategory.LetterNumber:
+ case UnicodeCategory.UppercaseLetter:
+ case UnicodeCategory.LowercaseLetter:
+ case UnicodeCategory.TitlecaseLetter:
+ case UnicodeCategory.ModifierLetter:
+ case UnicodeCategory.OtherLetter:
return true;
+ }
+ return false;
+ }
+ static bool is_identifier_part_character_slow_part (char c)
+ {
switch (Char.GetUnicodeCategory (c)) {
- case UnicodeCategory.ConnectorPunctuation:
-
- // combining-character: A Unicode character of classes Mn or Mc
- case UnicodeCategory.NonSpacingMark:
- case UnicodeCategory.SpacingCombiningMark:
-
- // decimal-digit-character: A Unicode character of the class Nd
- case UnicodeCategory.DecimalDigitNumber:
+ // connecting-character: A Unicode character of the class Pc
+ case UnicodeCategory.ConnectorPunctuation:
+
+ // combining-character: A Unicode character of classes Mn or Mc
+ case UnicodeCategory.NonSpacingMark:
+ case UnicodeCategory.SpacingCombiningMark:
+
+ // decimal-digit-character: A Unicode character of the class Nd
+ case UnicodeCategory.DecimalDigitNumber:
+
+ // plus is_identifier_start_character_slow_part
+ case UnicodeCategory.LetterNumber:
+ case UnicodeCategory.UppercaseLetter:
+ case UnicodeCategory.LowercaseLetter:
+ case UnicodeCategory.TitlecaseLetter:
+ case UnicodeCategory.ModifierLetter:
+ case UnicodeCategory.OtherLetter:
return true;
+
+ // formatting-character: A Unicode character of the class Cf
+ case UnicodeCategory.Format:
+ // csc bug compatibility which recognizes it as a whitespace
+ return c != 0xFEFF;
}
return false;
case Token.NULL:
case Token.THIS:
case Token.NEW:
+ case Token.INTERPOLATED_STRING:
next_token = Token.INTERR;
break;
return true;
}
+ bool ScanClosingInterpolationBrace ()
+ {
+ PushPosition ();
+
+ bool? res = null;
+ int str_quote = 0;
+ do {
+ var c = reader.Read ();
+ switch (c) {
+ case '\"':
+ ++str_quote;
+ break;
+ case -1:
+ res = false;
+ break;
+ case '}':
+ if (str_quote % 2 == 1) {
+ res = true;
+ }
+
+ break;
+ }
+ } while (res == null);
+
+ PopPosition ();
+ return res.Value;
+ }
+
int TokenizeNumber (int value)
{
number_pos = 0;
}
Report.Warning (1633, 1, Location, "Unrecognized #pragma directive");
+
+ // Eat any remaining characters on the line
+ ReadToEndOfLine ();
}
bool eval_val (string s)
if (c == '\\') {
int surrogate;
c = escape (c, out surrogate);
- if (surrogate != 0) {
- id_builder [pos++] = (char) c;
+ if (quoted || is_identifier_start_character (c)) {
+ // it's added bellow
+ } else if (surrogate != 0) {
+ id_builder [pos++] = (char)c;
c = surrogate;
+ } else {
+ Report.Error (1056, Location, "Unexpected character `\\{0}'", c.ToString ("x4"));
+ return Token.ERROR;
}
}
c = escape (c, out surrogate);
if (is_identifier_part_character ((char) c))
id_builder[pos++] = (char) c;
-
- if (surrogate != 0) {
+ else if (surrogate != 0) {
c = surrogate;
+ } else {
+ switch (c) {
+ // TODO: Probably need more whitespace characters
+ case 0xFEFF:
+ putback_char = c;
+ break;
+ default:
+ Report.Error (1056, Location, "Unexpected character `\\{0}'", c.ToString ("x4"));
+ return Token.ERROR;
+ }
}
continue;
return Token.OPEN_BRACE;
case '}':
if (parsing_string_interpolation > 0) {
- if (peek_char () != '}') {
- --parsing_string_interpolation;
- return TokenizeInterpolatedString ();
- }
-
- continue;
+ --parsing_string_interpolation;
+ return TokenizeInterpolatedString ();
}
val = ltb.Create (current_source, ref_line, col);
return Token.EOF;
case '"':
- if (parsing_string_interpolation > 0) {
+ if (parsing_string_interpolation > 0 && !ScanClosingInterpolationBrace ()) {
parsing_string_interpolation = 0;
Report.Error (8076, Location, "Missing close delimiter `}' for interpolated expression");
- val = null;
+ val = new StringLiteral (context.BuiltinTypes, "", Location);
return Token.INTERPOLATED_STRING_END;
}
if (pos == value_builder.Length)
Array.Resize (ref value_builder, pos * 2);
+ if (pos == value_builder.Length)
+ Array.Resize (ref value_builder, pos * 2);
+
value_builder [pos++] = (char)ch;
ch = surrogate;
}
}
++col;
+ if (pos == value_builder.Length)
+ Array.Resize (ref value_builder, pos * 2);
+
value_builder[pos++] = (char) ch;
}
}