/* equation.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from equation.vala, do not modify */

/*
 * Copyright (C) 2004-2008 Sami Pietila
 * Copyright (C) 2008-2012 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 3 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 "calculator.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
enum  {
	EQUATION_0_PROPERTY,
	EQUATION_NUM_PROPERTIES
};
static GParamSpec* equation_properties[EQUATION_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define TYPE_EQUATION_PARSER (equation_parser_get_type ())
#define EQUATION_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_EQUATION_PARSER, EquationParser))
#define EQUATION_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_EQUATION_PARSER, EquationParserClass))
#define IS_EQUATION_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_EQUATION_PARSER))
#define IS_EQUATION_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_EQUATION_PARSER))
#define EQUATION_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_EQUATION_PARSER, EquationParserClass))

typedef struct _EquationParser EquationParser;
typedef struct _EquationParserClass EquationParserClass;
#define _parser_unref0(var) ((var == NULL) ? NULL : (var = (parser_unref (var), NULL)))
typedef struct _EquationParserPrivate EquationParserPrivate;

struct _EquationPrivate {
	gchar* expression;
	Number* last_operand;
	gchar* last_token;
};

struct _EquationParser {
	Parser parent_instance;
	EquationParserPrivate * priv;
};

struct _EquationParserClass {
	ParserClass parent_class;
};

struct _EquationParserPrivate {
	Equation* equation;
};

static gint Equation_private_offset;
static gpointer equation_parent_class = NULL;
static gint EquationParser_private_offset;
static gpointer equation_parser_parent_class = NULL;

VALA_EXTERN GType equation_parser_get_type (void) G_GNUC_CONST ;
VALA_EXTERN EquationParser* equation_parser_new (Equation* equation,
                                     const gchar* expression);
VALA_EXTERN EquationParser* equation_parser_construct (GType object_type,
                                           Equation* equation,
                                           const gchar* expression);
static guint* _uint_dup (guint* self);
static gboolean equation_real_variable_is_defined (Equation* self,
                                            const gchar* name);
static Number* equation_real_get_variable (Equation* self,
                                    const gchar* name);
static gboolean equation_real_unit_is_defined (Equation* self,
                                        const gchar* name);
static gboolean equation_real_literal_base_is_defined (Equation* self,
                                                const gchar* name);
static void equation_real_set_variable (Equation* self,
                                 const gchar* name,
                                 Number* x);
static gboolean equation_real_function_is_defined (Equation* self,
                                            const gchar* name);
static Number* equation_real_convert (Equation* self,
                               Number* x,
                               const gchar* x_units,
                               const gchar* z_units,
                               Unit** x_unit,
                               Unit** z_unit);
static gchar* equation_real_get_last_operation (Equation* self,
                                         Number** operand);
static void equation_finalize (GObject * obj);
static GType equation_get_type_once (void);
static gboolean equation_parser_real_variable_is_defined (Parser* base,
                                                   const gchar* name);
static Number* equation_parser_real_get_variable (Parser* base,
                                           const gchar* name);
static void equation_parser_real_set_variable (Parser* base,
                                        const gchar* name,
                                        Number* x);
static gboolean equation_parser_real_function_is_defined (Parser* base,
                                                   const gchar* name);
static gboolean equation_parser_real_unit_is_defined (Parser* base,
                                               const gchar* name);
static gboolean equation_parser_real_currency_is_defined (Parser* base,
                                                   const gchar* name);
static gboolean equation_parser_real_currency_has_rate (Parser* base,
                                                 const gchar* name);
static Number* equation_parser_real_convert (Parser* base,
                                      Number* x,
                                      const gchar* x_units,
                                      const gchar* z_units,
                                      Unit** x_unit,
                                      Unit** z_unit);
static gboolean equation_parser_real_literal_base_is_defined (Parser* base,
                                                       const gchar* name);
static void equation_parser_finalize (Parser * obj);
static GType equation_parser_get_type_once (void);

static gboolean
string_get_next_char (const gchar* self,
                      gint* index,
                      gunichar* c)
{
	gunichar _vala_c = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	if (_vala_c != ((gunichar) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp0_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
}

gint
sub_atoi (const gchar* data)
{
	static const gunichar digits[10] = {8320U, 8321U, 8322U, 8323U, 8324U, 8325U, 8326U, 8327U, 8328U, 8329U};
	gint index = 0;
	gunichar c = 0U;
	gint value = 0;
	gint result;
	g_return_val_if_fail (data != NULL, 0);
	index = 0;
	value = 0;
	while (TRUE) {
		gunichar _tmp0_ = 0U;
		gboolean _tmp1_;
		gboolean is_subdigit = FALSE;
		_tmp1_ = string_get_next_char (data, &index, &_tmp0_);
		c = _tmp0_;
		if (!_tmp1_) {
			break;
		}
		is_subdigit = FALSE;
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp2_ = FALSE;
				_tmp2_ = TRUE;
				while (TRUE) {
					gunichar _tmp4_;
					if (!_tmp2_) {
						gint _tmp3_;
						_tmp3_ = i;
						i = _tmp3_ + 1;
					}
					_tmp2_ = FALSE;
					if (!(i < G_N_ELEMENTS (digits))) {
						break;
					}
					_tmp4_ = digits[i];
					if (c == _tmp4_) {
						value = (value * 10) + i;
						is_subdigit = TRUE;
						break;
					}
				}
			}
		}
		if (!is_subdigit) {
			result = -1;
			return result;
		}
	}
	result = value;
	return result;
}

gint
super_atoi (const gchar* data)
{
	static const gunichar digits[10] = {8304U, 185U, 178U, 179U, 8308U, 8309U, 8310U, 8311U, 8312U, 8313U};
	gint index = 0;
	gunichar c = 0U;
	gunichar _tmp0_ = 0U;
	gint sign = 0;
	gint value = 0;
	gint result;
	g_return_val_if_fail (data != NULL, 0);
	index = 0;
	string_get_next_char (data, &index, &_tmp0_);
	c = _tmp0_;
	sign = 1;
	if (c == 8315U) {
		sign = -1;
	} else {
		index = 0;
	}
	value = 0;
	while (TRUE) {
		gunichar _tmp1_ = 0U;
		gboolean _tmp2_;
		gboolean is_superdigit = FALSE;
		_tmp2_ = string_get_next_char (data, &index, &_tmp1_);
		c = _tmp1_;
		if (!_tmp2_) {
			break;
		}
		is_superdigit = FALSE;
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp3_ = FALSE;
				_tmp3_ = TRUE;
				while (TRUE) {
					gunichar _tmp5_;
					if (!_tmp3_) {
						gint _tmp4_;
						_tmp4_ = i;
						i = _tmp4_ + 1;
					}
					_tmp3_ = FALSE;
					if (!(i < G_N_ELEMENTS (digits))) {
						break;
					}
					_tmp5_ = digits[i];
					if (c == _tmp5_) {
						value = (value * 10) + i;
						is_superdigit = TRUE;
						break;
					}
				}
			}
		}
		if (!is_superdigit) {
			result = 0;
			return result;
		}
	}
	result = sign * value;
	return result;
}

static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

gchar*
mp_error_code_to_string (ErrorCode error_code)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* result;
	_tmp0_ = g_enum_to_string (TYPE_ERROR_CODE, error_code);
	_tmp1_ = string_replace (_tmp0_, "ERROR_CODE_", "ErrorCode.");
	_tmp2_ = _tmp1_;
	_g_free0 (_tmp0_);
	result = _tmp2_;
	return result;
}

 G_GNUC_NO_INLINE static GType
error_code_get_type_once (void)
{
	static const GEnumValue values[] = {{ERROR_CODE_NONE, "ERROR_CODE_NONE", "none"}, {ERROR_CODE_INVALID, "ERROR_CODE_INVALID", "invalid"}, {ERROR_CODE_UNKNOWN_VARIABLE, "ERROR_CODE_UNKNOWN_VARIABLE", "unknown-variable"}, {ERROR_CODE_UNKNOWN_FUNCTION, "ERROR_CODE_UNKNOWN_FUNCTION", "unknown-function"}, {ERROR_CODE_UNKNOWN_CONVERSION, "ERROR_CODE_UNKNOWN_CONVERSION", "unknown-conversion"}, {ERROR_CODE_UNKNOWN_UNIT, "ERROR_CODE_UNKNOWN_UNIT", "unknown-unit"}, {ERROR_CODE_UNKNOWN_RATE, "ERROR_CODE_UNKNOWN_RATE", "unknown-rate"}, {ERROR_CODE_MP, "ERROR_CODE_MP", "mp"}, {0, NULL, NULL}};
	GType error_code_type_id;
	error_code_type_id = g_enum_register_static ("ErrorCode", values);
	return error_code_type_id;
}

GType
error_code_get_type (void)
{
	static gsize error_code_type_id__once = 0;
	if (g_once_init_enter (&error_code_type_id__once)) {
		GType error_code_type_id;
		error_code_type_id = error_code_get_type_once ();
		g_once_init_leave (&error_code_type_id__once, error_code_type_id);
	}
	return error_code_type_id__once;
}

static inline gpointer
equation_get_instance_private (Equation* self)
{
	return G_STRUCT_MEMBER_P (self, Equation_private_offset);
}

Equation*
equation_construct (GType object_type,
                    const gchar* expression)
{
	Equation * self = NULL;
	gchar* _tmp0_;
	g_return_val_if_fail (expression != NULL, NULL);
	self = (Equation*) g_object_new (object_type, NULL);
	_tmp0_ = g_strdup (expression);
	_g_free0 (self->priv->expression);
	self->priv->expression = _tmp0_;
	return self;
}

Equation*
equation_new (const gchar* expression)
{
	return equation_construct (TYPE_EQUATION, expression);
}

static guint*
_uint_dup (guint* self)
{
	guint* dup;
	dup = g_new0 (guint, 1);
	memcpy (dup, self, sizeof (guint));
	return dup;
}

static gpointer
__uint_dup0 (gpointer self)
{
	return self ? _uint_dup (self) : NULL;
}

Number*
equation_parse (Equation* self,
                guint* representation_base,
                ErrorCode* error_code,
                gchar** error_token,
                guint** error_start,
                guint** error_end)
{
	guint _vala_representation_base = 0U;
	ErrorCode _vala_error_code = 0;
	gchar* _vala_error_token = NULL;
	guint* _vala_error_start = NULL;
	guint* _vala_error_end = NULL;
	EquationParser* parser = NULL;
	const gchar* _tmp0_;
	EquationParser* _tmp1_;
	Number* z = NULL;
	EquationParser* _tmp2_;
	guint _tmp3_ = 0U;
	ErrorCode _tmp4_ = 0;
	gchar* _tmp5_ = NULL;
	guint _tmp6_ = 0U;
	guint _tmp7_ = 0U;
	Number* _tmp8_;
	guint _tmp9_;
	guint* _tmp10_;
	guint _tmp11_;
	guint* _tmp12_;
	EquationParser* _tmp13_;
	Number* _tmp14_ = NULL;
	gchar* _tmp15_;
	const gchar* _tmp16_;
	const gchar* _tmp17_;
	Number* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->expression;
	_tmp1_ = equation_parser_new (self, _tmp0_);
	parser = _tmp1_;
	number_set_error (NULL);
	_tmp2_ = parser;
	_tmp8_ = parser_parse ((Parser*) _tmp2_, &_tmp3_, &_tmp4_, &_tmp5_, &_tmp6_, &_tmp7_);
	_vala_representation_base = _tmp3_;
	_vala_error_code = _tmp4_;
	_g_free0 (_vala_error_token);
	_vala_error_token = _tmp5_;
	_g_free0 (_vala_error_start);
	_tmp9_ = _tmp6_;
	_tmp10_ = __uint_dup0 (&_tmp9_);
	_vala_error_start = _tmp10_;
	_g_free0 (_vala_error_end);
	_tmp11_ = _tmp7_;
	_tmp12_ = __uint_dup0 (&_tmp11_);
	_vala_error_end = _tmp12_;
	z = _tmp8_;
	_tmp13_ = parser;
	_tmp15_ = parser_get_last_operation ((Parser*) _tmp13_, &_tmp14_);
	_g_object_unref0 (self->priv->last_operand);
	self->priv->last_operand = _tmp14_;
	_g_free0 (self->priv->last_token);
	self->priv->last_token = _tmp15_;
	if (_vala_error_code != ERROR_CODE_NONE) {
		result = NULL;
		_g_object_unref0 (z);
		_parser_unref0 (parser);
		if (representation_base) {
			*representation_base = _vala_representation_base;
		}
		if (error_code) {
			*error_code = _vala_error_code;
		}
		if (error_token) {
			*error_token = _vala_error_token;
		} else {
			_g_free0 (_vala_error_token);
		}
		if (error_start) {
			*error_start = _vala_error_start;
		} else {
			_g_free0 (_vala_error_start);
		}
		if (error_end) {
			*error_end = _vala_error_end;
		} else {
			_g_free0 (_vala_error_end);
		}
		return result;
	}
	_tmp16_ = number_get_error ();
	_tmp17_ = _tmp16_;
	if (_tmp17_ != NULL) {
		_vala_error_code = ERROR_CODE_MP;
		result = NULL;
		_g_object_unref0 (z);
		_parser_unref0 (parser);
		if (representation_base) {
			*representation_base = _vala_representation_base;
		}
		if (error_code) {
			*error_code = _vala_error_code;
		}
		if (error_token) {
			*error_token = _vala_error_token;
		} else {
			_g_free0 (_vala_error_token);
		}
		if (error_start) {
			*error_start = _vala_error_start;
		} else {
			_g_free0 (_vala_error_start);
		}
		if (error_end) {
			*error_end = _vala_error_end;
		} else {
			_g_free0 (_vala_error_end);
		}
		return result;
	}
	result = z;
	_parser_unref0 (parser);
	if (representation_base) {
		*representation_base = _vala_representation_base;
	}
	if (error_code) {
		*error_code = _vala_error_code;
	}
	if (error_token) {
		*error_token = _vala_error_token;
	} else {
		_g_free0 (_vala_error_token);
	}
	if (error_start) {
		*error_start = _vala_error_start;
	} else {
		_g_free0 (_vala_error_start);
	}
	if (error_end) {
		*error_end = _vala_error_end;
	} else {
		_g_free0 (_vala_error_end);
	}
	return result;
}

static gboolean
equation_real_variable_is_defined (Equation* self,
                                   const gchar* name)
{
	gboolean result;
	g_return_val_if_fail (name != NULL, FALSE);
	result = FALSE;
	return result;
}

gboolean
equation_variable_is_defined (Equation* self,
                              const gchar* name)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->variable_is_defined) {
		return _klass_->variable_is_defined (self, name);
	}
	return FALSE;
}

static Number*
equation_real_get_variable (Equation* self,
                            const gchar* name)
{
	Number* result;
	g_return_val_if_fail (name != NULL, NULL);
	result = NULL;
	return result;
}

Number*
equation_get_variable (Equation* self,
                       const gchar* name)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->get_variable) {
		return _klass_->get_variable (self, name);
	}
	return NULL;
}

static gboolean
equation_real_unit_is_defined (Equation* self,
                               const gchar* name)
{
	gboolean result;
	g_return_val_if_fail (name != NULL, FALSE);
	result = FALSE;
	return result;
}

gboolean
equation_unit_is_defined (Equation* self,
                          const gchar* name)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->unit_is_defined) {
		return _klass_->unit_is_defined (self, name);
	}
	return FALSE;
}

static gboolean
equation_real_literal_base_is_defined (Equation* self,
                                       const gchar* name)
{
	gboolean result;
	g_return_val_if_fail (name != NULL, FALSE);
	result = FALSE;
	return result;
}

gboolean
equation_literal_base_is_defined (Equation* self,
                                  const gchar* name)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->literal_base_is_defined) {
		return _klass_->literal_base_is_defined (self, name);
	}
	return FALSE;
}

static void
equation_real_set_variable (Equation* self,
                            const gchar* name,
                            Number* x)
{
	g_return_if_fail (name != NULL);
	g_return_if_fail (x != NULL);
}

void
equation_set_variable (Equation* self,
                       const gchar* name,
                       Number* x)
{
	EquationClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->set_variable) {
		_klass_->set_variable (self, name, x);
	}
}

static gboolean
equation_real_function_is_defined (Equation* self,
                                   const gchar* name)
{
	gboolean result;
	g_return_val_if_fail (name != NULL, FALSE);
	result = FALSE;
	return result;
}

gboolean
equation_function_is_defined (Equation* self,
                              const gchar* name)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->function_is_defined) {
		return _klass_->function_is_defined (self, name);
	}
	return FALSE;
}

static Number*
equation_real_convert (Equation* self,
                       Number* x,
                       const gchar* x_units,
                       const gchar* z_units,
                       Unit** x_unit,
                       Unit** z_unit)
{
	Unit* _vala_x_unit = NULL;
	Unit* _vala_z_unit = NULL;
	UnitManager* _tmp0_;
	UnitManager* _tmp1_;
	Unit* _tmp2_ = NULL;
	Unit* _tmp3_ = NULL;
	Number* _tmp4_;
	Number* _tmp5_;
	Number* result;
	g_return_val_if_fail (x != NULL, NULL);
	g_return_val_if_fail (x_units != NULL, NULL);
	g_return_val_if_fail (z_units != NULL, NULL);
	_tmp0_ = unit_manager_get_default ();
	_tmp1_ = _tmp0_;
	_tmp4_ = unit_manager_convert_by_symbol (_tmp1_, x, x_units, z_units, &_tmp2_, &_tmp3_);
	_g_object_unref0 (_vala_x_unit);
	_vala_x_unit = _tmp2_;
	_g_object_unref0 (_vala_z_unit);
	_vala_z_unit = _tmp3_;
	_tmp5_ = _tmp4_;
	_g_object_unref0 (_tmp1_);
	result = _tmp5_;
	if (x_unit) {
		*x_unit = _vala_x_unit;
	} else {
		_g_object_unref0 (_vala_x_unit);
	}
	if (z_unit) {
		*z_unit = _vala_z_unit;
	} else {
		_g_object_unref0 (_vala_z_unit);
	}
	return result;
}

Number*
equation_convert (Equation* self,
                  Number* x,
                  const gchar* x_units,
                  const gchar* z_units,
                  Unit** x_unit,
                  Unit** z_unit)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->convert) {
		return _klass_->convert (self, x, x_units, z_units, x_unit, z_unit);
	}
	return NULL;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static gchar*
equation_real_get_last_operation (Equation* self,
                                  Number** operand)
{
	Number* _vala_operand = NULL;
	Number* _tmp0_;
	Number* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	_tmp0_ = self->priv->last_operand;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (_vala_operand);
	_vala_operand = _tmp1_;
	_tmp2_ = self->priv->last_token;
	_tmp3_ = g_strdup (_tmp2_);
	result = _tmp3_;
	if (operand) {
		*operand = _vala_operand;
	} else {
		_g_object_unref0 (_vala_operand);
	}
	return result;
}

gchar*
equation_get_last_operation (Equation* self,
                             Number** operand)
{
	EquationClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = EQUATION_GET_CLASS (self);
	if (_klass_->get_last_operation) {
		return _klass_->get_last_operation (self, operand);
	}
	return NULL;
}

static void
equation_class_init (EquationClass * klass,
                     gpointer klass_data)
{
	equation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Equation_private_offset);
	((EquationClass *) klass)->variable_is_defined = (gboolean (*) (Equation*, const gchar*)) equation_real_variable_is_defined;
	((EquationClass *) klass)->get_variable = (Number* (*) (Equation*, const gchar*)) equation_real_get_variable;
	((EquationClass *) klass)->unit_is_defined = (gboolean (*) (Equation*, const gchar*)) equation_real_unit_is_defined;
	((EquationClass *) klass)->literal_base_is_defined = (gboolean (*) (Equation*, const gchar*)) equation_real_literal_base_is_defined;
	((EquationClass *) klass)->set_variable = (void (*) (Equation*, const gchar*, Number*)) equation_real_set_variable;
	((EquationClass *) klass)->function_is_defined = (gboolean (*) (Equation*, const gchar*)) equation_real_function_is_defined;
	((EquationClass *) klass)->convert = (Number* (*) (Equation*, Number*, const gchar*, const gchar*, Unit**, Unit**)) equation_real_convert;
	((EquationClass *) klass)->get_last_operation = (gchar* (*) (Equation*, Number**)) equation_real_get_last_operation;
	G_OBJECT_CLASS (klass)->finalize = equation_finalize;
}

static void
equation_instance_init (Equation * self,
                        gpointer klass)
{
	self->priv = equation_get_instance_private (self);
}

static void
equation_finalize (GObject * obj)
{
	Equation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_EQUATION, Equation);
	_g_free0 (self->priv->expression);
	_g_object_unref0 (self->priv->last_operand);
	_g_free0 (self->priv->last_token);
	G_OBJECT_CLASS (equation_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
equation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (EquationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) equation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Equation), 0, (GInstanceInitFunc) equation_instance_init, NULL };
	GType equation_type_id;
	equation_type_id = g_type_register_static (G_TYPE_OBJECT, "Equation", &g_define_type_info, 0);
	Equation_private_offset = g_type_add_instance_private (equation_type_id, sizeof (EquationPrivate));
	return equation_type_id;
}

GType
equation_get_type (void)
{
	static gsize equation_type_id__once = 0;
	if (g_once_init_enter (&equation_type_id__once)) {
		GType equation_type_id;
		equation_type_id = equation_get_type_once ();
		g_once_init_leave (&equation_type_id__once, equation_type_id);
	}
	return equation_type_id__once;
}

static inline gpointer
equation_parser_get_instance_private (EquationParser* self)
{
	return G_STRUCT_MEMBER_P (self, EquationParser_private_offset);
}

EquationParser*
equation_parser_construct (GType object_type,
                           Equation* equation,
                           const gchar* expression)
{
	EquationParser* self = NULL;
	Equation* _tmp0_;
	g_return_val_if_fail (equation != NULL, NULL);
	g_return_val_if_fail (expression != NULL, NULL);
	self = (EquationParser*) parser_construct (object_type, expression, equation->base, equation->wordlen, equation->angle_units);
	_tmp0_ = _g_object_ref0 (equation);
	_g_object_unref0 (self->priv->equation);
	self->priv->equation = _tmp0_;
	return self;
}

EquationParser*
equation_parser_new (Equation* equation,
                     const gchar* expression)
{
	return equation_parser_construct (TYPE_EQUATION_PARSER, equation, expression);
}

static gboolean
equation_parser_real_variable_is_defined (Parser* base,
                                          const gchar* name)
{
	EquationParser * self;
	GHashTable* _tmp0_;
	Equation* _tmp1_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = parser_CONSTANTS;
	if (g_hash_table_contains (_tmp0_, name)) {
		result = TRUE;
		return result;
	}
	_tmp1_ = self->priv->equation;
	result = equation_variable_is_defined (_tmp1_, name);
	return result;
}

static Number*
equation_parser_real_get_variable (Parser* base,
                                   const gchar* name)
{
	EquationParser * self;
	GHashTable* _tmp0_;
	Number* result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = parser_CONSTANTS;
	if (g_hash_table_contains (_tmp0_, name)) {
		GHashTable* _tmp1_;
		gconstpointer _tmp2_;
		Number* _tmp3_;
		_tmp1_ = parser_CONSTANTS;
		_tmp2_ = g_hash_table_lookup (_tmp1_, name);
		_tmp3_ = _g_object_ref0 ((Number*) _tmp2_);
		result = _tmp3_;
		return result;
	} else {
		Equation* _tmp4_;
		Number* _tmp5_;
		_tmp4_ = self->priv->equation;
		_tmp5_ = equation_get_variable (_tmp4_, name);
		result = _tmp5_;
		return result;
	}
}

static void
equation_parser_real_set_variable (Parser* base,
                                   const gchar* name,
                                   Number* x)
{
	EquationParser * self;
	GHashTable* _tmp0_;
	Equation* _tmp1_;
	self = (EquationParser*) base;
	g_return_if_fail (name != NULL);
	g_return_if_fail (x != NULL);
	_tmp0_ = parser_CONSTANTS;
	if (g_hash_table_contains (_tmp0_, name)) {
		return;
	}
	_tmp1_ = self->priv->equation;
	equation_set_variable (_tmp1_, name, x);
}

static gboolean
equation_parser_real_function_is_defined (Parser* base,
                                          const gchar* name)
{
	EquationParser * self;
	FunctionManager* function_manager = NULL;
	FunctionManager* _tmp0_;
	FunctionManager* _tmp1_;
	Equation* _tmp2_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = function_manager_get_default_function_manager ();
	function_manager = _tmp0_;
	_tmp1_ = function_manager;
	if (function_manager_is_function_defined (_tmp1_, name)) {
		result = TRUE;
		_g_object_unref0 (function_manager);
		return result;
	}
	_tmp2_ = self->priv->equation;
	result = equation_function_is_defined (_tmp2_, name);
	_g_object_unref0 (function_manager);
	return result;
}

static gboolean
equation_parser_real_unit_is_defined (Parser* base,
                                      const gchar* name)
{
	EquationParser * self;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	UnitManager* unit_manager = NULL;
	UnitManager* _tmp7_;
	UnitManager* _tmp8_;
	Unit* _tmp9_;
	Unit* _tmp10_;
	gboolean _tmp11_;
	Equation* _tmp12_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	if (g_strcmp0 (name, "hex") == 0) {
		_tmp6_ = TRUE;
	} else {
		_tmp6_ = g_strcmp0 (name, "hexadecimal") == 0;
	}
	if (_tmp6_) {
		_tmp5_ = TRUE;
	} else {
		_tmp5_ = g_strcmp0 (name, "dec") == 0;
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = g_strcmp0 (name, "decimal") == 0;
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = g_strcmp0 (name, "oct") == 0;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = g_strcmp0 (name, "octal") == 0;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = g_strcmp0 (name, "bin") == 0;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (name, "binary") == 0;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp7_ = unit_manager_get_default ();
	unit_manager = _tmp7_;
	_tmp8_ = unit_manager;
	_tmp9_ = unit_manager_get_defined_unit (_tmp8_, name);
	_tmp10_ = _tmp9_;
	_tmp11_ = _tmp10_ != NULL;
	_g_object_unref0 (_tmp10_);
	if (_tmp11_) {
		result = TRUE;
		_g_object_unref0 (unit_manager);
		return result;
	}
	_tmp12_ = self->priv->equation;
	result = equation_unit_is_defined (_tmp12_, name);
	_g_object_unref0 (unit_manager);
	return result;
}

static gboolean
equation_parser_real_currency_is_defined (Parser* base,
                                          const gchar* name)
{
	EquationParser * self;
	UnitManager* unit_manager = NULL;
	UnitManager* _tmp0_;
	Unit* found_unit = NULL;
	UnitManager* _tmp1_;
	Unit* _tmp2_;
	gboolean _tmp3_ = FALSE;
	Unit* _tmp4_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = unit_manager_get_default ();
	unit_manager = _tmp0_;
	_tmp1_ = unit_manager;
	_tmp2_ = unit_manager_get_defined_unit (_tmp1_, name);
	found_unit = _tmp2_;
	_tmp4_ = found_unit;
	if (_tmp4_ != NULL) {
		UnitCategory* _tmp5_ = NULL;
		UnitManager* _tmp6_;
		Unit* _tmp7_;
		gchar* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		UnitCategory* _tmp11_;
		UnitCategory* _tmp12_;
		gchar* _tmp13_ = NULL;
		_tmp6_ = unit_manager;
		_tmp7_ = found_unit;
		_tmp8_ = unit_get_name (_tmp7_);
		_tmp9_ = _tmp8_;
		_tmp10_ = _tmp9_;
		_tmp11_ = unit_manager_get_category_of_unit (_tmp6_, _tmp10_);
		_tmp12_ = _tmp11_;
		_g_free0 (_tmp10_);
		_tmp5_ = _tmp12_;
		_tmp13_ = NULL;
		if (_tmp5_ != NULL) {
			gchar* _tmp14_;
			gchar* _tmp15_;
			_tmp14_ = unit_category_get_name (_tmp5_);
			_tmp15_ = _tmp14_;
			_g_free0 (_tmp13_);
			_tmp13_ = _tmp15_;
		}
		_tmp3_ = g_strcmp0 (_tmp13_, "currency") == 0;
		_g_free0 (_tmp13_);
		_g_object_unref0 (_tmp5_);
	} else {
		_tmp3_ = FALSE;
	}
	result = _tmp3_;
	_g_object_unref0 (found_unit);
	_g_object_unref0 (unit_manager);
	return result;
}

static gboolean
equation_parser_real_currency_has_rate (Parser* base,
                                        const gchar* name)
{
	EquationParser * self;
	CurrencyManager* currency_manager = NULL;
	CurrencyManager* _tmp0_;
	CurrencyManager* _tmp1_;
	Currency* _tmp2_;
	Currency* _tmp3_;
	gboolean _tmp4_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = currency_manager_get_default (TRUE, TRUE);
	currency_manager = _tmp0_;
	_tmp1_ = currency_manager;
	_tmp2_ = currency_manager_get_currency (_tmp1_, name);
	_tmp3_ = _tmp2_;
	_tmp4_ = _tmp3_ != NULL;
	_g_object_unref0 (_tmp3_);
	if (_tmp4_) {
		result = TRUE;
		_g_object_unref0 (currency_manager);
		return result;
	}
	result = FALSE;
	_g_object_unref0 (currency_manager);
	return result;
}

static Number*
equation_parser_real_convert (Parser* base,
                              Number* x,
                              const gchar* x_units,
                              const gchar* z_units,
                              Unit** x_unit,
                              Unit** z_unit)
{
	EquationParser * self;
	Unit* _vala_x_unit = NULL;
	Unit* _vala_z_unit = NULL;
	Equation* _tmp0_;
	Unit* _tmp1_ = NULL;
	Unit* _tmp2_ = NULL;
	Number* _tmp3_;
	Number* result;
	self = (EquationParser*) base;
	g_return_val_if_fail (x != NULL, NULL);
	g_return_val_if_fail (x_units != NULL, NULL);
	g_return_val_if_fail (z_units != NULL, NULL);
	_tmp0_ = self->priv->equation;
	_tmp3_ = equation_convert (_tmp0_, x, x_units, z_units, &_tmp1_, &_tmp2_);
	_g_object_unref0 (_vala_x_unit);
	_vala_x_unit = _tmp1_;
	_g_object_unref0 (_vala_z_unit);
	_vala_z_unit = _tmp2_;
	result = _tmp3_;
	if (x_unit) {
		*x_unit = _vala_x_unit;
	} else {
		_g_object_unref0 (_vala_x_unit);
	}
	if (z_unit) {
		*z_unit = _vala_z_unit;
	} else {
		_g_object_unref0 (_vala_z_unit);
	}
	return result;
}

static gboolean
equation_parser_real_literal_base_is_defined (Parser* base,
                                              const gchar* name)
{
	EquationParser * self;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	Equation* _tmp2_;
	gboolean result;
	self = (EquationParser*) base;
	g_return_val_if_fail (name != NULL, FALSE);
	if (g_strcmp0 (name, "0x") == 0) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = g_strcmp0 (name, "0b") == 0;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (name, "0o") == 0;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp2_ = self->priv->equation;
	result = equation_literal_base_is_defined (_tmp2_, name);
	return result;
}

static void
equation_parser_class_init (EquationParserClass * klass,
                            gpointer klass_data)
{
	equation_parser_parent_class = g_type_class_peek_parent (klass);
	((ParserClass *) klass)->finalize = equation_parser_finalize;
	g_type_class_adjust_private_offset (klass, &EquationParser_private_offset);
	((ParserClass *) klass)->variable_is_defined = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_variable_is_defined;
	((ParserClass *) klass)->get_variable = (Number* (*) (Parser*, const gchar*)) equation_parser_real_get_variable;
	((ParserClass *) klass)->set_variable = (void (*) (Parser*, const gchar*, Number*)) equation_parser_real_set_variable;
	((ParserClass *) klass)->function_is_defined = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_function_is_defined;
	((ParserClass *) klass)->unit_is_defined = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_unit_is_defined;
	((ParserClass *) klass)->currency_is_defined = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_currency_is_defined;
	((ParserClass *) klass)->currency_has_rate = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_currency_has_rate;
	((ParserClass *) klass)->convert = (Number* (*) (Parser*, Number*, const gchar*, const gchar*, Unit**, Unit**)) equation_parser_real_convert;
	((ParserClass *) klass)->literal_base_is_defined = (gboolean (*) (Parser*, const gchar*)) equation_parser_real_literal_base_is_defined;
}

static void
equation_parser_instance_init (EquationParser * self,
                               gpointer klass)
{
	self->priv = equation_parser_get_instance_private (self);
}

static void
equation_parser_finalize (Parser * obj)
{
	EquationParser * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_EQUATION_PARSER, EquationParser);
	_g_object_unref0 (self->priv->equation);
	PARSER_CLASS (equation_parser_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
equation_parser_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (EquationParserClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) equation_parser_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EquationParser), 0, (GInstanceInitFunc) equation_parser_instance_init, NULL };
	GType equation_parser_type_id;
	equation_parser_type_id = g_type_register_static (TYPE_PARSER, "EquationParser", &g_define_type_info, 0);
	EquationParser_private_offset = g_type_add_instance_private (equation_parser_type_id, sizeof (EquationParserPrivate));
	return equation_parser_type_id;
}

GType
equation_parser_get_type (void)
{
	static gsize equation_parser_type_id__once = 0;
	if (g_once_init_enter (&equation_parser_type_id__once)) {
		GType equation_parser_type_id;
		equation_parser_type_id = equation_parser_get_type_once ();
		g_once_init_leave (&equation_parser_type_id__once, equation_parser_type_id);
	}
	return equation_parser_type_id__once;
}

