Как написать макрос для создания элемента списка

У меня есть список структур, в структуре есть поле, которое определяет ее тип (предположим, что это имя). Я хотел бы иметь макрос следующим образом:

MYKEEP <name>.<field> <ANY KEEP>;

который будет переведен на:

keep value(mylist.has(it.name == <name>)) => mylist.first(it.name == <name>).<field> <ANY KEEP>

Можно ли это сделать без макроса "как вычислено"?


person Kamil.Khoury    schedule 22.07.2014    source источник
comment
Не совсем понимаю, что вы здесь ограничиваете. mylist.has(it.name == <name>) вернет логическое значение, для которого вы не можете разыменовывать <field>.   -  person Tudor Timi    schedule 22.07.2014
comment
Извините за опечатку, хотел написать первым и не написал   -  person Kamil.Khoury    schedule 23.07.2014
comment
Итак, в основном вы хотите знать, можете ли вы упростить ограничение, верно?   -  person Tudor Timi    schedule 23.07.2014
comment
Кроме того, то, что вы показали, это не макрос define as computed, а обычный макрос define as.   -  person Tudor Timi    schedule 23.07.2014
comment
Как я уже сказал, я не хочу, чтобы это было вычислено   -  person Kamil.Khoury    schedule 23.07.2014


Ответы (2)


похоже, вы хотите получить список структур в качестве входных данных, проверить значение некоторых полей структуры, а затем присвоить постоянное значение другому полю структуры в соответствии с этим значением.

принимая во внимание производительность, такого рода «инъективные» отношения между двумя полями должны быть в процедурном коде, а не в генеративном. (скорее всего, в post_generate()).

рассмотрите возможность использования определения как макроса, который выглядит следующим образом:

 define <name_induced_field'struct_member>  "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{

post_generate() is also{
    for each in l{
        if (it.t==<name'exp>){
            it.<field'exp> = <ANY_KEEP'exp>;
        };
    };

};
};

а затем использовать его в коде следующим образом:

type mytype: [AA,BB];

struct s {

t:mytype;
!i:int;

};

extend sys{

MYKEEP AA i 1;
MYKEEP BB i 2;

l:list of s;
keep l.size()==5;
};

примечание: если поле структуры имеет такое же отношение к своему имени в других случаях, рассмотрите возможность ограничения поля внутри структуры, например:

 define <name_induced_field'struct_member>  "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{
keep value(t==<name'exp>) => (<field'exp>==<ANY_KEEP'exp>);
};

type mytype: [AA,BB];

struct s {

MYKEEP AA i 1;
MYKEEP BB i 2;

t:mytype;
i:int;

post_generate() is also{
print me;
};
};
person yuvalg    schedule 23.07.2014

процедурный код мне не помогает, потому что эти поля могут влиять на другие во время генерации. Мне удалось найти макрос, который работает:

define <ana_packet_gen_con_keep1'exp>   "KEEP_CON [(<WORD>soft) ]<type'exp>\.<field'any> <exp>" as {
    keep for each (con) in it.containers {
        <WORD> (con.con_type==<type'exp>) => con.as_a(<type'exp>'con_type ana_container).<field'any> <exp>;
    };
};

Не слишком ли влияет на производительность наличие нескольких «сохранять для каждого»?

person Kamil.Khoury    schedule 23.07.2014
comment
Разве это не немного отличается от того, что вы хотели в вопросе? Это не ограничивает ваш список наличием элемента типа <type> или? Кроме того, он ограничивает все элементы типа ‹type›, а не только первый. - person Tudor Timi; 23.07.2014
comment
Это не имеет значения, это ограничение является более общим, я могу изменить его, чтобы получить номер структуры. - person Kamil.Khoury; 23.07.2014
comment
Понятия не имею о for each, но IMO, решатель в любом случае должен перебирать все элементы списка, чтобы решить их. Я думаю, что ограничивающим фактором будет размер вашего списка, а не количество for each ограничений, которые у вас есть. - person Tudor Timi; 23.07.2014