removed most of the shared_ptr usage and retooled temporary variables to recycle
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user