From 0e9c9abf7c08d6d7772968d97d7650bc545d8459 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 1 Sep 2019 20:07:09 +0200 Subject: [PATCH] Implements unknown types --- src/Binder/Binder.cpp | 2 ++ src/Diagnostics/DiagnosticsHolder.cpp | 6 ++--- src/Diagnostics/DiagnosticsHolder.hpp | 4 +-- src/ScriptTypes/ScriptType.hpp | 3 +++ src/ScriptTypes/TableScriptType.hpp | 27 +++++++++++++++++--- tests/integration/ModuleTests.cpp | 36 ++++++++++++++++++++++++--- 6 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index 6084002..53ba075 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -124,6 +124,8 @@ namespace Porygon::Binder { return ScriptType::BoolType; case HashedString::ConstHash("string"): return StringScriptType::Dynamic; + case HashedString::ConstHash("table"): + return make_shared(); default: if (!UserData::UserDataStorage::HasUserDataType(hash)) { return nullptr; diff --git a/src/Diagnostics/DiagnosticsHolder.cpp b/src/Diagnostics/DiagnosticsHolder.cpp index 716a0c0..7579051 100644 --- a/src/Diagnostics/DiagnosticsHolder.cpp +++ b/src/Diagnostics/DiagnosticsHolder.cpp @@ -10,8 +10,8 @@ vector DiagnosticsHolder::GetDiagnostics() { void DiagnosticsHolder::Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length, const std::vector& arguments) { _diagnostics.emplace_back(severity, code, start, length, arguments); - if (severity >= DiagnosticSeverity::Error){ - _hasErrors = true; + if (severity == DiagnosticSeverity::Error){ + _hasErrors = static_cast(1); } } @@ -28,7 +28,7 @@ void DiagnosticsHolder::LogInfo(DiagnosticCode code, unsigned int start, unsigne } bool DiagnosticsHolder::HasErrors() { - return _hasErrors; + return _hasErrors == static_cast(1); } int DiagnosticsHolder::DiagnosticsCount() { diff --git a/src/Diagnostics/DiagnosticsHolder.hpp b/src/Diagnostics/DiagnosticsHolder.hpp index 3337e5c..d43ba0d 100644 --- a/src/Diagnostics/DiagnosticsHolder.hpp +++ b/src/Diagnostics/DiagnosticsHolder.hpp @@ -13,13 +13,13 @@ using namespace std; namespace Porygon::Diagnostics { class DiagnosticsHolder { - bool _hasErrors; + byte _hasErrors; vector _diagnostics; vector _lineStarts; vector _lineLength; public: - explicit DiagnosticsHolder(const u16string& str) :_hasErrors(false), _lineStarts(vector{0}) { + explicit DiagnosticsHolder(const u16string& str) : _hasErrors(static_cast(0)), _lineStarts(vector{0}) { size_t lineLength = 0; for (size_t i = 0; i < str.size(); i++){ lineLength++; diff --git a/src/ScriptTypes/ScriptType.hpp b/src/ScriptTypes/ScriptType.hpp index 764d54c..bf8ad54 100644 --- a/src/ScriptTypes/ScriptType.hpp +++ b/src/ScriptTypes/ScriptType.hpp @@ -77,6 +77,9 @@ namespace Porygon{ } [[nodiscard]] virtual CastResult CastableTo(const shared_ptr& castType, bool explicitCast) const{ + if (_class == TypeClass::All){ + return CastResult ::UncheckedCast; + } if (explicitCast) return CastResult::InvalidCast; return CastResult::InvalidCast; diff --git a/src/ScriptTypes/TableScriptType.hpp b/src/ScriptTypes/TableScriptType.hpp index b996653..e40b53c 100644 --- a/src/ScriptTypes/TableScriptType.hpp +++ b/src/ScriptTypes/TableScriptType.hpp @@ -15,9 +15,18 @@ namespace Porygon{ _localVariableCount(localVariableCount) {} + explicit TableScriptType() + : ScriptType(TypeClass::Table), + _values(nullptr), + _localVariableCount(0) + {} + + ~TableScriptType() final{ - for (auto i : *_values){ - delete i.second; + if (_values != nullptr){ + for (const auto& i : *_values){ + delete i.second; + } } delete _values; } @@ -33,10 +42,10 @@ namespace Porygon{ shared_ptr GetIndexedType(const ScriptType* indexer) const final{ auto stringKey = dynamic_cast(indexer); - if (stringKey->IsKnownAtBind()){ + if (stringKey != nullptr && stringKey->IsKnownAtBind() && _values != nullptr){ return _values-> at(Utilities::HashedString::CreateLookup(stringKey->GetHashValue()))->GetType(); } - throw "TODO: indexing with dynamic keys"; + return make_shared(TypeClass::All); } [[nodiscard]] inline shared_ptr GetIndexedType(uint32_t hash) const final{ @@ -46,6 +55,16 @@ namespace Porygon{ [[nodiscard]] inline const map* GetValues() const{ return _values; } + + [[nodiscard]] + bool CanBeIterated() const final { + return true; + } + + [[nodiscard]] + shared_ptr GetIteratorKeyType() const final { + return make_shared(TypeClass::All); + } }; } diff --git a/tests/integration/ModuleTests.cpp b/tests/integration/ModuleTests.cpp index 085b8ac..309c805 100644 --- a/tests/integration/ModuleTests.cpp +++ b/tests/integration/ModuleTests.cpp @@ -11,7 +11,20 @@ class ModuleHandler{ Internal(){ MODULES = { {"simple_return", Script::Create(u"return 500")}, - {"simple_variables", Script::Create(u"foo = 50\nbar = \'test\'")} + {"simple_variables", Script::Create(u"foo = 50\nbar = \'test\'")}, + { + "complex_module", Script::Create(uR"( +local module = { + function contains(table table, string s) + for _, v in table do + if (v == s) then return true end + end + return false + end +} +return module +)") + } }; } @@ -22,6 +35,8 @@ class ModuleHandler{ MODULES.clear(); } }; +public: + static Internal* _internal; static Internal* GetInternal(){ @@ -35,10 +50,11 @@ class ModuleHandler{ } inline static Script* ResolveModule(const char* moduleName, size_t size){ - return GetInternal()->MODULES[moduleName]; + auto module = GetInternal()->MODULES[moduleName]; + REQUIRE(!module->Diagnostics->HasErrors()); + return module; } -public: static void Initialize(){ ScriptOptions::GetDefaultScriptOptions()->SetModuleExistsFunc(DoesModuleExist); ScriptOptions::GetDefaultScriptOptions()->SetResolveModuleFunc(ResolveModule); @@ -77,4 +93,18 @@ require("simple_variables") delete script; } +TEST_CASE( "Require string table contains", "[integration]" ) { + ModuleHandler::Initialize(); + auto script = Script::Create(uR"( +local list = require("complex_module") +return list.contains({"foo", "bar"}, "bar") +)"); + REQUIRE(!script->Diagnostics -> HasErrors()); + auto result = script->Evaluate(); + CHECK(result->EvaluateBool()); + + delete script; +} + + #endif