⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.c

📁 一个用flex、bison和vc开发的堆栈机
💻 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 + -