[Monodevelop-patches-list] r2282 - in trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn: . Gui

Chris Toshok toshok at mono-cvs.ximian.com
Tue Mar 1 18:58:20 EST 2005


Author: toshok
Date: 2005-03-01 18:58:20 -0500 (Tue, 01 Mar 2005)
New Revision: 2282

Added:
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs
Modified:
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs
   trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am
Log:
2005-03-01  Chris Toshok  <toshok at ximian.com>

	* Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_member):
	strip out the part of add_struct that adds individual fields and
	implement all the DebuggerBrowsableAttribute handling.
	(DebuggerVariablePad.add_struct): display both fields and
	properties.
	(DebuggerVariablePad.GetDebuggerBrowsableAttribute): returns the
	first DebuggerBrowsable attribute for a given ITargetMemberInfo,
	if there are any.
	(DebuggerVariablePad.GetDebuggerDisplayAttribute): returns the
	first DebuggerDisplay attribute for a given ITargetObject, if
	there are any.
	(DebuggerVariablePad.EvaluateDebuggerDisplay): given the
	DebuggerDisplay attribute's value, evaluate any nested
	{expressions} and convert them all to strings.
	(DebuggerVariablePad.add_object): if it's a struct or class, add
	the DebuggerDisplay if there is one.

	* DebuggingService.cs (MainThread): add a getter for this, so we
	can grab a thread with which to evaluate expressions in
	DebuggerDisplayAttributes.

	* Makefile.am (FILES): add stripped down files from the debugger
	source - EvaluationContext.cs (formerly ScriptingContext),
	Expression.cs, MyTextReader.cs, CSharpTokenizer.cs, and
	CSharpExpressionParser.cs.



Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,753 @@
+// created by jay 0.7 (c) 1998 Axel.Schreiner at informatik.uni-osnabrueck.de
+
+#line 2 "CSharpExpressionParser.jay"
+using System.Text;
+using System.IO;
+using System.Collections;
+using System;
+
+namespace Debugger.Frontend
+{
+#if NET_2_0
+	public class CSharpExpressionParser
+	{
+		EvaluationContext current_context;
+		MyTextReader reader;
+		Tokenizer lexer;
+
+		protected bool yacc_verbose_flag = false;
+
+		public bool Verbose {
+			set {
+				yacc_verbose_flag = value;
+			}
+
+			get {
+				return yacc_verbose_flag;
+			}
+		}
+
+#line default
+
+  /** simplified error message.
+      @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
+    */
+  public void yyerror (string message) {
+    yyerror(message, null);
+  }
+
+  /** (syntax) error message.
+      Can be overwritten to control message format.
+      @param message text to be displayed.
+      @param expected vector of acceptable tokens, if available.
+    */
+  public void yyerror (string message, string[] expected) {
+    if ((expected != null) && (expected.Length  > 0)) {
+      System.Console.Write (message+", expecting");
+      for (int n = 0; n < expected.Length; ++ n)
+        System.Console.Write (" "+expected[n]);
+        System.Console.WriteLine ();
+    } else
+      System.Console.WriteLine (message);
+  }
+
+  /** debugging support, requires the package jay.yydebug.
+      Set to null to suppress debugging messages.
+    */
+  internal yydebug.yyDebug debug;
+
+  protected static  int yyFinal = 13;
+  public static  string [] yyRule = {
+    "$accept : parse_expression",
+    "parse_expression : primary_expression",
+    "primary_expression : expression",
+    "primary_expression : expression ASSIGN expression",
+    "expression : NUMBER",
+    "expression : INTEGER",
+    "expression : STRING",
+    "expression : THIS",
+    "expression : CATCH",
+    "expression : BASE DOTDOT IDENTIFIER",
+    "expression : BASE DOT IDENTIFIER",
+    "expression : variable_or_type_name",
+    "expression : PERCENT IDENTIFIER",
+    "expression : STAR expression",
+    "expression : AMPERSAND expression",
+    "expression : expression OPEN_BRACKET expression CLOSE_BRACKET",
+    "expression : expression OPEN_PARENS argument_list CLOSE_PARENS",
+    "expression : NEW variable_or_type_name OPEN_PARENS argument_list CLOSE_PARENS",
+    "expression : OPEN_PARENS variable_or_type_name CLOSE_PARENS expression",
+    "expression : OPEN_PARENS expression CLOSE_PARENS",
+    "argument_list :",
+    "argument_list : argument_list_0",
+    "argument_list_0 : expression",
+    "argument_list_0 : argument_list_0 COMMA expression",
+    "variable_or_type_name : IDENTIFIER",
+    "variable_or_type_name : expression DOT IDENTIFIER",
+    "variable_or_type_name : expression DOTDOT IDENTIFIER",
+    "variable_or_type_name : expression MINUS OP_GT IDENTIFIER",
+  };
+  protected static  string [] yyNames = {    
+    "end-of-file",null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,"QUIT","EOF","NONE","ERROR",
+    "IDENTIFIER","INTEGER","NUMBER","STRING","HASH","AT","PERCENT",
+    "DOLLAR","DOT","DOTDOT","BANG","COMMA","ASSIGN","STAR","PLUS","MINUS",
+    "DIV","OPEN_PARENS","CLOSE_PARENS","OPEN_BRACKET","CLOSE_BRACKET",
+    "OP_LT","OP_GT","COLON","AMPERSAND","LENGTH","LOWER","UPPER","NEW",
+    "THIS","BASE","CATCH",
+  };
+
+  /** index-checked interface to yyNames[].
+      @param token single character or %token value.
+      @return token name or [illegal] or [unknown].
+    */
+  public static string yyname (int token) {
+    if ((token < 0) || (token > yyNames.Length)) return "[illegal]";
+    string name;
+    if ((name = yyNames[token]) != null) return name;
+    return "[unknown]";
+  }
+
+  /** computes list of expected tokens on error by tracing the tables.
+      @param state for which to compute the list.
+      @return list of token names.
+    */
+  protected string[] yyExpecting (int state) {
+    int token, n, len = 0;
+    bool[] ok = new bool[yyNames.Length];
+
+    if ((n = yySindex[state]) != 0)
+      for (token = n < 0 ? -n : 0;
+           (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+          ++ len;
+          ok[token] = true;
+        }
+    if ((n = yyRindex[state]) != 0)
+      for (token = n < 0 ? -n : 0;
+           (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+          ++ len;
+          ok[token] = true;
+        }
+
+    string [] result = new string[len];
+    for (n = token = 0; n < len;  ++ token)
+      if (ok[token]) result[n++] = yyNames[token];
+    return result;
+  }
+
+  /** the generated parser, with debugging messages.
+      Maintains a state and a value stack, currently with fixed maximum size.
+      @param yyLex scanner.
+      @param yydebug debug message writer implementing yyDebug, or null.
+      @return result of the last reduction, if any.
+      @throws yyException on irrecoverable parse error.
+    */
+ internal Object yyparse (yyParser.yyInput yyLex, Object yyd)
+				 {
+    this.debug = (yydebug.yyDebug)yyd;
+    return yyparse(yyLex);
+  }
+
+  /** initial size and increment of the state/value stack [default 256].
+      This is not final so that it can be overwritten outside of invocations
+      of yyparse().
+    */
+  protected int yyMax;
+
+  /** executed at the beginning of a reduce action.
+      Used as $$ = yyDefault($1), prior to the user-specified action, if any.
+      Can be overwritten to provide deep copy, etc.
+      @param first value for $1, or null.
+      @return first.
+    */
+  protected Object yyDefault (Object first) {
+    return first;
+  }
+
+  /** the generated parser.
+      Maintains a state and a value stack, currently with fixed maximum size.
+      @param yyLex scanner.
+      @return result of the last reduction, if any.
+      @throws yyException on irrecoverable parse error.
+    */
+  internal Object yyparse (yyParser.yyInput yyLex)
+				{
+    if (yyMax <= 0) yyMax = 256;			// initial size
+    int yyState = 0;                                   // state stack ptr
+    int [] yyStates = new int[yyMax];	                // state stack 
+    Object yyVal = null;                               // value stack ptr
+    Object [] yyVals = new Object[yyMax];	        // value stack
+    int yyToken = -1;					// current input
+    int yyErrorFlag = 0;				// #tks to shift
+
+    int yyTop = 0;
+    goto skip;
+    yyLoop:
+    yyTop++;
+    skip:
+    for (;; ++ yyTop) {
+      if (yyTop >= yyStates.Length) {			// dynamically increase
+        int[] i = new int[yyStates.Length+yyMax];
+        yyStates.CopyTo (i, 0);
+        yyStates = i;
+        Object[] o = new Object[yyVals.Length+yyMax];
+        yyVals.CopyTo (o, 0);
+        yyVals = o;
+      }
+      yyStates[yyTop] = yyState;
+      yyVals[yyTop] = yyVal;
+      if (debug != null) debug.push(yyState, yyVal);
+
+      yyDiscarded: for (;;) {	// discarding a token does not change stack
+        int yyN;
+        if ((yyN = yyDefRed[yyState]) == 0) {	// else [default] reduce (yyN)
+          if (yyToken < 0) {
+            yyToken = yyLex.advance() ? yyLex.token() : 0;
+            if (debug != null)
+              debug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
+          }
+          if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
+              && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
+            if (debug != null)
+              debug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
+            yyState = yyTable[yyN];		// shift to yyN
+            yyVal = yyLex.value();
+            yyToken = -1;
+            if (yyErrorFlag > 0) -- yyErrorFlag;
+            goto yyLoop;
+          }
+          if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
+              && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
+            yyN = yyTable[yyN];			// reduce (yyN)
+          else
+            switch (yyErrorFlag) {
+  
+            case 0:
+              yyerror("syntax error", yyExpecting(yyState));
+              if (debug != null) debug.error("syntax error");
+              goto case 1;
+            case 1: case 2:
+              yyErrorFlag = 3;
+              do {
+                if ((yyN = yySindex[yyStates[yyTop]]) != 0
+                    && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length
+                    && yyCheck[yyN] == Token.yyErrorCode) {
+                  if (debug != null)
+                    debug.shift(yyStates[yyTop], yyTable[yyN], 3);
+                  yyState = yyTable[yyN];
+                  yyVal = yyLex.value();
+                  goto yyLoop;
+                }
+                if (debug != null) debug.pop(yyStates[yyTop]);
+              } while (-- yyTop >= 0);
+              if (debug != null) debug.reject();
+              throw new yyParser.yyException("irrecoverable syntax error");
+  
+            case 3:
+              if (yyToken == 0) {
+                if (debug != null) debug.reject();
+                throw new yyParser.yyException("irrecoverable syntax error at end-of-file");
+              }
+              if (debug != null)
+                debug.discard(yyState, yyToken, yyname(yyToken),
+  							yyLex.value());
+              yyToken = -1;
+              goto yyDiscarded;		// leave stack alone
+            }
+        }
+        int yyV = yyTop + 1-yyLen[yyN];
+        if (debug != null)
+          debug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
+        yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
+        switch (yyN) {
+case 1:
+#line 75 "CSharpExpressionParser.jay"
+  {
+		return yyVals[0+yyTop];
+	  }
+  break;
+case 3:
+#line 83 "CSharpExpressionParser.jay"
+  {
+		yyVal = new AssignmentExpression ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
+	  }
+  break;
+case 4:
+#line 90 "CSharpExpressionParser.jay"
+  {
+		yyVal = new NumberExpression ((long) yyVals[0+yyTop]);
+	  }
+  break;
+case 5:
+#line 94 "CSharpExpressionParser.jay"
+  {
+		yyVal = new NumberExpression ((int) yyVals[0+yyTop]);
+	  }
+  break;
+case 6:
+#line 98 "CSharpExpressionParser.jay"
+  {
+		yyVal = new StringExpression ((string) yyVals[0+yyTop]);
+	  }
+  break;
+case 7:
+#line 102 "CSharpExpressionParser.jay"
+  {
+		yyVal = new ThisExpression ();
+	  }
+  break;
+case 8:
+#line 106 "CSharpExpressionParser.jay"
+  {
+    //		yyVal = new CatchExpression ();
+	  }
+  break;
+case 9:
+#line 110 "CSharpExpressionParser.jay"
+  {
+		yyVal = new MemberAccessExpression (new BaseExpression (), "." + ((string) yyVals[0+yyTop]));
+	  }
+  break;
+case 10:
+#line 114 "CSharpExpressionParser.jay"
+  {
+		yyVal = new MemberAccessExpression (new BaseExpression (), (string) yyVals[0+yyTop]);
+	  }
+  break;
+case 12:
+#line 119 "CSharpExpressionParser.jay"
+  {
+    //		yyVal = new RegisterExpression ((string) yyVals[0+yyTop], 0);
+	  }
+  break;
+case 13:
+#line 123 "CSharpExpressionParser.jay"
+  {
+		yyVal = new PointerDereferenceExpression ((Expression) yyVals[0+yyTop], false);
+	  }
+  break;
+case 14:
+#line 127 "CSharpExpressionParser.jay"
+  {
+		yyVal = new AddressOfExpression ((Expression) yyVals[0+yyTop]);
+	  }
+  break;
+case 15:
+#line 131 "CSharpExpressionParser.jay"
+  {
+		yyVal = new ArrayAccessExpression ((Expression) yyVals[-3+yyTop], (Expression) yyVals[-1+yyTop]);
+	  }
+  break;
+case 16:
+#line 135 "CSharpExpressionParser.jay"
+  {
+		yyVal = new InvocationExpression ((Expression) yyVals[-3+yyTop], ((Expression []) yyVals[-1+yyTop]));
+	  }
+  break;
+case 17:
+#line 139 "CSharpExpressionParser.jay"
+  {
+		yyVal = new NewExpression ((Expression) yyVals[-3+yyTop], ((Expression []) yyVals[-1+yyTop]));
+	  }
+  break;
+case 18:
+#line 143 "CSharpExpressionParser.jay"
+  {
+		yyVal = new CastExpression ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
+	  }
+  break;
+case 19:
+#line 147 "CSharpExpressionParser.jay"
+  {
+		yyVal = yyVals[-1+yyTop];
+	  }
+  break;
+case 20:
+#line 154 "CSharpExpressionParser.jay"
+  {
+		yyVal = new Expression [0];
+	  }
+  break;
+case 21:
+#line 158 "CSharpExpressionParser.jay"
+  {
+		Expression[] args = new Expression [((ArrayList) yyVals[0+yyTop]).Count];
+		((ArrayList) yyVals[0+yyTop]).CopyTo (args, 0);
+
+		yyVal = args;
+	  }
+  break;
+case 22:
+#line 168 "CSharpExpressionParser.jay"
+  {
+		ArrayList args = new ArrayList ();
+		args.Add (yyVals[0+yyTop]);
+
+		yyVal = args;
+	  }
+  break;
+case 23:
+#line 175 "CSharpExpressionParser.jay"
+  {
+		ArrayList args = (ArrayList) yyVals[-2+yyTop];
+		args.Add (yyVals[0+yyTop]);
+
+		yyVal = args;
+	  }
+  break;
+case 24:
+#line 185 "CSharpExpressionParser.jay"
+  {
+		yyVal = new SimpleNameExpression ((string) yyVals[0+yyTop]);
+	  }
+  break;
+case 25:
+#line 189 "CSharpExpressionParser.jay"
+  { 
+		yyVal = new MemberAccessExpression ((Expression) yyVals[-2+yyTop], (string) yyVals[0+yyTop]);
+	  }
+  break;
+case 26:
+#line 193 "CSharpExpressionParser.jay"
+  { 
+		yyVal = new MemberAccessExpression ((Expression) yyVals[-2+yyTop], "." + (string) yyVals[0+yyTop]);
+	  }
+  break;
+case 27:
+#line 197 "CSharpExpressionParser.jay"
+  {
+		Expression expr = new PointerDereferenceExpression ((Expression) yyVals[-3+yyTop], true);
+		yyVal = new MemberAccessExpression (expr, (string) yyVals[0+yyTop]);
+	  }
+  break;
+#line default
+        }
+        yyTop -= yyLen[yyN];
+        yyState = yyStates[yyTop];
+        int yyM = yyLhs[yyN];
+        if (yyState == 0 && yyM == 0) {
+          if (debug != null) debug.shift(0, yyFinal);
+          yyState = yyFinal;
+          if (yyToken < 0) {
+            yyToken = yyLex.advance() ? yyLex.token() : 0;
+            if (debug != null)
+               debug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
+          }
+          if (yyToken == 0) {
+            if (debug != null) debug.accept(yyVal);
+            return yyVal;
+          }
+          goto yyLoop;
+        }
+        if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
+            && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
+          yyState = yyTable[yyN];
+        else
+          yyState = yyDgoto[yyM];
+        if (debug != null) debug.shift(yyStates[yyTop], yyState);
+	 goto yyLoop;
+      }
+    }
+  }
+
+   static  short [] yyLhs  = {              -1,
+    0,    1,    1,    2,    2,    2,    2,    2,    2,    2,
+    2,    2,    2,    2,    2,    2,    2,    2,    2,    4,
+    4,    5,    5,    3,    3,    3,    3,
+  };
+   static  short [] yyLen = {           2,
+    1,    1,    3,    1,    1,    1,    1,    1,    3,    3,
+    1,    2,    2,    2,    4,    4,    5,    4,    3,    0,
+    1,    1,    3,    1,    3,    3,    4,
+  };
+   static  short [] yyDefRed = {            0,
+   24,    5,    4,    6,    0,    0,    0,    0,    0,    7,
+    0,    8,    0,    1,    0,   11,   12,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   19,    0,    0,   10,    9,   25,   26,    0,    0,
+    0,    0,    0,    0,    0,    0,   27,   16,    0,   15,
+   17,    0,
+  };
+  protected static  short [] yyDgoto  = {            13,
+   14,   41,   16,   42,   43,
+  };
+  protected static  short [] yySindex = {         -246,
+    0,    0,    0,    0, -255, -246, -246, -246, -246,    0,
+ -245,    0,    0,    0, -215,    0,    0, -198, -210, -253,
+ -198, -198, -256, -232, -230, -227, -225, -246, -243, -246,
+ -246,    0, -246, -246,    0,    0,    0,    0, -198, -224,
+ -198, -241, -223, -228, -198, -222,    0,    0, -246,    0,
+    0, -198,
+  };
+  protected static  short [] yyRindex = {            0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,   47,    0,    0,    1,    0, -195,
+    4,    0, -257,    0,    0,    0,    0,    0,    0, -217,
+    0,    0,    0, -217,    0,    0,    0,    0,   56,    0,
+ -272,    0, -212,    0,   14,    0,    0,    0,    0,    0,
+    0, -252,
+  };
+  protected static  short [] yyGindex = {            0,
+    0,    2,   -4,   30,    0,
+  };
+  protected static  short [] yyTable = {            22,
+   13,   15,   20,   14,   23,   17,   22,   18,   19,   21,
+   22,   11,   11,   18,    1,    2,    3,    4,   11,   23,
+    5,   34,   11,   24,   25,   33,   23,    6,   35,   39,
+   36,    7,   44,   37,   45,   38,   47,   48,    8,   40,
+   26,   27,    9,   10,   11,   12,    2,   29,   49,   30,
+   52,   31,   50,   26,   27,    3,   51,   28,   26,   27,
+   29,   20,   30,   46,   31,   29,   21,   30,   32,   31,
+   26,   27,    0,   11,   11,    0,    0,   29,    0,   30,
+   11,   31,   11,    0,   11,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   13,   13,    0,   14,   14,    0,    0,   13,
+    0,   13,   14,    0,   14,   18,   18,    0,    0,    0,
+    0,    0,   18,    0,   18,
+  };
+  protected static  short [] yyCheck = {           272,
+    0,    0,    7,    0,    9,  261,  279,    6,    7,    8,
+    9,  269,  270,    0,  261,  262,  263,  264,  276,  272,
+  267,  278,  280,  269,  270,  279,  279,  274,  261,   28,
+  261,  278,   31,  261,   33,  261,  261,  279,  285,  283,
+  269,  270,  289,  290,  291,  292,    0,  276,  272,  278,
+   49,  280,  281,  269,  270,    0,  279,  273,  269,  270,
+  276,  279,  278,   34,  280,  276,  279,  278,  279,  280,
+  269,  270,   -1,  269,  270,   -1,   -1,  276,   -1,  278,
+  276,  280,  278,   -1,  280,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  272,  273,   -1,  272,  273,   -1,   -1,  279,
+   -1,  281,  279,   -1,  281,  272,  273,   -1,   -1,   -1,
+   -1,   -1,  279,   -1,  281,
+  };
+
+#line 204 "CSharpExpressionParser.jay"
+
+public CSharpExpressionParser (EvaluationContext context, string name)
+{
+	this.reader = new MyTextReader ();
+	this.current_context = context;
+
+	lexer = new Tokenizer (context, reader, name);
+}
+
+public Expression Parse (string text)
+{
+	try {
+		reader.Text = text;
+		lexer.restart ();
+		if (yacc_verbose_flag)
+			return (Expression) yyparse (lexer, new yydebug.yyDebugSimple ());
+		else
+			return (Expression) yyparse (lexer);
+	} catch (Exception e){
+		// Please do not remove this, it is used during debugging
+		// of the grammar
+		//
+// 		current_context.Error (lexer.location + "  : Parsing error ");
+// 		current_context.Error (e.ToString ());
+		return null;
+	}
+}
+
+/* end end end */
+}
+#line default
+namespace yydebug {
+        using System;
+	 internal interface yyDebug {
+		 void push (int state, Object value);
+		 void lex (int state, int token, string name, Object value);
+		 void shift (int from, int to, int errorFlag);
+		 void pop (int state);
+		 void discard (int state, int token, string name, Object value);
+		 void reduce (int from, int to, int rule, string text, int len);
+		 void shift (int from, int to);
+		 void accept (Object value);
+		 void error (string message);
+		 void reject ();
+	 }
+	 
+	 class yyDebugSimple : yyDebug {
+		 void println (string s){
+			 Console.WriteLine (s);
+		 }
+		 
+		 public void push (int state, Object value) {
+			 println ("push\tstate "+state+"\tvalue "+value);
+		 }
+		 
+		 public void lex (int state, int token, string name, Object value) {
+			 println("lex\tstate "+state+"\treading "+name+"\tvalue "+value);
+		 }
+		 
+		 public void shift (int from, int to, int errorFlag) {
+			 switch (errorFlag) {
+			 default:				// normally
+				 println("shift\tfrom state "+from+" to "+to);
+				 break;
+			 case 0: case 1: case 2:		// in error recovery
+				 println("shift\tfrom state "+from+" to "+to
+					     +"\t"+errorFlag+" left to recover");
+				 break;
+			 case 3:				// normally
+				 println("shift\tfrom state "+from+" to "+to+"\ton error");
+				 break;
+			 }
+		 }
+		 
+		 public void pop (int state) {
+			 println("pop\tstate "+state+"\ton error");
+		 }
+		 
+		 public void discard (int state, int token, string name, Object value) {
+			 println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value);
+		 }
+		 
+		 public void reduce (int from, int to, int rule, string text, int len) {
+			 println("reduce\tstate "+from+"\tuncover "+to
+				     +"\trule ("+rule+") "+text);
+		 }
+		 
+		 public void shift (int from, int to) {
+			 println("goto\tfrom state "+from+" to "+to);
+		 }
+		 
+		 public void accept (Object value) {
+			 println("accept\tvalue "+value);
+		 }
+		 
+		 public void error (string message) {
+			 println("error\t"+message);
+		 }
+		 
+		 public void reject () {
+			 println("reject");
+		 }
+		 
+	 }
+}
+// %token constants
+ class Token {
+  public const int QUIT = 257;
+  public const int EOF = 258;
+  public const int NONE = 259;
+  public const int ERROR = 260;
+  public const int IDENTIFIER = 261;
+  public const int INTEGER = 262;
+  public const int NUMBER = 263;
+  public const int STRING = 264;
+  public const int HASH = 265;
+  public const int AT = 266;
+  public const int PERCENT = 267;
+  public const int DOLLAR = 268;
+  public const int DOT = 269;
+  public const int DOTDOT = 270;
+  public const int BANG = 271;
+  public const int COMMA = 272;
+  public const int ASSIGN = 273;
+  public const int STAR = 274;
+  public const int PLUS = 275;
+  public const int MINUS = 276;
+  public const int DIV = 277;
+  public const int OPEN_PARENS = 278;
+  public const int CLOSE_PARENS = 279;
+  public const int OPEN_BRACKET = 280;
+  public const int CLOSE_BRACKET = 281;
+  public const int OP_LT = 282;
+  public const int OP_GT = 283;
+  public const int COLON = 284;
+  public const int AMPERSAND = 285;
+  public const int LENGTH = 286;
+  public const int LOWER = 287;
+  public const int UPPER = 288;
+  public const int NEW = 289;
+  public const int THIS = 290;
+  public const int BASE = 291;
+  public const int CATCH = 292;
+  public const int yyErrorCode = 256;
+ }
+ namespace yyParser {
+  using System;
+  /** thrown for irrecoverable syntax errors and stack overflow.
+    */
+  internal class yyException : System.Exception {
+    public yyException (string message) : base (message) {
+    }
+  }
+
+  /** must be implemented by a scanner object to supply input to the parser.
+    */
+  internal interface yyInput {
+    /** move on to next token.
+        @return false if positioned beyond tokens.
+        @throws IOException on input error.
+      */
+    bool advance (); // throws java.io.IOException;
+    /** classifies current token.
+        Should not be called if advance() returned false.
+        @return current %token or single character.
+      */
+    int token ();
+    /** associated with current token.
+        Should not be called if advance() returned false.
+        @return value for token().
+      */
+    Object value ();
+  }
+ }
+#endif
+} // close outermost namespace, that MUST HAVE BEEN opened in the prolog

Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,235 @@
+%{
+using System.Text;
+using System.IO;
+using System.Collections;
+using System;
+
+namespace Debugger.Frontend
+{
+#if NET_2_0
+	public class CSharpExpressionParser
+	{
+		EvaluationContext current_context;
+		MyTextReader reader;
+		Tokenizer lexer;
+
+		protected bool yacc_verbose_flag = false;
+
+		public bool Verbose {
+			set {
+				yacc_verbose_flag = value;
+			}
+
+			get {
+				return yacc_verbose_flag;
+			}
+		}
+
+%}
+
+%token QUIT
+%token EOF
+%token NONE	// This token is never returned by our lexer
+%token ERROR	// This is used not by the parser, but by the tokenizer.
+		// do not remove.
+
+%token IDENTIFIER
+%token INTEGER
+%token NUMBER
+%token STRING
+%token HASH
+%token AT
+%token PERCENT
+%token DOLLAR
+%token DOT
+%token DOTDOT
+%token BANG
+%token COMMA
+%token ASSIGN
+%token STAR
+%token PLUS
+%token MINUS
+%token DIV
+%token OPEN_PARENS
+%token CLOSE_PARENS
+%token OPEN_BRACKET
+%token CLOSE_BRACKET
+%token OP_LT
+%token OP_GT
+%token COLON
+%token AMPERSAND
+
+%token LENGTH
+%token LOWER
+%token UPPER
+
+%token NEW
+%token THIS
+%token BASE
+%token CATCH
+
+%start parse_expression
+%%
+
+parse_expression
+	: primary_expression
+	  {
+		return $1;
+	  }
+	;
+
+primary_expression
+	: expression
+	| expression ASSIGN expression
+	  {
+		$$ = new AssignmentExpression ((Expression) $1, (Expression) $3);
+	  }
+	;	
+
+expression
+	: NUMBER
+	  {
+		$$ = new NumberExpression ((long) $1);
+	  }
+	| INTEGER
+	  {
+		$$ = new NumberExpression ((int) $1);
+	  }
+	| STRING
+	  {
+		$$ = new StringExpression ((string) $1);
+	  }
+	| THIS
+	  {
+		$$ = new ThisExpression ();
+	  }
+	| CATCH
+	  {
+//		$$ = new CatchExpression ();
+	  }
+	| BASE DOTDOT IDENTIFIER
+	  {
+		$$ = new MemberAccessExpression (new BaseExpression (), "." + ((string) $3));
+	  }
+	| BASE DOT IDENTIFIER
+	  {
+		$$ = new MemberAccessExpression (new BaseExpression (), (string) $3);
+	  }
+	| variable_or_type_name
+	| PERCENT IDENTIFIER
+	  {
+//		$$ = new RegisterExpression ((string) $2, 0);
+	  }
+	| STAR expression
+	  {
+		$$ = new PointerDereferenceExpression ((Expression) $2, false);
+	  }
+	| AMPERSAND expression
+	  {
+		$$ = new AddressOfExpression ((Expression) $2);
+	  }
+	| expression OPEN_BRACKET expression CLOSE_BRACKET
+	  {
+		$$ = new ArrayAccessExpression ((Expression) $1, (Expression) $3);
+	  }
+	| expression OPEN_PARENS argument_list CLOSE_PARENS
+	  {
+		$$ = new InvocationExpression ((Expression) $1, ((Expression []) $3));
+	  }
+	| NEW variable_or_type_name OPEN_PARENS argument_list CLOSE_PARENS
+	  {
+		$$ = new NewExpression ((Expression) $2, ((Expression []) $4));
+	  }
+	| OPEN_PARENS variable_or_type_name CLOSE_PARENS expression
+	  {
+		$$ = new CastExpression ((Expression) $2, (Expression) $4);
+	  }
+	| OPEN_PARENS expression CLOSE_PARENS
+	  {
+		$$ = $2;
+	  }
+	;
+
+argument_list
+	: /* empty */
+	  {
+		$$ = new Expression [0];
+	  }
+	| argument_list_0
+	  {
+		Expression[] args = new Expression [((ArrayList) $1).Count];
+		((ArrayList) $1).CopyTo (args, 0);
+
+		$$ = args;
+	  }
+	;
+
+argument_list_0
+	: expression
+	  {
+		ArrayList args = new ArrayList ();
+		args.Add ($1);
+
+		$$ = args;
+	  }
+	| argument_list_0 COMMA expression
+	  {
+		ArrayList args = (ArrayList) $1;
+		args.Add ($3);
+
+		$$ = args;
+	  }
+	;
+
+variable_or_type_name
+	: IDENTIFIER
+	  {
+		$$ = new SimpleNameExpression ((string) $1);
+	  }
+	| expression DOT IDENTIFIER
+	  { 
+		$$ = new MemberAccessExpression ((Expression) $1, (string) $3);
+	  }
+	| expression DOTDOT IDENTIFIER
+	  { 
+		$$ = new MemberAccessExpression ((Expression) $1, "." + (string) $3);
+	  }
+	| expression MINUS OP_GT IDENTIFIER
+	  {
+		Expression expr = new PointerDereferenceExpression ((Expression) $1, true);
+		$$ = new MemberAccessExpression (expr, (string) $4);
+	  }
+	;
+
+%%
+
+public CSharpExpressionParser (EvaluationContext context, string name)
+{
+	this.reader = new MyTextReader ();
+	this.current_context = context;
+
+	lexer = new Tokenizer (context, reader, name);
+}
+
+public Expression Parse (string text)
+{
+	try {
+		reader.Text = text;
+		lexer.restart ();
+		if (yacc_verbose_flag)
+			return (Expression) yyparse (lexer, new yydebug.yyDebugSimple ());
+		else
+			return (Expression) yyparse (lexer);
+	} catch (Exception e){
+		// Please do not remove this, it is used during debugging
+		// of the grammar
+		//
+//		current_context.Error (lexer.location + "  : Parsing error ");
+//		current_context.Error (e.ToString ());
+		return null;
+	}
+}
+
+/* end end end */
+#endif
+}

Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,570 @@
+#if NET_2_0
+using System;
+using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using Mono.Debugger;
+
+namespace Debugger.Frontend
+{
+	public class SyntaxError : Exception
+	{
+		public SyntaxError (string message)
+			: base ("syntax error: " + message)
+		{ }
+	}
+
+	public class Tokenizer : yyParser.yyInput
+	{
+		//
+		// Class variables
+		// 
+		static Hashtable keywords;
+		static Hashtable short_keywords;
+		static System.Text.StringBuilder id_builder;
+		static System.Text.StringBuilder string_builder;
+		static System.Text.StringBuilder number_builder;
+
+		//
+		// Values for the associated token returned
+		//
+		int putback_char;
+		Object val;
+
+		//
+		// Class initializer
+		// 
+		static Tokenizer ()
+		{
+			InitTokens ();
+			id_builder = new System.Text.StringBuilder ();
+			string_builder = new System.Text.StringBuilder ();
+			number_builder = new System.Text.StringBuilder ();
+		}
+
+		static void InitTokens ()
+		{
+			keywords = new Hashtable ();
+			short_keywords = new Hashtable ();
+
+			keywords.Add ("new", Token.NEW);
+			keywords.Add ("this", Token.THIS);
+			keywords.Add ("base", Token.BASE);
+			keywords.Add ("catch", Token.CATCH);
+		}
+
+		EvaluationContext context;
+		TextReader reader;
+		string ref_name;
+		int current_token;
+		int col = 1;
+
+		//
+		// Whether tokens have been seen on this line
+		//
+		bool tokens_seen = false;
+
+		//
+		// Details about the error encoutered by the tokenizer
+		//
+		string error_details;
+		
+		public string error {
+			get {
+				return error_details;
+			}
+		}
+
+		public Tokenizer (EvaluationContext context, TextReader reader, string name)
+		{
+			this.context = context;
+			this.reader = reader;
+			this.ref_name = name;
+		}
+
+		public void restart ()
+		{
+			tokens_seen = false;
+			col = 1;
+		}
+
+		//
+		// Accepts exactly count (4 or 8) hex, no more no less
+		//
+		int getHex (int count, out bool error)
+		{
+			int i;
+			int total = 0;
+			int c;
+			int top = count != -1 ? count : 4;
+			
+			getChar ();
+			error = false;
+			for (i = 0; i < top; i++){
+				c = getChar ();
+				
+				if (c >= '0' && c <= '9')
+					c = (int) c - (int) '0';
+				else if (c >= 'A' && c <= 'F')
+					c = (int) c - (int) 'A' + 10;
+				else if (c >= 'a' && c <= 'f')
+					c = (int) c - (int) 'a' + 10;
+				else {
+					error = true;
+					return 0;
+				}
+				
+				total = (total * 16) + c;
+				if (count == -1){
+					int p = peekChar ();
+					if (p == -1)
+						break;
+					if (!is_hex ((char)p))
+						break;
+				}
+			}
+			return total;
+		}
+
+		int escape (int c)
+		{
+			bool error;
+			int d;
+			int v;
+
+			d = peekChar ();
+			if (c != '\\')
+				return c;
+			
+			switch (d){
+			case 'a':
+				v = '\a'; break;
+			case 'b':
+				v = '\b'; break;
+			case 'n':
+				v = '\n'; break;
+			case 't':
+				v = '\t'; break;
+			case 'v':
+				v = '\v'; break;
+			case 'r':
+				v = '\r'; break;
+			case '\\':
+				v = '\\'; break;
+			case 'f':
+				v = '\f'; break;
+			case '0':
+				v = 0; break;
+			case '"':
+				v = '"'; break;
+			case '\'':
+				v = '\''; break;
+			case 'x':
+				v = getHex (-1, out error);
+				if (error)
+					goto default;
+				return v;
+			case 'u':
+				v = getHex (4, out error);
+				if (error)
+					goto default;
+				return v;
+			case 'U':
+				v = getHex (8, out error);
+				if (error)
+					goto default;
+				return v;
+			default:
+// 				context.Error ("Unrecognized escape sequence in " + (char)d);
+				return d;
+			}
+			getChar ();
+			return v;
+		}
+
+		int getChar ()
+		{
+			if (putback_char != -1){
+				int x = putback_char;
+				putback_char = -1;
+
+				return x;
+			}
+			return reader.Read ();
+		}
+
+		int peekChar ()
+		{
+			if (putback_char != -1)
+				return putback_char;
+			return reader.Peek ();
+		}
+
+		void putback (int c)
+		{
+			if (putback_char != -1)
+				throw new Exception ("This should not happen putback on putback");
+			putback_char = c;
+		}
+
+		public bool advance ()
+		{
+			return peekChar () >= 0;
+		}
+
+		bool is_identifier_start_character (char c)
+		{
+			return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || Char.IsLetter (c);
+		}
+
+		bool is_identifier_part_character (char c)
+		{
+			return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || Char.IsLetter (c);
+		}
+
+		int GetKeyword (string name, bool tokens_seen)
+		{
+			object o = keywords [name];
+
+			if (o != null)
+				return (int) o;
+
+			if (tokens_seen)
+				return -1;
+
+			o = short_keywords [name];
+			if (o != null)
+				return (int) o;
+
+			return -1;
+		}
+
+		//
+		// Invoked if we know we have .digits or digits
+		//
+		int is_number (int c)
+		{
+			number_builder.Length = 0;
+
+			if (c >= '0' && c <= '9'){
+				if (c == '0' && peekChar () == 'x' || peekChar () == 'X'){
+					getChar ();
+					hex_digits (-1);
+
+					string s = number_builder.ToString ();
+
+					val = (long) System.UInt64.Parse (s, NumberStyles.HexNumber);
+					return Token.NUMBER;
+				}
+				decimal_digits (c);
+
+				val = (int) System.UInt32.Parse (number_builder.ToString ());
+				return Token.INTEGER;
+			}
+
+			throw new Exception ("Is Number should never reach this point");
+		}
+
+		bool decimal_digits (int c)
+		{
+			int d;
+			bool seen_digits = false;
+			
+			if (c != -1)
+				number_builder.Append ((char) c);
+			
+			while ((d = peekChar ()) != -1){
+				if (d >= '0' && d <= '9'){
+					number_builder.Append ((char) d);
+					getChar ();
+					seen_digits = true;
+				} else
+					break;
+			}
+			
+			return seen_digits;
+		}
+
+		bool is_hex (int e)
+		{
+			return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
+		}
+		
+		void hex_digits (int c)
+		{
+			int d;
+
+			if (c != -1)
+				number_builder.Append ((char) c);
+			while ((d = peekChar ()) != -1){
+				if (is_hex (d)){
+					number_builder.Append ((char) d);
+					getChar ();
+				} else
+					break;
+			}
+		}
+
+		private int consume_identifier (int c, bool quoted) 
+		{
+			bool old_tokens_seen = tokens_seen;
+			tokens_seen = true;
+
+			id_builder.Length = 0;
+
+			id_builder.Append ((char) c);
+					
+			while ((c = peekChar ()) != -1) {
+				if (is_identifier_part_character ((char) c)){
+					id_builder.Append ((char)getChar ());
+					col++;
+				} else 
+					break;
+			}
+
+			string ids = id_builder.ToString ();
+			int keyword = GetKeyword (ids, old_tokens_seen);
+
+			if (keyword == -1 || quoted){
+				val = ids;
+				if (ids.Length > 512){
+// 					context.Error ("Identifier too long (limit is 512 chars)");
+				}
+				return Token.IDENTIFIER;
+			}
+
+			return keyword;
+		}
+
+		private int consume_string (bool quoted) 
+		{
+			int c;
+			string_builder.Length = 0;
+								
+			while ((c = getChar ()) != -1){
+				if (c == '"'){
+					if (quoted && peekChar () == '"'){
+						string_builder.Append ((char) c);
+						getChar ();
+						continue;
+					} else {
+						val = string_builder.ToString ();
+						return Token.STRING;
+					}
+				}
+
+				if (c == '\n'){
+// 					if (!quoted)
+// 						context.Error ("Newline in constant");
+					col = 0;
+				} else
+					col++;
+
+				if (!quoted){
+					c = escape (c);
+					if (c == -1)
+						return Token.ERROR;
+				}
+				string_builder.Append ((char) c);
+			}
+
+// 			context.Error ("Unterminated string literal");
+			return Token.EOF;
+		}
+
+		private int consume_quoted_identifier ()
+		{
+			int c;
+
+			id_builder.Length = 0;
+								
+			while ((c = getChar ()) != -1){
+				if (c == '\''){
+					val = id_builder.ToString ();
+					return Token.IDENTIFIER;
+				}
+
+				if (c == '\n')
+					col = 0;
+				else
+					col++;
+
+				id_builder.Append ((char) c);
+			}
+
+// 			context.Error ("Unterminated quoted identifier");
+			return Token.EOF;
+		}
+
+		private string consume_help ()
+		{
+			int c;
+			StringBuilder sb = new StringBuilder ();
+								
+			while ((c = getChar ()) != -1){
+				if (c == '\n') {
+					col = 0;
+					return sb.ToString ();
+				}
+
+				col++;
+				sb.Append ((char) c);
+			}
+
+			return sb.ToString ();
+		}
+
+		public int xtoken ()
+		{
+			int c;
+
+			val = null;
+			// optimization: eliminate col and implement #directive semantic correctly.
+			for (;(c = getChar ()) != -1; col++) {
+				if (is_identifier_start_character ((char)c))
+					return consume_identifier (c, false);
+
+				if (c == 0)
+					continue;
+				else if (c == '#')
+					return Token.HASH;
+				else if (c == '@')
+					return Token.AT;
+				else if (c == '%')
+					return Token.PERCENT;
+				else if (c == '$')
+					return Token.DOLLAR;
+				else if (c == '.')
+					if ((c = peekChar ()) == '.') {
+						getChar ();
+						return Token.DOTDOT;
+					}
+					else {
+						return Token.DOT;
+					}
+				else if (c == '!')
+					return Token.BANG;
+				else if (c == '=')
+					return Token.ASSIGN;
+				else if (c == '*')
+					return Token.STAR;
+				else if (c == '+')
+					return Token.PLUS;
+				else if (c == '-') // FIXME: negative numbers...
+					return Token.MINUS;
+				else if (c == '/')
+					return Token.DIV;
+				else if (c == '(')
+					return Token.OPEN_PARENS;
+				else if (c == ')')
+					return Token.CLOSE_PARENS;
+				else if (c == '[')
+					return Token.OPEN_BRACKET;
+				else if (c == ']')
+					return Token.CLOSE_BRACKET;
+				else if (c == ',')
+					return Token.COMMA;
+				else if (c == '<')
+					return Token.OP_LT;
+				else if (c == '>')
+					return Token.OP_GT;
+				else if (c == ':')
+					return Token.COLON;
+				else if (c == '&')
+					return Token.AMPERSAND;
+
+				if (c >= '0' && c <= '9') {
+					tokens_seen = true;
+					return is_number (c);
+				}
+
+				if (c == '"')
+					return consume_string (false);
+
+				if (c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r' || c == '\n'){
+					if (current_token == Token.HASH) {
+ 						error_details = "No whitespace allowed after `#'";
+						return Token.ERROR;
+					} else if (current_token == Token.AT) {
+						error_details = "No whitespace allowed after `@'";
+						return Token.ERROR;
+					}
+
+					if (c == '\t')
+						col = (((col + 8) / 8) * 8) - 1;
+					continue;
+				}
+
+				if (c == '\'')
+					return consume_quoted_identifier ();
+
+				error_details = "Unknown character `" + (char) c + "'";
+				return Token.ERROR;
+			}
+
+			return Token.EOF;
+		}
+
+		public int token ()
+		{
+			current_token = xtoken ();
+			return current_token;
+		}
+
+		public Object value ()
+		{
+			return val;
+		}
+
+		static Hashtable tokenValues;
+		
+		private static Hashtable TokenValueName
+		{
+			get {
+				if (tokenValues == null)
+					tokenValues = GetTokenValueNameHash ();
+
+				return tokenValues;
+			}
+		}
+
+		private static Hashtable GetTokenValueNameHash ()
+		{
+			Type t = typeof (Token);
+			FieldInfo [] fields = t.GetFields ();
+			Hashtable hash = new Hashtable ();
+			foreach (FieldInfo field in fields) {
+				if (field.IsLiteral && field.IsStatic && field.FieldType == typeof (int))
+					hash.Add (field.GetValue (null), field.Name);
+			}
+			return hash;
+		}
+
+		//
+		// Returns a verbose representation of the current location
+		//
+		public string location {
+			get {
+				string det;
+
+				if (current_token == Token.ERROR)
+					det = "detail: " + error_details;
+				else
+					det = "";
+				
+				// return "Line:     "+line+" Col: "+col + "\n" +
+				//       "VirtLine: "+ref_line +
+				//       " Token: "+current_token + " " + det;
+				string current_token_name = TokenValueName [current_token] as string;
+				if (current_token_name == null)
+					current_token_name = current_token.ToString ();
+
+				return String.Format ("{0}, Token: {1} {2}", ref_name,
+						      current_token_name, det);
+			}
+		}
+	}
+}
+#endif

Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog	2005-03-01 23:58:20 UTC (rev 2282)
@@ -1,3 +1,31 @@
+2005-03-01  Chris Toshok  <toshok at ximian.com>
+
+	* Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_member):
+	strip out the part of add_struct that adds individual fields and
+	implement all the DebuggerBrowsableAttribute handling.
+	(DebuggerVariablePad.add_struct): display both fields and
+	properties.
+	(DebuggerVariablePad.GetDebuggerBrowsableAttribute): returns the
+	first DebuggerBrowsable attribute for a given ITargetMemberInfo,
+	if there are any.
+	(DebuggerVariablePad.GetDebuggerDisplayAttribute): returns the
+	first DebuggerDisplay attribute for a given ITargetObject, if
+	there are any.
+	(DebuggerVariablePad.EvaluateDebuggerDisplay): given the
+	DebuggerDisplay attribute's value, evaluate any nested
+	{expressions} and convert them all to strings.
+	(DebuggerVariablePad.add_object): if it's a struct or class, add
+	the DebuggerDisplay if there is one.
+
+	* DebuggingService.cs (MainThread): add a getter for this, so we
+	can grab a thread with which to evaluate expressions in
+	DebuggerDisplayAttributes.
+
+	* Makefile.am (FILES): add stripped down files from the debugger
+	source - EvaluationContext.cs (formerly ScriptingContext),
+	Expression.cs, MyTextReader.cs, CSharpTokenizer.cs, and
+	CSharpExpressionParser.cs.
+
 2005-02-25  Chris Toshok  <toshok at ximian.com>
 
 	* Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_data): fix

Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -323,12 +323,20 @@
 			}
 		}
 
