added static initializers and now it builds and links!
This commit is contained in:
20
yab2cpp.cpp
20
yab2cpp.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
44
yab2cpp.h
44
yab2cpp.h
@@ -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> >¶mList);
|
||||||
void generateReturn(shared_ptr<expression>expr);
|
void generateReturn(shared_ptr<expression>expr);
|
||||||
void generateReturn();
|
void generateReturn();
|
||||||
virtual void generateBreak();
|
virtual void generateBreak();
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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> >¶mList)
|
||||||
{
|
{
|
||||||
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";
|
||||||
|
|||||||
Reference in New Issue
Block a user