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" #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. */ /* These correspond to the enum COMPILE_ERRORS. */
const char *COMPILE_ERROR_NAMES[]={ const char *COMPILE_ERROR_NAMES[]={
"no error", "no error",
@@ -200,19 +204,17 @@ void logger(string s)
void shutDown() void shutDown()
{ {
if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl; 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."); varNames << "variable " << iter->first << " has ID " << iter->second << "\n";
if (mode & DUMP && (logfile))
{
fn::dumpCallStack();
}
} }
operands::dumpVars(); varNames << endl;
label::dumpLabels(); label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl; output_cpp << "}\n}return state;\n}"<< endl;
} }

View File

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

View File

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

View File

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

View File

@@ -8,11 +8,30 @@
*/ */
#include "yab2cpp.h" #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 */ /* 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() shared_ptr<fn>fn::getCurrentSub()
{ {
list<shared_ptr<fn> >callStack;
return callStack.back(); return callStack.back();
} }
@@ -36,6 +55,7 @@ void fn::generateGosub(shared_ptr<label> sub)
fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB) fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB)
{ {
this->funcName="unnamed gosub";
this->ret=gosub; this->ret=gosub;
} }
@@ -47,7 +67,7 @@ shared_ptr<fn> fn::getSub(string &name)
} }
shared_ptr<operands>fn::generateCall(string &name, shared_ptr<operands>fn::generateCall(string &name,
list<shared_ptr<operands> >paramList) list<shared_ptr<operands> >&paramList)
{ {
auto v=params.begin(); auto v=params.begin();
shared_ptr<operands>current; shared_ptr<operands>current;
@@ -76,7 +96,7 @@ shared_ptr<operands>fn::generateCall(string &name,
error(E_TYPE_MISMATCH); error(E_TYPE_MISMATCH);
} }
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(shared_ptr<expression>(
new expression(current.get()))); new expression(current)));
++v; ++v;
} }
/* pad remaining unassigned variables with empty values */ /* pad remaining unassigned variables with empty values */
@@ -87,19 +107,19 @@ shared_ptr<operands>fn::generateCall(string &name,
case T_FLOATVAR: case T_FLOATVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(shared_ptr<expression>(
new expression( new expression(
new constOp("0.0", T_FLOAT) shared_ptr<constOp>(new constOp("0.0", T_FLOAT))
))); )));
break; break;
case T_INTVAR: case T_INTVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(shared_ptr<expression>(
new expression( new expression(
new constOp("0", T_INT) shared_ptr<constOp>(new constOp("0", T_INT))
))); )));
break; break;
case T_STRINGVAR: case T_STRINGVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(shared_ptr<expression>(
new expression( new expression(
new constOp("", T_STRING) shared_ptr<constOp>(new constOp("", T_STRING))
))); )));
default: default:
error(E_INTERNAL); error(E_INTERNAL);
@@ -172,8 +192,8 @@ void fn::close()
this->generateReturn(); this->generateReturn();
} }
funcs_h << "};\n"; funcs_h << "};\n";
fn::locals.clear(); locals.clear();
fn::statics.clear(); statics.clear();
this->params.clear(); this->params.clear();
scopeGlobal=true; 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); if (!scopeGlobal) error(E_END_FUNCTION);
/*check if this function name is already used*/ /*check if this function name is already used*/
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->funcName=s;
this->id= ++nextID; this->id= ++nextID;
/*define storage for locals*/ /*define storage for locals*/
funcs_h << "struct f" << this->id <<"\n{\n"; funcs_h << "struct f" << this->id <<"\n{\n";