public AddressOfExpression(Expression expr)
 {
     this.expr = expr;
     name = '&' + expr.Name;
 }
 public ConditionalExpression(Expression test, Expression true_expr, Expression false_expr)
 {
     this.test = test;
     this.true_expr = true_expr;
     this.false_expr = false_expr;
 }
        protected override Expression DoResolve(EvaluationContext context)
        {
            expr = expr.Resolve (context);
            if (expr == null)
                return null;

            resolved = true;
            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 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);
            }
        }
        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 SourceLocation DoEvaluateLocation(EvaluationContext context,
								      LocationType type, Expression[] types)
        {
            if (types != null)
                return null;

            return location;
        }
        protected virtual SourceLocation DoEvaluateLocation(EvaluationContext context,
								     LocationType type, Expression[] types)
        {
            return null;
        }
        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;
        }
 public PointerDereferenceExpression(Expression expr, bool current_ok)
 {
     this.expr = expr;
     this.current_ok = current_ok;
     name = '*' + expr.Name;
 }
        public ArrayAccessExpression(Expression expr, Expression index)
        {
            this.expr = expr;
            this.index = index;

            name = String.Format ("{0}[{1}]", expr.Name, index);
        }
        public NewExpression(Expression type_expr, Expression[] arguments)
        {
            this.type_expr = type_expr;
            this.arguments = arguments;

            name = String.Format ("new {0} ()", type_expr.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;
        }
        protected override Expression DoResolve(EvaluationContext context)
        {
            test = test.Resolve (context);
            true_expr = true_expr.Resolve (context);
            false_expr = false_expr.Resolve (context);

            resolved = true;
            return this;
        }
        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 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);
            }
        }
 public TypeOfExpression(Expression expr)
 {
     this.expr = expr;
 }
        public InvocationExpression(Expression method_expr, Expression[] arguments)
        {
            this.method_expr = method_expr;
            this.arguments = arguments;

            name = String.Format ("{0} ()", method_expr.Name);
        }
        public AssignmentExpression(Expression left, Expression right)
        {
            this.left = left;
            this.right = right;

            name = left.Name + "=" + right.Name;
        }
        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);
        }
        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;
        }
 public MemberAccessExpression(Expression left, string name)
 {
     this.left = left;
     this.name = name;
 }
 public CastExpression(Expression target, Expression expr)
 {
     this.target = target;
     this.expr = expr;
     this.name = String.Format ("(({0}) {1})", target.Name, expr.Name);
 }
        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 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);
        }