parent $misc object $lock_parser var $root child_index 0 var $root owners [$lock_parser] var $root fertile 0 var $root inited 1 var $root owned [$lock_parser] var $root manager $lock_parser var $root writable [$lock_parser] var $root readable ['parameters, 'methods, 'code] var $root dbref 'lock_parser method parse arg s, env; var stack, lock, n, m, obj, len; stack = []; while (1) { // Look for valid prefixes. while (1) { while (s && ((s[1]) == " ")) s = substr(s, 2); if (!s) throw(~parse, "String ends unexpectedly."); if ((s[1]) == "(") { stack = stack + ['open]; s = substr(s, 2); } else if ((s[1]) == "!") { stack = stack + ['not]; s = substr(s, 2); } else { break; } } // Look for an object obj_name. for n in [1 .. strlen(s)] { if ((s[n]) in ")&|") { n = n - 1; break; } } m = n; while (m && ((s[m]) == " ")) m = m - 1; if (!m) throw(~parse, "Null object obj_name."); obj = (> env.match_environment(substr(s, 1, m)) <); lock = $object_lock_class.new(obj); stack = stack + [lock]; s = substr(s, n + 1); // Loop until no more reduction to be done. while (1) { // Process negations, ands, ors. while (1) { len = listlen(stack); if (len < 2) break; if ((stack[len - 1]) == 'not) { lock = $not_lock_class.new(stack[len]); stack = sublist(stack, 1, len - 2) + [lock]; } else if ((stack[len - 1]) == 'and) { lock = $and_lock_class.new(stack[len - 2], stack[len]); stack = sublist(stack, 1, len - 3) + [lock]; } else if ((stack[len - 1]) == 'or) { lock = $or_lock_class.new(stack[len - 2], stack[len]); stack = sublist(stack, 1, len - 3) + [lock]; } else { break; } } // Close parens, if necessary; otherwise stop. if ((!s) || ((s[1]) != ")")) break; while (s && ((s[1]) == ")")) { len = listlen(stack); if ((len < 2) || ((stack[len - 1]) != 'open)) throw(~parse, "Misplaced right parenthesis."); stack = sublist(stack, 1, len - 2) + [stack[len]]; s = substr(s, 2); while (s && ((s[1]) == " ")) s = substr(s, 2); } } // Are we done? if (!s) { if (listlen(stack) > 1) throw(~parse, "Unmatched left parentheses."); return stack[1]; } // No, we're at a conjunction. if ((s[1]) == "&") { stack = stack + ['and]; s = substr(s, 2); } else if ((s[1]) == "|") { stack = stack + ['or]; s = substr(s, 2); } else { throw(~parse, "Illegal character following right parenthesis."); } } .