На этом шаге мы рассмотрим порядок создания программ в muLISP81. Эти сведения
будут полезны при создании программ в более поздних версиях.
Этап кодирования и выполнения
Этап тестирования
Этап трансляции
Расмотрим наиболее важные составные части среды программирования muLISP81 в порядке их использования на этапах разработки программы.
Текст программы сначала помещается в файл с помощью текстового редактора.
При вводе выражения в систему muLISP81 пустые строки и пробелы игнорируются. Пробел употребляется, когда необходимо отделить аргументы функции, причем вместо единичного пробела всегда может быть использовано несколько пробелов.
В текст программы можно включать комментарии, которые заключаются
в символы %. Например:
% Это комментарий... %
Интерпретатор загружается из операционной системы MS-DOS командой
C:\>LISP
После этого на экране дисплея вы увидете следующее:
muLISP-80 2.12 (07/09/81)
Copyright (C) 1981 MICROSOFT
Licensed from The SOFT WAREHOUSE
$
Символ "$" - это так называемое приглашение, при помощи которого интерпретатор дает знать, что он выполнил вычисление значения предыдущего выражения и ждет нового выражения.
После символа приглашения "$" вы можете обратиться к следующим функциям muLISP81 (таблица 1):
Загружает в память компьютера программу, хранящуюся в файле FILENAME.EXT. | |
Сохраняет в файле FILENAME.SYS текущее состояние памяти (рабочую обстановку). | |
Восстанавливает из файла записанную до этого на диск рабочую обстановку (функции и переменные) из файла FILENAME.SYS. То же можно сделать в командной строке: C:\>LISP FILENAME. | |
Возвращение в операционную систему. |
Если определения функций были синтаксически верны и сообщения об ошибке не последовало, то можно начать тестирование их работы.
Для тестирования программ в систему muLISP81 включена функция TRACE. С помощью трассировки вы можете отследить вычисление тестируемой функции (или функций) с целью локализации и исправления ошибок. Если некоторая функция помечается как трассируемая, то система информирует об имени функции и значениях аргументов каждый раз при входе в функцию и соответственно выводит значение функции, как только оно вычислено.
Трассировка включается с помощью вызова:
$ (TRACE)
NIL
Далее, пометим нужные нам функции как "трассируемые":
(TRACE Имена_трассируемых_функций)
Имена трассируемых функций разделяются пробелами. Например:
$ (TRACE PLUS1 PLUS2)
NIL
После этого интерпретатор трассирует вычисление функций PLUS1 и PLUS2.
Трассировку можно отменить директивой UNTRACE:
$ (UNTRACE PLUS1)
Найденные ошибки исправляются в текстовом редакторе.
Приведем исходные тексты функций TRACE и UNTRACE.
% File: TRACE.LIB (c) 06/26/80 The Soft Warehouse % % Аргументами функции TRACE являются имена функций, кото- рые мы хотим трассировать. Трассировка содержит имена вы- зываемых функций и аргументов и возвращаемое значение после вычислений. Трассируются только функции, определен- ные с помощью LAMBDA и NLAMBDA % (PROG1 "" (PUTD DEFUN (QUOTE (NLAMBDA (FUNC DEF) (PUTD FUNC DEF) FUNC ))) ) % --------------------------------------------------- % (DEFUN TRACE (LAMBDA LST (SETQ INDENT 0) (MAPC LST (QUOTE (LAMBDA (FUN BODY FUN#) (SETQ BODY (GETD FUN)) (SETQ FUN# (PACK (LIST FUN #))) (MOVD FUN FUN#) ((MEMBER (CAR BODY) (QUOTE (LAMBDA NLAMBDA))) (PUTD FUN (LIST (CAR BODY) (CADR BODY) (LIST EVTRACE FUN (CADR BODY) FUN#) )) ) (PRIN1 FUN) (PRINT " is not a LAMBDA defined function") )) ) )) % ---------------------- % (DEFUN UNTRACE (LAMBDA LST % Функция UNTRACE отменяет трассировку % (MAPC LST (QUOTE (LAMBDA (FUN FUN#) (SETQ FUN# (PACK (LIST FUN #))) ( (GETD FUN#) (MOVD FUN# FUN) (MOVD NIL FUN#) ) )) ) )) % ----------------------------------- % (DEFUN EVTRACE (NLAMBDA (FUN ARGS FUN#) (PRTARGS FUN ARGS) (PRTRSLT FUN (APPLY FUN# (MAKARGS ARGS))) )) % ----------------------------- % (DEFUN PRTARGS (LAMBDA (FUN ARGS) (SPACES INDENT) (SETQ INDENT (PLUS INDENT 1)) (PRIN1 FUN) (PRIN1 " [") ( (NULL ARGS) (PRINT "]") ) ( LOOP ( (ATOM ARGS) (SETQ ARGS (EVAL ARGS)) ( LOOP (PRIN1 (CAR ARGS)) (SETQ ARGS (CDR ARGS)) ( (ATOM ARGS) ) (PRIN1 ", ") ) ) (PRIN1 (EVAL (CAR ARGS))) (SETQ ARGS (CDR ARGS)) ( (NULL ARGS) ) (PRIN1 ", ") ) (PRINT "]") )) % ----------------------------- % (DEFUN PRTRSLT (LAMBDA (FUN RSLT) (SETQ INDENT (DIFFERENCE INDENT 1)) (SPACES INDENT) (PRIN1 FUN) (PRIN1 " = ") (PRINT RSLT) RSLT )) % ------------------------- % (DEFUN MAKARGS (LAMBDA (ARGS) ( (NULL ARGS) NIL) ( (ATOM ARGS) (EVAL ARGS) ) (CONS (EVAL (CAR ARGS)) (MAKARGS (CDR ARGS))) )) % -------------------------- % (DEFUN MAPC (LAMBDA (LST FUNC) (LOOP ( (NULL LST) NIL) ( FUNC (CAR LST) ) ( SETQ LST (CDR LST) ) ) )) (RDS)
Часто при создании текста программы вы случайно набираете на клавиатуре "русский" символ, весьма похожий на латинский... Как обнаружить такую ошибку? Приведем полезную утилиту, позволяющую сделать это:
(DEFUN LIKE (LST) % Построение списка тех атомов из списка атомов LST, ко-% % торые в своем имени содержат русские буквы А, В, Е, % % К, М, Н, О, Р, С, Т, Х, похожие по написанию на % % латинские % (COND ( (NULL LST) NIL ) ( (RUS_LETTER (UNPACK (CAR LST))) (CONS (CAR LST) (LIKE (CDR LST))) ) ( T (LIKE (CDR LST)) ) ) ) % -------------------- % (DEFUN RUS_LETTER (LST) % Предикат, возвращающий T, если в имени атома встреча- % % ется одна из следующих русских букв: % % А В Е К М Н О Р С Т Х % (COND ( (NULL LST) NIL ) ( (MEMBER (CAR LST) '(А В Е К М Н О Р С Т Х)) T) ( T (RUS_LETTER (CDR LST)) ) ) )
Тестовый пример:
$ (LIKE '(АВ АА AA))
(АВ АА)
В первых двух атомах списка использовались русские буквы.
Оттестированную программу можно транслировать с помощью интерпретатора muLISP81
при помощи функции SAVE. Интерпретатор создает вариант программы на машинном
языке, требующий меньше памяти и работающий значительно быстрее, чем интерпретируемая
версия. Разница, как правило, составляет один порядок, но зависит, естественно, от транслируемой
программы.
На следующем шаге мы приведем правила работы с системой программирования muLISP85.
Этап кодирования и выполнения
Этап тестирования
Этап трансляции