gurba-0.40/
gurba-0.40/bin/
gurba-0.40/lib/
gurba-0.40/lib/cmds/guild/fighter/
gurba-0.40/lib/cmds/monster/
gurba-0.40/lib/cmds/race/catfolk/
gurba-0.40/lib/cmds/race/dwarf/
gurba-0.40/lib/cmds/verb/
gurba-0.40/lib/daemons/data/
gurba-0.40/lib/data/boards/
gurba-0.40/lib/data/messages/
gurba-0.40/lib/data/players/
gurba-0.40/lib/design/
gurba-0.40/lib/domains/gurba/
gurba-0.40/lib/domains/gurba/guilds/fighter/
gurba-0.40/lib/domains/gurba/monsters/
gurba-0.40/lib/domains/gurba/objects/armor/
gurba-0.40/lib/domains/gurba/objects/clothing/
gurba-0.40/lib/domains/gurba/objects/weapons/
gurba-0.40/lib/domains/gurba/vendors/
gurba-0.40/lib/kernel/cmds/admin/
gurba-0.40/lib/kernel/daemons/
gurba-0.40/lib/kernel/include/
gurba-0.40/lib/kernel/lib/
gurba-0.40/lib/kernel/net/
gurba-0.40/lib/kernel/sys/
gurba-0.40/lib/logs/
gurba-0.40/lib/pub/
gurba-0.40/lib/std/modules/languages/
gurba-0.40/lib/std/races/
gurba-0.40/lib/std/races/monsters/
gurba-0.40/lib/wiz/fudge/
gurba-0.40/lib/wiz/spud/
gurba-0.40/src/host/beos/
gurba-0.40/src/host/pc/res/
gurba-0.40/src/kfun/
gurba-0.40/src/lpc/
gurba-0.40/src/parser/
gurba-0.40/tmp/
#include <type.h>

#undef DEBUG_PARSE

mapping verbs;
string *names;
string grammar;
object last_obj;

void rescan_verbs( void );

void create( void ) {
  int i;

  verbs = ([ ]);
  rescan_verbs();
}

string *query_verbs( void ) {
  return( names );
}

int is_verb( string verb ) {
  if( member_array( verb, map_indices( verbs ) ) != -1 )
    return( 1 );
  return( 0 );
}

object query_verb_object( string verb ) {

  return( verbs[verb] );
}

string query_grammar( void ) {
  return( grammar );
}

mixed parse( string str ) {
  mixed *result;
  string function;
  mixed returned;
  int i;

  last_obj = 0;

  result = parse_string( grammar, str );

#ifdef DEBUG_PARSE
  write( "result: " + dump_value( result, ([ ]) ) );
#endif

  if( result == 0 )
    return( 0 );

  function = "";
  if( sizeof( result ) > 1 ) {
    for( i = 0; i < sizeof( result ); i ++ ) {
      switch( typeof( result[i] ) ) {
      case T_STRING:
	/*	if( i == 0 ) */
	  function += lowercase(result[i]) + " ";
	  /*	else
		function += "str "; */
	break;
      case T_OBJECT:
	if( result[i]->is_living() )

	  function += "liv ";
	else
	  function += "obj ";
	break;
      }
    }
    function = implode( explode( function, " " ), "_" );
  } else {
    function = result[0];
  }
  
#ifdef DEBUG_PARSE
  write( "Function : 'can_" + function + "' in object " + verbs[result[0]] ); 
#endif

  switch( sizeof( result ) ) {
  case 1:
    returned = call_other( verbs[result[0]], "can_" + function );
    break;
  case 2:
    returned = call_other( verbs[result[0]], "can_" + function, 
			   result[1] );
    break;
  case 3:
    returned = call_other( verbs[result[0]], "can_" + function, 
			   result[1], result[2] );
    break;
  case 4:
    returned = call_other( verbs[result[0]], "can_" + function, 
			   result[1], result[2], result[3] );
    break;
  case 5:
    returned = call_other( verbs[result[0]], "can_" + function, 
			   result[1], result[2], result[3], result[4] );
    break;
  }

  if( returned == 1 ) {
#ifdef DEBUG_PARSE
      write( "calling : " + "do_" + function ); 
#endif
      switch( sizeof( result ) ) {
      case 1:
	returned = call_other( verbs[result[0]], "do_" + function );
	break;
      case 2:
	returned = call_other( verbs[result[0]], "do_" + function, 
			       result[1] );
	break;
      case 3:
	returned = call_other( verbs[result[0]], "do_" + function, 
			       result[1], result[2] );
	break;
      case 4:
	returned = call_other( verbs[result[0]], "do_" + function, 
			       result[1], result[2], result[3] );
	break;
      case 5:
	returned = call_other( verbs[result[0]], "do_" + function, 
			       result[1], result[2], result[3], result[4] );
	break;
      }
  }
  
  if( returned == 0 ) {
    returned = 1;
  }
  return( returned );
}

void rescan_verbs( void ) {
  mixed *list;
  string verb;
  int i;
  mixed info;

  list = get_dir( "/cmds/verb/*.c" );
  names = list[0];

  for( i = 0; i < sizeof( names ); i++ ) {
    names[i] = names[i][.. (strlen( names[i] )-3)];
    verb = "/cmds/verb/" + names[i];
    verbs[names[i]] = verb;
  }

  grammar = "whitespace = / / word = /[a-z]+/ number = /[0-9]+/ ";

  for( i = 0; i < sizeof( names ); i++ ) {
    write( "Scanning " + names[i] + "(" + verbs[names[i]] + ")" );
  
    info = call_other( verbs[names[i]], "query_verb_info" );

    write( "Verb info: " + dump_value( info, ([]) ) );

    if( sizeof( info ) > 0 ) {
      /* Rules and aliases */
      int j;

      for( j = 0; j < sizeof( info ); j++ ) {
	string *words;
	int k;

	grammar += "Sentence: '" + names[i] + "' ";

	words = explode( info[j], " " );
	for( k = 0; k < sizeof( words ); k++ ) {

	  switch( words[k] ) {
	  case "OBJ":
	    grammar += "OBJ ";
	    break;
	  case "OBJA":
	    grammar += "OBJA ";
	    break;
	  case "OBJI":
	    grammar += "OBJI ";
	    break;
	  case "OBJE":
	    grammar += "OBJE ";
	    break;
	  case "OBJC":
	    grammar += "OBJC ";
	    break;
	  case "LIV":
	    grammar += "LIV ";
	    break;
	  default:
	    grammar += "'" + words[k] + "' ";
	  }
	}
      }
    }
  }
  grammar = grammar + "OBJ: Object ? find_direct_object \
OBJA: Object ? construct_obj_packet \
OBJI: Object ? find_inv_object \
OBJE: Object ? find_environment_object \
OBJC: Object ? find_container_object \
LIV: Object ? find_living_object \
Object: Article_List Adjective_List Noun Obj_Index \
Article: 'the' \
Article: 'a' \
Article: 'an' \
Article: 'any' \
Article: 'my' \
Article: 'in' \
Article: 'at' \
Article: 'on' \
Article: \
Article_List: Article ? group_results \
Adjectives: word Adjectives \
Adjectives: \
Adjective_List: Adjectives ? group_results \
Preposition: word \
Preposition: \
Preposition_List: Preposition ? group_results \
Noun: word \
words: word ? group_results \
Index: number \
Index: \
Obj_Index: Index ? define_obj_index \
";

}

static mixed *construct_obj_packet(mixed *mpTree)
{
  string res;
  int i;

#ifdef DEBUG_PARSE
  write( "construct_obj_packet(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" ); 
#endif

  res = "";

  for( i = 0; i < sizeof( mpTree[1] ); i++ )
    res += mpTree[1][i] + " ";

  res += mpTree[2];

  return ({ res });
}

static mixed *find_container_object( mixed *mpTree ) {
  object ob;

#ifdef DEBUG_PARSE
  write( "find_container_object(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" );
#endif

  if( last_obj == 0 ) {
    write( "Parse error: Tell Fudge!\n" );
    return( 0 );
  }

  if( sizeof( mpTree[1] ) > 0 ) {
    ob = last_obj->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
  } else {
    ob = last_obj->find_object_num( mpTree[2], mpTree[3] );
  }
  if( ob == 0 ) {
    return 0;
  }
  
  last_obj = ob;
  return( ({ ob }) );

}

static mixed *find_living_object( mixed *mpTree ) {
  object ob;

#ifdef DEBUG_PARSE
  write( "find_living_object(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" ); 
#endif
  
  if( sizeof( mpTree[1] ) > 0 ) {
    ob = this_environment()->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
  } else {
    ob = this_environment()->find_object_num( mpTree[2], mpTree[3] );
  }
  
  if( ob != 0 ) {
    if( ob->is_living() ) {
      last_obj = ob;
      return( ({ ob }) );
    }
  }

  return( 0 );

}

static mixed *find_direct_object( mixed *mpTree ) {
  object ob;
  
#ifdef DEBUG_PARSE
  write( "find_direct_object(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" ); 
#endif
  
  if( sizeof( mpTree[1] ) > 0 ) {
    /* With adjective */
    ob = this_environment()->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
    if( ob == 0 ) {
      ob = this_player()->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
      if( ob == 0 ) {
	return 0;
      }
    }
  } else {
    ob = this_environment()->find_object_num( mpTree[2], mpTree[3] );
    if( ob == 0 ) {
      ob = this_player()->find_object_num( mpTree[2], mpTree[3] );
      if( ob == 0 ) {
	return 0;
      }
    }
  }
  
  if( ob->is_living() ) {
    return( 0 );
  }

  last_obj = ob;
  return( ({ ob }) );
}

static mixed *find_inv_object( mixed *mpTree ) {
  object ob;
  
#ifdef DEBUG_PARSE
  write( "find_inv_object(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" ); 
#endif
  
  if( sizeof( mpTree[1] ) > 0 ) {
    /* With adjective */
    ob = this_player()->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
  } else {
    /* Without adjective */
    ob = this_player()->find_object_num( mpTree[2], mpTree[3] );
  }
  if( ob == 0 ) {
    return 0;
  }

  last_obj = ob;
  return( ({ ob }) );
}

static mixed *find_environment_object( mixed *mpTree ) {
  object ob;
  
#ifdef DEBUG_PARSE
  write( "find_environment_object(" 
	 + dump_value( mpTree[0], ([ ])) + ","
	 + dump_value( mpTree[1], ([ ])) + ","
	 + dump_value( mpTree[2], ([ ])) + ","
	 + dump_value( mpTree[3], ([ ])) + ")\n" ); 
#endif

  if( sizeof( mpTree[1] ) > 0 ) {
    ob = this_environment()->find_adjs_object_num( mpTree[1], mpTree[2], mpTree[3] );
  } else {
    ob = this_environment()->find_object_num( mpTree[2], mpTree[3] );
  }
  if( ob == 0 ) {
    return 0;
  }

  last_obj = ob;
  return( ({ ob }) );
}

static mixed *define_obj_index( mixed *mpTree ) {
  if( !mpTree || !sizeof( mpTree ) )
    return( ({ 1 }) );
  else
    return( ({ (int) mpTree[0] }) );
}

static mixed *group_results( mixed *mpTree ) {
  return( ({ mpTree }) );
}