Created merged_expr_t class for chained expressions
This commit is contained in:
parent
be778e3879
commit
c33d7480a6
2 changed files with 102 additions and 1 deletions
41
src/expr.cc
41
src/expr.cc
|
|
@ -163,6 +163,47 @@ void expr_t::dump(std::ostream& out) const
|
||||||
if (ptr) ptr->dump(out, 0);
|
if (ptr) ptr->dump(out, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool merged_expr_t::check_for_single_identifier(const string& expr)
|
||||||
|
{
|
||||||
|
bool single_identifier = true;
|
||||||
|
for (const char * p = expr.c_str(); *p; ++p)
|
||||||
|
if (! std::isalnum(*p) || *p == '_') {
|
||||||
|
single_identifier = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (single_identifier) {
|
||||||
|
set_base_expr(expr);
|
||||||
|
exprs.clear();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void merged_expr_t::compile(scope_t& scope)
|
||||||
|
{
|
||||||
|
if (exprs.empty()) {
|
||||||
|
parse(base_expr);
|
||||||
|
} else {
|
||||||
|
std::ostringstream buf;
|
||||||
|
|
||||||
|
buf << "__tmp_" << term << "=(" << term << "=(" << base_expr << ")";
|
||||||
|
foreach (const string& expr, exprs) {
|
||||||
|
if (merge_operator == ";")
|
||||||
|
buf << merge_operator << term << "=" << expr;
|
||||||
|
else
|
||||||
|
buf << merge_operator << "(" << expr << ")";
|
||||||
|
}
|
||||||
|
buf << ";" << term << ");__tmp_" << term;
|
||||||
|
|
||||||
|
DEBUG("expr.merged.compile", "Compiled expr: " << buf.str());
|
||||||
|
parse(buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_t::compile(scope);
|
||||||
|
}
|
||||||
|
|
||||||
value_t source_command(call_scope_t& args)
|
value_t source_command(call_scope_t& args)
|
||||||
{
|
{
|
||||||
std::istream * in = NULL;
|
std::istream * in = NULL;
|
||||||
|
|
|
||||||
62
src/expr.h
62
src/expr.h
|
|
@ -172,8 +172,68 @@ inline value_t expr_value(expr_t::ptr_op_t op) {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
class call_scope_t;
|
// A merged expression allows one to set an expression term, "foo", and
|
||||||
|
// a base expression, "bar", and then merge in later expressions that
|
||||||
|
// utilize foo. For example:
|
||||||
|
//
|
||||||
|
// foo: bar
|
||||||
|
// merge: foo * 10
|
||||||
|
// merge: foo + 20
|
||||||
|
//
|
||||||
|
// When this expression is finally compiled, the base and merged
|
||||||
|
// elements are written into this:
|
||||||
|
//
|
||||||
|
// __tmp=(foo=bar; foo=foo*10; foo=foo+20);__tmp
|
||||||
|
//
|
||||||
|
// This allows users to select flags like -O, -B or -I at any time, and
|
||||||
|
// also combine flags such as -V and -A.
|
||||||
|
|
||||||
|
class merged_expr_t : public expr_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
string term;
|
||||||
|
string base_expr;
|
||||||
|
string merge_operator;
|
||||||
|
std::list<string> exprs;
|
||||||
|
|
||||||
|
merged_expr_t(const string& _term, const string& expr,
|
||||||
|
const string& merge_op = ";")
|
||||||
|
: expr_t(), term(_term), base_expr(expr), merge_operator(merge_op) {
|
||||||
|
TRACE_CTOR(merged_expr_t, "string, string, string");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~merged_expr_t() {
|
||||||
|
TRACE_DTOR(merged_expr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_term(const string& _term) {
|
||||||
|
term = _term;
|
||||||
|
}
|
||||||
|
void set_base_expr(const string& expr) {
|
||||||
|
base_expr = expr;
|
||||||
|
}
|
||||||
|
void set_merge_operator(const string& merge_op) {
|
||||||
|
merge_operator = merge_op;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_for_single_identifier(const string& expr);
|
||||||
|
|
||||||
|
void prepend(const string& expr) {
|
||||||
|
if (! check_for_single_identifier(expr))
|
||||||
|
exprs.push_front(expr);
|
||||||
|
}
|
||||||
|
void append(const string& expr) {
|
||||||
|
if (! check_for_single_identifier(expr))
|
||||||
|
exprs.push_back(expr);
|
||||||
|
}
|
||||||
|
void remove(const string& expr) {
|
||||||
|
exprs.remove(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(scope_t& scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
class call_scope_t;
|
||||||
value_t source_command(call_scope_t& scope);
|
value_t source_command(call_scope_t& scope);
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue