Ошибки PascalABC.NET

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 модулей, циклично скреплённых друг с другом, очень не хочется без лишней причины всё это разгребать))).

свойство типа записи, поле типа запись, приведение оbject к типу запись

Инициализация массива массивов в сокращенной форме. Ошибка выполнения: Индекс находился вне границ массива.

begin
  var c: array of array of integer := ((1,2,3),(4,5,6,7),(6,7,8)); //тут ошибка рантайма
  c.Println
end.

А вот пример, который в справке

begin
  var c: array of array of integer := ((1,2,3),(4,5),(6,7,8));
  c.Println;//[1,2,3] [4,5,0] [6,7,8]
end.

вроде бы и работает, но почему второму под-массиву (ну который первый по индексу) дописывается третий элемент - 0?

Да, это правильно. Память подстраивается под первую строку.

Вообще, эту инициализацию я бы запретил - именно из-за неё у нас большие проблемы с различием между

var x := выражение;

и

То есть, синтаксис старой Delphi нас тянет назад
var x: T := выражение;

Так это ошибка или нет, я не понял. А еще можно спросить, у вас написано в справке, что

var a := Arr(Arr(1,3,5),Arr(7,8),Arr(5,6)); // array of array of integer

но при наведении на переменную в рамке пишет: var a: array of T; как это понять, компилятор не выводит тип или справка не соответствует? %D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA

Это не ошибка.

Система Intellisense, выводящая типы при наведении, у нас не такая мощная и не выводит тип T.

Ну, в #884 вы тоже сказали что это слишком сложно для вашего анализатор кода, но оказалось просто. Давайте всё же разберёмся перед тем как говорить что вы не сможете это реализовать.

Но это сбивает с толку. И какой массив получается на выходе? С подмассивами одинаковой длины “отнормированными” по первому? А зачем? Вся фишка массива массивов в том, что у него внутренние массивы разной длины, а так получается, что, в лучшем случае, их дополняет нулями. И что же делать? Инициализировать другими способами можно, но что с этим способом? Уберете его?

1 лайк

ibond у нас ответственный за Intellisense. А где я говорил, что не будем реализовывать?

А может вспомнить, что основная ниша - это обучение и не оглядываться постоянно на Delphi там, где это вредит языку?

Как пример, была такая настольная СУБД - FoxPro. Еще в ДОС-версиях, тогда еще Microsoft и не думал ее приобретать. Кроме совершенно новых и продвинутых инструментов, она содержала в себе все, что было у предшественников - dBASE и FoxBASE, как и PasalABC.NET содержит в себе “наследие предков”. Это было понятно: имелось большое количество старых наработок и надо было дать возможность безболезненного портирования. Потом появились версии Visual FoxPro (VFP в народе), которые по-прежнему тащили в себе груз еще от dBASE - но это оправдывалось тем, что "а вот люди перешли со старых программ на FoxPro/DOS и теперь им надо обеспечить портирование под VFP. Выходили новые версии VFP, впечатленная производительностью, эту СУБД приобрела Microsoft. А старое наследие в языке так и оставалось. И только в последних версиях, когда уже ясно стало, что сохранение “старья” тормозит новые концепции, от него начали избавляться. Да и то в виде полумеры: директивным переключением движка СУБД между разными синтаксисами.

Может, пора бы и в PascalABC.NET кое от чего избавиться, если оно сильно мешает, а не воевать с этими ветряными мельницами? А то может получиться, как старом анекдоте.

Посетитель небольшого кафе делает заказ и в ожидании разглядывает интерьер. Его внимание привлекает большой транспарант: “Война мухам!”. Между тем мухи с немалым энтузиазмом в заведении присутствуют. Посетитель интересуется у официанта, как это соотносится с лозунгом о войне и получает ответ: “Да, война была. Но мы проиграли…”

Не хотелось бы проиграть войну из-за вопроса совместимости чего-то там с какой-то устаревшей Delphi.

1 лайк

Вы сказали что это не ошибка. не_ошибка, в моём понимании, это то что так и задумано, а значит и не должно быть исправлено. Ну ладно, тогда тоже закину в issue.