diff options
| Commit | fc647ed2ecf67355a13f09ff7e2c68b943691cf4 (patch) | |
|---|---|---|
| Author | 2018-11-11 21:49:25 +0200 | |
| Committer | 2018-11-11 21:49:38 +0200 | |
| Files | ed84295d8aff230c30e5f1daf2f120e79bebbef0 /spasm/src | |
| IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.tar IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.tar.gz IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.zip | ||
| Parent | 990a8f5e2c2d6e246acfd8b7a99ac1cbf4fb1675 (diff) | |
Removed data stack class
5 files changed, 60 insertions, 271 deletions
| -rw-r--r-- | spasm/src/dstack.cpp | 172 | ||||
| -rw-r--r-- | spasm/src/dstack.hpp | 46 | ||||
| -rw-r--r-- | spasm/src/spasm.cpp | 100 | ||||
| -rw-r--r-- | spasm/src/spasm_impl.hpp | 9 | ||||
| -rw-r--r-- | spasm/src/types.hpp | 4 |
diff --git a/spasm/src/dstack.cpp b/spasm/src/dstack.cpp deleted file mode 100644 index 93592ed..0000000 --- a/spasm/src/dstack.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "dstack.hpp" - -#include <algorithm> - -namespace SpasmImpl -{ -Dstack::Dstack() : bottom(NULL), tos(NULL), s_size(0) {} - -Dstack::Dstack(const Dstack& ds) : s_size(ds.s_size) -{ - copy_dstack(ds); -} - -Dstack& Dstack::operator=(const Dstack& ds) -{ - if (this != &ds) - { - if (bottom) - delete[] bottom; - s_size = ds.s_size; - copy_dstack(ds); - } - return *this; -} - -Dstack::~Dstack() -{ - if (bottom) - delete[] bottom; -} - -/** - * Makes the stack occupy new_size bytes - * \param new_size new size for the stack - */ -void Dstack::reserve(size_t new_size) -{ - size_t offset = tos - bottom; - byte* new_bottom = new byte[new_size]; - if (bottom) - { - std::copy(bottom, bottom + std::min(s_size, new_size), new_bottom); - delete[] bottom; - } - bottom = new_bottom; - tos = new_bottom + offset; - s_size = new_size; -} - -/*! -** Pushes x in the stack. -** If the stack is full its size is doubled. -** \param x data_t object to be pushed on the stack -*/ -void Dstack::push(data_t x) -{ - if (bottom + s_size < tos + sizeof(data_t)) - reserve((s_size ? s_size : sizeof(data_t)) * 2); - *((data_t*)tos) = x; - tos += sizeof(data_t); -} - -/*! -** Pushes the object of size x_size bytes pointed by x in the stack. -** If the stack is full its size is doubled (or more is x_size is greater -** than the size of the stack). -** \param x pointer to the element to be pushed on the stack -** \param x_size size of the element -*/ -void Dstack::push(byte* x, size_t x_size) -{ - if (bottom + s_size < tos + x_size) - reserve(s_size + ((s_size > x_size) ? s_size : x_size)); - std::copy(x, x + x_size, tos); - tos += x_size; -} - -/*! -** Pops an object of size x_size from the stack. -** The object is written to the place pointed by x. -** -** \param x pointer to the place for popping -** \param x_size size of the object to be popped -*/ -void Dstack::pop(void* x, size_t x_size) -{ - if (tos - x_size >= bottom) - { - std::copy(tos - x_size, tos, (byte*)x); - tos -= x_size; - } -} - -/*! -** \return a single data_t object, popping it from the stack. -*/ -data_t Dstack::pop() -{ - data_t x{}; - if (tos - sizeof(data_t) >= bottom) - { - tos -= sizeof(data_t); - x = *((data_t*)tos); - } - return x; -} - -/*! -** \return copy of the data_t object that is on top of the stack -*/ -data_t Dstack::top() const -{ - data_t x{}; - if (tos - sizeof(data_t) >= bottom) - { - x = *((data_t*)(tos - sizeof(data_t))); - } - return x; -} - -/*! -** \return the size of the stack in bytes -*/ -size_t Dstack::size() const -{ - return tos - bottom; -} - -/*! -** \return the space reserved for the stack in bytes -*/ -size_t Dstack::reserved() const -{ - return s_size; -} - -/*! -** Frees unused memory. Note that it is not always possible because memory -** management is done with new / delete -*/ - -void Dstack::strip_memory() -{ - reserve(size()); -} - -/*! -** \return true if the stack is empty -*/ -bool Dstack::empty() const -{ - return tos - bottom == 0; -} - -/*! -** Creates a copy of ds -** -** \param ds data stack to be copied -*/ -void Dstack::copy_dstack(const Dstack& ds) -{ - if (ds.bottom) - { - bottom = new byte[ds.s_size]; - tos = bottom + (ds.tos - ds.bottom); - std::copy(ds.bottom, ds.tos, bottom); - } - else - bottom = tos = NULL; -} - -} // namespace SpasmImpl diff --git a/spasm/src/dstack.hpp b/spasm/src/dstack.hpp deleted file mode 100644 index 850b66b..0000000 --- a/spasm/src/dstack.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef DSTACK_HPP -#define DSTACK_HPP - -#include "types.hpp" - -namespace SpasmImpl -{ -//! class representing the data stack - -/*! The class is quite simple stack. It is byte-orientatied - every push -** and pop is done in bytes with no taking care of any byte order! -*/ -class Dstack -{ - public: - Dstack(); - Dstack(const Dstack&); - Dstack& operator=(const Dstack&); - ~Dstack(); - void push(data_t); - void push(byte*, size_t); - void pop(void*, size_t); - data_t pop(); - data_t top() const; - - void reserve(size_t); - void strip_memory(); - size_t size() const; - size_t reserved() const; - bool empty() const; - - private: - void copy_dstack(const Dstack&); - - //! pointer to the bottom of the stack - byte* bottom; - - //! pointer to the top of the stack - byte* tos; - - //! size of the stack in bytes - size_t s_size; -}; -} // namespace SpasmImpl - -#endif // #ifndef DSTACK_HPP diff --git a/spasm/src/spasm.cpp b/spasm/src/spasm.cpp index e67c975..857143f 100644 --- a/spasm/src/spasm.cpp +++ b/spasm/src/spasm.cpp @@ -1,10 +1,13 @@ #include <algorithm> #include <iostream> +#include <cassert> #include "spasm.hpp" namespace SpasmImpl { + + PC_t Spasm::op_size = 21; // Be sure the same number is on the previous and next lines Operation Spasm::operations[] = {NULL, @@ -105,16 +108,6 @@ void Spasm::deleteobj() } /*! -** Returns the dstack, so that it can be examined after execution -** -** \return const reference to the data stack -*/ -const Dstack& Spasm::get_dstack() const -{ - return data_stack; -} - -/*! ** Starts the machine. The machine stops if it reaches an invalid opcode ** or opcode 0 or the pc reaches beyond the end of the bytecode. */ @@ -139,7 +132,7 @@ void Spasm::run() void Spasm::push() { ++pc; - data_stack.push(*reinterpret_cast<data_t*>(bytecode + pc)); + push_data(*reinterpret_cast<data_t*>(bytecode + pc)); pc += sizeof(data_t) - 1; } @@ -148,7 +141,7 @@ void Spasm::push() */ void Spasm::pop() { - data_stack.pop(); + data_stack.pop_back(); } /*! @@ -156,7 +149,7 @@ void Spasm::pop() */ void Spasm::dup() { - data_stack.push(data_stack.top()); + push_data(data_stack.back()); } /*! @@ -167,7 +160,7 @@ void Spasm::read() { data_t x; *istr >> x; - data_stack.push(x); + push_data(x); } /*! @@ -176,7 +169,8 @@ void Spasm::read() */ void Spasm::print() { - *ostr << data_stack.pop(); + *ostr << data_stack.back(); + pop(); } /*! @@ -185,9 +179,9 @@ void Spasm::print() */ void Spasm::plus() { - data_t x, y = data_stack.pop(); - x = data_stack.pop(); - data_stack.push(x + y); + data_t x, y = pop_data(); + x = pop_data(); + push_data(x + y); } /*! @@ -196,9 +190,9 @@ void Spasm::plus() */ void Spasm::minus() { - data_t x, y = data_stack.pop(); - x = data_stack.pop(); - data_stack.push(x - y); + data_t x, y = pop_data(); + x = pop_data(); + push_data(x - y); } /*! @@ -207,9 +201,9 @@ void Spasm::minus() */ void Spasm::multiply() { - data_t x, y = data_stack.pop(); - x = data_stack.pop(); - data_stack.push(x * y); + data_t y = pop_data(), + x = pop_data(); + push_data(x * y); } /*! @@ -218,9 +212,9 @@ void Spasm::multiply() */ void Spasm::divide() { - data_t x, y = data_stack.pop(); - x = data_stack.pop(); - data_stack.push(x / y); + data_t y = pop_data(), + x = pop_data(); + push_data(x / y); } /*! @@ -229,9 +223,9 @@ void Spasm::divide() */ void Spasm::modulus() { - data_t x, y = data_stack.pop(); - x = data_stack.pop(); - data_stack.push(x % y); + data_t y = pop_data(), + x = pop_data(); + push_data(x % y); } /*! @@ -242,7 +236,7 @@ void Spasm::modulus() void Spasm::gotrue() { ++pc; - if (data_stack.pop()) + if (pop_data()) pc = *(reinterpret_cast<PC_t*>(bytecode + pc)) - 1; else pc += sizeof(size_t) - 1; @@ -256,7 +250,7 @@ void Spasm::gotrue() void Spasm::gofalse() { ++pc; - if (!data_stack.pop()) + if (!pop_data()) pc = *(reinterpret_cast<PC_t*>(bytecode + pc)) - 1; else pc += sizeof(size_t) - 1; @@ -278,12 +272,15 @@ void Spasm::go() */ void Spasm::call() { + assert(false && "not-implemented"); +#if 0 size_t fs; // new frame size return_stack.push(pc); // using the ++pc in run() - data_stack.pop(&fs, sizeof(fs)); - data_stack.pop(&pc, sizeof(pc)); + pop_data(&fs, sizeof(fs)); + pop_data(&pc, sizeof(pc)); frame.new_frame(fs); --pc; // the ++pc in run() +#endif } /*! @@ -303,10 +300,7 @@ void Spasm::ret() */ void Spasm::load() { - size_t offset; - - data_stack.pop(&offset, sizeof(offset)); - data_stack.push(frame[offset]); + assert(false && "not-implemented"); } /*! @@ -314,11 +308,7 @@ void Spasm::load() */ void Spasm::store() { - data_t value = data_stack.pop(); - size_t offset; - - data_stack.pop(&offset, sizeof(offset)); - frame[offset] = value; + assert(false && "not-implemented"); } /*! @@ -327,10 +317,10 @@ void Spasm::store() */ void Spasm::less() { - data_t y = data_stack.pop(); - data_t x = data_stack.pop(); + data_t y = pop_data(); + data_t x = pop_data(); - data_stack.push(x < y); + push_data(x < y); } /*! @@ -339,10 +329,22 @@ void Spasm::less() */ void Spasm::lesseq() { - data_t y = data_stack.pop(); - data_t x = data_stack.pop(); + data_t y = pop_data(); + data_t x = pop_data(); + + push_data(x <= y); +} + +data_t Spasm::pop_data() +{ + auto result = data_stack.back(); + data_stack.pop_back(); + return result; +} - data_stack.push(x <= y); +void Spasm::push_data(data_t data) +{ + data_stack.push_back(data); } } // namespace SpasmImpl diff --git a/spasm/src/spasm_impl.hpp b/spasm/src/spasm_impl.hpp index 78c5d08..7c4d8f7 100644 --- a/spasm/src/spasm_impl.hpp +++ b/spasm/src/spasm_impl.hpp @@ -3,7 +3,6 @@ #include <iostream> -#include "dstack.hpp" #include "frames.hpp" #include "types.hpp" @@ -29,8 +28,6 @@ class Spasm void run(); - const Dstack& get_dstack() const; - private: //! Operations (opcodes) of the machine static Operation operations[]; @@ -47,8 +44,9 @@ class Spasm //! bytecode of the program byte* bytecode; + typedef SPVector<data_t> DataStack; //! Data stack for arithmetic operations and control flow - Dstack data_stack; + DataStack data_stack; //! Return stack for the addresses of the returns Rstack_t return_stack; @@ -91,6 +89,9 @@ class Spasm // private method for copying and deleting an object void copybc(const Spasm&); void deleteobj(); + + data_t pop_data(); + void push_data(data_t); }; } // namespace SpasmImpl diff --git a/spasm/src/types.hpp b/spasm/src/types.hpp index 0d86cab..4a8606b 100644 --- a/spasm/src/types.hpp +++ b/spasm/src/types.hpp @@ -3,6 +3,7 @@ #include <cstdlib> #include <stack> +#include <vector> namespace SpasmImpl { @@ -13,5 +14,8 @@ typedef std::stack<PC_t> Rstack_t; class Spasm; typedef void (Spasm::*Operation)(); + +template <typename T> +using SPVector = std::vector<T>; } // namespace SpasmImpl #endif // ----- #ifndef TYPES_HPP |
