Implemented generic for loops
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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 {
|
||||
|
||||
6
src/Evaluator/EvalValues/TableEvalValue.cpp
Normal file
6
src/Evaluator/EvalValues/TableEvalValue.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "TableEvalValue.hpp"
|
||||
#include "../Iterator/SimpleKeyIterator.hpp"
|
||||
|
||||
Porygon::Evaluation::Iterator * Porygon::Evaluation::TableEvalValue::GetKeyIterator() const {
|
||||
return new TableKeyIterator(this);
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
src/Evaluator/Iterator/SimpleKeyIterator.cpp
Normal file
3
src/Evaluator/Iterator/SimpleKeyIterator.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
#include "SimpleKeyIterator.hpp"
|
||||
39
src/Evaluator/Iterator/SimpleKeyIterator.hpp
Normal file
39
src/Evaluator/Iterator/SimpleKeyIterator.hpp
Normal 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
|
||||
Reference in New Issue
Block a user