ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf/match.pm
(Generate patch)

Comparing deliantra/server/lib/cf/match.pm (file contents):
Revision 1.13 by root, Sun Oct 11 23:51:47 2009 UTC vs.
Revision 1.18 by root, Mon Oct 12 21:27:55 2009 UTC

110 110
111=item in env 111=item in env
112 112
113Replaces all objects by their containing object, if they have one. 113Replaces all objects by their containing object, if they have one.
114 114
115=item in arch
116
117Replaces all objects by their archetypes.
118
115=item in map 119=item in map
116 120
117Replaces all objects by the objects that are on the same mapspace as them. 121Replaces all objects by the objects that are on the same mapspace as them.
118 122
119=item in <cond> 123=item in <condition>
120 124
121Finds all context objects matching the condition, and then puts their 125Finds all context objects matching the condition, and then puts their
122inventories into the context set. 126inventories into the context set.
123 127
124Note that C<in inv> is simply a special case of an C<< in <cond> >> that 128Note that C<in inv> is simply a special case of an C<< in <condition> >> that
125matches any object. 129matches any object.
126 130
127Example: find all spells inside potions inside the inventory of the context 131Example: find all spells inside potions inside the inventory of the context
128object(s). 132object(s).
129 133
136 140
137Example: check if the context object I<is> a spell, or I<contains> a spell. 141Example: check if the context object I<is> a spell, or I<contains> a spell.
138 142
139 type=SPELL also in inv 143 type=SPELL also in inv
140 144
141=item deep in ... 145=item also deep in ...
142 146
143Repeats the operation as many times as possible. This can be used to 147Repeats the operation as many times as possible. This can be used to
144recursively look into objects. 148recursively look into objects.
145 149
146=item also deep in ... 150So for example, C<also deep in inv> means to take the inventory of all
151objects, taking their inventories, and so on, and adding all these objects
152to the context set.
147 153
148C<also> and C<deep> can be combined. 154Similarly, C<also deep in env> means to take the environment object, their
155environemnt object and so on.
149 156
150Example: check if there are any unpaid items in an inventory, 157Example: check if there are any unpaid items in an inventory,
151or in the inventories of the inventory objects, and so on. 158or in the inventories of the inventory objects, and so on.
152 159
153 unpaid also deep in inv 160 unpaid also deep in inv
287=item match(match) 294=item match(match)
288 295
289An independent match - semantics like C<count>, except it only matters 296An independent match - semantics like C<count>, except it only matters
290whether the match finds any object (which is faster). 297whether the match finds any object (which is faster).
291 298
292=item dump 299=item dump()
293 300
294Dumps the object to the server log when executed, and evaluates to true. 301Dumps the object to the server log when executed, and evaluates to true.
295 302
296Note that logical operations are short-circuiting, so this only dumps 303Note that logical operations are short-circuiting, so this only dumps
297potions: 304potions:
298 305
299 type=POTION and dump 306 type=POTION and dump()
300 307
301=back 308=back
302 309
303=head2 GRAMMAR 310=head2 GRAMMAR
304 311
313 root = 'object' | 'self' | 'source' | 'originator' 320 root = 'object' | 'self' | 'source' | 'originator'
314 chain = condition 321 chain = condition
315 | chain also deep 'in' set 322 | chain also deep 'in' set
316 also = nothing | 'also' 323 also = nothing | 'also'
317 deep = nothing | 'deep' 324 deep = nothing | 'deep'
318 set = 'inv' | 'env' | 'map' 325 set = 'inv' | 'env' | 'arch' | 'map'
319 326
320 empty = 327 empty =
321 328
322 # boolean matching condition 329 # boolean matching condition
323 330
324 condition = factor 331 condition = factor
325 | factor 'and'? cond 332 | factor 'and'? condition
326 | factor 'or' cond 333 | factor 'or' condition
327 334
328 factor = 'not' factor 335 factor = 'not' factor
329 | '(' cond ')' 336 | '(' condition ')'
330 | expr 337 | expr
331 | expr operator constant 338 | expr operator constant
332 339
333 operator = '=' | '==' | '!=' | '<' | '<=' | '>' | '>=' 340 operator = '=' | '==' | '!=' | '<' | '<=' | '>' | '>='
334 341
391 }, 398 },
392 match => sub { 399 match => sub {
393 local $all = 0; 400 local $all = 0;
394 '(scalar ' . &match ('$_') . ')' 401 '(scalar ' . &match ('$_') . ')'
395 }, 402 },
396 );
397
398 our %special = (
399 any => sub {
400 1
401 },
402 dump => sub { 403 dump => sub {
403 'do { 404 'do {
404 warn "cf::match::match dump:\n" 405 warn "cf::match::match dump:\n"
405 . "self: " . eval { $self->name } . "\n" 406 . "self: " . eval { $self->name } . "\n"
406 . $_->as_string; 407 . $_->as_string;
407 1 408 1
408 }'; 409 }';
409 }, 410 },
410 ); 411 );
411 412
413 our %special = (
414 any => sub {
415 1
416 },
417 );
418
412 sub constant { 419 sub constant {
413 ws; 420 ws;
414 421
415 return $1 if /\G([\-\+0-9\.]+)/gc; 422 return $1 if /\G([\-\+0-9\.]+)/gc;
416 return "cf::$1" if /\G([A-Z0-9_]+)/gc; 423 return "cf::$1" if /\G([A-Z0-9_]+)/gc;
527 534
528 while () { 535 while () {
529 ws; 536 ws;
530 537
531 # first check some stop-symbols, so we don't have to backtrack 538 # first check some stop-symbols, so we don't have to backtrack
532 if (/\G(?=also\b|deep\b|in\b|of\b\)|$)/gc) { 539 if (/\G(?=also\b|deep\b|in\b|of\b\)|\z)/gc) {
540 pos = pos; # argh. the misop hits again. again. again. again. you die.
533 last; 541 last;
534 542
535 } elsif (/\Gor\b/gc) { 543 } elsif (/\Gor\b/gc) {
536 $res .= " || "; 544 $res .= " || ";
537 545
557 my $deep = /\Gdeep\s+/gc + 0; 565 my $deep = /\Gdeep\s+/gc + 0;
558 566
559 if (/\Gin\s+/gc) { 567 if (/\Gin\s+/gc) {
560 my $expand; 568 my $expand;
561 569
562 if (/\G(inv|env|map)\b/gc) { 570 if (/\G(inv|env|map|arch)\b/gc) {
563 if ($1 eq "inv") { 571 if ($1 eq "inv") {
564 $expand = "map \$_->inv,"; 572 $expand = "map \$_->inv,";
565 } elsif ($1 eq "env") { 573 } elsif ($1 eq "env") {
566 $expand = "map \$_->env // (),"; 574 $expand = "map \$_->env // (),";
575 } elsif ($1 eq "arch") {
576 $expand = "map \$_->arch,";
577 $deep = 0; # infinite loop otherwise
567 } elsif ($1 eq "map") { 578 } elsif ($1 eq "map") {
568 $expand = "map \$_->map->at (\$_->x, \$_->y),"; 579 $expand = "map \$_->map->at (\$_->x, \$_->y),";
580 $deep = 0; # infinite loop otherwise
569 } 581 }
570 } else { 582 } else {
571 $expand = "map \$_->inv, grep { " . condition . " }"; 583 $expand = "map \$_->inv, grep { " . condition . " }";
572 } 584 }
573 585
610 my $res; 622 my $res;
611 623
612 eval { 624 eval {
613 $res = cf::match::parser::match "\$object"; 625 $res = cf::match::parser::match "\$object";
614 626
615 /\G\s*$/gc 627 /\G$/gc
616 or die "unexpected trailing characters after match\n"; 628 or die "unexpected trailing characters after match\n";
617 }; 629 };
618 630
619 if ($@) { 631 if ($@) {
620 my $ctx = 20; 632 my $ctx = 20;
627 639
628 $res 640 $res
629} 641}
630 642
631if (0) {#d# 643if (0) {#d#
632 die parse 'applied', 1; 644 die parse 'type=SPELL_EFFECT and match(name="bullet" in arch)', 1;
633 exit 0; 645 exit 0;
634} 646}
635 647
636=item cf::match::match $match, $object[, $self[, $source[, $originator]]] 648=item cf::match::match $match, $object[, $self[, $source[, $originator]]]
637 649
671 &{ 683 &{
672 $CACHE{"$all$match"} ||= compile $match, $all 684 $CACHE{"$all$match"} ||= compile $match, $all
673 } 685 }
674} 686}
675 687
688our $CACHE_CLEARER = AE::timer 3600, 3600, sub {
689 %CACHE = ();
690};
691
676#d# $::schmorp=cf::player::find "schmorp"& 692#d# $::schmorp=cf::player::find "schmorp"&
677#d# cf::match::match '', $::schmorp->ob 693#d# cf::match::match '', $::schmorp->ob
678 694
679 695
680=back 696=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines