StackAssembly 0.1: Initial Implementation
published onIntroduction
StackAssembly is a minimalist, stack-based, assembly-like programming language. Here's a small taste:
# Push `0` to the stack.
0
increment:
# Increment the value on the stack by `1`.
1 +
# If the value on the stack is smaller than `255`, jump
# to `increment:`.
0 copy 255 <
@increment
jump_if
# Looks like we didn't jump to `increment:` that last time,
# so the value must be `255` now.
255 = assert
If you want to learn more about the language, the GitHub repository is the best place to start.
I previously posted about the design of StackAssembly's initial version, which I've now implemented. Since the result is faithful to the original design, I'm not going to repeat myself here, and will only call out the few things I added.
Additions to the Initial Design
Comments
Leaving comments out of the initial design was questionable in the first place. But I wanted to implement the initial version within a few weeks, saw the danger of overloading it, and decided to err on the side of caution.
Overall, I still agree with that decision. But it made sense to include comments regardless. Implementing them took very little effort, and it turned out I needed them.
After a bit of back and forth, I decided that for now, I just want to provide a set of examples as the primary form of documentation. And those only made sense with comments.
# This is an example of StackAssembly code.
1 2 +
assert
For these examples, I also needed an assert operator. assert takes one input and triggers an "assertion failed" effect, if that input is zero.
-1 1 < assert
This provides some advantages to the examples:
- The examples consist of multiple parts, and I didn't want to leave values on the stack, from one part to the next.
assert(in combination with=) was an elegant way to remove those values, while also documenting what they are. - As a side effect, the examples now test themselves, and can be checked in the CI build. That ensures they stay up to date.
Hexadecimal Integers
The initial design included bitwise operations, and the lack of hexadecimal (or octal, or binary) integers made the tests for those hard to read. I initially made do by adding additional comments.
But when I wrote the examples, I reversed my decision and implemented hexadecimal integers. That was absolutely trivial, made any code involving bitwise operators much more clear, and I should have just done it in the first place.
0xf0f0 0xff00 xor
Conclusion
So that's it! Just a few additions to the initial design; all rather minor, but still quite useful. If you want to see more of the rest of the language, check out the repository or the design document.
The implementation only took a few weeks. This means that I met one of my goals, a quick first milestone that is self-contained and satisfying. The other goal, a language that can support real code, well, we'll see.
That's what's next: playing around with the language, writing some code, and figuring out what's still missing.