Rework evaluation to use shared pointers, fix bugs
This commit is contained in:
parent
4408cf00cd
commit
6206fef4c5
|
@ -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));
|
||||
|
|
|
@ -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(){
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -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{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
return _value;
|
||||
}
|
||||
|
||||
EvalValue* Clone() final{
|
||||
return new StringEvalValue(_value);
|
||||
shared_ptr<EvalValue> Clone() final{
|
||||
return make_shared<StringEvalValue>(_value);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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--;
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue