/* valaintegerliteral.c generated by valac, the Vala compiler
 * generated from valaintegerliteral.vala, do not modify */

/* valaintegerliteral.vala
 *
 * Copyright (C) 2006-2010  Jürg Billeter
 *
 * 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
 *
 * Author:
 * 	Jürg Billeter <j@bitron.ch>
 */

#include <glib.h>
#include <glib-object.h>
#include "vala.h"
#include <stdlib.h>
#include <string.h>

#define _g_free0(var) (var = (g_free (var), NULL))
#define _vala_code_node_unref0(var) ((var == NULL) ? NULL : (var = (vala_code_node_unref (var), NULL)))

struct _ValaIntegerLiteralPrivate {
	gchar* _value;
	gchar* _type_suffix;
};


static gpointer vala_integer_literal_parent_class = NULL;

#define VALA_INTEGER_LITERAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VALA_TYPE_INTEGER_LITERAL, ValaIntegerLiteralPrivate))
static void vala_integer_literal_real_accept (ValaCodeNode* base, ValaCodeVisitor* visitor);
static gchar* vala_integer_literal_real_to_string (ValaCodeNode* base);
static gboolean vala_integer_literal_real_is_pure (ValaExpression* base);
static gboolean vala_integer_literal_real_check (ValaCodeNode* base, ValaCodeContext* context);
static void vala_integer_literal_real_emit (ValaCodeNode* base, ValaCodeGenerator* codegen);
static void vala_integer_literal_finalize (ValaCodeNode * obj);


/**
 * Creates a new integer literal.
 *
 * @param i      literal value
 * @param source reference to source code
 * @return       newly created integer literal
 */
ValaIntegerLiteral* vala_integer_literal_construct (GType object_type, const gchar* i, ValaSourceReference* source) {
	ValaIntegerLiteral* self = NULL;
	const gchar* _tmp0_;
	ValaSourceReference* _tmp1_;
	g_return_val_if_fail (i != NULL, NULL);
	self = (ValaIntegerLiteral*) vala_literal_construct (object_type);
	_tmp0_ = i;
	vala_integer_literal_set_value (self, _tmp0_);
	_tmp1_ = source;
	vala_code_node_set_source_reference ((ValaCodeNode*) self, _tmp1_);
	return self;
}


ValaIntegerLiteral* vala_integer_literal_new (const gchar* i, ValaSourceReference* source) {
	return vala_integer_literal_construct (VALA_TYPE_INTEGER_LITERAL, i, source);
}


static void vala_integer_literal_real_accept (ValaCodeNode* base, ValaCodeVisitor* visitor) {
	ValaIntegerLiteral * self;
	ValaCodeVisitor* _tmp0_;
	ValaCodeVisitor* _tmp1_;
	self = (ValaIntegerLiteral*) base;
	g_return_if_fail (visitor != NULL);
	_tmp0_ = visitor;
	vala_code_visitor_visit_integer_literal (_tmp0_, self);
	_tmp1_ = visitor;
	vala_code_visitor_visit_expression (_tmp1_, (ValaExpression*) self);
}


static gchar* vala_integer_literal_real_to_string (ValaCodeNode* base) {
	ValaIntegerLiteral * self;
	gchar* result = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	self = (ValaIntegerLiteral*) base;
	_tmp0_ = self->priv->_value;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}


static gboolean vala_integer_literal_real_is_pure (ValaExpression* base) {
	ValaIntegerLiteral * self;
	gboolean result = FALSE;
	self = (ValaIntegerLiteral*) base;
	result = TRUE;
	return result;
}


