Rework evaluation to use shared pointers, fix bugs

This commit is contained in:
Deukhoofd 2019-06-01 21:38:39 +02:00
parent 4408cf00cd
commit 6206fef4c5
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
17 changed files with 122 additions and 133 deletions

View File

@ -90,7 +90,7 @@ VariableAssignment BoundScope::AssignVariable(int identifier, const std::shared_
} else{
// Assigning
auto var = this->GetVariable(exists, identifier);
if (var->GetType() != type){
if (var->GetType().get()->operator!=(type.get())){
return VariableAssignment(VariableAssignmentResult::VariableDefinedWithDifferentType, nullptr);
}
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, exists, false));

View File

@ -1,3 +1,5 @@
#include <utility>
#ifndef PORYGONLANG_BOUNDVARIABLE_HPP
#define PORYGONLANG_BOUNDVARIABLE_HPP
@ -10,9 +12,7 @@ using namespace std;
class BoundVariable{
std::shared_ptr<ScriptType> _type;
public:
explicit BoundVariable(std::shared_ptr<ScriptType> type) : _type(type){
}
~BoundVariable(){
explicit BoundVariable(std::shared_ptr<ScriptType> type) : _type(std::move(type)){
}
std::shared_ptr<ScriptType> GetType(){

View File

@ -5,68 +5,58 @@
#include "EvalValues/NumericEvalValue.hpp"
#include "EvalValues/StringEvalValue.hpp"
NumericEvalValue* Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
NumericEvalValue* leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
NumericEvalValue* rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
NumericEvalValue* result;
switch (expression->GetOperation()){
case BoundBinaryOperation ::Addition:
result = leftValue -> operator+ (rightValue);
result = leftValue.get() -> operator+ (rightValue.get());
break;
case BoundBinaryOperation::Subtraction:
result = leftValue -> operator- (rightValue);
result = leftValue.get() -> operator- (rightValue.get());
break;
case BoundBinaryOperation::Multiplication:
result = leftValue -> operator* (rightValue);
result = leftValue.get() -> operator* (rightValue.get());
break;
case BoundBinaryOperation::Division:
result = leftValue -> operator/ (rightValue);
result = leftValue.get() -> operator/ (rightValue.get());
break;
default:
delete leftValue;
delete rightValue;
throw EvaluationException("Can't evaluate operation to numeric");
}
delete leftValue;
delete rightValue;
return result;
return shared_ptr<NumericEvalValue>(result);
}
BooleanEvalValue* Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expression){
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expression){
switch (expression->GetOperation()){
case BoundBinaryOperation::Equality:
{
EvalValue* leftValue = this -> EvaluateExpression(expression->GetLeft());
EvalValue* rightValue = this -> EvaluateExpression(expression->GetRight());
bool equals = leftValue->operator==(rightValue);
delete leftValue;
delete rightValue;
return new BooleanEvalValue(equals);
auto leftValue = this -> EvaluateExpression(expression->GetLeft());
auto rightValue = this -> EvaluateExpression(expression->GetRight());
bool equals = leftValue.get()->operator==(rightValue.get());
return make_shared<BooleanEvalValue>(equals);
}
case BoundBinaryOperation::Inequality:
{
EvalValue* leftValue = this -> EvaluateExpression(expression->GetLeft());
EvalValue* rightValue = this -> EvaluateExpression(expression->GetRight());
bool equals = leftValue->operator!=(rightValue);
delete leftValue;
delete rightValue;
return new BooleanEvalValue(equals);
auto leftValue = this -> EvaluateExpression(expression->GetLeft());
auto rightValue = this -> EvaluateExpression(expression->GetRight());
bool equals = leftValue.get()->operator!=(rightValue.get());
return make_shared<BooleanEvalValue>(equals);
}
case BoundBinaryOperation::LogicalAnd:
{
BooleanEvalValue* leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
auto leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
if (!leftValue->EvaluateBool()) return leftValue;
delete leftValue;
BooleanEvalValue* rightValue = this -> EvaluateBoolExpression(expression->GetRight());
auto rightValue = this -> EvaluateBoolExpression(expression->GetRight());
return rightValue;
}
case BoundBinaryOperation::LogicalOr:
{
BooleanEvalValue* leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
auto leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
if (leftValue->EvaluateBool()) return leftValue;
delete leftValue;
BooleanEvalValue* rightValue = this -> EvaluateBoolExpression(expression->GetRight());
auto rightValue = this -> EvaluateBoolExpression(expression->GetRight());
return rightValue;
}
default:
@ -74,15 +64,13 @@ BooleanEvalValue* Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expres
}
}
StringEvalValue* Evaluator::EvaluateStringBinary(BoundBinaryExpression* expression){
shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(BoundBinaryExpression* expression){
if (expression->GetOperation() != BoundBinaryOperation::Concatenation)
throw;
std::ostringstream strs;
auto left = this -> EvaluateStringExpression(expression->GetLeft());
strs << left->EvaluateString();
delete left;
auto right = this -> EvaluateExpression(expression->GetRight());
strs << right->EvaluateString();
delete right;
return new StringEvalValue(strs.str());
return make_shared<StringEvalValue>(strs.str());
}

View File

@ -20,7 +20,7 @@ public:
return ! (this->operator==(b));
}
virtual EvalValue* Clone() = 0;
virtual shared_ptr<EvalValue> Clone() = 0;
virtual long EvaluateInteger(){
throw EvaluationException("Can't evaluate this EvalValue as integer.");
@ -45,8 +45,8 @@ public:
_type = std::make_shared<ScriptType>(TypeClass::Bool);
}
EvalValue* Clone() final{
return new BooleanEvalValue(_value);
shared_ptr<EvalValue> Clone() final{
return make_shared<BooleanEvalValue>(_value);
}
std::shared_ptr<ScriptType> GetType() final{

View File

@ -48,8 +48,8 @@ public:
return strs.str();
}
EvalValue* Clone() final{
return new IntegerEvalValue(_value);
shared_ptr<EvalValue> Clone() final{
return make_shared<IntegerEvalValue>(_value);
}
};
@ -76,8 +76,8 @@ public:
return strs.str();
}
EvalValue* Clone() final{
return new FloatEvalValue(_value);
shared_ptr<EvalValue> Clone() final{
return make_shared<FloatEvalValue>(_value);
}
};

View File

@ -25,10 +25,11 @@ public:
return _type;
}
EvalValue* Clone() final{
return new ScriptFunctionEvalValue(_innerBlock, _type);
shared_ptr<EvalValue> Clone() final{
return make_shared<ScriptFunctionEvalValue>(_innerBlock, _type);
}
bool operator ==(EvalValue* b) final{
if (b->GetType()->GetClass() != TypeClass::Function)
return false;

View File

@ -29,8 +29,8 @@ public:
return _value;
}
EvalValue* Clone() final{
return new StringEvalValue(_value);
shared_ptr<EvalValue> Clone() final{
return make_shared<StringEvalValue>(_value);
}
};

View File

@ -1,25 +1,22 @@
#include "EvaluationScope.hpp"
#include <memory>
EvaluationScope::EvaluationScope(unordered_map<int, EvalValue *> *scriptVariables, int deepestScope) {
EvaluationScope::EvaluationScope(unordered_map<int, shared_ptr<EvalValue>> *scriptVariables, int deepestScope) {
_scriptScope = scriptVariables;
_localScope = vector<unordered_map<int, EvalValue*>>(deepestScope);
_localScope = vector<unordered_map<int, shared_ptr<EvalValue>>>(deepestScope);
_currentScope = -1;
}
EvaluationScope::~EvaluationScope() {
_localScope.clear();
}
void EvaluationScope::CreateVariable(int scope, int id, EvalValue *value) {
void EvaluationScope::CreateVariable(int scope, int id, shared_ptr<EvalValue> value) {
if (scope == 0){
_scriptScope->insert_or_assign(id, value);
} else{
_localScope[scope - 1].insert({id, value});
_localScope[scope - 1].insert_or_assign(id, value);
}
}
void EvaluationScope::SetVariable(int scope, int id, EvalValue *value) {
void EvaluationScope::SetVariable(int scope, int id, shared_ptr<EvalValue> value) {
if (scope == 0){
_scriptScope->insert_or_assign(id, value);
} else{
@ -27,7 +24,7 @@ void EvaluationScope::SetVariable(int scope, int id, EvalValue *value) {
}
}
EvalValue *EvaluationScope::GetVariable(int scope, int id) {
shared_ptr<EvalValue> EvaluationScope::GetVariable(int scope, int id) {
if (scope == 0){
return _scriptScope->at(id);
}
@ -40,9 +37,7 @@ void EvaluationScope::OuterScope() {
void EvaluationScope::InnerScope() {
auto scope = this->_localScope[_currentScope];
for (auto v: scope){
delete v.second;
}
scope.clear();
_currentScope--;
}

View File

@ -7,18 +7,18 @@
#include "../EvalValues/EvalValue.hpp"
class EvaluationScope {
unordered_map<int, EvalValue*>* _scriptScope;
vector<unordered_map<int, EvalValue*>> _localScope;
unordered_map<int, shared_ptr<EvalValue>>* _scriptScope;
vector<unordered_map<int, shared_ptr<EvalValue>>> _localScope;
int _currentScope;
public:
explicit EvaluationScope(unordered_map<int, EvalValue*>* scriptVariables, int deepestScope);
~EvaluationScope();
explicit EvaluationScope(unordered_map<int, shared_ptr<EvalValue>>* scriptVariables, int deepestScope);
~EvaluationScope() = default;
void CreateVariable(int scope, int id, EvalValue* value);
void SetVariable(int scope, int id, EvalValue* value);
void CreateVariable(int scope, int id, shared_ptr<EvalValue> value);
void SetVariable(int scope, int id, shared_ptr<EvalValue> value);
void OuterScope();
void InnerScope();
EvalValue* GetVariable(int scope, int id);
shared_ptr<EvalValue> GetVariable(int scope, int id);
};

View File

@ -1,10 +1,13 @@
#include <memory>
#include "Evaluator.hpp"
#include "EvaluationException.hpp"
#include "../Script.hpp"
#include "EvaluationScope/EvaluationScope.hpp"
#include "EvalValues/ScriptFunctionEvalValue.hpp"
using namespace std;
void Evaluator::Evaluate(BoundScriptStatement *statement) {
this->_evaluationScope = new EvaluationScope(this->_scriptData->_scriptVariables, statement->GetDeepestScope());
EvaluateBlockStatement(statement);
@ -32,8 +35,6 @@ void Evaluator::EvaluateBlockStatement(BoundBlockStatement* statement) {
}
void Evaluator::EvaluateExpressionStatement(BoundExpressionStatement *statement) {
// Delete previously saved value.
delete this->_scriptData->_lastValue;
// Save new value
this->_scriptData->_lastValue = this -> EvaluateExpression(statement->GetExpression());
}
@ -52,7 +53,7 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta
auto type = statement->GetType();
auto key = statement->GetKey();
auto block = statement->GetBlock();
auto value = new ScriptFunctionEvalValue(block, type);
auto value = make_shared<ScriptFunctionEvalValue>(block, type);
if (key->IsCreation()){
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), value);
} else{
@ -60,7 +61,7 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta
}
}
EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
shared_ptr<EvalValue> Evaluator::EvaluateExpression(BoundExpression *expression) {
auto type = expression -> GetType();
switch (type->GetClass()){
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
@ -72,18 +73,18 @@ EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
}
}
EvalValue* Evaluator::GetVariable(BoundVariableExpression* expression){
shared_ptr<EvalValue> Evaluator::GetVariable(BoundVariableExpression* expression){
return this->_evaluationScope->GetVariable(expression->GetScope(), expression->GetId())->Clone();
}
NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expression) {
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(BoundExpression *expression) {
switch (expression->GetKind()){
case BoundExpressionKind ::LiteralInteger: return new IntegerEvalValue(((BoundLiteralIntegerExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralFloat: return new FloatEvalValue(((BoundLiteralFloatExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralInteger: return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralFloat: return make_shared<FloatEvalValue>(((BoundLiteralFloatExpression*)expression)->GetValue());
case BoundExpressionKind::Unary: return this -> EvaluateIntegerUnary((BoundUnaryExpression*)expression);
case BoundExpressionKind ::Binary: return this -> EvaluateIntegerBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Variable: return (NumericEvalValue*)this->GetVariable((BoundVariableExpression*)expression);
case BoundExpressionKind ::FunctionCall: return (NumericEvalValue*)this->EvaluateFunctionCallExpression(expression);
case BoundExpressionKind::Variable: return dynamic_pointer_cast<NumericEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
case BoundExpressionKind ::LiteralString:
case BoundExpressionKind ::LiteralBool:
@ -92,13 +93,13 @@ NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expressi
}
}
BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralBool: return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Variable: return (BooleanEvalValue*)this->GetVariable((BoundVariableExpression*)expression);
case BoundExpressionKind ::FunctionCall: return (BooleanEvalValue*)this->EvaluateFunctionCallExpression(expression);
case BoundExpressionKind::Variable: return dynamic_pointer_cast<BooleanEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:
@ -109,14 +110,14 @@ BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression)
}
}
StringEvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {
shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind::LiteralString:
return new StringEvalValue(((BoundLiteralStringExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralString:
return make_shared<StringEvalValue>(((BoundLiteralStringExpression*)expression)->GetValue());
case BoundExpressionKind::Binary:
return this -> EvaluateStringBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Variable: return (StringEvalValue*)this->GetVariable((BoundVariableExpression*)expression);
case BoundExpressionKind ::FunctionCall: return (StringEvalValue*)this->EvaluateFunctionCallExpression(expression);
case BoundExpressionKind::Variable: return dynamic_pointer_cast<StringEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:
@ -128,13 +129,13 @@ StringEvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression
}
}
EvalValue* Evaluator::EvaluateFunctionExpression(BoundExpression * expression){
shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(BoundExpression * expression){
switch (expression->GetKind()){
case BoundExpressionKind ::Variable: return this->GetVariable((BoundVariableExpression*)expression);
default: throw;
}
}
EvalValue* Evaluator::EvaluateNilExpression(BoundExpression * expression){
shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(BoundExpression * expression){
switch (expression->GetKind()){
case BoundExpressionKind ::FunctionCall:
return this->EvaluateFunctionCallExpression(expression);
@ -144,11 +145,11 @@ EvalValue* Evaluator::EvaluateNilExpression(BoundExpression * expression){
}
EvalValue* Evaluator::EvaluateFunctionCallExpression(BoundExpression* expression){
shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression* expression){
auto functionCall = (BoundFunctionCallExpression*)expression;
auto function = (ScriptFunctionEvalValue*)this->EvaluateExpression(functionCall->GetFunctionExpression());
auto function = dynamic_pointer_cast<ScriptFunctionEvalValue>(this->EvaluateExpression(functionCall->GetFunctionExpression()));
auto boundParameters = functionCall->GetParameters();
auto parameters = vector<EvalValue*>(boundParameters.size());
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters.size());
for (int i = 0; i < boundParameters.size(); i++){
parameters[i] = this->EvaluateExpression(boundParameters[i]);
}

View File

@ -3,7 +3,6 @@
#define PORYGONLANG_EVALUATOR_HPP
#include <string>
#include <boost/any.hpp>
#include "../Binder/BoundStatements/BoundStatement.hpp"
#include "../Script.hpp"
#include "EvalValues/EvalValue.hpp"
@ -12,10 +11,10 @@
#include "EvalValues/StringEvalValue.hpp"
#include "EvaluationScope/EvaluationScope.hpp"
using namespace boost;
using namespace std;
class Evaluator {
EvalValue* _result;
shared_ptr<EvalValue> _result;
Script* _scriptData;
EvaluationScope* _evaluationScope;
@ -25,31 +24,29 @@ class Evaluator {
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
EvalValue* EvaluateExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
BooleanEvalValue* EvaluateBoolExpression(BoundExpression* expression);
StringEvalValue* EvaluateStringExpression(BoundExpression* expression);
EvalValue* EvaluateFunctionExpression(BoundExpression *expression);
EvalValue *EvaluateNilExpression(BoundExpression *expression);
shared_ptr<EvalValue> EvaluateExpression(BoundExpression* expression);
shared_ptr<NumericEvalValue> EvaluateIntegerExpression(BoundExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBoolExpression(BoundExpression* expression);
shared_ptr<StringEvalValue> EvaluateStringExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateFunctionExpression(BoundExpression *expression);
shared_ptr<EvalValue>EvaluateNilExpression(BoundExpression *expression);
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
StringEvalValue *EvaluateStringBinary(BoundBinaryExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerBinary(BoundBinaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanBinary(BoundBinaryExpression *expression);
shared_ptr<StringEvalValue> EvaluateStringBinary(BoundBinaryExpression *expression);
NumericEvalValue* EvaluateIntegerUnary(BoundUnaryExpression* expression);
BooleanEvalValue *EvaluateBooleanUnary(BoundUnaryExpression *expression);
EvalValue *EvaluateFunctionCallExpression(BoundExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerUnary(BoundUnaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanUnary(BoundUnaryExpression *expression);
shared_ptr<EvalValue> EvaluateFunctionCallExpression(BoundExpression *expression);
EvalValue *GetVariable(BoundVariableExpression *expression);
shared_ptr<EvalValue> GetVariable(BoundVariableExpression *expression);
public:
explicit Evaluator(Script* script){
_scriptData = script;
_result = nullptr;
_evaluationScope = nullptr;
}
~Evaluator(){
delete _result;
delete _evaluationScope;
}

View File

@ -4,19 +4,17 @@
#include "EvaluationException.hpp"
#include "../Script.hpp"
NumericEvalValue *Evaluator::EvaluateIntegerUnary(BoundUnaryExpression *expression) {
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::Negation:
{
auto operandValue = EvaluateIntegerExpression(expression->GetOperand());
if (operandValue->IsFloat()){
double f = operandValue->EvaluateFloat();
delete operandValue;
return new FloatEvalValue(-f);
return make_shared<FloatEvalValue>(-f);
} else{
long l = operandValue->EvaluateInteger();
delete operandValue;
return new IntegerEvalValue(-l);
return make_shared<IntegerEvalValue>(-l);
}
}
case BoundUnaryOperation::LogicalNegation:
@ -24,14 +22,13 @@ NumericEvalValue *Evaluator::EvaluateIntegerUnary(BoundUnaryExpression *expressi
}
}
BooleanEvalValue *Evaluator::EvaluateBooleanUnary(BoundUnaryExpression *expression) {
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanUnary(BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::LogicalNegation:
{
auto val = EvaluateBoolExpression(expression->GetOperand());
bool b = val->EvaluateBool();
delete val;
return new BooleanEvalValue(!b);
return make_shared<BooleanEvalValue>(!b);
}
case BoundUnaryOperation::Negation:
throw;

View File

@ -1,4 +1,5 @@
#include <algorithm>
#include "Parser.hpp"
#include "ParsedStatements/ParsedStatement.hpp"
#include "UnaryOperatorKind.hpp"
@ -65,7 +66,7 @@ ParsedStatement *Parser::ParseAssignment(IToken *current) {
return new ParsedAssignmentStatement(isLocal, ((IdentifierToken*)identifier) -> Value, expression, start, expression->GetEndPosition() - start);
}
ParsedStatement *Parser::ParseBlock(vector<TokenKind> endTokens) {
ParsedStatement *Parser::ParseBlock(const vector<TokenKind>& endTokens) {
vector<ParsedStatement*> statements;
while (true){
auto next = this -> Next();

View File

@ -1,9 +1,9 @@
#include <utility>
#ifndef PORYGONLANG_PARSER_HPP
#define PORYGONLANG_PARSER_HPP
#include <utility>
#include <vector>
#include "ParsedStatements/ParsedStatement.hpp"
#include "../Script.hpp"
@ -27,7 +27,7 @@ class Parser {
ParsedStatement* ParseStatement(IToken* current);
ParsedStatement* ParseAssignment(IToken* current);
ParsedStatement *ParseBlock(vector<TokenKind> endTokens);
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens);
ParsedStatement* ParseFunctionDeclaration(IToken* current);
ParsedExpression* ParseExpression(IToken* current);

View File

@ -16,7 +16,7 @@ Script::Script() {
_evaluator = new Evaluator(this);
_lastValue = nullptr;
BoundScript = nullptr;
_scriptVariables = new unordered_map<int, EvalValue*>(0);
_scriptVariables = new unordered_map<int, shared_ptr<EvalValue>>(0);
}
void Script::Evaluate() {
@ -26,11 +26,7 @@ void Script::Evaluate() {
Script::~Script() {
delete this -> Diagnostics;
delete this -> BoundScript;
delete this -> _lastValue;
delete this -> _evaluator;
for (auto v : *this->_scriptVariables){
delete v.second;
}
this->_scriptVariables->clear();
delete this->_scriptVariables;
}
@ -58,7 +54,7 @@ void Script::Parse(string script) {
}
EvalValue *Script::GetVariable(const string &key) {
return _scriptVariables -> at(HashedString(key).GetHash());
return _scriptVariables -> at(HashedString(key).GetHash()).get();
}
bool Script::HasVariable(const string &key) {

View File

@ -19,9 +19,9 @@ using namespace std;
class Script {
friend class Evaluator;
EvalValue* _lastValue;
shared_ptr<EvalValue> _lastValue;
Evaluator* _evaluator;
unordered_map<int, EvalValue*>* _scriptVariables;
unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables;
explicit Script();
@ -36,7 +36,7 @@ public:
void Evaluate();
EvalValue* GetLastValue(){
return _lastValue;
return _lastValue.get();
};
EvalValue* GetVariable(const string& key);

View File

@ -25,4 +25,17 @@ TEST_CASE( "Define script function and call", "[integration]" ) {
delete script;
}
TEST_CASE( "Define script function and call multiple times", "[integration]" ) {
Script* script = Script::Create("result = 0 function add(number a) result = result + a end add(1) add(4)");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto variable = script->GetVariable("add");
REQUIRE(variable != nullptr);
REQUIRE(variable->GetType()->GetClass() == TypeClass::Function);
auto result = script->GetVariable("result");
REQUIRE(result->GetType()->GetClass() == TypeClass::Number);
REQUIRE(result->EvaluateInteger() == 5);
delete script;
}
#endif