split yab2cpp.cpp into 2 parts, finished for loop and started variables
This commit is contained in:
309
yab2cpp.cpp
309
yab2cpp.cpp
@@ -1,18 +1,25 @@
|
|||||||
|
/*
|
||||||
|
** Yab2Cpp
|
||||||
|
**
|
||||||
|
** Transpiler by Samuel D. Crow
|
||||||
|
**
|
||||||
|
** Based on Yab
|
||||||
|
**
|
||||||
|
*/
|
||||||
#include "yab2cpp.h"
|
#include "yab2cpp.h"
|
||||||
|
|
||||||
enum COMPILEERRORS errorLevel=E_OK;
|
enum COMPILE_ERRORS errorLevel=E_OK;
|
||||||
unsigned int mode=0;
|
unsigned int mode=0;
|
||||||
unsigned int indentLevel=0;
|
unsigned int indentLevel=0;
|
||||||
bool scopeGlobal=true;
|
bool scopeGlobal=true;
|
||||||
|
|
||||||
extern ofstream output_cpp;
|
ifstream src;
|
||||||
extern ofstream funcs_h;
|
ofstream output_cpp;
|
||||||
extern ofstream heap_h;
|
ofstream funcs_h;
|
||||||
extern ofstream consts_h;
|
ofstream heap_h;
|
||||||
extern ofstream logfile;
|
ofstream consts_h;
|
||||||
extern ofstream varNames;
|
ofstream logfile;
|
||||||
|
ofstream varNames;
|
||||||
extern ifstream src;
|
|
||||||
|
|
||||||
/* private prototypes */
|
/* private prototypes */
|
||||||
void helpText(string &);
|
void helpText(string &);
|
||||||
@@ -173,6 +180,7 @@ static void operands::dumpVars(ostream &out)
|
|||||||
}
|
}
|
||||||
out << endl;
|
out << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int operands::getOrCreateStr(ostream &k, string &s)
|
unsigned int operands::getOrCreateStr(ostream &k, string &s)
|
||||||
{
|
{
|
||||||
auto iter=constStr.find(s);
|
auto iter=constStr.find(s);
|
||||||
@@ -288,6 +296,16 @@ void operands::generateBox(ostream &out)
|
|||||||
out << this->getID() << ";\n";
|
out << this->getID() << ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operands *operands::getOrCreateGlobal(ostream &heap, string &s, enum TYPES t)
|
||||||
|
{
|
||||||
|
operands op*=operands::globals->find(s);
|
||||||
|
if (op==globals.end())
|
||||||
|
{
|
||||||
|
op=new variable(heap, s, t);
|
||||||
|
}
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
void operands::boxName(ostream &out)
|
void operands::boxName(ostream &out)
|
||||||
{
|
{
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
@@ -444,259 +462,64 @@ expression::~expression()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* base class of all the code structure types */
|
|
||||||
|
|
||||||
codeType::codeType(enum CODES t)
|
/* variable definitions */
|
||||||
|
variable::variable(ostream &scope, string &name, enum TYPES t):operands(t)
|
||||||
{
|
{
|
||||||
this->id= ++nextID;
|
this->generateBox(scope);
|
||||||
nesting.push_back(this);
|
|
||||||
this->type=t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
codeType *codeType::getCurrent()
|
variable *variable::getOrCreateVarName(ostream &func, ostream &heap, string &name, enum TYPES t)
|
||||||
{
|
{
|
||||||
return nesting.back;
|
variable *v;
|
||||||
|
if (!scopeGlobal)
|
||||||
|
{
|
||||||
|
fn *currentFunc=fn::getCurrentSub();
|
||||||
|
v=fn::getOrCreateVar(func, heap, t, name, false);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<variable *>operands::getOrCreateGlobal(heap, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void codeType::close()
|
void variable::assignment(expression *value)
|
||||||
{
|
{
|
||||||
nesting.pop_back();
|
operands *op=value->evaluate();
|
||||||
}
|
enum TYPES t=op->getSimpleVarType();
|
||||||
|
switch (this->getType())
|
||||||
/* label definitions and helper routines */
|
|
||||||
|
|
||||||
label *label::find(string &s)
|
|
||||||
{
|
{
|
||||||
auto ret=lookup.find(s);
|
case T_FLOATVAR:
|
||||||
return(ret==lookup.end()?NULL:ret->second);
|
if (t==T_INTVAR)
|
||||||
}
|
|
||||||
|
|
||||||
void label::dumpLabels(ostream &v)
|
|
||||||
{
|
{
|
||||||
v << "Global Labels\n\n";
|
/* TODO: convert int to float */
|
||||||
for(auto iter=lookup.begin(); iter!=lookup.end(); ++iter)
|
|
||||||
{
|
|
||||||
v << "label " << iter->first << " has ID " << iter->second->getID() << "\n" ;
|
|
||||||
}
|
|
||||||
v << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void label::generateJumpTo(ostream &out)
|
|
||||||
{
|
|
||||||
out << "state=" << this->getID() << ";\nbreak;\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void label::generateOnNSkip(ostream &k, list<label *> &dest)
|
|
||||||
{
|
|
||||||
if (dest->size()<2)
|
|
||||||
{
|
|
||||||
errorLevel=E_BAD_SYNTAX;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
auto iter=dest.start();
|
|
||||||
k << "j" << this->getID() << "[]={" << *iter;
|
|
||||||
++iter;
|
|
||||||
while(iter!=dest.end())
|
|
||||||
{
|
|
||||||
k << ", " << *iter;
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
k << "}\njs" << this->getID()<< "=" << dest->size() << ";\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void label::generateOnNTo(ostream &out, expression *e)
|
|
||||||
{
|
|
||||||
operands *o=e->evaluate();
|
|
||||||
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
|
||||||
{
|
|
||||||
out << "if(";
|
|
||||||
o->boxName(out);
|
|
||||||
out << ">=0 && ";
|
|
||||||
o->boxName(out);
|
|
||||||
out << "<js" << this->getID() << ")state=j[";
|
|
||||||
o->boxName(out);
|
|
||||||
out << "];\nbreak;\n";
|
|
||||||
}
|
|
||||||
delete e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void label::generateCondJump(ostream &out, expression *e)
|
|
||||||
{
|
|
||||||
operands *o=e->evaluate();
|
|
||||||
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
|
||||||
{
|
|
||||||
out << "if(";
|
|
||||||
o->boxName(out);
|
|
||||||
out << "!=0)state=" << this->getID() << ";\nbreak;\n";
|
|
||||||
}
|
|
||||||
delete e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void label::generate(ostream &out)
|
|
||||||
{
|
|
||||||
out << "case " << this->getID() <<":\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* conditional definition */
|
|
||||||
|
|
||||||
conditional::conditional(ostream &out, expression *e):codeType(T_IF)
|
|
||||||
{
|
|
||||||
this->redo=new label();
|
|
||||||
redo->generate(out);
|
|
||||||
this->done=new label();
|
|
||||||
expression *f=new expression(e,O_NOT);
|
|
||||||
this->chain=new label();
|
|
||||||
chain->generateCondJump(out, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void conditional::generateBreak(ostream &out)
|
|
||||||
{
|
|
||||||
done->generateJumpTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void conditional::generateContinue(ostream &out)
|
|
||||||
{
|
|
||||||
redo->generateJumpTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void conditional::alternative(ostream &out, expression *e=NULL)
|
|
||||||
{
|
|
||||||
done->generateJumpTo(out);
|
|
||||||
this->chain->generate();
|
|
||||||
delete this->chain;
|
|
||||||
this->chain=NULL;
|
|
||||||
if(e!=NULL)
|
|
||||||
{
|
|
||||||
this->chain=new label();
|
|
||||||
expression *f=new expression(e,O_NOT);
|
|
||||||
chain->generateJumpCond(out, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void conditional::close(ostream &out)
|
|
||||||
{
|
|
||||||
if(this->chain)
|
|
||||||
{
|
|
||||||
/* elsif ended without else in between */
|
|
||||||
errorLevel=E_BAD_SYNTAX;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
this->done->generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
conditional::~conditional()
|
|
||||||
{
|
|
||||||
delete this->done;
|
|
||||||
delete this->redo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop definitions */
|
|
||||||
repeatLoop::repeatLoop(ostream &out):codeType(T_REPEATLOOP)
|
|
||||||
{
|
|
||||||
this->loopStart=new label();
|
|
||||||
this->loopEnd=new label();
|
|
||||||
loopStart->generate(out;)
|
|
||||||
}
|
|
||||||
|
|
||||||
void repeatLoop::generateBreak(ostream &out)
|
|
||||||
{
|
|
||||||
loopEnd->generateJumpTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void repeatLoop::close(ostream &out, expression *e)
|
|
||||||
{
|
|
||||||
expression *f=new expression(e, O_NOT);
|
|
||||||
loopStart->generateCondJump(out, f);
|
|
||||||
loopEnd->generate(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
repeatLoop::~repeatLoop()
|
|
||||||
{
|
|
||||||
delete loopStart;
|
|
||||||
delete loopEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
doLoop::doLoop(ostream &out):codeType(T_DOLOOP)
|
|
||||||
{
|
|
||||||
this->loopStart=new label();
|
|
||||||
this->loopEnd=new label();
|
|
||||||
loopStart->generate(out;)
|
|
||||||
}
|
|
||||||
|
|
||||||
void doLoop::generateBreak(ostream &out)
|
|
||||||
{
|
|
||||||
loopEnd->generateJumpTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doLoop::close(ostream &out)
|
|
||||||
{
|
|
||||||
this->loopStart->generateJumpTo(out);
|
|
||||||
this->loopEnd->generate(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
doLoop::~doLoop()
|
|
||||||
{ delete loopStart;
|
|
||||||
delete loopEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
whileLoop::whileLoop(ostream &out, expression *e):codeType(T_WHILELOOP)
|
|
||||||
{
|
|
||||||
loopContinue=new label();
|
|
||||||
loopStart=new label();
|
|
||||||
loopEnd=new label();
|
|
||||||
cond=e;
|
|
||||||
loopStart->generateJumpTo(out);
|
|
||||||
loopContinue->generate(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void whileLoop::generateBreak(ostream &out)
|
|
||||||
{
|
|
||||||
loopEnd->generateJumpTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void whileLoop::close(ostream &out)
|
|
||||||
{
|
|
||||||
loopStart->generate(out);
|
|
||||||
loopContinue->generateJumpCond(out, cond);
|
|
||||||
loopEnd->generate(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
whileLoop::~whileLoop()
|
|
||||||
{
|
|
||||||
delete loopStart;
|
|
||||||
delete loopContinue;
|
|
||||||
delete loopEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: make the stopper into a full range check */
|
|
||||||
forLoop::forLoop(ostream &out, ostream &k, variable *v, expression *start, expression *stop, expression *stepVal=NULL):codeType(T_FORLOOP)
|
|
||||||
{
|
|
||||||
expression *stopper=new expression(new expression (v), O_UNEQUAL, stop);
|
|
||||||
v->assignment(out, start);
|
|
||||||
infrastructure=new whileLoop(out, stopper);
|
|
||||||
if (stepVal)
|
|
||||||
{
|
|
||||||
step=stepVal;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
step=new expression(operands::createConst(k, "1", T_INT));
|
if (t!=T_FLOATVAR)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void forLoop::generateBreak(ostream &out)
|
|
||||||
{
|
{
|
||||||
infrastructure->generateBreak(out);
|
errorLevel=E_TYPE_MISMATCH;
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void forLoop::close(ostream &out)
|
break;
|
||||||
|
default:
|
||||||
|
if (t!=this->getType())
|
||||||
{
|
{
|
||||||
expression *stepper=new expression(new expression(v), O_PLUS, step);
|
errorLevel=E_TYPE_MISMATCH;
|
||||||
v->assignment(out, stepper)
|
exit(1);
|
||||||
infrastructure->close(ostream &out);
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->boxName(output_cpp);
|
||||||
|
output_cpp << "=";
|
||||||
|
op->boxName(output_cpp);
|
||||||
|
output_cpp << ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function definitions */
|
/* function definitions */
|
||||||
|
fn *fn::getCurrentSub()
|
||||||
|
{
|
||||||
|
return callStack.back;
|
||||||
|
}
|
||||||
|
|
||||||
void fn::generateOnNSub(ostream &out, expression *e)
|
void fn::generateOnNSub(ostream &out, expression *e)
|
||||||
{
|
{
|
||||||
|
|||||||
33
yab2cpp.h
33
yab2cpp.h
@@ -20,6 +20,13 @@ using namespace std;
|
|||||||
#define VER_MINOR 0
|
#define VER_MINOR 0
|
||||||
#define VER_RELEASE 1
|
#define VER_RELEASE 1
|
||||||
|
|
||||||
|
extern ofstream output_cpp;
|
||||||
|
extern ofstream funcs_h;
|
||||||
|
extern ofstream heap_h;
|
||||||
|
extern ofstream consts_h;
|
||||||
|
extern ofstream logfile;
|
||||||
|
extern ofstream varNames;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** list of all compiler errors
|
** list of all compiler errors
|
||||||
**
|
**
|
||||||
@@ -36,6 +43,11 @@ enum COMPILE_ERRORS {
|
|||||||
E_DUPLICATE_SYMBOL
|
E_DUPLICATE_SYMBOL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern enum COMPILE_ERRORS errorLevel;
|
||||||
|
extern unsigned int mode;
|
||||||
|
extern unsigned int indentLevel;
|
||||||
|
extern bool scopeGlobal;
|
||||||
|
|
||||||
/* These correspond to the enum COMPILE_ERRORS. */
|
/* These correspond to the enum COMPILE_ERRORS. */
|
||||||
const char *COMPILE_ERROR_NAMES[]={
|
const char *COMPILE_ERROR_NAMES[]={
|
||||||
"no error",
|
"no error",
|
||||||
@@ -170,6 +182,7 @@ public:
|
|||||||
static void dumpVars(ostream &out);
|
static void dumpVars(ostream &out);
|
||||||
static unsigned int getOrCreateStr(ostream &k, string &s);
|
static unsigned int getOrCreateStr(ostream &k, string &s);
|
||||||
static operands *createConst(ostream &k, string &s, enum TYPES t);
|
static operands *createConst(ostream &k, string &s, enum TYPES t);
|
||||||
|
static operands *getOrCreateGlobal(ostream &heap, string &s, enum TYPES t);
|
||||||
|
|
||||||
enum TYPES getSimpleVarType();
|
enum TYPES getSimpleVarType();
|
||||||
void generateBox(ostream &out);
|
void generateBox(ostream &out);
|
||||||
@@ -222,7 +235,8 @@ public:
|
|||||||
enum CODES getType() const {return this->type;}
|
enum CODES getType() const {return this->type;}
|
||||||
unsigned int getID() const {return this->id;}
|
unsigned int getID() const {return this->id;}
|
||||||
|
|
||||||
codeType *getCurrent();
|
static codeType *getCurrent();
|
||||||
|
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void generateBreak(ostream &out)=0;
|
virtual void generateBreak(ostream &out)=0;
|
||||||
|
|
||||||
@@ -272,7 +286,7 @@ public:
|
|||||||
void alternative(ostream &out, expression *e=NULL); /* enable else or elsif condition */
|
void alternative(ostream &out, expression *e=NULL); /* enable else or elsif condition */
|
||||||
virtual void close(ostream &out) override; /* end if */
|
virtual void close(ostream &out) override; /* end if */
|
||||||
|
|
||||||
explicit conditional(expression *e):codeType(T_IF);
|
explicit conditional(ostream &out, expression *e);
|
||||||
virtual ~conditional();
|
virtual ~conditional();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -285,7 +299,7 @@ public:
|
|||||||
virtual void generateBreak(ostream &out) override;
|
virtual void generateBreak(ostream &out) override;
|
||||||
virtual void close(ostream &out, expression *e) override;
|
virtual void close(ostream &out, expression *e) override;
|
||||||
|
|
||||||
explicit repeatLoop(ostream &out):codeType(T_REPEATLOOP);
|
explicit repeatLoop(ostream &out);
|
||||||
virtual ~repeatLoop();
|
virtual ~repeatLoop();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -318,8 +332,10 @@ public:
|
|||||||
class variable:public operands
|
class variable:public operands
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static variable *getOrCreateVarName(ostream &func, ostream &heap, string &name, enum TYPES t);
|
||||||
|
|
||||||
void assignment(ostream &out, expression *value);
|
void assignment(ostream &out, expression *value);
|
||||||
explicit variable(ostream &scope, string &name, enum TYPES t):operands(t);
|
explicit variable(ostream &scope, string &name, enum TYPES t);
|
||||||
virtual variable()
|
virtual variable()
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
@@ -330,7 +346,7 @@ class arrayType:public variable
|
|||||||
public:
|
public:
|
||||||
virtual void boxName(ostream &out, list<unsigned int>indexes) override;
|
virtual void boxName(ostream &out, list<unsigned int>indexes) override;
|
||||||
|
|
||||||
explicit arrayType(ostream &scope, string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/
|
explicit arrayType(ostream &heap, string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/
|
||||||
virtual ~arrayType()
|
virtual ~arrayType()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@@ -338,6 +354,8 @@ public:
|
|||||||
class forLoop:public codeType
|
class forLoop:public codeType
|
||||||
{
|
{
|
||||||
variable *var;
|
variable *var;
|
||||||
|
variable *startTemp;
|
||||||
|
variable *stopTemp;
|
||||||
whileLoop *infrastructure;
|
whileLoop *infrastructure;
|
||||||
expression *step;
|
expression *step;
|
||||||
public:
|
public:
|
||||||
@@ -358,11 +376,12 @@ class fn:codeType
|
|||||||
shared_ptr<label>ret;
|
shared_ptr<label>ret;
|
||||||
unsigned int parameters;
|
unsigned int parameters;
|
||||||
public:
|
public:
|
||||||
|
static variable *getOrCreateVar(ostream &func, ostream &heap, enum TYPES t, string &s, bool stat);
|
||||||
static void dumpCallStack(ostream &out);
|
static void dumpCallStack(ostream &out);
|
||||||
|
static fn *getCurrentSub();
|
||||||
|
|
||||||
void setParameters(unsigned int num) const {this->parameters=num;}
|
void setParameters(unsigned int num) const {this->parameters=num;}
|
||||||
|
|
||||||
void addLocal(operands *);
|
|
||||||
void addStatic(operands *);
|
|
||||||
void generateCall(ostream &out, string &name, unsigned int params);
|
void generateCall(ostream &out, string &name, unsigned int params);
|
||||||
void generateReturn(ostream &out, expression *expr=NULL);
|
void generateReturn(ostream &out, expression *expr=NULL);
|
||||||
void generateGosub(ostream &out, shared_ptr<label> sub);
|
void generateGosub(ostream &out, shared_ptr<label> sub);
|
||||||
|
|||||||
282
yabCodeStructures.cpp
Normal file
282
yabCodeStructures.cpp
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
** Yab2Cpp
|
||||||
|
**
|
||||||
|
** Transpiler by Samuel D. Crow
|
||||||
|
**
|
||||||
|
** Based on Yab
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "yab2cpp.h"
|
||||||
|
|
||||||
|
/* base class of all the code structure types */
|
||||||
|
|
||||||
|
codeType::codeType(enum CODES t)
|
||||||
|
{
|
||||||
|
this->id= ++nextID;
|
||||||
|
nesting.push_back(this);
|
||||||
|
this->type=t;
|
||||||
|
}
|
||||||
|
|
||||||
|
codeType *codeType::getCurrent()
|
||||||
|
{
|
||||||
|
return nesting.back;
|
||||||
|
}
|
||||||
|
|
||||||
|
void codeType::close()
|
||||||
|
{
|
||||||
|
nesting.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* label definitions and helper routines */
|
||||||
|
|
||||||
|
label *label::find(string &s)
|
||||||
|
{
|
||||||
|
auto ret=lookup.find(s);
|
||||||
|
return(ret==lookup.end()?NULL:ret->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::dumpLabels(ostream &v)
|
||||||
|
{
|
||||||
|
v << "Global Labels\n\n";
|
||||||
|
for(auto iter=lookup.begin(); iter!=lookup.end(); ++iter)
|
||||||
|
{
|
||||||
|
v << "label " << iter->first << " has ID " << iter->second->getID() << "\n" ;
|
||||||
|
}
|
||||||
|
v << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::generateJumpTo(ostream &out)
|
||||||
|
{
|
||||||
|
out << "state=" << this->getID() << ";\nbreak;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::generateOnNSkip(ostream &k, list<label *> &dest)
|
||||||
|
{
|
||||||
|
if (dest->size()<2)
|
||||||
|
{
|
||||||
|
errorLevel=E_BAD_SYNTAX;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
auto iter=dest.start();
|
||||||
|
k << "j" << this->getID() << "[]={" << *iter;
|
||||||
|
++iter;
|
||||||
|
while(iter!=dest.end())
|
||||||
|
{
|
||||||
|
k << ", " << *iter;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
k << "}\njs" << this->getID()<< "=" << dest->size() << ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::generateOnNTo(ostream &out, expression *e)
|
||||||
|
{
|
||||||
|
operands *o=e->evaluate();
|
||||||
|
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
||||||
|
{
|
||||||
|
out << "if(";
|
||||||
|
o->boxName(out);
|
||||||
|
out << ">=0 && ";
|
||||||
|
o->boxName(out);
|
||||||
|
out << "<js" << this->getID() << ")state=j[";
|
||||||
|
o->boxName(out);
|
||||||
|
out << "];\nbreak;\n";
|
||||||
|
}
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::generateCondJump(ostream &out, expression *e)
|
||||||
|
{
|
||||||
|
operands *o=e->evaluate();
|
||||||
|
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
||||||
|
{
|
||||||
|
out << "if(";
|
||||||
|
o->boxName(out);
|
||||||
|
out << "!=0)state=" << this->getID() << ";\nbreak;\n";
|
||||||
|
}
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::generate(ostream &out)
|
||||||
|
{
|
||||||
|
out << "case " << this->getID() <<":\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* conditional definition */
|
||||||
|
|
||||||
|
conditional::conditional(ostream &out, expression *e):codeType(T_IF)
|
||||||
|
{
|
||||||
|
this->redo=new label();
|
||||||
|
redo->generate(out);
|
||||||
|
this->done=new label();
|
||||||
|
expression *f=new expression(e,O_NOT);
|
||||||
|
this->chain=new label();
|
||||||
|
chain->generateCondJump(out, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void conditional::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
done->generateJumpTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void conditional::generateContinue(ostream &out)
|
||||||
|
{
|
||||||
|
redo->generateJumpTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void conditional::alternative(ostream &out, expression *e=NULL)
|
||||||
|
{
|
||||||
|
done->generateJumpTo(out);
|
||||||
|
this->chain->generate();
|
||||||
|
delete this->chain;
|
||||||
|
this->chain=NULL;
|
||||||
|
if(e!=NULL)
|
||||||
|
{
|
||||||
|
this->chain=new label();
|
||||||
|
expression *f=new expression(e,O_NOT);
|
||||||
|
chain->generateJumpCond(out, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void conditional::close(ostream &out)
|
||||||
|
{
|
||||||
|
if(this->chain)
|
||||||
|
{
|
||||||
|
/* elsif ended without else in between */
|
||||||
|
errorLevel=E_BAD_SYNTAX;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
this->done->generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional::~conditional()
|
||||||
|
{
|
||||||
|
delete this->done;
|
||||||
|
delete this->redo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop definitions */
|
||||||
|
repeatLoop::repeatLoop(ostream &out):codeType(T_REPEATLOOP)
|
||||||
|
{
|
||||||
|
this->loopStart=new label();
|
||||||
|
this->loopEnd=new label();
|
||||||
|
loopStart->generate(out;)
|
||||||
|
}
|
||||||
|
|
||||||
|
void repeatLoop::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
loopEnd->generateJumpTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void repeatLoop::close(ostream &out, expression *e)
|
||||||
|
{
|
||||||
|
expression *f=new expression(e, O_NOT);
|
||||||
|
loopStart->generateCondJump(out, f);
|
||||||
|
loopEnd->generate(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatLoop::~repeatLoop()
|
||||||
|
{
|
||||||
|
delete loopStart;
|
||||||
|
delete loopEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
doLoop::doLoop(ostream &out):codeType(T_DOLOOP)
|
||||||
|
{
|
||||||
|
this->loopStart=new label();
|
||||||
|
this->loopEnd=new label();
|
||||||
|
loopStart->generate(out;)
|
||||||
|
}
|
||||||
|
|
||||||
|
void doLoop::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
loopEnd->generateJumpTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doLoop::close(ostream &out)
|
||||||
|
{
|
||||||
|
this->loopStart->generateJumpTo(out);
|
||||||
|
this->loopEnd->generate(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
doLoop::~doLoop()
|
||||||
|
{ delete loopStart;
|
||||||
|
delete loopEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
whileLoop::whileLoop(ostream &out, expression *e):codeType(T_WHILELOOP)
|
||||||
|
{
|
||||||
|
loopContinue=new label();
|
||||||
|
loopStart=new label();
|
||||||
|
loopEnd=new label();
|
||||||
|
cond=e;
|
||||||
|
loopStart->generateJumpTo(out);
|
||||||
|
loopContinue->generate(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void whileLoop::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
loopEnd->generateJumpTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void whileLoop::close(ostream &out)
|
||||||
|
{
|
||||||
|
loopStart->generate(out);
|
||||||
|
loopContinue->generateJumpCond(out, cond);
|
||||||
|
loopEnd->generate(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
whileLoop::~whileLoop()
|
||||||
|
{
|
||||||
|
delete loopStart;
|
||||||
|
delete loopContinue;
|
||||||
|
delete loopEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
forLoop::forLoop(ostream &out, ostream &k, variable *v, expression *start, expression *stop, expression *stepVal=NULL):codeType(T_FORLOOP)
|
||||||
|
{
|
||||||
|
/*v=start;
|
||||||
|
stopTemp=stop;*/
|
||||||
|
v->assignment(out, start);
|
||||||
|
stopTemp->assignment(out, stop);
|
||||||
|
/* if (v<stopTemp) */
|
||||||
|
conditional *c=new conditional(out, new expression(new expression(v), O_LESS, new expression(stopTemp)));
|
||||||
|
/* startTemp=v;*/
|
||||||
|
startTemp->assignment(out, new expression(v));
|
||||||
|
/* else */
|
||||||
|
c->alternative(out);
|
||||||
|
/* startTemp=stopTemp;
|
||||||
|
stopTemp=v;*/
|
||||||
|
startTemp->assignment(out, new expression(stopTemp));
|
||||||
|
stopTemp->assignment(out, new expression(v));
|
||||||
|
/* endif */
|
||||||
|
c->close(out);
|
||||||
|
delete c;
|
||||||
|
/* while (v<=stopTemp && v>=startTemp) */
|
||||||
|
expression *stopper1=new expression(new expression(v), O_LESS_EQUAL, new expression(stopTemp));
|
||||||
|
expression *stopper2=new expression(new expression(v), O_GREATER_EQUAL, new expression(startTemp));
|
||||||
|
expression *stopper=new expression(stopper1, O_AND, stopper2);
|
||||||
|
this->infrastructure=new whileLoop(out, new expression(stopper, O_UNEQUAL,
|
||||||
|
new expression(operands::createConst(k, "0", T_INT))));
|
||||||
|
if (stepVal)
|
||||||
|
{
|
||||||
|
step=stepVal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* if not present "step" is assumed to be 1 */
|
||||||
|
step=new expression(operands::createConst(k, "1", T_INT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void forLoop::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
infrastructure->generateBreak(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void forLoop::close(ostream &out)
|
||||||
|
{
|
||||||
|
/* v=v+step; */
|
||||||
|
expression *stepper=new expression(new expression(v), O_PLUS, step);
|
||||||
|
v->assignment(out, stepper)
|
||||||
|
infrastructure->close(ostream &out);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user