Zorko писал(а):
Олеж, я тут заметил, что для Спека все три варианта реализации нашего FOR уступают по размеру кода банальному REPEAT/UNTIL:
...
В связи с чем возникла идея: сделать ещё одну версию FOR (компактный) для оптимизации по размеру кода, что будет особенно ценно для Спека. Работать он может по тому же принципу, что и REPEAT/UNTIL (для тех случаев, где точно известно, что количество итераций > 0). И пусть этот вариант сравнивает достижение конца цикла не по "больше" или "меньше", а по "равно"/"не равно" — сравнение на равность на Z80 эффективнее (не нужно учитывать знак). Пусть также данный вариант игнорирует и не учитывает случаи изменения переменной цикла внутри цикла, тоже для эффективности. Кстати, этим вариантом можно будет проверять код "на прочность".
Нужно посмотреть, за счет чего достигнута экономия, может быть можно и не создавать новый вариант, а усовершенствовать имеющийся.
Для экономии кода и времени для Спекки я уже неоднократно предлагал ввести
особые макросы, позволяющие выйти на уровень ассемблера напрямую. А это позволит использовать дополнительные флажки процессора и проверку флагов сразу после декремента, что на уровне Си недоступно.
Zorko писал(а):
Сегодня думал о том, что неплохо бы запрещать изменение переменной цикла как только её использовали в FOR, а после END опять разрешать. Даже не нашёл недостатков такого решения, кроме сложностей реализации для хитрых случаев. Например, пусть модуль Modul экспортирует переменную i как разрешённую для изменения. Модуль Abc её изменяет. А вдруг тут нашему модулю Xd понадобилось такое:
Код: "OBERON"
FOR Modul.i := 1 TO 100 DO ...
Запрет изменения переменной может помешать её передаче в какую-то процедуру по VAR (а такая передача не обязательно повлечёт её изменение). Но вот должна ли простая числовая переменная передаваться по VAR, если её никто в процедуре и не собирался менять? Или всё-таки бывает удобно иметь параметр, который в некоторых случаях процедура будет менять, а в других нет? Надо это обдумать.
Думаю, что стоит наложить ограничение на локальность переменной цикла. Ни в коем случае эта переменная не должна быть экспортируемой.
И пусть она будет отдельной переменной - не элементом массива или записи.
Также такая переменная пусть будет "самой локальной" - она должна быть объявлена на самом внутреннем уровне, в котором применяется FOR (т.е. будет локальной переменной той процедуры, где написан FOR).
Это может несколько увеличить расход памяти, потому что для каждой процедуры, использующей FOR, потребуется специальная локальная переменная именно этой процедуры. А можно было бы обойтись одной общей (глобальной) переменной для циклов FOR, принадлежащей охватывающей процедуре.
Но такая экономия подразумевает, что мы следим за вложенностью циклов. В частности, если процедуры используют цикл FOR с общей глобальной переменной, то нельзя вызывать одну процедуру изнутри цикла, запущенного в другой. Вручную отслеживать такие зависимости - плохой стиль, допустимый только в случае нехватки ресурсов. Поэтому, думаю, всё же следует такое ограничение наложить на переменную цикла (и отойти от стандарта ещё на шаг
).