📄 addop.c
字号:
/* * 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 + -