Замечания и предложения

Ну вот как раз из за инкапсуляции, чтоб эта переменная не была видна там, где её не надо использовать. Отсутствие инкапсуляции создаёт возможность ошибиться. К примеру, использовать эту переменную вместо другой. Компилятор примет, а такую ошибку будет не легко найти. Можно ещё сделать так:

begin
  //код
  begin 
    var sym: char;
    Repeat
      sym := CurrentIOSystem.read_symbol;
    Until (sym = END_OF_LINE_SYMBOL) or (sym = char(-1)) 
  end;
  //код
end.

Но тогда, приходится делать лишние begin end

Извините, но не нужно путать мягкое с теплым. С чего бы вдруг рекомендации, принятые для блоков begin … end и цикла со счетчиком, стали вдруг руководящими указаниями для циклов с пред- и постусловиями? Для блоков - там понятно, это позволяет компилятору строить более компактный код, да и программисту проще не скакать истерически по листингу в поисках описаний. Для цикла со счетчиком понятно: локализация счетчика не позволяет пользователю “выстрелить себе в ногу”, используя последнее значение параметра цикла за пределами цикла, поскольку значение это языком не определено и остается на усмотрении реализатора. Но циклы с пост- и предусловием тут каким боком?

Я привожу конкретный пример с заменой repeat на while. Я пытаюсь объяснить его логику. Сам я тоже ввёл бы глобальную переменную.

А в одном из ранних Бейсиков, встроенных в прошивку персоналки, была странная константа с комментарием “Так захотел Билл [Гейтс]” - и что? Ну написали так авторы, забожалось им сделать замену на while

Автор выше пишет, что замену сделать сложно и я пытаюсь понять почему. Посмотрел код, не смог понять, где там вообще области видимости вводятся в конструкцию.

Это как раз понятно. Непонятно, почему автоматически нельзя сделать такую инкапсуляцию.

Я уже сказал

Если заключать во внешние begin end и не вставлять принудительно ограничение видимости между repeat и until (если сам пользователь туда блок не вставит с begin end), не видно особенных проблем. Там у вас проблемы появлялись когда переменную пытались после until описывать.

1 лайк

Можете, пожалуйста, добавить в $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:

image

И:

image

Очень похоже на очередное проявление этого бага, но в данном случае его можно легко обойти, добавив эту фичу в $endregion.

1 лайк

Извиняюсь … А что там за проблема то с 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 вообще выбивается из общей картины.

2 лайка

В большинстве функциональных языков - достаточно естественно такие вещи описывать, даже в 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 ?