Deduplication of constants in the chunk; Clean up
This commit is contained in:
parent
e85297bcbb
commit
60535e20d6
@ -111,7 +111,15 @@ impl Chunk {
|
|||||||
.ok_or(ChunkError::ConstantIndexOutOfBounds { index, position })
|
.ok_or(ChunkError::ConstantIndexOutOfBounds { index, position })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_constant(&mut self, value: Value, position: Span) -> Result<u8, ChunkError> {
|
pub fn push_or_get_constant(&mut self, value: Value, position: Span) -> Result<u8, ChunkError> {
|
||||||
|
if let Some(index) = self
|
||||||
|
.constants
|
||||||
|
.iter()
|
||||||
|
.position(|constant| constant == &value)
|
||||||
|
{
|
||||||
|
return Ok(index as u8);
|
||||||
|
}
|
||||||
|
|
||||||
let starting_length = self.constants.len();
|
let starting_length = self.constants.len();
|
||||||
|
|
||||||
if starting_length + 1 > (u8::MAX as usize) {
|
if starting_length + 1 > (u8::MAX as usize) {
|
||||||
|
@ -79,7 +79,7 @@ impl_from_str_for_native_function! {
|
|||||||
(Assert, 0_u8, "assert", false),
|
(Assert, 0_u8, "assert", false),
|
||||||
(AssertEqual, 1_u8, "assert_equal", false),
|
(AssertEqual, 1_u8, "assert_equal", false),
|
||||||
(AssertNotEqual, 2_u8, "assert_not_equal", false),
|
(AssertNotEqual, 2_u8, "assert_not_equal", false),
|
||||||
(Panic, 3_u8, "panic", false),
|
(Panic, 3_u8, "panic", true),
|
||||||
|
|
||||||
// Type conversion
|
// Type conversion
|
||||||
(Parse, 4_u8, "parse", true),
|
(Parse, 4_u8, "parse", true),
|
||||||
|
@ -236,7 +236,7 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit_constant(&mut self, value: Value, position: Span) -> Result<(), ParseError> {
|
fn emit_constant(&mut self, value: Value, position: Span) -> Result<(), ParseError> {
|
||||||
let constant_index = self.chunk.push_constant(value, position)?;
|
let constant_index = self.chunk.push_or_get_constant(value, position)?;
|
||||||
let register = self.next_register();
|
let register = self.next_register();
|
||||||
|
|
||||||
self.emit_instruction(
|
self.emit_instruction(
|
||||||
@ -960,7 +960,6 @@ impl<'src> Parser<'src> {
|
|||||||
let block_allowed = Allowed {
|
let block_allowed = Allowed {
|
||||||
assignment: allowed.assignment,
|
assignment: allowed.assignment,
|
||||||
explicit_return: allowed.explicit_return,
|
explicit_return: allowed.explicit_return,
|
||||||
implicit_return: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Token::LeftCurlyBrace = self.current_token {
|
if let Token::LeftCurlyBrace = self.current_token {
|
||||||
@ -1093,7 +1092,6 @@ impl<'src> Parser<'src> {
|
|||||||
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,
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let block_end = self.chunk.len() as u8;
|
let block_end = self.chunk.len() as u8;
|
||||||
@ -1166,7 +1164,6 @@ impl<'src> Parser<'src> {
|
|||||||
self.parse_statement(Allowed {
|
self.parse_statement(Allowed {
|
||||||
assignment: true,
|
assignment: true,
|
||||||
explicit_return: false,
|
explicit_return: false,
|
||||||
implicit_return: true,
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if self.is_eof() || self.allow(Token::RightCurlyBrace)? {
|
if self.is_eof() || self.allow(Token::RightCurlyBrace)? {
|
||||||
@ -1195,7 +1192,6 @@ impl<'src> Parser<'src> {
|
|||||||
Allowed {
|
Allowed {
|
||||||
assignment: false,
|
assignment: false,
|
||||||
explicit_return: false,
|
explicit_return: false,
|
||||||
implicit_return: false,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1206,7 +1202,6 @@ impl<'src> Parser<'src> {
|
|||||||
Allowed {
|
Allowed {
|
||||||
assignment: false,
|
assignment: false,
|
||||||
explicit_return: false,
|
explicit_return: false,
|
||||||
implicit_return: false,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1591,7 +1586,6 @@ pub enum Context {
|
|||||||
struct Allowed {
|
struct Allowed {
|
||||||
pub assignment: bool,
|
pub assignment: bool,
|
||||||
pub explicit_return: bool,
|
pub explicit_return: bool,
|
||||||
pub implicit_return: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrefixFunction<'a> = fn(&mut Parser<'a>, Allowed) -> Result<(), ParseError>;
|
type PrefixFunction<'a> = fn(&mut Parser<'a>, Allowed) -> Result<(), ParseError>;
|
||||||
|
@ -10,7 +10,7 @@ fn equality_assignment_long() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(13, 15)
|
Span(13, 15)
|
||||||
@ -22,7 +22,7 @@ fn equality_assignment_long() {
|
|||||||
(Instruction::get_local(1, 0), Span(43, 44)),
|
(Instruction::get_local(1, 0), Span(43, 44)),
|
||||||
(Instruction::r#return(true), Span(44, 44)),
|
(Instruction::r#return(true), Span(44, 44)),
|
||||||
],
|
],
|
||||||
vec![Value::integer(4), Value::integer(4)],
|
vec![Value::integer(4)],
|
||||||
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
@ -40,7 +40,7 @@ fn equality_assignment_short() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(10, 12)
|
Span(10, 12)
|
||||||
@ -52,7 +52,7 @@ fn equality_assignment_short() {
|
|||||||
(Instruction::get_local(1, 0), Span(15, 16)),
|
(Instruction::get_local(1, 0), Span(15, 16)),
|
||||||
(Instruction::r#return(true), Span(16, 16)),
|
(Instruction::r#return(true), Span(16, 16)),
|
||||||
],
|
],
|
||||||
vec![Value::integer(4), Value::integer(4)],
|
vec![Value::integer(4)],
|
||||||
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
@ -78,23 +78,23 @@ fn if_else_assigment() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(22, 24)
|
Span(22, 24)
|
||||||
),
|
),
|
||||||
(Instruction::jump(5, true), Span(22, 24)),
|
(Instruction::jump(5, true), Span(22, 24)),
|
||||||
(Instruction::load_constant(0, 2, false), Span(41, 42)),
|
(Instruction::load_constant(0, 1, false), Span(41, 42)),
|
||||||
(Instruction::load_constant(1, 3, false), Span(44, 45)),
|
(Instruction::load_constant(1, 2, false), Span(44, 45)),
|
||||||
(Instruction::load_constant(2, 4, false), Span(47, 48)),
|
(Instruction::load_constant(2, 3, false), Span(47, 48)),
|
||||||
(Instruction::load_constant(3, 5, false), Span(50, 51)),
|
(Instruction::load_constant(3, 0, false), Span(50, 51)),
|
||||||
(Instruction::load_constant(4, 6, false), Span(65, 67)),
|
(Instruction::load_constant(4, 4, false), Span(65, 67)),
|
||||||
(Instruction::jump(6, true), Span(138, 139)),
|
(Instruction::jump(6, true), Span(138, 139)),
|
||||||
(Instruction::jump(5, true), Span(138, 139)),
|
(Instruction::jump(5, true), Span(138, 139)),
|
||||||
(Instruction::load_constant(5, 7, false), Span(97, 98)),
|
(Instruction::load_constant(5, 1, false), Span(97, 98)),
|
||||||
(Instruction::load_constant(6, 8, false), Span(100, 101)),
|
(Instruction::load_constant(6, 2, false), Span(100, 101)),
|
||||||
(Instruction::load_constant(7, 9, false), Span(103, 104)),
|
(Instruction::load_constant(7, 3, false), Span(103, 104)),
|
||||||
(Instruction::load_constant(8, 10, false), Span(106, 107)),
|
(Instruction::load_constant(8, 0, false), Span(106, 107)),
|
||||||
(
|
(
|
||||||
Instruction::call_native(9, NativeFunction::Panic, 0),
|
Instruction::call_native(9, NativeFunction::Panic, 0),
|
||||||
Span(121, 128)
|
Span(121, 128)
|
||||||
@ -105,17 +105,11 @@ fn if_else_assigment() {
|
|||||||
(Instruction::r#return(true), Span(149, 149)),
|
(Instruction::r#return(true), Span(149, 149)),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
Value::integer(4),
|
|
||||||
Value::integer(4),
|
Value::integer(4),
|
||||||
Value::integer(1),
|
Value::integer(1),
|
||||||
Value::integer(2),
|
Value::integer(2),
|
||||||
Value::integer(3),
|
Value::integer(3),
|
||||||
Value::integer(4),
|
|
||||||
Value::integer(42),
|
Value::integer(42),
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(3),
|
|
||||||
Value::integer(4),
|
|
||||||
],
|
],
|
||||||
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
vec![Local::new(Identifier::new("a"), None, false, 0, 0)]
|
||||||
)),
|
)),
|
||||||
@ -139,36 +133,30 @@ fn if_else_complex() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(14, 16)
|
Span(14, 16)
|
||||||
),
|
),
|
||||||
(Instruction::jump(5, true), Span(14, 16)),
|
(Instruction::jump(5, true), Span(14, 16)),
|
||||||
(Instruction::load_constant(0, 2, false), Span(33, 34)),
|
(Instruction::load_constant(0, 0, false), Span(33, 34)),
|
||||||
(Instruction::load_constant(1, 3, false), Span(36, 37)),
|
(Instruction::load_constant(1, 1, false), Span(36, 37)),
|
||||||
(Instruction::load_constant(2, 4, false), Span(39, 40)),
|
(Instruction::load_constant(2, 2, false), Span(39, 40)),
|
||||||
(Instruction::load_constant(3, 5, false), Span(42, 43)),
|
(Instruction::load_constant(3, 3, false), Span(42, 43)),
|
||||||
(Instruction::jump(5, true), Span(95, 95)),
|
(Instruction::jump(5, true), Span(95, 95)),
|
||||||
(Instruction::jump(4, true), Span(95, 95)),
|
(Instruction::jump(4, true), Span(95, 95)),
|
||||||
(Instruction::load_constant(4, 6, false), Span(74, 75)),
|
(Instruction::load_constant(4, 0, false), Span(74, 75)),
|
||||||
(Instruction::load_constant(5, 7, false), Span(77, 78)),
|
(Instruction::load_constant(5, 1, false), Span(77, 78)),
|
||||||
(Instruction::load_constant(6, 8, false), Span(80, 81)),
|
(Instruction::load_constant(6, 2, false), Span(80, 81)),
|
||||||
(Instruction::load_constant(7, 9, false), Span(83, 84)),
|
(Instruction::load_constant(7, 3, false), Span(83, 84)),
|
||||||
(Instruction::r#move(7, 3), Span(95, 95)),
|
(Instruction::r#move(7, 3), Span(95, 95)),
|
||||||
(Instruction::r#return(false), Span(95, 95)),
|
(Instruction::r#return(false), Span(95, 95)),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(1),
|
Value::integer(1),
|
||||||
Value::integer(2),
|
Value::integer(2),
|
||||||
Value::integer(3),
|
Value::integer(3),
|
||||||
Value::integer(4),
|
Value::integer(4),
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(3),
|
|
||||||
Value::integer(4)
|
|
||||||
],
|
],
|
||||||
vec![]
|
vec![]
|
||||||
))
|
))
|
||||||
@ -289,13 +277,13 @@ fn if_else_true() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(5, 7)
|
Span(5, 7)
|
||||||
),
|
),
|
||||||
(Instruction::jump(1, true), Span(5, 7)),
|
(Instruction::jump(1, true), Span(5, 7)),
|
||||||
(Instruction::load_constant(0, 2, true), Span(12, 14)),
|
(Instruction::load_constant(0, 1, true), Span(12, 14)),
|
||||||
(
|
(
|
||||||
Instruction::call_native(1, NativeFunction::Panic, 0),
|
Instruction::call_native(1, NativeFunction::Panic, 0),
|
||||||
Span(24, 31)
|
Span(24, 31)
|
||||||
@ -303,7 +291,7 @@ fn if_else_true() {
|
|||||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
(Instruction::r#move(1, 0), Span(33, 33)),
|
||||||
(Instruction::r#return(true), Span(33, 33))
|
(Instruction::r#return(true), Span(33, 33))
|
||||||
],
|
],
|
||||||
vec![Value::integer(1), Value::integer(1), Value::integer(42)],
|
vec![Value::integer(1), Value::integer(42)],
|
||||||
vec![]
|
vec![]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
@ -327,10 +315,10 @@ fn if_false() {
|
|||||||
Span(5, 7)
|
Span(5, 7)
|
||||||
),
|
),
|
||||||
(Instruction::jump(1, true), Span(5, 7)),
|
(Instruction::jump(1, true), Span(5, 7)),
|
||||||
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
(Instruction::load_constant(0, 1, false), Span(12, 13)),
|
||||||
(Instruction::r#return(false), Span(15, 15))
|
(Instruction::r#return(false), Span(15, 15))
|
||||||
],
|
],
|
||||||
vec![Value::integer(1), Value::integer(2), Value::integer(2)],
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
vec![]
|
vec![]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
@ -348,16 +336,16 @@ fn if_true() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(5, 7)
|
Span(5, 7)
|
||||||
),
|
),
|
||||||
(Instruction::jump(1, true), Span(5, 7)),
|
(Instruction::jump(1, true), Span(5, 7)),
|
||||||
(Instruction::load_constant(0, 2, false), Span(12, 13)),
|
(Instruction::load_constant(0, 1, false), Span(12, 13)),
|
||||||
(Instruction::r#return(false), Span(15, 15))
|
(Instruction::r#return(false), Span(15, 15))
|
||||||
],
|
],
|
||||||
vec![Value::integer(1), Value::integer(1), Value::integer(2)],
|
vec![Value::integer(1), Value::integer(2)],
|
||||||
vec![]
|
vec![]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
@ -48,57 +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 block_scope() {
|
|
||||||
let source = "
|
|
||||||
let a = 0;
|
|
||||||
{
|
|
||||||
let b = 42;
|
|
||||||
{
|
|
||||||
let c = 1;
|
|
||||||
}
|
|
||||||
let d = 2;
|
|
||||||
}
|
|
||||||
let e = 1;
|
|
||||||
";
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
parse(source),
|
|
||||||
Ok(Chunk::with_data(
|
|
||||||
None,
|
|
||||||
vec![
|
|
||||||
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
|
||||||
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
|
||||||
(Instruction::load_constant(1, 1, false), Span(50, 52)),
|
|
||||||
(Instruction::define_local(1, 1, false), Span(46, 47)),
|
|
||||||
(Instruction::load_constant(2, 2, false), Span(92, 93)),
|
|
||||||
(Instruction::define_local(2, 2, false), Span(88, 89)),
|
|
||||||
(Instruction::load_constant(3, 3, false), Span(129, 130)),
|
|
||||||
(Instruction::define_local(3, 3, false), Span(125, 126)),
|
|
||||||
(Instruction::load_constant(4, 4, false), Span(158, 159)),
|
|
||||||
(Instruction::define_local(4, 4, false), Span(154, 155)),
|
|
||||||
(Instruction::r#return(false), Span(165, 165))
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
Value::integer(0),
|
|
||||||
Value::integer(42),
|
|
||||||
Value::integer(1),
|
|
||||||
Value::integer(2),
|
|
||||||
Value::integer(1)
|
|
||||||
],
|
|
||||||
vec![
|
|
||||||
Local::new(Identifier::new("a"), None, false, 0, 0),
|
|
||||||
Local::new(Identifier::new("b"), None, false, 1, 1),
|
|
||||||
Local::new(Identifier::new("c"), None, false, 2, 2),
|
|
||||||
Local::new(Identifier::new("d"), None, false, 1, 3),
|
|
||||||
Local::new(Identifier::new("e"), None, false, 0, 4),
|
|
||||||
]
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(run(source), Ok(None));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant() {
|
fn constant() {
|
||||||
let source = "42";
|
let source = "42";
|
||||||
@ -150,14 +99,14 @@ fn divide() {
|
|||||||
None,
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::divide(0, 0, 1)
|
*Instruction::divide(0, 0, 0)
|
||||||
.set_b_is_constant()
|
.set_b_is_constant()
|
||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(2, 3)
|
Span(2, 3)
|
||||||
),
|
),
|
||||||
(Instruction::r#return(true), Span(5, 5))
|
(Instruction::r#return(true), Span(5, 5))
|
||||||
],
|
],
|
||||||
vec![Value::integer(2), Value::integer(2)],
|
vec![Value::integer(2)],
|
||||||
vec![]
|
vec![]
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
@ -177,13 +126,13 @@ fn divide_assign() {
|
|||||||
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
(
|
(
|
||||||
*Instruction::divide(0, 0, 1).set_c_is_constant(),
|
*Instruction::divide(0, 0, 0).set_c_is_constant(),
|
||||||
Span(17, 19)
|
Span(17, 19)
|
||||||
),
|
),
|
||||||
(Instruction::get_local(1, 0), Span(23, 24)),
|
(Instruction::get_local(1, 0), Span(23, 24)),
|
||||||
(Instruction::r#return(true), Span(24, 24))
|
(Instruction::r#return(true), Span(24, 24))
|
||||||
],
|
],
|
||||||
vec![Value::integer(2), Value::integer(2)],
|
vec![Value::integer(2)],
|
||||||
vec![Local::new(Identifier::new("a"), None, true, 0, 0)]
|
vec![Local::new(Identifier::new("a"), None, true, 0, 0)]
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -12,6 +12,56 @@ fn allow_access_to_parent_scope() {
|
|||||||
assert_eq!(run(source), Ok(Some(Value::integer(1))));
|
assert_eq!(run(source), Ok(Some(Value::integer(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn block_scope() {
|
||||||
|
let source = "
|
||||||
|
let a = 0;
|
||||||
|
{
|
||||||
|
let b = 42;
|
||||||
|
{
|
||||||
|
let c = 1;
|
||||||
|
}
|
||||||
|
let d = 2;
|
||||||
|
}
|
||||||
|
let e = 1;
|
||||||
|
";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
||||||
|
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
||||||
|
(Instruction::load_constant(1, 1, false), Span(50, 52)),
|
||||||
|
(Instruction::define_local(1, 1, false), Span(46, 47)),
|
||||||
|
(Instruction::load_constant(2, 2, false), Span(92, 93)),
|
||||||
|
(Instruction::define_local(2, 2, false), Span(88, 89)),
|
||||||
|
(Instruction::load_constant(3, 3, false), Span(129, 130)),
|
||||||
|
(Instruction::define_local(3, 3, false), Span(125, 126)),
|
||||||
|
(Instruction::load_constant(4, 2, false), Span(158, 159)),
|
||||||
|
(Instruction::define_local(4, 4, false), Span(154, 155)),
|
||||||
|
(Instruction::r#return(false), Span(165, 165))
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Value::integer(0),
|
||||||
|
Value::integer(42),
|
||||||
|
Value::integer(1),
|
||||||
|
Value::integer(2),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Local::new(Identifier::new("a"), None, false, 0, 0),
|
||||||
|
Local::new(Identifier::new("b"), None, false, 1, 1),
|
||||||
|
Local::new(Identifier::new("c"), None, false, 2, 2),
|
||||||
|
Local::new(Identifier::new("d"), None, false, 1, 3),
|
||||||
|
Local::new(Identifier::new("e"), None, false, 0, 4),
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(run(source), Ok(None));
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn disallow_access_to_child_scope() {
|
// fn disallow_access_to_child_scope() {
|
||||||
// let source = r#"
|
// let source = r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user