Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src
diff options
context:
space:
mode:
Commitfc647ed2ecf67355a13f09ff7e2c68b943691cf4 (patch)
Author
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-11 21:49:25 +0200
Committer
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-11 21:49:38 +0200
Filesed84295d8aff230c30e5f1daf2f120e79bebbef0 /spasm/src
IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.tar
IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.tar.gz
IPL-fc647ed2ecf67355a13f09ff7e2c68b943691cf4.zip
Parent990a8f5e2c2d6e246acfd8b7a99ac1cbf4fb1675 (diff)
Removed data stack class
5 files changed, 60 insertions, 271 deletions
-rw-r--r--spasm/src/dstack.cpp172
-rw-r--r--spasm/src/dstack.hpp46
-rw-r--r--spasm/src/spasm.cpp100
-rw-r--r--spasm/src/spasm_impl.hpp9
-rw-r--r--spasm/src/types.hpp4
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