zwreec is a compiler for interactive fiction in the Twee format (created by the Twine software) to Z-machine instructions (Z-code) which can be run with interpreters like frotz or gargoyle.
This project is build using the Rust language and Cargo as package manager. It is structured as a library, so that it can be used by other Rust projects, but it also contains a command line binary implementation, which can be used as a fully functioning compiler.
You can download a prebuilt version of our binary implementation for 64-bit Linux and OS X.
To build zwreec from source, you will need to have both Rust 1.1.0 and Cargo installed on your system. You can download the Rust binaries on their website, by using your system's package manager or by running this in your shell:
curl -sSf https://static.rust-lang.org/rustup.sh | sh
Cargo should be installed alongside current Rust binaries.
After installing Rust, zwreec can be complied using these commands:
git clone https://github.com/Drakulix/zwreec
cd zwreec
cargo build --release
The resulting binary can be found at target/release/zwreec
.
Usage: zwreec [-hV] [-vqwf] [-l [LOGFILE]] [-o OUTPUT] INPUT
Options:
-v --verbose Be more verbose. Can be used multiple times.
-q --quiet Be quiet
-w --overwrite Overwrite output file if necessary.
-l --logfile [LOGFILE]
Specify log file (additionally to logging on stderr)
-o FILE Name of the output file
-h --help Display this help and exit
-V --version Display version
Additional help:
--help -v Print the full set of options zwreec accepts
This repository contains a few sample Twee-Files used for the library's integration tests. They are located under tests/integration/should-compile/
. To compile them you can use the following command:
$ ./target/release/zwreec -o CurrentStatus.z8 ./tests/integration/should-compile/CurrentStatus.twee
Edit the above line to compile different twee adventures.
Then you can run ./CurrentStatus.z8
with your favorite Z-code interpreter.
For more information on supported Twee functions see this wiki site.
The library uses a fork of rustlex to to do lexical analysis.
To use zwreec in your project you can add it as a dependency to your Cargo.toml
.
[dependencies.zwreec]
git = "https:://github.com/Drakulix/zwreec"
Then you can use it in your crate root:
extern crate zwreec;
The following example is itself a full working command line compiler. It is a simpler version of the Reference Binary Implementation.
extern crate zwreec;
use std::env;
use std::error::Error;
use std::fs::File;
use std::path::Path;
fn main() {
let mut args: Vec<String> = env::args().collect();
if args.len() != 2 { panic!("Need exactly one input file!"); }
let cfg = zwreec::config::Config::default_config();
let mut input = match File::open(Path::new(&args[1])) {
Ok(file) => file,
Err(why) => { panic!("Couldn't open input: {}", Error::description(&why)); }
};
let mut output = match File::create(Path::new("a.z8")) {
Ok(file) => file,
Err(why) => { panic!("Couldn't open output: {}", Error::description(&why)); }
};
zwreec::compile(cfg, &mut input, &mut output);
}
zwreec was developed by students as part of the course "Softwareprojekt Übersetzerbau" in 2015.
You can find the extensive autogenerated documentation of zwreec and its dependencies under drakulix.github.io/zwreec/.
You can contribute to zwreec by opening issues and creating pull requests. To contribute code to the project make sure to document every function with a rustdoc compatible docstring. The project is configured so that the compiler will emit warnings if code is not documented properly.
Also make sure to run the zwreec test suite to check if everything is working correctly and is not generating any warnings by running
cargo test
in your shell. Try compiling some of the integration tests in tests/integration/should-compile
yourself and visually inspect them in your Z-machine interpreter(s). If you change/add Z-machine opcodes try testing them on as many interpreters as possible. If you need further support feel free to open an issue. We will try to respond in a timely manner but you know how life turns out sometimes… We can't promise anything.