[system] / trunk / pg / lib / Parser / Complex.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/Parser/Complex.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5509 - (download) (as text) (annotate)
Sat Sep 15 00:56:51 2007 UTC (12 years, 2 months ago) by dpvc
File size: 2749 byte(s)
Formula objects and Context objects contain reference loops, which
prevent them from being freed properly by perl when they are no longer
needed.  This is a source of an important memory leak in WeBWorK.  The
problem has been fixed by using Scalar::Util::weaken for these
recursive references, so these objects can be freed properly when they
go out of scope.  This should cause an improvement in the memory usage
of the httpd child processes.

    1 #########################################################################
    2 #
    3 #  Implements the Complex class
    4 #
    5 package Parser::Complex;
    6 use strict;
    7 our @ISA = qw(Parser::Item);
    8 
    9 $Parser::class->{Complex} = 'Parser::Complex';
   10 
   11 sub new {
   12   my $self = shift; my $class = ref($self) || $self;
   13   my $equation = shift; my $context = $equation->{context};
   14   my $num; my ($value,$ref) = @_;
   15   $value = [$value,0] unless ref($value) eq 'ARRAY';
   16   $value->[1] = 0 unless defined($value->[1]);
   17   $equation->Error("Complex Numbers must have real and complex parts",$ref)
   18     if (scalar(@{$value}) != 2);
   19   $num = bless {
   20     value => $value, type => $Value::Type{complex}, isConstant => 1,
   21     ref => $ref, equation => $equation,
   22   }, $class;
   23   $num->weaken;
   24   my $z = $self->Package("Complex",$context)->make($context,@{$value});
   25   $num->{isOne}  = 1 if ($z cmp 1) == 0;
   26   $num->{isZero} = 1 if $z == 0;
   27   return $num;
   28 }
   29 
   30 #
   31 #  We know the answer to these, so no need to compute them.
   32 #
   33 sub isComplex {1}
   34 sub isNumber {1}
   35 sub isRealNumber {0}
   36 
   37 #
   38 #  Use Value.pm to evaluate these
   39 #
   40 sub eval {
   41   my $self = shift;
   42   return $self->Package("Complex")->make($self->context,@{$self->{value}});
   43 }
   44 
   45 #
   46 #  Factor out a common negative.
   47 #
   48 sub reduce {
   49   my $self = shift; my ($a,$b) = @{$self->{value}};
   50   my $context = $self->context; my $reduce = $context->{reduction};
   51   if ($reduce->{'-a-bi'} && $a <= 0 && $b <= 0 && ($a != 0 || $b != 0)) {
   52     $self->{value} = [-$a,-$b];
   53     $self = Parser::UOP::Neg($self);
   54     $self->{isOne} = 1 if $self->Package("Complex")->make($context,-$a,-$b) eq "1";
   55   }
   56   return $self;
   57 }
   58 
   59 $Parser::reduce->{'-a-bi'} = 1;
   60 
   61 #
   62 #  Use Value::Complex to format the number
   63 #  Add parens if the parent oparator has higher precedence
   64 #    than addition (and there IS an addition or subtraction).
   65 #
   66 sub string {
   67   my $self = shift; my $precedence = shift;
   68   my $context = $self->context; my $plus = $context->{operators}{'+'}{precedence};
   69   my $z = $self->Package("Complex")->make($context,@{$self->{value}})->string($self->{equation});
   70   $z = "(".$z.")" if defined($precedence) && $precedence > $plus && $z =~ m/[-+]/;
   71   return $z;
   72 }
   73 
   74 sub TeX {
   75   my $self = shift; my $precedence = shift;
   76   my $context = $self->context; my $plus = $context->{operators}{'+'}{precedence};
   77   my $z = $self->Package("Complex")->make($context,@{$self->{value}})->TeX($self->{equation});
   78   $z = '\left('.$z.'\right)' if defined($precedence) && $precedence > $plus && $z =~ m/[-+]/;
   79   return $z;
   80 }
   81 
   82 sub perl {
   83   my $self = shift; my $parens = shift;
   84   my $perl = $self->Package("Complex")->make($self->context,@{$self->{value}})->perl;
   85   $perl = '('.$perl.')' if $parens;
   86   return $perl;
   87 }
   88 
   89 #########################################################################
   90 
   91 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9