Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 170
Текст из файла (страница 170)
Строка 2. Комментарии в языке Е1ЯР начинаются с символа «. » и продолжаются до копна строки. Строка Х Функция 5нннехс объявлена как функция с одним параметром. Она возвращает сумму элементов, содержащихся в сс параметре. Определением функции 5оптйехг является выражение, записанное в строках 4-5. Строка 4. Функция соло ищет первую истинную пару «предикат, выражение >. Первая пара имеет прсдикат пн11 Ч, который принимает истинное значение после обработки последнего введенного значения. Функция печатает 50М= и возвращает управлснис. Конструкция ргодп последовательно выполняет последовательность выражений, в данном случае -- функцшо ргтпг, а за ней — выражение 0 как значение по умолчанию.
Строка 5. Если вектор Ч нс пуп~ой (обычный случай), прсдикат Т становится вариантом по умолчанию для функции соло в строке й, Вектор Ч без первого элемента передается рскурсивпо функции 5цпг(ех1, и после возвращения голова У прибавляется к ранее вычисленной сумме. Строка 6. ! !ЯР печатает имя функции 30ММсХТ как результат выполнения строк 3-5. Строки 7 — 11. В этих строках опрслслястся функция бег! прн(, нмсьошая два параметра: указатель входного файла 1 и количество элементов вектора, которос осталось прочитать, с.
Это определение демонстрирует синтаксис функции пе1пп, использусмой для определения функции; в Яс!пппе применяется другая конструкция, ое1ьпе. Функция Яес1прШ возвращает список значений прочитанных данных. Строка 9. Функция свпо' сначала сравнивает счетчик с с нулем, п если он равен нулю, возвращает пустой список.
Строка 10. Если счетчик нс равен нулю, функция бе(! прнг создаст новый вектор, читая атом из файла 1 и добавляя его в голову списка, возвращаемого после рекурсивного вызова бес!прЛ с параметрами 1 и счетчиком, уменьшенным на единицу. Строки 12 — 18. Злесь определяется основная управляющая функция программы. Функция Оо11 нс имеет параметров. Стрьола 1Х Функция ргойп последовательно выполняет выражения строк 14-17. Строка 14.
Функция преп открывает файл 11зр.да1а и возвращает указатель на файл. Функция зеГП присваивает этот указатель переменной ьпгь1е. 11ослсдоватсльность действий следующая; вычисляется аргумент преп, а затсм осу щсствлястся присваиванис переменной ьпгь1е. Страха 15. Вызывается функция бес!про( (строки 8 — 10) с параметром ьпгь1е, который был определен в строке 14, и результатом выполнения функции геао, который будет счетчиком количества элементов вектора, подлсжаьцих суммированикь. Функция зеьо присваивает эти ььходььььс данные переменной аггау. строка 17. Входные данные (гписок аггау) передаются функции Бппьйехг, определенной в строках 3 — 5, которая возвращает сумму членов списка.
Строка 19 Вызывается функция Ро1г. Строки 20 — 24. Если файл 11зр.йага содержит следующие данные: 41234 то в строках 20 -23 представлен резулю ат работы программы. В этом примере дважды папсчатано число 10 — один раз как результат выполнения функции ргь пС в строке 17, второй раз как значение, возвращснцос функцией Оо!1. П.6.1. Объекты данных Элементарные типы данных Элементарными ти памп объектов данных в языке !.!3Р являются списки и атомы. Определения функций и списки свойстн являются специальными типамн списков особой важности. Во всех реализациях обычно такжс предусмотрены массивы, числа и строки, однако эти типы играют пс столь важную роль в языке. Переменные и константы. В языке 1 !ЯР атом является основным элементарным типом объектов данных. Атом иногда называьот литеральным атомом (Вега! агат), чтобы отличить от числа (аитег!с агат), которое большинством функций языка !!БР также классифи пи руотси как атом.
Синтаксически атом является идентификаторомм — это последовательность букв и цифр, нач и наьошаяся с буквы, Для 618 Приложение. Обзоры языков идентификаторов обычно нс учитгявается регистр задания букв. В опрсделениях функций языка 11БР атомы выполняют обычную роль идснтификаторов — они используются в качсстве имсн псрсменных, функций, формальных параметров и т, д. Однако во время выполисния атомы языка ЫЯР являются не просто идентификаторами. Любой атом — это сложный объект данных, представленный областью памяти, которая солержит дескриптор типа для атома вместе с указателсм на список свойств.
Список свойств содержит различные свойства, ассоциированные с атомом, одним из которых вссгда является его печатное имя — символьная строка, представляющая атом при вводе и выводе. Другие свойства прсдставляют собой различные связывания для атома, которые могут включать функцию, с именем, соответствующим имени атома, и другис свойства, назначаемые программой во время выполнения. Котла бы атом ни появлялся в качестве компонента другого объскта данных, напримср списка, он представлястся указателсм на область памяти, служащим представлением этого атома во время выполнения. Таким образом, любая ссылка на атом АВС во врсмя выполнсния программы 11ЯР прсдставлена указатслсм на эту область памяти.
Каждый атом также обыкновенно появляется как компонент в определяемой системой центральной таблице, называемой списком обьеюпов (оЬ йхг). Таблица оЬ Ы обычно организуется как хэш-таблица, которая позволяет осуществлять эффективный поиск печатного имени (символьной строки) и получать значение указатсля на атом с этим печатным имснсм. Например, когда вводится список и очередной элемент являстся символьной строкой "АВГ, представляющей атом АВС, функция гезй иьдет в таблице оЬ Ы элемент "АВГ, который также содержит указатель на область памяти, где хранится атом АВС. Этот указатель вставлястся в список, конструирусмый в соответствующей точке.
Можно использовать числа (числовые атомы) в целом формате или формате с плавающей точкой. Используется аппаратное представление, ио требустся также и дескриптор времени выполнения, так что для каждого числа используется два слова. Однако это представлсние хорошо сочетается с представлением, использусмым для литеральных атомов; число — это атом, обозначенный как принадлежащий специальному типу, с указатслем на битовую строку, прсдставляющую число, вместо указатсля на список свойств. Строки в языке ЫБР представляются обычными строками символов. Следуст знать, что одиночная кавычка ( ' ) чнтерпретирустся как функция свате для литеральных (не вычисляемых) аргументов функции. Список свойств.
Каждый литеральный атом имест связанный с ним список свойств, доступ к которому осуществляется чсрсз указатсль, хранимый в области памяти, прсдставляюшсй атом. Список свойств является обычным списком языка АКР, отличаюшийся только тем, что его элементы располагаются в чередующейся последовательности логическими парами ияя свойства!значение свойства. Если атом является именем функции, его список свойств содержит имя свойства, дающее тип функции, и указатель на список, представляющий собой опредслсние функции.
Программист может добавлять другие требуемые свойства, некоторые элементарные операции также могут добавлять свойства. Структурированные типы денных В большинстве реализаций языка !.!ВР предусмотрены некоторые разновидности таких объектов данных, как векторы или массивы. Однако в разных реализациях эти объекты представлены весьма иеодииаково, что объясняется сравнительно иебольшой их значимостью для написания программ иа языке !.!ЗР. Типичная реализация содержит фупкпию снега(ЬоппФ, которая создает векториый объект даииых с диапазоиом изменения иидексов от 0 до заданной границы Ьоппс. Кажлый компоиепт вектора может содержать указатель иа любой объект данных!.! ЯР; изначально значения указателей установлены равными пн.
Функция де1н(несгог, зиЬасг1рГ) возвращает указатель, хранящийся в указаииом компоиеитс вектора- аргумента, Таким образом, функция данн является 1.!ЯР-версией операции иидексации для получения значения компонента вектора. Функция рпгн используется для присвоения нового значения компоненту вектора. Опредсляемые программистом фупкции пишутся в форме списков для ввода, как видно из листинга П.В. Программы ввода в языке (,!ЯР пс делают различий между определениями функций и списками данных, а просто преобразуют все списки во внутреннее прсдставлсиие связанных списков.
Каждый встречающийся атом ищется в таблице об йзг, и если атом уже существует, то возвращается указатель иа него, если же атома в списке пег, то создается новый атом. Ииициализация и присваиваиие. В отличие от других языков прямое присваиваиие ие играет важной роли в программировании иа языке В!ЯР.
Многие программы иа языке !.1ЯР иаписаиы вообще без операций присваивания, а для достижсиия того же эффекта неявным образом используются рекурсия и передача параметров. Однако прпсвапваиие используется внутри ссгмеитов ргод, где программа па языке 1.!ЯР принимает вид обычной последовательности операторов. Основной операцией присваивания является зеад, Выражение 1зеад х на1) присваивает переменной х новое значение на1, причем результатом этого выражения является величина на1 (таким образом, хенд — это функция, ио ее зиачеиие обычно игнорируется). Элементарная операция зег аналогична зегд, за исключением того, что псремеииая (а имеиио атом), которой присваивается значение, может быть вычислена, Например, (зег(саг Ь) на1) эквивалентно (зе~д х на1), если атом хявляется первым элементом списка Ь.
Функции гр1аса и гр1аса позволяют присваивать значения соответствеиио полям саг и сдг любого элемента списка. Например, 1гр1аса Ь на1) присвоит значеиие на) в качестве первого элемента списка Ь, заместив текущий первый элемеит. П.6.2.
Управление последовательностью действий ! 1БР пс делает различий между данными !.!БР и программами !.!ЗР. Этим объясняется простота питерпретатора 1!ЯР. По срависпию с другими языками, которые рассматриваются в даииой киипь выполнение программы па языке !.1ЯР иитсрссио тем, что осиовиой иитерпретатор может быть описан ца 1!ЗР. Функции арр1у передается указатель иа функцию, которую следует выполнить, и арр1у иитерпретируст определение этой функции, используя вторую функцию ена1 для вычислеиия каждого аргумента. 620 Приложение.
Обзоры языков Транслятор языка Е)ЗР— это просто функция геа<). Функция геа<1 сканирует символьную строку из входного файла или с терминала, ища правильный идентификаторр илп оп исковую структуру. Если найлен одиночный идентификатор, функция просматривает таблицу о!> !!а!для получения указателя на соответствующий атом (или для создания нового атома, если не найден атом с заданным печатным именем). Если найдена списковая структура, начинающаяся с символа «(», то сканируется каждый элел<е>тт списка, пока не будет найден соответствующий символ «(». Каждый элемент списка транслируется во внутреннюю форму, и в соответствующем месте в список вставляется указатель саг.