0

I am making a toy programming language in c++, but i have run into a problem. I have noticed that in c++ a stack can only store one type of data. I was wondering if there was an easy way to fix this problem, such as by storing in the stack a byte array of each object. I was wondering if anyone knows how the jvm overcomes this issue. The types i would need to store on the stack would be char, short, int, float, double, strings, arrays, and references to objects. I understand that the jvm stack might be more of an abstraction, but if it is i would still like to know how they have accomplished it. If it makes any difference, i am only planning to target windows computers.

4
  • 3
    C++ can do that with a std::stack<boost::variant<...>>. Commented Oct 21, 2013 at 23:17
  • 2
    Typically, in most languages, this is solved by storing MORE than just the data itself. Such as a "type identifcation" (e.g. an enum) on the stack. Commented Oct 21, 2013 at 23:17
  • how can i use boost with visual studio express Commented Oct 21, 2013 at 23:17
  • how would i store more than data itself, because i cant create a generic object in c++, especially, how would i store different dimensional arrays and such Commented Oct 21, 2013 at 23:19

3 Answers 3

3

You know C++ has support for inheritance and polymorphism, right? A far easier way to do this is to derive all your tokens from a common base class, and make a stack of Base * objects, for instance:

#include <iostream>
#include <string>
#include <stack>
#include <memory>

class base {
    public:
        virtual void print_token() = 0;
        virtual ~base() {}
};

class token_a : public base {
    public:
        token_a(int n) : n(n) {}
        virtual void print_token() { std::cout << n << std::endl; }

    private:
        int n;
};

class token_b : public base {
    public:
        token_b(std::string s) : s(s) {}
        virtual void print_token() { std::cout << s << std::endl; }

    private:
        std::string s;
};

int main(void) {
    std::stack<std::shared_ptr<base> > my_stack;
    my_stack.push(std::shared_ptr<base>(new token_a(5)));
    my_stack.push(std::shared_ptr<base>(new token_b("a word")));

    for ( int i = 0; i < 2; ++i ) {
        std::shared_ptr<base> pb = my_stack.top();
        pb->print_token();
        my_stack.pop();
    }

    return 0;
}

outputs:

paul@local:~/src/cpp/scratch$ ./stack
a word
5
paul@local:~/src/cpp/scratch$
Sign up to request clarification or add additional context in comments.

Comments

2

The way I have solved this problem (in C, for a lisp interpretr, about 25 years ago, but same idea applies today) is to have a struct with a type and a union inside it:

struct Data   // or class
{
    enum kind { floatkind, intkind, stringkind, refkind };
    Kind kind;
    union
    {
       double f;
       int i;
       std::string s;
       Data* r;     // reference, can't use Data &r without heavy trickery. 
    } u;

    Data(double d) { kind = floatkind; u.f = d; }
    Data(int i) { kind = intkind; u.i = i; }
    ... 
}

std::stack<Data> st;

st.push(Data(42));
st.push(Data(3.14));

Comments

0

Just a guess, but the jvm probably treats everything as an object, so the stack is simply a collection of objects.

You can do the same, if you create a base data object class and derive all your supported data types from it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.