Implements string evaluation and concat

This commit is contained in:
Deukhoofd 2019-05-25 16:15:20 +02:00
parent b536187593
commit 0205b92ae6
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
10 changed files with 123 additions and 6 deletions

View File

@ -79,8 +79,10 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Addition, new NumericScriptType(false, false),
expression->GetStartPosition(), expression->GetLength());
}
} else if (boundLeftType->GetClass() == TypeClass::String){
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Concatenation, new ScriptType(TypeClass::String),
expression->GetStartPosition(), expression->GetLength());
}
//TODO: String Concatenation
break;
case BinaryOperatorKind ::Subtraction:
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){

View File

@ -3,6 +3,7 @@
#include "EvaluationException.hpp"
#include "Evaluator.hpp"
#include "EvalValues/NumericEvalValue.hpp"
#include "EvalValues/StringEvalValue.hpp"
NumericEvalValue* Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
NumericEvalValue* leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
@ -71,4 +72,17 @@ BooleanEvalValue* Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expres
default:
throw EvaluationException("Can't evaluate operation to boolean");
}
}
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());
}

View File

@ -5,6 +5,7 @@
#include "../../ScriptType.hpp"
#include "../EvaluationException.hpp"
#include <string>
#include <sstream>
class EvalValue{
public:
@ -57,6 +58,12 @@ public:
return false;
return this->EvaluateBool() == b->EvaluateBool();
};
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
};
#endif //PORYGONLANG_EVALVALUE_HPP

View File

@ -2,6 +2,7 @@
#ifndef PORYGONLANG_NUMERICEVALVALUE_HPP
#define PORYGONLANG_NUMERICEVALVALUE_HPP
#include <sstream>
#include "EvalValue.hpp"
class NumericEvalValue : public EvalValue{
@ -43,6 +44,12 @@ public:
long EvaluateInteger() final{
return _value;
}
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
};
class FloatEvalValue : public NumericEvalValue{
@ -61,6 +68,12 @@ public:
double EvaluateFloat() final{
return _value;
}
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
};
#endif //PORYGONLANG_NUMERICEVALVALUE_HPP

View File

@ -0,0 +1,2 @@
#include "StringEvalValue.hpp"

View File

@ -0,0 +1,38 @@
#ifndef PORYGONLANG_STRINGEVALVALUE_HPP
#define PORYGONLANG_STRINGEVALVALUE_HPP
#include <string>
#include "EvalValue.hpp"
using namespace std;
class StringEvalValue : public EvalValue{
string _value;
ScriptType* _type;
public:
explicit StringEvalValue(string s){
_value = move(s);
_type = new ScriptType(TypeClass::String);
}
~StringEvalValue() final{
delete _type;
}
ScriptType* GetType() final{
return _type;
};
bool operator ==(EvalValue* b) final{
if (b->GetType()->GetClass() != TypeClass::String)
return false;
return this->_value == b->EvaluateString();
};
string EvaluateString() final{
return _value;
}
};
#endif //PORYGONLANG_STRINGEVALVALUE_HPP

View File

@ -33,6 +33,7 @@ EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
switch (type->GetClass()){
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
case TypeClass ::Bool: return this -> EvaluateBoolExpression(expression);
case TypeClass ::String: return this -> EvaluateStringExpression(expression);
default: throw;
}
}
@ -56,6 +57,7 @@ BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression)
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:
case BoundExpressionKind::LiteralFloat:
@ -65,7 +67,19 @@ BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression)
}
}
EvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {
return nullptr;
}
StringEvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind::LiteralString:
return new StringEvalValue(((BoundLiteralStringExpression*)expression)->GetValue());
case BoundExpressionKind::Binary:
return this -> EvaluateStringBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:
case BoundExpressionKind::LiteralFloat:
case BoundExpressionKind::LiteralBool:
case BoundExpressionKind::Unary:
throw;
}}

View File

@ -8,6 +8,7 @@
#include "../Script.hpp"
#include "EvalValues/EvalValue.hpp"
#include "EvalValues/NumericEvalValue.hpp"
#include "EvalValues/StringEvalValue.hpp"
using namespace boost;
@ -24,10 +25,11 @@ class Evaluator {
EvalValue* EvaluateExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
BooleanEvalValue* EvaluateBoolExpression(BoundExpression* expression);
EvalValue* EvaluateStringExpression(BoundExpression* expression);
StringEvalValue* EvaluateStringExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
StringEvalValue *EvaluateStringBinary(BoundBinaryExpression *expression);
NumericEvalValue* EvaluateIntegerUnary(BoundUnaryExpression* expression);
BooleanEvalValue *EvaluateBooleanUnary(BoundUnaryExpression *expression);

View File

@ -20,7 +20,7 @@ public:
_class = c;
}
TypeClass GetClass(){
const TypeClass GetClass(){
return _class;
}
};

View File

@ -0,0 +1,25 @@
#ifdef TESTS_BUILD
#include <catch.hpp>
#include "../src/Script.hpp"
TEST_CASE( "Simple String", "[integration]" ) {
Script script = Script::Create("\"foo bar\"");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateString() == "foo bar");
}
TEST_CASE( "String Concat", "[integration]" ) {
Script script = Script::Create("\"foo\" + \"bar\"");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateString() == "foobar");
}
#endif