diff --git a/src/Orchard.Tests.Modules/SimpleScripting/EvaluatorTests.cs b/src/Orchard.Tests.Modules/SimpleScripting/EvaluatorTests.cs index 8c99c148a..67edb15d4 100644 --- a/src/Orchard.Tests.Modules/SimpleScripting/EvaluatorTests.cs +++ b/src/Orchard.Tests.Modules/SimpleScripting/EvaluatorTests.cs @@ -1,4 +1,6 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; using NUnit.Framework; using Orchard.Widgets.SimpleScripting.Compiler; @@ -33,11 +35,25 @@ namespace Orchard.Tests.Modules.SimpleScripting { Assert.That(result.Value, Is.EqualTo(4)); } + [Test] + public void EvaluateSimpleMethodCall() { + var result = EvaluateSimpleExpression("print 1 + 2 * 3 - 6 / 2", + (m, args) => (m == "print") ? (int)args[0] * 2 : 0); + Assert.That(result.IsError, Is.False); + Assert.That(result.Value, Is.EqualTo(4 * 2)); + } + private EvaluationResult EvaluateSimpleExpression(string expression) { + return EvaluateSimpleExpression(expression, (m, args) => null); + } + + private EvaluationResult EvaluateSimpleExpression( + string expression, Func, object> methodInvocationCallback) { + var ast = new Parser(expression).Parse(); var result = new Interpreter().Evalutate(new EvaluationContext { Tree = ast, - MethodInvocationCallback = (m, args) => null + MethodInvocationCallback = methodInvocationCallback }); return result; } diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/MethodCallAstNode.cs b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/MethodCallAstNode.cs index d77d1004a..52b98f763 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/MethodCallAstNode.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/MethodCallAstNode.cs @@ -11,6 +11,9 @@ namespace Orchard.Widgets.SimpleScripting.Ast { _arguments = arguments; } + public Token Target { get { return _token; } } + public IList Arguments { get { return _arguments; } } + public Token Token { get { return _token; } } public override IEnumerable Children { diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Interpreter.cs b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Interpreter.cs index 2f1cb40df..086824eef 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Interpreter.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Interpreter.cs @@ -4,16 +4,14 @@ using Orchard.Widgets.SimpleScripting.Ast; namespace Orchard.Widgets.SimpleScripting.Compiler { public class Interpreter { - private readonly InterpreterVisitor _interpreterVisitor = new InterpreterVisitor(); - public EvaluationResult Evalutate(EvaluationContext context) { - return _interpreterVisitor.Evaluate(context); + return new InterpreterVisitor(context).Evaluate(); } } public class EvaluationContext { public AbstractSyntaxTree Tree { get; set; } - public Func> MethodInvocationCallback { get; set; } + public Func, object> MethodInvocationCallback { get; set; } } public class EvaluationResult { diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/InterpreterVisitor.cs b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/InterpreterVisitor.cs index 0a12d61ff..9805d6d5a 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/InterpreterVisitor.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/InterpreterVisitor.cs @@ -1,10 +1,17 @@ using System; +using System.Linq; using Orchard.Widgets.SimpleScripting.Ast; namespace Orchard.Widgets.SimpleScripting.Compiler { public class InterpreterVisitor : AstVisitor { - public EvaluationResult Evaluate(EvaluationContext context) { - return Evaluate(context.Tree.Root); + private readonly EvaluationContext _context; + + public InterpreterVisitor(EvaluationContext context) { + _context = context; + } + + public EvaluationResult Evaluate() { + return Evaluate(_context.Tree.Root); } private EvaluationResult Evaluate(AstNode node) { @@ -54,6 +61,14 @@ namespace Orchard.Widgets.SimpleScripting.Compiler { } } + public override object VisitMethodCall(MethodCallAstNode node) { + var arguments = node.Arguments.Select(arg => Evaluate(arg)).ToList(); + if (arguments.Any(arg => arg.IsError)) + return arguments.First(arg => arg.IsError); + + return Result(_context.MethodInvocationCallback((string)node.Target.Value, arguments.Select(arg => arg.Value).ToList())); + } + public override object VisitError(ErrorAstNode node) { return Error(node.Message); }