2014-02-11 11:26:28 +01:00
|
|
|
#ifndef __stack_h__
|
|
|
|
#define __stack_h__
|
|
|
|
|
2014-02-12 11:26:26 +01:00
|
|
|
#include <string.h>
|
2022-02-07 16:36:27 +01:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <deque>
|
2014-02-11 11:26:28 +01:00
|
|
|
#include <map>
|
|
|
|
|
2022-02-07 16:36:27 +01:00
|
|
|
#include "object.hpp"
|
|
|
|
using namespace std;
|
2014-02-11 11:26:28 +01:00
|
|
|
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @brief stack object, parens of program, storing execution stack values or programs
|
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
class rpnstack : public deque<object*> {
|
2018-08-12 15:06:04 +02:00
|
|
|
public:
|
2022-02-07 16:36:27 +01:00
|
|
|
rpnstack() {}
|
2022-02-12 19:11:22 +01:00
|
|
|
virtual ~rpnstack() {
|
|
|
|
for_each(begin(), end(), [](object* o) { delete o; });
|
|
|
|
erase(begin(), end());
|
|
|
|
}
|
2017-05-02 10:47:03 +02:00
|
|
|
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @brief copy a whole stack entry and push it back to another stack
|
|
|
|
///
|
|
|
|
/// @param from copy from
|
|
|
|
/// @param index_from index t ocopy from
|
|
|
|
/// @param to copy to
|
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
static void copy_and_push_front(rpnstack& from, unsigned int index_from, rpnstack& to) {
|
2022-02-12 19:11:22 +01:00
|
|
|
// carefull: caller must ensure that index_from is correct
|
|
|
|
auto newObj = from[index_from]->clone();
|
|
|
|
if (newObj != nullptr)
|
|
|
|
to.push_front(newObj);
|
2018-08-12 15:06:04 +02:00
|
|
|
}
|
|
|
|
|
2022-02-11 14:00:15 +01:00
|
|
|
/// @brief erase a stack entry from it index
|
|
|
|
///
|
|
|
|
/// @param first index to start
|
|
|
|
/// @param last index to stop
|
|
|
|
///
|
|
|
|
void del(int first = 0, int last = -1) {
|
2022-02-12 19:11:22 +01:00
|
|
|
if (size() > 0) {
|
2022-02-11 14:00:15 +01:00
|
|
|
if (last == -1)
|
|
|
|
erase(begin() + first);
|
|
|
|
else if (last >= first)
|
|
|
|
erase(begin() + first, begin() + last + 1); // carefull, deque::erase doesn't include the last element
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-12 19:11:22 +01:00
|
|
|
/// @brief pop front several entries
|
2018-08-13 00:15:20 +02:00
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
/// @param levels nb of entries
|
2018-08-13 00:15:20 +02:00
|
|
|
///
|
2022-02-12 19:11:22 +01:00
|
|
|
void pop_front(int levels, bool del = true) {
|
|
|
|
for (int i = 0; i < levels; i++) {
|
|
|
|
if (del)
|
|
|
|
delete deque::front();
|
|
|
|
deque::pop_front();
|
|
|
|
}
|
2017-04-22 00:29:50 +02:00
|
|
|
}
|
2015-05-19 17:51:03 +02:00
|
|
|
|
2022-02-12 19:11:22 +01:00
|
|
|
/// @brief pop front 1 entry
|
2018-08-13 00:15:20 +02:00
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
/// @return retrieved object
|
2018-08-13 00:15:20 +02:00
|
|
|
///
|
2022-02-11 14:00:15 +01:00
|
|
|
object* pop_front() {
|
|
|
|
object* o = front();
|
|
|
|
pop_front(1);
|
2022-02-07 16:36:27 +01:00
|
|
|
return o;
|
2018-08-12 15:06:04 +02:00
|
|
|
}
|
2022-02-12 19:11:22 +01:00
|
|
|
|
|
|
|
// access helpers
|
|
|
|
cmd_type_t type(int level) {
|
|
|
|
// carefull: caller must ensure that level is correct
|
|
|
|
return at(level)->_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class objectType> auto obj(int level) {
|
|
|
|
// carefull: caller must ensure that level is correct
|
|
|
|
return static_cast<objectType*>(at(level));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class objectType> auto& value(int level) {
|
|
|
|
// carefull: caller must ensure that level is correct
|
|
|
|
return static_cast<objectType*>(at(level))->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pop() {
|
|
|
|
(void)rpnstack::pop_front(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void push(object* o) {
|
|
|
|
deque<object*>::push_front(o);
|
|
|
|
}
|
2018-08-12 11:50:49 +02:00
|
|
|
};
|
2017-04-21 17:40:01 +02:00
|
|
|
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @brief heap object, storing variables (=named object)
|
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
class heap : public map<string, object*> {
|
2018-08-12 15:06:04 +02:00
|
|
|
public:
|
|
|
|
heap() {}
|
|
|
|
virtual ~heap() {}
|
|
|
|
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @brief get a variable
|
2022-02-07 16:36:27 +01:00
|
|
|
///
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @param name the variable name
|
|
|
|
/// @param obj the variable content
|
|
|
|
/// @return true the variable was found
|
|
|
|
/// @return false the variable was not found
|
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
bool get(const string name, object*& obj) {
|
2018-08-12 15:06:04 +02:00
|
|
|
bool ret = false;
|
2022-02-07 16:36:27 +01:00
|
|
|
auto i = find(name);
|
|
|
|
if (i != end()) {
|
|
|
|
obj = i->second;
|
2018-08-12 15:06:04 +02:00
|
|
|
ret = true;
|
|
|
|
}
|
|
|
|
return ret;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
2018-08-12 15:06:04 +02:00
|
|
|
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @brief get a variable by its index in heap
|
2022-02-07 16:36:27 +01:00
|
|
|
///
|
2018-08-13 00:15:20 +02:00
|
|
|
/// @param num the variable index
|
|
|
|
/// @param name the variable name
|
|
|
|
/// @param obj the variable content
|
|
|
|
/// @return true the variable was found
|
|
|
|
/// @return false the variable was not found
|
|
|
|
///
|
2022-02-07 16:36:27 +01:00
|
|
|
bool get_by_index(int num, string& name, object*& obj) {
|
|
|
|
if (num >= 0 && num < (int)size()) {
|
2018-08-12 15:06:04 +02:00
|
|
|
object* local;
|
2022-02-07 16:36:27 +01:00
|
|
|
auto i = begin();
|
|
|
|
for (; num > 0; num--, i++)
|
|
|
|
;
|
|
|
|
obj = i->second;
|
2018-08-12 15:06:04 +02:00
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-11 11:26:28 +01:00
|
|
|
};
|
|
|
|
|
2018-08-12 11:50:49 +02:00
|
|
|
#endif // __stack_h__
|