removed most of the shared_ptr usage and retooled temporary variables to recycle

This commit is contained in:
Samuel D. Crow
2021-03-28 22:35:35 -05:00
parent fd89b1a054
commit bb2be9c16c
7 changed files with 452 additions and 291 deletions

View File

@@ -10,9 +10,9 @@
#include "yab2cpp.h" #include "yab2cpp.h"
#include <cassert> #include <cassert>
unordered_map<string, shared_ptr<variableType> >globals; unordered_map<string, unique_ptr<variableType> >globals;
unordered_map<string, shared_ptr<variableType> >locals; unordered_map<string, unique_ptr<variableType> >locals;
unordered_map<string, shared_ptr<variableType> >statics; unordered_map<string, unique_ptr<variableType> >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[]={
@@ -27,7 +27,8 @@ const char *COMPILE_ERROR_NAMES[]={
"value returned from gosub call", "value returned from gosub call",
"undefined subroutine name", "undefined subroutine name",
"too many parameters in function call", "too many parameters in function call",
"value cannot be assigned" "value cannot be assigned",
"undimensioned array or undeclared function"
}; };
/* These correspond to the types of enum TYPES. */ /* These correspond to the types of enum TYPES. */
@@ -214,8 +215,8 @@ void setUp()
[[noreturn]] void error(enum COMPILE_ERRORS e) [[noreturn]] void error(enum COMPILE_ERRORS e)
{ {
cerr << COMPILE_ERROR_NAMES[e] << endl;
errorLevel=e; errorLevel=e;
shutDown();
exit(1); exit(1);
} }
@@ -245,6 +246,8 @@ void shutDown()
{ {
if (errorLevel != E_OK) cerr << "\nERROR: " if (errorLevel != E_OK) cerr << "\nERROR: "
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl; << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
logger("Purging tempVar queues");
tempVar::eraseQueues();
logger("Dumping stack."); logger("Dumping stack.");
if (DUMP && (logfile)) fn::dumpCallStack(); if (DUMP && (logfile)) fn::dumpCallStack();
if (DUMP) if (DUMP)
@@ -271,17 +274,14 @@ void shutDown()
statics.clear(); statics.clear();
} }
shared_ptr<string>name; variableType *v;
shared_ptr<variableType>v; printSegment *print;
shared_ptr<printSegment>print;
void testInt() void testInt()
{ {
name=shared_ptr<string>(new string("v")); string name=string("v");
v=variableType::getOrCreateVar(*name, T_INTVAR); v=variableType::getOrCreateVar(name, T_INTVAR);
v->assignment(shared_ptr<expression>(new expression( v->assignment(new expression(new constOp("2", T_INT)));
shared_ptr<operands>(new constOp("2", T_INT))))); print=new printSegment(new expression(v));
print=shared_ptr<printSegment>(
new printSegment(shared_ptr<expression>(new expression(v))));
print->generate(); print->generate();
label::generateEnd(); label::generateEnd();
} }

View File

@@ -7,10 +7,11 @@
** **
*/ */
#include "yab2cpp.h" #include "yab2cpp.h"
#include <cassert>
unordered_map<string, shared_ptr<variableType> >globals; unordered_map<string, unique_ptr<variableType> >globals;
unordered_map<string, shared_ptr<variableType> >locals; unordered_map<string, unique_ptr<variableType> >locals;
unordered_map<string, shared_ptr<variableType> >statics; unordered_map<string, unique_ptr<variableType> >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[]={
@@ -25,7 +26,8 @@ const char *COMPILE_ERROR_NAMES[]={
"value returned from gosub call", "value returned from gosub call",
"undefined subroutine name", "undefined subroutine name",
"too many parameters in function call", "too many parameters in function call",
"value cannot be assigned" "value cannot be assigned",
"undimensioned array or undeclared function"
}; };
/* These correspond to the types of enum TYPES. */ /* These correspond to the types of enum TYPES. */
@@ -92,7 +94,6 @@ void shutDown();
/* process command line parameters */ /* process command line parameters */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
atexit(shutDown);
switch (argc) switch (argc)
{ {
case 1: case 1:
@@ -150,6 +151,7 @@ int main(int argc, char *argv[])
helpText(argv[0]); helpText(argv[0]);
break; break;
} }
cout << "program exiting" <<endl;
return 0; return 0;
} }
@@ -177,15 +179,26 @@ void setUp()
funcs_h.open("output/functions.h"); funcs_h.open("output/functions.h");
consts_h.open("output/consts.h"); consts_h.open("output/consts.h");
heap_h.open("output/heap.h"); heap_h.open("output/heap.h");
output_cpp << "#include <runtime.h>\n#include \"consts.h\"\n" output_cpp << "#include \"../runtime/runtime.h\"\n#include \"consts.h\"\n"
<< "#include \"heap.h\"\n#include \"functions.h\"\n" << "#include \"heap.h\"\n#include \"functions.h\"\n"
<< "int main(int argc, char *argv[])\n{\n" << "unsigned int state=START;\nunsigned int run(){\n"
<< "unsigned int state=start;\nint run(){\nwhile (state>=start){\n" << "while (state>=START){\n"
<< "switch(state){\ncase start:" << endl; << "switch(state){\ncase START:" << endl;
if (DUMP) }
{ else
varNames.open("varnames.txt"); {
} output_cpp.open("/dev/null");
funcs_h.open("/dev/null");
consts_h.open("/dev/null");
heap_h.open("/dev/null");
}
if (DUMP)
{
varNames.open("varnames.log");
}
else
{
varNames.open("/dev/null");
} }
if (DEBUG) if (DEBUG)
{ {
@@ -193,11 +206,16 @@ void setUp()
logfile.open("parse.log"); logfile.open("parse.log");
logger("Setup complete."); logger("Setup complete.");
} }
else
{
logfile.open("/dev/null");
}
} }
[[noreturn]] void error(enum COMPILE_ERRORS e) [[noreturn]] void error(enum COMPILE_ERRORS e)
{ {
errorLevel=e; errorLevel=e;
shutDown();
exit(1); exit(1);
} }
@@ -218,27 +236,41 @@ void logger(string s)
if (DEBUG) if (DEBUG)
{ {
indent(); indent();
logfile << s << endl; logfile << s << "\n";
} }
} }
/* shutdown the compiler and exit */ /* shutdown the compiler and exit */
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;
logger("Purging tempVar queues");
tempVar::eraseQueues();
logger("Dumping stack."); logger("Dumping stack.");
if (DUMP && (logfile)) if (DUMP && (logfile)) fn::dumpCallStack();
if (DUMP)
{ {
fn::dumpCallStack(); varNames << "Global Variables\n";
} for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
varNames << "Global Variables\n"; {
for(auto iter=globals.begin(); iter!=globals.end(); ++iter) varNames << "variable " << iter->first
{ << " has ID " << iter->second->getID() << "\n";
varNames << "variable " << iter->first << " has ID " << iter->second << "\n"; }
} varNames << endl;
varNames << endl;
label::dumpLabels(); label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl; }
if (COMPILE)
{
output_cpp << "default:\nstate=UNDEFINED_STATE_ERROR;\n"
<< "break;\n}\n}\nreturn state;\n}"<< endl;
funcs_h.flush();
consts_h.flush();
heap_h.flush();
}
globals.clear();
locals.clear();
statics.clear();
} }
/* open files and compile */ /* open files and compile */
@@ -250,4 +282,3 @@ void compile()
shutDown(); shutDown();
} }

183
yab2cpp.h
View File

@@ -29,9 +29,9 @@ 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<variableType> >globals; extern unordered_map<string, unique_ptr<variableType> >globals;
extern unordered_map<string, shared_ptr<variableType> >locals; extern unordered_map<string, unique_ptr<variableType> >locals;
extern unordered_map<string, shared_ptr<variableType> >statics; extern unordered_map<string, unique_ptr<variableType> >statics;
extern const string CODETYPES[]; extern const string CODETYPES[];
extern const string TYPENAMES[]; extern const string TYPENAMES[];
@@ -41,7 +41,8 @@ extern const string TYPENAMES[];
** Note: There must be a corresponding error message ** Note: There must be a corresponding error message
** to each entry in the COMPILE_ERROR_NAMES constant array. ** to each entry in the COMPILE_ERROR_NAMES constant array.
*/ */
enum COMPILE_ERRORS { enum COMPILE_ERRORS:unsigned int
{
E_OK=0, E_OK=0,
E_BAD_SYNTAX, E_BAD_SYNTAX,
E_TYPE_MISMATCH, E_TYPE_MISMATCH,
@@ -68,7 +69,7 @@ extern bool DEBUG;
extern bool TRACE; extern bool TRACE;
/* list of all variableType and constant types */ /* list of all variableType and constant types */
enum TYPES enum TYPES:unsigned int
{ {
T_UNKNOWN=0, T_UNKNOWN=0,
T_NONE, T_NONE,
@@ -85,7 +86,7 @@ enum TYPES
}; };
/* list of all kinds of other code structures */ /* list of all kinds of other code structures */
enum CODES enum CODES:unsigned int
{ {
T_PRINT=0, T_PRINT=0,
T_PRINTSEGMENT, T_PRINTSEGMENT,
@@ -116,14 +117,14 @@ typedef union
}boxTypes; }boxTypes;
/* subtypes of the T_PRINTSEPARATOR type */ /* subtypes of the T_PRINTSEPARATOR type */
enum SEPARATORS enum SEPARATORS:unsigned int
{ {
S_COMMA, S_COMMA,
S_SEMICOLON, S_SEMICOLON,
S_LINEFEED S_LINEFEED
}; };
enum SCOPES enum SCOPES:unsigned int
{ {
S_UNKNOWN, S_UNKNOWN,
S_LOCAL, S_LOCAL,
@@ -131,7 +132,7 @@ enum SCOPES
S_GLOBAL S_GLOBAL
}; };
enum OPERATORS enum OPERATORS:unsigned int
{ {
O_PLUS, O_PLUS,
O_MINUS, O_MINUS,
@@ -165,20 +166,46 @@ class operands
enum TYPES type; enum TYPES type;
unsigned int id; unsigned int id;
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:
void generateBox(enum SCOPES s);
explicit operands(enum TYPES t);
virtual ~operands()
{}
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;}
enum TYPES getSimpleVarType(); enum TYPES getSimpleVarType();
void generateBox(enum SCOPES s);
virtual string boxName(); virtual string boxName();
enum TYPES coerceTypes(); static enum TYPES getSimpleVarType(enum TYPES t);
explicit operands(enum TYPES t); /* abstract factory */
virtual ~operands() static operands *createOp(enum TYPES t);
virtual void dispose();
};
class tempVar:public operands
{
static list<tempVar *>intQueue;
static list<tempVar *>floatQueue;
static list<tempVar *>stringQueue;
/* private constructor called by getOrCreateVar */
explicit tempVar(enum TYPES t);
/* private destructor called by eraseQueues */
virtual ~tempVar()
{} {}
public:
/* factory method to recycle existing tempVar */
static tempVar *getOrCreateVar(enum TYPES t);
/* purge queues at end of compile */
static void eraseQueues();
/* recycle tempVar in a queue */
virtual void dispose();
}; };
/* constant operands */ /* constant operands */
@@ -203,36 +230,23 @@ public:
/* expression can be terminal or non-terminal node */ /* expression can be terminal or non-terminal node */
class expression class expression
{ {
shared_ptr<operands>op; operands *op;
shared_ptr<expression>left; expression *left;
shared_ptr<expression>right; expression *right;
enum OPERATORS oper; enum OPERATORS oper;
public: public:
enum OPERATORS getOp() const {return oper;} enum OPERATORS getOp() const {return oper;}
shared_ptr<expression>getLeft() const {return left;} expression *getLeft() const {return left;}
shared_ptr<expression>getRight() const {return right;} expression *getRight() const {return right;}
bool isBinOp(); bool isBinOp();
shared_ptr<operands>evaluate(); operands *evaluate();
shared_ptr<operands>stringEval(shared_ptr<operands>l,
shared_ptr<operands>r);
/* r is NULL for unary operators */ /* r is NULL for unary operators */
expression(shared_ptr<expression>l, enum OPERATORS o, expression(expression *l, enum OPERATORS o, expression *r=nullptr);
shared_ptr<expression>r=NULL)
{
this->left=l;
this->right=r;
this->oper=o;
}
/* Terminal expression node */ /* Terminal expression node */
expression(shared_ptr<operands>x) expression(operands *x);
{
op=x;
oper=O_TERM;
}
/*TODO: Recycle temporary variableTypes when not in debug mode*/
virtual ~expression() virtual ~expression()
{} {}
}; };
@@ -252,7 +266,7 @@ class label
{ {
unsigned int id; unsigned int id;
static unsigned int nextID; static unsigned int nextID;
static unordered_map<string, shared_ptr<label> > lookup; static unordered_map<string, unique_ptr<label> > lookup;
public: public:
static void dumpLabels(); static void dumpLabels();
static void generateEnd(); static void generateEnd();
@@ -262,19 +276,18 @@ public:
void generateJumpTo(); void generateJumpTo();
/* pass generateOnNSkip as second paramater /* pass generateOnNSkip as second paramater
to generateOnNTo or generateOnNSub */ to generateOnNTo or generateOnNSub */
unsigned int generateOnNSkip(list<shared_ptr<label> >&dest); unsigned int generateOnNSkip(list<label *>&dest);
static void generateOnNTo(shared_ptr<expression>e, unsigned int skip); static void generateOnNTo(expression *e, unsigned int skip);
void generateCondJump(shared_ptr<expression>e); void generateCondJump(expression *e);
void generate(); void generate();
static shared_ptr<label>find(string &s); static label *find(string &s);
label(){this->id = ++nextID;} label(){this->id = ++nextID;}
label(string &s) label(string &s)
{ {
unordered_map<string, shared_ptr<label> >lookup;
label(); label();
label::lookup[s]=shared_ptr<label>(this); label::lookup[s]=unique_ptr<label>(this);
} }
virtual ~label() virtual ~label()
@@ -285,20 +298,20 @@ public:
class ifStatement:public codeType class ifStatement:public codeType
{ {
/* for continue command */ /* for continue command */
shared_ptr<label>redo; label *redo;
/* for break or after "then" condition */ /* for break or after "then" condition */
shared_ptr<label>done; label *done;
/* For elsif command */ /* For elsif command */
shared_ptr<label>chain; label *chain;
public: public:
void generateContinue(); void generateContinue();
virtual void generateBreak(); virtual void generateBreak();
/* enable else or elsif condition */ /* enable else or elsif condition */
void alternative(shared_ptr<expression>e=NULL); void alternative(expression *e=nullptr);
/* end if */ /* end if */
virtual void close(); virtual void close();
explicit ifStatement(shared_ptr<expression>e); explicit ifStatement(expression *e);
virtual ~ifStatement() virtual ~ifStatement()
{} {}
}; };
@@ -306,11 +319,11 @@ public:
/* looping constructs */ /* looping constructs */
class repeatLoop:public codeType class repeatLoop:public codeType
{ {
shared_ptr<label>loopStart; label *loopStart;
shared_ptr<label>loopEnd; label *loopEnd;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(shared_ptr<expression>e); virtual void close(expression *e);
explicit repeatLoop(); explicit repeatLoop();
virtual ~repeatLoop() virtual ~repeatLoop()
@@ -319,8 +332,8 @@ public:
class doLoop:public codeType class doLoop:public codeType
{ {
shared_ptr<label>loopStart; label *loopStart;
shared_ptr<label>loopEnd; label *loopEnd;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
@@ -332,15 +345,15 @@ public:
class whileLoop:public codeType class whileLoop:public codeType
{ {
shared_ptr<label>loopContinue; label *loopContinue;
shared_ptr<label>loopStart; label *loopStart;
shared_ptr<label>loopEnd; label *loopEnd;
shared_ptr<expression>cond; expression *cond;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
explicit whileLoop(shared_ptr<expression>e); explicit whileLoop(expression *e);
virtual ~whileLoop() virtual ~whileLoop()
{} {}
}; };
@@ -349,9 +362,9 @@ class variableType:public operands
{ {
enum SCOPES myScope; enum SCOPES myScope;
public: public:
static shared_ptr<variableType>getOrCreateVar(string &name, enum TYPES t); static variableType *getOrCreateVar(string &name, enum TYPES t);
void assignment(shared_ptr<expression>value); void assignment(expression *value);
/* always call generateBox() after new variableType() */ /* always call generateBox() after new variableType() */
variableType(enum SCOPES s, string &name, enum TYPES t); variableType(enum SCOPES s, string &name, enum TYPES t);
variableType(); variableType();
@@ -364,11 +377,10 @@ class arrayType:public variableType
list<unsigned int> dimensions; list<unsigned int> dimensions;
public: public:
string generateBox(enum SCOPES s); string generateBox(enum SCOPES s);
virtual string boxName(list<shared_ptr<operands> >indexes); virtual string boxName(list<operands *>indexes);
virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);} virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);}
void assignment(list<shared_ptr<expression> >indexes, void assignment(list<expression *>indexes, expression *value);
shared_ptr<expression>value);
explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim); explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim);
/*:variableType(scope, name, t);*/ /*:variableType(scope, name, t);*/
@@ -378,67 +390,66 @@ public:
class forLoop:public codeType class forLoop:public codeType
{ {
shared_ptr<variableType>var; variableType *var;
shared_ptr<variableType>startTemp; variableType *startTemp;
shared_ptr<variableType>stopTemp; variableType *stopTemp;
shared_ptr<whileLoop>infrastructure; whileLoop *infrastructure;
shared_ptr<expression>step; expression *step;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
explicit forLoop(shared_ptr<variableType>v, shared_ptr<expression>start, explicit forLoop(variableType *v, expression *start, expression *stop,
shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL); expression *stepVal=nullptr);
virtual ~forLoop() virtual ~forLoop()
{} {}
}; };
class fn:codeType class fn:codeType
{ {
static unordered_map<string, shared_ptr<fn> > functions; static unordered_map<string, unique_ptr<fn> > functions;
static list<shared_ptr<fn> > callStack; static list<fn *> callStack;
static unsigned int nextID; static unsigned int nextID;
list<shared_ptr<variableType> >params; list<variableType * >params;
string funcName; string funcName;
unsigned int id; unsigned int id;
enum TYPES kind; enum TYPES kind;
shared_ptr<operands>rc; operands *rc;
/* two labels common to all subroutine calls */ /* two labels common to all subroutine calls */
shared_ptr<label>startAddr; label *startAddr;
shared_ptr<label>ret; label *ret;
/* private constructor used by generateGosub and generateOnNSub*/ /* private constructor used by generateGosub and generateOnNSub*/
fn(shared_ptr<label>gosub); fn(label *gosub);
public: public:
static void dumpCallStack(); static void dumpCallStack();
static shared_ptr<fn>getCurrentSub(); static fn *getCurrentSub();
static shared_ptr<fn>getSub(string &name); static fn *getSub(string &name);
static void generateGosub(shared_ptr<label> sub); static void generateGosub(label * sub);
/* must be called after label::generateOnNSkip */ /* must be called after label::generateOnNSkip */
static void generateOnNSub(shared_ptr<expression>e, unsigned int skip); static void generateOnNSub(expression *e, unsigned int skip);
unsigned int getID() const {return this->id;} 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<variableType>); void addParameter(variableType *);
shared_ptr<operands>generateCall(string &name, operands *generateCall(string &name, list<operands *>&paramList);
list<shared_ptr<operands> >&paramList); void generateReturn(expression *expr);
void generateReturn(shared_ptr<expression>expr);
void generateReturn(); void generateReturn();
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
fn(string &name, enum CODES t, shared_ptr<operands>returnCode=NULL); fn(string &name, enum CODES t, operands *returnCode=nullptr);
virtual ~fn() virtual ~fn()
{} {}
}; };
class printSegment class printSegment
{ {
shared_ptr<expression>cargo; expression *cargo;
enum SEPARATORS sep; enum SEPARATORS sep;
public: public:
void generate(); void generate();
printSegment(shared_ptr<expression>e=NULL, enum SEPARATORS s=S_LINEFEED); printSegment(expression *e=nullptr, enum SEPARATORS s=S_LINEFEED);
virtual ~printSegment() virtual ~printSegment()
{} {}
}; };

View File

@@ -10,7 +10,7 @@
#include "runtime/runtime.h" #include "runtime/runtime.h"
/* static initializers */ /* static initializers */
unordered_map<string, shared_ptr<label> > label::lookup; unordered_map<string, unique_ptr<label> > label::lookup;
unsigned int label::nextID=START; unsigned int label::nextID=START;
/* base class of all the code structure types */ /* base class of all the code structure types */
@@ -36,11 +36,11 @@ codeType::~codeType()
} }
/* label definitions and helper routines */ /* label definitions and helper routines */
shared_ptr<label>label::find(string &s) label *label::find(string &s)
{ {
unordered_map<string, shared_ptr<label> >lookup; unordered_map<string, shared_ptr<label> >lookup;
auto ret=label::lookup.find(s); auto ret=label::lookup.find(s);
return(ret==label::lookup.end()?NULL:ret->second); return(ret==label::lookup.end()?nullptr:ret->second.get());
} }
void label::dumpLabels() void label::dumpLabels()
@@ -65,7 +65,7 @@ void label::generateJumpTo()
} }
/* pass this as second parameter to generateOnNTo or generateOnNSub */ /* pass this as second parameter to generateOnNTo or generateOnNSub */
unsigned int label::generateOnNSkip(list<shared_ptr<label> >&dest) unsigned int label::generateOnNSkip(list<label *>&dest)
{ {
if (dest.size()<2)error(E_BAD_SYNTAX); if (dest.size()<2)error(E_BAD_SYNTAX);
auto iter=dest.begin(); auto iter=dest.begin();
@@ -80,25 +80,33 @@ unsigned int label::generateOnNSkip(list<shared_ptr<label> >&dest)
return this->getID(); return this->getID();
} }
void label::generateOnNTo(shared_ptr<expression>e, unsigned int skip) void label::generateOnNTo(expression *e, unsigned int skip)
{ {
shared_ptr<operands>o=e->evaluate(); operands *o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR) if (o->getType()==T_INT||o->getType()==T_INTVAR)
{ {
output_cpp<< "if(" << o->boxName() << ">=0 && " output_cpp<< "if(" << o->boxName() << ">=0 && "
<< o->boxName() << "<js" << skip << ")state=j[" << o->boxName() << "<js" << skip << ")state=j["
<< o->boxName() << "];\nbreak;\n"; << o->boxName() << "];\nbreak;\n";
o->dispose();
delete e;
return;
} }
error(E_TYPE_MISMATCH);
} }
void label::generateCondJump(shared_ptr<expression>e) void label::generateCondJump(expression *e)
{ {
shared_ptr<operands>o=e->evaluate(); operands *o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR) if (o->getType()==T_INT||o->getType()==T_INTVAR)
{ {
output_cpp<< "if(" << o->boxName() output_cpp<< "if(" << o->boxName()
<< "!=0)state=" << this->getID() << ";\nbreak;\n"; << "!=0)state=" << this->getID() << ";\nbreak;\n";
o->dispose();
delete e;
return;
} }
error(E_TYPE_MISMATCH);
} }
void label::generate() void label::generate()
@@ -108,13 +116,13 @@ void label::generate()
/* ifStatement definition */ /* ifStatement definition */
ifStatement::ifStatement(shared_ptr<expression>e):codeType(T_IF) ifStatement::ifStatement(expression *e):codeType(T_IF)
{ {
this->redo=shared_ptr<label>(new label()); this->redo=new label();
redo->generate(); redo->generate();
this->done=shared_ptr<label>(new label()); this->done=new label();
shared_ptr<expression>f=shared_ptr<expression>(new expression(e,O_NOT)); expression *f=new expression(e,O_NOT);
this->chain=shared_ptr<label>(new label()); this->chain=new label();
chain->generateCondJump(f); chain->generateCondJump(f);
} }
@@ -128,16 +136,15 @@ void ifStatement::generateContinue()
redo->generateJumpTo(); redo->generateJumpTo();
} }
void ifStatement::alternative(shared_ptr<expression>e) void ifStatement::alternative(expression *e)
{ {
done->generateJumpTo(); done->generateJumpTo();
this->chain->generate(); this->chain->generate();
this->chain=NULL; this->chain=nullptr;
if(e!=NULL) if(e!=nullptr)
{ {
this->chain=shared_ptr<label>(new label()); this->chain=new label();
shared_ptr<expression>f=shared_ptr<expression>( expression *f=new expression(e,O_NOT);
new expression(e,O_NOT));
chain->generateCondJump(f); chain->generateCondJump(f);
} }
} }
@@ -152,8 +159,8 @@ void ifStatement::close()
/* Loop definitions */ /* Loop definitions */
repeatLoop::repeatLoop():codeType(T_REPEATLOOP) repeatLoop::repeatLoop():codeType(T_REPEATLOOP)
{ {
this->loopStart=shared_ptr<label>(new label()); this->loopStart=new label();
this->loopEnd=shared_ptr<label>(new label()); this->loopEnd=new label();
loopStart->generate(); loopStart->generate();
} }
@@ -162,17 +169,17 @@ void repeatLoop::generateBreak()
loopEnd->generateJumpTo(); loopEnd->generateJumpTo();
} }
void repeatLoop::close(shared_ptr<expression>e) void repeatLoop::close(expression *e)
{ {
shared_ptr<expression>f=shared_ptr<expression>(new expression(e, O_NOT)); expression *f=new expression(e, O_NOT);
loopStart->generateCondJump(f); loopStart->generateCondJump(f);
loopEnd->generate(); loopEnd->generate();
} }
doLoop::doLoop():codeType(T_DOLOOP) doLoop::doLoop():codeType(T_DOLOOP)
{ {
this->loopStart=shared_ptr<label>(new label()); this->loopStart=new label();
this->loopEnd=shared_ptr<label>(new label()); this->loopEnd=new label();
loopStart->generate(); loopStart->generate();
} }
@@ -187,11 +194,11 @@ void doLoop::close()
this->loopEnd->generate(); this->loopEnd->generate();
} }
whileLoop::whileLoop(shared_ptr<expression>e):codeType(T_WHILELOOP) whileLoop::whileLoop(expression *e):codeType(T_WHILELOOP)
{ {
loopContinue=shared_ptr<label>(new label()); loopContinue=new label();
loopStart=shared_ptr<label>(new label()); loopStart=new label();
loopEnd=shared_ptr<label>(new label()); loopEnd=new label();
cond=e; cond=e;
loopStart->generateJumpTo(); loopStart->generateJumpTo();
loopContinue->generate(); loopContinue->generate();
@@ -209,42 +216,34 @@ void whileLoop::close()
loopEnd->generate(); loopEnd->generate();
} }
forLoop::forLoop(shared_ptr<variableType>v, forLoop::forLoop(variableType *v, expression *start, expression *stop,
shared_ptr<expression>start, shared_ptr<expression>stop, expression *stepVal):codeType(T_FORLOOP)
shared_ptr<expression>stepVal):codeType(T_FORLOOP)
{ {
/*v=start; /*v=start;
stopTemp=stop;*/ stopTemp=stop;*/
v->assignment(start); v->assignment(start);
stopTemp->assignment(stop); stopTemp->assignment(stop);
/* if (v<stopTemp) */ /* if (v<stopTemp) */
shared_ptr<ifStatement>c=shared_ptr<ifStatement>(new ifStatement( ifStatement *c=new ifStatement(new expression(new expression(v), O_LESS,
shared_ptr<expression>(new expression(shared_ptr<expression>( new expression(stopTemp)));
new expression(v)), O_LESS, shared_ptr<expression>(
new expression(stopTemp))))));
/* startTemp=v;*/ /* startTemp=v;*/
startTemp->assignment(shared_ptr<expression>(new expression(v))); startTemp->assignment(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))); startTemp->assignment(new expression(stopTemp));
stopTemp->assignment(shared_ptr<expression>(new expression(v))); stopTemp->assignment(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( expression *stopper1=new expression(new expression(v), O_LESS_EQUAL,
shared_ptr<expression>(new expression(v)), O_LESS_EQUAL, new expression(stopTemp));
shared_ptr<expression>(new expression(stopTemp)))); expression *stopper2=new expression(new expression(v), O_GREATER_EQUAL,
shared_ptr<expression>stopper2=shared_ptr<expression>(new expression( new expression(startTemp));
shared_ptr<expression>(new expression(v)), O_GREATER_EQUAL, expression *stopper=new expression(stopper1, O_AND, stopper2);
shared_ptr<expression>(new expression(startTemp)))); infrastructure=new whileLoop(new expression(stopper, O_UNEQUAL,
shared_ptr<expression>stopper=shared_ptr<expression>(new expression( new expression(new constOp("0", T_INT))));
stopper1, O_AND, stopper2));
shared_ptr<whileLoop>infrastructure=shared_ptr<whileLoop>(new whileLoop(
shared_ptr<expression>(new expression(stopper, O_UNEQUAL,
shared_ptr<expression>(new expression(
shared_ptr<constOp>(new constOp("0", T_INT))))))));
if (stepVal) if (stepVal)
{ {
step=stepVal; step=stepVal;
@@ -252,8 +251,7 @@ forLoop::forLoop(shared_ptr<variableType>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( step=new expression(new constOp("1", T_INT));
shared_ptr<constOp>(new constOp("1", T_INT))));
} }
} }
@@ -265,8 +263,7 @@ void forLoop::generateBreak()
void forLoop::close() void forLoop::close()
{ {
/* var=var+step; */ /* var=var+step; */
shared_ptr<expression>stepper=shared_ptr<expression>(new expression( expression *stepper=new expression(new expression(var), O_PLUS, step);
shared_ptr<expression>(new expression(var)), O_PLUS, step));
var->assignment(stepper); var->assignment(stepper);
infrastructure->close(); infrastructure->close();
} }

