Implement closing for lists
This commit is contained in:
parent
37dc2e05c5
commit
2f8c46f0a5
@ -15,10 +15,11 @@ impl Instruction {
|
||||
instruction
|
||||
}
|
||||
|
||||
pub fn close(to_register: u8) -> Instruction {
|
||||
pub fn close(from_register: u8, to_register: u8) -> Instruction {
|
||||
let mut instruction = Instruction(Operation::Close as u32);
|
||||
|
||||
instruction.set_destination(to_register);
|
||||
instruction.set_first_argument(from_register);
|
||||
instruction.set_second_argument(to_register);
|
||||
|
||||
instruction
|
||||
}
|
||||
@ -243,7 +244,12 @@ impl Instruction {
|
||||
Operation::Move => {
|
||||
format!("R({}) = R({})", self.destination(), self.first_argument())
|
||||
}
|
||||
Operation::Close => format!("R({})", self.destination()),
|
||||
Operation::Close => {
|
||||
let from_register = self.first_argument();
|
||||
let to_register = self.second_argument().saturating_sub(1);
|
||||
|
||||
format!("R({from_register})..=R({to_register})")
|
||||
}
|
||||
Operation::LoadConstant => {
|
||||
let constant_index = self.first_argument();
|
||||
|
||||
@ -274,7 +280,7 @@ impl Instruction {
|
||||
let last_index = destination - 1;
|
||||
|
||||
format!(
|
||||
"R({}) = [R({})..R({})]",
|
||||
"R({}) = [R({})..=R({})]",
|
||||
destination, first_index, last_index
|
||||
)
|
||||
}
|
||||
@ -556,15 +562,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn close() {
|
||||
let mut instruction = Instruction::close(1);
|
||||
|
||||
instruction.set_first_argument_to_constant();
|
||||
instruction.set_second_argument_to_constant();
|
||||
let instruction = Instruction::close(1, 2);
|
||||
|
||||
assert_eq!(instruction.operation(), Operation::Close);
|
||||
assert_eq!(instruction.destination(), 1);
|
||||
assert!(instruction.first_argument_is_constant());
|
||||
assert!(instruction.second_argument_is_constant());
|
||||
assert_eq!(instruction.first_argument(), 1);
|
||||
assert_eq!(instruction.second_argument(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -485,8 +485,17 @@ impl<'src> Parser<'src> {
|
||||
let mut length = 0;
|
||||
|
||||
while !self.allow(TokenKind::RightSquareBrace)? && !self.is_eof() {
|
||||
let next_register = self.current_register;
|
||||
|
||||
self.parse(Precedence::Assignment)?; // Do not allow assignment
|
||||
|
||||
if next_register != self.current_register - 1 {
|
||||
self.emit_instruction(
|
||||
Instruction::close(next_register, self.current_register - 1),
|
||||
self.current_position,
|
||||
);
|
||||
}
|
||||
|
||||
length += 1;
|
||||
|
||||
if !self.allow(TokenKind::Comma)? {
|
||||
|
@ -66,7 +66,14 @@ impl Vm {
|
||||
|
||||
self.insert(value, to, position)?;
|
||||
}
|
||||
Operation::Close => todo!(),
|
||||
Operation::Close => {
|
||||
let from = instruction.first_argument();
|
||||
let to = instruction.second_argument();
|
||||
|
||||
for register_index in from..to {
|
||||
self.register_stack[register_index as usize] = None;
|
||||
}
|
||||
}
|
||||
Operation::LoadConstant => {
|
||||
let to_register = instruction.destination();
|
||||
let from_constant = instruction.first_argument();
|
||||
@ -77,13 +84,17 @@ impl Vm {
|
||||
Operation::LoadList => {
|
||||
let to_register = instruction.destination();
|
||||
let length = instruction.first_argument();
|
||||
let first_register = to_register - length;
|
||||
let first_register = to_register - length - 1;
|
||||
let last_register = to_register - 1;
|
||||
|
||||
let mut list = Vec::with_capacity(length as usize);
|
||||
|
||||
for register_index in first_register..=last_register {
|
||||
let value = self.clone(register_index, position)?;
|
||||
let value = match self.clone(register_index, position) {
|
||||
Ok(value) => value,
|
||||
Err(VmError::EmptyRegister { .. }) => continue,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
|
||||
list.push(value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user