output parameter, buffer by default

This commit is contained in:
mehbark 2025-07-03 21:04:42 -04:00
parent 6b3497c5fc
commit 2d22cd689e
4 changed files with 26 additions and 14 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
flamegraph.svg
perf.data

View file

@ -45,11 +45,11 @@ ymin ->y0
(64 iter + put) (64 iter + put)
ite ite
x0 0.03 + ->x0 x0 0.0055 + ->x0
) )
while! while!
10 put 10 put
y0 0.08 + ->y0 y0 0.021 + ->y0
xmin ->x0 xmin ->x0
) )
while! while!

View file

@ -45,11 +45,11 @@ impl<'a> Val<'a> {
} }
} }
fn call(&self, stack: &mut Stack<'a>) { fn call(&self, stack: &mut Stack<'a>, out: &mut impl io::Write) {
match self { match self {
Val::Num(n) => stack.push(Val::Num(*n)), Val::Num(n) => stack.push(Val::Num(*n)),
Val::Fun { insts, env } => { Val::Fun { insts, env } => {
eval(insts, stack, &env.clone()); eval(insts, stack, &env.clone(), out);
} }
} }
} }
@ -184,7 +184,12 @@ impl<'a> Stack<'a> {
} }
} }
fn eval<'a>(insts: &'a [Inst<'a>], stack: &mut Stack<'a>, env: &Rc<RefCell<Env<'a>>>) { fn eval<'a>(
insts: &'a [Inst<'a>],
stack: &mut Stack<'a>,
env: &Rc<RefCell<Env<'a>>>,
out: &mut impl io::Write,
) {
for i in insts { for i in insts {
match i { match i {
Inst::Set(var) => env.borrow_mut().set(var, stack.pop_default()), Inst::Set(var) => env.borrow_mut().set(var, stack.pop_default()),
@ -216,15 +221,15 @@ fn eval<'a>(insts: &'a [Inst<'a>], stack: &mut Stack<'a>, env: &Rc<RefCell<Env<'
stack.push(b); stack.push(b);
} }
"print" => { "print" => {
print!("{}", stack.pop_default()); write!(out, "{}", stack.pop_default()).unwrap();
} }
"println" => { "println" => {
println!("{}", stack.pop_default()); writeln!(out, "{}", stack.pop_default()).unwrap();
} }
"put" => { "put" => {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
let byte = stack.pop_num() as u8; let byte = stack.pop_num() as u8;
io::stdout().write_all(&[byte]).unwrap(); out.write_all(&[byte]).unwrap();
} }
"explode" => { "explode" => {
eprintln!("I ESPLODED"); eprintln!("I ESPLODED");
@ -240,9 +245,9 @@ fn eval<'a>(insts: &'a [Inst<'a>], stack: &mut Stack<'a>, env: &Rc<RefCell<Env<'
let then = stack.pop_default(); let then = stack.pop_default();
let test = stack.pop_default(); let test = stack.pop_default();
if test.to_num() == 0.0 { if test.to_num() == 0.0 {
r#else.call(stack); r#else.call(stack, out);
} else { } else {
then.call(stack); then.call(stack, out);
} }
} }
_ => stack.push( _ => stack.push(
@ -254,7 +259,7 @@ fn eval<'a>(insts: &'a [Inst<'a>], stack: &mut Stack<'a>, env: &Rc<RefCell<Env<'
Inst::Num(n) => stack.push(Val::Num(*n)), Inst::Num(n) => stack.push(Val::Num(*n)),
Inst::Call => { Inst::Call => {
let f = stack.pop_default(); let f = stack.pop_default();
f.call(stack); f.call(stack, out);
} }
Inst::Block(insts) => stack.push(Val::Fun { Inst::Block(insts) => stack.push(Val::Fun {
insts, insts,
@ -267,7 +272,12 @@ fn eval<'a>(insts: &'a [Inst<'a>], stack: &mut Stack<'a>, env: &Rc<RefCell<Env<'
} }
} }
pub fn run(insts: &[Inst<'_>]) { pub fn run(insts: &[Inst<'_>], out: &mut impl io::Write) {
let mut stack = Stack::new(); let mut stack = Stack::new();
eval(insts, &mut stack, &Rc::new(RefCell::new(Env::default()))); eval(
insts,
&mut stack,
&Rc::new(RefCell::new(Env::default())),
out,
);
} }

View file

@ -12,5 +12,5 @@ fn main() {
let insts = parse(&src); let insts = parse(&src);
eprintln!("{}!", Inst::Block(insts.clone())); eprintln!("{}!", Inst::Block(insts.clone()));
run(&insts); run(&insts, &mut io::BufWriter::new(io::stdout().lock()));
} }