+#if NET_2_0
+		public Process MainThread {
+			get {
+				return proc;
+			}
+		}
+#endif
+
 		public Process[] Threads {
-		  get {
+			get {
 				Process[] retval = new Process [procs.Count];
 				procs.Values.CopyTo (retval, 0);
 				return retval;
-		  }
+			}
 		}
 
 		public object CurrentFrame {

Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,251 @@
+#if NET_2_0
+using System;
+using System.Collections;
+using Mono.Debugger;
+using Mono.Debugger.Languages;
+
+namespace Debugger.Frontend {
+
+	public class FrameHandle
+	{
+		StackFrame frame;
+
+		public FrameHandle (StackFrame frame)
+		{
+			this.frame = frame;
+		}
+
+		public StackFrame Frame {
+			get { return frame; }
+		}
+
+		public ILanguage Language {
+			get {
+				if (frame.Language == null)
+					throw new EvaluationException (
+						"Stack frame has no source language.");
+
+				return frame.Language;
+			}
+		}
+	}
+
+	public class BacktraceHandle
+	{
+		FrameHandle[] frames;
+
+		public BacktraceHandle (ProcessHandle process, Backtrace backtrace)
+		{
+			StackFrame[] bt_frames = backtrace.Frames;
+			if (bt_frames != null) {
+				frames = new FrameHandle [bt_frames.Length];
+				for (int i = 0; i < frames.Length; i++)
+					frames [i] = new FrameHandle (bt_frames [i]);
+			} else
+				frames = new FrameHandle [0];
+		}
+
+		public int Length {
+			get { return frames.Length; }
+		}
+
+		public FrameHandle this [int number] {
+			get { return frames [number]; }
+		}
+	}
+
+	public class ProcessHandle
+	{
+		ThreadGroup tgroup;
+		Process process;
+		string name;
+		int id;
+
+		public ProcessHandle (Process process)
+		{
+			this.process = process;
+			this.name = process.Name;
+			this.id = process.ID;
+		}
+
+
+		public ProcessHandle (Process process, int pid)
+			: this (process)
+		{
+			if (process.HasTarget) {
+				if (!process.IsDaemon) {
+					StackFrame frame = process.CurrentFrame;
+					current_frame = new FrameHandle (frame);
+				}
+			}
+		}
+
+		public Process Process {
+			get { return process; }
+		}
+
+		public ThreadGroup ThreadGroup {
+			get { return tgroup; }
+		}
+
+		BacktraceHandle current_backtrace = null;
+
+		int current_frame_idx = -1;
+		FrameHandle current_frame = null;
+		AssemblerLine current_insn = null;
+
+		public int CurrentFrameIndex {
+			get {
+				if (current_frame_idx == -1)
+					return 0;
+
+				return current_frame_idx;
+			}
+
+			set {
+				GetBacktrace (-1);
+				if ((value < 0) || (value >= current_backtrace.Length))
+					throw new EvaluationException ("No such frame.");
+
+				current_frame_idx = value;
+				current_frame = current_backtrace [current_frame_idx];
+			}
+		}
+
+
+		public BacktraceHandle GetBacktrace (int max_frames)
+		{
+			if (State == TargetState.NO_TARGET)
+				throw new EvaluationException ("No stack.");
+			else if (!process.IsStopped)
+				throw new EvaluationException ("{0} is not stopped.", Name);
+
+			if ((max_frames == -1) && (current_backtrace != null))
+				return current_backtrace;
+
+			current_backtrace = new BacktraceHandle (this, process.GetBacktrace (max_frames));
+
+			if (current_backtrace == null)
+				throw new EvaluationException ("No stack.");
+
+			return current_backtrace;
+		}
+
+		public FrameHandle CurrentFrame {
+			get {
+				return GetFrame (current_frame_idx);
+			}
+		}
+
+		public FrameHandle GetFrame (int number)
+		{
+			if (State == TargetState.NO_TARGET)
+				throw new EvaluationException ("No stack.");
+			else if (!process.IsStopped)
+				throw new EvaluationException ("{0} is not stopped.", Name);
+
+			if (number == -1) {
+				if (current_frame == null)
+					current_frame = new FrameHandle (process.CurrentFrame);
+
+				return current_frame;
+			}
+
+			GetBacktrace (-1);
+			if (number >= current_backtrace.Length)
+				throw new EvaluationException ("No such frame: {0}", number);
+
+			return current_backtrace [number];
+		}
+
+		public TargetState State {
+			get {
+				if (process == null)
+					return TargetState.NO_TARGET;
+				else
+					return process.State;
+			}
+		}
+
+		public string Name {
+			get {
+				return name;
+			}
+		}
+	}
+
+	public class EvaluationException : Exception
+	{
+		public EvaluationException (string format, params object[] args)
+			: base (String.Format (format, args))
+		{ }
+	}
+
+	public class EvaluationContext
+	{
+		ProcessHandle current_process;
+		int current_frame_idx = -1;
+		ITargetObject this_obj;
+
+		static AddressDomain address_domain = new AddressDomain ("Evaluation");
+
+		public EvaluationContext (ITargetObject this_obj)
+		{
+			this.this_obj = this_obj;
+		}
+
+		public ITargetObject This {
+			get {
+				return this_obj;
+			}
+		}
+
+		public ProcessHandle CurrentProcess {
+			get { return current_process; }
+			set { current_process = value; }
+		}
+
+		public FrameHandle CurrentFrame {
+			get {
+				return current_process.GetFrame (current_frame_idx);
+			}
+		}
+
+		public int CurrentFrameIndex {
+			get {
+				return current_frame_idx;
+			}
+
+			set {
+				current_frame_idx = value;
+			}
+		}
+
+		public string[] GetNamespaces (FrameHandle frame)
+		{
+			IMethod method = frame.Frame.Method;
+			if ((method == null) || !method.HasSource)
+				return null;
+
+			MethodSource msource = method.Source;
+			if (msource.IsDynamic)
+				return null;
+
+			return msource.GetNamespaces ();
+		}
+
+		public string[] GetNamespaces ()
+		{
+			return GetNamespaces (CurrentFrame);
+		}
+
+		public AddressDomain AddressDomain {
+			get {
+				return address_domain;
+			}
+		}
+
+	}
+
+}
+#endif

Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,1604 @@
+#if NET_2_0
+using System;
+using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using Mono.Debugger;
+using Mono.Debugger.Languages;
+
+namespace Debugger.Frontend
+{
+	public enum LocationType
+	{
+		Method,
+		PropertyGetter,
+		PropertySetter,
+		EventAdd,
+		EventRemove
+	}
+
+	public abstract class Expression
+	{
+		public abstract string Name {
+			get;
+		}
+
+		protected bool resolved;
+
+		protected virtual ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			return EvaluateVariable (context).TypeInfo.Type;
+		}
+
+		public ITargetType EvaluateType (EvaluationContext context)
+		{
+			if (!resolved)
+				throw new InvalidOperationException (
+					String.Format (
+						"Some clown tried to evaluate the " +
+						"unresolved expression `{0}'", Name));
+
+			try {
+				ITargetType type = DoEvaluateType (context);
+				if (type == null)
+					throw new EvaluationException (
+						"Cannot get type of expression `{0}'", Name);
+
+				return type;
+			} catch (LocationInvalidException ex) {
+				throw new EvaluationException (
+					"Location of variable `{0}' is invalid: {1}",
+					Name, ex.Message);
+			}
+		}
+
+		protected virtual object DoEvaluate (EvaluationContext context)
+		{
+			return DoEvaluateVariable (context);
+		}
+
+		public object Evaluate (EvaluationContext context)
+		{
+			if (!resolved)
+				throw new InvalidOperationException (
+					String.Format (
+						"Some clown tried to evaluate the " +
+						"unresolved expression `{0}'", Name));
+
+			object result = DoEvaluate (context);
+			if (result == null)
+				throw new EvaluationException (
+					"Cannot evaluate expression `{0}'", Name);
+
+			return result;
+		}
+
+		protected virtual ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			return null;
+		}
+
+		public ITargetObject EvaluateVariable (EvaluationContext context)
+		{
+			if (!resolved)
+				throw new InvalidOperationException (
+					String.Format (
+						"Some clown tried to evaluate the " +
+						"unresolved expression `{0}' ({1})", Name,
+						GetType ()));
+
+			try {
+				ITargetObject retval = DoEvaluateVariable (context);
+				if (retval == null)
+					throw new EvaluationException (
+						"Expression `{0}' is not a variable", Name);
+
+				return retval;
+			} catch (LocationInvalidException ex) {
+				throw new EvaluationException (
+					"Location of variable `{0}' is invalid: {1}",
+					Name, ex.Message);
+			}
+		}
+
+		protected virtual SourceLocation DoEvaluateLocation (EvaluationContext context,
+								     LocationType type, Expression[] types)
+		{
+			return null;
+		}
+
+		public SourceLocation EvaluateLocation (EvaluationContext context, LocationType type,
+							Expression [] types)
+		{
+			if (!resolved)
+				throw new InvalidOperationException (
+					String.Format (
+						"Some clown tried to evaluate the " +
+						"unresolved expression `{0}'", Name));
+
+			try {
+				SourceLocation location = DoEvaluateLocation (context, type, types);
+				if (location == null)
+					throw new EvaluationException (
+						"Expression `{0}' is not a method", Name);
+
+				return location;
+			} catch (LocationInvalidException ex) {
+				throw new EvaluationException (
+					"Location of variable `{0}' is invalid: {1}",
+					Name, ex.Message);
+			}
+		}
+
+		protected virtual bool DoAssign (EvaluationContext context, ITargetObject obj)
+		{
+			return false;
+		}
+
+		public void Assign (EvaluationContext context, ITargetObject obj)
+		{
+			if (!resolved)
+				throw new InvalidOperationException (
+					String.Format (
+						"Some clown tried to evaluate the " +
+						"unresolved expression `{0}'", Name));
+
+			bool ok = DoAssign (context, obj);
+			if (!ok)
+				throw new EvaluationException (
+					"Expression `{0}' is not an lvalue", Name);
+		}
+
+		protected virtual Expression DoResolveType (EvaluationContext context)
+		{
+			return null;
+		}
+
+		public Expression ResolveType (EvaluationContext context)
+		{
+			Expression expr = DoResolveType (context);
+			if (expr == null)
+				throw new EvaluationException (
+					"Expression `{0}' is not a type.", Name);
+
+			return expr;
+		}
+
+		public Expression TryResolveType (EvaluationContext context)
+		{
+			try {
+				return DoResolveType (context);
+			} catch (EvaluationException) {
+				return null;
+			} catch (Mono.Debugger.TargetException) {
+				return null;
+			}
+		}
+
+		protected abstract Expression DoResolve (EvaluationContext context);
+
+		public Expression Resolve (EvaluationContext context)
+		{
+			Expression expr = DoResolve (context);
+			if (expr == null)
+				throw new EvaluationException (
+					"Expression `{0}' is not a variable or value.", Name);
+
+			return expr;
+		}
+
+		public Expression TryResolve (EvaluationContext context)
+		{
+			try {
+				return DoResolve (context);
+			} catch (EvaluationException) {
+				return null;
+			} catch (Mono.Debugger.TargetException) {
+				return null;
+			}
+		}
+
+		public override string ToString ()
+		{
+			return String.Format ("{0} ({1})", GetType (), Name);
+		}
+	}
+
+	public class NumberExpression : PointerExpression
+	{
+		object val;
+
+		public NumberExpression (int val)
+		{
+			this.val = val;
+		}
+
+		public NumberExpression (long val)
+		{
+			this.val = val;
+		}
+
+		public long Value {
+			get {
+				if (val is int)
+					return (long) (int) val;
+				else
+					return (long) val;
+			}
+		}
+
+		public override string Name {
+			get {
+				if (val is long)
+					return String.Format ("0x{0:x}", (long) val);
+				else
+					return val.ToString ();
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			StackFrame frame = context.CurrentFrame.Frame;
+			if ((frame.Language == null) ||
+			    !frame.Language.CanCreateInstance (val.GetType ()))
+				return null;
+
+			return frame.Language.CreateInstance (frame, val);
+		}
+
+		public override TargetLocation EvaluateAddress (EvaluationContext context)
+		{
+			TargetAddress addr = new TargetAddress (context.AddressDomain, Value);
+			return new AbsoluteTargetLocation (context.CurrentFrame.Frame, addr);
+		}
+
+		protected override object DoEvaluate (EvaluationContext context)
+		{
+			return val;
+		}
+	}
+
+	public class StringExpression : Expression
+	{
+		string val;
+
+		public StringExpression (string val)
+		{
+			this.val = val;
+		}
+
+		public override string Name {
+			get { return val; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			resolved = true;
+			return this;
+		}
+
+		protected override object DoEvaluate (EvaluationContext context)
+		{
+			return val;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			StackFrame frame = context.CurrentFrame.Frame;
+			if ((frame.Language == null) ||
+			    !frame.Language.CanCreateInstance (typeof (string)))
+				return null;
+
+			return frame.Language.CreateInstance (frame, val);
+		}
+	}
+
+	public class ThisExpression : Expression
+	{
+		public override string Name {
+			get { return "this"; }
+		}
+
+		protected FrameHandle frame;
+		protected IVariable var;
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			frame = context.CurrentFrame;
+			IMethod method = frame.Frame.Method;
+			if (method == null)
+				throw new EvaluationException (
+					"Keyword `this' not allowed: no current method.");
+
+			if (!method.HasThis)
+				throw new EvaluationException (
+					"Keyword `this' not allowed: current method is " +
+					"either static or unmanaged.");
+
+			var = method.This;
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			return context.This;
+		}
+	}
+
+	public class BaseExpression : ThisExpression
+	{
+		public override string Name {
+			get { return "base"; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			Expression expr = base.DoResolve (context);
+			if (expr == null)
+				return null;
+
+			if (var.Type.Kind != TargetObjectKind.Class)
+				throw new EvaluationException (
+					"`base' is only allowed in a class.");
+			if (!((ITargetClassType) var.Type).HasParent)
+				throw new EvaluationException (
+					"Current class has no base class.");
+
+			return expr;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			return ((ITargetClassObject) base.DoEvaluateVariable (context)).Parent;
+		}
+	}
+
+	public class TypeExpression : Expression
+	{
+		ITargetType type;
+
+		public TypeExpression (ITargetType type)
+		{
+			this.type = type;
+			resolved = true;
+		}
+
+		public override string Name {
+			get { return type.Name; }
+		}
+
+		protected override Expression DoResolveType (EvaluationContext context)
+		{
+			return this;
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			return this;
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			return type;
+		}
+
+		protected override object DoEvaluate (EvaluationContext context)
+		{
+			return type;
+		}
+	}
+
+	public class SourceExpression : Expression
+	{
+		SourceLocation location;
+
+		public SourceExpression (SourceLocation location)
+		{
+			this.location = location;
+			resolved = true;
+		}
+
+		public override string Name {
+			get { return location.Name; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			resolved = true;
+			return this;
+		}
+
+		protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+								      LocationType type, Expression[] types)
+		{
+			if (types != null)
+				return null;
+
+			return location;
+		}
+	}
+
+	public class SimpleNameExpression : Expression
+	{
+		string name;
+
+		public SimpleNameExpression (string name)
+		{
+			this.name = name;
+		}
+
+		public override string Name {
+			get { return name; }
+		}
+
+                public static string MakeFQN (string nsn, string name)
+                {
+                        if (nsn == "")
+                                return name;
+                        return String.Concat (nsn, ".", name);
+                }
+
+		Expression LookupMember (EvaluationContext context, FrameHandle frame,
+					 string full_name)
+		{
+			return StructAccessExpression.FindMember (
+				context.This.TypeInfo.Type as ITargetStructType, frame.Frame,
+				(ITargetStructObject) context.This, false, full_name);
+		}
+
+		Expression Lookup (EvaluationContext context, FrameHandle frame)
+		{
+			string[] namespaces = context.GetNamespaces (frame);
+			if (namespaces == null)
+				return null;
+
+			foreach (string ns in namespaces) {
+				string full_name = MakeFQN (ns, name);
+				Expression expr = LookupMember (context, frame, full_name);
+				if (expr != null)
+					return expr;
+			}
+
+			return null;
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			FrameHandle frame = context.CurrentFrame;
+
+			Expression expr = LookupMember (context, frame, name);
+			if (expr != null)
+				return expr;
+
+			expr = Lookup (context, frame);
+			if (expr != null)
+				return expr;
+
+// 			SourceLocation location = context.Interpreter.FindMethod (name);
+// 			if (location != null)
+// 				return new SourceExpression (location);
+
+			expr = DoResolveType (context);
+			if (expr != null)
+				return expr;
+
+			throw new EvaluationException ("No such type of method: `{0}'", Name);
+		}
+
+		protected override Expression DoResolveType (EvaluationContext context)
+		{
+			FrameHandle frame = context.CurrentFrame;
+			ITargetType type = frame.Language.LookupType (frame.Frame, name);
+			if (type != null)
+				return new TypeExpression (type);
+
+			string[] namespaces = context.GetNamespaces (frame);
+			if (namespaces == null)
+				return null;
+
+			foreach (string ns in namespaces) {
+				string full_name = MakeFQN (ns, name);
+				type = frame.Language.LookupType (frame.Frame, full_name);
+				if (type != null)
+					return new TypeExpression (type);
+			}
+
+			return null;
+		}
+	}
+
+	public class MemberAccessExpression : Expression
+	{
+		Expression left;
+		string name;
+
+		public MemberAccessExpression (Expression left, string name)
+		{
+			this.left = left;
+			this.name = name;
+		}
+
+		public override string Name {
+			get { return left.Name + "." + name; }
+		}
+
+		public Expression ResolveMemberAccess (EvaluationContext context, bool allow_instance)
+		{
+			StackFrame frame = context.CurrentFrame.Frame;
+
+			Expression expr;
+			Expression ltype = left.TryResolveType (context);
+			if (ltype != null) {
+				ITargetStructType stype = ltype.EvaluateType (context)
+					as ITargetStructType;
+				if (stype == null)
+					throw new EvaluationException (
+						"`{0}' is not a struct or class", ltype.Name);
+
+				expr = StructAccessExpression.FindMember (
+					stype, frame, null, allow_instance, name);
+				if (expr == null)
+					throw new EvaluationException (
+						"Type `{0}' has no member `{1}'",
+						stype.Name, name);
+
+				return expr;
+			}
+
+			Expression lexpr = left.TryResolve (context);
+			if (lexpr == null)
+				throw new EvaluationException (
+					"No such variable or type: `{0}'", left.Name);
+
+			ITargetStructObject sobj = lexpr.EvaluateVariable (context)
+				as ITargetStructObject;
+			if (sobj == null)
+				throw new EvaluationException (
+					"`{0}' is not a struct or class", left.Name);
+
+			expr = StructAccessExpression.FindMember (
+				sobj.Type, frame, sobj, true, name);
+			if (expr == null)
+				throw new EvaluationException (
+					"Type `{0}' has no member `{1}'",
+					sobj.Type.Name, name);
+
+			return expr;
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			return ResolveMemberAccess (context, false);
+		}
+
+		protected override Expression DoResolveType (EvaluationContext context)
+		{
+			StackFrame frame = context.CurrentFrame.Frame;
+
+			ITargetType the_type;
+
+			Expression ltype = left.TryResolveType (context);
+			if (ltype == null)
+				the_type = frame.Language.LookupType (frame, Name);
+			else {
+				string nested = ltype.Name + "+" + name;
+				the_type = frame.Language.LookupType (frame, nested);
+			}
+
+			if (the_type == null)
+				return null;
+
+			return new TypeExpression (the_type);
+		}
+	}
+
+	public class MethodGroupExpression : Expression
+	{
+		ITargetStructType stype;
+		ITargetStructObject instance;
+		ILanguage language;
+		string name;
+		ArrayList methods;
+
+		public MethodGroupExpression (ITargetStructType stype, string name,
+					      ITargetStructObject instance,
+					      ILanguage language, ArrayList methods)
+		{
+			this.stype = stype;
+			this.instance = instance;
+			this.language = language;
+			this.name = name;
+			this.methods = methods;
+			resolved = true;
+		}
+
+		public override string Name {
+			get { return stype.Name + "." + name; }
+		}
+
+		public bool IsStatic {
+			get { return instance == null; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			return this;
+		}
+
+		protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+								      LocationType type, Expression[] types)
+		{
+			try {
+				ITargetMethodInfo method = OverloadResolve (context, types);
+				return new SourceLocation (method.Type.Source);
+			} catch {
+// 				ArrayList list = new ArrayList ();
+// 				foreach (ITargetMethodInfo method in methods) {
+// 					if (method.Type.Source == null)
+// 						continue;
+// 					list.Add (method.Type.Source);
+// 				}
+// 				SourceMethod[] sources = new SourceMethod [list.Count];
+// 				list.CopyTo (sources, 0);
+// 				throw new MultipleLocationsMatchException (sources);
+			  return null;
+			}
+		}
+
+		public ITargetFunctionObject EvaluateMethod (EvaluationContext context,
+							     StackFrame frame,
+							     Expression[] arguments)
+		{
+			ITargetMethodInfo method = OverloadResolve (context, arguments);
+
+			if (method.IsStatic)
+				return stype.GetStaticMethod (frame, method.Index);
+			else if (!IsStatic)
+				return instance.GetMethod (method.Index);
+			else
+				throw new EvaluationException (
+					"Instance method {0} cannot be used in " +
+					"static context.", Name);
+		}
+
+		protected ITargetMethodInfo OverloadResolve (EvaluationContext context,
+							     Expression[] types)
+		{
+			ArrayList candidates = new ArrayList ();
+
+			foreach (ITargetMethodInfo method in methods) {
+				if ((types != null) &&
+				    (method.Type.ParameterTypes.Length != types.Length))
+					continue;
+
+				candidates.Add (method);
+			}
+
+			if (candidates.Count == 1)
+				return (ITargetMethodInfo) candidates [0];
+
+			if (candidates.Count == 0)
+				throw new EvaluationException (
+					"No overload of method `{0}' has {1} arguments.",
+					Name, types.Length);
+
+			if (types == null)
+				throw new EvaluationException (
+					"Ambiguous method `{0}'; need to use " +
+					"full name", Name);
+
+			ITargetMethodInfo match = OverloadResolve (
+				context, language, stype, types, candidates);
+
+			if (match == null)
+				throw new EvaluationException (
+					"Ambiguous method `{0}'; need to use " +
+					"full name", Name);
+
+			return match;
+		}
+
+		public static ITargetMethodInfo OverloadResolve (EvaluationContext context,
+								 ILanguage language,
+								 ITargetStructType stype,
+								 Expression[] types,
+								 ArrayList candidates)
+		{
+			// We do a very simple overload resolution here
+			ITargetType[] argtypes = new ITargetType [types.Length];
+			for (int i = 0; i < types.Length; i++)
+				argtypes [i] = types [i].EvaluateType (context);
+
+			// Ok, no we need to find an exact match.
+			ITargetMethodInfo match = null;
+			foreach (ITargetMethodInfo method in candidates) {
+				bool ok = true;
+				for (int i = 0; i < types.Length; i++) {
+					if (method.Type.ParameterTypes [i].TypeHandle != argtypes [i].TypeHandle) {
+						ok = false;
+						break;
+					}
+				}
+
+				if (!ok)
+					continue;
+
+				// We need to find exactly one match
+				if (match != null)
+					return null;
+
+				match = method;
+			}
+
+			return match;
+		}
+	}
+
+	public class TypeOfExpression : Expression
+	{
+		Expression expr;
+
+		public TypeOfExpression (Expression expr)
+		{
+			this.expr = expr;
+		}
+
+		public override string Name {
+			get { return String.Format ("typeof ({0})", expr.Name); }
+		}
+
+		protected override Expression DoResolveType (EvaluationContext context)
+		{
+			return expr.ResolveType (context);
+		}
+		
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			return expr.Resolve (context);
+		}
+	}
+
+	public abstract class PointerExpression : Expression
+	{
+		public abstract TargetLocation EvaluateAddress (EvaluationContext context);
+	}
+
+	public class StructAccessExpression : Expression
+	{
+		string name;
+
+		public readonly string Identifier;
+		public readonly bool IsStatic;
+
+		ITargetStructType Type;
+		ITargetStructObject Instance;
+		StackFrame Frame;
+
+		protected StructAccessExpression (StackFrame frame, ITargetStructType type,
+						  string identifier)
+		{
+			this.Frame = frame;
+			this.Type = type;
+			this.Identifier = identifier;
+			this.IsStatic = true;
+			resolved = true;
+		}
+
+		protected StructAccessExpression (StackFrame frame,
+						  ITargetStructObject instance,
+						  string identifier)
+		{
+			this.Frame = frame;
+			this.Type = instance.Type;
+			this.Instance = instance;
+			this.Identifier = identifier;
+			this.IsStatic = false;
+			resolved = true;
+		}
+
+		public override string Name {
+			get {
+				return Identifier;
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			return this;
+		}
+
+		protected ITargetObject GetField (ITargetStructObject sobj, ITargetFieldInfo field)
+		{
+			try {
+				return sobj.GetField (field.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get field {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetStaticField (ITargetStructType stype, StackFrame frame, ITargetFieldInfo field)
+		{
+			try {
+				return stype.GetStaticField (frame, field.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get field {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetProperty (ITargetStructObject sobj, ITargetPropertyInfo property)
+		{
+			try {
+				return sobj.GetProperty (property.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get property {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetStaticProperty (ITargetStructType stype, StackFrame frame, ITargetPropertyInfo property)
+		{
+			try {
+				return stype.GetStaticProperty (frame, property.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get property {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetEvent (ITargetStructObject sobj, ITargetEventInfo ev)
+		{
+			try {
+				return sobj.GetEvent (ev.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get event {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetStaticEvent (ITargetStructType stype, StackFrame frame, ITargetEventInfo ev)
+		{
+			try {
+				return stype.GetStaticEvent (frame, ev.Index);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Can't get event {0}: {1}", Name, ex.Message);
+			}
+		}
+
+		protected ITargetObject GetMember (ITargetStructObject sobj, ITargetMemberInfo member)
+		{
+			if (member is ITargetPropertyInfo)
+				return GetProperty (sobj, (ITargetPropertyInfo) member);
+			else if (member is ITargetEventInfo)
+				return GetEvent (sobj, (ITargetEventInfo) member);
+			else
+				return GetField (sobj, (ITargetFieldInfo) member);
+		}
+
+		protected ITargetObject GetStaticMember (ITargetStructType stype, StackFrame frame, ITargetMemberInfo member)
+		{
+			if (member is ITargetPropertyInfo)
+				return GetStaticProperty (stype, frame, (ITargetPropertyInfo) member);
+			else if (member is ITargetEventInfo)
+				return GetStaticEvent (stype, frame, (ITargetEventInfo) member);
+			else
+				return GetStaticField (stype, frame, (ITargetFieldInfo) member);
+		}
+
+		public static ITargetMemberInfo FindMember (ITargetStructType stype, bool is_static, string name)
+		{
+			if (!is_static) {
+				foreach (ITargetFieldInfo field in stype.Fields)
+					if (field.Name == name)
+						return field;
+
+				foreach (ITargetPropertyInfo property in stype.Properties)
+					if (property.Name == name)
+						return property;
+
+				foreach (ITargetEventInfo ev in stype.Events)
+					if (ev.Name == name)
+						return ev;
+			}
+
+			foreach (ITargetFieldInfo field in stype.StaticFields)
+				if (field.Name == name)
+					return field;
+
+			foreach (ITargetPropertyInfo property in stype.StaticProperties)
+				if (property.Name == name)
+					return property;
+
+			foreach (ITargetEventInfo ev in stype.StaticEvents)
+				if (ev.Name == name)
+					return ev;
+
+			return null;
+		}
+
+		public static Expression FindMember (ITargetStructType stype, StackFrame frame,
+						     ITargetStructObject instance, bool allow_instance,
+						     string name)
+		{
+			ITargetMemberInfo member = FindMember (stype, (instance == null) && !allow_instance, name);
+			if (member != null) {
+				if (instance != null)
+					return new StructAccessExpression (frame, instance, name);
+				else
+					return new StructAccessExpression (frame, stype, name);
+			}
+
+			ArrayList methods = new ArrayList ();
+
+		again:
+			if (name == ".ctor") {
+				foreach (ITargetMethodInfo method in stype.Constructors) {
+					methods.Add (method);
+				}
+			}
+			else if (name == ".cctor") {
+				foreach (ITargetMethodInfo method in stype.StaticConstructors) {
+					methods.Add (method);
+				}
+			}
+			else {
+				if ((instance != null) || allow_instance) {
+					foreach (ITargetMethodInfo method in stype.Methods) {
+						if (method.Name != name)
+							continue;
+
+						methods.Add (method);
+					}
+				}
+
+				foreach (ITargetMethodInfo method in stype.StaticMethods) {
+					if (method.Name != name)
+						continue;
+
+					methods.Add (method);
+				}
+			}
+
+
+			if (methods.Count > 0)
+				return new MethodGroupExpression (
+					stype, name, instance, frame.Language, methods);
+
+			ITargetClassType ctype = stype as ITargetClassType;
+			if ((ctype != null) && ctype.HasParent) {
+				stype = ctype.ParentType;
+				goto again;
+			}
+
+			return null;
+		}
+
+		protected ITargetMemberInfo FindMember (EvaluationContext context, bool report_error)
+		{
+			ITargetMemberInfo member = FindMember (Type, IsStatic, Identifier);
+			if ((member != null) || !report_error)
+				return member;
+
+			if (IsStatic)
+				throw new EvaluationException ("Type {0} has no static member {1}.", Type.Name, Identifier);
+			else
+				throw new EvaluationException ("Type {0} has no member {1}.", Type.Name, Identifier);
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			ITargetMemberInfo member = FindMember (context, true);
+
+			if (member.IsStatic)
+				return GetStaticMember (Type, Frame, member);
+			else if (!IsStatic)
+				return GetMember (Instance, member);
+			else
+				throw new EvaluationException ("Instance member {0} cannot be used in static context.", Name);
+		}
+
+		protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+								      LocationType type, Expression[] types)
+		{
+			ITargetMemberInfo member = FindMember (context, true);
+			if (member == null)
+				return null;
+
+			ITargetFunctionType func;
+
+			switch (type) {
+			case LocationType.PropertyGetter:
+			case LocationType.PropertySetter:
+				ITargetPropertyInfo property = member as ITargetPropertyInfo;
+				if (property == null)
+					return null;
+
+				if (type == LocationType.PropertyGetter) {
+					if (!property.CanRead)
+						throw new EvaluationException (
+							"Property {0} doesn't have a getter.", Name);
+					func = property.Getter;
+				} else {
+					if (!property.CanWrite)
+						throw new EvaluationException (
+							"Property {0} doesn't have a setter.", Name);
+					func = property.Setter;
+				}
+
+				return new SourceLocation (func.Source);
+			case LocationType.EventAdd:
+			case LocationType.EventRemove:
+				ITargetEventInfo ev = member as ITargetEventInfo;
+				if (ev == null)
+					return null;
+
+				if (type == LocationType.EventAdd) {
+					func = ev.Add;
+				} else {
+					func = ev.Remove;
+				}
+
+				return new SourceLocation (func.Source);
+			default:
+				return null;
+			}
+		}
+	}
+
+	public class PointerDereferenceExpression : PointerExpression
+	{
+		Expression expr;
+		string name;
+		bool current_ok;
+
+		public PointerDereferenceExpression (Expression expr, bool current_ok)
+		{
+			this.expr = expr;
+			this.current_ok = current_ok;
+			name = '*' + expr.Name;
+		}
+
+		public override string Name {
+			get {
+				return name;
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			expr = expr.Resolve (context);
+			if (expr == null)
+				return null;
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			ITargetType type = expr.EvaluateType (context);
+
+			ITargetPointerType ptype = type as ITargetPointerType;
+			if (ptype != null)
+				return ptype.StaticType;
+
+			throw new EvaluationException (
+				"Expression `{0}' is not a pointer.", expr.Name);
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			ITargetObject obj = expr.EvaluateVariable (context);
+
+			ITargetPointerObject pobj = obj as ITargetPointerObject;
+			if (pobj != null) {
+				if (!pobj.HasDereferencedObject)
+					throw new EvaluationException (
+						"Cannot dereference `{0}'.", expr.Name);
+
+				return pobj.DereferencedObject;
+			}
+
+			ITargetClassObject cobj = obj as ITargetClassObject;
+			if (current_ok && (cobj != null))
+				return cobj.CurrentObject;
+
+			throw new EvaluationException (
+				"Expression `{0}' is not a pointer type.", expr.Name);
+		}
+
+		public override TargetLocation EvaluateAddress (EvaluationContext context)
+		{
+			FrameHandle frame = context.CurrentFrame;
+
+			object obj = expr.Resolve (context);
+			if (obj is int)
+				obj = (long) (int) obj;
+			if (obj is long) {
+				TargetAddress taddress = new TargetAddress (
+					frame.Frame.AddressDomain, (long) obj);
+
+				return new AbsoluteTargetLocation (frame.Frame, taddress);
+			}
+
+			ITargetPointerObject pobj = obj as ITargetPointerObject;
+			if (pobj == null)
+				throw new EvaluationException (
+					"Expression `{0}' is not a pointer type.", expr.Name);
+
+			return pobj.Location;
+		}
+	}
+
+	public class AddressOfExpression : PointerExpression
+	{
+		Expression expr;
+		string name;
+
+		public AddressOfExpression (Expression expr)
+		{
+			this.expr = expr;
+			name = '&' + expr.Name;
+		}
+
+		public override string Name {
+			get {
+				return name;
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			expr = expr.Resolve (context);
+			if (expr == null)
+				return null;
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			FrameHandle frame = context.CurrentFrame;
+
+			ITargetPointerType ptype = expr.EvaluateType (context)
+				as ITargetPointerType;
+			if (ptype != null)
+				return ptype;
+
+			return frame.Language.PointerType;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			FrameHandle frame = context.CurrentFrame;
+
+			TargetLocation location = EvaluateAddress (context);
+			return frame.Language.CreatePointer (frame.Frame, location.Address);
+		}
+
+		public override TargetLocation EvaluateAddress (EvaluationContext context)
+		{
+			ITargetObject obj = expr.EvaluateVariable (context);
+			if (!obj.Location.HasAddress)
+				throw new EvaluationException (
+					"Cannot take address of expression `{0}'", expr.Name);
+			return obj.Location;
+		}
+	}
+
+	public class ArrayAccessExpression : Expression
+	{
+		Expression expr, index;
+		string name;
+
+		public ArrayAccessExpression (Expression expr, Expression index)
+		{
+			this.expr = expr;
+			this.index = index;
+
+			name = String.Format ("{0}[{1}]", expr.Name, index);
+		}
+
+		public override string Name {
+			get {
+				return name;
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			expr = expr.Resolve (context);
+			if (expr == null)
+				return null;
+
+			index = index.Resolve (context);
+			if (index == null)
+				return null;
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			int i;
+
+			ITargetObject obj = expr.EvaluateVariable (context);
+
+			try {
+				i = (int) this.index.Evaluate (context);
+			} catch (Exception e) {
+				throw new EvaluationException (
+					"Cannot convert {0} to an integer for indexing: {1}",
+					this.index, e);
+			}
+
+			ITargetArrayObject aobj = obj as ITargetArrayObject;
+			if (aobj == null) {
+				ITargetPointerObject pobj = obj as ITargetPointerObject;
+				if ((pobj != null) && pobj.Type.IsArray)
+					return pobj.GetArrayElement (i);
+
+				throw new EvaluationException (
+							      "Variable {0} is not an array type.", expr.Name);
+			}
+
+			if ((i < aobj.LowerBound) || (i >= aobj.UpperBound)) {
+				if (aobj.UpperBound == 0)
+					throw new EvaluationException (
+								      "Index {0} of array expression {1} out of bounds " +
+								      "(array is of zero length)", i, expr.Name);
+				else
+					throw new EvaluationException (
+								      "Index {0} of array expression {1} out of bounds " +
+								      "(must be between {2} and {3}).", i, expr.Name,
+								      aobj.LowerBound, aobj.UpperBound - 1);
+			}
+
+			return aobj [i];
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			ITargetArrayType type = expr.EvaluateType (context)
+				as ITargetArrayType;
+			if (type == null)
+				throw new EvaluationException (
+					"Variable {0} is not an array type.", expr.Name);
+
+			return type.ElementType;
+		}
+	}
+
+	public class CastExpression : Expression
+	{
+		Expression target, expr;
+		string name;
+
+		public CastExpression (Expression target, Expression expr)
+		{
+			this.target = target;
+			this.expr = expr;
+			this.name = String.Format ("(({0}) {1})", target.Name, expr.Name);
+		}
+
+		public override string Name {
+			get {
+				return name;
+			}
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			target = target.ResolveType (context);
+			if (target == null)
+				return null;
+
+			expr = expr.Resolve (context);
+			if (expr == null)
+				return null;
+
+			resolved = true;
+			return this;
+		}
+
+		static ITargetClassObject TryParentCast (EvaluationContext context,
+							 ITargetClassObject source,
+							 ITargetClassType source_type,
+							 ITargetClassType target_type)
+		{
+			if (source_type == target_type)
+				return source;
+
+			if (!source_type.HasParent)
+				return null;
+
+			source = TryParentCast (
+				context, source, source_type.ParentType, target_type);
+			if (source == null)
+				return null;
+
+			return source.Parent;
+		}
+
+		static ITargetClassObject TryCurrentCast (EvaluationContext context,
+							  ITargetClassObject source,
+							  ITargetClassType source_type,
+							  ITargetClassType target_type)
+		{
+			ITargetClassObject current = source.CurrentObject;
+			if (current.Type == source_type)
+				return null;
+
+			return TryParentCast (context, current, current.Type, target_type);
+		}
+
+		static ITargetObject TryCast (EvaluationContext context, ITargetObject source,
+					      ITargetClassType target_type)
+		{
+			if (source.TypeInfo.Type == target_type)
+				return source;
+
+			ITargetClassObject sobj = source as ITargetClassObject;
+			if (sobj == null)
+				return null;
+
+			ITargetClassObject result;
+			result = TryParentCast (context, sobj, sobj.Type, target_type);
+			if (result != null)
+				return result;
+
+			return TryCurrentCast (context, sobj, sobj.Type, target_type);
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			ITargetClassType type = target.EvaluateType (context)
+				as ITargetClassType;
+			if (type == null)
+				throw new EvaluationException (
+					"Variable {0} is not a class type.", target.Name);
+
+			ITargetClassObject source = expr.EvaluateVariable (context)
+				as ITargetClassObject;
+			if (source == null)
+				throw new EvaluationException (
+					"Variable {0} is not a class type.", expr.Name);
+
+			ITargetObject obj = TryCast (context, source, type);
+			if (obj == null)
+				throw new EvaluationException (
+					"Cannot cast from {0} to {1}.", source.Type.Name,
+					type.Name);
+
+			return obj;
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			ITargetObject obj = EvaluateVariable (context);
+			if (obj == null)
+				return null;
+
+			return obj.TypeInfo.Type;
+		}
+	}
+
+	public class InvocationExpression : Expression
+	{
+		Expression method_expr;
+		Expression[] arguments;
+		MethodGroupExpression mg;
+		string name;
+
+		public InvocationExpression (Expression method_expr, Expression[] arguments)
+		{
+			this.method_expr = method_expr;
+			this.arguments = arguments;
+
+			name = String.Format ("{0} ()", method_expr.Name);
+		}
+
+		public override string Name {
+			get { return name; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			method_expr = method_expr.Resolve (context);
+			if (method_expr == null)
+				return null;
+
+			mg = method_expr as MethodGroupExpression;
+			if (mg == null)
+				throw new EvaluationException (
+					"Expression `{0}' is not a method.", method_expr.Name);
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			return Invoke (context, false);
+		}
+
+		protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+								      LocationType type, Expression[] types)
+		{
+			Expression[] argtypes = new Expression [arguments.Length];
+			for (int i = 0; i < arguments.Length; i++) {
+				argtypes [i] = arguments [i].ResolveType (context);
+				if (argtypes [i] == null)
+					return null;
+			}
+
+			return method_expr.EvaluateLocation (context, type, argtypes);
+		}
+
+		public ITargetObject Invoke (EvaluationContext context, bool debug)
+		{
+			Expression[] args = new Expression [arguments.Length];
+			for (int i = 0; i < arguments.Length; i++) {
+				args [i] = arguments [i].Resolve (context);
+				if (args [i] == null)
+					return null;
+			}
+
+			ITargetFunctionObject func = mg.EvaluateMethod (
+				context, context.CurrentFrame.Frame, args);
+
+			ITargetObject[] objs = new ITargetObject [args.Length];
+			for (int i = 0; i < args.Length; i++)
+				objs [i] = args [i].EvaluateVariable (context);
+
+			try {
+				ITargetObject retval = func.Invoke (objs, debug);
+				if (!debug && !func.Type.HasReturnValue)
+					throw new EvaluationException ("Method `{0}' doesn't return a value.", Name);
+
+				return retval;
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException ("Invocation of `{0}' raised an exception: {1}", Name, ex.Message);
+			}
+		}
+	}
+
+	public class NewExpression : Expression
+	{
+		Expression type_expr;
+		Expression[] arguments;
+		string name;
+
+		public NewExpression (Expression type_expr, Expression[] arguments)
+		{
+			this.type_expr = type_expr;
+			this.arguments = arguments;
+
+			name = String.Format ("new {0} ()", type_expr.Name);
+		}
+
+		public override string Name {
+			get { return name; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			type_expr = type_expr.ResolveType (context);
+			if (type_expr == null)
+				return null;
+
+			for (int i = 0; i < arguments.Length; i++) {
+				arguments [i] = arguments [i].Resolve (context);
+				if (arguments [i] == null)
+					return null;
+			}
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetType DoEvaluateType (EvaluationContext context)
+		{
+			return type_expr.EvaluateType (context);
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			return Invoke (context, false);
+		}
+
+		public ITargetObject Invoke (EvaluationContext context, bool debug)
+		{
+			FrameHandle frame = context.CurrentFrame;
+
+			ITargetStructType stype = type_expr.EvaluateType (context)
+				as ITargetStructType;
+			if (stype == null)
+				throw new EvaluationException (
+					"Type `{0}' is not a struct or class.",
+					type_expr.Name);
+
+			ArrayList candidates = new ArrayList ();
+			candidates.AddRange (stype.Constructors);
+
+			ITargetMethodInfo method;
+			if (candidates.Count == 0)
+				throw new EvaluationException (
+					"Type `{0}' has no public constructor.",
+					type_expr.Name);
+			else if (candidates.Count == 1)
+				method = (ITargetMethodInfo) candidates [0];
+			else
+				method = MethodGroupExpression.OverloadResolve (
+					context, frame.Frame.Language, stype, arguments,
+					candidates);
+
+			if (method == null)
+				throw new EvaluationException (
+					"Type `{0}' has no constructor which is applicable " +
+					"for your list of arguments.", type_expr.Name);
+
+			ITargetFunctionObject ctor = stype.GetConstructor (
+				frame.Frame, method.Index);
+
+			ITargetObject[] args = new ITargetObject [arguments.Length];
+			for (int i = 0; i < arguments.Length; i++)
+				args [i] = arguments [i].EvaluateVariable (context);
+
+			try {
+				return ctor.Type.InvokeStatic (frame.Frame, args, debug);
+			} catch (Mono.Debugger.TargetInvocationException ex) {
+				throw new EvaluationException (
+					"Invocation of type `{0}'s constructor raised an " +
+					"exception: {1}", type_expr.Name, ex.Message);
+			}
+		}
+	}
+
+	public class AssignmentExpression : Expression
+	{
+		Expression left, right;
+		string name;
+
+		public AssignmentExpression (Expression left, Expression right)
+		{
+			this.left = left;
+			this.right = right;
+
+			name = left.Name + "=" + right.Name;
+		}
+
+		public override string Name {
+			get { return name; }
+		}
+
+		protected override Expression DoResolve (EvaluationContext context)
+		{
+			left = left.Resolve (context);
+			if (left == null)
+				return null;
+
+			right = right.Resolve (context);
+			if (right == null)
+				return null;
+
+			resolved = true;
+			return this;
+		}
+
+		protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+		{
+			ITargetObject obj = right.EvaluateVariable (context);
+			left.Assign (context, obj);
+			return obj;
+		}
+	}
+}
+#endif

Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -2,9 +2,11 @@
 using Gtk;
 using GtkSharp;
 using System;
+using System.Diagnostics;
 using System.IO;
 using System.Collections;
 using System.Globalization;
+using System.Text;
 using System.Runtime.InteropServices;
 using Mono.Debugger;
 using Mono.Debugger.Languages;
@@ -12,11 +14,13 @@
 using MonoDevelop.Core.Services;
 using MonoDevelop.Services;
 
+using Debugger.Frontend;
+
 namespace MonoDevelop.SourceEditor.Gui
 {
 	public class DebuggerVariablePad : Gtk.ScrolledWindow
 	{
-		StackFrame current_frame;
+		Mono.Debugger.StackFrame current_frame;
 
 		Gtk.TreeView tree;
 		Gtk.TreeStore store;
@@ -91,19 +95,106 @@
 			return inserted;
 		}
 
-		bool add_struct (TreeIter parent, ITargetStructObject sobj)
+		bool add_member (TreeIter parent, ITargetStructObject sobj, ITargetMemberInfo member, bool is_field)
 		{
 			bool inserted = false;
 
-			foreach (ITargetFieldInfo field in sobj.Type.Fields) {
+#if NET_2_0
+			DebuggerBrowsableAttribute battr = GetDebuggerBrowsableAttribute (member);
+			if (battr == null) {
 				TreeIter iter = store.Append (parent);
-				add_object (sobj.GetField (field.Index), field.Name, iter);
+				add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+					    member.Name, iter);
 				inserted = true;
 			}
+			else {
+				TreeIter iter;
 
+				switch (battr.State) {
+				case DebuggerBrowsableState.Never:
+					// don't display it at all
+					continue;
+				case DebuggerBrowsableState.Collapsed:
+					// the default behavior for the debugger (c&p from above)
+					iter = store.Append (parent);
+					add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+						    member.Name, iter);
+					inserted = true;
+					break;
+				case DebuggerBrowsableState.Expanded:
+					// add it as in the Collapsed case...
+					iter = store.Append (parent);
+					add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+						    member.Name, iter);
+					inserted = true;
+					// then expand the row
+					tree.ExpandRow (store.GetPath (iter), false);
+					break;
+				case DebuggerBrowsableState.RootHidden:
+					ITargetObject member_obj = is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index);
+
+					if (member_obj != null) {
+						switch (member_obj.TypeInfo.Type.Kind) {
+						case TargetObjectKind.Array:
+							iter = store.Append (parent);
+							// handle arrays normally, should check how vs2005 does this.
+							add_object (member_obj, member.Name, iter);
+							inserted = true;
+							break;
+						case TargetObjectKind.Class:
+							try {
+								add_class (parent, (ITargetClassObject)member_obj);
+								inserted = true;
+							}
+							catch {
+								// what about this case?  where the member is possibly
+								// uninitialized, do we try to add it later?
+							}
+							break;
+						case TargetObjectKind.Struct:
+							try {
+								add_struct (parent, (ITargetStructObject)member_obj);
+								inserted = true;
+							}
+							catch {
+								// what about this case?  where the member is possibly
+								// uninitialized, do we try to add it later?
+							}
+							break;
+						default:
+							// nothing
+							break;
+						}
+					}
+					break;
+				}
+			}
+#else
+			TreeIter iter = store.Append (parent);
+			add_object (sobj.GetField (member.Index), member.Name, iter);
+			inserted = true;
+#endif
+
 			return inserted;
 		}
 
+		bool add_struct (TreeIter parent, ITargetStructObject sobj)
+		{
+			bool inserted = false;
+
+			foreach (ITargetFieldInfo field in sobj.Type.Fields) {
+				if (add_member (parent, sobj, field, true))
+					inserted = true;
+			}
+
+			foreach (ITargetPropertyInfo prop in sobj.Type.Properties) {
+				if (add_member (parent, sobj, prop, false))
+					inserted = true;
+			}
+
+			return inserted;
+		}
+
 		bool add_class (TreeIter parent, ITargetClassObject sobj)
 		{
 			bool inserted = false;
@@ -198,6 +289,104 @@
 			iters.Add (parent, obj);
 		}
 
+#if NET_2_0
+		DebuggerBrowsableAttribute GetDebuggerBrowsableAttribute (ITargetMemberInfo info)
+		{
+	  		if (info.Handle != null && info.Handle is System.Reflection.MemberInfo) {
+				System.Reflection.MemberInfo mi = (System.Reflection.MemberInfo)info.Handle;
+				object[] attrs = mi.GetCustomAttributes (typeof (DebuggerBrowsableAttribute), false);
+
+				if (attrs != null && attrs.Length > 0)
+					return (DebuggerBrowsableAttribute)attrs[0];
+			}
+
+			return null;
+		}
+
+		DebuggerDisplayAttribute GetDebuggerDisplayAttribute (ITargetObject obj)
+		{
+			if (obj.TypeInfo.Type.TypeHandle != null && obj.TypeInfo.Type.TypeHandle is Type) {
+				Type t = (Type)obj.TypeInfo.Type.TypeHandle;
+				object[] attrs = t.GetCustomAttributes (typeof (DebuggerDisplayAttribute), false);
+
+				if (attrs != null && attrs.Length > 0)
+					return (DebuggerDisplayAttribute)attrs[0];
+			}
+
+			return null;
+		}
+
+		string EvaluateDebuggerDisplay (ITargetObject obj, string display)
+		{
+			StringBuilder sb = new StringBuilder ("");
+			DebuggingService dbgr = (DebuggingService)ServiceManager.GetService (typeof (DebuggingService));
+			EvaluationContext ctx = new EvaluationContext (obj);
+
+			ctx.CurrentProcess = new ProcessHandle (dbgr.MainThread);
+
+			/* break up the string into runs of {...} and
+			 * normal text.  treat the {...} as C#
+			 * expressions, and evaluate them */
+			int start_idx = 0;
+
+			while (true) {
+				int left_idx;
+				int right_idx;
+				left_idx = display.IndexOf ('{', start_idx);
+
+				if (left_idx == -1) {
+					/* we're done. */
+					sb.Append (display.Substring (start_idx));
+					break;
+				}
+				if (left_idx != start_idx) {
+					sb.Append (display.Substring (start_idx, left_idx - start_idx));
+				}
+				right_idx = display.IndexOf ('}', left_idx + 1);
+				if (right_idx == -1) {
+					// '{...\0'.  ignore the '{', append the rest, and break out */
+					sb.Append (display.Substring (left_idx + 1));
+					break;
+				}
+
+				if (right_idx - left_idx > 1) {
+					// there's enough space for an
+					// expression.  parse it and see
+					// what we get.
+
+					string snippet = display.Substring (left_idx + 1, right_idx - left_idx - 1);
+
+					CSharpExpressionParser parser = new CSharpExpressionParser (ctx, snippet);
+					Expression expr = parser.Parse (snippet);
+
+					expr = expr.Resolve (ctx);
+					object retval = expr.Evaluate (ctx);
+
+#region "c&p'ed from debugger/frontend/Style.cs"
+					if (retval is long) {
+						sb.Append (String.Format ("0x{0:x}", (long) retval));
+					}
+					else if (retval is string) {
+						sb.Append ('"' + (string) retval + '"');
+					}
+					else if (retval is ITargetObject) {
+						ITargetObject tobj = (ITargetObject) retval;
+						sb.Append (tobj.Print ());
+					}
+					else {
+						sb.Append (retval.ToString ());
+					}
+#endregion
+				}
+				
+
+				start_idx = right_idx + 1;
+			}
+
+			return sb.ToString ();
+		}
+#endif
+
 		void add_object (ITargetObject obj, string name, TreeIter iter)
 		{
 			AmbienceService amb = (AmbienceService)MonoDevelop.Core.Services.ServiceManager.GetService (typeof (AmbienceService));
@@ -211,8 +400,16 @@
 				break;
 
 			case TargetObjectKind.Array:
+				add_data (obj, iter);
+				break;
 			case TargetObjectKind.Struct:
 			case TargetObjectKind.Class:
+#if NET_2_0
+				DebuggerDisplayAttribute dattr = GetDebuggerDisplayAttribute (obj);
+				if (dattr != null)
+					store.SetValue (iter, 2,
+							new GLib.Value (EvaluateDebuggerDisplay (obj, dattr.Value)));
+#endif
 				add_data (obj, iter);
 				break;
 			}
@@ -281,7 +478,7 @@
 		protected void OnPausedEvent (object o, EventArgs args)
 		{
 			DebuggingService dbgr = (DebuggingService)ServiceManager.GetService (typeof (DebuggingService));
-			current_frame = (StackFrame)dbgr.CurrentFrame;
+			current_frame = (Mono.Debugger.StackFrame)dbgr.CurrentFrame;
 			UpdateDisplay ();
 		}
 	}

Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am	2005-03-01 23:58:20 UTC (rev 2282)
@@ -11,6 +11,11 @@
 FILES = \
 DebuggerCommands.cs \
 DebuggingService.cs \
+EvaluationContext.cs \
+Expression.cs \
+CSharpTokenizer.cs \
+CSharpExpressionParser.cs \
+MyTextReader.cs \
 Gui/DebuggerLocalsPad.cs \
 Gui/DebuggerVariablePad.cs \
 Gui/DebuggerStackTracePad.cs \

Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs	2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs	2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,76 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Debugger.Frontend
+{
+	internal class MyTextReader : TextReader
+	{
+		bool closed = false;
+		string current_line = null;
+		int pos = 0;
+
+		public string Text {
+			set {
+				if (closed)
+					throw new InvalidOperationException ("Reader is closed.");
+
+				pos = 0;
+				current_line = value;
+			}
+		}
+
+		bool check_line ()
+		{
+			if (closed || (current_line == null))
+				return false;
+
+			if (pos >= current_line.Length) {
+				current_line = null;
+				return false;
+			}
+
+			return true;
+		}
+
+		public override int Peek ()
+		{
+			if (!check_line ())
+				return -1;
+
+			return current_line [pos];
+		}
+
+		public override int Read ()
+		{
+			if (!check_line ())
+				return -1;
+
+			return current_line [pos++];
+		}
+
+		public override string ReadLine ()
+		{
+			string retval;
+
+			if (!check_line ())
+				return String.Empty;
+
+			retval = current_line;
+			current_line = null;
+			return retval;
+		}
+
+		public override string ReadToEnd ()
+		{
+			return ReadLine ();
+		}
+
+		public override void Close ()
+		{
+			current_line = null;
+			closed = true;
+			base.Close ();
+		}
+	}
+}




More information about the Monodevelop-patches-list mailing list