Лекции по построению компилятора на Pascal
14. Типы
ВВЕДЕНИЕ
В последней главе (Часть 13, Процедуры) я упомянул, что в ней и в следующей главе мы
рассмотрим две возможности, которые помогут отделить игрушечный язык от настоящего,
пригодного к использованию. В ней мы рассмотрели вызовы процедур. Многие из вас
терпеливо ждали, начиная с Августа'89] когда я выдам вторую. Хорошо, вот она.
В этой главе мы поговорим о том, как работать с различными типами данных. Как и в
последней главе, я не буду сейчас включать эти возможности непосредственно в компилятор
TINY. Вместо этого я буду использовать тот же самый подход, который так хорошо служил
нам в прошлом: использование только фрагментов синтаксического анализатора и одно-
символьных токенов. Как обычно, это позволит нам добраться непосредственно до сути
вопроса не продираясь сквозь массу ненужного кода. Так как основные проблемы при работе
с множественными типами данных возникают в арифметических операциях, на них мы и
сконцентрируем свое внимание.
Несколько предупреждений: Во-первых, есть некоторые типы, которые я не буду охватывать
в этой главе. Здесь мы будем говорить только о простых, встроенных типах. Мы даже не
будем работать с массивами, указателями или строками, я охвачу их в следующих
нескольких главах.
Во-вторых, мы также не будем обсуждать и типы, определяемые пользователем. Это будет
значительно позже, по той простой причине, что я все еще не убедил себя, что эти
определяемые пользователем типы должны быть в языке KISS. В более поздних главах я
собираюсь охватить по крайней мере основные концепции определяемых пользователем
типов, записей и т.д., просто для того, чтобы серия была полной. Но действительно ли они
будут включены как часть KISS - все еще открытый вопрос. Я открыт для комментариев и
предложений по этой теме.
Наконец, я должен предупредить вас: то, что мы собираемся сделать может добавить массу
дополнительных сложностей и в синтаксический анализатор и в генерируемый код.]]
Поддерживать различные типы достаточно просто. Сложность возникает когда вы
добавляете правила преобразования между типами. Вообще-то, будет ли ваш компилятор
простым или сложным зависит от способа, выбранного вами для определения правил
преобразования типов. Даже если вы решите запретить любые преобразования типов (как в
Ada, например) проблема все еще остается, и она встроена в математику. Когда вы
умножаете два коротких числа, к примеру, вы можете получить длинный результат.
Я подошел к этой проблеме очень осторожно, пытаясь сохранить простоту. Но мы не можем
полностью избежать сложности. Как обычно случается, мы оказываемся перед
необходимостью выбирать между качеством кода и сложностью и, как обычно, я
предпочитаю выбрать самый простой подход.
ЧТО БУДЕТ ДАЛЬШЕ?
Прежде чем мы погрузимся в это занятие, я думаю вам бы хотелось знать что мы сейчас
собираемся делать...] особенно после того, как прошло столько много времени с прошлой
главы.
Тем временем я не бездействовал. Я разбил компилятор на модули. Одна из проблем, с
которыми я столкнулся, в том, что так как мы охватывали новые области и вследствие этого
расширяли возможности компилятора TINY, он становился все больше и больше. Я понял
пару глав назад, что это приводило к затруднениям и именно поэтому я возвратился к
использованию только фрагментов компилятора в последней и этой главах. Кажется просто
глупо заново воспроизводить код для, скажем, обработки булевых исключающих ИЛИ, когда
тема дискуссии - передача параметров.