using System;
using System.Text;
-using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
entry.column = column;
return entry;
}
+
+ //
+ // Used for token not required by expression evaluator
+ //
+ public static LocatedToken CreateOptional (int row, int col)
+ {
+#if false
+ return Create (row, col);
+#endif
+ return null;
+ }
public static void Initialize ()
{
int col = 0;
int previous_col;
int current_token;
+ int tab_size;
bool handle_get_set = false;
bool handle_remove_add = false;
bool handle_where = false;
bool handle_typeof = false;
bool lambda_arguments_parsing;
Location current_comment_location = Location.Null;
- ArrayList escaped_identifiers;
+ List<Location> escaped_identifiers;
int parsing_generic_less_than;
//
get { return handle_typeof; }
set { handle_typeof = value; }
}
+
+ public int TabSize {
+ get { return tab_size; }
+ set { tab_size = value; }
+ }
public XmlCommentState doc_state {
get { return xml_doc_state; }
void AddEscapedIdentifier (Location loc)
{
if (escaped_identifiers == null)
- escaped_identifiers = new ArrayList ();
+ escaped_identifiers = new List<Location> ();
escaped_identifiers.Add (loc);
}
// Values for the associated token returned
//
internal int putback_char; // Used by repl only
- Object val;
+ object val;
//
// Pre-processor
//
// pre-processor if stack state:
//
- Stack ifstack;
+ Stack<int> ifstack;
static System.Text.StringBuilder string_builder;
// on its own to deamiguate a token in behalf of the
// parser.
//
- Stack position_stack = new Stack (2);
+ Stack<Position> position_stack = new Stack<Position> (2);
+
class Position {
public int position;
public int line;
public bool hidden;
public int putback_char;
public int previous_col;
- public Stack ifstack;
+ public Stack<int> ifstack;
public int parsing_generic_less_than;
public int current_token;
+ public object val;
public Position (Tokenizer t)
{
hidden = t.hidden;
putback_char = t.putback_char;
previous_col = t.previous_col;
- if (t.ifstack != null && t.ifstack.Count != 0)
- ifstack = (Stack)t.ifstack.Clone ();
+ if (t.ifstack != null && t.ifstack.Count != 0) {
+ // There is no simple way to clone Stack<T> all
+ // methods reverse the order
+ var clone = t.ifstack.ToArray ();
+ Array.Reverse (clone);
+ ifstack = new Stack<int> (clone);
+ }
parsing_generic_less_than = t.parsing_generic_less_than;
current_token = t.current_token;
+ val = t.val;
}
}
public void PopPosition ()
{
- Position p = (Position) position_stack.Pop ();
+ Position p = position_stack.Pop ();
reader.Position = p.position;
ref_line = p.ref_line;
ifstack = p.ifstack;
parsing_generic_less_than = p.parsing_generic_less_than;
current_token = p.current_token;
+ val = p.val;
}
// Do not reset the position, ignore it.
xml_comment_buffer = new StringBuilder ();
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ tab_size = 4;
+ else
+ tab_size = 8;
+
//
// FIXME: This could be `Location.Push' but we have to
// find out why the MS compiler allows this
//
// Open parens micro parser. Detects both lambda and cast ambiguity.
- //
-
+ //
int TokenizeOpenParens ()
{
int ptoken;
//
// Expression inside parens is lambda, (int i) =>
//
- if (current_token == Token.ARROW) {
- if (RootContext.Version <= LanguageVersion.ISO_2)
- Report.FeatureIsNotAvailable (Location, "lambda expressions");
-
+ if (current_token == Token.ARROW)
return Token.OPEN_PARENS_LAMBDA;
- }
//
// Expression inside parens is single type, (int[])
case Token.BANG:
case Token.TILDE:
case Token.IDENTIFIER:
- case Token.LITERAL_INTEGER:
- case Token.LITERAL_FLOAT:
- case Token.LITERAL_DOUBLE:
- case Token.LITERAL_DECIMAL:
- case Token.LITERAL_CHARACTER:
- case Token.LITERAL_STRING:
+ case Token.LITERAL:
case Token.BASE:
case Token.CHECKED:
case Token.DELEGATE:
case Token.TRUE:
case Token.FALSE:
case Token.NULL:
- case Token.LITERAL_INTEGER:
- case Token.LITERAL_STRING:
+ case Token.LITERAL:
return Token.INTERR;
}
current_token = Token.NONE;
int next_token;
switch (xtoken ()) {
- case Token.LITERAL_INTEGER:
- case Token.LITERAL_STRING:
- case Token.LITERAL_CHARACTER:
- case Token.LITERAL_DECIMAL:
- case Token.LITERAL_DOUBLE:
- case Token.LITERAL_FLOAT:
+ case Token.LITERAL:
case Token.TRUE:
case Token.FALSE:
case Token.NULL:
return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
}
- static int real_type_suffix (int c)
+ static TypeCode real_type_suffix (int c)
{
- int t;
-
switch (c){
case 'F': case 'f':
- t = Token.LITERAL_FLOAT;
- break;
+ return TypeCode.Single;
case 'D': case 'd':
- t = Token.LITERAL_DOUBLE;
- break;
+ return TypeCode.Double;
case 'M': case 'm':
- t= Token.LITERAL_DECIMAL;
- break;
+ return TypeCode.Decimal;
default:
- return Token.NONE;
+ return TypeCode.Empty;
}
- return t;
}
int integer_type_suffix (ulong ul, int c)
}
if (is_long && is_unsigned){
- val = ul;
- return Token.LITERAL_INTEGER;
- } else if (is_unsigned){
+ val = new ULongLiteral (ul, Location);
+ return Token.LITERAL;
+ }
+
+ if (is_unsigned){
// uint if possible, or ulong else.
if ((ul & 0xffffffff00000000) == 0)
- val = (uint) ul;
+ val = new UIntLiteral ((uint) ul, Location);
else
- val = ul;
+ val = new ULongLiteral (ul, Location);
} else if (is_long){
// long if possible, ulong otherwise
if ((ul & 0x8000000000000000) != 0)
- val = ul;
+ val = new ULongLiteral (ul, Location);
else
- val = (long) ul;
+ val = new LongLiteral ((long) ul, Location);
} else {
// int, uint, long or ulong in that order
if ((ul & 0xffffffff00000000) == 0){
uint ui = (uint) ul;
if ((ui & 0x80000000) != 0)
- val = ui;
+ val = new UIntLiteral (ui, Location);
else
- val = (int) ui;
+ val = new IntLiteral ((int) ui, Location);
} else {
if ((ul & 0x8000000000000000) != 0)
- val = ul;
+ val = new ULongLiteral (ul, Location);
else
- val = (long) ul;
+ val = new LongLiteral ((long) ul, Location);
}
}
- return Token.LITERAL_INTEGER;
+ return Token.LITERAL;
}
//
} catch (OverflowException) {
error_details = "Integral constant is too large";
Report.Error (1021, Location, error_details);
- val = 0ul;
- return Token.LITERAL_INTEGER;
+ val = new IntLiteral (0, Location);
+ return Token.LITERAL;
}
catch (FormatException) {
Report.Error (1013, Location, "Invalid number");
- val = 0ul;
- return Token.LITERAL_INTEGER;
+ val = new IntLiteral (0, Location);
+ return Token.LITERAL;
}
}
- int adjust_real (int t)
+ int adjust_real (TypeCode t)
{
string s = new String (number_builder, 0, number_pos);
const string error_details = "Floating-point constant is outside the range of type `{0}'";
switch (t){
- case Token.LITERAL_DECIMAL:
+ case TypeCode.Decimal:
try {
- val = System.Decimal.Parse (s, styles, csharp_format_info);
+ val = new DecimalLiteral (decimal.Parse (s, styles, csharp_format_info), Location);
} catch (OverflowException) {
- val = 0m;
+ val = new DecimalLiteral (0, Location);
Report.Error (594, Location, error_details, "decimal");
}
break;
- case Token.LITERAL_FLOAT:
+ case TypeCode.Single:
try {
- val = float.Parse (s, styles, csharp_format_info);
+ val = new FloatLiteral (float.Parse (s, styles, csharp_format_info), Location);
} catch (OverflowException) {
- val = 0.0f;
+ val = new FloatLiteral (0, Location);
Report.Error (594, Location, error_details, "float");
}
break;
-
- case Token.LITERAL_DOUBLE:
- case Token.NONE:
- t = Token.LITERAL_DOUBLE;
+ default:
try {
- val = System.Double.Parse (s, styles, csharp_format_info);
+ val = new DoubleLiteral (double.Parse (s, styles, csharp_format_info), Location);
} catch (OverflowException) {
- val = 0.0;
+ val = new DoubleLiteral (0, Location);
Report.Error (594, Location, error_details, "double");
}
break;
}
- return t;
+
+ return Token.LITERAL;
}
int handle_hex ()
} catch (OverflowException){
error_details = "Integral constant is too large";
Report.Error (1021, Location, error_details);
- val = 0ul;
- return Token.LITERAL_INTEGER;
+ val = new IntLiteral (0, Location);
+ return Token.LITERAL;
}
catch (FormatException) {
Report.Error (1013, Location, "Invalid number");
- val = 0ul;
- return Token.LITERAL_INTEGER;
+ val = new IntLiteral (0, Location);
+ return Token.LITERAL;
}
return integer_type_suffix (ul, peek_char ());
int is_number (int c)
{
bool is_real = false;
- int type;
number_pos = 0;
c = get_char ();
}
- type = real_type_suffix (c);
- if (type == Token.NONE && !is_real){
+ var type = real_type_suffix (c);
+ if (type == TypeCode.Empty && !is_real){
putback (c);
return adjust_int (c);
- } else
- is_real = true;
+ }
+
+ is_real = true;
- if (type == Token.NONE){
+ if (type == TypeCode.Empty){
putback (c);
}
if (is_real)
return adjust_real (type);
- Console.WriteLine ("This should not be reached");
throw new Exception ("Is Number should never reach this point");
}
if (arg.StartsWith (w_restore)) {
int[] codes = ParseNumbers (arg.Substring (w_restore.Length));
- Hashtable w_table = Report.warning_ignore_table;
+ var w_table = Report.warning_ignore_table;
foreach (int code in codes) {
- if (w_table != null && w_table.Contains (code))
+ if (w_table != null && w_table.ContainsKey (code))
Report.Warning (1635, 1, Location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
Report.RegisterWarningRegion (Location).WarningEnable (Location, code, Report);
}
Error_UnexpectedDirective ("no #region for this #endregion");
return true;
}
- int pop = (int) ifstack.Pop ();
+ int pop = ifstack.Pop ();
if ((pop & REGION) == 0)
Report.Error (1027, Location, "Expected `#endif' directive");
case "if":
if (ifstack == null)
- ifstack = new Stack (2);
+ ifstack = new Stack<int> (2);
int flags = region_directive ? REGION : 0;
if (ifstack.Count == 0){
flags |= PARENT_TAKING;
} else {
- int state = (int) ifstack.Peek ();
+ int state = ifstack.Peek ();
if ((state & TAKING) != 0) {
flags |= PARENT_TAKING;
}
Error_UnexpectedDirective ("no #if for this #endif");
return true;
} else {
- pop = (int) ifstack.Pop ();
+ pop = ifstack.Pop ();
if ((pop & REGION) != 0)
Report.Error (1038, Location, "#endregion directive expected");
if (ifstack.Count == 0)
return true;
- int state = (int) ifstack.Peek ();
+ int state = ifstack.Peek ();
return (state & TAKING) != 0;
}
Error_UnexpectedDirective ("no #if for this #elif");
return true;
} else {
- int state = (int) ifstack.Pop ();
+ int state = ifstack.Pop ();
if ((state & REGION) != 0) {
Report.Error (1038, Location, "#endregion directive expected");
Error_UnexpectedDirective ("no #if for this #else");
return true;
} else {
- int state = (int) ifstack.Peek ();
+ int state = ifstack.Peek ();
if ((state & REGION) != 0) {
Report.Error (1038, Location, "#endregion directive expected");
get_char ();
continue;
} else {
- val = string_builder.ToString ();
- return Token.LITERAL_STRING;
+ val = new StringLiteral (string_builder.ToString (), Location);
+ return Token.LITERAL;
}
}
while ((c = get_char ()) != -1) {
switch (c) {
case '\t':
- col = ((col + 8) / 8) * 8;
+ col = ((col + tab_size) / tab_size) * tab_size;
continue;
case ' ':
// To block doccomment inside attribute declaration.
if (doc_state == XmlCommentState.Allowed)
doc_state = XmlCommentState.NotAllowed;
+ val = LocatedToken.CreateOptional (ref_line, col);
return Token.OPEN_BRACKET;
case ']':
+ val = LocatedToken.CreateOptional (ref_line, col);
return Token.CLOSE_BRACKET;
case '(':
val = LocatedToken.Create (ref_line, col);
return Token.OPEN_PARENS;
case ')':
+ val = LocatedToken.CreateOptional (ref_line, col);
return Token.CLOSE_PARENS;
case ',':
+ val = LocatedToken.CreateOptional (ref_line, col);
return Token.COMMA;
case ';':
+ val = LocatedToken.CreateOptional (ref_line, col);
return Token.SEMICOLON;
case '~':
+ val = LocatedToken.Create (ref_line, col);
return Token.TILDE;
case '?':
+ val = LocatedToken.Create (ref_line, col);
return TokenizePossibleNullableType ();
case '<':
+ val = LocatedToken.Create (ref_line, col);
if (parsing_generic_less_than++ > 0)
return Token.OP_GENERICS_LT;
return TokenizeLessThan ();
case '>':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '='){
return Token.OP_GT;
case '+':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '+') {
d = Token.OP_INC;
return d;
case '-':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '-') {
d = Token.OP_DEC;
return d;
case '!':
+ val = LocatedToken.Create (ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_NE;
return Token.BANG;
case '=':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '='){
get_char ();
return Token.ASSIGN;
case '&':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '&'){
get_char ();
return Token.BITWISE_AND;
case '|':
+ val = LocatedToken.Create (ref_line, col);
d = peek_char ();
if (d == '|'){
get_char ();
return Token.BITWISE_OR;
case '*':
+ val = LocatedToken.Create (ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_MULT_ASSIGN;
}
- val = LocatedToken.Create (ref_line, col);
return Token.STAR;
case '/':
d = peek_char ();
if (d == '='){
+ val = LocatedToken.Create (ref_line, col);
get_char ();
return Token.OP_DIV_ASSIGN;
}
return Token.DIV;
case '%':
+ val = LocatedToken.Create (ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_MOD_ASSIGN;
return Token.PERCENT;
case '^':
+ val = LocatedToken.Create (ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_XOR_ASSIGN;
return Token.CARRET;
case ':':
+ val = LocatedToken.Create (ref_line, col);
if (peek_char () == ':') {
get_char ();
return Token.DOUBLE_COLON;
if (d != 0)
throw new NotImplementedException ();
- val = (char) c;
+ val = new CharLiteral ((char) c, Location);
c = get_char ();
if (c != '\'') {
return Token.ERROR;
}
- return Token.LITERAL_CHARACTER;
+ return Token.LITERAL;
}
int TokenizeLessThan ()
public void cleanup ()
{
if (ifstack != null && ifstack.Count >= 1) {
- int state = (int) ifstack.Pop ();
+ int state = ifstack.Pop ();
if ((state & REGION) != 0)
Report.Error (1038, Location, "#endregion directive expected");
else