mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Cat instruction with limited implementation
This commit is contained in:
@@ -54,6 +54,7 @@ pub enum InstructionByte {
|
||||
ThisSubCall = 0x33,
|
||||
Next = 0x34,
|
||||
UnpackIterRes = 0x35,
|
||||
Cat = 0x36,
|
||||
}
|
||||
|
||||
impl InstructionByte {
|
||||
@@ -115,6 +116,7 @@ impl InstructionByte {
|
||||
0x33 => ThisSubCall,
|
||||
0x34 => Next,
|
||||
0x35 => UnpackIterRes,
|
||||
0x36 => Cat,
|
||||
|
||||
_ => panic!("Unrecognized instruction: {}", byte),
|
||||
};
|
||||
|
||||
@@ -292,6 +292,7 @@ pub enum Instruction {
|
||||
ThisSubCall(Value, Value, Value, Register),
|
||||
Next(Register, Register),
|
||||
UnpackIterRes(Register, Register, Register),
|
||||
Cat(Value, Register),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Instruction {
|
||||
@@ -457,6 +458,9 @@ impl std::fmt::Display for Instruction {
|
||||
obj, value_register, done_register
|
||||
)
|
||||
}
|
||||
Instruction::Cat(iterables, register) => {
|
||||
write!(f, "cat {} {}", iterables, register)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -521,6 +525,7 @@ impl Instruction {
|
||||
ThisSubCall(..) => InstructionByte::ThisSubCall,
|
||||
Next(..) => InstructionByte::Next,
|
||||
UnpackIterRes(..) => InstructionByte::UnpackIterRes,
|
||||
Cat(..) => InstructionByte::Cat,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +240,10 @@ impl Assembler {
|
||||
self.register(value_dst);
|
||||
self.register(done_dst);
|
||||
}
|
||||
Cat(iterables, dst) => {
|
||||
self.value(iterables);
|
||||
self.register(dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -229,6 +229,7 @@ impl<'a> AssemblyParser<'a> {
|
||||
("this_subcall", InstructionByte::ThisSubCall),
|
||||
("next", InstructionByte::Next),
|
||||
("unpack_iter_res", InstructionByte::UnpackIterRes),
|
||||
("cat", InstructionByte::Cat),
|
||||
]);
|
||||
|
||||
for (word, instruction) in instruction_word_map {
|
||||
@@ -693,6 +694,7 @@ impl<'a> AssemblyParser<'a> {
|
||||
self.assemble_register(),
|
||||
self.assemble_register(),
|
||||
),
|
||||
Cat => Instruction::Cat(self.assemble_value(), self.assemble_register()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ pub fn instruction_mutates_this(instruction: &Instruction) -> bool {
|
||||
| ImportStar(_, reg)
|
||||
| SetCatch(_, reg)
|
||||
| ConstSubCall(_, _, _, reg)
|
||||
| ThisSubCall(_, _, _, reg) => reg == &Register::This,
|
||||
| ThisSubCall(_, _, _, reg)
|
||||
| Cat(_, reg) => reg == &Register::This,
|
||||
|
||||
Next(iter, res) => iter == &Register::This || res == &Register::This,
|
||||
UnpackIterRes(_, value_reg, done_reg) => {
|
||||
|
||||
@@ -244,7 +244,8 @@ where
|
||||
| UnaryMinus(arg, _)
|
||||
| Import(arg, _)
|
||||
| ImportStar(arg, _)
|
||||
| Throw(arg) => {
|
||||
| Throw(arg)
|
||||
| Cat(arg, _) => {
|
||||
self.value(Some(owner), arg);
|
||||
}
|
||||
OpPlus(arg1, arg2, _)
|
||||
|
||||
@@ -519,6 +519,34 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
operations::op_sub(self.registers[iter_res_i].clone(), "done".to_val())?;
|
||||
}
|
||||
}
|
||||
|
||||
Cat => {
|
||||
let mut vals = Vec::<Val>::new();
|
||||
|
||||
let bytecode_type = self.decoder.decode_type();
|
||||
|
||||
if bytecode_type != BytecodeType::Array {
|
||||
panic!("Not implemented: cat instruction not using inline array");
|
||||
}
|
||||
|
||||
while self.decoder.peek_type() != BytecodeType::End {
|
||||
let iterable = self.decoder.decode_val(&self.registers);
|
||||
|
||||
match iterable {
|
||||
Val::Array(array_data) => {
|
||||
for item in &array_data.elements {
|
||||
vals.push(item.clone());
|
||||
}
|
||||
}
|
||||
_ => todo!("Cat: Non-array iterable"),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Just skip the byte in release builds?
|
||||
assert!(self.decoder.decode_type() == BytecodeType::End);
|
||||
|
||||
self.registers[self.decoder.decode_register_index().unwrap()] = vals.to_val();
|
||||
}
|
||||
};
|
||||
|
||||
Ok(FrameStepOk::Continue)
|
||||
|
||||
Reference in New Issue
Block a user