From 06de5290da63ec7effe27a923ccf1ac56cc13865 Mon Sep 17 00:00:00 2001 From: Tijmen van Nesselrooij Date: Sun, 17 May 2020 13:28:59 +0200 Subject: [PATCH] Add STDIN interrupt and error handling for all interrupts --- bin/test.wasm | 5 ++++- include/execute/error.hpp | 6 ++++++ src/execute/error.cpp | 7 +++++++ src/execute/interrupts.cpp | 8 ++++++++ src/interpret/statement.cpp | 8 +++++++- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bin/test.wasm b/bin/test.wasm index 5deeb94..1e6ed42 100644 --- a/bin/test.wasm +++ b/bin/test.wasm @@ -90,7 +90,10 @@ int $3; # Jump over the interrupt call noop_function; -int $3; + +# Echo a character +int $4; +int $0; exit; noop_function: diff --git a/include/execute/error.hpp b/include/execute/error.hpp index 5e899d6..590358c 100644 --- a/include/execute/error.hpp +++ b/include/execute/error.hpp @@ -33,6 +33,12 @@ namespace Execute MissingLabel(std::string const & label); }; + class InterruptIndexOutOfRange : public RuntimeError + { + public: + InterruptIndexOutOfRange(int const index); + }; + namespace Internal { class BadValueType : public RuntimeError diff --git a/src/execute/error.cpp b/src/execute/error.cpp index b4876b2..5c39726 100644 --- a/src/execute/error.cpp +++ b/src/execute/error.cpp @@ -34,6 +34,13 @@ namespace Execute message += '"'; } + InterruptIndexOutOfRange::InterruptIndexOutOfRange(int const index) + { + message = "Interrupt index "; + message += std::to_string(index); + message += " is out of range"; + } + namespace Internal { BadValueType::BadValueType() diff --git a/src/execute/interrupts.cpp b/src/execute/interrupts.cpp index 325b4e6..867fed9 100644 --- a/src/execute/interrupts.cpp +++ b/src/execute/interrupts.cpp @@ -7,6 +7,7 @@ namespace Execute { return std::vector { + /* STDOUT INTERRUPTS */ // 0 print char [](Execute::Registers & registers, std::vector & memory) { std::putc(registers.A, stdout); }, // 1 print decimal integer @@ -21,6 +22,13 @@ namespace Execute { std::putc(memory[i], stdout); } + }, + + /* STDIN INTERRUPTS */ + // 10 get char from STDIN + [](Execute::Registers & registers, std::vector & memory) + { + registers.A = std::getchar(); } }; } diff --git a/src/interpret/statement.cpp b/src/interpret/statement.cpp index bd9b789..1a39720 100644 --- a/src/interpret/statement.cpp +++ b/src/interpret/statement.cpp @@ -89,7 +89,13 @@ namespace Interpret void InterruptStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) { - state.interrupts[firstArgument.GetValue(state, registers)](registers, state.memory); + auto const interruptIndex = firstArgument.GetValue(state, registers); + if (interruptIndex < 0 || static_cast(interruptIndex) > state.interrupts.size()) + { + throw Execute::InterruptIndexOutOfRange(interruptIndex); + } + + state.interrupts[interruptIndex](registers, state.memory); } void PopStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)