Fixed bugs with paramaters being passed to the wrong callsite
This commit is contained in:
2
Makefile
2
Makefile
@@ -48,4 +48,4 @@ build/yabFunctions.o: $(YABFUNCTIONS_SOURCE_DEPS)
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf build/*.o output/*.o yab2cpp tester
|
rm -rf build/*.o output/*.h output/*.cpp yab2cpp tester
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ CFLAGS += -std=c++11
|
|||||||
#CFLAGS += -Os
|
#CFLAGS += -Os
|
||||||
LFLAGS :=
|
LFLAGS :=
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
all: binaries
|
all: binaries
|
||||||
|
|
||||||
binaries: bin_main
|
.PHONY: binaries
|
||||||
|
binaries: main
|
||||||
|
|
||||||
SRC := ../output/
|
SRC := ../output/
|
||||||
|
|
||||||
@@ -16,7 +18,7 @@ OUTPUT_DEPS := $(SRC)consts.h $(SRC)heap.h $(SRC)functions.h runtime.h $(SRC)out
|
|||||||
|
|
||||||
MAIN_OBJ_DEPS := output.o main.o
|
MAIN_OBJ_DEPS := output.o main.o
|
||||||
|
|
||||||
bin_main: $(MAIN_OBJ_DEPS)
|
main: $(MAIN_OBJ_DEPS)
|
||||||
$(CC) -o main $(MAIN_OBJ_DEPS)
|
$(CC) -o main $(MAIN_OBJ_DEPS)
|
||||||
|
|
||||||
main.o: $(OUTPUT_DEPS)
|
main.o: $(OUTPUT_DEPS)
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ subroutine *callStack=nullptr;
|
|||||||
subroutine::subroutine(unsigned int r)
|
subroutine::subroutine(unsigned int r)
|
||||||
{
|
{
|
||||||
this->ret=r;
|
this->ret=r;
|
||||||
this->called=callStack;
|
this->callStackNode=callStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int subroutine::close()
|
unsigned int subroutine::close()
|
||||||
{
|
{
|
||||||
if (callStack==nullptr) return STACK_UNDERFLOW_ERROR;
|
if (callStack==nullptr) return STACK_UNDERFLOW_ERROR;
|
||||||
unsigned int r=callStack->ret;
|
unsigned int r=callStack->ret;
|
||||||
subroutine *l=callStack->called;
|
subroutine *l=callStack->callStackNode;
|
||||||
delete callStack;
|
delete callStack;
|
||||||
callStack=l;
|
callStack=l;
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** Practice runtime header for Yab2Cpp
|
** Runtime header for Yab2Cpp
|
||||||
**
|
**
|
||||||
** by Samuel D. Crow
|
** by Samuel D. Crow
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This enum contains all of the error states used at runtime.
|
||||||
|
*/
|
||||||
enum STATES:unsigned int
|
enum STATES:unsigned int
|
||||||
{
|
{
|
||||||
EXIT,
|
EXIT,
|
||||||
@@ -18,9 +21,12 @@ enum STATES:unsigned int
|
|||||||
START
|
START
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
This class wraps the function class and is inherited by every subroutine.
|
||||||
|
*/
|
||||||
class subroutine
|
class subroutine
|
||||||
{
|
{
|
||||||
subroutine *called;
|
subroutine *callStackNode;
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ const char *COMPILE_ERROR_NAMES[]={
|
|||||||
"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"
|
"undimensioned array or undeclared function",
|
||||||
|
"return code was not specified on function"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These correspond to the types of enum TYPES. */
|
/* These correspond to the types of enum TYPES. */
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ const char *COMPILE_ERROR_NAMES[]={
|
|||||||
"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"
|
"undimensioned array or undeclared function",
|
||||||
|
"return code was not specified on function"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These correspond to the types of enum TYPES. */
|
/* These correspond to the types of enum TYPES. */
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ enum COMPILE_ERRORS:unsigned int
|
|||||||
E_SUBROUTINE_NOT_FOUND,
|
E_SUBROUTINE_NOT_FOUND,
|
||||||
E_TOO_MANY_PARAMETERS,
|
E_TOO_MANY_PARAMETERS,
|
||||||
E_UNASSIGNABLE_TYPE,
|
E_UNASSIGNABLE_TYPE,
|
||||||
E_UNDIMENSIONED_ARRAY
|
E_UNDIMENSIONED_ARRAY,
|
||||||
|
E_RETURN_CODE_OMITTED
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum COMPILE_ERRORS errorLevel;
|
extern enum COMPILE_ERRORS errorLevel;
|
||||||
@@ -66,6 +67,7 @@ extern unsigned int indentLevel;
|
|||||||
/*TODO: Replace scopeGlobal with currentFunc==nullptr*/
|
/*TODO: Replace scopeGlobal with currentFunc==nullptr*/
|
||||||
extern bool scopeGlobal;
|
extern bool scopeGlobal;
|
||||||
extern fn *currentFunc;
|
extern fn *currentFunc;
|
||||||
|
extern unsigned int callEnumerator;
|
||||||
|
|
||||||
/* flags used internally by the compiler */
|
/* flags used internally by the compiler */
|
||||||
extern bool COMPILE;
|
extern bool COMPILE;
|
||||||
@@ -181,7 +183,7 @@ public:
|
|||||||
static enum TYPES getSimpleVarType(enum TYPES t);
|
static enum TYPES getSimpleVarType(enum TYPES t);
|
||||||
void generateBox(enum SCOPES s);
|
void generateBox(enum SCOPES s);
|
||||||
|
|
||||||
void assignment(expression *value);
|
void assignment(expression *value, bool paramDef=false);
|
||||||
static operands *createOp(enum TYPES t);
|
static operands *createOp(enum TYPES t);
|
||||||
virtual void dispose();
|
virtual void dispose();
|
||||||
};
|
};
|
||||||
@@ -360,12 +362,9 @@ class variableType:public operands
|
|||||||
fn *handle;
|
fn *handle;
|
||||||
public:
|
public:
|
||||||
static variableType *getOrCreateVar(string &name, enum TYPES t);
|
static variableType *getOrCreateVar(string &name, enum TYPES t);
|
||||||
static variableType *cloneAttributes(variableType *v);
|
|
||||||
|
|
||||||
virtual string boxName();
|
virtual string boxName();
|
||||||
/* always call generateBox() after new variableType() */
|
/* always call generateBox() after new variableType() */
|
||||||
variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHandle);
|
variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHandle);
|
||||||
variableType();
|
|
||||||
~variableType()
|
~variableType()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -121,16 +121,28 @@ string operands::boxName()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void operands::assignment(expression *value)
|
void operands::assignment(expression *value, bool paramDef)
|
||||||
{
|
{
|
||||||
operands *op=value->evaluate();
|
operands *op=value->evaluate();
|
||||||
enum TYPES t=op->getSimpleVarType();
|
enum TYPES t=op->getSimpleVarType();
|
||||||
|
stringstream dest;
|
||||||
|
string d;
|
||||||
|
if (paramDef)
|
||||||
|
{
|
||||||
|
dest << "sub" << callEnumerator << "->v" << this->getID();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest << this->boxName();
|
||||||
|
}
|
||||||
|
d=dest.str();
|
||||||
|
dest.clear();
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
{
|
{
|
||||||
case T_FLOATVAR:
|
case T_FLOATVAR:
|
||||||
if (t==T_INTVAR)
|
if (t==T_INTVAR)
|
||||||
{
|
{
|
||||||
output_cpp << this->boxName() << "="
|
output_cpp << d << "="
|
||||||
<< "static_cast<double>("
|
<< "static_cast<double>("
|
||||||
<< op->boxName() << ");\n";
|
<< op->boxName() << ");\n";
|
||||||
}
|
}
|
||||||
@@ -138,12 +150,12 @@ void operands::assignment(expression *value)
|
|||||||
{
|
{
|
||||||
if (t!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
if (t!=T_FLOATVAR) error(E_TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
output_cpp << this->boxName() << "="
|
output_cpp << d << "="
|
||||||
<< op->boxName() << ";\n";
|
<< op->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (t!=this->getType()) error(E_TYPE_MISMATCH);
|
if (t!=this->getType()) error(E_TYPE_MISMATCH);
|
||||||
output_cpp << this->boxName() << "="
|
output_cpp << d << "="
|
||||||
<< op->boxName() << ";\n";
|
<< op->boxName() << ";\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -530,12 +542,15 @@ variableType::variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHand
|
|||||||
string variableType::boxName()
|
string variableType::boxName()
|
||||||
{
|
{
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
if (myScope==S_LOCAL || myScope==S_PARAMETER)
|
switch (myScope)
|
||||||
{
|
{
|
||||||
ss << "sub" << this->handle->getID() << "->v" << this->getID();
|
case S_LOCAL:
|
||||||
return ss.str();
|
case S_PARAMETER:
|
||||||
|
ss << "sub" << this->handle->getID() << "->v" << this->getID();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ss << "v" << this->getID();
|
||||||
}
|
}
|
||||||
ss << "v" << this->getID();
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
/* static initializers */
|
/* static initializers */
|
||||||
unordered_map<string, unique_ptr<fn> > fn::functions;
|
unordered_map<string, unique_ptr<fn> > fn::functions;
|
||||||
unsigned int fn::nextID;
|
unsigned int fn::nextID;
|
||||||
|
unsigned int callEnumerator=0;
|
||||||
|
|
||||||
/* function definitions */
|
/* function definitions */
|
||||||
void fn::dumpFunctionIDs()
|
void fn::dumpFunctionIDs()
|
||||||
@@ -75,7 +76,7 @@ void fn::addParameter(string &name, enum TYPES t)
|
|||||||
/* TODO needs to be broken into smaller pieces */
|
/* TODO needs to be broken into smaller pieces */
|
||||||
operands *fn::generateCall(string &name, list<operands *>¶mList)
|
operands *fn::generateCall(string &name, list<operands *>¶mList)
|
||||||
{
|
{
|
||||||
static unsigned int callEnumerator;
|
++callEnumerator;
|
||||||
auto v=params.begin();
|
auto v=params.begin();
|
||||||
operands *current;
|
operands *current;
|
||||||
label *retAddr=new label();
|
label *retAddr=new label();
|
||||||
@@ -88,11 +89,9 @@ operands *fn::generateCall(string &name, list<operands *>¶mList)
|
|||||||
{
|
{
|
||||||
error(E_TOO_MANY_PARAMETERS);
|
error(E_TOO_MANY_PARAMETERS);
|
||||||
}
|
}
|
||||||
/* TODO CHECK THIS */
|
|
||||||
++callEnumerator;
|
|
||||||
heap_h << "struct f" << g->getID()
|
heap_h << "struct f" << g->getID()
|
||||||
<< " *sub" << callEnumerator << ";\n";
|
<< " *sub" << callEnumerator << ";\n";
|
||||||
output_cpp << " sub" << callEnumerator
|
output_cpp << "sub" << callEnumerator
|
||||||
<< "= new f" << g->getID()
|
<< "= new f" << g->getID()
|
||||||
<< "(" << retAddr->getID() << ");\n"
|
<< "(" << retAddr->getID() << ");\n"
|
||||||
<< "callStack = sub" << callEnumerator << ";\n";
|
<< "callStack = sub" << callEnumerator << ";\n";
|
||||||
@@ -105,10 +104,11 @@ operands *fn::generateCall(string &name, list<operands *>¶mList)
|
|||||||
if(current->getSimpleVarType()!=(*v)->getType())
|
if(current->getSimpleVarType()!=(*v)->getType())
|
||||||
{
|
{
|
||||||
cerr << "assigning " << TYPENAMES[current->getType()]
|
cerr << "assigning " << TYPENAMES[current->getType()]
|
||||||
<< " to " << (*v)->getType() << endl;
|
<< " to " << TYPENAMES[(*v)->getType()] << endl;
|
||||||
error(E_TYPE_MISMATCH);
|
error(E_TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
(*v)->assignment(new expression(current));
|
cerr << "assigning to parameter in sub" << callEnumerator <<"\n";
|
||||||
|
(*v)->assignment(new expression(current), true);
|
||||||
++v;
|
++v;
|
||||||
}
|
}
|
||||||
/* pad remaining unassigned variables with empty values */
|
/* pad remaining unassigned variables with empty values */
|
||||||
@@ -137,7 +137,18 @@ operands *fn::generateCall(string &name, list<operands *>¶mList)
|
|||||||
/* typeless return for gosub family */
|
/* typeless return for gosub family */
|
||||||
void fn::generateReturn()
|
void fn::generateReturn()
|
||||||
{
|
{
|
||||||
output_cpp << "state=subroutine::close();\nbreak;\n";
|
switch (this->getType())
|
||||||
|
{
|
||||||
|
case T_UNKNOWNFUNC:
|
||||||
|
output_cpp << "state=f" << this->getID()
|
||||||
|
<< "::close();\nbreak;\n";
|
||||||
|
break;
|
||||||
|
case T_GOSUB:
|
||||||
|
output_cpp << "state=subroutine::close();\nbreak;\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(E_RETURN_CODE_OMITTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fn::generateReturn(expression *expr)
|
void fn::generateReturn(expression *expr)
|
||||||
|
|||||||
Reference in New Issue
Block a user