Пара вопросов по статье "Макросы Немерле, расширенный курс".
От: febus Германия  
Дата: 17.08.11 23:51
Оценка:
1. В первой части есть такой вот пример:

macro BuildClass ()
{
  def ctx = Nemerle.Macros.ImplicitCTX();
  def astOfClass = <[ decl:
    internal class FooBar
    {
      public static SomeMethod () : void
      {
        System.Console.WriteLine ("Hello world");
      }
    }
  ]>;

  def builder = ctx.Env.Define(astOfClass);
 
  builder.Compile();
 
  <[ FooBar.SomeMethod () ]>
}



Класс FooBar объявлается internal в макросборке. Однако, я могу напрямую вызвать FooBar.SomeMethod (), несмотря на то, что FooBar объявлен как internal, т.е. по идее д.б. виден только внутри макросборки. Так и должно быть?

2. Во второй части, при объявлении макроса forindex говорится, что якобы есть ошибка в системе квазицитирования и потому вариант

| <[ $minExpr <= $i =< $maxExpr ]> => 
  <[ for (mutable $i = $minExpr;     $i =< $maxExpr; $i += $step) $body ]>
| <[ $minExpr <  $i =< $maxExpr ]> => 
  <[ for (mutable $i = $minExpr + 1; $i =< $maxExpr; $i += $step) $body ]>
| <[ $minExpr <  $i <  $maxExpr ]> => 
  <[ for (mutable $i = $minExpr + 1; $i <  $maxExpr; $i += $step) $body ]>
| <[ $minExpr <= $i <  $maxExpr ]> => 
  <[ for (mutable $i = $minExpr;     $i <  $maxExpr; $i += $step) $body ]>


не срабатывает. Действительно при попытке откомпилировать проект вылетает MatchFailureException.
Если внимательно присмотреться, то можно заметить весьма странный способ записи для меньше или равно: =<. Так вот, если в квазицитатах в приведенном выше куске заменить =< на <=, то все нормально распознается.
Т.е. так работает:

    | <[ $minExpr <= $i <= $maxExpr ]> => 
      <[ for (mutable $i = $minExpr;     $i <= $maxExpr; $i += $step) $body ]>
    | <[ $minExpr <  $i <= $maxExpr ]> => 
      <[ for (mutable $i = $minExpr + 1; $i <= $maxExpr; $i += $step) $body ]>
    | <[ $minExpr <  $i <  $maxExpr ]> => 
      <[ for (mutable $i = $minExpr + 1; $i <  $maxExpr; $i += $step) $body ]>
    | <[ $minExpr <= $i <  $maxExpr ]> => 
      <[ for (mutable $i = $minExpr;     $i <  $maxExpr; $i += $step) $body ]>


Поэтому, как мне кажется, это просто опечатка, повлекшая за собой неверный вывод об ошибке в системе квазицитирования.
Пока все, читаю дальше
Re: Пара вопросов по статье "Макросы Немерле, расширенный ку
От: Ziaw Россия  
Дата: 18.08.11 04:18
Оценка: 53 (2)
Здравствуйте, febus, Вы писали:

F>Класс FooBar объявлается internal в макросборке. Однако, я могу напрямую вызвать FooBar.SomeMethod (), несмотря на то, что FooBar объявлен как internal, т.е. по идее д.б. виден только внутри макросборки. Так и должно быть?


Макрос создает класс в компилируемой сборке. Квазицитаты не "выполняются", это сахар для конструктора AST. Любую квазицитату компилятор превращает в конструктор AST и работает далее, как с обычным вариантным типом. Точно также работает expression tree в C#.

F>Поэтому, как мне кажется, это просто опечатка, повлекшая за собой неверный вывод об ошибке в системе квазицитирования.


Похоже на то
Re: Пара вопросов по статье "Макросы Немерле, расширенный ку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.11 14:41
Оценка: 4 (1)
Здравствуйте, febus, Вы писали:

F>Класс FooBar объявлается internal в макросборке. Однако, я могу напрямую вызвать FooBar.SomeMethod (), несмотря на то, что FooBar объявлен как internal, т.е. по идее д.б. виден только внутри макросборки. Так и должно быть?


Ziaw полностью прав. Используя (и создавая) макросы нужно четко понимать, что макрос — это средство генерации (или модификации) кода. Он (макрос) не является частью кода конечной программы. Он раскрывается во время компиляции конечной программы и порождает (или модифицирует) код внутри конечной программы. По этому генерируемый макросами код ни чем не отличается от кода который написан программистом вручную.

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

F>2. Во второй части, при объявлении макроса forindex говорится, что якобы есть ошибка в системе квазицитирования и потому вариант


F>
F>| <[ $minExpr <= $i =< $maxExpr ]> => 
F>  <[ for (mutable $i = $minExpr;     $i =< $maxExpr; $i += $step) $body ]>
F>| <[ $minExpr <  $i =< $maxExpr ]> => 
F>  <[ for (mutable $i = $minExpr + 1; $i =< $maxExpr; $i += $step) $body ]>
F>| <[ $minExpr <  $i <  $maxExpr ]> => 
F>  <[ for (mutable $i = $minExpr + 1; $i <  $maxExpr; $i += $step) $body ]>
F>| <[ $minExpr <= $i <  $maxExpr ]> => 
F>  <[ for (mutable $i = $minExpr;     $i <  $maxExpr; $i += $step) $body ]>
F>


F>не срабатывает. Действительно при попытке откомпилировать проект вылетает MatchFailureException.

F>Если внимательно присмотреться, то можно заметить весьма странный способ записи для меньше или равно: =<. Так вот, если в квазицитатах в приведенном выше куске заменить =< на <=, то все нормально распознается.
F>Поэтому, как мне кажется, это просто опечатка, повлекшая за собой неверный вывод об ошибке в системе квазицитирования.

Ага. Это не странный способ. Это я напутал. Тут уже где-то в комментариях к статье об этом говорили. Надо было сразу поменять, но я запамятовал.

В общем, поправил статью. Так что теперь там все правильно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Пара вопросов по статье "Макросы Немерле, расширенный
От: febus Германия  
Дата: 18.08.11 15:19
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>В общем, поправил статью. Так что теперь там все правильно.
Да, не в тему, но:
Статья
Автор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.
по PEG-у отсутствует в списке статей о Немерле и в дереве сайта слева.
Найти ее можно лишь поиском, либо регулярно читая этот форум.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.