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

Diff of /trunk/pg/lib/Parser.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2558 Revision 2609
1# handle sqrt(-1) and log of negatives (make complexes)
2# do division by zero and log of zero checks in compound functions
3# add context flags for various reduction checks
4# make context flag for reduction of constants
5# make reduce have reduce patterns as parameters
6# more reduce patterns
7# make operator strings customizable (reduce, and other places they are used)
8# add parens alternately as () and []?
9
10package Parser; 1package Parser;
11my $pkg = "Parser"; 2my $pkg = "Parser";
12 3
13use strict; 4use strict;
14#use Carp; 5#use Carp;
22sub new { 13sub new {
23 my $self = shift; my $class = ref($self) || $self; 14 my $self = shift; my $class = ref($self) || $self;
24 my $string = shift; 15 my $string = shift;
25 my $math = bless { 16 my $math = bless {
26 string => undef, 17 string => undef,
27 tokens => [], 18 tokens => [], tree => undef,
28 tree => undef,
29 variables => {}, values => {}, 19 variables => {}, values => {},
30 context => Parser::Context->current, 20 context => Parser::Context->current,
31 error => 0, errorPos => undef,
32 message => '',
33 }, $class; 21 }, $class;
34 if (ref($string) =~ m/^(Parser|Value::Formula)/) { 22 if (ref($string) =~ m/^(Parser|Value::Formula)/) {
35 my $tree = $string; $tree = $tree->{tree} if exists $tree->{tree}; 23 my $tree = $string; $tree = $tree->{tree} if exists $tree->{tree};
36 $math->{tree} = $tree->copy($math); 24 $math->{tree} = $tree->copy($math);
37 } elsif (ref($string) =~ m/^Value/) { 25 } elsif (ref($string) =~ m/^Value/) {
68 push(@{$tokens},['op',$5,$p0,$p1,$space]) if (defined($5)); 56 push(@{$tokens},['op',$5,$p0,$p1,$space]) if (defined($5));
69 push(@{$tokens},['open',$6,$p0,$p1,$space]) if (defined($6)); 57 push(@{$tokens},['open',$6,$p0,$p1,$space]) if (defined($6));
70 push(@{$tokens},['close',$7,$p0,$p1,$space]) if (defined($7)); 58 push(@{$tokens},['close',$7,$p0,$p1,$space]) if (defined($7));
71 push(@{$tokens},['var',$8,$p0,$p1,$space]) if (defined($8)); 59 push(@{$tokens},['var',$8,$p0,$p1,$space]) if (defined($8));
72 } else { 60 } else {
73 push(@{$tokens},['error',substr($string,$p0,3),$p0]); 61 push(@{$tokens},['error',substr($string,$p0,1),$p0,$p0+1]);
74 $self->{error} = 1; 62 $self->{error} = 1;
75 last; 63 last;
76 } 64 }
77 $space = ($string =~ m/\G\s+/gc); 65 $space = ($string =~ m/\G\s+/gc);
78 } 66 }
101 /num/ and do {$self->Num($ref->[1]); last}; 89 /num/ and do {$self->Num($ref->[1]); last};
102 /const/ and do {$self->Const($ref->[1]); last}; 90 /const/ and do {$self->Const($ref->[1]); last};
103 /var/ and do {$self->Var($ref->[1]); last}; 91 /var/ and do {$self->Var($ref->[1]); last};
104 /fn/ and do {$self->Fn($ref->[1]); last}; 92 /fn/ and do {$self->Fn($ref->[1]); last};
105 /str/ and do {$self->Str($ref->[1]); last}; 93 /str/ and do {$self->Str($ref->[1]); last};
106 /error/ and do {$self->Error("Unexpected characters '$ref->[1]'",$ref); last}; 94 /error/ and do {$self->Error("Unexpected character '$ref->[1]'",$ref); last};
107 } 95 }
108 return if ($self->{error}); 96 return if ($self->{error});
109 } 97 }
110 $self->Close('start'); return if ($self->{error}); 98 $self->Close('start'); return if ($self->{error});
111 $self->{tree} = $self->{stack}->[0]->{value}; 99 $self->{tree} = $self->{stack}->[0]->{value};
641 my $self = shift; my ($value,$type); 629 my $self = shift; my ($value,$type);
642 my $variables = $self->{context}{variables}; 630 my $variables = $self->{context}{variables};
643 $self->{values} = {@_}; 631 $self->{values} = {@_};
644 foreach my $x (keys %{$self->{values}}) { 632 foreach my $x (keys %{$self->{values}}) {
645 $self->Error("Undeclared variable '$x'") unless defined $variables->{$x}; 633 $self->Error("Undeclared variable '$x'") unless defined $variables->{$x};
646 $value = $self->{values}{$x}; 634 $value = Value::makeValue($self->{values}{$x});
647 $value = Value::Formula->new($value) unless
648 Value::matchNumber($value) || Value::isFormula($value) || Value::isValue($value);
649 if (Value::isFormula($value)) {$type = $value->typeRef} 635 if (Value::isFormula($value)) {$type = $value->typeRef}
650 else {($value,$type) = Value::getValueType($self,$value)} 636 else {($value,$type) = Value::getValueType($self,$value)}
651 $self->Error("Variable '$x' should be of type $variables->{$x}{type}{name}") 637 $self->Error("Variable '$x' should be of type $variables->{$x}{type}{name}")
652 unless Parser::Item::typeMatch($type,$variables->{$x}{type}); 638 unless Parser::Item::typeMatch($type,$variables->{$x}{type});
653 $self->{values}{$x} = $value; 639 $self->{values}{$x} = $value;
654 } 640 }
641}
642
643
644##################################################
645##################################################
646#
647# Convert a student answer to a formula, with error trapping.
648# If the result is undef, there was an error (message is in Context()->{error} object)
649#
650
651sub Formula {
652 my $f = shift;
653 eval {Value::Formula->new($f)};
654}
655
656#
657# Evaluate a formula, with error trapping.
658# If the result is undef, there was an error (message is in Context()->{error} object)
659# If the result was a real, make it a fuzzy one.
660#
661sub Evaluate {
662 my $f = shift;
663 return unless defined($f);
664 my $v = eval {$f->eval(@_)};
665 $v = Value::makeValue($v) if defined($v);
666 return $v;
667}
668
669
670##################################################
671##################################################
672#
673# Produce a vector in ijk form
674#
675sub ijk {
676 my $self = shift;
677 $self->{tree}->ijk;
655} 678}
656 679
657######################################################################### 680#########################################################################
658######################################################################### 681#########################################################################
659# 682#
662 685
663use Parser::Item; 686use Parser::Item;
664use Value; 687use Value;
665use Value::Formula; 688use Value::Formula;
666use Parser::Context; 689use Parser::Context;
690use Parser::Context::Default;
691
667# use Parser::Differentiation; 692# use Parser::Differentiation;
668 693
694###########################################################################
695
696use vars qw($installed);
697$Parser::installed = 1;
698
699###########################################################################
700###########################################################################
701#
702# To Do:
703#
704# handle sqrt(-1) and log of negatives (make complexes)
705# do division by zero and log of zero checks in compound functions
706# add context flags for various reduction checks
707# make context flag for reduction of constants
708# make reduce have reduce patterns as parameters
709# more reduce patterns
710# make operator strings customizable (reduce, and other places they are used)
711# add parens alternately as () and []?
712#
669######################################################################### 713#########################################################################
670 714
6711; 7151;
672 716

Legend:
Removed from v.2558  
changed lines
  Added in v.2609

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9