1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*
* Main include file for Mathomatic, an algebraic manipulator written entirely in C.
*
* Copyright (C) 1987-2008 George Gesslein II.
*/
#if LIBRARY
#define SILENT 1
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b)) /* return the maximum of two values */
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b)) /* return the minimum of two values */
#endif
#ifndef INFINITY
#define INFINITY HUGE_VAL /* the floating point, positive infinity constant */
#endif
#ifndef isfinite
#define isfinite(d) finite(d) /* true if d is finite (not infinity or NaN) */
#endif
#define ARR_CNT(a) ((int) (sizeof(a)/sizeof(a[0]))) /* returns the number of elements in an array */
#define CLEAR_ARRAY(a) memset(a, 0, sizeof(a)) /* sets all elements of an array to zero */
#define MAX_K_INTEGER 1.0e14 /* maximum representable integer, 14 digits for doubles */
#define MAX_PRECISION 16 /* maximum useful display precision (number of digits) */
#define blt(dst, src, cnt) memmove((char *) (dst), (char *) (src), (size_t) (cnt)) /* memory copy function */
#define always_positive(power) (fmod((double) (power), 2.0) == 0.0) /* true if all real numbers raised to "power" result in positive, real numbers */
#if I18N /* internationalization */
#define _(str) gettext(str)
#else
#define _(str) str
#endif
#define STANDARD_SCREEN_COLUMNS 80 /* default number of columns of characters on the screen */
#define STANDARD_SCREEN_ROWS 24 /* default number of lines on the screen */
#define TMP_FILE "/tmp/mathomatic.XXXXXX" /* temp file template */
#define PROMPT "-> " /* user interface prompt string */
#define HTML_PROMPT "—> "
#define MAX_CMD_LEN PATH_MAX /* maximum command line length (not equations), also max file name length */
#define MAX_PROMPT_LEN STANDARD_SCREEN_COLUMNS /* maximum length of prompts */
/*
* The following defines the maximum number of equation spaces that can be allocated.
*/
#define N_EQUATIONS 100
/*
* The following defines the default maximum mathematical expression size.
* Expression arrays are allocated with this size by default,
* there are 2 of these for each equation space (1 for LHS and 1 for RHS).
* DEFAULT_N_TOKENS is linearly related to the actual memory usage of Mathomatic.
* This should be made much smaller for handhelds and embedded systems.
* Do not set to less than 100.
*/
#define DEFAULT_N_TOKENS 30000
#define DIVISOR_SIZE (DEFAULT_N_TOKENS / 2) /* a nice maximum divisor size */
/*
* All Mathomatic variables are referenced by the long data type.
* The actual name string is stored separately.
*/
#define MAX_VAR_NAMES 8000 /* maximum number of variable names, keep this under (VAR_MASK - VAR_OFFSET) */
#define MAX_VAR_LEN 100 /* maximum number of characters in variable names */
#define MAX_VARS min(DEFAULT_N_TOKENS / 4, 1000) /* maximum number of unique variables handled in each equation */
#define VAR_OFFSET 'A' /* makes space for predefined variables */
#define VAR_MASK 0x3fffL /* mask for bits containing a reference to the variable name */
#define VAR_SHIFT 14 /* number of bits set in VAR_MASK */
#define SUBSCRIPT_MASK 63 /* mask for variable subscript after shifting VAR_SHIFT */
#define MAX_SUBSCRIPT (SUBSCRIPT_MASK - 1) /* maximum variable subscript, currently only used for "sign" variables */
typedef char sign_array_type[MAX_SUBSCRIPT+2]; /* boolean array for generating unique "sign" variables */
enum kind_list { /* kinds of tokens specified in the union below */
CONSTANT,
VARIABLE,
OPERATOR
};
typedef union {
double constant; /* internal storage for mathematical constants */
long variable; /* internal storage for mathematical variables */
/* predefined special variables follow (order is important) */
#define V_NULL 0L /* null variable, should never be stored in an expression */
#define V_E 1L /* the constant "e" or "e#" */
#define V_PI 2L /* the constant "pi" or "pi#" */
#define IMAGINARY 3L /* the imaginary constant "i" or "i#" */
#define SIGN 4L /* for "sign" variables */
#define MATCH_ANY 5L /* match any variable (wild-card variable) */
int operatr; /* internal storage for mathematical operators */
/* valid operators follow (order doesn't matter) */
#define PLUS 1 /* a + b */
#define MINUS 2 /* a - b */
#define TIMES 3 /* a * b */
#define DIVIDE 4 /* a / b */
#define MODULUS 5 /* a % b */
#define POWER 6 /* a ^ b */
#define FACTORIAL 7 /* a! */
#define NEGATE 8 /* special parser operator */
#define IDIVIDE 9 /* a // b */
} storage_type;
typedef struct { /* storage structure for each token in an expression */
enum kind_list kind; /* kind of token */
int level; /* level of parentheses, origin 1 */
storage_type token; /* the actual token */
} token_type;
typedef struct { /* variable sort data structure */
long v; /* Mathomatic variable */
int count; /* number of times the variable occurs */
} sort_type;
/* Debugging macros: */
#if SILENT
#define list_tdebug(level)
#define side_debug(level, p1, n1)
#define debug_string(level, str)
#else
#define list_tdebug(level) list_debug(level, tlhs, n_tlhs, trhs, n_trhs)
#define side_debug(level, p1, n1) list_debug(level, p1, n1, NULL, 0)
#define debug_string(level, str) { if (debug_level >= (level)) printf("%s\n", str); }
#endif
|