rpnc
Source codeWhat is it? Link to heading
rpnc is a calculator for your terminal that uses reverse polish notation (RPN), which is inspired by my Hewlett Packard model 28S advanced scientific calculator, and written in pure Go.
Here’s a little demo of how one could calculate $\frac{543}{(123+74)^2}$ using rpnc:
The result is printed onto the terminal once you exit the program.
You can read up on how RPN works more in depth in this post, but in simple terms, it’s a way to write mathematical expressions without the need for parentheses.
Currently it can perform all the fundamental operations that a regular
calculator can like: adding, subtracting, multiplying, and dividing. In
addition, it has functions for manipulating its stack like: swap, dup,
roll, and drop.
My vision for this project is much more than just a simple little calculator app however.
Vision Link to heading
I intend to make rpnc fully programmable just like my aforementioned 28S. I will
be extending it to be able to interpret reverse polish LISP (RPL) programs. The
calculator will have another mode in addition to its current interactive mode.
This new mode, the interpreter mode, will allow users to evaluate expressions
from .rpl files, or directly from the command line like
rpnc eval -f ./example.rpl and rpnc eval "543 123 74 + 2 ^ /"
Much like the 28S, it will also have a directory hierarchy and a custom menu where users can save functions that they wish to have direct access to instead of having to type them out:
Since there are no dedicated buttons for things like these on a keyboard, I plan
to make menu items accessible via CTRL modifiers. So in the case of the image
above for example, the user would press ctrl+1 and ctrl+2 to access the MOD
and SWAP menu items respectively.
Where Can You Get It? Link to heading
Look no further than my git repo :)
Other Neat Things Link to heading
Implementing the RPL interpreter is a pretty interesting task. As I started studying about interpreters, I started to notice in other languages, like Go for instance, the same techniques that I had read about. Like tokenization of strings during lexical analysis.
Taken from token.go in token package of Go’s standard library:
// The list of tokens.
const (
// Special tokens
ILLEGAL Token = iota
EOF
COMMENT
literal_beg
// Identifiers and basic type literals
// (these tokens stand for classes of literals)
IDENT // main
INT // 12345
FLOAT // 123.45
IMAG // 123.45i
CHAR // 'a'
STRING // "abc"
literal_end
.
.
.
ADD // +
SUB // -
MUL // *
QUO // /
REM // %
.
.
.
)
The specific book I chose to read to help me implement RPL is called Crafting Interpreters by Robert Nystrom. It’s a step-by-step on how to build a language from scratch, but worded in a conversational tone. I highly recommend it.