started build script and went on a massive bug hunt

This commit is contained in:
Samuel D. Crow
2021-03-16 17:01:28 -05:00
parent 4eb08efc9d
commit 1dae0a4b54
6 changed files with 322 additions and 276 deletions

40
Makefile Normal file
View File

@@ -0,0 +1,40 @@
#Makefile for yab2cpp
#by Samuel D. Crow
#presently architecture-neutral
CC=g++
LD=g++
#release build
#FLAGS=-c -Os -std=c++11
#LDFLAGS=
#debug build
FLAGS=-c -g -Og -std=c++11
LDFLAGS=
AR=ar r
LD=g++
default: yab2cpp
yabDataStructures.o: yabDataStructures.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabDataStructures.o yabDataStructures.cpp
yabCodeStructures.o: yabCodeStructures.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabCodeStructures.o yabCodeStructures.cpp
yabFunctions.o: yabFunctions.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabFunctions.o yabFunctions.cpp
yab2cpp.o: yab2cpp.cpp yab2cpp.h
$(CC) $(FLAGS) -o yab2cpp.o yab2cpp.cpp
BASIC_framework.a: yabDataStructures.o yabCodeStructures.o yabFunctions.o
$(AR) yabDataStructures.o yabCodeStructures.o yabFunctions.o
yab2cpp: BASIC_framework.a yab2cpp.o
$(LD) $(LDFLAGS) -o buildyab2cpp yab2cpp.o -lBASIC_framework
clean:
rm -f *.o yab2cpp BASIC_framework.a

View File

@@ -22,9 +22,10 @@ ofstream logfile;
ofstream varNames;
/* private prototypes */
void helpText(string &);
void helpText(string);
void setup();
void compile();
void shutDown();
void logger(string &);
/* process command line parameters */
int main(int argc, char *argv[])
@@ -98,29 +99,35 @@ void setUp()
if (mode & COMPILE)
{
/* compile mode */
output_cpp=new ofstream("build/output.cpp");
funcs_h=new ofstream ("functions.h");
consts_h=new ofstream("consts.h");
heap_h=new ofstream("heap.h");
output_cpp.open("output/output.cpp");
funcs_h.open("output/functions.h");
consts_h.open("output/consts.h");
heap_h.open("output/heap.h");
output_cpp << "#include <runtime.h>\n#include \"consts.h\"\n"
<< "#include \"heap.h\"\n#include \"functions.h\"\n"
<< "unsigned int state=start;\nint run(){\nwhile (state>=start){\n"
<< "switch(state){\ncase start:" << endl;
if (mode & DEBUG)
{
varNames=new ofstream("varnames.txt");
varNames.open("varnames.txt");
}
}
if (mode & DUMP)
{
/* dump identifier mode */
logfile=fopen("parse.log","w");
logfile.open("parse.log");
logger("Setup complete.");
}
}
void error(enum COMPILE_ERRORS e)
{
errorLevel=e;
exit(1);
}
/* write a note in the logfile */
void logger(string &contents)
void logger(string s)
{
unsigned int count;
if (mode & DEBUG)
@@ -131,14 +138,14 @@ void logger(string &contents)
logfile << '\t';
--count;
}
logfile << contents << endl;
logfile << s << endl;
}
}
/* shutdown the compiler and exit */
void shutDown()
{
if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILEERRORNAMES[errorLevel] << "\n\n" << endl;
if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
if (fn::isCallStackEmpty())
{
logger("Stack was empty");
@@ -146,26 +153,22 @@ void shutDown()
else
{
logger("Dumping stack.");
if (mode & DUMP && logfile != NULL)
if (mode & DUMP && (logfile))
{
fn::dumpCallStack(logfile);
fn::dumpCallStack();
}
}
operands::dumpVars();
label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl;
}
}
/* open files and compile */
void compile()
{
setUp();
/* parse */
ctx = mb_create(NULL);
while(mb_parse(ctx, NULL)){logger("done");}
mb_destroy(ctx);
shutDown();
}

145
yab2cpp.h
View File

