|
|
|
|
@@ -45,13 +45,19 @@ namespace Interpret
|
|
|
|
|
throw ExpectedRegister(token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddArithmeticArguments(ThreeArgumentStatement & statement, unsigned const operandIndex, std::vector<Token::Token> const & tokens)
|
|
|
|
|
void AddArithmeticArguments(ArithmeticStatement & statement, unsigned const operandIndex, std::vector<Token::Token> const & tokens)
|
|
|
|
|
{
|
|
|
|
|
statement.firstArgument = GetImmediateOrRegisterArgument(operandIndex + 1u, tokens);
|
|
|
|
|
statement.secondArgument = GetImmediateOrRegisterArgument(operandIndex + 2u, tokens);
|
|
|
|
|
statement.thirdArgument = GetRegisterArgument(operandIndex + 3u, tokens);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddLogicArguments(ControlFlowStatement & statement, unsigned const operandIndex, std::vector<Token::Token> const & tokens)
|
|
|
|
|
{
|
|
|
|
|
statement.firstArgument = GetImmediateOrRegisterArgument(operandIndex + 1u, tokens);
|
|
|
|
|
statement.secondArgument = GetImmediateOrRegisterArgument(operandIndex + 2u, tokens);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<Statement> ExtractStatement(unsigned const operandIndex, std::vector<Token::Token> const & tokens)
|
|
|
|
|
{
|
|
|
|
|
auto const & token = tokens[operandIndex];
|
|
|
|
|
@@ -59,8 +65,8 @@ namespace Interpret
|
|
|
|
|
{
|
|
|
|
|
case Token::OperandType::AddInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 + argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -70,8 +76,8 @@ namespace Interpret
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::SubtractInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 - argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -81,8 +87,8 @@ namespace Interpret
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::DivideInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 / argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -92,8 +98,8 @@ namespace Interpret
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::MultiplyInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 * argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -103,8 +109,8 @@ namespace Interpret
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::ShiftIntegerLeft:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 << argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -114,8 +120,8 @@ namespace Interpret
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::ShiftIntegerRight:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ThreeArgumentStatement>();
|
|
|
|
|
statement->function = [](Execute::Flags & flags, int argument1, int argument2, int & argument3)
|
|
|
|
|
auto statement = std::make_unique<ArithmeticStatement>();
|
|
|
|
|
statement->function = [](int argument1, int argument2, int & argument3)
|
|
|
|
|
{
|
|
|
|
|
argument3 = argument1 >> argument2;
|
|
|
|
|
};
|
|
|
|
|
@@ -133,6 +139,60 @@ namespace Interpret
|
|
|
|
|
return std::make_unique<JumpStatement>(std::get<std::string>(labelToken.data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::LessThanInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ControlFlowStatement>();
|
|
|
|
|
statement->function = [](Execute::State & state, int argument1, int argument2)
|
|
|
|
|
{
|
|
|
|
|
if (argument1 < argument2)
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 1u;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 2u;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
AddLogicArguments(*statement, operandIndex, tokens);
|
|
|
|
|
return statement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::GreaterThanInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ControlFlowStatement>();
|
|
|
|
|
statement->function = [](Execute::State & state, int argument1, int argument2)
|
|
|
|
|
{
|
|
|
|
|
if (argument1 > argument2)
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 1u;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 2u;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
AddLogicArguments(*statement, operandIndex, tokens);
|
|
|
|
|
return statement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::EqualInteger:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<ControlFlowStatement>();
|
|
|
|
|
statement->function = [](Execute::State & state, int argument1, int argument2)
|
|
|
|
|
{
|
|
|
|
|
if (argument1 == argument2)
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 1u;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state.nextStatement = state.currentStatement + 2u;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
AddLogicArguments(*statement, operandIndex, tokens);
|
|
|
|
|
return statement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
auto statement = std::make_unique<NoArgumentStatement>();
|
|
|
|
|
@@ -155,6 +215,11 @@ namespace Interpret
|
|
|
|
|
case Token::OperandType::ShiftIntegerRight:
|
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::LessThanInteger:
|
|
|
|
|
case Token::OperandType::GreaterThanInteger:
|
|
|
|
|
case Token::OperandType::EqualInteger:
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
|
|
case Token::OperandType::Jump:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|