?? code.c
字號:
#include <stdio.h>
#include <assert.h>
#include "stkmach.h"
#include "cc_tab.h"
#include "math.h"
#define NSTACK 256
static Datum stack[NSTACK];
static Datum *stackp;/*next free spot on stack*/
#define NPROG 2000
Inst prog[NPROG];
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 */
int indef = 0;
#define NFRAME 100
Frame frame[NFRAME];
Frame *fp;
initcode()
{
stackp = stack;
progp = progbase;
fp = frame;
returning = 0;
}
push(Datum d)
{
if (stackp >= &stack[NSTACK])
execerror("stack overflow", (char *)0);
*(stackp++) = d;
}
Datum pop()
{
if (stackp <= stack)
execerror("stack underflow", (char *)0);
return *(--stackp);
}
Inst *code(Inst f)
{
Inst *oprogp = progp;
if (progp >= &prog[NPROG])
execerror("program too big", (char *)0);
*(progp++) = f;
return oprogp;
}
excute(Inst p)
{
for (pc=p; *pc!=STOP; )
(*(*pc++))();
}
constpush()
{
Datum d;
d.val = ((symrec *)*pc++)->value.val;
push(d);
}
varpush()
{
Datum d;
d.sym = (symrec *)(*pc++);
push(d);
}
add()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val += d2.val;
push(d1);
}
sub()
{
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);
}
divi()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
if (d2.val == 0.0)
execerror("divided by zero", (char *) 0);
d1.val /= d2.val;
push(d1);
}
neg()
{
Datum d;
d = pop();
d.val = 0.0 - d.val;
push(d);
}
power()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = pow(d1.val, d2.val);
push(d1);
}
eval() /*取變量值*/
{
Datum d;
d = pop();
if (d.sym->type == UNDEF)
execerror("undefine variable", d.sym->name);
d.val = d.sym->value.val;
push(d);
}
assign() /*賦值*/
{
Datum d1, d2;
d1 = pop();
d2 = pop();
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
execerror("assignment to non-variable", d1.sym->name);
d1.sym->value.val = d2.val;
d1.sym->type = VAR;
push(d2);
}
print() /*彈出并打印棧頂元素值*/
{
Datum d;
d = pop();
printf("\t%.8g\n", d.val);
}
bltin() /*計算棧頂函數值*/
{
Datum d;
d = pop();
d.val = (*(double (*)())(*pc++))(d.val);/* *pc為返回值為雙精度的函數指針 */
push(d);
}
gt()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val > d2.val);
push(d1);
}
lt()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val < d2.val);
push(d1);
}
ge()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val >= d2.val);
push(d1);
}
le()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val <= d2.val);
push(d1);
}
eq()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val == d2.val);
push(d1);
}
ne()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val != d2.val);
push(d1);
}
and()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val && d2.val);
push(d1);
}
or()
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val || d2.val);
push(d1);
}
not()
{
Datum d;
d = pop();
d.val = (double)(!d.val);
push(d);
}
whilecode()
{
Datum d;
Inst *savepc = pc; /* loop body */
excute(savepc+2);
d = pop();
while (d.val) {
excute(*((Inst **)(savepc))); /* body */
excute(savepc+2);
d = pop();
}
pc = *((Inst **)(savepc+1)); /* next statement */
}
ifcode()
{
Datum d;
Inst *savepc = pc; /* then part */
excute(savepc+3);
d = pop();
if (d.val)
excute(*((Inst **)(savepc))); /* then */
else if (*((Inst **)(savepc+1))) /* else part */
excute(*((Inst **)(savepc+1)));
pc = *((Inst **)(savepc+2)); /* next statement */
}
prexpr() /* print numeric value*/
{
Datum d;
d = pop();
printf("%.8g\n", d.val);
}
defnonly(char *s)
{
if (!indef)
execerror(s, "used outside definition");
}
call()
{
symrec *sp = (symrec *)pc[0];/*symbol table entry for function/procedure*/
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 */
excute(sp->value.defn);
returning = 0;
}
ret()
{
int i;
for (i=0; i<fp->nargs; i++)
pop(); /* pop arguments */
pc = (Inst *)fp->retpc;
--fp;
returning = 1;
}
funcret()
{
Datum d;
/*assert(fp != frame);*/
if (fp->sp->type == PROCEDURE)
execerror(fp->sp->name, "(proc) returns value");
d = pop();
ret();
push(d);
}
procret()
{
Datum d;
if (fp->sp->type == FUNCTION)
execerror(fp->sp->name, "(proc) returns no value");
d = pop();
}
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 to 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;
}
varread()
{
Datum d;
extern FILE *yyin;
symrec *var = (symrec *) *pc++;
Again:
switch (fscanf(yyin, "%lf", &var->value.val))
{
case EOF:
if (moreinput())
goto Again;
d.val = var->value.val = 0.0;
break;
case 0:
execerror("non-number read into", var->name);
break;
default:
d.val = 1.0;
break;
}
var->type = VAR;
push(d);
}
prstr()
{
printf("%s", (char *) *pc++);
}
define(symrec *sp)
{
sp->value.defn = (Inst)progbase; /* start of the code */
progbase = progp; /* next code starts here */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -