added static initializers and now it builds and links!

This commit is contained in:
Samuel D. Crow
2021-03-19 19:26:10 -05:00
parent 68c4806a3d
commit e5d08cc31b
5 changed files with 102 additions and 115 deletions

View File

@@ -8,6 +8,10 @@
*/
#include "yab2cpp.h"
unordered_map<string, shared_ptr<variable> >globals;
unordered_map<string, shared_ptr<variable> >locals;
unordered_map<string, shared_ptr<variable> >statics;
/* These correspond to the enum COMPILE_ERRORS. */
const char *COMPILE_ERROR_NAMES[]={
"no error",
@@ -200,19 +204,17 @@ void logger(string s)
void shutDown()
{
if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
if (fn::isCallStackEmpty())
logger("Dumping stack.");
if (mode & DUMP && (logfile))
{
logger("Stack was empty");
fn::dumpCallStack();
}
else
varNames << "Global Variables\n";
for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
{
logger("Dumping stack.");
if (mode & DUMP && (logfile))
{
fn::dumpCallStack();
}
varNames << "variable " << iter->first << " has ID " << iter->second << "\n";
}
operands::dumpVars();
varNames << endl;
label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl;
}

View File

@@ -22,13 +22,16 @@ using namespace std;
#define VER_MINOR 0
#define VER_RELEASE 1
class variable;
extern ofstream output_cpp;
extern ofstream funcs_h;
extern ofstream heap_h;
extern ofstream consts_h;
extern ofstream logfile;
extern ofstream varNames;
extern unordered_map<string, shared_ptr<variable> >globals;
extern unordered_map<string, shared_ptr<variable> >locals;
extern unordered_map<string, shared_ptr<variable> >statics;
/*
** list of all compiler errors
**
@@ -151,7 +154,7 @@ enum OPERATORS
/* global prototype */
[[noreturn]] void error(enum COMPILE_ERRORS err);
void logger(string s);
/* internal states used by the parser */
class scope:public ofstream
{
@@ -172,16 +175,10 @@ class operands
static unsigned int nextID;
/* private constructor for parameter passing only */
explicit operands(unsigned int id, enum TYPES t);
protected:
static unordered_map<string, shared_ptr<operands>> globals;
public:
enum TYPES getType() const {return type;}
unsigned int getID() const {return id;}
static shared_ptr<operands>findGlobal(string &s);
static void dumpVars();
static shared_ptr<operands>getOrCreateGlobal(string &s, enum TYPES t);
enum TYPES getSimpleVarType();
void generateBox(enum SCOPES s);
virtual string boxName();
@@ -233,26 +230,24 @@ public:
this->right=r;
this->oper=o;
}
expression(operands *x)
expression(shared_ptr<operands>x)
{
op=shared_ptr<operands>(x);
op=x;
oper=O_TERM;
}
/*TODO: Recycle temporary variables when not in debug mode*/
virtual ~expression();
virtual ~expression()
{}
};
/* parent class of all code types */
class codeType
{
enum CODES type;
static list<shared_ptr<codeType> >nesting;
public:
enum CODES getType() const {return this->type;}
static shared_ptr<codeType> getCurrent();
virtual void close();
virtual void close()=0;
virtual void generateBreak()=0;
explicit codeType(enum CODES t);
@@ -283,8 +278,9 @@ public:
label(){this->id = ++nextID;}
label(string &s)
{
unordered_map<string, shared_ptr<label> >lookup;
label();
lookup[s]=shared_ptr<label>(this);
label::lookup[s]=shared_ptr<label>(this);
}
virtual ~label()
@@ -357,7 +353,7 @@ public:
static shared_ptr<variable>getOrCreateVar(string &name, enum TYPES t);
void assignment(shared_ptr<expression>value);
explicit variable(enum SCOPES s, string &name, enum TYPES t);
variable(enum SCOPES s, string &name, enum TYPES t);
variable();
~variable()
{}
@@ -386,29 +382,27 @@ public:
virtual void close();
explicit forLoop(shared_ptr<variable>v, shared_ptr<expression>start, shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL);
virtual ~forLoop();
virtual ~forLoop()
{}
};
class fn:codeType
{
friend variable;
static unordered_map<string, shared_ptr<fn> >functions;
static unordered_map<string, shared_ptr<fn> > functions;
static list<shared_ptr<fn> > callStack;
static unsigned int nextID;
list<shared_ptr<variable> >params;
string funcName;
unsigned int id;
enum TYPES kind;
shared_ptr<operands>rc;
/* two labels common to all subroutine calls */
shared_ptr<label>startAddr;
shared_ptr<label>ret;
/* private constructor used by generateGosub and generateOnNSub*/
fn(shared_ptr<label>gosub);
static unordered_map<string, shared_ptr<variable> >locals;
static unordered_map<string, shared_ptr<variable> >statics;
public:
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);
@@ -419,7 +413,7 @@ public:
int getNumParams() const {return this->params.size();}
void addParameter(shared_ptr<variable>);
shared_ptr<operands>generateCall(string &name, list<shared_ptr<operands> >paramList);
shared_ptr<operands>generateCall(string &name, list<shared_ptr<operands> >&paramList);
void generateReturn(shared_ptr<expression>expr);
void generateReturn();
virtual void generateBreak();

View File

@@ -8,28 +8,22 @@
*/
#include "yab2cpp.h"
/* static initializers */
unordered_map<string, shared_ptr<label> > label::lookup;
unsigned int label::nextID;
/* base class of all the code structure types */
codeType::codeType(enum CODES t)
{
nesting.push_back(shared_ptr<codeType>(this));
this->type=t;
}
shared_ptr<codeType> codeType::getCurrent()
{
return nesting.back();
}
void codeType::close()
{
nesting.pop_back();
}
/* label definitions and helper routines */
shared_ptr<label>label::find(string &s)
{
auto ret=lookup.find(s);
return(ret==lookup.end()?NULL:ret->second);
unordered_map<string, shared_ptr<label> >lookup;
auto ret=label::lookup.find(s);
return(ret==label::lookup.end()?NULL:ret->second);
}
void label::dumpLabels()
@@ -201,30 +195,30 @@ forLoop::forLoop(shared_ptr<variable>v,
stopTemp->assignment(stop);
/* if (v<stopTemp) */
shared_ptr<ifStatement>c=shared_ptr<ifStatement>(new ifStatement(
shared_ptr<expression>(new expression(shared_ptr<expression>(new expression(v.get())),
O_LESS, shared_ptr<expression>(new expression(stopTemp.get()))))));
shared_ptr<expression>(new expression(shared_ptr<expression>(new expression(v)),
O_LESS, shared_ptr<expression>(new expression(stopTemp))))));
/* startTemp=v;*/
startTemp->assignment(shared_ptr<expression>(new expression(v.get())));
startTemp->assignment(shared_ptr<expression>(new expression(v)));
/* else */
c->alternative();
/* startTemp=stopTemp;
stopTemp=v;*/
startTemp->assignment(shared_ptr<expression>(new expression(stopTemp.get())));
stopTemp->assignment(shared_ptr<expression>(new expression(v.get())));
startTemp->assignment(shared_ptr<expression>(new expression(stopTemp)));
stopTemp->assignment(shared_ptr<expression>(new expression(v)));
/* endif */
c->close();
/* while (v<=stopTemp && v>=startTemp) */
shared_ptr<expression>stopper1=shared_ptr<expression>(new expression(
shared_ptr<expression>(new expression(v.get())), O_LESS_EQUAL,
shared_ptr<expression>(new expression(stopTemp.get()))));
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.get())), O_GREATER_EQUAL,
shared_ptr<expression>(new expression(startTemp.get()))));
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(
new constOp("0", T_INT))))));
shared_ptr<constOp>(new constOp("0", T_INT)))))));
if (stepVal)
{
step=stepVal;
@@ -232,7 +226,8 @@ forLoop::forLoop(shared_ptr<variable>v,
else
{
/* if not present "step" is assumed to be 1 */
step=shared_ptr<expression>(new expression(new constOp("1", T_INT)));
step=shared_ptr<expression>(new expression(
shared_ptr<constOp>(new constOp("1", T_INT))));
}
}
@@ -245,7 +240,7 @@ void forLoop::close()
{
/* var=var+step; */
shared_ptr<expression>stepper=shared_ptr<expression>(new expression(
shared_ptr<expression>(new expression(var.get())), O_PLUS, step));
shared_ptr<expression>(new expression(var)), O_PLUS, step));
var->assignment(stepper);
infrastructure->close();
}

View File

@@ -8,7 +8,10 @@
*/
#include "yab2cpp.h"
/* forward declaration and static initializers */
class fn;
unsigned int operands::nextID;
unordered_map<string, unsigned int> constOp::strConst;
/* scope methods */
ofstream &scope::operator<<(ostream &in)
@@ -24,26 +27,6 @@ ofstream &scope::operator<<(ostream &in)
}
/* methods for operands */
shared_ptr<operands>operands::findGlobal(string &s)
{
auto iter=operands::globals.find(s);
if (iter==operands::globals.end())
{
return NULL;
}
return iter->second;
}
void operands::dumpVars()
{
varNames << "Global Variables\n";
for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
{
varNames << "variable " << iter->first << " has ID " << iter->second << "\n";
}
varNames << endl;
}
enum TYPES operands::getSimpleVarType()
{
switch (this->getType())
@@ -96,16 +79,6 @@ void operands::generateBox(enum SCOPES s)
y << x;
}
shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
{
auto op=globals.find(s);
if (op==globals.end())
{
return shared_ptr<variable>(new variable(S_GLOBAL, s, t));
}
return op->second;
}
string operands::boxName()
{
ostringstream s;
@@ -143,6 +116,8 @@ void constOp::processConst( const string &s)
/* constructor for constOp */
constOp::constOp(const string &s, enum TYPES t):operands(t)
{
/* make sure string folder is initialized */
unordered_map<string, shared_ptr<operands> >strConst;
switch (t)
{
case T_INT:
@@ -155,8 +130,8 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
break;
case T_STRING:
{
auto i=strConst.find(s);
if (i!=strConst.end())
auto i=constOp::strConst.find(s);
if (i!=constOp::strConst.end())
{
processConst((*i).second);
}
@@ -164,7 +139,7 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
{
consts_h << "const string ";
processConst(s);
strConst[s]=getID();
constOp::strConst[s]=getID();
}
}
break;
@@ -206,12 +181,12 @@ shared_ptr<operands>expression::evaluate()
enum TYPES rt=r->getSimpleVarType();
if (lt==T_INTVAR && rt==T_FLOATVAR)
{
l=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(l.get())), 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=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(r.get())), 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);
@@ -346,18 +321,18 @@ variable::variable(enum SCOPES s, string &name, enum TYPES t):operands(t)
switch (s)
{
case S_LOCAL:
if(fn::locals.find(name)!=fn::locals.end() ||
fn::statics.find(name)!=fn::statics.end() ) error(E_DUPLICATE_SYMBOL);
fn::locals[name]=shared_ptr<variable>(this);
if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
locals[name]=shared_ptr<variable>(this);
break;
case S_GLOBAL:
if(findGlobal(name)!=NULL) error(E_DUPLICATE_SYMBOL);
if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL);
globals[name]=shared_ptr<variable>(this);
break;
case S_STATIC:
if(fn::locals.find(name)!=fn::locals.end() ||
fn::statics.find(name)!=fn::statics.end() ) error(E_DUPLICATE_SYMBOL);
fn::statics[name]=shared_ptr<variable>(this);
if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
statics[name]=shared_ptr<variable>(this);
break;
default:
error(E_INTERNAL);
@@ -369,13 +344,13 @@ shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
{
if (!scopeGlobal)
{
return fn::getOrCreateVar(t, name, false);
auto i=locals.find(name);
if(i!=locals.end())return i->second;
i=statics.find(name);
if(i!=statics.end())return i->second;
}
/* TODO: verify if type is compatible */
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.get())));
return v;
if (globals.find(name)!=globals.end())return globals[name];
return shared_ptr<variable>(new variable(scopeGlobal?S_GLOBAL:S_LOCAL, name, t));
}
void variable::assignment(shared_ptr<expression>value)

View File

@@ -8,11 +8,30 @@
*/
#include "yab2cpp.h"
class label;
/* static initializers */
unordered_map<string, shared_ptr<fn> > fn::functions;
list<shared_ptr<fn> >fn::callStack;
unsigned int fn::nextID;
/* function definitions */
void fn::dumpCallStack()
{
auto i=callStack.rbegin();
if (i==callStack.rend())
{
logfile << "call stack was empty\n";
return;
}
do
{
logfile << (*i)->funcName << "\n";
++i;
} while(i!=callStack.rend());
}
shared_ptr<fn>fn::getCurrentSub()
{
list<shared_ptr<fn> >callStack;
return callStack.back();
}
@@ -36,6 +55,7 @@ void fn::generateGosub(shared_ptr<label> sub)
fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB)
{
this->funcName="unnamed gosub";
this->ret=gosub;
}
@@ -47,7 +67,7 @@ shared_ptr<fn> fn::getSub(string &name)
}
shared_ptr<operands>fn::generateCall(string &name,
list<shared_ptr<operands> >paramList)
list<shared_ptr<operands> >&paramList)
{
auto v=params.begin();
shared_ptr<operands>current;
@@ -76,7 +96,7 @@ shared_ptr<operands>fn::generateCall(string &name,
error(E_TYPE_MISMATCH);
}
(*v)->assignment(shared_ptr<expression>(
new expression(current.get())));
new expression(current)));
++v;
}
/* pad remaining unassigned variables with empty values */
@@ -87,19 +107,19 @@ shared_ptr<operands>fn::generateCall(string &name,
case T_FLOATVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
new constOp("0.0", T_FLOAT)
shared_ptr<constOp>(new constOp("0.0", T_FLOAT))
)));
break;
case T_INTVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
new constOp("0", T_INT)
shared_ptr<constOp>(new constOp("0", T_INT))
)));
break;
case T_STRINGVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
new constOp("", T_STRING)
shared_ptr<constOp>(new constOp("", T_STRING))
)));
default:
error(E_INTERNAL);
@@ -172,8 +192,8 @@ void fn::close()
this->generateReturn();
}
funcs_h << "};\n";
fn::locals.clear();
fn::statics.clear();
locals.clear();
statics.clear();
this->params.clear();
scopeGlobal=true;
}
@@ -184,6 +204,7 @@ fn::fn(string &s, enum CODES t, shared_ptr<operands>returnCode):codeType(t)
if (!scopeGlobal) error(E_END_FUNCTION);
/*check if this function name is already used*/
if (fn::functions.find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
this->funcName=s;
this->id= ++nextID;
/*define storage for locals*/
funcs_h << "struct f" << this->id <<"\n{\n";