Esempio n. 1
0
void BitVector::read(const char *location)
  {
    _has_count = false;
    _count = 0;
    const char *follow = location;
    suif_assert((*follow == '0') && (follow[1] == 'x'));
    follow += 2;
    bool sign_extend = (*follow == '.');
    while (*follow == '.')
        ++follow;
    const char *end = follow;
    while (*end != 0)
        ++end;
    suif_assert(end > follow);
    remove_reference(_block);
    size_t hex_digits_per_word = sizeof(BitVector::ChunkT) * 2;
    bool infinity_is_one =
            (sign_extend ? ((*follow > '7') || (*follow < '0')) : false);
    size_t word_count =
            ((end - follow) + hex_digits_per_word - 1) / hex_digits_per_word;
    _block = new BitVectorBlock(word_count, infinity_is_one, word_count);
    size_t word_num = word_count;
    if (((end - follow) % hex_digits_per_word) > 0)
      {
        BitVector::ChunkT high_word = (infinity_is_one ? ~0lu : 0lu);
        while (((end - follow) % hex_digits_per_word) > 0)
          {
            unsigned char new_half_byte = convert_from_hex(*follow);
            suif_assert(new_half_byte != 16);
            high_word = (high_word << 4) | new_half_byte;
            ++follow;
          }
        --word_num;
        _block->_data[word_num] = high_word;
      }
    while (follow < end)
      {
        BitVector::ChunkT this_word = 0;
        for (size_t digit_num = 0; digit_num < hex_digits_per_word;
             ++digit_num)
          {
            unsigned char new_half_byte = convert_from_hex(*follow);
            suif_assert(new_half_byte != 16);
            this_word = (this_word << 4) | new_half_byte;
            ++follow;
          }
        --word_num;
        _block->_data[word_num] = this_word;
      }
    assert(follow == end);
    assert(word_num == 0);
    _block->unpad();
  }
Esempio n. 2
0
void BitVectorBlock::expand_data(size_t new_data_length)
  {
    suif_assert(new_data_length >= 0);
    if (new_data_length <= _data_length)
        return;
    if (new_data_length > _data_space)
      {
        BitVector::ChunkT *new_data = new BitVector::ChunkT[new_data_length];
        for (size_t chunk_num = 0; chunk_num < _data_length; ++chunk_num)
            new_data[chunk_num] = _data[chunk_num];
        if (_data != NULL)
            delete[] _data;
        _data = new_data;
        _data_space = new_data_length;
      }
    BitVector::ChunkT mask = 0;
    if (_infinity_bit_is_one)
        mask = ~0;
    for (size_t chunk_num = _data_length; chunk_num < new_data_length;
         ++chunk_num)
      {
        _data[chunk_num] = mask;
      }
    _data_length = new_data_length;
  }
Esempio n. 3
0
/*
 * Derives a new vtbl from the parent's vtbl.
 * Methods whose is_dispatched field is false are ignored.
 */
