diff options
Diffstat (limited to 'Aufgabe6/RPN/lib')
| -rw-r--r-- | Aufgabe6/RPN/lib/RPN.pm | 364 |
1 files changed, 361 insertions, 3 deletions
diff --git a/Aufgabe6/RPN/lib/RPN.pm b/Aufgabe6/RPN/lib/RPN.pm index 92f6f50..693ca51 100644 --- a/Aufgabe6/RPN/lib/RPN.pm +++ b/Aufgabe6/RPN/lib/RPN.pm @@ -2,6 +2,7 @@ package RPN; use strict; use warnings; +use Math::Trig; require Exporter; @@ -25,10 +26,367 @@ our $VERSION = '1.0'; # Preloaded methods go here. +my %operations = ( + "POP" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + pop @$stackRef; + } + ), + "DUP" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, @$stackRef[-1]); + } + ), + "PI" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 0) + { + return undef; + } + + push (@$stackRef, 4.0*atan2(1.0,1.0)); + } + ), + "++" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + @$stackRef[-1]++; + } + ), + "--" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + @$stackRef[-1]--; + } + ), + "ABS" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, abs pop (@$stackRef)); + } + ), + "COS" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, cos pop (@$stackRef)); + } + ), + "EXP" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, exp pop (@$stackRef)); + } + ), + "INT" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, int pop (@$stackRef)); + } + ), + "LOG" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, log pop (@$stackRef)); + } + ), + "ROUND" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, sprintf ("%.0f", pop (@$stackRef))); + } + ), + "SIN" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, sin pop (@$stackRef)); + } + ), + "SQRT" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, sqrt pop (@$stackRef)); + } + ), + "TAN" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 1) + { + return undef; + } + + push (@$stackRef, tan pop (@$stackRef)); + } + ), + "%" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 % $var2); + } + ), + "*" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 * $var2); + } + ), + "+" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 + $var2); + } + ), + "-" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 - $var2); + } + ), + "/" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 / $var2); + } + ), + "ATAN2" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, atan2 $var1, $var2); + } + ), + "EXCH" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + push (@$stackRef, (pop (@$stackRef), pop (@$stackRef))); + } + ), + "MAX" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 > $var2 ? $var1 : $var2); + } + ), + "MIN" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 < $var2 ? $var1 : $var2); + } + ), + "POW" => ( + sub { + my ($stackRef) = @_; + + if (scalar @{$stackRef} < 2) + { + return undef; + } + + my $var2 = pop (@$stackRef); + my $var1 = pop (@$stackRef); + + push (@$stackRef, $var1 ** $var2); + } + ) +); + sub rpn { - my ( $par1 ) = @_; - print "Modul RPN Funktion 'rpn'\n"; - return $par1; + my ( $RpnString ) = @_; + + # Check if RPN String is supplied. + if(!defined $RpnString) + { + printf STDERR "RpnString needs to be supplied.\n"; + return undef; + } + + # RPN value stack + my @stack; + + for my $operand (split /\s+/, $RpnString) + { + if (defined $operations{$operand}) + { + if(!defined($operations{$operand}->(\@stack))) + { + return undef; + } + } + else + { + if ($operand =~ /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/) + { + push (@stack, $operand); + } + else + { + print STDERR "RpnString contains a value that is not numeric or an operand.\n"; + return undef; + } + } + } + + if (scalar @stack != 1) + { + print STDERR "After calculation there is not one value on stack.\n"; + return undef; + } + + return $stack[0]; } 1; |
