Array support now works
This commit is contained in:
@@ -34,6 +34,9 @@ int main(int argc, char *argv[])
|
|||||||
case UNDEFINED_STATE_ERROR:
|
case UNDEFINED_STATE_ERROR:
|
||||||
puts("Program encountered an undefined state\n");
|
puts("Program encountered an undefined state\n");
|
||||||
break;
|
break;
|
||||||
|
case OUT_OF_RANGE:
|
||||||
|
puts("Array index out of range\n");
|
||||||
|
break;
|
||||||
case EXIT:
|
case EXIT:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ enum STATES:unsigned int
|
|||||||
EXIT,
|
EXIT,
|
||||||
UNDEFINED_STATE_ERROR,
|
UNDEFINED_STATE_ERROR,
|
||||||
STACK_UNDERFLOW_ERROR,
|
STACK_UNDERFLOW_ERROR,
|
||||||
|
OUT_OF_RANGE,
|
||||||
START
|
START
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
35
tester.cpp
35
tester.cpp
@@ -29,7 +29,8 @@ const char *COMPILE_ERROR_NAMES[]={
|
|||||||
"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"
|
"return code was not specified on function",
|
||||||
|
"wrong number of dimensions when accessing array"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These correspond to the types of enum TYPES. */
|
/* These correspond to the types of enum TYPES. */
|
||||||
@@ -462,6 +463,37 @@ void testOnNCall()
|
|||||||
logger("testOnNCall cleared");
|
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 */
|
/* open files and compile */
|
||||||
void compile()
|
void compile()
|
||||||
{
|
{
|
||||||
@@ -473,6 +505,7 @@ void compile()
|
|||||||
testIf();
|
testIf();
|
||||||
testForLoop();
|
testForLoop();
|
||||||
testOnNCall();
|
testOnNCall();
|
||||||
|
testArray();
|
||||||
logger("generating end");
|
logger("generating end");
|
||||||
label::generateEnd();
|
label::generateEnd();
|
||||||
/*check for nesting error */
|
/*check for nesting error */
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ const char *COMPILE_ERROR_NAMES[]={
|
|||||||
"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"
|
"return code was not specified on function",
|
||||||
|
"wrong number of dimensions when accessing array"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These correspond to the types of enum TYPES. */
|
/* These correspond to the types of enum TYPES. */
|
||||||
|
|||||||
10
yab2cpp.h
10
yab2cpp.h
@@ -59,7 +59,8 @@ enum COMPILE_ERRORS:unsigned int
|
|||||||
E_TOO_MANY_PARAMETERS,
|
E_TOO_MANY_PARAMETERS,
|
||||||
E_UNASSIGNABLE_TYPE,
|
E_UNASSIGNABLE_TYPE,
|
||||||
E_UNDIMENSIONED_ARRAY,
|
E_UNDIMENSIONED_ARRAY,
|
||||||
E_RETURN_CODE_OMITTED
|
E_RETURN_CODE_OMITTED,
|
||||||
|
E_WRONG_NUMBER_OF_DIMENSIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum COMPILE_ERRORS errorLevel;
|
extern enum COMPILE_ERRORS errorLevel;
|
||||||
@@ -371,9 +372,12 @@ public:
|
|||||||
class arrayType:public variableType
|
class arrayType:public variableType
|
||||||
{
|
{
|
||||||
list<unsigned int> dimensions;
|
list<unsigned int> dimensions;
|
||||||
|
|
||||||
|
list<operands *> &evaluateIndexes(list<expression *>indexes);
|
||||||
|
string sourceName(list<operands *> source);
|
||||||
public:
|
public:
|
||||||
string generateBox(enum SCOPES s);
|
void generateBox(enum SCOPES s);
|
||||||
virtual string boxName(list<operands *>indexes);
|
operands *getElement(list<expression *>indexes);
|
||||||
virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);}
|
virtual string boxName(){error(E_UNDIMENSIONED_ARRAY);}
|
||||||
|
|
||||||
void assignment(list<expression *>indexes, expression *value);
|
void assignment(list<expression *>indexes, expression *value);
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
#include "yab2cpp.h"
|
#include "yab2cpp.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
/* forward declaration and static initializers */
|
/* forward declaration and static initializers */
|
||||||
class fn;
|
class fn;
|
||||||
@@ -576,20 +579,43 @@ variableType *variableType::getOrCreateVar(string &name, enum TYPES t)
|
|||||||
return v;
|
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();
|
auto i=indexes.begin();
|
||||||
out << 'v' << this->getID();
|
auto i2 = dimensions.begin();
|
||||||
while (i!=indexes.end())
|
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;
|
++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;
|
ostringstream out;
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
@@ -612,7 +638,7 @@ string arrayType::generateBox(enum SCOPES s)
|
|||||||
out << '[' << *i << ']';
|
out << '[' << *i << ']';
|
||||||
}
|
}
|
||||||
out << ";\n";
|
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):
|
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;
|
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)
|
void arrayType::assignment(list<expression *>indexes, expression *value)
|
||||||
{
|
{
|
||||||
list<operands *>x;
|
list<operands *>x=this->evaluateIndexes(indexes);
|
||||||
operands *op=value->evaluate();
|
operands *op=value->evaluate();
|
||||||
enum TYPES t=op->getSimpleVarType();
|
enum TYPES t=op->getSimpleVarType();
|
||||||
auto i=indexes.begin();
|
|
||||||
while(i!=indexes.end())
|
|
||||||
{
|
|
||||||
x.push_back((*i)->evaluate());
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
switch (this->getType())
|
switch (this->getType())
|
||||||
{
|
{
|
||||||
case T_FLOATCALL_ARRAY:
|
case T_FLOATCALL_ARRAY:
|
||||||
if (t==T_INTVAR)
|
if (t==T_INTVAR)
|
||||||
{
|
{
|
||||||
output_cpp << this->boxName(x)
|
output_cpp << this->sourceName(x)
|
||||||
<< "=static_cast<double>("
|
<< "=static_cast<double>("
|
||||||
<< op->boxName() << ");\n";
|
<< op->boxName() << ");\n";
|
||||||
return;
|
return;
|
||||||
@@ -653,7 +684,7 @@ void arrayType::assignment(list<expression *>indexes, expression *value)
|
|||||||
default:
|
default:
|
||||||
error(E_INTERNAL);
|
error(E_INTERNAL);
|
||||||
}
|
}
|
||||||
output_cpp << this->boxName(x) << '=' << op->boxName() <<";\n";
|
output_cpp << this->sourceName(x) << '=' << op->boxName() <<";\n";
|
||||||
op->dispose();
|
op->dispose();
|
||||||
delete value;
|
delete value;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user