Bitsy aims to be the best language to implement when writing your first compiler or interpreter. It is a resource for programmers learning about language design.
- Read more about the Bitsy language: BITSY.md
- See the canonical implementation: BitsySwift
- Read more about why Bitsy exists: Introducing Bitsy
- See the formal language grammar in BNF notation: GRAMMAR
BitsySpec aims to codify the definition of Bitsy in a series of tests that can be run against any Bitsy implementation. BitsySpec consists of two parts:
- A command line utility for running test specifications against any implementation of Bitsy
- A series of "specs", Bitsy programs paired with their expected output, to test the correctness of a given Bitsy implementation
BitsySpec is a useful tool for a first time language implementor. It provides fast, automated feedback on what works and whats left to do in your implementation, even enabling a test driven approach if desired.
This version of BitsySpec has been tested with
- macOS 12.3 (Monterey) and Ubuntu 20.04 LTS
- Xcode 13.3
- Swift 5.6
although basically only a Swift toolchain is required to build the project. Thus, it may also run perfectly fine on Windows.
Swift is an implementation detail of BitsySpec. Your compiler or interpreter can be implemented in virtually any language.
To 'install' BitsySpec, simply clone and build the repository. You must have the
Swift compiler available in your PATH
:
git clone https://github.com/apbendi/bitsyspec.git
cd bitsyspec
./build.sh
The runspecs
script can be used to conveniently run all specs included
in this repo with a provided implementation of Bitsy.
./runspecs path/to/my-bitsy
✅ Add Integer literals
✅ Allow for variable assignment and use
✅ Divide Integer literals
✅ Calculate the factorial of a number
✅ Calculate the first 10 numbers in the fibonacci sequence
✅ Branch on negative values with IFN
✅ Branch to ELSE on non-negative values with IFN
✅ Handle nested branching with IFN
✅ Branch to ELSE on positive values with IFP
✅ Handle nested branching with IFP...ELSE
✅ Handle nested branching with IFP
✅ Branch on positive values with IFP
✅ Branch on zero values with IFZ
✅ Branch to ELSE on non-zero values with IFZ
✅ Handle nested branching with IFZ
✅ Break from a LOOP construct
✅ Break from LOOP based on a counter
✅ Allow for nested LOOP constructs
✅ Calculate modulus between Integer literal
✅ Multiply several Integer literals
✅ Handle precedence with parentheses
✅ Handle precedence of mathematical operators
✅ Calculate all the primes up to 23
✅ Print an integer literal
✅ Print multiple integer literals
✅ Subtract Integer literals
✅ Allow use of unassigned variable identifiers
Once built, the command line utility in bin/
can also be pointed at any .bitsy
file
or directory containing multiple .bitsy
files. Each .bitsy
file found is run.
bin/bitsyspec
usage: bitsyspec bitsy_path spec_path
run spec(s) at spec_path using bitsy implementation at bitsy_path
If the file is prepended with a code comment
which defines the expected output,bitsyspec
will run the spec and report
success or failure. The comment must be in the
correct format.
*Note: bitsyspec
assumes your implementation takes a .bitsy
file as
its only argument, which it can immediately run. For example:
my-bitsy print42.bitsy
42
Depending on the details of your
implementation, you may have to wrap it in a shell script to achieve this. See
bitsy-swift
's
runbitsy
for an example.*
This repo contains a collection of specs
in the /specs
directory. The goal that the specs contained
there fully define Bitsy, such that:
- An implementation passing all specs is considered a valid Bitsy implementation
- A change to the language would be expressed by a change to or addition of a spec
At the moment, the specs are woefully short of this goal. Where an undefined behavior or ambiguity exists in the language, the behavior of the current canonical implementation (bitsy-swift) should be assumed. Please open an issue to report these!
Want to help us get closer to a fully defined and spec'd language? Consider Contributing
While Bitsy has been created partially in response to a perceived lack of approachable resources for learning language implementation, there are still some good places to start.
- Let's Build a Compiler; this paper from the late 80's (!) is an excellent introduction to compilation. The biggest downside is the use of Pascal and m68K assembly. While working through this tutorial, I partially translate his code to Swift.
- The Super Tiny Compiler is a great resource by James Kyle- a minimal, extremely well commented compiler written in JavaScript. Be sure to also checkout the associated conference talk
- A Nanopass Framework for Compiler Education (PDF)
- Stanford Compiler Course with Alex Aiken; a more advanced resource for learning some theory and going deeper.
I'll be speaking about creating Bitsy and implementing it in Swift at 360iDev and Indie DevStock. If you're attending either, be sure to say hello!
- BitsySwift - A Bitsy compiler written in Swift; the first-and-canonical implementation of Bitsy.
- Bitsy.NET - Bitsy implementations in C# and Visual Basic.
- xbitsy - A Bitsy interpreter written in Elixir.
- BitsyLLVM - A Bitsy compiler based on the LLVM compiler infrastructure.
Open a pull request to add your implementation to the list!
Contributions are welcome, and there's lots to do! BitsySpec, both the utility
and the spec suite, are considered version 0.1.0
at this point. Your feedback
and help are needed.
Discussions about changing the language are welcomed, and will be considered by their alignment with Bitsy's goal: to be a teaching and learning tool for programmers interested in language implementation.
Probably the best thing you could do right now is attempt your own implementation of Bitsy in your favorite language. Your experience in doing so will provide invaluable feedback!
Please be kind and respectful of others when participating!