output parameter, buffer by default
This commit is contained in:
parent
6b3497c5fc
commit
2d22cd689e
4 changed files with 26 additions and 14 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
|||
/target
|
||||
flamegraph.svg
|
||||
perf.data
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
32
src/eval.rs
32
src/eval.rs
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue