Reworked handling of numerical key tables to make iteration over keys actual numerics, instead of strings
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2019-06-27 14:02:31 +02:00
parent d86e9ba8ae
commit 9727c9365e
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
8 changed files with 121 additions and 11 deletions

View File

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

View File

@ -0,0 +1,69 @@
#ifndef PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP
#define PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP
#include <utility>
#include <map>
#include "EvalValue.hpp"
using namespace std;
namespace Porygon::Evaluation {
class NumericalTableEvalValue : public EvalValue {
const shared_ptr<vector<shared_ptr<EvalValue>>> _table;
const size_t _hash;
explicit NumericalTableEvalValue(shared_ptr<vector<shared_ptr<EvalValue>>> table, size_t hash)
: _table(std::move(table)),
_hash(hash)
{
}
public:
explicit NumericalTableEvalValue(shared_ptr<vector<shared_ptr<EvalValue>>> table) :
_table(std::move(table)),
_hash(rand())
{
}
const TypeClass GetTypeClass() const final {
return TypeClass::Table;
}
const size_t GetHashCode() const final {
return _hash;
}
const bool operator==(EvalValue *b) const final {
return this->_hash == b->GetHashCode();
}
const shared_ptr<EvalValue> Clone() const final {
return shared_ptr<EvalValue>(new NumericalTableEvalValue(_table, _hash));
}
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
const auto index = val->EvaluateInteger() - 1;
return this->_table->at(index);
}
const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final {
return this->_table->at(hash - 1);
}
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const final {
auto index = key->EvaluateInteger();
this->_table->at(index - 1) = value;
}
Iterator * GetKeyIterator() const final;
const shared_ptr<vector<shared_ptr<EvalValue>>> GetTable() const{
return _table;
};
};
}
#undef iteratorKind
#endif //PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP

View File

@ -11,6 +11,7 @@
#include "../TableScriptType.hpp" #include "../TableScriptType.hpp"
#include "../UserData/UserDataFunction.hpp" #include "../UserData/UserDataFunction.hpp"
#include "../Utilities/StringUtils.hpp" #include "../Utilities/StringUtils.hpp"
#include "EvalValues/NumericalTableEvalValue.hpp"
using namespace std; using namespace std;
using namespace Porygon::Binder; using namespace Porygon::Binder;
@ -417,14 +418,13 @@ namespace Porygon::Evaluation {
const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) { const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
auto tableExpression = (BoundNumericalTableExpression *) expression; auto tableExpression = (BoundNumericalTableExpression *) expression;
auto valueExpressions = tableExpression->GetExpressions(); auto valueExpressions = tableExpression->GetExpressions();
auto values = new map<Utilities::HashedString, shared_ptr<EvalValue>>(); auto values = new vector<shared_ptr<EvalValue>>(valueExpressions->size());
for (int i = 0; i < valueExpressions->size(); i++) { for (int i = 0; i < valueExpressions->size(); i++) {
auto val = this->EvaluateExpression(valueExpressions->at(i)); auto val = this->EvaluateExpression(valueExpressions->at(i));
auto key = new u16string(Utilities::StringUtils::IntToString(i + 1)); values->at(i) = val;
values->insert({Utilities::HashedString(key), val});
} }
auto valuesPointer = shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>>(values); auto valuesPointer = shared_ptr<vector<shared_ptr<EvalValue>>>(values);
return make_shared<TableEvalValue>(valuesPointer); return make_shared<NumericalTableEvalValue>(valuesPointer);
} }
const shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) { const shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {

View File

@ -0,0 +1 @@
#include "NumericalKeyIterator.hpp"

View File

@ -0,0 +1,34 @@
#ifndef PORYGONLANG_NUMERICALKEYITERATOR_HPP
#define PORYGONLANG_NUMERICALKEYITERATOR_HPP
#include "Iterator.hpp"
#include "../EvalValues/NumericalTableEvalValue.hpp"
#include "../EvalValues/NumericEvalValue.hpp"
namespace Porygon::Evaluation{
class NumericalKeyIterator : public Iterator{
const shared_ptr<vector<shared_ptr<EvalValue>>> _vec;
const size_t _size;
long _position = 0;
public:
explicit NumericalKeyIterator(const NumericalTableEvalValue* table)
: _vec(table->GetTable()), _size(_vec->size() + 1){}
shared_ptr<EvalValue> GetCurrent() final{
return make_shared<IntegerEvalValue>(_position);
}
bool MoveNext() final{
_position++;
return _position != _size;
}
void Reset() final{
_position = 0;
}
};
}
#endif //PORYGONLANG_NUMERICALKEYITERATOR_HPP

View File

@ -28,7 +28,7 @@ namespace Porygon::Evaluation{
return _iterator != _end; return _iterator != _end;
} }
void Reset(){ void Reset() final{
throw EvaluationException("Can't reset table key iterator"); throw EvaluationException("Can't reset table key iterator");
} }
}; };

View File

@ -182,7 +182,7 @@ namespace Porygon{
return true; return true;
} }
shared_ptr<ScriptType> GetIteratorKeyType() const final{ shared_ptr<ScriptType> GetIteratorKeyType() const final{
return make_shared<StringScriptType>(false, 0); return make_shared<NumericScriptType>(true, false);
} }
}; };
} }

View File

@ -63,7 +63,7 @@ end
TEST_CASE( "Generic for loop over simple numerical table, get keys", "[integration]" ) { TEST_CASE( "Generic for loop over simple numerical table, get keys", "[integration]" ) {
auto script = Script::Create(uR"( auto script = Script::Create(uR"(
local table = {1, 3, 5, 7, 9} local table = {1, 3, 5, 7, 9}
result = "" result = 0
for i in table do for i in table do
result = result + i result = result + i
end end
@ -71,14 +71,14 @@ end
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); script->Evaluate();
auto var = script->GetVariable(u"result"); auto var = script->GetVariable(u"result");
REQUIRE(var->EvaluateString() == u"12345"); REQUIRE(var->EvaluateInteger() == 15);
delete script; delete script;
} }
TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) { TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) {
auto script = Script::Create(uR"( auto script = Script::Create(uR"(
local table = {1, 3, 5, 7, 9} local table = {1, 3, 5, 7, 9}
result = "" result = 0
for i,v in table do for i,v in table do
result = result + v result = result + v
end end
@ -86,7 +86,7 @@ end
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); script->Evaluate();
auto var = script->GetVariable(u"result"); auto var = script->GetVariable(u"result");
REQUIRE(var->EvaluateString() == u"13579"); REQUIRE(var->EvaluateInteger() == 25);
delete script; delete script;
} }