File Coverage

blib/lib/Decl/Node.pm
Criterion Covered Total %
statement 404 591 68.3
branch 198 330 60.0
condition 28 84 33.3
subroutine 87 130 66.9
pod 98 98 100.0
total 815 1233 66.1


line stmt bran cond sub pod time code
1             package hashtie;
2 12     12   75 use warnings;
  12         24  
  12         409  
3 12     12   64 use strict;
  12         23  
  12         5955  
4             #require Tie::Hash;
5             #our @ISA = qw(Tie::ExtraHash); - Apparently only standard in perl >= 5.10. I'm copying it here to remove that dependency, because
6             # let's face it, it's eleven lines of code.
7             # Nota bene: CPAN Testers freaking rock!
8            
9             sub new {
10 0     0   0 my $pkg = shift;
11 0         0 $pkg->TIEHASH(@_);
12             }
13 1201     1201   2038 sub TIEHASH { my $p = shift; bless [{}, @_], $p }
  1201         13649  
14             #sub STORE { $_[0][0]{$_[1]} = $_[2] }
15             #sub FETCH { $_[0][0]{$_[1]} }
16 0     0   0 sub FIRSTKEY { my $a = scalar keys %{$_[0][0]}; each %{$_[0][0]} }
  0         0  
  0         0  
  0         0  
17 0     0   0 sub NEXTKEY { each %{$_[0][0]} }
  0         0  
18 108     108   590 sub EXISTS { exists $_[0][0]->{$_[1]} }
19 0     0   0 sub DELETE { delete $_[0][0]->{$_[1]} }
20 0     0   0 sub CLEAR { %{$_[0][0]} = () }
  0         0  
21 0     0   0 sub SCALAR { scalar %{$_[0][0]} }
  0         0  
22            
23             # My versions of STORE and FETCH.
24             sub STORE {
25 28     28   62 my ($this, $key, $value) = @_;
26 28 100       97 if ($this->[1]{$key}) { return &{$this->[1]{$key}}(undef, $this->[0], $key, $value); }
  1         3  
  1         28  
27 27 50       165 return $this->[2]->setvalue($key, $value) if defined $this->[2];
28 0         0 $this->[0]{$key} = $value;
29             }
30            
31             sub just_store {
32 52     52   106 my ($this, $key, $value) = @_;
33 52         188 $this->[0]{$key} = $value;
34             }
35            
36             sub FETCH {
37 45     45   82 my ($this, $key, $value) = @_;
38 45 100       133 if ($this->[1]{$key}) { return &{$this->[1]{$key}}(undef, $this->[0], $key); }
  4         8  
  4         109  
39 41 50       194 return $this->[2]->get_value($key) if defined $this->[2];
40 0         0 $this->[0]{$key};
41             }
42            
43             sub just_get {
44 148     148   222 my ($this, $key, $value) = @_;
45 148         914 $this->[0]{$key};
46             }
47            
48             package Decl::Node;
49            
50 12     12   88 use warnings;
  12         30  
  12         348  
51 12     12   67 use strict;
  12         30  
  12         441  
52            
53 12     12   17148 use Iterator::Simple qw(:all);
  12         69612  
  12         3976  
54 12     12   11892 use Text::ParseWords;
  12         30405  
  12         968  
55 12     12   93 use Decl::Semantics::Code;
  12         26  
  12         377  
56 12     12   8194 use Decl::Util;
  12         37  
  12         1060  
57 12     12   8673 use Data::Dumper;
  12         44727  
  12         813  
58 12     12   85 use Carp;
  12         23  
  12         1794  
59            
60             =head1 NAME
61            
62             Decl::Node - implements a node in a declarative structure.
63            
64             =head1 VERSION
65            
66             Version 0.08
67            
68             =cut
69            
70             our $VERSION = '0.08';
71            
72            
73             =head1 SYNOPSIS
74            
75             Each node in a C structure is represented by one of these objects. Specific semantics modules subclass these nodes for each of their
76             components.
77            
78             =head2 defines(), tags_defined()
79            
80             Called by C during import, to find out what xmlapi tags this plugin claims to implement. This is a class method, and by default
81             we've got nothing.
82            
83             The C function governs how C works.
84            
85             =cut
86 0     0 1 0 sub defines { (); }
87             sub tags_defined {
88 0     0 1 0 my $self = shift;
89 0         0 my $tag = Decl->new_data('handle');
90 0         0 foreach ($self->defines()) {
91 0         0 $tag->load($_);
92             }
93 0         0 return $tag;
94             }
95            
96             =head2 overloaded ""
97            
98             The node class returns tag(class) when expressed as a string.
99            
100             =cut
101            
102 12     12   77 use Scalar::Util qw(refaddr);
  12         20  
  12         2659  
103 1342     1342   3805 use overload ('""' => sub { $_[0]->tag . '(' . ref($_[0]) . ':' . refaddr($_[0]) . ')' },
104 17     17   130 '==' => sub { refaddr($_[0]) eq refaddr($_[1]) },
105 3     3   394 'eq' => sub { refaddr($_[0]) eq refaddr($_[1]) },
106 12     12   74 '!=' => sub { refaddr($_[0]) ne refaddr($_[1]) });
  12     0   34  
  12         271  
  0         0  
107            
108             =head2 refaddr_or_undef
109            
110             This is a cheap trick we're going to use for inserting children after other children.
111            
112             =cut
113            
114             sub refaddr_or_undef {
115 188     188 1 308 my $r = refaddr ($_[0]);
116 188 100       348 $r = $_[0] if not defined $r;
117 188         498 $r;
118             }
119            
120             =head2 new()
121            
122             The constructor for a node takes either one or an arrayref containing two texts. If one, it is the entire line-and-body of a node;
123             if the arrayref, the line and the body are already separated. If they're delivered together, they're split before proceeding.
124            
125             The line and body are retained, although they may be further parsed later. If the body is parsed, its text is discarded and is reconstructed if it's
126             needed for self-description. (This can be suppressed if a non-standard parser is used that has no self-description facility.)
127            
128             The node's I is the first word in the line. The tag determines everything pertaining to this entire section of the
129             application, including how its contents are parsed.
130            
131             =cut
132            
133             sub new {
134 1201     1201 1 3973 my $class = shift;
135             #print STDERR "Adding $class\n";
136             my $self = bless {
137             state => 'unparsed', # Fresh.
138             payload => undef, # Not built.
139 0     0   0 sub => sub {}, # Null action.
140 1201         31274 callable => 0, # Default is not callable.
141             owncode => 0, # Default doesn't have own callable code.
142             macroresult => 0, # Default is explicit text.
143             flag => '', # Indicates special handling of content.
144             name => '',
145             namelist => [],
146             parameters => {},
147             parmlist => [],
148             options => {},
149             optionlist => [],
150             label => '',
151             parser => undef,
152             code => undef,
153             finalcode => undef,
154             errors => [],
155             elements => [],
156             parent => undef,
157             comment => '',
158             bracket => 0,
159             replaced => 0,
160             group => 0,
161             parsemode => '', # Default is to use class nodes. Other valid values: text, vanilla.
162             is_reference=> 0,
163             }, $class;
164            
165 1201         3243 my %values = ();
166 1201         1791 my %handlers = ();
167 1201         5744 $self->{hashtie} = tie %values, 'hashtie', \%handlers, $self;
168 1201         3023 $self->{v} = \%values;
169 1201         2385 $self->{h} = \%handlers;
170 1201         2593 $self->{e} = {};
171            
172             # Now prepare the body as needed.
173 1201         1625 my ($line, $body);
174 1201         2165 $body = shift;
175             #print STDERR "new: body is " . Dumper ($body);
176 1201 100       2982 $body = '' unless defined $body;
177 1201 100       2639 if (ref $body eq 'ARRAY') {
178             #print STDERR "new: body is arrayref\n";
179             {
180 10         15 my @bodyrest;
  10         15  
181 10         29 ($line, @bodyrest) = @$body;
182             #print STDERR "new: first line is $line\n";
183 10         28 $body = \@bodyrest;
184             }
185             } else {
186 1191         4794 ($line, $body) = split /\n/, $body, 2;
187             }
188            
189 1201 100       3433 $line = 'node' unless defined $line;
190 1201         3168 my ($fulltag, $rest) = split /\s+/, $line, 2;
191 1201         2891 my ($tag, $flag) = splittag ($fulltag);
192 1201         3022 $self->{tag} = $tag;
193 1201         2272 $self->{flag} = $flag;
194 1201         4723 $self->{line} = $rest;
195 1201 100       3765 $self->{line} = '' if not defined $self->{line};
196 1201         2643 $self->{body} = $body;
197            
198 1201         5014 return $self;
199             }
200            
201             =head2 splittag - class method
202            
203             This splits the flag off a tag (e.g. template. => template + .)
204            
205             =cut
206            
207 2400     2400 1 17357 sub splittag { $_[0] =~ /^(.*?)([\?\!\*\.\+:]*)$/; }
208            
209             =head2 tag(), flag(), is($tag), name(), names(), line(), hasbody(), body(), elements(), truenodes(), payload()
210            
211             Accessor functions.
212            
213             =cut
214            
215 12716     12716 1 67507 sub tag { $_[0]->{tag} }
216 2996 100   2996 1 18505 sub flag { $_[1] ? (index ($_[0]->{flag}, $_[1]) >= 0) : $_[0]->{flag} }
217             sub is {
218 23821     23821 1 32877 my ($self, $is) = @_;
219 23821         53355 foreach (split /\|/, $is) {
220 23823 100       79819 return 1 if $self->{tag} eq $_;
221             }
222 23719         74447 return 0;
223             }
224 88     88 1 1813 sub name { $_[0]->{name} }
225 0     0 1 0 sub names { @{$_[0]->{namelist}} }
  0         0  
226 976     976 1 6207 sub line { $_[0]->{line} }
227 0 0   0 1 0 sub hasbody { defined $_[0]->{body} ? ($_[0]->{body} ? 1 : 0) : 0 }
    0          
228 2114     2114 1 8458 sub body { $_[0]->{body} }
229 820     820 1 1097 sub elements { @{$_[0]->{elements}} }
  820         4385  
230 10831 50   10831 1 11615 sub truenodes { grep { ref $_ && (defined $_[1] ? $_->is($_[1]) : 1) } @{$_[0]->{elements}} }
  30851 100       112574  
  10831         34008  
231 983     983 1 3987 sub payload { $_[0]->{payload} }
232            
233             =head2 nodes($flavor)
234            
235             The I nodes (C of a parent are the actual structural children that aren't comments. This function returns
236             the I nodes - by using a grouping structure, the results of macros, selects, and inserts can appear to be rooted
237             in the parent at precisely the place their progenitor is located.
238            
239             If C<$flavor> is specified, C returns only those children with tags equal to C<$flavor>; otherwise, all functional
240             children are returned.
241            
242             =cut
243            
244             sub nodes {
245 10823     10823 1 14656 my ($self, $flavor) = @_;
246 10823         19743 my @return = ();
247            
248 10823         23476 foreach my $n ($self->truenodes) {
249 30625 100       107393 if ($n->{group}) {
    50          
    100          
250 0         0 push @return, $n->nodes($flavor);
251             } elsif (defined $flavor ? $n->is($flavor) : 1) {
252 6985         14532 push @return, $n;
253             }
254             }
255 10823 100       54545 return wantarray ? @return : (@return ? $return[0] : undef);
    100          
256             }
257            
258             =head2 content_nodes($flavor)
259            
260             The I nodes of a parent are the functional nodes returned by C minus any that have the flag ':'. This permits nodes to be split
261             into "meta" specifications and child specifications for a given parent. An example might be providing a "style:" parameter for a text structure, or
262             a "path:" parameter for a directory.
263            
264             =cut
265            
266             sub content_nodes {
267 8     8 1 23 my ($self, $flavor) = @_;
268 8         20 my @return = ();
269            
270 8         40 foreach my $n ($self->truenodes) {
271 23 50 33     200 if ($n->{group} and not $n->flag(':')) {
    50 33        
    50          
272 0         0 push @return, $n->content_nodes($flavor);
273             } elsif ((defined $flavor ? $n->is($flavor) : 1) and not $n->flag(':')) {
274 23         61 push @return, $n;
275             }
276             }
277 8 0       53 return wantarray ? @return : (@return ? $return[0] : undef);
    50          
278             }
279            
280            
281             =head2 parent(), ancestry()
282            
283             A list of all the tags of nodes above this one, culminating in this one's tag, returned as an arrayref.
284            
285             =cut
286            
287 7284     7284 1 23949 sub parent { $_[0]->{parent} }
288             sub ancestry {
289 646     646 1 976 my ($self) = @_;
290 646         1340 my $parent = $self->parent();
291 646 50 33     2558 (defined $parent and $parent != $self->root()) ? [@{$parent->ancestry()}, $self->tag()] : [$self->tag()];
  0         0  
292             }
293            
294             =head2 parameter($p), option($o), parmlist(), optionlist(), parameter_n(), option_n(), label(), parser(), code(), gencode(), errors(), bracket(), comment()
295            
296             More accessor functions.
297            
298             =cut
299            
300 328 100 66 328 1 2757 sub parameter { $_[0]->{parameters}->{$_[1]} || $_[2] || '' }
301 8 0 33 8 1 504 sub option { $_[0]->{options}->{$_[1]} || $_[2] || '' }
302 2     2 1 869 sub option_n { ($_[0]->optionlist)[$_[1]-1] }
303 3     3 1 20 sub parameter_n { ($_[0]->parmlist)[$_[1]-1] }
304 57     57 1 71 sub parmlist { @{$_[0]->{parmlist}} }
  57         228  
305 63     63 1 87 sub optionlist { @{$_[0]->{optionlist}} }
  63         257  
306 175     175 1 3282 sub label { $_[0]->{label} }
307 42     42 1 184 sub parser { $_[0]->{parser} }
308 116     116 1 587 sub code { $_[0]->{code} }
309 0     0 1 0 sub gencode { $_[0]->{gencode} }
310 80     80 1 323 sub bracket { $_[0]->{bracket} }
311 42     42 1 128 sub comment { $_[0]->{comment} }
312            
313 0     0 1 0 sub errors { @{$_[0]->{errors}} }
  0         0  
314            
315             =head2 plist(@parameters)
316            
317             Given a list of parameters, returns a hash (not a hashref) of their values, first looking in the parameters, then looking for children
318             of the same name and returning their labels if necessary. This allows us to specify a parameter for a given object either like this:
319            
320             object (parm1=value1, parm2 = value2)
321            
322             or like this:
323            
324             object
325             parm1 "value1"
326             parm2 "value2"
327            
328             It just depends on what you find more readable at the time. For this to work during payload build, though, the children have to be built
329             first, which isn't the default - so you have to call $self->build_children before using this in the payload build.
330            
331             This is really useful if you're wrapping a module that uses a hash to initialize its object. Like, say, L.
332            
333             =cut
334            
335             sub plist {
336 1     1 1 8 my $self = shift;
337 1         3 my %p;
338 1         3 foreach my $p (@_) {
339 3 100       10 if ($self->parameter($p)) {
    50          
340 2         6 $p{$p} = $self->parameter($p);
341             } elsif (my $pnode = $self->find($p)) {
342 1         6 $p{$p} = $pnode->label;
343             }
344             }
345            
346 1         12 %p;
347             }
348            
349             =head2 parm_css (parameter), set_css_values (hashref, parameter_string), prepare_css_value (hashref, name), get_css_value (hashref, name)
350            
351             CSS is characterized by a sort of "parameter tree", where many parameters can be seen as nested in a hierarchy. Take fonts, for example.
352             A font has a size, a name, a bolded flag, and so on. To specify a font, then, we end up with things like font-name, font-size, font-bold, etc.
353             In CSS, we can also group those things together and get something like font="name: Times; size: 20", and that is equivalent to
354             font-name="Times", font-size="20". See?
355            
356             This function does the same thing with the parameters of a node. If you give it a name "font" it will find /font-*/ as well, and munge
357             the values into the "font" value. It returns a hashref containing the entire hierarchy of these things, and it will also interpret any
358             string-type parameters in the higher levels, e.g. font="size: 20; name: Times" will go into {size=>20, name=>'Times'}. Honestly, I love
359             this way of handling parameters in CSS.
360            
361             If you give a name "font-size" it will also find any font="size: 20" specification and retrieve the appropriate value.
362            
363             It I decompose multiple hierarchical levels starting from a string (e.g. something like font="size: {type: 3}" will not be parsed for
364             font-size-type, because you'd need curly brackets or something anyway, and this ain't JSON, it's just simple CSS-like parameter addressing.
365            
366             =cut
367            
368             sub parm_css {
369 7     7 1 34 my ($self, $parameter) = @_;
370 7         14 my $return = {};
371 7         14 my $top = $parameter;
372 7         26 $top =~ s/[.\-\/].*$//;
373 7 100       21 hh_set ($return, $top, $self->parameter ($top)) if $self->parameter($top);
374 7         23 foreach ($self->parmlist()) {
375 15 100       118 if ($_ =~ /^$top[.\-\/]/) {
376 10         24 hh_set ($return, $_, $self->parameter ($_));
377             }
378             }
379 7         27 return hh_get ($return, $parameter);
380             }
381            
382            
383             =head2 flags({flag=>numeric value, ...}), oflags({flag=>numeric value, ...})
384            
385             A quick utility to produce an OR'd flag set from a list of parameter words. Pass it a hashref containing numeric values for a set of words, and
386             you'll get back the OR'd sum of the flags found in the parameters. The C function does this for the parameters (round parens) and the C
387             function does the same for the options [square brackets].
388            
389             =cut
390            
391             sub flags {
392 0     0 1 0 my ($self, $f) = @_;
393            
394 0         0 my $r = 0;
395            
396 0         0 while (my ($k, $v) = each %$f) {
397 0 0       0 $r |= $v if $self->parameter ($k);
398             }
399 0         0 return $r;
400             }
401             sub oflags {
402 0     0 1 0 my ($self, $f) = @_;
403            
404 0         0 my $r = 0;
405            
406 0         0 for (my ($k, $v) = each %$f) {
407 0 0       0 $r |= $v if $self->option ($k);
408             }
409 0         0 return $r;
410             }
411            
412             =head2 list_parameter ($name)
413            
414             Sometimes, instead of having e.g. position-x and position-y parameters, it's easier to have something like p=40 20 or dim=20x20. We can use
415             the C function to obtain a list of any numbers separated by non-number characters. (Note that due to the line parser using
416             commas to separate the parameters themselves, the separator can't be a comma. Unless you want to write a different line parser, in which
417             case, go you!)
418            
419             So the separator characters can be: !@#$%^&*|:;~x and space.
420            
421             =cut
422            
423 0     0 1 0 sub list_parameter { split /[!@\#\$%\^\&\*\|:;~xX ]/, parameter(@_); }
424            
425             =head1 BUILDING STRUCTURE
426            
427             =head2 load ($string, $after)
428            
429             The C method loads declarative specification text into a node by calling the parser appropriate to the node. Multiple loads can be carried out,
430             and will simply add to text already there.
431            
432             The return value is the list of objects added to the target, if any.
433            
434             =cut
435            
436             sub load {
437 758     758 1 1861 my ($self, $string, $after) = @_;
438            
439 758         1258 my @added;
440            
441 758 100       1877 if (ref $string) {
442             #print STDERR "load: Adding from arrayref!\n" . Dumper($string);
443 9 50       35 if (ref $string ne 'ARRAY') { # In case we're loading already-created nodes.
444 0         0 $string->{parent} = $self;
445 0         0 $self->{elements} = [$self->elements, $string];
446 0         0 push @added, $string;
447             } else {
448 9         26 my $root = $self->root;
449 9 100       41 $string = [$string] unless ref $$string[0];
450 9         23 foreach my $addition (@$string) {
451             #print STDERR "addition is $addition\n";
452             #print STDERR "line is " . ref($addition) ? $$addition[0] : $addition;
453 10 50       36 my $tag = ref($addition) ? $$addition[0] : $addition;
454 10         55 $tag =~ s/ .*//;
455             #print STDERR ", tag is $tag\n";
456            
457             # Make and add the tag by hand (for a text body, this is done by the parser in the 'else' block below).
458 10         39 my $newtag = $root->makenode($self, $tag, $addition);
459 10         24 $newtag->{parent} = $self;
460 10         30 $self->{elements} = [$self->elements, $newtag];
461            
462 10         49 push @added, $newtag;
463             }
464             }
465             } else {
466             # Taken from the Perl recipes:
467 749         1118 my ($white, $leader); # common whitespace and common leading string
468 749 100       2687 if ($string =~ /^\s*(?:([^\w\s]+)(\s*).*\n)(?:\s*\1\2?.*\n)+$/) {
469 3         18 ($white, $leader) = ($2, quotemeta($1));
470             } else {
471 746         3070 ($white, $leader) = ($string =~ /^(\s+)/, '');
472             }
473 749 100       2324 $leader = '' unless $leader;
474 749 100       1997 $white = '' unless $white;
475 749         3252 $white =~ s/^\n*//;
476 749 100 100     4322 $string =~ s/^\s*?$leader(?:$white)?//gm if $leader or $white;
477 749         2322 my $root = $self->root();
478 749         3587 @added = $root->parse ($self, $string);
479             }
480            
481 758 100       2103 if ($after) {
482             # Rearrange $self->{elements} if we were given an 'after' node that appears in 'elements'.
483 6         11 my @newels = ();
484 6         10 my $found_after = 0;
485 6         10 foreach my $e (@{$self->{elements}}) {
  6         18  
486 50 100       111 if (refaddr_or_undef($e) eq refaddr_or_undef($after)) {
487 6         12 $found_after = 1;
488 6         14 push @newels, $e;
489 6         13 foreach my $a (@added) {
490 6         22 push @newels, $a;
491             }
492             } else {
493 44 100       91 last if grep {refaddr_or_undef($_) eq refaddr_or_undef($e)} @added;
  44         78  
494 38         88 push @newels, $e;
495             }
496             }
497 6 50       31 $self->{elements} = \@newels if $found_after;
498             }
499            
500 758         1616 foreach (@added) {
501 927 50       6064 $_->build if $_->can('build');
502             }
503             #print Dumper($self->sketch);
504 757 100       5898 return wantarray ? @added : (@added ? $added[0] : undef);
    100          
505             }
506            
507             =head2 macroinsert ($spec, $after)
508            
509             This function adds structure to a given node at runtime that won't show up in the node's C results. It is used by the macro system (hence
510             the name) but can be used by other runtime structure modifiers that act more or less like macros. The idea is that this structure is meaningful at runtime
511             but is semantically already accounted for in the existing definition, and should I be generated only at runtime.
512            
513             =cut
514            
515             sub macroinsert {
516 7     7 1 1690 my ($self, $string, $after) = @_;
517 7         36 my @objects = $self->load($string, $after);
518 7         46 foreach (@objects) {
519 9         30 $_->{macroresult} = 1;
520             }
521 7         30 @objects;
522             }
523            
524             =head2 replace_node ($old_node, $new_node)
525            
526             There are times when dynamically changing semantics force us to reevaluate an existing node during the build phase. We use C
527             to replace the existing node with the newly interpeted variant. It works by actual pointer. If the C isn't found, nothing will
528             happen.
529            
530             =cut
531            
532             sub replace_node {
533 0     0 1 0 my ($self, $old, $new) = @_;
534 0         0 $old->{replaced} = $new; # Make sure ongoing builds build the right node.
535 0         0 foreach (@{$self->{elements}}) {
  0         0  
536 0 0       0 next unless ref $_;
537 0 0       0 $_ = $new if $_ == $old;
538             }
539             }
540            
541             =head2 Setting parts of a node: set_name($name), set_label($label), set_parmlist (@list), set_parameter($key, $value), set_optionlist (@list), set_option($key, $value)
542            
543             These are handy for building a node from scratch.
544            
545             =cut
546            
547             sub set_name {
548 0     0 1 0 my $self = shift;
549 0         0 $self->{name} = $_[0];
550 0         0 $self->{namelist} = [@_]; # Make a copy!
551             }
552             sub set_label {
553 278     278 1 514 my $self = shift;
554 278         1246 $self->{label} = $_[0];
555             }
556             sub set_parmlist {
557 0     0 1 0 my $self = shift;
558 0         0 $self->{parmlist} = [@_];
559             }
560             sub set_parameter {
561 0     0 1 0 my ($self, $key, $value) = @_;
562 0         0 $self->{parameters}->{$key} = $value;
563             }
564             sub set_optionlist {
565 0     0 1 0 my $self = shift;
566 0         0 $self->{optionlist} = [@_];
567             }
568             sub set_option {
569 0     0 1 0 my ($self, $key, $value) = @_;
570 0         0 $self->{options}->{$key} = $value;
571             }
572            
573             =head2 The build process: build(), preprocess(), preprocess_line(), decode_line(), parse_body(), build_payload(), build_children(), add_to_parent(), post_build()
574            
575             The C function parses the body of the tag, then builds the payload it defines, then calls build on each child if appropriate, then adds itself
576             to its parent. It provides the hooks C (checks for macro nature and expresses if so), C (asks the application to call the appropriate
577             parser for the tag), C (does nothing by default), C (calls C on each element), and C
578             (does nothing by default).
579            
580             If this tag corresponds to a macro, then substitution takes place before parsing, in the preprocess step.
581            
582             =cut
583            
584             sub build {
585 984     984 1 1581 my $self = shift;
586 984 50       2788 return $self->{replaced}->build if $self->{replaced};
587            
588 984 100       2816 if ($self->{state} ne 'built') {
589 975 100       2484 if ($self->root()->{macro_definitions}->{$self->tag}) { # This is required because in some cases, the macro definition may have been
590             # registered *after* the class was already assigned to the macro instance.
591             # E.g.:
592             # define my_macro
593             # ...
594             # my_macro
595             # (On the same level with the same parent, my_macro has already been split out.)
596 4         19 bless $self, 'Decl::Semantics::Macro';
597             }
598 975         2610 $self->{force_text} = 0;
599 975         2674 $self->preprocess_line;
600 975         2238 $self->decode_line;
601 975         3815 $self->preprocess;
602 975 50       4860 $self->parse_body unless $self->{force_text};
603 975         3294 $self->build_payload;
604 974 100       4589 $self->build_children unless $self->{force_text};
605 974         3182 $self->add_to_parent;
606 974         3183 $self->post_build;
607            
608 974         2380 $self->{state} = 'built';
609             }
610 983         2634 return $self->payload;
611             }
612            
613 975     975 1 1241 sub preprocess_line {}
614            
615             sub decode_line { # Was called parse_line, but there was an unfortunate and brain-bending collision with Text::ParseWords. Oy.
616 975     975 1 1362 my $self = shift;
617 975         1901 my $root = $self->root;
618 975         3531 $root->parse_line ($self);
619             }
620            
621 975     975 1 1482 sub preprocess {}
622            
623             sub parse_body {
624 975     975 1 1737 my $self = shift;
625 975 50       8597 if ($self->tag =~ /^!/) {
626 0         0 $self->{tag} =~ s/^!//;
627             } else {
628 975         2786 my $root = $self->root;
629 975 100       3305 if (ref $self->body eq 'ARRAY') {
630             # If we have an arrayref input, we don't need to parse it! (2010-12-05)
631             #print "parse_body: body is an arrayref\n";
632 10         21 my $list = $self->{body};
633 10         23 $self->{body} = '';
634 10         30 foreach (@$list) {
635 9         57 $self->load ($_);
636             }
637             } else {
638 965 100 100     2038 my @results = $root->parse ($self, $self->body) if $self->body and not $self->{bracket};
639 965 100       4633 $self->{body} = '' if @results;
640             }
641             }
642             }
643            
644 942     942 1 1679 sub build_payload {}
645            
646             sub build_children {
647 977     977 1 3584 my $self = shift;
648            
649 977         2709 foreach ($self->nodes) {
650 55 50       412 $_->build if $_->can('build');
651             }
652             }
653            
654 974     974 1 1244 sub add_to_parent {}
655            
656 974     974 1 1263 sub post_build {}
657            
658             =head1 STRUCTURE ACCESS
659            
660             =head2 find($locator), findbyname($locator)
661            
662             Given a node, finds a descendant using a simple XPath-like language. Once you build a recursive-descent parser facility into your language, this sort
663             of thing gets a whole lot easier. The C function looks by tag; the C treats the tag as a type and thus the name as the search
664             property.
665            
666             Generation separators are '.', '/', or ':' depending on how you like it. Offsets by number are in round brackets (), while finding children by name is
667             done with square brackets []. Square brackets [name] find tags named "name". Square brackets [name name2] find name lists (which nodes can have, yes),
668             and square brackets with an = or =~ can also search for nodes by other values.
669            
670             You can also pass the results of a parse (the arrayref tree) in as the path; this allows you to build the parse tree using other tools instead of forcing
671             you to build a string (it also allows a single parse result to be used recursively without having to parse it again).
672            
673             =cut
674            
675             sub find {
676 71     71 1 2935 my ($self, $path) = @_;
677            
678 71 100       751 $path = $self->root->parse_using ($path, 'locator') unless ref $path;
679 71 100       336 return $self if @$path == 0;
680            
681 34         87 my $first = shift @$path;
682 34         136 foreach ($self->nodes) {
683 69 100       286 return $_->find($path) if $_->match($first);
684             }
685 0         0 return undef;
686             }
687             sub findbyname {
688 8     8 1 17 my ($self, $path) = @_;
689            
690 8 100       33 $path = $self->root->parse_using ($path, 'locator') unless ref $path;
691 8 100       36 return $self if @$path == 0;
692            
693 6         10 my $first = shift @$path;
694 6         21 foreach ($self->nodes) {
695 12 100       41 return $_->findbyname($path) if $_->matchbyname($first);
696             }
697 0         0 return undef;
698             }
699            
700             =head2 match($pathelement), matchbyname($pathelement)
701            
702             Returns a true value if the node matches the path element specified; otherwise, returns a false value.
703            
704             =cut
705            
706             sub match {
707 6218     6218 1 8741 my ($self, $pathelement) = @_;
708 6218 100       17908 return ($self->tag eq $pathelement) unless ref $pathelement;
709 40         64 my ($tag, $name) = @$pathelement;
710 40 100 100     84 return 1 if $self->tag eq $tag and $self->name eq $name;
711 29         103 return 0;
712             }
713            
714             sub matchbyname {
715 12     12 1 21 my ($self, $pathelement) = @_;
716 12 50       44 return ($self->name eq $pathelement) unless ref $pathelement;
717 0         0 my ($name, $label) = @$pathelement;
718 0 0 0     0 return 1 if $self->name eq $name and $self->label eq $label;
719 0         0 return 0;
720             }
721            
722             =head2 first($nodename)
723            
724             Given a node, finds a descendant with the given tag anywhere in its descent. Uses the same path notation as C.
725            
726             =cut
727            
728             sub first {
729 6428     6428 1 11555 my ($self, $path) = @_;
730            
731 6428 100       14591 $path = $self->root->parse_using ($path, 'locator') unless ref $path;
732 6428 50       13378 return $self if @$path == 0;
733            
734 6428         10717 my ($first, @rest) = @$path;
735 6428         12111 foreach ($self->nodes) {
736 6149 100       13076 if ($_->match($first)) {
737 12         53 my $possible = $_->find(\@rest);
738 12 50       63 return $possible if $possible;
739             }
740 6137         14641 my $child = $_->first($path);
741 6137 100       15913 return $child if $child;
742             }
743 6400         14177 return undef;
744             }
745            
746             =head2 search($nodename)
747            
748             Given a node, finds all descendants with the given tag.
749            
750             =cut
751            
752             sub search {
753 3     3 1 23 my ($self, $path) = @_;
754 3         6 my @returns = ();
755 3         7 foreach ($self->nodes) {
756 2 50       6 push @returns, $_ if $_->tag eq $path;
757 2         15 push @returns, $_->search($path);
758             }
759             @returns
760 3         11 }
761            
762             =head2 search_data($type)
763            
764             Given a node, finds all its descendents that match the given type in either name or tag.
765             If the type ends in a ':', will only return meta nodes.
766            
767             =cut
768            
769             sub search_data {
770 0     0 1 0 my ($self, $type) = @_;
771 0         0 my $flag = '';
772 0 0       0 if ($type =~ /:$/) { # TODO: just : flag?
773 0         0 $type =~ s/:$//;
774 0         0 $flag = ':';
775             }
776 0         0 my @returns = ();
777 0         0 foreach ($self->nodes) {
778 0 0 0     0 if ($_->is($type) || $_->name eq ($type)) {
779 0 0 0     0 push @returns, $_ if not $flag or $_->flag($flag);
780             }
781 0         0 push @returns, $_->search_data($type . $flag);
782             }
783 0         0 @returns;
784             }
785            
786             =head2 describe, myline, describe_content
787            
788             The C function is used to get our code back out so we can reparse it later if we want to. It includes the body and any children.
789             The C function just does that without the body and children (just the actual line).
790             The C function does just the body and children (without the actual line).
791            
792             We could also use this to check the output of the parser, which notoriously just stops on a line if it encounters something it's not
793             expecting.
794            
795             =cut
796            
797             sub myline {
798 41     41 1 54 my ($self) = @_;
799            
800 41         74 my $description = $self->tag . $self->flag;
801 41         71 foreach (@{$self->{namelist}}) {
  41         112  
802 30         82 $description .= " " . $_;
803             }
804            
805 41 100       106 if ($self->parmlist) {
806 16 50       35 $description .= " (" .
    100          
807             join (', ', map {
808 4         14 $self->parameter($_) eq 'yes' ?
809             $_ :
810             ($self->parameter($_) =~ / |"/ ?
811             $_ . '="' . escapequote ($self->parameter($_)) . '"' :
812             $_ . '=' . $self->parameter($_))
813             } $self->parmlist) .
814             ")";
815             }
816            
817 41 100       110 if ($self->optionlist) {
818 8 0       25 $description .= " [" .
    50          
819             join (', ', map {
820 4         12 $self->option($_) eq 'yes' ?
821             $_ :
822             ($self->option($_) =~ / |"/ ?
823             $_ . '="' . escapequote ($self->option($_)) . '"' :
824             $_ . '=' . $self->option($_))
825             } $self->optionlist) .
826             "]";
827             }
828            
829 41 100       95 $description .= ' "' . $self->label . '"' if $self->label ne '';
830 41 50       95 $description .= ' ' . $self->parser . ' <' if $self->parser;
831 41 100       87 $description .= ' ' . $self->code if $self->code;
832 41 100       94 $description .= ' ' . $self->bracket if $self->bracket;
833 41 50       90 $description .= ' ' . $self->comment if $self->comment;
834            
835 41         176 $description;
836             }
837            
838             sub describe {
839 41     41 1 59 my ($self, $macro_ok) = @_;
840            
841 41         117 $self->myline . "\n" . $self->describe_content (' ', $macro_ok);
842             }
843             sub describe_content {
844 41     41 1 75 my ($self, $prefix, $macro_ok) = @_;
845 41         63 my $description = '';
846 41 50       105 $prefix = '' unless defined $prefix;
847 41 50       72 $macro_ok = 0 unless defined $macro_ok;
848            
849 41 100       83 if ($self->body) {
850 7         20 foreach (split /\n/, $self->body) {
851 19         50 $description .= "$prefix$_\n";
852             }
853 7 100       20 $description .= "}\n" if $self->bracket;
854             } else {
855 34         69 foreach ($self->elements) {
856 29 50 100     147 if (not ref $_) {
    100          
857 0         0 $description .= $_;
858             } elsif ($_->{macroresult} and not $macro_ok) {
859 3         7 next;
860             } else {
861 26         72 foreach (split /\n/, $_->describe($macro_ok)) {
862 42         141 $description .= "$prefix$_\n";
863             }
864             }
865             }
866             }
867            
868 41         254 $description;
869             }
870            
871             =head2 sketch (), sketch_c(), sketch_d()
872            
873             Returns a thin structure reflecting the nodal structure of the node in question:
874            
875             ['tag',
876             [['child1', []],
877             ['child2', []]]]
878            
879             Like that. I'm building it for testing purposes, but it might be useful for something else, too.
880            
881             The C variant also includes the class of each node, and the C variant runs the
882             whole thing through Dumper first.
883            
884             =cut
885            
886             sub sketch {
887 40     40 1 65 my ($self) = @_;
888            
889 40         89 [$self->tag, [map { $_->sketch() } $self->nodes()]];
  35         111  
890             }
891             sub sketch_c {
892 0     0 1 0 my ($self) = @_;
893            
894 0         0 [$self->tag, ref($self), [map { $_->sketch_c() } $self->nodes()]];
  0         0  
895             }
896 0     0 1 0 sub sketch_d { Dumper ($_[0]->sketch_c); }
897            
898             =head2 mylocation()
899            
900             This reports the node's own location in the code tree.
901            
902             =cut
903            
904             sub mylocation {
905 0     0 1 0 my $self = shift;
906 0         0 my $p = $self->parent->mylocation();
907 0         0 my $l = $self->tag() . '[' . join(' ', $self->names()) . ']';
908 0 0       0 return '/' . $l if $p eq '/';
909 0         0 return $p . '/' . $l;
910             }
911            
912             =head2 go($item)
913            
914             For callable nodes, this is one way to call them. The default is to call the go methods of all the children of the node, in sequence.
915             The last result is returned as our result (this means that the overall tree may have a return value if you set things up right).
916            
917             =cut
918            
919             sub go {
920 14     14 1 33 my $self = shift;
921 14         57 my $callcontext = shift;
922            
923 14         93 $self = $self->deref;
924 14 50       50 return unless defined $self; # TODO: warning
925 14 50       57 return unless $self->{callable};
926 14 100 66     85 return &{$self->{sub}}($callcontext, @_) if $self->{owncode} && $self->{sub};
  6         211  
927            
928 8         18 my $return;
929             my $last_iffy;
930 8         16 my $master_iffy = undef;
931 8         62 foreach ($self->content_nodes) {
932 23 100       79 next unless $_->{callable};
933 11 100       41 next if $_->{callable} eq 'sub';
934 10 100       44 next if $_->{event};
935 6 50       33 if ($_->{callable} eq '?') {
936 0         0 $last_iffy = $_;
937 0 0 0     0 $master_iffy = $_ if $_->flag('!') and not defined $master_iffy;
938             } else {
939 6         56 $return = $_->go (@_);
940 6         34 undef $last_iffy;
941             }
942             }
943 8 50       33 return $master_iffy->go(@_) if defined $master_iffy;
944 8 50       30 return $last_iffy->go(@_) if defined $last_iffy;
945 8         152 $return;
946             }
947            
948             =head2 closure(...)
949            
950             For callable nodes, this is the other way to call them; it returns the closure created during initialization. Note that the
951             default closure is really boring.
952            
953             =cut
954            
955 0     0 1 0 sub closure { $_[0]->{sub} }
956            
957            
958             =head2 iterate()
959            
960             Returns an L iterator over the body of the node. If the body is a text body, each call returns a line. If the body is a bracketed
961             code body, it is executed to return an iterable object. Yes, this is neat.
962            
963             If we're a parser macro, we'll run our special parser over the body instead of the normal parser.
964            
965             TODO: shouldn't this be recursive for structured nodes?
966            
967             TODO: might want to do something clever with a code ref tag. (I.e. if the tag is a reference but also has a code block, perhaps evaluate the code
968             block to figure out the reference or something. This might be a plate of beans.)
969            
970             =cut
971            
972             sub iterate {
973 18     18 1 1229 my $self = shift;
974            
975 18         64 $self = $self->deref;
976 18 50       52 return iter([]) unless defined $self; # TODO: warning
977 18 50 66     56 return iter([]) unless $self->code or $self->nodes or $self->body;
      66        
978 18 100 66     96 if ($self->code or $self->bracket) {
    100          
979             # This is code to be executed, that should return an iterable object.
980 1         3 my $code;
981 1 50       4 if ($self->code) {
982 0         0 $code = $self->code;
983             } else {
984 1         4 $code = $self->bracket . "\n";
985 1         6 $code =~ s/^{//;
986 1         6 $code .= $self->body;
987             }
988 1         9 my $sub = Decl::Semantics::Code::make_code ($self, $code);
989 1         34 my $result = &$sub();
990 1 50       218 if (ref $result) {
991 1         5 return iter ($result);
992             } else {
993 0         0 my @lines = split /\n/, $result;
994 0         0 return iter (\@lines);
995             }
996             } elsif ($self->nodes) {
997             # Iterate over children.
998 3         9 return ichain map { $_->iterate } $self->nodes;
  17         198  
999             } else {
1000             # This is text to be iterated over.
1001 14         39 my @lines = split /\n/, $self->body;
1002 14         80 return iter (\@lines);
1003             }
1004             }
1005            
1006             =head2 text()
1007            
1008             This returns a tokenstream on the node's body permitting a consumer to read a series of words interspersed with formatting commands.
1009             The formatting commands are pretty loose - essentially, "blankline" is the only one. Punctuation is treated as letters in words; that is,
1010             only whitespace is elided in the tokenization process.
1011            
1012             If the node has been parsed, it probably doesn't have a body any more, so this will return a blank tokenstream. On the other hand, if the node
1013             is callable, it will be called, and the result will be used as input to the tokenstream - same rules as C above.
1014            
1015             =cut
1016            
1017            
1018             =head2 express(), content()
1019            
1020             The C function returns the iterated content from iterate(), assembled into lines with as few newlines as possible.
1021             The C function is normally an alias for C.
1022            
1023             =cut
1024            
1025             sub express {
1026 0     0 1 0 my $self = shift;
1027 0         0 $self->content(@_);
1028             }
1029             sub content {
1030 3     3 1 29 my ($self, $linebreak) = @_;
1031 3 50       12 $linebreak = "\n" unless $linebreak;
1032            
1033 3         19 my $i = $self->iterate;
1034 3         200 my $result = '';
1035 3         7 my $line;
1036            
1037 3         4 do {
1038 13         33 $line = $i->();
1039 13 100       204 return $result unless defined $line;
1040            
1041 10         17 chomp $line;
1042 10         38 $result .= "$line\n";
1043             } while (defined $line);
1044            
1045 0         0 return $result;
1046             }
1047            
1048             #my $linestart = 1; TODO: figure out why I thought this should be the default. Sigh.
1049             #do {
1050             # $line = $i->();
1051             # if (defined $line) {
1052             # if ($self->parameter('raw')) {
1053             # $result .= $line . "\n";
1054             # } else {
1055             # $line =~ s/\s+$//;
1056             # if ($line ne '') {
1057             # $result .= ($linestart ? '' : ' ') . $line;
1058             # $linestart = 0;
1059             # } else {
1060             # $result .= $linebreak;
1061             # $linestart = 1;
1062             # }
1063             # }
1064             # }
1065             #} while (defined $line);
1066            
1067            
1068             our $ACCEPT_EVENTS = 0;
1069            
1070             =head2 event_context
1071            
1072             If the node is an event context (e.g. a window or frame or dialog), this should return the payload of the node.
1073             Otherwise, it returns the event_context of the parent node.
1074            
1075             =cut
1076            
1077             sub event_context {
1078 57 50   57 1 194 return $_[0] if $ACCEPT_EVENTS;
1079 57 50       157 return $_[0]->parent()->event_context() if $_[0]->parent;
1080 0         0 $_[0]->root;
1081             }
1082            
1083             =head2 root
1084            
1085             Returns the parent - all nodes do this. The top node at C returns itself.
1086            
1087             =cut
1088            
1089 4686     4686 1 10704 sub root {$_[0]->parent->root}
1090            
1091             =head2 error
1092            
1093             Error handling is the part of programming I'm worst at. But you just have to bite the bullet and address your weaknesses,
1094             so here is an error marker function. If there's a problem with a node specification, this marks it. Later we'll do something
1095             sensible with it. TODO: something sensible.
1096            
1097             =cut
1098            
1099             sub error {
1100 0     0 1 0 my ($self, $error) = @_;
1101 0 0       0 $self->{errors} = [] unless $self->{errors};
1102 0         0 push @{$self->{errors}}, $error;
  0         0  
1103             #print STDERR "$error\n"; # TODO: bad long-term...
1104             }
1105            
1106             =head2 find_data
1107            
1108             The C function finds a data node starting at a given point in the tree. Right now, it's just going to look for nodes
1109             by name/tag, but more mature locators should follow eventually.
1110            
1111             =cut
1112            
1113             sub find_data {
1114 4     4 1 8 my ($self, $data) = @_;
1115 4 50       13 $data = 'data' unless defined $data;
1116 4 0       8 foreach ($self->nodes) { return ($_, $_->tag) if $_->name eq $data; }
  0         0  
1117 4 0       11 foreach ($self->nodes) { return ($_, $_->tag) if $_->is($data); }
  0         0  
1118 4 50       11 return $self->parent->find_data ($data) if $self->parent;
1119 0         0 return (undef, undef);
1120             }
1121            
1122             =head2 find_context (tag, name)
1123            
1124             Here, we search for a node with a given name and tag in almost the same way as C - first searching our siblings, then our parent's
1125             siblings, and so on. Used to look for macro definitions, databases, whatever. If either the tag or the name is omitted, it won't be
1126             used for comparison (thus the first tag of any name or the first named tag of any type will be returned).
1127            
1128             Note I said "almost". Any node that comes after the caller won't be considered context. (Neither will the caller itself.) Ditto the parent,
1129             grandparent, etc. What that means is that context has to appear in the source before the point where C is called.
1130            
1131             =cut
1132            
1133             sub find_context {
1134 0     0 1 0 my ($self, $tag, $name) = @_;
1135 0 0       0 return unless ($self->parent);
1136 0         0 foreach ($self->parent->nodes) {
1137 0 0       0 last if $_ == $self;
1138 0 0 0     0 return ($_) if ((not defined $tag) || $_->is($tag)) and ((not defined $name) || $_->name eq $name);
      0        
      0        
1139             }
1140 0         0 $self->parent->find_context($tag, $name);
1141             }
1142            
1143            
1144             =head2 find_ref (tag, name)
1145            
1146             The C function looks for tag-and-name combinations that don't have the "is_reference" flag set. It returns the first it finds.
1147             If either tag or name is C, it ignores that spec.
1148            
1149             =cut
1150            
1151             sub find_ref {
1152 0     0 1 0 my ($self, $tag, $name) = @_;
1153 0         0 foreach ($self->nodes) {
1154 0 0 0     0 next if $_->{is_reference} or $_->flag('?');
1155 0 0 0     0 return $_ if ((not defined $tag) || $_->is($tag)) and ((not defined $name) || $_->name eq $name);
      0        
      0        
1156             }
1157 0         0 $self->parent->find_ref ($tag, $name);
1158             }
1159            
1160             =head2 deref ()
1161            
1162             The C function uses C to dereference a reference tag. If the tag you give it isn't a reference, you'll just get that tag back.
1163             If it's a dangling reference, you'll get C.
1164            
1165             =cut
1166            
1167             sub deref {
1168 32     32 1 56 my ($self) = @_;
1169 32 50 33     194 return $self unless $self->{is_reference} or $self->flag('?');
1170 0 0       0 return $self->parent->find_ref (undef, $self->name) if defined $self->name;
1171 0         0 return $self->parent->find_ref ($self->tag);
1172             }
1173            
1174             =head2 set(), get(), get_pair()
1175            
1176             These provide a place for object constructors to stash useful information. The C function gets a parameter if the named user variable
1177             hasn't been set. It also allows the specification of a default value.
1178            
1179             C gets a pair of named values as an arrayref, with a single arrayref default if neither is found. The individual defaults are assumed
1180             to be 0.
1181            
1182             =cut
1183            
1184             sub set {
1185 0     0 1 0 my ($self, $var, $value) = @_;
1186 0         0 $self->{user}->{$var} = $value;
1187             }
1188             sub get {
1189 0     0 1 0 my ($self, $var, $default) = @_;
1190 0 0       0 return $self->{user}->{$var} if defined $self->{user}->{$var};
1191 0 0       0 return $self->{parameters}->{$var} if defined $self->{parameters}->{$var};
1192 0 0       0 return $default if defined $default;
1193 0         0 ''
1194             }
1195             sub get_pair {
1196 0     0 1 0 my ($self, $x, $y, $default) = @_;
1197            
1198 0 0 0     0 if ($self->get($x) ne '' || $self->get($y) ne '') {
1199 0         0 return [($self->get($x, 0)), ($self->get($y, 0))];
1200             }
1201 0         0 return $default;
1202             }
1203            
1204             =head1 VALUES
1205            
1206             The value system in a Decl node is getting pretty darned complex. Essentially, though, each node has a value lookup hash that either has scalar values directly
1207             or closures that can be used as proxies for values found in other nodes. (For example, if a node is a macro instantiation, then mostly we're going to be referring
1208             to values in the definition, not in the instance. If a node hasn't explicitly defined a value but its parent has, then when we set that value we'll want to set it
1209             in the parent, not in the child. And so on.)
1210            
1211             When we first want to use a given value in a node, we'll call "find_value". That will return a closure that can be called to get or set the value. If the value
1212             can't be set, the closure will simply have no effect. The closure will be stashed locally so that it need only be located once, and we're always assured of being
1213             able to access the same storage location for a given name.
1214            
1215             =head2 find_value($var), with helper function get_value_closure
1216            
1217             To find a value:
1218            
1219             1. Return any previously located closure.
1220             2. If we're a macro instantiation, look at the macro definition.
1221             3. See if there's a local definition for the value; return it if so.
1222             4. See if we have any local constant definitions (our children, evaluated as values).
1223             5. Check our event context.
1224             6. If we're still not in luck, ask our parent to do the same.
1225             7. Otherwise, return "undefined". A set will then create a local variable if necessary.
1226            
1227             The closure returned by get_value_closure has the same signature as the varhandlers used by the value tag.
1228             So weird as it sounds, the key and value are in parameters 2 and 3.
1229            
1230             =cut
1231            
1232             sub get_value_closure {
1233 74     74 1 115 my ($self, $value) = @_;
1234 74 50       185 return $self->{h}->{$value} if exists $self->{h}->{$value};
1235 74         174 my $v = $self->{hashtie}->just_get($value);
1236 74 100       262 return $v if ref $v eq 'CODE';
1237             return sub {
1238 74 100   74   212 $self->{hashtie}->just_store($value, $_[3]) if defined $_[3];
1239 74         197 $self->{hashtie}->just_get($value);
1240             }
1241 31         163 }
1242            
1243             sub find_value {
1244 95     95 1 139 my ($self, $value) = @_;
1245            
1246             #print STDERR "find_value! $self\n";
1247 95 100       258 return $self->{h}->{$value} if exists $self->{h}->{$value};
1248             #print STDERR "0\n";
1249 91 100       334 return $self->get_value_closure($value) if exists $self->{v}->{$value};
1250             #print STDERR "1\n";
1251            
1252 17         42 my $target = $self;
1253 17 50       54 $target = $self->{instantiates} if $self->{instantiates}; # TODO: maybe. Consider a "context" keyword or sigil or something.
1254            
1255             #print STDERR "target is actually $target\n";
1256 17 50       64 if (exists $target->{h}->{$value}) {
1257             #print STDERR "There is a target handler\n";
1258 0         0 $self->{h}->{$value} = $target->{h}->{$value};
1259 0         0 return $self->{v}->{$value};
1260             }
1261 17 50       61 if (exists $target->{v}->{$value}) {
1262             #print STDERR "local pointer " . $target->{v}->{$value} . " found\n";
1263 0         0 $self->{hashtie}->just_store($value, $target->get_value_closure($value));
1264 0         0 return $self->{hashtie}->just_get($value);
1265             }
1266            
1267 17         65 foreach my $child ($target->nodes) {
1268 4 50 33     12 if ($child->is($value) or $child->name eq $value) {
1269 0 0       0 if ($child->label) {
1270             #print STDERR "local child " . $child->describe . " found\n";
1271 0     0   0 $self->{hashtie}->just_store ($value, sub { $child->label });
  0         0  
1272 0         0 return $self->{hashtie}->just_get ($value);
1273             }
1274 0 0       0 if ($child->describe_content) {
1275             #print STDERR "local child " . $child->describe . " found\n";
1276 0     0   0 $self->{hashtie}->just_store ($value, sub { $child->describe_content });
  0         0  
1277 0         0 return $self->{hashtie}->just_get ($value);
1278             }
1279 0         0 last;
1280             }
1281             }
1282            
1283 17 100       57 unless ($target->event_context == $target) {
1284             #print STDERR "We have an event context\n";
1285 13         41 my $cx = $target->event_context;
1286 13 50       61 if (exists $cx->{h}->{$value}) {
1287             #print STDERR "There is a target handler in the cx\n";
1288 0         0 $self->{h}->{$value} = $cx->{h}->{$value};
1289 0         0 return $self->{h}->{$value};
1290             }
1291             #print STDERR "Looking in event context $cx\n";
1292 13         74 my $context_value = $cx->find_value($value);
1293             #print STDERR "3\n";
1294 13 100       45 if (defined $context_value) {
1295             #print STDERR "context value $context_value found\n";
1296 12         42 $self->{hashtie}->just_store ($value, $context_value);
1297 12         36 return $context_value;
1298             }
1299             #print STDERR "Was not defined in event context $cx\n";
1300             }
1301            
1302             #print STDERR "Looking in parent\n";
1303 5 100       17 return $self->parent->find_value($value) if $self->parent;
1304             #print STDERR "Returning undef\n";
1305 4         13 return undef;
1306             }
1307            
1308            
1309             =head2 value($var), setvalue($var, $value)
1310            
1311             Accesses the global application value named.
1312            
1313             =cut
1314            
1315 12     12 1 107 sub value { $_[0]->{v}->{$_[1]} }
1316             #sub setvalue { $_[0]->{v}->{$_[1]} = $_[2]; }
1317             sub setvalue {
1318 29     29 1 61 my ($self, $value, $newvalue) = @_;
1319 29 50       90 return if $value =~ /^\*/; # Set has no effect on *-values.
1320 29         110 my $var = $self->find_value($value);
1321 29 100       179 return $var->($self, $self->{v}, $value, $newvalue) if defined $var;
1322 1         6 $self->{hashtie}->just_store($value, $newvalue);
1323             }
1324            
1325             =head2 get_value($var)
1326            
1327             Given the name of a value, we can find it in various places, which we look at in order:
1328            
1329             - A set value in the node asked
1330             - Rinse and repeat for the node's parent.
1331            
1332             Names starting with an asterisk find parts of the node itself: *name, *label, *parameter ,
1333             *option , *content, and anything else I forgot and add later. A double asterisk gets the same values
1334             from the parent. Triple asterisk, grandparent, etc.
1335            
1336             =cut
1337            
1338             sub get_value {
1339 52     52 1 115 my ($self, $value) = @_;
1340            
1341 52 50       133 if ($value =~ /^\*/) {
1342 0         0 $value =~ s/^\* *//;
1343 0 0       0 return $self->parent->get_value ($value) if $value =~ /^\*/;
1344 0 0       0 return $self->name if $value eq 'name';
1345 0 0       0 return $self->label if $value eq 'label';
1346 0 0       0 return $self->describe_content('', 0) if $value eq 'content';
1347 0         0 return undef;
1348             }
1349            
1350 52         128 my $var = $self->find_value($value);
1351 52 100       178 return if not defined $var;
1352 50         264 $var->($self, $self->{v}, $value);
1353             }
1354            
1355             =head2 express_value($valuespec)
1356            
1357             A full value spec pipes a given value through a series of filters:
1358            
1359             [|]*
1360            
1361             A filter is simply a function that takes one parameter. (This is an oversimplification: the filter can be given parameters that are space-delimited.)
1362            
1363             If no lookup value is desired as a starting value, you can also just start the pipe with a filter/function call. marked with an exclamation mark:
1364            
1365             ![|]*
1366            
1367             Clear? Clear.
1368            
1369             =cut
1370            
1371             sub express_value {
1372 0     0 1 0 my ($self, $valspec) = @_;
1373 0         0 my @pieces = split /\|/, $valspec; # TODO: a real parser to permit pipe characters within strings.
1374 0         0 my $value = '';
1375 0 0       0 if ($pieces[0] =~ /^!/) {
1376 0         0 $pieces[0] =~ s/^! *//;
1377             } else {
1378 0         0 $value = $self->get_value(shift @pieces);
1379             }
1380 0         0 while (my $filter = shift @pieces) {
1381 0         0 $filter =~ s/^\s*//;
1382 0         0 $filter =~ s/\s*$//;
1383 0         0 my @words = parse_line ('\s+', 0, $filter);
1384 0         0 my $filter = shift @words;
1385 0         0 $value = $self->call_filter($filter, $value, @words);
1386             }
1387 0         0 $value;
1388             }
1389            
1390            
1391             =head2 register_varhandler ($event, $handler)
1392            
1393             Registers a variable handler in the event context. If there is a handler registered for a name, it will be called instead of the normal
1394             hash read and write. This means you can attach active content to a variable, then treat it just like any other variable in your code.
1395            
1396             =cut
1397            
1398             sub register_varhandler {
1399 4     4 1 12 my ($self, $key, $handler) = @_;
1400 4         23 $self->{h}->{$key} = $handler;
1401             }
1402            
1403            
1404             =head2 subs()
1405            
1406             Returns all our direct children named 'sub', plus the same thing from our parent. Our answers mask our parent's.
1407            
1408             =cut
1409            
1410             sub subs {
1411 40     40 1 70 my $self = shift;
1412 40 100       103 my $subs = $self->parent ? $self->parent()->subs() : {};
1413 40         163 foreach ($self->nodes()) {
1414 80 100       189 next unless $_->tag() eq 'sub';
1415 2         29 $_->build();
1416 2         13 $subs->{$_->name} = $_;
1417             }
1418 40         133 return $subs;
1419             }
1420            
1421             =head2 find_filter(filter), call_filter(filter, value)
1422            
1423             Finds a filter by name from a given point in the tree and calls it with a set of parameters.
1424            
1425             =cut
1426            
1427             sub find_filter {
1428 0     0 1   my ($self, $filter) = @_;
1429            
1430 0 0         $self = $self->{instantiates} if $self->{instantiates}; # TODO: I think this is probably correct.
1431 0           foreach ($self->nodes()) {
1432 0 0 0       return $_ if $_->is("sub|filter") and $_->name eq $filter;
1433             }
1434 0 0         return $self->parent->find_filter($filter) if $self->parent;
1435 0           $filter = Decl->register_filter($filter);
1436 0           return $filter;
1437             }
1438            
1439             sub call_filter {
1440 0     0 1   my $self = shift;
1441 0           my $filter = shift;
1442 0           my $value = shift;
1443            
1444 0           $filter = $self->find_filter($filter);
1445 0 0         if (not defined $filter) {
1446             # TODO: warning
1447 0           return $value;
1448             }
1449 0 0         if (ref $filter eq 'CODE') {
1450 0           return &$filter ($value, @_);
1451             }
1452 0           $filter->go(undef, $value, @_);
1453             }
1454            
1455             #=head2 AUTOLOAD
1456             #
1457             #If a call is made against a node with a payload, the node will try to proxy the payload object's methods using AUTOLOAD.
1458             #
1459             #TODO: some kind of dot notation to permit this to work with inner nodes.
1460             #
1461             #=cut
1462             #
1463             #sub AUTOLOAD {
1464             # my ($self) = @_;
1465             # croak "No method $AUTOLOAD" unless $self->payload and ref($self->payload);
1466             #
1467             # my $name = our $AUTOLOAD;
1468             # $name =~ s/.*://;
1469             # return "No method $AUTOLOAD" unless $self->payload->can($name);
1470             #
1471             # *$AUTOLOAD = eval "sub { my \$self = shift; \$self->payload->$name (\@_) }";
1472             # goto &$AUTOLOAD;
1473             #}
1474            
1475            
1476             =head1 OUTPUT
1477            
1478             =head2 write(), log(), output()
1479            
1480             The C function is supported for any node; by default it simply passes its arguments up to its parent. The top of the tree will print everything
1481             to STDOUT - by default. At any point in the tree, though, a node may claim ownership of the output stream by having an option [output]; any C
1482             called below that node's parent will be written to that node's C. Obviously, this is a good way to use files.
1483            
1484             The C function is exactly the same, except the default is to write to STDERR and the option to use is [log].
1485            
1486             There is another difference: a file used as [output] will by default start from scratch ('w'), while a file used as [log] will append its material ('a').
1487             Either is opened during build, and closed when the program closes.
1488            
1489             If it's not in [output] or [log] mode, however, each call to C on a file is independent; the file is closed afterwards and no handle is kept around.
1490             This can be overridden with a (keepopen) parameter or a (>>) parameter for appending. (Any appending file will be opened for appending during build and
1491             closed when the program closes.)
1492            
1493             If a file is in keepopen mode, the buffers are flushed after each C/C.
1494            
1495             The C function defaults to C. For a macro definition, though, it is used to build the macro to be instantiated.
1496            
1497             =cut
1498            
1499             sub output {
1500 0     0 1   my $self = shift;
1501 0           $self->write(@_);
1502             }
1503            
1504             sub write {
1505 0     0 1   my $self = shift;
1506 0           $self->parent->write(@_);
1507             }
1508             sub log {
1509 0     0 1   my $self = shift;
1510 0           $self->parent->log(@_);
1511             }
1512            
1513             =head1 AUTHOR
1514            
1515             Michael Roberts, C<< >>
1516            
1517             =head1 BUGS
1518            
1519             Please report any bugs or feature requests to C, or through
1520             the web interface at L. I will be notified, and then you'll
1521             automatically be notified of progress on your bug as I make changes.
1522            
1523             =head1 LICENSE AND COPYRIGHT
1524            
1525             Copyright 2010 Michael Roberts.
1526            
1527             This program is free software; you can redistribute it and/or modify it
1528             under the terms of either: the GNU General Public License as published
1529             by the Free Software Foundation; or the Artistic License.
1530            
1531             See http://dev.perl.org/licenses/ for more information.
1532            
1533             =cut
1534            
1535             1; # End of Decl::Node