Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
//! Leveraging tuples to make a statically typed, concatenative EDSL in Rust.
//!
//! I'm not sure how practical it really is – Rust's syntax can make it a little
//! hard to read, but it's fun to play around with it. The neat thing is how
//! little copying occurs. Everything is moved in and out by-value in a pipeline.
//!
//! Thanks goes to [Tekmo on reddit](http://www.reddit.com/r/programming/
//! comments/1zzom4/using_functionlength_to_implement_a_stack_language/cfyibsr)
//! for the idea.
//!
//! To run the tests:
//!
//! ~~~
//! rustc --test stack_edsl.rs && ./stack_edsl
//! ~~~
use std::fmt;
fn pop<T, Stack>((_, stack): (T, Stack)) -> Stack {
stack
}
fn dup<T: Clone, Stack>((x, stack): (T, Stack)) -> (T, (T, Stack)) {
(x.clone(), (x, stack))
}
fn swap<T, Stack>((x, (y, stack)): (T, (T, Stack))) -> (T, (T, Stack)) {
(y, (x, stack))
}
fn eq<Stack, T: Eq>((x, (y, stack)): (T, (T, Stack))) -> (bool, Stack) {
(x == y, stack)
}
fn add<Stack, T: Add<T, T>>((x, (y, stack)): (T, (T, Stack))) -> (T, Stack) {
(x + y, stack)
}
fn mul<Stack, T: Mul<T, T>>((x, (y, stack)): (T, (T, Stack))) -> (T, Stack) {
(x * y, stack)
}
fn square<Stack, T: Clone + Mul<T, T>>(stack: (T, Stack)) -> (T, Stack) {
mul(dup(stack))
}
#[allow(dead_code)]
fn show<T: fmt::Show, Stack>((x, stack): (T, Stack)) -> (T, Stack) {
println!("{}", x); (x, stack)
}
#[test]
fn test(){
assert_eq!(pop((4, (2, ()))), (2, ()));
assert_eq!(dup((3, ())), (3, (3, ())));
assert_eq!(swap((4, (2, ()))), (2, (4, ())));
assert_eq!(eq((4, (2, ()))), (false, ()));
assert_eq!(eq((4, (4, ()))), (true, ()));
assert_eq!(add((4, (2, ()))), (6, ()));
assert_eq!(mul((4, (2, ()))), (8, ()));
assert_eq!(square((3, ())), (9, ()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment