added loop constructs and a few missing methods elsewhere
This commit is contained in:
135
yab2cpp.cpp
135
yab2cpp.cpp
@@ -173,16 +173,39 @@ static void operands::dumpVars(ostream &out)
|
|||||||
}
|
}
|
||||||
out << endl;
|
out << endl;
|
||||||
}
|
}
|
||||||
unsigned int operands::getOrCreateStr(string &s, ostream &k)
|
unsigned int operands::getOrCreateStr(ostream &k, string &s)
|
||||||
{
|
{
|
||||||
auto iter=constStr.find(s);
|
auto iter=constStr.find(s);
|
||||||
if (iter!=constStr.end()) return iter->second;
|
if (iter!=constStr.end()) return iter->second;
|
||||||
++nextID;
|
++nextID;
|
||||||
k << "const string sk" << nextID << "=\"" << s << "\";\n";
|
k << "const string k" << nextID << "=\"" << s << "\";\n";
|
||||||
constStr[s]=nextID;
|
constStr[s]=nextID;
|
||||||
return nextID;
|
return nextID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int operands::createConst(ostream &k, string &s, enum TYPES t)
|
||||||
|
{
|
||||||
|
operands *me=new operands(t);
|
||||||
|
if (t==T_INT)
|
||||||
|
{
|
||||||
|
k << "const int k";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (t==T_FLOAT)
|
||||||
|
{
|
||||||
|
k << "const double k";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorLevel=E_TYPE_MISMATCH;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k << me->getID() << "=" << s << ";\n";
|
||||||
|
return me;
|
||||||
|
}
|
||||||
|
|
||||||
enum TYPES operands::getSimpleVarType()
|
enum TYPES operands::getSimpleVarType()
|
||||||
{
|
{
|
||||||
switch type
|
switch type
|
||||||
@@ -559,11 +582,119 @@ void conditional::close(ostream &out)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
this->done->generate();
|
this->done->generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional::~conditional()
|
||||||
|
{
|
||||||
delete this->done;
|
delete this->done;
|
||||||
delete this->redo;
|
delete this->redo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop definitions */
|
/* 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
|
||||||
|
{
|
||||||
|
step=new expression(operands::createConst(k, "1", T_INT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void forLoop::generateBreak(ostream &out)
|
||||||
|
{
|
||||||
|
infrastructure->generateBreak(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void forLoop::close(ostream &out)
|
||||||
|
{
|
||||||
|
expression *stepper=new expression(new expression(v), O_PLUS, step);
|
||||||
|
v->assignment(out, stepper)
|
||||||
|
infrastructure->close(ostream &out);
|
||||||
|
}
|
||||||
|
|
||||||
/* function definitions */
|
/* function definitions */
|
||||||
|
|
||||||
|
|||||||
127
yab2cpp.h
127
yab2cpp.h
@@ -168,7 +168,8 @@ public:
|
|||||||
unsigned int getID() const {return id;}
|
unsigned int getID() const {return id;}
|
||||||
|
|
||||||
static void dumpVars(ostream &out);
|
static void dumpVars(ostream &out);
|
||||||
static unsigned int getOrCreateStr(string &s);
|
static unsigned int getOrCreateStr(ostream &k, string &s);
|
||||||
|
static operands *createConst(ostream &k, string &s, enum TYPES t);
|
||||||
|
|
||||||
enum TYPES getSimpleVarType();
|
enum TYPES getSimpleVarType();
|
||||||
void generateBox(ostream &out);
|
void generateBox(ostream &out);
|
||||||
@@ -202,6 +203,11 @@ public:
|
|||||||
this->right=r;
|
this->right=r;
|
||||||
this->oper=o;
|
this->oper=o;
|
||||||
}
|
}
|
||||||
|
expression(operands x)
|
||||||
|
{
|
||||||
|
op=x;
|
||||||
|
oper=O_TERM;
|
||||||
|
}
|
||||||
virtual ~expression();
|
virtual ~expression();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,11 +224,11 @@ public:
|
|||||||
|
|
||||||
codeType *getCurrent();
|
codeType *getCurrent();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
virtual void generateBreak(ostream &out)=0;
|
||||||
|
|
||||||
explicit codeType(enum CODES t);
|
explicit codeType(enum CODES t);
|
||||||
virtual ~codeType()
|
virtual ~codeType()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class label
|
class label
|
||||||
@@ -257,83 +263,88 @@ public:
|
|||||||
/* if statement */
|
/* if statement */
|
||||||
class conditional:public codeType
|
class conditional:public codeType
|
||||||
{
|
{
|
||||||
shared_ptr<label>redo; /* for continue command */
|
label *redo; /* for continue command */
|
||||||
shared_ptr<label>done; /* for break or after "then" condition */
|
label *done; /* for break or after "then" condition */
|
||||||
shared_ptr<label>chain; /* For elsif command */
|
label *chain; /* For elsif command */
|
||||||
public:
|
public:
|
||||||
void generateContinue(ostream &out);
|
void generateContinue(ostream &out);
|
||||||
void generateBreak(ostream &out);
|
virtual void generateBreak(ostream &out) override;
|
||||||
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(expression *e):codeType(T_IF);
|
||||||
virtual ~conditional()
|
virtual ~conditional();
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* looping constructs */
|
/* looping constructs */
|
||||||
class repeatLoop:public codeType
|
class repeatLoop:public codeType
|
||||||
{
|
{
|
||||||
shared_ptr<label>loopStart;
|
label *loopStart;
|
||||||
shared_ptr<label>loopEnd;
|
label *loopEnd;
|
||||||
public:
|
public:
|
||||||
virtual void close(ostream &out, expression *) override;
|
virtual void generateBreak(ostream &out) override;
|
||||||
|
virtual void close(ostream &out, expression *e) override;
|
||||||
|
|
||||||
explicit repeatLoop():codeType(T_REPEATLOOP);
|
explicit repeatLoop(ostream &out):codeType(T_REPEATLOOP);
|
||||||
virtual ~repeatLoop()
|
virtual ~repeatLoop();
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class doLoop:public codeType
|
class doLoop:public codeType
|
||||||
{
|
{
|
||||||
shared_ptr<label>loopStart;
|
label *loopStart;
|
||||||
shared_ptr<label>loopEnd;
|
label *loopEnd;
|
||||||
public:
|
public:
|
||||||
virtual void close();
|
virtual void generateBreak(ostream &out) override;
|
||||||
|
virtual void close(ostream &out) override;
|
||||||
|
|
||||||
explicit doLoop():codeType(T_DOLOOP);
|
explicit doLoop():codeType(T_DOLOOP);
|
||||||
virtual ~doLoop()
|
virtual ~doLoop();
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class whileLoop:public codeType
|
class whileLoop:public codeType
|
||||||
{
|
{
|
||||||
shared_ptr<label> loopContinue;
|
label *loopContinue;
|
||||||
shared_ptr<label> loopExit;
|
label *loopStart;
|
||||||
expression cond;
|
label *loopEnd;
|
||||||
|
expression *cond;
|
||||||
public:
|
public:
|
||||||
virtual void close();
|
virtual void generateBreak(ostream &out) override;
|
||||||
|
virtual void close(ostream &out) override;
|
||||||
|
|
||||||
explicit whileLoop(expression e):codeType(T_WHILELOOP);
|
explicit whileLoop(ostream &out, expression *e):codeType(T_WHILELOOP);
|
||||||
virtual ~whileLoop()
|
virtual ~whileLoop();
|
||||||
|
};
|
||||||
|
|
||||||
|
class variable:public operands
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void assignment(ostream &out, expression *value);
|
||||||
|
explicit variable(ostream &scope, string &name, enum TYPES t):operands(t);
|
||||||
|
virtual variable()
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
class arrayType:public variable
|
||||||
|
{
|
||||||
|
list<unsigned int> dimensions;
|
||||||
|
public:
|
||||||
|
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);*/
|
||||||
|
virtual ~arrayType()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class variable;
|
|
||||||
|
|
||||||
/* TODO: Define expression constant ONE */
|
|
||||||
class forLoop:public codeType
|
class forLoop:public codeType
|
||||||
{
|
{
|
||||||
shared_ptr<variable *>var;
|
variable *var;
|
||||||
shared_ptr<label>loopContinue;
|
whileLoop *infrastructure;
|
||||||
shared_ptr<label>loopExit;
|
|
||||||
expression *step;
|
expression *step;
|
||||||
expression *cond;
|
|
||||||
public:
|
public:
|
||||||
virtual void close();
|
virtual void generateBreak(ostream &out);
|
||||||
|
virtual void close(ostream &out);
|
||||||
explicit forLoop(string &name, enum TYPES t, expression *start, expression *stop, expression *stepVal):assignment(name, t, start)
|
|
||||||
{
|
|
||||||
this->cond=stop;
|
|
||||||
this->step=stepVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit forLoop(string &name, enum TYPES t, expression *start, expression *stop)
|
|
||||||
{
|
|
||||||
extern operands *ONE;
|
|
||||||
forLoop(name, t, start, stop, ONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
explicit forLoop(ostream &out, ostream &k, variable *v, expression *start, expression *stop, expression *stepVal=NULL);
|
||||||
virtual ~forLoop();
|
virtual ~forLoop();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -347,7 +358,6 @@ class fn:codeType
|
|||||||
shared_ptr<label>ret;
|
shared_ptr<label>ret;
|
||||||
unsigned int parameters;
|
unsigned int parameters;
|
||||||
public:
|
public:
|
||||||
static bool isCallStackEmpty() {return callStack.size()>0;}
|
|
||||||
static void dumpCallStack(ostream &out);
|
static void dumpCallStack(ostream &out);
|
||||||
void setParameters(unsigned int num) const {this->parameters=num;}
|
void setParameters(unsigned int num) const {this->parameters=num;}
|
||||||
|
|
||||||
@@ -358,33 +368,14 @@ public:
|
|||||||
void generateGosub(ostream &out, shared_ptr<label> sub);
|
void generateGosub(ostream &out, shared_ptr<label> sub);
|
||||||
/* must be called after label::generateOnNSkip */
|
/* must be called after label::generateOnNSkip */
|
||||||
void generateOnNSub(ostream &out, expression *e);
|
void generateOnNSub(ostream &out, expression *e);
|
||||||
virtual void close();
|
virtual void generateBreak(ostream &out);
|
||||||
|
virtual void close(ostream &out);
|
||||||
|
|
||||||
fn(string &name);
|
fn(string &name);
|
||||||
fn(label *gosub);
|
fn(label *gosub);
|
||||||
virtual ~fn();
|
virtual ~fn();
|
||||||
};
|
};
|
||||||
|
|
||||||
class variable:public operands
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static assignment(expression *value);
|
|
||||||
explicit variable(ostream &scope, string &name, enum TYPES t):operands(t);
|
|
||||||
virtual variable()
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
|
|
||||||
class arrayType:public variable
|
|
||||||
{
|
|
||||||
list<unsigned int> dimensions;
|
|
||||||
public:
|
|
||||||
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);
|
|
||||||
virtual ~arrayType()
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The next two structures are used to implement the PRINT statement. */
|
/* The next two structures are used to implement the PRINT statement. */
|
||||||
class printSegments
|
class printSegments
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user