dc(1) buffer
One idea for a calculator is to use dc(1) but to buffer the commands in a text editor so you can use all the text editor things for entering and mangling the text. So in vi(1) with a buffer of
which with the cursor on the 640 line (as compared to GUI where who knows where the cursor might be pointing to, into a text area or somewhere else in the GUI) one can then type :,+3!dc to send the lines containing 640 through p inclusive through dc.
One problem is that the selection is replaced with the results of the filter, so there's no easy way to have the results and also keep the inputs, unless you just so happen to already have a tool that duplicates standard input to standard out and then replays those same lines as standard input to some other program. Something like (or that uses) tee(1) but not resulting in the duplicated output ending up in a regular file.
$ echo 2 2 + p | CLIPBOARD=/usr/bin/dc copycat
2 2 + p
4
Another problem is that dc(1) needs a "p" to actually print the results. My custom version of dc(1) needs no such flag and prints results by default, and would be a different place the "preserve the inputs" feature could be implemented.
One downside (or upside, depending on your view) of the filter is that there is no persistent dc(1) process running so state is not preserved e.g. registers or whatnot are not kept between runs. To support this one would need to keep a dc(1) running somewhere under a daemon and then pipe your commands to that daemon and consume the outputs somehow. This is a bit more complicated, but may work for some, especially if dc(1) is more complicated and has a lot more state to preserve or has a much longer startup time so starting it at boot (or otherwise infrequently) makes sense than waiting for it to get up off disk. MATLAB for instance while it has many features took 45 seconds or so to process a "2 + 2" command at startup.
Something like a spreadsheet
One might invent a particular format such that math expressions are evaluated in certain areas of the text, perhaps after some token such as a tab or when a digit first appears. In this case the input that is not the math expression must be preserved. Suppose we wish to double some amount of something,
Fernite Carbide 13671 2 *
Fullerides 4851 2 *
Hypersynaptic Fibers 490 2 *
so the filter will need to do math only on the last three tokens of each line: a digit as far as I know cannot appear in any item name, so the math bit starts where there is a digit. That is, the desired output is
Fernite Carbide 27342
Fullerides 9702
Hypersynaptic Fibers 980
though a simple (and perhaps too simple) filter such as
perl -nE '/^([^0-9]+)(.*)/ && print $1 . `/usr/bin/dc -e "$2" -ep`'
might be a bit awkward to type in vi, so if done often should be put into an easy to call script, and more error handling added. A more complicated filter might pass through blank lines and comments, etc. A related problem is getting " 2 *" or whatever onto the end of each line suitable for such modification. A different format might specify a sticky expression to use for numbers until the end of file or some other tag is parsed, so the above might instead be written as
# !m 2 *
Fernite Carbide 13671
Fullerides 4851
Hypersynaptic Fibers 490
# !m 7 *
Morphite 245
Robotics 84
Thermonuclear Trigger Unit 490
...
to multiply the numbers in the first "paragraph" by two, and those in the second "paragraph" by seven, where "# !m ..." indicates the sticky math expression for subsequent numbers, or whatever tagging scheme that works for you.
At some point this might all be turned into a proper spreadsheet or program, or not.