summaryrefslogtreecommitdiff
path: root/src/mp-equation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mp-equation.c')
-rw-r--r--src/mp-equation.c273
1 files changed, 47 insertions, 226 deletions
diff --git a/src/mp-equation.c b/src/mp-equation.c
index cec5536..9b6a195 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -1,33 +1,21 @@
-/* Copyright (c) 2004-2008 Sami Pietila
- * Copyright (c) 2008-2009 Robert Ancell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+/*
+ * Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (C) 2008-2011 Robert Ancell.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
*/
#include <ctype.h>
-
-#include "mp-equation-private.h"
-#include "mp-equation-parser.h"
-#include "mp-equation-lexer.h"
-
-extern int _mp_equation_parse(yyscan_t yyscanner);
-
+#include <string.h>
+#include <stdlib.h>
+#include "parser.h"
static int
-variable_is_defined(MPEquationParserState *state, const char *name)
+variable_is_defined(ParserState *state, const char *name)
{
/* FIXME: Make more generic */
if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "π") == 0)
@@ -39,7 +27,7 @@ variable_is_defined(MPEquationParserState *state, const char *name)
static int
-get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
+get_variable(ParserState *state, const char *name, MPNumber *z)
{
int result = 1;
@@ -58,7 +46,7 @@ get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
}
static void
-set_variable(MPEquationParserState *state, const char *name, const MPNumber *x)
+set_variable(ParserState *state, const char *name, const MPNumber *x)
{
// Reserved words, e, π, mod, and, or, xor, not, abs, log, ln, sqrt, int, frac, sin, cos, ...
if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "π") == 0)
@@ -115,7 +103,7 @@ super_atoi(const char *data)
static int
-function_is_defined(MPEquationParserState *state, const char *name)
+function_is_defined(ParserState *state, const char *name)
{
char *c, *lower_name;
@@ -140,8 +128,8 @@ function_is_defined(MPEquationParserState *state, const char *name)
strcmp(lower_name, "re") == 0 ||
strcmp(lower_name, "im") == 0 ||
strcmp(lower_name, "sin") == 0 || strcmp(lower_name, "cos") == 0 || strcmp(lower_name, "tan") == 0 ||
- strcmp(lower_name, "sin⁻¹") == 0 || strcmp(lower_name, "cos⁻¹") == 0 || strcmp(lower_name, "tan⁻¹") == 0 ||
strcmp(lower_name, "asin") == 0 || strcmp(lower_name, "acos") == 0 || strcmp(lower_name, "atan") == 0 ||
+ strcmp(lower_name, "sin⁻¹") == 0 || strcmp(lower_name, "cos⁻¹") == 0 || strcmp(lower_name, "tan⁻¹") == 0 ||
strcmp(lower_name, "sinh") == 0 || strcmp(lower_name, "cosh") == 0 || strcmp(lower_name, "tanh") == 0 ||
strcmp(lower_name, "sinh⁻¹") == 0 || strcmp(lower_name, "cosh⁻¹") == 0 || strcmp(lower_name, "tanh⁻¹") == 0 ||
strcmp(lower_name, "asinh") == 0 || strcmp(lower_name, "acosh") == 0 || strcmp(lower_name, "atanh") == 0 ||
@@ -159,7 +147,7 @@ function_is_defined(MPEquationParserState *state, const char *name)
static int
-get_function(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z)
+get_function(ParserState *state, const char *name, const MPNumber *x, MPNumber *z)
{
char *c, *lower_name;
int result = 1;
@@ -247,168 +235,12 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
static int
-do_convert(const char *units[][2], const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
-{
- int x_index, z_index;
- MPNumber x_factor, z_factor;
-
- for (x_index = 0; units[x_index][0] != NULL && strcmp(units[x_index][0], x_units) != 0; x_index++);
- if (units[x_index][0] == NULL)
- return 0;
- for (z_index = 0; units[z_index][0] != NULL && strcmp(units[z_index][0], z_units) != 0; z_index++);
- if (units[z_index][0] == NULL)
- return 0;
-
- mp_set_from_string(units[x_index][1], 10, &x_factor);
- mp_set_from_string(units[z_index][1], 10, &z_factor);
- mp_multiply(x, &x_factor, z);
- mp_divide(z, &z_factor, z);
-
- return 1;
-}
-
-
-static int
-convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
+convert(ParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
{
- const char *length_units[][2] = {
- {"parsec", "30857000000000000"},
- {"parsecs", "30857000000000000"},
- {"pc", "30857000000000000"},
- {"lightyear", "9460730472580800"},
- {"lightyears", "9460730472580800"},
- {"ly", "9460730472580800"},
- {"au", "149597870691"},
- {"nm", "1852000"},
- {"mile", "1609.344"},
- {"miles", "1609.344"},
- {"mi", "1609.344"},
- {"kilometer", "1000"},
- {"kilometers", "1000"},
- {"km", "1000"},
- {"kms", "1000"},
- {"cable", "219.456"},
- {"cables", "219.456"},
- {"cb", "219.456"},
- {"fathom", "1.8288"},
- {"fathoms", "1.8288"},
- {"ftm", "1.8288"},
- {"meter", "1"},
- {"meters", "1"},
- {"m", "1"},
- {"yard", "0.9144"},
- {"yd", "0.9144"},
- {"foot", "0.3048"},
- {"feet", "0.3048"},
- {"ft", "0.3048"},
- {"inch", "0.0254"},
- {"inches", "0.0254"},
- {"centimeter", "0.01"},
- {"centimeters", "0.01"},
- {"cm", "0.01"},
- {"cms", "0.01"},
- {"millimeter", "0.001"},
- {"millimeters", "0.001"},
- {"mm", "0.001"},
- {"micrometer", "0.000001"},
- {"micrometers", "0.000001"},
- {"um", "0.000001"},
- {"nanometer", "0.000000001"},
- {"nanometers", "0.000000001"},
- {NULL, NULL}
- };
-
- const char *area_units[][2] = {
- {"hectare", "10000"},
- {"hectares", "10000"},
- {"acre", "4046.8564224"},
- {"acres", "4046.8564224"},
- {"m²", "1"},
- {"cm²", "0.001"},
- {"mm²", "0.000001"},
- {NULL, NULL}
- };
-
- const char *volume_units[][2] = {
- {"m³", "1000"},
- {"gallon", "3.785412"},
- {"gallons", "3.785412"},
- {"gal", "3.785412"},
- {"litre", "1"},
- {"litres", "1"},
- {"liter", "1"},
- {"liters", "1"},
- {"L", "1"},
- {"quart", "0.9463529"},
- {"quarts", "0.9463529"},
- {"qt", "0.9463529"},
- {"pint", "0.4731765"},
- {"pints", "0.4731765"},
- {"pt", "0.4731765"},
- {"millilitre", "0.001"},
- {"millilitres", "0.001"},
- {"milliliter", "0.001"},
- {"milliliters", "0.001"},
- {"mL", "0.001"},
- {"cm³", "0.001"},
- {"mm³", "0.000001"},
- {NULL, NULL}
- };
-
- const char *weight_units[][2] = {
- {"tonne", "1000"},
- {"tonnes", "1000"},
- {"kilograms", "1"},
- {"kilogramme", "1"},
- {"kilogrammes", "1"},
- {"kg", "1"},
- {"kgs", "1"},
- {"pound", "0.45359237"},
- {"pounds", "0.45359237"},
- {"lb", "0.45359237"},
- {"ounce", "0.002834952"},
- {"ounces", "0.002834952"},
- {"oz", "0.002834952"},
- {"gram", "0.001"},
- {"grams", "0.001"},
- {"gramme", "0.001"},
- {"grammes", "0.001"},
- {"g", "0.001"},
- {NULL, NULL}
- };
-
- const char *time_units[][2] = {
- {"year", "31557600"},
- {"years", "31557600"},
- {"day", "86400"},
- {"days", "86400"},
- {"hour", "3600"},
- {"hours", "3600"},
- {"minute", "60"},
- {"minutes", "60"},
- {"second", "1"},
- {"seconds", "1"},
- {"s", "1"},
- {"millisecond", "0.001"},
- {"milliseconds", "0.001"},
- {"ms", "0.001"},
- {"microsecond", "0.000001"},
- {"microseconds", "0.000001"},
- {"us", "0.000001"},
- {NULL, NULL}
- };
-
- if (do_convert(length_units, x, x_units, z_units, z) ||
- do_convert(area_units, x, x_units, z_units, z) ||
- do_convert(volume_units, x, x_units, z_units, z) ||
- do_convert(weight_units, x, x_units, z_units, z) ||
- do_convert(time_units, x, x_units, z_units, z))
- return 1;
-
if (state->options->convert)
return state->options->convert(x, x_units, z_units, z, state->options->callback_data);
-
- return 0;
+ else
+ return 0;
}
@@ -416,49 +248,44 @@ MPErrorCode
mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result, char **error_token)
{
int ret;
- MPEquationParserState state;
- yyscan_t yyscanner;
- YY_BUFFER_STATE buffer;
+ int err;
+ ParserState* state;
+ state = p_create_parser (expression, options);
if (!(expression && result) || strlen(expression) == 0)
return PARSER_ERR_INVALID;
- memset(&state, 0, sizeof(MPEquationParserState));
- state.options = options;
- state.variable_is_defined = variable_is_defined;
- state.get_variable = get_variable;
- state.set_variable = set_variable;
- state.function_is_defined = function_is_defined;
- state.get_function = get_function;
- state.convert = convert;
- state.error = 0;
-
+ state->variable_is_defined = variable_is_defined;
+ state->get_variable = get_variable;
+ state->set_variable = set_variable;
+ state->function_is_defined = function_is_defined;
+ state->get_function = get_function;
+ state->convert = convert;
+ state->error = 0;
mp_clear_error();
-
- _mp_equation_lex_init_extra(&state, &yyscanner);
- buffer = _mp_equation__scan_string(expression, yyscanner);
-
- ret = _mp_equation_parse(yyscanner);
- if (state.error_token != NULL && error_token != NULL) {
- *error_token = state.error_token;
+ ret = p_parse (state);
+ if (state->error_token != NULL && error_token != NULL) {
+ *error_token = state->error_token;
}
-
- _mp_equation__delete_buffer(buffer, yyscanner);
- _mp_equation_lex_destroy(yyscanner);
-
/* Error during parsing */
- if (state.error)
- return state.error;
+ if (state->error) {
+ err = state->error;
+ p_destroy_parser (state);
+ return err;
+ }
- if (mp_get_error())
+ if (mp_get_error()) {
+ p_destroy_parser (state);
return PARSER_ERR_MP;
+ }
/* Failed to parse */
- if (ret)
+ if (ret) {
+ p_destroy_parser (state);
return PARSER_ERR_INVALID;
-
- mp_set_from_mp(&state.ret, result);
-
+ }
+ mp_set_from_mp(&state->ret, result);
+ p_destroy_parser (state);
return PARSER_ERR_NONE;
}
@@ -486,9 +313,3 @@ mp_error_code_to_string(MPErrorCode error_code)
return "Unknown parser error";
}
}
-
-
-int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text)
-{
- return 0;
-}