#!/usr/bin/perl # # This is SmiffyCalc 1.1b - 2008-09-17 # # Originally released as: # http://www.smiffysplace.com/smiffycalc # # Re-released with minor modifications for PerlMonks. # # This calculator is capable of doing anything to your # system that Perl is so should be used with care and # NEVER run as root. # use strict; use Math::Trig; use DB_File; # Rude Words(tm) regex - used to determine if the boss # is swearing at me. This means that we can vent our # frustration by closing the app with the command # '$rude_word off'. # # Words should be separated by a pipe | symbol: # # word1|word2|word3|etc # # A somewhat sanitised version of Smiffy's list is # presented for public consumption: my $rudewords='bugger|zark'; # State preservation file location: my $db=$ENV{HOME} . '/.smiffycalc.db'; # The %v hash needs to be tied to a db file so that # we can persist values of variables and parameters. my (%v,$in,$baddb); tie(%v,'DB_File',$db) or dberror(); # $v{init} is a flag that we write to the database # file to confirm that we have preserved previous # state. unless ($v{init}) { $v{dp}='8'; # default decimal places $v{init}=1; } # Welcome message. print "SmiffyCalc: Perl eval calculator - enter expression\nor help for more information.\n\n"; # And how was the boss last time? if ($v{leftas} eq 'pissy') { print "Hope you're in a better mood than last time, boss.\n\n"; undef $v{leftas}; } elsif ($v{leftas} eq 'cool') { print "How ya been, boss?\n\n"; undef $v{leftas}; } # # Main loop # while (1) { print "sc ($v{dp}dp): "; $in=; # Setting variables. if ($in=~m/^set\s/i) { doset(); next; } # Polite termination. elsif ($in=~m/^quit$|^exit$|^bye$|^goodbye$|^adios$|^auf wiedersehen$|^au revoir$/i) { $v{leftas}='cool'; last; } # Unpolite termination. elsif ($in=~m/[$rudewords]\s*off/i) { print "\nYeah, I love you too. Quitting \"as requested\". BASTARD!\n\007\007\007"; $v{leftas}='pissy'; last; } # We don't do loops. elsif ($in=~m/^last|^next|^for|^while/i) { print "Loop functions are not supported.\n"; next; } # Help, I'm lost! elsif ($in=~m/^help!*$|^hilfe!*$|^au secours!*$|^halp!*$|^\?+$/i) { dohelp(); next; } # Show a variable. elsif ($in=~m/^show\s/i) { doshow(); next; } # Clear a variable. elsif ($in=~m/^clear\s/i) { doclear(); next; } # Do as previous, assuming there was a previous. if ($in=~m/ditto/i) { if ($v{lasta}) { $in=~s/ditto/$v{lasta}/ig; } else { print "There was no previous argument.\n"; next; } } $v{lasta}=$in; # Substitute in the last result, if required. if ($in=~m/result/i) { if ($v{lastr}) { $in=~s/result/$v{lastr}/ig; } else { print "There was no previous argument.\n"; next; } } # Substitute and defined variables. for my $thisvar (keys %v) { $in=~s/\$$thisvar/$v{$thisvar}/g; } # Print out what we think we are going to evaluate. print "Eval: $in\n"; # Do the eval and print the result. $v{lastr}=eval($in); my $fmtstr='%0.' . $v{dp} . 'f'; my $res=sprintf($fmtstr,$v{lastr}); print "$res\n"; } # End of loop. # Dyslexics of the world untie! untie %v unless $baddb; exit; ############# # Hey, where's my preferences file? sub dberror { print "WARNING: Unable to open preferences file $db - cannot preserve\n"; print "state after this programme has been closed.\n\n"; $baddb=1; } # Help text - probably needs some work. sub dohelp { print<