Fixed subroutine bugs

This commit is contained in:
Samuel D. Crow
2021-04-16 18:56:10 -05:00
parent ca08646b93
commit 9ddac1afd6
8 changed files with 64 additions and 41 deletions

View File

@@ -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;

View File

@@ -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()
{} {}
}; };

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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()

View File

@@ -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)

View File

@@ -87,11 +87,12 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
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*/