예제 #1
0
파일: apply.c 프로젝트: tcort/edgar
obj_t * apply(obj_t *args, obj_t *env) {

	assert(IS_LIST(args));

	if (IS_LIST(CAR(args)) && IS_FUNC(CAR(CAR(args)))) {

		return (FUNC(CAR(CAR(args))))(CDR(args), env);
	} else if (IS_LIST(CAR(args)) && IS_DEFUNC(CAR(CAR(args)))) {

		obj_t * func_args;
		obj_t * call_args;

		obj_t * body;
		obj_t * result;

		body = clone_obj(BODY(CAR(CAR(args))));
		func_args = ARGS(CAR(CAR(args)));
		call_args = CDR(args);

		/* ((<DEFUNC:[args=(X)][body=(TIMES X X)]>) 3) */

		while (IS_LIST(func_args) && IS_LIST(call_args)) {
			obj_t * func_arg = CAR(func_args);
			obj_t * call_arg = CAR(call_args);

			replace_obj(func_arg, call_arg, body);

			func_args = CDR(func_args);
			call_args = CDR(call_args);
		}

		if ((IS_LIST(func_args) && !IS_LIST(call_args)) ||
				(!IS_LIST(func_args) && IS_LIST(call_args))) {

			free_obj(body); /* clean up */

			fprintf(stdout, "Unexpected number of arguments\n");
			return alloc_fail();
		}

		result = eval(body, env);

		free_obj(body);

		return result;

	} else {

		return clone_obj(args);
	}
}
예제 #2
0
void reset_area( D_AREA *area )
{
   ITERATOR it,rIt; // it = room iterator, rIt = reset iterator
   D_OBJ *o;
   D_RESET *reset;
   D_MOBILE *m;
   D_ROOM *room;
   
   AttachIterator( &it, area->rooms );
   while( ( room = (D_ROOM*)NextInList( &it ) ) != NULL )
   {
      AttachIterator( &rIt, room->resets );
      while( ( reset = (D_RESET*)NextInList(&rIt) ) != NULL )
      {
         switch( reset->type )
         {
            default:
            {
               bug( "Invalid reset type %c.", reset->type );
               break;
            }
            case 'o':
            case 'O':
            {
                //if the reset has already fired once we need to see if the object
                //is still there, if its not, make a new one.
               if( reset->ptr )
               {
                  //if object is still there skip this reset
                  if( IsInList( reset->ptr, room->objects ) ) 
                     continue;
               }
               if( ( o = clone_obj( fobv( reset->vnum ) ) ) == NULL )
               {
                  bug( "Reset calls for object vnum %i which does not exist.", reset->vnum );
                  continue;
               }
               AttachToList( o, room->objects );
               //does the reset reference any subresets (contained objects)?
               if( reset->nest && SizeOfList( reset->nest ) > 0 )
               {
               }
               
               o->reset = reset;
               reset->ptr = o;
               break;
            }
            case 'm':
            case 'M':
            {
               if( reset->ptr )
               {
                  if( IsInList( reset->ptr, npc_list ) )
                     continue;
               }
               if( ( m = clone_npc( fmbv( reset->vnum ) ) ) == NULL )
               {
                  bug( "Reset calls for NPC vnum %i which does not exist.", reset->vnum );
                  continue;
               }
               AttachToList( m, room->mobiles );
               m->npc_data->reset = reset;
               reset->ptr = m;
               break;
            }
         }
      }
      DetachIterator( &rIt );
   }
   DetachIterator( &it );
   return;
}