finish bf interpreter

This commit is contained in:
Sebastian Hugentobler 2025-05-28 21:28:25 +02:00
parent 2d739d98cc
commit 98dfbc8503
Signed by: shu
SSH key fingerprint: SHA256:ppcx6MlixdNZd5EUM1nkHOKoyQYoJwzuQKXM6J/t66M
6 changed files with 55 additions and 9 deletions

View file

@ -4,3 +4,6 @@
[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>> [>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>
]<<< ]<<<
] ]
This program doesn't terminate; you will have to kill it.
Daniel B Cristofani (cristofdathevanetdotcom)
http://www.hevanet.com/cristofd/brainfuck/

38
bf/game_of_life.bf Normal file
View file

@ -0,0 +1,38 @@
[life.b -- John Horton Conway's Game of Life
(c) 2021 Daniel B. Cristofani
http://brainfuck.org/]
>>>->+>+++++>(++++++++++)[[>>>+<<<-]>+++++>+>>+[<<+>>>>>+<<<-]<-]>>>>[
[>>>+>+<<<<-]+++>>+[<+>>>+>+<<<-]>>[>[[>>>+<<<-]<]<<++>+>>>>>>-]<-
]+++>+>[[-]<+<[>+++++++++++++++++<-]<+]>>[
[+++++++++.-------->>>]+[-<<<]>>>[>>,----------[>]<]<<[
<<<[
>--[<->>+>-<<-]<[[>>>]+>-[+>>+>-]+[<<<]<-]>++>[<+>-]
>[[>>>]+[<<<]>>>-]+[->>>]<-[++>]>[------<]>+++[<<<]>
]<
]>[
-[+>>+>-]+>>+>>>+>[<<<]>->+>[
>[->+>+++>>++[>>>]+++<<<++<<<++[>>>]>>>]<<<[>[>>>]+>>>]
<<<<<<<[<<++<+[-<<<+]->++>>>++>>>++<<<<]<<<+[-<<<+]+>->>->>
]<<+<<+<<<+<<-[+<+<<-]+<+[
->+>[-<-<<[<<<]>[>>[>>>]<<+<[<<<]>-]]
<[<[<[<<<]>+>>[>>>]<<-]<[<<<]]>>>->>>[>>>]+>
]>+[-<<[-]<]-[
[>>>]<[<<[<<<]>>>>>+>[>>>]<-]>>>[>[>>>]<<<<+>[<<<]>>-]>
]<<<<<<[---<-----[-[-[<->>+++<+++++++[-]]]]<+<+]>
]>>
]
[This program simulates the Game of Life cellular automaton.
It duplicates the interface of the classic program at
http://www.linusakesson.net/programming/brainfuck/index.php,
but this program was written from scratch.
Type e.g. "be" to toggle the fifth cell in the second row, "q" to quit,
or a bare linefeed to advance one generation.
Grid wraps toroidally. Board size in parentheses in first line (2-166 work).
This program is licensed under a Creative Commons Attribution-ShareAlike 4.0
International License (http://creativecommons.org/licenses/by-sa/4.0/).]

View file

@ -68,7 +68,7 @@ class Interpreter {
} }
if (instruction == ",") { if (instruction == ",") {
tape.current.data = promptAscii("> ");
} }
if (instruction == "[" and tape.current.data == 0) { if (instruction == "[" and tape.current.data == 0) {
@ -96,5 +96,5 @@ class Interpreter {
} }
} }
var interpreter = Interpreter("bf/helloworld.bf"); var interpreter = Interpreter("bf/game_of_life.bf");
interpreter.run(); interpreter.run();

2
lox/read_ascii.lox Normal file
View file

@ -0,0 +1,2 @@
var a = promptAscii("> ");
print a;

View file

@ -187,7 +187,7 @@ impl Callable for AsciiOut {
struct PromptAscii; struct PromptAscii;
impl Callable for PromptAscii { impl Callable for PromptAscii {
fn name(&self) -> String { fn name(&self) -> String {
"prompt_ascii".into() "promptAscii".into()
} }
fn arity(&self) -> usize { fn arity(&self) -> usize {
@ -207,14 +207,17 @@ impl Callable for PromptAscii {
.first() .first()
.ok_or(CallingError::CallFailed("arg not readable".into()))?; .ok_or(CallingError::CallFailed("arg not readable".into()))?;
if let Value::String(prompt) = prompt { if let Value::String(prompt) = prompt {
print!("{prompt} "); print!("{prompt}");
stdout().flush(); stdout()
.flush()
.map_err(|e| CallingError::CallFailed(e.to_string()))?;
let mut buffer = [0; 1]; let mut buffer = [0; 1];
stdin().read_exact(&mut buffer); stdin()
.read_exact(&mut buffer)
.map_err(|e| CallingError::CallFailed(e.to_string()))?;
todo!() Ok(Value::Number(OrderedFloat(buffer[0] as f64)))
// Ok(Value::Number(buffer[0] as char))
} else { } else {
Err(CallingError::CallFailed("prompt must be a string".into())) Err(CallingError::CallFailed("prompt must be a string".into()))
} }
@ -241,7 +244,7 @@ pub fn all() -> Vec<(String, Value)> {
Value::Callable((Rc::new(ReadFile {}), CallableType::Function)), Value::Callable((Rc::new(ReadFile {}), CallableType::Function)),
), ),
( (
"prompt".into(), "promptAscii".into(),
Value::Callable((Rc::new(PromptAscii {}), CallableType::Function)), Value::Callable((Rc::new(PromptAscii {}), CallableType::Function)),
), ),
] ]