Ошибки PascalABC.NET

Нет, всё правильно, потому что следующий код тоже не вызовет ошибку:

begin
  var a := Arr(1,3,5);
  for var i := 5 to a.Length-1 do
    writeln(a[i]);
end.

Узнать как оно работает точнее, потому что для этого используется WinAPI. Но в любом случае, это стандартная функция .Net . Паскаль лишь добавляет вывод 0 когда subs пустая или nil, вместо исключения.

так там sub не пустая, там пробел, ну можно по другому

begin
  var s := 'ABC';
  var i := Pos('C', s);
  write(Pos('C', s, i + 1));
end.

тут тоже нет ошибки, а вот если Pos(‘C’,s,i+2) то уже выдает ошибку

А вот как… Похоже, оно вот так сопоставляет from со строкой:

image

В .Net версии там идёт от 0 до 3, но паскаль посылает .Net версии from-1 вместо from, поэтому получается от 1 до 4.

В случае когда вы посылаете i+1 (что было бы просто i, если бы не было -1 выше) - вы ищите в пустой строке, что допустимо.

Действительно, зачем всё сдвигать на еденичку - не понятно. Но то что значения больше i+1 выдают ошибку это стандартный функционал .Net .

Не должна быть. Поправили реализацию. В обновлении будет работать корректно - без исключений

2 сообщения перенесены в тему Болталка PascalABC.NET

begin
  var i: integer?;
  i := true ? nil : 5;
end.

Пишет что нельзя присвоить value-типу nil, хотя в данном случае подразумевается что результат будет Nullable. Это ошибка?

В C# это тоже не работает:

int? j = true ? null : 5;

Там сообщение об ошибке другое

Тут разрешает НЕ ставить точки с запятой:

type
  t1=class
    
    b1:byte
    
    public
    
    b2:byte
    
  end;

begin end.

А с методами так не проходит:

type
  t1=class
    
    function f1:byte := 0
    
    public
    
    function f2:byte := 0
    
  end;

begin end.

Так и задумано?

К сожалению, да. В конце секции можно не ставить. Это сделано для совместимости с Delphi и Borland Pascal. Там такое компилируется

type
  t1=record
    b1:byte
  end;

Методов внутри там нет, потому для методов мы это уже запретили

15 мая был откачен фикс #796, и с того момента стало ещё хуже. Теперь не только компилятор не работает для var d: t1 := (a + b).f1. Теперь эта строчка ещё и полностью ломает анализатор кода:

image

Точки сворачивания просто не появляются.

Можете, пожалуйста, объяснить ситуацию с этой issue, чтоб я понимал что является ошибкой а что нет?

И, желательно, исправить хотя бы сообщение об ошибке, потому что Встречено '.', а ожидалось ';' полностью сбивает с толку. В такой короткой строчке ещё можно догадаться что не так, но я успел отбить себе лоб об эту невидимую стену, в местах где всё не так элементарно.

Конструкция (a + b).f1 давала конфликты в грамматике. Как-то мы это пропустили.

Конфликты в грамматике - это вот что такое. Это значит, что правильная программа случайно может оказаться неправильной и наоборот. Причем, непредсказуемо. Это - кошмар.

Эта ошибка просуществовала какое-то время. Плохо, что мы её заметили не сразу. Откатили.

По поводу сообщения об ошибке. Оно Вам не нравится, но оно верное. После (a+b) может идти точка с запятой. Точка теперь идти не может. Вот и выдаётся это сообщение об ошибке.

t1(a + b) - это вызов функции - после него точка может идти

То, что Вы хотите всё-таки точку, вас сбивает

Вот так работает - уже прекрасно )))

begin
  var (a, b) := (3, 5);
  (a+b).ToString.Println
end.

Ну так правильно. В заголовке issue так и сказано, надо не только оператор, а ещё и объявление переменной с : <тип этой переменной>. И это главная проблема. Во всех случаях после скобок даёт ставить точку. По крайней мере я не знаю таких. А тут, вдруг.

Но это всё же не повод говорить что вы никогда не исправите. Хотя бы оставьте ту issue, отложив в долгий ящик. Это всё же лучше.

И что с анализатором кода? Он, вроде, на момент создания issue не был сломал и сломался только после отката. То как он себя в этой ситуации ведёт - ну очень не хорошо.

Ну, мы не умеем побеждать конфликты в грамматике и заставлять солнце двигаться в другую сторону. Можно конечно Issue на что угодно, но не поможет.

Хорошо, если вы не будете исправлять - напишите об этой особенности языка в справке или где то ещё. И добавьте своё сообщение об ошибке, которое будет объяснять почему это всюду после скобочек можно использовать точку, а тут нельзя. Такого типа:
Использование "." после оператора, на строчке с объявлением переменной и её типа - запрещено.
Длинно, но вы поймите, отсутствие нормального объяснения не только сбивает с толку в смысле “а что я сделал не так?”, а ещё и в смысле “это ошибка или так и задумано?”. Через пол года, когда я забуду про эту недо-фичу - я снова потрачу много времени на попытки найти что вызвало такое странное поведение, только чтоб в конце понять что это ещё один дубль #796. Очень демотивирует, знаете ли, когда много труда и времени выбрасывается в форточку.

2 лайка
begin
  var d:=new Dictionary<byte,word>;
  d.Add(1,2);
  //var s:sequence of word := d.Values + word(5);//Ошибка: Нет перегруженной подпрограммы с такими типами параметров
  var s:sequence of word := IEnumerable&<word>(d.Values) + word(5);
  s.Println;//Выводит "2 5", как и ожидалось
end.

Почему тут не даёт написать d.Values + word(5), это ошибка?

Есть серия issue. Общее у них то что у как то полученной записи вызывается метод, и компилятор создаёт для этого вызова не правильный IL код. Прослеживается следующая тенденция:

  • #901 - метод возвращает запись;
  • #910 - конструктор возвращает запись;
  • #974 - глобальная/статичная функция возвращает запись;

Я вот не могу вспомнить, есть ещё какой то способ получить запись? Напишите, если знаете, если с этим способом тоже генерируется не правильный IL код - возможно получится исправить ошибку до того как она сломает чью то программу.

@admin, @ibond, можете пожалуйста посмотреть сюда и сказать, является ли внутренняя ошибка при компиляции test.pas ещё 1 проявлением #951?

Там 5 модулей, циклично скреплённых друг с другом, очень не хочется без лишней причины всё это разгребать))).