# 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;
card => 1, # degrees radians grades
coord => 0, # cartesian polar spherical
complex => 0, # real complex
- menushow => 6,
+ menushow => 12,
); # %set
my @menus = (
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)
'#' => '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
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
'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;
} # 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) = @_;
clear;
showmenu();
showstack();
-addstr($height+1, 0, "> ");
+addstr($height+1, 0, "> "); # prompt
while (1) {
addstr($height+1, 2, showval($val{i}, $set{base}));
} # 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;
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$/) {
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 {
}} # 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