Add string input interrupt from STDIN

This commit is contained in:
2020-05-17 14:13:15 +02:00
parent 2d820e7028
commit fc2870ca74
5 changed files with 92 additions and 16 deletions

View File

@@ -137,5 +137,8 @@ the first argument
- `2` put value of register A as hexadecimal integer on stdout
- `3` put the string pointed at by register A for the amount of characters
defined by register B on stdout
- [4..4] Input from STDIN
- [4..5] Input from STDIN
- `4` get a single ASCII character from STDIN and store it in register A
- `5` get a string of a maximum length determined by register B and store it
in the address specified by register A. After execution register B will
contain the number of characters actually read.

View File

@@ -88,12 +88,22 @@ seti %A $900;
seti %B $4;
int $3;
# Jump over the interrupt
# Call a function
call noop_function;
# Echo a character
int $4;
int $0;
seti %A $10; # newline
int $0;
# Echo a string
seti %A $0;
seti %B $10;
int $5;
int $3;
exit;
noop_function:

View File

@@ -39,6 +39,12 @@ namespace Execute
InterruptIndexOutOfRange(int const index);
};
class OutOfMemory : public RuntimeError
{
public:
OutOfMemory(int const memoryLocation, int const memorySize);
};
namespace Internal
{
class BadValueType : public RuntimeError

View File

@@ -41,6 +41,15 @@ namespace Execute
message += " is out of range";
}
OutOfMemory::OutOfMemory(int const memoryLocation, int const memorySize)
{
message = "Attempted interaction at memory location ";
message += std::to_string(memoryLocation);
message += " with size ";
message += std::to_string(memorySize);
message += " failed";
}
namespace Internal
{
BadValueType::BadValueType()

View File

@@ -1,4 +1,5 @@
#include <cstdio>
#include <execute/error.hpp>
#include <execute/interrupts.hpp>
namespace Execute
@@ -18,6 +19,11 @@ namespace Execute
[](Execute::Registers & registers, std::vector<std::uint8_t> & memory)
{
unsigned const end = registers.A + registers.B;
if (end >= memory.size())
{
throw OutOfMemory(registers.A, registers.B);
}
for(unsigned i = registers.A; i < end; ++i)
{
std::putc(memory[i], stdout);
@@ -29,7 +35,49 @@ namespace Execute
[](Execute::Registers & registers, std::vector<std::uint8_t> & memory)
{
registers.A = std::getchar();
if (registers.A == '\n')
{
return;
}
while(std::getchar() != '\n');
},
// 11 get string from STDIN
[](Execute::Registers & registers, std::vector<std::uint8_t> & memory)
{
if (registers.B <= 0)
{
registers.B = 0;
return;
}
if (registers.A < 0 || static_cast<unsigned>(registers.A + registers.B) >= memory.size())
{
throw OutOfMemory(registers.A, registers.B);
}
int charactersRead = 0;
bool newlineRead = false;
while(charactersRead < registers.B)
{
char result = std::getchar();
if (result == '\n')
{
newlineRead = true;
break;
}
memory[registers.A + charactersRead] = result;
++charactersRead;
}
registers.B = charactersRead;
if (!newlineRead)
{
while(std::getchar() != '\n');
}
},
};
}
}