43
44
Dictionary<string,ValueReference> userVariables = new Dictionary<string, ValueReference> ();
45
public override ValueReference Evaluate (EvaluationContext ctx, string exp, EvaluationOptions options)
46
public override ValueReference Evaluate (EvaluationContext ctx, string exp, object expectedType)
47
48
if (exp.StartsWith ("?"))
48
49
exp = exp.Substring (1).Trim ();
72
73
Expression expObj = parser.ParseExpression ();
73
74
if (expObj == null)
74
75
throw new EvaluatorException ("Could not parse expression '" + exp + "'");
75
EvaluatorVisitor ev = new EvaluatorVisitor (ctx, exp, options, userVariables);
76
EvaluatorVisitor ev = new EvaluatorVisitor (ctx, exp, expectedType, userVariables);
76
77
return (ValueReference) expObj.AcceptVisitor (ev, null);
80
81
class EvaluatorVisitor: AbstractAstVisitor
82
83
EvaluationContext ctx;
84
EvaluationOptions options;
84
EvaluationOptions options;
85
87
Dictionary<string,ValueReference> userVariables;
87
public EvaluatorVisitor (EvaluationContext ctx, string name, EvaluationOptions options, Dictionary<string,ValueReference> userVariables)
89
public EvaluatorVisitor (EvaluationContext ctx, string name, object expectedType, Dictionary<string,ValueReference> userVariables)
91
this.options = options;
93
this.expectedType = expectedType;
92
94
this.userVariables = userVariables;
95
this.options = ctx.Options;
95
98
public override object VisitUnaryOperatorExpression (ICSharpCode.NRefactory.Ast.UnaryOperatorExpression unaryOperatorExpression, object data)
160
163
if (primitiveExpression.Value != null)
161
164
return LiteralValueReference.CreateObjectLiteral (ctx, name, primitiveExpression.Value);
162
else if (options.ExpectedType != null)
163
return new NullValueReference (ctx, options.ExpectedType);
165
else if (expectedType != null)
166
return new NullValueReference (ctx, expectedType);
165
168
return new NullValueReference (ctx, ctx.Adapter.GetType (ctx, "System.Object"));
178
181
public override object VisitInvocationExpression (ICSharpCode.NRefactory.Ast.InvocationExpression invocationExpression, object data)
180
if (!options.CanEvaluateMethods)
183
if (!options.AllowMethodEvaluation)
181
184
throw CreateNotSupportedError ();
183
186
ValueReference target = null;
288
291
ValueReference thisobj = ctx.Adapter.GetThisReference (ctx);
289
292
object thistype = ctx.Adapter.GetEnclosingType (ctx);
291
var = ctx.Adapter.GetMember (ctx, thistype, thisobj != null ? thisobj.Value : null, name);
294
var = ctx.Adapter.GetMember (ctx, thisobj, thistype, thisobj != null ? thisobj.Value : null, name);
378
381
case BinaryOperatorType.LogicalAnd: {
379
if (!(bool)left.ObjectValue)
382
object val = left.ObjectValue;
384
throw CreateParseError ("Left operand of logical And must be a boolean");
386
return LiteralValueReference.CreateObjectLiteral (ctx, name, false);
381
387
return rightExp.AcceptVisitor (this, data);
383
389
case BinaryOperatorType.LogicalOr: {
384
if ((bool)left.ObjectValue)
390
object val = left.ObjectValue;
392
throw CreateParseError ("Left operand of logical Or must be a boolean");
394
return LiteralValueReference.CreateObjectLiteral (ctx, name, true);
386
395
return rightExp.AcceptVisitor (this, data);
394
403
if (oper == BinaryOperatorType.Add || oper == BinaryOperatorType.Concat) {
395
404
if (val1 is string || val2 is string) {
396
if (!(val1 is string))
405
if (!(val1 is string) && val1 != null)
397
406
val1 = left.CallToString ();
398
if (!(val2 is string))
407
if (!(val2 is string) && val2 != null)
399
408
val2 = right.CallToString ();
400
409
return LiteralValueReference.CreateObjectLiteral (ctx, name, (string) val1 + (string) val2);
404
if ((oper == BinaryOperatorType.ExclusiveOr) && (val1 is bool) && !(val2 is bool))
413
if ((oper == BinaryOperatorType.ExclusiveOr) && (val1 is bool) && (val2 is bool))
405
414
return LiteralValueReference.CreateObjectLiteral (ctx, name, (bool)val1 ^ (bool)val2);
408
417
case BinaryOperatorType.Equality:
418
if (val1 == null || val2 == null)
419
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 == val2);
409
420
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1.Equals (val2));
410
421
case BinaryOperatorType.InEquality:
422
if (val1 == null || val2 == null)
423
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 != val2);
411
424
return LiteralValueReference.CreateObjectLiteral (ctx, name, !val1.Equals (val2));
412
425
case BinaryOperatorType.ReferenceEquality:
413
426
return LiteralValueReference.CreateObjectLiteral (ctx, name, val1 == val2);
417
430
throw CreateParseError ("Invalid binary operator.");
420
long v1 = Convert.ToInt64 (left.ObjectValue);
421
long v2 = Convert.ToInt64 (right.ObjectValue);
433
if (val1 == null || val2 == null || (val1 is bool) || (val2 is bool))
434
throw CreateParseError ("Invalid operands in binary operator");
439
v1 = Convert.ToInt64 (val1);
440
v2 = Convert.ToInt64 (val2);
442
throw CreateParseError ("Invalid operands in binary operator");
481
504
public override object VisitAssignmentExpression (ICSharpCode.NRefactory.Ast.AssignmentExpression assignmentExpression, object data)
483
if (!options.CanEvaluateMethods)
506
if (!options.AllowMethodEvaluation)
484
507
throw CreateNotSupportedError ();
486
509
ValueReference left = (ValueReference) assignmentExpression.Left.AcceptVisitor (this, data);