Ошибки PascalABC.NET

Нет. Вы неверно трактуете. Эти последовательности сами по себе не существуют. Они существуют только перед операндом: -z, --z. Второе трактуется как -(-z).

А позвольте спросить: зачем в выражении --z скобки? Скобки ставятся если порядок может быть различным и от этого зависит результат. Например, в 1 * (2 + 3). А здесь невозможно поставить скобки вообще никак кроме как одним способом.

И это правильно, поскольку в С++ в свое время много было писано про точки следования и ошибку UB (“Если программа пытается модифицировать одну переменную дважды не пересекая точку следования, то это ведет к undefined behavior”), посему лучше и не поднимать вопроса о значении выражения вида i=i++ + ++i;

Нет, я трактую именно так, как Вы написали, это я неверно выразился, думая, что “и так понятно”. Согласен, что надо писать так, чтобы была однозначность и это мой ляп.

Но вот Фортран, к примеру, запрещает писать i=i+++i, а интерактивные IDE в бейсиках после ввода i=i++++++i оставляют i=i+i. Я потому и отметил, что речь не о всех языках.

Этого же можно достичь и в других языках, вызывая i := f() + f() Так что дело не в C++.

Ещё раз повторю, что в выражении --z всё в порядке с трактовкой

Так я же с Вами не спорю))))

1 лайк

Предлагайте

1 лайк

Конечно, не в С++, а в том, что операция + не создает точки следования.

Ну раз нереально починить - надо сделать хотя бы чтоб не мешало.

Я говорю именно про количество, а не частоту. Конечно такая пакость редко попадается, но всё же попадается.

Это ведь не сложно, поставить 1 if проверяющий, есть ли какие то данные об ошибке, если нету - не выводить меседжбокс и не переставлять курсор.

Так мы ж и сделали такую пакостную ошибку чтобы её исправлять. А то если это пакостное окно не будет показываться - Вы и не будете писать про ошибку :slight_smile:

И когда волки оказались сыты, а овцы остались целы, возникла новая проблема: как накормить овец?

Чтобы не попасться в этот капкан, надо делать пакостные ошибки. :stuck_out_tongue_winking_eye:

  1. Кстати говоря, среда позволяет писать русскими буквами идентификаторы, то почему бы не добавить возможность написания ключевых слов языка русскими словами? Это к удобству - поскольку переключаться между раскладками не очень удобно. И начинающие могут языка английского не знать - на русском было бы им гораздо легче. Как смотрите на эту идею, разработчики?
  2. Вторая идея - добавить сниппеты для простых языковых конструкций, например, для: if, while, for, foreach, class, record.

Для того чтоб полностью писать на русском языке есть ёпта-скрипт и ему подобные))). А в паскале эта возможность добавлена шоб було, ради её продвижения захламлять ключевые слова не стоит. Разве что если включать это какой то директивой…

Надо добавить возможность управления ими из IDE и сохранение между версиями. Так то они уже есть, к примеру набираете be в начале файла и нажимаете Shift+Space, вам ставит begin end.. Список сниппетов, с которыми уже работает паскаль есть в файле

C:\Program Files (x86)\PascalABC.NET\template.pct.

1 лайк

Да, переключать раскладку проблематично, но читать текст с русскими идентификаторами порой очень хорошо. Гораздо лучше чем с транслитом типа PoiskProstovaChisla.

Ключевые слова русскими - мы пробовали, но плохо. Просто получается перевод ключевых слов один в один. Но - ужас:

для и := 1 до 10 делать
нц
  переменная жи := и * 2;
  Print(жи)
кц
2 лайка

Попытка сделать русифицированный Паскаль была и называлась она “Глагол”

 ОТДЕЛ Привет+;
 
 ИСПОЛЬЗУЕТ Вывод ИЗ "...\Отделы\Обмен\";
 
 УКАЗ
   Вывод.Цепь("Привет!")
 
 КОН Привет.

Как говорится, “Спаси и сохрани нас, Господи!” Я не готов морально вместо longint писать ширцел :tired_face:

Русские идентификаторы - зачастую хорошо. Не далее как сегодня решал школьную задачку.

Summary
type
  Монетка=(Орел,Решетка);
  КорзинаЯблок = List<integer>;
    
function БросокМонетки:=Random(2)=1 ? Орел : Решетка;

function ЗаполнитьКорзину(d:char):КорзинаЯблок;
// считаем, что яблоко весит от 100 до 250 г,
// и что в корзину вмещается около 8 кг яблок.
begin
  Result:=new КорзинаЯблок;
  var ВесЯблок:=0;
  while ВесЯблок<=8000 do begin
    var Яблоко:=Random(100,250);
    Result.Add(Яблоко);
    ВесЯблок+=Яблоко
    end;
  if d='1' then begin
    Write('Яблоки в корзине: ');
    Result.Println
    end;
