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.19 by root, Tue Oct 13 15:58:19 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines