Fixed subroutine bugs
This commit is contained in:
@@ -7,16 +7,16 @@
|
|||||||
|
|
||||||
struct subroutine *callStack=nullptr;
|
struct subroutine *callStack=nullptr;
|
||||||
|
|
||||||
subroutine::subroutine(enum STATES r)
|
subroutine::subroutine(unsigned int r)
|
||||||
{
|
{
|
||||||
this->ret=r;
|
this->ret=r;
|
||||||
this->called=callStack;
|
this->called=callStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum STATES subroutine::close()
|
unsigned int subroutine::close()
|
||||||
{
|
{
|
||||||
if (callStack==nullptr) return STACK_UNDERFLOW_ERROR;
|
if (callStack==nullptr) return STACK_UNDERFLOW_ERROR;
|
||||||
enum STATES r=callStack->ret;
|
unsigned int r=callStack->ret;
|
||||||
struct subroutine *l=callStack->called;
|
struct subroutine *l=callStack->called;
|
||||||
delete callStack;
|
delete callStack;
|
||||||
callStack=l;
|
callStack=l;
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ enum STATES:unsigned int
|
|||||||
class subroutine
|
class subroutine
|
||||||
{
|
{
|
||||||
struct subroutine *called;
|
struct subroutine *called;
|
||||||
enum STATES ret;
|
unsigned int ret;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static enum STATES close();
|
static unsigned int close();
|
||||||
subroutine(enum STATES r);
|
subroutine(unsigned int r);
|
||||||
virtual ~subroutine()
|
virtual ~subroutine()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
13
tester.cpp
13
tester.cpp
@@ -247,8 +247,7 @@ void shutDown()
|
|||||||
{
|
{
|
||||||
if (errorLevel != E_OK) cerr << "\nERROR: "
|
if (errorLevel != E_OK) cerr << "\nERROR: "
|
||||||
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
|
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
|
||||||
logger("Shutting Down: Purging tempVar queues");
|
logger("Shutting Down");
|
||||||
tempVar::eraseQueues();
|
|
||||||
if (DUMP)
|
if (DUMP)
|
||||||
{
|
{
|
||||||
fn::dumpFunctionIDs();
|
fn::dumpFunctionIDs();
|
||||||
@@ -259,8 +258,11 @@ void shutDown()
|
|||||||
<< " has ID " << iter->second->getID() << "\n";
|
<< " has ID " << iter->second->getID() << "\n";
|
||||||
}
|
}
|
||||||
varNames << endl;
|
varNames << endl;
|
||||||
label::dumpLabels();
|
label::dumpLabels();
|
||||||
}
|
}
|
||||||
|
globals.clear();
|
||||||
|
locals.clear();
|
||||||
|
statics.clear();
|
||||||
if (COMPILE)
|
if (COMPILE)
|
||||||
{
|
{
|
||||||
output_cpp << "default:\nstate=UNDEFINED_STATE_ERROR;\n"
|
output_cpp << "default:\nstate=UNDEFINED_STATE_ERROR;\n"
|
||||||
@@ -269,9 +271,7 @@ void shutDown()
|
|||||||
consts_h.flush();
|
consts_h.flush();
|
||||||
heap_h.flush();
|
heap_h.flush();
|
||||||
}
|
}
|
||||||
globals.clear();
|
tempVar::eraseQueues();
|
||||||
locals.clear();
|
|
||||||
statics.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variableType *v;
|
variableType *v;
|
||||||
@@ -365,6 +365,7 @@ void compile()
|
|||||||
testString();
|
testString();
|
||||||
testFloat();
|
testFloat();
|
||||||
testFunc();
|
testFunc();
|
||||||
|
logger("generating end");
|
||||||
label::generateEnd();
|
label::generateEnd();
|
||||||
/*check for nesting error */
|
/*check for nesting error */
|
||||||
if (!scopeGlobal) error(E_END_FUNCTION);
|
if (!scopeGlobal) error(E_END_FUNCTION);
|
||||||
|
|||||||
@@ -246,8 +246,7 @@ void shutDown()
|
|||||||
{
|
{
|
||||||
if (errorLevel != E_OK) cerr << "\nERROR: "
|
if (errorLevel != E_OK) cerr << "\nERROR: "
|
||||||
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
|
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
|
||||||
logger("Purging tempVar queues");
|
logger("Shutting Down\n");
|
||||||
tempVar::eraseQueues();
|
|
||||||
if (DUMP)
|
if (DUMP)
|
||||||
{
|
{
|
||||||
varNames << "Global Variables\n";
|
varNames << "Global Variables\n";
|
||||||
@@ -257,7 +256,7 @@ void shutDown()
|
|||||||
<< " has ID " << iter->second->getID() << "\n";
|
<< " has ID " << iter->second->getID() << "\n";
|
||||||
}
|
}
|
||||||
varNames << endl;
|
varNames << endl;
|
||||||
label::dumpLabels();
|
label::dumpLabels();
|
||||||
}
|
}
|
||||||
if (COMPILE)
|
if (COMPILE)
|
||||||
{
|
{
|
||||||
@@ -270,6 +269,7 @@ void shutDown()
|
|||||||
globals.clear();
|
globals.clear();
|
||||||
locals.clear();
|
locals.clear();
|
||||||
statics.clear();
|
statics.clear();
|
||||||
|
tempVar::eraseQueues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open files and compile */
|
/* open files and compile */
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ public:
|
|||||||
virtual string boxName();
|
virtual string boxName();
|
||||||
static enum TYPES getSimpleVarType(enum TYPES t);
|
static enum TYPES getSimpleVarType(enum TYPES t);
|
||||||
|
|
||||||
/* abstract factory */
|
|
||||||
static operands *createOp(enum TYPES t);
|
static operands *createOp(enum TYPES t);
|
||||||
virtual void dispose();
|
virtual void dispose();
|
||||||
};
|
};
|
||||||
@@ -410,7 +409,6 @@ class fn
|
|||||||
enum CODES type;
|
enum CODES type;
|
||||||
enum TYPES kind;
|
enum TYPES kind;
|
||||||
operands *rc;
|
operands *rc;
|
||||||
/* two labels common to all subroutine calls */
|
|
||||||
label *startAddr;
|
label *startAddr;
|
||||||
/* stamdard constructor called by declare */
|
/* stamdard constructor called by declare */
|
||||||
fn(enum CODES t, operands *returnCode=nullptr);
|
fn(enum CODES t, operands *returnCode=nullptr);
|
||||||
|
|||||||
@@ -45,13 +45,12 @@ label *label::find(string &s)
|
|||||||
|
|
||||||
void label::dumpLabels()
|
void label::dumpLabels()
|
||||||
{
|
{
|
||||||
varNames << "Global Labels\n\n";
|
varNames << "Global Labels\n" << endl;
|
||||||
for(auto iter=lookup.begin(); iter!=lookup.end(); ++iter)
|
for(auto iter=lookup.begin(); iter!=lookup.end(); ++iter)
|
||||||
{
|
{
|
||||||
varNames << "label " << iter->first << " has ID "
|
varNames << "label " << iter->first << " has ID "
|
||||||
<< iter->second->getID() << "\n" ;
|
<< iter->second->getID() << endl ;
|
||||||
}
|
}
|
||||||
varNames << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void label::generateEnd()
|
void label::generateEnd()
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ void operands::generateBox(enum SCOPES s)
|
|||||||
switch (s)
|
switch (s)
|
||||||
{
|
{
|
||||||
case S_LOCAL:
|
case S_LOCAL:
|
||||||
|
case S_PARAMETER:
|
||||||
funcs_h << ss.str();
|
funcs_h << ss.str();
|
||||||
return;
|
return;
|
||||||
case S_GLOBAL:
|
case S_GLOBAL:
|
||||||
@@ -202,35 +203,38 @@ void tempVar::eraseQueues()
|
|||||||
i=intQueue.back();
|
i=intQueue.back();
|
||||||
if (DUMP)
|
if (DUMP)
|
||||||
{
|
{
|
||||||
logfile << "variable " << i->boxName()
|
varNames << "variable " << i->boxName()
|
||||||
<< " is a temporary integer\n";
|
<< " is a temporary integer" << endl;
|
||||||
}
|
}
|
||||||
delete i;
|
|
||||||
intQueue.pop_back();
|
intQueue.pop_back();
|
||||||
|
delete i;
|
||||||
}
|
}
|
||||||
|
cerr << "intger temps purged" << endl;
|
||||||
while(!floatQueue.empty())
|
while(!floatQueue.empty())
|
||||||
{
|
{
|
||||||
i=floatQueue.back();
|
i=floatQueue.back();
|
||||||
if (DUMP)
|
if (DUMP)
|
||||||
{
|
{
|
||||||
logfile << "variable " << i->boxName()
|
varNames << "variable " << i->boxName()
|
||||||
<< " is a temporary floating point\n";
|
<< " is a temporary floating point" << endl;
|
||||||
}
|
}
|
||||||
delete i;
|
|
||||||
floatQueue.pop_back();
|
floatQueue.pop_back();
|
||||||
|
delete i;
|
||||||
}
|
}
|
||||||
|
cerr << "floating point temps purged" << endl;
|
||||||
while(!stringQueue.empty())
|
while(!stringQueue.empty())
|
||||||
{
|
{
|
||||||
i=stringQueue.back();
|
i=stringQueue.back();
|
||||||
if (DUMP)
|
if (DUMP)
|
||||||
{
|
{
|
||||||
logfile << "variable " << i->boxName()
|
varNames << "variable " << i->boxName()
|
||||||
<< " is a temporary string\n";
|
<< " is a temporary string" << endl;
|
||||||
}
|
}
|
||||||
delete i;
|
|
||||||
stringQueue.pop_back();
|
stringQueue.pop_back();
|
||||||
|
delete i;
|
||||||
}
|
}
|
||||||
if (DUMP) logfile << endl;
|
cerr << "string temps purged" << endl;
|
||||||
|
if (DUMP) varNames << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void constOp::processConst(unsigned int i)
|
void constOp::processConst(unsigned int i)
|
||||||
|
|||||||
@@ -87,11 +87,12 @@ operands *fn::generateCall(string &name, list<operands *>¶mList)
|
|||||||
error(E_TOO_MANY_PARAMETERS);
|
error(E_TOO_MANY_PARAMETERS);
|
||||||
}
|
}
|
||||||
/* TODO CHECK THIS */
|
/* TODO CHECK THIS */
|
||||||
output_cpp << "struct f" << g->getID()
|
heap_h << "struct f" << g->getID()
|
||||||
<< " *sub" << this->getID()
|
<< " *sub" << this->getID() << ";\n";
|
||||||
<< "= new struct f" << g->getID()
|
output_cpp << " sub" << this->getID()
|
||||||
|
<< "= new f" << g->getID()
|
||||||
<< "(" << retAddr->getID() << ");\n"
|
<< "(" << retAddr->getID() << ");\n"
|
||||||
<< "callStack = sub" <<this->getID() << ";\n";
|
<< "callStack = sub" << this->getID() << ";\n";
|
||||||
|
|
||||||
/* TODO Make parameter processing a separate function */
|
/* TODO Make parameter processing a separate function */
|
||||||
while(paramList.size()>0)
|
while(paramList.size()>0)
|
||||||
@@ -143,7 +144,8 @@ void fn::generateReturn(expression *expr)
|
|||||||
logger("expression evaluated");
|
logger("expression evaluated");
|
||||||
this->kind=rc->getSimpleVarType();
|
this->kind=rc->getSimpleVarType();
|
||||||
logger("generating return");
|
logger("generating return");
|
||||||
generateReturn();
|
output_cpp << "state=f" << this->getID()
|
||||||
|
<< "::close();\nbreak;\n";
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
{
|
{
|
||||||
case T_UNKNOWNFUNC:
|
case T_UNKNOWNFUNC:
|
||||||
@@ -189,32 +191,46 @@ void fn::close()
|
|||||||
varNames << "\nLocal variables in function f" << this->getID() << "\n";
|
varNames << "\nLocal variables in function f" << this->getID() << "\n";
|
||||||
if(i==locals.end())
|
if(i==locals.end())
|
||||||
{
|
{
|
||||||
varNames << "no non-static locals\n";
|
varNames << "no non-static locals" << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
varNames << "variable " << i->first << " has id v"
|
varNames << "variable " << i->first << " has id v"
|
||||||
<< i->second.get()->getID() << "\n";
|
<< i->second.get()->getID() << endl;
|
||||||
++i;
|
++i;
|
||||||
}while(i!=locals.end());
|
}while(i!=locals.end());
|
||||||
}
|
}
|
||||||
i=statics.begin();
|
i=statics.begin();
|
||||||
varNames << "\n Static locals in function f" << this->getID() << "\n";
|
varNames << "\nStatic locals in function f" << this->getID() << "\n";
|
||||||
if (i==statics.end())
|
if (i==statics.end())
|
||||||
{
|
{
|
||||||
varNames << "no static locals\n";
|
varNames << "no static locals" << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
varNames << "variable " << i->first << " has id v"
|
varNames << "variable " << i->first << " has id v"
|
||||||
<< i->second.get()->getID() << "\n";
|
<< i->second.get()->getID() << endl;
|
||||||
++i;
|
++i;
|
||||||
} while (i!=statics.end());
|
} while (i!=statics.end());
|
||||||
}
|
}
|
||||||
|
auto iter=this->parameters.begin();
|
||||||
|
if (iter==this->parameters.end())
|
||||||
|
{
|
||||||
|
varNames << "no parameters passed to function f" << this->getID() << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
varNames << "paramater " << iter->first << "has id v"
|
||||||
|
<< iter->second->getID() << endl;
|
||||||
|
} while (iter!=this->parameters.end());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
locals.clear();
|
locals.clear();
|
||||||
statics.clear();
|
statics.clear();
|
||||||
@@ -246,7 +262,12 @@ fn::fn(enum CODES t, operands *returnCode)
|
|||||||
this->type=t;
|
this->type=t;
|
||||||
this->id= ++nextID;
|
this->id= ++nextID;
|
||||||
/*define storage for locals*/
|
/*define storage for locals*/
|
||||||
if (t!=T_GOSUB) funcs_h << "struct f" << this->id <<":public subroutine\n{\n";
|
if (t!=T_GOSUB)
|
||||||
|
{
|
||||||
|
funcs_h << "struct f" << this->id <<":public subroutine\n{\nf"
|
||||||
|
<< this->id << "(unsigned int x):subroutine(x)\n{}\n"
|
||||||
|
<< "virtual ~f" << this->id <<"()\n{}\n\n";
|
||||||
|
}
|
||||||
/*keep track of where the return code will be sent to*/
|
/*keep track of where the return code will be sent to*/
|
||||||
this->rc=returnCode;
|
this->rc=returnCode;
|
||||||
/*allocate and generate start address label*/
|
/*allocate and generate start address label*/
|
||||||
|
|||||||
Reference in New Issue
Block a user