Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/zk-phi/rpn-calc

Handy RPN calculator for hackers
https://github.com/zk-phi/rpn-calc

emacs

Last synced: about 2 months ago
JSON representation

Handy RPN calculator for hackers

Awesome Lists containing this project

README

        

* rpn-calc.el

プログラマ向け RPN 電卓

quick RPN calculator for hackers

** Screencast

[[img/screencast.gif]]

** NOTE: Breaking changes in the latest version
*** Quote (') behavior for symbols are changed

| | NOT quoted (foo) | quoted ('foo) | function-quoted (#'foo) |
|-----------------+----------------------------+----------------+-------------------------|
| last version | variable "foo" | function "foo" | symbol "foo" |
| current version | function or variable "foo" | symbol "foo" | symbol "foo" |

Pros: functions also can be called without prefixing quotes ('), and
function quote (#') is no longer required to push raw symbols

Cons: if a name is both defined as function and variable, it's not
possible to refer the variable definition

- Function call examples
- last version

: random -> ERROR: void variable "random"
: 'random -> 12345
: #'random -> random

- current version

: random -> 12345
: 'random -> random

- Variable reference examples
- last version

: default-directory -> "~/"
: 'default-directory -> void function "default-directory"
: #'default-directory -> default-directory

- current version

: default-directory -> "~/"
: 'default-directory -> default-diectory

** Advantages

=rpn-calc= is designed to be a handy tool for daily programming
use.

- =rpn-calc= uses popup instead of making a new window, and you don't
need to move your eyes between the edit point and the calculator
window

- =rpn-calc= displays hints like binary representation of numbers,
which may be useful for programmers

- =rpn-calc= is designed to be used with minimal key presses.

- =rpn-calc= is easy to customize. You can add/remove some operators
with just one or two lines of Emacs Lisp

- You can push not only numbers but any Emacs Lisp objects to the
stack, and you can apply any Emacs Lisp function to them. So
=rpn-calc= can also be used as an interactive, RPN version of
=eval-expression=

See also "Other Features" section.

** Installation

Require this script

: (require 'rpn-calc)

and invoke with =M-x rpn-calc=.

** Tutorial

1. You can push objects by pressing =[SPC]= after entering an
S-expression (try: =120[SPC]=). You can also push more complex
expressisons like =(buffer-name (current-buffer))[SPC]=, or quoted
expressions

Pro tip: in Emacs, =#xFF= = =#b11111111= = =255=

2. When you enter an operator name, top elements in the stack are
popped and applied to the operator (try: =1[SPC]sin=). List of
built-in operators are listed in the section below. You can add
some operators by pushing list like =(NAME ARITY . FUNCTION)= to
=rpn-calc-operator-table=

: (push '("twice" 1 . (lambda (x) (* x 2))) rpn-calc-operator-table)

3. You can also push a function name to call it (try:
=10[SPC]number-to-string[SPC]=), or a variable name to refer it
(try =most-positive-fixnum[SPC]=). If the function accepts =&rest=
arguments, all elements in the stack are passed (try:
=10[SPC]20[SPC]30[SPC]list[SPC]=). This behavior can be changed via
=rpn-calc-apply-rest-args=. Note that if a symbol is both defined
as function and variable, function definition takes precedence

** Built-in Operators

- math
- + :: pop =y=, =x= and push =(+ x y)=
- -- :: pop =y=, =x= and push =(- x y)=
- / :: pop =y=, =x= and push =(/ x y)=
- * :: pop =y=, =x= and push =(* x y)=
- % :: pop =y=, =x= and push =(mod x y)= (modulo)
- sin :: pop =x= and push =(sin x)= (sine)
- cos :: pop =x= and push =(cos x)= (cosine)
- tan :: pop =x= and push =(tan x)= (tangent)
- ln :: pop =x= and push =(log x)= (natural log)
- lg :: pop =x= and push =(log x 10)= (log base 10)
- log :: pop =y=, =x= and push =(log y x)= (log base x)

- bitwise
- & :: pop =y=, =x= and push =(logand x y)= (bitwise and)
- | :: pop =y=, =x= and push =(logor x y)= (bitwise or)
- ^ :: pop =y=, =x= and push =(logxor x y)= (bitwise xor)
- ~ :: pop =x= and push =(lognot x)= (bitwise not)
- << :: pop =y=, =x= and push =(ash x y)= (shift left)
- >> :: pop =y=, =x= and push =(ash x (- y))= (shift right)

- int <-> float
- float :: pop =x= and push =(float x)= (int -> float)
- int :: pop =x= and push =(truncate x)= (float -> int)
- trunc :: pop =x= and push =(truncate x)= (round toward zero)
- floor :: pop =x= and push =(floor x)= (largest integer < x)
- ceil :: pop =x= and push =(ceil x)= (smallest integer > x)
- round :: pop =x= and push =(round x)= (nearest integer to x)

- stack manipulation
- :: pop an item
- : :: pop =x=, and push =x= twice (duplicate)
- \ :: pop =x=, =y= and push =y=, =x= (swap)

** Features

- Implicit "SPC"

rpn-calc automatically pushes the input (without pressing "SPC") to
reduce keypresses, when :

- non-digit character is entered after a number ::

Example: =1evenp[SPC]= is equivalent to =1[SPC]evenp[SPC]=.

- outer-most closing paren is entered ::

Example: =(1+ (point))= is equivalent to =(1+ (point))[SPC]=.

- build-in operator name is completed ::

Example: =1sin= is equivalent to =1[SPC]sin[SPC]=.

- Display hints for inserted objects

- hex/binary representation of integers

- IEEE754 representation of floating-point numbers

- arglist of functions

- variable value of symbols

- Push buffer string to the stack

You can push expressions in a buffer to the stack by selecting the
expression before invoking =rpn-calc=

- Insert result to the buffer

You can insert the result by pressing =RET= in =rpn-calc=

- Push items into middle of the stack.

You can move cursor with =rpn-calc-next= (bound to =C-n= by default)
and =rpn-calc-previous= (=C-p= resp.) while in =rpn-calc=, to insert
items into middle of the stack (try: =1[SPC]2[SPC]3[C-n][SPC]=)

** Dependencies

- popup.el