Correct manual

This commit is contained in:
Louis Rubet 2022-02-28 18:10:25 +01:00
parent 60099e32cf
commit c0813c9307
3 changed files with 226 additions and 217 deletions

431
MANUAL.md
View file

@ -1,44 +1,39 @@
# **rpn** - reference manual # **rpn** - reference manual
**rpn** **rpn**
- is a structured full-featured **math-oriented language** inspired by Hewlett-Packard **R**everse **P**olish **L**isp (**HP28S** and **HP48GX** user manuals are provided as references), including **real**, **complex**, **stack**, **store**, **branch**, **program**, **test**, **trig** and **logs** commands and more to come - is a structured full-featured **math-oriented language** inspired by Hewlett-Packard **R**everse **P**olish **L**isp (**HP28S** and **HP48GX** user manuals are provided as references), including **real**, **complex**, **stack**, **store**, **branch**, **program**, **test**, **trig** and **logs** commands and more to come,
- is implemented as a **command-line calculator** for most popular Linux distributions - is implemented as a **command-line calculator**,
- brings powerfull calculation facilities on floating point numbers with __arbitrary precision__ provided by **GNU MP** and **GNU MPFR** libraries - brings powerfull calculation facilities on floating point numbers with __arbitrary precision__ provided by **GNU MP** and **GNU MPFR** libraries
- uses that so cool **reverse polish notation** - uses that so cool **reverse polish notation**.
## Doc overview ## Doc overview
This page gives some examples and lists the commands currently implemented. This page gives some examples and lists the commands currently implemented.
For a most complete help, please refer to HP28S and HP48GX manuals provided in the sources For a most complete help, please refer to HP28S and HP48GX manuals provided in the sources.
A help command is provided by rpn: A help command is provided by rpn:
``` ```rpn
rpn> help rpn> help
rpn v2.4.0, (c) 2022 <louis@rubet.fr>, GNU LGPL v3 rpn v2.4.0, (c) 2022 <louis@rubet.fr>
Reverse Polish Notation CLI calculator
Reverse Polish Notation language
using GMP v6.1.2 under GNU LGPL
MPFR v4.0.1 under GNU LGPL
and linenoise-ng v1.0.0 under BSD
Syntax: rpn [command] Syntax: rpn [command]
with optional command = list of commands with optional command = list of commands
GENERAL GENERAL
nop no operation nop no operation
help this help message help this help message
(...) (...)
``` ```
## Quick examples ## Quick examples
### easy calculation with **stacked results** ### Easy calculation with **stacked results**
```
```rpn
rpn> 1 2 + rpn> 1 2 +
3 3
rpn> 2 sqrt rpn> 2 sqrt
@ -46,9 +41,9 @@ rpn> 2 sqrt
1> 1.4142135623730950488016887242096980786 1> 1.4142135623730950488016887242096980786
``` ```
### **programs** and **variables** ### **Programs** and **variables**
``` ```rpn
rpn> << rot * swap 2 / neg dup sq rot - sqrt >> 'quadratic_solution' sto rpn> << rot * swap 2 / neg dup sq rot - sqrt >> 'quadratic_solution' sto
rpn> 1 2 -3 quadratic_solution rpn> 1 2 -3 quadratic_solution
2> -1 2> -1
@ -57,17 +52,19 @@ rpn> vars
var 1: name 'quadratic_solution', type program, value << rot * swap 2 / chs dup sq rot - sqrt >> var 1: name 'quadratic_solution', type program, value << rot * swap 2 / chs dup sq rot - sqrt >>
``` ```
### **local variables** ### **Local variables**
```
```rpn
rpn> << -> x y << x y + ln >> >> 'P' sto rpn> << -> x y << x y + ln >> >> 'P' sto
rpn> 1 2 P rpn> 1 2 P
rpn> 1.0986122886681096913952452369225257046 rpn> 1.0986122886681096913952452369225257046
``` ```
### **arbitrary precision** ### **Arbitrary precision**
The number of significant digits can be very large thanks to GNU MPFR The number of significant digits can be very large thanks to GNU MPFR
``` ```rpn
rpn> 256 prec rpn> 256 prec
rpn> pi rpn> pi
3.1415926535897932384626433832795028841971693993751058209749445923078164062862 3.1415926535897932384626433832795028841971693993751058209749445923078164062862
@ -76,10 +73,11 @@ rpn> erase 10000 prec pi
rpn> rpn>
``` ```
### object types ### Object types
The following objects are managed: **floating numbers**, **complexes**, **symbols**, **strings**, **programs**, plus language **keywords** (commands and flow controls). The following objects are managed: **floating numbers**, **complexes**, **symbols**, **strings**, **programs**, plus language **keywords** (commands and flow controls).
```
```rpn
5> 12.3456 5> 12.3456
4> (1,-2.33) 4> (1,-2.33)
3> 'symbol' 3> 'symbol'
@ -106,9 +104,9 @@ Autocompletion works like those in Linux shells, with keys \<tab\>, Ctrl-R \<sea
- Arbitrary base numbers are entered as `<base>b<number>`. - Arbitrary base numbers are entered as `<base>b<number>`.
- Representation can be individualy changed with keywords `dec`, `bin`, `hex` and `<n> base`. - Representation can be individualy changed with keywords `dec`, `bin`, `hex` and `<n> base`.
ex: ex:
```
```rpn
rpn> 5.6 0xaabb 0b1101 7b1252 rpn> 5.6 0xaabb 0b1101 7b1252
4> 5.6 4> 5.6
3> 0xaabb 3> 0xaabb
@ -123,203 +121,204 @@ rpn> 7b1252 dec
### general ### general
|keyword|description| | keyword | description |
|-|-| |-------------------|-----------------------------------------|
|`nop` | no operation | `nop` | no operation |
|`help` `h` `?` | this help message | `help` `h` `?` | this help message |
|`quit` `q` `exit` | quit software | `quit` `q` `exit` | quit software |
|`version` | show rpn version | `version` | show rpn version |
|`uname` | show rpn complete identification string | `uname` | show rpn complete identification string |
|`history`| see commands history | `history` | see commands history |
### usual operations - real and complex ### usual operations - real and complex
|keyword|description| | keyword | description |
|-|-| |-------------|------------------------------------------------------------------|
|`+`| addition | `+` | addition |
|`-`| substraction | `-` | substraction |
|`neg` `chs`| negation | `neg` `chs` | negation |
|`*`| multiplication | `*` | multiplication |
|`/`| division | `/` | division |
|`inv`| inverse | `inv` | inverse |
|`^` `pow`| power | `^` `pow` | power |
|`sqrt`| square root | `sqrt` | square root |
|`sq` `sqr`| square | `sq` `sqr` | square |
|`abs`| absolute value for a number or `sqrt(re*re+im*im)` for a complex | `abs` | absolute value for a number or `sqrt(re*re+im*im)` for a complex |
|`dec`| decimal representation | `dec` | decimal representation |
|`hex`| hexadecimal representation | `hex` | hexadecimal representation |
|`bin`| binary representation | `bin` | binary representation |
|`base`| arbitrary base representation | `base` | arbitrary base representation |
|`sign`| sign of a real, unary vector in the same direction for a complex | `sign` | sign of a real, unary vector in the same direction for a complex |
### operations on reals ### operations on reals
|keyword|description| | keyword | description |
|-|-| |---------|-------------------------------------------------|
|`%`| purcent | `%` | purcent |
|`%CH`| inverse purcent | `%CH` | inverse purcent |
|`mod`| modulo | `mod` | modulo |
|`fact`| n! for integer n or Gamma(x+1) for fractional x | `fact` | n! for integer n or Gamma(x+1) for fractional x |
|`mant`| mantissa of a real number | `mant` | mantissa of a real number |
|`xpon`| exponant of a real number | `xpon` | exponant of a real number |
|`floor`| largest number <= | `floor` | largest number <= |
|`ceil`| smallest number >= | `ceil` | smallest number >= |
|`ip`| integer part | `ip` | integer part |
|`fp`| fractional part | `fp` | fractional part |
|`min`| min of 2 real numbers | `min` | min of 2 real numbers |
|`max`| max of 2 real numbers | `max` | max of 2 real numbers |
### operations on complexes ### operations on complexes
|keyword|description| | keyword | description |
|-|-| |---------|----------------------------------|
|`re`| complex real part | `re` | complex real part |
|`im`| complex imaginary part | `im` | complex imaginary part |
|`conj`| complex conjugate | `conj` | complex conjugate |
|`arg`| complex argument in radians | `arg` | complex argument in radians |
|`r->p`| rectangular to polar coordinates | `r->p` | rectangular to polar coordinates |
|`p->r`| polar to rectangular coordinates | `p->r` | polar to rectangular coordinates |
|`r->c`| transform 2 reals in a complex | `r->c` | transform 2 reals in a complex |
|`c->r`| transform a complex in 2 reals | `c->r` | transform a complex in 2 reals |
### mode ### mode
|keyword|description| | keyword | description |
|-|-| |-----------|------------------------------------------------------------------------------------------------------------------------------------|
|`std`| standard floating numbers representation. ex: `std` | `std` | standard floating numbers representation. ex: `std` |
|`fix`| fixed point representation. ex: `6 fix` | `fix` | fixed point representation. ex: `6 fix` |
|`sci`| scientific floating point representation. ex: `20 sci` | `sci` | scientific floating point representation. ex: `20 sci` |
|`prec`| set float precision in bits. ex: `256 prec` | `prec` | set float precision in bits. ex: `256 prec` |
|`round`| set float rounding mode. Authorized values are: `"nearest"` `"toward zero"` `"toward +inf"` `"toward -inf"` `"away from zero"`. ex: `"nearest" round` | `round` | set float rounding mode. Authorized values are: |
|`default` | set float representation and precision to default | | `"nearest (even)", "toward zero", "toward +inf", "toward -inf", "away from zero", "faithful rounding", "nearest (away from zero)"` |
|`type` | show type of stack first entry | `default` | set float representation and precision to default |
| `type` | show type of stack first entry |
### test ### test
|keyword|description| | keyword | description |
|-|-| |---------|--------------------------------|
|`>`| binary operator > | `>` | binary operator > |
|`>=`| binary operator >= | `>=` | binary operator >= |
|`<`| binary operator < | `<` | binary operator < |
|`<=`| binary operator <= | `<=` | binary operator <= |
|`!=`| binary operator != (different) | `!=` | binary operator != (different) |
|`==`| binary operator == (equal) | `==` | binary operator == (equal) |
|`and`| boolean operator and | `and` | boolean operator and |
|`or`| boolean operator or | `or` | boolean operator or |
|`xor`| boolean operator xor | `xor` | boolean operator xor |
|`not`| boolean operator not | `not` | boolean operator not |
|`same`| boolean operator same (equal) | `same` | boolean operator same (equal) |
### stack ### stack
|keyword|description| | keyword | description |
|-|-| |---------------|-----------------------------------------------------------------|
|`swap`| swap 2 first stack entries | `swap` | swap 2 first stack entries |
|`drop`| drop first stack entry | `drop` | drop first stack entry |
|`drop2`| drop 2 first stack entries | `drop2` | drop 2 first stack entries |
|`dropn`| drop n first stack entries | `dropn` | drop n first stack entries |
|`del` `erase`| drop all stack entries | `del` `erase` | drop all stack entries |
|`rot`| rotate 3 first stack entries | `rot` | rotate 3 first stack entries |
|`dup`| duplicate first stack entry | `dup` | duplicate first stack entry |
|`dup2`| duplicate 2 first stack entries | `dup2` | duplicate 2 first stack entries |
|`dupn`| duplicate n first stack entries | `dupn` | duplicate n first stack entries |
|`pick`| push a copy of the given stack level onto the stack | `pick` | push a copy of the given stack level onto the stack |
|`depth`| give stack depth | `depth` | give stack depth |
|`roll`| move a stack entry to the top of the stack | `roll` | move a stack entry to the top of the stack |
|`rolld`| move the element on top of the stack to a higher stack position | `rolld` | move the element on top of the stack to a higher stack position |
|`over`| push a copy of the element in stack level 2 onto the stack | `over` | push a copy of the element in stack level 2 onto the stack |
### string ### string
|keyword|description| | keyword | description |
|-|-| |---------|------------------------------------------------------------------------------------------|
|`->str`| convert an object into a string | `->str` | convert an object into a string |
|`str->`| convert a string into an object | `str->` | convert a string into an object |
|`chr`| convert ASCII character code in stack level 1 into a string | `chr` | convert ASCII character code in stack level 1 into a string |
|`num`| return ASCII code of the first character of the string in stack level 1 as a real number | `num` | return ASCII code of the first character of the string in stack level 1 as a real number |
|`size`| return the length of the string | `size` | return the length of the string |
|`pos`| seach for the string in level 1 within the string in level 2 | `pos` | seach for the string in level 1 within the string in level 2 |
|`sub`| return a substring of the string in level 3 | `sub` | return a substring of the string in level 3 |
### branch ### branch
|keyword|description| | keyword | description |
|-|-| |----------|-------------------------------------------------------------------------------------------------------|
|`if`| `(test-instruction) if then (true-instructions) else (false-instructions) end` | `if` | `(test-instruction) if then (true-instructions) else (false-instructions) end` |
|`then`| used with if | `then` | used with if |
|`else`| used with if | `else` | used with if |
|`end`| used with various branch instructions | `end` | used with various branch instructions |
|`ift`| similar to if-then-end: `(test-instruction) (true-instruction) ift` | `ift` | similar to if-then-end: `(test-instruction) (true-instruction) ift` |
|`ifte`| similar to if-then-else-end: `(test-instruction) (true-instruction) (false-instruction) ifte` | `ifte` | similar to if-then-else-end: `(test-instruction) (true-instruction) (false-instruction) ifte` |
|`start`| `(start) (end) start (instructions) [next,(step) step]`. ex: `10 20 30 1 2 start + next` | `start` | `(start) (end) start (instructions) [next,(step) step]`. ex: `10 20 30 1 2 start + next` |
|`for`| `(start) (end) for (variable) (instructions) [next,(step) step]`. ex: `1 2 for i i 'a' sto+ 0.1 step` | `for` | `(start) (end) for (variable) (instructions) [next,(step) step]`. ex: `1 2 for i i 'a' sto+ 0.1 step` |
|`next`| used with start and for | `next` | used with start and for |
|`step`| used with start and for | `step` | used with start and for |
|`do`| `do (instructions) until (condition) end` | `do` | `do (instructions) until (condition) end` |
|`until` | used with do | `until` | used with do |
|`while` | `while (test-instruction) repeat (loop-instructions) end` | `while` | `while (test-instruction) repeat (loop-instructions) end` |
|`repeat` | used with while | `repeat` | used with while |
### store ### store
|keyword|description| | keyword | description |
|-|-| |---------|-----------------------------------------------------------------|
|`sto`| store a variable. ex: ```1 'name' sto``` | `sto` | store a variable. ex: ```1 'name' sto``` |
|`rcl`| recall a variable. ex: ```'name' rcl``` | `rcl` | recall a variable. ex: ```'name' rcl``` |
|`purge`| delete a variable. ex: ```'name' purge``` | `purge` | delete a variable. ex: ```'name' purge``` |
|`vars`| list all variables | `vars` | list all variables |
|`clusr`| erase all variables | `clusr` | erase all variables |
|`edit`| edit a variable content | `edit` | edit a variable content |
|`sto+`| add to a stored variable. ex: 1 'name' sto+ 'name' 2 sto+ | `sto+` | add to a stored variable. ex: 1 'name' sto+ 'name' 2 sto+ |
|`sto-`| substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto- | `sto-` | substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto- |
|`sto*`| multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto* | `sto*` | multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto* |
|`sto/`| divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/ | `sto/` | divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/ |
|`sneg`| negate a variable. ex: 'name' sneg | `sneg` | negate a variable. ex: 'name' sneg |
|`sinv`| inverse a variable. ex: 1 'name' sinv | `sinv` | inverse a variable. ex: 1 'name' sinv |
### program ### program
|keyword|description| | keyword | description |
|-|-| |---------|-----------------------------------------------------------------------------|
|`eval`| evaluate (run) a program, or recall a variable. ex: `'my_prog' eval` | `eval` | evaluate (run) a program, or recall a variable. ex: `'my_prog' eval` |
|`->`| load program local variables. ex: `<< -> n m << 0 n m for i i + next >> >>` | `->` | load program local variables. ex: `<< -> n m << 0 n m for i i + next >> >>` |
### trig on reals and complexes ### trig on reals and complexes
|keyword|description| | keyword | description |
|-|-| |---------|----------------------------|
|`pi`| pi constant | `pi` | pi constant |
|`sin`| sinus | `sin` | sinus |
|`asin`| arg sinus | `asin` | arg sinus |
|`cos`| cosinus | `cos` | cosinus |
|`acos`| arg cosinus | `acos` | arg cosinus |
|`tan`| tangent | `tan` | tangent |
|`atan`| arg tangent | `atan` | arg tangent |
|`d->r`| convert degrees to radians | `d->r` | convert degrees to radians |
|`r->d`| convert radians to degrees | `r->d` | convert radians to degrees |
### logs on reals and complexes ### logs on reals and complexes
|keyword|description| | keyword | description |
|-|-| |------------------|-----------------------------------------------|
|`e`| Euler constant | `e` | Euler constant |
|`ln` `log`| logarithm base e | `ln` `log` | logarithm base e |
|`lnp1`| ln(1+x) which is useful when x is close to 0 | `lnp1` | ln(1+x) which is useful when x is close to 0 |
|`exp`| exponential | `exp` | exponential |
|`expm`| exp(x)-1 which is useful when x is close to 0 | `expm` | exp(x)-1 which is useful when x is close to 0 |
|`log10`| logarithm base 10 | `log10` | logarithm base 10 |
|`alog10` `exp10`| exponential base 10 | `alog10` `exp10` | exponential base 10 |
|`log2`| logarithm base 2 | `log2` | logarithm base 2 |
|`alog2` `exp2`| exponential base 2 | `alog2` `exp2` | exponential base 2 |
|`sinh`| hyperbolic sine | `sinh` | hyperbolic sine |
|`asinh`| inverse hyperbolic sine | `asinh` | inverse hyperbolic sine |
|`cosh`| hyperbolic cosine | `cosh` | hyperbolic cosine |
|`acosh`| inverse hyperbolic cosine | `acosh` | inverse hyperbolic cosine |
|`tanh`| hyperbolic tangent | `tanh` | hyperbolic tangent |
|`atanh`| inverse hyperbolic tangent | `atanh` | inverse hyperbolic tangent |
|`time`| time in format HH.MMSSssssss | `time` | time in format HH.MMSSssssss |
|`date`| date in format (M)M.DDYYYY | `date` | date in format (M)M.DDYYYY |
|`ticks`| system tick in µs | `ticks` | system tick in µs |
### default ### default
@ -331,46 +330,58 @@ Default rounding mode is 'nearest'
## Tests ## Tests
- A set of complete test sheets are given in the [test](https://github.com/louisrubet/rpn/tree/master/test) subdirectory. Each version is fully tested before delivery - A set of complete test sheets are given in the [test](https://github.com/louisrubet/rpn/tree/master/test) subdirectory.
- All tests are run each at each pull on a pull request branch. Memory tests (`valgrind`) are also executed on each tests.
- Test sheets syntax is - Test sheets syntax is
``` ```shell
# cat my_test_sheet.txt cat my_test_sheet.md
## Test sheet example # Test sheet example
default erase `default del`
## test step 1
`1 dup 1 +`
# test step 1
1 dup 1 +
-> stack size should be 2 -> stack size should be 2
-> stack should be 1, 2
-> error should be 0
erase
# test step 2 -> stack should be 1, 2
2 4 / 0.5 ==
-> error should be 0
`del`
## test step 2
`2 4 / 0.5 ==`
-> stack should be 1 -> stack should be 1
erase
`del`
``` ```
- Test sheet can be played with the command `test` - Test sheet can be played with the command `test`
``` ```rpn
rpn> "my_test_sheet.txt" rpn> "my_test_sheet.md" test
"my_test_sheet.txt"
rpn> test rpn version is v2.3.2-68-g60099e3
my_test_sheet.md: Test sheet example
## test step 1 PASSED
## test step 2 PASSED
run 2 tests: 2 passed, 0 failed (4 steps: 4 passed, 0 failed)
my_test_sheet.txt: Test sheet example
# test step 1 PASSED
# test step 2 PASSED
my_test_sheet.txt: run 2 tests: 2 passed, 0 failed (4 steps: 4 passed, 0 failed)
Total: run 2 tests: 2 passed, 0 failed (4 steps: 4 passed, 0 failed) Total: run 2 tests: 2 passed, 0 failed (4 steps: 4 passed, 0 failed)
rpn> rpn>
``` ```
- Please follow these rules to write correct test sheets: - Please follow these rules to write correct test sheets:
- make the test sheet begins by `default erase`
- make the test sheet begins by `default del`
- the 3 existing tests are `-> stack size should be (number)` `-> stack should be (values separated by commas)` `-> error should be (error number)` - the 3 existing tests are `-> stack size should be (number)` `-> stack should be (values separated by commas)` `-> error should be (error number)`

View file

@ -1,7 +1,5 @@
# **rpn** - **R**everse **P**olish **N**otation CLI calculator [![License: LGPLv3](https://www.gnu.org/graphics/lgplv3-88x31.png)](https://www.gnu.org/licenses/lgpl-3.0.en.html) # **rpn** - **R**everse **P**olish **N**otation CLI calculator [![License: LGPLv3](https://www.gnu.org/graphics/lgplv3-88x31.png)](https://www.gnu.org/licenses/lgpl-3.0.en.html)
A math functional language using reverse polish notation.
### A math functional language using reverse polish notation ### A math functional language using reverse polish notation
```rpn ```rpn
@ -42,7 +40,7 @@ rpn> pi
rpn> rpn>
``` ```
### Variables, strings, structured programming ### Variables, structured programming
```rpn ```rpn
rpn> « rot * swap 2 / chs dup sq rot - sqrt » 'quad' sto rpn> « rot * swap 2 / chs dup sq rot - sqrt » 'quad' sto

View file

@ -69,9 +69,9 @@ vector<program::keyword_t> program::keywords_{
{kKeyword, "sci", &program::RpnSci, "scientific floating point representation. ex: 20 sci"}, {kKeyword, "sci", &program::RpnSci, "scientific floating point representation. ex: 20 sci"},
{kKeyword, "prec", &program::RpnPrecision, "set float precision in bits. ex: 256 prec"}, {kKeyword, "prec", &program::RpnPrecision, "set float precision in bits. ex: 256 prec"},
{kKeyword, "round", &program::RpnRound, {kKeyword, "round", &program::RpnRound,
"set float rounding mode.\n\tex: [\"nearest (even)\", \"toward zero\", \"toward " "set float rounding mode in \n\t\"nearest (even)\", \"toward zero\", \"toward "
"+inf\", \"toward -inf\", \"away from zero\", \"faithful rounding\", \"nearest (away from zero)\"] round"}, "+inf\", \"toward -inf\", \"away from zero\", \"faithful rounding\", \"nearest (away from zero)\""
"\n\tex: \"nearest (even)\" round"},
{kKeyword, "default", &program::RpnDefault, "set float representation and precision to default"}, {kKeyword, "default", &program::RpnDefault, "set float representation and precision to default"},
{kKeyword, "type", &program::RpnType, "show type of stack first entry"}, {kKeyword, "type", &program::RpnType, "show type of stack first entry"},
{kKeyword, "hex", &program::RpnHex, "hexadecimal representation, applies on stack level 0 only"}, {kKeyword, "hex", &program::RpnHex, "hexadecimal representation, applies on stack level 0 only"},