Skip to content

Instantly share code, notes, and snippets.

@judofyr
Last active December 8, 2023 11:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save judofyr/7ed4b52af2107119d4cc1f989ca63201 to your computer and use it in GitHub Desktop.
Save judofyr/7ed4b52af2107119d4cc1f989ca63201 to your computer and use it in GitHub Desktop.
Brainfuck macro in Rust
#![recursion_limit="100"]
use std::io;
use std::io::{Write, Read};
use std::num::Wrapping;
struct Tape<'a> {
stdin: &'a mut Read,
stdout: &'a mut Write,
data: Vec<Wrapping<u8>>,
pos: usize
}
impl<'a> Tape<'a> {
fn new(len: usize, stdin: &'a mut Read, stdout: &'a mut Write) -> Tape<'a> {
Tape {
data: vec![Wrapping(0); len],
pos: 0,
stdin: stdin,
stdout: stdout
}
}
fn dot(self: &mut Self) {
self.stdout.write(&[self.data[self.pos].0]).unwrap();
}
fn comma(self: &mut Self) {
let mut data: [u8; 1] = [255]; // EOF is -1
self.stdin.read(&mut data).unwrap();
self.data[self.pos] = Wrapping(data[0]);
}
}
macro_rules! bf {
($var:ident; > $($rest:tt)*) => { $var.pos += 1; bf!($var; $($rest)*); };
($var:ident; < $($rest:tt)*) => { $var.pos -= 1; bf!($var; $($rest)*); };
($var:ident; + $($rest:tt)*) => { $var.data[$var.pos] += Wrapping(1); bf!($var; $($rest)*); };
($var:ident; - $($rest:tt)*) => { $var.data[$var.pos] -= Wrapping(1); bf!($var; $($rest)*); };
($var:ident; . $($rest:tt)*) => { $var.dot(); bf!($var; $($rest)*); };
($var:ident; , $($rest:tt)*) => { $var.comma(); bf!($var; $($rest)*); };
($var:ident; [ $($body:tt)* ] $($rest:tt)* ) => {
while $var.data[$var.pos].0 != 0 {
bf!($var; $($body)*);
};
bf!($var; $($rest)*);
};
($var:ident; .. $($rest:tt)*) => { bf!($var; . . $($rest)*); };
($var:ident; >> $($rest:tt)*) => { bf!($var; > > $($rest)*); };
($var:ident; << $($rest:tt)*) => { bf!($var; < < $($rest)*); };
($var:ident; -> $($rest:tt)*) => { bf!($var; - > $($rest)*); };
($var:ident; <- $($rest:tt)*) => { bf!($var; < - $($rest)*); };
($var:ident;) => { };
}
fn main() {
let mut out = io::stdout();
let mut sin = io::stdin();
// https://esolangs.org/wiki/Brainfuck#Cell_Size
{
let mut t = Tape::new(5, &mut sin, &mut out);
bf! { t;
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
[>++++<-]>[<++++++++>-]<[>++++++++<-]
+>[>
++++++++++[>+++++<-]>+.-.[-]<
<[-]<->] <[>>
+++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
++++++++[>+++++++<-]>.[-]<
<-]<
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-.
};
}
// https://esolangs.org/wiki/Brainfuck#Cat
{
let mut t = Tape::new(1, &mut sin, &mut out);
bf! { t; ,+[-.,+] };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment