I do a fort compiler in C ++ , faced with the problem of implementing a common for int and char[] stack. Tell me how best to implement a common stack?

  • 2
    By char [] do you understand variable-length strings? Well, no one will hurt you to keep the length of what you pushed into the stack, even though it will be expensive. - gbg
  • Hm Are you sure that if such questions arise, you should already write a compiler? - VladD
  • 2
    On the subject of the question: wrap in a structure that contains the data type. Keep a pointer to this structure on the stack. Or use boost::any . - VladD
  • Questions arise because I study. I'll try boost :: any, thanks for the hint - j0hn
  • one
    The fort is the simplest conceptual - Dmitry Ponyatov

1 answer 1

There are at least two options:

  1. C-approach:

     typedef struct ForthType { enum { INT; FLOAT; PTR; STR; BYTECODE; ... } type; // тэг Ρ‚ΠΈΠΏΠ° union { // Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π² памяти ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² ΠΎΠ΄Π½ΠΈΡ… адрСсах int i; float f; void *p; char *s; ... } } D[Dsz]; int Dp=0; #define PUSH(X) { D[Dp++]=X; } #define POP(X) (D[--Dp]) 
  2. C ++: generalizing the task - a heterogeneous container is required that can store arbitrary data types (for example, a list in Python or Lisp). Implemented through

    1. type tree inherited from a single ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎΠ³ΠΎ base class
    2. any STL containers store pointers to the base class Base*
    3. all work with objects needs to be implemented through Base* , the definition of a specific type, typeid(Base*number) and dymanic_cast<Int*>(number)->...
 struct Base { virtual ~Base(); // для Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° // 1+ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция // ΠΏΠΎ классикС: [пустой] Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ дСструктор virtual string dot(); // для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π½ΡƒΠΆΠ½Π° // своя рСализация слова <Ρ‚ΠΎΡ‡ΠΊΠ°> string val; // строка -- ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π΄Π°Π½Π½Ρ‹Ρ…: // Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² тСкстовом Π²ΠΈΠ΄Π΅, // Π² частности ΠΈΠΌΠ΅Π½Π° слов vector<Base*> bytecode; // понадобится ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π½Π΅ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ // опрСдСлСния слов virtual add(Base*); // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π°Π·ΠΎΠ²ΠΎΠΉ Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΠΈ virtual sub(Base*); virtual mul(Base*); virtual div(Base*); ... }; 

Data stack:

 stack<Base*> DataStack; // (!!!) Ρ…Ρ€Π°Π½ΠΈΠΌ Π½Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Π½ΠΈΡ… 

Stack of returns:

 stack<Base*> ReturnStack; 

Dictionaries

 struct Vocabulary:Base; Vocabulary FORTH("FORTH",NULL); struct Vocabulary:Base { Vocabulary(string name,Vocabulary*next=&FORTH); Vocabulary* next; // для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π΅Ρ€Π΅Π²Π° словарСй для поиска map<string,Base*> words; // Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ Base* Find(string); // функция рСкурсивного поиска words/*next }; Vocabulary FORTH; 

We inherit the types we want to work with:

Integers (only numbers, not addresses):

 struct Int: Base { int val; // (!) ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Int(std::string); Int(int); string dot(); // конструкторы ΠΈ Π΄Π°ΠΌΠΏ int add(Base*); int sub(Base*); ... }; // вычислСния 

At one time, there was a terrible lack of a floating point, and the float / str (1) encoding / decoding words, even had to intXXh hang a resident calculator written in TurboC (1) for calculations it was elementary to use the FPU stack)

 struct Float: Base { float val ; // (!) ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Float(string); Float(float); string dot(); ... }; 

Pointers

 struct Ptr: Base { Ptr(void*); void *val; };