Releases: tomtheisen/stax
Stax 1.2.1
Minor bug fix release.
String literal compression did not work at all in 1.2.0. It just produced the same output in all cases, never yielding a smaller literal.
Stax 1.2.0
Stax 1.2.0
Interpreter deprecation
Up until now, I've been maintaining two implementations of the stax language "specification".
- The official web-based stax interpreter, as hosted on https://staxlang.xyz/
- A C# CLI implementation
Henceforth, only the first one will be maintained. The C# CLI was the first implementation, but it no longer serves much purpose, so it's deprecated. It will stay on version 1.1.10.
JS bigint
support now required
Up until now, native ES2020 bigint
was used opportunistically. For environments that didn't have support, the npm big-integer
package was used. This dependency as been removed. That means that stax intperpreter now requires a javascript environment with native bigint
support. Fortunately, that's almost everything.
It's not all removals though. Some stuff was added too.
Features
- New instruction:
:e
calculatesexp(x) = e ** x
for any numeric valuex
. - New output control characters. There are three control characters that have new behavior when output.
- Carriage Return - When encountered, clear the current line of output. Codepoint: 13. This is
"`3"
in a string literal. The|.
instruction outputs a single carriage return. - Form Feed - When encountered, clear all output. Codepoint: 12. This is
"`5"
in a string literal. The|:
instruction outputs a single form feed. - Backspace - Remove the previous character of output, if any. Codepoint: 8. There's no specific literal support. You can output one using
8]p
.
- Carriage Return - When encountered, clear the current line of output. Codepoint: 13. This is
- New instruction:
|,
. This will pause execution for one frame. (as defined byrequestAnimationFrame
) Useful for animations e.g.W|,|:30m|i+A:_|8A*@11+'*)
. - New "RNG"-ish instruction
|'
. The outputs of these use a deterministic PRNG that's seeded with the program's source code, so the output is repeatable, but it looks random. The behavior depends on the type of the top value on the stack.- Given an array, choose an element.
- Given an integer, choose a non-negative that's lower.
- Given a float, chose a non-negative float that's lower.
- New "eval" instruction
l
. Given a string of stax code, just execute it. The debugger will step over this code. It's not possible to step "into" the code evaluated in this way. - When output is produced during execution, the document automatically scrolls to show it.
- Fixed a bug that occurred when using the
\n\n+
input separator without providing any input. - Fixed a bug when using the Compress Literals button on a program containing unterminated string literals.
- Fixed a bug in the interpreter that would cause block terminators to get mis-parsed in certain contexts like
{{}{}F
. Thanks Razetime.
Stax 1.1.10
Stax 1.1.10
Language Features
- Base-64 symbol table constant,
V6
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
) - Logarithm instructions now work on a greater range of inputs, including those too big to fit in a floating point value.
- New caesar cipher instruction
:3
. For example,"xyz" 2
=>"zab"
Web UI Features
- More strategies are employed by the "Compress Literals" button.
- New keyboard shortcuts:
F9
to toggle side panel, and arrow keys to navigate sections.
Stax 1.1.9
Stax 1.1.9
Language Features
Vx
is a constant that contains the packed stax encoding as a 256 length array.- UTF-8 encoding and decoding instructions are available as
|k
and|K
respectively. 0xff
and0b100110
style numeric literals can now be implicitly parsed from input, or from a string using thee
instruction.
Web UI Features
- The "Golf" button will not remove necessary whitespace between numeric literals. For example,
0 1 2
will be golfed to01 2
. In general some programs require consecutive literals, but there's usually a shorter way in "practical" (lol) cases.
Stax 1.1.8
Stax 1.1.8
Language stuff
- New constants for
- lowercase vowels with 'y' -
Vy
- uppercase vowels with 'y' -
VY
- lowercase consonants without 'y' -
Vz
- uppercase consonants without 'y' -
VZ
- lowercase vowels with 'y' -
- Negative bit-shifts reverse direction. For example, a negative left shift becomes a right shift.
- New instruction:
:n
gets all the n-part factorizations of an integer (e.g.4
,3
=>[[1,1,4],[1,2,2],[1,4,1],[2,1,2],[2,2,1],[4,1,1]]
) - New instruction:
:C
gets the columns of an array of arrays without rectangularizing. Similar to transpose, but doesn't use a fill element. Instead, collapse the gaps. e.g.[[1,2],[],[3],[4,5,6]]
->[[1,3,4],[2,5],[6]]
- Bug fix: String conversion of floating point numbers was incorrect for numbers greater than 1 with a zero in the tenths place, such as
1.02
. - The power of 10 and power of 2 instructions
|A
and|2
now produces correct rational output for negative inputs.
User experience stuff
- New Hello world walkthrough linked in the docs on github
- Improved string reduction strategies for the Compress Literals button in the web app. None of these involve any language changes.
- In the web app, during program execution, the viewport scrolls down to track the most recent output. The debugger control buttons stay visible in a sticky header.
- In the web app, theme changes are distributed to all instances via BroadcastChannel. Just for fun.
- Stax sorts are stable, but javascript sort is only sometimes stable. The web app now leverages the stability of the underlying sort method, when applicable.
Stax 1.1.7
Stax 1.1.7
Language stuff
- New instruction:
:i
interleaves an array of arrays in a round-robin fashion. For example[[1, 2], [3], [4, 5, 6]]
becomes[1, 3, 4, 2, 5, 6]
. In a program - New instruction:
:x
escapes special regex characters in a string. For example"Yes? No."
becomes"Yes\? No\."
. In a program - New instruction:
B
converts a floating point number to a 64-element array of bits comprising the IEEE-754 representation. In a program - Infinite shorthand filter and map: Normally a trailing
f
orm
with no open block uses the rest of the program to filter or map the values in an array or an integer range created by an integer. The new behavior is that if a floating point infinity is encountered instead of an integer or array, then all positive integers will be used. For exampleVImJ
will print all positive squares. If you're using the web app, something will probably crash at some point, due to the unlimited output size. In a program - Attempting to access an element from an empty array using
@
,h
, orH
now immediately terminates normally instead of causing an error. If no output has been produced so far, that means the top of the stack will be printed implicitly, which is the normal behavior for programs that don't explicitly produce output. In a program - Bug fix:
|n
for multiset-xor could mutate one of its operands, possibly causing copied arrays to get modified elsewhere on the stack. - Bug fix:
|~
for last-index-of wouldn't find occurrences of the substring if it was at the very end. - Bug fix:
R
regex replacement went into an infinite loop when matching an infinite string and replacing using a block. - Implicit input eval can convert a single python-style triple-quoted multi-line string into a single value. See the execution part of the docs for more detail. In a program
User "experience" stuff
- Dark theme. So hot right now.
- "Dump stacks" button in the source tools pane. It's available for ASCII programs with line breaks. When the button is pressed, the memory state at the end of each line is added to the source code as a comment. If you can think of a better name for the button, I'll use it.
- Added a Mandelbrot generator as an example program. This is a nice way to show the new behavior of
K
for cross-map, which now produces output immediately rather than waiting for an entire line to output. - Turned off word wrap in the text areas.
- Improved the performance of many of the set-related operations, as if anyone cares about runtime performance. I finally figured out a way to do arbitrary sets and maps in javascript. It's not really obvious how to do it with arbitrary objects having value semantics.
- Integer ranges appear as "[1 .. 5]" in the debugger instead of "[1, 2, 3, 4, 5]". Example at breakpoint
- The literal compression tools got a little bit smarter. For example,
"HELLO WORLD"
compresses as`%s=I6]`^
, which is "Hello world" followed by an uppercase transform. Integer compressions have a few more strategies too. None of these involve any new language features. - Maybe it might work in Safari 10. Thanks Daniel.
Stax 1.1.6
Stax 1.1.6
The web UI some changes.
- A syntax for compressed integer literals is introduced. They look like string literals followed by
%
, which previously calculated the literal length. For example8479773284726973836978
can be represented by" s3BqIr!fqmn"%
. Don't worry about why; there's a tool to convert for you. - There's a new "Tools" panel in the web UI where the perma-link options, compression tools, and examples have been moved.
- There are a few additional tools in there too.
- Layout options to move around the input and debug panes
- New literal compressions: single integer (as mentioned above) and unicode-aware string compressor. e.g.
"π is a fundamental constant"
is "compressed" to"sru1&WI(l&G(G&Q]?K/QCE9pM(]&KQ'5%pU:"!
, which doesn't really look shorter. But it is ASCII, so a program that includes it can still be packed. - There is a button to compress all literals in a program inline. For instance
"code"P"golf"P
will turn into`~x`P`K0!`P
. It might be a little buggy.
- On load, the web UI will attempt to load the last program out of
sessionStorage
. This might be useful if you accidentally navigated away before saving a stax masterpiece, or perhaps a staxterpiece.
There are also some new instructions and bug fixes.
- New instruction:
|j
"rationalizes" a floating point number. For example1.8
->9/5
. Internally, this uses a Stern-Brocot binary search, only slightly different. This instruction represents the majority of effort in this release, even though it's only a few lines of code. - New instruction:
|N
gets the rounded-down nth root of a number. For example130 3
->5
. - New instruction:
:a
gets the binary representation of a number as a string, in a specified fixed width. For example22 8
->"00010110"
. - And another one for hexadecimal:
:h
. For example30 4
->"001e"
- New instruction:
:N
tests whether an integer is a specified nth power. For example,64 6
->1
. - Bug fix: When a shorthand generator is followed by an unbalanced trailing
}
, the default generator block^
was not applied. This is probably the most esoteric and pointless stax bug that will ever exist. Maybe? Anyway,1{G}g3}2%
now correctly produces 1, 3, 5 instead of 1, 1, 1. - Bug fix:
|q
for integer square root was inaccurate for very large values. It was implemented using 64-bit floats. Obviously that was never going to work. 1.2e3
-style floating point literals can be understood by the implicit input eval, as well as thee
instruction.- In regex replace
R
, when a block is used for the replacer, numbers are now implicitly converted to strings, eliminating the need to use$
to convert to string. - The modulus instruction
%
returns the first operand when the second is zero. It just felt right. - The multiplicity operator
:/
is supposed to test the number of times that one number can evenly divide another. When the first number is zero, just return infinity rather than looping forever.
Stax 1.1.5
Stax v1.1.5
The web UI has been slightly re-organized.
- Some of the tools have been moved into a drop-down menu.
- There are a few different editor layouts available.
- There's a button to reset the code, input, and all ui state.
New features
- There are several instructions that normally operate on two values, but are no-ops when there's only a single value between both of the runtime stacks. Henceforth, these instructions will move the single value to the main stack if it's on the input stack. Affected instructions are
I
M
S
t
T
+
*
. - New instruction:
|$
compares two values and produces -1, 0, or 1. - New instruction:
|{
compares two arrays for set-wise equality. - New instruction:
|}
compares two arrays for multiset equality. (same elements in any order) - Minimum or maximum of an array via
|m
and|M
produces positive and negative infinity respectively. - New instruction:
%
splits an array at an index and pushes both parts separately. This deprecates:/
. - New instruction:
:@
pops element from array at specified index. It pushes the remaining array and popped element separately. - New instruction:
:$
performs a cartesian product or power. When operating on an array and an integer, it will be the cartesian power. When operating on an array of arrays, it will be the cartesian product of sub-arrays. - New instruction:
:E
gets the first and last element of an array in a 2-array. - Many instructions that iterate over arrays are also able to iterate over implicit ranges
[1..n]
when they encounter an integer instead of an array. In the web implementation now, instead of materializing the entire array, they use a more efficient iterator structure. For example10000000mJ
will start print squares immediately, rather than allocating a 10-million element array first. - When debugging a program in the web interface, partial lines will immediately be visible in output. Formerly output only becamse visible when a newline terminated a line.
Bug fixes
- In the web UI, there were several instructions that internally used deprecated stax instructions. These internal usages were updated to supported instructions.
- Rotating an empty array using
|(
or|)
produces an empty array instead of crashing. |b
for multiset intersection mutated its second value, rather than making a copy first. If that array was copied from elsewhere, it could be incorrectly mutated as well.
Stax 1.1.4
Stax 1.1.4
New instructions
VN
pushes NaN:]
sets the bit(s) at the specified index(es) in an integer. It expects two intgers, or an integer followed by an array of integers.:[
unsets the bit(s) in the same way.::
toggles the bit(s) in the same way.
Instruction deprecations
for getting truthy indices from an array has been deprecated. Use:T
:1
instead.for inverting letter case is deprecated. Use:C
:~
instead.- Several instructions were shortened. The old ones continue to work, but have been deprecated.
Operation | New instruction | Old instruction |
---|---|---|
Exponentiation | # |
|* |
Bitwise And | I |
|& |
Bitwise Or | M |
|| |
Bitwise Xor | S |
|^ |
Scalar Minimum | t |
|m |
Sclara Maximum | T |
|M |
Note that array minimum maximum are still performed using |m
and |M
.
Behavior changes
- In the javascript targetted implementation, integers are now provided by ECMAScript bigints, where available. Otherwise,
big-integer
npm package is used. In the web UI, the current integer implementation is displayed near the build information. :~
sets the interior bits of an integer. It has been changed so that for non-positive inputs, it produces -1.
Stax 1.1.3
Stax 1.1.3
Language:
- Eval interprets
∞
and-∞
as floating point infinities. Works withe
and implicit input evaluation. - Directly printing an infinity and converting one to string using
$
consistently produce"∞"
. - Deprecated
:F
to get indices of falsy elements. Use:0
instead. - Bugfix: Multiplying array by negative integer mutated array in place before repeating.
- Remove-at
|@
works with negative indices. - Absolute difference
:-
now works with any kind of mixed numeric operands. - Totient function instruction
:t
works for input of 1. - Fibonacci instruction
|5
produces values for negative integers as if the sequence extended infinitely in both directions. - Bugfix: All-partitions
:!
and all-excerpts:e
work for empty array input (producing empty output) - Bugfix: Format number
j
produces specified number of decimal places, even for 0.0.
Web UI: (https://staxlang.xyz/)
- Copy button to copy entire output to clipboard
- Forgot to set foreground color in CSS. Oops.
- Limit the height of the automatically sized input box. For really large outputs, scrolling the whole document could be inconvenient.
- The automatic code type classifier is the thing that decides whether to show the "Pack", "Unpack", or "Golf" button. It's smarter now, and can distinguish between 5 kinds of program source.
- LooseAscii, // all ascii with extra whitespace or comments
- LowAscii, // ascii with no extra whitespace, but can't be packed, e.g. newline in string literal
- TightAscii, // minified ascii, could be packed
- Packed, // PackedStax, tightest representation known
- UnpackedNonascii, // Unpackable, due to emojis or something
- If a program is running, pressing esacpe stops the program instead of closing the quick reference panel.
Bonus:
- Fixed typos in documentation