2021-03-13 16:49:58 -06:00
|
|
|
/*
|
|
|
|
** Yab2Cpp
|
|
|
|
**
|
|
|
|
** Transpiler by Samuel D. Crow
|
|
|
|
**
|
|
|
|
** Based on Yab
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
#include "yab2cpp.h"
|
|
|
|
|
2021-03-19 19:26:10 -05:00
|
|
|
/* forward declaration and static initializers */
|
2021-03-16 17:01:28 -05:00
|
|
|
class fn;
|
2021-03-19 19:26:10 -05:00
|
|
|
unsigned int operands::nextID;
|
|
|
|
unordered_map<string, unsigned int> constOp::strConst;
|
2021-03-16 17:01:28 -05:00
|
|
|
|
2021-03-17 18:56:14 -05:00
|
|
|
/* scope methods */
|
|
|
|
ofstream &scope::operator<<(ostream &in)
|
|
|
|
{
|
|
|
|
switch (this->myscope)
|
|
|
|
{
|
|
|
|
case S_LOCAL:
|
|
|
|
return funcs_h;
|
|
|
|
case S_GLOBAL:
|
|
|
|
case S_STATIC:
|
|
|
|
return heap_h;
|
2021-03-23 15:25:59 -05:00
|
|
|
default:
|
|
|
|
break;
|
2021-03-17 18:56:14 -05:00
|
|
|
}
|
2021-03-23 15:25:59 -05:00
|
|
|
error(E_INTERNAL);
|
2021-03-17 18:56:14 -05:00
|
|
|
}
|
|
|
|
|
2021-03-13 16:49:58 -06:00
|
|
|
/* methods for operands */
|
|
|
|
enum TYPES operands::getSimpleVarType()
|
|
|
|
{
|
2021-03-16 17:01:28 -05:00
|
|
|
switch (this->getType())
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
|
|
|
case T_FLOAT:
|
|
|
|
case T_FLOATCALL_ARRAY:
|
|
|
|
case T_FLOATVAR:
|
|
|
|
return T_FLOATVAR;
|
|
|
|
case T_INT:
|
|
|
|
case T_INTCALL_ARRAY:
|
|
|
|
case T_INTVAR:
|
|
|
|
return T_INTVAR;
|
|
|
|
case T_STRING:
|
|
|
|
case T_STRINGCALL_ARRAY:
|
|
|
|
case T_STRINGVAR:
|
|
|
|
return T_STRINGVAR;
|
2021-03-23 15:25:59 -05:00
|
|
|
default:
|
|
|
|
break;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
2021-03-15 14:04:53 -05:00
|
|
|
error(E_UNASSIGNABLE_TYPE);
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/* operands used by expression parser and variables */
|
|
|
|
|
|
|
|
operands::operands(enum TYPES t)
|
|
|
|
{
|
|
|
|
this->id = ++nextID;
|
|
|
|
this->type=t;
|
|
|
|
}
|
|
|
|
|
2021-03-17 18:56:14 -05:00
|
|
|
void operands::generateBox(enum SCOPES s)
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
2021-03-17 18:56:14 -05:00
|
|
|
string x;
|
|
|
|
scope y(s);
|
|
|
|
stringstream ss;
|
2021-03-13 16:49:58 -06:00
|
|
|
switch (this->getSimpleVarType())
|
|
|
|
{
|
|
|
|
case T_INTVAR:
|
2021-03-17 18:56:14 -05:00
|
|
|
ss << "int v";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case T_FLOATVAR:
|
2021-03-17 18:56:14 -05:00
|
|
|
ss << "double v";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case T_STRINGVAR:
|
2021-03-17 18:56:14 -05:00
|
|
|
ss << "string v";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
default:
|
2021-03-17 18:56:14 -05:00
|
|
|
error(E_TYPE_MISMATCH);
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
2021-03-17 18:56:14 -05:00
|
|
|
ss << this->getID() << ";\n";
|
|
|
|
ss.str(x);
|
|
|
|
y << x;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
|
2021-03-16 17:01:28 -05:00
|
|
|
string operands::boxName()
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
2021-03-16 17:01:28 -05:00
|
|
|
ostringstream s;
|
2021-03-17 18:56:14 -05:00
|
|
|
string x;
|
2021-03-13 16:49:58 -06:00
|
|
|
switch (this->getType())
|
|
|
|
{
|
|
|
|
case T_STRINGVAR:
|
|
|
|
case T_INTVAR:
|
|
|
|
case T_FLOATVAR:
|
2021-03-16 17:01:28 -05:00
|
|
|
s << 'v' << this->getID();
|
2021-03-17 18:56:14 -05:00
|
|
|
s.str(x);
|
|
|
|
s.clear();
|
|
|
|
return x;
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2021-03-15 14:04:53 -05:00
|
|
|
error(E_INTERNAL);
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-17 18:56:14 -05:00
|
|
|
void constOp::processConst(unsigned int i)
|
|
|
|
{
|
|
|
|
stringstream me;
|
|
|
|
me << 'k' << i;
|
|
|
|
me.str(box);
|
|
|
|
}
|
|
|
|
|
|
|
|
void constOp::processConst( const string &s)
|
|
|
|
{
|
|
|
|
processConst(getID());
|
|
|
|
consts_h << box << "=" << s << ";\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* constructor for constOp */
|
|
|
|
constOp::constOp(const string &s, enum TYPES t):operands(t)
|
|
|
|
{
|
2021-03-19 19:26:10 -05:00
|
|
|
/* make sure string folder is initialized */
|
|
|
|
unordered_map<string, shared_ptr<operands> >strConst;
|
2021-03-17 18:56:14 -05:00
|
|
|
switch (t)
|
|
|
|
{
|
|
|
|
case T_INT:
|
|
|
|
consts_h << "const int ";
|
|
|
|
processConst(s);
|
|
|
|
break;
|
|
|
|
case T_FLOAT:
|
|
|
|
consts_h << "const double ";
|
|
|
|
processConst(s);
|
|
|
|
break;
|
|
|
|
case T_STRING:
|
|
|
|
{
|
2021-03-19 19:26:10 -05:00
|
|
|
auto i=constOp::strConst.find(s);
|
|
|
|
if (i!=constOp::strConst.end())
|
2021-03-17 18:56:14 -05:00
|
|
|
{
|
|
|
|
processConst((*i).second);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
consts_h << "const string ";
|
|
|
|
processConst(s);
|
2021-03-19 19:26:10 -05:00
|
|
|
constOp::strConst[s]=getID();
|
2021-03-17 18:56:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error(E_TYPE_MISMATCH);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-13 16:49:58 -06:00
|
|
|
/* expression parsing routines */
|
|
|
|
|
|
|
|
/* binary vs. unary ops */
|
|
|
|
bool expression::isBinOp()
|
|
|
|
{
|
2021-03-16 17:01:28 -05:00
|
|
|
switch (this->getOp())
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
2021-03-23 15:25:59 -05:00
|
|
|
/* fallthrough for multiselect */
|
2021-03-13 16:49:58 -06:00
|
|
|
case O_NEGATE:
|
|
|
|
case O_NOT:
|
|
|
|
case O_INVERT:
|
2021-03-15 14:04:53 -05:00
|
|
|
case O_INT_TO_FLOAT:
|
2021-03-13 16:49:58 -06:00
|
|
|
return false;
|
2021-03-23 15:25:59 -05:00
|
|
|
default:
|
|
|
|
return true;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
2021-03-23 15:25:59 -05:00
|
|
|
/* unreachable code */
|
|
|
|
error(E_INTERNAL);
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
|
2021-03-16 17:01:28 -05:00
|
|
|
shared_ptr<operands>expression::evaluate()
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
|
|
|
if (this->getOp()==O_TERM) return op;
|
2021-03-16 17:01:28 -05:00
|
|
|
shared_ptr<operands>l;
|
|
|
|
shared_ptr<operands>r;
|
2021-03-13 16:49:58 -06:00
|
|
|
enum TYPES t;
|
2021-03-17 18:56:14 -05:00
|
|
|
enum SCOPES scopeVar=(scopeGlobal?S_GLOBAL:S_LOCAL);
|
2021-03-13 16:49:58 -06:00
|
|
|
l=this->getLeft()->evaluate();
|
|
|
|
if (this->isBinOp())
|
|
|
|
{
|
|
|
|
r=this->getRight()->evaluate();
|
2021-03-15 14:04:53 -05:00
|
|
|
enum TYPES lt=l->getSimpleVarType();
|
|
|
|
enum TYPES rt=r->getSimpleVarType();
|
|
|
|
if (lt==T_INTVAR && rt==T_FLOATVAR)
|
|
|
|
{
|
2021-03-23 15:25:59 -05:00
|
|
|
l=shared_ptr<operands>((new expression(shared_ptr<expression>(
|
|
|
|
new expression(l)), O_INT_TO_FLOAT))->evaluate());
|
2021-03-15 14:04:53 -05:00
|
|
|
lt=T_FLOATVAR;
|
|
|
|
}
|
|
|
|
if (lt==T_FLOATVAR && rt==T_INTVAR)
|
|
|
|
{
|
2021-03-23 15:25:59 -05:00
|
|
|
r=shared_ptr<operands>((new expression(shared_ptr<expression>(
|
|
|
|
new expression(r)), O_INT_TO_FLOAT))->evaluate());
|
2021-03-15 14:04:53 -05:00
|
|
|
rt=T_FLOATVAR;
|
|
|
|
}
|
|
|
|
if (lt!=rt)error(E_TYPE_MISMATCH);
|
|
|
|
t=lt;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t=l->getSimpleVarType();
|
|
|
|
r=NULL;
|
|
|
|
}
|
|
|
|
switch (this->getOp())
|
|
|
|
{
|
2021-03-23 15:25:59 -05:00
|
|
|
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);
|
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "+" << r->boxName();
|
|
|
|
break;
|
2021-03-13 16:49:58 -06:00
|
|
|
case O_INVERT:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-13 16:49:58 -06:00
|
|
|
output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n";
|
|
|
|
break;
|
|
|
|
case O_NEGATE:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-13 16:49:58 -06:00
|
|
|
output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n";
|
|
|
|
break;
|
|
|
|
case O_NOT:
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-13 16:49:58 -06:00
|
|
|
output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n";
|
|
|
|
break;
|
2021-03-15 14:04:53 -05:00
|
|
|
case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_FLOATVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-15 14:04:53 -05:00
|
|
|
output_cpp << this->op->boxName() << "= const_cast<double>("
|
|
|
|
<< l->boxName() << ");\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
/* TODO: Check for divide by zero error and modulo zero error */
|
|
|
|
case O_REMAINDER:
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "%" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_DIVIDE:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "/" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_PLUS:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "+" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_MINUS:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "-" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_MULTIPLY:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(t));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "*" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_OR:
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "|" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_AND:
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=" << l->boxName()
|
|
|
|
<< "&" << r->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_GREATER:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< ">" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_LESS:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< "<" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_GREATER_EQUAL:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< ">=" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_LESS_EQUAL:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< "<=" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_EQUAL:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< "==" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
case O_UNEQUAL:
|
2021-03-16 17:01:28 -05:00
|
|
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
2021-03-17 18:56:14 -05:00
|
|
|
this->op->generateBox(scopeVar);
|
2021-03-23 15:25:59 -05:00
|
|
|
output_cpp << this->op->boxName() << "=(" << l->boxName()
|
|
|
|
<< "!=" << r->boxName() << ")?-1:0;\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errorLevel=E_INTERNAL;
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* convert expression into single operand */
|
|
|
|
this->oper=O_TERM;
|
|
|
|
return this->op;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* variable definitions */
|
2021-03-24 12:47:00 -05:00
|
|
|
variableType::variableType(enum SCOPES s, string &name, enum TYPES t):operands(t)
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
2021-03-17 18:56:14 -05:00
|
|
|
this->myScope=s;
|
|
|
|
switch (s)
|
|
|
|
{
|
|
|
|
case S_LOCAL:
|
2021-03-19 19:26:10 -05:00
|
|
|
if(locals.find(name)!=locals.end() ||
|
|
|
|
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
|
2021-03-24 12:47:00 -05:00
|
|
|
locals[name]=shared_ptr<variableType>(this);
|
2021-03-17 18:56:14 -05:00
|
|
|
break;
|
|
|
|
case S_GLOBAL:
|
2021-03-19 19:26:10 -05:00
|
|
|
if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL);
|
2021-03-24 12:47:00 -05:00
|
|
|
globals[name]=shared_ptr<variableType>(this);
|
2021-03-17 18:56:14 -05:00
|
|
|
break;
|
|
|
|
case S_STATIC:
|
2021-03-19 19:26:10 -05:00
|
|
|
if(locals.find(name)!=locals.end() ||
|
|
|
|
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
|
2021-03-24 12:47:00 -05:00
|
|
|
statics[name]=shared_ptr<variableType>(this);
|
2021-03-17 18:56:14 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error(E_INTERNAL);
|
|
|
|
}
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
|
2021-03-24 12:47:00 -05:00
|
|
|
shared_ptr<variableType> variableType::getOrCreateVar(string &name, enum TYPES t)
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
|
|
|
if (!scopeGlobal)
|
|
|
|
{
|
2021-03-19 19:26:10 -05:00
|
|
|
auto i=locals.find(name);
|
|
|
|
if(i!=locals.end())return i->second;
|
|
|
|
i=statics.find(name);
|
|
|
|
if(i!=statics.end())return i->second;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
2021-03-19 19:26:10 -05:00
|
|
|
if (globals.find(name)!=globals.end())return globals[name];
|
2021-03-24 12:47:00 -05:00
|
|
|
shared_ptr<variableType>v=shared_ptr<variableType>(new variableType(
|
2021-03-24 09:28:03 -05:00
|
|
|
scopeGlobal?S_GLOBAL:S_LOCAL, name, t));
|
|
|
|
v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
|
|
|
|
return v;
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
|
2021-03-24 12:47:00 -05:00
|
|
|
void variableType::assignment(shared_ptr<expression>value)
|
2021-03-13 16:49:58 -06:00
|
|
|
{
|
2021-03-16 17:01:28 -05:00
|
|
|
shared_ptr<operands>op=value->evaluate();
|
2021-03-13 16:49:58 -06:00
|
|
|
enum TYPES t=op->getSimpleVarType();
|
|
|
|
switch (this->getType())
|
|
|
|
{
|
|
|
|
case T_FLOATVAR:
|
|
|
|
if (t==T_INTVAR)
|
|
|
|
{
|
2021-03-15 14:04:53 -05:00
|
|
|
output_cpp << this->boxName() << "="
|
|
|
|
<< "static_cast<double>("
|
|
|
|
<< op->boxName() << ");\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
2021-03-13 16:49:58 -06:00
|
|
|
}
|
2021-03-15 14:04:53 -05:00
|
|
|
output_cpp << this->boxName() << "="
|
|
|
|
<< op->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
default:
|
2021-03-15 14:04:53 -05:00
|
|
|
if (t!=this->getType()) error(E_TYPE_MISMATCH);
|
|
|
|
output_cpp << this->boxName() << "="
|
|
|
|
<< op->boxName() << ";\n";
|
2021-03-13 16:49:58 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-03-24 09:28:03 -05:00
|
|
|
|
2021-03-24 10:17:01 -05:00
|
|
|
string arrayType::boxName(list<shared_ptr<operands> >indexes)
|
2021-03-24 09:28:03 -05:00
|
|
|
{
|
|
|
|
ostringstream out;
|
|
|
|
string buf;
|
|
|
|
auto i=indexes.begin();
|
|
|
|
out << 'v' << this->getID();
|
|
|
|
while (i!=indexes.end())
|
|
|
|
{
|
2021-03-24 10:17:01 -05:00
|
|
|
out << '[' << (*i)->boxName() << ']';
|
|
|
|
++i;
|
2021-03-24 09:28:03 -05:00
|
|
|
}
|
|
|
|
out.str(buf);
|
|
|
|
out.clear();
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
string arrayType::generateBox(enum SCOPES s)
|
|
|
|
{
|
|
|
|
ostringstream out;
|
|
|
|
string buf;
|
|
|
|
switch (this->getType())
|
|
|
|
{
|
|
|
|
case T_STRINGCALL_ARRAY:
|
|
|
|
out << "string ";
|
|
|
|
break;
|
|
|
|
case T_INTCALL_ARRAY:
|
|
|
|
out << "int ";
|
|
|
|
break;
|
|
|
|
case T_FLOATCALL_ARRAY:
|
|
|
|
out << "double ";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error(E_INTERNAL);
|
|
|
|
}
|
2021-03-24 10:17:01 -05:00
|
|
|
out << 'v' << this->getID();
|
|
|
|
for (auto i=dimensions.begin();i!=dimensions.end();++i)
|
|
|
|
{
|
|
|
|
out << '[' << *i << ']';
|
|
|
|
}
|
|
|
|
out << ";\n";
|
2021-03-24 09:28:03 -05:00
|
|
|
out.str(buf);
|
|
|
|
out.clear();
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
|
2021-03-24 12:47:00 -05:00
|
|
|
variableType(S_GLOBAL, name, t)
|
2021-03-24 09:28:03 -05:00
|
|
|
{
|
|
|
|
this->dimensions=dim;
|
2021-03-24 10:17:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void arrayType::assignment(list<shared_ptr<expression> >indexes,
|
|
|
|
shared_ptr<expression>value)
|
|
|
|
{
|
|
|
|
list<shared_ptr<operands>>x;
|
|
|
|
shared_ptr<operands>op=value->evaluate();
|
|
|
|
enum TYPES t=op->getSimpleVarType();
|
|
|
|
auto i=indexes.begin();
|
|
|
|
while(i!=indexes.end())
|
|
|
|
{
|
|
|
|
x.push_back((*i)->evaluate());
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
switch (this->getType())
|
|
|
|
{
|
|
|
|
case T_FLOATCALL_ARRAY:
|
|
|
|
if (t==T_INTVAR)
|
|
|
|
{
|
|
|
|
output_cpp << this->boxName(x)
|
|
|
|
<< "=static_cast<double>("
|
|
|
|
<< op->boxName() << ");\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (t!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
|
|
|
break;
|
|
|
|
case T_INTCALL_ARRAY:
|
|
|
|
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
|
|
|
|
break;
|
|
|
|
case T_STRINGCALL_ARRAY:
|
|
|
|
if (t!=T_STRINGVAR) error(E_TYPE_MISMATCH);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error(E_INTERNAL);
|
|
|
|
}
|
|
|
|
output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n";
|
|
|
|
}
|