I'm now debugging the interpreter again. I have added events and am implementing a special event, called a breakpoint exception. This is triggerred after every instruction, except when we are in a breakpoint already. But my code is going on after it should stop.
My desLib is included as an attatchment. It goes in your include directory.
main.cpp:
pnf.hpp:
As you can see, it's supposed to trigger a builtin function if there is no user-defined function. Here is exceptiontest.pnf:
Here there is a user-defined function so we use this instead of the builtin function. The output when running this is:
There is only supposed to be one breakpoint triggerred after the, "Hello World!". I have no idea whether this is going wrong on the RET instruction, or the breakpoint, or the PRINTLN instruction.
My desLib is included as an attatchment. It goes in your include directory.
main.cpp:
Code:
#include "../pnf.hpp"
int main(int argc, char ** argv)
{
if (argc < 2)
{
error(ERROR, (char *)"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, (char *)"Program Not Found.");
}
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
ILBL - Declares a label.
LBL TVOID 0V
IVAR - Declares a variable.
VAR TVOID [variable]
IELBL - Declares an event label.
ELBL TVOID 0V
IEVLOAD - Loads a value into %evalue.
EVLOAD TVOID [value]
IHEADD - Adds a Hardware Event to the table.
HEADD TVOID [event label number]
IHEREM - Removes a Hardware Event from the table.
HEREM TVOID 0V
IHEED - Edits a Hardware Event in the table. %evalue must be the hevent
number.
HEED TVOID [new event label number number]
IHEGET - Gets a Hardware Event event label number from the table. Puts it
in %evalue.
HEGET TVOID [hardware event number]
ISHEADD - Adds a System Hardware Event to the table.
SHEADD TVOID [event label number]
ISHEREM - Removes a System Hardware Event from the table.
SHEREM TVOID 0V
ISHEED - Edits a System Hardware Event in the table. %evalue must be the
shevent number.
SHEED TVOID [new event label number number]
ISHEGET - Gets a System Hardware Event event label number from the table.
Puts it in %evalue.
SHEGET TVOID [hardware event number]
IEADD - Adds an Event to the table.
EADD TVOID [event label number]
IEREM - Removes an Event from the table.
EREM TVOID 0V
IEED - Edits an Event in the table. %evalue must be the event number.
EED TVOID [new event label number number]
IEGET - Gets an Event event label number from the table. Puts it in \
%evalue.
EGET TVOID [hardware event number]
IEXADD - Adds an Exception to the table.
EXADD TVOID [event label number]
IEXREM - Removes an Exception from the table.
EXREM TVOID 0V
IEXED - Edits an Exception in the table. %evalue must be the exception
number.
EXED TVOID [new event label number number]
IEXGET - Gets an Exception event label number from the table. Puts it
in %evalue.
EXGET TVOID [hardware event number]
IIADD - Adds an Interrupt to the table.
IADD TVOID [event label number]
IIREM - Removes an Interrupt from the table.
IREM TVOID 0V
IIED - Edits an Interrupt in the table. %evalue must be the interrupt
number.
IED TVOID [new event label number number]
IIGET - Gets an Interrupt event label number from the table. Puts it
in %evalue.
IGET TVOID [hardware event number]
IHEVENT - Executes a Hardware Event subroutine.
HEVENT TVOID [hardware event number]
ISHEVENT - Executes a System Hardware Event Subroutine.
SHEVENT TVOID [system hardware event number]
IEVENT - Executes an Event subroutine.
EVENT TVOID [event number]
IEXCEPTION - Executes an Exception subroutine.
EXCEPTION TVOID [exception number]
IINT - Executes an Interrupt (User Defined Event) subroutine.
INT TVOID [interrupt number]
*/
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,
IELBL,
IEVLOAD,
IHEADD,
IHEREM,
IHEED,
IHEGET,
ISHEADD,
ISHEREM,
ISHEED,
ISHEGET,
IEADD,
IEREM,
IEED,
IEGET,
IEXADD,
IEXREM,
IEXED,
IEXGET,
IIADD,
IIREM,
IIED,
IIGET,
IHEVENT,
ISHEVENT,
IEVENT,
IEXCEPTION,
IINT
};
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, (char *)"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 (char *)"true";
else
return (char *)"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 = (char *)"";
}
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;
}
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, (char *)"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, (char *)"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, (char *)"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, (char *)"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, (char *)"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((char *)"");
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)
{
if (i >= length())
{
insert();
mem.put(0, 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();
}
class ETable
{
private:
Array<unsigned long> table;
public:
void add(unsigned long value);
void remove();
void edit(unsigned long index, unsigned long value);
unsigned long get(unsigned long index);
unsigned long length();
};
void ETable::add(unsigned long value)
{
if (length() == 1)
table.put(0, value);
else
{
table.insert();
table.put((length() - 1), value);
}
}
void ETable::remove()
{
table.remove();
}
void ETable::edit(unsigned long index, unsigned long value)
{
if (index < length())
table.put(index, value);
else
{
add(value);
}
}
unsigned long ETable::get(unsigned long index)
{
if (index >= length())
add(0);
return table.get(index);
}
unsigned long ETable::length()
{
return table.length();
}
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;
Array<unsigned long> elabels;
unsigned long evalue;
ETable hevents;
ETable shevents;
ETable events;
ETable exceptions;
ETable interrupts;
PNF_Variable accumulator;
PNF_Variable calc;
};
class PNF
{
private:
Memory mem;
Registers reg;
Stack stk;
stack<unsigned long> substk;
bool breakpoint;
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();
void breakpoint_exception();
};
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);
breakpoint = false;
}
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 = (char *)"!@.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;
}
}
for (unsigned long j = 0, k = 0; j != reg.ecount; ++j)
{
if (mem.get(j) == IELBL && mem.get(j + 1) == TVOID && mem.get(j + 2) == 0)
{
reg.elabels.put(j + 3, k);
reg.elabels.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.");
};
continue;
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.");
else
{
cout << "a";
exit(0);
}
default:
crash("Invalid Type.");
};
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;
if (breakpoint == true)
{
i = i - 3;
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 = 0;
for (is = k; mem.get(is) != 0; ++is)
cout << (char)mem.get(is);
cout << endl;
i = is + 1;
j = i + 1;
k = i + 2;
if (breakpoint == true)
{
i = i - 3;
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 = (char *)"";
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 = (char *)"";
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 = (char *)"";
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 = (char *)"";
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 = (char *)"";
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 = (char *)"";
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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid CALLL.");
break;
case IRET:
if (reg.type == 0 && reg.operand == 0)
{
i = (substk.top());
i += 3;
substk.pop();
// GOTO Address
j = i + 1;
k = i + 2;
// Breakpoint is done...
breakpoint = false;
i = i - 3;
j = i + 1;
k = i + 2;
}
else
crash("Invalid RET.");
cout << "b";
continue;
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;
if (breakpoint == true)
{
i = i - 3;
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;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
break;
default:
crash("Invalid Type.");
break;
};
}
break;
case IEND:
{
// Do nothing, just a marker for the end.
}
break;
case IELBL:
{
// Work done on loads2().
}
break;
case IEVLOAD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = (unsigned long)reg.operand;
}
break;
case IHEADD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.hevents.add(reg.operand);
}
break;
case IHEREM:
{
if (reg.type != TVOID && reg.operand != 0)
crash("Invalid Type or Void Value.");
else
reg.hevents.remove();
}
break;
case IHEED:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.hevents.edit(reg.evalue, reg.operand);
}
break;
case IHEGET:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = reg.hevents.get(reg.operand);
}
break;
case ISHEADD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.shevents.add(reg.operand);
}
break;
case ISHEREM:
{
if (reg.type != TVOID && reg.operand != 0)
crash("Invalid Type or Void Value.");
else
reg.shevents.remove();
}
break;
case ISHEED:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.shevents.edit(reg.evalue, reg.operand);
}
break;
case ISHEGET:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = reg.shevents.get(reg.operand);
}
break;
case IEADD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.events.add(reg.operand);
}
break;
case IEREM:
{
if (reg.type != TVOID && reg.operand != 0)
crash("Invalid Type or Void Value.");
else
reg.events.remove();
}
break;
case IEED:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.events.edit(reg.evalue, reg.operand);
}
break;
case IEGET:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = reg.events.get(reg.operand);
}
break;
case IEXADD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.exceptions.add(reg.operand);
}
break;
case IEXREM:
{
if (reg.type != TVOID && reg.operand != 0)
crash("Invalid Type or Void Value.");
else
reg.exceptions.remove();
}
break;
case IEXED:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.exceptions.edit(reg.evalue, reg.operand);
}
break;
case IEXGET:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = reg.exceptions.get(reg.operand);
}
break;
case IIADD:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.interrupts.add(reg.operand);
}
break;
case IIREM:
{
if (reg.type != TVOID && reg.operand != 0)
crash("Invalid Type or Void Value.");
else
reg.interrupts.remove();
}
break;
case IIED:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.interrupts.edit(reg.evalue, reg.operand);
}
break;
case IIGET:
{
if (reg.type != TVOID)
crash("Invalid Type.");
else
reg.evalue = reg.interrupts.get(reg.operand);
}
break;
case IHEVENT:
{
if (reg.type == 0)
{
// Push current instruction address.
substk.push(i);
// GOTO Address
reg.operand = reg.hevents.get(reg.operand);
reg.operand = reg.elabels.get(reg.operand);
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid HEVENT.");
}
break;
case ISHEVENT:
{
if (reg.type == 0)
{
// Push current instruction address.
substk.push(i);
// GOTO Address
reg.operand = reg.shevents.get(reg.operand);
reg.operand = reg.elabels.get(reg.operand);
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid SHEVENT.");
}
break;
case IEVENT:
{
if (reg.type == 0)
{
// Push current instruction address.
substk.push(i);
// GOTO Address
reg.operand = reg.events.get(reg.operand);
reg.operand = reg.elabels.get(reg.operand);
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid EVENT.");
}
break;
case IEXCEPTION:
{
if (reg.type == 0)
{
// Push current instruction address.
substk.push(i);
// GOTO Address
reg.operand = reg.exceptions.get(reg.operand);
reg.operand = reg.elabels.get(reg.operand);
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid EXCEPTION.");
}
break;
case IINT:
{
if (reg.type == 0)
{
// Push current instruction address.
substk.push(i);
// GOTO Address
reg.operand = reg.interrupts.get(reg.operand);
reg.operand = reg.elabels.get(reg.operand);
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
if (breakpoint == true)
{
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
crash("Invalid INT.");
}
break;
default:
crash("Invalid Instruction.");
break;
}
// Execute breakpoint exception if not in breakpoint
if (breakpoint == false)
{
// Tell the program we are now in a breakpoint...
breakpoint = true;
// Push current instruction address.
cout << "i: " << i << "\n";
substk.push(i);
// GOTO Address
reg.operand = reg.exceptions.get(0);
reg.operand = reg.elabels.get(reg.operand);
if (reg.operand == 0)
breakpoint_exception();
else
{
i = reg.operand;
j = reg.operand + 1;
k = reg.operand + 2;
i = i - 3;
j = i + 1;
k = i + 2;
}
}
else
cout << "Not in breakpoint.\n";
}
}
void PNF::breakpoint_exception()
{
}
Code:
!@.PNF
0 0 0
75 0 0
6 4 72 101 108 108 111 32 87 111 114 108 100 33 0
3 0 0
61 0 0
6 4 73 110 32 98 114 101 97 107 112 111 105 110 116 46 0
55 0 0
60 0 0
Code:
i: 3
In breakpoint.
Not in breakpoint.
6bHello World!
i: 21
In breakpoint.
Not in breakpoint.
61bi: 24
In breakpoint.
Not in breakpoint.
6bIn breakpoint.
i: 44
In breakpoint.
Not in breakpoint.
60bi: 47
In breakpoint.
Not in breakpoint.
0bterminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.