vtbl_t* SingleInheritanceVtbls::
derive_vtbl( vtbl_t* parent_vtbl,
	     SingleInheritanceClassType* current_class )
{
  suif_assert( current_class );

  if( ! current_class->get_methods_are_complete() )
    handle_incomplete_class( current_class );
  
  if ( parent_vtbl == NULL )
    parent_vtbl = new vtbl_t();

  // copy the parent vtbl
  vtbl_t* current_vtbl = new vtbl_t( *parent_vtbl );

  list<InstanceMethodSymbol* > method_list =
    collect_stos<InstanceMethodSymbol,InstanceMethodSymbol>( current_class->get_instance_method_symbol_table() );    
  
  for ( unsigned i = 0 ; i < method_list.size() ; i++ ) {
    InstanceMethodSymbol* msym = method_list[i];

    if ( msym->get_is_dispatched() )
      insert_method( msym, current_vtbl );
  }

  // insert vtbl in map
  _vtbls.enter_value( current_class, current_vtbl );

  return current_vtbl;
}
Esempio n. 4
0
void SuifEnv::error( SuifObject* obj, const char* file_name,
                       int line_number,
                       const char* module_name,
                       const char* description, va_list args ) {
  suif_assert( _error_subsystem );
  _error_subsystem->error( obj, file_name, line_number, module_name, description, args );
}
Esempio n. 5
0
void SuifEnv::warning( const char* file_name,
                       int line_number,
                       const char* module_name,
                       const char* description, va_list args ) {
  suif_assert( _error_subsystem );
  _error_subsystem->warning( file_name, line_number, module_name, description, args );
}
Esempio n. 6
0
WalkingMaps::WalkingMaps(const WalkingMaps &other) :
  _done(false), _skip(false), _pre_map(0),
  _children_map(0), _post_map(0), _process_map(0),
  _user_state(0)
{
  suif_assert(false);
}
Esempio n. 7
0
void SuifEnv::information( const char* file_name,
                       int line_number,
                       const char* module_name,
                       int verbosity_level,
                       const char* description, va_list args ) {
  suif_assert( _error_subsystem );
  _error_subsystem->information( file_name, line_number, module_name, verbosity_level, description, args );
}
static DataType *unqualify_data_type(Type *t) {
  while (is_kind_of<QualifiedType>(t)) {
    t = to<QualifiedType>(t)->get_base_type();
  }
  if (is_kind_of<DataType>(t)) return(to<DataType>(t));
  suif_assert( false );
  return 0;
}
Esempio n. 9
0
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void SuifPrinterModule::print(ostream& output, const SuifObject*rootNode)
{
  suif_assert(rootNode != NULL);
  //const MetaClass *type = rootNode->get_meta_class();
   int _indent = 2;

   print2(output, ObjectWrapper(rootNode), emptyLString, _indent);
   output <<endl;
}
Statement *while_statement_walker::dismantle_while_statement(WhileStatement *the_while){
    Statement *result = 0;

    Expression *condition = the_while->get_condition();

    // we are going to reuse the condition so we must remove it
    // from the if statement first to avoid ownership conflicts

    //    the_while->set_condition(SourceOp());
    //    remove_source_op(condition);
    remove_suif_object(condition);

    Statement *body = the_while->get_body();
    CodeLabelSymbol *break_label = the_while->get_break_label();
    CodeLabelSymbol *continue_label = the_while->get_continue_label();

    // likewise of these parts - remove from if.

    the_while->set_body(0);
    the_while->set_break_label(0);
    the_while->set_continue_label(0);

    if (body != 0) {
        StatementList *replacement = create_statement_list(body->get_suif_env());
        result = replacement;
        suif_assert(continue_label != 0);
        UnaryExpression* negated_condition = 
	    create_unary_expression(body->get_suif_env(),
				   condition->get_result_type(),
				   k_logical_not,
				   condition );
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label));
        replacement-> append_statement(create_branch_statement(body->get_suif_env(),
                                                 negated_condition, break_label));
        replacement->append_statement(body);

        suif_assert(break_label != 0);
        replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_label));
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label));
        }

    the_while->get_parent()->replace(the_while,result);
    return result;
}
Esempio n. 11
0
BitVector::ChunkT BitVector::get_chunk(size_t chunk_num) const
  {
    suif_assert(chunk_num >= 0);
    if (chunk_num >= _block->_data_length)
      {
        return (_block->_infinity_bit_is_one ? ~(BitVector::ChunkT)0 :
                (BitVector::ChunkT)0);
      }
    return _block->_data[chunk_num];
  }
Esempio n. 12
0
bool BitVector::get_bit(size_t bit_num) const
  {
    suif_assert(bit_num >= 0);
    size_t chunk_num = bit_num / (size_t)BITS_PER_WORD;
    if (chunk_num >= _block->_data_length)
        return _block->_infinity_bit_is_one;
    BitVector::ChunkT mask =
            ((BitVector::ChunkT)1) << (bit_num % (size_t)BITS_PER_WORD);
    return (((_block->_data[chunk_num] & mask) == 0) ? false : true);
  }
Esempio n. 13
0
void BitVector::set_chunk(size_t chunk_num, BitVector::ChunkT new_chunk)
  {
    suif_assert(chunk_num >= 0);
    make_changable();
    if (chunk_num >= _block->_data_length)
        _block->expand_data(chunk_num + 1);
    _block->_data[chunk_num] = new_chunk;
    size_t bit_num = (chunk_num + 1) * (size_t)BITS_PER_WORD;
    if (bit_num > _block->_num_significant_bits)
        _block->_num_significant_bits = bit_num;
    _block->unpad();
  }
Esempio n. 14
0
SuifEnv::SuifEnv(const SuifEnv &other) :
  input_sub_system( 0 ),
  output_subsystem( 0 ),
  cloneSubSystem( 0 ),
  _dll_subsystem( 0 ),
  _module_subsystem( 0 ),
  _error_subsystem( 0 ),
  _print_subsystem( 0 ),
  _type_builder( 0 ),
  _object_factory( 0 ),
  factories( new list<RealObjectFactory*> ),
  _file_set_block( 0 ),
  rudimentaryAddressMap( 0 )
{
  suif_assert(false);
}
Esempio n. 15
0
static void handle_static_children_suif_object(WalkingMaps *walk,
					SuifObject *obj) {
  // use the object iterator to find all suiffobjects.
  // check to see that the parent is ME
  for (Iter<SuifObject> iter =
	 collect_instance_objects<SuifObject>(obj);
       iter.is_valid(); iter.next()) {
    //  list<SuifObject *>::iterator iter = the_list->begin();
    //  for (; iter != the_list->end(); iter++) {
    SuifObject *child = &iter.current();

    if (child == 0 ) continue;
    suif_assert(child->get_parent() == obj);
    walk->get_process_map()->apply(child);
    if (walk->is_done()) return;
  }
}
Esempio n. 16
0
void BitVector::set_bit(size_t bit_num, bool new_value)
  {
    suif_assert(bit_num >= 0);
    if ((bit_num >= _block->_num_significant_bits) &&
        (new_value == _block->_infinity_bit_is_one))
      {
        return;
      }
    make_changable();
    size_t chunk_num = bit_num / (size_t)BITS_PER_WORD;
    if (chunk_num >= _block->_data_length)
        _block->expand_data(chunk_num + 1);
    BitVector::ChunkT mask =
            ((BitVector::ChunkT)1) << (bit_num % (size_t)BITS_PER_WORD);
    if (new_value)
        _block->_data[chunk_num] |= mask;
    else
        _block->_data[chunk_num] &= ~mask;
    if (bit_num >= _block->_num_significant_bits)
        _block->_num_significant_bits = bit_num + 1;
    _block->unpad();
  }
Esempio n. 17
0
void SGraphBit::set_node_successors(SGraphNode node, const BitVector *t) {
  suif_assert(is_node_member(node));
  BitVector *bv = retrieve_bv(node);
  (*bv) = (*t);
}
Esempio n. 18
0
WalkingMaps& WalkingMaps::operator=(const WalkingMaps &other) {
  suif_assert(false); return(*this);
}
Esempio n. 19
0
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){
    suif_hash_map<ParameterSymbol*, Type*> params;
    TypeBuilder *tb = (TypeBuilder*)
         get_suif_env()->get_object_factory(TypeBuilder::get_class_name());

    // collect all procedure parameters of pointer type into params list
    for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator();
        iter.is_valid(); iter.next())
    {
        ParameterSymbol* par_sym = iter.current();
        Type* par_type = tb->unqualify_type(par_sym->get_type());

        if(is_kind_of<PointerType>(par_type)){
            // put NULLs into the map at first,
            // they will later be overwritten
            params[par_sym] = NULL;
        }
    }
    if(params.size()==0) return;    // nothing to do
    
    // walk thru all AREs and look for arrays that are in the param list
    {for(Iter<ArrayReferenceExpression> iter =
        object_iterator<ArrayReferenceExpression>(proc_def);
            iter.is_valid(); iter.next())
        {
            ArrayReferenceExpression* are = &iter.current();
            if(is_kind_of<UnaryExpression>(are->get_base_array_address())){
                UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address());
                if(ue->get_opcode() == k_convert){
                    if(is_kind_of<LoadVariableExpression>(ue->get_source())){
                        LoadVariableExpression* lve = 
                            to<LoadVariableExpression>(ue->get_source());
                        VariableSymbol* array = lve->get_source();
            
                        for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin();
                            iter!=params.end();iter++)
                        {
                            ParameterSymbol* par_sym = (*iter).first;
                            if(par_sym == array){
                                // match!
                                Type* array_type;
                                suif_hash_map<ParameterSymbol*, Type*>::iterator iter =
                                    params.find(par_sym);
                                
                                if(iter==params.end() || (*iter).second==NULL){
                                    //array_type = to<PointerType>(ue->get_result_type())->get_reference_type();
                                    array_type = tb->get_qualified_type(ue->get_result_type());
                                    params[par_sym] = array_type;
                                    //printf("%s has type ",par_sym->get_name().c_str());
                                    //array_type->print_to_default();
                                }else{
                                    array_type = params[par_sym].second;
                                    suif_assert(is_kind_of<QualifiedType>(array_type));
                                }

                                array->replace(array->get_type(), array_type);
                                remove_suif_object(ue);
                                remove_suif_object(lve);
                                lve->replace(lve->get_result_type(), tb->unqualify_type(array_type));
                                // put the LoadVar directly under ARE
                                are->set_base_array_address(lve);
                                //are->print_to_default();
                            }
                        }
                    } else {
                        suif_warning(ue->get_source(),
                            ("Expecting a LoadVariableExpression here"));
                    }
                } else {
                    suif_warning(ue, ("Disallow converts in AREs for "
                            "things other than procedure parameters"));
                }
            }
        }
    }
}
Esempio n. 20
0
SuifEnv& SuifEnv::operator=(const SuifEnv &) {
  suif_assert(false);
  return(*this);
}
Esempio n. 21
0
 ~hash_bin_type(void)
   { suif_assert((next == 0) && (_ref_count == 0)); }
void DismantleStructuredReturns::do_file_set_block( FileSetBlock* file_set_block ) {
    suif_map<CProcedureType *,QualifiedType *> type_map;
    list<ArrayReferenceExpression*> ref_exprs;
    SuifEnv *env = 0;
    TypeBuilder *tb = 0;
    VoidType *vt = 0;
    for (Iter<ProcedureSymbol> iter =
                object_iterator<ProcedureSymbol>(file_set_block);
	iter.is_valid();
	iter.next()) {
	ProcedureSymbol *sym = &iter.current();
	Type *type = sym->get_type();
	if (!is_kind_of<CProcedureType>(type))
	    continue;
	CProcedureType *cp_type = to<CProcedureType>(type);
	type = cp_type->get_result_type();
	if (!env) {
	    env = type->get_suif_env();
	    tb = (TypeBuilder*)
                env->get_object_factory(TypeBuilder::get_class_name());
	    vt = tb->get_void_type();
	    }
	suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type);

	QualifiedType *qtype;
	
 	if (t_iter == type_map.end()) {
	    if (!is_kind_of<GroupType>(type) && !is_kind_of<ArrayType>(type))
                continue;
	    qtype = tb->get_qualified_type(
                        tb->get_pointer_type(to<DataType>(type)));

	    cp_type->set_result_type(vt);
	    
	    cp_type->insert_argument(0,qtype);
	    type_map.enter_value(cp_type,qtype);
	    }
	else {
	    qtype = (*t_iter).second;
	    }
	ProcedureDefinition *def = sym->get_definition();
	if (!def) 
	    continue;
	ParameterSymbol *par = create_parameter_symbol(env,qtype);
	def->get_symbol_table()->append_symbol_table_object(par);
        def->insert_formal_parameter(0,par);
	//	Convert all returns into assigned and returns
	for (Iter<ReturnStatement> ret_iter = object_iterator<ReturnStatement>(def->get_body());
        	ret_iter.is_valid();
        	ret_iter.next()) {
	    ReturnStatement *ret = &ret_iter.current();
	    Expression *retval = ret->get_return_value();
	    ret->set_return_value(0);
	    retval->set_parent(0);
	    insert_statement_before(ret,
			create_store_statement(env,retval,create_var_use(par)));
	    }
	}
    //	Change all calls to the new form
    for (Iter<CallStatement> cs_iter =
                object_iterator<CallStatement>(file_set_block);
        cs_iter.is_valid();
        cs_iter.next()) {
        CallStatement *call = &cs_iter.current();
	Type *type = call->get_callee_address()->get_result_type();
	Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type());
        if (!is_kind_of<PointerType>(p_type))
            continue;
        p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type());

	if (!is_kind_of<CProcedureType>(p_type))
	    continue;
	CProcedureType *cp_type = to<CProcedureType>(p_type);
	
	suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type);
	if (t_iter == type_map.end())
	    continue;
	QualifiedType *qtype = (*t_iter).second;
	DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type())
		->get_reference_type()));
	VariableSymbol *var =
      	    new_anonymous_variable(env,call,tb->get_qualified_type(var_type));
	Expression *exp = create_symbol_address_expression(
		env,
		tb->get_pointer_type(var_type),
		var);
        call->insert_argument(0,exp);
        call->set_destination(0);
	}

    for (Iter<CallExpression> ce_iter =
                object_iterator<CallExpression>(file_set_block);
        ce_iter.is_valid();
        ce_iter.next()) {
        CallExpression *call = &ce_iter.current();
        Type *type = call->get_callee_address()->get_result_type();
        Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type());
	if (!is_kind_of<PointerType>(p_type))
            continue;
	p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type());
        if (!is_kind_of<CProcedureType>(p_type))
            continue;
        CProcedureType *cp_type = to<CProcedureType>(p_type);
