It's a calculator for the unwise. Public domain.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Emil 0e98e380f0
2 months ago
old-dc init 2 months ago
test init 2 months ago
.gitignore compiles 2 months ago
LICENSE init 2 months ago
Makefile init 2 months ago
README init 2 months ago
README.2 init 2 months ago
config.h init 2 months ago init 2 months ago
dc.c compiles 2 months ago
ns.c init 2 months ago
retrospective init 2 months ago


-- DC --

desktop calculator implementation

Copyright 2022, 2023 Emil Williams, see LICENSE

GMP based DC. Uses readline. No limitations, either.

-- Notes --

Note that much of the dc(1) man page is applicable, and is the formal root of
this project. It is partly abidded in the featureset, of course this program is
not GNU dc or a POSIX implementation* but it closely aligns to the manual page
as a primary source of how DC should generally operate.

Diviations exist, and this should be either treated as a bug, or a feature
depending on the case regarding it. If some feature incorrectly matches dc(1)
and deliberate incompatibility is not stated then it is a bug. See section

Warning : Numbers are purely base 10 and hexadecimal is not implemented in any
way but I've Ensured there are no hinderences with A-F with my
conflicting character set.

* There is no POSIX definition of DC, currently. There is a POSIX defition of
BC, however. A formal proposal of DC should likely be a reduced subset of
GNU/DC, with all normal printing and stack operations, along with registers,
strings, and params, with the miscellaneous features and requirements for
handling the REPL, files and STDIN all in the same or limited way (such that
this program would be complicit) for the CLI. Of course this would come with
the specification of multiple precision.

This section is just a brief airing and goalset of what the codebase can do.

-- Printing --

p - print top
n - print pop no newline
f - print all

-- Arithmetic --

n1 is the first popped value, and so on.

+/-* such that n1 OP n2, pushes 1 result
^ n2 to the power of n1, and is not limited
v n1's square root

Note that |, % and ~ have been omitted due to being 'pointless'.
They may be added later with mpf_t to mpz_t conversion.

- Stack --

c clear
d duplicate
r reverse n1 and n2
z pushes top

-- Regs --

any character from \0 to \377 [256] is a valid register and check config for
stack max r being any character as stated.

sr sets a popped value from the primary stack onto r
lr gets a value from r and push that onto the stack
Sr pushes a popped value unto the registers stack
Lr pops a value unto the main stack
;r pops two values from the the primary stack, such and pushes n2 at index n1
:r pops a value and pushes that index unto the primary stack

Note that a sr value is not destroyed by Sr. This is technically an
incompatibility but I don't see a reason to maintain such abnormality.

-- Params --

Push / Pop

I / i set input radix
K / k set the precision (of everything, including registers)

-- Misc. --

q quit
# a comment.

-- Incompats --

- FIXME on i and input radix

A-F notation will refer to the numbers 10-15,
however the Input Radix must be already set higher
than these symbols as mpf_set_str does not respect these symbols normally.

- FIXME on k and precision settings

the expression: 128k2 3/ ran under this program and GNU DC preduce different outputs,
GNU: .66666666666666666666666666666666666666666666666666666666666666666666\
CACT: 0.6666666666666666666666666666666666666667

128 refers to apparently a 128 digits of precision, rather than the traditional number of bits.
And it rounds up...

- DISCREPANCY we print a prefixing zero on fractions 1 < & > -1

- FIXME not very meaningful o

o has no effect on output.

- FIXME readline does not take kindly to input


# loads 20 into register 012's stack
# loads that back into the main stack
# prints top of stack

does not have the same effect as when ran as ours, infact, the S call would
preduce a clamping error at the CLI REGCHAR level.

I believe this is an issue with how input is read, thus an issue with how readline filters it's returned string.

- WARN registers without DC_COMPLY

Are reduced to a smaller subset and only normal ascii characters are respected (' ' - '~')
Only 95 registers out of a naturally presumed 256 registers as stated by DC's man page.

- INCOMPAT readline respects DEL sometimes

% echo '^?20' | ./dc
% echo '^?20' | dc

This is the equivalent of UB in your terminal emulator.

MINOR INCOMPAT FIXME dc prints characters greater than 126 (~) in octal under the format PROGN ": %04o unimplemented\n"

-- TODO --

- Partial work, nothing tangable
~ Partial completion
? Experimental stage completion
* Completed with confidence
No work or consideration has been done
X Incompatible completed

[*] dynamic stack allocation
[*] A-F hexadecimal w/ compat
[X] Params
[*] :;
[*] registers
[-] digit counts
[-] cyclical nrotate R
[ ] strings/macros

-- Findings --

GNU dc has leaks but it has two orders of magnitude less total space allocated.