it builds but doesn't link yet
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ bison.output
|
|||||||
yab
|
yab
|
||||||
*.o
|
*.o
|
||||||
*.so
|
*.so
|
||||||
|
.vscode/*
|
||||||
|
|||||||
16
Makefile
16
Makefile
@@ -5,16 +5,16 @@
|
|||||||
|
|
||||||
CC=g++
|
CC=g++
|
||||||
LD=g++
|
LD=g++
|
||||||
|
|
||||||
#release build
|
#release build
|
||||||
#FLAGS=-c -Os -std=c++11
|
#FLAGS=-c -Os -std=c++11
|
||||||
#LDFLAGS=
|
#LDFLAGS=LDFLAGS=-std=c++11
|
||||||
|
|
||||||
#debug build
|
#debug build
|
||||||
FLAGS=-c -g -Og -std=c++11
|
FLAGS=-c -g -Og -std=c++11
|
||||||
LDFLAGS=
|
LDFLAGS=-std=c++11
|
||||||
|
|
||||||
AR=ar r
|
AR=ar r
|
||||||
LD=g++
|
|
||||||
|
|
||||||
default: yab2cpp
|
default: yab2cpp
|
||||||
|
|
||||||
@@ -30,11 +30,13 @@ yabFunctions.o: yabFunctions.cpp yab2cpp.h
|
|||||||
yab2cpp.o: yab2cpp.cpp yab2cpp.h
|
yab2cpp.o: yab2cpp.cpp yab2cpp.h
|
||||||
$(CC) $(FLAGS) -o yab2cpp.o yab2cpp.cpp
|
$(CC) $(FLAGS) -o yab2cpp.o yab2cpp.cpp
|
||||||
|
|
||||||
BASIC_framework.a: yabDataStructures.o yabCodeStructures.o yabFunctions.o
|
#BASIC_framework.a: yabDataStructures.o yabCodeStructures.o yabFunctions.o
|
||||||
$(AR) yabDataStructures.o yabCodeStructures.o yabFunctions.o
|
# $(AR) BASIC_framework.a yabDataStructures.o yabCodeStructures.o yabFunctions.o
|
||||||
|
|
||||||
yab2cpp: BASIC_framework.a yab2cpp.o
|
#yab2cpp: BASIC_framework.a yab2cpp.o
|
||||||
$(LD) $(LDFLAGS) -o buildyab2cpp yab2cpp.o -lBASIC_framework
|
yab2cpp: yab2cpp.o yabCodeStructures.o yabDataStructures.o yabFunctions.o
|
||||||
|
$(LD) $(LDFLAGS) -o yab2cpp yab2cpp.o yabCodeStructures.o yabDataStructures.o yabFunctions.o
|
||||||
|
#BASIC_framework.a
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o yab2cpp BASIC_framework.a
|
rm -f *.o yab2cpp BASIC_framework.a
|
||||||
|
|||||||
54
yab2cpp.cpp
54
yab2cpp.cpp
@@ -8,6 +8,60 @@
|
|||||||
*/
|
*/
|
||||||
#include "yab2cpp.h"
|
#include "yab2cpp.h"
|
||||||
|
|
||||||
|
/* These correspond to the enum COMPILE_ERRORS. */
|
||||||
|
const char *COMPILE_ERROR_NAMES[]={
|
||||||
|
"no error",
|
||||||
|
"incorrect syntax",
|
||||||
|
"wrong type",
|
||||||
|
"failed allocation",
|
||||||
|
"stack underflow",
|
||||||
|
"internal compiler error",
|
||||||
|
"duplicated label",
|
||||||
|
"previous subroutine didn't end",
|
||||||
|
"value returned from gosub call",
|
||||||
|
"undefined subroutine name",
|
||||||
|
"too many parameters in function call",
|
||||||
|
"value cannot be assigned"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* These correspond to the types of enum TYPES. */
|
||||||
|
const string TYPENAMES[]={
|
||||||
|
"unknown",
|
||||||
|
"none",
|
||||||
|
"string constant",
|
||||||
|
"integer constant",
|
||||||
|
"floating point constant",
|
||||||
|
"string variable",
|
||||||
|
"integer variable",
|
||||||
|
"floating point variable",
|
||||||
|
"string array or function",
|
||||||
|
"integer array or function",
|
||||||
|
"floating point array or function",
|
||||||
|
"string array or function",
|
||||||
|
"function"
|
||||||
|
};
|
||||||
|
|
||||||
|
const string CODETYPES[]={
|
||||||
|
"print sequence",
|
||||||
|
"print segment",
|
||||||
|
"while loop",
|
||||||
|
"for loop",
|
||||||
|
"repeat loop",
|
||||||
|
"do loop",
|
||||||
|
"if statement",
|
||||||
|
"procedure statement",
|
||||||
|
"function statement",
|
||||||
|
"assignment",
|
||||||
|
"label",
|
||||||
|
"parameter list or array index",
|
||||||
|
"data item",
|
||||||
|
"function returning string",
|
||||||
|
"function returning floating point",
|
||||||
|
"function returning integer",
|
||||||
|
"function returning nothing",
|
||||||
|
"function"
|
||||||
|
};
|
||||||
|
|
||||||
enum COMPILE_ERRORS errorLevel=E_OK;
|
enum COMPILE_ERRORS errorLevel=E_OK;
|
||||||
unsigned int mode=0;
|
unsigned int mode=0;
|
||||||
unsigned int indentLevel=0;
|
unsigned int indentLevel=0;
|
||||||
|
|||||||
118
yab2cpp.h
118
yab2cpp.h
@@ -55,22 +55,6 @@ extern unsigned int mode;
|
|||||||
extern unsigned int indentLevel;
|
extern unsigned int indentLevel;
|
||||||
extern bool scopeGlobal;
|
extern bool scopeGlobal;
|
||||||
|
|
||||||
/* These correspond to the enum COMPILE_ERRORS. */
|
|
||||||
const char *COMPILE_ERROR_NAMES[]={
|
|
||||||
"no error",
|
|
||||||
"incorrect syntax",
|
|
||||||
"wrong type",
|
|
||||||
"failed allocation",
|
|
||||||
"stack underflow",
|
|
||||||
"internal compiler error",
|
|
||||||
"duplicated label",
|
|
||||||
"previous subroutine didn't end",
|
|
||||||
"value returned from gosub call",
|
|
||||||
"undefined subroutine name",
|
|
||||||
"too many parameters in function call",
|
|
||||||
"value cannot be assigned"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* flags used internally by the compiler
|
/* flags used internally by the compiler
|
||||||
(must be powers of 2) */
|
(must be powers of 2) */
|
||||||
#define COMPILE 1
|
#define COMPILE 1
|
||||||
@@ -117,44 +101,6 @@ enum CODES
|
|||||||
T_UNKNOWNFUNC
|
T_UNKNOWNFUNC
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These correspond to the types of enum TYPES. */
|
|
||||||
const string TYPENAMES[]={
|
|
||||||
"unknown",
|
|
||||||
"none",
|
|
||||||
"string constant",
|
|
||||||
"integer constant",
|
|
||||||
"floating point constant",
|
|
||||||
"string variable",
|
|
||||||
"integer variable",
|
|
||||||
"floating point variable",
|
|
||||||
"string array or function",
|
|
||||||
"integer array or function",
|
|
||||||
"floating point array or function",
|
|
||||||
"string array or function",
|
|
||||||
"function"
|
|
||||||
};
|
|
||||||
|
|
||||||
const string CODETYPES[]={
|
|
||||||
"print sequence",
|
|
||||||
"print segment",
|
|
||||||
"while loop",
|
|
||||||
"for loop",
|
|
||||||
"repeat loop",
|
|
||||||
"do loop",
|
|
||||||
"if statement",
|
|
||||||
"procedure statement",
|
|
||||||
"function statement",
|
|
||||||
"assignment",
|
|
||||||
"label",
|
|
||||||
"parameter list or array index",
|
|
||||||
"data item",
|
|
||||||
"function returning string",
|
|
||||||
"function returning floating point",
|
|
||||||
"function returning integer",
|
|
||||||
"function returning nothing",
|
|
||||||
"function"
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
@@ -170,6 +116,14 @@ enum SEPARATORS
|
|||||||
S_LINEFEED
|
S_LINEFEED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SCOPES
|
||||||
|
{
|
||||||
|
S_UNKNOWN,
|
||||||
|
S_LOCAL,
|
||||||
|
S_STATIC,
|
||||||
|
S_GLOBAL
|
||||||
|
};
|
||||||
|
|
||||||
enum OPERATORS
|
enum OPERATORS
|
||||||
{
|
{
|
||||||
O_PLUS,
|
O_PLUS,
|
||||||
@@ -199,27 +153,37 @@ 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
|
||||||
|
{
|
||||||
|
enum SCOPES myscope;
|
||||||
|
public:
|
||||||
|
ofstream &operator<<(ostream &in);
|
||||||
|
enum SCOPES getScope() const {return myscope;}
|
||||||
|
|
||||||
|
scope(enum SCOPES s){myscope=s;}
|
||||||
|
~scope()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
class operands
|
class operands
|
||||||
{
|
{
|
||||||
enum TYPES type;
|
enum TYPES type;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
static unsigned int nextID;
|
static unsigned int nextID;
|
||||||
static unordered_map<string, shared_ptr<operands>> globals;
|
|
||||||
static unordered_map<string, unsigned int> strConst;
|
|
||||||
/* 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 shared_ptr<operands>findGlobal(string &s);
|
||||||
static void dumpVars();
|
static void dumpVars();
|
||||||
static shared_ptr<operands>getOrCreateStr(string s);
|
|
||||||
static shared_ptr<operands>createConst(string s, enum TYPES t);
|
|
||||||
static shared_ptr<operands>getOrCreateGlobal(string &s, enum TYPES t);
|
static shared_ptr<operands>getOrCreateGlobal(string &s, enum TYPES t);
|
||||||
|
|
||||||
enum TYPES getSimpleVarType();
|
enum TYPES getSimpleVarType();
|
||||||
void generateBox(ostream &scope);
|
void generateBox(enum SCOPES s);
|
||||||
virtual string boxName();
|
virtual string boxName();
|
||||||
enum TYPES coerceTypes();
|
enum TYPES coerceTypes();
|
||||||
|
|
||||||
@@ -228,6 +192,24 @@ public:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class constOp:public operands
|
||||||
|
{
|
||||||
|
/* box is defined once in the constructor */
|
||||||
|
string box;
|
||||||
|
static unordered_map<string, unsigned int> strConst;
|
||||||
|
|
||||||
|
/* const for id that exists already */
|
||||||
|
void processConst(unsigned int i);
|
||||||
|
/* const that must be defined still */
|
||||||
|
void processConst(const string &s);
|
||||||
|
public:
|
||||||
|
virtual string boxName(){return box;}
|
||||||
|
|
||||||
|
constOp(const string &s, enum TYPES t);
|
||||||
|
~constOp()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/* expression can be terminal or non-terminal */
|
/* expression can be terminal or non-terminal */
|
||||||
class expression
|
class expression
|
||||||
{
|
{
|
||||||
@@ -251,9 +233,9 @@ public:
|
|||||||
this->right=r;
|
this->right=r;
|
||||||
this->oper=o;
|
this->oper=o;
|
||||||
}
|
}
|
||||||
expression(shared_ptr<operands>x)
|
expression(operands *x)
|
||||||
{
|
{
|
||||||
op=x;
|
op=shared_ptr<operands>(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*/
|
||||||
@@ -370,12 +352,12 @@ public:
|
|||||||
|
|
||||||
class variable:public operands
|
class variable:public operands
|
||||||
{
|
{
|
||||||
ostream &myScope;
|
enum SCOPES myScope;
|
||||||
public:
|
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(ostream &scope, string &name, enum TYPES t);
|
explicit variable(enum SCOPES s, string &name, enum TYPES t);
|
||||||
variable();
|
variable();
|
||||||
~variable()
|
~variable()
|
||||||
{}
|
{}
|
||||||
@@ -409,18 +391,20 @@ public:
|
|||||||
|
|
||||||
class fn:codeType
|
class fn:codeType
|
||||||
{
|
{
|
||||||
static unordered_map<string, shared_ptr<variable> >locals;
|
friend variable;
|
||||||
static unordered_map<string, shared_ptr<variable> >statics;
|
|
||||||
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;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
enum TYPES kind;
|
enum TYPES kind;
|
||||||
|
shared_ptr<operands>rc;
|
||||||
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 shared_ptr<variable>getOrCreateVar(enum TYPES t, string &s, bool stat);
|
||||||
static void dumpCallStack();
|
static void dumpCallStack();
|
||||||
@@ -436,12 +420,12 @@ public:
|
|||||||
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);
|
||||||
shared_ptr<operands>generateReturn(shared_ptr<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);
|
fn(string &name, enum CODES t, shared_ptr<operands>returnCode=NULL);
|
||||||
virtual ~fn()
|
virtual ~fn()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ void ifStatement::generateContinue()
|
|||||||
redo->generateJumpTo();
|
redo->generateJumpTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ifStatement::alternative(shared_ptr<expression>e=NULL)
|
void ifStatement::alternative(shared_ptr<expression>e)
|
||||||
{
|
{
|
||||||
done->generateJumpTo();
|
done->generateJumpTo();
|
||||||
this->chain->generate();
|
this->chain->generate();
|
||||||
@@ -201,7 +201,7 @@ void whileLoop::close()
|
|||||||
|
|
||||||
forLoop::forLoop(shared_ptr<variable>v,
|
forLoop::forLoop(shared_ptr<variable>v,
|
||||||
shared_ptr<expression>start, shared_ptr<expression>stop,
|
shared_ptr<expression>start, shared_ptr<expression>stop,
|
||||||
shared_ptr<expression>stepVal=NULL):codeType(T_FORLOOP)
|
shared_ptr<expression>stepVal):codeType(T_FORLOOP)
|
||||||
{
|
{
|
||||||
/*v=start;
|
/*v=start;
|
||||||
stopTemp=stop;*/
|
stopTemp=stop;*/
|
||||||
@@ -209,30 +209,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)),
|
shared_ptr<expression>(new expression(shared_ptr<expression>(new expression(v.get())),
|
||||||
O_LESS, shared_ptr<expression>(new expression(stopTemp))))));
|
O_LESS, shared_ptr<expression>(new expression(stopTemp.get()))))));
|
||||||
/* startTemp=v;*/
|
/* startTemp=v;*/
|
||||||
startTemp->assignment(shared_ptr<expression>(new expression(v)));
|
startTemp->assignment(shared_ptr<expression>(new expression(v.get())));
|
||||||
/* else */
|
/* else */
|
||||||
c->alternative();
|
c->alternative();
|
||||||
/* startTemp=stopTemp;
|
/* startTemp=stopTemp;
|
||||||
stopTemp=v;*/
|
stopTemp=v;*/
|
||||||
startTemp->assignment(shared_ptr<expression>(new expression(stopTemp)));
|
startTemp->assignment(shared_ptr<expression>(new expression(stopTemp.get())));
|
||||||
stopTemp->assignment(shared_ptr<expression>(new expression(v)));
|
stopTemp->assignment(shared_ptr<expression>(new expression(v.get())));
|
||||||
/* 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)), O_LESS_EQUAL,
|
shared_ptr<expression>(new expression(v.get())), O_LESS_EQUAL,
|
||||||
shared_ptr<expression>(new expression(stopTemp))));
|
shared_ptr<expression>(new expression(stopTemp.get()))));
|
||||||
shared_ptr<expression>stopper2=shared_ptr<expression>(new expression(
|
shared_ptr<expression>stopper2=shared_ptr<expression>(new expression(
|
||||||
shared_ptr<expression>(new expression(v)), O_GREATER_EQUAL,
|
shared_ptr<expression>(new expression(v.get())), O_GREATER_EQUAL,
|
||||||
shared_ptr<expression>(new expression(startTemp))));
|
shared_ptr<expression>(new expression(startTemp.get()))));
|
||||||
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(
|
||||||
operands::createConst(string("0"), T_INT))))));
|
new constOp("0", T_INT))))));
|
||||||
if (stepVal)
|
if (stepVal)
|
||||||
{
|
{
|
||||||
step=stepVal;
|
step=stepVal;
|
||||||
@@ -240,7 +240,7 @@ 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(operands::createConst("1", T_INT)));
|
step=shared_ptr<expression>(new expression(new constOp("1", T_INT)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +253,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)), O_PLUS, step));
|
shared_ptr<expression>(new expression(var.get())), O_PLUS, step));
|
||||||
var->assignment(stepper);
|
var->assignment(stepper);
|
||||||
infrastructure->close();
|
infrastructure->close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,19 @@
|
|||||||
|
|
||||||
class fn;
|
class fn;
|
||||||
|
|
||||||
|
/* scope methods */
|
||||||
|
ofstream &scope::operator<<(ostream &in)
|
||||||
|
{
|
||||||
|
switch (this->myscope)
|
||||||
|
{
|
||||||
|
case S_LOCAL:
|
||||||
|
return funcs_h;
|
||||||
|
case S_GLOBAL:
|
||||||
|
case S_STATIC:
|
||||||
|
return heap_h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* methods for operands */
|
/* methods for operands */
|
||||||
shared_ptr<operands>operands::findGlobal(string &s)
|
shared_ptr<operands>operands::findGlobal(string &s)
|
||||||
{
|
{
|
||||||
@@ -31,42 +44,6 @@ void operands::dumpVars()
|
|||||||
varNames << endl;
|
varNames << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<operands> operands::getOrCreateStr(string s)
|
|
||||||
{
|
|
||||||
auto iter=operands::strConst.find(s);
|
|
||||||
if (iter!=operands::strConst.end())
|
|
||||||
{
|
|
||||||
return shared_ptr<operands>(new operands(iter->second, T_STRING));
|
|
||||||
}
|
|
||||||
++nextID;
|
|
||||||
consts_h << "const string k" << nextID << "=\"" << s << "\";\n";
|
|
||||||
operands::strConst[s]=nextID;
|
|
||||||
return shared_ptr<operands>(new operands(nextID, T_STRING));
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<operands>operands::createConst(string s, enum TYPES t)
|
|
||||||
{
|
|
||||||
shared_ptr<operands>me=shared_ptr<operands>(new operands(t));
|
|
||||||
if (t==T_INT)
|
|
||||||
{
|
|
||||||
consts_h << "const int k";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (t==T_FLOAT)
|
|
||||||
{
|
|
||||||
consts_h << "const double k";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errorLevel=E_TYPE_MISMATCH;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
consts_h << me->getID() << "=" << s << ";\n";
|
|
||||||
return me;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TYPES operands::getSimpleVarType()
|
enum TYPES operands::getSimpleVarType()
|
||||||
{
|
{
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
@@ -95,25 +72,28 @@ operands::operands(enum TYPES t)
|
|||||||
this->type=t;
|
this->type=t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operands::generateBox(ostream &scope)
|
void operands::generateBox(enum SCOPES s)
|
||||||
{
|
{
|
||||||
|
string x;
|
||||||
|
scope y(s);
|
||||||
|
stringstream ss;
|
||||||
switch (this->getSimpleVarType())
|
switch (this->getSimpleVarType())
|
||||||
{
|
{
|
||||||
case T_INTVAR:
|
case T_INTVAR:
|
||||||
scope << "int v";
|
ss << "int v";
|
||||||
break;
|
break;
|
||||||
case T_FLOATVAR:
|
case T_FLOATVAR:
|
||||||
scope << "double v";
|
ss << "double v";
|
||||||
break;
|
break;
|
||||||
case T_STRINGVAR:
|
case T_STRINGVAR:
|
||||||
scope << "string v";
|
ss << "string v";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errorLevel=E_TYPE_MISMATCH;
|
error(E_TYPE_MISMATCH);
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
scope << this->getID() << ";\n";
|
ss << this->getID() << ";\n";
|
||||||
|
ss.str(x);
|
||||||
|
y << x;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
|
shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
|
||||||
@@ -121,7 +101,7 @@ shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
|
|||||||
auto op=globals.find(s);
|
auto op=globals.find(s);
|
||||||
if (op==globals.end())
|
if (op==globals.end())
|
||||||
{
|
{
|
||||||
return shared_ptr<variable>(new variable(heap_h, s, t));
|
return shared_ptr<variable>(new variable(S_GLOBAL, s, t));
|
||||||
}
|
}
|
||||||
return op->second;
|
return op->second;
|
||||||
}
|
}
|
||||||
@@ -129,13 +109,16 @@ shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
|
|||||||
string operands::boxName()
|
string operands::boxName()
|
||||||
{
|
{
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
|
string x;
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
{
|
{
|
||||||
case T_STRINGVAR:
|
case T_STRINGVAR:
|
||||||
case T_INTVAR:
|
case T_INTVAR:
|
||||||
case T_FLOATVAR:
|
case T_FLOATVAR:
|
||||||
s << 'v' << this->getID();
|
s << 'v' << this->getID();
|
||||||
return s.str();
|
s.str(x);
|
||||||
|
s.clear();
|
||||||
|
return x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -143,6 +126,54 @@ string operands::boxName()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void constOp::processConst(unsigned int i)
|
||||||
|
{
|
||||||
|
stringstream me;
|
||||||
|
me << 'k' << i;
|
||||||
|
me.str(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void constOp::processConst( const string &s)
|
||||||
|
{
|
||||||
|
processConst(getID());
|
||||||
|
consts_h << box << "=" << s << ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* constructor for constOp */
|
||||||
|
constOp::constOp(const string &s, enum TYPES t):operands(t)
|
||||||
|
{
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case T_INT:
|
||||||
|
consts_h << "const int ";
|
||||||
|
processConst(s);
|
||||||
|
break;
|
||||||
|
case T_FLOAT:
|
||||||
|
consts_h << "const double ";
|
||||||
|
processConst(s);
|
||||||
|
break;
|
||||||
|
case T_STRING:
|
||||||
|
{
|
||||||
|
auto i=strConst.find(s);
|
||||||
|
if (i!=strConst.end())
|
||||||
|
{
|
||||||
|
processConst((*i).second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
consts_h << "const string ";
|
||||||
|
processConst(s);
|
||||||
|
strConst[s]=getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(E_TYPE_MISMATCH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* expression parsing routines */
|
/* expression parsing routines */
|
||||||
|
|
||||||
/* binary vs. unary ops */
|
/* binary vs. unary ops */
|
||||||
@@ -166,7 +197,7 @@ shared_ptr<operands>expression::evaluate()
|
|||||||
shared_ptr<operands>l;
|
shared_ptr<operands>l;
|
||||||
shared_ptr<operands>r;
|
shared_ptr<operands>r;
|
||||||
enum TYPES t;
|
enum TYPES t;
|
||||||
ostream &scope=scopeGlobal?heap_h:funcs_h;
|
enum SCOPES scopeVar=(scopeGlobal?S_GLOBAL:S_LOCAL);
|
||||||
l=this->getLeft()->evaluate();
|
l=this->getLeft()->evaluate();
|
||||||
if (this->isBinOp())
|
if (this->isBinOp())
|
||||||
{
|
{
|
||||||
@@ -175,12 +206,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)), O_INT_TO_FLOAT))->evaluate());
|
l=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(l.get())), 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)), O_INT_TO_FLOAT))->evaluate());
|
r=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(r.get())), 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);
|
||||||
@@ -196,92 +227,92 @@ shared_ptr<operands>expression::evaluate()
|
|||||||
{
|
{
|
||||||
case O_INVERT:
|
case O_INVERT:
|
||||||
this->op=shared_ptr<operands>(new operands(t));
|
this->op=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
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=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
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=shared_ptr<operands>(new operands(T_FLOATVAR));
|
||||||
this->op->generateBox(scope);
|
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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
case O_DIVIDE:
|
case O_DIVIDE:
|
||||||
this->op=shared_ptr<operands>(new operands(t));
|
this->op=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
case O_PLUS:
|
case O_PLUS:
|
||||||
this->op=shared_ptr<operands>(new operands(t));
|
this->op=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
case O_MINUS:
|
case O_MINUS:
|
||||||
this->op=shared_ptr<operands>(new operands(t));
|
this->op=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
case O_MULTIPLY:
|
case O_MULTIPLY:
|
||||||
this->op=shared_ptr<operands>(new operands(t));
|
this->op=shared_ptr<operands>(new operands(t));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << 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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << 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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n";
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
case O_GREATER:
|
case O_GREATER:
|
||||||
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n";
|
||||||
break;
|
break;
|
||||||
case O_LESS:
|
case O_LESS:
|
||||||
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << 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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << 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=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n";
|
||||||
break;
|
break;
|
||||||
case O_EQUAL:
|
case O_EQUAL:
|
||||||
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n";
|
||||||
break;
|
break;
|
||||||
case O_UNEQUAL:
|
case O_UNEQUAL:
|
||||||
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
this->op=shared_ptr<operands>(new operands(T_INTVAR));
|
||||||
this->op->generateBox(scope);
|
this->op->generateBox(scopeVar);
|
||||||
output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n";
|
output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -299,7 +330,7 @@ shared_ptr<operands> expression::stringEval(shared_ptr<operands>l, shared_ptr<op
|
|||||||
if (this->getOp()==O_STRING_CONCAT)
|
if (this->getOp()==O_STRING_CONCAT)
|
||||||
{
|
{
|
||||||
this->op=shared_ptr<operands>(new operands(T_STRINGVAR));
|
this->op=shared_ptr<operands>(new operands(T_STRINGVAR));
|
||||||
this->op->generateBox(scopeGlobal?heap_h:funcs_h);
|
this->op->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
|
||||||
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName();
|
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName();
|
||||||
}
|
}
|
||||||
else error(E_INTERNAL);
|
else error(E_INTERNAL);
|
||||||
@@ -309,9 +340,29 @@ shared_ptr<operands> expression::stringEval(shared_ptr<operands>l, shared_ptr<op
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* variable definitions */
|
/* variable definitions */
|
||||||
variable::variable(ostream &scope, string &name, enum TYPES t):operands(t)
|
variable::variable(enum SCOPES s, string &name, enum TYPES t):operands(t)
|
||||||
{
|
{
|
||||||
this->generateBox(scope); /*TODO: FINISH THIS*/
|
this->myScope=s;
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case S_LOCAL:
|
||||||
|
if(fn::locals.find(name)!=fn::locals.end() ||
|
||||||
|
fn::statics.find(name)!=fn::statics.end() ) error(E_DUPLICATE_SYMBOL);
|
||||||
|
fn::locals[name]=shared_ptr<variable>(this);
|
||||||
|
break;
|
||||||
|
case S_GLOBAL:
|
||||||
|
if(findGlobal(name)!=NULL) error(E_DUPLICATE_SYMBOL);
|
||||||
|
globals[name]=shared_ptr<variable>(this);
|
||||||
|
break;
|
||||||
|
case S_STATIC:
|
||||||
|
if(fn::locals.find(name)!=fn::locals.end() ||
|
||||||
|
fn::statics.find(name)!=fn::statics.end() ) error(E_DUPLICATE_SYMBOL);
|
||||||
|
fn::statics[name]=shared_ptr<variable>(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(E_INTERNAL);
|
||||||
|
}
|
||||||
|
this->generateBox(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
|
shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
|
||||||
@@ -323,7 +374,7 @@ shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
|
|||||||
/* TODO: verify if type is compatible */
|
/* TODO: verify if type is compatible */
|
||||||
shared_ptr<operands>op=operands::getOrCreateGlobal(name, t);
|
shared_ptr<operands>op=operands::getOrCreateGlobal(name, t);
|
||||||
shared_ptr<variable>v=shared_ptr<variable>(new variable());
|
shared_ptr<variable>v=shared_ptr<variable>(new variable());
|
||||||
v->assignment(shared_ptr<expression>(new expression(op)));
|
v->assignment(shared_ptr<expression>(new expression(op.get())));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ shared_ptr<operands>fn::generateCall(string &name,
|
|||||||
<< "*sub" << this->getID()
|
<< "*sub" << this->getID()
|
||||||
<< "= new struct f" << g->getID()
|
<< "= new struct f" << g->getID()
|
||||||
<< "();\n";
|
<< "();\n";
|
||||||
|
|
||||||
|
/* TODO Make parameter processing a separate function */
|
||||||
while(paramList.size()>0)
|
while(paramList.size()>0)
|
||||||
{
|
{
|
||||||
current= paramList.front();
|
current= paramList.front();
|
||||||
@@ -74,7 +76,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)));
|
new expression(current.get())));
|
||||||
++v;
|
++v;
|
||||||
}
|
}
|
||||||
/* pad remaining unassigned variables with empty values */
|
/* pad remaining unassigned variables with empty values */
|
||||||
@@ -85,26 +87,28 @@ 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(
|
||||||
operands::createConst("0.0", T_FLOAT)
|
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(
|
||||||
operands::createConst("0", T_INT)
|
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(
|
||||||
operands::getOrCreateStr(string("")
|
new constOp("", T_STRING)
|
||||||
))));
|
)));
|
||||||
default:
|
default:
|
||||||
error(E_TYPE_MISMATCH);
|
error(E_INTERNAL);
|
||||||
}
|
}
|
||||||
++v;
|
++v;
|
||||||
}
|
}
|
||||||
return g->/*TODO FINISH THIS*/
|
g->startAddr->generateJumpTo();
|
||||||
|
g->ret->generate();
|
||||||
|
return g->rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fn::generateReturn()
|
void fn::generateReturn()
|
||||||
@@ -126,47 +130,29 @@ void fn::generateReturn()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<operands>fn::generateReturn(shared_ptr<expression>expr)
|
void fn::generateReturn(shared_ptr<expression>expr)
|
||||||
{
|
{
|
||||||
shared_ptr<operands>out=expr->evaluate();
|
this->rc=expr->evaluate();
|
||||||
this->kind=out->getSimpleVarType();
|
this->kind=rc->getSimpleVarType();
|
||||||
this->ret->generateJumpTo();
|
this->ret->generateJumpTo();
|
||||||
fn::callStack.pop_back();
|
fn::callStack.pop_back();
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
{
|
{
|
||||||
case T_UNKNOWNFUNC:
|
case T_UNKNOWNFUNC:
|
||||||
return out;
|
return;
|
||||||
case T_STRINGFUNC:
|
case T_STRINGFUNC:
|
||||||
if (kind!=T_STRINGVAR)
|
if (kind!=T_STRINGVAR) error(E_TYPE_MISMATCH);
|
||||||
{
|
return;
|
||||||
errorLevel=E_TYPE_MISMATCH;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
case T_INTFUNC:
|
case T_INTFUNC:
|
||||||
if (kind!=T_INTVAR&&kind!=T_FLOATVAR)
|
if (kind!=T_INTVAR&&kind!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
||||||
{
|
return;
|
||||||
errorLevel=E_TYPE_MISMATCH;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
case T_FLOATFUNC:
|
case T_FLOATFUNC:
|
||||||
if(kind!=T_FLOATVAR)
|
if(kind!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
||||||
{
|
return;
|
||||||
errorLevel=E_TYPE_MISMATCH;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
case T_GOSUB:
|
case T_GOSUB:
|
||||||
{
|
error(E_GOSUB_CANNOT_RETURN_VALUE);
|
||||||
errorLevel=E_GOSUB_CANNOT_RETURN_VALUE;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
error(E_BAD_SYNTAX);
|
||||||
errorLevel=E_BAD_SYNTAX;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,13 +179,24 @@ void fn::close()
|
|||||||
scopeGlobal=true;
|
scopeGlobal=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn::fn(string &s, enum CODES t):codeType(t)
|
fn::fn(string &s, enum CODES t, shared_ptr<operands>returnCode):codeType(t)
|
||||||
{
|
{
|
||||||
|
/*check for nesting error */
|
||||||
if (!scopeGlobal) error(E_END_FUNCTION);
|
if (!scopeGlobal) error(E_END_FUNCTION);
|
||||||
|
/*check if this function name is already used*/
|
||||||
if (fn::functions.find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
|
if (fn::functions.find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
|
||||||
this->id= ++nextID;
|
this->id= ++nextID;
|
||||||
|
/*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*/
|
||||||
this->ret=shared_ptr<label>(new label());
|
this->ret=shared_ptr<label>(new label());
|
||||||
fn::functions[s]=this;
|
/*allocate function name*/
|
||||||
|
fn::functions[s]=shared_ptr<fn>(this);
|
||||||
|
/* initiate local scope */
|
||||||
scopeGlobal=false;
|
scopeGlobal=false;
|
||||||
|
/*keep track of where the return code will be sent to*/
|
||||||
|
this->rc=returnCode;
|
||||||
|
/*allocate and generate start address label*/
|
||||||
|
this->startAddr=shared_ptr<label>(new label());
|
||||||
|
startAddr->generate();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user