Чтение онлайн

на главную - закладки

Жанры

UNIX — универсальная среда программирования
Шрифт:

}

Когда в процессе выполнения вызывается функция или процедура, все аргументы уже вычислены и помещены в стек (первый аргумент находится на наибольшем уровне). Код операции вызова (

call
) сопровождается указателем на таблицу имен и числом аргументов. Сохраняется образ стека, в котором содержится вся существенная информация о программе: запись в таблице имен, место возврата после вызова, место хранения аргументов в стеке выражений, а также число аргументов, сопровождающих вызов. Образ стека создается функцией
call
, которая затем выполняет тело программы.

call /* call a function */

{

 Symbol *sp = (Symbol*)pc[0]; /* symbol table entry */

 /* for function */

 if (fp++ >= &frame[NFRAME-1])

execerror(sp->name, "call nested too deeply");

 fp->sp = sp;

 fp->nargs = (int)pc[1];

 fp->retpc = pc + 2;

 fp->argn = stackp - 1; /* last argument */

 execute(sp->u.defn);

 returning = 0;

}

Создаваемая

структура показана на рис. 8.2.

Рис. 8.2: Структуры данных для вызова процедуры

В конце концов произойдет возврат из вызываемой программы при выполнении

procret
или
funcret
:

funcret /* return from a function */

{

 Datum d;

 if (fp->sp->type == PROCEDURE)

execerror(fp->sp->name, "(proc) returns value");

 d = pop; /* preserve function return value */

 ret;

 push(d);

}

procret /* return from a procedure */

{

 if (fp->sp->type == FUNCTION)

execerror(fp->sp->name(func) returns no value");

 ret;

}

Функция

ret
удаляет аргументы из стека, сохраняет указатель на образ стека
fp
и устанавливает счетчик команд:

ret /* common return from func or proc */

{

 int i;

 for (i = 0; i < fp->nargs; i++)

pop; /* pop arguments */

 pc = (Inst*)fp->retpc;

 --fp;

 returning = 1;

}

Некоторые программы интерпретатора нуждаются в небольших поправках для учета ситуаций, когда происходит

возврат во вложенных операторах. Решение не элегантно, но верно и состоит во введении признака с именем
returning
, который принимает значение 1 при обнаружении оператора
return
. Выполнение, организуемое функциями
ifcode
,
whilecode
,
execute
, завершается раньше, если установлен признак
returning
; в функции
call
он обнуляется.

ifcode {

 Datum d;

 Inst *savepc = pc; /* then part */

 execute(savepc+3); /* condition */

 d = pop;

 if (d.val)

execute(*((Inst**)(savepc)));

 else if (*((Inst**)(savepc+1))) /* else part? */

execute(*((Inst**)(savepc+1)));

 if (!returning)

pc = *((Inst**)(savepc+2)); /* next stmt */

}

whilecode {

 Datum d;

 Inst *savepc = pc;

 execute(savepc+2); /* condition */

 d = pop;

 while (d.val) {

execute(*((Inst**)(savepc))); /* body */

if (returning)

break;

execute(savepc+2); /* condition */

d = pop;

 }

 if (!returning)

pc = *((Inst**)(savepc+1)); /* next stmt */

}

execute(p)

 Inst *p;

{

 for (pc = p; *pc != STOP && !returning; )

(*((++pc)[-1]));

}

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

getarg
, которая следит за сбалансированностью стека:

double *getarg /* return pointer to argument */

{

 int nargs = (int)*pc++;

 if (nargs > fp->nargs)

execerror(fp->sp->name, "not enough arguments");

 return &fp->argn[nargs - fp->nargs].val;

}

arg /* push argument onto stack */

{

 Datum d;

 d.val = *getarg;

Поделиться:
Популярные книги

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Я сделаю это сама

Кальк Салма
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я сделаю это сама

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Боярышня Дуняша

Меллер Юлия Викторовна
1. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Дуняша

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Леди для короля. Оборотная сторона короны

Воронцова Александра
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Черный Маг Императора 5

Герда Александр
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 5

Невест так много. Дилогия

Завойчинская Милена
Невест так много
Любовные романы:
любовно-фантастические романы
7.62
рейтинг книги
Невест так много. Дилогия

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Крещение огнем

Сапковский Анджей
5. Ведьмак
Фантастика:
фэнтези
9.40
рейтинг книги
Крещение огнем

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая