home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / perl / 8038 < prev    next >
Encoding:
Text File  |  1993-01-28  |  4.1 KB  |  228 lines

  1. Path: sparky!uunet!ferkel.ucsb.edu!taco!gatech!hubcap!ncrcae!ncrhub2!ncrgw2!psinntp!internet!sbi!zeuswtc!pivot!bet
  2. From: bet@sbi.com (Bennett Todd @ Salomon Brothers Inc., NY )
  3. Newsgroups: comp.lang.perl
  4. Subject: HP-style calculator in perl
  5. Message-ID: <837@pivot.sbi.com>
  6. Date: 27 Jan 93 21:49:28 GMT
  7. Sender: news@pivot.sbi.com
  8. Organization: Salomon Brothers, Inc.
  9. Lines: 216
  10. Nntp-Posting-Host: sandstorm
  11.  
  12.  
  13. I finally got tired of not having an HP-style termcap-based calculator
  14. around, so I wrote one in Perl. The implementation isn't especially pretty,
  15. but it seems to work fine [at least for me]. I couldn't get the ioctl call
  16. to work for finding out the baud rate (which termcap.pl wants for computing
  17. padding) so I just wired in 9600. Aside from that it pretty much worked
  18. right the first time:-).
  19.  
  20. This implements numeric entry, the arithmetic operators "+". "-", "*", "/",
  21. and "^" (y**x); ^L redraws the screen; "x" recalls the last-x register; "X"
  22. exchanges the x and y registers; and "q" quits. I think I have the tracking
  23. of last-x and stack push correctly reproducing the behavior of an HP
  24. calculator. I call this thing ``hp''.
  25.  
  26. Share and Enjoy!
  27.  
  28. -Bennett
  29. bet@sbi.com
  30.  
  31. #!/usr/local/bin/perl
  32. ($progname=$0) =~ s#.*/##;
  33. $term = $ENV{'TERM'} || 'ansi';
  34.  
  35.  
  36. require 'sys/ioctl.ph';
  37. #ioctl(STDIN,&TIOCGETP,$foo) || die "$progname: ioctl failed: $!\n";
  38. #($ispeed,$ospeed) = unpack('cc',$foo);
  39. ($ispeed,$ospeed) = (&B9600,&B9600);
  40.  
  41. require 'termcap.pl';
  42. &Tgetent($term);
  43.  
  44. sub clear {
  45.     print $TC{'cl'};
  46. }
  47.  
  48. sub clear_to_end_of_display {
  49.     print $TC{'cd'};
  50. }
  51.  
  52. sub clear_to_end_of_line {
  53.     print $TC{'ce'};
  54. }
  55.  
  56. sub tgoto {
  57.     ($col,$row) = @_;
  58.     print &Tgoto($TC{'cm'},$col,$row);
  59. }
  60.  
  61. sub term_init {
  62.     system("stty -echo raw");
  63. }
  64. sub term_restore {
  65.     system("stty echo -raw");
  66.     &tgoto(0,8);
  67. }
  68.  
  69. sub die_cleanly {
  70.     &term_restore;
  71.     exit(0);
  72. }
  73.  
  74. sub getch {
  75.     local($foo);
  76.     sysread(STDIN,$foo,1) || &die_cleanly;
  77.     $foo;
  78. }
  79.  
  80. $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = die_cleanly;
  81. &term_init;
  82. $| = 1;
  83.  
  84.  
  85. # Screen layout
  86. # These are rows for all the registers and such
  87.  
  88. %loc = (
  89.     't', 0,
  90.     'z', 1,
  91.     'y', 2,
  92.     'x', 3,
  93.     'lastx', 5,
  94.     'input', 7
  95. );
  96.  
  97. $lastx = $x = $y = $z = $t = 0;
  98.  
  99. sub refresh {
  100.     &tgoto(0,$loc{'t'});
  101.     printf("%12.2f", $t);&clear_to_end_of_line;
  102.     &tgoto(0,$loc{'z'});
  103.     printf("%12.2f", $z);&clear_to_end_of_line;
  104.     &tgoto(0,$loc{'y'});
  105.     printf("%12.2f", $y);&clear_to_end_of_line;
  106.     &tgoto(0,$loc{'x'});
  107.     printf("%12.2f", $x);&clear_to_end_of_line;
  108.     &tgoto(0,$loc{'lastx'});
  109.     printf("%12.2f", $lastx);&clear_to_end_of_line;
  110.     &tgoto(0,$loc{'input'});
  111. }
  112.  
  113. &clear;
  114. &refresh;
  115. $_ = &getch;
  116. $dopush = 0;
  117.  
  118. command: while (!/q/) {
  119.     /q/ && last command;
  120.     /\014/ && do {
  121.         &clear;
  122.         &refresh;
  123.         $_ = &getch;
  124.         next command;
  125.     };
  126.     /[0-9.]/ && do {
  127.         &pushstack if $dopush;
  128.         $x = &getnum;
  129.         $dopush = 1;
  130.         &refresh;
  131.         next command;
  132.     };
  133.     /[\r\n]/ && do {
  134.         &pushstack;
  135.         $dopush = 0;
  136.         &refresh;
  137.         $_ = &getch;
  138.         next command;
  139.     };
  140.     /\+/ && do {
  141.         $lastx = $x;
  142.         ($x,$y,$z) = ($x+$y,$z,$t);
  143.         $dopush = 1;
  144.         &refresh;
  145.         $_ = &getch;
  146.         next command;
  147.     };
  148.     /-/ && do {
  149.         $lastx = $x;
  150.         ($x,$y,$z) = ($y-$x,$z,$t);
  151.         $dopush = 1;
  152.         &refresh;
  153.         $_ = &getch;
  154.         next command;
  155.     };
  156.     /\*/ && do {
  157.         $lastx = $x;
  158.         ($x,$y,$z) = ($x*$y,$z,$t);
  159.         $dopush = 1;
  160.         &refresh;
  161.         $_ = &getch;
  162.         next command;
  163.     };
  164.     /\// && do {
  165.         $lastx = $x;
  166.         ($x,$y,$z) = ($y/$x,$z,$t);
  167.         $dopush = 1;
  168.         &refresh;
  169.         $_ = &getch;
  170.         next command;
  171.     };
  172.     /\^/ && do {
  173.         $lastx = $x;
  174.         ($x,$y,$z) = ($y**$x,$z,$t);
  175.         $dopush = 1;
  176.         &refresh;
  177.         $_ = &getch;
  178.         next command;
  179.     };
  180.     /x/ && do {
  181.         &pushstack if $dopush;
  182.         $x = $lastx;
  183.         $dopush = 1;
  184.         &refresh;
  185.         $_ = &getch;
  186.         next command;
  187.     };
  188.     /X/ && do {
  189.         $lastx = $x;
  190.         ($x,$y) = ($y,$x);
  191.         $dopush = 1;
  192.         &refresh;
  193.         $_ = &getch;
  194.         next command;
  195.     };
  196.     $_ = &getch;
  197. }
  198.  
  199. sub pushstack {
  200.     ($t,$z,$y) = ($z,$y,$x);
  201. }
  202.  
  203. sub getnum {
  204.     local($num) = $_;
  205.     print $num;
  206.     $_ = &getch;
  207.     digit: while (/[0-9.\008\127]/) {
  208.         /[0-9.]/ && do {
  209.             print $_;
  210.             $num .= $_;
  211.             $_ = &getch;
  212.             next digit;
  213.         };
  214.         /[\008\127]/ && do {
  215.             chop($num);
  216.             print "\008 \008";
  217.             $_ = &getch;
  218.             next digit;
  219.         };
  220.     }
  221.     &tgoto(0,$loc{'input'});
  222.     &clear_to_end_of_display;
  223.     $num+0;
  224. }
  225.             
  226.     
  227. &die_cleanly;
  228.