Example #1
0
void test_move_card_from_non_stack_empty_stack_to_stack_empty_stack() {
  struct stack *origin, *destination;
  struct card *card[6];

  for (int i = 0; i < 6; i++) {
    card_malloc(&card[i]);
    card_init(card[i]);
    card_set(card[i], TWO + i, i % 5, i % 2, 99, 99);
  }

  stack_malloc(&origin);
  stack_malloc(&destination);
  stack_init(origin);
  stack_init(destination);
  for (int i = 0; i < 6; i++) {
    stack_push(&origin, card[i]);
  }
  move_card(&origin, &destination);

  assert(stack_length(origin) == 5);
  assert(stack_length(destination) == 1);
  assert(cards_equal(destination->card, card[5]));

  move_card(&origin, &destination);

  assert(stack_length(origin) == 4);
  assert(stack_length(destination) == 2);
  assert(cards_equal(destination->card, card[4]));

  move_card(&origin, &destination);

  assert(stack_length(origin) == 3);
  assert(stack_length(destination) == 3);
  assert(cards_equal(destination->card, card[3]));

  stack_free(origin);
  stack_free(destination);
}
Example #2
0
double _parse(gchar *args, struct global_vars *gvars)
{
	gchar mul_char = '*';
	gdouble minus_one = -1.0;
	gchar null = 0;
	gint args_len = strlen(args);
	
	struct stack *arguments = stack_init(sizeof(gdouble));
	struct stack *operators = stack_init(sizeof(gchar));

	gint i = 0;
	gint j = 0;
	gint local_nest_level = 0;

	gint8 last_p = 0;  /** priority of last parsed operator */
	gboolean coef_flag = FALSE;  /** set if value might preceed a bracket and thus become a coefficient */
	gboolean func_flag = FALSE;  /** set if result of next bracket is to be passed as an argument to function <symbol> */
	gboolean nest_flag = FALSE;  /** indicates characters are being collected and not parsed */
	gboolean nest_init_flag = FALSE;  /** necessary to skip first character '(' during string collection */
	gboolean neg_flag = TRUE;  /** set if next '-' will make number signed and not be an operator */
	gboolean frac_flag = FALSE;
	
	
	//char nested_term[100] = { 0 }; /** collector string for contents of nested term */
	GString *nested_term = g_string_new(&null);
	//char symbol[100] = { 0 }; /** collector string for symbol name */
	GString *symbol = g_string_new(&null);


	for (i=0; i < args_len; i++)
	{

		if (nest_init_flag) {nest_init_flag = FALSE;}

		/** lock computing by raising nest level, substitute '*' if coefficient exists */
		if (args[i] == '(')
		{
			if (!nest_flag) /** nested interpreting is just about to be initialized */
			{
				if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);}
				coef_flag = TRUE;
				nest_flag = TRUE;
				nest_init_flag = TRUE;
				gvars->nest_level += 1;
				nested_term = g_string_new(&null);
			}
			else  /** nested interpreting is in progress */
			{
				local_nest_level += 1;
			}
		}

		else if (args[i] == ')')
		{
			if (nest_flag && local_nest_level == 0) /** nesting has reached end */
			{
				nest_flag = FALSE;
				gdouble nested_term_result = _parse(nested_term->str, gvars);
				gvars->nest_level -= 1;
				g_string_free(nested_term, TRUE);
				nested_term = g_string_new(&null);
				if (func_flag)
				{
					gdouble compute_function_results = compute_function(symbol->str, nested_term_result, gvars);
					stack_push(arguments, &compute_function_results);
					func_flag = FALSE;
					g_string_free(symbol, TRUE);
					symbol = g_string_new(&null);
				}
				else {stack_push(arguments, &nested_term_result);}
			}
			else  /** nested interpreting is in progress, passing by uninterpreted ')' */
			{
				local_nest_level -= 1;
			}
		}


		if (!nest_flag)
		{

			if (args[i] == '.' || args[i] == ',')
			{
				if (g_ascii_isdigit(char_at(args,i+1))) {frac_flag = TRUE;}
				else {gvars->error_type = 3; return 0;}
			}

			else if (g_ascii_isdigit(args[i]))  /** parse number */
			{
				if (gvars->debug)
					{for (j=0;j<gvars->nest_level;j++) {g_printf("   ");} g_printf("args[%d] is digit\n", i);}

				gint8 dig = to_d(args[i]);
				stack_push(gvars->digits, &dig);
				if (frac_flag) {gvars->frac_point -= 1;}
				/** check if there is more than one digit or fractal part */
				if (!(g_ascii_isdigit(char_at(args, i+1)) || char_at(args, i+1) == '.' || char_at(args, i+1) == ','))
				{
					if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);}
					gdouble joined_dig =  join_digits(gvars->digits, gvars->frac_point);
					stack_push(arguments, &joined_dig);
					neg_flag = FALSE; coef_flag = TRUE; frac_flag = FALSE; gvars->frac_point = 0;
				}
			}

			else if (isoperator(args[i]))  /** parse operators */
			{
				if (gvars->debug)
					{for (j=0;j<gvars->nest_level;j++) {g_printf("   ");} g_printf("args[%d] is operator\n", i);}

				if (neg_flag && args[i] == '-')  /** check if preceeding minus changes sign of next symbol */
				{
					neg_flag = FALSE;
					stack_push(arguments, &minus_one); stack_push(operators, &mul_char); last_p = priority(mul_char);
				}
				else
				{
					if (stack_length(arguments) <= stack_length(operators)) {gvars->error_type = 4; break;}
					/** check beforehand if lower priority operator is encountered */
					if (priority(args[i]) < last_p) {compute(arguments, operators, gvars);}
					last_p = priority(args[i]);
					stack_push(operators, &args[i]);
					coef_flag = FALSE;
					neg_flag = TRUE;
				}
			}

			else if (g_ascii_isalpha(args[i])) /** parse letters */
			{
				if (gvars->debug)
					{for (j=0;j<gvars->nest_level;j++) {g_printf("   ");} printf("args[%d] is letter\n", i);}

				if (coef_flag) {coef_flag = FALSE; stack_push(operators, &mul_char); last_p = priority(mul_char);}
				if (neg_flag) {neg_flag = FALSE;}
				g_string_append_c(symbol, args[i]);
				if (char_at(args,i+1) == '(')
				{
					compute_function(symbol->str, 1.337, gvars);
					if (gvars->error_type != 0)
					{
						gvars->error_type = 0;
						gdouble looked_up_c = lookup_constant(symbol->str, gvars);
						stack_push(arguments, &looked_up_c);
						//+symbol = "";
						g_string_free(symbol, TRUE);
						symbol = g_string_new(&null);
						coef_flag = TRUE;
					}
					else {func_flag = TRUE;}
				}
				else if (!g_ascii_isalpha(char_at(args,i+1)))
				{
					gdouble looked_up_c = lookup_constant(symbol->str, gvars);
					stack_push(arguments, &looked_up_c);
					g_string_free(symbol, TRUE);
					symbol = g_string_new(&null);
					coef_flag = TRUE;
				}
			}

		}

		else if (!nest_init_flag) /** this collector block needs to be skipped once so the first '(' isn't collected */
		{
			g_string_append_c(nested_term, args[i]);
		}

		if (args[i] == ' ') {coef_flag = FALSE;}

		if (char_at(args,i) == '#') {break;}  /** failsafe, in case array bounds are left */
	}
	if (gvars->debug)
		{printf("<args>\n");stack_dump(arguments, 'd');printf("<ops>\n");stack_dump(operators, 'c');printf("<>\n");}

	if (local_nest_level != 0 && gvars->error_type == 0) {gvars->error_type = 1;}
	if (neg_flag && gvars->error_type == 0) {gvars->error_type = 4;}
	if (gvars->error_type == 0) {compute(arguments, operators, gvars);}
	if (stack_length(arguments) > 1 && gvars->error_type == 0) {gvars->error_type = 4;printf("no2\n");}

	gdouble return_value = 0;
	if (gvars->error_type == 0) {stack_pop(arguments, &return_value);}
	stack_destroy(arguments);
	stack_destroy(operators);

	return return_value;
}
Example #3
0
void key_path(int graph[][MAX])
{
	int graph2[MAX][MAX];
	int i;
	for (i = 0; i < MAX; i++) {
		int j;
		for (j = 0; j < MAX; j++)
			graph2[i][j] = graph[i][j];
	}

	stack sve, svl;
	init_stack(&sve, 100);
	init_stack(&svl, 100);
	int ve[MAX];
	for (i = 0; i < MAX; i++)
		ve[i] = 0;
	int j;
	for (j = 0; j < MAX; j++) {
		for (i = 0; i < MAX; i++) {
			if (graph2[i][j] != 0)
				break;
		}
		if (i == MAX)
			push(&sve, j);
	}

	while (stack_length(&sve)) {
		int s = pop(&sve);
		push(&svl, s);
		int n;

		for (n = 0; n < MAX; n++) {
			graph2[s][n] = 0;
			if (graph[s][n] != 0) {
				int l;
				for (l = 0; l < MAX; l++) {
					if (graph2[l][n] != 0)
						break;
				}
				if (l == MAX)
					push(&sve, n);
			}
		}

		int m;
		for (m = 0; m < MAX; m++) {
			if (graph[s][m] != 0)
				if (ve[s]+graph[s][m] > ve[m])
					ve[m] = ve[s] + graph[s][m];
		}
	}

	int vl[MAX];
	for (i = 0; i < MAX; i++)
		vl[i] = ve[MAX-1];
	int x;
	while (stack_length(&svl)) {
		int v = pop(&svl);
		for (x = 0; x < MAX; x++)
			if (graph[x][v] != 0)
				if ((vl[v] - graph[x][v]) < vl[x])
					vl[x] = vl[v] - graph[x][v];
	}

	int key[MAX];
	i = 0;
	int y;
	for (y = 0; y < MAX; y++) {
		if (ve[y] == vl[y]) {
			key[i] = y;
			i++;
		}
	}
	printf("all the key node: ");
	for (y = 0; y < i; y++)
		printf ("%d ", key[y]);
	printf("\n");

	printf("keypath: ");
	int prev = key[0];
	int next = key[1];
	int length = 0;
	int ne;
	while (1) {
		length += graph[prev][next];
		printf("%d ", prev);
		if (next == key[i-1]) {
			printf ("%d\n", next);
			break;
		}
		for (y = 0; y < i; y++) {
			ne = key[y];
			if (graph[next][ne] != 0 ) {
				prev = next;
				next = ne;
				break;
			}
		}
	}

	printf("keypath length: %d\n", length);
}
Example #4
0
void print_stack(stack *s)
{
    while(stack_length(s) != 0)
    	printf("%c", pop(s));
    printf ("\n");
}
Example #5
0
Link interpret(Link codeblock_link ,  Link This, Link Arg){
    
    CallEnv env = callenv_new_root( codeblock_link, This, Arg);
    LinkStack stack = env->stack;
    
    
    Link b          = NULL;
    Link link       = NULL;
    Link parent     = NULL;
    Link child_key  = NULL;
    
    Link pusher     = NULL; // Anything in this variable gets pushed onto the stack
    Link trapped    = NULL; // This is the last critical caught by the trap operator
    
    int    delta = 0; // jump delta

    /* Main interpreter loop */
    while(1){

        switch( *(env->current++) ){

            case INTRO:
                env->current+=4;
                break;

            case ALLOC_MODULE:
                delta = read_offset(env);
                env->module->global_vars = linkarray_new(delta);
                break;
            
            case ALLOC_LOCAL:
                delta = read_offset(env);
                env->local = linkarray_new(delta);
                break;
                                
            case NO_OP:
                break;
            
            case RETURN: // if there is something on the env->stack stack pop it off and return it, if not return null link
                if (   stack_length(stack) - env->stack_offset ){
                    pusher = stack_pop(stack);
                }else{
                    pusher = object_create(Global->null_type);
                }
                goto done;

            case RAISE: // if there is something on the stack stack pop it off and return it, if not return null link
            
                if (  stack_length(stack) - env->stack_offset ){
                    pusher = create_critical(stack_pop(stack));
                }else{
                    pusher = create_critical(object_create(Global->null_type));
                }
                goto done;

            case PUSH_LEX:
                delta = read_offset(env);
                //fprintf(stderr , "push lex [%i]    %p\n", delta,env->function->value.codeblock->lexicals);
                pusher = link_dup(env->function->value.codeblock->lexicals->vars[delta]);
                break;
                
            case STORE_LEX:
                delta = read_offset(env);
                //fprintf(stderr , "storing lex [%i]    %p\n", delta,env->function->value.codeblock->lexicals);
                b = env->function->value.codeblock->lexicals->vars[delta];
            
                if (b){
                    if  ( (b->type == Global->function_type) && 
                          (b->value.codeblock->lexicals == env->function->value.codeblock->lexicals)
                        )  b->value.codeblock->lexical_cycles--;
                    link_free(b);
                }
                
                b = link_dup(stack_peek(stack));
                if  ( (b->type == Global->function_type) && 
                      (b->value.codeblock->lexicals == env->function->value.codeblock->lexicals)
                    )  b->value.codeblock->lexical_cycles++;
                
                env->function->value.codeblock->lexicals->vars[delta] = b;
                
                break;
            
            case DEF:
                if (env->Def) link_free(env->Def);
                env->Def = stack_pop(env->stack);
                pusher = link_dup(env->Def);
                break;
            
            case PUSH_DEF:
                if ( ! env->Def){
                    pusher = exception("NoDefObject",NULL, NULL);
                }
                pusher = link_dup(env->Def);
                break;
                
                
                
            case ALLOC_LEXICAL:
                delta = read_offset(env);
                lexicals_alloc( env->function, delta);
                //env->lexical_root = 1;
                break;
                
            case STORE_ARG:
                delta = read_offset(env);
                
                if (env->Arg->value.array->length  > delta){
                    retry_store_arg:
                    env->Arg->value.array->links[delta] =  link_dup( stack_peek(stack) );
                }else{
                    array_push(env->Arg, NULL);
                    goto retry_store_arg;
                } 
                break;
                
            case PUSH_ARG:
                delta = read_offset(env);
                if (env->Arg->value.array->length  > delta){
                    pusher = link_dup(  env->Arg->value.array->links[delta]);
                }else{
                    pusher = exception("ArgsIndexOutOfBounds", NULL, NULL);
                }
            
                break;
                
            case STORE_GVAR:
                delta = read_offset(env);
                if (env->module->global_vars->links[delta]){
                    link_free(env->module->global_vars->links[delta]);
                }
                env->module->global_vars->links[delta] = link_dup( stack_peek(stack) );
                break;

            case STORE_VAR:
                delta = read_offset(env);

                if (env->local->links[delta]){
                    link_free(env->local->links[delta]);
                }
            
                env->local->links[delta] = link_dup( stack_peek(stack) );
                break;

            case STORE_CHILD:
                link        = stack_pop(stack); // value
                child_key   = stack_pop(stack); // key to find the child
                parent      = stack_pop(stack); // parent to look in
                pusher = object_addChild(parent, link, child_key);
                goto STORE_COMMON;

            case STORE_ATTR:
                link           = stack_pop(stack); // value
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in
                pusher = addAttr(parent, link,child_key);
                goto STORE_COMMON;
                
            STORE_COMMON:
                if (! pusher){
                    pusher = exception("AssignError", NULL, NULL);
                    link_free(link);
                }
            
                link_free(child_key);
                link_free(parent);
                break;

            case LT:
                delta = compare(env);
                pusher = create_numberi( (delta < 0)  ? 1 : 0 );
                break;

            case GT:
                delta = compare(env);
                pusher = create_numberi( (delta > 0)  ? 1 : 0 );
                break;

            case EQ:
                delta = compare(env);
                pusher = create_numberi( (delta == 0)  ? 1 : 0 );
                break;

            case NE:
                delta = compare(env);
                pusher = create_numberi( (delta == 0)  ? 0 : 1 );
                break;

            case LE:
                delta = compare(env);
                pusher = create_numberi( (delta <= 0)  ? 1 : 0 );
                break;

            case GE:
                delta = compare(env);
                pusher = create_numberi( (delta >= 0)  ? 1 : 0 );
                break;
        
            case CMP:
                delta = compare(env);
                pusher = create_numberi( delta );
                break;
            
            case OR:
            case AND:
                break;

            case SUB:
                b = stack_pop(env->stack);
                link = stack_pop(env->stack);
            
                if ( (link->type == Global->number_type) && (link->type == b->type)){
                    pusher = create_number(link->value.number - b->value.number);
                    link_free(link);
                    link_free(b);
                    break;
                }            
            
                pusher = object_op_minus(link,b);
                link_free(link);
                link_free(b);
            
                break;
            
            case ADD:
                b = stack_pop(env->stack);
                link = stack_pop(env->stack);
            
                if ( (link->type == Global->number_type) && (link->type == b->type)){
                    pusher = create_number(link->value.number + b->value.number);
                    link_free(link);
                    link_free(b);
                    break;
                }            
            
                pusher = object_op_plus(link,b);
                link_free(link);
                link_free(b);
                
                break;
                        
            case DIV:
                binary_op(env , object_op_divide);
                break;
            
            case MULT:
                binary_op(env , object_op_multiply);
                break;
            
            case MOD:
                binary_op(env , object_op_modulus);
                break;
            
            case POW:
                binary_op(env , object_op_power);
                break;
            
            case NEG:
                unary_op(env, object_op_neg);
                break;
            
            case NOT:
                link = stack_pop(stack);
                pusher = create_numberi(  (object_is_true(link))  ?  0 : 1 );
                link_free(link);
                break;

            case TEST:
            case ELSE:
                break;

            case DO:
                delta = read_offset(env);
                link  = codeblock_literal2( env->function->value.codeblock->parent, delta  );
                if (env->function->value.codeblock->lexicals) {
                    lexicals_attach( env->function->value.codeblock->lexicals, link);
                }
                env = callenv_new_doblock(env,link);
                break;
            
            case PUSH_ARRAY:
                delta = read_offset(env);
                pusher =  array_new_subarray( stack , delta);
                break;
                
            case CALL:
                link   = stack_pop(stack);     // the arguments in an array
                b      = stack_pop(stack);     // the function that gets called
                parent = link_dup(env->This);  // caller
                goto CALL_COMMON;

            
            case CALL_ATTR:            
                link       = stack_pop(stack);    // arguments
                child_key  = stack_pop(stack);    // name of the function
                parent     = stack_pop(stack);    // caller
                b = getAttr(parent,child_key); // the function that gets called           
                link_free(child_key); // no longer need the attributes key
            
                if (! b) {
                    pusher = exception("AttrNotFound", NULL, NULL);
                    break;
                }
                goto CALL_COMMON;
                
            case CALL_CHILD:
                link       = stack_pop(stack);     // ARG
                child_key  = stack_pop(stack);
                parent     = stack_pop(stack);     // THIS
                b = object_getChild(parent,child_key);
                link_free(child_key);
                goto CALL_COMMON;

            CALL_COMMON:
                /* function type so we can call it inline */
                if (b->type == Global->function_type){
                    env = callenv_new_function(env, b, parent, link); // ce , func,this, arg

                /* Not a CodeBlock so we have to use its virtual call function */
                }else{
                    pusher = object_call(b,  parent, link);// function, caller, args
                    link_free(link);
                    if (parent) link_free(parent);
                    link_free(b);
                    if (! pusher) pusher = object_create(Global->null_type);
                }
                break;

            case DEL_CHILD:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                /* delete child from container */
                pusher = object_delChild(parent,child_key);
                if (! pusher) pusher = exception("ChildNotFound", object_getString(child_key), NULL);
                        
                link_free(child_key);
                link_free(parent);
                break;                
                
            case DEL_ATTR:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                /* delete attr from container */
                pusher = delAttr(parent,child_key);
                if (! pusher) pusher = exception("AttrNotFound", object_getString(child_key), NULL);

                link_free(child_key);
                link_free(parent);
                break;                
                
            case GET_CHILD:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                pusher = object_getChild(parent, child_key);            
                if (! pusher) pusher = exception("ChildNotFound", object_getString(child_key), NULL);

                link_free(parent);
                link_free(child_key);
                break;

            case GET_ATTR:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                pusher = getAttr(parent, child_key);
                if (! pusher) pusher = exception("AttrNotFound", object_getString(child_key), NULL);

                link_free(parent);
                link_free(child_key);
                break;

            case TRAP:
                break;

            case CLEAR:
                for ( delta = stack_length( stack ) ; delta > env->stack_offset ; delta--){
                    link_free( stack_pop(stack) );    
                }    
                break;
            
            case STOP:
                break;

            done:
            case END:
                for ( delta = stack_length( stack ) ; delta > env->stack_offset ; delta--){
                    link_free( stack_pop(stack) );    
                }    
                addBacktrace(pusher, env->function, env->linenum);
                env = callenv_free(env);

                if (! env) goto end;
                
                if (! pusher) pusher = object_create(Global->null_type);
                break;

            /* JUMPS */
            case JIT:  /* Jump if true */
                delta = read_offset(env);
                link = stack_peek(stack);
                if ( link->type->is_true(link) )  env->current = env->start+delta;
                break;

            case JIF:  /* Jump if false */
                delta = read_offset(env);
                link = stack_peek(stack);
                if ( ! link->type->is_true(link) )  env->current = env->start+delta;
                break;
                

            case JIF_POP:  /* Pop value then jump if value is false,  */
                delta = read_offset(env);
                link = stack_pop(stack);
                if ( ! link->type->is_true(link) )  env->current = env->start+delta;
                link_free(link);
                break;
                
            case JUMP:  /* Absolute jump */
                delta = read_offset(env);
                env->current = env->start + delta;
                break;

            case JINC: /* Jump If Not Critical */
                delta = read_offset(env);
                env->current = env->start+delta;
                break;
                
              jinc_critical:
                delta = read_offset(env);
            
                if (trapped) link_free(trapped);
                trapped = pusher->value.link;
                pusher->value.link = NULL;
                link_free(pusher);
                pusher = NULL;
                break;

            case PUSH_NULL:
                pusher = create_null();
                break;

            case PUSH_NUM:
                pusher = create_number( *((number_t *)env->current) );
                env->current+= sizeof(number_t);
                break;
            
            case PUSH_STR:
                delta = read_offset(env);
                pusher = create_string_literal( env->start + delta  );
                break;

            case PUSH_GVAR:
                delta = read_offset(env);
                pusher = link_dup(env->module->global_vars->links[delta]);
            
                if (! pusher){
                    pusher = exception("GlobalVariableUsedBeforeSet",NULL,NULL);
                }
                break;
            
            case PUSH_VAR:
                delta = read_offset(env);
             
                pusher = link_dup(env->local->links[delta]);
                
                if (! pusher){
                    pusher = exception("VariableUsedBeforeSet",NULL,NULL);;
                }
                break;
            
            case PUSH_BLOCK:
                delta = read_offset(env);
                pusher  = codeblock_literal2( env->function->value.codeblock->parent, delta  );
                if (env->function->value.codeblock->lexicals) {
                    lexicals_attach( env->function->value.codeblock->lexicals, pusher);
                }
                break;

            case PUSH_SYS:
                pusher = link_dup(Global->SYS_MODULE);
                break;
            
            case PUSH_MODULE:
                pusher = link_dup( env->function->value.codeblock->parent);
                break;
            
            case TYPEOF:
                link = stack_pop(stack);
                pusher = link_dup( link->type->type_link);
                link_free(link);
                break;
            
            case PUSH_THIS:
                pusher = link_dup(env->This);
                break;

            case PUSH_SELF:
                pusher = link_dup(env->Self);
                break;
            
            case PUSH_ARGS:
                pusher = link_dup(env->Arg);
                break;

            case PUSH_TRAPPED:
                pusher = trapped ? link_dup(trapped) : object_create(Global->null_type);
                break;
            
            case POP:
                link_free( stack_pop(stack) );
                break;

            case LINE:
                env->linenum = read_offset(env);
                break;

            default:
                fprintf(stderr," UNRECOGNIZED OPCODE ERROR %i\n", *(env->current));
                fprintf(stderr,"     near line %i\n", (int)(env->linenum));
                exit(1);
                break;
        }
                
        if (pusher) {
            
            if ( is_critical( pusher ) ){
                if ( *(env->current) == JINC)  goto jinc_critical;
                goto done;
            }
            
            stack_push(stack , pusher);
            pusher = NULL;
        }
        
    }

    end:

    if (trapped) link_free(trapped);
    return pusher;
}