Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, CodingUnit, Вы писали:
CU>>Спасибо за ответ Владислав и подробное описание, хотел заметить что автомат иерархический, в Boo был описан плоский автомат, на практике чаще автоматы нужны сложные, то есть когда состояния могут быть вложенными друг в друга, как я описал здесь:...
VD>Я показал как можно спроектировать синтаксис и как его разбирать. Думаю, что основные моменты я показал, так что будет не сложно переделать его в иерархический вариант.
CU>>графически они выглядят примерно так
CU>>здесь
CU>>В принципе с метаатрибутом описать весь автомат можно, лишь бы это не сложно было сделать, тогда описание будет выглядеть примерно так:
CU>>VD>...
CU>> state Sub1
CU>> {
CU>> | entry => {
CU>> Action1 // действие при входе
CU>> }
CU>> | exit => Action2 // действие при выходе
CU>>})]
CU>>
VD>Так выглядит красивее. Только одно замечание. Вот эти вот "entry" и "exit" ведь к самому автомату отношения не имеют, да? Это ведь реакция?
VD>На мой взгляд лучше не забивать описание автомата действиями которые должны осуществляться при переходах. Действия лучше помещать в методы внутри класса. Метод EnterIn_IdleInGear_State(), который я изобразил в своем примере как раз и был таким действием. Их можно помечать атрибутами или распознавать по имени. В моем случае подразумевалось, что он будет распознаваться оп имени. Можно их описывать и на основании атрибутов. Например, для приведенного выше фрагмента можно описать реакции так:
VD>[c#]
Все работает замечательно, на Nemerle можно строить неплохие DSL, но вот беда, почему то не хотят создаваться в цикле объявления событий, то есть создаются правильные PExpr объявления члена класса события, но когда начинается конечная компиляция оказывается что члены поля и методов add,remove генерируются с одинаковыми именами, соответствующих названию в той строчке в которой производилось объявление, например если делаешь так:
// функция которая создает события из описания где то списка событий
def create_events(model)
{
model.Events.Map(x =>
{
def ename : string =x.Name; // это имя члена
<[ decl: public event $(ename : usesite) : EventHandler; ]> // на выходе объявление члена события
});
}
def defs=create_events(model); // создаем список объявлений
defs.Iter(x => typebuilder.Define(x)); // добавляем в typebuilder
при этом возникает ошибка в духе: _N2_ename_usesite_field duplicated identifier, тоже самое и с методами add,remove, исследовав этот вопрос оказывается когда создается с помощью цитаты объявление события оно всегда использует имя объявления в данном случае текст $(ename : usesite), и с помощью него создает имя членов, видимо подразумевая что событие должно объявлятся с константным именем и всегда разным, но что делать если надо объявить на основе динамических данных? Я решил эту задачу только с помощью специального метода, который берет объявление с помощью цитаты, которое преобразуется в ClassMember.Event и создает новый класс ClassMember.Event заменяя имена на новые и оставляя тела такие же как в старом созданном с помощью цитаты, тогда сообщение об ошибке не возникает, но это не выход, надо видимо чтобы имя полей и методов add,remove, при объявлении квази цитаты использовалось уникальное на основе имени которое берется из выражения, а не на основе текста выражения, это надо править компилятор, где бы найти файл где вся эта логика распознавания цитат реализуется? Может ли помочь наш всемогущий Владислав?