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

📄 addop.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * addop - add opcodes to a function being compiled * * Copyright (C) 1999-2006  David I. Bell and Ernest Bowen * * Primary author:  David I. Bell * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL.  You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. * * @(#) $Revision: 29.13 $ * @(#) $Id: addop.c,v 29.13 2006/06/20 10:28:06 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/addop.c,v $ * * Under source code control:	1990/02/15 01:48:10 * File existed as early as:	before 1990 * * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include "calc.h"#include "opcodes.h"#include "string.h"#include "func.h"#include "token.h"#include "label.h"#include "symbol.h"#define FUNCALLOCSIZE	20	/* reallocate size for functions */#define OPCODEALLOCSIZE 100	/* reallocate size for opcodes in functions */static unsigned long maxopcodes;/* number of opcodes available */static long newindex;		/* index of new function */static char *newname;		/* name of new function */static long oldop;		/* previous opcode */static long oldoldop;		/* opcode before previous opcode */static long debugline;		/* line number of latest debug opcode */static long funccount;		/* number of functions */static long funcavail;		/* available number of functions */static FUNC *functemplate;	/* function definition template */static FUNC **functions;	/* table of functions */static STRINGHEAD funcnames;	/* function names *//* * Initialize the table of user defined functions. */voidinitfunctions(void){	initstr(&funcnames);	maxopcodes = OPCODEALLOCSIZE;	functemplate = (FUNC *) malloc(funcsize(maxopcodes));	if (functemplate == NULL) {		math_error("Cannot allocate function template");		/*NOTREACHED*/	}	functions = (FUNC **) malloc(sizeof(FUNC *) * FUNCALLOCSIZE);	if (functions == NULL) {		math_error("Cannot allocate function table");		/*NOTREACHED*/	}	funccount = 0;	funcavail = FUNCALLOCSIZE;}/* * Show the list of user defined functions. */voidshowfunctions(void){	FUNC *fp;		/* current function */	long count;	long index;	count = 0;	if (funccount > 0) {		if (conf->resource_debug & RSCDBG_FUNC_INFO)			math_str("Index\tName        \tArgs\tOpcodes\n"				 "-----\t------     \t---- \t------\n");		else			math_str("Name\tArguments\n"				 "----\t---------\n");		for (index = 0; index < funccount; index++) {			fp = functions[index];			if (conf->resource_debug & RSCDBG_FUNC_INFO) {				math_fmt("%5ld\t%-12s\t", index,					namestr(&funcnames,index));				if (fp) {					count++;					math_fmt("%-5d\t%-5ld\n",					 fp->f_paramcount, fp->f_opcodecount);				} else {					math_str("null\t0\n");				}			} else {				if (fp == NULL)					continue;				count++;				math_fmt("%-12s\t%-2d\n", namestr(&funcnames,					index), fp->f_paramcount);			}		}	}	if (conf->resource_debug & RSCDBG_FUNC_INFO) {		math_fmt("\nNumber non-null: %ld\n", count);		math_fmt("Number null: %ld\n", funccount - count);		math_fmt("Total number: %ld\n", funccount);	} else {		if (count > 0)			math_fmt("\nNumber: %ld\n", count);		else			math_str("No user functions defined\n");	}}/* * Initialize a function for definition. * Newflag is TRUE if we should allocate a new function structure, * instead of the usual overwriting of the template function structure. * The new structure is returned in the global curfunc variable. * * given: *	name		name of function *	newflag		TRUE if need new structure */voidbeginfunc(char *name, BOOL newflag){	register FUNC *fp;		/* current function */	newindex = adduserfunc(name);	maxopcodes = OPCODEALLOCSIZE;	fp = functemplate;	if (newflag) {		fp = (FUNC *) malloc(funcsize(maxopcodes));		if (fp == NULL) {			math_error("Cannot allocate temporary function");			/*NOTREACHED*/		}	}	fp->f_next = NULL;	fp->f_localcount = 0;	fp->f_opcodecount = 0;	fp->f_savedvalue.v_type = V_NULL;	fp->f_savedvalue.v_subtype = V_NOSUBTYPE;	newname = namestr(&funcnames, newindex);	fp->f_name = newname;	curfunc = fp;	initlocals();	initlabels();	oldop = OP_NOP;	oldoldop = OP_NOP;	debugline = 0;	errorcount = 0;}/* * Commit the just defined function for use. * This replaces any existing definition for the function. * This should only be called for normal user-defined functions. */voidendfunc(void){	register FUNC *fp;		/* function just finished */	size_t size;			/* size of just created function */	unsigned long index;	if (oldop != OP_RETURN) {		addop(OP_UNDEF);		addop(OP_RETURN);	}	checklabels();	if (errorcount) {		scanerror(T_NULL,"Compilation of \"%s\" failed: %ld error(s)",			 newname, errorcount);		return;	}	size = funcsize(curfunc->f_opcodecount);	fp = (FUNC *) malloc(size);	if (fp == NULL) {		math_error("Cannot commit function");		/*NOTREACHED*/	}	memcpy((char *) fp, (char *) curfunc, size);	if (curfunc != functemplate)		free(curfunc);	if (newname[0] != '*' && (conf->traceflags & TRACE_FNCODES)) {		dumpnames = TRUE;		for (size = 0; size < fp->f_opcodecount; ) {			printf("%ld: ", (unsigned long)size);			size += dumpop(&fp->f_opcodes[size]);		}	}	if ((inputisterminal() && conf->resource_debug & RSCDBG_STDIN_FUNC) ||	    (!inputisterminal() && conf->resource_debug & RSCDBG_FILE_FUNC)) {		printf("%s(", newname);		for (index = 0; index <	 fp->f_paramcount; index++) {			if (index)				putchar(',');			printf("%s", paramname(index));		}		printf(") ");		if (functions[newindex])			printf("re");		printf("defined\n");	}	if (functions[newindex]) {		freenumbers(functions[newindex]);		free(functions[newindex]);	}	functions[newindex] = fp;}/* * Find the user function with the specified name, and return its index. * If the function does not exist, its name is added to the function table * and an error will be generated when it is called if it is still undefined. * * given: *	name		name of function */longadduserfunc(char *name){	long index;		/* index of function */	index = findstr(&funcnames, name);	if (index >= 0)		return index;	if (funccount >= funcavail) {		functions = (FUNC **) realloc(functions,			sizeof(FUNC *) * (funcavail + FUNCALLOCSIZE));		if (functions == NULL) {			math_error("Failed to reallocate function table");			/*NOTREACHED*/		}		funcavail += FUNCALLOCSIZE;	}	if (addstr(&funcnames, name) == NULL) {		math_error("Cannot save function name");		/*NOTREACHED*/	}	index = funccount++;	functions[index] = NULL;	return index;}/* * Remove user defined function */voidrmuserfunc(char *name){	long index;		/* index of function */	index = findstr(&funcnames, name);	if (index < 0) {		warning("No function named \"%s\" to be undefined", name);		return;	}	if (functions[index] == NULL) {		warning("No defined function \"%s\" to be undefined", name);		return;	}	freenumbers(functions[index]);	free(functions[index]);	if ((inputisterminal() && conf->resource_debug & RSCDBG_STDIN_FUNC) ||	    (!inputisterminal() && conf->resource_debug & RSCDBG_FILE_FUNC))		printf("%s() undefined\n", name);	functions[index] = NULL;}/* * Free memory used to store function and its constants */voidfreefunc(FUNC *fp){	long index;	unsigned long i;	if (fp == NULL)		return;	if (fp == curfunc) {		index = newindex;	} else {		for (index = 0; index < funccount; index++) {			if (functions[index] == fp)				break;		}		if (index == funccount) {			math_error("Bad call to freefunc!!!");			/*NOTREACHED*/		}	}	if (newname[0] != '*' && (conf->traceflags & TRACE_FNCODES)) {		printf("Freeing function \"%s\"\n",namestr(&funcnames,index));		dumpnames = FALSE;		for (i = 0; i < fp->f_opcodecount; ) {			printf("%ld: ", i);			i += dumpop(&fp->f_opcodes[i]);		}	}	freenumbers(fp);	if (fp != functemplate)		free(fp);}voidrmalluserfunc(void){	FUNC *fp;	long index;	for (index = 0; index < funccount; index++) {		fp = functions[index];		if (fp) {			freefunc(fp);			functions[index] = NULL;		}	}}/* * get index of defined user function with specified name, or -1 if there

⌨️ 快捷键说明

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