Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src / ASTInterpreter.cpp
diff options
context:
space:
mode:
Commitd8704c516b3a8b32817ffcad1868d7cd135efe48 (patch)
Author
 Dimitar Trendafilov <trendafilov.dn@gmail.com>
2020-11-01 21:34:40 +0200
Committer
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2020-11-09 22:08:19 +0200
Files9aa5a380b09ef52e899a54ac90d347a917b904ee /JSImpl/src/ASTInterpreter.cpp
IPL-d8704c516b3a8b32817ffcad1868d7cd135efe48.tar
IPL-d8704c516b3a8b32817ffcad1868d7cd135efe48.tar.gz
IPL-d8704c516b3a8b32817ffcad1868d7cd135efe48.zip
Parentb93662dbcc9d30c69cce7d1342606cafc60bb3f0 (diff)
Move AST interpreter value to std::variant
1 files changed, 145 insertions, 16 deletions
-rw-r--r--JSImpl/src/ASTInterpreter.cpp161
diff --git a/JSImpl/src/ASTInterpreter.cpp b/JSImpl/src/ASTInterpreter.cpp
index ae0d2b5..fd631ca 100644
--- a/JSImpl/src/ASTInterpreter.cpp
+++ b/JSImpl/src/ASTInterpreter.cpp
@@ -11,14 +11,135 @@ namespace
template <typename T>
ASTInterpreter::ValuePtr MakeValue(T&& v)
{
- return IPLMakeSharePtr<double>(v);
+ return IPLMakeSharePtr<ASTInterpreter::Value>(v);
}
template <typename T>
ASTInterpreter::ValuePtr MakeValue(const T& v)
{
- return IPLMakeSharePtr<double>(v);
+ return IPLMakeSharePtr<ASTInterpreter::Value>(v);
}
+
+ struct ValueToBool
+ {
+ bool operator()(double d) const
+ {
+ return d != 0.0;
+ }
+ };
+
+ struct ValueAdd
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l + r);
+ }
+ };
+
+ struct ValueMinus
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l - r);
+ }
+ };
+ struct ValueProduct
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l * r);
+ }
+ };
+ struct ValueDivide
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l / r);
+ }
+ };
+ struct ValueLess
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l < r);
+ }
+ };
+ struct ValueLessEqual
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l <= r);
+ }
+ };
+ struct ValueGreater
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l > r);
+ }
+ };
+ struct ValueGreaterEqual
+ {
+ ASTInterpreter::ValuePtr operator()(double l, double r) const
+ {
+ return MakeValue(l >= r);
+ }
+ };
+
+ struct ValueEqualEqual
+ {
+ ASTInterpreter::ValuePtr operator()(double left, double right) const
+ {
+ return MakeValue(fabs(left - right) <= 0.0001);
+ }
+ };
+
+ struct ValueBangEqual
+ {
+ ASTInterpreter::ValuePtr operator()(double left, double right) const
+ {
+ return MakeValue(fabs(left - right) > 0.0001);
+ }
+ };
+
+ struct ValueUnaryMinus
+ {
+ ASTInterpreter::ValuePtr operator()(double v) const
+ {
+ return MakeValue(-v);
+ }
+ };
+ struct ValueIncrement
+ {
+ void operator()(double& v) const
+ {
+ v += 1;
+ }
+ };
+
+ struct ValueDecrement
+ {
+ void operator()(double& v) const
+ {
+ v -= 1;
+ }
+ };
+
+ struct ValuePrint
+ {
+ ValuePrint(const char* name, ASTInterpreter::Printer* printer)
+ : Name(name)
+ , Printer(printer)
+ {}
+
+ void operator()(double value) const
+ {
+ Printer->PrintVariable(Name, value);
+ }
+
+ const char* Name;
+ ASTInterpreter::Printer* Printer;
+ };
}
struct LValueExtractor : public ExpressionVisitor
@@ -113,7 +234,7 @@ bool ASTInterpreter::EvalToBool(const ExpressionPtr& e)
e->Accept(*this);
auto result = m_Evaluation.back();
m_Evaluation.pop_back();
- return *result != 0.0;
+ return std::visit(ValueToBool(), *result);
}
void ASTInterpreter::EnterScope()
@@ -186,37 +307,37 @@ void ASTInterpreter::Visit(BinaryExpression* e) {
switch (e->GetOperator()) {
case TokenType::Plus:
- m_Evaluation.push_back(MakeValue(left + right));
+ m_Evaluation.push_back(std::visit(ValueAdd(), left, right));
break;
case TokenType::Minus:
- m_Evaluation.push_back(MakeValue(left - right));
+ m_Evaluation.push_back(std::visit(ValueMinus(), left, right));
break;
case TokenType::Star:
- m_Evaluation.push_back(MakeValue(left * right));
+ m_Evaluation.push_back(std::visit(ValueProduct(), left, right));
break;
case TokenType::Division:
- m_Evaluation.push_back(MakeValue(left / right));
+ m_Evaluation.push_back(std::visit(ValueDivide(), left, right));
break;
case TokenType::Less:
- m_Evaluation.push_back(MakeValue(left < right));
+ m_Evaluation.push_back(std::visit(ValueLess(), left, right));
break;
case TokenType::LessEqual:
- m_Evaluation.push_back(MakeValue(left <= right));
+ m_Evaluation.push_back(std::visit(ValueLessEqual(), left, right));
break;
case TokenType::Greater:
- m_Evaluation.push_back(MakeValue(left > right));
+ m_Evaluation.push_back(std::visit(ValueGreater(), left, right));
break;
case TokenType::GreaterEqual:
- m_Evaluation.push_back(MakeValue(left >= right));
+ m_Evaluation.push_back(std::visit(ValueGreaterEqual(), left, right));
break;
case TokenType::Comma:
m_Evaluation.push_back(MakeValue(std::move(right)));
break;
case TokenType::EqualEqual:
- m_Evaluation.push_back(MakeValue(fabs(left - right) < 0.0001));
+ m_Evaluation.push_back(std::visit(ValueEqualEqual(), left, right));
break;
case TokenType::BangEqual:
- m_Evaluation.push_back(MakeValue(fabs(left - right) > 0.0001));
+ m_Evaluation.push_back(std::visit(ValueBangEqual(), left, right));
break;
case TokenType::Equal:
{
@@ -238,7 +359,7 @@ void ASTInterpreter::Visit(UnaryExpression* e) {
e->GetExpr()->Accept(*this);
auto v = m_Evaluation.back();
m_Evaluation.pop_back();
- m_Evaluation.push_back(MakeValue(-(*v)));
+ m_Evaluation.push_back(std::visit(ValueUnaryMinus(), *v));
break;
}
case TokenType::Plus:
@@ -255,7 +376,14 @@ void ASTInterpreter::Visit(UnaryExpression* e) {
{
m_Evaluation.push_back(MakeValue(*lvalue));
}
- *lvalue += e->GetOperator() == TokenType::PlusPlus ? 1 : -1;
+ if (e->GetOperator() == TokenType::PlusPlus)
+ {
+ std::visit(ValueIncrement(), *lvalue);
+ }
+ else
+ {
+ std::visit(ValueDecrement(), *lvalue);
+ }
if (!e->GetSuffix())
{
m_Evaluation.push_back(MakeValue(*lvalue));
@@ -364,6 +492,7 @@ void ASTInterpreter::Print(Printer& p)
{
for (auto& it : m_Variables)
{
- p.PrintVariable(it.first.c_str(), *ModifyVariable(it.first));
+ auto& value = ModifyVariable(it.first);
+ std::visit(ValuePrint(it.first.c_str(), &p), *value);
}
}