View File

@@ -12,11 +12,15 @@
class fn; class fn;
unsigned int operands::nextID=0; unsigned int operands::nextID=0;
unordered_map<string, unsigned int> constOp::strConst; unordered_map<string, unsigned int> constOp::strConst;
list<tempVar *>tempVar::intQueue;
list<tempVar *>tempVar::floatQueue;
list<tempVar *>tempVar::stringQueue;
/* methods for operands */ /* methods for operands */
enum TYPES operands::getSimpleVarType() enum TYPES operands::getSimpleVarType(enum TYPES t)
{ {
switch (this->getType()) switch (t)
{ {
case T_FLOAT: case T_FLOAT:
case T_FLOATCALL_ARRAY: case T_FLOATCALL_ARRAY:
@@ -36,8 +40,12 @@ enum TYPES operands::getSimpleVarType()
error(E_UNASSIGNABLE_TYPE); error(E_UNASSIGNABLE_TYPE);
} }
/* operands used by expression parser and variables */ enum TYPES operands::getSimpleVarType()
{
return getSimpleVarType(this->getType());
}
/* operands used by expression parser and variables */
operands::operands(enum TYPES t) operands::operands(enum TYPES t)
{ {
this->id = ++nextID; this->id = ++nextID;
@@ -77,6 +85,22 @@ void operands::generateBox(enum SCOPES s)
error(E_INTERNAL); error(E_INTERNAL);
} }
operands *operands::createOp(enum TYPES t)
{
if (DEBUG)
{
operands *x=createOp(t);
x->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
return x;
}
return tempVar::getOrCreateVar(t);
}
void operands::dispose()
{
delete this;
}
string operands::boxName() string operands::boxName()
{ {
ostringstream s; ostringstream s;
@@ -97,6 +121,119 @@ string operands::boxName()
} }
} }
tempVar::tempVar(enum TYPES t):operands(t)
{
generateBox(S_GLOBAL);
}
tempVar *tempVar::getOrCreateVar(enum TYPES t)
{
if (t!=getSimpleVarType(t))
{
error(E_TYPE_MISMATCH);
}
switch (t)
{
case T_INTVAR:
if (intQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=intQueue.back();
intQueue.pop_back();
return x;
}
break;
case T_FLOATVAR:
if (floatQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=floatQueue.back();
floatQueue.pop_back();
return x;
}
break;
case T_STRINGVAR:
if (stringQueue.empty())
{
return new tempVar(t);
}
else
{
tempVar *x=stringQueue.back();
stringQueue.pop_back();
return x;
}
default:
break;
}
/* unreachable code */
error(E_INTERNAL);
}
void tempVar::dispose()
{
switch(this->getType())
{
case T_STRINGVAR:
stringQueue.emplace_front(this);
return;
case T_FLOATVAR:
floatQueue.emplace_front(this);
return;
case T_INTVAR:
intQueue.emplace_front(this);
return;
default:
break;
}
error(E_INTERNAL);
}
void tempVar::eraseQueues()
{
tempVar *i;
while(!intQueue.empty())
{
i=intQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary integer\n";
}
delete i;
intQueue.pop_back();
}
while(!floatQueue.empty())
{
i=floatQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary floating point\n";
}
delete i;
floatQueue.pop_back();
}
while(!stringQueue.empty())
{
i=stringQueue.back();
if (DUMP)
{
logfile << "variable " << i->boxName()
<< " is a temporary string\n";
}
delete i;
stringQueue.pop_back();
}
if (DUMP) logfile << endl;
}
void constOp::processConst(unsigned int i) void constOp::processConst(unsigned int i)
{ {
stringstream me; stringstream me;
@@ -136,7 +273,8 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
else else
{ {
consts_h << "const string "; consts_h << "const string ";
processConst(s); processConst(getID());
consts_h << box << "=\"" << s << "\";\n";
constOp::strConst[s]=getID(); constOp::strConst[s]=getID();
} }
} }
@@ -148,6 +286,18 @@ constOp::constOp(const string &s, enum TYPES t):operands(t)
} }
/* expression parsing routines */ /* expression parsing routines */
expression::expression(expression *l, enum OPERATORS o, expression *r)
{
this->left=l;
this->right=r;
this->oper=o;
}
expression::expression(operands *x)
{
op=x;
oper=O_TERM;
}
/* binary vs. unary ops */ /* binary vs. unary ops */
bool expression::isBinOp() bool expression::isBinOp()
@@ -167,13 +317,12 @@ bool expression::isBinOp()
error(E_INTERNAL); error(E_INTERNAL);
} }
shared_ptr<operands>expression::evaluate() operands *expression::evaluate()
{ {
if (this->getOp()==O_TERM) return op; if (this->getOp()==O_TERM) return op;
shared_ptr<operands>l; operands *l;
shared_ptr<operands>r; operands *r;
enum TYPES t; enum TYPES t;
enum SCOPES scopeVar=(scopeGlobal?S_GLOBAL:S_LOCAL);
l=this->getLeft()->evaluate(); l=this->getLeft()->evaluate();
if (this->isBinOp()) if (this->isBinOp())
{ {
@@ -182,14 +331,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>( l=(new expression(new expression(l), O_INT_TO_FLOAT))->evaluate();
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>( r=(new expression(new expression(r), O_INT_TO_FLOAT))->evaluate();
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);
@@ -198,127 +345,111 @@ shared_ptr<operands>expression::evaluate()
else else
{ {
t=l->getSimpleVarType(); t=l->getSimpleVarType();
r=NULL; r=nullptr;
} }
switch (this->getOp()) switch (this->getOp())
{ {
case O_STRING_CONCAT: case O_STRING_CONCAT:
if (t!=T_STRINGVAR) error(E_BAD_SYNTAX); if (t!=T_STRINGVAR) error(E_BAD_SYNTAX);
this->op=shared_ptr<operands>(new operands(T_STRINGVAR)); this->op=operands::createOp(T_STRINGVAR);
this->op->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "+" << r->boxName(); << "+" << r->boxName();
break; break;
case O_INVERT: case O_INVERT:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n";
break; break;
case O_NEGATE: case O_NEGATE:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n";
break; break;
case O_NOT: case O_NOT:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n";
break; break;
case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */ case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */
this->op=shared_ptr<operands>(new operands(T_FLOATVAR)); this->op=operands::createOp(T_FLOATVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "= const_cast<double>(" output_cpp << this->op->boxName() << "= const_cast<double>("
<< l->boxName() << ");\n"; << l->boxName() << ");\n";
/* TODO: Check for divide by zero error and modulo zero error */ /* TODO: Check for divide by zero error and modulo zero error */
case O_REMAINDER: case O_REMAINDER:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "%" << r->boxName() << ";\n"; << "%" << r->boxName() << ";\n";
break; break;
case O_DIVIDE: case O_DIVIDE:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "/" << r->boxName() << ";\n"; << "/" << r->boxName() << ";\n";
break; break;
case O_PLUS: case O_PLUS:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "+" << r->boxName() << ";\n"; << "+" << r->boxName() << ";\n";
break; break;
case O_MINUS: case O_MINUS:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "-" << r->boxName() << ";\n"; << "-" << r->boxName() << ";\n";
break; break;
case O_MULTIPLY: case O_MULTIPLY:
this->op=shared_ptr<operands>(new operands(t)); this->op=operands::createOp(t);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "*" << r->boxName() << ";\n"; << "*" << r->boxName() << ";\n";
break; break;
case O_OR: case O_OR:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "|" << r->boxName() << ";\n"; << "|" << r->boxName() << ";\n";
break; break;
case O_AND: case O_AND:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=" << l->boxName() output_cpp << this->op->boxName() << "=" << l->boxName()
<< "&" << r->boxName() << ";\n"; << "&" << r->boxName() << ";\n";
break; break;
case O_GREATER: case O_GREATER:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< ">" << r->boxName() << ")?-1:0;\n"; << ">" << r->boxName() << ")?-1:0;\n";
break; break;
case O_LESS: case O_LESS:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "<" << r->boxName() << ")?-1:0;\n"; << "<" << r->boxName() << ")?-1:0;\n";
break; break;
case O_GREATER_EQUAL: case O_GREATER_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< ">=" << r->boxName() << ")?-1:0;\n"; << ">=" << r->boxName() << ")?-1:0;\n";
break; break;
case O_LESS_EQUAL: case O_LESS_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "<=" << r->boxName() << ")?-1:0;\n"; << "<=" << r->boxName() << ")?-1:0;\n";
break; break;
case O_EQUAL: case O_EQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "==" << r->boxName() << ")?-1:0;\n"; << "==" << r->boxName() << ")?-1:0;\n";
break; break;
case O_UNEQUAL: case O_UNEQUAL:
this->op=shared_ptr<operands>(new operands(T_INTVAR)); this->op=operands::createOp(T_INTVAR);
this->op->generateBox(scopeVar);
output_cpp << this->op->boxName() << "=(" << l->boxName() output_cpp << this->op->boxName() << "=(" << l->boxName()
<< "!=" << r->boxName() << ")?-1:0;\n"; << "!=" << r->boxName() << ")?-1:0;\n";
break; break;
default: default:
errorLevel=E_INTERNAL; error(E_INTERNAL);
exit(1);
break;
} }
/* convert expression into single operand */ /* convert expression into single operand */
this->oper=O_TERM; this->oper=O_TERM;
l->dispose();
delete left;
r->dispose();
delete right;
return this->op; return this->op;
} }
@@ -331,41 +462,40 @@ variableType::variableType(enum SCOPES s, string &name, enum TYPES t):operands(t
case S_LOCAL: case S_LOCAL:
if(locals.find(name)!=locals.end() || if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
locals[name]=shared_ptr<variableType>(this); locals[name]=unique_ptr<variableType>(this);
break; break;
case S_GLOBAL: case S_GLOBAL:
if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL); if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL);
globals[name]=shared_ptr<variableType>(this); globals[name]=unique_ptr<variableType>(this);
break; break;
case S_STATIC: case S_STATIC:
if(locals.find(name)!=locals.end() || if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
statics[name]=shared_ptr<variableType>(this); statics[name]=unique_ptr<variableType>(this);
break; break;
default: default:
error(E_INTERNAL); error(E_INTERNAL);
} }
} }
shared_ptr<variableType> variableType::getOrCreateVar(string &name, enum TYPES t) variableType *variableType::getOrCreateVar(string &name, enum TYPES t)
{ {
if (!scopeGlobal) if (!scopeGlobal)
{ {
auto i=locals.find(name); auto i=locals.find(name);
if(i!=locals.end())return i->second; if(i!=locals.end())return i->second.get();
i=statics.find(name); i=statics.find(name);
if(i!=statics.end())return i->second; if(i!=statics.end())return i->second.get();
} }
if (globals.find(name)!=globals.end())return globals[name]; if (globals.find(name)!=globals.end())return globals[name].get();
shared_ptr<variableType>v=shared_ptr<variableType>(new variableType( variableType *v=new variableType(scopeGlobal?S_GLOBAL:S_LOCAL, name, t);
scopeGlobal?S_GLOBAL:S_LOCAL, name, t));
v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL); v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
return v; return v;
} }
void variableType::assignment(shared_ptr<expression>value) void variableType::assignment(expression *value)
{ {
shared_ptr<operands>op=value->evaluate(); operands *op=value->evaluate();
enum TYPES t=op->getSimpleVarType(); enum TYPES t=op->getSimpleVarType();
switch (this->getType()) switch (this->getType())
{ {
@@ -389,9 +519,11 @@ void variableType::assignment(shared_ptr<expression>value)
<< op->boxName() << ";\n"; << op->boxName() << ";\n";
break; break;
} }
op->dispose();
delete value;
} }
string arrayType::boxName(list<shared_ptr<operands> >indexes) string arrayType::boxName(list<operands *>indexes)
{ {
ostringstream out; ostringstream out;
auto i=indexes.begin(); auto i=indexes.begin();
@@ -436,11 +568,10 @@ arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
this->dimensions=dim; this->dimensions=dim;
} }
void arrayType::assignment(list<shared_ptr<expression> >indexes, void arrayType::assignment(list<expression *>indexes, expression *value)
shared_ptr<expression>value)
{ {
list<shared_ptr<operands>>x; list<operands *>x;
shared_ptr<operands>op=value->evaluate(); operands *op=value->evaluate();
enum TYPES t=op->getSimpleVarType(); enum TYPES t=op->getSimpleVarType();
auto i=indexes.begin(); auto i=indexes.begin();
while(i!=indexes.end()) while(i!=indexes.end())
@@ -470,4 +601,6 @@ void arrayType::assignment(list<shared_ptr<expression> >indexes,
error(E_INTERNAL); error(E_INTERNAL);
} }
output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n"; output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n";
op->dispose();
delete value;
} }

