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: Структуры данных для вызова процедуры
В конце концов произойдет возврат из вызываемой программы при выполнении
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
рейтинг книги
Я сделаю это сама
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Флеш Рояль
Детективы:
триллеры
7.11
рейтинг книги
Боярышня Дуняша
1. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Газлайтер. Том 8
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Черный Маг Императора 5
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Невест так много. Дилогия
Невест так много
Любовные романы:
любовно-фантастические романы
7.62
рейтинг книги
Идеальный мир для Социопата 3
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Повелитель механического легиона. Том VIII
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Наследник павшего дома. Том I
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Крещение огнем
5. Ведьмак
Фантастика:
фэнтези
9.40
рейтинг книги
Камень Книга двенадцатая
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00