Fixes and changes for function declarations, using shared_ptr instead of raw pointers

This commit is contained in:
Deukhoofd 2019-06-01 13:43:25 +02:00
parent 6936b26cae
commit 1231a77761
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
8 changed files with 91 additions and 68 deletions

View File

@ -1,5 +1,8 @@
#include <memory>
#include "Binder.hpp" #include "Binder.hpp"
#include <memory>
BoundScriptStatement *Binder::Bind(Script* script, ParsedScriptStatement *s, BoundScope* scriptScope) { BoundScriptStatement *Binder::Bind(Script* script, ParsedScriptStatement *s, BoundScope* scriptScope) {
auto binder = Binder(); auto binder = Binder();
@ -75,22 +78,27 @@ ScriptType* ParseTypeIdentifier(HashedString s){
BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statement) { BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statement) {
auto functionStatement = (ParsedFunctionDeclarationStatement*) statement; auto functionStatement = (ParsedFunctionDeclarationStatement*) statement;
auto parameters = functionStatement->GetParameters(); auto parameters = functionStatement->GetParameters();
vector<ScriptType*> parameterTypes = vector<ScriptType*>(parameters.size()); vector<std::shared_ptr<ScriptType>> parameterTypes = vector<std::shared_ptr<ScriptType>>(parameters.size());
vector<int> parameterKeys = vector<int>(parameters.size()); vector<std::shared_ptr<BoundVariableKey>> parameterKeys = vector<std::shared_ptr<BoundVariableKey>>(parameters.size());
this->_scope->GoInnerScope(); this->_scope->GoInnerScope();
auto scopeId = this->_scope->GetCurrentScope();
for (int i = 0; i < parameters.size(); i++){ for (int i = 0; i < parameters.size(); i++){
auto var = parameters[i]; auto var = parameters[i];
auto parsedType = ParseTypeIdentifier(var->GetType()); auto parsedType = ParseTypeIdentifier(var->GetType());
parameterTypes[i] = parsedType; parameterTypes[i] = std::shared_ptr<ScriptType>(parsedType);
parameterKeys[i] = var->GetIdentifier().GetHash(); auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), *parsedType);
this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), *parsedType); if (parameterAssignment.GetResult() == VariableAssignmentResult::Ok){
parameterKeys[i] = std::shared_ptr<BoundVariableKey>(parameterAssignment.GetKey());
}
else{
//TODO: log error
continue;
}
} }
auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock()); auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock());
this->_scope->GoOuterScope(); this->_scope->GoOuterScope();
auto identifier = functionStatement->GetIdentifier(); auto identifier = functionStatement->GetIdentifier();
auto returnType = new ScriptType(TypeClass::Nil); auto returnType = std::make_shared<ScriptType>(TypeClass::Nil);
auto type = new FunctionScriptType(returnType, parameterTypes, parameterKeys, scopeId); auto type = new FunctionScriptType(returnType, parameterTypes, parameterKeys);
auto assignment = this->_scope->AssignVariable(identifier.GetHash(), *type); auto assignment = this->_scope->AssignVariable(identifier.GetHash(), *type);
if (assignment.GetResult() == VariableAssignmentResult::Ok){ if (assignment.GetResult() == VariableAssignmentResult::Ok){
return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock); return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock);

View File

@ -0,0 +1,43 @@
#ifndef PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP
#define PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP
#include <memory>
#include "BoundStatement.hpp"
class BoundFunctionDeclarationStatement : public BoundStatement{
BoundVariableKey* _key;
std::shared_ptr<BoundBlockStatement> _block;
FunctionScriptType* _type;
public:
BoundFunctionDeclarationStatement(FunctionScriptType* type, BoundVariableKey* key, BoundBlockStatement* block){
_key = key;
_block = shared_ptr<BoundBlockStatement>(block);
_type = type;
}
~BoundFunctionDeclarationStatement() final{
delete _key;
delete _type;
}
BoundStatementKind GetKind() final{
return BoundStatementKind ::FunctionDeclaration;
}
BoundVariableKey* GetKey(){
return _key;
}
std::shared_ptr<BoundBlockStatement> GetBlock(){
return _block;
}
FunctionScriptType* GetType(){
return _type;
}
};
#include "BoundStatement.hpp"
#endif //PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP

View File

@ -8,6 +8,7 @@
#include "../BoundExpressions/BoundExpression.hpp" #include "../BoundExpressions/BoundExpression.hpp"
#include "../BoundVariables/BoundVariableKey.hpp" #include "../BoundVariables/BoundVariableKey.hpp"
using namespace std; using namespace std;
enum class BoundStatementKind{ enum class BoundStatementKind{
@ -115,32 +116,6 @@ public:
} }
}; };
class BoundFunctionDeclarationStatement : public BoundStatement{ #include "BoundFunctionDeclarationStatement.hpp"
BoundVariableKey* _key;
BoundBlockStatement* _block;
FunctionScriptType* _type;
public:
BoundFunctionDeclarationStatement(FunctionScriptType* type, BoundVariableKey* key, BoundBlockStatement* block){
_key = key;
_block = block;
_type = type;
}
BoundStatementKind GetKind() final{
return BoundStatementKind ::FunctionDeclaration;
}
BoundVariableKey* GetKey(){
return _key;
}
BoundBlockStatement* GetBlock(){
return _block;
}
FunctionScriptType* GetType(){
return _type;
}
};
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP #endif //PORYGONLANG_BOUNDSTATEMENT_HPP

View File