;
        suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type);
        if (t_iter == type_map.end())
            continue;
        QualifiedType *qtype = (*t_iter).second;
        DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type())
                ->get_reference_type()));
        VariableSymbol *var =
            new_anonymous_variable(env,call,tb->get_qualified_type(var_type));
        Expression *exp = create_symbol_address_expression(
                env,
                tb->get_pointer_type(var_type),
                var);
        call->insert_argument(0,exp);

	Statement *loc = get_expression_owner(call);
	call->get_parent()->replace(call,create_var_use(var));
	call->set_parent(0);
        suif_assert(vt != 0);
        call->set_result_type(vt);

	EvalStatement *es = create_eval_statement(env);
	insert_statement_before(loc,es);
	// Would be better to turn this into a call statement
	es->append_expression(call);
        }
    }
Esempio n. 23
0
void SuifEnv::write( const String& outputFileName ) const {
  suif_assert( output_subsystem );
  output_subsystem->write( outputFileName );
}
Esempio n. 24
0
FileSetBlock *SuifEnv::read_more( const String& inputFileName ) const {
  suif_assert( input_sub_system );
  return input_sub_system->read( inputFileName );
}
Esempio n. 25
0
void SGraphBit::add_edge(const SGraphEdge &edge) {
  suif_assert(is_node_member(edge.from()));
  suif_assert(is_node_member(edge.to()));

  retrieve_bv(edge.from())->set_bit(edge.to(), true);
}
Esempio n. 26
0
/**
    Convert ArrayReferenceExpression \a top_array to a 
    MultiDimArrayExpression.
*/
void OneDimArrayConverter::
convert_array_expr2multi_array_expr(ArrayReferenceExpression* top_array){
    Expression* expr = top_array;
    unsigned int i = 0;

    suif_vector<Expression*> lower_bounds;
    suif_vector<Expression*> upper_bounds;
    list<Expression*> indices;
    IInteger bit_size, bit_alignment;
    suif_vector<ArrayReferenceExpression *> exprs;

    do{
        ArrayReferenceExpression* are = to<ArrayReferenceExpression>(expr);
        expr = are->get_base_array_address();
        exprs.push_back(are);
	} while(is_kind_of<ArrayReferenceExpression>(expr));

    // collect bounds and indeces
    for (unsigned int exp_ind = 0; exp_ind < exprs.size();exp_ind++)
    {
        ArrayReferenceExpression* are = exprs[exp_ind];
        DataType* type = are->get_base_array_address()->get_result_type();
        ArrayType* array_type;

		if(is_kind_of<ArrayType>(type)){
			array_type = to<ArrayType>(type);
		}else{
			array_type = to<ArrayType>(
				unwrap_ptr_ref_type(type)->get_base_type());
		}
        
        bit_size = array_type->get_element_type()->
                get_base_type()->get_bit_size();
        bit_alignment = array_type->get_element_type()->
                get_base_type()->get_bit_alignment();

        // What happens to ArrayType?? Does it become garbage?
        suif_assert(array_type->get_lower_bound());
        suif_assert(array_type->get_upper_bound());

        // clone bounds and add to the lists
        lower_bounds.push_back(array_type->get_lower_bound());
        upper_bounds.push_back(array_type->get_upper_bound());
        // save the index
        Expression* index = are->get_index();
        remove_suif_object(index); index->set_parent(NULL);
        indices.push_back(index);

        suif_assert(upper_bounds[i]);
        suif_assert(lower_bounds[i]);
        suif_assert(indices[i]);

        i++;
	}

    // Build the offset for the expression. We have to traverse upwards to do this
    Expression *top_expr_base = exprs[exprs.size()-1]->get_base_array_address();
    
	DataType* top_expr_base_type = top_expr_base->get_result_type();
	ArrayType* top_array_type;
	if(is_kind_of<ArrayType>(top_expr_base_type)){
		top_array_type = to<ArrayType>(top_expr_base_type);
	}else{
		top_array_type = to<ArrayType>(tb->unqualify_data_type(unwrap_ptr_ref_type(
			top_expr_base_type)));
	}
    
	Expression* inc    = create_int_constant(suif_env, 1);
    Expression* offset = create_int_constant(suif_env, 0);
    suif_vector<Expression *> elements;

    for (unsigned int ind = 0;ind < lower_bounds.size(); ind ++)
    {
        Expression *lower = lower_bounds[ind];
        Expression *upper = upper_bounds[ind];

        offset = 
            build_dyadic_expression(k_add, 
                offset,
                build_dyadic_expression(
                    k_multiply, 
                    deep_suif_clone(inc),
                    deep_suif_clone(lower)));
        
        Expression *element =
                    build_dyadic_expression(k_add, 
                        build_dyadic_expression(k_subtract,
                            deep_suif_clone(upper), 
                            deep_suif_clone(lower)),
                        create_int_constant(suif_env,1));

        inc = build_dyadic_expression(k_multiply, 
            inc, 
            deep_suif_clone(element));

	    elements.push_back(element);
    }
    // Now, inc and offset are ready

    // retrieve the multi-type
    MultiDimArrayType* multi_type;
	suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter =
	    type_map->find(top_array_type);
#ifdef CONVERT_TYPES
    suif_assert_message((type_iter != type_map->end()),
        ("Array type never translated"));
#else
    if(type_iter == type_map->end()){
        multi_type = array_type2multi_array_type(top_array_type);
    }else
#endif //CONVERT_TYPES
    multi_type = (*type_iter).second;

    remove_suif_object(top_expr_base);

    // add a convert to the necessary type
    top_expr_base = create_unary_expression(suif_env, 
            tb->get_pointer_type(multi_type), 
            k_convert, top_expr_base);
    //top_expr_base->print_to_default();

    // construct the expression to be returned 
    MultiDimArrayExpression* mae =
        create_multi_dim_array_expression(suif_env,
            top_array->get_result_type(), 
            top_expr_base, 
            offset);

    // now when we have the expression, set the indices
    for (list<Expression*>::iterator ind_iter = indices.begin();
        ind_iter!=indices.end(); ind_iter++)
    {
        Expression* index = *ind_iter;
        //printf("%p \t", index);index->print_to_default();
        mae->append_index(index);
    }

    for (suif_vector<Expression *>::iterator eiter = elements.begin();
        eiter != elements.end(); eiter ++)
    {
        Expression* element = *eiter;
        mae->append_element(element);
    }

    replace_expression(top_array, mae);
}