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

📄 addop.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 2 页
字号:
 * is none or if it has been undefined */longgetuserfunc(char *name){	long index;	index = findstr(&funcnames, name);	if (index >= 0 && functions[index] != NULL)		return index;	return -1L;}/* * Clear any optimization that may be done for the next opcode. * This is used when defining a label. */voidclearopt(void){	oldop = OP_NOP;	oldoldop = OP_NOP;	debugline = 0;}/* * Find a function structure given its index. */FUNC *findfunc(long index){	if (index >= funccount) {		math_error("Undefined function");		/*NOTREACHED*/	}	return functions[index];}/* * Return the name of a function given its index. */char *namefunc(long index){	return namestr(&funcnames, index);}/* * Let a matrix indexing operation know that it will be treated as a write * reference instead of just as a read reference. */voidwriteindexop(void){	if (oldop == OP_INDEXADDR)		curfunc->f_opcodes[curfunc->f_opcodecount - 1] = TRUE;}/* * Add an opcode to the current function being compiled. * Note: This can change the curfunc global variable when the * function needs expanding. */voidaddop(long op){	register FUNC *fp;		/* current function */	NUMBER *q, *q1, *q2;	unsigned long count;	BOOL cut;	int diff;	fp = curfunc;	count = fp->f_opcodecount;	cut = TRUE;	diff = 2;	q = NULL;	if ((count + 5) >= maxopcodes) {		maxopcodes += OPCODEALLOCSIZE;		fp = (FUNC *) malloc(funcsize(maxopcodes));		if (fp == NULL) {			math_error("cannot malloc function");			/*NOTREACHED*/		}		memcpy((char *) fp, (char *) curfunc,			funcsize(curfunc->f_opcodecount));		if (curfunc != functemplate)			free(curfunc);		curfunc = fp;	}	/*	 * Check the current opcode against the previous opcode and try to	 * slightly optimize the code depending on the various combinations.	 */	switch (op) {	case OP_GETVALUE:		switch (oldop) {		case OP_NUMBER:		case OP_ZERO:		case OP_ONE:		case OP_IMAGINARY:		case OP_GETEPSILON:		case OP_SETEPSILON:		case OP_STRING:		case OP_UNDEF:		case OP_GETCONFIG:		case OP_SETCONFIG:			return;		case OP_DUPLICATE:			diff = 1;			oldop = OP_DUPVALUE;			break;		case OP_FIADDR:			diff = 1;			oldop = OP_FIVALUE;			break;		case OP_GLOBALADDR:			diff = 1 + PTR_SIZE;			oldop = OP_GLOBALVALUE;			break;		case OP_LOCALADDR:			oldop = OP_LOCALVALUE;			break;		case OP_PARAMADDR:			oldop = OP_PARAMVALUE;			break;		case OP_ELEMADDR:			oldop = OP_ELEMVALUE;			break;		default:			cut = FALSE;		}		if (cut) {			fp->f_opcodes[count - diff] = oldop;			return;		}		break;	case OP_POP:		switch (oldop) {		case OP_ASSIGN:			fp->f_opcodes[count-1] = OP_ASSIGNPOP;			oldop = OP_ASSIGNPOP;			return;		case OP_NUMBER:		case OP_IMAGINARY:			q = constvalue(fp->f_opcodes[count-1]);			qfree(q);			break;		case OP_STRING:			sfree(findstring((long)fp->f_opcodes[count-1]));			break;		case OP_LOCALADDR:		case OP_PARAMADDR:			break;		case OP_GLOBALADDR:			diff = 1 + PTR_SIZE;			break;		case OP_UNDEF:			fp->f_opcodecount -= 1;			oldop = OP_NOP;			oldoldop = OP_NOP;			return;		default:			cut = FALSE;		}		if (cut) {			fp->f_opcodecount -= diff;			oldop = OP_NOP;			oldoldop = OP_NOP;			warning("Constant before comma operator");			return;		}		break;	case OP_NEGATE:		if (oldop == OP_NUMBER) {			q = constvalue(fp->f_opcodes[count-1]);			fp->f_opcodes[count-1] = addqconstant(qneg(q));			qfree(q);			return;		}	}	if (oldop == OP_NUMBER) {		if (oldoldop == OP_NUMBER) {			q1 = constvalue(fp->f_opcodes[count - 3]);			q2 = constvalue(fp->f_opcodes[count - 1]);			switch (op) {			case OP_DIV:				if (qiszero(q2)) {					cut = FALSE;					break;				}				q = qqdiv(q1,q2);				break;			case OP_MUL:				q = qmul(q1,q2);				break;			case OP_ADD:				q = qqadd(q1,q2);				break;			case OP_SUB:				q = qsub(q1,q2);				break;			case OP_POWER:				if (qisfrac(q2) || qisneg(q2))					cut = FALSE;				else					q = qpowi(q1,q2);				break;			default:				cut = FALSE;			}			if (cut) {				qfree(q1);				qfree(q2);				fp->f_opcodes[count - 3] = addqconstant(q);				fp->f_opcodecount -= 2;				oldoldop = OP_NOP;				return;			}		} else if (op != OP_NUMBER) {			q = constvalue(fp->f_opcodes[count - 1]);			if (op == OP_POWER) {				if (qcmpi(q, 2L) == 0) {					fp->f_opcodecount--;					fp->f_opcodes[count - 2] = OP_SQUARE;					qfree(q);					oldop = OP_SQUARE;					return;				}				if (qcmpi(q, 4L) == 0) {					fp->f_opcodes[count - 2] = OP_SQUARE;					fp->f_opcodes[count - 1] = OP_SQUARE;					qfree(q);					oldop = OP_SQUARE;					return;				}			}			if (qiszero(q)) {				qfree(q);				fp->f_opcodes[count - 2] = OP_ZERO;				fp->f_opcodecount--;			} else if (qisone(q)) {				qfree(q);				fp->f_opcodes[count - 2] = OP_ONE;				fp->f_opcodecount--;			}		}	}	/*	 * No optimization possible, so store the opcode.	 */	fp->f_opcodes[fp->f_opcodecount] = op;	fp->f_opcodecount++;	oldoldop = oldop;	oldop = op;}/* * Add an opcode and and one integer argument to the current function * being compiled. */voidaddopone(long op, long arg){	if (op == OP_DEBUG) {		if ((conf->traceflags & TRACE_NODEBUG) || (arg == debugline))			return;		debugline = arg;		if (oldop == OP_DEBUG) {			curfunc->f_opcodes[curfunc->f_opcodecount - 1] = arg;			return;		}	}	addop(op);	curfunc->f_opcodes[curfunc->f_opcodecount] = arg;	curfunc->f_opcodecount++;}/* * Add an opcode and and two integer arguments to the current function * being compiled. */voidaddoptwo(long op, long arg1, long arg2){	addop(op);	curfunc->f_opcodes[curfunc->f_opcodecount++] = arg1;	curfunc->f_opcodes[curfunc->f_opcodecount++] = arg2;}/* * Add an opcode and a character pointer to the function being compiled. */voidaddopptr(long op, char *ptr){	char **ptraddr;	addop(op);	ptraddr = (char **) &curfunc->f_opcodes[curfunc->f_opcodecount];	*ptraddr = ptr;	curfunc->f_opcodecount += PTR_SIZE;}/* * Add an opcode and an index and an argument count for a function call. */voidaddopfunction(long op, long index, int count){	long newop;	if ((op == OP_CALL) && ((newop = builtinopcode(index)) != OP_NOP)) {		if ((newop == OP_SETCONFIG) && (count == 1))			newop = OP_GETCONFIG;		if ((newop == OP_SETEPSILON) && (count == 0))			newop = OP_GETEPSILON;		if ((newop == OP_ABS) && (count == 1))			addop(OP_GETEPSILON);		addop(newop);		return;	}	addop(op);	curfunc->f_opcodes[curfunc->f_opcodecount++] = index;	curfunc->f_opcodes[curfunc->f_opcodecount++] = count;}/* * Add a jump-type opcode and a label to the function being compiled. * * given: *	label		label to be added */voidaddoplabel(long op, LABEL *label){	addop(op);	uselabel(label);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -