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
}
Макрос, изменяющий синтаксис
От:
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: Макрос, изменяющий синтаксис
Здравствуйте, vaskir, Вы писали:
V>Выдаёт ошибку "Error: Unbound name `foo`". Видимо, $val надо как-то преобразовать?
Должно так работать. Фу же формируется парсером. Там "цвет" должен быть подходящим.
Сейчас уже плохо соображаю. Завтра погляжу, что там не так.
Есть логика намерений и логика обстоятельств,
последняя всегда сильнее .
Re: Макрос, изменяющий синтаксис
Здравствуйте, 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 действительно не связан.
Сам макрос нормально работает
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[2]: Макрос, изменяющий синтаксис
Здравствуйте, STDray, Вы писали:
STD>Ошибка в коде теста.
STD>1. Неверно расставлены фигурные скобки.
STD>2.
STD>STD> def y =
STD> def foo = 45;
STD> def x = cond (1 < foo < 4);
STD>
Это компилируется?
Я даже подумать не мог об этом. Потому и читал тест как 3 присвоения идущих подряд.
Есть логика намерений и логика обстоятельств,
последняя всегда сильнее .
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить