From 820fb864bdb79ee34991e276b27dd74cfdc3eaab Mon Sep 17 00:00:00 2001 From: "Samuel D. Crow" Date: Mon, 1 Aug 2022 15:35:43 -0500 Subject: [PATCH] Fixed bugs with paramaters being passed to the wrong callsite --- Makefile | 2 +- runtime/Makefile | 6 ++++-- runtime/main.cpp | 4 ++-- runtime/runtime.h | 10 ++++++++-- tester.cpp | 3 ++- yab2cpp.cpp | 3 ++- yab2cpp.h | 9 ++++----- yabDataStructures.cpp | 31 +++++++++++++++++++++++-------- yabFunctions.cpp | 25 ++++++++++++++++++------- 9 files changed, 64 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 36a7d88..59c5469 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/runtime/Makefile b/runtime/Makefile index f6ba35b..0892928 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -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) diff --git a/runtime/main.cpp b/runtime/main.cpp index 8ee2fc0..88b5b0e 100644 --- a/runtime/main.cpp +++ b/runtime/main.cpp @@ -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; diff --git a/runtime/runtime.h b/runtime/runtime.h index 9432eb2..59b8971 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -1,5 +1,5 @@ /* -** Practice runtime header for Yab2Cpp +** Runtime header for Yab2Cpp ** ** by Samuel D. Crow */ @@ -10,6 +10,9 @@ #include 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: diff --git a/tester.cpp b/tester.cpp index 1f21cb4..dbb5f34 100644 --- a/tester.cpp +++ b/tester.cpp @@ -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. */ diff --git a/yab2cpp.cpp b/yab2cpp.cpp index 87c9553..2b7d4e6 100644 --- a/yab2cpp.cpp +++ b/yab2cpp.cpp @@ -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. */ diff --git a/yab2cpp.h b/yab2cpp.h index 952c62a..df8704c 100644 --- a/yab2cpp.h +++ b/yab2cpp.h @@ -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() {} }; diff --git a/yabDataStructures.cpp b/yabDataStructures.cpp index 5838c48..9eb15fa 100644 --- a/yabDataStructures.cpp +++ b/yabDataStructures.cpp @@ -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(" << 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(); } diff --git a/yabFunctions.cpp b/yabFunctions.cpp index 41d8f9e..9eecfbf 100644 --- a/yabFunctions.cpp +++ b/yabFunctions.cpp @@ -11,6 +11,7 @@ /* static initializers */ unordered_map > 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¶mList) { - 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¶mList) { 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¶mList) 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¶mList) /* 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)