The `hypot` and `atan2` operators have dedicated glyphs.
Somehow, these glyphs were lost in the last font update.
Restored from eariler version.
Fixes: #295
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add missing glyph for the `⇄` sign, which is to be used for
a few upcoming functions.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Suggested-by: Jeff Roetman
Implement `if` `then` `else` blocks, as well as the `iferr` variants.
Being able to test `iferr` also required implementing several
secondary error-management commands, like `errm`, `errn` and `doerr`.
Fixes: #290Fixes: #291
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the `type` command that returns the type of an object as an
integer. No attempt is made to match the return value of `TYPE` on the
HP48. Maybe someday if this has any value.
Add the `typename` which is a portable version of the above, returning
the type name as text.
Fixes: #285
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `bytes` command on HP calculators returns the size of the object
in the first level of the stack, and the CRC32 (hash) of the object
in the second level fo the stack.
The implememntation here returns the _complete_ representation of the
object in level 2. Also, the size is always an integral number of
bytes (the Saturn-based calculators were 4-bit, so byte sizes could be
half integer)
The lowest part of the number matches the result of the `type` command.
Fixes: #284
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Following several requests from various users, implement `→Num`
(converting numbers to decimal representation) and its counterpart,
`→Q` (converting numbers to fractions), including the special cases
for pi and i.
Fixes: #255Fixes: #282
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The fixed-base based numbers are not that useful in practice, so
putting that under `CONFIG_FIXED_BASED_OBJECTS`. This can be
reactivated easily if we need it.
Fixes: #274
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add the basic rules for `expand`, `collect` and `simplify`.
And to be honest, I am quite proud of the fact that the core code looks
_exactly_ like this (this is actual code):
```c++
return rewrite((x+y)*z, x*z+y*z,
x*(y+z), x*y+x*z,
(x-y)*z, x*z-y*z,
x*(y-z), x*y-x*z);
```
A lot of template metaprogramming to turn that into transparent
building of _compile-time constants_ representing the RPL objects for
the equations, and passing that to the `rewrite` function that was
implemented earlier.
What is really neet about this is that the generated equations:
* Are automatically _shared_ if used multiple times, because they are
represented by the same template. So the equations used in `collect`
and those used in `expand` (which are the same in reverse) share the
same memory.
* Automatically go into QSPI, not consuming precious flash space,
because they are represented as initialized data arrays, and I
requested that all C++ .rodata go in QSPI.
I intentionally did not support the historical names
(`expan` and `colct`). Our level of compatibility with the HP48 is
never going to be that good anyway.
The code as is works with `clang`, but runs into unsatisfied symbols
with g++ 10.3 due to what I believe is a g++ bug (that's what living
on the edge of template metaprogramming gives you):
```
/opt/homebrew/Cellar/arm-none-eabi-gcc/10.3-2021.07/gcc/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: build/release/equation.o: in function `equation::collect() const':
equation.cc:(.text._ZNK8equation7collectEv+0xd0): undefined reference to `eq<(unsigned char)10, (unsigned char)1, (unsigned char)120, (unsigned char)10, (unsigned char)1, (unsigned char)122, (unsigned char)57, (unsigned char)10, (unsigned char)1, (unsigned char)121, (unsigned char)10, (unsigned char)1, (unsigned char)122, (unsigned char)57, (unsigned char)55>::object_data'
```
Fixes: #231
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add explicit limits for the number of rewrites and the maximum size
for big numbers.
Fixes: #214
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement a general equation rewrite engine that we can use
to implement a variety of computer-algebra features.
Fixes: #203
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
In order to accelerate processing, it is desirable to simplify
symbolic expressions as we build them. This will minimize memory usage
and processing time, notably for symbolic matrices.
Note that the implementation carefully avoids non-numeric values,
for example to make sure that `{ 1 2 3 } 0 +` is not "simplified".
Fixes#197
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
General algorithm to compute the determinant
Compute the determinant by diagonalizing the matrix.
All computations are done in a way that will be conducive to getting
the correct result with integers or fractions. This is a step towards
implementing matrix invert and division.
The algorithm used is somewhat inspired from [this source][det], but
adapted for the RPL implementation in DB48X. Specifically, the matrix
is "exploded" to the stack by the `is_matrix()` function, which
returns the size of the matrix and puts all elements on the stack if
successful. The stack is then used as an array of value during the
various manipulations. Note that in the case of `det`, we can use a
single array, but that this technique can be extended to have multiple
arrays, which will be necessary for the division.
[det]:v https://www.geeksforgeeks.org/determinant-of-a-matrixFixes: #187
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the `GET` function on list, arrays and text.
Getting a character from a text value is a DB48X extension, which I
thought was in newRPL based on documentation, but experiments show
that does not work at the moment.
Getting an element from a two-dimensional array is not going to work
the same as for RPL, and I wonder if I _want_ to make it work the
same. In traditional RPL, `[ [1 2 3] [4 5 6] ] 1 GET` gives you
`1`. In the DB48X implementation, it gives `[1 2 3]`. I think that
being able to extract vectors from a matrix is useful, and the ability
to extract an individual element using a list index should address
that problem.
Not yet implemented:
- `GET` with a list index for matrices
- `GET` with a name (dereferencing the name)
Fixes: #173
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement a context-sensitive `ToolsMenu`, bound to the `Σ+` key.
This menu looks at the stack to attempt to figure out the relevant menu.
Implement a context-sensitive `Help` function on the same principle.
Also fixes a bug in the way the help file was closed.
Fixes: #127 (Tools key)
Fixes: #162 (Help command)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add an explicit unit to rendering of polar complex number argument,
e.g. show `1∡90°` instead of just `1∡90`.
Fixes: #161
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Functions `sin`, `cos`, `tan`, `asin`, `acos`, `atan` and `atan2`
respect angle settings.
Parsing and rendering of polar angles respects that setting, but
that makes the internally-stored angle component setting dependent
(and it is not correctly updated when changing settings)
Fixes: #119
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add a command for pi. This inserts itself in equations for the moment.
Until we have a setting for numerical approximations, we will remain
with a symbolic value.
Fixes: #143
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add various ancilary functions for complex management, like conversions
from real to complex, extraction of real and imaginary part, etc.
Also add the factorial function
Fixes: #134Fixes: #135
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This makes symbolic expressions that use them more readable, notably
as a result of symbolic evaluation for complex numbers
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add glyphs for ⅉ, ℎ (Planck's constant), ℏ (reduced Planck constant),
ℝ (will be useful for some menu entries), ℚ (same).
I'm still looking for the best place to take a k for quaternions.
The mathematical k is out of range (out of the 16-bit range I'd rather stay in)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement a parser for polar and rectangular types.
Also added missing glyphs for ⅈ (used as complex number separator) and ℂ
(used already in some complex menus), and reorganize menus a bit to match
latest thinking in terms of layout.
Fixes: #15
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This makes it possible to quickly save the sate of the calculator.
This is the meaning of the 'SAVE' labeling on the proposed keyboard layout.
Fixes: #113
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
On the HP-48, `same` compares objects without evaluating names,
whereas `==` follows names. Note that DB48X adds `=` which tests
for equality rather than identity.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Block with local variables, e.g. `→ X Y « X Y - X Y + * »`
Local values reside above the stack. They are referenced by an index,
which makes them very efficient (there is no name lookup). Reading
or storing in a local variable is as efficient as accessing the stack.
This is much faster than global variables, which require a rather slow
linear name lookup and, when storing, moving the directory object.
Implements #54
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Fetch the version number directly from git.
Add the `Version` command with version information.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `PowerOff` command shuts down the system.
The `SystemSetup` command displays the system setup menu
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Allow a multiplicity of spacing options:
* Using thin space, e.g. `1 000 000.000 00`
* Using a comma or a dot, opposite of decimal mark, e.g. `1.000.000,000.00`
* Using a tick mark, e.g. `1'000'000,000'00`
* Using an underscore, e.g. `1_000_000,000_00`
Also allows different spacing for normal and based numbers, and for
mantissa and fractional part.
Fixes#59
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Make it possible to select the font to display:
* The result (first level of the stack)
* The stack (higher levels of the stack)
* The editor (when editing one or two lines)
* THe multi-line editor (when editing more than two lines)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When using the a specific suffix, e.g. `#1234Ah`, you force the base of the
object to be hexadecimal. It does not change even if you change it on display.
When not using a specific suffix, e.g. `#1234A`, the current base setting is
used, and the display changes when the `Base` setting is changed.
Fixes#18
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Centralize the functions saving all the settings in a single
`Modes` function.
Add settings for word-size and base.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The NonSciRange command controls when the display switches from
standard to scientific notation.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The idea is to keep the same symbols that the DM42 software uses in
a compatible location, to make it possible to alternatively load the
DM42 and DB48X program.
This seems to work relatively well, but there is a strange behavior
from the DM42 program that complains about being unable to open
the STATE directory of the calculator. It is possible that it is
confused by the presence of .48S files there.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The existing code was really hard to read and maintain. I could not get FIX to
really work the way it's supposed to be, so restarted from the ground up.
While I was thinking about this, added the `SIG` mode for display, which
displays significant digits. I remember some other calculator having that, and
it's neat. It's like `STD`, but with a given precision.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This will allow us to export and parse a variable that contains directories and
subdirectories.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Two representations for fractions, one for small value of numerator and
denominator, one when both values are larger.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Having a sized type for bignum is more efficient both at runtime and in terms of
memory usage:
- At runtime, we don't need all the 7-bit masking and modulo-7 arithmetic
- In terms of memory, there is a cross-over at 63 bits, which is almost exactly
where it becomes uninteresting to do in-CPU arithmetic
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>