Add call operand
This commit is contained in:
@@ -5,9 +5,9 @@ namespace Execute
|
||||
void VirtualMachine::Step()
|
||||
{
|
||||
state.nextStatement = state.currentStatement + 1u;
|
||||
|
||||
|
||||
code.statements[state.currentStatement]->Execute(flags, state, registers);
|
||||
|
||||
|
||||
state.currentStatement = state.nextStatement;
|
||||
if (state.currentStatement >= code.statements.size())
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace Execute
|
||||
return code.statements[state.currentStatement].get();
|
||||
}
|
||||
|
||||
bool VirtualMachine::IsTerminated() const { return terminated; }
|
||||
bool VirtualMachine::IsTerminated() const { return terminated; }
|
||||
|
||||
VirtualMachine VirtualMachine::CreateFromCode(Interpret::Code const & code)
|
||||
{
|
||||
|
||||
@@ -150,9 +150,21 @@ namespace Interpret
|
||||
{
|
||||
throw ExpectedLabel(labelToken);
|
||||
}
|
||||
|
||||
return std::make_unique<JumpStatement>(std::get<std::string>(labelToken.data));
|
||||
}
|
||||
|
||||
case Token::OperandType::CallFunction:
|
||||
{
|
||||
auto labelToken = tokens[operandIndex + 1u];
|
||||
if (labelToken.type != Token::TokenType::Label)
|
||||
{
|
||||
throw ExpectedLabel(labelToken);
|
||||
}
|
||||
|
||||
return std::make_unique<FunctionCallStatement>(std::get<std::string>(labelToken.data));
|
||||
}
|
||||
|
||||
case Token::OperandType::LessThanInteger:
|
||||
{
|
||||
auto statement = std::make_unique<ControlFlowStatement>();
|
||||
@@ -243,9 +255,12 @@ namespace Interpret
|
||||
default:
|
||||
{
|
||||
auto statement = std::make_unique<NoArgumentStatement>();
|
||||
|
||||
|
||||
// TODO throw error?
|
||||
statement->function = [](Execute::Flags & flags, Execute::Registers & registers) { std::puts("ExtractStatement: Extracted unhandled operator type"); };
|
||||
statement->function = [](Execute::Flags & flags, Execute::Registers & registers)
|
||||
{
|
||||
std::puts("ExtractStatement: Extracted unhandled operator type");
|
||||
};
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
@@ -287,6 +302,7 @@ namespace Interpret
|
||||
return 2;
|
||||
|
||||
case Token::OperandType::Jump:
|
||||
case Token::OperandType::CallFunction:
|
||||
case Token::OperandType::Interrupt:
|
||||
case Token::OperandType::PushInteger:
|
||||
case Token::OperandType::PopInteger:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <execute/error.hpp>
|
||||
#include <interpret/statement.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Interpret
|
||||
{
|
||||
@@ -41,6 +42,30 @@ namespace Interpret
|
||||
{
|
||||
}
|
||||
|
||||
void FunctionCallStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||
{
|
||||
auto const & elem = state.labelStatementIndice.find(label);
|
||||
if (elem == state.labelStatementIndice.end())
|
||||
{
|
||||
throw std::runtime_error("Attempted call nonexisting function (missing label)");
|
||||
}
|
||||
|
||||
if ((state.memory.size() - state.stackPointer) < sizeof(unsigned))
|
||||
{
|
||||
throw Execute::StackOverflow();
|
||||
}
|
||||
|
||||
*(reinterpret_cast<unsigned *>(state.memory.data() + state.stackPointer + (sizeof(unsigned) - 1))) = state.nextStatement;
|
||||
|
||||
state.stackPointer += sizeof(int);
|
||||
state.nextStatement = elem->second;
|
||||
}
|
||||
|
||||
FunctionCallStatement::FunctionCallStatement(std::string const & _label)
|
||||
: label(_label)
|
||||
{
|
||||
}
|
||||
|
||||
void SetStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||
{
|
||||
firstArgument.GetValue(state, registers) = secondArgument.GetValue(state, registers);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Token
|
||||
{ "shri", OperandType::ShiftIntegerRight },
|
||||
{ "shli", OperandType::ShiftIntegerLeft },
|
||||
{ "jmp", OperandType::Jump },
|
||||
{ "call", OperandType::CallFunction },
|
||||
{ "lti", OperandType::LessThanInteger },
|
||||
{ "gti", OperandType::GreaterThanInteger },
|
||||
{ "eqi", OperandType::EqualInteger },
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace Token
|
||||
: lineNumber(other.lineNumber),
|
||||
lineColumn(other.lineColumn),
|
||||
type(other.type),
|
||||
isValid(other.isValid),
|
||||
valueType(other.valueType),
|
||||
isValid(other.isValid),
|
||||
data(other.data)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <token/tokenizer.hpp>
|
||||
|
||||
namespace Token
|
||||
|
||||
Reference in New Issue
Block a user