Skip to content

Commit ad159d6

Browse files
committed
Remove ugly hack for ISEOF and MATCH
1 parent 13b774e commit ad159d6

File tree

4 files changed

+56
-40
lines changed

4 files changed

+56
-40
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ cc_library(
5858
hdrs = ["expression.h"],
5959
deps = [
6060
":parser",
61+
":stream",
6162
":value",
6263
":variable",
6364
"@com_google_absl//absl/strings",

checktestdata.cc

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -399,28 +399,11 @@ class Listener : public checktestdataBaseListener {
399399
} else if (ctx->function()) {
400400
switch (ctx->function()->getStart()->getType()) {
401401
case checktestdataParser::ISEOF: {
402-
Value v;
403-
expr_stack_.emplace_back([this, v]() mutable {
404-
v = Value{input_->empty()};
405-
return std::make_pair(false, &v);
406-
});
402+
expr_stack_.emplace_back(&input_);
407403
break;
408404
}
409405
case checktestdataParser::MATCH: {
410-
Value v;
411-
Expression clazz = pop_expr();
412-
expr_stack_.emplace_back([this, v, clazz]() mutable {
413-
const auto& s = std::get<Value::string>(clazz.eval().value_);
414-
v = Value{false};
415-
for (char c : s) {
416-
if (peek(*input_) == c) {
417-
v = Value{true};
418-
break;
419-
}
420-
}
421-
return std::make_pair(false, &v);
422-
});
423-
406+
expr_stack_.emplace_back(&input_, pop_expr());
424407
break;
425408
}
426409
default: {

expression.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <exception>
66
#include <mutex>
77

8+
#include "stream.h"
9+
810
#include "absl/strings/str_cat.h"
911

1012
namespace {
@@ -86,6 +88,8 @@ Value parseToken(const antlr4::Token* literal) {
8688
}
8789
} // namespace
8890

91+
Expression::Expression() = default;
92+
8993
Expression::Expression(Value v)
9094
: value_(std::move(v)), eval_(&Expression::constEval) {}
9195

@@ -131,6 +135,7 @@ Expression::Expression(const antlr4::Token* unop, Expression e) {
131135
}
132136
}
133137

138+
// UNIQUE, STRLEN, INARRAY functions
134139
Expression::Expression(const antlr4::Token* function,
135140
std::vector<Expression> arguments) {
136141
switch (function->getType()) {
@@ -154,6 +159,43 @@ Expression::Expression(const antlr4::Token* function,
154159
}
155160
}
156161

162+
// ISEOF function
163+
Expression::Expression(std::string_view** input)
164+
: eval_(&Expression::iseofEval), input_(input) {}
165+
166+
// MATCH function
167+
Expression::Expression(std::string_view** input, Expression match)
168+
: eval_(&Expression::matchEval), children_({match}), input_(input) {}
169+
170+
template <Expression::EvalFn inner>
171+
std::pair<bool, const Value*> Expression::foldConst() {
172+
auto result = (this->*inner)();
173+
if (result.first) {
174+
*this = Expression{*result.second};
175+
} else {
176+
eval_ = inner;
177+
}
178+
return callEval();
179+
}
180+
181+
std::pair<bool, const Value*> Expression::iseofEval() {
182+
value_ = Value{(**input_).empty()};
183+
return {false, &value_};
184+
}
185+
186+
std::pair<bool, const Value*> Expression::matchEval() {
187+
Value::string clazz = std::get<Value::string>(children_[0].eval().value_);
188+
bool found = false;
189+
for (char c : clazz) {
190+
if (peek(**input_) == c) {
191+
found = true;
192+
break;
193+
}
194+
}
195+
value_ = Value{found};
196+
return {false, &value_};
197+
}
198+
157199
std::pair<bool, const Value*> Expression::strlenEval() {
158200
auto res = children_[0].callEval();
159201
value_ = Value{

expression.h

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ class Expression {
1313
public:
1414
const Value& eval() { return *callEval().second; }
1515
void assign(const Value& v) { (this->*assign_)(v); }
16-
Expression() {}
16+
Expression();
1717
Expression(Value v);
1818
Expression(Variable* variable, std::vector<Expression> idx);
1919
Expression(const antlr4::Token* literal);
2020
Expression(const antlr4::Token* binop, Expression a, Expression b);
2121
Expression(const antlr4::Token* unop, Expression e);
22+
// UNIQUE, STRLEN, INARRAY functions
2223
Expression(const antlr4::Token* function, std::vector<Expression> arguments);
23-
template <typename F,
24-
typename _ = std::enable_if_t<std::is_invocable_v<F>, void>>
25-
Expression(F f)
26-
: eval_(&Expression::foldConst<&Expression::backdoorEval<F>>),
27-
context_(std::move(f)) {}
24+
// ISEOF function
25+
Expression(std::string_view** input);
26+
// MATCH function
27+
Expression(std::string_view** input, Expression match);
2828

2929
private:
3030
auto idx() {
@@ -36,15 +36,7 @@ class Expression {
3636
std::pair<bool, const Value*> constEval();
3737
using EvalFn = decltype(&Expression::constEval);
3838
template <EvalFn inner>
39-
std::pair<bool, const Value*> foldConst() {
40-
auto result = (this->*inner)();
41-
if (result.first) {
42-
*this = Expression{std::move(*result.second)};
43-
} else {
44-
eval_ = inner;
45-
}
46-
return callEval();
47-
}
39+
std::pair<bool, const Value*> foldConst();
4840
template <int op>
4941
std::pair<bool, const Value*> binopEval();
5042
std::pair<bool, const Value*> unaryMinusEval();
@@ -56,10 +48,8 @@ class Expression {
5648
std::pair<bool, const Value*> uniqueEval();
5749
std::pair<bool, const Value*> inarrayEval();
5850
std::pair<bool, const Value*> strlenEval();
59-
template <typename F>
60-
std::pair<bool, const Value*> backdoorEval() {
61-
return (*std::any_cast<F>(&context_))();
62-
}
51+
std::pair<bool, const Value*> iseofEval();
52+
std::pair<bool, const Value*> matchEval();
6353
template <size_t size>
6454
void variableArrayAssignment(const Value& value) {
6555
variable_->set<size>(idx(), value);
@@ -76,10 +66,10 @@ class Expression {
7666
AssignFn getVariableAssignment(size_t i);
7767

7868
Value value_;
79-
Variable* variable_;
69+
Variable* variable_ = nullptr;
8070
std::vector<const Variable*> variables_;
8171
EvalFn eval_ = &Expression::invalid;
8272
AssignFn assign_ = &Expression::invalidAssignment;
8373
std::vector<Expression> children_;
84-
std::any context_;
74+
std::string_view** input_ = nullptr;
8575
};

0 commit comments

Comments
 (0)