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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue