使用 IronPython 简化为 C# 应用程序编写的 DSL

发布于 2024-08-02 18:52:16 字数 1257 浏览 3 评论 0原文

感谢上一个问题,我正忙于尝试 IronPython、IronRuby 和 Boo 来为我的 C# 应用程序创建 DSL。第一步是 IronPython,因为它拥有更大的用户和知识库。如果我能在这里做好一些事情,我就可以停下来。

这是我的问题:

我希望我的 IronPython 脚本能够访问名为 Lib 的类中的函数。现在,我可以将程序集添加到 IronPython 运行时,并通过在我创建的范围内执行语句来导入类:

// load 'ScriptLib' assembly
Assembly libraryAssembly = Assembly.LoadFile(libraryPath);
_runtime.LoadAssembly(libraryAssembly);

// import 'Lib' class from 'ScriptLib'
ScriptSource imports = _engine.CreateScriptSourceFromString("from ScriptLib import Lib", SourceCodeKind.Statements);
imports.Execute(_scope);

// run .py script:
ScriptSource script = _engine.CreateScriptSourceFromFile(scriptPath);
script.Execute(_scope);

如果我想运行 Lib::PrintHello,它只是一个 hello world 样式语句,我的 Python 脚本包含:

Lib.PrintHello()

或(如果它不是静态的):

library = new Lib()
library.PrintHello()

我怎样才能改变我的环境,以便我可以在Python脚本中包含基本的语句,如下所示:

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

我希望这些脚本对于非程序员来说是简单的。我不想让他们知道类是什么或者它是如何工作的。 IronPython 确实存在,因此一些基本操作(例如 for、do、if 和基本函数定义)不需要我为 DSL 编写编译器。

Thanks to suggestions from a previous question, I'm busy trying out IronPython, IronRuby and Boo to create a DSL for my C# app. Step one is IronPython, due to the larger user and knowledge base. If I can get something to work well here, I can just stop.

Here is my problem:

I want my IronPython script to have access to the functions in a class called Lib. Right now I can add the assembly to the IronPython runtime and import the class by executing the statement in the scope I created:

// load 'ScriptLib' assembly
Assembly libraryAssembly = Assembly.LoadFile(libraryPath);
_runtime.LoadAssembly(libraryAssembly);

// import 'Lib' class from 'ScriptLib'
ScriptSource imports = _engine.CreateScriptSourceFromString("from ScriptLib import Lib", SourceCodeKind.Statements);
imports.Execute(_scope);

// run .py script:
ScriptSource script = _engine.CreateScriptSourceFromFile(scriptPath);
script.Execute(_scope);

If I want to run Lib::PrintHello, which is just a hello world style statement, my Python script contains:

Lib.PrintHello()

or (if it's not static):

library = new Lib()
library.PrintHello()

How can I change my environment so that I can just have basic statments in the Python script like this:

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

I want these scripts to be simple for a non-programmer to write. I don't want them to have to know what a class is or how it works. IronPython is really just there so that some basic operations like for, do, if, and a basic function definition don't require my writing a compiler for my DSL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初与友歌 2024-08-09 18:52:16

您应该能够执行以下操作:

var objOps = _engine.Operations;
var lib = new Lib();

foreach (string memberName in objOps.GetMemberNames(lib)) {
    _scope.SetVariable(memberName, objOps.GetMember(lib, memberName));
}

这将从 lib objec 中获取所有成员,然后将它们注入到 ScriptScope 中。这是通过 Python ObjectOperations 类完成的,因此您得到的成员将是 Python 成员。因此,如果您随后使用 IronRuby 执行类似的操作,则相同的代码基本上应该可以工作。

You should be able to do something like:

var objOps = _engine.Operations;
var lib = new Lib();

foreach (string memberName in objOps.GetMemberNames(lib)) {
    _scope.SetVariable(memberName, objOps.GetMember(lib, memberName));
}

This will get all of the members from the lib objec and then inject them into the ScriptScope. This is done w/ the Python ObjectOperations class so that the members you get off will be Python members. So if you then do something similar w/ IronRuby the same code should basically work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文