Support for length unary operator
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
bd9eac9056
commit
73142afa8a
|
@ -599,8 +599,15 @@ namespace Porygon::Binder {
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
case UnaryOperatorKind::Count:
|
||||||
|
if (operandType->IsCountable()){
|
||||||
|
return new BoundUnaryExpression(operand, BoundUnaryOperation::Count,
|
||||||
|
NumericScriptType::AwareInt,
|
||||||
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception("Unknown unary operator was called.");
|
||||||
}
|
}
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoUnaryOperationFound,
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoUnaryOperationFound,
|
||||||
expression->GetStartPosition(),
|
expression->GetStartPosition(),
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Porygon::Binder {
|
||||||
|
|
||||||
enum class BoundUnaryOperation {
|
enum class BoundUnaryOperation {
|
||||||
Negation,
|
Negation,
|
||||||
|
Count,
|
||||||
LogicalNegation,
|
LogicalNegation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "NumericalTableEvalValue.hpp"
|
#include "NumericalTableEvalValue.hpp"
|
||||||
#include "../Iterator/NumericalKeyIterator.hpp"
|
#include "../Iterator/NumericalKeyIterator.hpp"
|
||||||
|
#include "../../Utilities/Random.hpp"
|
||||||
|
|
||||||
inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const {
|
inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const {
|
||||||
return new NumericalKeyIterator(this);
|
return new NumericalKeyIterator(this);
|
||||||
|
@ -7,6 +8,14 @@ inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalVal
|
||||||
|
|
||||||
Porygon::Evaluation::NumericalTableEvalValue::NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table) :
|
Porygon::Evaluation::NumericalTableEvalValue::NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table) :
|
||||||
_table(std::move(table)),
|
_table(std::move(table)),
|
||||||
_hash(rand())
|
_hash(Utilities::Random::Get())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Porygon::Evaluation::EvalValue *
|
||||||
|
Porygon::Evaluation::NumericalTableEvalValue::UnaryOperation(Porygon::Binder::BoundUnaryOperation operation) const {
|
||||||
|
if (operation == Porygon::Binder::BoundUnaryOperation::Count){
|
||||||
|
return new NumericEvalValue(static_cast<int64_t>(this->_table->size()));
|
||||||
|
}
|
||||||
|
return EvalValue::UnaryOperation(operation);
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,9 @@ namespace Porygon::Evaluation {
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline shared_ptr<vector<EvalValuePointer>> GetTable() const{
|
inline shared_ptr<vector<EvalValuePointer>> GetTable() const{
|
||||||
return _table;
|
return _table;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override;;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "EvalValue.hpp"
|
#include "EvalValue.hpp"
|
||||||
|
#include "NumericEvalValue.hpp"
|
||||||
#include "../../Utilities/HashedString.hpp"
|
#include "../../Utilities/HashedString.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -68,6 +69,13 @@ namespace Porygon::Evaluation {
|
||||||
auto str = stringStream.str();
|
auto str = stringStream.str();
|
||||||
return new StringEvalValue(str);
|
return new StringEvalValue(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override {
|
||||||
|
if (operation == Binder::BoundUnaryOperation ::Count){
|
||||||
|
return new NumericEvalValue(static_cast<int64_t >(_value->size()));
|
||||||
|
}
|
||||||
|
return EvalValue::UnaryOperation(operation);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
#include "TableEvalValue.hpp"
|
#include "TableEvalValue.hpp"
|
||||||
#include "../Iterator/SimpleKeyIterator.hpp"
|
#include "../Iterator/SimpleKeyIterator.hpp"
|
||||||
|
#include "NumericEvalValue.hpp"
|
||||||
|
|
||||||
inline Porygon::Evaluation::Iterator * Porygon::Evaluation::TableEvalValue::GetKeyIterator() const {
|
inline Porygon::Evaluation::Iterator * Porygon::Evaluation::TableEvalValue::GetKeyIterator() const {
|
||||||
return new TableKeyIterator(this);
|
return new TableKeyIterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Porygon::Evaluation::EvalValue *
|
||||||
|
Porygon::Evaluation::TableEvalValue::UnaryOperation(Porygon::Binder::BoundUnaryOperation operation) const {
|
||||||
|
if (operation == Porygon::Binder::BoundUnaryOperation::Count){
|
||||||
|
return new NumericEvalValue(static_cast<int64_t>(this->_table->size()));
|
||||||
|
}
|
||||||
|
return EvalValue::UnaryOperation(operation);
|
||||||
|
}
|
||||||
|
|
|
@ -83,7 +83,9 @@ namespace Porygon::Evaluation {
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> GetTableIteratorEnd() const{
|
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> GetTableIteratorEnd() const{
|
||||||
return _table->cend();
|
return _table->cend();
|
||||||
};
|
}
|
||||||
|
|
||||||
|
EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override;;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@ namespace Porygon::Parser {
|
||||||
}
|
}
|
||||||
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedCharacter, this->_position - 1, 1);
|
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedCharacter, this->_position - 1, 1);
|
||||||
return new SimpleToken(TokenKind::BadToken, this->_position - 1, 1);
|
return new SimpleToken(TokenKind::BadToken, this->_position - 1, 1);
|
||||||
|
case '#':
|
||||||
|
return new SimpleToken(TokenKind::HashToken, this->_position - 1, 1);
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
|
|
|
@ -362,6 +362,7 @@ namespace Porygon::Parser {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case TokenKind::PlusToken:
|
case TokenKind::PlusToken:
|
||||||
case TokenKind::MinusToken:
|
case TokenKind::MinusToken:
|
||||||
|
case TokenKind::HashToken:
|
||||||
case TokenKind::NotKeyword:
|
case TokenKind::NotKeyword:
|
||||||
return OperatorPrecedence::Unary;
|
return OperatorPrecedence::Unary;
|
||||||
default:
|
default:
|
||||||
|
@ -375,6 +376,8 @@ namespace Porygon::Parser {
|
||||||
return UnaryOperatorKind::Identity;
|
return UnaryOperatorKind::Identity;
|
||||||
case TokenKind::MinusToken:
|
case TokenKind::MinusToken:
|
||||||
return UnaryOperatorKind::Negation;
|
return UnaryOperatorKind::Negation;
|
||||||
|
case TokenKind::HashToken :
|
||||||
|
return UnaryOperatorKind::Count;
|
||||||
case TokenKind::NotKeyword:
|
case TokenKind::NotKeyword:
|
||||||
return UnaryOperatorKind::LogicalNegation;
|
return UnaryOperatorKind::LogicalNegation;
|
||||||
default: // This should never trigger, so throw.
|
default: // This should never trigger, so throw.
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Porygon::Parser {
|
||||||
LessEquals,
|
LessEquals,
|
||||||
Greater,
|
Greater,
|
||||||
GreaterEquals,
|
GreaterEquals,
|
||||||
|
HashToken,
|
||||||
|
|
||||||
OpenParenthesis,
|
OpenParenthesis,
|
||||||
CloseParenthesis,
|
CloseParenthesis,
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Porygon::Parser {
|
||||||
enum class UnaryOperatorKind {
|
enum class UnaryOperatorKind {
|
||||||
Identity,
|
Identity,
|
||||||
Negation,
|
Negation,
|
||||||
|
Count,
|
||||||
LogicalNegation,
|
LogicalNegation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "../Script.hpp"
|
#include "../Script.hpp"
|
||||||
#include "../UserData/UserDataFunctionType.hpp"
|
#include "../UserData/UserDataFunctionType.hpp"
|
||||||
|
#include "ScriptType.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Porygon{
|
namespace Porygon{
|
||||||
inline bool ScriptType::CanBeIndexedWith(const ScriptType *) const{
|
inline bool ScriptType::CanBeIndexedWith(const ScriptType *) const{
|
||||||
|
@ -76,6 +78,14 @@ namespace Porygon{
|
||||||
return ToString(this->_class);
|
return ToString(this->_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptType::IsCountable() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringScriptType::IsCountable() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"{
|
extern "C"{
|
||||||
ScriptType* CreateScriptType(Porygon::TypeClass t){
|
ScriptType* CreateScriptType(Porygon::TypeClass t){
|
||||||
return new ScriptType(t);
|
return new ScriptType(t);
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace Porygon{
|
||||||
|
|
||||||
[[nodiscard]] virtual CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const;
|
[[nodiscard]] virtual CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual bool IsCountable() const;
|
||||||
|
|
||||||
static std::string ToString(TypeClass c);
|
static std::string ToString(TypeClass c);
|
||||||
[[nodiscard]] virtual std::string ToString() const;
|
[[nodiscard]] virtual std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
@ -145,6 +147,8 @@ namespace Porygon{
|
||||||
inline uint32_t GetHashValue() const{
|
inline uint32_t GetHashValue() const{
|
||||||
return _hashValue;
|
return _hashValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsCountable() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NumericalTableScriptType : public ScriptType{
|
class NumericalTableScriptType : public ScriptType{
|
||||||
|
|
|
@ -65,6 +65,10 @@ namespace Porygon{
|
||||||
shared_ptr<const ScriptType> GetIteratorKeyType() const final {
|
shared_ptr<const ScriptType> GetIteratorKeyType() const final {
|
||||||
return make_shared<ScriptType>(TypeClass::Any);
|
return make_shared<ScriptType>(TypeClass::Any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsCountable() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ namespace Porygon::UserData {
|
||||||
_iterable(iterable)
|
_iterable(iterable)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static shared_ptr<UserDataCollectionType> CreateIndexable(const shared_ptr<const ScriptType>& keyType, const shared_ptr<const ScriptType>& valueType){
|
static shared_ptr<UserDataCollectionType> CreateIndexable(const shared_ptr<const ScriptType>& keyType,
|
||||||
|
const shared_ptr<const ScriptType>& valueType){
|
||||||
return make_shared<UserDataCollectionType>(keyType, valueType, true, true);
|
return make_shared<UserDataCollectionType>(keyType, valueType, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +66,10 @@ namespace Porygon::UserData {
|
||||||
return _valueType;
|
return _valueType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsCountable() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@ UserDataCollectionType* CreateCollectionType(const ScriptType* keyType, const Sc
|
||||||
UserDataCollectionValue* CreateCollectionValue(UserDataCollectionType* type, void* obj,
|
UserDataCollectionValue* CreateCollectionValue(UserDataCollectionType* type, void* obj,
|
||||||
const EvalValue* (*get)(void*, const EvalValue*),
|
const EvalValue* (*get)(void*, const EvalValue*),
|
||||||
void (*set)(void*, const EvalValue*, const EvalValue*),
|
void (*set)(void*, const EvalValue*, const EvalValue*),
|
||||||
Iterator* (*getIterator)(void*)){
|
Iterator* (*getIterator)(void*), size_t (getSize)(void*)){
|
||||||
return new UserDataCollectionValue(shared_ptr<UserDataCollectionType>(type), new UserDataCollectionHelper(obj, get, set, getIterator));
|
return new UserDataCollectionValue(shared_ptr<UserDataCollectionType>(type),
|
||||||
|
new UserDataCollectionHelper(obj, get, set, getIterator, getSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "UserDataCollectionType.hpp"
|
#include "UserDataCollectionType.hpp"
|
||||||
#include "../../Evaluator/EvalValues/EvalValue.hpp"
|
#include "../../Evaluator/EvalValues/EvalValue.hpp"
|
||||||
#include "../../Utilities/Random.hpp"
|
#include "../../Utilities/Random.hpp"
|
||||||
|
#include "../../Evaluator/EvalValues/NumericEvalValue.hpp"
|
||||||
|
|
||||||
using namespace Porygon::Evaluation;
|
using namespace Porygon::Evaluation;
|
||||||
|
|
||||||
|
@ -15,12 +16,14 @@ namespace Porygon::UserData {
|
||||||
const EvalValue* (*_get)(void*, const EvalValue*);
|
const EvalValue* (*_get)(void*, const EvalValue*);
|
||||||
void (*_set)(void*, const EvalValue* , const EvalValue*);
|
void (*_set)(void*, const EvalValue* , const EvalValue*);
|
||||||
Iterator* (*_getIterator)(void*);
|
Iterator* (*_getIterator)(void*);
|
||||||
|
size_t (*_getLength)(void*);
|
||||||
public:
|
public:
|
||||||
UserDataCollectionHelper(void* parentObject,
|
UserDataCollectionHelper(void* parentObject,
|
||||||
const EvalValue* (*get)(void*, const EvalValue*),
|
const EvalValue* (*get)(void*, const EvalValue*),
|
||||||
void (*set)(void*, const EvalValue*, const EvalValue*),
|
void (*set)(void*, const EvalValue*, const EvalValue*),
|
||||||
Iterator* (*getIterator)(void*))
|
Iterator* (*getIterator)(void*), size_t (*getLength)(void*))
|
||||||
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator){}
|
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator),
|
||||||
|
_getLength(getLength){}
|
||||||
|
|
||||||
const EvalValue* Get(const EvalValue* key) const{
|
const EvalValue* Get(const EvalValue* key) const{
|
||||||
return _get(_parentObject, key);
|
return _get(_parentObject, key);
|
||||||
|
@ -33,6 +36,10 @@ namespace Porygon::UserData {
|
||||||
[[nodiscard]] Iterator* GetIterator() const{
|
[[nodiscard]] Iterator* GetIterator() const{
|
||||||
return _getIterator(_parentObject);
|
return _getIterator(_parentObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t GetLength() const{
|
||||||
|
return _getLength(_parentObject);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class UserDataCollectionValue : public Evaluation::EvalValue{
|
class UserDataCollectionValue : public Evaluation::EvalValue{
|
||||||
|
@ -46,7 +53,7 @@ namespace Porygon::UserData {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UserDataCollectionValue(shared_ptr<const ScriptType> type, const UserDataCollectionHelper* helper)
|
UserDataCollectionValue(const shared_ptr<const ScriptType>& type, const UserDataCollectionHelper* helper)
|
||||||
: _type(dynamic_pointer_cast<const UserDataCollectionType>(type)), _helper(helper), _hash(Utilities::Random::Get())
|
: _type(dynamic_pointer_cast<const UserDataCollectionType>(type)), _helper(helper), _hash(Utilities::Random::Get())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -85,6 +92,13 @@ namespace Porygon::UserData {
|
||||||
_helper->Set(key, value);
|
_helper->Set(key, value);
|
||||||
delete value;
|
delete value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override {
|
||||||
|
if (operation == Binder::BoundUnaryOperation::Count){
|
||||||
|
return new NumericEvalValue(static_cast<int64_t>(_helper->GetLength()));
|
||||||
|
}
|
||||||
|
return EvalValue::UnaryOperation(operation);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,8 @@ Porygon::Utilities::HashedString* Convert(const char* k){
|
||||||
auto val = ((T_USERDATA*)obj)->fieldName; \
|
auto val = ((T_USERDATA*)obj)->fieldName; \
|
||||||
auto size = val.size(); \
|
auto size = val.size(); \
|
||||||
return new Porygon::UserData::UserDataCollectionRangeIterator(0, size); \
|
return new Porygon::UserData::UserDataCollectionRangeIterator(0, size); \
|
||||||
|
}, [](void* obj) -> size_t{ \
|
||||||
|
return ((T_USERDATA*)obj)->fieldName.size(); \
|
||||||
} \
|
} \
|
||||||
) \
|
) \
|
||||||
) \
|
) \
|
||||||
|
|
Loading…
Reference in New Issue