Add exit operand
This commit is contained in:
@@ -91,9 +91,7 @@ int $3;
|
|||||||
# Jump over the interrupt
|
# Jump over the interrupt
|
||||||
call noop_function;
|
call noop_function;
|
||||||
int $3;
|
int $3;
|
||||||
jmp the_real_exit;
|
exit;
|
||||||
|
|
||||||
noop_function:
|
noop_function:
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
the_real_exit:
|
|
||||||
@@ -13,6 +13,7 @@ namespace Execute
|
|||||||
std::vector<InterruptFn> const interrupts;
|
std::vector<InterruptFn> const interrupts;
|
||||||
std::vector<std::uint8_t> memory;
|
std::vector<std::uint8_t> memory;
|
||||||
unsigned stackPointer;
|
unsigned stackPointer;
|
||||||
|
bool terminated;
|
||||||
|
|
||||||
State(std::unordered_map<std::string, unsigned> const & labelStatementIndice, unsigned const memorySize);
|
State(std::unordered_map<std::string, unsigned> const & labelStatementIndice, unsigned const memorySize);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ namespace Interpret
|
|||||||
void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override;
|
void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ExitProgramStatement : Statement
|
||||||
|
{
|
||||||
|
void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override;
|
||||||
|
};
|
||||||
|
|
||||||
struct SetStatement : Statement
|
struct SetStatement : Statement
|
||||||
{
|
{
|
||||||
Value firstArgument;
|
Value firstArgument;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace Token
|
|||||||
Jump,
|
Jump,
|
||||||
CallFunction,
|
CallFunction,
|
||||||
ReturnFromFunction,
|
ReturnFromFunction,
|
||||||
|
ExitProgram,
|
||||||
LessThanInteger,
|
LessThanInteger,
|
||||||
GreaterThanInteger,
|
GreaterThanInteger,
|
||||||
EqualInteger,
|
EqualInteger,
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ namespace Execute
|
|||||||
labelStatementIndice(_labelStatementIndice),
|
labelStatementIndice(_labelStatementIndice),
|
||||||
interrupts(GetInterrupts()),
|
interrupts(GetInterrupts()),
|
||||||
memory(memorySize),
|
memory(memorySize),
|
||||||
stackPointer(0u)
|
stackPointer(0u),
|
||||||
|
terminated(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.currentStatement = state.nextStatement;
|
state.currentStatement = state.nextStatement;
|
||||||
if (state.currentStatement >= code.statements.size())
|
if (state.currentStatement >= code.statements.size() || state.terminated)
|
||||||
{
|
{
|
||||||
terminated = true;
|
terminated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,6 +170,11 @@ namespace Interpret
|
|||||||
return std::make_unique<ReturnFromFunctionStatement>();
|
return std::make_unique<ReturnFromFunctionStatement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Token::OperandType::ExitProgram:
|
||||||
|
{
|
||||||
|
return std::make_unique<ExitProgramStatement>();
|
||||||
|
}
|
||||||
|
|
||||||
case Token::OperandType::LessThanInteger:
|
case Token::OperandType::LessThanInteger:
|
||||||
{
|
{
|
||||||
auto statement = std::make_unique<ControlFlowStatement>();
|
auto statement = std::make_unique<ControlFlowStatement>();
|
||||||
@@ -316,6 +321,7 @@ namespace Interpret
|
|||||||
default:
|
default:
|
||||||
std::printf("WARNING: returning default argument length of 0 for operand type %i\n", static_cast<int>(type));
|
std::printf("WARNING: returning default argument length of 0 for operand type %i\n", static_cast<int>(type));
|
||||||
case Token::OperandType::ReturnFromFunction:
|
case Token::OperandType::ReturnFromFunction:
|
||||||
|
case Token::OperandType::ExitProgram:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,11 @@ namespace Interpret
|
|||||||
state.stackPointer -= sizeof(unsigned);
|
state.stackPointer -= sizeof(unsigned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExitProgramStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
|
{
|
||||||
|
state.terminated = true;
|
||||||
|
}
|
||||||
|
|
||||||
void SetStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
void SetStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
{
|
{
|
||||||
firstArgument.GetValue(state, registers) = secondArgument.GetValue(state, registers);
|
firstArgument.GetValue(state, registers) = secondArgument.GetValue(state, registers);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Token
|
|||||||
{ "jmp", OperandType::Jump },
|
{ "jmp", OperandType::Jump },
|
||||||
{ "call", OperandType::CallFunction },
|
{ "call", OperandType::CallFunction },
|
||||||
{ "ret", OperandType::ReturnFromFunction },
|
{ "ret", OperandType::ReturnFromFunction },
|
||||||
|
{ "exit", OperandType::ExitProgram },
|
||||||
{ "lti", OperandType::LessThanInteger },
|
{ "lti", OperandType::LessThanInteger },
|
||||||
{ "gti", OperandType::GreaterThanInteger },
|
{ "gti", OperandType::GreaterThanInteger },
|
||||||
{ "eqi", OperandType::EqualInteger },
|
{ "eqi", OperandType::EqualInteger },
|
||||||
|
|||||||
Reference in New Issue
Block a user