72
73
IParser parser = ParserFactory.CreateParser (SupportedLanguage.CSharp, codeStream);
73
74
Expression expObj = parser.ParseExpression ();
74
75
if (expObj == null)
75
throw new EvaluatorException ("Could not parse expression '" + exp + "'");
76
throw new EvaluatorException ("Could not parse expression '{0}'", exp);
76
77
EvaluatorVisitor ev = new EvaluatorVisitor (ctx, exp, expectedType, userVariables);
77
78
return (ValueReference) expObj.AcceptVisitor (ev, null);
81
public string Resolve (DebuggerSession session, SourceLocation location, string exp)
83
if (exp.StartsWith ("?"))
84
return "?" + Resolve (session, location, exp.Substring (1).Trim ());
85
if (exp.StartsWith ("var "))
86
return "var " + Resolve (session, location, exp.Substring (4).Trim (' ','\t'));
88
StringReader codeStream = new StringReader (exp);
89
IParser parser = ParserFactory.CreateParser (SupportedLanguage.CSharp, codeStream);
90
Expression expObj = parser.ParseExpression ();
92
throw new EvaluatorException ("Could not parse expression '{0}'", exp);
93
NRefactoryResolverVisitor ev = new NRefactoryResolverVisitor (session, location, exp);
94
expObj.AcceptVisitor (ev, null);
95
return ev.GetResolvedExpression ();
81
99
class EvaluatorVisitor: AbstractAstVisitor
137
155
public override object VisitTypeReferenceExpression (ICSharpCode.NRefactory.Ast.TypeReferenceExpression typeReferenceExpression, object data)
157
if (typeReferenceExpression.TypeReference.IsGlobal) {
158
string name = typeReferenceExpression.TypeReference.Type;
159
object type = ctx.Options.AllowImplicitTypeLoading ? ctx.Adapter.ForceLoadType (ctx, name) : ctx.Adapter.GetType (ctx, name);
161
return new TypeValueReference (ctx, type);
163
if (!ctx.Options.AllowImplicitTypeLoading) {
164
string[] namespaces = ctx.Adapter.GetImportedNamespaces (ctx);
165
if (namespaces.Length > 0) {
166
// Look in namespaces
167
foreach (string ns in namespaces) {
168
if (name == ns || ns.StartsWith (name + "."))
169
return new NamespaceValueReference (ctx, name);
173
// Assume it is a namespace.
174
return new NamespaceValueReference (ctx, name);
139
177
throw CreateNotSupportedError ();
392
437
throw CreateParseError ("Left operand of logical Or must be a boolean");
394
439
return LiteralValueReference.CreateObjectLiteral (ctx, name, true);
395
return rightExp.AcceptVisitor (this, data);
440
ValueReference vr = (ValueReference) rightExp.AcceptVisitor (this, data);
441
if (ctx.Adapter.GetTypeName (ctx, vr.Type) != "System.Boolean")
442
throw CreateParseError ("Right operand of logical Or must be a boolean");
399
447
ValueReference right = (ValueReference) rightExp.AcceptVisitor (this, data);
448
object targetVal1 = left.Value;
449
object targetVal2 = right.Value;
400
450
object val1 = left.ObjectValue;
401
451
object val2 = right.ObjectValue;
403
453
if (oper == BinaryOperatorType.Add || oper == BinaryOperatorType.Concat) {
404
454
if (val1 is string || val2 is string) {
405
455
if (!(val1 is string) && val1 != null)
406
val1 = left.CallToString ();
456
val1 = ctx.Adapter.CallToString (ctx, targetVal1);
407
457
if (!(val2 is string) && val2 != null)
408
val2 = right.CallToString ();
458
val2 = ctx.Adapter.CallToString (ctx, targetVal2);
409
459
return LiteralValueReference.CreateObjectLiteral (ctx, name, (string) val1 + (string) val2);
413
463
if ((oper == BinaryOperatorType.ExclusiveOr) && (val1 is bool) && (val2 is bool))
414
464
return LiteralValueReference.CreateObjectLiteral (ctx, name, (bool)val1 ^ (bool)val2);
417
case BinaryOperatorType.Equality:
418
if (val1 == null || val2 == null)
466
if ((val1 == null || !val1.GetType ().IsPrimitive) && (val2 == null || !val2.GetType ().IsPrimitive)) {
468
case BinaryOperatorType.Equality:
469
if (val1 == null || val2 == null)
470
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 == val2);
471
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1.Equals (val2));
472
case BinaryOperatorType.InEquality:
473
if (val1 == null || val2 == null)
474
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 != val2);
475
return LiteralValueReference.CreateObjectLiteral (ctx, name, !val1.Equals (val2));
476
case BinaryOperatorType.ReferenceEquality:
419
477
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 == val2);
420
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1.Equals (val2));
421
case BinaryOperatorType.InEquality:
422
if (val1 == null || val2 == null)
478
case BinaryOperatorType.ReferenceInequality:
423
479
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 != val2);
424
return LiteralValueReference.CreateObjectLiteral (ctx, name, !val1.Equals (val2));
425
case BinaryOperatorType.ReferenceEquality:
426
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 == val2);
427
case BinaryOperatorType.ReferenceInequality:
428
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 != val2);
429
case BinaryOperatorType.Concat:
430
throw CreateParseError ("Invalid binary operator.");
480
case BinaryOperatorType.Concat:
481
throw CreateParseError ("Invalid binary operator.");
433
485
if (val1 == null || val2 == null || (val1 is bool) || (val2 is bool))
434
486
throw CreateParseError ("Invalid operands in binary operator");
489
object longType = ctx.Adapter.GetType (ctx, "System.Int64");
439
v1 = Convert.ToInt64 (val1);
440
v2 = Convert.ToInt64 (val2);
492
object c1 = ctx.Adapter.Cast (ctx, targetVal1, longType);
493
v1 = (long) ctx.Adapter.TargetObjectToObject (ctx, c1);
495
object c2 = ctx.Adapter.Cast (ctx, targetVal2, longType);
496
v2 = (long) ctx.Adapter.TargetObjectToObject (ctx, c2);
442
498
throw CreateParseError ("Invalid operands in binary operator");
461
517
case BinaryOperatorType.GreaterThanOrEqual: res = v1 >= v2; break;
462
518
case BinaryOperatorType.LessThan: res = v1 < v2; break;
463
519
case BinaryOperatorType.LessThanOrEqual: res = v1 <= v2; break;
520
case BinaryOperatorType.ReferenceEquality:
521
case BinaryOperatorType.Equality: res = v1 == v2; break;
522
case BinaryOperatorType.ReferenceInequality:
523
case BinaryOperatorType.InEquality: res = v1 != v2; break;
464
524
default: throw CreateParseError ("Invalid binary operator.");
467
527
if (!(res is bool))
468
528
res = (long) Convert.ChangeType (res, GetCommonType (v1, v2));
530
if (ctx.Adapter.IsEnum (ctx, targetVal1)) {
531
object tval = ctx.Adapter.Cast (ctx, ctx.Adapter.CreateValue (ctx, res), ctx.Adapter.GetValueType (ctx, targetVal1));
532
return LiteralValueReference.CreateTargetObjectLiteral (ctx, name, tval);
534
if (ctx.Adapter.IsEnum (ctx, targetVal2)) {
535
object tval = ctx.Adapter.Cast (ctx, ctx.Adapter.CreateValue (ctx, res), ctx.Adapter.GetValueType (ctx, targetVal2));
536
return LiteralValueReference.CreateTargetObjectLiteral (ctx, name, tval);
469
539
return LiteralValueReference.CreateObjectLiteral (ctx, name, res);