То есть, в случае с #69 - Chr не используется. На конец стека загружает число 69 и после этого его под видом char передают во write.
И даже если бы использовалось Chr, я не могу понять вашу логику. Chr($45) работает нормально. Как и const const1 = $45;, константы то не ломается от того что в них разрешили чтоб перед числом вплотную стоял $. И case тоже…
“Перестаньте мне тыкать в нос вашей проклятой латынью!” (с)
Ну причем тут декомпиляция? Кому нужны детали внутренней реализации? Запустите Вашу программу и посмотрите на результат. - он одинаков, следовательно ДЛЯ ПОЛЬЗОВАТЕЛЯ эти конструкции - синонимы.
Речь о том, что сочетание символов #$ синтаксически запрещено.
“Перестаньте мне тыкать в нос вашей проклятой латынью!” (с)
Я не прошу вам понять всё что там написано (для простейшего понимания я добавил приписку в конце того ответа). Но не так уж сложно заметить, что в первом случае ( #69 ) нету
из второго ( Chr(69) ). “call” переводится как “вызвать”, если что))
Я не уверен на 100% как оно сделано, но вроде парсинг выражений это отдельная штука, не зависящая от того в case выражение или в ?:. Поэтому его не надо будет учить работать с каждой другой фичей.
Вы так сильно уверены, что мне непонятно написанное Вами? ))) Думаю, буду недалек от истины, предположив, что я писал программы на ассемблере, когда еще Ваши родители пешком под стол ходили.
Куда важнее, что мы действительно не знаем “как оно там сделано”. Я даже допускаю крамольную мысль, что часть кода писали люди, покинувшие команду и нынешним разработчикам тоже местами не совсем все ясно. Поэтому мы не можем оперировать идеями о том, что там где надо “подкрутить”.
Ну, не совсем ясно тут не страшно. Потому что это во многих местах, и что то обязательно забудется вначале. Потом систему тестов надо писать, не забыть ограничение на максимальную константу, потом автоформатирование и тесты для автоформатирования, потом интеллисенс. Много вообщем всего.
Если я правильно помню, у Вас был главный нерешенный вопрос, что должен возвращать срез - матрицу, массив массивов, массив последовательностей и т.д. Ну и синтаксис для среза матрицы до конца не устоялся. Опять же, безопасные срезы должны быть или нет?
А как с синтаксисом быть? Паскаль же не пропустит конструкции вида a[, :5], которая означает, что в срез попадут колонки 0…4 по всем строкам, а писать a[0:a.RowCount, :5] - это совсем уж некузяво. Да и не знаю, даже если писать a[0:, :5] - тоже, хорошо ли это?
Иными словами, предположим, я реализую некую процедуру (или их набор) для работы со срезами, но как быть с параметрами? Передавать пока туда одну символьную строку вида ‘, :5’ и парсить там ее?
Может, сделаем так: я подумаю над реализацией, а Вы - над приемлемым синтаксисом для срезов в тех случаях, когда по одному из измерений срез не производится?
И еще, “старая песня”: срез мы сделали, он потом куда, раз уж матрицу вернули? На присваивание? У нас с матрицами (на мой взгляд, конечно) проблема осталась, толком не решенная: как получить в функциональном стиле новую матрицу на основе прежней. У нас есть работающий по всей матрице Transform, будет срез - он и по срезу будет работать. Но можно ли модифицированный срез назад запихнуть? По-моему нет, потому что это потребует разрешить срезы в левой части оператора присваивания, что противоречит функциональному программированию. А как тогда? Только ужасающие циклы либо жуткая лямбда в Transform, которая из-за замены 15 элементов в массиве 1000х1000 сделает миллион трансформаций? Ну просто суперэффективно… (((
А что в случае a[1, 2:3]? тоже матрицу, 1x2 ? Может всё же массив?
Почему? Ну, Transform, конечно, не сработает, потому что он процедура. Но можно сделать что то такое:
function TransformFunc<T>(self:array[,] of T; f: T->T):array[,] of T; extensionmethod;
begin
self.Transform(f);
Result := self;
end;
begin
var a := new integer[9,9];
a[2:3, 4:5] := a[4:5, 2:3].TransformFunc;
end.
a[:,:] - вся матрица
a[2:,:3] - да пожалуйста
a[1,:] - одномерный массив
a[:,2] - одномерный массив
Всё это копии разумеется. Других проблем не решают.
Синтаксис сделаем потом.
Вам надо разобраться в реализации функций
function CheckAndCorrectFromToAndCalcCountForSystemSlice
procedure CorrectFromTo
procedure CheckStepAndCorrectFromTo
function SystemSlice
function SystemSliceArrayImpl
CreateSliceFromArrayInternal
и все связанные. И по идее сделать такие же, но двумерные
type VV = class
public
a: array of integer;
class procedure operator:=(var left: VV; right: integer);
begin
for var i:=0 to left.a.Length-1 do
left.a[i] := right;
end;
constructor(aa: array of integer) := a := aa;
end;
function Meth(Self: array of integer): VV; extensionmethod;
begin
Result := new VV(Self);
end;
begin
var a := new integer[5];
var x := a.Meth;
x := 3;
Print(a);
end.
Если бы можно было по синтаксису a.Meth использовать в левой части присваивания,
то пазл бы сложился. Представьте себе, что a.Meth - это a[2:5]
Подождите, почему? Можно же определять когда срез в левой части, и вместо того чтоб выдавать ошибку “нельзя присвоить левой части” - превращать это выражение в вызов процедуры:
Ну да ну да, но это - бОльшая кровь. Это надо затрагивать не только конструкцию a.Meth, но и мучить оператор присваивания.
А это - провоцирование ошибок.
Хотя - можно попробовать: