Initial work on iterators, rework of variable handling by including actual string
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
1a84661c79
commit
76b8ba3ebc
|
@ -72,8 +72,8 @@ namespace Porygon::Binder {
|
|||
auto boundExpression = this->BindExpression(s->GetExpression());
|
||||
VariableAssignment assignment =
|
||||
s->IsLocal() ?
|
||||
this->_scope->CreateExplicitLocal(s->GetIdentifier().GetHash(), boundExpression->GetType())
|
||||
: this->_scope->AssignVariable(s->GetIdentifier().GetHash(), boundExpression->GetType());
|
||||
this->_scope->CreateExplicitLocal(s->GetIdentifier(), boundExpression->GetType())
|
||||
: this->_scope->AssignVariable(s->GetIdentifier(), boundExpression->GetType());
|
||||
if (assignment.GetResult() == VariableAssignmentResult::Ok) {
|
||||
auto key = assignment.GetKey();
|
||||
return new BoundAssignmentStatement(key, boundExpression);
|
||||
|
@ -139,7 +139,7 @@ namespace Porygon::Binder {
|
|||
return new BoundBadStatement();
|
||||
}
|
||||
parameterTypes.at(i) = parsedType;
|
||||
auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), parsedType);
|
||||
auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier(), parsedType);
|
||||
if (parameterAssignment.GetResult() == VariableAssignmentResult::Ok) {
|
||||
parameterKeys.at(i) = std::shared_ptr<BoundVariableKey>(parameterAssignment.GetKey());
|
||||
} else {
|
||||
|
@ -153,7 +153,7 @@ namespace Porygon::Binder {
|
|||
auto type = make_shared<FunctionScriptType>(returnType, parameterTypes, parameterKeys, scopeIndex);
|
||||
this->_currentFunction = type;
|
||||
|
||||
auto assignment = this->_scope->AssignVariable(identifier.GetHash(), type);
|
||||
auto assignment = this->_scope->AssignVariable(identifier, type);
|
||||
if (assignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
|
@ -242,7 +242,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
|
||||
this -> _scope ->GoInnerScope();
|
||||
auto variableKey = this -> _scope ->CreateExplicitLocal(identifier.GetHash(), make_shared<NumericScriptType>(true, false));
|
||||
auto variableKey = this -> _scope ->CreateExplicitLocal(identifier, make_shared<NumericScriptType>(true, false));
|
||||
if (variableKey.GetResult() != VariableAssignmentResult::Ok){
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
|
@ -300,15 +300,15 @@ namespace Porygon::Binder {
|
|||
|
||||
BoundExpression *Binder::BindVariableExpression(const VariableExpression *expression) {
|
||||
auto key = expression->GetValue();
|
||||
auto scope = this->_scope->Exists(key.GetHash());
|
||||
auto scope = this->_scope->Exists(key);
|
||||
if (scope == -1) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::VariableNotFound, expression->GetStartPosition(),
|
||||
expression->GetLength());
|
||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
auto var = this->_scope->GetVariable(scope, key.GetHash());
|
||||
auto var = this->_scope->GetVariable(scope, key);
|
||||
auto type = var->GetType();
|
||||
return new BoundVariableExpression(new BoundVariableKey(key.GetHash(), scope, false), type,
|
||||
return new BoundVariableExpression(new BoundVariableKey(key, scope, false), type,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
|
||||
|
@ -616,7 +616,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
|
||||
BoundExpression *Binder::BindTableExpression(const ParsedTableExpression *expression) {
|
||||
auto tableScope = new unordered_map<uint32_t, BoundVariable *>();
|
||||
auto tableScope = new map<Utilities::HashedString, BoundVariable *>();
|
||||
auto innerScope = new BoundScope(tableScope);
|
||||
auto currentScope = this->_scope;
|
||||
this->_scope = innerScope;
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include "BoundScope.hpp"
|
||||
|
||||
namespace Porygon::Binder {
|
||||
BoundScope::BoundScope(unordered_map<uint32_t, BoundVariable *> *tableScope) {
|
||||
BoundScope::BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope) {
|
||||
_tableScope = tableScope;
|
||||
_currentScope = 1;
|
||||
_lastCreatedScope = 1;
|
||||
auto localUpmostScope = new unordered_map<uint32_t, BoundVariable *>();
|
||||
auto localUpmostScope = new map<Utilities::HashedString, BoundVariable *>();
|
||||
_localScope.push_back(localUpmostScope);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace Porygon::Binder {
|
|||
_lastCreatedScope++;
|
||||
_currentScope = _lastCreatedScope;
|
||||
if (_localScope.size() < _currentScope) {
|
||||
auto innerScope = new unordered_map<uint32_t, BoundVariable *>();
|
||||
auto innerScope = new map<Utilities::HashedString, BoundVariable *>();
|
||||
_localScope.push_back(innerScope);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace Porygon::Binder {
|
|||
_currentScope--;
|
||||
}
|
||||
|
||||
int BoundScope::Exists(int key) {
|
||||
int BoundScope::Exists(Utilities::HashedString key) {
|
||||
auto found = this->_tableScope->find(key);
|
||||
if (found != _tableScope->end()) {
|
||||
return 0;
|
||||
|
@ -54,7 +54,7 @@ namespace Porygon::Binder {
|
|||
return -1;
|
||||
}
|
||||
|
||||
BoundVariable *BoundScope::GetVariable(uint32_t scope, uint32_t identifier) {
|
||||
BoundVariable *BoundScope::GetVariable(uint32_t scope, Utilities::HashedString identifier) {
|
||||
if (scope == 0) {
|
||||
auto find = this->_tableScope->find(identifier);
|
||||
if (find != _tableScope->end()) {
|
||||
|
@ -71,7 +71,7 @@ namespace Porygon::Binder {
|
|||
}
|
||||
}
|
||||
|
||||
VariableAssignment BoundScope::CreateExplicitLocal(uint32_t identifier, std::shared_ptr<ScriptType> type) {
|
||||
VariableAssignment BoundScope::CreateExplicitLocal(Utilities::HashedString identifier, std::shared_ptr<ScriptType> type) {
|
||||
auto scope = this->_localScope.at(this->_currentScope - 1);
|
||||
if (scope->find(identifier) != scope->end()) {
|
||||
return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr);
|
||||
|
@ -81,7 +81,7 @@ namespace Porygon::Binder {
|
|||
new BoundVariableKey(identifier, this->_currentScope, true));
|
||||
}
|
||||
|
||||
VariableAssignment BoundScope::AssignVariable(uint32_t identifier, const std::shared_ptr<ScriptType> &type) {
|
||||
VariableAssignment BoundScope::AssignVariable(Utilities::HashedString identifier, const std::shared_ptr<ScriptType> &type) {
|
||||
int exists = this->Exists(identifier);
|
||||
if (exists == -1) {
|
||||
// Creation
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#define PORYGONLANG_BOUNDSCOPE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "BoundVariable.hpp"
|
||||
|
@ -15,12 +15,12 @@ using namespace std;
|
|||
|
||||
namespace Porygon::Binder {
|
||||
class BoundScope {
|
||||
unordered_map<uint32_t, BoundVariable *> *_tableScope;
|
||||
vector<unordered_map<uint32_t, BoundVariable *> *> _localScope;
|
||||
map<Utilities::HashedString, BoundVariable *> *_tableScope;
|
||||
vector<map<Utilities::HashedString, BoundVariable *> *> _localScope;
|
||||
int _currentScope;
|
||||
int _lastCreatedScope;
|
||||
public:
|
||||
explicit BoundScope(unordered_map<uint32_t, BoundVariable *> *tableScope);
|
||||
explicit BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope);
|
||||
|
||||
~BoundScope();
|
||||
|
||||
|
@ -28,13 +28,13 @@ namespace Porygon::Binder {
|
|||
|
||||
void GoOuterScope();
|
||||
|
||||
int Exists(int key);
|
||||
int Exists(Utilities::HashedString key);
|
||||
|
||||
BoundVariable *GetVariable(uint32_t scope, uint32_t identifier);
|
||||
BoundVariable *GetVariable(uint32_t scope, Utilities::HashedString identifier);
|
||||
|
||||
VariableAssignment CreateExplicitLocal(uint32_t identifier, std::shared_ptr<ScriptType> type);
|
||||
VariableAssignment CreateExplicitLocal(Utilities::HashedString identifier, std::shared_ptr<ScriptType> type);
|
||||
|
||||
VariableAssignment AssignVariable(uint32_t identifier, const std::shared_ptr<ScriptType> &type);
|
||||
VariableAssignment AssignVariable(Utilities::HashedString identifier, const std::shared_ptr<ScriptType> &type);
|
||||
|
||||
size_t GetLocalVariableCount() {
|
||||
return _localScope.size();
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#define PORYGONLANG_BOUNDVARIABLEKEY_HPP
|
||||
|
||||
#include <string>
|
||||
#include "../../Utilities/HashedString.hpp"
|
||||
|
||||
namespace Porygon::Binder {
|
||||
class BoundVariableKey {
|
||||
const int _identifier;
|
||||
const Utilities::HashedString _identifier;
|
||||
const unsigned int _scopeId;
|
||||
const bool _isCreation;
|
||||
const uint64_t _hash;
|
||||
|
@ -18,14 +19,14 @@ namespace Porygon::Binder {
|
|||
}
|
||||
|
||||
public:
|
||||
BoundVariableKey(int id, unsigned int scope, bool creation)
|
||||
BoundVariableKey(Utilities::HashedString id, unsigned int scope, bool creation)
|
||||
: _identifier(id),
|
||||
_scopeId(scope),
|
||||
_isCreation(creation),
|
||||
_hash(KnuthsHash(id, scope)) {}
|
||||
_hash(KnuthsHash(id.GetHash(), scope)) {}
|
||||
|
||||
|
||||
const int GetIdentifier() const {
|
||||
const Utilities::HashedString GetIdentifier() const {
|
||||
return _identifier;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,9 +83,9 @@ namespace Porygon::Evaluation {
|
|||
throw;
|
||||
std::basic_ostringstream<char16_t> stringStream;
|
||||
auto left = this->EvaluateStringExpression(expression->GetLeft());
|
||||
stringStream << *left->EvaluateString();
|
||||
stringStream << left->EvaluateString();
|
||||
auto right = this->EvaluateExpression(expression->GetRight());
|
||||
stringStream << *right->EvaluateString();
|
||||
stringStream << right->EvaluateString();
|
||||
return make_shared<StringEvalValue>(stringStream.str());
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ namespace Porygon::Evaluation {
|
|||
}
|
||||
|
||||
const char16_t *EvaluateEvalValueString(EvalValue *v) {
|
||||
return v->EvaluateString()->c_str();
|
||||
return (new u16string(v->EvaluateString()))->c_str();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Porygon::Evaluation {
|
|||
throw EvaluationException("Can't evaluate this EvalValue as bool.");
|
||||
}
|
||||
|
||||
virtual const std::u16string *EvaluateString() const {
|
||||
virtual const std::u16string EvaluateString() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as string.");
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include <sstream>
|
||||
#include "EvalValue.hpp"
|
||||
#include "../../Utilities/StringUtils.hpp"
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class NumericEvalValue : public EvalValue {
|
||||
|
||||
|
@ -58,6 +60,10 @@ namespace Porygon::Evaluation {
|
|||
return _value;
|
||||
}
|
||||
|
||||
const std::u16string EvaluateString() const final{
|
||||
return Utilities::StringUtils::IntToString(_value);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return make_shared<IntegerEvalValue>(_value);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ namespace Porygon::Evaluation {
|
|||
return this->_hash == b->GetHashCode();
|
||||
};
|
||||
|
||||
const u16string *EvaluateString() const final {
|
||||
return &_value;
|
||||
const u16string EvaluateString() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#ifndef PORYGONLANG_TABLEEVALVALUE_HPP
|
||||
#define PORYGONLANG_TABLEEVALVALUE_HPP
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "EvalValue.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class TableEvalValue : public EvalValue {
|
||||
shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> _table;
|
||||
shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> _table;
|
||||
size_t _hash;
|
||||
|
||||
explicit TableEvalValue(shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> table, size_t 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<unordered_map<uint32_t, shared_ptr<EvalValue>>> table) {
|
||||
explicit TableEvalValue(shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>> table) {
|
||||
_table = std::move(table);
|
||||
_hash = rand();
|
||||
}
|
||||
|
@ -39,23 +39,30 @@ namespace Porygon::Evaluation {
|
|||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
|
||||
auto hash = val->GetHashCode();
|
||||
return this->_table->at(hash);
|
||||
const auto stringKey = val->EvaluateString();
|
||||
return this->_table->at(Utilities::HashedString(stringKey));
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final {
|
||||
return this->_table->at(hash);
|
||||
return this->_table->at(Utilities::HashedString(hash));
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(const char *val) const {
|
||||
auto hash = Utilities::HashedString::ConstHash(val);
|
||||
return this->_table->at(hash);
|
||||
return this->_table->at(Utilities::HashedString(hash));
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const final {
|
||||
auto hash = key->GetHashCode();
|
||||
this->_table->at(hash) = value;
|
||||
this->_table->at(Utilities::HashedString(hash)) = value;
|
||||
}
|
||||
|
||||
const _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> GetTableIterator() const{
|
||||
return _table->cbegin();
|
||||
};
|
||||
const _Rb_tree_const_iterator<pair<const Utilities::HashedString, shared_ptr<EvalValue>>> GetTableIteratorEnd() const{
|
||||
return _table->cend();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
#include <memory>
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
EvaluationScope::EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>> *scriptVariables,
|
||||
EvaluationScope::EvaluationScope(map<Utilities::HashedString, shared_ptr<EvalValue>> *scriptVariables,
|
||||
int localVariableCount) {
|
||||
_scriptScope = scriptVariables;
|
||||
_localScope = unordered_map<uint64_t, shared_ptr<EvalValue>>(localVariableCount);
|
||||
_localScope = map<uint64_t, shared_ptr<EvalValue>>();
|
||||
}
|
||||
|
||||
void EvaluationScope::CreateVariable(const BoundVariableKey *key, const shared_ptr<EvalValue> &value) {
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
#ifndef PORYGONLANG_EVALUATIONSCOPE_HPP
|
||||
#define PORYGONLANG_EVALUATIONSCOPE_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "../EvalValues/EvalValue.hpp"
|
||||
using namespace Porygon::Binder;
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class EvaluationScope {
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>> *_scriptScope;
|
||||
unordered_map<uint64_t, shared_ptr<EvalValue>> _localScope;
|
||||
map<Utilities::HashedString, shared_ptr<EvalValue>> *_scriptScope;
|
||||
map<uint64_t, shared_ptr<EvalValue>> _localScope;
|
||||
public:
|
||||
explicit EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>> *scriptVariables, int deepestScope);
|
||||
explicit EvaluationScope(map<Utilities::HashedString, shared_ptr<EvalValue>> *scriptVariables, int deepestScope);
|
||||
|
||||
~EvaluationScope() = default;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../Binder/BoundExpressions/BoundTableExpression.hpp"
|
||||
#include "../TableScriptType.hpp"
|
||||
#include "../UserData/UserDataFunction.hpp"
|
||||
#include "../Utilities/StringUtils.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Binder;
|
||||
|
@ -388,12 +389,13 @@ namespace Porygon::Evaluation {
|
|||
const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundNumericalTableExpression *) expression;
|
||||
auto valueExpressions = tableExpression->GetExpressions();
|
||||
auto values = new unordered_map<uint32_t, shared_ptr<EvalValue>>(valueExpressions->size());
|
||||
auto values = new map<Utilities::HashedString, shared_ptr<EvalValue>>();
|
||||
for (int i = 0; i < valueExpressions->size(); i++) {
|
||||
auto val = this->EvaluateExpression(valueExpressions->at(i));
|
||||
values->insert({i + 1, val});
|
||||
auto key = Utilities::StringUtils::IntToString(i + 1);
|
||||
values->insert({Utilities::HashedString(key), val});
|
||||
}
|
||||
auto valuesPointer = shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>>(values);
|
||||
auto valuesPointer = shared_ptr<map<Utilities::HashedString, shared_ptr<EvalValue>>>(values);
|
||||
return make_shared<TableEvalValue>(valuesPointer);
|
||||
}
|
||||
|
||||
|
@ -401,7 +403,7 @@ namespace Porygon::Evaluation {
|
|||
auto tableExpression = (BoundTableExpression *) expression;
|
||||
auto type = dynamic_pointer_cast<TableScriptType>(tableExpression->GetType());
|
||||
auto declaredVars = type->GetValues();
|
||||
auto variables = make_shared<unordered_map<uint32_t, shared_ptr<EvalValue>>>(declaredVars->size());
|
||||
auto variables = make_shared<map<Utilities::HashedString, shared_ptr<EvalValue>>>();
|
||||
for (auto i : *declaredVars) {
|
||||
variables->insert({i.first, nullptr});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ using namespace std;
|
|||
namespace Porygon::Evaluation{
|
||||
class Evaluator {
|
||||
shared_ptr<EvalValue> _returnValue;
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>>* _scriptVariables;
|
||||
map<Utilities::HashedString, shared_ptr<EvalValue>>* _scriptVariables;
|
||||
bool _hasReturned;
|
||||
shared_ptr<EvalValue> _lastValue;
|
||||
|
||||
|
@ -56,7 +56,7 @@ namespace Porygon::Evaluation{
|
|||
|
||||
const shared_ptr<EvalValue> GetVariable(const BoundVariableExpression *expression);
|
||||
public:
|
||||
explicit Evaluator(unordered_map<uint32_t, shared_ptr<EvalValue>>* scriptVariables){
|
||||
explicit Evaluator(map<Utilities::HashedString, shared_ptr<EvalValue>>* scriptVariables){
|
||||
_scriptVariables = scriptVariables;
|
||||
_hasReturned = false;
|
||||
_returnValue = nullptr;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#include "Iterator.hpp"
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
#ifndef PORYGONLANG_ITERATOR_HPP
|
||||
#define PORYGONLANG_ITERATOR_HPP
|
||||
|
||||
#include <memory>
|
||||
#include "../EvalValues/EvalValue.hpp"
|
||||
#include "../EvalValues/TableEvalValue.hpp"
|
||||
#include "../EvalValues/StringEvalValue.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Porygon::Evaluation{
|
||||
class Iterator {
|
||||
public:
|
||||
virtual shared_ptr<EvalValue> GetCurrent() = 0;
|
||||
virtual bool MoveNext() = 0;
|
||||
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");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PORYGONLANG_ITERATOR_HPP
|
|
@ -25,7 +25,8 @@ Porygon::Script *Porygon::Script::Create(const string &script) {
|
|||
Porygon::Script::Script(const u16string& s) {
|
||||
Diagnostics = new Diagnostics::DiagnosticsHolder(s);
|
||||
_boundScript = nullptr;
|
||||
_scriptVariables = new unordered_map<uint32_t, shared_ptr<EvalValue>>(0);
|
||||
|
||||
_scriptVariables = new map<Utilities::HashedString, shared_ptr<EvalValue>>();
|
||||
_evaluator = new Evaluator(this -> _scriptVariables);
|
||||
|
||||
this -> Parse(s);
|
||||
|
@ -53,7 +54,7 @@ void Porygon::Script::Parse(const u16string& script) {
|
|||
}
|
||||
lexResult.clear();
|
||||
if (!Diagnostics->HasErrors()){
|
||||
unordered_map<uint32_t, BoundVariable*> scriptScope;
|
||||
map<Utilities::HashedString, BoundVariable*> scriptScope;
|
||||
auto bindScope = new BoundScope(&scriptScope);
|
||||
this->_boundScript = Binder::Binder::Bind(this, parseResult, bindScope);
|
||||
for (const auto& v : scriptScope){
|
||||
|
@ -66,11 +67,11 @@ void Porygon::Script::Parse(const u16string& script) {
|
|||
}
|
||||
|
||||
EvalValue *Porygon::Script::GetVariable(const u16string &key) {
|
||||
return _scriptVariables -> at(HashedString(key).GetHash()).get();
|
||||
return _scriptVariables -> at(HashedString(key)).get();
|
||||
}
|
||||
|
||||
bool Porygon::Script::HasVariable(const u16string &key) {
|
||||
auto f = _scriptVariables->find(HashedString(key).GetHash());
|
||||
auto f = _scriptVariables->find(HashedString(key));
|
||||
return f != _scriptVariables->end();
|
||||
}
|
||||
|
||||
|
@ -79,7 +80,7 @@ EvalValue *Porygon::Script::GetLastValue() {
|
|||
}
|
||||
|
||||
bool Porygon::Script::HasFunction(const u16string &key) {
|
||||
auto f = _scriptVariables->find(HashedString(key).GetHash());
|
||||
auto f = _scriptVariables->find(HashedString(key));
|
||||
return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "Diagnostics/DiagnosticsHolder.hpp"
|
||||
#include "Binder/BoundStatements/BoundStatement.hpp"
|
||||
#include "Evaluator/Evaluator.hpp"
|
||||
|
@ -18,7 +18,7 @@ using namespace Porygon::Evaluation;
|
|||
namespace Porygon{
|
||||
class Script {
|
||||
Evaluator* _evaluator;
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>>* _scriptVariables;
|
||||
map<Utilities::HashedString, shared_ptr<EvalValue>>* _scriptVariables;
|
||||
Binder::BoundScriptStatement* _boundScript;
|
||||
shared_ptr<ScriptType> _returnType;
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
namespace Porygon{
|
||||
class TableScriptType : public ScriptType{
|
||||
const unordered_map<uint32_t, BoundVariable*>* _values;
|
||||
const map<Utilities::HashedString, BoundVariable*>* _values;
|
||||
const int _localVariableCount;
|
||||
public:
|
||||
explicit TableScriptType(unordered_map<uint32_t, BoundVariable*>* values, int localVariableCount)
|
||||
explicit TableScriptType(map<Utilities::HashedString, BoundVariable*>* values, int localVariableCount)
|
||||
: ScriptType(TypeClass::Table),
|
||||
_values(values),
|
||||
_localVariableCount(localVariableCount)
|
||||
|
@ -33,16 +33,16 @@ namespace Porygon{
|
|||
const shared_ptr<ScriptType> GetIndexedType(ScriptType* indexer) const final{
|
||||
auto stringKey = (StringScriptType*)indexer;
|
||||
if (stringKey->IsKnownAtBind()){
|
||||
return _values-> at(stringKey->GetHashValue())->GetType();
|
||||
return _values-> at(Utilities::HashedString(stringKey->GetHashValue()))->GetType();
|
||||
}
|
||||
throw "TODO: indexing with dynamic keys";
|
||||
}
|
||||
|
||||
const shared_ptr<ScriptType> GetIndexedType(uint32_t hash) const final{
|
||||
return _values-> at(hash)->GetType();
|
||||
return _values-> at(Utilities::HashedString(hash))->GetType();
|
||||
}
|
||||
|
||||
const unordered_map<uint32_t, BoundVariable*>* GetValues() const{
|
||||
const map<Utilities::HashedString, BoundVariable*>* GetValues() const{
|
||||
return _values;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,28 @@
|
|||
namespace Porygon::Utilities{
|
||||
class HashedString{
|
||||
const uint32_t _hash;
|
||||
const std::u16string _string;
|
||||
public:
|
||||
explicit HashedString(const std::u16string& s) : _hash(ConstHash(s.c_str())){
|
||||
explicit HashedString(const std::u16string& s)
|
||||
: _hash(ConstHash(s.c_str())),
|
||||
_string(s)
|
||||
{
|
||||
}
|
||||
explicit HashedString(char16_t const *input) : _hash(ConstHash(input)){
|
||||
explicit HashedString(char16_t const *input)
|
||||
: _hash(ConstHash(input)),
|
||||
_string(std::u16string(input))
|
||||
{
|
||||
}
|
||||
|
||||
explicit HashedString(char const *input) : _hash(ConstHash(input)){
|
||||
}
|
||||
|
||||
HashedString(const HashedString& b) = default;
|
||||
explicit HashedString(uint32_t hash) : _hash(hash){
|
||||
}
|
||||
|
||||
HashedString(const HashedString& b) :_hash(b._hash), _string(b._string){
|
||||
|
||||
};
|
||||
|
||||
static uint32_t constexpr ConstHash(char16_t const *input) {
|
||||
return *input ?
|
||||
|
@ -34,12 +46,24 @@ namespace Porygon::Utilities{
|
|||
return _hash;
|
||||
}
|
||||
|
||||
const std::u16string* GetString() const{
|
||||
return &_string;
|
||||
}
|
||||
|
||||
bool operator==(const HashedString& b) const{
|
||||
return _hash == b._hash;
|
||||
}
|
||||
bool operator!=(const HashedString& b) const{
|
||||
return _hash != b._hash;
|
||||
}
|
||||
bool operator<(const HashedString& b) const{
|
||||
return _hash < b._hash;
|
||||
}
|
||||
bool operator>(const HashedString& b) const{
|
||||
return _hash > b._hash;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef PORYGONLANG_STRINGUTILS_HPP
|
||||
#define PORYGONLANG_STRINGUTILS_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <sstream>
|
||||
|
||||
namespace Porygon::Utilities{
|
||||
class StringUtils{
|
||||
public:
|
||||
static std::u16string IntToString(long const &i) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> conv;
|
||||
return conv.from_bytes(std::to_string(i));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_STRINGUTILS_HPP
|
|
@ -8,7 +8,7 @@ TEST_CASE( "String indexing", "[integration]" ) {
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(*lastValue->EvaluateString() == u"b");
|
||||
REQUIRE(lastValue->EvaluateString() == u"b");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ return foo.bar
|
|||
)");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto result = script->Evaluate();
|
||||
REQUIRE(*result->EvaluateString() == u"test");
|
||||
REQUIRE(result->EvaluateString() == u"test");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ TEST_CASE( "Simple String", "[integration]" ) {
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(*lastValue->EvaluateString() == u"foo bar");
|
||||
REQUIRE(lastValue->EvaluateString() == u"foo bar");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ TEST_CASE( "String Concat", "[integration]" ) {
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(*lastValue->EvaluateString() == u"foobar");
|
||||
REQUIRE(lastValue->EvaluateString() == u"foobar");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ TEST_CASE( "String Concat 2", "[integration]" ) {
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(*lastValue->EvaluateString() == u"foobar");
|
||||
REQUIRE(lastValue->EvaluateString() == u"foobar");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ return table[3]
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto variable = script->Evaluate();
|
||||
REQUIRE(variable != nullptr);
|
||||
REQUIRE(*variable->EvaluateString() == u"foo");
|
||||
REQUIRE(variable->EvaluateString() == u"foo");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ table = {
|
|||
auto variable = script->GetVariable(u"table");
|
||||
REQUIRE(variable != nullptr);
|
||||
auto table = (TableEvalValue*)variable;
|
||||
CHECK(*table->IndexValue("foo")->EvaluateString() == u"test");
|
||||
CHECK(table->IndexValue("foo")->EvaluateString() == u"test");
|
||||
CHECK(table->IndexValue("bar")->EvaluateInteger() == 100);
|
||||
delete script;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ TEST_CASE( "Able to use emoji", "[integration]" ) {
|
|||
REQUIRE(script -> HasVariable(uR"(💩)"));
|
||||
auto variable = script->GetVariable(uR"(💩)");
|
||||
REQUIRE(variable != nullptr);
|
||||
CHECK(*variable->EvaluateString() == u"LJ");
|
||||
CHECK(variable->EvaluateString() == u"LJ");
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue