diff --git a/concept-code/iteration.vsm b/concept-code/iteration.vsm index 7b08f21..a606179 100644 --- a/concept-code/iteration.vsm +++ b/concept-code/iteration.vsm @@ -1,19 +1,20 @@ export @_anon0 {} @_anon0 = function() { - mov 0 %sub + mov 0 %sum mov [1, 2, 3] %nums - sub %nums $SymbolIterator %_iter0 + sub $Symbol "iterator" %symbol_dot_iterator + subcall %nums %symbol_dot_iterator [] %_iter0 jmp :for_continue0 for_test0: jmpif %_done0 :for_end0 - op+ %sub %_value0 %sub + op+ %sum %_value0 %sum for_continue0: next %_iter0 %_iter_res0 - unpack_iter_res %_value0 %_done0 + unpack_iter_res %_iter_res0 %_value0 %_done0 jmp :for_test0 for_end0: diff --git a/valuescript_vm/src/bytecode_stack_frame.rs b/valuescript_vm/src/bytecode_stack_frame.rs index e76bf60..f05815a 100644 --- a/valuescript_vm/src/bytecode_stack_frame.rs +++ b/valuescript_vm/src/bytecode_stack_frame.rs @@ -459,8 +459,54 @@ impl StackFrameTrait for BytecodeStackFrame { } } - Next => todo!(), - UnpackIterRes => todo!(), + Next => { + let iter_i = match self.decoder.decode_register_index() { + Some(i) => i, + None => panic!("The ignore register is not iterable"), + }; + + let res_i = self.decoder.decode_register_index(); + + let next_fn = operations::op_sub(self.registers[iter_i].clone(), "next".to_val())?; + + match next_fn.load_function() { + LoadFunctionResult::NotAFunction => { + return Err(".next() is not a function".to_type_error()) + } + LoadFunctionResult::NativeFunction(fn_) => { + let res = fn_(ThisWrapper::new(false, &mut self.registers[iter_i]), vec![])?; + + if let Some(res_i) = res_i { + self.registers[res_i] = res; + } + } + LoadFunctionResult::StackFrame(mut new_frame) => { + new_frame.write_this(false, self.registers[iter_i].clone())?; + + self.return_target = res_i; + self.this_target = Some(iter_i); + + return Ok(FrameStepOk::Push(new_frame)); + } + }; + } + + UnpackIterRes => { + let iter_res_i = match self.decoder.decode_register_index() { + Some(i) => i, + None => panic!("Can't unpack the ignore register"), + }; + + if let Some(value_i) = self.decoder.decode_register_index() { + self.registers[value_i] = + operations::op_sub(self.registers[iter_res_i].clone(), "value".to_val())?; + } + + if let Some(done_i) = self.decoder.decode_register_index() { + self.registers[done_i] = + operations::op_sub(self.registers[iter_res_i].clone(), "done".to_val())?; + } + } }; Ok(FrameStepOk::Continue)