Implemented generic for loops
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-26 16:19:34 +02:00
parent cfd558b718
commit d86e9ba8ae
18 changed files with 325 additions and 44 deletions

View File

@@ -2,11 +2,17 @@
#ifndef PORYGONLANG_EVALVALUE_HPP
#define PORYGONLANG_EVALVALUE_HPP
#include "../../ScriptType.hpp"
#include "../EvaluationException.hpp"
#include <string>
#include <sstream>
#include <memory>
#include "../../ScriptType.hpp"
#include "../EvaluationException.hpp"
namespace Porygon::Evaluation{
class EvalValue;
class Iterator;
}
#include "../Iterator/Iterator.hpp"
namespace Porygon::Evaluation {
class EvalValue {
@@ -54,6 +60,10 @@ namespace Porygon::Evaluation {
virtual void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const {
throw EvaluationException("Can't index this EvalValue");
}
virtual Iterator * GetKeyIterator() const{
throw EvaluationException("Can't iterate over this EvalValue");
}
};
class BooleanEvalValue : public EvalValue {

View File

@@ -0,0 +1,6 @@
#include "TableEvalValue.hpp"
#include "../Iterator/SimpleKeyIterator.hpp"
Porygon::Evaluation::Iterator * Porygon::Evaluation::TableEvalValue::GetKeyIterator() const {
return new TableKeyIterator(this);
}

View File

@@ -1,3 +1,4 @@
#ifndef PORYGONLANG_TABLEEVALVALUE_HPP
#define PORYGONLANG_TABLEEVALVALUE_HPP
#include <utility>
@@ -8,18 +9,20 @@ using namespace std;
namespace Porygon::Evaluation {
class TableEvalValue : public EvalValue {
shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> _table;
size_t _hash;
const shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> _table;
const size_t _hash;
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> table, size_t hash) {
_table = std::move(table);
_hash = hash;
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> table, size_t hash)
: _table(std::move(table)),
_hash(hash)
{
}
public:
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> table) {
_table = std::move(table);
_hash = rand();
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> table) :
_table(std::move(table)),
_hash(rand())
{
}
const TypeClass GetTypeClass() const final {
@@ -57,6 +60,8 @@ namespace Porygon::Evaluation {
this->_table->at(Utilities::HashedString::CreateLookup(hash)) = value;
}
Iterator * GetKeyIterator() const final;
const _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> GetTableIterator() const{
return _table->cbegin();
};

View File

@@ -45,6 +45,8 @@ namespace Porygon::Evaluation {
return this->EvaluateConditionalStatement((BoundConditionalStatement *) statement);
case BoundStatementKind::NumericalFor:
return this->EvaluateNumericalForStatement((BoundNumericalForStatement*)statement);
case BoundStatementKind::GenericFor:
return this-> EvaluateGenericForStatement((BoundGenericForStatement*)statement);
case BoundStatementKind::Bad:
throw;
@@ -151,6 +153,32 @@ namespace Porygon::Evaluation {
}
}
void Evaluator::EvaluateGenericForStatement(const BoundGenericForStatement *statement) {
auto iteratorVal = EvaluateExpression(statement -> GetIterator());
auto iterator = iteratorVal -> GetKeyIterator();
auto keyVariable = statement ->GetKeyIdentifier();
auto valueVariable = statement ->GetValueIdentifier();
this -> _evaluationScope -> CreateVariable(keyVariable, nullptr);
if (valueVariable != nullptr)
this -> _evaluationScope -> CreateVariable(valueVariable, nullptr);
auto block = (BoundBlockStatement*)statement -> GetBlock();
while (iterator->MoveNext()){
auto currentKey = iterator->GetCurrent();
this -> _evaluationScope -> SetVariable(keyVariable, currentKey);
if (valueVariable != nullptr){
auto currentValue = iteratorVal -> IndexValue(currentKey.get());
this -> _evaluationScope -> SetVariable(valueVariable, currentValue);
}
this -> EvaluateBlockStatement(block);
}
}
/////////////////
// Expressions //
/////////////////
const shared_ptr<EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
auto type = expression->GetType();
switch (type->GetClass()) {
@@ -425,5 +453,4 @@ namespace Porygon::Evaluation {
throw;
}
}
}

View File

@@ -32,6 +32,7 @@ namespace Porygon::Evaluation{
void EvaluateReturnStatement(const BoundReturnStatement *statement);
void EvaluateConditionalStatement(const BoundConditionalStatement *statement);
void EvaluateNumericalForStatement(const BoundNumericalForStatement *statement);
void EvaluateGenericForStatement(const BoundGenericForStatement *statement);
const shared_ptr<EvalValue> EvaluateExpression(const BoundExpression *expression);
const shared_ptr<NumericEvalValue> EvaluateIntegerExpression(const BoundExpression *expression);

View File

@@ -4,8 +4,6 @@
#include <memory>
#include "../EvalValues/EvalValue.hpp"
#include "../EvalValues/TableEvalValue.hpp"
#include "../EvalValues/StringEvalValue.hpp"
using namespace std;
@@ -17,26 +15,6 @@ namespace Porygon::Evaluation{
virtual void Reset() = 0;
};
class TableKeyIterator : Iterator{
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> _iterator;
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> _end;
public:
TableKeyIterator(shared_ptr<TableEvalValue> table)
: _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){}
shared_ptr<EvalValue> GetCurrent() final{
return make_shared<StringEvalValue>(*_iterator->first.GetString());
}
bool MoveNext() final{
std::advance(_iterator, 1);
return _iterator != _end;
}
void Reset(){
throw EvaluationException("Can't reset table key iterator");
}
};
}

View File

@@ -0,0 +1,3 @@
#include "SimpleKeyIterator.hpp"

View File

@@ -0,0 +1,39 @@
#ifndef PORYGONLANG_SIMPLEKEYITERATOR_HPP
#define PORYGONLANG_SIMPLEKEYITERATOR_HPP
#include "Iterator.hpp"
#include "../EvalValues/TableEvalValue.hpp"
#include "../EvalValues/StringEvalValue.hpp"
namespace Porygon::Evaluation{
class TableKeyIterator : public Iterator{
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> _iterator;
_Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> _end;
bool _hasStarted = false;
public:
explicit TableKeyIterator(const TableEvalValue* table)
: _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){}
shared_ptr<EvalValue> GetCurrent() final{
return make_shared<StringEvalValue>(*_iterator->first.GetString());
}
bool MoveNext() final{
if (_hasStarted){
std::advance(_iterator, 1);
} else{
_hasStarted = true;
}
return _iterator != _end;
}
void Reset(){
throw EvaluationException("Can't reset table key iterator");
}
};
}
#endif //PORYGONLANG_SIMPLEKEYITERATOR_HPP