Implements string evaluation and concat
This commit is contained in:
parent
b536187593
commit
0205b92ae6
|
@ -79,8 +79,10 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Addition, new NumericScriptType(false, false),
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Addition, new NumericScriptType(false, false),
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
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;
|
break;
|
||||||
case BinaryOperatorKind ::Subtraction:
|
case BinaryOperatorKind ::Subtraction:
|
||||||
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
|
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "EvaluationException.hpp"
|
#include "EvaluationException.hpp"
|
||||||
#include "Evaluator.hpp"
|
#include "Evaluator.hpp"
|
||||||
#include "EvalValues/NumericEvalValue.hpp"
|
#include "EvalValues/NumericEvalValue.hpp"
|
||||||
|
#include "EvalValues/StringEvalValue.hpp"
|
||||||
|
|
||||||
NumericEvalValue* Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
|
NumericEvalValue* Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
|
||||||
NumericEvalValue* leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
NumericEvalValue* leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||||
|
@ -71,4 +72,17 @@ BooleanEvalValue* Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expres
|
||||||
default:
|
default:
|
||||||
throw EvaluationException("Can't evaluate operation to boolean");
|
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());
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../../ScriptType.hpp"
|
#include "../../ScriptType.hpp"
|
||||||
#include "../EvaluationException.hpp"
|
#include "../EvaluationException.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
class EvalValue{
|
class EvalValue{
|
||||||
public:
|
public:
|
||||||
|
@ -57,6 +58,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
return this->EvaluateBool() == b->EvaluateBool();
|
return this->EvaluateBool() == b->EvaluateBool();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string EvaluateString() final{
|
||||||
|
std::ostringstream strs;
|
||||||
|
strs << _value;
|
||||||
|
return strs.str();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_EVALVALUE_HPP
|
#endif //PORYGONLANG_EVALVALUE_HPP
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#ifndef PORYGONLANG_NUMERICEVALVALUE_HPP
|
#ifndef PORYGONLANG_NUMERICEVALVALUE_HPP
|
||||||
#define PORYGONLANG_NUMERICEVALVALUE_HPP
|
#define PORYGONLANG_NUMERICEVALVALUE_HPP
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include "EvalValue.hpp"
|
#include "EvalValue.hpp"
|
||||||
|
|
||||||
class NumericEvalValue : public EvalValue{
|
class NumericEvalValue : public EvalValue{
|
||||||
|
@ -43,6 +44,12 @@ public:
|
||||||
long EvaluateInteger() final{
|
long EvaluateInteger() final{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EvaluateString() final{
|
||||||
|
std::ostringstream strs;
|
||||||
|
strs << _value;
|
||||||
|
return strs.str();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatEvalValue : public NumericEvalValue{
|
class FloatEvalValue : public NumericEvalValue{
|
||||||
|
@ -61,6 +68,12 @@ public:
|
||||||
double EvaluateFloat() final{
|
double EvaluateFloat() final{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EvaluateString() final{
|
||||||
|
std::ostringstream strs;
|
||||||
|
strs << _value;
|
||||||
|
return strs.str();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_NUMERICEVALVALUE_HPP
|
#endif //PORYGONLANG_NUMERICEVALVALUE_HPP
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
#include "StringEvalValue.hpp"
|
|
@ -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
|
|
@ -33,6 +33,7 @@ EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
|
||||||
switch (type->GetClass()){
|
switch (type->GetClass()){
|
||||||
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
|
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
|
||||||
case TypeClass ::Bool: return this -> EvaluateBoolExpression(expression);
|
case TypeClass ::Bool: return this -> EvaluateBoolExpression(expression);
|
||||||
|
case TypeClass ::String: return this -> EvaluateStringExpression(expression);
|
||||||
default: throw;
|
default: throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +57,7 @@ BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression)
|
||||||
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
|
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
|
||||||
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
|
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
|
||||||
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
|
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
|
||||||
|
|
||||||
case BoundExpressionKind::Bad:
|
case BoundExpressionKind::Bad:
|
||||||
case BoundExpressionKind::LiteralInteger:
|
case BoundExpressionKind::LiteralInteger:
|
||||||
case BoundExpressionKind::LiteralFloat:
|
case BoundExpressionKind::LiteralFloat:
|
||||||
|
@ -65,7 +67,19 @@ BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {
|
StringEvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {
|
||||||
return nullptr;
|
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;
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../Script.hpp"
|
#include "../Script.hpp"
|
||||||
#include "EvalValues/EvalValue.hpp"
|
#include "EvalValues/EvalValue.hpp"
|
||||||
#include "EvalValues/NumericEvalValue.hpp"
|
#include "EvalValues/NumericEvalValue.hpp"
|
||||||
|
#include "EvalValues/StringEvalValue.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
@ -24,10 +25,11 @@ class Evaluator {
|
||||||
EvalValue* EvaluateExpression(BoundExpression* expression);
|
EvalValue* EvaluateExpression(BoundExpression* expression);
|
||||||
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
|
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
|
||||||
BooleanEvalValue* EvaluateBoolExpression(BoundExpression* expression);
|
BooleanEvalValue* EvaluateBoolExpression(BoundExpression* expression);
|
||||||
EvalValue* EvaluateStringExpression(BoundExpression* expression);
|
StringEvalValue* EvaluateStringExpression(BoundExpression* expression);
|
||||||
|
|
||||||
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
|
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
|
||||||
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
|
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
|
||||||
|
StringEvalValue *EvaluateStringBinary(BoundBinaryExpression *expression);
|
||||||
|
|
||||||
NumericEvalValue* EvaluateIntegerUnary(BoundUnaryExpression* expression);
|
NumericEvalValue* EvaluateIntegerUnary(BoundUnaryExpression* expression);
|
||||||
BooleanEvalValue *EvaluateBooleanUnary(BoundUnaryExpression *expression);
|
BooleanEvalValue *EvaluateBooleanUnary(BoundUnaryExpression *expression);
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
_class = c;
|
_class = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeClass GetClass(){
|
const TypeClass GetClass(){
|
||||||
return _class;
|
return _class;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue