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());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case UnaryOperatorKind::Count:
|
||||
if (operandType->IsCountable()){
|
||||
return new BoundUnaryExpression(operand, BoundUnaryOperation::Count,
|
||||
NumericScriptType::AwareInt,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Exception("Unknown unary operator was called.");
|
||||
}
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoUnaryOperationFound,
|
||||
expression->GetStartPosition(),
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Porygon::Binder {
|
|||
|
||||
enum class BoundUnaryOperation {
|
||||
Negation,
|
||||
Count,
|
||||
LogicalNegation,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "NumericalTableEvalValue.hpp"
|
||||
#include "../Iterator/NumericalKeyIterator.hpp"
|
||||
#include "../../Utilities/Random.hpp"
|
||||
|
||||
inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalValue::GetKeyIterator() const {
|
||||
return new NumericalKeyIterator(this);
|
||||
|
@ -7,6 +8,14 @@ inline Porygon::Evaluation::Iterator *Porygon::Evaluation::NumericalTableEvalVal
|
|||
|
||||
Porygon::Evaluation::NumericalTableEvalValue::NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> 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]]
|
||||
inline shared_ptr<vector<EvalValuePointer>> GetTable() const{
|
||||
return _table;
|
||||
};
|
||||
}
|
||||
|
||||
EvalValue *UnaryOperation(Binder::BoundUnaryOperation operation) const override;;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string>
|
||||
#include "EvalValue.hpp"
|
||||
#include "NumericEvalValue.hpp"
|
||||
#include "../../Utilities/HashedString.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
@ -68,6 +69,13 @@ namespace Porygon::Evaluation {
|
|||
auto str = stringStream.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 "../Iterator/SimpleKeyIterator.hpp"
|
||||
#include "NumericEvalValue.hpp"
|
||||
|
||||
inline Porygon::Evaluation::Iterator * Porygon::Evaluation::TableEvalValue::GetKeyIterator() const {
|
||||
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]]
|
||||
inline _Rb_tree_const_iterator<pair<const Utilities::HashedString, EvalValuePointer>> GetTableIteratorEnd() const{
|
||||
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);
|
||||
return new SimpleToken(TokenKind::BadToken, this->_position - 1, 1);
|
||||
case '#':
|
||||
return new SimpleToken(TokenKind::HashToken, this->_position - 1, 1);
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
|
|
|
@ -362,6 +362,7 @@ namespace Porygon::Parser {
|
|||
switch (kind) {
|
||||
case TokenKind::PlusToken:
|
||||
case TokenKind::MinusToken:
|
||||
case TokenKind::HashToken:
|
||||
case TokenKind::NotKeyword:
|
||||
return OperatorPrecedence::Unary;
|
||||
default:
|
||||
|
@ -375,6 +376,8 @@ namespace Porygon::Parser {
|
|||
return UnaryOperatorKind::Identity;
|
||||
case TokenKind::MinusToken:
|
||||
return UnaryOperatorKind::Negation;
|
||||
case TokenKind::HashToken :
|
||||
return UnaryOperatorKind::Count;
|
||||
case TokenKind::NotKeyword:
|
||||
return UnaryOperatorKind::LogicalNegation;
|
||||
default: // This should never trigger, so throw.
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Porygon::Parser {
|
|||
LessEquals,
|
||||
Greater,
|
||||
GreaterEquals,
|
||||
HashToken,
|
||||
|
||||
OpenParenthesis,
|
||||
CloseParenthesis,
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Porygon::Parser {
|
|||
enum class UnaryOperatorKind {
|
||||
Identity,
|
||||
Negation,
|
||||
Count,
|
||||
LogicalNegation,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "../Script.hpp"
|
||||
#include "../UserData/UserDataFunctionType.hpp"
|
||||
#include "ScriptType.hpp"
|
||||
|
||||
|
||||
namespace Porygon{
|
||||
inline bool ScriptType::CanBeIndexedWith(const ScriptType *) const{
|
||||
|
@ -76,6 +78,14 @@ namespace Porygon{
|
|||
return ToString(this->_class);
|
||||
}
|
||||
|
||||
bool ScriptType::IsCountable() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StringScriptType::IsCountable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C"{
|
||||
ScriptType* CreateScriptType(Porygon::TypeClass 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 bool IsCountable() const;
|
||||
|
||||
static std::string ToString(TypeClass c);
|
||||
[[nodiscard]] virtual std::string ToString() const;
|
||||
};
|
||||
|
@ -145,6 +147,8 @@ namespace Porygon{
|
|||
inline uint32_t GetHashValue() const{
|
||||
return _hashValue;
|
||||
}
|
||||
|
||||
bool IsCountable() const override;
|
||||
};
|
||||
|
||||
class NumericalTableScriptType : public ScriptType{
|
||||
|
|
|
@ -65,6 +65,10 @@ namespace Porygon{
|
|||
shared_ptr<const ScriptType> GetIteratorKeyType() const final {
|
||||
return make_shared<ScriptType>(TypeClass::Any);
|
||||
}
|
||||
|
||||
bool IsCountable() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ namespace Porygon::UserData {
|
|||
_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);
|
||||
}
|
||||
|
||||
|
@ -65,6 +66,10 @@ namespace Porygon::UserData {
|
|||
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,
|
||||
const EvalValue* (*get)(void*, const EvalValue*),
|
||||
void (*set)(void*, const EvalValue*, const EvalValue*),
|
||||
Iterator* (*getIterator)(void*)){
|
||||
return new UserDataCollectionValue(shared_ptr<UserDataCollectionType>(type), new UserDataCollectionHelper(obj, get, set, getIterator));
|
||||
Iterator* (*getIterator)(void*), size_t (getSize)(void*)){
|
||||
return new UserDataCollectionValue(shared_ptr<UserDataCollectionType>(type),
|
||||
new UserDataCollectionHelper(obj, get, set, getIterator, getSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "UserDataCollectionType.hpp"
|
||||
#include "../../Evaluator/EvalValues/EvalValue.hpp"
|
||||
#include "../../Utilities/Random.hpp"
|
||||
#include "../../Evaluator/EvalValues/NumericEvalValue.hpp"
|
||||
|
||||
using namespace Porygon::Evaluation;
|
||||
|
||||
|
@ -15,12 +16,14 @@ namespace Porygon::UserData {
|
|||
const EvalValue* (*_get)(void*, const EvalValue*);
|
||||
void (*_set)(void*, const EvalValue* , const EvalValue*);
|
||||
Iterator* (*_getIterator)(void*);
|
||||
size_t (*_getLength)(void*);
|
||||
public:
|
||||
UserDataCollectionHelper(void* parentObject,
|
||||
const EvalValue* (*get)(void*, const EvalValue*),
|
||||
void (*set)(void*, const EvalValue*, const EvalValue*),
|
||||
Iterator* (*getIterator)(void*))
|
||||
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator){}
|
||||
Iterator* (*getIterator)(void*), size_t (*getLength)(void*))
|
||||
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator),
|
||||
_getLength(getLength){}
|
||||
|
||||
const EvalValue* Get(const EvalValue* key) const{
|
||||
return _get(_parentObject, key);
|
||||
|
@ -33,6 +36,10 @@ namespace Porygon::UserData {
|
|||
[[nodiscard]] Iterator* GetIterator() const{
|
||||
return _getIterator(_parentObject);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t GetLength() const{
|
||||
return _getLength(_parentObject);
|
||||
}
|
||||
};
|
||||
|
||||
class UserDataCollectionValue : public Evaluation::EvalValue{
|
||||
|
@ -46,7 +53,7 @@ namespace Porygon::UserData {
|
|||
}
|
||||
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())
|
||||
{
|
||||
}
|
||||
|
@ -85,6 +92,13 @@ namespace Porygon::UserData {
|
|||
_helper->Set(key, 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 size = val.size(); \
|
||||
return new Porygon::UserData::UserDataCollectionRangeIterator(0, size); \
|
||||
}, [](void* obj) -> size_t{ \
|
||||
return ((T_USERDATA*)obj)->fieldName.size(); \
|
||||
} \
|
||||
) \
|
||||
) \
|
||||
|
|
Loading…
Reference in New Issue