Вход/Регистрация
UNIX — универсальная среда программирования
вернуться

Керниган Брайан Уилсон

Шрифт:

 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;

 push(d);

}

argassign /* store top of stack in argument */

{

 Datum d;

 d = pop;

 push(d); /* leave value on stack */

 *getarg = d.val;

}

Функции

prstr
и
prexpr
печатают строки и числа:

prstr /* print string value */

{

 printf("%s", (char*)*pc++);

}

prexpr /* print numeric value */

{

 Datum d;

 d = pop;

 printf("%.8g d.val);

}

Функция

varread
читает переменные. Она возвращает 0 при обнаружении конца файла и 1 — в противном случае, а также устанавливает значение указанной переменной:

varread /* read into variable */

  • Читать дальше
  • 1
  • ...
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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