int wpl_value_array::do_operator ( wpl_expression_state *exp_state, wpl_value *final_result, const struct wpl_operator_struct *op, wpl_value *lhs, wpl_value *rhs ) { this->lhs = lhs; this->rhs = rhs; int ret = WPL_OP_UNKNOWN; if (op == &OP_ARRAY_SUBSCRIPTING) { ret = array_subscripting(); } else if (op == &OP_INDIRECTION) { wpl_value *value = define_if_needed(0); return value->do_operator_recursive(exp_state, final_result); } else if (op == &OP_SAVE_DISCARD) { if (exp_state->empty_waiting()) { throw runtime_error("Cannot assign discard chain to array with operator '=>' without any previous operands"); } if (wpl_value *wait_top = exp_state->top_waiting()) { exp_state->pop_waiting(); exp_state->push_discard(wait_top); } /* Push discard chain to array */ int i; for (i = 0; i <= exp_state->get_discard_pos(); i++) { define_if_needed(size())->set_weak(exp_state->get_discard()[i]); } wpl_value_int res(i); return res.do_operator_recursive(exp_state, final_result); } else if (op == &OP_DISCARD) { ret = discard(); } else if (op == &OP_COUNT) { wpl_value_int count(size()); return count.do_operator_recursive(exp_state, final_result); } if (ret & WPL_OP_OK) { if (ret & WPL_OP_DISCARD) { exp_state->push_discard(result); } return result->do_operator_recursive(exp_state, final_result); } return ret; }
int wpl_value_array::array_subscripting() { if (!(lhs == this)) { throw runtime_error ("Left side of [] was not this array"); } int index = rhs->toInt(); if (index < 0) { throw runtime_error ("Negative index received in array subscription []"); } wpl_value *value = define_if_needed(index); result = value; return (WPL_OP_OK|WPL_OP_NAME_RESOLVED); }
int wpl_value_array::do_operator ( wpl_expression_state *exp_state, wpl_value *final_result, const struct wpl_operator_struct *op, wpl_value *lhs, wpl_value *rhs ) { this->lhs = lhs; this->rhs = rhs; int ret = WPL_OP_UNKNOWN; if (op == &OP_REPLACE_DISCARD) { /* Empty the array and then run save discard */ clear(); op = &OP_SAVE_DISCARD; } if (op == &OP_ARRAY_SUBSCRIPTING) { int index = rhs->toInt(); if (index < 0) { throw runtime_error ("Negative index received in array subscription []"); } wpl_value *value = get(index); if (!exp_state->empty()) { shunting_yard_carrier &next_carrier = exp_state->top(); if (next_carrier.op == &OP_DEFINED) { exp_state->pop(); wpl_value_bool result(value != NULL); return result.do_operator_recursive(exp_state, final_result); } } if (value == NULL) { value = template_type->new_instance(); set (index, value); } return value->do_operator_recursive(exp_state, final_result); } else if (op == &OP_INDIRECTION) { wpl_value *value = define_if_needed(0); return value->do_operator_recursive(exp_state, final_result); } else if (op == &OP_SAVE_DISCARD) { if (!lhs) { throw runtime_error("Cannot assign discard chain to array with operator '=>' without any previous operands"); } /* cerr << "LHS in array is " << lhs->toInt() << endl; exp_state->push_discard(lhs); if (wpl_value *wait_top = exp_state->top_waiting()) { exp_state->pop_waiting(); exp_state->push_discard(wait_top); }*/ /* Push discard chain to array */ int i; for (i = 0; i <= exp_state->get_discard_pos(); i++) { define_if_needed(size())->set_weak(exp_state->get_discard()[i]); } /* Push last element, our LHS */ define_if_needed(size())->set_weak(lhs); wpl_value_int res(i + 1); return res.do_operator_recursive(exp_state, final_result); } else if (op == &OP_DISCARD) { ret = discard(); } else if (op == &OP_COUNT) { wpl_value_int count(size()); return count.do_operator_recursive(exp_state, final_result); } else if (op == &OP_POINTERTO) { wpl_value_pointer result(exp_state->get_nss(), container_type, this); return result.do_operator_recursive(exp_state, final_result); } else if (op == &OP_ASSIGN) { if (!lhs->set_strong(rhs)) { cerr << "While assigning value of type " << rhs->get_type_name() << " to array of type " << get_type_name() << " in operator =:\n"; throw runtime_error("Incompatible types"); } return do_operator_recursive(exp_state, final_result); } if (ret & WPL_OP_OK) { if (ret & WPL_OP_DISCARD) { exp_state->push_discard(result); } return result->do_operator_recursive(exp_state, final_result); } return ret; }
void wpl_value_array::push_weak(wpl_value *value) { define_if_needed(size())->set_weak(value); }