static glong string_strnlen (gchar* str, glong maxlen) {
	glong result = 0L;
	gchar* end = NULL;
	gchar* _tmp0_;
	glong _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	_tmp0_ = str;
	_tmp1_ = maxlen;
	_tmp2_ = memchr (_tmp0_, 0, (gsize) _tmp1_);
	end = _tmp2_;
	_tmp3_ = end;
	if (_tmp3_ == NULL) {
		glong _tmp4_;
		_tmp4_ = maxlen;
		result = _tmp4_;
		return result;
	} else {
		gchar* _tmp5_;
		gchar* _tmp6_;
		_tmp5_ = end;
		_tmp6_ = str;
		result = (glong) (_tmp5_ - _tmp6_);
		return result;
	}
}


static gchar* string_substring (const gchar* self, glong offset, glong len) {
	gchar* result = NULL;
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	glong _tmp1_;
	glong _tmp8_;
	glong _tmp14_;
	glong _tmp17_;
	glong _tmp18_;
	glong _tmp19_;
	glong _tmp20_;
	glong _tmp21_;
	gchar* _tmp22_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = offset;
	if (_tmp1_ >= ((glong) 0)) {
		glong _tmp2_;
		_tmp2_ = len;
		_tmp0_ = _tmp2_ >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		glong _tmp3_;
		glong _tmp4_;
		glong _tmp5_;
		_tmp3_ = offset;
		_tmp4_ = len;
		_tmp5_ = string_strnlen ((gchar*) self, _tmp3_ + _tmp4_);
		string_length = _tmp5_;
	} else {
		gint _tmp6_;
		gint _tmp7_;
		_tmp6_ = strlen (self);
		_tmp7_ = _tmp6_;
		string_length = (glong) _tmp7_;
	}
	_tmp8_ = offset;
	if (_tmp8_ < ((glong) 0)) {
		glong _tmp9_;
		glong _tmp10_;
		glong _tmp11_;
		_tmp9_ = string_length;
		_tmp10_ = offset;
		offset = _tmp9_ + _tmp10_;
		_tmp11_ = offset;
		g_return_val_if_fail (_tmp11_ >= ((glong) 0), NULL);
	} else {
		glong _tmp12_;
		glong _tmp13_;
		_tmp12_ = offset;
		_tmp13_ = string_length;
		g_return_val_if_fail (_tmp12_ <= _tmp13_, NULL);
	}
	_tmp14_ = len;
	if (_tmp14_ < ((glong) 0)) {
		glong _tmp15_;
		glong _tmp16_;
		_tmp15_ = string_length;
		_tmp16_ = offset;
		len = _tmp15_ - _tmp16_;
	}
	_tmp17_ = offset;
	_tmp18_ = len;
	_tmp19_ = string_length;
	g_return_val_if_fail ((_tmp17_ + _tmp18_) <= _tmp19_, NULL);
	_tmp20_ = offset;
	_tmp21_ = len;
	_tmp22_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) _tmp21_);
	result = _tmp22_;
	return result;
}


static gint64 int64_parse (const gchar* str) {
	gint64 result = 0LL;
	const gchar* _tmp0_;
	gint64 _tmp1_;
	g_return_val_if_fail (str != NULL, 0LL);
	_tmp0_ = str;
	_tmp1_ = g_ascii_strtoll (_tmp0_, NULL, (guint) 0);
	result = _tmp1_;
	return result;
}


static gboolean vala_integer_literal_real_check (ValaCodeNode* base, ValaCodeContext* context) {
	ValaIntegerLiteral * self;
	gboolean result = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	gint l = 0;
	gboolean u = FALSE;
	gboolean _tmp16_ = FALSE;
	const gchar* _tmp17_;
	gboolean _tmp18_;
	gint64 n = 0LL;
	const gchar* _tmp27_;
	gint64 _tmp28_;
	gboolean _tmp29_ = FALSE;
	gboolean _tmp30_;
	gchar* type_name = NULL;
	gint _tmp37_;
	ValaStruct* st = NULL;
	ValaCodeContext* _tmp48_;
	ValaSemanticAnalyzer* _tmp49_;
	ValaSemanticAnalyzer* _tmp50_;
	ValaSymbol* _tmp51_;
	ValaScope* _tmp52_;
	ValaScope* _tmp53_;
	const gchar* _tmp54_;
	ValaSymbol* _tmp55_;
	ValaStruct* _tmp56_;
	ValaCodeContext* _tmp57_;
	ValaStruct* _tmp58_;
	const gchar* _tmp59_;
	const gchar* _tmp60_;
	ValaIntegerType* _tmp61_;
	ValaIntegerType* _tmp62_;
	gboolean _tmp63_;
	gboolean _tmp64_;
	self = (ValaIntegerLiteral*) base;
	g_return_val_if_fail (context != NULL, FALSE);
	_tmp0_ = vala_code_node_get_checked ((ValaCodeNode*) self);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp2_ = vala_code_node_get_error ((ValaCodeNode*) self);
		_tmp3_ = _tmp2_;
		result = !_tmp3_;
		return result;
	}
	vala_code_node_set_checked ((ValaCodeNode*) self, TRUE);
	l = 0;
	while (TRUE) {
		gboolean _tmp4_ = FALSE;
		const gchar* _tmp5_;
		gboolean _tmp6_;
		gint _tmp9_;
		const gchar* _tmp10_;
		const gchar* _tmp11_;
		gint _tmp12_;
		gint _tmp13_;
		gchar* _tmp14_;
		gchar* _tmp15_;
		_tmp5_ = self->priv->_value;
		_tmp6_ = g_str_has_suffix (_tmp5_, "l");
		if (_tmp6_) {
			_tmp4_ = TRUE;
		} else {
			const gchar* _tmp7_;
			gboolean _tmp8_;
			_tmp7_ = self->priv->_value;
			_tmp8_ = g_str_has_suffix (_tmp7_, "L");
			_tmp4_ = _tmp8_;
		}
		if (!_tmp4_) {
			break;
		}
		_tmp9_ = l;
		l = _tmp9_ + 1;
		_tmp10_ = self->priv->_value;
		_tmp11_ = self->priv->_value;
		_tmp12_ = strlen (_tmp11_);
		_tmp13_ = _tmp12_;
		_tmp14_ = string_substring (_tmp10_, (glong) 0, (glong) (_tmp13_ - 1));
		_tmp15_ = _tmp14_;
		vala_integer_literal_set_value (self, _tmp15_);
		_g_free0 (_tmp15_);
	}
	u = FALSE;
	_tmp17_ = self->priv->_value;
	_tmp18_ = g_str_has_suffix (_tmp17_, "u");
	if (_tmp18_) {
		_tmp16_ = TRUE;
	} else {
		const gchar* _tmp19_;
		gboolean _tmp20_;
		_tmp19_ = self->priv->_value;
		_tmp20_ = g_str_has_suffix (_tmp19_, "U");
		_tmp16_ = _tmp20_;
	}
	if (_tmp16_) {
		const gchar* _tmp21_;
		const gchar* _tmp22_;
		gint _tmp23_;
		gint _tmp24_;
		gchar* _tmp25_;
		gchar* _tmp26_;
		u = TRUE;
		_tmp21_ = self->priv->_value;
		_tmp22_ = self->priv->_value;
		_tmp23_ = strlen (_tmp22_);
		_tmp24_ = _tmp23_;
		_tmp25_ = string_substring (_tmp21_, (glong) 0, (glong) (_tmp24_ - 1));
		_tmp26_ = _tmp25_;
		vala_integer_literal_set_value (self, _tmp26_);
		_g_free0 (_tmp26_);
	}
	_tmp27_ = self->priv->_value;
	_tmp28_ = int64_parse (_tmp27_);
	n = _tmp28_;
	_tmp30_ = u;
	if (!_tmp30_) {
		gboolean _tmp31_ = FALSE;
		gint64 _tmp32_;
		_tmp32_ = n;
		if (_tmp32_ > ((gint64) G_MAXINT)) {
			_tmp31_ = TRUE;
		} else {
			gint64 _tmp33_;
			_tmp33_ = n;
			_tmp31_ = _tmp33_ < ((gint64) G_MININT);
		}
		_tmp29_ = _tmp31_;
	} else {
		_tmp29_ = FALSE;
	}
	if (_tmp29_) {
		l = 2;
	} else {
		gboolean _tmp34_ = FALSE;
		gboolean _tmp35_;
		_tmp35_ = u;
		if (_tmp35_) {
			gint64 _tmp36_;
			_tmp36_ = n;
			_tmp34_ = _tmp36_ > ((gint64) G_MAXUINT);
		} else {
			_tmp34_ = FALSE;
		}
		if (_tmp34_) {
			l = 2;
		}
	}
	_tmp37_ = l;
	if (_tmp37_ == 0) {
		gboolean _tmp38_;
		_tmp38_ = u;
		if (_tmp38_) {
			gchar* _tmp39_;
			vala_integer_literal_set_type_suffix (self, "U");
			_tmp39_ = g_strdup ("uint");
			_g_free0 (type_name);
			type_name = _tmp39_;
		} else {
			gchar* _tmp40_;
			vala_integer_literal_set_type_suffix (self, "");
			_tmp40_ = g_strdup ("int");
			_g_free0 (type_name);
			type_name = _tmp40_;
		}
	} else {
		gint _tmp41_;
		_tmp41_ = l;
		if (_tmp41_ == 1) {
			gboolean _tmp42_;
			_tmp42_ = u;
			if (_tmp42_) {
				gchar* _tmp43_;
				vala_integer_literal_set_type_suffix (self, "UL");
				_tmp43_ = g_strdup ("ulong");
				_g_free0 (type_name);
				type_name = _tmp43_;
			} else {
				gchar* _tmp44_;
				vala_integer_literal_set_type_suffix (self, "L");
				_tmp44_ = g_strdup ("long");
				_g_free0 (type_name);
				type_name = _tmp44_;
			}
		} else {
			gboolean _tmp45_;
			_tmp45_ = u;
			if (_tmp45_) {
				gchar* _tmp46_;
				vala_integer_literal_set_type_suffix (self, "ULL");
				_tmp46_ = g_strdup ("uint64");
				_g_free0 (type_name);
				type_name = _tmp46_;
			} else {
				gchar* _tmp47_;
				vala_integer_literal_set_type_suffix (self, "LL");
				_tmp47_ = g_strdup ("int64");
				_g_free0 (type_name);
				type_name = _tmp47_;
			}
		}
	}
	_tmp48_ = context;
	_tmp49_ = vala_code_context_get_analyzer (_tmp48_);
	_tmp50_ = _tmp49_;
	_tmp51_ = _tmp50_->root_symbol;
	_tmp52_ = vala_symbol_get_scope (_tmp51_);
	_tmp53_ = _tmp52_;
	_tmp54_ = type_name;
	_tmp55_ = vala_scope_lookup (_tmp53_, _tmp54_);
	st = G_TYPE_CHECK_INSTANCE_CAST (_tmp55_, VALA_TYPE_STRUCT, ValaStruct);
	_tmp56_ = st;
	_tmp57_ = context;
	vala_code_node_check ((ValaCodeNode*) _tmp56_, _tmp57_);
	_tmp58_ = st;
	_tmp59_ = self->priv->_value;
	_tmp60_ = type_name;
	_tmp61_ = vala_integer_type_new (_tmp58_, _tmp59_, _tmp60_);
	_tmp62_ = _tmp61_;
	vala_expression_set_value_type ((ValaExpression*) self, (ValaDataType*) _tmp62_);
	_vala_code_node_unref0 (_tmp62_);
	_tmp63_ = vala_code_node_get_error ((ValaCodeNode*) self);
	_tmp64_ = _tmp63_;
	result = !_tmp64_;
	_vala_code_node_unref0 (st);
	_g_free0 (type_name);
	return result;
}


static void vala_integer_literal_real_emit (ValaCodeNode* base, ValaCodeGenerator* codegen) {
	ValaIntegerLiteral * self;
	ValaCodeGenerator* _tmp0_;
	ValaCodeGenerator* _tmp1_;
	self = (ValaIntegerLiteral*) base;
	g_return_if_fail (codegen != NULL);
	_tmp0_ = codegen;
	vala_code_visitor_visit_integer_literal ((ValaCodeVisitor*) _tmp0_, self);
	_tmp1_ = codegen;
	vala_code_visitor_visit_expression ((ValaCodeVisitor*) _tmp1_, (ValaExpression*) self);
}


const gchar* vala_integer_literal_get_value (ValaIntegerLiteral* self) {
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_value;
	result = _tmp0_;
	return result;
}


void vala_integer_literal_set_value (ValaIntegerLiteral* self, const gchar* value) {
	const gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->priv->_value);
	self->priv->_value = _tmp1_;
}


const gchar* vala_integer_literal_get_type_suffix (ValaIntegerLiteral* self) {
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_type_suffix;
	result = _tmp0_;
	return result;
}


void vala_integer_literal_set_type_suffix (ValaIntegerLiteral* self, const gchar* value) {
	const gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->priv->_type_suffix);
	self->priv->_type_suffix = _tmp1_;
}


static void vala_integer_literal_class_init (ValaIntegerLiteralClass * klass) {
	vala_integer_literal_parent_class = g_type_class_peek_parent (klass);
	((ValaCodeNodeClass *) klass)->finalize = vala_integer_literal_finalize;
	g_type_class_add_private (klass, sizeof (ValaIntegerLiteralPrivate));
	((ValaCodeNodeClass *) klass)->accept = (void (*) (ValaCodeNode *, ValaCodeVisitor*)) vala_integer_literal_real_accept;
	((ValaCodeNodeClass *) klass)->to_string = (gchar* (*) (ValaCodeNode *)) vala_integer_literal_real_to_string;
	((ValaExpressionClass *) klass)->is_pure = (gboolean (*) (ValaExpression *)) vala_integer_literal_real_is_pure;
	((ValaCodeNodeClass *) klass)->check = (gboolean (*) (ValaCodeNode *, ValaCodeContext*)) vala_integer_literal_real_check;
	((ValaCodeNodeClass *) klass)->emit = (void (*) (ValaCodeNode *, ValaCodeGenerator*)) vala_integer_literal_real_emit;
}


static void vala_integer_literal_instance_init (ValaIntegerLiteral * self) {
	self->priv = VALA_INTEGER_LITERAL_GET_PRIVATE (self);
}


static void vala_integer_literal_finalize (ValaCodeNode * obj) {
	ValaIntegerLiteral * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, VALA_TYPE_INTEGER_LITERAL, ValaIntegerLiteral);
	_g_free0 (self->priv->_value);
	_g_free0 (self->priv->_type_suffix);
	VALA_CODE_NODE_CLASS (vala_integer_literal_parent_class)->finalize (obj);
}


/**
 * Represents an integer literal in the source code.
 */
GType vala_integer_literal_get_type (void) {
	static volatile gsize vala_integer_literal_type_id__volatile = 0;
	if (g_once_init_enter (&vala_integer_literal_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (ValaIntegerLiteralClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vala_integer_literal_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ValaIntegerLiteral), 0, (GInstanceInitFunc) vala_integer_literal_instance_init, NULL };
		GType vala_integer_literal_type_id;
		vala_integer_literal_type_id = g_type_register_static (VALA_TYPE_LITERAL, "ValaIntegerLiteral", &g_define_type_info, 0);
		g_once_init_leave (&vala_integer_literal_type_id__volatile, vala_integer_literal_type_id);
	}
	return vala_integer_literal_type_id__volatile;
}



