package compiler;

/*
 Verificar operacao unaria negacao valor em laco
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import API.Api;
import API.BuildParams;
import API.Middleware;
import API.Target;
import Export.MultCoreJun;
import Export.Simulation;
import IntermediaryCode.IRGenerator;
import java.util.logging.Level;
import java.util.logging.Logger;
import targets.mips.Translate;

/**
 *
 * @author Eugenio
 */
public class IVANNOSYS {

    protected static IvannosysCompiler COM;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {

        try {
            String cmd = "", file = "";

            if (args.length > 0) {
                cmd = args[0];
            }
            switch (cmd) {
                case "create":
                    break;
                default:
//                    Middleware.Add("mips.analise", new analise.AnaliseDependenciaMiddleware());
//                    Middleware.Add("mips.module.scheduling", new analise.ModuleSchedulingMiddleware());

                    COM = new IvannosysCompiler(
                            "UTF-8",
                            IvannosysCompiler.INPUT_FILE)
                            .include(".\\src\\samples")
                            .include(".\\src\\libs")
                            // Especifica a classe de geração de codigo de tres enderecos
                            .IRGenerator(new IRGenerator());
                    // Extensao dos arquivos 
//                            .setExtensionLibrary(".go");

                    // Inicializa a api do compilador
                    Api.Init(COM);

                    // Parametros de compilação
                    BuildParams.Add("display.ERROS", "true");
                    BuildParams.Add("display.IR", "true");
                    BuildParams.Add("display.AST", "true");
                    BuildParams.Add("mode", "developement");

                    // Especifica a classe de geração de código alvo mips
                    Translate Mips = new targets.mips.Translate();
                    // Adiciona dois metodos de exportação ao alvo mips 
                    // Metodo de simualcao
                    Mips.AddExportOption("simulation", new Simulation(new tools.mips.MipsSettings() {
                        {
                            // Não executar passo a passo
                            Set("step.by.step", "false");
                            // Necessario para poder usar os breakpoints
//                            Set("mode", "debug");
                            // Determina os pontos de para no codigo alvo
//                            Set("breakpoints", "94-9c");
//                            Set("breakpoints", "1d8,214,2e0,28c,2f0,250,330");
//                            Set("breakpoints", "1d8,214,250,28c,2dc,2e0,2d8,2f0,300,314,324,350,35c");
//                            Set("breakpoints", "2e8-350,35c");
//                            Set("breakpoints", "314,35c");
//                            Set("breakpoints", "350,35c");
                            // Caminho do arquivo de memoria de instrucoes
                            Set("memory.instruction", "\\src\\tools\\mips\\memory\\mi.memory");
                            // Tamanho da memorua de instrucoes 16 kb
                            Set("memory.instruction.size", 16 * 1024);
                            // Caminho do arquivo de memoria de dados
                            Set("memory.data", "\\src\\tools\\mips\\memory\\md.memory");
                            // Tamanho da memorua de dados 16 kb
                            Set("memory.data.size", 16 * 1024);
                            Set("memory.data.reset", "true");
                        }
                    }));

                    // Metodo exporta profile para arquitetura de juninho
                    Mips.AddExportOption("MultCoreJun", new MultCoreJun());

                    Target.Add("mips", Mips);

                    // Registra os processadores para o alvo mips
                    // Executa alocacao de registradores antes de traduzir cada bloco
                    Middleware.On("mips", "before.translate.block", "mips.register.alloc");
                    Middleware.On("mips", "after.translate.block", "mips.o.L1,mips.copy.dep");
                    // Atualiza os enderecos de saltos e set no campo offset
//                    Middleware.On("mips", "after.translate", "mips.update.address,mips.analise,mips.module.scheduling");
//                    Middleware.On("mips", "after.translate", "mips.update.address,mips.module.scheduling");
                    Middleware.On("mips", "after.translate", "mips.update.address");

                    // file = "src\\samples\\program.go";
                    // file = "src\\samples\\program.go";
                    // file = "src\\samples\\program_mult_jon.go";
//                    file = "src\\samples\\program_mult.go";
//                    file = "src\\samples\\program_jun_bit_count.go";
//                    file = "src\\samples\\program_jun_laplaciano.go";
//                    file = "src\\samples\\program_jun_bytes.go";
//                    file = "src\\samples\\program_jun_mult_manycore.go";
                    // Compila o arquivo de entrada
                    COM.Compile(cmd);
            }

        } catch (Exception ex) {
            Logger.getLogger(IVANNOSYS.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
