248
чрезвычайно простой. Конечно, все это для нашего специального, тривиального случая с
Expression. Естественно, для общего случая это будет более сложно. Но теперь вы
смотрите на финальную версию процедуры Assignment!
Все это выглядит как очень простое и ясное решение, и действительно это так.
Откомпилируйте эту программу и выполните те же самые тесты, что и ранее. Вы увидите,
что все типы данных преобразованы правильно и здесь немного, если вообще есть, зря
потраченных инструкций. Только преобразование "байт-длинное слово" использует две
инструкции когда можно было бы использовать одну, и мы могли бы легко изменить
Convert для обработки этого случая.
Хотя мы в этом случае не рассматривали переменные без знака, я думаю вы можете
видеть, что мы могли бы легко исправить процедуру Convert для работы и с этими
типами. Это "оставлено как упражнение для студента".
ЛИТЕРАЛЬНЫЕ АРГУМЕНТЫ
Зоркие читатели могли бы отметить, однако, что мы еще даже не имеем правильной
формы простого показателя, потому что мы не разрешаем загрузку литеральных
констант, только переменных. Давайте исправим это сейчас.
Для начала нам понадобится функция GetNum. Мы уже видели ее несколько версий,
некоторые возвращают только одиночный символ, некоторые строку, а некоторые целое
число. Та, которая нам здесь нужна будет возвращать длинное целое, так что она может
обрабатывать все, что мы ей подбросим. Обратите внимание, что здесь не возвращается
никакой информации о типах: GetNum не интересуется тем, как будет использоваться
число:
{ Get a Number }
function GetNum: LongInt;
var Val: LongInt;
begin
if not IsDigit(Look) then Expected('Integer');
Val := 0;
while IsDigit(Look) do begin
Val := 10 * Val + Ord(Look) - Ord('0');
GetChar;
end;
GetNum := Val;
SkipWhite;
end;
Теперь, когда работаем с литералами, мы имеем одну небольшую проблему. С
переменными мы знаем какого типа они должны быть потому что они были объявлены с
таким типом. Мы не имеем такой информации о типе для литералов. Когда программист
говорит "-1", означает ли это байт, слово или длинное слово? Мы не имеем никаких
сведений. Очевидным способом было бы использование наибольшего возможного типа,
т.е. длинного слова. Но это плохая идея, потому что когда мы примемся за более
сложные выражения, мы обнаружим, что это заставит каждое выражение включающее
литералы, также переводить в длинное.
Лучшим подходом было бы выбрать тип, основанный на значении литерала, как
показано далее: