removed most of the shared_ptr usage and retooled temporary variables to recycle

This commit is contained in:
Samuel D. Crow
2021-03-28 22:35:35 -05:00
parent fd89b1a054
commit bb2be9c16c
7 changed files with 452 additions and 291 deletions

View File

@@ -12,11 +12,15 @@
class fn;
unsigned int operands::nextID=0;
unordered_map<string, unsigned int> constOp::strConst;
list<tempVar *>tempVar::intQueue;
list<tempVar *>tempVar::floatQueue;
list<tempVar *>tempVar::stringQueue;
/* methods for operands */
enum TYPES operands::getSimpleVarType()
enum TYPES operands::getSimpleVarType(enum TYPES t)
{
switch (this->getType())
switch (t)
{
case T_FLOAT:
case T_FLOATCALL_ARRAY:
@@ -36,8 +40,12 @@ enum TYPES operands::getSimpleVarType()
error(E_UNASSIGNABLE_TYPE);
}
/* operands used by expression parser and variables */
enum TYPES operands::getSimpleVarType()
{
return getSimpleVarType(this->getType());
}
/* operands used by expression parser and variables */
operands::operands(enum TYPES t)
{
this->id = ++nextID;
@@ -77,6 +85,22 @@ void operands::generateBox(enum SCOPES s)
error(E_INTERNAL);
}
operands *operands::createOp(enum TYPES t)
{
if (DEBUG)
{
operands *x=createOp(t);
x->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
return x;
}
return tempVar::getOrCreateVar(t);
}
void operands::dispose()
{
delete this;
}
string operands::boxName()
{
ostringstream s;
@@ -97,6 +121,119 @@ string operands::boxName()
}
}
tempVar::tempVar(enum TYPES t):operands(t)
{
generateBox(S_GLOBAL);
}
tempVar *tempVar::getOrCreateVar(enum TYPES t)
{
if (t!=getSimpleVarType(t))
{
error(E_TYPE_MISMATCH);
}
switch (t)
{
case T_INTVAR:
if (intQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=intQueue.back();
intQueue.pop_back();
return x;
}
break;
case T_FLOATVAR:
if (floatQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=floatQueue.back();
floatQueue.pop_back();
return x;
}
break;
case T_STRINGVAR:
if (stringQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=stringQueue.back();
stringQueue.pop_back();
return x;
}
default:
break;
}
/* unreachable code */
error(E_INTERNAL);
}
void tempVar::dispose()
{
switch(this->getType())
{
case T_STRINGVAR:
stringQueue.emplace_front(this);
return;
case T_FLOATVAR:
floatQueue.emplace_front(this);
return;
case T_INTVAR:
intQueue.emplace_front(this);
return;
default:
break;
}
error(E_INTERNAL);
}
void tempVar::eraseQueues()
{
tempVar *i;
while(!intQueue.empty())
{
i=intQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary integer\n";
}
delete i;
intQueue.pop_back();
}
while(!floatQueue.empty())
{
i=floatQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary floating point\n";
}
delete i;
floatQueue.pop_back();
}
while(!stringQueue.empty())
{
i=stringQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary string\n";
}
delete i;
stringQueue.pop_back();
}
if (DUMP) logfile << endl;
}
void constOp::processConst(unsigned int i)
{
stringstream me;
@@ -136,7 +273,8 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
else
{
consts_h << "const string ";
processConst(s);
processConst(getID());
consts_h << box << "=\"" << s << "\";\n";
constOp::strConst[s]=getID();
}
}
@@ -148,6 +286,18 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
}
/* expression parsing routines */
expression::expression(expression *l, enum OPERATORS o, expression *r)
{
this->left=l;
this->right=r;
this->oper=o;
}
expression::expression(operands *x)
{
op=x;
oper=O_TERM;
}
/* binary vs. unary ops */
bool expression::isBinOp()
@@ -167,13 +317,12 @@ bool expression::isBinOp()
error(E_INTERNAL);
}
shared_ptr<operands>expression::evaluate()
operands *expression::evaluate()
{
if (this->getOp()==O_TERM) return op;
shared_ptr<operands>l;
shared_ptr<operands>r;
operands *l;
operands *r;
enum TYPES t;
enum SCOPES scopeVar=(scopeGlobal?S_GLOBAL:S_LOCAL);
l=this->getLeft()->evaluate();
if (this->isBinOp())
{
@@ -182,14 +331,12 @@ shared_ptr<operands>expression::evaluate()
enum TYPES rt=r->getSimpleVarType();
if (lt==T_INTVAR && rt==T_FLOATVAR)
{
l=shared_ptr<operands>((new expression(shared_ptr<expression>(
new expression(l)), O_INT_TO_FLOAT))->evaluate());
l=(new expression(new expression(l), O_INT_TO_FLOAT))->evaluate();
lt=T_FLOATVAR;
}
if (lt==T_FLOATVAR && rt==T_INTVAR)
{
r=shared_ptr<operands>((new expression(shared_ptr<expression>(
new expression(r)), O_INT_TO_FLOAT))->evaluate());
r=(new expression(new expression(r), O_INT_TO_FLOAT))->evaluate();
rt=T_FLOATVAR;
}
if (lt!=rt)error(E_TYPE_MISMATCH);
@@ -198,127 +345,111 @@ shared_ptr<operands>expression::evaluate()
else
{
t=l->getSimpleVarType();
r=NULL;
r=nullptr;
}
switch (this->getOp())
{
case O_STRING_CONCAT:
if (t!=T_STRINGVAR) error(E_BAD_SYNTAX);
this->op=shared_ptr<operands>(new operands(T_STRINGVAR));
this->op->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
this->op=operands::createOp(T_STRINGVAR);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "+" << r->boxName();
break;
case O_INVERT:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n";
break;
case O_NEGATE:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n";
break;
case O_NOT:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n";
break;
case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */
this->op=shared_ptr<operands>(new operands(T_FLOATVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_FLOATVAR);
output_cpp << this->op->boxName() << "= const_cast<double>("
<< l->boxName() << ");\n";
/* TODO: Check for divide by zero error and modulo zero error */
case O_REMAINDER:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "%" << r->boxName() << ";\n";
break;
case O_DIVIDE:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "/" << r->boxName() << ";\n";
break;
case O_PLUS:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "+" << r->boxName() << ";\n";
break;
case O_MINUS:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "-" << r->boxName() << ";\n";
break;
case O_MULTIPLY:
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scopeVar);
this->op=operands::createOp(t);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "*" << r->boxName() << ";\n";
break;
case O_OR:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "|" << r->boxName() << ";\n";
break;
case O_AND:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=" << l->boxName()
<< "&" << r->boxName() << ";\n";
break;
case O_GREATER:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< ">" << r->boxName() << ")?-1:0;\n";
break;
case O_LESS:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "<" << r->boxName() << ")?-1:0;\n";
break;
case O_GREATER_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< ">=" << r->boxName() << ")?-1:0;\n";
break;
case O_LESS_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "<=" << r->boxName() << ")?-1:0;\n";
break;
case O_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "==" << r->boxName() << ")?-1:0;\n";
break;
case O_UNEQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scopeVar);
this->op=operands::createOp(T_INTVAR);
output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "!=" << r->boxName() << ")?-1:0;\n";
break;
default:
errorLevel=E_INTERNAL;
exit(1);
break;
error(E_INTERNAL);
}
/* convert expression into single operand */
this->oper=O_TERM;
l->dispose();
delete left;
r->dispose();
delete right;
return this->op;
}
@@ -331,41 +462,40 @@ variableType::variableType(enum SCOPES s, string &name, enum TYPES t):operands(t
case S_LOCAL:
if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
locals[name]=shared_ptr<variableType>(this);
locals[name]=unique_ptr<variableType>(this);
break;
case S_GLOBAL:
if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL);
globals[name]=shared_ptr<variableType>(this);
globals[name]=unique_ptr<variableType>(this);
break;
case S_STATIC:
if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
statics[name]=shared_ptr<variableType>(this);
statics[name]=unique_ptr<variableType>(this);
break;
default:
error(E_INTERNAL);
}
}
shared_ptr<variableType> variableType::getOrCreateVar(string &name, enum TYPES t)
variableType *variableType::getOrCreateVar(string &name, enum TYPES t)
{
if (!scopeGlobal)
{
auto i=locals.find(name);
if(i!=locals.end())return i->second;
if(i!=locals.end())return i->second.get();
i=statics.find(name);
if(i!=statics.end())return i->second;
if(i!=statics.end())return i->second.get();
}
if (globals.find(name)!=globals.end())return globals[name];
shared_ptr<variableType>v=shared_ptr<variableType>(new variableType(
scopeGlobal?S_GLOBAL:S_LOCAL, name, t));
if (globals.find(name)!=globals.end())return globals[name].get();
variableType *v=new variableType(scopeGlobal?S_GLOBAL:S_LOCAL, name, t);
v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
return v;
}
void variableType::assignment(shared_ptr<expression>value)
void variableType::assignment(expression *value)
{
shared_ptr<operands>op=value->evaluate();
operands *op=value->evaluate();
enum TYPES t=op->getSimpleVarType();
switch (this->getType())
{
@@ -389,9 +519,11 @@ void variableType::assignment(shared_ptr<expression>value)
<< op->boxName() << ";\n";
break;
}
op->dispose();
delete value;
}
string arrayType::boxName(list<shared_ptr<operands> >indexes)
string arrayType::boxName(list<operands *>indexes)
{
ostringstream out;
auto i=indexes.begin();
@@ -436,11 +568,10 @@ arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
this->dimensions=dim;
}
void arrayType::assignment(list<shared_ptr<expression> >indexes,
shared_ptr<expression>value)
void arrayType::assignment(list<expression *>indexes, expression *value)
{
list<shared_ptr<operands>>x;
shared_ptr<operands>op=value->evaluate();
list<operands *>x;
operands *op=value->evaluate();
enum TYPES t=op->getSimpleVarType();
auto i=indexes.begin();
while(i!=indexes.end())
@@ -470,4 +601,6 @@ void arrayType::assignment(list<shared_ptr<expression> >indexes,
error(E_INTERNAL);
}
output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n";
op->dispose();
delete value;
}