added loop constructs and a few missing methods elsewhere

This commit is contained in:
Samuel D. Crow
2021-03-12 21:57:53 -06:00
parent db06b3bf62
commit 4943489628
2 changed files with 192 additions and 70 deletions

View File

@@ -173,16 +173,39 @@ static void operands::dumpVars(ostream &out)
}
out << endl;
}
unsigned int operands::getOrCreateStr(string &s, ostream &k)
unsigned int operands::getOrCreateStr(ostream &k, string &s)
{
auto iter=constStr.find(s);
if (iter!=constStr.end()) return iter->second;
++nextID;
k << "const string sk" << nextID << "=\"" << s << "\";\n";
k << "const string k" << nextID << "=\"" << s << "\";\n";
constStr[s]=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()
{
switch type
@@ -559,11 +582,119 @@ void conditional::close(ostream &out)
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
{
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 */

127
yab2cpp.h
View File

@@ -168,7 +168,8 @@ public:
unsigned int getID() const {return id;}
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();
void generateBox(ostream &out);
@@ -202,6 +203,11 @@ public:
this->right=r;
this->oper=o;
}
expression(operands x)
{
op=x;
oper=O_TERM;
}
virtual ~expression();
};
@@ -218,11 +224,11 @@ public:
codeType *getCurrent();
virtual void close();
virtual void generateBreak(ostream &out)=0;
explicit codeType(enum CODES t);
virtual ~codeType()
{
}
{}
};
class label
@@ -257,83 +263,88 @@ public:
/* if statement */
class conditional:public codeType
{
shared_ptr<label>redo; /* for continue command */
shared_ptr<label>done; /* for break or after "then" condition */
shared_ptr<label>chain; /* For elsif command */
label *redo; /* for continue command */
label *done; /* for break or after "then" condition */
label *chain; /* For elsif command */
public:
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 */
virtual void close(ostream &out) override; /* end if */
explicit conditional(expression *e):codeType(T_IF);
virtual ~conditional()
{}
virtual ~conditional();
};
/* looping constructs */
class repeatLoop:public codeType
{
shared_ptr<label>loopStart;
shared_ptr<label>loopEnd;
label *loopStart;
label *loopEnd;
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);
virtual ~repeatLoop()
{}
explicit repeatLoop(ostream &out):codeType(T_REPEATLOOP);
virtual ~repeatLoop();
};
class doLoop:public codeType
{
shared_ptr<label>loopStart;
shared_ptr<label>loopEnd;
label *loopStart;
label *loopEnd;
public:
virtual void close();
virtual void generateBreak(ostream &out) override;
virtual void close(ostream &out) override;
explicit doLoop():codeType(T_DOLOOP);
virtual ~doLoop()
{}
virtual ~doLoop();
};
class whileLoop:public codeType
{
shared_ptr<label> loopContinue;
shared_ptr<label> loopExit;
expression cond;
label *loopContinue;
label *loopStart;
label *loopEnd;
expression *cond;
public:
virtual void close();
virtual void generateBreak(ostream &out) override;
virtual void close(ostream &out) override;
explicit whileLoop(expression e):codeType(T_WHILELOOP);
virtual ~whileLoop()
explicit whileLoop(ostream &out, expression *e):codeType(T_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
{
shared_ptr<variable *>var;
shared_ptr<label>loopContinue;
shared_ptr<label>loopExit;
variable *var;
whileLoop *infrastructure;
expression *step;
expression *cond;
public:
virtual void close();
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);
}
virtual void generateBreak(ostream &out);
virtual void close(ostream &out);
explicit forLoop(ostream &out, ostream &k, variable *v, expression *start, expression *stop, expression *stepVal=NULL);
virtual ~forLoop();
};
@@ -347,7 +358,6 @@ class fn:codeType
shared_ptr<label>ret;
unsigned int parameters;
public:
static bool isCallStackEmpty() {return callStack.size()>0;}
static void dumpCallStack(ostream &out);
void setParameters(unsigned int num) const {this->parameters=num;}
@@ -358,33 +368,14 @@ public:
void generateGosub(ostream &out, shared_ptr<label> sub);
/* must be called after label::generateOnNSkip */
void generateOnNSub(ostream &out, expression *e);
virtual void close();
virtual void generateBreak(ostream &out);
virtual void close(ostream &out);
fn(string &name);
fn(label *gosub);
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. */
class printSegments
{