diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index cf80a6a..eed6ac0 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -1,5 +1,8 @@ +#include + #include "Binder.hpp" +#include BoundScriptStatement *Binder::Bind(Script* script, ParsedScriptStatement *s, BoundScope* scriptScope) { auto binder = Binder(); @@ -75,22 +78,27 @@ ScriptType* ParseTypeIdentifier(HashedString s){ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statement) { auto functionStatement = (ParsedFunctionDeclarationStatement*) statement; auto parameters = functionStatement->GetParameters(); - vector parameterTypes = vector(parameters.size()); - vector parameterKeys = vector(parameters.size()); + vector> parameterTypes = vector>(parameters.size()); + vector> parameterKeys = vector>(parameters.size()); this->_scope->GoInnerScope(); - auto scopeId = this->_scope->GetCurrentScope(); for (int i = 0; i < parameters.size(); i++){ auto var = parameters[i]; auto parsedType = ParseTypeIdentifier(var->GetType()); - parameterTypes[i] = parsedType; - parameterKeys[i] = var->GetIdentifier().GetHash(); - this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), *parsedType); + parameterTypes[i] = std::shared_ptr(parsedType); + auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), *parsedType); + if (parameterAssignment.GetResult() == VariableAssignmentResult::Ok){ + parameterKeys[i] = std::shared_ptr(parameterAssignment.GetKey()); + } + else{ + //TODO: log error + continue; + } } auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock()); this->_scope->GoOuterScope(); auto identifier = functionStatement->GetIdentifier(); - auto returnType = new ScriptType(TypeClass::Nil); - auto type = new FunctionScriptType(returnType, parameterTypes, parameterKeys, scopeId); + auto returnType = std::make_shared(TypeClass::Nil); + auto type = new FunctionScriptType(returnType, parameterTypes, parameterKeys); auto assignment = this->_scope->AssignVariable(identifier.GetHash(), *type); if (assignment.GetResult() == VariableAssignmentResult::Ok){ return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock); diff --git a/src/Binder/BoundStatements/BoundFunctionDeclarationStatement.hpp b/src/Binder/BoundStatements/BoundFunctionDeclarationStatement.hpp new file mode 100644 index 0000000..06019f0 --- /dev/null +++ b/src/Binder/BoundStatements/BoundFunctionDeclarationStatement.hpp @@ -0,0 +1,43 @@ + +#ifndef PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP +#define PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP + +#include +#include "BoundStatement.hpp" + +class BoundFunctionDeclarationStatement : public BoundStatement{ + BoundVariableKey* _key; + std::shared_ptr _block; + FunctionScriptType* _type; +public: + BoundFunctionDeclarationStatement(FunctionScriptType* type, BoundVariableKey* key, BoundBlockStatement* block){ + _key = key; + _block = shared_ptr(block); + _type = type; + } + + ~BoundFunctionDeclarationStatement() final{ + delete _key; + delete _type; + } + + BoundStatementKind GetKind() final{ + return BoundStatementKind ::FunctionDeclaration; + } + + BoundVariableKey* GetKey(){ + return _key; + } + + std::shared_ptr GetBlock(){ + return _block; + } + + FunctionScriptType* GetType(){ + return _type; + } +}; + +#include "BoundStatement.hpp" + +#endif //PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP diff --git a/src/Binder/BoundStatements/BoundStatement.hpp b/src/Binder/BoundStatements/BoundStatement.hpp index 920f192..1f75a52 100644 --- a/src/Binder/BoundStatements/BoundStatement.hpp +++ b/src/Binder/BoundStatements/BoundStatement.hpp @@ -8,6 +8,7 @@ #include "../BoundExpressions/BoundExpression.hpp" #include "../BoundVariables/BoundVariableKey.hpp" + using namespace std; enum class BoundStatementKind{ @@ -115,32 +116,6 @@ public: } }; -class BoundFunctionDeclarationStatement : public BoundStatement{ - 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; - } -}; +#include "BoundFunctionDeclarationStatement.hpp" #endif //PORYGONLANG_BOUNDSTATEMENT_HPP diff --git a/src/Binder/BoundVariables/BoundScope.cpp b/src/Binder/BoundVariables/BoundScope.cpp index 2b4c771..5fb482f 100644 --- a/src/Binder/BoundVariables/BoundScope.cpp +++ b/src/Binder/BoundVariables/BoundScope.cpp @@ -30,7 +30,11 @@ void BoundScope::GoInnerScope() { } void BoundScope::GoOuterScope() { - _localScope[_currentScope - 1]->clear(); + auto scope = _localScope[_currentScope - 1]; + for (auto v : *scope){ + delete v.second; + } + scope->clear(); _currentScope--; } diff --git a/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp b/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp index 18e98e5..bee9b26 100644 --- a/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp +++ b/src/Evaluator/EvalValues/ScriptFunctionEvalValue.hpp @@ -2,16 +2,18 @@ #ifndef PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP #define PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP +#include #include "../../ScriptType.hpp" #include "EvalValue.hpp" #include "../../Binder/BoundStatements/BoundStatement.hpp" #include "../Evaluator.hpp" + class ScriptFunctionEvalValue : public EvalValue{ - BoundBlockStatement* _innerBlock; + std::shared_ptr _innerBlock; FunctionScriptType _type; public: - explicit ScriptFunctionEvalValue(BoundBlockStatement* innerBlock, const FunctionScriptType& type) + explicit ScriptFunctionEvalValue(std::shared_ptr innerBlock, const FunctionScriptType& type) : _type(type) { _innerBlock = innerBlock; @@ -21,10 +23,6 @@ public: return new ScriptFunctionEvalValue(_innerBlock, _type); } - ~ScriptFunctionEvalValue() final{ - delete _innerBlock; - } - ScriptType* GetType() final{ return &_type; }; @@ -42,13 +40,13 @@ public: for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){ auto parameter = parameters[i]; auto requiredType = parameterTypes[i]; - if (parameter->GetType() != requiredType){ + if (parameter->GetType() != requiredType.get()){ throw EvaluationException("Passed wrong type to function."); } 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; } }; diff --git a/src/Parser/ParsedExpressions/ParsedExpression.hpp b/src/Parser/ParsedExpressions/ParsedExpression.hpp index c74f871..933ff2e 100644 --- a/src/Parser/ParsedExpressions/ParsedExpression.hpp +++ b/src/Parser/ParsedExpressions/ParsedExpression.hpp @@ -215,5 +215,10 @@ public: } }; +class FunctionCallExpression : public ParsedExpression{ + +public: +}; + #endif //PORYGONLANG_PARSEDEXPRESSION_HPP diff --git a/src/ScriptType.hpp b/src/ScriptType.hpp index cf498f6..67d6fbf 100644 --- a/src/ScriptType.hpp +++ b/src/ScriptType.hpp @@ -1,8 +1,12 @@ +#include + #ifndef PORYGONLANG_SCRIPTTYPE_HPP #define PORYGONLANG_SCRIPTTYPE_HPP #include #include +#include +#include "Binder/BoundVariables/BoundVariableKey.hpp" enum class TypeClass{ Error, @@ -58,40 +62,28 @@ public: }; class FunctionScriptType : public ScriptType{ - ScriptType* _returnType; - std::vector _parameterTypes; - std::vector _parameterKeys; - int _scopeId; + std::shared_ptr _returnType; + std::vector> _parameterTypes; + std::vector> _parameterKeys; public: - FunctionScriptType(ScriptType* returnType, std::vector parameterTypes, std::vector parameterKeys, int scopeId) + FunctionScriptType(std::shared_ptr returnType, std::vector> parameterTypes, + std::vector> parameterKeys) : ScriptType(TypeClass::Function){ - _returnType = returnType; + _returnType = std::move(returnType); _parameterTypes = std::move(parameterTypes); _parameterKeys = std::move(parameterKeys); - _scopeId = scopeId; } - ~FunctionScriptType() final{ - delete _returnType; - for (auto t: _parameterTypes){ - delete t; - } - } - ScriptType* GetReturnType(){ - return _returnType; + return _returnType.get(); } - std::vector GetParameterTypes(){ + std::vector> GetParameterTypes(){ return _parameterTypes; } - std::vector GetParameterKeys(){ + std::vector> GetParameterKeys(){ return _parameterKeys; } - - int GetScopeId(){ - return _scopeId; - } }; #endif //PORYGONLANG_SCRIPTTYPE_HPP diff --git a/tests/integration/Functions.cpp b/tests/integration/Functions.cpp index cc9c16b..548fdb6 100644 --- a/tests/integration/Functions.cpp +++ b/tests/integration/Functions.cpp @@ -12,6 +12,4 @@ TEST_CASE( "Define script function", "[integration]" ) { delete script; } - - #endif