Skip to content

Instantly share code, notes, and snippets.

@oldmammuth
Forked from fivemoreminix/main.rs
Last active January 14, 2021 16:43
Show Gist options
  • Save oldmammuth/9f6df4d60356c5289aed2182ec79d5b6 to your computer and use it in GitHub Desktop.
Save oldmammuth/9f6df4d60356c5289aed2182ec79d5b6 to your computer and use it in GitHub Desktop.
Simple Brainfuck to C traspiler written in Rust.
// "Hello, world!"
static PROGRAM: &'static str = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
fn main() {
let tokens = tokenize(PROGRAM);
//println!("{:?}", tokens);
let generated_code = generate(&tokens);
println!("{}", generated_code);
}
#[derive(Debug, PartialEq, Copy, Clone)]
enum Token {
Add, // +
Sub, // -
Right, // >
Left, // <
Read, // ,
Write, // .
BeginLoop, // [
EndLoop, // ]
}
use self::Token::*;
fn tokenize(input: &str) -> Vec<Token> {
let mut tokens = Vec::<Token>::new();
let mut chars = input.chars();
while let Some(c) = chars.next() {
match c {
'+' => tokens.push(Add),
'-' => tokens.push(Sub),
'>' => tokens.push(Right),
'<' => tokens.push(Left),
',' => tokens.push(Read),
'.' => tokens.push(Write),
'[' => tokens.push(BeginLoop),
']' => tokens.push(EndLoop),
_ => {}
}
}
tokens
}
fn generate(tokens: &[Token]) -> String {
let mut output = String::from(include_str!("preface.c"));
// Tabs are just for pretty printing indented text.
let mut indentation = 1u32;
fn indent(count: u32) -> String {
let mut indentation = String::new();
for _ in 0..count {
indentation.push_str(" "); // 4-space indentions
}
indentation
}
for &token in tokens {
match token {
Add => {
// Increment the value at the selected cell
output.push_str(&indent(indentation));
output.push_str("++*ptr;\n");
}
Sub => {
// Decrement the value at the selected cell
output.push_str(&indent(indentation));
output.push_str("--*ptr;\n");
}
Right => {
// Change our selected cell to the next to the right
output.push_str(&indent(indentation));
output.push_str("++ptr;\n");
}
Left => {
// Change our selected cell to the next to the left
output.push_str(&indent(indentation));
output.push_str("--ptr;\n");
}
Read => {
// Read a single character into the selected cell
output.push_str(&indent(indentation));
output.push_str("*ptr=getchar();\n");
}
Write => {
// Print the character at the selected cell
output.push_str(&indent(indentation));
output.push_str("putchar(*ptr);\n");
}
BeginLoop => {
// Begin a loop at the current cell
output.push_str(&indent(indentation));
output.push_str("while (*ptr) {\n");
indentation += 1;
}
EndLoop => {
// Close a loop
indentation -= 1;
output.push_str(&indent(indentation));
output.push_str("}\n");
}
}
}
output.push_str("}\n");
output
}
#include "stdio.h"
int main()
{
// Init
char tape[20000] = {0};
char *ptr = tape;
// Transpiled Brainf* Code
#!/bin/sh
cargo run > hello_world_brainf.c
gcc hello_world_brainf.c -o hello_world
./hello_world
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment