/**************************************************************************************
 * Chaga compiler                                                                     *
 * Copyright (C) 2026 Robert James Bruce                                              *
 *                                                                                    *
 * This file is part of the Chaga compiler.                                           *
 *                                                                                    *
 * The Chaga compiler 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.                                                                     *
 *                                                                                    *
 * The Chaga compiler 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 the Chaga compiler. If not, see <https://www.gnu.org/licenses/>.        *
 **************************************************************************************/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifndef CHAGA_COMPILER_CONSTANTS
#include "chaga_compiler-constants.h"
#endif

#ifndef CHAGA_DATA_STRUCTURES
#include "chaga_compiler-data_structures.h"
#endif

#include "chaga_compiler-data_structure_management.h"
#include "chaga_compiler-diagnostic_tools.h"


stackframe_node * create_stackframe_cross_reference_table_for_main_function (stackframe_node *, symtab_node *, unsigned long long int);
stackframe_node * create_stackframe_cross_reference_table_for_function (stackframe_node *, symtab_node *, unsigned long long int);
stackframe_node * create_stackframe_cross_reference_table_for_procedure (stackframe_node *, symtab_node *, unsigned long long int);
stackframe_node * create_stackframe_cross_reference_table (symtab_node *);
stackframe_node * add_new_symbol_table_entry_to_stackframe_cross_reference_table (stackframe_node *, symtab_node *, symtab_node *);
symtab_node * allocate_additional_temporary_stack_storage_variables_for_calls_to_functions_and_procedures (symtab_node *, ast_node *);
ast_node * create_assembler_program_first_pass (ast_node *);
ast_node * create_assembler_program_second_pass (ast_node *);
asmblr_node * create_assembler_program (ast_node *, symtab_node *, stackframe_node *);
asmblr_node * create_assembler_program_v2 (ast_node *, symtab_node *, stackframe_node *);
asmblr_node * create_assembler_output_for_main_function_definition (asmblr_node *, symtab_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_for_procedure_definition (asmblr_node *, symtab_node *, stackframe_node *, symtab_node *, unsigned long long int);
asmblr_node * create_assembler_output_print_statement (asmblr_node *, ast_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_set_statement (asmblr_node *, ast_node *, symtab_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_if_statement (asmblr_node *, ast_node *, symtab_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_while_statement (asmblr_node *, ast_node *, symtab_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_code_section_label (asmblr_node *, ast_node *, unsigned long long int);
asmblr_node * create_assembler_output_code_section_jump_statement (asmblr_node *, ast_node *, unsigned long long int);
asmblr_node * create_assembler_output_exit_main_function (asmblr_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_return_from_procedure (asmblr_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_call_statement (asmblr_node *, ast_node *, symtab_node *, stackframe_node *, unsigned long long int);
asmblr_node * create_assembler_output_for_operator_or_operand_to_build_runtime_expression (asmblr_node *, ast_node *, symtab_node *, stackframe_node *, stackframe_node *, unsigned long long int);
void write_assembler_output_to_file (FILE *, asmblr_node *);
void create_executable_output_file_from_x86_assembler_file (char *, char *, char *);
size_t symbol_table_count_number_of_datatype_declarations_for_given_scope_level_excluding_argv_argc_in_main (symtab_node *, unsigned long long int);
size_t symbol_table_count_number_of_datatype_declarations_for_given_scope_level (symtab_node *, unsigned long long int);
unsigned long long int * retrieve_highest_label_number_from_assembly_output (asmblr_node *);
unsigned long long int * retrieve_highest_label_number_from_abstract_syntax_tree (ast_node *);
ast_node * find_else_statement_associated_with_if_statement (ast_node *);
ast_node * find_next_statement_after_if_then_statement (ast_node *);
ast_node * find_next_statement_after_if_then_else_statement (ast_node *);
ast_node * find_closing_curly_brace_of_if_then_statement_block_for_if_then_else_statement (ast_node *);
ast_node * find_next_statement_after_while_statement (ast_node *);
ast_node * find_closing_curly_brace_of_while_statement_block (ast_node *);
size_t determine_stackframe_storage_size_for_all_locally_defined_variables_in_main (stackframe_node *, symtab_node *);
size_t determine_stackframe_storage_size_for_all_locally_defined_variables_based_on_scope_level (stackframe_node *, symtab_node *, unsigned long long int);
char * escape_double_quotes_inside_text (char *);

