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