258
ЗАВЕРШЕНИЕ
Наконец-то, в этой главе мы узнали как работать с переменными (и литералами)
различных типов. Как вы можете видеть, это не было слишком сложно. Фактически, в
каком-то отношении большая часть кода выглядит даже еще проще, чем это было в
более ранних программах. Только операторы умножения и деления требуют небольших
размышлений и планирования.
Основная идея, которая облегчила нам жизнь, - идея преобразования процедур типа
Expression в функции, возвращающие тип результата. Как только это было сделано, мы
смогли сохранить ту же самую общую структуру компилятора.
Я не буду притворяться, что мы охватили каждый одиночный аспект этой проблемы. Я
удобно проигнорировал беззнаковую арифметику. Из того, что мы сделали, я думаю вы
можете видеть, что их включение не добавляет никаких дополнительных проблем, просто
дополнительные проверки.
Я так же игнорировал логические операторы And, Or и т.д. Оказывается, их довольно
легко обрабатывать. Все логические операторы - побитовые операции, так что они
симметричны и, следовательно, работают в том же самом режиме, что и PopAdd. Однако,
имеется одно отличие: если необходимо расширить длину слова для логической
переменной, расширение должно быть сделано как число без знака. Числа с плавающей
точкой, снова, являются простыми для обработки... просто еще несколько процедур,
которые будут добавлены в run-time библиотеку или, возможно, инструкции для
математического сопроцессора.
Возможно более важно, что я также отделил проблему контроля соответствия типов, в
противоположность преобразованию. Другими словами, мы разрешили операции между
переменными всех комбинаций типов. Вообще, это не будет верным... конечно вы не
захотите прибавить целое число, например, к строке. Большинство языков также не
позволят вам смешивать символьные и целочисленные переменные.
Снова, в дейс твительности в этом случае нет никаких новых проблем для
рассмотрения. Мы уже проверяем типы двух операндов... в основном эти проверки
выполняются в процедурах типа SameType. Довольно просто включить вызов
обработчика ошибок если типы двух операндов несовместимы.
В общем случае мы можем рассматривать каждый одиночный оператор как
обрабатываемый отдельной процедурой, в зависимости от типа двух операндов. Это
просто, хотя и утомительно, реализовать просто создав таблицу переходов с типами
операндов как индексами. В Паскале эквивалентная операция включала бы вложенные
операторы Case. Некторые из вызываемых процедур могли бы тогда быть простыми
подпрограммами обработки ошибок, в то время как другие могли бы выполнять любые
виды преобразований, необходимые нам. При добавлении нами типов, число процедур
будет возрастать в геометрической прогрессии, но это все равно не неприемлемо
большое число процедур.
Сдесь же мы свернули такую таблицу переходов в гораздо меньшее количество
процедур, просто используя симметрию и другие упрощающие правила.
ПРИВОДИТЬ ИЛИ НЕ ПРИВОДИТЬ
В случае, если до вас еще не дошло, уверен дойдет, что TINY и KISS возможно не
будут строго типизированными языками, так как я разрешил автоматическое смешивание
и преобразование почти любых типов. Что поднимает следующий вопрос:
Это действительно то, что мы хотим сделать?
Ответ зависит от того, какого рода язык вам нужен и как вы хотели чтобы он себя вел.