Implements unknown types
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2019-09-01 20:07:09 +02:00
parent 01e5441d62
commit 0e9c9abf7c
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
6 changed files with 66 additions and 12 deletions

View File

@ -124,6 +124,8 @@ namespace Porygon::Binder {
return ScriptType::BoolType;
case HashedString::ConstHash("string"):
return StringScriptType::Dynamic;
case HashedString::ConstHash("table"):
return make_shared<TableScriptType>();
default:
if (!UserData::UserDataStorage::HasUserDataType(hash)) {
return nullptr;

View File

@ -10,8 +10,8 @@ vector<Diagnostic> DiagnosticsHolder::GetDiagnostics() {
void DiagnosticsHolder::Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length,
const std::vector<string>& arguments) {
_diagnostics.emplace_back(severity, code, start, length, arguments);
if (severity >= DiagnosticSeverity::Error){
_hasErrors = true;
if (severity == DiagnosticSeverity::Error){
_hasErrors = static_cast<byte>(1);
}
}
@ -28,7 +28,7 @@ void DiagnosticsHolder::LogInfo(DiagnosticCode code, unsigned int start, unsigne
}
bool DiagnosticsHolder::HasErrors() {
return _hasErrors;
return _hasErrors == static_cast<byte>(1);
}
int DiagnosticsHolder::DiagnosticsCount() {

View File

@ -13,13 +13,13 @@ using namespace std;
namespace Porygon::Diagnostics {
class DiagnosticsHolder {
bool _hasErrors;
byte _hasErrors;
vector<Diagnostic> _diagnostics;
vector<size_t> _lineStarts;
vector<size_t> _lineLength;
public:
explicit DiagnosticsHolder(const u16string& str) :_hasErrors(false), _lineStarts(vector<size_t>{0}) {
explicit DiagnosticsHolder(const u16string& str) : _hasErrors(static_cast<byte>(0)), _lineStarts(vector<size_t>{0}) {
size_t lineLength = 0;
for (size_t i = 0; i < str.size(); i++){
lineLength++;

View File

@ -77,6 +77,9 @@ namespace Porygon{
}
[[nodiscard]] virtual CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const{
if (_class == TypeClass::All){
return CastResult ::UncheckedCast;
}
if (explicitCast)
return CastResult::InvalidCast;
return CastResult::InvalidCast;

View File

@ -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<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
auto stringKey = dynamic_cast<const StringScriptType*>(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<ScriptType>(TypeClass::All);
}
[[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final{
@ -46,6 +55,16 @@ namespace Porygon{
[[nodiscard]] inline const map<Utilities::HashedString, BoundVariable*>* GetValues() const{
return _values;
}
[[nodiscard]]
bool CanBeIterated() const final {
return true;
}
[[nodiscard]]
shared_ptr<const ScriptType> GetIteratorKeyType() const final {
return make_shared<ScriptType>(TypeClass::All);
}
};
}

View File

@ -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