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) 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.0 |= 0b1000_0000;
self
} }
pub fn first_argument_is_constant(&self) -> bool { pub fn first_argument_is_constant(&self) -> bool {
self.0 & 0b1000_0000 != 0 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.0 |= 0b0100_0000;
self
} }
pub fn second_argument_is_constant(&self) -> bool { pub fn second_argument_is_constant(&self) -> bool {
@ -433,61 +437,62 @@ mod tests {
#[test] #[test]
fn r#move() { 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_first_argument_to_constant();
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Move); assert_eq!(instruction.operation(), Operation::Move);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn close() { fn close() {
let mut instruction = Instruction::close(255); let mut instruction = Instruction::close(1);
instruction.set_first_argument_to_constant(); instruction.set_first_argument_to_constant();
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Close); assert_eq!(instruction.operation(), Operation::Close);
assert_eq!(instruction.destination(), 1);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn load_constant() { 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_first_argument_to_constant();
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::LoadConstant); assert_eq!(instruction.operation(), Operation::LoadConstant);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn declare_local() { 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_first_argument_to_constant();
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::DeclareLocal); assert_eq!(instruction.operation(), Operation::DeclareLocal);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn add() { fn add() {
let mut instruction = Instruction::add(255, 255, 2); let mut instruction = Instruction::add(0, 1, 2);
instruction.set_operation(Operation::Add); instruction.set_operation(Operation::Add);
@ -495,8 +500,8 @@ mod tests {
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Add); assert_eq!(instruction.operation(), Operation::Add);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 2); assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
@ -504,7 +509,7 @@ mod tests {
#[test] #[test]
fn subtract() { fn subtract() {
let mut instruction = Instruction::subtract(255, 255, 255); let mut instruction = Instruction::subtract(0, 1, 2);
instruction.set_operation(Operation::Subtract); instruction.set_operation(Operation::Subtract);
@ -512,16 +517,16 @@ mod tests {
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Subtract); assert_eq!(instruction.operation(), Operation::Subtract);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 255); assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn multiply() { fn multiply() {
let mut instruction = Instruction::multiply(255, 255, 255); let mut instruction = Instruction::multiply(0, 1, 2);
instruction.set_operation(Operation::Multiply); instruction.set_operation(Operation::Multiply);
@ -529,16 +534,16 @@ mod tests {
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Multiply); assert_eq!(instruction.operation(), Operation::Multiply);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 255); assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn divide() { fn divide() {
let mut instruction = Instruction::divide(255, 255, 255); let mut instruction = Instruction::divide(0, 1, 2);
instruction.set_operation(Operation::Divide); instruction.set_operation(Operation::Divide);
@ -546,16 +551,16 @@ mod tests {
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Divide); assert_eq!(instruction.operation(), Operation::Divide);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert_eq!(instruction.second_argument(), 255); assert_eq!(instruction.second_argument(), 2);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_argument_is_constant()); assert!(instruction.second_argument_is_constant());
} }
#[test] #[test]
fn negate() { fn negate() {
let mut instruction = Instruction::negate(255, 255); let mut instruction = Instruction::negate(0, 1);
instruction.set_operation(Operation::Negate); instruction.set_operation(Operation::Negate);
@ -563,8 +568,8 @@ mod tests {
instruction.set_second_argument_to_constant(); instruction.set_second_argument_to_constant();
assert_eq!(instruction.operation(), Operation::Negate); assert_eq!(instruction.operation(), Operation::Negate);
assert_eq!(instruction.destination(), 255); assert_eq!(instruction.destination(), 0);
assert_eq!(instruction.first_argument(), 255); assert_eq!(instruction.first_argument(), 1);
assert!(instruction.first_argument_is_constant()); assert!(instruction.first_argument_is_constant());
assert!(instruction.second_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::load_constant(0, 0), Span(8, 10)),
(Instruction::declare_local(0, 0), Span(4, 5)), (Instruction::declare_local(0, 0), Span(4, 5)),
], ],
vec![Value::integer(42),], vec![Value::integer(42)],
vec![Local::new(Identifier::new("x"), 0, None)] vec![Local::new(Identifier::new("x"), 0, Some(0))]
)), )),
); );
} }
@ -26,7 +26,7 @@ fn integer() {
(Instruction::load_constant(0, 0), Span(0, 2)), (Instruction::load_constant(0, 0), Span(0, 2)),
(Instruction::r#return(), Span(0, 2)), (Instruction::r#return(), Span(0, 2)),
], ],
vec![Value::integer(42),], vec![Value::integer(42)],
vec![] vec![]
)) ))
); );
@ -38,10 +38,15 @@ fn add() {
parse("1 + 2"), parse("1 + 2"),
Ok(Chunk::with_data( Ok(Chunk::with_data(
vec![ 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)), (Instruction::r#return(), Span(0, 5)),
], ],
vec![Value::integer(1), Value::integer(2),], vec![Value::integer(1), Value::integer(2)],
vec![] vec![]
)) ))
); );
@ -53,10 +58,15 @@ fn subtract() {
parse("1 - 2"), parse("1 - 2"),
Ok(Chunk::with_data( Ok(Chunk::with_data(
vec![ 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)), (Instruction::r#return(), Span(0, 5)),
], ],
vec![Value::integer(1), Value::integer(2),], vec![Value::integer(1), Value::integer(2)],
vec![] vec![]
)) ))
); );