Value expressions now auto-compile themselves on first use if the expr_t

object is not constant.  This saves classes that use expr_t from having to
track such a detail themselves.
This commit is contained in:
John Wiegley 2008-08-01 02:20:09 -04:00
parent c98be73173
commit d213b32ffc
2 changed files with 40 additions and 24 deletions

62
expr.cc
View file

@ -37,17 +37,19 @@ namespace ledger {
std::auto_ptr<expr_t::parser_t> expr_t::parser; std::auto_ptr<expr_t::parser_t> expr_t::parser;
expr_t::expr_t() expr_t::expr_t() : compiled(false)
{ {
TRACE_CTOR(expr_t, ""); TRACE_CTOR(expr_t, "");
} }
expr_t::expr_t(const expr_t& other) : ptr(other.ptr), str(other.str) expr_t::expr_t(const expr_t& other)
: ptr(other.ptr), str(other.str), compiled(false)
{ {
TRACE_CTOR(expr_t, "copy"); TRACE_CTOR(expr_t, "copy");
} }
expr_t::expr_t(const string& _str, const unsigned int flags) : str(_str) expr_t::expr_t(const string& _str, const unsigned int flags)
: str(_str), compiled(false)
{ {
TRACE_CTOR(expr_t, "const string&"); TRACE_CTOR(expr_t, "const string&");
@ -55,7 +57,8 @@ expr_t::expr_t(const string& _str, const unsigned int flags) : str(_str)
ptr = parser->parse(str, flags); ptr = parser->parse(str, flags);
} }
expr_t::expr_t(std::istream& in, const unsigned int flags) expr_t::expr_t(std::istream& in, const unsigned int flags)
: compiled(false)
{ {
TRACE_CTOR(expr_t, "std::istream&"); TRACE_CTOR(expr_t, "std::istream&");
@ -63,7 +66,7 @@ expr_t::expr_t(const string& _str, const unsigned int flags) : str(_str)
} }
expr_t::expr_t(const ptr_op_t& _ptr, const string& _str) expr_t::expr_t(const ptr_op_t& _ptr, const string& _str)
: ptr(_ptr), str(_str) : ptr(_ptr), str(_str), compiled(false)
{ {
TRACE_CTOR(expr_t, "const ptr_op_t&, const string&"); TRACE_CTOR(expr_t, "const ptr_op_t&, const string&");
} }
@ -75,8 +78,11 @@ expr_t::~expr_t() throw()
expr_t& expr_t::operator=(const expr_t& _expr) expr_t& expr_t::operator=(const expr_t& _expr)
{ {
str = _expr.str; if (this != &_expr) {
ptr = _expr.ptr; str = _expr.str;
ptr = _expr.ptr;
compiled = _expr.compiled;
}
return *this; return *this;
} }
@ -85,8 +91,9 @@ void expr_t::parse(const string& _str, const unsigned int flags)
if (! parser.get()) if (! parser.get())
throw_(parse_error, "Value expression parser not initialized"); throw_(parse_error, "Value expression parser not initialized");
str = _str; str = _str;
ptr = parser->parse(str, flags); ptr = parser->parse(str, flags);
compiled = false;
} }
void expr_t::parse(std::istream& in, const unsigned int flags) void expr_t::parse(std::istream& in, const unsigned int flags)
@ -94,21 +101,32 @@ void expr_t::parse(std::istream& in, const unsigned int flags)
if (! parser.get()) if (! parser.get())
throw_(parse_error, "Value expression parser not initialized"); throw_(parse_error, "Value expression parser not initialized");
str = "<stream>"; str = "<stream>";
ptr = parser->parse(in, flags); ptr = parser->parse(in, flags);
compiled = false;
} }
void expr_t::compile(scope_t& scope) void expr_t::compile(scope_t& scope)
{ {
if (ptr.get()) if (ptr.get()) {
ptr = ptr->compile(scope); ptr = ptr->compile(scope);
compiled = true;
}
}
value_t expr_t::calc(scope_t& scope)
{
if (ptr.get()) {
if (! compiled)
compile(scope);
return ptr->calc(scope);
}
return NULL_VALUE;
} }
value_t expr_t::calc(scope_t& scope) const value_t expr_t::calc(scope_t& scope) const
{ {
if (ptr.get()) return ptr.get() ? ptr->calc(scope) : NULL_VALUE;
return ptr->calc(scope);
return NULL_VALUE;
} }
bool expr_t::is_constant() const bool expr_t::is_constant() const
@ -141,26 +159,22 @@ void expr_t::print(std::ostream& out, scope_t& scope) const
void expr_t::dump(std::ostream& out) const void expr_t::dump(std::ostream& out) const
{ {
if (ptr) if (ptr) ptr->dump(out, 0);
ptr->dump(out, 0);
} }
void expr_t::read(std::ostream& in) void expr_t::read(std::ostream& in)
{ {
if (ptr) if (ptr) ptr->read(in);
ptr->read(in);
} }
void expr_t::read(const char *& data) void expr_t::read(const char *& data)
{ {
if (ptr) if (ptr) ptr->read(data);
ptr->read(data);
} }
void expr_t::write(std::ostream& out) const void expr_t::write(std::ostream& out) const
{ {
if (ptr) if (ptr) ptr->write(out);
ptr->write(out);
} }
void expr_t::initialize() void expr_t::initialize()

2
expr.h
View file

@ -59,6 +59,7 @@ public:
private: private:
ptr_op_t ptr; ptr_op_t ptr;
string str; string str;
bool compiled;
static void initialize(); static void initialize();
static void shutdown(); static void shutdown();
@ -97,6 +98,7 @@ public:
void parse(std::istream& in, const unsigned int flags = 0); void parse(std::istream& in, const unsigned int flags = 0);
void compile(scope_t& scope); void compile(scope_t& scope);
value_t calc(scope_t& scope);
value_t calc(scope_t& scope) const; value_t calc(scope_t& scope) const;
bool is_constant() const; bool is_constant() const;