--- loncom/homework/math_parser/ENode.pm 2015/06/29 15:42:13 1.1 +++ loncom/homework/math_parser/ENode.pm 2017/01/27 20:24:26 1.5 @@ -26,7 +26,7 @@ use strict; use warnings; use utf8; -use feature "switch"; # Perl 5.10.1 +use Switch 'Perl6'; use aliased 'Apache::math_parser::CalcException'; use aliased 'Apache::math_parser::Operator'; @@ -50,13 +50,16 @@ use enum qw(NOT_AN_INTERVAL OPEN_OPEN OP # @param {interval_type} - The interval type, NOT_AN_INTERVAL | OPEN_OPEN | OPEN_CLOSED | CLOSED_OPEN | CLOSED_CLOSED ## sub new { - my $class = shift; + my ($class, $type, $op, $value, $children, $interval_type) = @_; + if (!defined $interval_type) { + $interval_type = NOT_AN_INTERVAL; + } my $self = { - _type => shift, - _op => shift, - _value => shift, - _children => shift, - _interval_type => shift // NOT_AN_INTERVAL, + _type => $type, + _op => $op, + _value => $value, + _children => $children, + _interval_type => $interval_type, }; bless $self, $class; return $self; @@ -307,15 +310,15 @@ sub calc { die CalcException->new("Missing parameter for function [_1].", $fname); } my ($q1, $q2); - if ($fname ~~ ['pow', 'sqrt', 'abs', 'exp', 'ln', 'log', 'log10', 'factorial', + if (string_in_array(['pow', 'sqrt', 'abs', 'exp', 'ln', 'log', 'log10', 'factorial', 'mod', 'sgn', 'ceil', 'floor', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', - 'atan2', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh']) { + 'atan2', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh'], $fname)) { $q1 = $children[1]->calc($env); if (!$q1->isa(Quantity)) { die CalcException->new("The [_1] function is not implemented for this type.", $fname); } } - if ($fname ~~ ['pow', 'mod', 'atan2']) { + if (string_in_array(['pow', 'mod', 'atan2'], $fname)) { if (!defined $children[2]) { die CalcException->new("Missing parameter for function [_1].", $fname); } @@ -634,7 +637,7 @@ sub toTeX { "Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi", "Omega", ); - if ($name ~~ @greek) { + if (string_in_array(\@greek, $name)) { return('\\'.$name); } elsif ($name eq "hbar") { return("\\hbar"); @@ -743,7 +746,12 @@ sub toTeX { } } when ("!") { - return($c0->toTeX()." !"); + my $s = $c0->toTeX(); + if ($c0->type == OPERATOR) { + $s = "(".$s.")"; + } + $s .= " !"; + return $s; } when ("%") { return($c0->toTeX()." \\% ".$c1->toTeX()); @@ -802,6 +810,14 @@ sub toTeX { when ("sqrt") { return "\\sqrt{".$c1->toTeX()."}"; } when ("abs") { return "|".$c1->toTeX()."|"; } when ("exp") { return "\\mathrm{e}^{".$c1->toTeX()."}"; } + when ("factorial") { + my $s = $c1->toTeX(); + if ($c1->type == OPERATOR) { + $s = "(".$s.")"; + } + $s .= " !"; + return $s; + } when ("diff") { if (scalar(@children) == 3) { return "\\frac{d}{d".$c2->toTeX()."} ".$c1->toTeX(); @@ -833,9 +849,14 @@ sub toTeX { return "\\lim_{".$c2->toTeX()." \\to ".$c3->toTeX(). "}".$c1->toTeX(); } else { - return "\\lim_{".$c2->toTeX()." \\to ".$c3->toTeX(). - (($c4->value eq "plus") ? "+" : "-"). - "}".$c1->toTeX(); + my $s = "\\lim_{".$c2->toTeX()." \\to ".$c3->toTeX(); + if ($c4->value eq "plus") { + $s .= "+"; + } elsif ($c4->value eq "minus") { + $s .= "-"; + } + $s .= "}".$c1->toTeX(); + return $s; } } when ("binomial") { @@ -1002,5 +1023,21 @@ sub createVectorOrMatrix { } } +## +# Tests if a string is in an array (using eq) (to avoid using $value ~~ @array) +# @param {Array} array - reference to the array of strings +# @param {string} value - the string to look for +# @returns 1 if found, 0 otherwise +## +sub string_in_array { + my ($array, $value) = @_; + foreach my $v (@{$array}) { + if ($v eq $value) { + return 1; + } + } + return 0; +} + 1; __END__