#From preusche Tue Apr 30 14:54 MET 1996
#Date: Tue, 30 Apr 1996 14:54:21 +0200

#!/usr/local/bin/perl 
#
# Oliver's erstes Perl-Programm: ein (gar nicht so dummer) Taschenrechner.
# 02/1996


$last=0;
for ($i=0; ; $i= ($i+1)%10)
{   print "#",$i,"= ";
    $input = <STDIN>;
    last if $input eq "";

    chop $input;

    # Replacement: implements own Syntax

    if ($input eq "")
    {   print "\t\t\t\t\t--> #", $i, '= ', $val[$i], "\n";
        next;
    }



    {   $input =~ s/^\s*["](.*)["]\s*$/'$1'/g;      # convert to single quote
        $input =~ s/!(\d)/(eval(\$prog\[$1\]))/g;   # evaluate Registers.
        $input =~ s/!!!/(eval(\$lllastprog))/g; # evaluate last last last d.P.
        $input =~ s/!!/(eval(\$llastprog))/g;   # evaluate last last defined P.
        $input =~ s/!/(eval(\$lastprog))/g; # evaluate last defined Program.
        $input =~ s/#(\d)/(\$val\[$1\])/g;  # Registers r<x>
        $input =~ s/####/\$llllast /g;      # Before Before Before Last result
        $input =~ s/###/\$lllast /g;        # Before Before Last result
        $input =~ s/##/\$llast /g;          # Before Last result
        $input =~ s/#/\$last /g;            # Last result
        $input =~ s/pi/(4*atan2(1,1))/gi;   # Pi
        $input =~ s/E/(exp(1))/g;           # e
        $input =~ s/\^/**/g;                # Exponent
#        print $input, "\n";
    }

    # now check for special cases

    if ($input =~ /^\s*(\?|[hH](elp|ELP)?)\s*$/)
    {   $i--;
        print <<"blabla";
        Hilfe: Dies ist ein einfacher Taschenrechner in Perl.
        Alte Werte werden in Registern abgespeichert, "#0" bis "#9".
        Man kann auch Zeichenketten eingeben: in "'...'"- Anführungsstrichen
        Zeichenketten kann man mit "!0" bis "!9" ausrechnen->Programm/Macros.
        Letzte ausgerechnete Zahl: #, vorletzte ##, vorvorletzte ###, und ###
        Letztes definierte Program !, vorletztes !!, vorvorlestes !!!.
        Beispiel: "'#+##'" eingeben, dann "0", dann "1" und ab da dauernd "!"
                    (Fibonacci-Zahlen). Fixpunktberechnung ebenso einfach.
        Pi: 3.14...
        E: 2.718...
        hex(...): hex->dez   oct(...): oct->dez  sprintf("%x",...) ->hex
        C-Style Syntax.
        14 Stellen Genauigkeit.
        Perl-Programmierbar: "$otto=77; $otto^2" geht z.B. ($xxx:Perl-Variable).
            Oder "for ($j=1; $j<5; $j++) {print $j;}"!!
            Bitte nicht $i, $val, $last oder $input als Variablen verwenden!
blabla
    }
    elsif ($input =~ m/^\s*'(.*)'\s*$/)         # treat macro-definition
    {   $prog[$i]= $1;
        $lllastprog=$llastprog;                 # take care of old definitions
         $llastprog= $lastprog;
          $lastprog=     $prog[$i];
        print "\t\t\t\t\t--> !", $i, '= ', $prog[$i], "\n";
        print "\t\t\t\t\t--> #", $i, '= ', $val[$i], "\n";
    }
    else
    {   $val[$i] = eval ($input . ";");
#        print "Fehler: $@" if $@ ne "";
        if ($@ eq "")
        {   $lllllast=$llllast;
             $llllast= $lllast;
              $lllast=  $llast;
               $llast=   $last;
                $last=$val[$i];
        }
        else 
        {   print "\t\t\t\t\t--> ERROR; no change\n";
        }
        print "\t\t\t\t\t--> #", $i, '= ', $val[$i], "\n";
    }
}
print "Thank you!\n"