@ -30,7 +30,11 @@ void BoundScope::GoInnerScope() {
} }
void BoundScope::GoOuterScope() { void BoundScope::GoOuterScope() {
_localScope[_currentScope - 1]->clear(); auto scope = _localScope[_currentScope - 1];
for (auto v : *scope){
delete v.second;
}
scope->clear();
_currentScope--; _currentScope--;
} }

View File

@ -2,16 +2,18 @@
#ifndef PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP #ifndef PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP
#define PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP #define PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP
#include <memory>
#include "../../ScriptType.hpp" #include "../../ScriptType.hpp"
#include "EvalValue.hpp" #include "EvalValue.hpp"
#include "../../Binder/BoundStatements/BoundStatement.hpp" #include "../../Binder/BoundStatements/BoundStatement.hpp"
#include "../Evaluator.hpp" #include "../Evaluator.hpp"
class ScriptFunctionEvalValue : public EvalValue{ class ScriptFunctionEvalValue : public EvalValue{
BoundBlockStatement* _innerBlock; std::shared_ptr<BoundBlockStatement> _innerBlock;
FunctionScriptType _type; FunctionScriptType _type;
public: public:
explicit ScriptFunctionEvalValue(BoundBlockStatement* innerBlock, const FunctionScriptType& type) explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock, const FunctionScriptType& type)
: _type(type) : _type(type)
{ {
_innerBlock = innerBlock; _innerBlock = innerBlock;
@ -21,10 +23,6 @@ public:
return new ScriptFunctionEvalValue(_innerBlock, _type); return new ScriptFunctionEvalValue(_innerBlock, _type);
} }
~ScriptFunctionEvalValue() final{
delete _innerBlock;
}
ScriptType* GetType() final{ ScriptType* GetType() final{
return &_type; return &_type;
}; };
@ -42,13 +40,13 @@ public:
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){ for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){
auto parameter = parameters[i]; auto parameter = parameters[i];
auto requiredType = parameterTypes[i]; auto requiredType = parameterTypes[i];
if (parameter->GetType() != requiredType){ if (parameter->GetType() != requiredType.get()){
throw EvaluationException("Passed wrong type to function."); throw EvaluationException("Passed wrong type to function.");
} }
auto key = parameterKeys[i]; auto key = parameterKeys[i];
scope->CreateVariable(_type.GetScopeId(), key, parameter->Clone()); scope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone());
} }
evaluator->EvaluateBlockStatement(_innerBlock); evaluator->EvaluateBlockStatement(_innerBlock.get());
return nullptr; return nullptr;
} }
}; };

View File

@ -215,5 +215,10 @@ public:
} }
}; };
class FunctionCallExpression : public ParsedExpression{
public:
};
#endif //PORYGONLANG_PARSEDEXPRESSION_HPP #endif //PORYGONLANG_PARSEDEXPRESSION_HPP

View File

@ -1,8 +1,12 @@
#include <utility>
#ifndef PORYGONLANG_SCRIPTTYPE_HPP #ifndef PORYGONLANG_SCRIPTTYPE_HPP
#define PORYGONLANG_SCRIPTTYPE_HPP #define PORYGONLANG_SCRIPTTYPE_HPP
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <memory>
#include "Binder/BoundVariables/BoundVariableKey.hpp"
enum class TypeClass{ enum class TypeClass{
Error, Error,
@ -58,40 +62,28 @@ public:
}; };
class FunctionScriptType : public ScriptType{ class FunctionScriptType : public ScriptType{
ScriptType* _returnType; std::shared_ptr<ScriptType> _returnType;
std::vector<ScriptType*> _parameterTypes; std::vector<std::shared_ptr<ScriptType>> _parameterTypes;
std::vector<int> _parameterKeys; std::vector<std::shared_ptr<BoundVariableKey>> _parameterKeys;
int _scopeId;
public: public:
FunctionScriptType(ScriptType* returnType, std::vector<ScriptType*> parameterTypes, std::vector<int> parameterKeys, int scopeId) FunctionScriptType(std::shared_ptr<ScriptType> returnType, std::vector<std::shared_ptr<ScriptType>> parameterTypes,
std::vector<std::shared_ptr<BoundVariableKey>> parameterKeys)
: ScriptType(TypeClass::Function){ : ScriptType(TypeClass::Function){
_returnType = returnType; _returnType = std::move(returnType);
_parameterTypes = std::move(parameterTypes); _parameterTypes = std::move(parameterTypes);
_parameterKeys = std::move(parameterKeys); _parameterKeys = std::move(parameterKeys);
_scopeId = scopeId;
} }
~FunctionScriptType() final{
delete _returnType;
for (auto t: _parameterTypes){
delete t;
}
}
ScriptType* GetReturnType(){ ScriptType* GetReturnType(){
return _returnType; return _returnType.get();
} }
std::vector<ScriptType*> GetParameterTypes(){ std::vector<std::shared_ptr<ScriptType>> GetParameterTypes(){
return _parameterTypes; return _parameterTypes;
} }
std::vector<int> GetParameterKeys(){ std::vector<std::shared_ptr<BoundVariableKey>> GetParameterKeys(){
return _parameterKeys; return _parameterKeys;
} }
int GetScopeId(){
return _scopeId;
}
}; };
#endif //PORYGONLANG_SCRIPTTYPE_HPP #endif //PORYGONLANG_SCRIPTTYPE_HPP

View File

@ -12,6 +12,4 @@ TEST_CASE( "Define script function", "[integration]" ) {
delete script; delete script;
} }
#endif #endif