-- 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 Incompats 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\ 666666666666666666666666666666666666666666666666666666666666 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 demo: 20S L p # 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 -- Key: - 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.