#include "copyright.h" #include <ctype.h> #include "db.h" #include "match.h" #include "externs.h" #include "config.h" #include "interface.h" int eval_boolexp(dbref player, struct boolexp *b) { if(b == TRUE_BOOLEXP) { return 1; } else { switch(b->type) { case BOOLEXP_AND: return (eval_boolexp(player, b->sub1) && eval_boolexp(player, b->sub2)); case BOOLEXP_OR: return (eval_boolexp(player, b->sub1) || eval_boolexp(player, b->sub2)); case BOOLEXP_NOT: return !eval_boolexp(player, b->sub1); case BOOLEXP_CONST: return (b->thing == player || member(b->thing, db[player].contents)); default: abort(); /* bad type */ return 0; } } } /* If the parser returns TRUE_BOOLEXP, you lose */ /* TRUE_BOOLEXP cannot be typed in by the user; use @unlock instead */ static const char *parsebuf; static dbref parse_player; static void skip_whitespace(void) { while(*parsebuf && isspace(*parsebuf)) parsebuf++; } static struct boolexp *parse_boolexp_E(void); /* defined below */ /* F -> (E); F -> !F; F -> object identifier */ static struct boolexp *parse_boolexp_F(void) { struct boolexp *b; char *p; char buf[BUFFER_LEN]; char msg[BUFFER_LEN]; skip_whitespace(); switch(*parsebuf) { case '(': parsebuf++; b = parse_boolexp_E(); skip_whitespace(); if(b == TRUE_BOOLEXP || *parsebuf++ != ')') { free_boolexp(b); return TRUE_BOOLEXP; } else { return b; } /* break; */ case NOT_TOKEN: parsebuf++; b = (struct boolexp *) malloc(sizeof(struct boolexp)); b->type = BOOLEXP_NOT; b->sub1 = parse_boolexp_F(); if(b->sub1 == TRUE_BOOLEXP) { free((void *) b); return TRUE_BOOLEXP; } else { return b; } /* break */ default: /* must have hit an object ref */ /* load the name into our buffer */ p = buf; while(*parsebuf && *parsebuf != AND_TOKEN && *parsebuf != OR_TOKEN && *parsebuf != ')') { *p++ = *parsebuf++; } /* strip trailing whitespace */ *p-- = '\0'; while(isspace(*p)) *p-- = '\0'; b = (struct boolexp *) malloc(sizeof(struct boolexp)); b->type = BOOLEXP_CONST; /* do the match */ init_match(parse_player, buf, TYPE_THING); match_neighbor(); match_possession(); match_me(); match_absolute(); match_player(); b->thing = match_result(); if(b->thing == NOTHING) { sprintf(msg, "I don't see %s here.", buf); notify(parse_player, msg); free((void *) b); return TRUE_BOOLEXP; } else if(b->thing == AMBIGUOUS) { sprintf(msg, "I don't know which %s you mean!", buf); notify(parse_player, msg); free((void *) b); return TRUE_BOOLEXP; } else { return b; } /* break */ } } /* T -> F; T -> F & T */ static struct boolexp *parse_boolexp_T(void) { struct boolexp *b; struct boolexp *b2; if((b = parse_boolexp_F()) == TRUE_BOOLEXP) { return b; } else { skip_whitespace(); if(*parsebuf == AND_TOKEN) { parsebuf++; b2 = (struct boolexp *) malloc(sizeof(struct boolexp)); b2->type = BOOLEXP_AND; b2->sub1 = b; if((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) { free_boolexp(b2); return TRUE_BOOLEXP; } else { return b2; } } else { return b; } } } /* E -> T; E -> T | E */ static struct boolexp *parse_boolexp_E(void) { struct boolexp *b; struct boolexp *b2; if((b = parse_boolexp_T()) == TRUE_BOOLEXP) { return b; } else { skip_whitespace(); if(*parsebuf == OR_TOKEN) { parsebuf++; b2 = (struct boolexp *) malloc(sizeof(struct boolexp)); b2->type = BOOLEXP_OR; b2->sub1 = b; if((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) { free_boolexp(b2); return TRUE_BOOLEXP; } else { return b2; } } else { return b; } } } struct boolexp *parse_boolexp(dbref player, const char *buf) { parsebuf = buf; parse_player = player; return parse_boolexp_E(); }