int main() { printf("Testing lists...\n"); List *list = (List *) create_list(); assert(list != NULL); assert(list->data == NULL); assert(list->next == NULL); int w = 42; int x = 1; int y = 2; int z = 3; append_to_list(list, &x); assert(*(int *)(list->data) == 1); assert(list->next != NULL); append_to_list(list, &y); assert(*(int *)(list->next->data) == 2); assert(list->next->next != NULL); append_to_list(list, &z); assert(*(int *)(list->next->next->data) == 3); assert(list->next->next->next != NULL); assert(list->next->next->next->data == NULL); assert(list->next->next->next->next == NULL); list = (List *) push_to_list(list, &w); assert(*(int *)(list->data) == 42); assert(list->next != NULL); list = (List *) pop_from_list(list); assert(*(int *)(list->data) == 1); assert(list_length(list) == 3); assert(list_index(list, &y) == 1); assert(list_index(list, &w) == -1); list = remove_from_list(list, &x); assert(*(int *)(list->data) == 2); list = push_to_list(list, &x); list = remove_from_list(list, &y); assert(*(int *)(list->next->data) == 3); printf("List tests passed\n"); return 0; }
void acdl_worklist_orderedt::dec_update (const local_SSAt &SSA, const acdl_domaint::meet_irreduciblet &stmt, const exprt& assertion) { // ********************************************************************** // Initialization Strategy: Guarantees top-down and bottom-up propagation // Decision -- Top // Leaf node -- Middle // Rest -- Bottom // ********************************************************************** typedef std::list<acdl_domaint::statementt> assert_worklistt; assert_worklistt assert_worklist; typedef std::list<acdl_domaint::statementt> predecs_worklistt; predecs_worklistt predecs_worklist; typedef std::list<acdl_domaint::statementt> leaf_worklistt; leaf_worklistt leaf_worklist; typedef std::list<acdl_domaint::statementt> inter_worklistt; inter_worklistt inter_worklist; assert_listt assert_list; if (SSA.nodes.empty ()) return; push_into_list(assert_worklist, stmt); // Now compute the transitive dependencies // compute fixpoint mu X. assert_nodes u predecessor(X) while(!assert_worklist.empty() > 0) { // collect all the leaf nodes const acdl_domaint::statementt statement=pop_from_list(assert_worklist); // select vars in the present statement acdl_domaint::varst vars; select_vars (statement, vars); // compute the predecessors update(SSA, vars, predecs_worklist, statement, assertion); // std::list<acdl_domaint::statementt>::iterator // iterassert=std::find(assert_list.begin(), assert_list.end(), statement); for(std::list<acdl_domaint::statementt>::const_iterator it=predecs_worklist.begin(); it!=predecs_worklist.end(); ++it) { std::list<acdl_domaint::statementt>::iterator finditer= std::find(worklist.begin(), worklist.end(), *it); // This is required to prevent inserting // individual assertions to the worklist std::list<acdl_domaint::statementt>::iterator iterassert= std::find(assert_list.begin(), assert_list.end(), *it); if(finditer==worklist.end() && iterassert==assert_list.end()) { // never seen this statement before push(*it); push_into_assertion_list(assert_worklist, *it); // push into map live_var_list.clear(); push_into_map(*it, live_var_list); } } } #ifdef DEBUG std::cout << "The content of the sliced but unordered worklist is as follows: " << std::endl; for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { std::cout << "Sliced Unordered Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; } #endif // order the leaf nodes right after all assertions // order the leaf nodes right after all assertions for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant || expr_rhs.is_true() || expr_rhs.is_false()) { push_into_list(leaf_worklist, *it); } else if(expr_rhs.type().id()!=ID_constant) { push_into_list(inter_worklist, *it); } } else { push_into_list(inter_worklist, *it); } } #if 0 for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.type().id()==ID_constant) { std::cout << "The type is " << expr_rhs.type().id() << std::endl; std::cout << "pushing equalities into leaf" << std::endl; push_into_list(leaf_worklist, *it); } else if(expr_rhs.type().id()!=ID_constant) { std::cout << "pushing equalities into inter" << std::endl; push_into_list(inter_worklist, *it); } } else { std::cout << "pushing constraint" << std::endl; push_into_list(inter_worklist, *it); } } #endif #if 0 // Do we need to separately treat ID_constraint ? if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant) push_into_list(leaf_worklist, *it); // We do not push nondet elements in to the worklist /* std::string str("nondet"); std::string rhs_str=id2string(expr_rhs.get(ID_identifier)); std::size_t found=rhs_str.find(str); // push the nondet statement in rhs if(found!=std::string::npos) push_into_list(leaf_worklist, *it); */ // exprt expr_rhs=expr.rhs(); // select vars in the present statement acdl_domaint::varst vars_rhs; select_vars (expr_rhs, vars_rhs); for(std::list<acdl_domaint::statementt>::const_iterator it1=worklist.begin(); it1!=worklist.end(); ++it1) { if(*it==*it1) continue; else { /*if(!(check_statement(*it1, vars_rhs))) { // *it is a leaf node // push_into_worklist(leaf_worklist, *it); } // this is an intermediate node, not leaf else {*/ push_into_list(inter_worklist, *it); } } } }
void acdl_worklist_orderedt::initialize (const local_SSAt &SSA, const exprt &assertion, const exprt& additional_constraint) { // ********************************************************************** // Initialization Strategy: Guarantees top-down and bottom-up propagation // Assertions -- Top // Leaf node -- Middle // Rest -- Bottom // ********************************************************************** typedef std::list<acdl_domaint::statementt> assert_worklistt; assert_worklistt assert_worklist; typedef std::list<acdl_domaint::statementt> predecs_worklistt; predecs_worklistt predecs_worklist; typedef std::list<acdl_domaint::statementt> leaf_worklistt; leaf_worklistt leaf_worklist; typedef std::list<acdl_domaint::statementt> inter_worklistt; inter_worklistt inter_worklist; assert_listt assert_list; #if 0 if (SSA.nodes.empty ()) return; #endif if(statements.empty()) return; // insert the assertions like (!(a1 && a2 && a3)) on to the worklist #if 0 and_exprt::operandst and_expr; for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin (); n_it!=SSA.nodes.end (); n_it++) { for (local_SSAt::nodet::assertionst::const_iterator a_it= n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++) { push_into_list(assert_worklist, *a_it); and_expr.push_back(*a_it); push_into_assertion_list(assert_list, not_exprt(*a_it)); // push into worklist_vars acdl_domaint::varst avars; find_symbols(*a_it, avars); worklist_vars.insert(avars.begin(), avars.end()); } } #endif push_into_list(assert_worklist, assertion); push_into_assertion_list(assert_list, not_exprt(assertion)); acdl_domaint::varst avars; find_symbols(assertion, avars); worklist_vars.insert(avars.begin(), avars.end()); // Now compute the transitive dependencies // compute fixpoint mu X. assert_nodes u predecessor(X) while(!assert_worklist.empty() > 0) { #ifdef DEBUG std::cout << "Populating the worklist" << std::endl; #endif // collect all the leaf nodes const acdl_domaint::statementt statement=pop_from_list(assert_worklist); // select vars in the present statement acdl_domaint::varst vars; select_vars (statement, vars); // compute the predecessors update(SSA, vars, predecs_worklist, statement, assertion); // std::list<acdl_domaint::statementt>::iterator // iterassert=std::find(assert_list.begin(), assert_list.end(), statement); for(std::list<acdl_domaint::statementt>::const_iterator it=predecs_worklist.begin(); it!=predecs_worklist.end(); ++it) { std::list<acdl_domaint::statementt>::iterator finditer= std::find(worklist.begin(), worklist.end(), *it); // This is required to prevent inserting // individual assertions to the worklist std::list<acdl_domaint::statementt>::iterator iterassert= std::find(assert_list.begin(), assert_list.end(), *it); if(finditer==worklist.end() && iterassert==assert_list.end()) { // never seen this statement before push(*it); push_into_assertion_list(assert_worklist, *it); } } } #ifdef DEBUG std::cout << "The content of the sliced but unordered worklist is as follows: " << std::endl; for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { std::cout << "Sliced Unordered Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; } #endif // order the leaf nodes right after all assertions for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant || expr_rhs.is_true() || expr_rhs.is_false()) { push_into_list(leaf_worklist, *it); } else if(expr_rhs.type().id()!=ID_constant) { push_into_list(inter_worklist, *it); } } else { push_into_list(inter_worklist, *it); } } #if 0 // order the leaf nodes right after all assertions for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { // Do we need to separately treat ID_constraint ? if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant) push_into_list(leaf_worklist, *it); // We do not push nondet elements in to the worklist /* std::string str("nondet"); std::string rhs_str=id2string(expr_rhs.get(ID_identifier)); std::size_t found=rhs_str.find(str); // push the nondet statement in rhs if(found!=std::string::npos) push_into_list(leaf_worklist, *it); */ // exprt expr_rhs=expr.rhs(); // select vars in the present statement acdl_domaint::varst vars_rhs; select_vars (expr_rhs, vars_rhs); for(std::list<acdl_domaint::statementt>::const_iterator it1=worklist.begin(); it1!=worklist.end(); ++it1) { if(*it==*it1) continue; /*else { if(!(check_statement(*it1, vars_rhs))) { // *it is a leaf node // push_into_worklist(leaf_worklist, *it); }*/ // this is an intermediate node, not leaf else { // pop the element from the list // const acdl_domaint::statementt statement=pop_from_worklist(worklist); push_into_list(inter_worklist, *it); } } } } #endif #ifdef DEBUG for(std::list<acdl_domaint::statementt>::const_iterator it=leaf_worklist.begin(); it!=leaf_worklist.end(); ++it) { std::cout << "Leaf Element::" << from_expr(SSA.ns, "", *it) << std::endl; } for(std::list<acdl_domaint::statementt>::const_iterator it=inter_worklist.begin(); it!=inter_worklist.end(); ++it) { std::cout << "Intermediate Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; } #endif // Now prepare the final worklist worklist.clear(); #if 0 // insert assertions // Push the negation of the assertions into the worklist unsigned int size=and_expr.size(); exprt::operandst::const_iterator it=and_expr.begin(); if(size==1) { exprt::operandst::const_iterator it=and_expr.begin(); #ifdef DEBUG std::cout << "First single assertion push: " << *it << std::endl; #endif exprt exp=*it; // push this into worklist at the end as TOP element not_exprt not_exp(exp); worklist.push_back(not_exp); } else { and_exprt final_and; std::swap(final_and.operands(), and_expr); not_exprt not_exp(final_and); #ifdef DEBUG // push this into worklist at the end as TOP element std::cout << "First push: " << not_exp.pretty() << std::endl; #endif worklist.push_back(not_exp); } #endif // push the assertion and additional constriant // in to the worklist worklist.push_back(not_exprt(assertion)); if(additional_constraint!=true_exprt()) worklist.push_back(additional_constraint); acdl_domaint::varst var_leaf; // insert leaf nodes while(!leaf_worklist.empty() > 0) { const acdl_domaint::statementt statement=pop_from_list(leaf_worklist); push_into_list (worklist, statement); acdl_domaint::varst lvars; find_symbols(statement, lvars); var_leaf.insert(lvars.begin(), lvars.end()); } // insert intermediate nodes while(!inter_worklist.empty() > 0) { const acdl_domaint::statementt statement=pop_from_list(inter_worklist); push_into_list (worklist, statement); // push into worklist_vars acdl_domaint::varst avars; find_symbols(statement, avars); // do not insert any leaf variables for(acdl_domaint::varst::const_iterator it=avars.begin(); it!=avars.end(); ++it) { if(var_leaf.find(*it)==var_leaf.end()) worklist_vars.insert(*it); } } #ifdef DEBUG std::cout << "The content of the ordered worklist is as follows: " << std::endl; for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) std::cout << "Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; #endif #if 0 // ********************************************** // Initialization Strategy: Add only assertions // ********************************************** if (SSA.nodes.empty ()) return; // insert the assertions like (!(a1 && a2 && a3)) on to the worklist and_exprt::operandst and_expr; for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin (); n_it!=SSA.nodes.end (); n_it++) { for (local_SSAt::nodet::assertionst::const_iterator a_it= n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++) { and_expr.push_back(*a_it); } } unsigned int size=and_expr.size(); #ifdef DEBUG std::cout << "The number of Assertions are : " << size << std::endl; #endif exprt::operandst::const_iterator it=and_expr.begin(); std::cout << "First single assertion push: " << *it << std::endl; if(size==1) { exprt::operandst::const_iterator it=and_expr.begin(); #ifdef DEBUG std::cout << "First single assertion push: " << *it << std::endl; #endif exprt exp=*it; not_exprt not_exp(exp); push(worklist, not_exp); } else { and_exprt final_and; std::swap(final_and.operands(), and_expr); not_exprt not_exp(final_and); #ifdef DEBUG std::cout << "First push: " << not_exp.pretty() << std::endl; #endif push(worklist, not_exp); } #endif #if 0 // ************************************************** // Initialization Strategy: Add the first SSA element // ************************************************** // check for equalities or constraints or next node if (SSA.nodes.empty ()) return; assert(!SSA.nodes.front ().equalities.empty ()); // insert the first SSA element on to the worklist push(worklist, SSA.nodes.front ().equalities.front ()); #ifdef DEBUG std::cout << "First push: " << from_expr (SSA.ns, "", SSA.nodes.front().equalities.front ()) << std::endl; #endif #endif }
char * create_closure_key( struct itemset * current_itemset ) { struct item * current_item; struct hash * looked_up; struct list * production; int p; int d; int i; // Push all the items in the itemset onto the unchecked stack. struct list * unchecked = new_list(); struct hash * current_items = current_itemset->items; struct list * key_list = new_list(); list_keys_in_hash( current_items, key_list, "" ); for ( i = 0; i < key_list->next_index; i++ ) { char * key = listlookup( key_list, i ); append_to_list( unchecked, (void *) hashlookup( current_items, key )->data ); } destroy_key_list( key_list ); // Now process unchecked items, possibly adding more along the way. while ( unchecked->next_index ) { current_item = pop_from_list( unchecked ); p = current_item->prod_num; d = current_item->dot; production = GRAMMAR[p].production; if ( d == production->next_index - 1 ) { // This item is complete. append_to_list( current_itemset->complete, (void *) current_item ); continue; // Nothing more to do here. } // Otherwise, this item is incomplete, // so record it in the appropriate ready_for slot for this itemset. char * predicted = listlookup( production, d + 1 ); struct list * items_ready_for = NULL; struct hash * looked_up = hashlookup( current_itemset->ready_for, predicted ); if ( ! looked_up ) { items_ready_for = new_list(); add_to_hash( current_itemset->ready_for, predicted, (void *) items_ready_for ); } else { items_ready_for = looked_up->data; } append_to_list( items_ready_for, (void *) current_item ); // If the predicted symbol is terminal, this item is done processing. if ( ( (int *) hashlookup( IS_TERMINAL, predicted )->data ) == &TRUE ) { continue; // Can't expand terminals. } // Otherwise, the predicted symbol is nonterminal, // so expand the itemset using all applicable productions. struct list * predicted_productions = hashlookup( PRODUCTIONS_FOR, predicted )->data; for ( i = 0; i < predicted_productions->next_index; i++ ) { int predicted_p = (long int) listlookup( predicted_productions, i ); struct item * predicted_item = new_item(); predicted_item->prod_num = predicted_p; char * predicted_key = create_item_key( predicted_item ); if ( looked_up = hashlookup( current_items, predicted_key ) ) { // Item unneeded. free( predicted_item ); free( predicted_key ); continue; } // Otherwise, add the new item to the itemset, and to the unchecked stack. add_to_hash( current_items, predicted_key, (void *) predicted_item ); free( predicted_key ); append_to_list( unchecked, (void *) predicted_item ); } } // Now that the itemset has been filled out, create and return its identifying string. key_list = new_list(); list_keys_in_hash( current_items, key_list, "" ); char * closure_key = join_key_list( key_list, "_" ); destroy_key_list( key_list ); return closure_key; }
struct lambda_expr * parse( char * string, char ** error ) { INPUT = string; struct lambda_expr * result; struct token * t = NULL; struct lambda_expr * (*action_function)( int, struct list * ); int current_state = 0; struct list * stack = new_list(); append_to_list( stack, (void *) (long int) 0 ); // Start stack with initial state. int i = 0; struct hash * row; struct hash * looked_up; struct list * trans_list; struct transition * trans; char * action; int arg; // Loop tokens of input. while ( 1 ) { if ( ! t ) { t = get_next_token( string, i ); if ( strcmp( t->type, "end" ) ) { i += ( t->last - t->first + 1 ); } } row = listlookup( TABLE, current_state ); looked_up = hashlookup( row, t->type ); if ( ! looked_up ) { *error = "No transition"; return NULL; } trans_list = looked_up->data; if ( trans_list->next_index == 0 ) { *error = "No transition"; return NULL; } if ( trans_list->next_index > 1 ) { *error = "Ambiguous transition."; return NULL; } trans = listlookup( trans_list, 0 ); action = trans->action; if ( !strcmp( action, "accept" ) ) { pop_from_list( stack ); // Throw away old state result = pop_from_list( stack ); pop_from_list( stack ); // Throw away initial state number destroy_empty_list( stack ); free( t ); return result; } arg = trans->arg; if ( !strcmp( action, "shift" ) ) { append_to_list( stack, (void *) t ); append_to_list( stack, (void *) (long int) arg ); current_state = arg; // Iterate state. t = NULL; // Force reading of another token,. continue; } // The action is "reduce" action_function = GRAMMAR[arg].reduction; result = (*action_function)( arg, stack ); // Perform action, change stack. current_state = (int) (long int) listlookup( stack, stack->next_index - 1 ); append_to_list( stack, (void *) result ); struct list * production = GRAMMAR[arg].production; char * lhs = listlookup( production, 0 ); row = listlookup( GOTO, current_state ); struct list * trans_list = hashlookup( row, lhs )->data; if ( !trans_list || trans_list->next_index == 0 ) { *error = "No transition."; return NULL; } else if ( trans_list->next_index >= 2 ) { *error = "Ambiguous transition."; return NULL; } current_state = (int) (long int) listlookup( trans_list, 0 ); append_to_list( stack, (void *) (long int) current_state ); } // End tokens of input loop. // Should never get here! }
void sys_send (struct msg *m, options_t options){ if(get_current_tid() == Posts[post].owner){ if(Threads[Posts[m->dest].owner].vm == Threads[Posts[m->from].owner].vm){ if(m->dest > POST_NUM_MAX || Posts[m->dest].owner == 0){ // TODO: send a error msg } prepend_to_list(Posts[m->dest].received, m); wake_thread(Posts[m->dest].owner); }else{ // TODO: move a page of a message to dest if(Posts[m->dest].handler == NULL){ // TODO: prepend_to_list(Posts[m->dest].received, m); }else{ // TODO: create thread and call handler } } } struct msg *sys_recv (post_id_t post, options_t options){ struct msg *m; if(get_current_tid() != Posts[post].owner) return NULL; if(is_list_empty(Posts[post].received)){ if(options & MSG_NOWAIT) return NULL; // wait for a message sleep_thread(Posts[m->dest].owner); } Posts[post].received = pop_from_list(Posts[post].received, (void *) &m); return m; } void sys_await (post_id_t post, void (*handler)(struct msg *m), uintmax_t max_thread_num){ if(get_current_tid() != Posts[post].owner) return; Posts[post].handler = handler; Posts[post].max_thread_num = max_thread_max; } struct msg *compose (size_t body_size){ return allocate_memory_block(sizeof(struct msg) + body_size); } void discard (struct msg *m){ free_memory_block(m); }