Generators now work

This commit is contained in:
Andrew Morris
2023-06-01 11:53:36 +10:00
parent 95e702b85e
commit 5712221cd6
5 changed files with 39 additions and 2 deletions

23
inputs/passing/range.ts Normal file
View File

@@ -0,0 +1,23 @@
//! test_output({"iter":[4,5,6,7,8,9],"iterSnapshot":[2,3,4,5,6,7,8,9]})
export default function main() {
let iter = range(10);
iter.next();
iter.next();
let iterSnapshot = iter;
iter.next();
iter.next();
return {
iter: [...iter],
iterSnapshot: [...iterSnapshot],
};
}
function* range(n: number) {
for (let i = 0; i < n; i++) {
yield i;
}
}

View File

@@ -553,7 +553,10 @@ impl StackFrameTrait for BytecodeStackFrame {
}
Yield => {
panic!("TODO: yield");
let val = self.decoder.decode_val(&self.registers);
self.decoder.decode_register_index(); // TODO: Use this
return Ok(FrameStepOk::Yield(val));
}
YieldStar => {

View File

@@ -154,7 +154,7 @@ impl StackFrameTrait for GeneratorFrame {
let fsr = self.generator.frame.step();
match fsr {
Err(_) => Err("TODO: exceptions inside generators".to_error()),
Err(_) => fsr, // TODO: Stack unwind internal stack first
Ok(FrameStepOk::Continue) | Ok(FrameStepOk::Push(_)) => fsr,
Ok(FrameStepOk::Pop(call_result)) => Ok(FrameStepOk::Pop(CallResult {
return_: IterationResult {
@@ -164,6 +164,14 @@ impl StackFrameTrait for GeneratorFrame {
.to_dynamic_val(),
this: take(&mut self.generator).to_dynamic_val(),
})),
Ok(FrameStepOk::Yield(val)) => Ok(FrameStepOk::Pop(CallResult {
return_: IterationResult {
value: val,
done: false,
}
.to_dynamic_val(),
this: take(&mut self.generator).to_dynamic_val(),
})),
}
}

View File

@@ -12,6 +12,7 @@ pub enum FrameStepOk {
Continue,
Pop(CallResult),
Push(StackFrame),
Yield(Val),
}
pub type FrameStepResult = Result<FrameStepOk, Val>;

View File

@@ -86,6 +86,8 @@ impl VirtualMachine {
FrameStepOk::Push(new_frame) => {
self.push(new_frame);
}
// TODO: Internal errors
FrameStepOk::Yield(_) => return self.handle_exception("Unexpected yield".to_error()),
}
Ok(())