end;

procedure ВзятьЯблоко(Корзина:КорзинаЯблок; var Яблоко:integer);
begin
  if БросокМонетки=Орел then begin
    Яблоко:=Корзина.Last;
    Корзина.RemoveAt(Корзина.Count-1)
    end
  else begin
    Яблоко:=Корзина.First;
    Корзина.RemoveAt(0)
    end
end;

procedure ЯблокоМальчику(Корзина,ЯблокиМальчика:КорзинаЯблок);
begin
  var Яблоко:integer;
  if Корзина.Count>0 then begin
    ВзятьЯблоко(Корзина,Яблоко);
    ЯблокиМальчика.Add(Яблоко)
    end
end;

begin
  Randomize;
  var ЯблокиСерика:=new КорзинаЯблок;
  var ЯблокиБерика:=new КорзинаЯблок;
  var n:=ReadlnInteger('Собрано корзин:');
  var d:=ReadlnChar('1 - отладочный вывод, иное - только результат:');
  loop n do begin
    var Корзина:=ЗаполнитьКорзину(d);
    while Корзина.Count>0 do begin
      ЯблокоМальчику(Корзина,ЯблокиСерика);
      ЯблокоМальчику(Корзина,ЯблокиБерика);
      end;
    if d='1' then begin
      Write('Яблоки Серика: ');
      ЯблокиСерика.Print; Writeln(' Вес: ',ЯблокиСерика.Sum);
      Write('Яблоки Берика: ');
      ЯблокиБерика.Print; Writeln(' Вес: ',ЯблокиБерика.Sum)
      end
    end;
  Writeln('Общий вес яблок Серика: ',ЯблокиСерика.Sum,
      ', общий вес яблок Берика: ',ЯблокиБерика.Sum)
end.

P.S. Кто-нибудь расскажет, почему тут не работает тег [spoiler] и что писать вместо него?

1 лайк

Насчёт спойлера - тут, на форуме, есть кнопка…

image

Там под ней всё что надо. И рядом с ней ещё и Blur Spoiler, сам не знал, кстати :sweat_smile:.

1 лайк

Кстати, кто-нибудь знает, тут можно как-нибудь проще и быстрее (типа в одно касание/клик) копировать весь текст в clipboard из длинных код-боксов (без долгого и нудного выделения сначала его мышкой, а затем copy). На некоторых программерских форумах встречалась специальная отдельная кнопка под/над код-боксами – очень удобно. Может в админских настройках где-то есть подобное?

1 лайк

И опять же, вот предупреждения умеют ставить пустое поле для названия файла и номера строчки, в случае когда разработчик не позаботился о нормальном описании. Когда на них дбл кликаешь - они не показывают меседжбокс и не переставляют курсор, они вообще не сработывают при дбл клике. Почему нельзя так же с ошибками?!

type
  t1=class(System.IDisposable)
    public constructor := writeln('new t1');
    public destructor destroy; begin writeln('destroy') end;
    public destructor d1; begin writeln('d1') end;
    public destructor d2; begin writeln('d2') end;
    public procedure Dispose := writeln('Dispose');
  end;

procedure p1;
begin
  var o := new t1;
end;

begin
  begin
    p1;
  end;
  System.GC.Collect;
  Sleep(100000);
end.

Почему тут не вызывается ни деструкторы, ни Dispose? Это ошибка? Или код очистки надо ставить не в декструкторы и не в Dispose? Тогда куда?

И ещё 1:

type
  r1=record
    _b:byte;
    public property b:byte read _b write _b;
    
    function ToString:string; override := $'[b={_b}]';
  end;
  t1=class
    
    _p1:r1;
    
    function ReadP1:r1;
    begin
      writeln($'getting p1 = {_p1}');
      Result := _p1;
    end;
    
    procedure WriteP1(a:r1);
    begin
      writeln($'replacing {_p1} with {a}');
      _p1 := a;
    end;
    
    property p1:r1 read ReadP1 write WriteP1;
    
  end;

begin
  var a := new t1;
  a.p1.b := 1;//компилируется, но ничего не делает
  a.p1.b += 1;//компилируется, но ничего не делает
  writeln(a._p1);
  //a.p1._b += 1;//Ошибка: Нельзя присвоить левой части
end.

Свойству r1.b даёт присваивать и изменять значение, но его не сохраняет. А полю r1._b не даёт изменять значение. Это нормальное поведение?

Хорошо, @ibond, а как тогда вызывать I1.p1? И как вызывать System.Collections.Generic.IEnumerable<T>.GetEnumerator?