Ejemplo n.º 1
0
void CompileCommand::Execute(StreamParser& input, Log& output)
{
    /* --- Compilation --- */

    /* Parse input stream */
    ReadArgs(input);

    if (outputFilename_.empty())
    {
        output.Error("missing output filename for code generation");
        return;
    }

    /* Setup I/O stream for assembly */
    std::unique_ptr<std::iostream> assembly;
    if (options_.showAsm)
    {
        assembly = MakeUnique<std::fstream>(
            OutputFilename(outputFilename_, "xasm", output),
            (std::fstream::in | std::fstream::out | std::fstream::trunc)
        );
    }
    else
        assembly = MakeUnique<std::stringstream>();

    /* Setup compilation falgs */
    auto flags = GetCompilationFlags();

    if (output.verbose)
        flags << CompileFlags::Verbose;
    
    /* Setup compilation configuration */
    CompileConfig config;

    for (const auto& source : sources_)
    {
        auto file = std::make_shared<std::ifstream>(source);
        if (!file->good())
        {
            output.Error("reading source file \"" + source + "\" failed");
            return;
        }
        else
            config.sources.push_back({ source, file });
    }

    config.assembly     = assembly.get();
    config.cfgDumpPath  = options_.cfgDumpPath;
    config.flags        = flags;

    /* Compile code */
    if (Compile(config, &output.stream))
    {
        /* Assemble code */
        config.assembly->seekg(0);
        auto byteCode = Assemble(*config.assembly, &output.stream);
        if (byteCode)
        {
            /* Write byte code to file */
            if (byteCode->WriteToFile(OutputFilename(outputFilename_, "xbc", output)))
            {
                /* Print success message */
                if (output.verbose)
                    output.Success("compilation successful");
            }
        }
    }
}