home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / tinymud2.zip / BOOLEXP.C next >
C/C++ Source or Header  |  1990-09-02  |  4KB  |  185 lines

  1. #include "copyright.h"
  2.  
  3. #include <ctype.h>
  4.  
  5. #include "db.h"
  6. #include "match.h"
  7. #include "externs.h"
  8. #include "config.h"
  9. #include "interface.h"
  10.  
  11. int eval_boolexp(dbref player, struct boolexp *b)
  12. {
  13.     if(b == TRUE_BOOLEXP) {
  14.     return 1;
  15.     } else {
  16.     switch(b->type) {
  17.       case BOOLEXP_AND:
  18.         return (eval_boolexp(player, b->sub1)
  19.             && eval_boolexp(player, b->sub2));
  20.       case BOOLEXP_OR:
  21.         return (eval_boolexp(player, b->sub1)
  22.             || eval_boolexp(player, b->sub2));
  23.       case BOOLEXP_NOT:
  24.         return !eval_boolexp(player, b->sub1);
  25.       case BOOLEXP_CONST:
  26.         return (b->thing == player
  27.             || member(b->thing, db[player].contents));
  28.       default:
  29.         abort();        /* bad type */
  30.         return 0;
  31.     }
  32.     }
  33. }
  34.  
  35. /* If the parser returns TRUE_BOOLEXP, you lose */
  36. /* TRUE_BOOLEXP cannot be typed in by the user; use @unlock instead */
  37. static const char *parsebuf;
  38. static dbref parse_player;
  39.  
  40. static void skip_whitespace(void)
  41. {
  42.     while(*parsebuf && isspace(*parsebuf)) parsebuf++;
  43. }
  44.  
  45. static struct boolexp *parse_boolexp_E(void); /* defined below */
  46.  
  47. /* F -> (E); F -> !F; F -> object identifier */
  48. static struct boolexp *parse_boolexp_F(void)
  49. {
  50.     struct boolexp *b;
  51.     char *p;
  52.     char buf[BUFFER_LEN];
  53.     char msg[BUFFER_LEN];
  54.  
  55.     skip_whitespace();
  56.     switch(*parsebuf) {
  57.       case '(':
  58.     parsebuf++;
  59.     b = parse_boolexp_E();
  60.     skip_whitespace();
  61.     if(b == TRUE_BOOLEXP || *parsebuf++ != ')') {
  62.         free_boolexp(b);
  63.         return TRUE_BOOLEXP;
  64.     } else {
  65.         return b;
  66.     }
  67.     /* break; */
  68.       case NOT_TOKEN:
  69.     parsebuf++;
  70.     b = (struct boolexp *) malloc(sizeof(struct boolexp));
  71.     b->type = BOOLEXP_NOT;
  72.     b->sub1 = parse_boolexp_F();
  73.     if(b->sub1 == TRUE_BOOLEXP) {
  74.         free((void *) b);
  75.         return TRUE_BOOLEXP;
  76.     } else {
  77.         return b;
  78.     }
  79.     /* break */
  80.       default:
  81.     /* must have hit an object ref */
  82.     /* load the name into our buffer */
  83.     p = buf;
  84.     while(*parsebuf
  85.           && *parsebuf != AND_TOKEN
  86.           && *parsebuf != OR_TOKEN
  87.           && *parsebuf != ')') {
  88.         *p++ = *parsebuf++;
  89.     }
  90.     /* strip trailing whitespace */
  91.     *p-- = '\0';
  92.     while(isspace(*p)) *p-- = '\0';
  93.  
  94.     b = (struct boolexp *) malloc(sizeof(struct boolexp));
  95.     b->type = BOOLEXP_CONST;
  96.  
  97.     /* do the match */
  98.     init_match(parse_player, buf, TYPE_THING);
  99.     match_neighbor();
  100.     match_possession();
  101.     match_me();
  102.     match_absolute();
  103.     match_player();
  104.     b->thing = match_result();
  105.  
  106.     if(b->thing == NOTHING) {
  107.         sprintf(msg, "I don't see %s here.", buf);
  108.         notify(parse_player, msg);
  109.         free((void *) b);
  110.         return TRUE_BOOLEXP;
  111.     } else if(b->thing == AMBIGUOUS) {
  112.         sprintf(msg, "I don't know which %s you mean!", buf);
  113.         notify(parse_player, msg);
  114.         free((void *) b);
  115.         return TRUE_BOOLEXP;
  116.     } else {
  117.         return b;
  118.     }
  119.     /* break */
  120.     }
  121. }
  122.  
  123. /* T -> F; T -> F & T */
  124. static struct boolexp *parse_boolexp_T(void)
  125. {
  126.     struct boolexp *b;
  127.     struct boolexp *b2;
  128.  
  129.     if((b = parse_boolexp_F()) == TRUE_BOOLEXP) {
  130.     return b;
  131.     } else {
  132.     skip_whitespace();
  133.     if(*parsebuf == AND_TOKEN) {
  134.         parsebuf++;
  135.  
  136.         b2 = (struct boolexp *) malloc(sizeof(struct boolexp));
  137.         b2->type = BOOLEXP_AND;
  138.         b2->sub1 = b;
  139.         if((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) {
  140.         free_boolexp(b2);
  141.         return TRUE_BOOLEXP;
  142.         } else {
  143.         return b2;
  144.         }
  145.     } else {
  146.         return b;
  147.     }
  148.     }
  149. }
  150.  
  151. /* E -> T; E -> T | E */
  152. static struct boolexp *parse_boolexp_E(void)
  153. {
  154.     struct boolexp *b;
  155.     struct boolexp *b2;
  156.  
  157.     if((b = parse_boolexp_T()) == TRUE_BOOLEXP) {
  158.     return b;
  159.     } else {
  160.     skip_whitespace();
  161.     if(*parsebuf == OR_TOKEN) {
  162.         parsebuf++;
  163.  
  164.         b2 = (struct boolexp *) malloc(sizeof(struct boolexp));
  165.         b2->type = BOOLEXP_OR;
  166.         b2->sub1 = b;
  167.         if((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) {
  168.         free_boolexp(b2);
  169.         return TRUE_BOOLEXP;
  170.         } else {
  171.         return b2;
  172.         }
  173.     } else {
  174.         return b;
  175.     }
  176.     }
  177. }
  178.  
  179. struct boolexp *parse_boolexp(dbref player, const char *buf)
  180. {
  181.     parsebuf = buf;
  182.     parse_player = player;
  183.     return parse_boolexp_E();
  184. }
  185.