как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 14:11
Оценка:
Добрый день! Возник вопрос: как мне вывести на экран некоторый AST во всех деталях? Я видел, что в базовых классах выражений перегружен метод ToString(), но он дает слишком мало информации для моего случая. Хотелось бы получить что-то вроде E_call(E_ref("f"), [Parm(E_ref("x"))] (как в разделе 9.1 статьи Метапрограммирование в Nemerle
Автор(ы): Kamil Skalski, Michal Moskal и Pawel Olszta
Дата: 23.05.2006
Пример C++ показывает, что индустрии нужны системы метапрограммирования – даже достаточно причудливая система шаблонов широко используется для вычислений во время компиляции. Эта статья является исследованием возможного внедрения техники метапрограммирования в индустриальную среду в более чистой форме. Мы, таким образом, фокусируемся на том, чтобы сделать нашу систему легкой в использовании для программистов, как пишущих, так и использующих макросы.
).
Re: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.11 14:28
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Добрый день! Возник вопрос: как мне вывести на экран некоторый AST во всех деталях? Я видел, что в базовых классах выражений перегружен метод ToString(), но он дает слишком мало информации для моего случая. Хотелось бы получить что-то вроде E_call(E_ref("f"), [Parm(E_ref("x"))] (как в разделе 9.1 статьи Метапрограммирование в Nemerle
Автор(ы): Kamil Skalski, Michal Moskal и Pawel Olszta
Дата: 23.05.2006
Пример C++ показывает, что индустрии нужны системы метапрограммирования – даже достаточно причудливая система шаблонов широко используется для вычислений во время компиляции. Эта статья является исследованием возможного внедрения техники метапрограммирования в индустриальную среду в более чистой форме. Мы, таким образом, фокусируемся на том, чтобы сделать нашу систему легкой в использовании для программистов, как пишущих, так и использующих макросы.
).


Если нужны детали, то имеет смысл не печатеть АСТ, а рассматривать его под отладчиком. Там можно все что угодно увидеть. Вставляешь в макрос assert2(flase), жмешь Retry в появившемся окне делаешь шаг, чтобы выйти из контекста assert-а и в окне Locals или Watch1 смотришь что в переменных.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 14:48
Оценка:
Иногда хочется просто дампнуть текст — у меня, например, студия не установлена, и я пишу в емаксе. В любом случае, я нафигачил простенькую реализацию на рефлекшне. Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)

using System;
using System.Linq;
using System.Text;
using System.Console;
using System.Reflection;
using System.Reflection.BindingFlags;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;

class Helper
{
    public static Render(this exprs : list[PExpr]) : String
    {
        def buf = StringBuilder();
        buf.Append("[");

        mutable first = true;
        foreach (expr in exprs)
        {
            if (first) { first = false; }
            else { buf.Append(", "); }

            buf.Append(expr.Render());
        }
                                                             
        buf.Append("]");
        buf.ToString();    
    }

    public static Render(this expr : PExpr) : String 
    {
        def buf = StringBuilder();
        def t = expr.GetType();
        buf.Append(t.Name);
        buf.Append("(");

        mutable first = true;
        foreach (f in t.GetFields(Public | Instance | DeclaredOnly))
        {
            if (first) { first = false; }
            else { buf.Append(", "); }

            buf.Append(f.Name);
            buf.Append(" = ");

            def v = f.GetValue(expr);
            if (v is PExpr) buf.Append((v :> PExpr).Render());
            else if (v is list[PExpr]) buf.Append((v :> list[PExpr]).Render()); 
            else buf.Append(v.ToString());
        }
                                                             
        buf.Append(")");
        buf.ToString();
    }

    public static Dump(this exprs : list[PExpr]) : void
    {
        WriteLine(exprs.Render());
    }

    public static Dump(this expr : PExpr) : void
    {
        WriteLine(expr.Render());
    }
}
Re[3]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.11 14:59
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Иногда хочется просто дампнуть текст — у меня, например, студия не установлена, и я пишу в емаксе. В любом случае, я нафигачил простенькую реализацию на рефлекшне.


Можно и так. Еще погляди темы FDSC. Он тоже пытался так АСТ изучать. Там кроме рефлекшона еще было решение на лифтинге через макро-апи.

XB>Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)


Дык потому я в свое время за немерл и взялся. С одной стороны намного привычнее, а с другой есть те самые макросы (которые меня и интересовали тогда).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.11 15:06
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)


Да... Кстати, отвыкай. Эффективность повысится раз в 10, если освоишь продвинутые методы. Например, вот этот кусок кода:
XB>    public static Render(this exprs : list[PExpr]) : String
XB>    {
XB>        def buf = StringBuilder();
XB>        buf.Append("[");

XB>        mutable first = true;
XB>        foreach (expr in exprs)
XB>        {
XB>            if (first) { first = false; }
XB>            else { buf.Append(", "); }

XB>            buf.Append(expr.Render());
XB>        }
                                                             
XB>        buf.Append("]");
XB>        buf.ToString();    
XB>    }

Сворачивается в:
    public static Render(this exprs : list[PExpr]) : String
    {
      $<#..$(exprs; ", "; expr.Render())#>
    }


При этом, собственно, сам метод становится не особо то и нужным, так как выражение можно и по месту подставить.

Так же имеет смысл поглядеть макрос StringTemplate:
https://github.com/rsdn/nemerle/blob/master/ncc/testsuite/positive/string-template-1.n
https://github.com/rsdn/nemerle/blob/master/ncc/testsuite/positive/string-template-2.n
https://github.com/rsdn/nemerle/blob/master/ncc/testsuite/positive/string-template-3.n

Это, кстати, и есть демонстрация силы ДСЛ-подхода. Код практически равен декларации намерений.

И код получается очень эффективным.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 15:16
Оценка:
О! Крутота!! На сишарпе я бы написал просто exprs.StringJoin(expr => expr.Render()), но тут у меня нету моей библиотечки с хелперами. Впрочем, твой вариант еще круче.
Re[4]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 15:18
Оценка:
Кстати, дословно твой пример не прокатил — выдает ошибку unbound name `expr'.
Re[5]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 15:21
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Кстати, дословно твой пример не прокатил — выдает ошибку unbound name `expr'.

Окей, надо было просто написать $<#..$(exprs; ", "; Render)#>. А что будет, если вызываемый метод требует более одного параметра? Как в таком случае сослаться на переменную итерации?
Re[5]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.11 17:28
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>О! Крутота!! На сишарпе я бы написал просто exprs.StringJoin(expr => expr.Render()),


И получил бы создание временного объекта (делегата) и косвенный вызов на ровном месте. Плюс, все равно не достиг бы той же выразительности.

XB>но тут у меня нету моей библиотечки с хелперами. Впрочем, твой вариант еще круче.


Это как раз не проблема. Подключай библиотеку и пользуйся. Дотент, однако .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.09.11 17:37
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>>Кстати, дословно твой пример не прокатил — выдает ошибку unbound name `expr'.


Это я лохонулся. Надо было так:
$<#..$(exprs; ", "; _.Render())#>

Это так называемое частичное применение. В скале его тоже вроде бы ввели. Кстати, как я понимаю, содрали с немерла.
Частичное применение это сахар для лямбд, заменяющий отсутствие автоматического каррирования.


XB>Окей, надо было просто написать $<#..$(exprs; ", "; Render)#>. А что будет, если вызываемый метод требует более одного параметра? Как в таком случае сослаться на переменную итерации?


Лямбду описать.
$<#..$(exprs; ", "; expr => expr.Render(a, b, c))#>


Или ввести локальную фукнцию:

def convert(expr)
{
  делаем что хотим... и возвращаем строку
}
$<#..$(exprs; ", "; convert)#>


В общем, в третьем разделе требуется функция преобразования элемента в строку.

Здесь описание для $-строк.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 28.09.11 18:54
Оценка:
А, понятно. Я думал, что там магический синтаксис, а это просто лямбда. Кстати, справедливости ради, подчеркивания как плейсхолдеры в лямбдах в скале были с самого начала, а самое начало было за несколько лет до Немерле.
Re[8]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.11 17:46
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>А, понятно. Я думал, что там магический синтаксис, а это просто лямбда. Кстати, справедливости ради, подчеркивания как плейсхолдеры в лямбдах в скале были с самого начала, а самое начало было за несколько лет до Немерле.


Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 29.09.11 17:50
Оценка:
VD>Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Виноват, обязательно уточню.
Re[9]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 03.10.11 14:35
Оценка:
VD>Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Мартин говорит, что эту штуку для Скалы они придумали самостоятельно. Она, действительно, была не с самого начала. Но когда точно ее добавили — он не помнит, а в логах пока не нашел.
Re[10]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.10.11 18:41
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Мартин говорит, что эту штуку для Скалы они придумали самостоятельно. Она, действительно, была не с самого начала. Но когда точно ее добавили — он не помнит, а в логах пока не нашел.


Ну, все так всегда говорят . Единственное доказательство первенства — это дата коммита в котором реализована фича.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: как распечатать AST во время компиляции?
От: xeno.by xeno.by
Дата: 03.10.11 18:43
Оценка:
VD>Ну, все так всегда говорят . Единственное доказательство первенства — это дата коммита в котором реализована фича.
Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?
Re[12]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.10.11 19:00
Оценка:
Здравствуйте, xeno.by, Вы писали:

XB>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?


Бывают конечно. Но тут есть два "но". Во-первых, при этом они, обычно, не являются похожи как две капли воды. Во-вторых, независимое открытие велосипеда — это доказательство недалекости и лени велосипедостроителя. Он должен был изначально изучить имеющиеся конкурирующие продукты и узнать что в них есть интересного. Так что, на мой взгляд, независимое открытие велосипеда хуже чем завимсовование фичи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: как распечатать AST во время компиляции?
От: gerrCrazzy  
Дата: 04.10.11 18:27
Оценка: 4 (2)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, xeno.by, Вы писали:


XB>>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?


VD>Бывают конечно.


Я тут поразмахиваю Схемой из 2002 года, чтобы вы не ссорились.
Re[14]: как распечатать AST во время компиляции?
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.10.11 14:41
Оценка:
Здравствуйте, gerrCrazzy, Вы писали:

XB>>>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?


VD>>Бывают конечно.


C>Я тут поразмахиваю Схемой из 2002 года, чтобы вы не ссорились.


А можно узнать чем конкретно ты решил по размахивать?

Мы тут вообще-то говорили о использования синтаксиса используемого в скале и немерле. Твоя ссылка имеет мало общего с этим синтаксисом. Разве что сама идея частичного применения без каринга.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: как распечатать AST во время компиляции?
От: gerrCrazzy  
Дата: 05.10.11 21:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Мы тут вообще-то говорили о использования синтаксиса используемого в скале и немерле. Твоя ссылка имеет мало общего с этим синтаксисом. Разве что сама идея частичного применения без каринга.


Мопед в общем-то не мой, но люди недавно реализовали частичное применение в Erlang именно с синтаксисом Nemerle:

Cut: This adds support for cuts to Erlang. These are inspired by the Scheme form of cuts.
Cuts can be thought of as a light-weight form of abstraction, with similarities to partial application (or currying).

Разумеется, есть вероятность того, что нам не договаривают, и вовсе не Scheme был прообразом этой фичи. Разработчики тупо ночью подсмотрели и утащили к себе Немеролвую реализацию.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.