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
pnf.hpp
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:
I was trying to debug the PRINTLN instruction, which corresponds to the 6 4 [...].
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 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