wrote on n sub unit test and made necessary fixes
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
CC := g++
|
CC := g++
|
||||||
CFLAGS := -Wall
|
CFLAGS := -Wall
|
||||||
CFLAGS += -std=c++11
|
CFLAGS += -std=c++11
|
||||||
#CFLAGS += -fno-rtti
|
CFLAGS += -fno-rtti
|
||||||
#CFLAGS += -fno-exceptions
|
CFLAGS += -fno-exceptions
|
||||||
#CFLAGS += -Os
|
CFLAGS += -Os
|
||||||
LFLAGS :=
|
LFLAGS :=
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|||||||
53
tester.cpp
53
tester.cpp
@@ -410,6 +410,58 @@ void testForLoop()
|
|||||||
logger("testForLoop cleared");
|
logger("testForLoop cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testOnNCall()
|
||||||
|
{
|
||||||
|
logger("testOnNCall entered");
|
||||||
|
string s1 = string("func1");
|
||||||
|
fn *f1=fn::declare(s1, T_UNKNOWNFUNC);
|
||||||
|
print=new printSegment(new expression(new constOp(string("one"), T_STRING)));
|
||||||
|
print->generate();
|
||||||
|
delete print;
|
||||||
|
f1->close();
|
||||||
|
logger("func1 declared");
|
||||||
|
string s2=string("func2");
|
||||||
|
fn *f2=fn::declare(s2, T_UNKNOWNFUNC);
|
||||||
|
print=new printSegment(new expression(new constOp(string("two"), T_STRING)));
|
||||||
|
print->generate();
|
||||||
|
delete print;
|
||||||
|
f2->close();
|
||||||
|
logger("func2 declared");
|
||||||
|
string s3=string("func3");
|
||||||
|
fn *f3=fn::declare(s3, T_UNKNOWNFUNC);
|
||||||
|
print=new printSegment(new expression(new constOp(string("three"), T_STRING)));
|
||||||
|
print->generate();
|
||||||
|
delete print;
|
||||||
|
f3->close();
|
||||||
|
logger("func3 declared");
|
||||||
|
string s=string("countdown");
|
||||||
|
variableType *q=variableType::getOrCreateVar(s, T_INTVAR);
|
||||||
|
logger("countdown var declared");
|
||||||
|
forLoop *f=new forLoop(q,
|
||||||
|
new expression(new constOp("3",T_INT)),
|
||||||
|
new expression(new constOp("0",T_INT)),
|
||||||
|
new expression(new constOp("-1",T_INT))
|
||||||
|
);
|
||||||
|
logger("forloop declared");
|
||||||
|
list<label *> l;
|
||||||
|
l.push_back(f1->getStart());
|
||||||
|
l.push_back(f2->getStart());
|
||||||
|
l.push_back(f3->getStart());
|
||||||
|
logger("list allocated");
|
||||||
|
unsigned int x = label::generateOnNSkip(l);
|
||||||
|
fn::generateOnNSub(new expression(q), x);
|
||||||
|
logger("on countdown gosub declared");
|
||||||
|
print=new printSegment(new expression(new constOp("fallthrough condition test",T_STRING)));
|
||||||
|
print->generate();
|
||||||
|
delete print;
|
||||||
|
logger("fallthrough condition declared");
|
||||||
|
f->close();
|
||||||
|
v->dispose();
|
||||||
|
l.clear();
|
||||||
|
delete f;
|
||||||
|
logger("testOnNCall cleared");
|
||||||
|
}
|
||||||
|
|
||||||
/* open files and compile */
|
/* open files and compile */
|
||||||
void compile()
|
void compile()
|
||||||
{
|
{
|
||||||
@@ -420,6 +472,7 @@ void compile()
|
|||||||
testFunc();
|
testFunc();
|
||||||
testIf();
|
testIf();
|
||||||
testForLoop();
|
testForLoop();
|
||||||
|
testOnNCall();
|
||||||
logger("generating end");
|
logger("generating end");
|
||||||
label::generateEnd();
|
label::generateEnd();
|
||||||
/*check for nesting error */
|
/*check for nesting error */
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ 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<label *>&dest);
|
static unsigned int generateOnNSkip(list<label *>&dest);
|
||||||
static void generateOnNTo(expression *e, unsigned int skip);
|
static void generateOnNTo(expression *e, unsigned int skip);
|
||||||
void generateCondJump(expression *e);
|
void generateCondJump(expression *e);
|
||||||
void generate();
|
void generate();
|
||||||
@@ -420,9 +420,11 @@ public:
|
|||||||
/* must be called after label::generateOnNSkip */
|
/* must be called after label::generateOnNSkip */
|
||||||
static void generateOnNSub(expression *e, unsigned int skip);
|
static void generateOnNSub(expression *e, unsigned int skip);
|
||||||
|
|
||||||
|
label *getStart() const {return startAddr;}
|
||||||
enum CODES getType() const {return this->type;}
|
enum CODES getType() const {return this->type;}
|
||||||
unsigned int getID() const {return this->id;}
|
unsigned int getID() const {return this->id;}
|
||||||
size_t getNumParams() const {return this->params.size();}
|
size_t getNumParams() const {return this->params.size();}
|
||||||
|
/* can return nullptr if not found */
|
||||||
variableType *getLocalVar(string &name);
|
variableType *getLocalVar(string &name);
|
||||||
void addParameter(string &name, enum TYPES t);
|
void addParameter(string &name, enum TYPES t);
|
||||||
|
|
||||||
|
|||||||
@@ -60,52 +60,49 @@ void label::generateEnd()
|
|||||||
|
|
||||||
void label::generateJumpTo()
|
void label::generateJumpTo()
|
||||||
{
|
{
|
||||||
output_cpp << "state=" << this->getID() << ";\nbreak;\n";
|
output_cpp << "{state=" << this->getID() << ";break;}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass this as second parameter to generateOnNTo or generateOnNSub */
|
/* pass this as second parameter to generateOnNTo or generateOnNSub */
|
||||||
unsigned int label::generateOnNSkip(list<label *>&dest)
|
unsigned int label::generateOnNSkip(list<label *>&dest)
|
||||||
{
|
{
|
||||||
|
unsigned int ret=++nextID;
|
||||||
if (dest.size()<2)error(E_BAD_SYNTAX);
|
if (dest.size()<2)error(E_BAD_SYNTAX);
|
||||||
auto iter=dest.begin();
|
auto iter=dest.begin();
|
||||||
consts_h << "j" << this->getID() << "[]={" << *iter;
|
consts_h << "const unsigned int j" << ret << "[]={\n" << (*iter)->getID();
|
||||||
++iter;
|
++iter;
|
||||||
while(iter!=dest.end())
|
while(iter!=dest.end())
|
||||||
{
|
{
|
||||||
consts_h << ", " << *iter;
|
consts_h << ",\n" << (*iter)->getID();
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
consts_h << "}\njs" << this->getID()<< "=" << dest.size() << ";\n";
|
consts_h << "\n};\nconst int js" << ret << "=" << dest.size() << ";\n";
|
||||||
return this->getID();
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void label::generateOnNTo(expression *e, unsigned int skip)
|
void label::generateOnNTo(expression *e, unsigned int skip)
|
||||||
{
|
{
|
||||||
operands *o=e->evaluate();
|
// indexed by one instead of zero so we subtract one
|
||||||
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
expression *e2=new expression(e, O_MINUS,
|
||||||
{
|
new expression(new constOp("1", T_INT)));
|
||||||
output_cpp<< "if(" << o->boxName() << ">=0 && "
|
operands *o=e2->evaluate();
|
||||||
<< o->boxName() << "<js" << skip << ")state=j["
|
output_cpp << "if(" << o->boxName() << ">=0 && "
|
||||||
<< o->boxName() << "];\nbreak;\n";
|
<< o->boxName() << "<js" << skip
|
||||||
o->dispose();
|
<< "){state=j" << skip << "["
|
||||||
delete e;
|
<< o->boxName() << "];break;}\n";
|
||||||
return;
|
o->dispose();
|
||||||
}
|
delete e2;
|
||||||
error(E_TYPE_MISMATCH);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void label::generateCondJump(expression *e)
|
void label::generateCondJump(expression *e)
|
||||||
{
|
{
|
||||||
operands *o=e->evaluate();
|
operands *o=e->evaluate();
|
||||||
if (o->getType()==T_INT||o->getType()==T_INTVAR)
|
if (o->getSimpleVarType()!=T_INTVAR)error(E_TYPE_MISMATCH);
|
||||||
{
|
output_cpp<< "if(" << o->boxName()
|
||||||
output_cpp<< "if(" << o->boxName()
|
<< "!=0){state=" << this->getID() << ";break;}\n";
|
||||||
<< "!=0){state=" << this->getID() << ";break;}\n";
|
o->dispose();
|
||||||
o->dispose();
|
delete e;
|
||||||
delete e;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
error(E_TYPE_MISMATCH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void label::generate()
|
void label::generate()
|
||||||
|
|||||||
@@ -33,18 +33,18 @@ void fn::dumpFunctionIDs()
|
|||||||
|
|
||||||
void fn::generateOnNSub(expression *e, unsigned int skip)
|
void fn::generateOnNSub(expression *e, unsigned int skip)
|
||||||
{
|
{
|
||||||
label *r=new label();
|
label *retLabel=new label();
|
||||||
output_cpp << "callStack=new subroutine(" << r->getID() << ");\n";
|
output_cpp << "callStack=new subroutine(" << retLabel->getID() << ");\n";
|
||||||
label::generateOnNTo(e, skip);
|
label::generateOnNTo(e, skip);
|
||||||
r->generate();
|
retLabel->generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fn::generateGosub(label *sub)
|
void fn::generateGosub(label *sub)
|
||||||
{
|
{
|
||||||
label *r=new label();
|
label *retLabel=new label();
|
||||||
output_cpp << "callStack=new subroutine(" << r->getID() << ");\n";
|
output_cpp << "callStack=new subroutine(" << retLabel->getID() << ");\n";
|
||||||
sub->generateJumpTo();
|
sub->generateJumpTo();
|
||||||
r->generate();
|
retLabel->generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn *fn::getSub(string &name)
|
fn *fn::getSub(string &name)
|
||||||
@@ -285,7 +285,7 @@ fn::fn(enum CODES t, operands *returnCode)
|
|||||||
{
|
{
|
||||||
funcs_h << "struct f" << this->id <<":public subroutine\n{\nf"
|
funcs_h << "struct f" << this->id <<":public subroutine\n{\nf"
|
||||||
<< this->id << "(unsigned int x):subroutine(x)\n{}\n"
|
<< this->id << "(unsigned int x):subroutine(x)\n{}\n"
|
||||||
<< "virtual ~f" << this->id <<"()\n{}\n\n";
|
<< "virtual ~f" << this->id <<"()\n{}\n";
|
||||||
}
|
}
|
||||||
/*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;
|
||||||
|
|||||||
Reference in New Issue
Block a user