| … | |
… | |
| 56 | push(@{$tokens},['op',$5,$p0,$p1,$space]) if (defined($5)); |
56 | push(@{$tokens},['op',$5,$p0,$p1,$space]) if (defined($5)); |
| 57 | push(@{$tokens},['open',$6,$p0,$p1,$space]) if (defined($6)); |
57 | push(@{$tokens},['open',$6,$p0,$p1,$space]) if (defined($6)); |
| 58 | push(@{$tokens},['close',$7,$p0,$p1,$space]) if (defined($7)); |
58 | push(@{$tokens},['close',$7,$p0,$p1,$space]) if (defined($7)); |
| 59 | push(@{$tokens},['var',$8,$p0,$p1,$space]) if (defined($8)); |
59 | push(@{$tokens},['var',$8,$p0,$p1,$space]) if (defined($8)); |
| 60 | } else { |
60 | } else { |
| 61 | push(@{$tokens},['error',substr($string,$p0,3),$p0]); |
61 | push(@{$tokens},['error',substr($string,$p0,1),$p0,$p0+1]); |
| 62 | $self->{error} = 1; |
62 | $self->{error} = 1; |
| 63 | last; |
63 | last; |
| 64 | } |
64 | } |
| 65 | $space = ($string =~ m/\G\s+/gc); |
65 | $space = ($string =~ m/\G\s+/gc); |
| 66 | } |
66 | } |
| … | |
… | |
| 89 | /num/ and do {$self->Num($ref->[1]); last}; |
89 | /num/ and do {$self->Num($ref->[1]); last}; |
| 90 | /const/ and do {$self->Const($ref->[1]); last}; |
90 | /const/ and do {$self->Const($ref->[1]); last}; |
| 91 | /var/ and do {$self->Var($ref->[1]); last}; |
91 | /var/ and do {$self->Var($ref->[1]); last}; |
| 92 | /fn/ and do {$self->Fn($ref->[1]); last}; |
92 | /fn/ and do {$self->Fn($ref->[1]); last}; |
| 93 | /str/ and do {$self->Str($ref->[1]); last}; |
93 | /str/ and do {$self->Str($ref->[1]); last}; |
| 94 | /error/ and do {$self->Error("Unexpected characters '$ref->[1]'",$ref); last}; |
94 | /error/ and do {$self->Error("Unexpected character '$ref->[1]'",$ref); last}; |
| 95 | } |
95 | } |
| 96 | return if ($self->{error}); |
96 | return if ($self->{error}); |
| 97 | } |
97 | } |
| 98 | $self->Close('start'); return if ($self->{error}); |
98 | $self->Close('start'); return if ($self->{error}); |
| 99 | $self->{tree} = $self->{stack}->[0]->{value}; |
99 | $self->{tree} = $self->{stack}->[0]->{value}; |
| … | |
… | |
| 644 | |
644 | |
| 645 | |
645 | |
| 646 | ################################################## |
646 | ################################################## |
| 647 | ################################################## |
647 | ################################################## |
| 648 | # |
648 | # |
|
|
649 | # Convert a student answer to a formula, with error trapping. |
|
|
650 | # If the result is undef, there was an error (message is in Context()->{error} object) |
|
|
651 | # |
|
|
652 | |
|
|
653 | sub Formula { |
|
|
654 | my $f = shift; |
|
|
655 | eval {Value::Formula->new($f)}; |
|
|
656 | } |
|
|
657 | |
|
|
658 | # |
|
|
659 | # Evaluate a formula, with error trapping. |
|
|
660 | # If the result is undef, there was an error (message is in Context()->{error} object) |
|
|
661 | # If the result was a real, make it a fuzzy one. |
|
|
662 | # |
|
|
663 | sub Evaluate { |
|
|
664 | my $f = shift; |
|
|
665 | return unless defined($f); |
|
|
666 | my $v = eval {$f->eval(@_)}; |
|
|
667 | $v = Value::Real->new($v) if defined($v) && $f->isRealNumber; |
|
|
668 | return $v; |
|
|
669 | } |
|
|
670 | |
|
|
671 | |
|
|
672 | ################################################## |
|
|
673 | ################################################## |
|
|
674 | # |
| 649 | # Produce a vector in ijk form |
675 | # Produce a vector in ijk form |
| 650 | # |
676 | # |
| 651 | sub ijk { |
677 | sub ijk { |
| 652 | my $self = shift; |
678 | my $self = shift; |
| 653 | $self->{tree}->ijk; |
679 | $self->{tree}->ijk; |
| … | |
… | |
| 664 | use Value::Formula; |
690 | use Value::Formula; |
| 665 | use Parser::Context; |
691 | use Parser::Context; |
| 666 | use Parser::Context::Default; |
692 | use Parser::Context::Default; |
| 667 | |
693 | |
| 668 | # use Parser::Differentiation; |
694 | # use Parser::Differentiation; |
|
|
695 | |
|
|
696 | ########################################################################### |
|
|
697 | |
|
|
698 | use vars qw($installed); |
|
|
699 | $Parser::installed = 1; |
| 669 | |
700 | |
| 670 | ########################################################################### |
701 | ########################################################################### |
| 671 | ########################################################################### |
702 | ########################################################################### |
| 672 | # |
703 | # |
| 673 | # To Do: |
704 | # To Do: |