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
flamegraph.svg
perf.data

View file

@ -45,11 +45,11 @@ ymin ->y0
(64 iter + put)
ite
x0 0.03 + ->x0
x0 0.0055 + ->x0
)
while!
10 put
y0 0.08 + ->y0
y0 0.021 + ->y0
xmin ->x0
)
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 {
Val::Num(n) => stack.push(Val::Num(*n)),
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 {
match i {
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);
}
"print" => {
print!("{}", stack.pop_default());
write!(out, "{}", stack.pop_default()).unwrap();
}
"println" => {
println!("{}", stack.pop_default());
writeln!(out, "{}", stack.pop_default()).unwrap();
}
"put" => {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
let byte = stack.pop_num() as u8;
io::stdout().write_all(&[byte]).unwrap();
out.write_all(&[byte]).unwrap();
}
"explode" => {
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 test = stack.pop_default();
if test.to_num() == 0.0 {
r#else.call(stack);
r#else.call(stack, out);
} else {
then.call(stack);
then.call(stack, out);
}
}
_ => 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::Call => {
let f = stack.pop_default();
f.call(stack);
f.call(stack, out);
}
Inst::Block(insts) => stack.push(Val::Fun {
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();
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);
eprintln!("{}!", Inst::Block(insts.clone()));
run(&insts);
run(&insts, &mut io::BufWriter::new(io::stdout().lock()));
}