Fix while loop jumps; Pass tests
This commit is contained in:
parent
604962c535
commit
febd7bb054
@ -1092,7 +1092,7 @@ impl<'src> Parser<'src> {
|
|||||||
fn parse_while(&mut self, allowed: Allowed) -> Result<(), ParseError> {
|
fn parse_while(&mut self, allowed: Allowed) -> Result<(), ParseError> {
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
|
|
||||||
let jump_start = self.chunk.len() as u8;
|
let expression_start = self.chunk.len() as u8;
|
||||||
|
|
||||||
self.parse_expression()?;
|
self.parse_expression()?;
|
||||||
|
|
||||||
@ -1102,21 +1102,27 @@ impl<'src> Parser<'src> {
|
|||||||
{
|
{
|
||||||
self.chunk.instructions_mut().pop();
|
self.chunk.instructions_mut().pop();
|
||||||
self.chunk.instructions_mut().pop();
|
self.chunk.instructions_mut().pop();
|
||||||
|
self.chunk.instructions_mut().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let block_start = self.chunk.len();
|
||||||
|
|
||||||
self.parse_block(Allowed {
|
self.parse_block(Allowed {
|
||||||
assignment: true,
|
assignment: true,
|
||||||
explicit_return: allowed.explicit_return,
|
explicit_return: allowed.explicit_return,
|
||||||
implicit_return: false,
|
implicit_return: false,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if let Some(jump) = self.get_last_jump_mut() {
|
let block_end = self.chunk.len() as u8;
|
||||||
jump.set_b(jump.b() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let jump_end = self.chunk.len() as u8;
|
self.chunk.insert_instruction(
|
||||||
let jump_distance = jump_end - jump_start;
|
block_start,
|
||||||
let jump_back = Instruction::jump(jump_distance, false);
|
Instruction::jump(block_end - block_start as u8 + 1, true),
|
||||||
|
self.current_position,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let jump_back_distance = block_end - expression_start + 1;
|
||||||
|
let jump_back = Instruction::jump(jump_back_distance, false);
|
||||||
|
|
||||||
self.emit_instruction(jump_back, self.current_position);
|
self.emit_instruction(jump_back, self.current_position);
|
||||||
self.optimize_statement();
|
self.optimize_statement();
|
||||||
|
@ -353,7 +353,7 @@ impl Vm {
|
|||||||
let new_ip = if is_positive {
|
let new_ip = if is_positive {
|
||||||
self.ip + jump_distance as usize
|
self.ip + jump_distance as usize
|
||||||
} else {
|
} else {
|
||||||
self.ip - jump_distance as usize
|
self.ip - jump_distance as usize - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
self.jump_to_ip(new_ip);
|
self.jump_to_ip(new_ip);
|
||||||
|
169
dust-lang/tests/comparison.rs
Normal file
169
dust-lang/tests/comparison.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
use dust_lang::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equal() {
|
||||||
|
let source = "1 == 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 4)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||||
|
(Instruction::r#return(true), Span(6, 6)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn greater() {
|
||||||
|
let source = "1 > 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::less_equal(false, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 3)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 3)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 3)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
||||||
|
(Instruction::r#return(true), Span(5, 5)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn greater_than_or_equal() {
|
||||||
|
let source = "1 >= 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::less(false, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 4)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||||
|
(Instruction::r#return(true), Span(6, 6)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn less_than() {
|
||||||
|
let source = "1 < 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::less(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 3)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 3)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 3)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
||||||
|
(Instruction::r#return(true), Span(5, 5)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn less_than_or_equal() {
|
||||||
|
let source = "1 <= 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::less_equal(true, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 4)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||||
|
(Instruction::r#return(true), Span(6, 6)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn not_equal() {
|
||||||
|
let source = "1 != 2";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
*Instruction::equal(false, 0, 1)
|
||||||
|
.set_b_is_constant()
|
||||||
|
.set_c_is_constant(),
|
||||||
|
Span(2, 4)
|
||||||
|
),
|
||||||
|
(Instruction::jump(1, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
||||||
|
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||||
|
(Instruction::r#return(true), Span(6, 6)),
|
||||||
|
],
|
||||||
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
@ -48,29 +48,6 @@ fn add_assign() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::integer(3))));
|
assert_eq!(run(source), Ok(Some(Value::integer(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn and() {
|
|
||||||
let source = "true && false";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
|
||||||
(Instruction::test(0, false), Span(5, 7)),
|
|
||||||
(Instruction::jump(4, true), Span(5, 7)),
|
|
||||||
(Instruction::load_boolean(1, false, false), Span(8, 13)),
|
|
||||||
(Instruction::r#return(true), Span(13, 13)),
|
|
||||||
],
|
|
||||||
vec![],
|
|
||||||
vec![]
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_scope() {
|
fn block_scope() {
|
||||||
let source = "
|
let source = "
|
||||||
@ -243,34 +220,6 @@ fn empty_list() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::list(0, 0, Type::Any))));
|
assert_eq!(run(source), Ok(Some(Value::list(0, 0, Type::Any))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn equal() {
|
|
||||||
let source = "1 == 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 4)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
|
||||||
(Instruction::r#return(true), Span(6, 6)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function() {
|
fn function() {
|
||||||
let source = "fn(a: int, b: int) -> int { a + b }";
|
let source = "fn(a: int, b: int) -> int { a + b }";
|
||||||
@ -404,118 +353,6 @@ fn function_call() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::integer(3))));
|
assert_eq!(run(source), Ok(Some(Value::integer(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater() {
|
|
||||||
let source = "1 > 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::less_equal(false, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 3)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 3)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 3)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
|
||||||
(Instruction::r#return(true), Span(5, 5)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than_or_equal() {
|
|
||||||
let source = "1 >= 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::less(false, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 4)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
|
||||||
(Instruction::r#return(true), Span(6, 6)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than() {
|
|
||||||
let source = "1 < 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::less(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 3)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 3)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 3)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
|
||||||
(Instruction::r#return(true), Span(5, 5)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than_or_equal() {
|
|
||||||
let source = "1 <= 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::less_equal(true, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 4)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
|
||||||
(Instruction::r#return(true), Span(6, 6)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list() {
|
fn list() {
|
||||||
let source = "[1, 2, 3]";
|
let source = "[1, 2, 3]";
|
||||||
@ -747,57 +584,6 @@ fn not() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn not_equal() {
|
|
||||||
let source = "1 != 2";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
*Instruction::equal(false, 0, 1)
|
|
||||||
.set_b_is_constant()
|
|
||||||
.set_c_is_constant(),
|
|
||||||
Span(2, 4)
|
|
||||||
),
|
|
||||||
(Instruction::jump(3, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, true, true), Span(2, 4)),
|
|
||||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
|
||||||
(Instruction::r#return(true), Span(6, 6)),
|
|
||||||
],
|
|
||||||
vec![Value::integer(1), Value::integer(2)],
|
|
||||||
vec![]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn or() {
|
|
||||||
let source = "true || false";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
|
||||||
(Instruction::test(0, true), Span(5, 7)),
|
|
||||||
(Instruction::jump(4, true), Span(5, 7)),
|
|
||||||
(Instruction::load_boolean(1, false, false), Span(8, 13)),
|
|
||||||
(Instruction::r#return(true), Span(13, 13)),
|
|
||||||
],
|
|
||||||
vec![],
|
|
||||||
vec![]
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parentheses_precedence() {
|
fn parentheses_precedence() {
|
||||||
let source = "(1 + 2) * 3";
|
let source = "(1 + 2) * 3";
|
||||||
@ -917,7 +703,7 @@ fn variable_and() {
|
|||||||
(Instruction::define_local(1, 1, false), Span(18, 19)),
|
(Instruction::define_local(1, 1, false), Span(18, 19)),
|
||||||
(Instruction::get_local(2, 0), Span(29, 30)),
|
(Instruction::get_local(2, 0), Span(29, 30)),
|
||||||
(Instruction::test(2, false), Span(31, 33)),
|
(Instruction::test(2, false), Span(31, 33)),
|
||||||
(Instruction::jump(8, true), Span(31, 33)),
|
(Instruction::jump(1, true), Span(31, 33)),
|
||||||
(Instruction::get_local(3, 1), Span(34, 35)),
|
(Instruction::get_local(3, 1), Span(34, 35)),
|
||||||
(Instruction::r#return(true), Span(35, 35)),
|
(Instruction::r#return(true), Span(35, 35)),
|
||||||
],
|
],
|
||||||
@ -947,9 +733,9 @@ fn r#while() {
|
|||||||
*Instruction::less(true, 0, 1).set_c_is_constant(),
|
*Instruction::less(true, 0, 1).set_c_is_constant(),
|
||||||
Span(23, 24)
|
Span(23, 24)
|
||||||
),
|
),
|
||||||
(Instruction::jump(7, true), Span(23, 24)),
|
|
||||||
(*Instruction::add(0, 0, 2).set_c_is_constant(), Span(39, 40)),
|
|
||||||
(Instruction::jump(2, true), Span(41, 42)),
|
(Instruction::jump(2, true), Span(41, 42)),
|
||||||
|
(*Instruction::add(0, 0, 2).set_c_is_constant(), Span(39, 40)),
|
||||||
|
(Instruction::jump(3, false), Span(41, 42)),
|
||||||
(Instruction::get_local(1, 0), Span(41, 42)),
|
(Instruction::get_local(1, 0), Span(41, 42)),
|
||||||
(Instruction::r#return(true), Span(42, 42)),
|
(Instruction::r#return(true), Span(42, 42)),
|
||||||
],
|
],
|
||||||
|
47
dust-lang/tests/logic.rs
Normal file
47
dust-lang/tests/logic.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use dust_lang::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn and() {
|
||||||
|
let source = "true && false";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
|
(Instruction::test(0, false), Span(5, 7)),
|
||||||
|
(Instruction::jump(1, true), Span(5, 7)),
|
||||||
|
(Instruction::load_boolean(1, false, false), Span(8, 13)),
|
||||||
|
(Instruction::r#return(true), Span(13, 13)),
|
||||||
|
],
|
||||||
|
vec![],
|
||||||
|
vec![]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(false))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn or() {
|
||||||
|
let source = "true || false";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
|
(Instruction::test(0, true), Span(5, 7)),
|
||||||
|
(Instruction::jump(1, true), Span(5, 7)),
|
||||||
|
(Instruction::load_boolean(1, false, false), Span(8, 13)),
|
||||||
|
(Instruction::r#return(true), Span(13, 13)),
|
||||||
|
],
|
||||||
|
vec![],
|
||||||
|
vec![]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||||
|
}
|
@ -11,7 +11,7 @@ while count <= 15 {
|
|||||||
} else if divides_by_5 {
|
} else if divides_by_5 {
|
||||||
"buzz"
|
"buzz"
|
||||||
} else {
|
} else {
|
||||||
string(count)
|
to_string(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
write_line(output)
|
write_line(output)
|
||||||
|
Loading…
Reference in New Issue
Block a user