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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5026 - (download) (as text) (annotate)
Sat Jun 23 20:08:07 2007 UTC (12 years, 8 months ago) by dpvc
File size: 4163 byte(s)
Make the Package method really be a method of the context rather than
the Value objects, and make the Value method call the context one.
This means it is not necessary to pass the context as a parameter any
longer.

    1 #########################################################################
    2 #
    3 #  Implements the basic parse tree node.  Subclasses of this class
    4 #  are things like binary operator, function call, and so on.
    5 #
    6 package Parser::Item;
    7 use strict;
    8 
    9 #
   10 #  Return the class name of an item
   11 #
   12 sub class {
   13   my $self = ref(shift);
   14   $self =~ s/[^:]*:://; $self =~ s/::.*//;
   15   return $self;
   16 }
   17 
   18 #
   19 #  Get the equation context
   20 #
   21 sub context {
   22   my $self = shift;
   23   return (ref($self) ? $self->{equation}{context} : Value->context);
   24 }
   25 
   26 #
   27 #  Get the package for a given Parser class
   28 #
   29 sub Item {
   30   my $self = shift; my $class = shift;
   31   my $context = (Value::isContext($_[0]) ? shift : $self->context);
   32   return $context->{parser}{$class} if defined $context->{parser}{$class};
   33   return "Parser::$class" if defined @{"Parser::${class}::ISA"};
   34   Value::Error("No such package 'Parser::%s'",$class);
   35 }
   36 
   37 #
   38 #  Same but for Value classes
   39 #
   40 sub Package {
   41   my $self = shift; my $class = shift;
   42   my $context = (Value::isContext($_[0]) ? shift : $self->context);
   43   $context->Package($class);
   44 }
   45 
   46 #
   47 #  Get various type information
   48 #
   49 sub type {my $self = shift; return $self->{type}{name}}
   50 sub typeRef {my $self = shift; return $self->{type}}
   51 sub length {my $self = shift; return $self->{type}{length}}
   52 sub entryType {
   53   my $self = shift; my $type = $self->{type};
   54   return $type->{list} ? $type->{entryType}: $type;
   55 }
   56 
   57 #
   58 #  True if two types agree
   59 #
   60 sub typeMatch {
   61   my ($ltype,$rtype) = @_;
   62   return 0 if ($ltype->{name} ne $rtype->{name});
   63   return 1 if (!$ltype->{list} && !$rtype->{list});
   64   return 0 if ($ltype->{list} != $rtype->{list});
   65   return 0 if ($ltype->{length} ne $rtype->{length});
   66   return typeMatch($ltype->{entryType},$rtype->{entryType});
   67 }
   68 
   69 #
   70 #  Check if an item is a number, complex, etc.
   71 #
   72 sub isRealNumber {my $self = shift; return $self->isNumber && !$self->isComplex}
   73 sub isNumber {my $self = shift; return ($self->typeRef->{name} eq 'Number')}
   74 sub isComplex {
   75   my $self = shift; my $type = $self->typeRef;
   76   return ($type->{name} eq 'Number' && $type->{length} == 2);
   77 }
   78 sub isNumOrInfinity {
   79   my $self = shift;
   80   return ($self->isRealNumber || $self->{isInfinite});
   81 }
   82 
   83 #
   84 #  Check if an item is a unary negation
   85 #
   86 sub isNeg {
   87   my $self = shift;
   88   return ($self->class eq 'UOP' && $self->{uop} eq 'u-' && !$self->{op}->{isInfinite});
   89 }
   90 
   91 #
   92 #  Check if an item can be in a union or is a set or reals
   93 #    (overridden in subclasses)
   94 #
   95 sub canBeInUnion {0}
   96 sub isSetOfReals {(shift)->type =~ m/^(Interval|Union|Set)$/}
   97 
   98 #
   99 #  Add parens to an expression (alternating the type of paren)
  100 #
  101 sub addParens {
  102   my $self = shift; my $string = shift;
  103   if ($string =~ m/^[^\[]*\(/) {return '['.$string.']'}
  104   return '('.$string.')';
  105 }
  106 
  107 #
  108 #  These are stubs for the subclasses
  109 #
  110 sub getVariables {{}}   #  find out what variables are used
  111 sub makeList {shift}    #  flatten a tree of commas into a list
  112 sub makeMatrix {}       #  convert a list to a matrix
  113 
  114 sub reduce {shift}
  115 sub substitute {shift}
  116 sub string {}
  117 sub TeX {}
  118 sub perl {}
  119 
  120 sub ijk {
  121   my $self = shift;
  122   $self->Error("Can't use method 'ijk' with objects of type '%s'",$self->type);
  123 }
  124 
  125 #
  126 #  Recursively copy an item, and set a new equation pointer, if any
  127 #
  128 sub copy {
  129   my $self = shift; my $equation = shift;
  130   my $new = {%{$self}};
  131   if (ref($self) ne 'HASH') {
  132     bless $new, ref($self);
  133     $new->{equation} = $equation if defined($equation);
  134     $new->{ref} = undef;
  135   }
  136   $new->{type} = copy($self->{type}) if defined($self->{type});
  137   return $new;
  138 }
  139 
  140 #
  141 #  Report an error message
  142 #
  143 sub Error {
  144   my $self = shift;
  145   my $message = shift; $message = [$message,@_] if scalar(@_) > 0;
  146   $self->{equation}->Error($message,$self->{ref}) if defined($self->{equation});
  147   Parser->Error($message);
  148 }
  149 
  150 #########################################################################
  151 #
  152 #  Load the subclasses.
  153 #
  154 
  155 END {
  156   use Parser::BOP;
  157   use Parser::UOP;
  158   use Parser::List;
  159   use Parser::Function;
  160   use Parser::Variable;
  161   use Parser::Constant;
  162   use Parser::Value;
  163   use Parser::Number;
  164   use Parser::Complex;
  165   use Parser::String;
  166 }
  167 
  168 #########################################################################
  169 
  170 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9