release 1.05
authorShiar <shiar@shiar.org>
Fri, 10 Sep 2004 22:39:27 +0000 (00:39 +0200)
committerShiar <shiar@shiar.org>
Thu, 10 Jul 2008 19:25:31 +0000 (21:25 +0200)
- hp48-like drop (backspace but not editing value)
- error on insufficient arguments for command
- command backspacing

sdc.pl

diff --git a/sdc.pl b/sdc.pl
index b91c2096146971967e9f9e31bc332883874d5b63..02ec1e36e0f6820d23d730815fd2e43fe739c6dc 100755 (executable)
--- a/sdc.pl
+++ b/sdc.pl
@@ -7,6 +7,7 @@
 # 06-18       - start
 # 06-25       -
 # 08-04 14:45 - error dialog (don't mess up screen)
+# 09-10 19:45 - hp48-like drop (bs); argument checking; command backspacing
 
 use strict;
 use warnings;
@@ -36,7 +37,7 @@ my %set = (
        card     =>  1,  # degrees radians grades
        coord    =>  0,  # cartesian polar spherical
        complex  =>  0,  # real complex
-       menushow =>  6,
+       menushow => 12,
 ); # %set
 
 my @menus = (
@@ -159,14 +160,15 @@ my %falias = (
 my %alias = (
        chr 4 => 'quit', # ^D
        chr 9 => 'more', # tab
-       '_' => 'chs', # change sign; 48: y
-       'e' => 'eex', # exponent; 48: z
+       '_'   => 'chs', # change sign; 48: y
+       'e'   => 'eex', # exponent; 48: z
 #      "\033\133\062\176" => 'swap', # ins
-       chr(27).chr(91).chr(51).chr(126) => 'clear', # del
+       "\033\133\063\176" => "clear", # del
        chr 127 => 'drop', # backspace
-       chr 8 => 'drop', # backspace
-       chr 13 => ' ', # enter
-       "\014" => 'refresh', # ^L
+       chr 8   => 'drop', # backspace
+       chr 13  => 'enter', # enter
+       ' '     => 'enter', # space
+       "\014"  => 'refresh', # ^L
 #      "\033\133\110" => 'refresh', # home
 
 #      "\033\133\101" => '', # up; 48: k (stack)
@@ -179,19 +181,19 @@ my %alias = (
        '#' => 'xor',
        '~' => 'not',
 
-               's' => 'sin',
-       chr(27).'s' => 'asin',
-               'c' => 'cos',
-       chr(27).'c' => 'acos',
-               't' => 'tan',
-       chr(27).'t' => 'atan',
-               'l' => 'log',
-       chr(27).'l' => 'alog',
-               'n' => 'ln',
-       chr(27).'n' => 'exp',
-               'q' => 'sq',
-       chr(27).'q' => 'sqrt',
-       chr(27).'^' => 'xroot',
+           "s" => 'sin',
+       "\033s" => 'asin',
+           "c" => 'cos',
+       "\033c" => 'acos',
+           "t" => 'tan',
+       "\033t" => 'atan',
+           "l" => 'log',
+       "\033l" => 'alog',
+           "n" => 'ln',
+       "\033n" => 'exp',
+           "q" => 'sq',
+       "\033q" => 'sqrt',
+       "\033^" => 'xroot',
 ); # %alias
 
 =cut
@@ -227,12 +229,12 @@ my %action = (
                        shift @stack;
                }
        }], # backspace
-       'clear'  => [0, sub {
+       'clear'=> [0, sub {
                #todo: if (val{i}) delete char after cursor
                @stack = (); %val = (i=>undef, frac=>0)
        }], # clear all
 
-       ' '    => [0, sub {
+       'enter'=> [0, sub {
                unshift @stack, $val{i};
                %val = (i=>undef, frac=>0);
        }], # duplication
@@ -299,7 +301,7 @@ my %action = (
        'bin'  => [0, sub {$set{base} = 2}], # binary
        'oct'  => [0, sub {$set{base} = 8}], # octal
        'hex'  => [0, sub {$set{base} = 16}], # hexadecimal
-       'base36' => [0, sub {$set{base} = 36}], # alphanumerical
+       'base' => [1, sub {$set{base} = shift @stack}], # alphanumerical
 ); # %action
 
 my %unit;
@@ -331,6 +333,17 @@ $unit{$_->[0]} = { name=>$_->[0], type=>$i, val=>$_->[1] } for map {$i++; @$_} (
 } # create unit table
 
 
+sub error($) {
+       attron(A_REVERSE);
+       addstr(0, 0, shift);
+       attroff(A_REVERSE);
+       clrtoeol;
+       refresh;
+
+       ReadKey; # wait for confirm
+       1 while defined (ReadKey -1); # clear key buffer
+} # error
+
 sub showval($$);
 sub showval($$) {
        my ($val, $base) = @_;
@@ -391,7 +404,7 @@ DRAW:
 clear;
 showmenu();
 showstack();
-addstr($height+1, 0, "> ");
+addstr($height+1, 0, "> ");  # prompt
 
 while (1) {
        addstr($height+1, 2, showval($val{i}, $set{base}));
@@ -407,10 +420,15 @@ while (1) {
                } # read additional keys
        } # escape sequence
 
-       exists $alias{$_}  and $_ = $alias{$_};
-       exists $falias{$_} and $_ = $menu[$falias{$_}];
+       exists $alias{$_}  and $_ = $alias{$_};  # command shortkeys
+       if (exists $falias{$_}) {
+               unless ($_ = $menu[$falias{$_}]) {
+                       error("* no such menu entry *");
+                       goto DRAW;
+               }
+       } # function key
 
-       $_ = delete $val{bla} if exists $val{bla} and $_ eq ' ';
+       $_ = delete $val{bla} if exists $val{bla} and $_ eq 'enter';
 
        if ($_ eq 'quit') {
                last;
@@ -419,19 +437,18 @@ while (1) {
                goto DRAW;
        } # refresh
 
-       elsif (/>(\d+)$/) {
-               @menu = @{ $menus[$1] };
-               $menumin = 0;
-               showmenu();
-       } # submenu
-
        elsif (exists $val{bla} or /^[A-Z]$/) {
                if (defined $val{i}) {
                        unshift @stack, $val{i};
                        %val = (i=>undef, frac=>0);
                        showstack();
-               }
-               $val{bla} .= lc $_;
+               } # enter present value
+               if ($_ eq "drop") {
+                       $val{bla} = substr $val{bla}, 0, -1;
+               } # backspace
+               else {
+                       $val{bla} .= lc $_;
+               } # add character
        } # manual command
 
        elsif (exists $action{$_} or /^\d$/) {
@@ -443,15 +460,26 @@ while (1) {
                        unshift @stack, $val{i};
                        %val = (i=>undef, frac=>0);
                } # auto enter
+               if ($type>0 and $type>@stack) {
+                       error("* insufficient stack arguments for operation *");
+                       goto DRAW;
+               } # insufficient arguments
                $cmd->();
                showstack() if $type>=0;
        } # some operation
 
+       elsif (/>(\d+)$/) {
+               @menu = @{ $menus[$1] };
+               $menumin = 0;
+               showmenu();
+       } # submenu
+
        elsif ($_ =~ /^_/) {{
                $_ = $unit{substr $_, 1} or next;
                if (exists $val{unit} and $val{unit}{type}==$_->{type}) {
-                       unshift @stack, $val{i} and showstack() if defined $val{i};
+                       unshift @stack, $val{i} if defined $val{i};
                        $stack[0] *= delete($val{unit})->{val} / $_->{val};
+                       showstack();
                        %val = (i=>undef, frac=>0);
                } # convert
                else {
@@ -460,14 +488,7 @@ while (1) {
        }} # conversion
 
        else {
-               attron(A_REVERSE);
-               addstr($height+1, 0, "* error: ".join(' ', map ord, split //, $_)." *");
-               attroff(A_REVERSE);
-               clrtoeol;
-               refresh;
-
-               ReadKey; # wait for confirm
-               1 while defined (ReadKey -1); # clear key buffer
+               error("* error: ".join(' ', map ord, split //, $_)." *");
                goto DRAW; # screen messed up
        } # error
 } # input loop