Introduced a new SCOPE expression terminal
This commit is contained in:
parent
4e8c9805bb
commit
bc9ff7095f
6 changed files with 118 additions and 65 deletions
|
|
@ -44,7 +44,7 @@ void push_sort_value(std::list<sort_value_t>& sort_values,
|
||||||
if (node->kind == expr_t::op_t::O_CONS) {
|
if (node->kind == expr_t::op_t::O_CONS) {
|
||||||
while (node && node->kind == expr_t::op_t::O_CONS) {
|
while (node && node->kind == expr_t::op_t::O_CONS) {
|
||||||
push_sort_value(sort_values, node->left(), scope);
|
push_sort_value(sort_values, node->left(), scope);
|
||||||
node = node->right();
|
node = node->has_right() ? node->right() : NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool inverted = false;
|
bool inverted = false;
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
expr_t::ptr_op_t colorize_op;
|
expr_t::ptr_op_t colorize_op;
|
||||||
if (op->kind == expr_t::op_t::O_CONS) {
|
if (op->kind == expr_t::op_t::O_CONS) {
|
||||||
amount_op = op->left();
|
amount_op = op->left();
|
||||||
colorize_op = op->right();
|
colorize_op = op->has_right() ? op->right() : NULL;
|
||||||
} else {
|
} else {
|
||||||
amount_op = op;
|
amount_op = op;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
93
src/op.cc
93
src/op.cc
|
|
@ -50,7 +50,7 @@ namespace {
|
||||||
expr_t::ptr_op_t value_op;
|
expr_t::ptr_op_t value_op;
|
||||||
if (next->kind == expr_t::op_t::O_CONS) {
|
if (next->kind == expr_t::op_t::O_CONS) {
|
||||||
value_op = next->left();
|
value_op = next->left();
|
||||||
next = next->right();
|
next = next->has_right() ? next->right() : NULL;
|
||||||
} else {
|
} else {
|
||||||
value_op = next;
|
value_op = next;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
|
|
@ -78,10 +78,12 @@ namespace {
|
||||||
|
|
||||||
expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
{
|
{
|
||||||
|
scope_t * scope_ptr = &scope;
|
||||||
|
|
||||||
if (is_ident()) {
|
if (is_ident()) {
|
||||||
DEBUG("expr.compile", "lookup: " << as_ident());
|
DEBUG("expr.compile", "lookup: " << as_ident());
|
||||||
|
|
||||||
if (ptr_op_t def = scope.lookup(symbol_t::FUNCTION, as_ident())) {
|
if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) {
|
||||||
// Identifier references are first looked up at the point of
|
// Identifier references are first looked up at the point of
|
||||||
// definition, and then at the point of every use if they could
|
// definition, and then at the point of every use if they could
|
||||||
// not be found there.
|
// not be found there.
|
||||||
|
|
@ -91,21 +93,26 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
def->dump(*_log_stream, 0);
|
def->dump(*_log_stream, 0);
|
||||||
}
|
}
|
||||||
#endif // defined(DEBUG_ON)
|
#endif // defined(DEBUG_ON)
|
||||||
return copy(def);
|
return copy(def);
|
||||||
}
|
}
|
||||||
else if (left()) {
|
else if (left()) {
|
||||||
return copy();
|
return copy();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
else if (is_scope()) {
|
||||||
if (kind < TERMINALS)
|
shared_ptr<scope_t> subscope(new symbol_scope_t(scope));
|
||||||
|
DEBUG("expr.compile", "creating scope");
|
||||||
|
set_scope(subscope);
|
||||||
|
scope_ptr = subscope.get();
|
||||||
|
}
|
||||||
|
else if (kind < TERMINALS) {
|
||||||
return this;
|
return this;
|
||||||
|
}
|
||||||
if (kind == O_DEFINE) {
|
else if (kind == O_DEFINE) {
|
||||||
switch (left()->kind) {
|
switch (left()->kind) {
|
||||||
case IDENT:
|
case IDENT:
|
||||||
scope.define(symbol_t::FUNCTION, left()->as_ident(), right());
|
scope_ptr->define(symbol_t::FUNCTION, left()->as_ident(), right());
|
||||||
break;
|
break;
|
||||||
case O_CALL:
|
case O_CALL:
|
||||||
if (left()->left()->is_ident()) {
|
if (left()->left()->is_ident()) {
|
||||||
|
|
@ -113,7 +120,8 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
node->set_left(left()->right());
|
node->set_left(left()->right());
|
||||||
node->set_right(right());
|
node->set_right(right());
|
||||||
|
|
||||||
scope.define(symbol_t::FUNCTION, left()->left()->as_ident(), node);
|
scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(),
|
||||||
|
node);
|
||||||
} else {
|
} else {
|
||||||
throw_(compile_error, _("Invalid function definition"));
|
throw_(compile_error, _("Invalid function definition"));
|
||||||
}
|
}
|
||||||
|
|
@ -121,13 +129,13 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
default:
|
default:
|
||||||
throw_(compile_error, _("Invalid function definition"));
|
throw_(compile_error, _("Invalid function definition"));
|
||||||
}
|
}
|
||||||
return wrap_value(value_t());
|
return wrap_value(NULL_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_op_t lhs(left()->compile(scope, depth));
|
ptr_op_t lhs(left()->compile(*scope_ptr, depth));
|
||||||
ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ?
|
ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ?
|
||||||
(kind == O_LOOKUP ? right() :
|
(kind == O_LOOKUP ? right() :
|
||||||
right()->compile(scope, depth)) : NULL);
|
right()->compile(*scope_ptr, depth)) : NULL);
|
||||||
|
|
||||||
if (lhs == left() && (! rhs || rhs == right()))
|
if (lhs == left() && (! rhs || rhs == right()))
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -136,22 +144,19 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
|
|
||||||
// Reduce constants immediately if possible
|
// Reduce constants immediately if possible
|
||||||
if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value()))
|
if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value()))
|
||||||
return wrap_value(intermediate->calc(scope, NULL, depth));
|
return wrap_value(intermediate->calc(*scope_ptr, NULL, depth));
|
||||||
|
|
||||||
return intermediate;
|
return intermediate;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_ON)
|
|
||||||
bool skip_debug = false;
|
|
||||||
#endif
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
value_t result;
|
value_t result;
|
||||||
|
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
if (! skip_debug && SHOW_DEBUG("expr.calc")) {
|
if (SHOW_DEBUG("expr.calc")) {
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++)
|
||||||
ledger::_log_buffer << '.';
|
ledger::_log_buffer << '.';
|
||||||
ledger::_log_buffer << op_context(this) << " => ...";
|
ledger::_log_buffer << op_context(this) << " => ...";
|
||||||
|
|
@ -196,12 +201,18 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
call_scope_t call_args(scope, locus, depth);
|
call_scope_t call_args(scope, locus, depth);
|
||||||
result = as_function()(call_args);
|
result = as_function()(call_args);
|
||||||
check_type_context(scope, result);
|
check_type_context(scope, result);
|
||||||
#if defined(DEBUG_ON)
|
|
||||||
skip_debug = true;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SCOPE:
|
||||||
|
if (is_scope_unset()) {
|
||||||
|
symbol_scope_t subscope(scope);
|
||||||
|
result = left()->calc(subscope, locus, depth + 1);
|
||||||
|
} else {
|
||||||
|
result = left()->calc(*as_scope(), locus, depth + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case O_LAMBDA: {
|
case O_LAMBDA: {
|
||||||
call_scope_t& call_args(downcast<call_scope_t>(scope));
|
call_scope_t& call_args(downcast<call_scope_t>(scope));
|
||||||
std::size_t args_count(call_args.size());
|
std::size_t args_count(call_args.size());
|
||||||
|
|
@ -267,7 +278,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
throw_(calc_error, _("Calling unknown function '%1'") << name);
|
throw_(calc_error, _("Calling unknown function '%1'") << name);
|
||||||
|
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
if (! skip_debug && SHOW_DEBUG("expr.calc")) {
|
if (SHOW_DEBUG("expr.calc")) {
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++)
|
||||||
ledger::_log_buffer << '.';
|
ledger::_log_buffer << '.';
|
||||||
ledger::_log_buffer << " args: ";
|
ledger::_log_buffer << " args: ";
|
||||||
|
|
@ -382,7 +393,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
ptr_op_t value_op;
|
ptr_op_t value_op;
|
||||||
if (next->kind == O_CONS) {
|
if (next->kind == O_CONS) {
|
||||||
value_op = next->left();
|
value_op = next->left();
|
||||||
next = next->right();
|
next = next->has_right() ? next->right() : NULL;
|
||||||
} else {
|
} else {
|
||||||
value_op = next;
|
value_op = next;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
|
|
@ -395,14 +406,13 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_SEQ: {
|
case O_SEQ: {
|
||||||
symbol_scope_t seq_scope(scope);
|
// An O_SEQ is very similar to an O_CONS except that only the last
|
||||||
|
// result value in the series is kept. O_CONS builds up a list.
|
||||||
// An O_SEQ is very similar to an O_CONS except that only the last result
|
|
||||||
// value in the series is kept. O_CONS builds up a list.
|
|
||||||
//
|
//
|
||||||
// Another feature of O_SEQ is that it pushes a new symbol scope onto the
|
// Another feature of O_SEQ is that it pushes a new symbol scope
|
||||||
// stack.
|
// onto the stack. We evaluate the left side here to catch any
|
||||||
result = left()->calc(seq_scope, locus, depth + 1);
|
// side-effects, such as definitions in the case of 'x = 1; x'.
|
||||||
|
result = left()->calc(scope, locus, depth + 1);
|
||||||
|
|
||||||
if (has_right()) {
|
if (has_right()) {
|
||||||
ptr_op_t next = right();
|
ptr_op_t next = right();
|
||||||
|
|
@ -415,7 +425,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
value_op = next;
|
value_op = next;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
result = value_op->calc(seq_scope, locus, depth + 1);
|
result = value_op->calc(scope, locus, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -426,7 +436,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
if (! skip_debug && SHOW_DEBUG("expr.calc")) {
|
if (SHOW_DEBUG("expr.calc")) {
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++)
|
||||||
ledger::_log_buffer << '.';
|
ledger::_log_buffer << '.';
|
||||||
ledger::_log_buffer << op_context(this) << " => ";
|
ledger::_log_buffer << op_context(this) << " => ";
|
||||||
|
|
@ -476,9 +486,8 @@ namespace {
|
||||||
|
|
||||||
if (op->has_right()) {
|
if (op->has_right()) {
|
||||||
out << "; ";
|
out << "; ";
|
||||||
|
if (op->right()->kind == expr_t::op_t::O_SEQ)
|
||||||
if (op->right()->kind == expr_t::op_t::O_CONS)
|
found = print_seq(out, op->right(), context);
|
||||||
found = print_cons(out, op->right(), context);
|
|
||||||
else if (op->right()->print(out, context))
|
else if (op->right()->print(out, context))
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
@ -515,6 +524,11 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
|
||||||
out << "<FUNCTION>";
|
out << "<FUNCTION>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCOPE:
|
||||||
|
if (left() && left()->print(out, context))
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case O_NOT:
|
case O_NOT:
|
||||||
out << "! ";
|
out << "! ";
|
||||||
if (left() && left()->print(out, context))
|
if (left() && left()->print(out, context))
|
||||||
|
|
@ -625,7 +639,6 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
|
||||||
case O_CONS:
|
case O_CONS:
|
||||||
found = print_cons(out, this, context);
|
found = print_cons(out, this, context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_SEQ:
|
case O_SEQ:
|
||||||
found = print_seq(out, this, context);
|
found = print_seq(out, this, context);
|
||||||
break;
|
break;
|
||||||
|
|
@ -726,6 +739,14 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const
|
||||||
out << "FUNCTION";
|
out << "FUNCTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCOPE:
|
||||||
|
out << "SCOPE: ";
|
||||||
|
if (is_scope_unset())
|
||||||
|
out << "null";
|
||||||
|
else
|
||||||
|
out << as_scope().get();
|
||||||
|
break;
|
||||||
|
|
||||||
case O_DEFINE: out << "O_DEFINE"; break;
|
case O_DEFINE: out << "O_DEFINE"; break;
|
||||||
case O_LOOKUP: out << "O_LOOKUP"; break;
|
case O_LOOKUP: out << "O_LOOKUP"; break;
|
||||||
case O_LAMBDA: out << "O_LAMBDA"; break;
|
case O_LAMBDA: out << "O_LAMBDA"; break;
|
||||||
|
|
@ -765,7 +786,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const
|
||||||
|
|
||||||
// An identifier is a special non-terminal, in that its left() can
|
// An identifier is a special non-terminal, in that its left() can
|
||||||
// hold the compiled definition of the identifier.
|
// hold the compiled definition of the identifier.
|
||||||
if (kind > TERMINALS || is_ident()) {
|
if (kind > TERMINALS || is_ident() || is_scope()) {
|
||||||
if (left()) {
|
if (left()) {
|
||||||
left()->dump(out, depth + 1);
|
left()->dump(out, depth + 1);
|
||||||
if (kind > UNARY_OPERATORS && has_right())
|
if (kind > UNARY_OPERATORS && has_right())
|
||||||
|
|
|
||||||
51
src/op.h
51
src/op.h
|
|
@ -58,10 +58,12 @@ private:
|
||||||
mutable short refc;
|
mutable short refc;
|
||||||
ptr_op_t left_;
|
ptr_op_t left_;
|
||||||
|
|
||||||
variant<ptr_op_t, // used by all binary operators
|
variant<boost::blank,
|
||||||
|
ptr_op_t, // used by all binary operators
|
||||||
value_t, // used by constant VALUE
|
value_t, // used by constant VALUE
|
||||||
string, // used by constant IDENT
|
string, // used by constant IDENT
|
||||||
expr_t::func_t // used by terminal FUNCTION
|
expr_t::func_t, // used by terminal FUNCTION
|
||||||
|
shared_ptr<scope_t> // used by terminal SCOPE
|
||||||
> data;
|
> data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -73,6 +75,7 @@ public:
|
||||||
CONSTANTS,
|
CONSTANTS,
|
||||||
|
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
|
SCOPE,
|
||||||
|
|
||||||
TERMINALS,
|
TERMINALS,
|
||||||
|
|
||||||
|
|
@ -173,7 +176,7 @@ public:
|
||||||
return kind == FUNCTION;
|
return kind == FUNCTION;
|
||||||
}
|
}
|
||||||
expr_t::func_t& as_function_lval() {
|
expr_t::func_t& as_function_lval() {
|
||||||
assert(kind == FUNCTION);
|
assert(is_function());
|
||||||
return boost::get<expr_t::func_t>(data);
|
return boost::get<expr_t::func_t>(data);
|
||||||
}
|
}
|
||||||
const expr_t::func_t& as_function() const {
|
const expr_t::func_t& as_function() const {
|
||||||
|
|
@ -183,21 +186,41 @@ public:
|
||||||
data = val;
|
data = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_scope() const {
|
||||||
|
return kind == SCOPE;
|
||||||
|
}
|
||||||
|
bool is_scope_unset() const {
|
||||||
|
return data.which() == 0;
|
||||||
|
}
|
||||||
|
shared_ptr<scope_t> as_scope_lval() {
|
||||||
|
assert(is_scope());
|
||||||
|
return boost::get<shared_ptr<scope_t> >(data);
|
||||||
|
}
|
||||||
|
const shared_ptr<scope_t> as_scope() const {
|
||||||
|
return const_cast<op_t *>(this)->as_scope_lval();
|
||||||
|
}
|
||||||
|
void set_scope(shared_ptr<scope_t> val) {
|
||||||
|
data = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These three functions must use 'kind == IDENT' rather than
|
||||||
|
// 'is_ident()', because they are called before the `data' member gets
|
||||||
|
// set, which is_ident() tests.
|
||||||
ptr_op_t& left() {
|
ptr_op_t& left() {
|
||||||
assert(kind > TERMINALS || kind == IDENT);
|
assert(kind > TERMINALS || kind == IDENT || is_scope());
|
||||||
return left_;
|
return left_;
|
||||||
}
|
}
|
||||||
const ptr_op_t& left() const {
|
const ptr_op_t& left() const {
|
||||||
assert(kind > TERMINALS || kind == IDENT);
|
assert(kind > TERMINALS || kind == IDENT || is_scope());
|
||||||
return left_;
|
return left_;
|
||||||
}
|
}
|
||||||
void set_left(const ptr_op_t& expr) {
|
void set_left(const ptr_op_t& expr) {
|
||||||
assert(kind > TERMINALS || kind == IDENT);
|
assert(kind > TERMINALS || kind == IDENT || is_scope());
|
||||||
left_ = expr;
|
left_ = expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_op_t& as_op_lval() {
|
ptr_op_t& as_op_lval() {
|
||||||
assert(kind > TERMINALS || kind == IDENT);
|
assert(kind > TERMINALS || is_ident());
|
||||||
return boost::get<ptr_op_t>(data);
|
return boost::get<ptr_op_t>(data);
|
||||||
}
|
}
|
||||||
const ptr_op_t& as_op() const {
|
const ptr_op_t& as_op() const {
|
||||||
|
|
@ -219,7 +242,7 @@ public:
|
||||||
bool has_right() const {
|
bool has_right() const {
|
||||||
if (kind < TERMINALS)
|
if (kind < TERMINALS)
|
||||||
return false;
|
return false;
|
||||||
return as_op();
|
return data.which() != 0 && as_op();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -284,6 +307,7 @@ public:
|
||||||
|
|
||||||
static ptr_op_t wrap_value(const value_t& val);
|
static ptr_op_t wrap_value(const value_t& val);
|
||||||
static ptr_op_t wrap_functor(expr_t::func_t fobj);
|
static ptr_op_t wrap_functor(expr_t::func_t fobj);
|
||||||
|
static ptr_op_t wrap_scope(shared_ptr<scope_t> sobj);
|
||||||
|
|
||||||
#if defined(HAVE_BOOST_SERIALIZATION)
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
private:
|
private:
|
||||||
|
|
@ -295,13 +319,13 @@ private:
|
||||||
void serialize(Archive& ar, const unsigned int /* version */) {
|
void serialize(Archive& ar, const unsigned int /* version */) {
|
||||||
ar & refc;
|
ar & refc;
|
||||||
ar & kind;
|
ar & kind;
|
||||||
if (Archive::is_loading::value || ! left_ || left_->kind != FUNCTION) {
|
if (Archive::is_loading::value || ! left_ || ! left_->is_function()) {
|
||||||
ar & left_;
|
ar & left_;
|
||||||
} else {
|
} else {
|
||||||
ptr_op_t temp_op;
|
ptr_op_t temp_op;
|
||||||
ar & temp_op;
|
ar & temp_op;
|
||||||
}
|
}
|
||||||
if (Archive::is_loading::value || kind == VALUE || kind == IDENT ||
|
if (Archive::is_loading::value || is_value() || is_ident() ||
|
||||||
(kind > UNARY_OPERATORS &&
|
(kind > UNARY_OPERATORS &&
|
||||||
(! has_right() || ! right()->is_function()))) {
|
(! has_right() || ! right()->is_function()))) {
|
||||||
ar & data;
|
ar & data;
|
||||||
|
|
@ -335,6 +359,13 @@ expr_t::op_t::wrap_functor(expr_t::func_t fobj) {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline expr_t::ptr_op_t
|
||||||
|
expr_t::op_t::wrap_scope(shared_ptr<scope_t> sobj) {
|
||||||
|
ptr_op_t temp(new op_t(op_t::SCOPE));
|
||||||
|
temp->set_scope(sobj);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
#define MAKE_FUNCTOR(x) expr_t::op_t::wrap_functor(bind(&x, this, _1))
|
#define MAKE_FUNCTOR(x) expr_t::op_t::wrap_functor(bind(&x, this, _1))
|
||||||
#define WRAP_FUNCTOR(x) expr_t::op_t::wrap_functor(x)
|
#define WRAP_FUNCTOR(x) expr_t::op_t::wrap_functor(x)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,6 @@ expr_t::parser_t::parse_comma_expr(std::istream& in,
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_CONS);
|
node = new op_t(op_t::O_CONS);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
|
|
||||||
next = node;
|
next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,7 +492,9 @@ expr_t::parser_t::parse_assign_expr(std::istream& in,
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_DEFINE);
|
node = new op_t(op_t::O_DEFINE);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_lambda_expr(in, tflags));
|
ptr_op_t scope(new op_t(op_t::SCOPE));
|
||||||
|
scope->set_left(parse_lambda_expr(in, tflags));
|
||||||
|
node->set_right(scope);
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
}
|
}
|
||||||
|
|
@ -509,24 +510,24 @@ expr_t::parser_t::parse_value_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_assign_expr(in, tflags));
|
ptr_op_t node(parse_assign_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
ptr_op_t next;
|
ptr_op_t chain;
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::SEMI) {
|
if (tok.kind == token_t::SEMI) {
|
||||||
if (! next) {
|
ptr_op_t seq(new op_t(op_t::O_SEQ));
|
||||||
ptr_op_t prev(node);
|
if (! chain) {
|
||||||
node = new op_t(op_t::O_SEQ);
|
seq->set_left(node);
|
||||||
node->set_left(prev);
|
ptr_op_t scope(new op_t(op_t::SCOPE));
|
||||||
|
scope->set_left(seq);
|
||||||
next = node;
|
node = scope;
|
||||||
|
} else {
|
||||||
|
seq->set_left(chain->right());
|
||||||
|
ptr_op_t scope(new op_t(op_t::SCOPE));
|
||||||
|
scope->set_left(seq);
|
||||||
|
chain->set_right(scope);
|
||||||
}
|
}
|
||||||
|
seq->set_right(parse_assign_expr(in, tflags));
|
||||||
ptr_op_t chain(new op_t(op_t::O_SEQ));
|
chain = seq;
|
||||||
chain->set_left(parse_assign_expr(in, tflags));
|
|
||||||
|
|
||||||
next->set_right(chain);
|
|
||||||
next = chain;
|
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1727,7 +1727,7 @@ void value_t::print(std::ostream& _out,
|
||||||
|
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case VOID:
|
case VOID:
|
||||||
out << "";
|
out << "(null)";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue