fork download
  1. use std::collections::VecDeque;
  2. use std::collections::HashMap;
  3. enum Token {
  4. Inc,
  5. Dec,
  6. IncPtr,
  7. DecPtr,
  8. StartLoop,
  9. EndLoop,
  10. Input,
  11. Output,
  12. }
  13. impl Token{
  14. fn tokenize(c:char) -> Option<Token>{
  15. match c{
  16. '+' => Some(Token::Inc),
  17. '-' => Some(Token::Dec),
  18. '>' => Some(Token::IncPtr),
  19. '<' => Some(Token::DecPtr),
  20. '[' => Some(Token::StartLoop),
  21. ']' => Some(Token::EndLoop),
  22. ',' => Some(Token::Input),
  23. '.' => Some(Token::Output),
  24. _ => None,
  25. }
  26. }
  27. fn tokenize_from_array(char_array: Vec<char>)->Vec<Token>{
  28. let mut token_array: Vec<Token> = Vec::new();
  29. for c in char_array{
  30. if let Some(token) = Token::tokenize(c){
  31. token_array.push(token);
  32. }
  33. }
  34. return token_array;
  35. }
  36. fn get_loop_token_ptr(token_array:&Vec<Token>)->
  37. (HashMap<u32,u32>,HashMap<u32,u32>){
  38. let mut start_end_map : HashMap<u32,u32> = HashMap::new();
  39. let mut end_start_map : HashMap<u32,u32> = HashMap::new();
  40. let mut start_ptr_stack : Vec<u32> = Vec::new();
  41. let mut ptr : u32 = 0;
  42. for token in token_array{
  43. match *token{
  44. Token::StartLoop => {
  45. start_ptr_stack.push(ptr);
  46. },
  47. Token::EndLoop => {
  48. if let Some(start_ptr) = start_ptr_stack.pop(){
  49. start_end_map.insert(start_ptr, ptr);
  50. end_start_map.insert(ptr, start_ptr);
  51. }else{
  52. panic!("Too many ']' tokens detected!");
  53. }
  54. },
  55. _ => {}
  56. }
  57. ptr+=1;
  58. }
  59. if ! start_ptr_stack.is_empty(){
  60. panic!("Too many '[' tokens detected!");
  61. }
  62. return (start_end_map, end_start_map);
  63. }
  64. //fn for token '+'.
  65. fn inc_mem_val(memory :&mut Vec<u32>, memory_ptr:u16){
  66. if let Some(val) = memory.get_mut(memory_ptr as usize) {
  67. *val += 1;
  68. }
  69. }
  70. //fn for token '-'.
  71. fn dec_mem_val(memory :&mut Vec<u32>, memory_ptr:u16){
  72. if let Some(val) = memory.get_mut(memory_ptr as usize) {
  73. *val -= 1;
  74. }
  75. }
  76. //fn for token '>'.
  77. fn inc_mem_ptr(memory_ptr:&mut u16){
  78. *memory_ptr +=1;
  79. }
  80. //fn for token '<'.
  81. fn dec_mem_ptr(memory_ptr:&mut u16){
  82. *memory_ptr -=1;
  83. }
  84. //fn for token '['.
  85. fn jump_loop_end_token_if_mem_0(mem_val:Option<&u32>,
  86. loop_start_end_token_ptr_map:&HashMap<u32,u32>,
  87. token_ptr : &mut u32){
  88. if let Some(val) = mem_val{
  89. if *val != 0{return;}
  90. }else{return;}
  91. if let Some(end_ptr) = loop_start_end_token_ptr_map.get(token_ptr){
  92. *token_ptr = *end_ptr;
  93. }else{
  94. panic!("no pair ']' token found.");
  95. }
  96. }
  97. //fn for token ']'.
  98. fn jump_loop_start_token_if_mem_not_0(mem_val:Option<&u32>,
  99. loop_end_start_token_ptr_map:&HashMap<u32,u32>,
  100. token_ptr : &mut u32){
  101. if let Some(val) = mem_val{
  102. if *val == 0{return;}
  103. }else{return;}
  104. if let Some(start_ptr) = loop_end_start_token_ptr_map.get(token_ptr){
  105. *token_ptr = *start_ptr;
  106. }else{
  107. panic!("no pair '[' token found.");
  108. }
  109. }
  110. //fn for token ','.
  111. fn put_char_from_input_to_mem(input_char_array:&mut VecDeque<char>,
  112. memory :&mut Vec<u32>, memory_ptr:u16){
  113. if let Some(val) = memory.get_mut(memory_ptr as usize){
  114. if let Some(c) = input_char_array.pop_front() {
  115. *val = u32::from(c);
  116. }
  117. }
  118. }
  119. //fn for token '.'.
  120. fn join_output_char_to_str(output_char:Option<char>, output_str:&mut String){
  121. if let Some(c) = output_char{
  122. output_str.push(c);
  123. }
  124. }
  125. }
  126. struct BfInterpreter{
  127. token_array : Vec<Token>,
  128. token_ptr : u32,
  129. memory : Vec<u32>,
  130. memory_ptr: u16,
  131. input : VecDeque<char>,
  132. output : String,
  133. loop_start_end_token_ptr_map : HashMap<u32,u32>,
  134. loop_end_start_token_ptr_map : HashMap<u32,u32>,
  135. }
  136. impl BfInterpreter{
  137. fn init(src: &str, input: &str) -> BfInterpreter {
  138. let ta = Token::tokenize_from_array(src.chars().collect::<Vec<char>>());
  139. let (lsetpm,lestpm) = Token::get_loop_token_ptr(&ta);
  140. BfInterpreter{
  141. token_array : ta,
  142. token_ptr : 0,
  143. //Brainf*ck's number of memory cell is defined to be larger than 30,000.
  144. //So this program should reserve size of u16::max_value(),
  145. //which is expected to be 2^16 = 65,536.
  146. memory : vec![0 ; u16::max_value() as usize],
  147. memory_ptr : 0,
  148. input : input.chars().collect(),
  149. output : String::from(""),
  150. loop_start_end_token_ptr_map : lsetpm,
  151. loop_end_start_token_ptr_map : lestpm,
  152. }
  153. }
  154. fn exec(&mut self){
  155. let token_array = &self.token_array;
  156. while let Some(token) = token_array.get(self.token_ptr as usize){
  157. match *token{
  158. Token::Inc => {
  159. Token::inc_mem_val(&mut self.memory, self.memory_ptr);
  160. }
  161. Token::Dec => {
  162. Token::dec_mem_val(&mut self.memory, self.memory_ptr);
  163. }
  164. Token::IncPtr => {
  165. Token::inc_mem_ptr(&mut self.memory_ptr);
  166. }
  167. Token::DecPtr => {
  168. Token::dec_mem_ptr(&mut self.memory_ptr);
  169. }
  170. Token::StartLoop => {
  171. Token::jump_loop_end_token_if_mem_0(
  172. self.memory.get(self.memory_ptr as usize),
  173. &self.loop_start_end_token_ptr_map,
  174. &mut self.token_ptr
  175. );
  176. }
  177. Token::EndLoop => {
  178. Token::jump_loop_start_token_if_mem_not_0(
  179. self.memory.get(self.memory_ptr as usize),
  180. &self.loop_end_start_token_ptr_map,
  181. &mut self.token_ptr
  182. );
  183. }
  184. Token::Input => {
  185. Token::put_char_from_input_to_mem(
  186. &mut self.input,
  187. &mut self.memory, self.memory_ptr
  188. );
  189. }
  190. Token::Output => {
  191. Token::join_output_char_to_str(
  192. self.memory.get(self.memory_ptr as usize)
  193. .and_then(|i| std::char::from_u32(*i)),
  194. &mut self.output);
  195. }
  196. }
  197. self.token_ptr += 1;
  198. }
  199. }
  200. fn output(&self)->&str{
  201. return &self.output;
  202. }
  203. }
  204. fn main (){
  205. let src: &str =
  206. "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
  207. ------------.<++++++++.--------.+++.------.--------.>+.";
  208. let input : &str = "";
  209. let mut bf = BfInterpreter::init(src, input);
  210. bf.exec();
  211. println!("{}",bf.output());
  212. }
Success #stdin #stdout 0s 14960KB
stdin
Standard input is empty
stdout
Hello, world!