diff --git a/src/interpreter/datatypes/argumentdatatype.cpp b/src/interpreter/datatypes/argumentdatatype.cpp index 77a7340..70da8ea 100644 --- a/src/interpreter/datatypes/argumentdatatype.cpp +++ b/src/interpreter/datatypes/argumentdatatype.cpp @@ -1,9 +1,22 @@ #include "argumentdatatype.h" #include "interpreter/values/literalvalue.h" +#include "interpreter/context.h" using namespace CS; +using namespace std; -ArgumentDataType::ArgumentDataType() {} +ArgumentDataType::ArgumentDataType() { + _methods.insert( + pair( + "pop", + &ArgumentDataType::pop) + ); + _methods.insert( + pair( + "push", + &ArgumentDataType::push) + ); +} ArgumentDataType::~ArgumentDataType() {} @@ -18,3 +31,63 @@ LiteralValue* ArgumentDataType::cast(LiteralValue* value) const { break; } } + +LiteralValue* ArgumentDataType::pop( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 0 ) + return nullptr; + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + if( !array->empty() ) + { + delete array->back(); + array->pop_back(); + } + + auto newLiteralValue = new ArgumentLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newLiteralValue); + + return new NullLiteralValue(); +} + +LiteralValue* ArgumentDataType::push( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 1 ) + return nullptr; + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + array->push_back(argumentValues->front()->clone()); + + auto newValue = new ArgumentLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newValue); + + return new NullLiteralValue(); +} diff --git a/src/interpreter/datatypes/argumentdatatype.h b/src/interpreter/datatypes/argumentdatatype.h index da0020b..acea337 100644 --- a/src/interpreter/datatypes/argumentdatatype.h +++ b/src/interpreter/datatypes/argumentdatatype.h @@ -11,6 +11,9 @@ class ArgumentDataType : public DataType ArgumentDataType(); ~ArgumentDataType(); LiteralValue* cast(LiteralValue*) const; +private: + static LiteralValue* push(std::string,const LiteralValue*,const LiteralValue*); + static LiteralValue* pop(std::string,const LiteralValue*,const LiteralValue*); }; } diff --git a/src/interpreter/datatypes/arraydatatype.cpp b/src/interpreter/datatypes/arraydatatype.cpp index 142f453..6333309 100644 --- a/src/interpreter/datatypes/arraydatatype.cpp +++ b/src/interpreter/datatypes/arraydatatype.cpp @@ -1,6 +1,6 @@ #include "arraydatatype.h" #include "interpreter/values/literalvalue.h" -#include +#include "interpreter/context.h" using namespace CS; using namespace std; @@ -16,6 +16,26 @@ ArrayDataType::ArrayDataType() { "at", &ArrayDataType::at) ); + _methods.insert( + pair( + "append", + &ArrayDataType::append) + ); + _methods.insert( + pair( + "insert", + &ArrayDataType::insert) + ); + _methods.insert( + pair( + "remove", + &ArrayDataType::remove) + ); + _methods.insert( + pair( + "pop", + &ArrayDataType::pop) + ); } ArrayDataType::~ArrayDataType() {} @@ -87,3 +107,137 @@ LiteralValue* ArrayDataType::at( return (*it)->clone(); } + +LiteralValue* ArrayDataType::append( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 1 ) + return nullptr; + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + array->push_back(argumentValues->front()->clone()); + + auto newValue = new ArrayLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newValue); + + return new NullLiteralValue(); +} + +LiteralValue* ArrayDataType::insert( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 2 ) + return nullptr; + + if( argumentValues->front()->getDataTypeId() != DataTypesId::Numeric ) + return nullptr; + + unsigned index = *(double*)argumentValues->front()->getValue(); + argumentValues->pop_front(); + LiteralValue* newValue = argumentValues->front(); + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + auto it = array->begin(); + for(unsigned i = 0; i < index; i++) + it++; + + array->insert(it,newValue->clone()); + + auto newLiteralValue = new ArrayLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newLiteralValue); + + return new NullLiteralValue(); +} + +LiteralValue* ArrayDataType::remove( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 1 ) + return nullptr; + + if( argumentValues->front()->getDataTypeId() != DataTypesId::Numeric ) + return nullptr; + + unsigned index = *(double*)argumentValues->front()->getValue(); + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + auto it = array->begin(); + for(unsigned i = 0; i < index; i++) + it++; + + delete *it; + array->erase(it); + + auto newLiteralValue = new ArrayLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newLiteralValue); + + return new NullLiteralValue(); +} + +LiteralValue* ArrayDataType::pop( + string variableName, + const LiteralValue* value, + const LiteralValue* args + ) { + + if( args->getDataTypeId() != DataTypesId::Argument ) + return nullptr; + + auto argumentValues = (list*)args->getValue(); + + if( argumentValues->size() != 0 ) + return nullptr; + + if( !value ) + return nullptr; + + auto array = (list*)value->getValue(); + + delete array->back(); + array->pop_back(); + + auto newLiteralValue = new ArrayLiteralValue(*array); + + Context::getInstance()->setVariableValue(variableName,newLiteralValue); + + return new NullLiteralValue(); +} diff --git a/src/interpreter/datatypes/arraydatatype.h b/src/interpreter/datatypes/arraydatatype.h index 0e6e9ef..1d54205 100644 --- a/src/interpreter/datatypes/arraydatatype.h +++ b/src/interpreter/datatypes/arraydatatype.h @@ -14,6 +14,10 @@ class ArrayDataType : public DataType private: static LiteralValue* size(std::string,const LiteralValue*,const LiteralValue*); static LiteralValue* at(std::string,const LiteralValue*,const LiteralValue*); + static LiteralValue* append(std::string,const LiteralValue*,const LiteralValue*); + static LiteralValue* insert(std::string,const LiteralValue*,const LiteralValue*); + static LiteralValue* remove(std::string,const LiteralValue*,const LiteralValue*); + static LiteralValue* pop(std::string,const LiteralValue*,const LiteralValue*); }; } diff --git a/src/interpreter/datatypes/sounddatatype.cpp b/src/interpreter/datatypes/sounddatatype.cpp index bd5faf1..b0b857b 100644 --- a/src/interpreter/datatypes/sounddatatype.cpp +++ b/src/interpreter/datatypes/sounddatatype.cpp @@ -151,6 +151,11 @@ LiteralValue* SoundDataType::play( } case DataTypesId::Argument: { + if( ((list*)((ArgumentLiteralValue*)(*it))->getValue())->front()->getDataTypeId() == DataTypesId::Argument ) + { + argumentValues = (list*)((ArgumentLiteralValue*)(*it))->getValue(); + it = argumentValues->begin(); + } for( ; it != argumentValues->end(); it++ ) { const list* argumentList = (list*)((ArgumentLiteralValue*)(*it))->getValue(); @@ -171,7 +176,10 @@ LiteralValue* SoundDataType::play( } argIt++; if( argIt == argumentList->end() ) - return nullptr; + { + generator->play(freqList,0,startTick,variableName); + return new NullLiteralValue(); + } if( (*argIt)->getDataTypeId() != DataTypesId::Numeric ) return nullptr;