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

📄 func.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1994 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * Built-in functions implemented here */#include <sys/types.h>#include <sys/times.h>#include <time.h>#include "calc.h"#include "opcodes.h"#include "token.h"#include "func.h"#include "string.h"#include "symbol.h"/* if HZ & CLK_TCK are not defined, pick typical values, hope for the best */#if !defined(HZ)#  define HZ 60#endif#if !defined(CLK_TCK)# undef CLK_TCK# define CLK_TCK HZ#endifextern int errno;/* * Totally numeric functions. */static NUMBER *f_cfsim();	/* simplify number using continued fractions */static NUMBER *f_ilog();	/* return log of one number to another */static NUMBER *f_faccnt();	/* count of divisions */static NUMBER *f_min();		/* minimum of several arguments */static NUMBER *f_max();		/* maximum of several arguments */static NUMBER *f_hmean();	/* harmonic mean */static NUMBER *f_trunc();	/* truncate number to specified decimal places */static NUMBER *f_btrunc();	/* truncate number to specified binary places */static NUMBER *f_gcd();		/* greatest common divisor */static NUMBER *f_lcm();		/* least common multiple */static NUMBER *f_xor();		/* xor of several arguments */static NUMBER *f_ceil();	/* ceiling of a fraction */static NUMBER *f_floor();	/* floor of a fraction */static NUMBER *f_meq();		/* numbers are same modular value */static NUMBER *f_isrel();	/* two numbers are relatively prime */static NUMBER *f_ismult();	/* whether one number divides another */static NUMBER *f_mne();		/* whether a and b are not equal modulo c */static NUMBER *f_isset();	/* tests if a bit of a num (base 2) is set */static NUMBER *f_highbit();	/* high bit number in base 2 representation */static NUMBER *f_lowbit();	/* low bit number in base 2 representation */static NUMBER *f_near();	/* whether two numbers are near each other */static NUMBER *f_legtoleg();	/* positive form of leg to leg */static NUMBER *f_ilog10();	/* integer log of number base 10 */static NUMBER *f_ilog2();	/* integer log of number base 2 */static NUMBER *f_digits();	/* number of digits of number */static NUMBER *f_digit();	/* digit at specified decimal place of number */static NUMBER *f_places();	/* number of decimal places of number */static NUMBER *f_primetest();	/* primality test */static NUMBER *f_issquare();	/* whether number is a square */static NUMBER *f_runtime();	/* user runtime in seconds */static NUMBER *f_base();	/* set default output base *//* * General functions. */static VALUE f_hash();		/* produce hash from values */static VALUE f_bround();	/* round number to specified binary places */static VALUE f_round();		/* round number to specified decimal places */static VALUE f_det();		/* determinant of matrix */static VALUE f_mattrans();	/* return transpose of matrix */static VALUE f_matdim();	/* dimension of matrix */static VALUE f_matmax();	/* maximum index of matrix dimension */static VALUE f_matmin();	/* minimum index of matrix dimension */static VALUE f_matfill();	/* fill matrix with values */static VALUE f_listpush();	/* push element onto front of list */static VALUE f_listpop();	/* pop element from front of list */static VALUE f_listappend();	/* append element to end of list */static VALUE f_listremove();	/* remove element from end of list */static VALUE f_listinsert();	/* insert element into list */static VALUE f_listdelete();	/* delete element from list */static VALUE f_strlen();	/* length of string */static VALUE f_char();		/* character value of integer */static VALUE f_substr();	/* extract substring */static VALUE f_strcat();	/* concatenate strings */static VALUE f_ord();		/* get ordinal value for character */static VALUE f_avg();		/* average of several arguments */static VALUE f_ssq();		/* sum of squares */static VALUE f_poly();		/* result of evaluating polynomial */static VALUE f_sqrt();		/* square root of a number */static VALUE f_root();		/* number taken to root of another */static VALUE f_exp();		/* complex exponential */static VALUE f_ln();		/* complex natural logarithm */static VALUE f_power();		/* one value to another power */static VALUE f_cos();		/* complex cosine */static VALUE f_sin();		/* complex sine */static VALUE f_polar();		/* polar representation of complex number */static VALUE f_arg();		/* argument of complex number */static VALUE f_list();		/* create a list */static VALUE f_size();		/* number of elements in object */static VALUE f_search();	/* search matrix or list for match */static VALUE f_rsearch();	/* search matrix or list backwards for match */static VALUE f_cp();		/* cross product of vectors */static VALUE f_dp();		/* dot product of vectors */static VALUE f_prompt();	/* prompt for input line */static VALUE f_eval();		/* evaluate string into value */static VALUE f_str();		/* convert value to string */static VALUE f_fopen();		/* open file for reading or writing */static VALUE f_fprintf();	/* print data to file */static VALUE f_strprintf();	/* return printed data as a string */static VALUE f_fgetline();	/* read next line from file */static VALUE f_fgetc();		/* read next char from file */static VALUE f_fflush();	/* flush output to file */static VALUE f_printf();	/* print data to stdout */static VALUE f_fclose();	/* close file */static VALUE f_ferror();	/* whether error occurred */static VALUE f_feof();		/* whether end of file reached */static VALUE f_files();		/* return file handle or number of files */static VALUE f_assoc();		/* return a new association value */#define IN 100		/* maximum number of arguments */#define	FE 0x01		/* flag to indicate default epsilon argument */#define	FA 0x02		/* preserve addresses of variables *//* * List of primitive built-in functions */static struct builtin {	char *b_name;		/* name of built-in function */	short b_minargs;	/* minimum number of arguments */	short b_maxargs;	/* maximum number of arguments */	short b_flags;		/* special handling flags */	short b_opcode;		/* opcode which makes the call quick */	NUMBER *(*b_numfunc)();	/* routine to calculate numeric function */	VALUE (*b_valfunc)();	/* routine to calculate general values */	char *b_desc;		/* description of function */} builtins[] = {	"abs", 1, 2, 0, OP_ABS, 0, 0, "absolute value within accuracy b",	"acos", 1, 2, FE, OP_NOP, qacos, 0, "arccosine of a within accuracy b",	"acosh", 1, 2, FE, OP_NOP, qacosh, 0, "hyperbolic arccosine of a within accuracy b",	"append", 2, 2, FA, OP_NOP, 0, f_listappend, "append value to end of list",	"appr", 1, 2, FE, OP_NOP, qbappr, 0, "approximate a with simpler fraction to within b",	"arg", 1, 2, 0, OP_NOP, 0, f_arg, "argument (the angle) of complex number",	"asin", 1, 2, FE, OP_NOP, qasin, 0, "arcsine of a within accuracy b",	"asinh", 1, 2, FE, OP_NOP, qasinh, 0, "hyperbolic arcsine of a within accuracy b",	"assoc", 0, 0, 0, OP_NOP, 0, f_assoc, "create new association array",	"atan", 1, 2, FE, OP_NOP, qatan, 0, "arctangent of a within accuracy b",	"atan2", 2, 3, FE, OP_NOP, qatan2, 0, "angle to point (b,a) within accuracy c",	"atanh", 1, 2, FE, OP_NOP, qatanh, 0, "hyperbolic arctangent of a within accuracy b",	"avg", 1, IN, 0, OP_NOP, 0, f_avg, "arithmetic mean of values",	"base", 0, 1, 0, OP_NOP, f_base, 0, "set default output base",	"bround", 1, 2, 0, OP_NOP, 0, f_bround, "round value a to b number of binary places",	"btrunc", 1, 2, 0, OP_NOP, f_btrunc, 0, "truncate a to b number of binary places",	"ceil", 1, 1, 0, OP_NOP, f_ceil, 0, "smallest integer greater than or equal to number",	"cfappr", 1, 2, FE, OP_NOP, qcfappr, 0, "approximate a within accuracy b using\n\t\t    continued fractions",	"cfsim", 1, 1, 0, OP_NOP, f_cfsim, 0, "simplify number using continued fractions",	"char", 1, 1, 0, OP_NOP, 0, f_char, "character corresponding to integer value",	"cmp", 2, 2, 0, OP_CMP, 0, 0, "compare values returning -1, 0, or 1",	"comb", 2, 2, 0, OP_NOP, qcomb, 0, "combinatorial number a!/b!(a-b)!",	"config", 1, 2, 0, OP_SETCONFIG, 0, 0, "set or read configuration value",	"conj", 1, 1, 0, OP_CONJUGATE, 0, 0, "complex conjugate of value",	"cos", 1, 2, 0, OP_NOP, 0, f_cos, "cosine of value a within accuracy b",	"cosh", 1, 2, FE, OP_NOP, qcosh, 0, "hyperbolic cosine of a within accuracy b",	"cp", 2, 2, 0, OP_NOP, 0, f_cp, "Cross product of two vectors",	"delete", 2, 2, FA, OP_NOP, 0, f_listdelete, "delete element from list a at position b",	"den", 1, 1, 0, OP_DENOMINATOR, qden, 0, "denominator of fraction",	"det", 1, 1, 0, OP_NOP, 0, f_det, "determinant of matrix",	"digit", 2, 2, 0, OP_NOP, f_digit, 0, "digit at specified decimal place of number",	"digits", 1, 1, 0, OP_NOP, f_digits, 0, "number of digits in number",	"dp", 2, 2, 0, OP_NOP, 0, f_dp, "Dot product of two vectors",	"epsilon", 0, 1, 0, OP_SETEPSILON, 0, 0, "set or read allowed error for real calculations",	"eval", 1, 1, 0, OP_NOP, 0, f_eval, "Evaluate expression from string to value",	"exp", 1, 2, 0, OP_NOP, 0, f_exp, "exponential of value a within accuracy b",	"fcnt", 2, 2, 0, OP_NOP, f_faccnt, 0, "count of times one number divides another",	"fib", 1, 1, 0, OP_NOP, qfib, 0, "Fibonacci number F(n)",	"frem", 2, 2, 0, OP_NOP, qfacrem, 0, "number with all occurrences of factor removed",	"fact", 1, 1, 0, OP_NOP, qfact, 0, "factorial",	"fclose", 1, 1, 0, OP_NOP, 0, f_fclose, "close file",	"feof", 1, 1, 0, OP_NOP, 0, f_feof, "whether EOF reached for file",	"ferror", 1, 1, 0, OP_NOP, 0, f_ferror, "whether error occurred for file",	"fflush", 1, 1, 0, OP_NOP, 0, f_fflush, "flush output to file",	"fgetc", 1, 1, 0, OP_NOP, 0, f_fgetc, "read next char from file",	"fgetline", 1, 1, 0, OP_NOP, 0, f_fgetline, "read next line from file",	"files", 0, 1, 0, OP_NOP, 0, f_files, "return opened file or max number of opened files",	"floor", 1, 1, 0, OP_NOP, f_floor, 0, "greatest integer less than or equal to number",	"fopen", 2, 2, 0, OP_NOP, 0, f_fopen, "open file name a in mode b",	"fprintf", 2, IN, 0, OP_NOP, 0, f_fprintf, "print formatted output to opened file",	"frac", 1, 1, 0, OP_FRAC, qfrac, 0, "fractional part of value",	"gcd", 1, IN, 0, OP_NOP, f_gcd, 0, "greatest common divisor",	"gcdrem", 2, 2, 0, OP_NOP, qgcdrem, 0, "a divided repeatedly by gcd with b",	"hash", 1, IN, 0, OP_NOP, 0, f_hash, "return non-negative hash value for one or\n\t\t    more values",	"highbit", 1, 1, 0, OP_NOP, f_highbit, 0, "high bit number in base 2 representation",	"hmean", 1, IN, 0, OP_NOP, f_hmean, 0, "harmonic mean of values",	"hypot", 2, 3, FE, OP_NOP, qhypot, 0, "hypotenuse of right triangle within accuracy c",	"ilog", 2, 2, 0, OP_NOP, f_ilog, 0, "integral log of one number with another",	"ilog10", 1, 1, 0, OP_NOP, f_ilog10, 0, "integral log of a number base 10",	"ilog2", 1, 1, 0, OP_NOP, f_ilog2, 0, "integral log of a number base 2",	"im", 1, 1, 0, OP_IM, 0, 0, "imaginary part of complex number",	"insert", 3, 3, FA, OP_NOP, 0, f_listinsert, "insert value c into list a at position b", 	"int", 1, 1, 0, OP_INT, qint, 0, "integer part of value",	"inverse", 1, 1, 0, OP_INVERT, 0, 0, "multiplicative inverse of value",	"iroot", 2, 2, 0, OP_NOP, qiroot, 0, "integer b'th root of a",	"isassoc", 1, 1, 0, OP_ISASSOC, 0, 0, "whether a value is an association",	"iseven", 1, 1, 0, OP_ISEVEN, 0, 0, "whether a value is an even integer",	"isfile", 1, 1, 0, OP_ISFILE, 0, 0, "whether a value is a file",	"isint", 1, 1, 0, OP_ISINT, 0, 0, "whether a value is an integer",	"islist", 1, 1, 0, OP_ISLIST, 0, 0, "whether a value is a list",	"ismat", 1, 1, 0, OP_ISMAT, 0, 0, "whether a value is a matrix",	"ismult", 2, 2, 0, OP_NOP, f_ismult, 0, "whether a is a multiple of b",	"isnull", 1, 1, 0, OP_ISNULL, 0, 0, "whether a value is the null value",	"isnum", 1, 1, 0, OP_ISNUM, 0, 0, "whether a value is a number",	"isobj", 1, 1, 0, OP_ISOBJ, 0, 0, "whether a value is an object",	"isodd", 1, 1, 0, OP_ISODD, 0, 0, "whether a value is an odd integer",	"isqrt", 1, 1, 0, OP_NOP, qisqrt, 0, "integer part of square root",	"isreal", 1, 1, 0, OP_ISREAL, 0, 0, "whether a value is a real number",	"isset", 2, 2, 0, OP_NOP, f_isset, 0, "whether bit b of abs(a) (in base 2) is set",	"isstr", 1, 1, 0, OP_ISSTR, 0, 0, "whether a value is a string",	"isrel", 2, 2, 0, OP_NOP, f_isrel, 0, "whether two numbers are relatively prime",	"issimple", 1, 1, 0, OP_ISSIMPLE, 0, 0, "whether value is a simple type",	"issq", 1, 1, 0, OP_NOP, f_issquare, 0, "whether or not number is a square", 	"istype", 2, 2, 0, OP_ISTYPE, 0, 0, "whether the type of a is same as the type of b",	"jacobi", 2, 2, 0, OP_NOP, qjacobi, 0, "-1 => a is not quadratic residue mod b\n\t\t  1 => b is composite, or a is quad residue of b",	"lcm", 1, IN, 0, OP_NOP, f_lcm, 0, "least common multiple",	"lcmfact", 1, 1, 0, OP_NOP, qlcmfact, 0, "lcm of all integers up till number",	"lfactor", 2, 2, 0, OP_NOP, qlowfactor, 0, "lowest prime factor of a in first b primes",	"list", 0, IN, 0, OP_NOP, 0, f_list, "create list of specified values",	"ln", 1, 2, 0, OP_NOP, 0, f_ln, "natural logarithm of value a within accuracy b",	"lowbit", 1, 1, 0, OP_NOP, f_lowbit, 0, "low bit number in base 2 representation",	"ltol", 1, 2, FE, OP_NOP, f_legtoleg, 0, "leg-to-leg of unit right triangle (sqrt(1 - a^2))",	"matdim", 1, 1, 0, OP_NOP, 0, f_matdim, "number of dimensions of matrix",	"matfill", 2, 3, FA, OP_NOP, 0, f_matfill, "fill matrix with value b (value c on diagonal)",	"matmax", 2, 2, 0, OP_NOP, 0, f_matmax, "maximum index of matrix a dim b",	"matmin", 2, 2, 0, OP_NOP, 0, f_matmin, "minimum index of matrix a dim b",	"mattrans", 1, 1, 0, OP_NOP, 0, f_mattrans, "transpose of matrix",	"max", 1, IN, 0, OP_NOP, f_max, 0, "maximum value",	"meq", 3, 3, 0, OP_NOP, f_meq, 0, "whether a and b are equal modulo c",	"min", 1, IN, 0, OP_NOP, f_min, 0, "minimum value",	"minv", 2, 2, 0, OP_NOP, qminv, 0, "inverse of a modulo b",	"mmin", 2, 2, 0, OP_NOP, qminmod, 0, "a mod b value with smallest abs value",	"mne", 3, 3, 0, OP_NOP, f_mne, 0, "whether a and b are not equal modulo c",	"near", 2, 3, 0, OP_NOP, f_near, 0, "sign of (abs(a-b) - c)",	"norm", 1, 1, 0, OP_NORM, 0, 0, "norm of a value (square of absolute value)",	"null", 0, 0, 0, OP_UNDEF, 0, 0, "null value",	"num", 1, 1, 0, OP_NUMERATOR, qnum, 0, "numerator of fraction",	"ord", 1, 1, 0, OP_NOP, 0, f_ord, "integer corresponding to character value",	"param", 1, 1, 0, OP_ARGVALUE, 0, 0, "value of parameter n (or parameter count if n\n\t\t    is zero)",	"perm", 2, 2, 0, OP_NOP, qperm, 0, "permutation number a!/(a-b)!",	"pfact", 1, 1, 0, OP_NOP, qpfact, 0, "product of primes up till number",	"pi", 0, 1, FE, OP_NOP, qpi, 0, "value of pi accurate to within epsilon",	"places", 1, 1, 0, OP_NOP, f_places, 0, "places after decimal point (-1 if infinite)",	"pmod", 3, 3, 0, OP_NOP, qpowermod,0, "mod of a power (a ^ b (mod c))",	"polar", 2, 3, 0, OP_NOP, 0, f_polar, "complex value of polar coordinate (a * exp(b*1i))",	"poly", 2, IN, 0, OP_NOP, 0, f_poly, "(a1,a2,...,an,x) = a1*x^n+a2*x^(n-1)+...+an",	"pop", 1, 1, FA, OP_NOP, 0, f_listpop, "pop value from front of list",	"power", 2, 3, 0, OP_NOP, 0, f_power, "value a raised to the power b within accuracy c",	"ptest", 2, 2, 0, OP_NOP, f_primetest, 0, "probabilistic primality test",	"printf", 1, IN, 0, OP_NOP, 0, f_printf, "print formatted output to stdout",	"prompt", 1, 1, 0, OP_NOP, 0, f_prompt, "prompt for input line using value a",	"push", 2, 2, FA, OP_NOP, 0, f_listpush, "push value onto front of list",	"quomod", 4, 4, 0, OP_QUOMOD, 0, 0, "set c and d to quotient and remainder of a\n\t\t    divided by b",	"rcin", 2, 2, 0, OP_NOP, qredcin, 0, "convert normal number a to REDC number mod b",	"rcmul", 3, 3, 0, OP_NOP, qredcmul, 0, "multiply REDC numbers a and b mod c",	"rcout", 2, 2, 0, OP_NOP, qredcout, 0, "convert REDC number a mod b to normal number",	"rcpow", 3, 3, 0, OP_NOP, qredcpower, 0, "raise REDC number a to power b mod c",	"rcsq", 2, 2, 0, OP_NOP, qredcsquare, 0, "square REDC number a mod b",	"re", 1, 1, 0, OP_RE, 0, 0, "real part of complex number",	"remove", 1, 1, FA, OP_NOP, 0, f_listremove, "remove value from end of list",	"root", 2, 3, 0, OP_NOP, 0, f_root, "value a taken to the b'th root within accuracy c",	"round", 1, 2, 0, OP_NOP, 0, f_round, "round value a to b number of decimal places",	"rsearch", 2, 3, 0, OP_NOP, 0, f_rsearch, "reverse search matrix or list for value b\n\t\t    starting at index c",	"runtime", 0, 0, 0, OP_NOP, f_runtime, 0, "user mode cpu time in seconds",	"scale", 2, 2, 0, OP_SCALE, 0, 0, "scale value up or down by a power of two",	"search", 2, 3, 0, OP_NOP, 0, f_search, "search matrix or list for value b starting\n\t\t    at index c",	"sgn", 1, 1, 0, OP_SGN, qsign, 0, "sign of value (-1, 0, 1)",	"sin", 1, 2, 0, OP_NOP, 0, f_sin, "sine of value a within accuracy b",	"sinh", 1, 2, FE, OP_NOP, qsinh, 0, "hyperbolic sine of a within accuracy b",	"size", 1, 1, 0, OP_NOP, 0, f_size, "total number of elements in value",	"sqrt", 1, 2, 0, OP_NOP, 0, f_sqrt, "square root of value a within accuracy b",	"ssq", 1, IN, 0, OP_NOP, 0, f_ssq, "sum of squares of values",	"str", 1, 1, 0, OP_NOP, 0, f_str, "simple value converted to string",	"strcat", 1,IN, 0, OP_NOP, 0, f_strcat, "concatenate strings together",	"strlen", 1, 1, 0, OP_NOP, 0, f_strlen, "length of string",	"strprintf", 1, IN, 0, OP_NOP, 0, f_strprintf, "return formatted output as a string",	"substr", 3, 3, 0, OP_NOP, 0, f_substr, "substring of a from position b for c chars",	"swap", 2, 2, 0, OP_SWAP, 0, 0, "swap values of variables a and b (can be dangerous)",	"tan", 1, 2, FE, OP_NOP, qtan, 0, "tangent of a within accuracy b",	"tanh", 1, 2, FE, OP_NOP, qtanh, 0, "hyperbolic tangent of a within accuracy b",	"trunc", 1, 2, 0, OP_NOP, f_trunc, 0, "truncate a to b number of decimal places",	"xor", 1, IN, 0, OP_NOP, f_xor, 0, "logical xor",	NULL, 0, 0, 0, OP_NOP, 0, 0, NULL /* end of table */};/* * Call a built-in function. * Arguments to the function are on the stack, but are not removed here. * Functions are either purely numeric, or else can take any value type. */VALUEbuiltinfunc(index, argcount, stck)	int argcount;	long index;	VALUE *stck;		/* arguments on the stack */{	VALUE *sp;		/* pointer to stack entries */	VALUE **vpp;		/* pointer to current value address */	struct builtin *bp;	/* builtin function to be called */	long i;			/* index */	NUMBER *numargs[IN];	/* numeric arguments for function */	VALUE *valargs[IN];	/* addresses of actual arguments */	VALUE result;		/* general result of function */	if ((unsigned long)index >= (sizeof(builtins) / sizeof(builtins[0])) - 1)		math_error("Bad built-in function index");	bp = &builtins[index];	if (argcount < bp->b_minargs)		math_error("Too few arguments for builtin function \"%s\"", bp->b_name);	if ((argcount > bp->b_maxargs) || (argcount > IN))		math_error("Too many arguments for builtin function \"%s\"", bp->b_name);	/*	 * If an address was passed, then point at the real variable,	 * otherwise point at the stack value itself (unless the function	 * is very special).	 */	sp = stck - argcount + 1;	vpp = valargs;	for (i = argcount; i > 0; i--) {		if ((sp->v_type != V_ADDR) || (bp->b_flags & FA))			*vpp = sp;		else			*vpp = sp->v_addr;		sp++;		vpp++;	}	/*	 * Handle general values if the function accepts them.	 */	if (bp->b_valfunc) {		vpp = valargs;		if ((bp->b_minargs == 1) && (bp->b_maxargs == 1))			result = (*bp->b_valfunc)(vpp[0]);		else if ((bp->b_minargs == 2) && (bp->b_maxargs == 2))			result = (*bp->b_valfunc)(vpp[0], vpp[1]);		else if ((bp->b_minargs == 3) && (bp->b_maxargs == 3))			result = (*bp->b_valfunc)(vpp[0], vpp[1], vpp[2]);		else			result = (*bp->b_valfunc)(argcount, vpp);		return result;	}	/*	 * Function must be purely numeric, so handle that.	 */	vpp = valargs;	for (i = 0; i < argcount; i++) {		if ((*vpp)->v_type != V_NUM)			math_error("Non-real argument for builtin function %s", bp->b_name);		numargs[i] = (*vpp)->v_num;		vpp++;	}	result.v_type = V_NUM;	if (!(bp->b_flags & FE) && (bp->b_minargs != bp->b_maxargs)) {		result.v_num = (*bp->b_numfunc)(argcount, numargs);		return result;	}	if ((bp->b_flags & FE) && (argcount < bp->b_maxargs))		numargs[argcount++] = _epsilon_;	switch (argcount) {		case 0:			result.v_num = (*bp->b_numfunc)();			break;		case 1:			result.v_num = (*bp->b_numfunc)(numargs[0]);			break;		case 2:			result.v_num = (*bp->b_numfunc)(numargs[0], numargs[1]);			break;		case 3:			result.v_num = (*bp->b_numfunc)(numargs[0], numargs[1], numargs[2]);			break;		default:			math_error("Bad builtin function call");	}	return result;}static VALUEf_eval(vp)	VALUE *vp;{	FUNC	*oldfunc;	FUNC	*newfunc;	VALUE	result;	if (vp->v_type != V_STR)		math_error("Evaluating non-string argument");	(void) openstring(vp->v_str);	oldfunc = curfunc;	enterfilescope();	if (evaluate(TRUE)) {		exitfilescope();		freevalue(stack--);		newfunc = curfunc;		curfunc = oldfunc;		result = newfunc->f_savedvalue;		newfunc->f_savedvalue.v_type = V_NULL;		if (newfunc != oldfunc)			free(newfunc);		return result;	}	exitfilescope();	newfunc = curfunc;	curfunc = oldfunc;	freevalue(&newfunc->f_savedvalue);	newfunc->f_savedvalue.v_type = V_NULL;	if (newfunc != oldfunc)		free(newfunc);	math_error("Evaluation error");	/*NOTREACHED*/	abort ();}static VALUEf_prompt(vp)	VALUE *vp;{	VALUE result;	char *cp;	char *newcp;	if (inputisterminal()) {		printvalue(vp, PRINT_SHORT);		math_flush();	}	cp = nextline();	if (cp == NULL)		math_error("End of file while prompting");	if (*cp == '\0') {		result.v_type = V_STR;		result.v_subtype = V_STRLITERAL;		result.v_str = "";		return result;	}	newcp = (char *)malloc(strlen(cp) + 1);	if (newcp == NULL)		math_error("Cannot allocate string");	strcpy(newcp, cp);	result.v_str = newcp;	result.v_type = V_STR;	result.v_subtype = V_STRALLOC;	return result;}static VALUEf_str(vp)	VALUE *vp;{	VALUE result;	static char *cp;	switch (vp->v_type) {		case V_STR:			copyvalue(vp, &result);			return result;		case V_NULL:			result.v_str = "";			result.v_type = V_STR;			result.v_subtype = V_STRLITERAL;			return result;		case V_NUM:			math_divertio();			qprintnum(vp->v_num, MODE_DEFAULT);			cp = math_getdivertedio();			break;		case V_COM:			math_divertio();			comprint(vp->v_com);			cp = math_getdivertedio();			break;		default:			math_error("Non-simple type for string conversion");	}	result.v_str = cp;	result.v_type = V_STR;	result.v_subtype = V_STRALLOC;	return result;}static VALUEf_poly(count, vals)	int count;	VALUE **vals;{	VALUE *x;	VALUE result, tmp;	x = vals[--count];	copyvalue(*vals++, &result);	while (--count > 0) {		mulvalue(&result, x, &tmp);		freevalue(&result);		addvalue(*vals++, &tmp, &result);		freevalue(&tmp);	}	return result;}static NUMBER *f_mne(val1, val2, val3)	NUMBER *val1, *val2, *val3;{	return itoq((long) qcmpmod(val1, val2, val3));}static NUMBER *f_isrel(val1, val2)	NUMBER *val1, *val2;{	if (qisfrac(val1) || qisfrac(val2))		math_error("Non-integer for isrel");	return itoq((long) zrelprime(val1->num, val2->num));}static NUMBER *f_issquare(vp)	NUMBER *vp;{

⌨️ 快捷键说明

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