проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 09:48
Оценка:
есть простенький макрос:
namespace TestMacros
{
    public macro Cond(cond, trueExpr, falseExpr)
    {
        <[ if ($cond) $trueExpr; else $falseExpr ]>
    }
}


и есть вот такое его использование:

Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { TestMacros.Cond(true, 1, 2) }));

макрос ToExpression выдает ошибку conversion from Call (expr: TestMacros.Cond(true, 1, 2)) into 'expression tree' not supported

но разве должен вызов макроса паковаться в вариант MacroCall ?

сейчас при разборе мы падаем тут (файл ToExpressionImpl.n, в районе 370ой строки):


        | PExpr.Call(func, _parms) => 
        
          match (expr)
          {
            | <[ $inst . $_meth (..$args) ]>
            | <[ $_meth (..$args) ]> with inst = <[ null ]> =>              
              match (func.TypedObject) // TypedObject == null поэтому поднимается error()
              {
                ... тут туча всего..
                  
                | _ => error(expr)
              }
Re: проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 10:17
Оценка:
Здравствуйте, Jack128, Вы писали:


J>но разве должен вызов макроса паковаться в вариант MacroCall ?


криво фразу сформулировал Я думал, что все вызовы макросов пакуются в PExpr.MacroCall.
Re: проблемы с макросом ToExpression
От: hardcase Пират http://nemerle.org
Дата: 20.04.11 10:18
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { TestMacros.Cond(true, 1, 2) }));


J>макрос ToExpression выдает ошибку conversion from Call (expr: TestMacros.Cond(true, 1, 2)) into 'expression tree' not supported


J>но разве должен вызов макроса паковаться в вариант MacroCall ?


В MacroCall пакуются синтаксические макросы. Макрос в функциональной форме соответствует вызову функции и распознается в процессе типизации.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 12:41
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Jack128, Вы писали:


J>>Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { TestMacros.Cond(true, 1, 2) }));


J>>макрос ToExpression выдает ошибку conversion from Call (expr: TestMacros.Cond(true, 1, 2)) into 'expression tree' not supported


J>>но разве должен вызов макроса паковаться в вариант MacroCall ?


H>В MacroCall пакуются синтаксические макросы. Макрос в функциональной форме соответствует вызову функции и распознается в процессе типизации.


угу, точно. переделал на синтаксический макрос, терь другая проблема.

ToExpression (точнее LinqExprConvertion.ToExpr) не обрабатывает PExpr.Typed, я вроде добавил эту ветку, благо в ветке PExpr.Call практически аналогичнй код, и тут выплыла такая вещь:

вот этот код я скопировал для обработки PExpr.Typed

        | PExpr.Call(func, _parms) => 
          match (expr)
          {
            | <[ $inst . $_meth (..$args) ]>
            | <[ $_meth (..$args) ]> with inst = <[ null ]> =>
              
              match (func.TypedObject) // вот отсюда
              {
                 ...
                  
                | TExpr.Delayed(susp) =>
                  assert2(susp.IsResolved);
                  ToExpr(susp.PExpr, lparms, typer, susp.ResolutionResult) // у меня susp.PExpr : object == expr -> Получаем бесконечную рекурсию.
                | _ => error(expr)
              }

            | _ => error(expr)
          }



как такое может быть???
Re[3]: проблемы с макросом ToExpression
От: hardcase Пират http://nemerle.org
Дата: 20.04.11 13:46
Оценка:
Здравствуйте, Jack128, Вы писали:

J>как такое может быть???


Хм, как-то да выходит (Немерла нету под рукой). А что хочется получить-то?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 14:00
Оценка:
это макрос из немерЗдравствуйте, hardcase, Вы писали:

H>Здравствуйте, Jack128, Вы писали:


J>>как такое может быть???


H>Хм, как-то да выходит (Немерла нету под рукой). А что хочется получить-то?


что вот это работало:

Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { viewmodel(i = 10)})); // viewmodal — это макрос из NemerleOnRails http://code.google.com/p/nemerleonrails/source/browse/NRails.Macros/Mvc/ViewModel.n
Re[5]: проблемы с макросом ToExpression
От: Ziaw Россия  
Дата: 20.04.11 14:56
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { viewmodel(i = 10)})); // viewmodal — это макрос из NemerleOnRails http://code.google.com/p/nemerleonrails/source/browse/NRails.Macros/Mvc/ViewModel.n


Так низя. Макрос viewmodel делает тип для конкретной вьюхи. Не никакого смысла делать его IEnemerable. Тем более нет никакого смысла совать его в виде экспрешена в IQuerable (честно говоря у меня вообще нет понимания, как должен работать IQuerable для Enumerable.Range(0, 10)).

Один из вероятных правильных сценариев:
def Action() : ActionResult
{
  def range = Enumerable.Range(0, 10).Select(i => new (i = 10));
  viewmodel(range)
}
Re: проблемы с макросом ToExpression
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.04.11 15:51
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { TestMacros.Cond(true, 1, 2) }));


А чего ты хочешь добиться?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 17:11
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, Jack128, Вы писали:


J>>Enumerable.Range(0, 10).AsQueryable().Select(ToExpression(fun(i) { viewmodel(i = 10)})); // viewmodal — это макрос из NemerleOnRails http://code.google.com/p/nemerleonrails/source/browse/NRails.Macros/Mvc/ViewModel.n


Z>Так низя. Макрос viewmodel делает тип для конкретной вьюхи. Не никакого смысла делать его IEnemerable. Тем более нет никакого смысла совать его в виде экспрешена в IQuerable (честно говоря у меня вообще нет понимания, как должен работать IQuerable для Enumerable.Range(0, 10)).


да тривиально это работает, все экспрешены компилятся, а получившиеся делегаты отдаются на вход одноименным методам класса Enumerable

Z>Один из вероятных правильных сценариев:

Z>
Z>def Action() : ActionResult
Z>{
Z>  def range = Enumerable.Range(0, 10).Select(i => new (i = 10));
Z>  viewmodel(range)
Z>}
Z>


хм, да, не подумал, можно так обойти.
Re[2]: проблемы с макросом ToExpression
От: Jack128  
Дата: 20.04.11 17:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А чего ты хочешь добиться?


http://rsdn.ru/forum/nemerle/4242679.1.aspx
Автор: Jack128
Дата: 20.04.11


для данного конкретного макроса вопрос решился, тем не менее интересует вопрос, насколько безопасно на вход одному макросу можно отдавать код, сгенерённый другим макросом.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.