Array support now works

This commit is contained in:
Samuel D. Crow 2022-08-05 15:06:35 -05:00
parent 7930b048b8
commit 2354f0be28
6 changed files with 94 additions and 21 deletions

View File

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

View File

@ -18,6 +18,7 @@ enum STATES:unsigned int
EXIT,
UNDEFINED_STATE_ERROR,
STACK_UNDERFLOW_ERROR,
OUT_OF_RANGE,
START
};

View File

@ -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<unsigned int> dimensions;
dimensions.push_back(8);
arrayType *at=new arrayType(name, T_INTCALL_ARRAY, dimensions);
at->generateBox(S_GLOBAL);
list<expression *> 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 */

View File

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

View File

@ -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<unsigned int> dimensions;
list<operands *> &evaluateIndexes(list<expression *>indexes);
string sourceName(list<operands *> source);
public:
string generateBox(enum SCOPES s);
virtual string boxName(list<operands *>indexes);
void generateBox(enum SCOPES s);
operands *getElement(list<expression *>indexes);
virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);}
void assignment(list<expression *>indexes, expression *value);

View File

@ -7,6 +7,9 @@
**
*/
#include "yab2cpp.h"
#include <fstream>
#include <list>
#include <sstream>
/* forward declaration and static initializers */
class fn;
@ -576,20 +579,43 @@ variableType *variableType::getOrCreateVar(string &name, enum TYPES t)
return v;
}
string arrayType::boxName(list<operands *>indexes)
list<operands *> &arrayType::evaluateIndexes(list<expression *>indexes)
{
ostringstream out;
if (indexes.size()!=this->dimensions.size()) error(E_WRONG_NUMBER_OF_DIMENSIONS);
auto param= new list<operands *>();
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(list<expression *>indexes)
{
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, list<unsigned int>dim):
@ -621,23 +647,28 @@ arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
this->dimensions=dim;
}
string arrayType::sourceName(list<operands *>source)
{
ostringstream out;
out << 'v' << this->getID();
for (auto i=source.begin();i!=source.end();++i)
{
out << '[' << (*i)->boxName() << ']';
}
return out.str();
}
void arrayType::assignment(list<expression *>indexes, expression *value)
{
list<operands *>x;
list<operands *>x=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<double>("
<< op->boxName() << ");\n";
return;
@ -653,7 +684,7 @@ void arrayType::assignment(list<expression *>indexes, 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;
}