Упрощение написания DSL для приложения на C # с IronPython - PullRequest
9 голосов
/ 28 августа 2009

Благодаря предложениям из предыдущего вопроса я занят попыткой IronPython, IronRuby и Boo, чтобы создать DSL для моего приложения на C #. Первый шаг - 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 style, мой скрипт на Python содержит:

Lib.PrintHello()

или (если это не статично):

library = new Lib()
library.PrintHello()

Как я могу изменить свое окружение, чтобы в скрипте Python я мог просто иметь базовые характеристики:

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

Я хочу, чтобы эти сценарии были простыми для непрограммиста. Я не хочу, чтобы они знали, что такое класс или как он работает. IronPython действительно просто для того, чтобы некоторые базовые операции, такие как for, do, if и определение базовой функции, не требовали написания компилятора для моего DSL.

1 Ответ

19 голосов
/ 29 августа 2009

Вы должны быть в состоянии сделать что-то вроде:

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, тот же самый код должен работать.

...