def main():
    programs = sys.argv[1:]
    if (len(programs) == 0):
        errors.throw_error(errors.CompilerError(text='No file is given to coolc compiler.'))
    if (programs[0] == '-o'):
        if (len(programs) == 1):
            errors.throw_error(errors.CompilerError(text='No fileout is given to coolc compiler.'))
        fileout = programs[1]
        if (not str(fileout).endswith('.asm')):
            errors.throw_error(errors.CompilerError(text='Fileout must end with .asm extension.'))
        if (len(programs) == 2):
            errors.throw_error(errors.CompilerError(text='No file is given to coolc compiler.'))
        programs = programs[2:]
    else:
        fileout = (programs[0].split('.cl')[0] + '.asm')
    for program in programs:
        if (not str(program).endswith('.cl')):
            errors.throw_error(errors.CompilerError(text='Cool program files must end with a .cl extension.'))
    code = ''
    for program in programs:
        try:
            with open(program, encoding='utf-8') as file:
                code += (file.read() + '\n')
        except (IOError, FileNotFoundError):
            errors.throw_error(errors.CompilerError(text=f'File "{program}" was not found.'))
        except Exception:
            errors.throw_error(errors.CompilerError(text='An unexpected error occurred!'))
    print(f"Compiling file '{fileout}'...")
    from lexicography.lexer_rules import CoolLex
    lexer = CoolLex()
    lexer.build()
    from lexicography.grammar_rules import CoolParse
    parser = CoolParse(lexer)
    parser.build()
    program_ast = parser.parse(code)
    from semantic.type_collector import TypeCollectorVisitor
    from semantic.type_builder import TypeBuilderVisitor
    from semantic.type_checker import TypeCheckerVisitor
    typeCollector = TypeCollectorVisitor()
    typeCollector.visit(program_ast)
    typeBuilder = TypeBuilderVisitor(typeCollector.enviroment)
    typeBuilder.visit(program_ast)
    final_enviroment = typeBuilder.enviroment
    final_enviroment.build_types_graph()
    type_checker = TypeCheckerVisitor()
    type_checker.visit(program_ast, typeBuilder.enviroment)
    typed_ast = program_ast
    from generation.cil.cil_generator import CilGeneratorVisitor
    cil_code_generator = CilGeneratorVisitor(typed_ast, typeBuilder.enviroment)
    ast_cil = cil_code_generator.generate_code()
    from generation.mips.mips_writer import MIPSWriterVisitor
    from operator import itemgetter
    types_ids = typeBuilder.enviroment.types_dict
    hierarchy = ([0] * len(types_ids))
    for _type in typeBuilder.enviroment.types_list[1:]:
        hierarchy[types_ids[_type.name]] = types_ids[_type.parent]
    ast_cil.typesHierarchy = hierarchy
    mips_code_generator = MIPSWriterVisitor(ast_cil, fileout)
    mips_code_generator.generate_Mips()
def main():
    programs = sys.argv[1:]
    if (len(programs) == 0):
        errors.throw_error(errors.CompilerError(text='No file is given to coolc compiler.'))
    if (programs[0] == '-o'):
        if (len(programs) == 1):
            errors.throw_error(errors.CompilerError(text='No fileout is given to coolc compiler.'))
        fileout = programs[1]
        if (not str(fileout).endswith('.asm')):
            errors.throw_error(errors.CompilerError(text='Fileout must end with .asm extension.'))
        if (len(programs) == 2):
            errors.throw_error(errors.CompilerError(text='No file is given to coolc compiler.'))
        programs = programs[2:]
    else:
        fileout = (programs[0].split('.cl')[0] + '.asm')
    for program in programs:
        if (not str(program).endswith('.cl')):
            errors.throw_error(errors.CompilerError(text='Cool program files must end with a .cl extension.'))
    code = 
    for program in programs:
        try:
            with open(program, encoding='utf-8') as file:
                code += (file.read() + '\n')
        except (IOError, FileNotFoundError):
            errors.throw_error(errors.CompilerError(text=f'File "{program}" was not found.'))
        except Exception:
            errors.throw_error(errors.CompilerError(text='An unexpected error occurred!'))
    print(f"Compiling file '{fileout}'...")
    from lexicography.lexer_rules import CoolLex
    lexer = CoolLex()
    lexer.build()
    from lexicography.grammar_rules import CoolParse
    parser = CoolParse(lexer)
    parser.build()
    program_ast = parser.parse(code)
    from semantic.type_collector import TypeCollectorVisitor
    from semantic.type_builder import TypeBuilderVisitor
    from semantic.type_checker import TypeCheckerVisitor
    typeCollector = TypeCollectorVisitor()
    typeCollector.visit(program_ast)
    typeBuilder = TypeBuilderVisitor(typeCollector.enviroment)
    typeBuilder.visit(program_ast)
    final_enviroment = typeBuilder.enviroment
    final_enviroment.build_types_graph()
    type_checker = TypeCheckerVisitor()
    type_checker.visit(program_ast, typeBuilder.enviroment)
    typed_ast = program_ast
    from generation.cil.cil_generator import CilGeneratorVisitor
    cil_code_generator = CilGeneratorVisitor(typed_ast, typeBuilder.enviroment)
    ast_cil = cil_code_generator.generate_code()
    from generation.mips.mips_writer import MIPSWriterVisitor
    from operator import itemgetter
    types_ids = typeBuilder.enviroment.types_dict
    hierarchy = ([0] * len(types_ids))
    for _type in typeBuilder.enviroment.types_list[1:]:
        hierarchy[types_ids[_type.name]] = types_ids[_type.parent]
    ast_cil.typesHierarchy = hierarchy
    mips_code_generator = MIPSWriterVisitor(ast_cil, fileout)
    mips_code_generator.generate_Mips()