/* valacodegenerator.vala
 *
 * Copyright (C) 2007-2008  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>
 */

#ifndef __VALA_VALACODEGENERATOR_H__
#define __VALA_VALACODEGENERATOR_H__

#include <glib.h>
#include <glib-object.h>
#include <vala/valacodevisitor.h>
#include <vala/valacodenode.h>
#include <vala/valacodebinding.h>

G_BEGIN_DECLS


#define VALA_TYPE_CODE_GENERATOR (vala_code_generator_get_type ())
#define VALA_CODE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VALA_TYPE_CODE_GENERATOR, ValaCodeGenerator))
#define VALA_CODE_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VALA_TYPE_CODE_GENERATOR, ValaCodeGeneratorClass))
#define VALA_IS_CODE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VALA_TYPE_CODE_GENERATOR))
#define VALA_IS_CODE_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VALA_TYPE_CODE_GENERATOR))
#define VALA_CODE_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VALA_TYPE_CODE_GENERATOR, ValaCodeGeneratorClass))

typedef struct _ValaCodeGeneratorPrivate ValaCodeGeneratorPrivate;

/**
 * Abstract code visitor generating code.
 */
struct _ValaCodeGenerator {
	ValaCodeVisitor parent_instance;
	ValaCodeGeneratorPrivate * priv;
};

