Pass tests and fix instruction byte encoding bug

This commit is contained in:
Jeff 2024-09-15 02:03:54 -04:00
parent d1bdabed56
commit 97bde437e8
2 changed files with 52 additions and 37 deletions

View File

@ -112,16 +112,20 @@ impl Instruction {
Instruction(Operation::Return as u32)
}
pub fn set_first_argument_to_constant(&mut self) {
pub fn set_first_argument_to_constant(&mut self) -> &mut Self {
self.0 |= 0b1000_0000;
self
}
pub fn first_argument_is_constant(&self) -> bool {
self.0 & 0b1000_0000 != 0
}
pub fn set_second_argument_to_constant(&mut self) {
pub fn set_second_argument_to_constant(&mut self) -> &mut Self {
self.0 |= 0b0100_0000;
self
}
pub fn second_argument_is_constant(&self) -> bool {
@ -433,61 +437,62 @@ mod tests {
#[test]
fn r#move() {
let mut instruction = Instruction::r#move(255, 255);
let mut instruction = Instruction::r#move(0, 1);
instruction.set_first_argument_to_constant();
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Move);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn close() {
let mut instruction = Instruction::close(255);
let mut instruction = Instruction::close(1);
instruction.set_first_argument_to_constant();
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Close);
assert_eq!(instruction.destination(), 1);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn load_constant() {
let mut instruction = Instruction::load_constant(255, 255);
let mut instruction = Instruction::load_constant(0, 1);
instruction.set_first_argument_to_constant();
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::LoadConstant);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn declare_local() {
let mut instruction = Instruction::declare_local(255, 255);
let mut instruction = Instruction::declare_local(0, 1);
instruction.set_first_argument_to_constant();
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::DeclareLocal);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn add() {
let mut instruction = Instruction::add(255, 255, 2);
let mut instruction = Instruction::add(0, 1, 2);
instruction.set_operation(Operation::Add);
@ -495,8 +500,8 @@ mod tests {
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Add);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
@ -504,7 +509,7 @@ mod tests {
#[test]
fn subtract() {
let mut instruction = Instruction::subtract(255, 255, 255);
let mut instruction = Instruction::subtract(0, 1, 2);
instruction.set_operation(Operation::Subtract);
@ -512,16 +517,16 @@ mod tests {
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Subtract);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.second_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn multiply() {
let mut instruction = Instruction::multiply(255, 255, 255);
let mut instruction = Instruction::multiply(0, 1, 2);
instruction.set_operation(Operation::Multiply);
@ -529,16 +534,16 @@ mod tests {
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Multiply);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.second_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn divide() {
let mut instruction = Instruction::divide(255, 255, 255);
let mut instruction = Instruction::divide(0, 1, 2);
instruction.set_operation(Operation::Divide);
@ -546,16 +551,16 @@ mod tests {
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Divide);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.second_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}
#[test]
fn negate() {
let mut instruction = Instruction::negate(255, 255);
let mut instruction = Instruction::negate(0, 1);
instruction.set_operation(Operation::Negate);
@ -563,8 +568,8 @@ mod tests {
instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Negate);
assert_eq!(instruction.destination(), 255);
assert_eq!(instruction.first_argument(), 255);
assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant());
}

View File

@ -11,8 +11,8 @@ fn let_statement() {
(Instruction::load_constant(0, 0), Span(8, 10)),
(Instruction::declare_local(0, 0), Span(4, 5)),
],
vec![Value::integer(42),],
vec![Local::new(Identifier::new("x"), 0, None)]
vec![Value::integer(42)],
vec![Local::new(Identifier::new("x"), 0, Some(0))]
)),
);
}
@ -26,7 +26,7 @@ fn integer() {
(Instruction::load_constant(0, 0), Span(0, 2)),
(Instruction::r#return(), Span(0, 2)),
],
vec![Value::integer(42),],
vec![Value::integer(42)],
vec![]
))
);
@ -38,10 +38,15 @@ fn add() {
parse("1 + 2"),
Ok(Chunk::with_data(
vec![
(Instruction::add(0, 0, 1), Span(2, 3)),
(
*Instruction::add(0, 0, 1)
.set_first_argument_to_constant()
.set_second_argument_to_constant(),
Span(2, 3)
),
(Instruction::r#return(), Span(0, 5)),
],
vec![Value::integer(1), Value::integer(2),],
vec![Value::integer(1), Value::integer(2)],
vec![]
))
);
@ -53,10 +58,15 @@ fn subtract() {
parse("1 - 2"),
Ok(Chunk::with_data(
vec![
(Instruction::subtract(0, 0, 1), Span(2, 3)),
(
*Instruction::subtract(0, 0, 1)
.set_first_argument_to_constant()
.set_second_argument_to_constant(),
Span(2, 3)
),
(Instruction::r#return(), Span(0, 5)),
],
vec![Value::integer(1), Value::integer(2),],
vec![Value::integer(1), Value::integer(2)],
vec![]
))
);