Quantcast
Channel: Tech Support Guy
Viewing all articles
Browse latest Browse all 29110

Debugging Portable Numbers Format Interpreter

$
0
0
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 = "!@.PNF";
 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:

!@.PNF


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
File Type: zip deslib.zip (31.1 KB)

Viewing all articles
Browse latest Browse all 29110

Trending Articles