Литмир - Электронная Библиотека
Содержание  
A
A

$ cat init.с

...

static struct { /* Keywords */

 char *name;

 int kval;

} keywords [] = {

 "if",    IF,

 "else",  ELSE,

 "while", WHILE,

 "print", PRINT,

 0, 0,

};

...

Для занесения в таблицу имен ключевых слов нужно организовать еще один цикл в функции

init
:

...

for (i = 0; keywords[i].name; i++)

 install(keywords[i].name, keywords[i].kval, 0.0);

...

Изменения в функциях, управляющих таблицей имен, не требуются; в файле

code.c
есть функция
prexpr
, которая вызывается при выполнении оператора вида
print
выраж.

prexpr() /* print numeric value */

{

 Datum d;

 d = pop();

 printf ('"%.8g\n", d.val);

}

Это не та функция печати, которая автоматически вызывается для вывода окончательного результата вычислений. Здесь выбирается число из стека и добавляется символ перевода строки к выходному потоку.

Теперь

hoc5
представляет собой вполне полезный калькулятор, хотя для серьезного программирования необходимы дополнительные средства. В приведенных ниже упражнениях предлагаются возможные решения.

Упражнение 8.12

Добавьте для отладки к

hoc5
средство печати создаваемых машинных команд в понятной форме.

Упражнение 8.13

Введите в свою программу операции присваивания из языка Си вида

+=
,
*=
и т.п., а также операции инкремента и декремента
++
и
--
. Измените операции
&&
и
||
так, чтобы обеспечить вычисление слева направо и условное вычисление, как в Си программах.

Упражнение 8.14

Введите в

hoc5
оператор
for
, как в Си-программах. Добавьте операторы
break
и
continue
.

Упражнение 8.15

Как бы вы изменили грамматику или лексический анализатор

hoc5
(или и то, и другое), чтобы сделать программу более "терпимой" к использованию символов перевода строки? Каким образом можно ввести символ в качестве синонима символа перевода строки? Как ввести в язык примечания? Какой синтаксис, по вашему мнению, нужно использовать?

Упражнение 8.16

Добавьте к

hoc5
средства обработки прерываний, чтобы некорректные вычисления можно было остановить без потери значений уже вычисленных переменных.

Упражнение 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
и т.д., как в командных файлах, но, кроме того, допустимо присваивание параметрам. Функции и процедуры рекурсивны, но в качестве локальных переменных можно использовать только параметры; остальные переменные являются глобальными, т.е. доступными во всей программе.

117
{"b":"248117","o":1}