From 7c345d85e8c989470486f771b7f01b41fb296f19 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 14 Jun 2019 22:21:33 +0200 Subject: [PATCH] Work on making userdata work through extern C entry points --- src/Binder/Binder.cpp | 15 ++++++++++++--- src/Binder/BoundVariables/BoundScope.cpp | 12 ++++++------ src/Binder/BoundVariables/BoundScope.hpp | 12 ++++++------ src/Diagnostics/DiagnosticCode.hpp | 1 + src/Evaluator/EvalValues/TableEvalValue.hpp | 6 +++--- .../EvaluationScope/EvaluationScope.cpp | 2 +- .../EvaluationScope/EvaluationScope.hpp | 4 ++-- src/Evaluator/Evaluator.cpp | 6 +++--- src/Script.cpp | 8 ++++---- src/Script.hpp | 4 ++-- src/ScriptType.cpp | 14 ++++++++++++++ src/ScriptType.hpp | 6 +++--- src/TableScriptType.hpp | 6 +++--- src/UserData/UserData.cpp | 18 ++++++++++++++++++ src/UserData/UserData.hpp | 16 ++++++++++++---- src/UserData/UserDataField.cpp | 6 ++++++ src/UserData/UserDataField.hpp | 1 + src/UserData/UserDataScriptType.hpp | 16 +++++++++++++--- src/UserData/UserDataStorage.hpp | 10 +++++++--- src/UserData/UserDataValue.cpp | 6 ++++++ src/UserData/UserDataValue.hpp | 2 +- src/Utilities/HashedString.hpp | 8 ++++---- 22 files changed, 128 insertions(+), 51 deletions(-) diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index 2c8c8b2..47dda2b 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -83,11 +83,16 @@ BoundStatement *Binder::BindIndexAssignmentStatement(const ParsedStatement *stat } std::shared_ptr ParseTypeIdentifier(HashedString s){ - switch (s.GetHash()){ + auto hash = s.GetHash(); + switch (hash){ case HashedString::ConstHash("number"): return std::make_shared(false, false); case HashedString::ConstHash("bool"): return std::make_shared(TypeClass::Bool); case HashedString::ConstHash("string"): return std::make_shared(false, 0); - default: return std::make_shared(s.GetHash()); + default: + if (!UserDataStorage::HasUserDataType(hash)){ + return nullptr; + } + return std::make_shared(hash); } } @@ -102,6 +107,10 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(const ParsedStatement * for (int i = 0; i < parameters->size(); i++){ auto var = parameters -> at(i); auto parsedType = ParseTypeIdentifier(var->GetType()); + if (parsedType == nullptr){ + this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidTypeName, statement->GetStartPosition(), statement->GetLength()); + return new BoundBadStatement(); + } parameterTypes.at(i) = parsedType; auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), parsedType); if (parameterAssignment.GetResult() == VariableAssignmentResult::Ok){ @@ -442,7 +451,7 @@ BoundExpression* Binder::BindNumericalTableExpression(const ParsedNumericalTable } BoundExpression *Binder::BindTableExpression(const ParsedTableExpression *expression) { - auto tableScope = new unordered_map(); + auto tableScope = new unordered_map(); auto innerScope = new BoundScope(tableScope); auto currentScope = this -> _scope; this -> _scope = innerScope; diff --git a/src/Binder/BoundVariables/BoundScope.cpp b/src/Binder/BoundVariables/BoundScope.cpp index 1a9c1fa..1c7b334 100644 --- a/src/Binder/BoundVariables/BoundScope.cpp +++ b/src/Binder/BoundVariables/BoundScope.cpp @@ -3,11 +3,11 @@ #include "BoundScope.hpp" -BoundScope::BoundScope(unordered_map *tableScope) { +BoundScope::BoundScope(unordered_map *tableScope) { _tableScope = tableScope; _currentScope = 1; _lastCreatedScope = 1; - auto localUpmostScope = new unordered_map(); + auto localUpmostScope = new unordered_map(); _localScope.push_back(localUpmostScope); } @@ -24,7 +24,7 @@ void BoundScope::GoInnerScope() { _lastCreatedScope++; _currentScope = _lastCreatedScope; if (_localScope.size() < _currentScope){ - auto innerScope = new unordered_map(); + auto innerScope = new unordered_map(); _localScope.push_back(innerScope); } } @@ -53,7 +53,7 @@ int BoundScope::Exists(int key) { return -1; } -BoundVariable *BoundScope::GetVariable(int scope, int identifier) { +BoundVariable *BoundScope::GetVariable(uint32_t scope, uint32_t identifier) { if (scope == 0){ auto find = this -> _tableScope->find(identifier); if (find != _tableScope->end()){ @@ -70,7 +70,7 @@ BoundVariable *BoundScope::GetVariable(int scope, int identifier) { } } -VariableAssignment BoundScope::CreateExplicitLocal(int identifier, std::shared_ptr type) { +VariableAssignment BoundScope::CreateExplicitLocal(uint32_t identifier, std::shared_ptr type) { auto scope = this->_localScope.at(this->_currentScope - 1); if (scope -> find(identifier) != scope -> end()){ return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr); @@ -79,7 +79,7 @@ VariableAssignment BoundScope::CreateExplicitLocal(int identifier, std::shared_p return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, this->_currentScope, true)); } -VariableAssignment BoundScope::AssignVariable(int identifier, const std::shared_ptr& type) { +VariableAssignment BoundScope::AssignVariable(uint32_t identifier, const std::shared_ptr& type) { int exists = this->Exists(identifier); if (exists == -1){ // Creation diff --git a/src/Binder/BoundVariables/BoundScope.hpp b/src/Binder/BoundVariables/BoundScope.hpp index 82a646a..da19c1f 100644 --- a/src/Binder/BoundVariables/BoundScope.hpp +++ b/src/Binder/BoundVariables/BoundScope.hpp @@ -14,21 +14,21 @@ using namespace std; class BoundScope { - unordered_map* _tableScope; - vector*> _localScope; + unordered_map* _tableScope; + vector*> _localScope; int _currentScope; int _lastCreatedScope; public: - explicit BoundScope(unordered_map *tableScope); + explicit BoundScope(unordered_map *tableScope); ~BoundScope(); void GoInnerScope(); void GoOuterScope(); int Exists(int key); - BoundVariable* GetVariable(int scope, int identifier); - VariableAssignment CreateExplicitLocal(int identifier, std::shared_ptr type); - VariableAssignment AssignVariable(int identifier, const std::shared_ptr& type); + BoundVariable* GetVariable(uint32_t scope, uint32_t identifier); + VariableAssignment CreateExplicitLocal(uint32_t identifier, std::shared_ptr type); + VariableAssignment AssignVariable(uint32_t identifier, const std::shared_ptr& type); size_t GetLocalVariableCount(){ return _localScope.size(); diff --git a/src/Diagnostics/DiagnosticCode.hpp b/src/Diagnostics/DiagnosticCode.hpp index 4d38bbd..669b520 100644 --- a/src/Diagnostics/DiagnosticCode.hpp +++ b/src/Diagnostics/DiagnosticCode.hpp @@ -22,6 +22,7 @@ enum class DiagnosticCode{ InvalidReturnType, ConditionNotABool, InvalidTableValueType, + InvalidTypeName, }; #endif //PORYGONLANG_DIAGNOSTICCODE_HPP diff --git a/src/Evaluator/EvalValues/TableEvalValue.hpp b/src/Evaluator/EvalValues/TableEvalValue.hpp index 8af71f0..51b3c5d 100644 --- a/src/Evaluator/EvalValues/TableEvalValue.hpp +++ b/src/Evaluator/EvalValues/TableEvalValue.hpp @@ -7,15 +7,15 @@ using namespace std; class TableEvalValue : public EvalValue { - shared_ptr>> _table; + shared_ptr>> _table; size_t _hash; - explicit TableEvalValue(shared_ptr>> table, size_t hash){ + explicit TableEvalValue(shared_ptr>> table, size_t hash){ _table = std::move(table); _hash = hash; } public: - explicit TableEvalValue(shared_ptr>> table){ + explicit TableEvalValue(shared_ptr>> table){ _table = std::move(table); _hash = rand(); } diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.cpp b/src/Evaluator/EvaluationScope/EvaluationScope.cpp index d068cd1..fda399c 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.cpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.cpp @@ -2,7 +2,7 @@ #include "EvaluationScope.hpp" #include -EvaluationScope::EvaluationScope(unordered_map> *scriptVariables, int localVariableCount) { +EvaluationScope::EvaluationScope(unordered_map> *scriptVariables, int localVariableCount) { _scriptScope = scriptVariables; _localScope = unordered_map>(localVariableCount); } diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.hpp b/src/Evaluator/EvaluationScope/EvaluationScope.hpp index 8a2269f..f9e5820 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.hpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.hpp @@ -7,10 +7,10 @@ #include "../EvalValues/EvalValue.hpp" class EvaluationScope { - unordered_map>* _scriptScope; + unordered_map>* _scriptScope; unordered_map> _localScope; public: - explicit EvaluationScope(unordered_map>* scriptVariables, int deepestScope); + explicit EvaluationScope(unordered_map>* scriptVariables, int deepestScope); ~EvaluationScope() = default; void CreateVariable(const BoundVariableKey* key, const shared_ptr& value); diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index b83a239..075d80e 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -279,12 +279,12 @@ shared_ptr Evaluator::EvaluateIndexExpression(const BoundExpression * shared_ptr Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) { auto tableExpression = (BoundNumericalTableExpression*)expression; auto valueExpressions = tableExpression->GetExpressions(); - auto values = new unordered_map>(valueExpressions->size()); + auto values = new unordered_map>(valueExpressions->size()); for (int i = 0; i < valueExpressions->size(); i++){ auto val = this -> EvaluateExpression(valueExpressions -> at(i)); values -> insert({i + 1, val}); } - auto valuesPointer = shared_ptr>>(values); + auto valuesPointer = shared_ptr>>(values); return make_shared(valuesPointer); } @@ -292,7 +292,7 @@ shared_ptr Evaluator::EvaluateComplexTableExpression(const BoundExpre auto tableExpression = (BoundTableExpression*)expression; auto type = dynamic_pointer_cast(tableExpression->GetType()); auto declaredVars = type -> GetValues(); - auto variables = make_shared>>(declaredVars->size()); + auto variables = make_shared>>(declaredVars->size()); for (auto i : *declaredVars){ variables->insert({i.first, nullptr}); } diff --git a/src/Script.cpp b/src/Script.cpp index 60dd070..c64f1ee 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -17,7 +17,7 @@ Script::Script() { Diagnostics = new DiagnosticsHolder(); _evaluator = new Evaluator(this); _boundScript = nullptr; - _scriptVariables = new unordered_map>(0); + _scriptVariables = new unordered_map>(0); } EvalValue* Script::Evaluate() { @@ -42,7 +42,7 @@ void Script::Parse(const string& script) { } lexResult.clear(); if (!Diagnostics->HasErrors()){ - unordered_map scriptScope; + unordered_map scriptScope; auto bindScope = new BoundScope(&scriptScope); this->_boundScript = Binder::Bind(this, parseResult, bindScope); for (const auto& v : scriptScope){ @@ -72,9 +72,9 @@ bool Script::HasFunction(const string &key) { return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function; } -shared_ptr Script::CallFunction(const string &key, vector variables) { +shared_ptr Script::CallFunction(const string &key, const vector& variables) { auto var = (ScriptFunctionEvalValue*)GetVariable(key); - return this->_evaluator->EvaluateFunction(var, std::move(variables)); + return this->_evaluator->EvaluateFunction(var, variables); } extern "C" { diff --git a/src/Script.hpp b/src/Script.hpp index d25d804..9b51c97 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -18,7 +18,7 @@ class Script { friend class Evaluator; Evaluator* _evaluator; - unordered_map>* _scriptVariables; + unordered_map>* _scriptVariables; BoundScriptStatement* _boundScript; shared_ptr _returnType; @@ -45,7 +45,7 @@ public: EvalValue* GetVariable(const string& key); bool HasVariable(const string& key); - shared_ptr CallFunction(const string& key, vector variables); + shared_ptr CallFunction(const string& key, const vector& variables); bool HasFunction(const string& key); }; diff --git a/src/ScriptType.cpp b/src/ScriptType.cpp index dcadf01..bf57108 100644 --- a/src/ScriptType.cpp +++ b/src/ScriptType.cpp @@ -11,3 +11,17 @@ shared_ptr ScriptType::GetIndexedType(ScriptType *indexer) { } return make_shared(TypeClass::Error); } + +extern "C"{ + ScriptType* CreateScriptType(TypeClass t){ + return new ScriptType(t); + } + + ScriptType* CreateNumericScriptType(bool isAware, bool isFloat){ + return new NumericScriptType(isAware, isFloat); + } + + ScriptType* CreateStringScriptType(bool knownAtBind, uint32_t hash){ + return new StringScriptType(knownAtBind, hash); + } +} \ No newline at end of file diff --git a/src/ScriptType.hpp b/src/ScriptType.hpp index 598b1a3..7573426 100644 --- a/src/ScriptType.hpp +++ b/src/ScriptType.hpp @@ -76,9 +76,9 @@ public: class StringScriptType : public ScriptType{ bool _isKnownAtBind; - int _hashValue; + uint32_t _hashValue; public: - explicit StringScriptType(bool knownAtBind, int hashValue): ScriptType(TypeClass::String){ + explicit StringScriptType(bool knownAtBind, uint32_t hashValue): ScriptType(TypeClass::String){ _isKnownAtBind = knownAtBind; _hashValue = hashValue; } @@ -87,7 +87,7 @@ public: return _isKnownAtBind; } - int GetHashValue(){ + uint32_t GetHashValue(){ return _hashValue; } }; diff --git a/src/TableScriptType.hpp b/src/TableScriptType.hpp index 29abb48..0cc515a 100644 --- a/src/TableScriptType.hpp +++ b/src/TableScriptType.hpp @@ -5,10 +5,10 @@ #include "Binder/BoundVariables/BoundVariable.hpp" class TableScriptType : public ScriptType{ - const unordered_map* _values; + const unordered_map* _values; const int _localVariableCount; public: - explicit TableScriptType(unordered_map* values, int localVariableCount) + explicit TableScriptType(unordered_map* values, int localVariableCount) : ScriptType(TypeClass::Table), _values(values), _localVariableCount(localVariableCount) @@ -33,7 +33,7 @@ public: throw "TODO: indexing with dynamic keys"; } - const unordered_map* GetValues(){ + const unordered_map* GetValues(){ return _values; } diff --git a/src/UserData/UserData.cpp b/src/UserData/UserData.cpp index 4130941..50e83a8 100644 --- a/src/UserData/UserData.cpp +++ b/src/UserData/UserData.cpp @@ -1,2 +1,20 @@ #include "UserData.hpp" +#include "UserDataStorage.hpp" + +extern "C"{ + void RegisterUserDataType(uint32_t id){ + auto ud = new UserData({}); + UserDataStorage::RegisterType(id, ud); + } + + void RegisterUserDataField(uint32_t typeId, uint32_t fieldId, UserDataField* field){ + auto ud = UserDataStorage::GetUserDataType(typeId); + ud -> CreateField(fieldId, field); + } + + int32_t GetUserDataFieldCount(uint32_t typeId){ + auto ud = UserDataStorage::GetUserDataType(typeId); + return ud ->GetFieldCount(); + } +} \ No newline at end of file diff --git a/src/UserData/UserData.hpp b/src/UserData/UserData.hpp index e78d248..8617979 100644 --- a/src/UserData/UserData.hpp +++ b/src/UserData/UserData.hpp @@ -6,19 +6,27 @@ #include "UserDataField.hpp" class UserData { - std::unordered_map _fields; + std::unordered_map _fields; public: - explicit UserData(std::unordered_map fields){ + explicit UserData(std::unordered_map fields){ _fields = std::move(fields); } - bool ContainsField(int fieldId){ + bool ContainsField(uint32_t fieldId){ return _fields.find(fieldId) != _fields.end(); } - UserDataField* GetField(int fieldId){ + UserDataField* GetField(uint32_t fieldId){ return _fields[fieldId]; } + + void CreateField(uint32_t fieldId, UserDataField* field){ + _fields.insert({fieldId, field}); + } + + int32_t GetFieldCount(){ + return _fields.size(); + } }; diff --git a/src/UserData/UserDataField.cpp b/src/UserData/UserDataField.cpp index b01fafc..dce665d 100644 --- a/src/UserData/UserDataField.cpp +++ b/src/UserData/UserDataField.cpp @@ -1,2 +1,8 @@ #include "UserDataField.hpp" + +extern "C"{ + UserDataField* CreateUserDataField(ScriptType* type, EvalValue* (*getter)(void* obj), void (*setter)(void* obj, EvalValue* val)){ + return new UserDataField(type, getter, setter); + } +} \ No newline at end of file diff --git a/src/UserData/UserDataField.hpp b/src/UserData/UserDataField.hpp index 1409e72..1ff4af6 100644 --- a/src/UserData/UserDataField.hpp +++ b/src/UserData/UserDataField.hpp @@ -4,6 +4,7 @@ #include "../Evaluator/EvalValues/EvalValue.hpp" +#include "../Evaluator/EvalValues/NumericEvalValue.hpp" class UserDataField { shared_ptr _type; diff --git a/src/UserData/UserDataScriptType.hpp b/src/UserData/UserDataScriptType.hpp index d236440..9e5d31b 100644 --- a/src/UserData/UserDataScriptType.hpp +++ b/src/UserData/UserDataScriptType.hpp @@ -1,8 +1,9 @@ + #ifndef PORYGONLANG_USERDATASCRIPTTYPE_HPP #define PORYGONLANG_USERDATASCRIPTTYPE_HPP - +#include #include "../ScriptType.hpp" #include "UserData.hpp" #include "UserDataStorage.hpp" @@ -10,12 +11,21 @@ class UserDataScriptType : public ScriptType{ shared_ptr _userData; public: - explicit UserDataScriptType(int id) : ScriptType(TypeClass::UserData){ + explicit UserDataScriptType(uint32_t id) : ScriptType(TypeClass::UserData){ _userData = UserDataStorage::GetUserDataType(id); } + explicit UserDataScriptType(shared_ptr ud) : ScriptType(TypeClass::UserData){ + _userData = std::move(ud); + } bool CanBeIndexedWith(ScriptType* indexer) final{ - return indexer->GetClass() == TypeClass ::String; + if (indexer->GetClass() != TypeClass ::String){ + return false; + } + auto str = (StringScriptType*)indexer; + if (!str->IsKnownAtBind()) + return false; + return _userData->ContainsField(str->GetHashValue()); } shared_ptr GetIndexedType(ScriptType* indexer) final{ diff --git a/src/UserData/UserDataStorage.hpp b/src/UserData/UserDataStorage.hpp index 0fbc356..603e1d3 100644 --- a/src/UserData/UserDataStorage.hpp +++ b/src/UserData/UserDataStorage.hpp @@ -8,16 +8,20 @@ class UserDataStorage { class _internalDataStorage{ public: - std::unordered_map> _userData; + std::unordered_map> _userData; }; static _internalDataStorage _internal; public: - static void RegisterType(int i, UserData* ud){ + static void RegisterType(uint32_t i, UserData* ud){ UserDataStorage::_internal._userData.insert({i, shared_ptr(ud)}); } - static shared_ptr GetUserDataType(int i){ + static bool HasUserDataType(uint32_t i){ + return UserDataStorage::_internal._userData.find(i) != UserDataStorage::_internal._userData.end(); + } + + static shared_ptr GetUserDataType(uint32_t i){ return UserDataStorage::_internal._userData[i]; } }; diff --git a/src/UserData/UserDataValue.cpp b/src/UserData/UserDataValue.cpp index 1dfa6b6..83df841 100644 --- a/src/UserData/UserDataValue.cpp +++ b/src/UserData/UserDataValue.cpp @@ -1,2 +1,8 @@ #include "UserDataValue.hpp" + +extern "C"{ + UserDataValue* CreateUserDataEvalValue(uint32_t typeHash, void* obj){ + return new UserDataValue(typeHash, obj); + } +} \ No newline at end of file diff --git a/src/UserData/UserDataValue.hpp b/src/UserData/UserDataValue.hpp index 43243a4..a998584 100644 --- a/src/UserData/UserDataValue.hpp +++ b/src/UserData/UserDataValue.hpp @@ -17,7 +17,7 @@ public: _obj = obj; } - UserDataValue(int userDataId, void* obj){ + UserDataValue(uint32_t userDataId, void* obj){ _userData = UserDataStorage::GetUserDataType(userDataId); _obj = obj; } diff --git a/src/Utilities/HashedString.hpp b/src/Utilities/HashedString.hpp index 023d88e..bec8973 100644 --- a/src/Utilities/HashedString.hpp +++ b/src/Utilities/HashedString.hpp @@ -5,7 +5,7 @@ #include class HashedString{ - const int _hash; + const uint32_t _hash; public: explicit HashedString(const std::string& s) : _hash(ConstHash(s.c_str())){ } @@ -13,13 +13,13 @@ public: } HashedString(const HashedString& b) = default; - static unsigned constexpr ConstHash(char const *input) { + static uint32_t constexpr ConstHash(char const *input) { return *input ? - static_cast(*input) + 33 * ConstHash(input + 1) : + static_cast(*input) + 33 * ConstHash(input + 1) : 5381; } - const int GetHash() const{ + const uint32_t GetHash() const{ return _hash; }