Макрос, изменяющий синтаксис
От: vaskir Россия vaskir.blogspot.com
Дата: 14.01.16 19:42
Оценка:
Пытаюсь сделать макрос наподобие forindex отсюда
Автор(ы): Чистяков Владислав Юрьевич
Дата: 18.08.2011
Во второй части статьи о макросах Nemerle речь пойдет о макросах уровня выражения, о макросах, изменяющих синтаксис языка, а также о контексте компиляции, доступном в макросах, и тех возможностях, которые он предоставляет (типизации выражений, получении доступа к описанию типов проекта, информации о методах и т.п.).
.

macro RangePattern(body)
syntax ("cond", "(", body, ")") {
    SandboxImpl.DoTransform(Macros.ImplicitCTX(), body)
}

module SandboxImpl {
    public DoTransform(typer: Typer, body: PExpr) : PExpr {
        Macros.DefineCTX(typer);
            
        if (body is <[ $minExpr < $val < $maxExpr ]>)
        {
            <[ $val > $minExpr && $val < $maxExpr ]>
        }
        else
        {
            Message.Error(body.Location, $"Syntax error '$body'"); 
            <[ () ]>
        }
    }
}

Тест:
module Test {
    x(): void {
        def y = 
            def foo = 45;
            def x =  cond (1 < foo < 4);
        }
    }
}


Выдаёт ошибку "Error: Unbound name `foo`". Видимо, $val надо как-то преобразовать?
Re: Макрос, изменяющий синтаксис
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.01.16 00:26
Оценка:
Здравствуйте, vaskir, Вы писали:

V>Выдаёт ошибку "Error: Unbound name `foo`". Видимо, $val надо как-то преобразовать?


Должно так работать. Фу же формируется парсером. Там "цвет" должен быть подходящим.

Сейчас уже плохо соображаю. Завтра погляжу, что там не так.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Макрос, изменяющий синтаксис
От: STDray http://stdray.livejournal.com
Дата: 15.01.16 14:00
Оценка:
Здравствуйте, vaskir, Вы писали:

V>[/nemerle]

V>Тест:
V>
V>module Test {
V>    x(): void {
V>        def y = 
V>            def foo = 45;
V>            def x =  cond (1 < foo < 4);
V>        }
V>    }
V>}
V>


V>Выдаёт ошибку "Error: Unbound name `foo`". Видимо, $val надо как-то преобразовать?


Ошибка в коде теста.
1. Неверно расставлены фигурные скобки.
2.
        def y = 
            def foo = 45;
            def x =  cond (1 < foo < 4);


будет разобрано компилятором как

        def y = {
            def foo = 45;
        }
        def x =  cond (1 < foo < 4);

и foo действительно не связан.

Сам макрос нормально работает
http://files.rsdn.org/95716/condfoo.png
Re[2]: Макрос, изменяющий синтаксис
От: vaskir Россия vaskir.blogspot.com
Дата: 15.01.16 16:10
Оценка:
STD>Ошибка в коде теста.
STD>1. Неверно расставлены фигурные скобки.

OMG, прошу прощения Да, все работает ок.

Кстати, изначально я хотел написать макрос, позволяющий делать паттерн мэтчинг на такую конструкцию:

match (2) {
| cond (1 < foo < 4) => foo + 1
}


Или даже так:

match (2) {
| 1 < foo < 4 => foo + 1
}


Посмотрел, как используется <[case: | ... ]> в исходниках nemerle, но там везде сначала мэтчится весь match из которого выпадает list[MatchCase], который далее мэтчится на <[case: ]>.
Re[3]: Макрос, изменяющий синтаксис
От: vaskir Россия vaskir.blogspot.com
Дата: 15.01.16 18:25
Оценка: 53 (1)
Вроде что-то получилось:

macro RangePattern(body)
syntax ("my", body) {
    SandboxImpl.DoTransform(Macros.ImplicitCTX(), body)
}

module SandboxImpl {
    public DoTransform(typer: Typer, body: PExpr) : PExpr {
        Macros.DefineCTX(typer);
            
        if (body is <[ match ($val) { ..$cases } ]>)
        {
            def cases =
                cases.Map(case => 
                    match (case) {
                    | <[case: | $minExpr < $pvar < $maxExpr when $guard => $res ]>
                    | <[case: | $minExpr < $pvar < $maxExpr => $res ]> with guard = <[ true ]> =>
                        def guards = <[ $val > $minExpr && $val < $maxExpr && $guard ]>;
                        <[ case: | $pvar when $guards => $res ]>
                    | x => x
                    });
                
            <[ match ($val) { ..$cases } ]>                
        }
        else
        {
            Message.Error(body.Location, $"Syntax error '$body'"); 
            <[ () ]>
        }
    }
}


Работает на таком выражении:

my match (2) {
| 1 < x < 4 => x
| 1 < x < 4 when x > 1 => x + 1
| x when x > 10 => 1
}
Re[2]: Макрос, изменяющий синтаксис
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.01.16 18:57
Оценка:
Здравствуйте, STDray, Вы писали:

STD>Ошибка в коде теста.

STD>1. Неверно расставлены фигурные скобки.
STD>2.
STD>
STD>        def y = 
STD>            def foo = 45;
STD>            def x =  cond (1 < foo < 4);
STD>


Это компилируется?

Я даже подумать не мог об этом. Потому и читал тест как 3 присвоения идущих подряд.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.