2 unstable releases
0.2.0 | Oct 28, 2023 |
---|---|
0.1.0 | Oct 28, 2023 |
#2573 in Parser implementations
43KB
796 lines
Letterbox
An experimental esolang by Chris Natcharian.
The purpose of this crate is to define a simple, frontend-agnostic API with which more complex applications can run Letterbox programs in contained environments. Programs are interpreted from strings and create strings as output; data is stored independently and can be reused between programs.
Parts of this crate
LbStorage
represents a bank of 26 variables, each stored under a lowercase letter of the alphabet ('a' to 'z'). Each can hold one String or one float.LbToken
is an enum derived from Logos that defines the valid tokens of the Letterbox language. An instance ofLbToken::lexer
can convert a textual Letterbox program into individual tokens AND parse out their arguments.LbProgram
consumes a lexer containing zero or more tokens and executes them on someLbStorage
. It can also accept program arguments and expose program output.
For more details, see the crate docs.
To use this crate
letterbox-lang is available on crates.io. Add it as a dependency to your Cargo.toml file.
[dependencies]
...
letterbox-lang = "0.2.0"
If you want to contribute to this crate and make your own changes to the language, clone or fork the repo and add it to your project as a local dependency. For example:
[dependencies]
...
letterbox-lang = { path = "../letterbox-lang" }
How to write a Letterbox program
See the language documentation on its Esolang Wiki page.
How to run a Letterbox program
This is a minimal example of a Rust program that executes a Letterbox program. For a more full-featured example, see the Letterbox command line tool.
// import all required types
use letterbox_lang::prelude::*;
// get string representation of program
let program_string = "P'Hello world'".to_string();
// Create a lexer to consume the string
let lex: Lexer<LbToken> = LbToken::lexer(program_string);
// Create a new data storage struct on which the program will operate
let mut data: LbStorage = LbStorage::new();
// Get a string of whitespace-separated program arguments
let input_vec = "".to_string();
// Get an empty string with which to collect program output
let mut output_buffer = String::new();
// Define how many loop iterations are allowed before the program halts to prevent infinite loops
let loop_limit: usize = 100;
// Create a program struct which consumes the previous components
let mut program = LbProgram::new(
lex,
&mut data,
&input_vec,
&mut output_buffer,
loop_limit
).expect("Error initializing program");
// Run the program. This can be done only once.
let program_result: Result<(), String> = program.run();
// If the program results in a string, an error has occurred.
// Otherwise, the program succeeded.
if let Err(msg) = program_result {
println!("Error occurred: {}", msg);
}
else {
println!("{}", output_buffer); // prints Hello world!
}
Dependencies
~4.5MB
~54K SLoC