Memory added plus basic memory operations
This commit is contained in:
@@ -53,6 +53,10 @@ All symbols are reserved keywords and can therefore NOT be used as labels.
|
|||||||
|
|
||||||
## Symbols
|
## Symbols
|
||||||
|
|
||||||
|
## Directives
|
||||||
|
|
||||||
|
- `DECLARE` declares the first label argument to equal the second, immediate value, argument and is used to declare a constant for the virtual machine.
|
||||||
|
|
||||||
### Operands
|
### Operands
|
||||||
|
|
||||||
- `addi` add the first to the second argument and store the result in the third argument
|
- `addi` add the first to the second argument and store the result in the third argument
|
||||||
@@ -71,6 +75,11 @@ All symbols are reserved keywords and can therefore NOT be used as labels.
|
|||||||
- `gti` execute next statement if argument 1 is greater than argument 2 else skip the next statement
|
- `gti` execute next statement if argument 1 is greater than argument 2 else skip the next statement
|
||||||
- `eqi` execute the next statement if argument 1 is equal to argument 2 else skip the next statement
|
- `eqi` execute the next statement if argument 1 is equal to argument 2 else skip the next statement
|
||||||
|
|
||||||
|
## Memory
|
||||||
|
|
||||||
|
- `popi` pops the first value on the stack into the register specified as the first argument
|
||||||
|
- `pushi` pushes the value on the stack from the register or immediate value as the first argument
|
||||||
|
|
||||||
## Interupts
|
## Interupts
|
||||||
|
|
||||||
- 0..9 range:
|
- 0..9 range:
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
DECLARE MEMORY_SIZE $4096;
|
||||||
|
|
||||||
addi $10 $-5 %A;
|
addi $10 $-5 %A;
|
||||||
subi %A $2 %B;
|
subi %A $2 %B;
|
||||||
muli $2 %B %C;
|
muli $2 %B %C;
|
||||||
@@ -7,7 +9,7 @@ divi $2 %C %D;
|
|||||||
seti %A $0;
|
seti %A $0;
|
||||||
|
|
||||||
# Loop from 0 to 10
|
# Loop from 0 to 10
|
||||||
loop:
|
count_loop:
|
||||||
addi $1 %A %A;
|
addi $1 %A %A;
|
||||||
|
|
||||||
# Print the current value
|
# Print the current value
|
||||||
@@ -18,7 +20,7 @@ int $0;
|
|||||||
seti %A %B;
|
seti %A %B;
|
||||||
|
|
||||||
lti %A $10;
|
lti %A $10;
|
||||||
jmp loop;
|
jmp count_loop;
|
||||||
|
|
||||||
# Hello world
|
# Hello world
|
||||||
seti %A $72; # H
|
seti %A $72; # H
|
||||||
@@ -31,5 +33,24 @@ int $0;
|
|||||||
seti %A $111; # o
|
seti %A $111; # o
|
||||||
int $0;
|
int $0;
|
||||||
|
|
||||||
|
seti %A $32; # space
|
||||||
|
int $0;
|
||||||
|
|
||||||
|
pushi $68; # D
|
||||||
|
pushi $76; # L
|
||||||
|
pushi $82; # R
|
||||||
|
pushi $79; # O
|
||||||
|
pushi $87; # W
|
||||||
|
|
||||||
|
seti %B $5;
|
||||||
|
|
||||||
|
world_loop:
|
||||||
|
popi %A;
|
||||||
|
int $0;
|
||||||
|
|
||||||
|
subi %B $1 %B;
|
||||||
|
gti %B $0;
|
||||||
|
jmp world_loop;
|
||||||
|
|
||||||
seti %A $10; # newline
|
seti %A $10; # newline
|
||||||
int $0;
|
int $0;
|
||||||
19
include/execute/error.hpp
Normal file
19
include/execute/error.hpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Execute
|
||||||
|
{
|
||||||
|
struct RuntimeError
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StackUnderflow : RuntimeError
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StackOverflow : RuntimeError
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -11,7 +11,9 @@ namespace Execute
|
|||||||
unsigned nextStatement;
|
unsigned nextStatement;
|
||||||
std::unordered_map<std::string, unsigned> const & labelStatementIndice;
|
std::unordered_map<std::string, unsigned> const & labelStatementIndice;
|
||||||
std::vector<InterruptFn> const interrupts;
|
std::vector<InterruptFn> const interrupts;
|
||||||
|
std::vector<std::uint8_t> memory;
|
||||||
|
unsigned stackPointer;
|
||||||
|
|
||||||
State(std::unordered_map<std::string, unsigned> const & labelStatementIndice);
|
State(std::unordered_map<std::string, unsigned> const & labelStatementIndice, unsigned const memorySize);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,8 @@ namespace Execute
|
|||||||
|
|
||||||
void Step();
|
void Step();
|
||||||
|
|
||||||
|
VirtualMachine(Interpret::Code const & code, unsigned const memorySize);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Run();
|
void Run();
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
@@ -28,6 +30,6 @@ namespace Execute
|
|||||||
|
|
||||||
bool IsTerminated() const;
|
bool IsTerminated() const;
|
||||||
|
|
||||||
VirtualMachine(Interpret::Code const & code);
|
static VirtualMachine CreateFromCode(Interpret::Code const & code);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -11,5 +11,6 @@ namespace Interpret
|
|||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<Statement>> statements;
|
std::vector<std::unique_ptr<Statement>> statements;
|
||||||
std::unordered_map<std::string, unsigned> labelStatementIndice;
|
std::unordered_map<std::string, unsigned> labelStatementIndice;
|
||||||
|
std::unordered_map<std::string, int> declarations;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,7 @@ namespace Interpret
|
|||||||
{
|
{
|
||||||
std::unique_ptr<Statement> ExtractStatement(unsigned const operatorIndex, std::vector<Token::Token> const & tokens);
|
std::unique_ptr<Statement> ExtractStatement(unsigned const operatorIndex, std::vector<Token::Token> const & tokens);
|
||||||
|
|
||||||
|
std::tuple<std::string, int> ExtractDeclaration(unsigned const operatorIndex, std::vector<Token::Token> const & tokens);
|
||||||
|
|
||||||
int GetRequiredNumberOfArguments(Token::OperandType const type);
|
int GetRequiredNumberOfArguments(Token::OperandType const type);
|
||||||
}
|
}
|
||||||
@@ -69,4 +69,18 @@ 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 PushStatement : Statement
|
||||||
|
{
|
||||||
|
Value firstArgument;
|
||||||
|
|
||||||
|
void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PopStatement : Statement
|
||||||
|
{
|
||||||
|
Value firstArgument;
|
||||||
|
|
||||||
|
void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,10 @@ namespace Token
|
|||||||
GreaterThanInteger,
|
GreaterThanInteger,
|
||||||
EqualInteger,
|
EqualInteger,
|
||||||
SetInteger,
|
SetInteger,
|
||||||
Interrupt
|
Interrupt,
|
||||||
|
Declaration,
|
||||||
|
PushInteger,
|
||||||
|
PopInteger
|
||||||
};
|
};
|
||||||
|
|
||||||
OperandType GetOperandType(std::string const & op);
|
OperandType GetOperandType(std::string const & op);
|
||||||
|
|||||||
6
src/execute/error.cpp
Normal file
6
src/execute/error.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <execute/error.hpp>
|
||||||
|
|
||||||
|
namespace Execute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
State::State(std::unordered_map<std::string, unsigned> const & _labelStatementIndice)
|
State::State(std::unordered_map<std::string, unsigned> const & _labelStatementIndice, unsigned const memorySize)
|
||||||
: currentStatement(0u),
|
: currentStatement(0u),
|
||||||
nextStatement(1u),
|
nextStatement(1u),
|
||||||
labelStatementIndice(_labelStatementIndice),
|
labelStatementIndice(_labelStatementIndice),
|
||||||
interrupts(GetInterrupts())
|
interrupts(GetInterrupts()),
|
||||||
|
memory(memorySize),
|
||||||
|
stackPointer(0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,15 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VirtualMachine::VirtualMachine(Interpret::Code const & _code, unsigned const memorySize)
|
||||||
|
: flags(),
|
||||||
|
registers(),
|
||||||
|
state(_code.labelStatementIndice, memorySize),
|
||||||
|
terminated(false),
|
||||||
|
code(_code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualMachine::Run()
|
void VirtualMachine::Run()
|
||||||
{
|
{
|
||||||
while(!IsTerminated())
|
while(!IsTerminated())
|
||||||
@@ -41,12 +50,16 @@ namespace Execute
|
|||||||
|
|
||||||
bool VirtualMachine::IsTerminated() const { return terminated; }
|
bool VirtualMachine::IsTerminated() const { return terminated; }
|
||||||
|
|
||||||
VirtualMachine::VirtualMachine(Interpret::Code const & _code)
|
VirtualMachine VirtualMachine::CreateFromCode(Interpret::Code const & code)
|
||||||
: flags(),
|
|
||||||
registers(),
|
|
||||||
state(_code.labelStatementIndice),
|
|
||||||
terminated(false),
|
|
||||||
code(_code)
|
|
||||||
{
|
{
|
||||||
|
unsigned memorySize = 1024;
|
||||||
|
auto const & userMemorySizeDeclared = code.declarations.find("MEMORY_SIZE");
|
||||||
|
if (userMemorySizeDeclared != code.declarations.end() && userMemorySizeDeclared->second >= 0)
|
||||||
|
{
|
||||||
|
memorySize = userMemorySizeDeclared->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::printf("Creating Wassembly virtual machine with %u bytes of memory.\n", memorySize);
|
||||||
|
return VirtualMachine(code, memorySize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,19 @@ namespace Interpret
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code.statements.emplace_back(ExtractStatement(operatorTokenIndex, tokens));
|
switch(std::get<Token::OperandType>(tokens[operatorTokenIndex].data))
|
||||||
|
{
|
||||||
|
case Token::OperandType::Declaration:
|
||||||
|
{
|
||||||
|
auto const tuple = ExtractDeclaration(operatorTokenIndex, tokens);
|
||||||
|
code.declarations[std::get<0>(tuple)] = std::get<1>(tuple);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
code.statements.emplace_back(ExtractStatement(operatorTokenIndex, tokens));
|
||||||
|
break;
|
||||||
|
}
|
||||||
state = InterpreterState::FindOperand;
|
state = InterpreterState::FindOperand;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -210,6 +210,22 @@ namespace Interpret
|
|||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Token::OperandType::PopInteger:
|
||||||
|
{
|
||||||
|
auto statement = std::make_unique<PopStatement>();
|
||||||
|
statement->firstArgument = GetRegisterArgument(operandIndex + 1u, tokens);
|
||||||
|
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Token::OperandType::PushInteger:
|
||||||
|
{
|
||||||
|
auto statement = std::make_unique<PushStatement>();
|
||||||
|
statement->firstArgument = GetImmediateOrRegisterArgument(operandIndex + 1u, tokens);
|
||||||
|
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto statement = std::make_unique<NoArgumentStatement>();
|
auto statement = std::make_unique<NoArgumentStatement>();
|
||||||
@@ -221,6 +237,22 @@ namespace Interpret
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<std::string, int> ExtractDeclaration(unsigned const operatorIndex, std::vector<Token::Token> const & tokens)
|
||||||
|
{
|
||||||
|
if (tokens[operatorIndex + 1u].type != Token::TokenType::Label)
|
||||||
|
{
|
||||||
|
throw ExpectedLabel(tokens[operatorIndex + 1u]);
|
||||||
|
}
|
||||||
|
if (tokens[operatorIndex + 2u].type != Token::TokenType::ImmediateInteger)
|
||||||
|
{
|
||||||
|
throw ExpectedImmediate(tokens[operatorIndex + 2u]);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const label = std::get<std::string>(tokens[operatorIndex + 1u].data);
|
||||||
|
auto const value = std::get<int>(tokens[operatorIndex + 2u].data);
|
||||||
|
return std::make_tuple(label, value);
|
||||||
|
}
|
||||||
|
|
||||||
int GetRequiredNumberOfArguments(Token::OperandType const type)
|
int GetRequiredNumberOfArguments(Token::OperandType const type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -237,10 +269,13 @@ namespace Interpret
|
|||||||
case Token::OperandType::GreaterThanInteger:
|
case Token::OperandType::GreaterThanInteger:
|
||||||
case Token::OperandType::EqualInteger:
|
case Token::OperandType::EqualInteger:
|
||||||
case Token::OperandType::SetInteger:
|
case Token::OperandType::SetInteger:
|
||||||
|
case Token::OperandType::Declaration:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case Token::OperandType::Jump:
|
case Token::OperandType::Jump:
|
||||||
case Token::OperandType::Interrupt:
|
case Token::OperandType::Interrupt:
|
||||||
|
case Token::OperandType::PushInteger:
|
||||||
|
case Token::OperandType::PopInteger:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <execute/error.hpp>
|
||||||
#include <interpret/statement.hpp>
|
#include <interpret/statement.hpp>
|
||||||
|
|
||||||
namespace Interpret
|
namespace Interpret
|
||||||
@@ -49,4 +50,29 @@ namespace Interpret
|
|||||||
{
|
{
|
||||||
state.interrupts[firstArgument.GetValue(registers)](registers);
|
state.interrupts[firstArgument.GetValue(registers)](registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
|
{
|
||||||
|
if (state.stackPointer < sizeof(int))
|
||||||
|
{
|
||||||
|
throw Execute::StackUnderflow();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const value = *(reinterpret_cast<int const *>(state.memory.data() + (state.stackPointer - 1u)));
|
||||||
|
firstArgument.GetValue(registers) = value;
|
||||||
|
|
||||||
|
state.stackPointer -= sizeof(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
|
{
|
||||||
|
if ((state.memory.size() - state.stackPointer) < sizeof(int))
|
||||||
|
{
|
||||||
|
throw Execute::StackOverflow();
|
||||||
|
}
|
||||||
|
|
||||||
|
*(reinterpret_cast<int *>(state.memory.data() + state.stackPointer + (sizeof(int) - 1))) = firstArgument.GetValue(registers);
|
||||||
|
|
||||||
|
state.stackPointer += sizeof(int);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
100
src/main.cpp
100
src/main.cpp
@@ -24,35 +24,8 @@ void PrintTokenError(Interpret::TokenError const & err, std::vector<std::string>
|
|||||||
PrintBadToken(err.errorToken, lines);
|
PrintBadToken(err.errorToken, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
void PrintTokens(std::vector<Token::Token> const & tokens)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
|
||||||
{
|
|
||||||
std::puts("Usage: wassembly [filename.wasm]");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream input(argv[1]);
|
|
||||||
if (!input.is_open())
|
|
||||||
{
|
|
||||||
std::printf("Error: Cannot open file %s for reading", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Token::Token> tokens;
|
|
||||||
Token::Tokenizer tokenizer;
|
|
||||||
std::vector<std::string> lines; // DEBUG
|
|
||||||
std::string line;
|
|
||||||
unsigned lineNumber = 0;
|
|
||||||
while(std::getline(input, line))
|
|
||||||
{
|
|
||||||
tokenizer.Tokenize(line, lineNumber, tokens);
|
|
||||||
++lineNumber;
|
|
||||||
lines.push_back(line); // DEBUG
|
|
||||||
}
|
|
||||||
input.close();
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
std::puts("*** Tokenization result ***");
|
std::puts("*** Tokenization result ***");
|
||||||
unsigned statementNumber = 0u;
|
unsigned statementNumber = 0u;
|
||||||
std::printf("%02u - ", statementNumber);
|
std::printf("%02u - ", statementNumber);
|
||||||
@@ -73,7 +46,38 @@ int main(int argc, char ** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// END DEBUG
|
}
|
||||||
|
|
||||||
|
void PrintLabels(Interpret::Code const & code)
|
||||||
|
{
|
||||||
|
std::puts("\n*** Labels ***");
|
||||||
|
for(auto const & labelIndice : code.labelStatementIndice)
|
||||||
|
{
|
||||||
|
std::printf("Label %s points to statement %u\n", labelIndice.first.c_str(), labelIndice.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Interpret::Code GetCodeFromFile(std::string const & filePath)
|
||||||
|
{
|
||||||
|
std::ifstream input(filePath);
|
||||||
|
if (!input.is_open())
|
||||||
|
{
|
||||||
|
std::printf("Error: Cannot open file %s for reading", filePath.c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Token::Token> tokens;
|
||||||
|
Token::Tokenizer tokenizer;
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::string line;
|
||||||
|
unsigned lineNumber = 0;
|
||||||
|
while(std::getline(input, line))
|
||||||
|
{
|
||||||
|
tokenizer.Tokenize(line, lineNumber, tokens);
|
||||||
|
++lineNumber;
|
||||||
|
lines.push_back(line);
|
||||||
|
}
|
||||||
|
input.close();
|
||||||
|
|
||||||
// Validate the syntax
|
// Validate the syntax
|
||||||
bool syntaxOk = true;
|
bool syntaxOk = true;
|
||||||
@@ -90,7 +94,7 @@ int main(int argc, char ** argv)
|
|||||||
if (!syntaxOk)
|
if (!syntaxOk)
|
||||||
{
|
{
|
||||||
std::puts("Aborting due to syntax error(s)");
|
std::puts("Aborting due to syntax error(s)");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Interpret::Interpreter interpreter;
|
Interpret::Interpreter interpreter;
|
||||||
@@ -102,33 +106,23 @@ int main(int argc, char ** argv)
|
|||||||
catch(Interpret::TokenError & e)
|
catch(Interpret::TokenError & e)
|
||||||
{
|
{
|
||||||
PrintTokenError(e, lines);
|
PrintTokenError(e, lines);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
std::puts("Usage: wassembly [filename.wasm]");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG
|
auto const code = GetCodeFromFile(argv[1]);
|
||||||
std::puts("\n*** Labels ***");
|
auto vm = Execute::VirtualMachine::CreateFromCode(code);
|
||||||
for(auto const & labelIndice : code.labelStatementIndice)
|
|
||||||
{
|
|
||||||
std::printf("Label %s points to statement %u\n", labelIndice.first.c_str(), labelIndice.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::puts("\n*** Execution ***");
|
|
||||||
Execute::VirtualMachine vm(code);
|
|
||||||
vm.Run();
|
vm.Run();
|
||||||
/*
|
|
||||||
while(!vm.IsTerminated())
|
|
||||||
{
|
|
||||||
vm.SingleStep();
|
|
||||||
auto const & registers = vm.GetRegisters();
|
|
||||||
std::printf("A=%i B=%i C=%i D=%i\n", registers.A, registers.B, registers.C, registers.D);
|
|
||||||
auto const & state = vm.GetState();
|
|
||||||
std::printf("current_statement=%i\n", state.currentStatement);
|
|
||||||
|
|
||||||
std::puts("Press any key to step...");
|
|
||||||
std::getchar();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// END DEBUG
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,10 @@ namespace Token
|
|||||||
{ "gti", OperandType::GreaterThanInteger },
|
{ "gti", OperandType::GreaterThanInteger },
|
||||||
{ "eqi", OperandType::EqualInteger },
|
{ "eqi", OperandType::EqualInteger },
|
||||||
{ "seti", OperandType::SetInteger },
|
{ "seti", OperandType::SetInteger },
|
||||||
{ "int", OperandType::Interrupt }
|
{ "int", OperandType::Interrupt },
|
||||||
|
{ "DECLARE", OperandType::Declaration },
|
||||||
|
{ "pushi", OperandType::PushInteger},
|
||||||
|
{ "popi", OperandType::PopInteger},
|
||||||
};
|
};
|
||||||
|
|
||||||
auto const & result = operations.find(op);
|
auto const & result = operations.find(op);
|
||||||
|
|||||||
Reference in New Issue
Block a user