1. Computer problem? Tech Support Guy is completely free -- paid for by advertisers and donations. Click here to join today! If you're new to Tech Support Guy, we highly recommend that you visit our Guide for New Members.

Solved: Debugging Portable Numbers Format Interpreter

Discussion in 'Software Development' started by des000, Dec 1, 2013.

Thread Status:
Not open for further replies.
Advertisement
  1. des000

    des000 Thread Starter

    Joined:
    May 29, 2008
    Messages:
    295
    I'm trying to debug my new language that I'm in the process of creating. It's written in C++. I'm currently stuck on why it's code would produce a loop that would print my error message over and over, infinitely.

    main.cpp
    Code:
    #include "../pnf.hpp"
    
    
    int main(int argc, char ** argv)
    {
     if (argc < 2)
     {
      error(ERROR, "Wrong Arguments.");
      return -1;
     }
    
      if (argc >= 2)
      {
       PNF program(argc, argv);
        
        
       program.load();
       program.loads2();
       program.check();
       int ret = program.execute();
    
    
       return ret;
      }
      else
       error(ERROR, "Program Not Found.");
    }
    

    pnf.hpp
    Code:
    #include <deslib/deslib.hpp>
    #include <cstdlib>
    #include <cmath>
    #include <stack>
    #include <cctype>
    
    /*
     IVERSION   - Switches versions. It's not possible to switch versions yet, because it's the first version.
                  VERSION TVOID 0V
    
     IVOID      - Does nothing.
                  VOID TVOID 0V
    
     ICRASH     - Intentional crash of program.
                  CRASH TSTRING [string]
    
     IQUIT      - Quits the program. Returns return value.
                  QUIT TVOID [return value]
    
     IHALT      - Halts the system by entering a forever loop.
                  HALT TVOID 0V
    
     IPRINT     - Prints the specified value or the contents of the accumulator.
                  PRINT TVOID 0V
                  PRINT TBOOLEAN [data]
                  PRINT TNUMBER [data]
                  PRINT TCHARACTER [data]
                  PRINT TSTRING [data]
    
     IPRINTLN   - Prints the specified value or the contents of the accumulator,
                  then a newline.
                  PRINTLN TVOID 0V
                  PRINTLN TBOOLEAN [data]
                  PRINTLN TNUMBER [data]
                  PRINTLN TCHARACTER [data]
                  PRINTLN TSTRING [data]
    
     IREAD      - Reads in a value to the accumulator.
                  READ [type] 0V
    
     ILOAD      - Loads a value from memory into the accumulator.
                  LOAD [type] [address]
    
     ISTORE     - Stores the contents of the accumulator at the specified memory
                  location.
                  STORE TVOID [address]
    
     ILOADC     - Loads a value from memory into the %calc register.
                  LOADC [type] [address]
    
     ISTOREC    - Stores the contents of the %calc register into the specified
                  memory location.
                  STOREC TVOID [address]
    
     IESTORE    - Stores the contents of %accumulator into [%varcount].
                  ESTORE TVOID 0V
    
     IESTOREC    - Stores the contents of %calc into [%varcount].
                   ESTOREC TVOID 0V
    
     IVLOAD      - Gets a variable from variable location %operand, and stores it in
                   %accumulator.
                   VLOAD [type] [Variable Address]
    
     IVSTORE     - Stores a new variable from %accumulator to the next location.
                   VSTORE TVOID 0V
    
     IVLOADC     - Gets a variable from variable location %operand, and stores it in
                   %calc.
                   VLOADC [type] [Variable Address]
    
     IVSTOREC    - Stores a new variable from %calc to the next location.
                   VSTOREC TVOID 0V
    
     IMODT       - Modifies the type of %accumulator.
                   MODT [type] 0V
    
     IMODCT      - Modifies the type of %calc.
                   MODCT [type] 0V
    
     IADD       - Adds %calc or other value to %accumulator.
                  ADD TVOID 0V
                  ADD TNUMBER [data]
                  ADD TCHARACTER [data]
                  ADD TSTRING [data]
    
     ISUB       - Subtracts %calc from %accumulator.
                  SUB VOID 0
                  SUB TNUMBER [data]
    
     IMUL       - Multiplies %accumulator and %calc.
                  MUL VOID 0
                  MUL TNUMBER [data]
    
     IDIV       - Divides %calc by %accumulator.
                  DIV VOID 0
                  DIV TNUMBER [data]
    
     IMOD       - Takes a modulus of %accumulator and %calc.
                  MOD VOID 0
                  MOD TNUMBER [data]
    
     IPOW       - Raises %accumulator to the power of %calc.
                  POW VOID 0
                  POW TNUMBER [data]
    
     ISQRT      - Takes the square root of %accumulator.
                  SQRT VOID 0
                  SQRT TNUMBER [data]
    
     IINC       - Increments %accumulator.
                  INC TVOID 0V
    
     IDEC       - Decrements %accumulator.
                  DEC TVOID 0V
    
     IEQU       - Tests if %accumulator == %calc.
                  EQU TVOID 0V
                  EQU TBOOLEAN [data]
                  EQU TNUMBER [data]
                  EQU TCHARACTER [data]
    
     INEQU      - Tests if %accumulator != %calc.
                  NEQU TVOID 0V
                  NEQU TBOOLEAN [data]
                  NEQU TNUMBER [data]
                  NEQU TCHARACTER [data]
    
     IGTR       - Tests if %accumulator > %calc.
                  GTR TVOID 0V
                  GTR TNUMBER [data]
                  GTR TCHARACTER [data]
    
     ILSS       - Tests if %accumulator < %calc.
                  LSS TVOID 0V
                  LSS TNUMBER [data]
                  LSS TCHARACTER [data]
    
     IGEQU       - Tests if %accumulator >= %calc.
                   GEQU TVOID 0V
                   GEQU TNUMBER [data]
                   GEQU TCHARACTER [data]
    
     ILEQU       - Tests if %accumulator <= %calc.
                   LEQU TVOID 0V
                   LEQU TNUMBER [data]
                   LEQU TCHARACTER [data]
    
     IAND        - %accumulator && %calc
                   AND TVOID 0V
    
     IOR         - %accumulator || %calc
                   OR TVOID 0V
    
     INOT        - !(%accumulator)
                   NOT TVOID 0V
    
     IGOTO      - Go to the memory address specified and continue running the
                  program from there.
                  GOTO TVOID [memory address]
    
     ICGOTO      - Go to the memory address specified and continue running the
                  program from there if %accumulator equals true.
                  CGOTO TVOID [memory address]
    
     IZGOTO     - Go to the memory address specified if %accumulator is 0.
                  ZGOTO TVOID [memory address]
    
     IPGOTO     - Go to the memory address specified if %accumulator is > 0.
                  PGOTO TVOID [memory address]
    
     INGOTO     - Go to the memory address specified if %accumulator is < 0.
                  NGOTO TVOID [memory address]
    
     IGOTOL      - Go to the label specified and continue running the
                   program from there.
                   GOTO TVOID [label]
    
     ICGOTOL      - Go to the label specified and continue running the
                    program from there if %accumulator equals true.
                    CGOTO TVOID [label]
    
     IZGOTOL     - Go to the label specified if %accumulator is 0.
                   ZGOTO TVOID [label]
    
     IPGOTOL     - Go to the memory address specified if %accumulator is > 0.
                   PGOTO TVOID [label]
    
     INGOTOL     - Go to the label specified if %accumulator is < 0.
                   NGOTO TVOID [label]
    
     IST        - Sets %accumulator to 0 if %calc is 0. (Used for loops.)
                  ST TVOID 0V
    
     IPUSH      - Put the accumulator on the stack.
                  PUSH TVOID 0V
    
     IPOP       - Loads a value into the accumulator from the stack.
                  POP TVOID 0V
    
     ICALL      - Calls a subroutine that begins at [memory address].
                  CALL TVOID [memory address]
    
     ICALLL      - Calls a subroutine that begins at [label].
                   CALLL TVOID [label]
    
     IRET       - Returns from a subroutine.
                  RET TVOID 0
    
     IVAR       - Declares a variable.
                  VAR TVOID [variable]
    */
    enum PNF_Instruction_Enum
    { 
     IVERSION = 0,
     IVOID,
     ICRASH,
     IQUIT,
     IHALT,
     IPRINT,
     IPRINTLN,
     IREAD,
     ILOAD,
     ISTORE,
     ILOADC,
     ISTOREC,
     IELOAD,
     IESTORE,
     IELOADC,
     IESTOREC,
     IVLOAD,
     IVSTORE,
     IVLOADC,
     IVSTOREC,
     IMODT,
     IMODCT,
     IADD,
     ISUB,
     IMUL,
     IDIV,
     IMOD,
     IPOW,
     ISQRT,
     IINC,
     IDEC,
     IEQU,
     INEQU,
     IGTR,
     ILSS,
     IGEQU,
     ILEQU,
     IAND,
     IOR,
     INOT,
     IGOTO,
     ICGOTO,
     IZGOTO,
     IPGOTO,
     INGOTO,
     IGOTOL,
     ICGOTOL,
     IZGOTOL,
     IPGOTOL,
     INGOTOL,
     IST,
     IPUSH,
     IPOP,
     ICALL,
     ICALLL,
     IRET,
     IVAR,
     ILBL,
     IEPRINT,
     IEPRINTLN,
     IEND
    };
         
    enum PNF_Type_Enum 
    {
     TVOID = 0,
     TBOOLEAN,
     TNUMBER,
     TCHARACTER,
     TSTRING
    };
    
    
    class PNF_Void
    {
     public:
            void put();
            void get();
            
            double to_mem();
            void from_mem(double i);
    
            void print();
            void eprint();
            void read();
    };
    
    void PNF_Void::put()
    {
     // Does nothing
    }
    
    void PNF_Void::get()
    {
     // Does nothing
    }
    
    double PNF_Void::to_mem()
    {
     return 0;
    }
    
    void PNF_Void::from_mem(double i)
    {
     if (i != 0)
      error(ERROR, "Not Void.");
    }
    
    void PNF_Void::print()
    {
     cout << 0;
    }
    
    void PNF_Void::eprint()
    {
     cerr << 0;
    }
    
    void PNF_Void::read()
    {
     // Does nothing
    }
    
    
    class PNF_Boolean
    {
     protected:
               bool data;
     
     public:
            PNF_Boolean();
            PNF_Boolean(bool d);
            ~PNF_Boolean();
            
            
            void put(bool d);
            String get();
            
            double to_mem();
            void from_mem(double i);
    
            void print();
            void eprint();
            void read();
    };
    
    PNF_Boolean::PNF_Boolean()
    {
     data = false;
    }
    
    PNF_Boolean::PNF_Boolean(bool d)
    {
     data = d;
    }
    
    PNF_Boolean::~PNF_Boolean()
    {
     
    }
            
    void PNF_Boolean::put(bool d)
    {
     data = d;
    }
    
    String PNF_Boolean::get()
    {
     if (data == true)
      return "true";
     else
      return "false";
    }
    
    double PNF_Boolean::to_mem()
    {
     return data;
    }
    
    void PNF_Boolean::from_mem(double i)
    {
     data = (bool)i;
    }
    
    void PNF_Boolean::print()
    {
     cout << get();
    }
    
    void PNF_Boolean::eprint()
    {
     cerr << get();
    }
    
    void PNF_Boolean::read()
    {
     string data2;
     
     cin >> data2;
    
     if (data2 == "false")
      data = false;
     else if (data2 == "true")
      data = true;
     else
      data = false;
    }
    
    
    class PNF_Number
    {
     protected:
               double data;
               
               
     public:
            PNF_Number();
            PNF_Number(double d);
            ~PNF_Number();
            
            void put(double d);
            double get();
            
            
            double to_mem();
            void from_mem(double d);
    
            void print();
            void eprint();
            void read();
    
    
            void add(double d);
            void sub(double d);
            void mul(double d);
            void div(double d);
            void mod(double d);
    
            void pow(double d);
            void sqrt(double d);
            void inc(double d);
            void dec(double d);
    };
    
    PNF_Number::PNF_Number()
    {
     data = 0;
    }
    
    PNF_Number::PNF_Number(double d)
    {
     data = d;
    }
    
    PNF_Number::~PNF_Number()
    {
     
    }
            
    void PNF_Number::put(double d)
    {
     data = d;
    }
    
    double PNF_Number::get()
    {
     return data;
    }
    
    double PNF_Number::to_mem()
    {
     return get();
    }
    
    void PNF_Number::from_mem(double d)
    {
     put(d);
    }
    
    void PNF_Number::print()
    {
     cout << data;
    }
    
    void PNF_Number::eprint()
    {
     cerr << data;
    }
    
    void PNF_Number::read()
    {
     cin >> data;
    }
    
    void PNF_Number::add(double d)
    {
     data += d;
    }
    
    void PNF_Number::sub(double d)
    {
     data -= d;
    }
    
    void PNF_Number::mul(double d)
    {
     data *= d;
    }
    
    void PNF_Number::div(double d)
    {
     data /= d;
    }
    
    void PNF_Number::mod(double d)
    {
     long l = (long)data % (long)d;
     data = l;
    }
    
    void PNF_Number::pow(double d)
    {
     data = ::pow(data, (int)d);
    }
    
    void PNF_Number::sqrt(double d)
    {
     data = ::sqrt(data);
    }
    
    void PNF_Number::inc(double d)
    {
     ++data;
    }
    
    void PNF_Number::dec(double d)
    {
     --data;
    }
    
    
    class PNF_Character
    {
     protected:
               char data;
               
               
     public:
            PNF_Character();
            PNF_Character(char d);
            ~PNF_Character();
            
            void put(char d);
            char get();
            
            double to_mem();
            void from_mem(double c);
    
            void print();
            void eprint();
            void read();
    
            void add(char d);
    };
    
    PNF_Character::PNF_Character()
    {
     data = '\0';
    }
    
    PNF_Character::PNF_Character(char d)
    {
     data = d;
    }
    
    PNF_Character::~PNF_Character()
    {
     
    }
            
    void PNF_Character::put(char d)
    {
     data = d;
    }
    
    char PNF_Character::get()
    {
     return data;
    }
    
    double PNF_Character::to_mem()
    {
     return (double)data;
    }
    
    void PNF_Character::from_mem(double c)
    {
     data = (char)c;
    }
    
    void PNF_Character::print()
    {
     cout << data;
    }
    
    void PNF_Character::eprint()
    {
     cerr << data;
    }
    
    void PNF_Character::read()
    {
     cin >> data;
    }
    
    void PNF_Character::add(char d)
    {
     data += d;
    }
    
    
    class PNF_String
    {
     protected:
               String data;
               
     public:
            PNF_String();
            PNF_String(String d);
            ~PNF_String();
            
            void put(String d);
            String get();
            
            double * to_mem();
            void from_mem(double * w);
    
            void print();
            void eprint();
            void read();
    
            void add(String d);
    };
    
    PNF_String::PNF_String()
    {
     data = "";
    }
    
    PNF_String::PNF_String(String d)
    {
     data = d;
    }
    
    PNF_String::~PNF_String()
    {
     
    }
            
    void PNF_String::put(String d)
    {
     data = d;
    }
    
    String PNF_String::get()
    {
     return data;
    }
    
    double * PNF_String::to_mem()
    {
     double * ret = new double[data.size()];
     
     for (unsigned long i = 0; i < data.size(); ++i)
     {
      if ((data.getString().data()[i]) == '\0')
       break;
      ret[i] = (long)data.getString().data()[i];
     }
     ret[data.size()] = 0;
    
    
     return ret;
    }
    
    void PNF_String::from_mem(double * w)
    {
     unsigned long i;
     for (i = 0; w[i] != 0; ++i)
      data[i] = (char)w[i];
    }
    
    void PNF_String::print()
    {
     cout << data;
    }
    
    void PNF_String::eprint()
    {
     cerr << data;
    }
    
    void PNF_String::read()
    {
     cin >> data;
     //cout << d;
    }
    
    void PNF_String::add(String d)
    {
     data += d;
    }
    
    
    class PNF_Variable
    {
     private:
             PNF_Void v;
             PNF_Boolean b;
             PNF_Number n;
             PNF_Character c;
             PNF_String s;
     
     
             long type;         
     
     
     public:
            long getType();
            void setType(long t);
            
    
            void put(PNF_Void v);
            void put(PNF_Boolean b);
            void put(PNF_Number n);
            void put(PNF_Character c);
            void put(PNF_String s);
    
            double * getm();
            void putm(double * d);
    
            void print();
            void println();
            void eprint();
            void eprintln();
            void read();
    
            PNF_Void to_void();
            PNF_Boolean to_boolean();
            PNF_Number to_number();
            PNF_Character to_character();
            PNF_String to_string();
    };
    
    long PNF_Variable::getType()
    {
     return type;
    }
    
    void PNF_Variable::setType(long t)
    {
     type = t;
    }
    
    void PNF_Variable::put(PNF_Void v)
    {
     setType(TVOID);
     this->v = v;
    }
    
    void PNF_Variable::put(PNF_Boolean b)
    {
     setType(TBOOLEAN);
     this->b = b;
    }
    
    void PNF_Variable::put(PNF_Number n)
    {
     setType(TNUMBER);
     this->n = n;
    }
    
    void PNF_Variable::put(PNF_Character c)
    {
     setType(TCHARACTER);
     this->c = c;
    }
    
    void PNF_Variable::put(PNF_String s)
    {
     setType(TSTRING);
     this->s = s;
    }
            
    double * PNF_Variable::getm()
    {
     double * ret = new double;
    
     switch (type)
     {
      case TVOID:
           *ret = v.to_mem();
           break;
           
      case TBOOLEAN:
           *ret = b.to_mem();
           break;
           
      case TNUMBER:
           *ret = n.to_mem();
           break;
           
      case TCHARACTER:
           *ret = c.to_mem();
           break;
           
      case TSTRING:
           ret = s.to_mem();
           break;
     };
     
     return ret;
    }
    
    void PNF_Variable::putm(double * d)
    {
     switch (type)
     {
      case TVOID:
           v.from_mem(*d);
           break;
           
      case TBOOLEAN:
           b.from_mem(*d);
           break;
           
      case TNUMBER:
           n.from_mem(*d);
           break;
           
      case TCHARACTER:
           c.from_mem(*d);
           break;
           
      case TSTRING:
           s.from_mem(d);
           break;
     };
    }
    
    void PNF_Variable::print()
    {
     switch (type)
     {
      case TVOID:
       v.print();
       break;
    
      case TBOOLEAN:
       b.print();
       break;
    
      case TNUMBER:
       n.print();
       break;
    
      case TCHARACTER:
       c.print();
       break;
    
      case TSTRING:
       s.print();
       break;
    
      default:
       error(ERROR, "Invalid Type.");
       break;
     }
    }
    
    void PNF_Variable::println()
    {
     switch (type)
     {
      case TVOID:
       v.print();
       cout << endl;
       break;
    
      case TBOOLEAN:
       b.print();
       cout << endl;
       break;
    
      case TNUMBER:
       n.print();
       cout << endl;
       break;
    
      case TCHARACTER:
       c.print();
       cout << endl;
       break;
    
      case TSTRING:
       s.print();
       cout << endl;
       break;
    
      default:
       error(ERROR, "Invalid Type.");
       break;
     }
    }
    
    void PNF_Variable::eprint()
    {
     switch (type)
     {
      case TVOID:
       v.eprint();
       break;
    
      case TBOOLEAN:
       b.eprint();
       break;
    
      case TNUMBER:
       n.eprint();
       break;
    
      case TCHARACTER:
       c.eprint();
       break;
    
      case TSTRING:
       s.eprint();
       break;
    
      default:
       error(ERROR, "Invalid Type.");
       break;
     }
    }
    
    void PNF_Variable::eprintln()
    {
     switch (type)
     {
      case TVOID:
       v.eprint();
       cerr << endl;
       break;
    
      case TBOOLEAN:
       b.eprint();
       cerr << endl;
       break;
    
      case TNUMBER:
       n.eprint();
       cerr << endl;
       break;
    
      case TCHARACTER:
       c.eprint();
       cerr << endl;
       break;
    
      case TSTRING:
       s.eprint();
       cerr << endl;
       break;
    
      default:
       error(ERROR, "Invalid Type.");
       break;
     }
    }
    
    void PNF_Variable::read()
    {
     switch (getType())
     {
      case TVOID:
       v.read();
       break;
    
      case TBOOLEAN:
       b.read();
       break;
    
      case TNUMBER:
       n.read();
       break;
    
      case TCHARACTER:
       c.read();
       break;
    
      case TSTRING:
      {
       s.read();
       }
       break;
    
      default:
       error(ERROR, "Invalid Type.");
       break;
     }
    }
    
    PNF_Void PNF_Variable::to_void()
    {
     PNF_Void v;
     return v;
    }
    
    PNF_Boolean PNF_Variable::to_boolean()
    {
     PNF_Boolean b;
    
     switch (getType())
     {
      case TVOID:
           b.put(false);
           break;
    
      case TBOOLEAN:
           b = this->b;
           break;
    
      case TNUMBER:
           b.put(n.get());
           break;
    
      case TCHARACTER:
           b.put(c.get());
           break;
    
      case TSTRING:
           b.put(s.get()[0]);
           break;
     }
    
     return b;
    }
    
    PNF_Number PNF_Variable::to_number()
    {
     PNF_Number n;
    
     switch (getType())
     {
      case TVOID:
           n.put(0);
           break;
    
      case TBOOLEAN:
           if (b.get().getString() == "true")
              n.put(1);
           else
              n.put(0);
           break;
    
      case TNUMBER:
           n = this->n;
           break;
    
      case TCHARACTER:
           n.put(c.get());
           break;
    
      case TSTRING:
           n.put(s.get()[0]);
           break;
     }
    
     return n;
    }
    
    PNF_Character PNF_Variable::to_character()
    {
     PNF_Character c;
    
     switch (getType())
     {
      case TVOID:
           c = '\0';
           break;
    
      case TBOOLEAN:
           if (b.get().getString() == "true")
            c = 't';
           else
            c = 'f';
           break;
    
      case TNUMBER:
           c = (char)n.get();
           break;
    
      case TCHARACTER:
           c = this->c;
           break;
    
      case TSTRING:
           c = s.get()[0];
           break;
     }
    
    
     return c;
    }
    
    PNF_String PNF_Variable::to_string()
    {
     PNF_String s;
    
     switch (getType())
     {
      case TVOID:
           s.put("");
           break;
    
      case TBOOLEAN:
           s = b.get();
           break;
    
      case TNUMBER:
           s.put((char)n.get());
           break;
    
      case TCHARACTER:
           s.put(c.get());
           break;
    
      case TSTRING:
           s = this->s;
           break;
     }
    
    
     return s;
    }
    
    class Memory
    {
     private:
             Array<double> mem;
             
             
     public:
            Memory();
            ~Memory();
            
            
            double get(unsigned long i);
            void put(unsigned long i, double d);
            long length();
    
            Array<double> getmem();
            void setmem(Array<double> a);
    
            void insert();
            void remove();
    };
    
    Memory::Memory()
    {
     
    }
    
    Memory::~Memory()
    {
     
    }        
            
    double Memory::get(unsigned long i)
    {
     return mem.get(i);
    }
    
    void Memory::put(unsigned long i, double d)
    {
     if (i >= length())
     {
      insert();
      mem.put(d, i);
     }
     else
      mem.put(d, i);
    }
    
    long Memory::length()
    {
     return mem.length();
    }
    
    Array<double> Memory::getmem()
    {
     return this->mem;
    }
    
    void Memory::setmem(Array<double> a)
    {
     this->mem = a;
    }
    
    void Memory::insert()
    {
     mem.insert();
    }
    
    void Memory::remove()
    {
     mem.remove();
    }
    
    class Stack
    {
     private:
             stack<PNF_Variable> stk;
             
             
     public:
            Stack();
            ~Stack();
            
            
            PNF_Variable pop();
            void push(PNF_Variable & v);
            PNF_Variable top();
    
            long length();
    };
    
    Stack::Stack()
    {
     
    }
    
    Stack::~Stack()
    {
    
    }
                    
    PNF_Variable Stack::pop()
    {
     PNF_Variable ret = stk.top();
     stk.pop();
    
    
     return ret;
    }
    
    PNF_Variable Stack::top()
    {
     return stk.top();
    }
    
    void Stack::push(PNF_Variable & v)
    {
     stk.push(v);
    }
    
    long Stack::length()
    {
     return stk.size();
    }
    
    struct Registers
    {
     unsigned long icount;
    
     unsigned long instruction;
     unsigned long type;
     unsigned long operand;
    
     
     String iname;
     Array<String> args;
    
    
     unsigned long ecount;
     Array<unsigned long> varcount;
     Array<unsigned long> labels;
    
    
     PNF_Variable accumulator;
     PNF_Variable calc;
    };
     
            
    class PNF
    {
     private:       
             Memory mem;
             Registers reg;
             Stack stk;
             stack<unsigned long> substk;
             
     public:
            PNF(int argc, char ** argv);
            ~PNF();
            
            
            String getProgram();
            void setProgram(char * program);
    
            Memory & getmem();
            void setmem(Memory & mem);
            
            
            void crash(string str);
    
    
            void load();
            void loads2();
            void check();
            int execute();
    };
    
    
    PNF::PNF(int argc, char ** argv)
    {
     double l = 0;
     double * pl = &l;
     
     reg.icount = 0;
     reg.instruction = 0;
     reg.type = 0;
     reg.operand = 0;
    
     reg.iname = argv[0];
     for (long i = 0; i < argc; ++i)
     {
      if (i + 1 == argc)
       break;
    
      if (reg.args.length() < (argc - 1))
       reg.args.insert();
      reg.args.put(argv[i + 1], i);
     }
     
     reg.accumulator.setType(TVOID);
     reg.accumulator.putm(pl);
    
     reg.calc.setType(TVOID);
     reg.calc.putm(pl);
    }
    
    PNF::~PNF()
    {
     
    }
                    
    String PNF::getProgram()
    {
     return reg.iname;
    }
    
    void PNF::setProgram(char * program)
    {
     reg.iname = program;
    }        
    
    Memory & PNF::getmem()
    {
     return mem;
    }
    
    void PNF::setmem(Memory & mem)
    {
     for (unsigned long i = 0; i < this->mem.length(); ++i)
      mem.getmem().put(this->mem.get(i), i);
    }
    
    void PNF::crash(string str)
    {
     error(ERROR, str);
     cout << endl;
    
     cout << "Registers:\n";
     cout << "==========\n";
     cout << "%icount              = " << reg.icount << endl;
     cout << endl;
     cout << "%instruction         = " << reg.instruction << endl;
     cout << "%type                = " << reg.type << endl;
     cout << "%operand             = " << reg.operand << endl;
     cout << "%accumulator         = ";
     reg.accumulator.print();
     cout << endl;
     cout << "%calc                = ";
     reg.calc.print();
     cout << endl;
     cout << "%iname               = " << reg.iname;
     cout << "\n\n";
    
    
     for (unsigned long i = 0; i < mem.length(); ++i)
      cout << "memory[" << i << "]: " << mem.get(i) << endl;
     cout << "\n\n";
    
     for (unsigned long i = 0; i < stk.length(); ++i)
     {
      cout << "Stack[" << i << "]: ";
      stk.top().println();
     }
    
     for (unsigned long i = 0; i < reg.args.length(); ++i)
      cout << "args[" << i << "]: " << reg.args.get(i) << endl;
     cout << "\n\n";
     
     
     exit(-1);
    }
    
    void PNF::load()
    {
     fin.open(reg.args.get(0).getString().c_str());
     if (!fin)
      crash("Program Not Found or File Not Readable.");
     
     String signature = "[email protected]";
     String str;
     fin >> str;
    
     
     if (str.getString() == signature.getString())
     {
      double num = 0;
      
      unsigned long i;
      for (i = 0; !fin.eof(); ++i)
      { 
       fin >> num;
       mem.put(i, num);
      }
      reg.ecount = i;
     }
     else
      crash("Wrong Signature.");
     fin.close();
    }
    
    void PNF::loads2()
    {
     if (mem.get(0) != IVERSION)
      crash("Version Unknown.");
     if (mem.get(reg.ecount - 3) != IEND)
      crash("No END Instruction.");
    
     for (unsigned long j = 0, k = 0; j != reg.ecount; ++j)
     {
      if (mem.get(j) == IVAR && mem.get(j + 1) == TVOID)
      {
       reg.varcount.put(j + 2, k);
       reg.varcount.insert();
       ++k;
      }
     }
    
     for (unsigned long j = 0, k = 0; j != reg.ecount; ++j)
     {
      if (mem.get(j) == ILBL && mem.get(j + 1) == TVOID && mem.get(j + 2) == 0)
      {
       reg.labels.put(j + 3, k);
       reg.labels.insert();
       ++k;
      }
     }
    
     reg.icount = 0;
    }
    
    void PNF::check()
    {
     // Not implemented yet.
    }
    
    int PNF::execute()
    {
     // Execute program
     for (unsigned long i = 0, j = 1, k = 2; ; i += 3, j += 3, k += 3)
     {
      // Load the registers with the proper memory   
       ++reg.icount;
    
       reg.instruction = (long)mem.get(i);
       reg.type = (long)mem.get(j);
       reg.operand = (long)mem.get(k);
      
      
      // Run the instruction
      switch (reg.instruction)
      {
       case IVERSION:
            switch (reg.type)
            {
             case TVOID:
                   if (reg.operand != 0)
                    crash("Invalid VOID Value.");
                   else
                    ; // Version Not Needed Yet.
                   break;
                   
             default:
                   crash("Invalid Type.");
                   break;  
            };
            break;
            
       case IVOID:  
            switch (reg.type)
            {
             case TVOID:
                   if (reg.operand != 0)
                    crash("Invalid VOID Value.");
                   else
                    ; // Does Nothing...      
                   break;
                   
             default:
                   crash("Invalid Type.");
                   break;  
            };
            break;
            
       case ICRASH:
            switch (reg.type)
            {
             case TSTRING:   
                  {           
                   unsigned long l;
                   String str;
                   for (l = k; mem.get(l) != 0; ++l)
                   {
                    char c = (char)mem.get(l);
                    str = str + c;
                   }
                   i = l;
                   crash(str.getString());
                  }
                  break;
                  
             default:
                     crash("Invalid Type.");
                     break;
            }
            break;
            
       case IQUIT:
            switch (reg.type)
            {
             case TVOID:
                  if (reg.operand != 0)
                   crash("Invalid VOID Value.");
                  break;
                  
             default:
              crash("Invalid Type.");
              break;
            };
            exit(0);
            
            
       case IHALT:
            switch (reg.type)
            {
             case TVOID:
                  if (reg.operand != 0)
                   crash("Invalid VOID Value.");
                  else
                   for (;;)
                    ;
                  
             default:
              crash("Invalid Type.");
              break;
            };
            
       case IPRINT:
       {
            switch (reg.type)
            {
             case TVOID:
             {
              if (reg.operand != 0)
               crash("Invalid VOID Value.");
              else
              {
               reg.accumulator.print();
              }
             }
             break;
    
             case TBOOLEAN:
              switch (reg.operand)
              {
               case 0:
                cout << "false";
                break;
    
               case 1:
                cout << "true";
                break;
    
               default:
                cout << "true";
                break;
              }
              break;
    
             case TNUMBER:
              cout << reg.operand;
              break;
    
             case TCHARACTER:
              cout << (char)reg.operand;
              break;
    
             case TSTRING:
             {
              unsigned long is = 0;
              for (is = k; mem.get(is) != 0; ++is)          
               cout << (char)mem.get(is);
    
              i = is + 1;
              j = i + 1;
              k = i + 2;
             }
             break;
                  
             default:
              crash("Invalid Type.");
              break;
            };
       }
            break;
    
       case IPRINTLN:
       {
            switch (reg.type)
            {
             case TVOID:
                  if (reg.operand != 0)
                   crash("Invalid VOID Value.");
                  else
                  {
                   reg.accumulator.println();
                  }
                  break;
    
             case TBOOLEAN:
              switch (reg.operand)
              {
               case 0:
                cout << "false\n";
                break;
    
               case 1:
                cout << "true\n";
                break;
    
               default:
                cout << "true\n";
                break;
              }
              break;
    
             case TNUMBER:
              cout << reg.operand << endl;
              break;
    
             case TCHARACTER:
              cout << (char)reg.operand << endl;
              break;
    
             case TSTRING:
             {
              unsigned long is = k;
              double value = mem.get(is);
              while (value != 0)
              {
               cout << (char)value;
               ++is;
               value = mem.get(is);         
              }
              cout << endl;
    
              i = is + 12;
              j = i + 1;
              k = i + 2;
             }
             break;
                  
             default:
              crash("Invalid Type.");
              break;
            };
       }
            break;
    
       case IREAD:
            reg.accumulator.setType(reg.type);
    
            if (reg.operand != 0)
             crash("Invalid Parameter.");
            else
            {
             reg.accumulator.read();
            }
    
            break;
    
       case ILOAD:
            {
             double m;
             double * pm;
            
    
             reg.accumulator.setType(reg.type);
    
             switch (reg.accumulator.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.operand);
                   reg.accumulator.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.operand; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.accumulator.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
       case ISTORE:
            {
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             double * pm;
             pm = reg.accumulator.getm();
             
             switch (reg.accumulator.getType())
             {
              case TVOID:
               mem.put(reg.operand, *pm);
               break;
    
              case TBOOLEAN:
               mem.put(reg.operand, *pm);
               break;
    
              case TNUMBER:
               mem.put(reg.operand, *pm);
               break;
    
              case TCHARACTER:
               mem.put(reg.operand, *pm);
               break;
    
              case TSTRING:
               for (long i = 0; pm[i] != 0; ++i)
                mem.put(reg.operand + i, pm[i]);
               break;
    
    
              default:
               crash("Invalid Type.");
             }
            }
            break;
    
       case ILOADC:
            {
             double m;
             double * pm;
            
    
             reg.calc.setType(reg.type);
    
             switch (reg.calc.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.operand);
                   reg.calc.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.operand; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.calc.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
       case ISTOREC:
            {
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             double * pm;
             pm = reg.calc.getm();
             
             switch (reg.calc.getType())
             {
              case TVOID:
               mem.put(reg.operand, *pm);
               break;
    
              case TBOOLEAN:
               mem.put(reg.operand, *pm);
               break;
    
              case TNUMBER:
               mem.put(reg.operand, *pm);
               break;
    
              case TCHARACTER:
               mem.put(reg.operand, *pm);
               break;
    
              case TSTRING:
               for (long i = 0; pm[i] != 0; ++i)
                mem.put(reg.operand + i, pm[i]);
               break;
    
    
              default:
               crash("Invalid Type.");
             }
            }
            break;
    
       case IELOAD:
            {
             double m;
             double * pm;
            
    
             reg.accumulator.setType(reg.type);
    
             switch (reg.accumulator.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.ecount);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.ecount);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.ecount);
                   reg.accumulator.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.ecount; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.accumulator.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
       case IESTORE:
            {
             if (reg.operand != 0)
              crash("Invalid Operand.");
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             double * pm;
             pm = reg.accumulator.getm();
             
             switch (reg.accumulator.getType())
             {
              case TVOID:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TBOOLEAN:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TNUMBER:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TCHARACTER:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TSTRING:
               unsigned long i;
               for (i = 0; pm[i] != 0; ++i)
                mem.put(reg.ecount + i, pm[i]);
               reg.ecount += i;
               break;
    
    
              default:
               crash("Invalid Type.");
             }
            }
            break;
    
       case IELOADC:
            {
             double m;
             double * pm;
            
    
             reg.calc.setType(reg.type);
    
             switch (reg.calc.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.ecount);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.ecount);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.ecount);
                   reg.calc.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.ecount; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.calc.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
    case IESTOREC:
            {
             if (reg.operand != 0)
              crash("Invalid Operand.");
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             double * pm;
             pm = reg.calc.getm();
             
             switch (reg.calc.getType())
             {
              case TVOID:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TBOOLEAN:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TNUMBER:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TCHARACTER:
               mem.put(reg.ecount, *pm);
               ++reg.ecount;
               break;
    
              case TSTRING:
               unsigned long i;
               for (i = 0; pm[i] != 0; ++i)
                mem.put(reg.ecount + i, pm[i]);
               reg.ecount += i;
               break;
    
    
              default:
               crash("Invalid Type.");
             }
            }
            break;
    
      case IVLOAD:
            {
             double m;
             double * pm;
            
    
             reg.accumulator.setType(reg.type);
             reg.operand = reg.varcount.get(reg.operand);
    
             switch (reg.accumulator.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.accumulator.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.operand);
                   reg.accumulator.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.operand; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.accumulator.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
       case IVSTORE:
            {
             if (reg.operand != 0)
              crash("Invalid Operand.");
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             long j = reg.ecount;
             mem.put(j, IVAR);
             mem.put(j + 1, TVOID);
             double * pm;
             pm = reg.accumulator.getm();
    
    
             reg.varcount.insert();
             reg.varcount.put(j + 2, reg.varcount.length() - 1);
             
             switch (reg.accumulator.getType())
             {
              case TVOID:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TBOOLEAN:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TNUMBER:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TCHARACTER:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TSTRING:
               unsigned long i;
               for (i = 0; pm[i] != 0; ++i)
                mem.put((j + 2) + i, pm[i]);
               reg.ecount += 3;
               break;
    
    
              default:
               crash("Invalid Type.");
             }
    
             for (unsigned long j = 0, k = 0; j != reg.ecount; ++j)
             {
              if (mem.get(j) == IVAR && mem.get(j + 1) == TVOID)
              {
               reg.varcount.put(j + 2, k);
               reg.varcount.insert();
               ++k;
              }
             }
            }
            break;
    
      case IVLOADC:
            {
             double m;
             double * pm;
            
    
             reg.calc.setType(reg.type);
             reg.operand = reg.varcount.get(reg.operand);
    
             switch (reg.calc.getType())
             {
              case TBOOLEAN:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TNUMBER:
                   m = mem.get(reg.operand);
                   pm = &m;
    
                   reg.calc.putm(pm);
                   break;
    
              case TCHARACTER:
                   pm = &m;       
                   *pm = mem.get(reg.operand);
                   reg.calc.putm(pm);
                   break;
    
              case TSTRING:
              {           
                   String str = "";
                   long n;
                   long o;
                   for (n = reg.operand; mem.get(n) != 0; ++n)
                   {
                    char ch = (char)mem.get(n);
                    str += ch;
                   }
                   PNF_String str2(str.getString());
                   reg.calc.put(str2);
              }
              break;
                  
              default:
               crash("Invalid Type.");
               break;
             }
             break;
            }
    
       case IVSTOREC:
            {
             if (reg.operand != 0)
              crash("Invalid Operand.");
             if (reg.type != 0)
              crash("Invalid Type Identifier.");
    
             long j = reg.ecount;
             mem.put(j, IVAR);
             mem.put(j + 1, TVOID);
             double * pm;
             pm = reg.calc.getm();
    
    
             reg.varcount.insert();
             reg.varcount.put(j + 2, reg.varcount.length() - 1);
             
             switch (reg.calc.getType())
             {
              case TVOID:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TBOOLEAN:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TNUMBER:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TCHARACTER:
               mem.put(j + 2, *pm);
               reg.ecount += 3;
               break;
    
              case TSTRING:
               unsigned long i;
               for (i = 0; pm[i] != 0; ++i)
                mem.put((j + 2) + i, pm[i]);
               reg.ecount += 3;
               break;
    
    
              default:
               crash("Invalid Type.");
             }
    
             for (unsigned long j = 0, k = 0; j != reg.ecount; ++j)
             {
              if (mem.get(j) == IVAR && mem.get(j + 1) == TVOID)
              {
               reg.varcount.put(j + 2, k);
               reg.varcount.insert();
               ++k;
              }
             }
            }
            break;
    
       case IMODT:
            {
             if (reg.operand == 0)
              reg.accumulator.setType(reg.type);
             else
              crash("Invalid Operand.");
            }
            break;
    
       case IMODCT:
            {
             if (reg.operand == 0)
              reg.calc.setType(reg.type);
             else
              crash("Invalid Operand.");
            }
            break;
    
       case IADD:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.add(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                case TSTRING:
                {
                 PNF_String ts = reg.accumulator.to_string();
                 ts.add(reg.calc.to_string().get());
                 reg.accumulator.put(ts);
                 break;
                }
    
                default:
                 crash("Invalid ADD Instruction.");
                 break;
               }
              }
              else
               crash("Invalid ADD Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
               {
                reg.accumulator.to_number().add(reg.operand);
               }
               break;
    
               case TCHARACTER:
                reg.accumulator.to_character().add(reg.operand);
                break;
    
               case TSTRING:
               {
                unsigned long i2 = 0;
                for (i2 = k; mem.get(i2) != 0; ++i2)
                 reg.accumulator.to_character().add((char)mem.get(i2));
                i = i2;
                j = i + 1;
                k = i + 2;             
               }
               break;
    
               default:
                crash("Invalid ADD Instruction.");
              }
             }
            }
            break;
    
       case ISUB:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.sub(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                default:
                 crash("Invalid SUB Instruction.");
                 break;
               }
              }
              else
               crash("Invalid SUB Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().sub(reg.operand);
                break;
    
               default:
                crash("Invalid SUB Instruction.");
              }
             }
             break;
            }
    
       case IMUL:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.mul(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                default:
                 crash("Invalid MUL Instruction.");
                 break;
               }
              }
              else
               crash("Invalid MUL Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().mul(reg.operand);
                break;
    
               default:
                crash("Invalid MUL Instruction.");
              }
             }
             break;
            }
    
       case IDIV:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.div(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                default:
                 crash("Invalid DIV Instruction.");
                 break;
               }
              }
              else
               crash("Invalid DIV Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().div(reg.operand);
                break;
    
               default:
                crash("Invalid DIV Instruction.");
              }
             }
             break;
            }
    
            case IMOD:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.mod(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                default:
                 crash("Invalid MOD Instruction.");
                 break;
               }
              }
              else
               crash("Invalid MOD Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().sub(reg.operand);
                break;
    
               default:
                crash("Invalid MOD Instruction.");
              }
             }
             break;
            }
    
       case IPOW:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               switch (reg.accumulator.getType())
               {
                case TNUMBER:
                {
                 PNF_Number tn = reg.accumulator.to_number();
                 tn.pow(reg.calc.to_number().get());
                 reg.accumulator.put(tn);
                 break;
                }
    
                default:
                 crash("Invalid POW Instruction.");
                 break;
               }
              }
              else
               crash("Invalid POW Instruction.");
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().pow(reg.operand);
                break;
    
               default:
                crash("Invalid POW Instruction.");
              }
             }
             break;
            }
    
       case ISQRT:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              switch (reg.accumulator.getType())
              {
               case TNUMBER:
               {
                PNF_Number tn = reg.accumulator.to_number();
                tn.sqrt(reg.accumulator.to_number().get());
                reg.accumulator.put(tn);
                break;
               }
    
               default:
                crash("Invalid SQRT Instruction.");
                break;
              }
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
                reg.accumulator.to_number().sub(reg.operand);
                break;
    
               default:
                crash("Invalid SQRT Instruction.");
              }
             }
            }
            break;
    
       case IINC:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              switch (reg.accumulator.getType())
              {
               case TNUMBER:
               {
                PNF_Number tn = reg.accumulator.to_number();
                tn.inc(reg.accumulator.to_number().get());
                reg.accumulator.put(tn);
                break;
               }
    
               default:
                crash("Invalid INC Instruction.");
                break;
              }
             }
             else
              crash("Invalid INC Instruction.");
            }
            break;
    
       case IDEC:
            {
             if (reg.operand == 0 && reg.type == 0)
             {
              switch (reg.accumulator.getType())
              {
               case TNUMBER:
               {
                PNF_Number tn = reg.accumulator.to_number();
                tn.dec(reg.accumulator.to_number().get());
                reg.accumulator.put(tn);
                break;
               }
    
               default:
                crash("Invalid DEC Instruction.");
                break;
              }
             }
             else
              crash("Invalid DEC Instruction.");
            }
            break;
    
       case IEQU:
            {
             if (reg.type == TVOID && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() == reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TBOOLEAN:
               {
                 bool b = (reg.accumulator.to_boolean().get().getString() == "true" ? true : false);
                 bool b2 = (reg.operand == 0 ? false : true);
                 bool b3 = b && b2;
                 PNF_Boolean b4;
                 b4.put(b3);
                 reg.accumulator.put(b4);
                }
                break;
    
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() == reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() == (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case INEQU:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() != reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TBOOLEAN:
               {
                 bool b = (reg.accumulator.to_boolean().get().getString() != "true" ? true : false);
                 bool b2 = (reg.operand == 0 ? false : true);
                 bool b3 = b && b2;
                 PNF_Boolean b4;
                 b4.put(b3);
                 reg.accumulator.put(b4);
                }
                break;
    
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() != reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() != (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case IGTR:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() > reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() > reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() > (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case ILSS:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() < reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() < reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() < (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case IGEQU:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() >= reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() >= reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() >= (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case ILEQU:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_number().get() <= reg.calc.to_number().get());
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
             else
             {
              switch (reg.type)
              {
               case TNUMBER:
               {
                bool b = (reg.accumulator.to_number().get() <= reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               case TCHARACTER:
               {
                bool b = (reg.accumulator.to_character().get() <= (char)reg.operand);
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
               break;
    
               default:
                crash("Invalid Type.");
              }
             }
            }
            break;
    
       case IAND:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_boolean().get().getString() == "true" && reg.calc.to_boolean().get().getString() == "true");
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
            }
            break;
    
            case IOR:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.getType() == reg.calc.getType())
              {
               bool b = (reg.accumulator.to_boolean().get().getString() == "true" || reg.calc.to_boolean().get().getString() == "true");
               if (b == true)
               {
                PNF_Boolean b2;
                b2.put(b);
                reg.accumulator.put(b2);
               }
              }
             }
            }
            break;
    
            case INOT:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              if (reg.accumulator.to_boolean().get().getString() == "true")
               reg.accumulator.to_boolean().put(false);
              else
               reg.accumulator.to_boolean().put(true);
             }
            }
            break;
    
       case IGOTO:
            if (reg.type == 0)
            {
             i = reg.operand;
             j = reg.operand + 1;
             k = reg.operand + 2;     
            }
            else
             crash("Invalid GOTO.");
            break;
    
      case ICGOTO:
            if (reg.type == 0)
            {
             if (reg.accumulator.to_boolean().get().getString() == "true")
             {
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
            }
            else
             crash("Invalid CGOTO.");
            break;
    
       case IZGOTO:
            if (reg.accumulator.to_number().get() == 0)
            {
             if (reg.type == 0)
             {
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid ZGOTO.");
            }
            break;
    
       case IPGOTO:
            if (reg.accumulator.to_number().get() > 0)
            {
             if (reg.type == 0)
             {
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid PGOTO.");
            }
            break;
    
       case INGOTO:
            if (reg.accumulator.to_number().get() < 0)
            {
             if (reg.type == 0)
             {
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid NGOTO.");
            }
            break;
    
       case IGOTOL:
            if (reg.type == TVOID)
            {
             reg.operand = reg.labels.get(reg.operand);        
    
             i = reg.operand;
             j = reg.operand + 1;
             k = reg.operand + 2;     
            }
            else
             crash("Invalid GOTOL.");
            break;
    
      case ICGOTOL:
            if (reg.type == 0)
            {
             if (reg.accumulator.to_boolean().get().getString() == "true")
             {
              reg.operand = reg.labels.get(reg.operand);        
    
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
            }
            else
             crash("Invalid CGOTOL.");
            break;
    
       case IZGOTOL:
            if (reg.accumulator.to_number().get() == 0)
            {
             if (reg.type == 0)
             {
              reg.operand = reg.labels.get(reg.operand);        
    
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid ZGOTOL.");
            }
            break;
    
       case IPGOTOL:
            if (reg.accumulator.to_number().get() > 0)
            {
             if (reg.type == 0)
             {
              reg.operand = reg.labels.get(reg.operand);        
    
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid PGOTOL.");
            }
            break;
    
       case INGOTOL:
            if (reg.accumulator.to_number().get() < 0)
            {
             if (reg.type == 0)
             {
              reg.operand = reg.labels.get(reg.operand);        
    
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
             }
             else
              crash("Invalid NGOTOL.");
            }
            break;
    
       case IST:
            {
             if (reg.type == 0 && reg.operand == 0)
             {
              reg.calc.to_number().dec(1);
              if (reg.calc.to_number().get() == 0)
               reg.accumulator.put(reg.calc.to_number());
             }
            }
            break;
    
       case IPUSH:
            if (reg.operand == 0)
            {
             switch (reg.type)
             {
              case TVOID:
                      {                               
                       stk.push(reg.accumulator);                   
                      } 
                      break;
    
              default:
                      crash("Invalid PUSH.");
                      break;                 
             }
            }
            else
                crash("Invalid PUSH.");
            break;
    
           case IPOP:
            {
             if (reg.operand == 0)
             {         
              switch (reg.type)
              {
               case TVOID:  
               {                                    
                       reg.accumulator = stk.top();
                       stk.pop();
                       break;
               }
    
               default:
                       crash("Invalid POP.");
                       break;
              }
             }
             else
                 crash("Invalid POP.");
            }
            break;
    
           case ICALL:
            if (reg.type == 0)
            {
             // Push current instruction address.
             substk.push(i);
    
             // GOTO Address
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
            }
            else
             crash("Invalid CALL.");
            break;
    
           case ICALLL:
            if (reg.type == 0)
            {
             // Push current instruction address.
             substk.push(i);
    
             // GOTO Address
              reg.operand = reg.labels.get(reg.operand);
    
              i = reg.operand;
              j = reg.operand + 1;
              k = reg.operand + 2;     
            }
            else
             crash("Invalid CALLL.");
            break;
    
           case IRET:
            if (reg.type == 0 && reg.operand == 0)
            {
             i = (substk.top());
             substk.pop();
    
             // GOTO Address          
              j = i + 1;
              k = i + 2;     
            }
            else
             crash("Invalid RET.");
            break;
    
    
       case IVAR:
            {
             // Work done on loads2().
            }
            break;
    
       case ILBL:
            {
             // Work done on loads2().
            }
            break;
    
       case IEPRINT:
       {
            switch (reg.type)
            {
             case TVOID:
             {
              if (reg.operand != 0)
               crash("Invalid VOID Value.");
              else
              {
               reg.accumulator.eprint();
              }
             }
             break;
    
             case TBOOLEAN:
              switch (reg.operand)
              {
               case 0:
                cerr << "false";
                break;
    
               case 1:
                cerr << "true";
                break;
    
               default:
                cerr << "true";
                break;
              }
              break;
    
             case TNUMBER:
              cerr << reg.operand;
              break;
    
             case TCHARACTER:
              cerr << (char)reg.operand;
              break;
    
             case TSTRING:
             {
              unsigned long is = 0;
              for (is = k; mem.get(is) != 0; ++is)
               cerr << (char)mem.get(is);
    
              i = is + 1;
              j = i + 1;
              k = i + 2;
             }
             break;
                  
             default:
              crash("Invalid Type.");
              break;
            };
       }
            break;
    
       case IEPRINTLN:
       {
            switch (reg.type)
            {
             case TVOID:
                  if (reg.operand != 0)
                   crash("Invalid VOID Value.");
                  else
                  {
                   reg.accumulator.eprintln();
                  }
                  break;
    
             case TBOOLEAN:
              switch (reg.operand)
              {
               case 0:
                cerr << "false\n";
                break;
    
               case 1:
                cerr << "true\n";
                break;
    
               default:
                cerr << "true\n";
                break;
              }
              break;
    
             case TNUMBER:
              cerr << reg.operand << endl;
              break;
    
             case TCHARACTER:
              cerr << (char)reg.operand << endl;
              break;
    
             case TSTRING:
             {
              unsigned long is = 0;
              for (is = k; mem.get(is) != 0; ++is)
               cerr << (char)mem.get(is);
              cerr << endl;
    
              i = is + 1;
              j = i + 1;
              k = i + 2;
             }
             break;
                  
             default:
              crash("Invalid Type.");
              break;
            };
       }
            break;
     
       case IEND:
       {
        // Do nothing, just a marker for the end.
       }
       break;
            
            
       default:
               crash("Invalid Instruction.");
               break;
      }
     }
    }
    
    The desLib is included which it refers to. It must be unzipped in the include directory of your C++ compiler to work.

    The file I've been operating on, helloworld.pnf:
    Code:
    [email protected]
    
    
    0 0 0
    6 4 34 72 101 108 108 111 32 87 111 114 108 100 33 34 0
    3 0 0
    60 0 0
    
    I was trying to debug the PRINTLN instruction, which corresponds to the 6 4 [...].
     

    Attached Files:

  2. des000

    des000 Thread Starter

    Joined:
    May 29, 2008
    Messages:
    295
    Sample output:

    Code:
    "Hello World!"
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    * ERROR: Index Out of Bounds.
    
    And this error message just goes on and on.
     
  3. loserOlimbs

    loserOlimbs

    Joined:
    Jun 19, 2004
    Messages:
    7,800
    3400+ lines!

    Do you at least know where the error that is printed is generated?
     
  4. des000

    des000 Thread Starter

    Joined:
    May 29, 2008
    Messages:
    295
    I know that the message comes from the Array class in desLib. It's supposed to mimic Java's arrays. It will print a message if you are trying to access an element out of bounds. This is the message that is printed.

    I don't know however, why it's printed multiple times (in fact infinitely), or why I can see that the loop for PRINTLN executes right at least until what is supposed to be the end, and what seems to be the end, and then it goes to the error message.

    This could be a problem with the Array or Memory class, but I'm just not sure right now. The Memory class is found in pnf.hpp. The functions being invoked from those classes are: Memory::get(), and Array<double>::get().
     
  5. des000

    des000 Thread Starter

    Joined:
    May 29, 2008
    Messages:
    295
    I just figured it out! It was a problem with the counters. I needed to subtract 3 from the counters so that they would not be counted twice. Why this would make it loop and everything like that I don't know, but that's what it was.

    These lines:
    Code:
    i = i - 3;
    j = i + 1;
    k = i + 2;
    
    ...must be added to the place where it calculates i, j, and k!
     
  6. Sponsor

As Seen On
As Seen On...

Welcome to Tech Support Guy!

Are you looking for the solution to your computer problem? Join our site today to ask your question. This site is completely free -- paid for by advertisers and donations.

If you're not already familiar with forums, watch our Welcome Guide to get started.

Join over 733,556 other people just like you!

Thread Status:
Not open for further replies.

Short URL to this thread: https://techguy.org/1114287

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice