Fixed bugs with paramaters being passed to the wrong callsite

This commit is contained in:
Samuel D. Crow 2022-08-01 15:35:43 -05:00
parent 34f1abeda6
commit 820fb864bd
9 changed files with 64 additions and 29 deletions

View File

@ -48,4 +48,4 @@ build/yabFunctions.o: $(YABFUNCTIONS_SOURCE_DEPS)
.PHONY: clean
clean:
rm -rf build/*.o output/*.o yab2cpp tester
rm -rf build/*.o output/*.h output/*.cpp yab2cpp tester

View File

@ -6,9 +6,11 @@ CFLAGS += -std=c++11
#CFLAGS += -Os
LFLAGS :=
.PHONY: all
all: binaries
binaries: bin_main
.PHONY: binaries
binaries: main
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
bin_main: $(MAIN_OBJ_DEPS)
main: $(MAIN_OBJ_DEPS)
$(CC) -o main $(MAIN_OBJ_DEPS)
main.o: $(OUTPUT_DEPS)

View File

@ -11,14 +11,14 @@ subroutine *callStack=nullptr;
subroutine::subroutine(unsigned int r)
{
this->ret=r;
this->called=callStack;
this->callStackNode=callStack;
}
unsigned int subroutine::close()
{
if (callStack==nullptr) return STACK_UNDERFLOW_ERROR;
unsigned int r=callStack->ret;
subroutine *l=callStack->called;
subroutine *l=callStack->callStackNode;
delete callStack;
callStack=l;
return r;

View File

@ -1,5 +1,5 @@
/*
** Practice runtime header for Yab2Cpp
** Runtime header for Yab2Cpp
**
** by Samuel D. Crow
*/
@ -10,6 +10,9 @@
#include <cstdio>
using namespace std;
/*
This enum contains all of the error states used at runtime.
*/
enum STATES:unsigned int
{
EXIT,
@ -18,9 +21,12 @@ enum STATES:unsigned int
START
};
/*
This class wraps the function class and is inherited by every subroutine.
*/
class subroutine
{
subroutine *called;
subroutine *callStackNode;
unsigned int ret;
public:

View File

@ -28,7 +28,8 @@ const char *COMPILE_ERROR_NAMES[]={
"undefined subroutine name",
"too many parameters in function call",
"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. */

View File

@ -27,7 +27,8 @@ const char *COMPILE_ERROR_NAMES[]={
"undefined subroutine name",
"too many parameters in function call",
"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. */

View File

@ -58,7 +58,8 @@ enum COMPILE_ERRORS:unsigned int
E_SUBROUTINE_NOT_FOUND,
E_TOO_MANY_PARAMETERS,
E_UNASSIGNABLE_TYPE,
E_UNDIMENSIONED_ARRAY
E_UNDIMENSIONED_ARRAY,
E_RETURN_CODE_OMITTED
};
extern enum COMPILE_ERRORS errorLevel;
@ -66,6 +67,7 @@ extern unsigned int indentLevel;
/*TODO: Replace scopeGlobal with currentFunc==nullptr*/
extern bool scopeGlobal;
extern fn *currentFunc;
extern unsigned int callEnumerator;
/* flags used internally by the compiler */
extern bool COMPILE;
@ -181,7 +183,7 @@ public:
static enum TYPES getSimpleVarType(enum TYPES t);
void generateBox(enum SCOPES s);
void assignment(expression *value);
void assignment(expression *value, bool paramDef=false);
static operands *createOp(enum TYPES t);
virtual void dispose();
};
@ -360,12 +362,9 @@ class variableType:public operands
fn *handle;
public:
static variableType *getOrCreateVar(string &name, enum TYPES t);
static variableType *cloneAttributes(variableType *v);
virtual string boxName();
/* always call generateBox() after new variableType() */
variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHandle);
variableType();
~variableType()
{}
};

View File

@ -121,16 +121,28 @@ string operands::boxName()
}
}
void operands::assignment(expression *value)
void operands::assignment(expression *value, bool paramDef)
{
operands *op=value->evaluate();
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())
{
case T_FLOATVAR:
if (t==T_INTVAR)
{
output_cpp << this->boxName() << "="
output_cpp << d << "="
<< "static_cast<double>("
<< op->boxName() << ");\n";
}
@ -138,12 +150,12 @@ void operands::assignment(expression *value)
{
if (t!=T_FLOATVAR) error(E_TYPE_MISMATCH);
}
output_cpp << this->boxName() << "="
output_cpp << d << "="
<< op->boxName() << ";\n";
break;
default:
if (t!=this->getType()) error(E_TYPE_MISMATCH);
output_cpp << this->boxName() << "="
output_cpp << d << "="
<< op->boxName() << ";\n";
break;
}
@ -530,12 +542,15 @@ variableType::variableType(enum SCOPES s, string &name, enum TYPES t, fn *fnHand
string variableType::boxName()
{
ostringstream ss;
if (myScope==S_LOCAL || myScope==S_PARAMETER)
switch (myScope)
{
ss << "sub" << this->handle->getID() << "->v" << this->getID();
return ss.str();
case S_LOCAL:
case S_PARAMETER:
ss << "sub" << this->handle->getID() << "->v" << this->getID();
break;
default:
ss << "v" << this->getID();
}
ss << "v" << this->getID();
return ss.str();
}

View File

@ -11,6 +11,7 @@
/* static initializers */
unordered_map<string, unique_ptr<fn> > fn::functions;
unsigned int fn::nextID;
unsigned int callEnumerator=0;
/* function definitions */
void fn::dumpFunctionIDs()
@ -75,7 +76,7 @@ void fn::addParameter(string &name, enum TYPES t)
/* TODO needs to be broken into smaller pieces */
operands *fn::generateCall(string &name, list<operands *>&paramList)
{
static unsigned int callEnumerator;
++callEnumerator;
auto v=params.begin();
operands *current;
label *retAddr=new label();
@ -88,11 +89,9 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
{
error(E_TOO_MANY_PARAMETERS);
}
/* TODO CHECK THIS */
++callEnumerator;
heap_h << "struct f" << g->getID()
<< " *sub" << callEnumerator << ";\n";
output_cpp << " sub" << callEnumerator
output_cpp << "sub" << callEnumerator
<< "= new f" << g->getID()
<< "(" << retAddr->getID() << ");\n"
<< "callStack = sub" << callEnumerator << ";\n";
@ -105,10 +104,11 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
if(current->getSimpleVarType()!=(*v)->getType())
{
cerr << "assigning " << TYPENAMES[current->getType()]
<< " to " << (*v)->getType() << endl;
<< " to " << TYPENAMES[(*v)->getType()] << endl;
error(E_TYPE_MISMATCH);
}
(*v)->assignment(new expression(current));
cerr << "assigning to parameter in sub" << callEnumerator <<"\n";
(*v)->assignment(new expression(current), true);
++v;
}
/* pad remaining unassigned variables with empty values */
@ -137,7 +137,18 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
/* typeless return for gosub family */
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)