Allow the catalog to auto-complete all possible command spellings.
As a side effect, accelerate the parsing of commands.
All spellings are now stored in a static array, `object::spellings`.
This makes it possible to scan the table in both directions, i.e.
from `id` to text for name rendering, or from name to `id` for
parsing. This makes it also simpler to run operations that loop on all
spellings, including building the catalog entries.
Fixes: #626
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `Type` command is used in many programs. It is useful to have it
return HP-compatible values, even if the mapping is not entirely
accurate.
This is under control of the `DetailedTypes` / `CompatibleTypes`
settings. When in `CompatibleTypes` mode, an attempt is made to return
a compatible value, which lacks details. When in `DetailedTypes` mode,
the value returned is negative (to distinguish it from HP values) and
is gives precise information about the actual internal representation.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the following instructions:
* `RotateLeft` (`RL`)
* `RotateRight` (`RR`)
* `RotateLeftByte` (`RLB`)
* `RotateRightByte` (`RRB`)
* `ShiftLeft` (`SL`)
* `ShiftRight` (`SR`)
* `ShiftLeftByte` (`SLB`)
* `ShiftRightByte` (`SRB`)
* `ArithmeticShiftRight` (`ASR`)
DB48X adds counted variants of the above, that shift by an amount other than one
or eight.
* `RotateLeftCount` (`RLC`), rotating left several bits
* `RotateRightCount` (`RRC`), rotating right several bits
* `ShiftLeftCount` (`SLC`), shift left several bits
* `ShiftRightCount` (`SRC`), shift right several bits
* `ArithmeticShiftRightCount` (`ASRC`), arithmetic shift right several bits
Also slight rework of the `BasesMenu`.
Fixes: #622
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
`Map` applies an operation on all elements in a list or array. The
operation on the first level of the stack should take one argument and
return a single value.
`Reduce` applies a cumulative pairwise operation on all elements in a
list or array. The operation on the first level of the stack should
take two arguments and combine them into a single value. The result is
the repeated application of that operation to all elements.
`Filter` selects elements in a list of array based on a predicate. The
predicate given on level 1 of the stack takes a value as argument, and
returns a truth values. The resulting list is built with all elements
where the predicate is true.
Fixes: #613
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
`Head` returns the first element of a list, or an `Invalid dimension`
error if the list is empty.
`Tail` returns all but the first element of a list, or an `Invalid
dimension` error if the list is empty.
Also reorganize the `ListMenu` and add a `DataMenu`.
Fixes: #614
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `Min` and `Max` functions compare two elements.
For arrays, they perform an element-by-element comparison.
For lists, they perform a a lexicographic order comparison.
Fixes: #603
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `IP` command return the integer part.
The `FP` command return the fractional part.
Fixes: #601
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
`Char→Code` (`NUM`, `CODEPOINT`, `CharToUnicode`) returns the Unicode
codepoint of the first character in the text, or `-1` if the text is
empty. `"Hello" NUM` returns `72`.
`Text→Code` (`TextToUnicode`) returns a list of the Unicode codepoints
for all codepoints in the given text. `"Hello" Text→Code` returns `{
72 101 108 108 111 }`.
`Code→Text` (`CHR`, `Code→Char`) builds a text out of a Unicode
codepoint. The argument can be either a single numerical value or a
list of numerical values. A negative numerical value produces an empty
text. `{ 87 111 114 -22 108 100 }` returns `"World"`, the value `-22`
producing no character. `42 CHR` returns `"*"`, and `34 CHR` returns
`""""`, which is a 1-character text containing an ASCII quote `"`.
Fixes: #597
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `OBJ→` explodes an object into its sub-components. The various
sub-components are placed on the stack, and if necessary, information about the
size is places on the first level of the stack.
* Complex numbers are split into real and imaginary part (for rectangular form)
or modulus and argument (for polar form). The latter is an extension compared
to classical RPL, which always represent complex numbers in rectangular form.
* Unit objects are split into the value and unit expression. This is a deviation
from standard RPL, which places a unit object on the first level of the stack.
* Lists, programs and expressions are split into their individual components,
and the number of components is placed on the first level of the stack. For
programs, this is an extension of standard RPL. For expressions, this is a
deviation: HP calculators instead place only the top level object and
the arity.
* Arrays and vectors are split into their individual components, and the number
of elements is placed as a list on the first level of the stack. The dimension
list has one element for vectors, and two for matrices. If a given matrix is
not rectangular, then the command reports an `Invalid dimension` error.
* Fractions are split into numerator and denominator. This is a deviation from
the HP50G, which treats fractions as algebraic expressions.
* Text is evaluated as if it had been executed on the command line, in a way
similar to the `STR→` command.
Fixes: #596
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the `Compile` command, which evaluates a text as if
it was on the command line.
Fixes: #590
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `Size` command obeys to the description given in the HP50G advanced
reference, except that integers, equations and unit objects return a
size of 1, not some strange internal count that would be very
expensive to emulate on a totally different implementation.
Fixes: #588
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the RPL `case` statement, including a `case...when`
extension to traditional RPL.
The `case` statement can be used to select one case among many.
Inside a `case`, there is a list of conditions, each followed by
`then` or `when`. Code following `then` or `when` is executed when the
condition is met.
* A condition preceding `then` is a boolean condition, similar to the
condition in an `if` statement.
* A condition preceding `when` is a value that must match the current
value on the stack exactly.
For example, the following tests the sign of `X`:
```
X
case
dup 0 < then "Neg" end
dup 0 > then "Pos" end
"Zero"
end
```
The `when` syntax is useful to test exact values, for example, you can
check return the spelling of the ten digits with:
```
X
case
0 when "zero" end
1 when "one" end
2 when "two" end
3 when "three" end
4 when "four" end
5 when "five" end
6 when "size" end
7 when "seven" end
8 when "eight" end
9 when "nine" end
end
```
Fixes: #374
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This release provides statistics functions, scatter and bar plots, and flags.
**New features**:
* Statistics (#495) and linear regression (#569)
* File-based statistics (#571)
* `Sort`, `QuickSort`, `ReverseSort`, `ReverseQuickSort` and `RevList` (#572)
* Flags, i.e. `CF`, `SF`, `FS?`, etc (#43)
* Plot scaling commands such as `SCALE`, `CENTR`, `XRNG`, ... (#582)
* Add `CurveFilling` and `DrawPlotAxes` setting flags (#580)
* `ScatterPlot` (#577) and `BarPlot` (#579)
**Bugs**:
* Save settings enumerations as portable text (#565)
* Avoid infinite loop when reading at end of help file
* Repair behaviour of `-1 DIG`, broken by settings improvements
* Fix definition of `rpm` in units and units file
* Crash in `list::map` when called function errors out (#570)
* Fix editor horizontal movement when inserting commands (#576)
* Repair plotting demo (#583)
* Fix vertical position of axes in `DrawAxes` (#584)
* Very long drawing loop if `ppar` axes are backwards (#585)
**Improvements**:
* Sets editor selection correctly for command-line errors
* Ability to parse command and setting names in quotes, e.g. `'Radians'`
* Insert command names inside quotes (#575)
* Update documentation of implemented features (#569)
* Make `PlotParameters` a keyword (#578)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement flag commands both for standard numeric flags and
for system flags.
Fixes: #43
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement `Sort` (value sort), `QuickSort` (memory sort), `ReverseSort` (reverse
value sort), `ReverseQuickSort` (reverse memory sort).
Also implement `RevList` to reverse a list.
Also enhance the `comparison::compare` function to do lexical sorting of arrays.
Fixes: #572
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add `LinearRegression` command with the 4 fitting models available in
HP calculators, `LinearFit`, `ExponentialFit`, `LogarithmicFit` and
`PowerFit`.
Also add a new flag, `LinearFitSums` and `CurrentFitSums`, which
controls whether sum functions such as `ΣXY` return adjusted data
taking into account the current fitting model or not.
Related to: #569
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Names can be displayed in long form (original spelling), uppercase,
lowercase or capitalized.
This is similar to `CommandDisplayMode` but for names
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
A few quick bug fixes related to issues found in 0.4.11.
New features:
* `STO` and `RCL` to file (#375)
* Parsing of text containing quotes (#562)
Improvements:
* Rework file load/save dialog boxes
* Preliminary plumbing for statistics functions
Bugs:
* Error loading state files that contain directories (#559)
* Font setting for result was taken from editor font (#560)
* Crash running the `Shapes` demo (#563)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This release implements debugging, infinite RPL recursion, mixed
fractions, customizable units cycling, and restores missing entries in
the units menu.
New features:
* Allow customization of `Cycle` for units (#534)
* Allow infinite recursion in RPL code (#537)
* RPL program and expression debugging (#552) including after EXIT
* Mixed fractions such as `1 1/3` (#554)
* `BeepOn` and `SilentBeepOn` features (#280)
* `ScreenCapture` and keyboard shortcut (#434)
Bugs:
* Accept `2.3 FIX` and `#0 Background` (#557)
* Do not parse `67.200525` as a `decimal32` (#551)
* Bump low battery voltage to 2.550V (#553)
Improvements:
* Catalog shows all commands *containing* typed text (#556)
* Reorganize the units menu (#550) and restore missing units
* Remember menu page for `LastMenu` (#545)
* `SPC` key inserts `;` when inside parenthese (#499)
* Settings are now entirely defined by `ids.tbl` (#294)
* Improve user interface code consistency
* Improve GC handling of "just-past-end-of-object" pointers
* Remove the `execute()` RPL callback, rely on `evaluate()`
* Optimize allocation of 1-byte vs 2-byte opcodes
* Render `abs` as `abs` and not `norm` (accept `norm` while parsing)
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement screen capture, both as a keyboard shortcut and as
a programmable command (`ScreenCapture`).
This also fixes the order of some commands in the `ids.tbl`
file that were incorrectly marked as immediate when it would
make sense to make them programmable.
Fixes: #434
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add `MixedFractions` option to render `3/2` as `1 1/2`.
The opposite setting is `ImproperFractions`.
In addition, fractions can be rendered as small digits,
e.g. `¹²/₄₃`. This is controlled by the `SmallFractions` and
`BigFractions` settings.
The menus were updated accordingly.
Fixes#554
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Thanks to the RPL-stack evaluation loop, it is relatively easy to
implement debugging capabilities without impacting the performance of
the main evaluation loop significantly.
This commit implements the `Debug`, `SingleStep`, `MultipleSteps`,
`StepOver`, `StepOut`, `Halt`, `Continue` and `Kill` commands.
Fixes: #552
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Defer program and expression execution to the `program` class.
This allows us to remove `execute()`, which applies to every object,
with `run()`, which only exists for `program`. There is also a
`program::run()` static member that dynamic checks if we should run
`evaluate()` or if we can `run()`.
Also reimplement `while`, `until`, `if`, `ift`and `ifte` using a
deferred conditional so as to avoid C++ stack recursion.
This allows us to have really good behaviour on tail recursion, see
the `Collatz` and `CBench` examples in the `Demo.48S` file. For this
particular case, DB48X on DM42 is 25x faster than the HP50G, which
becomes slower as the recursion depth increases.
Fixes: #537
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The units file can contain a section beginning with `"=Cycle"`, which
specifies how `Cycle` should convert specific units. For example:
```
"=Cycle"
"in", "mm",
"mm", "cm"
"cm", "in"
"USD", "EUR"
"EUR", "CHF"
"CHF", "USD"
```
This enables quick unit conversions with a single key.
Fixes: #534
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add the `ShowBuiltinUnits` and `HideBuiltinUnits` commands to show or
hide built-in units when a units file is loaded.
Fixes: #542
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Load units from the `CONFIG/UNITS.CSV` file into memory.
Use that to populate the menus, and for the `lookup` function for conversions.
Fixes: #496
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Did a few additional focused optimizations that bring back another
100ms on the `NQueens` benchmark on the DM42.
This comes at the expense of about 4K of additional generated code,
which is probably as much as is reasonable to dedicate to this.
The numbers for the DM32 are now the best we ever had.
Fixes: #533
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Reimplement a range-based type-checking that does not require a memory
access and a bitmap check every time a type is checked.
This brings the `NQueens` execution time on DM42 from 1215 to 1175,
which is about 3%.
Fixes: #532
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Retrict the busy cursor drawing to key transitions:
* Starting to evaluate the command line
* Drawing the stack
* Entering / exiting the garbage collector
This leads to much less frequent animation, but gets us 20% back
on the `NQueens` benchmark on DM42 (from 1447 down to 1215ms).
Fixes: #531
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Copied the various commands from the HP50G's advanced reference manual,
and split them between implemented and not-implemented parts.
Copied the various entries in the `ids.tbl` file to build a section about
commands that only exist in DB48X.
Applied to magic Emacs-fu to add markdown links everywhere.
Fixes: #530
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `Cycle` command (EEX) for units works as follows:
- 100_m
- 1/10_km
- 0.1_km
- 1.0_dam
- 10.0_hm
- 100.0_m
Fixes: #517
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This release focuses on support for units, but also adds a large number of other
fixes and improvements.
New features:
* Power-off message indicating low-battery situation (#521)
* Add `ConvertToUnixPrefix` command and SI prefix menu keys (#513)
* Recognize all units that exist in the HP48, and a few more (#491)
* `UFACT` (`FactorUnit`) command (#512)
* Unit simplification, e.g. turn `1_m^2*s/s/m` into `1_m` (#506)
* Converting unity units to numbers (#502)
* `→Unit` command (#501)
* `UnitValue` (`UVAL`) command (#493)
* Implement "kibibytes" (`KiB`) and power-of-two SI prefixes (#492)
* Unit arithmetic (#481)
* Add `B->R` and `R->B` to `BasesMenu` (#488)
* Implement term reordering capability in `rewrite` (#484)
* `BaseUnits` (`UBase`) command (#483)
* Unit parsing for complex units, e.g. `1_cm^2` (#482)
* Unit arithmetic (#481) including automatic conversions (#480)
* `Convert` command (#480)
* Implement the `Cycle` command for unit objects
* Add `Å` character for angstroem (#477)
* Add `Merge state` to `State` system menu (#475)
* Use Unicode font to display the name of a program when executing it (#469)
* Allow incremental search to find digits and Unicode (#468)
* Add tool glyph to user interface font
Bug fixes:
* Do not parse symbols beyond input buffer (#524)
* Parse unit menu entries as expressions, not symbols (#523)
* Fix reduced-precision arithmetic (#521)
* Do not parse empty denominator as zero, e.g. `2/s` (#520)
* Do not parse a fraction inside a power, e.g. `X^2/3` (#519)
* Convert fractions to decimal in numeric mode (#516)
* Do not emit `mantissa_error` for valid numbers (#515)
* Apply negation correctly on unit objects (#500)
* Do not emit separator after trailing 0 in integer decimals (#489)
* Do not emit extra spacing before decimal separator (#485)
* Fix stack depth in one error case of `evaluate_function()`
* Fix display of next/previous icons for large menus (#478)
* Clear settings when loading a state (#474)
* Fix separators in whole part of decimal numbers when setting is not 3 (#464)
* Parse `(sin x)²+(cos x)²` correctly, as well as HP67 Mach example (#427)
Improvements:
* Rename `equation` as `expression` (#518) and `labelText` as `label_text`
* Do not update `LastArg` except for command line (#511)
* ToolsMenu: Connect units to the `UnitsConversionMenu` (#514)
* Display unit using `/` and `·`, e.g. `1_m·s^2/A` (#507)
* Show units menu for inverse units as `mm⁻¹` (#503)
* Display battery level more accurately, i.e. consider 2.6V "low" (#476)
* No longer acccept empty equations or parentheses, e.g. `1+()` (#487)
* Make `StandardDisplay` mode obey `MinimumSignificantDigits` (#462)
* Add algebraic evaluation function for easier evaluation in C++ code
* Reimplement `unit` type as a derivative of `complex` (#471)
* documentation: Use `🟨` and `🟦` for more commands (#467)
* Swap `Search` and `Copy` commands in `EditorMenu` (#466)
* `STO` stores variables at beginning of directory (#462)
* documentation: Add quickstart guide, used for video recording
* documentation: Add links to YouTube videos
* documentation: Add release notes
* documentation: Some typos and other improvements
* documentation: Rework section on keyboard mappings
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Saving `LastArg` is a relatively expensive operation, and while it is
extremely useful for interactive operations, is is much more rarely
used in programs.
The HP48 controls the saving of `LastArg` with flag -55, which is a
global setting, also shared by RPL when executing user programs. A
side effect is that if you run `'3*X-5' 'X' 0 ROOT`, the `LASTARG`
command gives a useless result (generally 0). An interactive user
might expect to get the parameters to the `ROOT` command, not the last
parameters used by some internal `ROOT` operation.
The code implemented in this change decouples that into two distinct
settings, one that controls the saving of `LastArg` for interactive
commands, i.e. either direct commands or for operations on the command
line, and another that controls the saving of `LastArg` while running
programs. The first one is enabled by default, the second one is
disabled by default.
An additional setting was defined to save the last stack.
Controling the saving of `LastArg` is important both for performance
and functionality.
Fixes: #511
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `equation` type does not really represent equations (it may)
but arithmetic expressions.
Fixes: #518
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement `ToUnit`, which takes a value and a unit and built a unit
with that value.
Fixes: #501
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Consider an equation like `''` or `'2+()`` as a syntax error.
This also removes one of the documented differences with HP RPL, which
was the possibility to write equations with empty slots, e.g. `'1+()`.
Fixes: #487
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement a term sorting and reordering capability.
Rewriting `u+v` to `v+u` will reorder names.
Also add this to `Expand` so that terms at the output of `Expand` are
automatically sorted corectly.
Fixes: #484
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement the `UBase` command, which converts to base units in
the metric system
Fixes: #483
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Also remove spaces in `_ A _ ` because that does not show up correctly in a real
markdown renderer, e.g. on GitHub.
Fixes: #467
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Relatively significant documentation update:
1. Move Story.txt to 2-Quickstart.md.
This will later be fleshed out to be a full Quickstart guide.
For now, it's simply a description of what to talk about in a movie
There was a bit of reordering to improve the flow as well.
2. Add links to issues and PRs to invite people to submit them
3. Move the Types section in file 3-Types.md
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Simplify the section on keyboard mapping to focus on keys that change,
removing all the menus excpet the most immediately useful ones.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This is a very basic implementation of unit objects.
Unit objects are treated as equations where the outermost object
is an ID_mkunit operator.
Fixes: #16
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Indicate that `{ 1 2 3} 2 -` does not work yet.
Indicate what `{ 1 2 3 4 5 } 2 /` is supposed to do.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Try to write the sections about the shift keys in a way that makes sense both on
the web and on the calculator.
Continuation of #450
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add a section that explains why the DM-32 keyboard layout is not
really usable without an overlay.
This is part of #450.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
There were two `Help` sections, one describing the built-in help, the other
describing the `Help` command itself. Merged the two.
Fixes: #451
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When `MinimumSignificantDigits` setting is -1, show `0.00055` in
`FIX 2` as `0.00` instead of `5.50E-4`
Fixes: #445
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Incorporate feedback from Cyrille de Brébisson about Maubert section.
Add section for HPCalc.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Allow images in the source markdown files, but skip them on calculator
Note that we need to skip them at runtime if we want to be able to
have them in the GitHub file correctly.
Fixes: #438
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The yellow and blue keys were rendered incorrectly, eating text that
was before them.
Additionally, on the calculator, it makes sense to use the same
symbols that are shown in the indicators area. Added code to support
that.
Fixes: #437
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Fixes the bug where the cursor was not blinking correctly unless some other
animation was happening (bug #407).
Add a setting to adjust the cursor blink rate, `CursorBlinkRate`.
Fixes: #407
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>