UNIX — универсальная среда программирования
UNIX — универсальная среда программирования читать книгу онлайн
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями
shell.
Для программистов-пользователей операционной системы UNIX.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
$ cat code.c#include "hoc.h"#include "y.tab.h"#include <stdio.h>#define NSTACK 256static Datum stack[NSTACK]; /* the stack */static Datum *stackp; /* next free spot on stack */#define NPROG 2000Inst prog[NPROG]; /* the machine */Inst *progp; /* next free spot for code generation */Inst *pc; /* program counter during execution */Inst *progbase = prog; /* start of current subprogram */int returning; /* 1 if return stmt seen */typedef struct Frame { /* proc/func call stack frame */ Symbol *sp; /* symbol table entry */ Inst *retpc; /* where to resume after return */ Datum *argn; /* n-th argument on stack */ int nargs; /* number of arguments */} Frame;#define NFRAME 100 Frame frame[NFRAME];Frame *fp; /* frame pointer */initcode() { progp = progbase; stackp = stack; fp = frame; returning = 0;}...$Поскольку теперь в таблице имен хранятся указатели на функции и процедуры, а также на строки для печати, необходимо расширить определение типа объединения в файле
hoc.h$ cat hoc.htypedef struct Symbol { /* symbol table entry */ char *name; short type; union { double val; /* VAR */ double (*ptr)(); /* BLTIN */ int (*defn)(); /* FUNCTION, PROCEDURE */ char *str; /* STRING */ } u; struct Symbol *next; /* to link to another */} Symbol;$В процессе трансляции функция
definedefine(sp) /* put func/proc in symbol table */ Symbol *sp;{ sp->u.defn = (Inst)progbase; /* start of code */ progbase = progp; /* next code starts here */}Когда в процессе выполнения вызывается функция или процедура, все аргументы уже вычислены и помещены в стек (первый аргумент находится на наибольшем уровне). Код операции вызова (
callcallcall() /* 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: Структуры данных для вызова процедуры
В конце концов произойдет возврат из вызываемой программы при выполнении
procretfuncretfuncret() /* 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();}Функция
retfpret() /* common return from func or proc */{ int i; for (i = 0; i < fp->nargs; i++) pop(); /* pop arguments */