View File

@@ -9,8 +9,8 @@
#include "yab2cpp.h" #include "yab2cpp.h"
/* static initializers */ /* static initializers */
unordered_map<string, shared_ptr<fn> > fn::functions; unordered_map<string, unique_ptr<fn> > fn::functions;
list<shared_ptr<fn> >fn::callStack; list<fn *>fn::callStack;
unsigned int fn::nextID=0; unsigned int fn::nextID=0;
/* function definitions */ /* function definitions */
@@ -29,50 +29,48 @@ void fn::dumpCallStack()
} while(i!=callStack.rend()); } while(i!=callStack.rend());
} }
shared_ptr<fn>fn::getCurrentSub() fn *fn::getCurrentSub()
{ {
list<shared_ptr<fn> >callStack;
return callStack.back(); return callStack.back();
} }
void fn::generateOnNSub(shared_ptr<expression>e, unsigned int skip) void fn::generateOnNSub(expression *e, unsigned int skip)
{ {
shared_ptr<label>r=shared_ptr<label>(new label()); label *r=new label();
shared_ptr<fn> self=shared_ptr<fn>(new fn(r)); fn *self=new fn(r);
fn::callStack.push_back(self); fn::callStack.push_back(self);
label::generateOnNTo(e, skip); label::generateOnNTo(e, skip);
r->generate(); r->generate();
} }
void fn::generateGosub(shared_ptr<label> sub) void fn::generateGosub(label *sub)
{ {
shared_ptr<label>r=shared_ptr<label>(new label()); label *r=new label();
shared_ptr<fn> self=shared_ptr<fn>(new fn(r)); fn *self=new fn(r);
fn::callStack.push_back(self); fn::callStack.push_back(self);
sub->generateJumpTo(); sub->generateJumpTo();
r->generate(); r->generate();
} }
fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB) fn::fn(label *gosub):codeType(T_GOSUB)
{ {
this->funcName="unnamed gosub"; this->funcName="unnamed gosub";
this->ret=gosub; this->ret=gosub;
} }
shared_ptr<fn> fn::getSub(string &name) fn *fn::getSub(string &name)
{ {
auto iter=fn::functions.find(name); auto iter=fn::functions.find(name);
if(iter==fn::functions.end()) return NULL; if(iter==fn::functions.end()) return nullptr;
return iter->second; return iter->second.get();
} }
shared_ptr<operands>fn::generateCall(string &name, operands *fn::generateCall(string &name, list<operands *>&paramList)
list<shared_ptr<operands> >&paramList)
{ {
auto v=params.begin(); auto v=params.begin();
shared_ptr<operands>current; operands *current;
shared_ptr<fn>g=fn::getSub(name); fn *g=fn::getSub(name);
if (g==NULL) if (g==nullptr)
{ {
error(E_SUBROUTINE_NOT_FOUND); error(E_SUBROUTINE_NOT_FOUND);
} }
@@ -95,8 +93,7 @@ shared_ptr<operands>fn::generateCall(string &name,
{ {
error(E_TYPE_MISMATCH); error(E_TYPE_MISMATCH);
} }
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(new expression(current));
new expression(current)));
++v; ++v;
} }
/* pad remaining unassigned variables with empty values */ /* pad remaining unassigned variables with empty values */
@@ -105,22 +102,13 @@ shared_ptr<operands>fn::generateCall(string &name,
switch ((*v)->getType()) switch ((*v)->getType())
{ {
case T_FLOATVAR: case T_FLOATVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(new expression(new constOp("0.0", T_FLOAT)));
new expression(
shared_ptr<constOp>(new constOp("0.0", T_FLOAT))
)));
break; break;
case T_INTVAR: case T_INTVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(new expression(new constOp("0", T_INT)));
new expression(
shared_ptr<constOp>(new constOp("0", T_INT))
)));
break; break;
case T_STRINGVAR: case T_STRINGVAR:
(*v)->assignment(shared_ptr<expression>( (*v)->assignment(new expression(new constOp("", T_STRING)));
new expression(
shared_ptr<constOp>(new constOp("", T_STRING))
)));
default: default:
error(E_INTERNAL); error(E_INTERNAL);
} }
@@ -133,7 +121,7 @@ shared_ptr<operands>fn::generateCall(string &name,
void fn::generateReturn() void fn::generateReturn()
{ {
shared_ptr<fn>c=getCurrentSub(); fn *c=getCurrentSub();
switch(c->getType()) switch(c->getType())
{ {
case T_UNKNOWNFUNC: case T_UNKNOWNFUNC:
@@ -149,12 +137,13 @@ void fn::generateReturn()
} }
} }
void fn::generateReturn(shared_ptr<expression>expr) void fn::generateReturn(expression *expr)
{ {
this->rc=expr->evaluate(); this->rc=expr->evaluate();
this->kind=rc->getSimpleVarType(); this->kind=rc->getSimpleVarType();
this->ret->generateJumpTo(); this->ret->generateJumpTo();
fn::callStack.pop_back(); fn::callStack.pop_back();
delete expr;
switch (this->getType()) switch (this->getType())
{ {
case T_UNKNOWNFUNC: case T_UNKNOWNFUNC:
@@ -198,7 +187,7 @@ void fn::close()
scopeGlobal=true; scopeGlobal=true;
} }
fn::fn(string &s, enum CODES t, shared_ptr<operands>returnCode):codeType(t) fn::fn(string &s, enum CODES t, operands *returnCode):codeType(t)
{ {
/*check for nesting error */ /*check for nesting error */
if (!scopeGlobal) error(E_END_FUNCTION); if (!scopeGlobal) error(E_END_FUNCTION);
@@ -209,14 +198,14 @@ fn::fn(string &s, enum CODES t, shared_ptr<operands>returnCode):codeType(t)
/*define storage for locals*/ /*define storage for locals*/
funcs_h << "struct f" << this->id <<"\n{\n"; funcs_h << "struct f" << this->id <<"\n{\n";
/*define label space for return*/ /*define label space for return*/
this->ret=shared_ptr<label>(new label()); this->ret=new label();
/*allocate function name*/ /*allocate function name*/
fn::functions[s]=shared_ptr<fn>(this); fn::functions[s]=unique_ptr<fn>(this);
/* initiate local scope */ /* initiate local scope */
scopeGlobal=false; scopeGlobal=false;
/*keep track of where the return code will be sent to*/ /*keep track of where the return code will be sent to*/
this->rc=returnCode; this->rc=returnCode;
/*allocate and generate start address label*/ /*allocate and generate start address label*/
this->startAddr=shared_ptr<label>(new label()); this->startAddr=new label();
startAddr->generate(); startAddr->generate();
} }

View File

@@ -8,7 +8,7 @@
*/ */
#include "yab2cpp.h" #include "yab2cpp.h"
printSegment::printSegment(shared_ptr<expression>e, enum SEPARATORS s) printSegment::printSegment(expression *e, enum SEPARATORS s)
{ {
cargo=e; cargo=e;
sep=s; sep=s;
@@ -18,11 +18,11 @@ void printSegment::generate()
{ {
if (cargo!=NULL) if (cargo!=NULL)
{ {
shared_ptr<operands>op=cargo->evaluate(); operands *op=cargo->evaluate();
switch (op->getSimpleVarType()) switch (op->getSimpleVarType())
{ {
case T_STRINGVAR: case T_STRINGVAR:
output_cpp << "printf(\"%s\", " << op->boxName() << ");\n"; output_cpp << "puts(" << op->boxName() << ");\n";
break; break;
case T_INTVAR: case T_INTVAR:
output_cpp << "printf(\"%d\", " << op->boxName() << ");\n"; output_cpp << "printf(\"%d\", " << op->boxName() << ");\n";