/* objectop.c: Function operators acting on the current object. */ #include "x.tab.h" #include "operator.h" #include "execute.h" #include "data.h" #include "ident.h" #include "object.h" #include "grammar.h" #include "config.h" #include "cache.h" #include "dbpack.h" void op_add_parameter(void) { Data *args; long result; /* Accept a symbol argument a data value to assign to the variable. */ if (!func_init_1(&args, SYMBOL)) return; result = object_add_param(cur_frame->object, args[0].u.symbol); if (result == paramexists_id) { cthrow(paramexists_id, "Parameter %I already exists.", args[0].u.symbol); } else { pop(1); push_int(1); } } void op_parameters(void) { List *params; Object *obj; int i; Var *var; Data d; /* Accept no arguments. */ if (!func_init_0()) return; /* Construct the list of variable names. */ obj = cur_frame->object; params = list_new(0); d.type = SYMBOL; for (i = 0; i < obj->vars.size; i++) { var = &obj->vars.tab[i]; if (var->name != -1 && var->cclass == obj->dbref) { d.u.symbol = var->name; params = list_add(params, &d); } } /* Push the list onto the stack. */ push_list(params); list_discard(params); } void op_del_parameter(void) { Data *args; long result; /* Accept one symbol argument. */ if (!func_init_1(&args, SYMBOL)) return; result = object_del_param(cur_frame->object, args[0].u.symbol); if (result == paramnf_id) { cthrow(paramnf_id, "Parameter %I does not exist.", args[0].u.symbol); } else { pop(1); push_int(1); } } void op_set_var(void) { Data *args; long result; /* Accept a symbol for the variable name and a data value of any type. */ if (!func_init_2(&args, SYMBOL, 0)) return; result = object_assign_var(cur_frame->object, cur_frame->method->object, args[0].u.symbol, &args[1]); if (result == paramnf_id) { cthrow(paramnf_id, "No such parameter %I.", args[0].u.symbol); } else { pop(2); push_int(1); } } void op_get_var(void) { Data *args, d; long result; /* Accept a symbol argument. */ if (!func_init_1(&args, SYMBOL)) return; result = object_retrieve_var(cur_frame->object, cur_frame->method->object, args[0].u.symbol, &d); if (result == paramnf_id) { cthrow(paramnf_id, "No such parameter %I.", args[0].u.symbol); } else { pop(1); data_dup(&stack[stack_pos], &d); stack_pos++; } } void op_compile(void) { Data *args, *d; Method *method; List *code, *errors; /* Accept a list of lines of code and a symbol for the name. */ if (!func_init_2(&args, LIST, SYMBOL)) return; code = args[0].u.list; /* Make sure that every element in the code list is a string. */ for (d = list_first(code); d; d = list_next(code, d)) { if (d->type != STRING) { cthrow(type_id, "Line %d (%D) is not a string.", d - list_first(code), d); return; } } method = compile(cur_frame->object, code, &errors); if (method) { object_add_method(cur_frame->object, args[1].u.symbol, method); /*method_discard(method);*/ } pop(2); push_list(errors); list_discard(errors); } void op_methods(void) { List *methods; Data d; Object *obj; int i; /* Accept no arguments. */ if (!func_init_0()) return; /* Construct the list of method names. */ obj = cur_frame->object; methods = list_new(obj->methods.size); for (i = 0; i < obj->methods.size; i++) { if (obj->methods.tab[i].m) { d.type = SYMBOL; d.u.symbol = obj->methods.tab[i].m->name; methods = list_add(methods, &d); } } /* Push the list onto the stack. */ check_stack(1); push_list(methods); list_discard(methods); } void op_find_method(void) { Data *args; Method *method; /* Accept a symbol argument giving the method name. */ if (!func_init_1(&args, SYMBOL)) return; /* Look for the method on the current object. */ method = object_find_method(cur_frame->object->dbref, args[0].u.symbol); pop(1); if (method) { push_dbref(method->object->dbref); cache_discard(method->object); } else { cthrow(methodnf_id, "Method %s not found.", ident_name(args[0].u.symbol)); } } void op_find_next_method(void) { Data *args; Method *method; /* Accept a symbol argument giving the method name, and a dbref giving the * object to search past. */ if (!func_init_2(&args, SYMBOL, DBREF)) return; /* Look for the method on the current object. */ method = object_find_next_method(cur_frame->object->dbref, args[0].u.symbol, args[1].u.dbref); if (method) { push_dbref(method->object->dbref); cache_discard(method->object); } else { cthrow(methodnf_id, "Method %s not found.", ident_name(args[0].u.symbol)); } } void op_list_method(void) { int num_args, indent, parens; Data *args; List *code; /* Accept a symbol for the method name, an optional integer for the * indentation, and an optional integer to specify full * parenthesization. */ if (!func_init_1_to_3(&args, &num_args, SYMBOL, INTEGER, INTEGER)) return; indent = (num_args >= 2) ? args[1].u.val : DEFAULT_INDENT; indent = (indent < 0) ? 0 : indent; parens = (num_args == 3) ? (args[2].u.val != 0) : 0; code = object_list_method(cur_frame->object, args[0].u.symbol, indent, parens); if (code) { pop(num_args); push_list(code); list_discard(code); } else { cthrow(methodnf_id, "Method %s not found.", ident_name(args[0].u.symbol)); } } void op_del_method(void) { Data *args; /* Accept a symbol for the method name. */ if (!func_init_1(&args, SYMBOL)) return; if (!object_del_method(cur_frame->object, args[0].u.symbol)) { cthrow(methodnf_id, "No method named %s was found.", ident_name(args[0].u.symbol)); } else { pop(1); push_int(1); } } void op_parents(void) { /* Accept no arguments. */ if (!func_init_0()) return; /* Push the parents list onto the stack. */ push_list(cur_frame->object->parents); } void op_children(void) { /* Accept no arguments. */ if (!func_init_0()) return; /* Push the children list onto the stack. */ push_list(cur_frame->object->children); } void op_ancestors(void) { List *ancestors; /* Accept no arguments. */ if (!func_init_0()) return; /* Get an ancestors list from the object. */ ancestors = object_ancestors(cur_frame->object->dbref); push_list(ancestors); list_discard(ancestors); } void op_has_ancestor(void) { Data *args; int result; /* Accept a dbref to check as an ancestor. */ if (!func_init_1(&args, DBREF)) return; result = object_has_ancestor(cur_frame->object->dbref, args[0].u.dbref); pop(1); push_int(result); } void op_size(void) { /* Accept no arguments. */ if (!func_init_0()) return; /* Push size of current object. */ push_int(size_object(cur_frame->object)); }