Pass tests and fix instruction byte encoding bug
This commit is contained in:
parent
d1bdabed56
commit
97bde437e8
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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![]
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user