From 2354f0be2800084a97be6c55823c130a295079cb Mon Sep 17 00:00:00 2001 From: "Samuel D. Crow" Date: Fri, 5 Aug 2022 15:06:35 -0500 Subject: [PATCH] Array support now works --- runtime/main.cpp | 3 +++ runtime/runtime.h | 1 + tester.cpp | 35 +++++++++++++++++++++++- yab2cpp.cpp | 3 ++- yab2cpp.h | 10 ++++--- yabDataStructures.cpp | 63 ++++++++++++++++++++++++++++++++----------- 6 files changed, 94 insertions(+), 21 deletions(-) diff --git a/runtime/main.cpp b/runtime/main.cpp index 88b5b0e..934b781 100644 --- a/runtime/main.cpp +++ b/runtime/main.cpp @@ -34,6 +34,9 @@ int main(int argc, char *argv[]) case UNDEFINED_STATE_ERROR: puts("Program encountered an undefined state\n"); break; + case OUT_OF_RANGE: + puts("Array index out of range\n"); + break; case EXIT: return 0; default: diff --git a/runtime/runtime.h b/runtime/runtime.h index 59b8971..c48e7be 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -18,6 +18,7 @@ enum STATES:unsigned int EXIT, UNDEFINED_STATE_ERROR, STACK_UNDERFLOW_ERROR, + OUT_OF_RANGE, START }; diff --git a/tester.cpp b/tester.cpp index 974a0b4..28b0cff 100644 --- a/tester.cpp +++ b/tester.cpp @@ -29,7 +29,8 @@ const char *COMPILE_ERROR_NAMES[]={ "too many parameters in function call", "value cannot be assigned", "undimensioned array or undeclared function", - "return code was not specified on function" + "return code was not specified on function", + "wrong number of dimensions when accessing array" }; /* These correspond to the types of enum TYPES. */ @@ -462,6 +463,37 @@ void testOnNCall() logger("testOnNCall cleared"); } +void testArray() { + string name=string("rhombic"); + list dimensions; + dimensions.push_back(8); + arrayType *at=new arrayType(name, T_INTCALL_ARRAY, dimensions); + at->generateBox(S_GLOBAL); + list indexes; + indexes.push_back(new expression(new constOp("5", T_INT))); + at->assignment(indexes, new expression(new constOp("4", T_INT))); + indexes.clear(); + string name2=string("quad"); + variableType *x=variableType::getOrCreateVar(name2, T_INTVAR); + forLoop *f=new forLoop(x, + new expression(new constOp("0", T_INT)), + new expression(new constOp("7", T_INT)) + ); + indexes.push_back(new expression(x)); + print=new printSegment(new expression(x), S_SEMICOLON); + print->generate(); + delete print; + print=new printSegment(new expression(new constOp(" has value ", T_STRING)), S_SEMICOLON); + print->generate(); + delete print; + print=new printSegment(new expression(at->getElement(indexes))); + print->generate(); + delete print; + f->close(); + dimensions.clear(); + delete f; +} + /* open files and compile */ void compile() { @@ -473,6 +505,7 @@ void compile() testIf(); testForLoop(); testOnNCall(); + testArray(); logger("generating end"); label::generateEnd(); /*check for nesting error */ diff --git a/yab2cpp.cpp b/yab2cpp.cpp index 2b7d4e6..d1fdf40 100644 --- a/yab2cpp.cpp +++ b/yab2cpp.cpp @@ -28,7 +28,8 @@ const char *COMPILE_ERROR_NAMES[]={ "too many parameters in function call", "value cannot be assigned", "undimensioned array or undeclared function", - "return code was not specified on function" + "return code was not specified on function", + "wrong number of dimensions when accessing array" }; /* These correspond to the types of enum TYPES. */ diff --git a/yab2cpp.h b/yab2cpp.h index a389426..153c90c 100644 --- a/yab2cpp.h +++ b/yab2cpp.h @@ -59,7 +59,8 @@ enum COMPILE_ERRORS:unsigned int E_TOO_MANY_PARAMETERS, E_UNASSIGNABLE_TYPE, E_UNDIMENSIONED_ARRAY, - E_RETURN_CODE_OMITTED + E_RETURN_CODE_OMITTED, + E_WRONG_NUMBER_OF_DIMENSIONS }; extern enum COMPILE_ERRORS errorLevel; @@ -371,9 +372,12 @@ public: class arrayType:public variableType { list dimensions; + + list &evaluateIndexes(listindexes); + string sourceName(list source); public: - string generateBox(enum SCOPES s); - virtual string boxName(listindexes); + void generateBox(enum SCOPES s); + operands *getElement(listindexes); virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);} void assignment(listindexes, expression *value); diff --git a/yabDataStructures.cpp b/yabDataStructures.cpp index 9eb15fa..e836715 100644 --- a/yabDataStructures.cpp +++ b/yabDataStructures.cpp @@ -7,6 +7,9 @@ ** */ #include "yab2cpp.h" +#include +#include +#include /* forward declaration and static initializers */ class fn; @@ -576,20 +579,43 @@ variableType *variableType::getOrCreateVar(string &name, enum TYPES t) return v; } -string arrayType::boxName(listindexes) +list &arrayType::evaluateIndexes(listindexes) { - ostringstream out; + if (indexes.size()!=this->dimensions.size()) error(E_WRONG_NUMBER_OF_DIMENSIONS); + auto param= new list(); + operands *o; auto i=indexes.begin(); - out << 'v' << this->getID(); + auto i2 = dimensions.begin(); while (i!=indexes.end()) { - out << '[' << (*i)->boxName() << ']'; + o=(*i)->evaluate(); + param->push_back(o); + output_cpp << "if (" << o->boxName() << ">=" << *i2 + << "){state=OUT_OF_RANGE;break;}\n"; ++i; + ++i2; } - return out.str(); + return *param; } -string arrayType::generateBox(enum SCOPES s) +operands *arrayType::getElement(listindexes) +{ + auto parameters = this->evaluateIndexes(indexes); + tempVar *tv=tempVar::getOrCreateVar(getSimpleVarType(this->getType())); + output_cpp << tv->boxName() << "=" + << 'v' << this->getID(); + auto i=parameters.begin(); + while (i!=parameters.end()) + { + output_cpp << '[' << (*i)->boxName() << ']'; + ++i; + } + output_cpp << ";\n"; + parameters.clear(); + return tv; +} + +void arrayType::generateBox(enum SCOPES s) { ostringstream out; switch (this->getType()) @@ -612,7 +638,7 @@ string arrayType::generateBox(enum SCOPES s) out << '[' << *i << ']'; } out << ";\n"; - return out.str(); + (s==S_LOCAL&&!scopeGlobal)?funcs_h:heap_h << out.str(); } arrayType::arrayType(string &name, enum TYPES t, listdim): @@ -621,23 +647,28 @@ arrayType::arrayType(string &name, enum TYPES t, listdim): this->dimensions=dim; } +string arrayType::sourceName(listsource) +{ + ostringstream out; + out << 'v' << this->getID(); + for (auto i=source.begin();i!=source.end();++i) + { + out << '[' << (*i)->boxName() << ']'; + } + return out.str(); +} + void arrayType::assignment(listindexes, expression *value) { - listx; + listx=this->evaluateIndexes(indexes); operands *op=value->evaluate(); enum TYPES t=op->getSimpleVarType(); - auto i=indexes.begin(); - while(i!=indexes.end()) - { - x.push_back((*i)->evaluate()); - ++i; - } switch (this->getType()) { case T_FLOATCALL_ARRAY: if (t==T_INTVAR) { - output_cpp << this->boxName(x) + output_cpp << this->sourceName(x) << "=static_cast(" << op->boxName() << ");\n"; return; @@ -653,7 +684,7 @@ void arrayType::assignment(listindexes, expression *value) default: error(E_INTERNAL); } - output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n"; + output_cpp << this->sourceName(x) << '=' << op->boxName() <<";\n"; op->dispose(); delete value; }