Читаем UNIX — универсальная среда программирования полностью

double errcheck(d, s) /* check result of library call */

 double d;

 char *s;

{

 if (errno == EDOM) {

  errno = 0;

  execerror(s, "argument out of domain");

 } else if (errno == ERANGE) {

  errno = 0;

  execerror(s, "result out of range");

 }

 return d;

}

3.4.7 symbol.c

#include "hoc.h"

#include "y.tab.h"


static Symbol *symlist =0; /* symbol table: linked list */


Symbol *lookup(s) /* find s in symbol table */

 char *s;

{

 Symbol *sp;


 for (sp = symlist; sp != (Symbol*)0; sp = sp-next)

  if (strcmp(sp-name, s) == 0)

   return sp;

 return 0; /* 0 == not found */

}


Symbol *install(s, t, d) /* install s in symbol table */

 char *s;

 int t;

 double d;

{

 Symbol *sp;

 char *emalloc;


 sp = (Symbol*)emalloc(sizeof(Symbol));

 sp-name = emalloc(strlen(s)+1); /* +1 for '\0' */

 strcpy(sp-name, s);

 sp-type = t;

 sp-u.val = d;

 sp-next = symlist; /* put at front of list */

 symlist = sp;

 return sp;

}


char *emalloc(n) /* check return from malloc */

 unsigned n;

{

 char *p, *malloc;


 p = malloc(n);

 if (p == 0)

  execerror("out of memory", (char*)0);

 return p;

}

3.5 hoc4

3.5.1 code.c

#include "hoc.h"

#include "y.tab.h"


#define NSTACK 256

static Datum stack[NSTACK]; /* the stack */

static Datum *stackp; /* next free spot on stack */


#define NPROG 2000

Inst prog[NPROG]; /* the machine */

Inst *progp; /* next free spot for code generation */

Inst *pc; /* program counter during execution */


initcode /* initialize for code generation */

{

 stackp = stack;

 progp = prog;

}


push(d) /* push d onto stack */

 Datum d;

{

 if (stackp = stack[NSTACK])

  execerror("stack overflow", (char*)0);

 *stackp++ = d;

}


Datum pop /* pop and return top elem from stack */

{

 if (stackp = stack)

  execerror("stack underflow", (char*)0);

 return *--stackp;

}


constpush /* push constant onto stack */

{

 Datum d;

 d.val = ((Symbol*)*pc++)-u.val;

 push(d);

}


varpush /* push variable onto stack */

{

 Datum d;

 d.sym = (Symbol*)(*pc++);

 push(d);

}


bltin /* evaluate built-in on top of stack */

{

 Datum d;

 d = pop;

 d.val = (*(double(*))(*pc++))(d.val);

 push(d);

}


eval /* evaluate variable on stack */

{

 Datum d;

 d = pop ;

 if (d.sym-type == UNDEF)

  execerror("undefined variable", d.sym-name);

 d.val = d.sym-u.val;

 push(d);

}


add /* add top two elems on stack */

{

 Datum d1, d2;

 d2 = pop;

 d1 = pop;

 d1.val += d2.val;

 push(d1);

}


sub /* subtract top of stack from next */

{

 Datum d1, d2;

 d2 = pop;

 d1 = pop;

 d1.val -= d2.val;

 push(d1);

}


mul {

 Datum d1, d2;

 d2 = pop;

 d1 = pop;

 d1.val *= d2.val;

 push(d1);

}


div {

 Datum d1, d2;

 d2 = pop;

 if (d2.val == 0.0)

  execerror("division by zero", (char*)0);

 d1 = pop;

 d1.val /= d2.val;

 push(d1);

}


negate {

 Datum d;

 d = pop;

 d.val = -d.val;

 push(d);

}


power {

 Datum d1, d2;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже