object_t *eval(object_t *exp, object_t *env) { object_t *ret = NULL; if (evaluate_to_self(exp)) { ret = exp; } else if (quoted(exp)) { ret = car(cdr(exp)); } else if (definition(exp)) { object_t *symb = car(cdr(exp)), *val = car(cdr(cdr(exp))); if (val == NULL) { create_new_variable(symb, get_nil(), env); } else { create_new_variable(symb, eval(val, env), env); } ret = symb; } else if (is_symbol(exp)) { //printf("\nfound symbol: %s\n\n", exp->values.symbol.value); ret = find_variable_value(exp, env); } else if (function(exp)) { object_t *arguments = make_arguments(cdr(exp), env); object_t *func = eval(car(exp), env); if (func == NULL || func == get_nil() || func->type != t_primitive) { fprintf(stderr, "func: %d\n", (unsigned int)func); //fprintf(stderr, "type: %d\n", func->type); die("Not a primitive!\n"); } else { ret = (func->values.primitive.function)(arguments); } } else if (maybe_eval_to_function(exp)) { object_t *c = car(exp); object_t *func = eval(c, env); if (!(func == NULL || nilp(func))) { object_t *arguments = make_arguments(cdr(exp), env); ret = (func->values.primitive.function)(arguments); } else { die("Not a function!\n"); } } else { die("Can't eval!\n"); } return ret; }
object_t *make_arguments(object_t *args, object_t *env) { if (nilp(args)) { return get_nil(); } else { return create_cons(eval(car(args), env), make_arguments(cdr(args), env)); } }
// compare one list to another, ie: "1 2 3" to "4 5 2" would return the matching // word, or 0 if not found char *strlistcmp(char *str1, char *str2) { static char buf[MAX_BUFFER]; char **arguments1 = make_arguments(str1); char **arguments2 = make_arguments(str2); long x, y; buf[0] = '\0'; for(x = 0; arguments1[x]; x++) for(y = 0; arguments2[y]; y++) if(!strcasecmp(arguments1[x], arguments2[y])) { strcpy(buf,arguments1[x]); break; } free_arguments(arguments1); free_arguments(arguments2); return buf[0] == '\0' ? 0 : buf; }
// count the number of words in a list. long countlist(char *haystack, char *needle) { char **arguments = make_arguments(haystack); long x, y = 0; for( x = 0; arguments[x]; x++) { if (!strcasecmp(arguments[x], needle)) y++; } free_arguments(arguments); return y; }
// same as above but abbreviations are allowed long strargindex(char *haystack, char *needle) { char **arguments = make_arguments(haystack); long x; for(x = 0; arguments[x]; x++) { if(!strindex(arguments[x], needle)) { free_arguments(arguments); return 0; } } free_arguments(arguments); return 1; }
/////////////// // FUNCTIONS // /////////////// void interpret(CREATURE *crit, char *buf) { CREATURE *xcrit=0; OBJECT *obj=0; SOCIAL *social=0; EXIT *exit=0; ROOM *room=0; char command[MAX_BUFFER]; char temp[MAX_BUFFER]; char *pbuf = command; char **arguments; char **editargs; long i = 0, x = 0; long string = 0; bool found = 0; bool command_ok = 0; bool social_ok = 0; strcpy(temp,buf); while( isspace(*buf) ) buf++; // check for one character commands without spaces to // seperate arguments. - i.e. chat yo = .yo | pip if(ispunct(*buf)) *pbuf++ = *buf++; else { while( !isspace(*buf) && *buf != '\0' ) *pbuf++ = *buf++; } *pbuf = '\0'; while( isspace(*buf) ) buf++; // moved exits before other commands - pip. // insert full exit name for abbreviated one. for( i = 0; directions[i].abbr; i++) { if (directions[i].abbr[0] != '\0' && !strcasecmp(command,directions[i].abbr)) { sprintf(command,"%s",directions[i].name); break; } } if(!IsDisabled(crit)) { for(exit = crit->in_room->exits; exit; exit = exit->next ) { if( !strindex(exit->name, command) ) { if((room = hashfind_room(exit->to_vnum)) == 0) { sendcrit(crit,"That exit enters into a domain far too powerful for you to handle."); mudlog("exit(%s) in room(%s:%d) has bad to_vnum(%d)!", exit->name, crit->in_room->name, crit->in_room->vnum, exit->to_vnum); continue; } if (exit->door >= DOOR_CLOSED && !IsImmortal(crit)) { sendcritf(crit,"The %s door is closed.",exit->name); return; } if (crit->rider) { sendcritf(crit,"You can't move on your own until %s dismounts you.",crit->rider->name); return; } // adding mounts! if (crit->mount) message("$n ride$x $p on $N.",crit,crit->mount,exit->name); else message("$n leave$x $p.",crit,0,exit->name); trans(crit,room); if (crit->mount) { trans(crit->mount,crit); message("$n arrive$x riding $N.",crit,crit->mount,crit->in_room); } message("$n $v arrived.",crit,crit->in_room,0); interpret(crit,"look"); return; } } } // check if they in editor and get a successful return (edited something) // otherwise let them use normal commands if(IsEditing(crit)) { if(crit->socket->string) { if(!(string = string_editor(crit,temp))) return; str_dup(&(*crit->socket->variable), crit->socket->string); DeleteObject(crit->socket->string) return; } else temp[0] = '\0'; if(!ValidString(command)) strcat(temp,""); else sprintf(temp,"%s %s",command,buf); editargs = make_arguments(temp); if(editor(crit,editargs)) { free_arguments(editargs); return; } free_arguments(editargs); }