From 5712221cd68b286f98c34f606b141cc6ba38ce52 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Thu, 1 Jun 2023 11:53:36 +1000 Subject: [PATCH] Generators now work --- inputs/passing/range.ts | 23 ++++++++++++++++++++++ valuescript_vm/src/bytecode_stack_frame.rs | 5 ++++- valuescript_vm/src/generator.rs | 10 +++++++++- valuescript_vm/src/stack_frame.rs | 1 + valuescript_vm/src/virtual_machine.rs | 2 ++ 5 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 inputs/passing/range.ts diff --git a/inputs/passing/range.ts b/inputs/passing/range.ts new file mode 100644 index 0000000..159803b --- /dev/null +++ b/inputs/passing/range.ts @@ -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; + } +} diff --git a/valuescript_vm/src/bytecode_stack_frame.rs b/valuescript_vm/src/bytecode_stack_frame.rs index c1f7a49..6c28007 100644 --- a/valuescript_vm/src/bytecode_stack_frame.rs +++ b/valuescript_vm/src/bytecode_stack_frame.rs @@ -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 => { diff --git a/valuescript_vm/src/generator.rs b/valuescript_vm/src/generator.rs index 38f4449..7da2de5 100644 --- a/valuescript_vm/src/generator.rs +++ b/valuescript_vm/src/generator.rs @@ -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(), + })), } } diff --git a/valuescript_vm/src/stack_frame.rs b/valuescript_vm/src/stack_frame.rs index 85070aa..80d66f9 100644 --- a/valuescript_vm/src/stack_frame.rs +++ b/valuescript_vm/src/stack_frame.rs @@ -12,6 +12,7 @@ pub enum FrameStepOk { Continue, Pop(CallResult), Push(StackFrame), + Yield(Val), } pub type FrameStepResult = Result; diff --git a/valuescript_vm/src/virtual_machine.rs b/valuescript_vm/src/virtual_machine.rs index ffd8b69..ac49a13 100644 --- a/valuescript_vm/src/virtual_machine.rs +++ b/valuescript_vm/src/virtual_machine.rs @@ -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(())