средства обработки прерываний, чтобы некорректные вычисления можно было остановить без потери значений уже вычисленных переменных.
Упражнение 8.17
Неудобно создавать программный файл, запускать его на выполнение, а затем редактировать с целью внесения небольших изменений. Как бы вы изменили
hoc5
, чтобы создать команду редактирования, которая автоматически вызывала бы редактор с уже считанной копией вашей
hoc
–
программы? Подсказка: изучите текст функции.
8.6 Этап 6: функции и процедуры; ввод-вывод
На последнем из описываемых здесь этапе развития программа значительно разрастается: в нее добавляются процедуры и функции, средства печати строк символов наряду с числами и чтения чисел из стандартного входного потока. Кроме того, в язык
hoc6
вводятся аргументы имен файлов, включая имя
"-"
, обозначающее стандартный входной поток. Все эти изменения увеличивают программу на 235 строк, доводя ее общий размер до 810 строк. В результате
hoc
преобразуется из калькулятора в интерпретатор языка программирования. Полностью программа приводится в приложении 3.
В грамматике вызовы функции определяются как выражения, а вызовы процедур как операторы. И то, и другое детально поясняется в приложении 2, где дается еще несколько примеров. Так, определение и использование процедуры печати всех чисел Фибоначчи, меньших заданного параметра, происходят следующим образом:
$ cat fib
proc fib {
a = 0
b = 1
while (b < $1) {
print b
с = b
b = a+b
a = с
}
print "\n"
}
$ hoc6 fib -
fib(1000)
1 1 2 3 5 8 13 21 34.55 89 144 233 377 610 987
...
Здесь также показано использование файлов: имя файла
"-"
задает стандартный входной поток.
Ниже приведена функция "факториал":
$ cat fac
func fac {
if ($1 <= 0) return 1 else return $1 * fac($1-1)
}
$ hoc6 fac -
fac(0)
1
fac(7)
5040
fac(10)
3628800
...
Внутри процедуры или функции к параметрам можно обращаться с помощью
$1
и т.д., как в командных файлах, но, кроме того, допустимо присваивание параметрам. Функции и процедуры рекурсивны, но в качестве локальных переменных можно использовать только параметры; остальные переменные являются глобальными, т.е. доступными
во всей программе.
В языке
hoc
функции и процедуры различаются, что дает возможность проверки, ценной для освобождения стека. (Ведь так легко забыть выполнить возврат или записать липшее выражение и получить несбалансированный стек!)
Требуется значительное число изменений для преобразования грамматики при переходе от
hoc5
к
hoc6
, но все они локальные. Нужны новые лексемы и нетерминальные символы, а в описание
%union
необходимо ввести новый элемент для хранения числа аргументов: