<commit_before>/*
 * Assembler file
 * 
 * This file is part of the "XieXie 2.0 Project" (Copyright (c) 2014 by <NAME>)
 * See "LICENSE.txt" for license information.
 */

#include "Assembler.h"
#include "Console.h"
#include "StringModifier.h"

#include <exception>

#include "VirtualMachine/XVMWrapper.h"
//#define _REMOVE_XVM_TESTSUITE_
//#include "VirtualMachine/xvm.c"


namespace XieXie
{


using namespace VirtualMachine;

Assembler::Assembler() :
    byteCode_   ( std::make_shared< ByteCode   >() ),
    intrinsics_ ( std::make_shared< Intrinsics >() )
{
    EstablishMnemonicTable();
}

bool Assembler::AssembleFile(const std::string& inFilename, const std::string& outFilename)
{
    /* Read and parse input file */
    std::ifstream inFile(inFilename, std::ios_base::in);

    if (!inFile.good())
    {
        Console::Error("reading file \"" + inFilename + "\" failed");
        return false;
    }

    /* Initialize parsing */
    line_.clear();
    lineIt_ = line_.end();

    sourceArea_.Reset();

    /* Read first line */
    try
    {
        ReadNextLine(inFile);
    }
    catch (const CompilerMessage& err)
    {
        errorReporter_.Add(err);
    }

    /* Read entire input file */
    while (!inFile.eof())
    {
        try
        {
            /* Read and parse next line */
            ReadNextLine(inFile);
            ParseLine();

            /* Check if line is finished */
            if (tkn_.type != Token::Types::__Unknown__)
                Error("trailing line not allowed after instruction");
        }
        catch (const CompilerMessage& err)
        {
            errorReporter_.Add(err);
        }
        catch (const std::exception& err)
        {
            errorReporter_.Add(AssemblerError(sourceArea_, err.what()));
        }
    }

    /* Resolve back-patch addresses */
    for (auto& patchAddr : backPatchAddresses_)
    {
        try
        {
            ResolveBackPatchAddress(patchAddr.first, patchAddr.second);
        }
        catch (const CompilerMessage& err)
        {
            errorReporter_.Add(err);
        }
    }

    /* Prints errors */
    bool hasErrors = errorReporter_.HasErrors();

    errorReporter_.Flush();

    if (hasErrors)
        return false;

    /* Write byte code to file */
    return CreateByteCode(outFilename);
}


/*
 * ======= Private: =======
 */

void Assembler::EstablishMnemonicTable()
{
    mnemonicTable_ = std::move(std::map<std::string, InstrCategory>
    {
        { "mov",  { InstrCategory::Categories::Reg2,    OPCODE_MOV2, OPCODE_MOV1  } },
        { "not",  { InstrCategory::Categories::Reg2,    OPCODE_NOT2, 0u           } },
        { "and",  { InstrCategory::Categories::Reg2,    OPCODE_AND2, OPCODE_AND1  } },
        { "or",   { InstrCategory::Categories::Reg2,    OPCODE_OR2,  OPCODE_OR1   } },
        { "xor",  { InstrCategory::Categories::Reg2,    OPCODE_XOR2, OPCODE_XOR1  } },
        { "add",  { InstrCategory::Categories::Reg2,    OPCODE_ADD2, OPCODE_ADD1  } },
        { "sub",  { InstrCategory::Categories::Reg2,    OPCODE_SUB2, OPCODE_SUB1  } },
        { "mul",  { InstrCategory::Categories::Reg2,    OPCODE_MUL2, OPCODE_MUL1  } },
        { "div",  { InstrCategory::Categories::Reg2,    OPCODE_DIV2, OPCODE_DIV1  } },
        { "mod",  { InstrCategory::Categories::Reg2,    OPCODE_MOD2, OPCODE_MOD1  } },
        { "sll",  { InstrCategory::Categories::Reg2,    OPCODE_SLL2, OPCODE_SLL1  } },
        { "slr",  { InstrCategory::Categories::Reg2,    OPCODE_SLR2, OPCODE_SLR1  } },
        { "cmp",  { InstrCategory::Categories::Reg2,    OPCODE_CMP,  0u           } },
        { "fti",  { InstrCategory::Categories::Reg2,    OPCODE_FTI,  0u           } },
        { "itf",  { InstrCategory::Categories::Reg2,    OPCODE_ITF,  0u           } },
        { "pop",  { InstrCategory::Categories::Reg1,    OPCODE_POP,  0u           } },
        { "inc",  { InstrCategory::Categories::Reg1,    OPCODE_INC,  0u           } },
        { "dec",  { InstrCategory::Categories::Reg1,    OPCODE_DEC,  0u           } },
        { "jmp",  { InstrCategory::Categories::Jump,    OPCODE_JMP,  0u           } },
        { "je",   { InstrCategory::Categories::Jump,    OPCODE_JE,   0u           } },
        { "jne",  { InstrCategory::Categories::Jump,    OPCODE_JNE,  0u           } },
        { "jg",   { InstrCategory::Categories::Jump,    OPCODE_JG,   0u           } },
        { "jl",   { InstrCategory::Categories::Jump,    OPCODE_JL,   0u           } },
        { "jge",  { InstrCategory::Categories::Jump,    OPCODE_JGE,  0u           } },
        { "jle",  { InstrCategory::Categories::Jump,    OPCODE_JLE,  0u           } },
        { "call", { InstrCategory::Categories::Jump,    OPCODE_CALL, 0u           } },
        { "addf", { InstrCategory::Categories::Float,   OPCODE_ADDF, 0u           } },
        { "subf", { InstrCategory::Categories::Reg2,    OPCODE_SUBF, 0u           } },
        { "mulf", { InstrCategory::Categories::Float,   OPCODE_MULF, 0u           } },
        { "divf", { InstrCategory::Categories::Float,   OPCODE_DIVF, 0u           } },
        { "cmpf", { InstrCategory::Categories::Float,   OPCODE_CMPF, 0u           } },
        { "lda",  { InstrCategory::Categories::Mem,     OPCODE_LDA,  0u           } },
        { "ldb",  { InstrCategory::Categories::MemOff,  OPCODE_LDB,  0u           } },
        { "ldw",  { InstrCategory::Categories::MemOff,  OPCODE_LDW,  0u           } },
        { "stb",  { InstrCategory::Categories::MemOff,  OPCODE_STB,  0u           } },
        { "stw",  { InstrCategory::Categories::MemOff,  OPCODE_STW,  0u           } },
        { "push", { InstrCategory::Categories::Special, OPCODE_PUSH, OPCODE_PUSHC } },
        { "stop", { InstrCategory::Categories::Special, OPCODE_STOP, 0u           } },
        { "ret",  { InstrCategory::Categories::Special, OPCODE_RET,  0u           } },
        { "invk", { InstrCategory::Categories::Special, OPCODE_INVK, 0u           } },
    });
}

void Assembler::Error(const std::string& message, bool appendSourceArea)
{
    if (appendSourceArea)
        throw AssemblerError(sourceArea_, message);
    else
        throw AssemblerError(message);
}<commit_msg>- Bug fix: "subf" instruction was created with wrong XVM function.<commit_after>/*
 * Assembler file
 * 
 * This file is part of the "XieXie 2.0 Project" (Copyright (c) 2014 by <NAME>)
 * See "LICENSE.txt" for license information.
 */

#include "Assembler.h"
#include "Console.h"
#include "StringModifier.h"

#include <exception>

#include "VirtualMachine/XVMWrapper.h"
//#define _REMOVE_XVM_TESTSUITE_
//#include "VirtualMachine/xvm.c"


namespace XieXie
{


using namespace VirtualMachine;

Assembler::Assembler() :
    byteCode_   ( std::make_shared< ByteCode   >() ),
    intrinsics_ ( std::make_shared< Intrinsics >() )
{
    EstablishMnemonicTable();
}

bool Assembler::AssembleFile(const std::string& inFilename, const std::string& outFilename)
{
    /* Read and parse input file */
    std::ifstream inFile(inFilename, std::ios_base::in);

    if (!inFile.good())
    {
        Console::Error("reading file \"" + inFilename + "\" failed");
        return false;
    }

    /* Initialize parsing */
    line_.clear();
    lineIt_ = line_.end();

    sourceArea_.Reset();

    /* Read first line */
    try
    {
        ReadNextLine(inFile);
    }
    catch (const CompilerMessage& err)
    {
        errorReporter_.Add(err);
    }

    /* Read entire input file */
    while (!inFile.eof())
    {
        try
        {
            /* Read and parse next line */
            ReadNextLine(inFile);
            ParseLine();

            /* Check if line is finished */
            if (tkn_.type != Token::Types::__Unknown__)
                Error("trailing line not allowed after instruction");
        }
        catch (const CompilerMessage& err)
        {
            errorReporter_.Add(err);
        }
        catch (const std::exception& err)
        {
            errorReporter_.Add(AssemblerError(sourceArea_, err.what()));
        }
    }

    /* Resolve back-patch addresses */
    for (auto& patchAddr : backPatchAddresses_)
    {
        try
        {
            ResolveBackPatchAddress(patchAddr.first, patchAddr.second);
        }
        catch (const CompilerMessage& err)
        {
            errorReporter_.Add(err);
        }
    }

    /* Prints errors */
    bool hasErrors = errorReporter_.HasErrors();

    errorReporter_.Flush();

    if (hasErrors)
        return false;

    /* Write byte code to file */
    return CreateByteCode(outFilename);
}


/*
 * ======= Private: =======
 */

void Assembler::EstablishMnemonicTable()
{
    mnemonicTable_ = std::move(std::map<std::string, InstrCategory>
    {
        { "mov",  { InstrCategory::Categories::Reg2,    OPCODE_MOV2, OPCODE_MOV1  } },
        { "not",  { InstrCategory::Categories::Reg2,    OPCODE_NOT2, 0u           } },
        { "and",  { InstrCategory::Categories::Reg2,    OPCODE_AND2, OPCODE_AND1  } },
        { "or",   { InstrCategory::Categories::Reg2,    OPCODE_OR2,  OPCODE_OR1   } },
        { "xor",  { InstrCategory::Categories::Reg2,    OPCODE_XOR2, OPCODE_XOR1  } },
        { "add",  { InstrCategory::Categories::Reg2,    OPCODE_ADD2, OPCODE_ADD1  } },
        { "sub",  { InstrCategory::Categories::Reg2,    OPCODE_SUB2, OPCODE_SUB1  } },
        { "mul",  { InstrCategory::Categories::Reg2,    OPCODE_MUL2, OPCODE_MUL1  } },
        { "div",  { InstrCategory::Categories::Reg2,    OPCODE_DIV2, OPCODE_DIV1  } },
        { "mod",  { InstrCategory::Categories::Reg2,    OPCODE_MOD2, OPCODE_MOD1  } },
        { "sll",  { InstrCategory::Categories::Reg2,    OPCODE_SLL2, OPCODE_SLL1  } },
        { "slr",  { InstrCategory::Categories::Reg2,    OPCODE_SLR2, OPCODE_SLR1  } },
        { "cmp",  { InstrCategory::Categories::Reg2,    OPCODE_CMP,  0u           } },
        { "fti",  { InstrCategory::Categories::Reg2,    OPCODE_FTI,  0u           } },
        { "itf",  { InstrCategory::Categories::Reg2,    OPCODE_ITF,  0u           } },
        { "pop",  { InstrCategory::Categories::Reg1,    OPCODE_POP,  0u           } },
        { "inc",  { InstrCategory::Categories::Reg1,    OPCODE_INC,  0u           } },
        { "dec",  { InstrCategory::Categories::Reg1,    OPCODE_DEC,  0u           } },
        { "jmp",  { InstrCategory::Categories::Jump,    OPCODE_JMP,  0u           } },
        { "je",   { InstrCategory::Categories::Jump,    OPCODE_JE,   0u           } },
        { "jne",  { InstrCategory::Categories::Jump,    OPCODE_JNE,  0u           } },
        { "jg",   { InstrCategory::Categories::Jump,    OPCODE_JG,   0u           } },
        { "jl",   { InstrCategory::Categories::Jump,    OPCODE_JL,   0u           } },
        { "jge",  { InstrCategory::Categories::Jump,    OPCODE_JGE,  0u           } },
        { "jle",  { InstrCategory::Categories::Jump,    OPCODE_JLE,  0u           } },
        { "call", { InstrCategory::Categories::Jump,    OPCODE_CALL, 0u           } },
        { "addf", { InstrCategory::Categories::Float,   OPCODE_ADDF, 0u           } },
        { "subf", { InstrCategory::Categories::Float,   OPCODE_SUBF, 0u           } },
        { "mulf", { InstrCategory::Categories::Float,   OPCODE_MULF, 0u           } },
        { "divf", { InstrCategory::Categories::Float,   OPCODE_DIVF, 0u           } },
        { "cmpf", { InstrCategory::Categories::Float,   OPCODE_CMPF, 0u           } },
        { "lda",  { InstrCategory::Categories::Mem,     OPCODE_LDA,  0u           } },
        { "ldb",  { InstrCategory::Categories::MemOff,  OPCODE_LDB,  0u           } },
        { "ldw",  { InstrCategory::Categories::MemOff,  OPCODE_LDW,  0u           } },
        { "stb",  { InstrCategory::Categories::MemOff,  OPCODE_STB,  0u           } },
        { "stw",  { InstrCategory::Categories::MemOff,  OPCODE_STW,  0u           } },
        { "push", { InstrCategory::Categories::Special, OPCODE_PUSH, OPCODE_PUSHC } },
        { "stop", { InstrCategory::Categories::Special, OPCODE_STOP, 0u           } },
        { "ret",  { InstrCategory::Categories::Special, OPCODE_RET,  0u           } },
        { "invk", { InstrCategory::Categories::Special, OPCODE_INVK, 0u           } },
    });
}

void Assembler::Error(const std::string& message, bool appendSourceArea)
{
    if (appendSourceArea)
        throw AssemblerError(sourceArea_, message);
    else
        throw AssemblerError(message);
}
{'fraction_non_alphanumeric': 0.1468903767040413, 'fraction_numerical': 0.012180366217633298, 'mean_word_length': 2.2833686440677967, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '399233', 'n_tokens_mistral': 4247, 'n_tokens_neox': 4060, 'n_words': 688}