split yab2cpp.cpp into 2 parts, finished for loop and started variables

This commit is contained in:
Samuel D. Crow
2021-03-13 14:26:41 -06:00
parent 4943489628
commit 43319754a8
3 changed files with 378 additions and 254 deletions

View File

@@ -1,18 +1,25 @@
/*
** Yab2Cpp
**
** Transpiler by Samuel D. Crow
**
** Based on Yab
**
*/
#include "yab2cpp.h"
enum COMPILEERRORS errorLevel=E_OK;
enum COMPILE_ERRORS errorLevel=E_OK;
unsigned int mode=0;
unsigned int indentLevel=0;
bool scopeGlobal=true;
extern ofstream output_cpp;
extern ofstream funcs_h;
extern ofstream heap_h;
extern ofstream consts_h;
extern ofstream logfile;
extern ofstream varNames;
extern ifstream src;
ifstream src;
ofstream output_cpp;
ofstream funcs_h;
ofstream heap_h;
ofstream consts_h;
ofstream logfile;
ofstream varNames;
/* private prototypes */
void helpText(string &);
@@ -173,6 +180,7 @@ static void operands::dumpVars(ostream &out)
}
out << endl;
}
unsigned int operands::getOrCreateStr(ostream &k, string &s)
{
auto iter=constStr.find(s);
@@ -288,6 +296,16 @@ void operands::generateBox(ostream &out)
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)
{
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;
nesting.push_back(this);
this->type=t;
this->generateBox(scope);
}
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();
}
/* label definitions and helper routines */
label *label::find(string &s)
operands *op=value->evaluate();
enum TYPES t=op->getSimpleVarType();
switch (this->getType())
{
auto ret=lookup.find(s);
return(ret==lookup.end()?NULL:ret->second);
}
void label::dumpLabels(ostream &v)
case T_FLOATVAR:
if (t==T_INTVAR)
{
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;
}
/* 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;
/* TODO: convert int to float */
}
else
{
step=new expression(operands::createConst(k, "1", T_INT));
}
}
void forLoop::generateBreak(ostream &out)
if (t!=T_FLOATVAR)
{
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);
v->assignment(out, stepper)
infrastructure->close(ostream &out);
errorLevel=E_TYPE_MISMATCH;
exit(1);
}
break;
}
this->boxName(output_cpp);
output_cpp << "=";
op->boxName(output_cpp);
output_cpp << ";\n";
}
/* function definitions */
fn *fn::getCurrentSub()
{
return callStack.back;
}
void fn::generateOnNSub(ostream &out, expression *e)
{

View File

@@ -20,6 +20,13 @@ using namespace std;
#define VER_MINOR 0
#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
**
@@ -36,6 +43,11 @@ enum COMPILE_ERRORS {
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. */
const char *COMPILE_ERROR_NAMES[]={
"no error",
@@ -170,6 +182,7 @@ public:
static void dumpVars(ostream &out);
static unsigned int getOrCreateStr(ostream &k, string &s);
static operands *createConst(ostream &k, string &s, enum TYPES t);
static operands *getOrCreateGlobal(ostream &heap, string &s, enum TYPES t);
enum TYPES getSimpleVarType();
void generateBox(ostream &out);
@@ -222,7 +235,8 @@ public:
enum CODES getType() const {return this->type;}
unsigned int getID() const {return this->id;}
codeType *getCurrent();
static codeType *getCurrent();
virtual void close();
virtual void generateBreak(ostream &out)=0;
@@ -272,7 +286,7 @@ public:
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);
explicit conditional(ostream &out, expression *e);
virtual ~conditional();
};
@@ -285,7 +299,7 @@ public:
virtual void generateBreak(ostream &out) override;
virtual void close(ostream &out, expression *e) override;
explicit repeatLoop(ostream &out):codeType(T_REPEATLOOP);
explicit repeatLoop(ostream &out);
virtual ~repeatLoop();
};
@@ -318,8 +332,10 @@ public:
class variable:public operands
{
public:
static variable *getOrCreateVarName(ostream &func, ostream &heap, string &name, enum TYPES t);
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()
{}
}
@@ -330,7 +346,7 @@ class arrayType:public variable
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);*/
explicit arrayType(ostream &heap, string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/
virtual ~arrayType()
{}
};
@@ -338,6 +354,8 @@ public:
class forLoop:public codeType
{
variable *var;
variable *startTemp;
variable *stopTemp;
whileLoop *infrastructure;
expression *step;
public:
@@ -358,11 +376,12 @@ class fn:codeType
shared_ptr<label>ret;
unsigned int parameters;
public:
static variable *getOrCreateVar(ostream &func, ostream &heap, enum TYPES t, string &s, bool stat);
static void dumpCallStack(ostream &out);
static fn *getCurrentSub();
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 generateReturn(ostream &out, expression *expr=NULL);
void generateGosub(ostream &out, shared_ptr<label> sub);

282
yabCodeStructures.cpp Normal file
View 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);
}