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 .PHONY: clean
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 #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)

View File

@@ -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;

View File

@@ -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:

View File

@@ -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. */

View File

@@ -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. */

View File

@@ -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()
{} {}
}; };

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(); 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)
{ {
case S_LOCAL:
case S_PARAMETER:
ss << "sub" << this->handle->getID() << "->v" << this->getID(); ss << "sub" << this->handle->getID() << "->v" << this->getID();
return ss.str(); break;
} default:
ss << "v" << this->getID(); ss << "v" << this->getID();
}
return ss.str(); return ss.str();
} }

View File

@@ -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 *>&paramList) operands *fn::generateCall(string &name, list<operands *>&paramList)
{ {
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,8 +89,6 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
{ {
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
@@ -105,10 +104,11 @@ operands *fn::generateCall(string &name, list<operands *>&paramList)
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 *>&paramList)
/* typeless return for gosub family */ /* typeless return for gosub family */
void fn::generateReturn() void fn::generateReturn()
{ {
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"; output_cpp << "state=subroutine::close();\nbreak;\n";
break;
default:
error(E_RETURN_CODE_OMITTED);
}
} }
void fn::generateReturn(expression *expr) void fn::generateReturn(expression *expr)