File Coverage

blib/lib/Math/Expr/Node.pm
Criterion Covered Total %
statement 60 65 92.3
branch 25 38 65.7
condition n/a
subroutine 15 15 100.0
pod 0 10 0.0
total 100 128 78.1


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             # Node.pm - A node in the expretion tree
4             # (c) Copyright 1998 Hakan Ardo
5             #
6             # This program is free software; you can redistribute it and/or modify
7             # it under the terms of the GNU General Public License as published by
8             # the Free Software Foundation; either version 2 of the License, or
9             # any later version.
10             #
11             # This program is distributed in the hope that it will be useful,
12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14             # GNU General Public License for more details.
15             #
16             # You should have received a copy of the GNU General Public License
17             # along with this program; if not, write to the Free Software
18             # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19              
20              
21             =head1 NAME
22              
23             Math::Expr::Num - A node in the expretion tree, used as superclass only
24              
25             =head1 SYNOPSIS
26              
27             package Math::Expr::Num;
28             require Math::Expr::Node;
29              
30             use Math::Expr::Node;
31             use vars qw(@ISA);
32             @ISA = qw(Math::Expr::Node);
33              
34              
35             =head1 DESCRIPTION
36              
37             Each expretion is represented by a tree where each opperation and variable
38             is a separate node. This class contain the common code for all those noeds.
39              
40             It also defines all the common methods used in those node classes and does
41             some typecheckinig for them. Therefor the methodname in the subclasses
42             should start with a '_'-char followed by the actually method name. This
43             method will be called by the acutall method in this class after the
44             typecheking is done.
45              
46             =cut
47              
48             package Math::Expr::Node;
49 1     1   5 use strict;
  1         2  
  1         942  
50              
51             # Type checking and result caching
52              
53             sub Subs{
54 178     178 0 347 my ($self, $vars) = @_;
55 178 50       644 $vars->isa("Math::Expr::VarSet")|| warn("Bad param vars: $vars");
56 178         473 $self->_Subs($vars);
57             }
58              
59 653     653 0 1685 sub Breakable{shift->_Breakable(@_)}
60 60     60 0 193 sub toMathML{shift->_toMathML}
61              
62             sub Set{
63 68     68 0 125 my ($self, $pos, $val) = @_;
64              
65 68 50       145 defined $pos || warn("Bad param pos: $pos");
66 68 50       265 $val->isa("Math::Expr::Node") || warn("Bad param val: $val");
67 68 50       122 !$self->InTable || warn "Can't edit items in the table";
68            
69 68         226 $self->_Set($pos,$val);
70             }
71              
72             sub Match{
73 75     75 0 166 my ($self,$rule,$pos,$pre)= @_;
74 75         184 my $key=$rule->tostr.'§'.$pos;
75              
76 75 50       290 $rule->isa("Math::Expr::Node") || warn "Bad param rule: $rule";
77 75 100       167 if (ref $pre) {
    50          
78 67 50       193 $pre->isa("Math::Expr::VarSet") || warn "Bad param pre: $pre";
79 67         242 $key.='§'.$pre->tostr;
80             }
81             elsif(defined $pre) {
82 0         0 warn "Bad param pre: $pre";
83             }
84              
85              
86 75 50       253 if ($self->{'Matches'}{$key}) {return $self->{'Matches'}{$key};}
  0         0  
87 75         526 $self->{'Matches'}{$key}=$self->_Match($rule,$pos,$pre);
88 75         294 $self->{'Matches'}{$key};
89             }
90              
91             sub SubMatch{
92 75     75 0 191 my ($self, $rule, $mset) = @_;
93              
94 75 50       245 $rule->isa("Math::Expr::Node") || warn "Bad param rule: $rule";
95 75 50       213 $mset->isa("Math::Expr::MatchSet") || warn "Bad param mset: $mset";
96              
97 75         246 my $key=$rule->tostr.'§'.$mset->tostr;
98 75 50       257 if ($self->{'SubMatches'}{$key}) {return $self->{'SubMatches'}{$key};}
  0         0  
99 75         240 $self->{'SubMatches'}{$key}=$self->_SubMatch($rule,$mset);
100 75         280 $self->{'SubMatches'}{$key};
101             }
102              
103 217     217 0 594 sub Copy{shift->_Copy}
104              
105             # Default actions
106              
107 204     204 0 507 sub Simplify {shift->IntoTable;}
108              
109 23     23   94 sub _Subs {shift;}
110              
111 14     14   36 sub _Breakable{0;}
112              
113             sub _Set {
114 10     10   20 my ($self, $pos, $val)=@_;
115              
116 10 50       25 if ($pos ne "") {warn "Bad pos: $pos"}
  0         0  
117 10         33 $val;
118             }
119              
120             sub _Match {
121 38     38   58 my ($self, $rule,$pos,$pri) = @_;
122 38         113 my $mset=new Math::Expr::MatchSet;
123              
124 38 50       85 if (!defined $pri) {$pri=new Math::Expr::VarSet}
  0         0  
125              
126 38         106 $mset->Set($pos, $pri);
127 38 100       109 if (!$self->SubMatch($rule, $mset)) {
128 28         75 $mset->del($pos);
129             }
130 38         133 $mset;
131             }
132              
133             # Table handling
134             #use MLDBM;
135             #use Fcntl;
136             my %table;
137             #tie %table, 'MLDBM','testmldbm', O_CREAT|O_RDWR, 0640 or die $!;
138              
139             sub InTable {
140 1256     1256 0 1643 my $self=shift;
141 1256 100       2839 if (defined $self->{'TableKey'}) {return 1} else {return 0}
  632         1699  
  624         1715  
142             }
143              
144             sub IntoTable {
145 713     713 0 957 my $self=shift;
146              
147 713 100       1446 if ($self->InTable) {return $self;}
  408         1526  
148              
149 305         816 my $key=$self->tostr;
150 305 100       817 if (defined $table{$key}) {return $table{$key};}
  202         1065  
151            
152 103 100       412 if ($self->isa("Math::Expr::Opp")) {
153 93         327 for (my $i=0; $i<=$#{$self->{'Opps'}}; $i++) {
  267         721  
154 174         426 $self->{'Opps'}[$i]=$self->{'Opps'}[$i]->IntoTable;
155             }
156             }
157 103         211 $self->{'TableKey'}=$key;
158 103         252 $table{$key}=$self;
159              
160 103         811 $self;
161             }
162             1;