mirror of
https://codeberg.org/scip/rpnc.git
synced 2025-12-17 04:21:01 +01:00
fixed x, added checks, enhanced doc
This commit is contained in:
86
README.md
86
README.md
@@ -136,6 +136,31 @@ sub stack of before.
|
|||||||
Every operation which modifies the stack can be reversed by entering
|
Every operation which modifies the stack can be reversed by entering
|
||||||
the <kbd>u</kbd> command. There's only one level of undo and no redo.
|
the <kbd>u</kbd> command. There's only one level of undo and no redo.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
You can define functions anytime directly on the cli or in a file called
|
||||||
|
`~/.rpnc`. A function has a name (which must not collide with existing
|
||||||
|
functions and commands) and a body of commands.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
f res2vcc 1.22 R1 R2 + R2 / 1 + *
|
||||||
|
|
||||||
|
Which calculates:
|
||||||
|
|
||||||
|
(((R1 + R2) / R2) + 1) * 1.22 = ??
|
||||||
|
|
||||||
|
To use it later, just enter the variables into the stack followed by the
|
||||||
|
function name:
|
||||||
|
|
||||||
|
470
|
||||||
|
220
|
||||||
|
res2vcc
|
||||||
|
|
||||||
|
You can also put the function definition in the config file
|
||||||
|
`~/.rpnc`. Empty lines and lines beginning with `#` will be ignored.
|
||||||
|
|
||||||
|
|
||||||
## Using STDIN via a PIPE
|
## Using STDIN via a PIPE
|
||||||
|
|
||||||
If the commandline includes any operator, commands will be read from
|
If the commandline includes any operator, commands will be read from
|
||||||
@@ -150,18 +175,22 @@ Examples:
|
|||||||
|
|
||||||
Both commands will print 4 to STDOUT.
|
Both commands will print 4 to STDOUT.
|
||||||
|
|
||||||
|
|
||||||
## Complete list of all supported commands:
|
## Complete list of all supported commands:
|
||||||
|
|
||||||
* <kbd>c</kbd> clear stack
|
### Stack Management
|
||||||
|
|
||||||
* <kbd>s</kbd> show the stack
|
* <kbd>s</kbd> show the stack
|
||||||
* <kbd>d</kbd> toggle debugging (current setting: 0)
|
* <kbd>ss</kbd> show the whole stack
|
||||||
* <kbd>r</kbd> reverse the stack
|
* <kbd>sc</kbd> clear stack
|
||||||
* <kbd>R</kbd> rotate the stack
|
* <kbd>scx</kbd> clear last stack element
|
||||||
* <kbd>(</kbd> enter collect mode
|
* <kbd>sr</kbd> reverse the stack
|
||||||
* <kbd>)</kbd> leave collect mode
|
* <kbd>srt</kbd> rotate the stack
|
||||||
* <kbd>u</kbd> undo last operation
|
|
||||||
* <kbd>q</kbd> finish (<kbd>C-d</kbd> works as well)
|
## Configuration
|
||||||
* <kbd>?</kbd> print help
|
|
||||||
|
* <kbd>td</kbd> toggle debugging (-d)
|
||||||
|
* <kbd>ts</kbd> toggle display of the stack (-n)
|
||||||
|
|
||||||
## Supported mathematical operators:
|
## Supported mathematical operators:
|
||||||
|
|
||||||
@@ -171,10 +200,47 @@ Both commands will print 4 to STDOUT.
|
|||||||
* <kbd>*</kbd> multiply
|
* <kbd>*</kbd> multiply
|
||||||
* <kbd>^</kbd> expotentiate
|
* <kbd>^</kbd> expotentiate
|
||||||
* <kbd>%</kbd> percent
|
* <kbd>%</kbd> percent
|
||||||
|
* <kbd>%+</kbd> add percent
|
||||||
|
* <kbd>%-</kbd> substract percent
|
||||||
|
* <kbd>%d</kbd> percentual difference
|
||||||
* <kbd>&</kbd> bitwise AND
|
* <kbd>&</kbd> bitwise AND
|
||||||
* <kbd>|</kbd> bitwise OR
|
* <kbd>|</kbd> bitwise OR
|
||||||
* <kbd>x</kbd> bitwise XOR
|
* <kbd>x</kbd> bitwise XOR
|
||||||
* <kbd>V</kbd> pull root (2nd if stack==1)
|
* <kbd>m</kbd> median
|
||||||
|
* <kbd>a</kbd> average
|
||||||
|
* <kbd>v</kbd> pull root (2nd if stack==1)
|
||||||
|
* <kbd>(</kbd> enter collect mode
|
||||||
|
* <kbd>)</kbd> leave collect mode
|
||||||
|
|
||||||
|
## Register Commands
|
||||||
|
|
||||||
|
* <kbd>r</kbd> put element into register
|
||||||
|
* <kbd>rc</kbd> clear register
|
||||||
|
* <kbd>rcx</kbd> clear last register element
|
||||||
|
|
||||||
|
## Various Commands
|
||||||
|
|
||||||
|
* <kbd>u</kbd> undo last operation
|
||||||
|
* <kbd>q</kbd> finish (<kbd>C-d</kbd> works as well)
|
||||||
|
* <kbd>h</kbd> show history of past operations
|
||||||
|
* <kbd>?</kbd> print help
|
||||||
|
|
||||||
|
## Converters
|
||||||
|
|
||||||
|
* <kbd>tl</kbd> gallons to liters
|
||||||
|
* <kbd>tk</kbd> miles to kilometers
|
||||||
|
* <kbd>tm</kbd> yards to meters
|
||||||
|
* <kbd>tc</kbd> inches to centimeters
|
||||||
|
* <kbd>tkb</kbd> bytes to kilobytes
|
||||||
|
* <kbd>tmb</kbd> bytes to megabytes
|
||||||
|
* <kbd>tgb</kbd> bytes to gigabytes
|
||||||
|
* <kbd>ttb</kbd> bytes to terabytes
|
||||||
|
|
||||||
|
## Function Comands
|
||||||
|
|
||||||
|
* <kbd>f NAME CODE</kbd> define a functions (see ab above)
|
||||||
|
* <kbd>fs</kbd> show list of defined functions
|
||||||
|
|
||||||
|
|
||||||
## Copyleft
|
## Copyleft
|
||||||
|
|
||||||
|
|||||||
33
rpnc
33
rpnc
@@ -106,6 +106,7 @@ my %func = (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'%d' => sub {
|
'%d' => sub {
|
||||||
# percentual difference
|
# percentual difference
|
||||||
if (scalar @_ == 2) {
|
if (scalar @_ == 2) {
|
||||||
@@ -118,6 +119,7 @@ my %func = (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'%+' => sub {
|
'%+' => sub {
|
||||||
# Y + (X $ of Y)
|
# Y + (X $ of Y)
|
||||||
if (scalar @_ == 2) {
|
if (scalar @_ == 2) {
|
||||||
@@ -130,6 +132,7 @@ my %func = (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'%-' => sub {
|
'%-' => sub {
|
||||||
# Y - (X $ of Y)
|
# Y - (X $ of Y)
|
||||||
if (scalar @_ == 2) {
|
if (scalar @_ == 2) {
|
||||||
@@ -142,6 +145,7 @@ my %func = (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'v' => sub {
|
'v' => sub {
|
||||||
if (scalar @_ == 2) {
|
if (scalar @_ == 2) {
|
||||||
my ($a, $b) = @_;
|
my ($a, $b) = @_;
|
||||||
@@ -152,11 +156,13 @@ my %func = (
|
|||||||
return "$a ** (1 / 2)";
|
return "$a ** (1 / 2)";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'pr' => sub {
|
'pr' => sub {
|
||||||
# parallel resistance, maybe add ~/.rpncrc support
|
# parallel resistance, maybe add ~/.rpncrc support
|
||||||
# where to add such custom functions...
|
# where to add such custom functions...
|
||||||
return "1 / (" . join(' + ', map { "1 / $_"} @_) . ")";
|
return "1 / (" . join(' + ', map { "1 / $_"} @_) . ")";
|
||||||
},
|
},
|
||||||
|
|
||||||
'm' => sub {
|
'm' => sub {
|
||||||
# median
|
# median
|
||||||
if (scalar @_ >= 2) {
|
if (scalar @_ >= 2) {
|
||||||
@@ -175,10 +181,12 @@ my %func = (
|
|||||||
undo(); return 0;
|
undo(); return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'a' => sub {
|
'a' => sub {
|
||||||
# average
|
# average
|
||||||
return "(" . join(' + ', @_) . ") / " . scalar @_;
|
return "(" . join(' + ', @_) . ") / " . scalar @_;
|
||||||
},
|
},
|
||||||
|
|
||||||
# converters:
|
# converters:
|
||||||
# gallons to liters
|
# gallons to liters
|
||||||
'tl' => sub { return $_[-1] * 3.785 },
|
'tl' => sub { return $_[-1] * 3.785 },
|
||||||
@@ -193,6 +201,9 @@ my %func = (
|
|||||||
'tmb' => sub { return $_[-1] / 1000 / 1000},
|
'tmb' => sub { return $_[-1] / 1000 / 1000},
|
||||||
'tgb' => sub { return $_[-1] / 1000 / 1000 / 1000 },
|
'tgb' => sub { return $_[-1] / 1000 / 1000 / 1000 },
|
||||||
'ttb' => sub { return $_[-1] / 1000 / 1000 / 1000 / 1000 },
|
'ttb' => sub { return $_[-1] / 1000 / 1000 / 1000 / 1000 },
|
||||||
|
|
||||||
|
# alias
|
||||||
|
'x' => sub { return join "^", @_ },
|
||||||
);
|
);
|
||||||
|
|
||||||
# math constants, always upper case letters, usable via eval{}
|
# math constants, always upper case letters, usable via eval{}
|
||||||
@@ -540,6 +551,21 @@ sub defun {
|
|||||||
my $code = shift;
|
my $code = shift;
|
||||||
my ($op, $name, @tokens) = split /\s\s*/, $code;
|
my ($op, $name, @tokens) = split /\s\s*/, $code;
|
||||||
|
|
||||||
|
if ($name !~ /^[a-zA-Z0-9_]+$/) {
|
||||||
|
print "invalid function name (a-z0-9_)!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grep {$name eq $_} keys %commands) {
|
||||||
|
print "reserved function name (command)!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grep {$name eq $_} keys %func) {
|
||||||
|
print "reserved function name (function)!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$custom{$name} = "@tokens";
|
$custom{$name} = "@tokens";
|
||||||
|
|
||||||
$func{$name} = sub {
|
$func{$name} = sub {
|
||||||
@@ -549,13 +575,14 @@ sub defun {
|
|||||||
# replace N1..NN with actual args
|
# replace N1..NN with actual args
|
||||||
my @body;
|
my @body;
|
||||||
foreach my $item (@tokens) {
|
foreach my $item (@tokens) {
|
||||||
if ($item =~ /^N(\d+)$/) {
|
if ($item =~ /^([A-Z])(\d+)$/) {
|
||||||
my $i = $1;
|
my $letter = $1;
|
||||||
|
my $i = $2;
|
||||||
if ($i <= $max) {
|
if ($i <= $max) {
|
||||||
push @body, $args[$i-1];
|
push @body, $args[$i-1];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print "undefined variable N$i!\n";
|
print "undefined variable ${letter}${i}!\n";
|
||||||
push @body, 0;
|
push @body, 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user