mirror of
https://github.com/mfillpot/mathomatic.git
synced 2026-01-08 04:29:39 +00:00
202 lines
8.9 KiB
C
202 lines
8.9 KiB
C
/*
|
|
* Main include file for Mathomatic. Can be edited.
|
|
*
|
|
* Copyright (C) 1987-2012 George Gesslein II.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library 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.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
|
|
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
|
|
|
|
*/
|
|
|
|
#ifndef DBL_DIG
|
|
#error "DBL_DIG not defined!"
|
|
#elif DBL_DIG != 15
|
|
#warning "DBL_DIG (the number of digits precision of doubles) is not 15."
|
|
#warning "This might be a problem."
|
|
#endif
|
|
|
|
#if sun
|
|
#define INFINITY_NAME "Infinity" /* set this to the name of the infinity constant as displayed by printf(3) */
|
|
#define NAN_NAME "NaN" /* set this to the name of the NaN constant as displayed by printf(3) */
|
|
#else
|
|
#define INFINITY_NAME "inf" /* set this to the name of the infinity constant as displayed by printf(3) */
|
|
#define NAN_NAME "nan" /* set this to the name of the NaN constant as displayed by printf(3) */
|
|
#endif
|
|
|
|
#ifndef PATH_MAX /* make sure the maximum file pathname length is set */
|
|
#define PATH_MAX 4096
|
|
#endif
|
|
|
|
#define MAX_K_INTEGER 1.0e15 /* maximum safely representable floating point integer, 15 digits for doubles */
|
|
|
|
#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: allow output in languages other than English using gettext(3). */
|
|
#define _(str) gettext(str)
|
|
#else
|
|
#define _(str) str /* Constant strings to be translated should be marked with this macro. */
|
|
/* Don't bother marking debug and fatal bug error strings. */
|
|
#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 TEXT_ROWS STANDARD_SCREEN_ROWS /* number of lines per page in the symbolic math library */
|
|
#define TEXT_COLUMNS STANDARD_SCREEN_COLUMNS /* default number of columns per page in the symbolic math library */
|
|
|
|
#define TMP_FILE "/tmp/mathomatic.XXXXXX" /* temporary file template for mkstemp(3) */
|
|
|
|
#define PROMPT_STR "-> " /* user interface main prompt strings, preceded by the current equation number */
|
|
#define HTML_PROMPT_STR "−> " /* main prompt in HTML output mode, should be same number of columns as above */
|
|
|
|
#define MAX_CMD_LEN min((max(PATH_MAX, 1024)), 16384) /* Maximum Mathomatic main prompt command-line length */
|
|
/* (not expression input, which can be much larger); */
|
|
/* also max filename length. */
|
|
#define MAX_PROMPT_LEN STANDARD_SCREEN_COLUMNS /* maximum length of prompts, limited to fit on normal terminals */
|
|
|
|
/*
|
|
* What follows is the definition of each array element in a mathematical expression,
|
|
* as stored internally by Mathomatic.
|
|
* Each mathematical expression is stored in a fixed-size array of token_type.
|
|
*/
|
|
|
|
enum kind_list { /* kinds of expression tokens specified in the union below */
|
|
CONSTANT,
|
|
VARIABLE,
|
|
OPERATOR
|
|
};
|
|
|
|
typedef union {
|
|
double constant; /* internal storage for Mathomatic numerical constants */
|
|
long variable; /* internal storage for Mathomatic 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 symbolic, universal constant "e" or "e#" */
|
|
#define V_PI 2L /* the symbolic, universal constant "pi" or "pi#" */
|
|
#define IMAGINARY 3L /* the imaginary constant "i" or "i#" */
|
|
#define SIGN 4L /* for two-valued "sign" variables, numeric variables should be before this */
|
|
#define MATCH_ANY 5L /* match any variable (wild-card variable) */
|
|
#define V_INTEGER_PREFIX "integer" /* prefix for the integer variable type */
|
|
int operatr; /* internal storage for Mathomatic operators */
|
|
/* Valid operators follow (in precedence order), 0 is reserved for no operator: */
|
|
#define PLUS 1 /* a + b */
|
|
#define MINUS 2 /* a - b */
|
|
#define NEGATE 3 /* special parser operator not seen outside parser */
|
|
#define TIMES 4 /* a * b */
|
|
#define DIVIDE 5 /* a / b */
|
|
#define MODULUS 6 /* a % b */
|
|
#define IDIVIDE 7 /* a // b */
|
|
#define POWER 8 /* a ^ b */
|
|
#define FACTORIAL 9 /* a! */
|
|
} 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;
|
|
|
|
/*
|
|
* The following defines the maximum number of equation spaces that can be allocated.
|
|
* The equation spaces are not allocated unless they are used or skipped over.
|
|
* This affects maximum memory usage.
|
|
*/
|
|
#ifndef N_EQUATIONS
|
|
#define N_EQUATIONS 200
|
|
#endif
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
#ifndef DEFAULT_N_TOKENS
|
|
#if HANDHELD
|
|
#define DEFAULT_N_TOKENS 10000
|
|
#else
|
|
#define DEFAULT_N_TOKENS 60000
|
|
#endif
|
|
#endif
|
|
#if (DEFAULT_N_TOKENS < 100 || DEFAULT_N_TOKENS >= (INT_MAX / 3))
|
|
#error DEFAULT_N_TOKENS out of range!
|
|
#endif
|
|
|
|
#define DIVISOR_SIZE min((DEFAULT_N_TOKENS / 2), 15000) /* a nice maximum divisor size */
|
|
|
|
/*
|
|
* All Mathomatic variables are referenced by the value in a C long int variable.
|
|
* 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 */
|
|
|
|
typedef struct { /* qsort(3) data structure for sorting Mathomatic variables */
|
|
long v; /* Mathomatic variable */
|
|
int count; /* number of times the variable occurs */
|
|
} sort_type;
|
|
|
|
/* A list of supported output languages for the code command: */
|
|
enum language_list {
|
|
C = 1, /* or C++ */
|
|
JAVA = 2,
|
|
PYTHON = 3
|
|
};
|
|
|
|
/* Debugging macros: */
|
|
#if SILENT
|
|
#define list_esdebug(level, en) { ; } /* Display an equation space. */
|
|
#define list_tdebug(level) { ; } /* Display the temporary equation (e.g.: when solving). */
|
|
#define side_debug(level, p1, n1) { ; } /* Display any expression. */
|
|
#define debug_string(level, str) { ; } /* Display any ASCII string. */
|
|
#else
|
|
#define list_esdebug(level, en) list_debug(level, lhs[en], n_lhs[en], rhs[en], n_rhs[en])
|
|
#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)) fprintf(gfp, "%s\n", str); }
|
|
#endif
|
|
|
|
/* The correct ways to determine if equation number "en" (origin 0) contains an expression or equation. */
|
|
#define empty_equation_space(en) ((en) < 0 || (en) >= n_equations || n_lhs[(en)] <= 0)
|
|
#define equation_space_is_equation(en) ((en) >= 0 && (en) < n_equations && n_lhs[(en)] > 0 && n_rhs[(en)] > 0)
|
|
|
|
/*
|
|
* The following are macros for displaying help text.
|
|
* When used properly, they will allow nicer looking wrap-around on all help text.
|
|
* If NOT80COLUMNS is 1, paragraphs will all be one long line.
|
|
* This is helpful when the output device has less than 80 text character columns.
|
|
*/
|
|
#if NOT80COLUMNS
|
|
#define SP(str) fprintf(gfp, "%s ", str) /* display part of a paragraph, separated with spaces (Space Paragraph) */
|
|
#define EP(str) fprintf(gfp, "%s\n", str) /* display the end of a paragraph (End Paragraph) */
|
|
#else /* Otherwise the following only works nicely with 80 column or wider screens; */
|
|
/* all strings passed to it should be less than 80 columns if possible, so it doesn't wrap around. */
|
|
#define SP(str) fprintf(gfp, "%s\n", str)
|
|
#define EP(str) fprintf(gfp, "%s\n", str)
|
|
#endif
|