mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Implement evaluation of method calls
--HG-- branch : dev
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Orchard.Widgets.SimpleScripting.Compiler;
|
using Orchard.Widgets.SimpleScripting.Compiler;
|
||||||
|
|
||||||
@@ -33,11 +35,25 @@ namespace Orchard.Tests.Modules.SimpleScripting {
|
|||||||
Assert.That(result.Value, Is.EqualTo(4));
|
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) {
|
private EvaluationResult EvaluateSimpleExpression(string expression) {
|
||||||
|
return EvaluateSimpleExpression(expression, (m, args) => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EvaluationResult EvaluateSimpleExpression(
|
||||||
|
string expression, Func<string, IList<object>, object> methodInvocationCallback) {
|
||||||
|
|
||||||
var ast = new Parser(expression).Parse();
|
var ast = new Parser(expression).Parse();
|
||||||
var result = new Interpreter().Evalutate(new EvaluationContext {
|
var result = new Interpreter().Evalutate(new EvaluationContext {
|
||||||
Tree = ast,
|
Tree = ast,
|
||||||
MethodInvocationCallback = (m, args) => null
|
MethodInvocationCallback = methodInvocationCallback
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,9 @@ namespace Orchard.Widgets.SimpleScripting.Ast {
|
|||||||
_arguments = arguments;
|
_arguments = arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Token Target { get { return _token; } }
|
||||||
|
public IList<AstNode> Arguments { get { return _arguments; } }
|
||||||
|
|
||||||
public Token Token { get { return _token; } }
|
public Token Token { get { return _token; } }
|
||||||
|
|
||||||
public override IEnumerable<AstNode> Children {
|
public override IEnumerable<AstNode> Children {
|
||||||
|
@@ -4,16 +4,14 @@ using Orchard.Widgets.SimpleScripting.Ast;
|
|||||||
|
|
||||||
namespace Orchard.Widgets.SimpleScripting.Compiler {
|
namespace Orchard.Widgets.SimpleScripting.Compiler {
|
||||||
public class Interpreter {
|
public class Interpreter {
|
||||||
private readonly InterpreterVisitor _interpreterVisitor = new InterpreterVisitor();
|
|
||||||
|
|
||||||
public EvaluationResult Evalutate(EvaluationContext context) {
|
public EvaluationResult Evalutate(EvaluationContext context) {
|
||||||
return _interpreterVisitor.Evaluate(context);
|
return new InterpreterVisitor(context).Evaluate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EvaluationContext {
|
public class EvaluationContext {
|
||||||
public AbstractSyntaxTree Tree { get; set; }
|
public AbstractSyntaxTree Tree { get; set; }
|
||||||
public Func<object, string, IList<object>> MethodInvocationCallback { get; set; }
|
public Func<string, IList<object>, object> MethodInvocationCallback { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EvaluationResult {
|
public class EvaluationResult {
|
||||||
|
@@ -1,10 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Orchard.Widgets.SimpleScripting.Ast;
|
using Orchard.Widgets.SimpleScripting.Ast;
|
||||||
|
|
||||||
namespace Orchard.Widgets.SimpleScripting.Compiler {
|
namespace Orchard.Widgets.SimpleScripting.Compiler {
|
||||||
public class InterpreterVisitor : AstVisitor {
|
public class InterpreterVisitor : AstVisitor {
|
||||||
public EvaluationResult Evaluate(EvaluationContext context) {
|
private readonly EvaluationContext _context;
|
||||||
return Evaluate(context.Tree.Root);
|
|
||||||
|
public InterpreterVisitor(EvaluationContext context) {
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EvaluationResult Evaluate() {
|
||||||
|
return Evaluate(_context.Tree.Root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EvaluationResult Evaluate(AstNode node) {
|
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) {
|
public override object VisitError(ErrorAstNode node) {
|
||||||
return Error(node.Message);
|
return Error(node.Message);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user