А в одном из ранних Бейсиков, встроенных в прошивку персоналки, была странная константа с комментарием “Так захотел Билл [Гейтс]” - и что? Ну написали так авторы, забожалось им сделать замену на while
…
Автор выше пишет, что замену сделать сложно и я пытаюсь понять почему. Посмотрел код, не смог понять, где там вообще области видимости вводятся в конструкцию.
Это как раз понятно. Непонятно, почему автоматически нельзя сделать такую инкапсуляцию.
Я уже сказал
Если заключать во внешние begin end и не вставлять принудительно ограничение видимости между repeat и until (если сам пользователь туда блок не вставит с begin end), не видно особенных проблем. Там у вас проблемы появлялись когда переменную пытались после until описывать.
Можете, пожалуйста, добавить в $endregion
фичу позволяющую явно указывать с каким $region
он соеденён?
begin
{$region r1}
{$region r2}
{$endregion r1}//этот $endregion должен соедениться с $region r1
end.
Проблема, ради которой я предлагаю это решение заключается в том, что допустим у меня есть следующий код:
begin
{$region r1.1}
{$region r2.1}
{$endregion r2.1}
{$region r2.2}
{$endregion r2.2}
{$endregion r1.1}
end.
И регион r2.1
свёрнут. Теперь в регион r2.2
добавим регион r3.1
:
begin
{$region r1.1}
{$region r2.1}
{$endregion r2.1}
{$region r2.2}
{$region r3.1}
{endregion r3.1}//А эту строчку ещё не успели написать
{$endregion r2.2}
{$endregion r1.1}
end.
Ещё до того как для r3.1
добавили его $endregion
- большая часть точек сворачивания ломаются, а r2.1
(тот что был свёрнут) не только разворачивается, но его ещё начинает глючить. Когда в каждом регионе по 150 строчек - это заставляет текст программы сходить с ума. Вот примеры того как глючит r2.1
:
И:
Очень похоже на очередное проявление этого бага, но в данном случае его можно легко обойти, добавив эту фичу в $endregion
.
Извиняюсь … А что там за проблема то с repeat-until инкапсуляцией. Я так понял, это здесь начинается
\pascalabcnet\Parsers\PascalABCParserNewSaushkin\ABCPascal.y :
repeat_stmt
: tkRepeat stmt_list tkUntil expr
{
$$ = new repeat_node($2 as statement_list, $4, @$);
($2 as statement_list).left_logical_bracket = $1;
($2 as statement_list).right_logical_bracket = $3;
$2.source_context = @1.Merge(@3);
}
;
Я правильно понял, что …logical_bracket означают как раз инкапсуляцию между repeat-until вместо заключения всей конструкции? То есть
repeat begin … end until expr
используется вместо
begin repeat … until expr end
Кстати, если я попробую поэкспериментировать с этим файлом y, что мне надо потом запустить, чтобы он сгенерировал нужные коды? Или там не всё так просто и надо руками что-то ещё делать?
А зачем? То, что Вы предлагаете, всё равно не будет делаться. В смысле спортивного интереса - чтобы создать дикий язык - его можно поэкспериментировать создать с нуля для собственного интереса.
Ещё раз - задайте себе вопрос: “в каком языке есть то, что я хочу?”
Почему дикий. Понятно же, что выражение в until использует то, что в блоке, почему ему перекрывают вид? Если добавляется некая возможность (в данном случае локальные переменные), то наверное логично её до конца довести. А так получается, что repeat-until вообще выбивается из общей картины.
В большинстве функциональных языков - достаточно естественно такие вещи описывать, даже в TRAC который я недавно упомянул это достаточно наглядно можно было бы пояснить (если там инкапсуляцию пытаться вставить)
#(Repeat-until, statements,expression)
вместо реализованной в данном случае версии
#(Repeat-until,(statements),expression)
Так я и не рекомендую это Вам делать. Более того, при отсутствии деления на стабильную и нестабильную версии я бы даже побоялся, если такое попытаются сделать, если это может привести к каким-нибудь порушениям в синтаксических деревьях. Я поэтому и спрашиваю, как с этим можно проэкспериментировать.
C++ наверно тоже “плохой” по-Вашему…
Ну, что то в этом конечно есть, всё же в C#, C++ и джаве такое запрещено, проверил. В общем это 1 из тех случаев, когда разработчики поступили по стандарту, не зависимо от того - какой он.
Так это естественно в С - я как раз смотрел, в C синтаксическое правило выглядит как
do statement while expression
а в Паскале
repeat statements_list until expression
А Страуструп вообще был против do while конструкции, мол там не инициализируется и приводит к ошибкам. Но это же Паскаль, не С
Лучше на мой взгляд освоить генератор компиляторов и сделать модельный язык, написав затем для него интерпретатор.
Разбираться, как это сделать в PascalABC.NET, по силам только профессиональному разработчику.
А если какие-то совсем небольшие изменения нужны?
Так это его местное гестапо заставило против воли добавить do… while ?
Невозможно. Компилятор - слишком сложная структура.
Я просто наивно полагал, что так как Вы используете Yacc, это всё-таки проще, чем лезть в какой-нибудь Free Pascal.
Что значит против воли добавить. Он написал в книжке не надо использовать, кто использует - сам виноват, зачем убирать конструкцию.