struct _ValaCodeGeneratorClass {
	ValaCodeVisitorClass parent_class;
	void (*emit) (ValaCodeGenerator* self, ValaCodeContext* context);
	ValaCodeBinding* (*create_namespace_binding) (ValaCodeGenerator* self, ValaNamespace* node);
	ValaCodeBinding* (*create_class_binding) (ValaCodeGenerator* self, ValaClass* node);
	ValaCodeBinding* (*create_struct_binding) (ValaCodeGenerator* self, ValaStruct* node);
	ValaCodeBinding* (*create_interface_binding) (ValaCodeGenerator* self, ValaInterface* node);
	ValaCodeBinding* (*create_enum_binding) (ValaCodeGenerator* self, ValaEnum* node);
	ValaCodeBinding* (*create_enum_value_binding) (ValaCodeGenerator* self, ValaEnumValue* node);
	ValaCodeBinding* (*create_error_domain_binding) (ValaCodeGenerator* self, ValaErrorDomain* node);
	ValaCodeBinding* (*create_error_code_binding) (ValaCodeGenerator* self, ValaErrorCode* node);
	ValaCodeBinding* (*create_delegate_binding) (ValaCodeGenerator* self, ValaDelegate* node);
	ValaCodeBinding* (*create_constant_binding) (ValaCodeGenerator* self, ValaConstant* node);
	ValaCodeBinding* (*create_field_binding) (ValaCodeGenerator* self, ValaField* node);
	ValaCodeBinding* (*create_method_binding) (ValaCodeGenerator* self, ValaMethod* node);
	ValaCodeBinding* (*create_dynamic_method_binding) (ValaCodeGenerator* self, ValaDynamicMethod* node);
	ValaCodeBinding* (*create_creation_method_binding) (ValaCodeGenerator* self, ValaCreationMethod* node);
	ValaCodeBinding* (*create_formal_parameter_binding) (ValaCodeGenerator* self, ValaFormalParameter* node);
	ValaCodeBinding* (*create_property_binding) (ValaCodeGenerator* self, ValaProperty* node);
	ValaCodeBinding* (*create_dynamic_property_binding) (ValaCodeGenerator* self, ValaDynamicProperty* node);
	ValaCodeBinding* (*create_property_accessor_binding) (ValaCodeGenerator* self, ValaPropertyAccessor* node);
	ValaCodeBinding* (*create_signal_binding) (ValaCodeGenerator* self, ValaSignal* node);
	ValaCodeBinding* (*create_dynamic_signal_binding) (ValaCodeGenerator* self, ValaDynamicSignal* node);
	ValaCodeBinding* (*create_constructor_binding) (ValaCodeGenerator* self, ValaConstructor* node);
	ValaCodeBinding* (*create_destructor_binding) (ValaCodeGenerator* self, ValaDestructor* node);
	ValaCodeBinding* (*create_type_parameter_binding) (ValaCodeGenerator* self, ValaTypeParameter* node);
	ValaCodeBinding* (*create_block_binding) (ValaCodeGenerator* self, ValaBlock* node);
	ValaCodeBinding* (*create_empty_statement_binding) (ValaCodeGenerator* self, ValaEmptyStatement* node);
	ValaCodeBinding* (*create_declaration_statement_binding) (ValaCodeGenerator* self, ValaDeclarationStatement* node);
	ValaCodeBinding* (*create_local_variable_binding) (ValaCodeGenerator* self, ValaLocalVariable* node);
	ValaCodeBinding* (*create_initializer_list_binding) (ValaCodeGenerator* self, ValaInitializerList* node);
	ValaCodeBinding* (*create_expression_statement_binding) (ValaCodeGenerator* self, ValaExpressionStatement* node);
	ValaCodeBinding* (*create_if_statement_binding) (ValaCodeGenerator* self, ValaIfStatement* node);
	ValaCodeBinding* (*create_switch_statement_binding) (ValaCodeGenerator* self, ValaSwitchStatement* node);
	ValaCodeBinding* (*create_switch_section_binding) (ValaCodeGenerator* self, ValaSwitchSection* node);
	ValaCodeBinding* (*create_switch_label_binding) (ValaCodeGenerator* self, ValaSwitchLabel* node);
	ValaCodeBinding* (*create_while_statement_binding) (ValaCodeGenerator* self, ValaWhileStatement* node);
	ValaCodeBinding* (*create_do_statement_binding) (ValaCodeGenerator* self, ValaDoStatement* node);
	ValaCodeBinding* (*create_for_statement_binding) (ValaCodeGenerator* self, ValaForStatement* node);
	ValaCodeBinding* (*create_foreach_statement_binding) (ValaCodeGenerator* self, ValaForeachStatement* node);
	ValaCodeBinding* (*create_break_statement_binding) (ValaCodeGenerator* self, ValaBreakStatement* node);
	ValaCodeBinding* (*create_continue_statement_binding) (ValaCodeGenerator* self, ValaContinueStatement* node);
	ValaCodeBinding* (*create_return_statement_binding) (ValaCodeGenerator* self, ValaReturnStatement* node);
	ValaCodeBinding* (*create_throw_statement_binding) (ValaCodeGenerator* self, ValaThrowStatement* node);
	ValaCodeBinding* (*create_try_statement_binding) (ValaCodeGenerator* self, ValaTryStatement* node);
	ValaCodeBinding* (*create_catch_clause_binding) (ValaCodeGenerator* self, ValaCatchClause* node);
	ValaCodeBinding* (*create_lock_statement_binding) (ValaCodeGenerator* self, ValaLockStatement* node);
	ValaCodeBinding* (*create_delete_statement_binding) (ValaCodeGenerator* self, ValaDeleteStatement* node);
	ValaCodeBinding* (*create_array_creation_expression_binding) (ValaCodeGenerator* self, ValaArrayCreationExpression* node);
	ValaCodeBinding* (*create_boolean_literal_binding) (ValaCodeGenerator* self, ValaBooleanLiteral* node);
	ValaCodeBinding* (*create_character_literal_binding) (ValaCodeGenerator* self, ValaCharacterLiteral* node);
	ValaCodeBinding* (*create_integer_literal_binding) (ValaCodeGenerator* self, ValaIntegerLiteral* node);
	ValaCodeBinding* (*create_real_literal_binding) (ValaCodeGenerator* self, ValaRealLiteral* node);
	ValaCodeBinding* (*create_string_literal_binding) (ValaCodeGenerator* self, ValaStringLiteral* node);
	ValaCodeBinding* (*create_null_literal_binding) (ValaCodeGenerator* self, ValaNullLiteral* node);
	ValaCodeBinding* (*create_parenthesized_expression_binding) (ValaCodeGenerator* self, ValaParenthesizedExpression* node);
	ValaCodeBinding* (*create_member_access_binding) (ValaCodeGenerator* self, ValaMemberAccess* node);
	ValaCodeBinding* (*create_invocation_expression_binding) (ValaCodeGenerator* self, ValaInvocationExpression* node);
	ValaCodeBinding* (*create_element_access_binding) (ValaCodeGenerator* self, ValaElementAccess* node);
	ValaCodeBinding* (*create_base_access_binding) (ValaCodeGenerator* self, ValaBaseAccess* node);
	ValaCodeBinding* (*create_postfix_expression_binding) (ValaCodeGenerator* self, ValaPostfixExpression* node);
	ValaCodeBinding* (*create_object_creation_expression_binding) (ValaCodeGenerator* self, ValaObjectCreationExpression* node);
	ValaCodeBinding* (*create_sizeof_expression_binding) (ValaCodeGenerator* self, ValaSizeofExpression* node);
	ValaCodeBinding* (*create_typeof_expression_binding) (ValaCodeGenerator* self, ValaTypeofExpression* node);
	ValaCodeBinding* (*create_unary_expression_binding) (ValaCodeGenerator* self, ValaUnaryExpression* node);
	ValaCodeBinding* (*create_cast_expression_binding) (ValaCodeGenerator* self, ValaCastExpression* node);
	ValaCodeBinding* (*create_pointer_indirection_binding) (ValaCodeGenerator* self, ValaPointerIndirection* node);
	ValaCodeBinding* (*create_addressof_expression_binding) (ValaCodeGenerator* self, ValaAddressofExpression* node);
	ValaCodeBinding* (*create_reference_transfer_expression_binding) (ValaCodeGenerator* self, ValaReferenceTransferExpression* node);
	ValaCodeBinding* (*create_binary_expression_binding) (ValaCodeGenerator* self, ValaBinaryExpression* node);
	ValaCodeBinding* (*create_type_check_binding) (ValaCodeGenerator* self, ValaTypeCheck* node);
	ValaCodeBinding* (*create_conditional_expression_binding) (ValaCodeGenerator* self, ValaConditionalExpression* node);
	ValaCodeBinding* (*create_lambda_expression_binding) (ValaCodeGenerator* self, ValaLambdaExpression* node);
	ValaCodeBinding* (*create_assignment_binding) (ValaCodeGenerator* self, ValaAssignment* node);
};


void vala_code_generator_emit (ValaCodeGenerator* self, ValaCodeContext* context);
ValaCodeBinding* vala_code_generator_create_namespace_binding (ValaCodeGenerator* self, ValaNamespace* node);
ValaCodeBinding* vala_code_generator_create_class_binding (ValaCodeGenerator* self, ValaClass* node);
ValaCodeBinding* vala_code_generator_create_struct_binding (ValaCodeGenerator* self, ValaStruct* node);
ValaCodeBinding* vala_code_generator_create_interface_binding (ValaCodeGenerator* self, ValaInterface* node);
ValaCodeBinding* vala_code_generator_create_enum_binding (ValaCodeGenerator* self, ValaEnum* node);
ValaCodeBinding* vala_code_generator_create_enum_value_binding (ValaCodeGenerator* self, ValaEnumValue* node);
ValaCodeBinding* vala_code_generator_create_error_domain_binding (ValaCodeGenerator* self, ValaErrorDomain* node);
ValaCodeBinding* vala_code_generator_create_error_code_binding (ValaCodeGenerator* self, ValaErrorCode* node);
ValaCodeBinding* vala_code_generator_create_delegate_binding (ValaCodeGenerator* self, ValaDelegate* node);
ValaCodeBinding* vala_code_generator_create_constant_binding (ValaCodeGenerator* self, ValaConstant* node);
ValaCodeBinding* vala_code_generator_create_field_binding (ValaCodeGenerator* self, ValaField* node);
ValaCodeBinding* vala_code_generator_create_method_binding (ValaCodeGenerator* self, ValaMethod* node);
ValaCodeBinding* vala_code_generator_create_dynamic_method_binding (ValaCodeGenerator* self, ValaDynamicMethod* node);
ValaCodeBinding* vala_code_generator_create_creation_method_binding (ValaCodeGenerator* self, ValaCreationMethod* node);
ValaCodeBinding* vala_code_generator_create_formal_parameter_binding (ValaCodeGenerator* self, ValaFormalParameter* node);
ValaCodeBinding* vala_code_generator_create_property_binding (ValaCodeGenerator* self, ValaProperty* node);
ValaCodeBinding* vala_code_generator_create_dynamic_property_binding (ValaCodeGenerator* self, ValaDynamicProperty* node);
ValaCodeBinding* vala_code_generator_create_property_accessor_binding (ValaCodeGenerator* self, ValaPropertyAccessor* node);
ValaCodeBinding* vala_code_generator_create_signal_binding (ValaCodeGenerator* self, ValaSignal* node);
ValaCodeBinding* vala_code_generator_create_dynamic_signal_binding (ValaCodeGenerator* self, ValaDynamicSignal* node);
ValaCodeBinding* vala_code_generator_create_constructor_binding (ValaCodeGenerator* self, ValaConstructor* node);
ValaCodeBinding* vala_code_generator_create_destructor_binding (ValaCodeGenerator* self, ValaDestructor* node);
ValaCodeBinding* vala_code_generator_create_type_parameter_binding (ValaCodeGenerator* self, ValaTypeParameter* node);
ValaCodeBinding* vala_code_generator_create_block_binding (ValaCodeGenerator* self, ValaBlock* node);
ValaCodeBinding* vala_code_generator_create_empty_statement_binding (ValaCodeGenerator* self, ValaEmptyStatement* node);
ValaCodeBinding* vala_code_generator_create_declaration_statement_binding (ValaCodeGenerator* self, ValaDeclarationStatement* node);
ValaCodeBinding* vala_code_generator_create_local_variable_binding (ValaCodeGenerator* self, ValaLocalVariable* node);
ValaCodeBinding* vala_code_generator_create_initializer_list_binding (ValaCodeGenerator* self, ValaInitializerList* node);
ValaCodeBinding* vala_code_generator_create_expression_statement_binding (ValaCodeGenerator* self, ValaExpressionStatement* node);
ValaCodeBinding* vala_code_generator_create_if_statement_binding (ValaCodeGenerator* self, ValaIfStatement* node);
ValaCodeBinding* vala_code_generator_create_switch_statement_binding (ValaCodeGenerator* self, ValaSwitchStatement* node);
ValaCodeBinding* vala_code_generator_create_switch_section_binding (ValaCodeGenerator* self, ValaSwitchSection* node);
ValaCodeBinding* vala_code_generator_create_switch_label_binding (ValaCodeGenerator* self, ValaSwitchLabel* node);
ValaCodeBinding* vala_code_generator_create_while_statement_binding (ValaCodeGenerator* self, ValaWhileStatement* node);
ValaCodeBinding* vala_code_generator_create_do_statement_binding (ValaCodeGenerator* self, ValaDoStatement* node);
ValaCodeBinding* vala_code_generator_create_for_statement_binding (ValaCodeGenerator* self, ValaForStatement* node);
ValaCodeBinding* vala_code_generator_create_foreach_statement_binding (ValaCodeGenerator* self, ValaForeachStatement* node);
ValaCodeBinding* vala_code_generator_create_break_statement_binding (ValaCodeGenerator* self, ValaBreakStatement* node);
ValaCodeBinding* vala_code_generator_create_continue_statement_binding (ValaCodeGenerator* self, ValaContinueStatement* node);
ValaCodeBinding* vala_code_generator_create_return_statement_binding (ValaCodeGenerator* self, ValaReturnStatement* node);
ValaCodeBinding* vala_code_generator_create_throw_statement_binding (ValaCodeGenerator* self, ValaThrowStatement* node);
ValaCodeBinding* vala_code_generator_create_try_statement_binding (ValaCodeGenerator* self, ValaTryStatement* node);
ValaCodeBinding* vala_code_generator_create_catch_clause_binding (ValaCodeGenerator* self, ValaCatchClause* node);
ValaCodeBinding* vala_code_generator_create_lock_statement_binding (ValaCodeGenerator* self, ValaLockStatement* node);
ValaCodeBinding* vala_code_generator_create_delete_statement_binding (ValaCodeGenerator* self, ValaDeleteStatement* node);
ValaCodeBinding* vala_code_generator_create_array_creation_expression_binding (ValaCodeGenerator* self, ValaArrayCreationExpression* node);
ValaCodeBinding* vala_code_generator_create_boolean_literal_binding (ValaCodeGenerator* self, ValaBooleanLiteral* node);
ValaCodeBinding* vala_code_generator_create_character_literal_binding (ValaCodeGenerator* self, ValaCharacterLiteral* node);
ValaCodeBinding* vala_code_generator_create_integer_literal_binding (ValaCodeGenerator* self, ValaIntegerLiteral* node);
ValaCodeBinding* vala_code_generator_create_real_literal_binding (ValaCodeGenerator* self, ValaRealLiteral* node);
ValaCodeBinding* vala_code_generator_create_string_literal_binding (ValaCodeGenerator* self, ValaStringLiteral* node);
ValaCodeBinding* vala_code_generator_create_null_literal_binding (ValaCodeGenerator* self, ValaNullLiteral* node);
ValaCodeBinding* vala_code_generator_create_parenthesized_expression_binding (ValaCodeGenerator* self, ValaParenthesizedExpression* node);
ValaCodeBinding* vala_code_generator_create_member_access_binding (ValaCodeGenerator* self, ValaMemberAccess* node);
ValaCodeBinding* vala_code_generator_create_invocation_expression_binding (ValaCodeGenerator* self, ValaInvocationExpression* node);
ValaCodeBinding* vala_code_generator_create_element_access_binding (ValaCodeGenerator* self, ValaElementAccess* node);
ValaCodeBinding* vala_code_generator_create_base_access_binding (ValaCodeGenerator* self, ValaBaseAccess* node);
ValaCodeBinding* vala_code_generator_create_postfix_expression_binding (ValaCodeGenerator* self, ValaPostfixExpression* node);
ValaCodeBinding* vala_code_generator_create_object_creation_expression_binding (ValaCodeGenerator* self, ValaObjectCreationExpression* node);
ValaCodeBinding* vala_code_generator_create_sizeof_expression_binding (ValaCodeGenerator* self, ValaSizeofExpression* node);
ValaCodeBinding* vala_code_generator_create_typeof_expression_binding (ValaCodeGenerator* self, ValaTypeofExpression* node);
ValaCodeBinding* vala_code_generator_create_unary_expression_binding (ValaCodeGenerator* self, ValaUnaryExpression* node);
ValaCodeBinding* vala_code_generator_create_cast_expression_binding (ValaCodeGenerator* self, ValaCastExpression* node);
ValaCodeBinding* vala_code_generator_create_pointer_indirection_binding (ValaCodeGenerator* self, ValaPointerIndirection* node);
ValaCodeBinding* vala_code_generator_create_addressof_expression_binding (ValaCodeGenerator* self, ValaAddressofExpression* node);
ValaCodeBinding* vala_code_generator_create_reference_transfer_expression_binding (ValaCodeGenerator* self, ValaReferenceTransferExpression* node);
ValaCodeBinding* vala_code_generator_create_binary_expression_binding (ValaCodeGenerator* self, ValaBinaryExpression* node);
ValaCodeBinding* vala_code_generator_create_type_check_binding (ValaCodeGenerator* self, ValaTypeCheck* node);
ValaCodeBinding* vala_code_generator_create_conditional_expression_binding (ValaCodeGenerator* self, ValaConditionalExpression* node);
ValaCodeBinding* vala_code_generator_create_lambda_expression_binding (ValaCodeGenerator* self, ValaLambdaExpression* node);
ValaCodeBinding* vala_code_generator_create_assignment_binding (ValaCodeGenerator* self, ValaAssignment* node);
ValaCodeGenerator* vala_code_generator_new (void);
GType vala_code_generator_get_type (void);


G_END_DECLS

#endif