@@ -13,6 +13,8 @@
#include <unordered_map>
#include <memory>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
@@ -90,7 +92,7 @@ enum TYPES
T_FLOATCALL_ARRAY,
T_STRINGCALL_ARRAY,
T_VOIDCALL
}
};
/* list of all kinds of other code structures */
enum CODES
{
@@ -194,6 +196,7 @@ enum OPERATORS
/* global prototype */
void error(enum COMPILE_ERRORS err);
void logger(string s);
/* internal states used by the parser */
class operands
@@ -201,21 +204,23 @@ class operands
enum TYPES type;
unsigned int id;
static unsigned int nextID;
static unordered_map<string, operands *> globals;
static unordered_map<string, shared_ptr<operands>> globals;
static unordered_map<string, unsigned int> strConst;
/* private constructor for parameter passing only */
explicit operands(unsigned int id, enum TYPES t);
public:
enum TYPES getType() const {return type;}
unsigned int getID() const {return id;}
static operands *findGlobal(string &s);
static void dumpVars(ostream &out);
static unsigned int getOrCreateStr(string &s);
static operands *createConst(string &s, enum TYPES t);
static operands *getOrCreateGlobal(string &s, enum TYPES t);
static shared_ptr<operands>findGlobal(string &s);
static void dumpVars();
static shared_ptr<operands>getOrCreateStr(string s);
static shared_ptr<operands>createConst(string s, enum TYPES t);
static shared_ptr<operands>getOrCreateGlobal(string &s, enum TYPES t);
enum TYPES getSimpleVarType();
void generateBox(ostream &scope);
virtual string &boxName();
virtual string boxName();
enum TYPES coerceTypes();
explicit operands(enum TYPES t);
@@ -226,27 +231,27 @@ public:
/* expression can be terminal or non-terminal */
class expression
{
operands *op;
expression *left;
expression *right;
shared_ptr<operands>op;
shared_ptr<expression>left;
shared_ptr<expression>right;
enum OPERATORS oper;
public:
enum OPERATORS getOp() const {return oper;}
expression *getLeft() const {return left;}
expression *getRight() const {return right;}
shared_ptr<expression>getLeft() const {return left;}
shared_ptr<expression>getRight() const {return right;}
bool isBinOp();
operands *evaluate();
operands *stringEval();
shared_ptr<operands>evaluate();
shared_ptr<operands>stringEval(shared_ptr<operands>l, shared_ptr<operands>r);
/* r is NULL for unary operators */
expression(expression *l, enum OPERATORS o, expression *r=NULL)
expression(shared_ptr<expression>l, enum OPERATORS o, shared_ptr<expression>r=NULL)
{
this->left=l;
this->right=r;
this->oper=o;
}
expression(operands x)
expression(shared_ptr<operands>x)
{
op=x;
oper=O_TERM;
@@ -259,11 +264,11 @@ public:
class codeType
{
enum CODES type;
static list<codeType *> nesting;
static list<shared_ptr<codeType> >nesting;
public:
enum CODES getType() const {return this->type;}
static codeType *getCurrent();
static shared_ptr<codeType> getCurrent();
virtual void close();
virtual void generateBreak()=0;
@@ -277,25 +282,27 @@ class label
{
unsigned int id;
static unsigned int nextID;
static unordered_map<string, label *> lookup;
static unordered_map<string, shared_ptr<label> > lookup;
public:
static dumpLabels(ostream &v);
static void dumpLabels();
unsigned int getID() const {return id;}
void generateJumpTo();
void generateOnNSkip(list<shared_ptr<label> >dest);
void generateOnNTo(expression *e);
void generateCondJump(expression *e);
/* pass generateOnNSkip as second paramater
to generateOnNTo or generateOnNSub */
unsigned int generateOnNSkip(list<shared_ptr<label> >&dest);
static void generateOnNTo(shared_ptr<expression>e, unsigned int skip);
void generateCondJump(shared_ptr<expression>e);
void generate();
static label *find(string &s);
static shared_ptr<label>find(string &s);
label(){this->id = ++nextID;}
label(string &s)
{
label();
lookup[s]=this;
lookup[s]=shared_ptr<label>(this);
}
virtual ~label()
@@ -303,77 +310,82 @@ public:
};
/* if statement */
class conditional:public codeType
class ifStatement:public codeType
{
label *redo; /* for continue command */
label *done; /* for break or after "then" condition */
label *chain; /* For elsif command */
shared_ptr<label>redo; /* for continue command */
shared_ptr<label>done; /* for break or after "then" condition */
shared_ptr<label>chain; /* For elsif command */
public:
void generateContinue();
virtual void generateBreak() override;
void alternative(expression *e=NULL); /* enable else or elsif condition */
void alternative(shared_ptr<expression>e=NULL); /* enable else or elsif condition */
virtual void close() override; /* end if */
explicit conditional(expression *e);
virtual ~conditional();
explicit ifStatement(shared_ptr<expression>e);
virtual ~ifStatement()
{}
};
/* looping constructs */
class repeatLoop:public codeType
{
label *loopStart;
label *loopEnd;
shared_ptr<label>loopStart;
shared_ptr<label>loopEnd;
public:
virtual void generateBreak() override;
virtual void close(expression *e) override;
virtual void close(shared_ptr<expression>e);
explicit repeatLoop();
virtual ~repeatLoop();
virtual ~repeatLoop()
{}
};
class doLoop:public codeType
{
label *loopStart;
label *loopEnd;
shared_ptr<label>loopStart;
shared_ptr<label>loopEnd;
public:
virtual void generateBreak() override;
virtual void close() override;
explicit doLoop();
virtual ~doLoop();
virtual ~doLoop()
{}
};
class whileLoop:public codeType
{
label *loopContinue;
label *loopStart;
label *loopEnd;
expression *cond;
shared_ptr<label>loopContinue;
shared_ptr<label>loopStart;
shared_ptr<label>loopEnd;
shared_ptr<expression>cond;
public:
virtual void generateBreak() override;
virtual void close() override;
explicit whileLoop(expression *e);
virtual ~whileLoop();
explicit whileLoop(shared_ptr<expression>e);
virtual ~whileLoop()
{}
};
class variable:public operands
{
ostream &myScope;
public:
static shared_ptr<variable>getOrCreateVarName(string &name, enum TYPES t);
static shared_ptr<variable>getOrCreateVar(string &name, enum TYPES t);
void assignment(expression *value);
void assignment(shared_ptr<expression>value);
explicit variable(ostream &scope, string &name, enum TYPES t);
virtual variable()
variable();
~variable()
{}
}
};
class arrayType:public variable
{
list<unsigned int> dimensions;
public:
virtual string &boxName(list<unsigned int>indexes) override;
virtual string &boxName(list<unsigned int>indexes);
explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/
virtual ~arrayType()
@@ -382,16 +394,16 @@ public:
class forLoop:public codeType
{
variable *var;
variable *startTemp;
variable *stopTemp;
shared_ptr<variable>var;
shared_ptr<variable>startTemp;
shared_ptr<variable>stopTemp;
whileLoop *infrastructure;
expression *step;
shared_ptr<expression>step;
public:
virtual void generateBreak();
virtual void close();
explicit forLoop(variable *v, expression *start, expression *stop, expression *stepVal=NULL);
explicit forLoop(shared_ptr<variable>v, shared_ptr<expression>start, shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL);
virtual ~forLoop();
};
@@ -408,22 +420,23 @@ class fn:codeType
shared_ptr<label>startAddr;
shared_ptr<label>ret;
/* private constructor used by generateGosub and generateOnNSub*/
fn(label *gosub);
fn(shared_ptr<label>gosub);
public:
static variable *getOrCreateVar(enum TYPES t, string &s, bool stat);
static shared_ptr<variable>getOrCreateVar(enum TYPES t, string &s, bool stat);
static void dumpCallStack();
static bool isCallStackEmpty(){return callStack.begin()==callStack.end();}
static shared_ptr<fn>getCurrentSub();
static shared_ptr<fn>getSub(string &name);
static void generateGosub(shared_ptr<label> sub);
/* must be called after label::generateOnNSkip */
static void generateOnNSub(expression *e);
static void generateOnNSub(shared_ptr<expression>e, unsigned int skip);
unsigned int getID() const {return this->id;}
int getNumParams() const {return this->params.size;}
int getNumParams() const {return this->params.size();}
void addParameter(shared_ptr<variable>);
operands *generateCall(string &name, list<shared_ptr<operands> >&paramList);
operands *generateReturn(expression *expr);
shared_ptr<operands>generateCall(string &name, list<shared_ptr<operands> >paramList);
shared_ptr<operands>generateReturn(shared_ptr<expression>expr);
void generateReturn();
virtual void generateBreak();
virtual void close();
@@ -436,15 +449,15 @@ public:
/* The next two structures are used to implement the PRINT statement. */
class printSegments
{
expression *cargo;
shared_ptr<expression>cargo;
enum SEPARATORS kind;
public:
printSegments(expression *e, enum SEPARATORS k)
printSegments(shared_ptr<expression>e, enum SEPARATORS k)
{
this->cargo=e;
this->kind=k;
}
printSegments(expression *e) {printSegments(e, S_LINEFEED);}
printSegments(shared_ptr<expression>e) {printSegments(e, S_LINEFEED);}
printSegments() {printSegments(NULL);}
virtual ~printSegments()
{}
@@ -452,7 +465,7 @@ public:
struct printStatement
{
list<printSegments *> segments;
list<shared_ptr<printSegments> >segments;
};
#endif

View File

@@ -11,13 +11,13 @@
/* base class of all the code structure types */
codeType::codeType(enum CODES t)
{
nesting.push_back(this);
nesting.push_back(shared_ptr<codeType>(this));
this->type=t;
}
codeType *codeType::getCurrent()
shared_ptr<codeType> codeType::getCurrent()
{
return nesting.back;
return nesting.back();
}
void codeType::close()
@@ -26,7 +26,7 @@ void codeType::close()
}
/* label definitions and helper routines */
label *label::find(string &s)
shared_ptr<label>label::find(string &s)
{
auto ret=lookup.find(s);
return(ret==lookup.end()?NULL:ret->second);
@@ -47,14 +47,15 @@ void label::generateJumpTo()
output_cpp << "state=" << this->getID() << ";\nbreak;\n";
}
void label::generateOnNSkip(list<shared_ptr<label> >dest)
/* pass this as second parameter to generateOnNTo or generateOnNSub */
unsigned int label::generateOnNSkip(list<shared_ptr<label> >&dest)
{
if (dest->size()<2)
if (dest.size()<2)
{
errorLevel=E_BAD_SYNTAX;
exit(1);
}
auto iter=dest.start();
auto iter=dest.begin();
consts_h << "j" << this->getID() << "[]={" << *iter;
++iter;
while(iter!=dest.end())
@@ -62,30 +63,29 @@ void label::generateOnNSkip(list<shared_ptr<label> >dest)
consts_h << ", " << *iter;
++iter;
}
consts_h << "}\njs" << this->getID()<< "=" << dest->size() << ";\n";
consts_h << "}\njs" << this->getID()<< "=" << dest.size() << ";\n";
return this->getID();
}
void label::generateOnNTo(expression *e)
void label::generateOnNTo(shared_ptr<expression>e, unsigned int skip)
{
operands *o=e->evaluate();
shared_ptr<operands>o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR)
{
output_cpp<< "if(" << o->boxName() << ">=0 && "
<< o->boxName() << "<js" << this->getID() << ")state=j["
<< o->boxName() << "<js" << skip << ")state=j["
<< o->boxName() << "];\nbreak;\n";
}
delete e;
}
void label::generateCondJump(expression *e)
void label::generateCondJump(shared_ptr<expression>e)
{
operands *o=e->evaluate();
shared_ptr<operands>o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR)
{
output_cpp<< "if(" << o->boxName()
<< "!=0)state=" << this->getID() << ";\nbreak;\n";
}
delete e;
}
void label::generate()
@@ -93,43 +93,42 @@ void label::generate()
output_cpp<< "case " << this->getID() <<":\n";
}
/* conditional definition */
/* ifStatement definition */
conditional::conditional(expression *e):codeType(T_IF)
ifStatement::ifStatement(shared_ptr<expression>e):codeType(T_IF)
{
this->redo=new label();
this->redo=shared_ptr<label>(new label());
redo->generate();
this->done=new label();
expression *f=new expression(e,O_NOT);
this->chain=new label();
this->done=shared_ptr<label>(new label());
shared_ptr<expression>f=shared_ptr<expression>(new expression(e,O_NOT));
this->chain=shared_ptr<label>(new label());
chain->generateCondJump(f);
}
void conditional::generateBreak()
void ifStatement::generateBreak()
{
done->generateJumpTo();
}
void conditional::generateContinue()
void ifStatement::generateContinue()
{
redo->generateJumpTo();
}
void conditional::alternative(expression *e=NULL)
void ifStatement::alternative(shared_ptr<expression>e=NULL)
{
done->generateJumpTo();
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(f);
this->chain=shared_ptr<label>(new label());
shared_ptr<expression>f=shared_ptr<expression>(new expression(e,O_NOT));
chain->generateCondJump(f);
}
}
void conditional::close()
void ifStatement::close()
{
if(this->chain)
{
@@ -140,17 +139,11 @@ void conditional::close()
this->done->generate();
}
conditional::~conditional()
{
delete this->done;
delete this->redo;
}
/* Loop definitions */
repeatLoop::repeatLoop():codeType(T_REPEATLOOP)
{
this->loopStart=new label();
this->loopEnd=new label();
this->loopStart=shared_ptr<label>(new label());
this->loopEnd=shared_ptr<label>(new label());
loopStart->generate();
}
@@ -159,23 +152,17 @@ void repeatLoop::generateBreak()
loopEnd->generateJumpTo();
}
void repeatLoop::close(expression *e)
void repeatLoop::close(shared_ptr<expression>e)
{
expression *f=new expression(e, O_NOT);
shared_ptr<expression>f=shared_ptr<expression>(new expression(e, O_NOT));
loopStart->generateCondJump(f);
loopEnd->generate();
}
repeatLoop::~repeatLoop()
{
delete loopStart;
delete loopEnd;
}
doLoop::doLoop():codeType(T_DOLOOP)
{
this->loopStart=new label();
this->loopEnd=new label();
this->loopStart=shared_ptr<label>(new label());
this->loopEnd=shared_ptr<label>(new label());
loopStart->generate();
}
@@ -190,16 +177,11 @@ void doLoop::close()
this->loopEnd->generate();
}
doLoop::~doLoop()
{ delete loopStart;
delete loopEnd;
}
whileLoop::whileLoop(expression *e):codeType(T_WHILELOOP)
whileLoop::whileLoop(shared_ptr<expression>e):codeType(T_WHILELOOP)
{
loopContinue=new label();
loopStart=new label();
loopEnd=new label();
loopContinue=shared_ptr<label>(new label());
loopStart=shared_ptr<label>(new label());
loopEnd=shared_ptr<label>(new label());
cond=e;
loopStart->generateJumpTo();
loopContinue->generate();
@@ -213,42 +195,44 @@ void whileLoop::generateBreak()
void whileLoop::close()
{
loopStart->generate();
loopContinue->generateJumpCond(cond);
loopContinue->generateCondJump(cond);
loopEnd->generate();
}
whileLoop::~whileLoop()
{
delete loopStart;
delete loopContinue;
delete loopEnd;
}
forLoop::forLoop(variable *v, expression *start, expression *stop, expression *stepVal=NULL):codeType(T_FORLOOP)
forLoop::forLoop(shared_ptr<variable>v,
shared_ptr<expression>start, shared_ptr<expression>stop,
shared_ptr<expression>stepVal=NULL):codeType(T_FORLOOP)
{
/*v=start;
stopTemp=stop;*/
v->assignment(start);
stopTemp->assignment(stop);
/* if (v<stopTemp) */
conditional *c=new conditional(new expression(new expression(v), O_LESS, new expression(stopTemp)));
shared_ptr<ifStatement>c=shared_ptr<ifStatement>(new ifStatement(
shared_ptr<expression>(new expression(shared_ptr<expression>(new expression(v)),
O_LESS, shared_ptr<expression>(new expression(stopTemp))))));
/* startTemp=v;*/
startTemp->assignment(new expression(v));
startTemp->assignment(shared_ptr<expression>(new expression(v)));
/* else */
c->alternative();
/* startTemp=stopTemp;
stopTemp=v;*/
startTemp->assignment(new expression(stopTemp));
stopTemp->assignment(new expression(v));
startTemp->assignment(shared_ptr<expression>(new expression(stopTemp)));
stopTemp->assignment(shared_ptr<expression>(new expression(v)));
/* endif */
c->close();
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(new expression(stopper, O_UNEQUAL,
new expression(operands::createConst("0", T_INT))));
shared_ptr<expression>stopper1=shared_ptr<expression>(new expression(
shared_ptr<expression>(new expression(v)), O_LESS_EQUAL,
shared_ptr<expression>(new expression(stopTemp))));
shared_ptr<expression>stopper2=shared_ptr<expression>(new expression(
shared_ptr<expression>(new expression(v)), O_GREATER_EQUAL,
shared_ptr<expression>(new expression(startTemp))));
shared_ptr<expression>stopper=shared_ptr<expression>(new expression(
stopper1, O_AND, stopper2));
this->infrastructure=new whileLoop(shared_ptr<expression>(new expression(
stopper, O_UNEQUAL, shared_ptr<expression>(new expression(
operands::createConst(string("0"), T_INT))))));
if (stepVal)
{
step=stepVal;
@@ -256,7 +240,7 @@ forLoop::forLoop(variable *v, expression *start, expression *stop, expression *s
else
{
/* if not present "step" is assumed to be 1 */
step=new expression(operands::createConst("1", T_INT));
step=shared_ptr<expression>(new expression(operands::createConst("1", T_INT)));
}
}
@@ -267,8 +251,9 @@ void forLoop::generateBreak()
void forLoop::close()
{
/* v=v+step; */
expression *stepper=new expression(new expression(v), O_PLUS, step);
v->assignment(stepper)
/* var=var+step; */
shared_ptr<expression>stepper=shared_ptr<expression>(new expression(
shared_ptr<expression>(new expression(var)), O_PLUS, step));
var->assignment(stepper);
infrastructure->close();
}

View File

@@ -8,8 +8,10 @@
*/
#include "yab2cpp.h"
class fn;
/* methods for operands */
static operands *findGlobal(string &s)
shared_ptr<operands>operands::findGlobal(string &s)
{
auto iter=operands::globals.find(s);
if (iter==operands::globals.end())
@@ -19,7 +21,7 @@ static operands *findGlobal(string &s)
return iter->second;
}
static void operands::dumpVars()
void operands::dumpVars()
{
varNames << "Global Variables\n";
for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
@@ -29,19 +31,22 @@ static void operands::dumpVars()
varNames << endl;
}
unsigned int operands::getOrCreateStr(string &s)
shared_ptr<operands> operands::getOrCreateStr(string s)
{
auto iter=constStr.find(s);
if (iter!=constStr.end()) return iter->second;
auto iter=operands::strConst.find(s);
if (iter!=operands::strConst.end())
{
return shared_ptr<operands>(new operands(iter->second, T_STRING));
}
++nextID;
consts_h << "const string k" << nextID << "=\"" << s << "\";\n";
constStr[s]=nextID;
return nextID;
operands::strConst[s]=nextID;
return shared_ptr<operands>(new operands(nextID, T_STRING));
}
unsigned int operands::createConst(string &s, enum TYPES t)
shared_ptr<operands>operands::createConst(string s, enum TYPES t)
{
operands *me=new operands(t);
shared_ptr<operands>me=shared_ptr<operands>(new operands(t));
if (t==T_INT)
{
consts_h << "const int k";
@@ -64,7 +69,7 @@ unsigned int operands::createConst(string &s, enum TYPES t)
enum TYPES operands::getSimpleVarType()
{
switch type
switch (this->getType())
{
case T_FLOAT:
case T_FLOATCALL_ARRAY:
@@ -111,29 +116,31 @@ void operands::generateBox(ostream &scope)
scope << this->getID() << ";\n";
}
operands *operands::getOrCreateGlobal(string &s, enum TYPES t)
shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
{
operands op*=operands::globals->find(s);
auto op=globals.find(s);
if (op==globals.end())
{
op=new variable(heap_h, s, t);
return shared_ptr<variable>(new variable(heap_h, s, t));
}
return op;
return op->second;
}
void operands::boxName(ostream &scope)
string operands::boxName()
{
ostringstream s;
switch (this->getType())
{
case T_STRINGVAR:
case T_INTVAR:
case T_FLOATVAR:
s << 'v' << this->getID();
return s.str();
break;
default:
error(E_INTERNAL);
}
scope << "v" << this->getID();
}
/* expression parsing routines */
@@ -141,7 +148,7 @@ void operands::boxName(ostream &scope)
/* binary vs. unary ops */
bool expression::isBinOp()
{
switch this->getOp()
switch (this->getOp())
{
case O_NEGATE:
case O_NOT:
@@ -153,10 +160,11 @@ bool expression::isBinOp()
return true;
}
operands *expression::evaluate()
shared_ptr<operands>expression::evaluate()
{
if (this->getOp()==O_TERM) return op;
operands *l, *r;
shared_ptr<operands>l;
shared_ptr<operands>r;
enum TYPES t;
ostream &scope=scopeGlobal?heap_h:funcs_h;
l=this->getLeft()->evaluate();
@@ -167,12 +175,12 @@ operands *expression::evaluate()
enum TYPES rt=r->getSimpleVarType();
if (lt==T_INTVAR && rt==T_FLOATVAR)
{
l=new expression(new expression(l), O_INT_TO_FLOAT)->evaluate();
l=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(l)), O_INT_TO_FLOAT))->evaluate());
lt=T_FLOATVAR;
}
if (lt==T_FLOATVAR && rt==T_INTVAR)
{
r=new expression(new expression(r), O_INT_TO_FLOAT)->evaluate();
r=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(r)), O_INT_TO_FLOAT))->evaluate());
rt=T_FLOATVAR;
}
if (lt!=rt)error(E_TYPE_MISMATCH);
@@ -183,96 +191,96 @@ operands *expression::evaluate()
t=l->getSimpleVarType();
r=NULL;
}
if (t==T_STRINGVAR) return expression::stringEval();
if (t==T_STRINGVAR) return expression::stringEval(l, r);
switch (this->getOp())
{
case O_INVERT:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n";
break;
case O_NEGATE:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n";
break;
case O_NOT:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n";
break;
case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */
this->op=new operands(T_FLOATVAR);
this->op=shared_ptr<operands>(new operands(T_FLOATVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= const_cast<double>("
<< l->boxName() << ");\n";
/* TODO: Check for divide by zero error and modulo zero error */
case O_REMAINDER:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n";
break;
case O_DIVIDE:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n";
break;
case O_PLUS:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n";
break;
case O_MINUS:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n";
break;
case O_MULTIPLY:
this->op=new operands(t);
this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << r->boxName() << ";\n";
break;
case O_OR:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << r->boxName() << ";\n";
break;
case O_AND:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n";
break;
case O_GREATER:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n";
break;
case O_LESS:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << r->boxName() << ")?-1:0;\n";
break;
case O_GREATER_EQUAL:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << r->boxName() << ")?-1:0;\n";
break;
case O_LESS_EQUAL:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n";
break;
case O_EQUAL:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n";
break;
case O_UNEQUAL:
this->op=new operands(T_INTVAR);
this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n";
break;
@@ -282,80 +290,46 @@ operands *expression::evaluate()
break;
}
/* convert expression into single operand */
delete this->left;
this->left=NULL;
if (r)
{
delete this->right;
this->right=NULL;
}
this->oper=O_TERM;
return this->op;
}
operands * expression::stringEval(ostream &scope, operands *l, operands *r)
shared_ptr<operands> expression::stringEval(shared_ptr<operands>l, shared_ptr<operands>r)
{
if (this->getOp()==O_STRING_CONCAT)
{
this->op=new operands(T_STRINGVAR);
this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" l->boxName() << "+" << r->boxName();
}
else
{
errorLevel=E_INTERNAL;
exit(1);
this->op=shared_ptr<operands>(new operands(T_STRINGVAR));
this->op->generateBox(scopeGlobal?heap_h:funcs_h);
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName();
}
else error(E_INTERNAL);
/* convert expression into single operand */
delete this->left;
this->left=NULL;
if (r)
{
delete this->right;
this->right=NULL;
}
this->oper=O_TERM;
return this->op;
}
expression::~expression()
{
if(this->getOp()==O_TERM)
{
delete this->op;
}
else
{
delete this->left;
if (this->isBinOp())
{
delete this->right;
}
}
}
/* variable definitions */
variable::variable(ostream &scope, string &name, enum TYPES t):operands(t)
{
this->generateBox(scope); /*TODO: FINISH THIS*/
}
variable *variable::getOrCreateVarName(string &name, enum TYPES t)
shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
{
if (!scopeGlobal)
{
return fn::getOrCreateVar(t, name, false);
}
/* TODO: verify if type is compatible */
shared_ptr<operands>op=operands::getOrCreateGlobal(name);
shared_ptr<variable>v=new variable();
v->assignment(new expression(op));
shared_ptr<operands>op=operands::getOrCreateGlobal(name, t);
shared_ptr<variable>v=shared_ptr<variable>(new variable());
v->assignment(shared_ptr<expression>(new expression(op)));
return v;
}
void variable::assignment(expression *value)
void variable::assignment(shared_ptr<expression>value)
{
operands *op=value->evaluate();
shared_ptr<operands>op=value->evaluate();
enum TYPES t=op->getSimpleVarType();
switch (this->getType())
{

View File

@@ -8,25 +8,27 @@
*/
#include "yab2cpp.h"
class label;
/* function definitions */
fn *fn::getCurrentSub()
shared_ptr<fn>fn::getCurrentSub()
{
return callStack.back;
return callStack.back();
}
void fn::generateOnNSub(expression *e)
void fn::generateOnNSub(shared_ptr<expression>e, unsigned int skip)
{
shared_ptr<label>r=new label();
shared_ptr<fn> self=new fn(r);
shared_ptr<label>r=shared_ptr<label>(new label());
shared_ptr<fn> self=shared_ptr<fn>(new fn(r));
fn::callStack.push_back(self);
label::generateOnNTo(e);
label::generateOnNTo(e, skip);
r->generate();
}
void fn::generateGosub(shared_ptr<label> sub)
{
shared_ptr<label>r=new label();
shared_ptr<fn> self=new fn(r);
shared_ptr<label>r=shared_ptr<label>(new label());
shared_ptr<fn> self=shared_ptr<fn>(new fn(r));
fn::callStack.push_back(self);
sub->generateJumpTo();
r->generate();
@@ -39,50 +41,79 @@ fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB)
shared_ptr<fn> fn::getSub(string &name)
{
auto iter=fn::functions.find(name)
auto iter=fn::functions.find(name);
if(iter==fn::functions.end()) return NULL;
return iter->second;
}
operands *fn::generateCall(string &name, list<shared_ptr<operands> >&paramList)
shared_ptr<operands>fn::generateCall(string &name,
list<shared_ptr<operands> >paramList)
{
auto v=params.begin();
shared_ptr<operands>current;
shared_ptr<fn>g=fn::getSub(name);
if (g==NULL)
{
errorLevel=E_SUBROUTINE_NOT_FOUND;
exit(1);
error(E_SUBROUTINE_NOT_FOUND);
}
if (paramList.size()>params.size())
{
errorLevel=E_TOO_MANY_PARAMETERS;
exit(1);
error(E_TOO_MANY_PARAMETERS);
}
output_cpp << "struct *f" << /* TODO: finish this */
<< "= new struct f" << g->getID();
/* TODO CHECK THIS */
output_cpp << "struct f" << g->getID()
<< "*sub" << this->getID()
<< "= new struct f" << g->getID()
<< "();\n";
while(paramList.size()>0)
{
current=paramList.front;
current= paramList.front();
paramList.pop_front();
if(current->getSimpleVarType()!=*v->getType())
if(current->getSimpleVarType()!=(*v)->getType())
{
errorLevel=E_TYPE_MISMATCH;
exit(1);
error(E_TYPE_MISMATCH);
}
(*v)->assignment(shared_ptr<expression>(
new expression(current)));
++v;
}
/* pad remaining unassigned variables with empty values */
while (v!=params.end())
{
switch ((*v)->getType())
{
case T_FLOATVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::createConst("0.0", T_FLOAT)
)));
break;
case T_INTVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::createConst("0", T_INT)
)));
break;
case T_STRINGVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::getOrCreateStr(string("")
))));
default:
error(E_TYPE_MISMATCH);
}
*v->assignment(new expression(current));
++v;
}
return g->/*TODO FINISH THIS*/
}
void fn::generateReturn()
{
shared_ptr<fn>c=fn::getCurrent();
shared_ptr<fn>c=getCurrentSub();
switch(c->getType())
{
case T_UNKNOWNFUNC:
/* set return type to NONE */
this->kind=T_NONE;
/*fallthrough*/
case T_GOSUB:
@@ -95,9 +126,9 @@ void fn::generateReturn()
}
}
operands *fn::generateReturn(expression *expr)
shared_ptr<operands>fn::generateReturn(shared_ptr<expression>expr)
{
operands *out=expr->evaluate();
shared_ptr<operands>out=expr->evaluate();
this->kind=out->getSimpleVarType();
this->ret->generateJumpTo();
fn::callStack.pop_back();
@@ -153,7 +184,7 @@ void fn::close()
(t==T_UNKNOWNFUNC||t==T_VOIDFUNC))
{
/* generate a typeless return */
this->generateReturn()
this->generateReturn();
}
funcs_h << "};\n";
fn::locals.clear();
@@ -165,10 +196,10 @@ void fn::close()
fn::fn(string &s, enum CODES t):codeType(t)
{
if (!scopeGlobal) error(E_END_FUNCTION);
if (fn::functions->find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
if (fn::functions.find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
this->id= ++nextID;
funcs_h << "struct f" << this->id <<"\n{\n";
this->ret=new label();
this->ret=shared_ptr<label>(new label());
fn::functions[s]=this;
scopeGlobal=false;
}