diff options
author | Jan de Visser <jan@de-visser.net> | 2021-10-21 18:10:25 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-25 12:59:42 +0200 |
commit | 9d1e27d8a880aa0d1bd7c61aba2f6f843826b6ba (patch) | |
tree | cb6f8aa55e82b2fa4625b4fb155e1740f197dad3 | |
parent | 73fc02365233d7ac0e29728beb129354c8b67c41 (diff) | |
download | serenity-9d1e27d8a880aa0d1bd7c61aba2f6f843826b6ba.zip |
LibSQL: Implement evaluate() method of BinaryOperatorExpression
Mostly just calls the appropriate methods on the Value objects.
Exception are the `Concatenate` (string concat), and the logical `and`
and `or` operators which are implemented directly in
`BinaryOperatorExpression::evaluate`
-rw-r--r-- | Userland/Libraries/LibSQL/AST/AST.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/AST/Expression.cpp | 66 |
2 files changed, 67 insertions, 0 deletions
diff --git a/Userland/Libraries/LibSQL/AST/AST.h b/Userland/Libraries/LibSQL/AST/AST.h index 168a61bb1d..06f2f2fdbc 100644 --- a/Userland/Libraries/LibSQL/AST/AST.h +++ b/Userland/Libraries/LibSQL/AST/AST.h @@ -490,6 +490,7 @@ public: } BinaryOperator type() const { return m_type; } + virtual Value evaluate(ExecutionContext&) const override; private: BinaryOperator m_type; diff --git a/Userland/Libraries/LibSQL/AST/Expression.cpp b/Userland/Libraries/LibSQL/AST/Expression.cpp index c9c20d2892..cd53fa66f0 100644 --- a/Userland/Libraries/LibSQL/AST/Expression.cpp +++ b/Userland/Libraries/LibSQL/AST/Expression.cpp @@ -49,6 +49,72 @@ Value ChainedExpression::evaluate(ExecutionContext& context) const return ret; } +Value BinaryOperatorExpression::evaluate(ExecutionContext& context) const +{ + Value lhs_value = lhs()->evaluate(context); + Value rhs_value = rhs()->evaluate(context); + switch (type()) { + case BinaryOperator::Concatenate: { + if (lhs_value.type() != SQLType::Text) { + VERIFY_NOT_REACHED(); + } + AK::StringBuilder builder; + builder.append(lhs_value.to_string()); + builder.append(rhs_value.to_string()); + return Value(builder.to_string()); + } + case BinaryOperator::Multiplication: + return lhs_value.multiply(rhs_value); + case BinaryOperator::Division: + return lhs_value.divide(rhs_value); + case BinaryOperator::Modulo: + return lhs_value.modulo(rhs_value); + case BinaryOperator::Plus: + return lhs_value.add(rhs_value); + case BinaryOperator::Minus: + return lhs_value.subtract(rhs_value); + case BinaryOperator::ShiftLeft: + return lhs_value.shift_left(rhs_value); + case BinaryOperator::ShiftRight: + return lhs_value.shift_right(rhs_value); + case BinaryOperator::BitwiseAnd: + return lhs_value.bitwise_and(rhs_value); + case BinaryOperator::BitwiseOr: + return lhs_value.bitwise_or(rhs_value); + case BinaryOperator::LessThan: + return Value(lhs_value.compare(rhs_value) < 0); + case BinaryOperator::LessThanEquals: + return Value(lhs_value.compare(rhs_value) <= 0); + case BinaryOperator::GreaterThan: + return Value(lhs_value.compare(rhs_value) > 0); + case BinaryOperator::GreaterThanEquals: + return Value(lhs_value.compare(rhs_value) >= 0); + case BinaryOperator::Equals: + return Value(lhs_value.compare(rhs_value) == 0); + case BinaryOperator::NotEquals: + return Value(lhs_value.compare(rhs_value) != 0); + case BinaryOperator::And: { + auto lhs_bool_maybe = lhs_value.to_bool(); + auto rhs_bool_maybe = rhs_value.to_bool(); + if (!lhs_bool_maybe.has_value() || !rhs_bool_maybe.has_value()) { + // TODO Error handling + VERIFY_NOT_REACHED(); + } + return Value(lhs_bool_maybe.value() && rhs_bool_maybe.value()); + } + case BinaryOperator::Or: { + auto lhs_bool_maybe = lhs_value.to_bool(); + auto rhs_bool_maybe = rhs_value.to_bool(); + if (!lhs_bool_maybe.has_value() || !rhs_bool_maybe.has_value()) { + // TODO Error handling + VERIFY_NOT_REACHED(); + } + return Value(lhs_bool_maybe.value() || rhs_bool_maybe.value()); + } + } + VERIFY_NOT_REACHED(); +} + Value UnaryOperatorExpression::evaluate(ExecutionContext& context) const { Value expression_value = NestedExpression::evaluate(context); |