13 unstable releases (3 breaking)
0.4.1 | Aug 17, 2023 |
---|---|
0.4.0 | Aug 3, 2023 |
0.3.2 | Jul 17, 2023 |
0.2.1 | Jul 16, 2023 |
0.1.3 | Jul 10, 2023 |
#385 in Programming languages
95KB
2K
SLoC
nand7400
An assembler library for the nand7400 computer, created by me during my internship at The WCL.
This library is built in Rust, and also binds directly to Swift as well, so you can treat it like a standard Swift package (see Usage: Swift). Swift bindings are made because the nand7400 computer is mainly programmed via an iOS/MacOS app.
Usage
Rust
You can use this library as any other standard rust library, no strings attached. Just add it to your Cargo.toml
and you're good to go.
Swift
This library is almost plug-and-play with Xcode
. To use this with Xcode
, you need to go into Targets > (your build target) > Build Phases > Link Binary With Libraries
and add the Nand7400
framework inside the Nand7400
library (The framework is the icon that looks like a bank or museum under the package). Otherwise, you will get a module not found
error, because Xcode
doesn't know where to find the framework powering the library.
Syntax
Literals
Literals are simply any number in decimal (base 10), hexidecimal (base 16), octal (base 8), or binary (base 2). Literals can have a prefix, either +
or -
in front of them. This signifies that the literals are signed (can go into the negatives), and will be parsed as such. If there is no prefix, then the literal is unsigned (cannot go into the negatives).
<+|-><0x|0o|0b><0-9a-fA-F>
Identifiers
An identifier is any string that starts with a letter and is followed by any number of letters, numbers, or underscores.
<a-zA-Z_><a-zA-Z0-9_>
Instructions
Instructions are an identifier that represent a specific opcode. They can be followed by a number of argumens, which can be either identifiers or literals. There can only be 1 instruction per line, and instructions are delimited by newlines.
<identifier> <identifier|literal...> <\n>
Labels
Labels represent the location in memory of the instruction right after them, and are identifiers followed by a colon. An instruction can (but doesn't need to) follow the label in the same line, or can be on the next line.
<identifier>: <instruction?> <\n>
Building
IMPORTANT!
You don't need to do any of this to actually use the library -- just follow the instructions above in Usage. This is only if you want to build the library yourself, on your own machine.
Lay of the Land
To get started building the library, you should first familiarize yourself with the project structure. There are 3 main packages in this repository:
-
nand7400
: The rust library itself. It has no dependencies to UniFFI or Swift, and is the core of the project.nand7400/examples
: Examples using the library in both Rust and Swift.
-
nand7400-ffi
: This is the binding library that is the glue between Rust and Swift. It does this through Mozilla's UniFFI, and it also contains a wrapper rust library that is used to executeuniffi-bindgen
commands. -
nand7400-bindings/swift
: The Swift package that binds to thenand7400
rust library. The package file for this isPackage.swift
.
Rust
To build the rust library, simply run cargo build
in the root directory of the project. You can use this library as any other standard rust library.
Swift
IMPORTANT!
If you change the
uniffi
version in thenand7400-ffi
package, you MUST change it EVERYWHERE else in the package. Otherwise, it will not compile correctly in Xcode (you will see a symbols missing/undefined error).
To build this library for Swift, you'll need a Mac with Xcode 12 or later that has the standard rust toolchain (rustup
and cargo
) installed. To build, run make package-swift
-- this automatically calls make setup-build
which sets up everything needed for building the package. This creates a Nand7400FFI.xcframework
folder, a Nand7400FFI.xcframework.zip
file, and a Nand7400FFI.xcframework.zip.sha256
checksum in the target
directory. You can then either upload Nand7400FFI.xcframework.zip
to be downloaded by the package, or point the package binary target path to the Nand7400FFI.xcframework
file.
When using this library, if NAND7400_LOCAL
is set, then it will automatically search for a local build of the XCFramework. Otherwise, it will download the XCFramework from the Github release.
Resources on how I did this
These are the resources I used to help me learn how to bind Rust into Swift:
Maybe you'll find them helpful too!
TODO:
- Add Swift bindings.
- Labels are 16 bits wide, not 8 (and count as 2 arguments respectively).
- Github/CircleCI(?) workflow for testing.
- Automatic building + packaging of the library.
- Automatic Crates.io uploads.
- Automatic Github releases + XCFramework uploads.
- Clean up code.
- Add more tests.
Dependencies
~4–6MB
~103K SLoC