1
0

Refactor to use 64-bit instructions

This commit is contained in:
Jeff 2024-11-25 20:43:18 -05:00
parent e04ead3848
commit fbaf59abe2
13 changed files with 467 additions and 569 deletions

View File

@ -1,13 +1,13 @@
use std::{ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
fs::{read_to_string, File, OpenOptions}, fs::{File, OpenOptions},
io::{stdin, stdout, Read, Write}, io::{stdin, stdout, Read, Write},
time::Instant, time::Instant,
}; };
use clap::{Args, Parser, Subcommand, ValueEnum}; use clap::{Args, Parser, Subcommand, ValueEnum};
use colored::Colorize; use colored::Colorize;
use dust_lang::{compile, display_token_list, format, lex, run_source, vm::run_chunk, Chunk}; use dust_lang::{compile, display_token_list, format, lex, vm::run_chunk};
use env_logger::Target; use env_logger::Target;
use log::{Level, LevelFilter}; use log::{Level, LevelFilter};

View File

@ -4,7 +4,7 @@
//! list of locals that can be executed by the Dust virtual machine. Chunks have a name when they //! list of locals that can be executed by the Dust virtual machine. Chunks have a name when they
//! belong to a named function. //! belong to a named function.
use std::fmt::{self, Debug, Display, Formatter}; use std::fmt::{self, Debug, Display, Formatter, Write};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -193,7 +193,7 @@ impl Debug for Chunk {
let disassembly = self.disassembler().style(false).disassemble(); let disassembly = self.disassembler().style(false).disassemble();
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
write!(f, "\n",)?; f.write_char('\n')?;
} }
write!(f, "{}", disassembly) write!(f, "{}", disassembly)

View File

@ -4,7 +4,6 @@
//! - [`compile`], which compiles the entire input and returns a chunk //! - [`compile`], which compiles the entire input and returns a chunk
//! - [`Compiler`], which compiles the input a token at a time while assembling a chunk //! - [`Compiler`], which compiles the input a token at a time while assembling a chunk
use std::{ use std::{
collections::HashMap,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
mem::replace, mem::replace,
num::{ParseFloatError, ParseIntError}, num::{ParseFloatError, ParseIntError},
@ -49,7 +48,7 @@ pub fn compile(source: &str) -> Result<Chunk, DustError> {
pub struct Compiler<'src> { pub struct Compiler<'src> {
chunk: Chunk, chunk: Chunk,
lexer: Lexer<'src>, lexer: Lexer<'src>,
local_declarations: HashMap<u8, u8>, local_declarations: Vec<u8>,
current_token: Token<'src>, current_token: Token<'src>,
current_position: Span, current_position: Span,
@ -79,7 +78,7 @@ impl<'src> Compiler<'src> {
Ok(Compiler { Ok(Compiler {
chunk, chunk,
lexer, lexer,
local_declarations: HashMap::new(), local_declarations: Vec::new(),
current_token, current_token,
current_position, current_position,
previous_token: Token::Eof, previous_token: Token::Eof,
@ -119,9 +118,7 @@ impl<'src> Compiler<'src> {
.iter() .iter()
.filter_map(|(instruction, _)| { .filter_map(|(instruction, _)| {
if instruction.yields_value() { if instruction.yields_value() {
let to_register = instruction.a(); Some(instruction.a() + 1)
Some(to_register + 1)
} else { } else {
None None
} }
@ -199,20 +196,21 @@ impl<'src> Compiler<'src> {
let identifier = ConcreteValue::string(identifier); let identifier = ConcreteValue::string(identifier);
let identifier_index = self.chunk.push_or_get_constant(identifier); let identifier_index = self.chunk.push_or_get_constant(identifier);
let local_index = self.chunk.locals().len() as u8; let local_index = self.chunk.locals().len();
self.chunk self.chunk
.locals_mut() .locals_mut()
.push(Local::new(identifier_index, r#type, is_mutable, scope)); .push(Local::new(identifier_index, r#type, is_mutable, scope));
self.local_declarations.insert(local_index, register_index); self.local_declarations.insert(local_index, register_index);
(local_index, identifier_index) (local_index as u8, identifier_index)
} }
fn redeclare_local(&mut self, local_index: u8, register_index: u8) -> Result<(), CompileError> { fn redeclare_local(&mut self, local_index: u8, register_index: u8) -> Result<(), CompileError> {
let local = self.get_local(local_index)?; let local_index = local_index as usize;
if !self.current_scope.contains(&local.scope) { if !self.local_declarations.len() <= local_index {
let local = self.get_local(local_index as u8)?;
let identifier = self let identifier = self
.chunk .chunk
.constants() .constants()
@ -228,7 +226,7 @@ impl<'src> Compiler<'src> {
}); });
} }
self.local_declarations.insert(local_index, register_index); self.local_declarations[local_index] = register_index;
Ok(()) Ok(())
} }
@ -696,19 +694,22 @@ impl<'src> Compiler<'src> {
let local = self.get_local(local_index)?; let local = self.get_local(local_index)?;
is_mutable_local = local.is_mutable; is_mutable_local = local.is_mutable;
*self.local_declarations.get(&local_index).ok_or_else(|| { *self
let identifier = self .local_declarations
.chunk .get(local_index as usize)
.constants() .ok_or_else(|| {
.get(local.identifier_index as usize) let identifier = self
.unwrap() .chunk
.to_string(); .constants()
.get(local.identifier_index as usize)
.unwrap()
.to_string();
CompileError::UndeclaredVariable { CompileError::UndeclaredVariable {
identifier, identifier,
position: self.current_position, position: self.current_position,
} }
})? })?
} }
Operation::LoadConstant => { Operation::LoadConstant => {
is_constant = true; is_constant = true;
@ -785,7 +786,6 @@ impl<'src> Compiler<'src> {
} else { } else {
self.next_register() self.next_register()
}; };
let mut new_instruction = match operator { let mut new_instruction = match operator {
Token::Plus => Instruction::add(register, left, right), Token::Plus => Instruction::add(register, left, right),
Token::PlusEqual => Instruction::add(register, left, right), Token::PlusEqual => Instruction::add(register, left, right),
@ -827,12 +827,7 @@ impl<'src> Compiler<'src> {
self.emit_instruction(new_instruction, operator_position); self.emit_instruction(new_instruction, operator_position);
if let Token::PlusEqual if is_assignment {
| Token::MinusEqual
| Token::StarEqual
| Token::SlashEqual
| Token::PercentEqual = operator
{
self.previous_expression_type = Type::None; self.previous_expression_type = Type::None;
} else { } else {
self.previous_expression_type = self.get_instruction_type(&left_instruction)?; self.previous_expression_type = self.get_instruction_type(&left_instruction)?;
@ -859,7 +854,6 @@ impl<'src> Compiler<'src> {
})?; })?;
let (push_back_left, left_is_constant, _, left) = let (push_back_left, left_is_constant, _, left) =
self.handle_binary_argument(&left_instruction)?; self.handle_binary_argument(&left_instruction)?;
let operator = self.current_token; let operator = self.current_token;
let operator_position = self.current_position; let operator_position = self.current_position;
let rule = ParseRule::from(&operator); let rule = ParseRule::from(&operator);
@ -1028,9 +1022,10 @@ impl<'src> Compiler<'src> {
}); });
} }
let register = self.next_register() - 1;
self.parse_expression()?; self.parse_expression()?;
let register = self.local_declarations[local_index as usize];
self.redeclare_local(local_index, register)?; self.redeclare_local(local_index, register)?;
self.emit_instruction( self.emit_instruction(
Instruction::set_local(register, local_index), Instruction::set_local(register, local_index),

View File

@ -8,7 +8,7 @@ use crate::{CompileError, DustError, LexError, Lexer, Token};
pub fn format( pub fn format(
source: &str, source: &str,
colored: bool, colored: bool,
indent: usize, _indent: usize,
line_numbers: bool, line_numbers: bool,
) -> Result<String, DustError> { ) -> Result<String, DustError> {
let lexer = Lexer::new(source); let lexer = Lexer::new(source);

File diff suppressed because it is too large Load Diff

View File

@ -74,8 +74,8 @@ macro_rules! define_native_function {
} }
} }
impl From<u8> for NativeFunction { impl From<u16> for NativeFunction {
fn from(byte: u8) -> Self { fn from(byte: u16) -> Self {
match byte { match byte {
$( $(
$byte => NativeFunction::$name, $byte => NativeFunction::$name,
@ -126,7 +126,7 @@ define_native_function! {
// (AssertNotEqual, 2_u8, "assert_not_equal", false), // (AssertNotEqual, 2_u8, "assert_not_equal", false),
( (
Panic, Panic,
3_u8, 3,
"panic", "panic",
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,
@ -143,7 +143,7 @@ define_native_function! {
// (ToInteger, 7_u8, "to_integer", true), // (ToInteger, 7_u8, "to_integer", true),
( (
ToString, ToString,
8_u8, 8,
"to_string", "to_string",
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,
@ -204,7 +204,7 @@ define_native_function! {
// (ReadFile, 49_u8, "read_file", true), // (ReadFile, 49_u8, "read_file", true),
( (
ReadLine, ReadLine,
50_u8, 50,
"read_line", "read_line",
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,
@ -220,7 +220,7 @@ define_native_function! {
// (PrependFile, 54_u8, "prepend_file", false), // (PrependFile, 54_u8, "prepend_file", false),
( (
Write, Write,
55_u8, 55,
"write", "write",
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,
@ -232,7 +232,7 @@ define_native_function! {
// (WriteFile, 56_u8, "write_file", false), // (WriteFile, 56_u8, "write_file", false),
( (
WriteLine, WriteLine,
57_u8, 57,
"write_line", "write_line",
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,

View File

@ -1,7 +1,6 @@
//! Virtual machine and errors //! Virtual machine and errors
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::HashMap,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
io, io,
}; };
@ -34,7 +33,7 @@ pub struct Vm<'a> {
chunk: &'a Chunk, chunk: &'a Chunk,
stack: Vec<Register>, stack: Vec<Register>,
parent: Option<&'a Vm<'a>>, parent: Option<&'a Vm<'a>>,
local_definitions: HashMap<u8, u8>, local_definitions: Vec<Option<u8>>,
ip: usize, ip: usize,
last_assigned_register: Option<u8>, last_assigned_register: Option<u8>,
@ -49,7 +48,7 @@ impl<'a> Vm<'a> {
chunk, chunk,
stack: Vec::new(), stack: Vec::new(),
parent, parent,
local_definitions: HashMap::new(), local_definitions: vec![None; chunk.locals().len()],
ip: 0, ip: 0,
last_assigned_register: None, last_assigned_register: None,
current_position: Span(0, 0), current_position: Span(0, 0),
@ -158,12 +157,12 @@ impl<'a> Vm<'a> {
let from_register = instruction.a(); let from_register = instruction.a();
let to_local = instruction.b(); let to_local = instruction.b();
self.define_local(to_local, from_register)?; self.local_definitions[to_local as usize] = Some(from_register);
} }
Operation::GetLocal => { Operation::GetLocal => {
let to_register = instruction.a(); let to_register = instruction.a();
let local_index = instruction.b(); let local_index = instruction.b();
let local_register = self.local_definitions.get(&local_index).copied().ok_or( let local_register = self.local_definitions[local_index as usize].ok_or(
VmError::UndefinedLocal { VmError::UndefinedLocal {
local_index, local_index,
position: self.current_position, position: self.current_position,
@ -176,16 +175,8 @@ impl<'a> Vm<'a> {
Operation::SetLocal => { Operation::SetLocal => {
let from_register = instruction.a(); let from_register = instruction.a();
let to_local = instruction.b(); let to_local = instruction.b();
let local_register = self.local_definitions.get(&to_local).copied().ok_or(
VmError::UndefinedLocal {
local_index: to_local,
position: self.current_position,
},
)?;
let register = Register::Pointer(Pointer::Stack(from_register));
self.define_local(to_local, from_register)?; self.local_definitions[to_local as usize] = Some(from_register);
self.set_register(local_register, register)?;
} }
Operation::Add => { Operation::Add => {
let to_register = instruction.a(); let to_register = instruction.a();
@ -640,14 +631,6 @@ impl<'a> Vm<'a> {
Ok(instruction) Ok(instruction)
} }
fn define_local(&mut self, local_index: u8, register_index: u8) -> Result<(), VmError> {
log::debug!("Define local L{}", local_index);
self.local_definitions.insert(local_index, register_index);
Ok(())
}
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View File

@ -23,8 +23,8 @@ fn function() {
], ],
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
vec![ vec![
Local::new(0, Type::Integer, false, Scope::default(), 0), Local::new(0, Type::Integer, false, Scope::default()),
Local::new(1, Type::Integer, false, Scope::default(), 1) Local::new(1, Type::Integer, false, Scope::default())
] ]
)))) ))))
); );
@ -64,8 +64,8 @@ fn function_call() {
], ],
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
vec![ vec![
Local::new(0, Type::Integer, false, Scope::default(), 0), Local::new(0, Type::Integer, false, Scope::default()),
Local::new(1, Type::Integer, false, Scope::default(), 1) Local::new(1, Type::Integer, false, Scope::default())
] ]
)), )),
ConcreteValue::Integer(1), ConcreteValue::Integer(1),
@ -93,6 +93,7 @@ fn function_declaration() {
}, },
vec![ vec![
(Instruction::load_constant(0, 0, false), Span(0, 40)), (Instruction::load_constant(0, 0, false), Span(0, 40)),
(Instruction::define_local(0, 0, false), Span(3, 6)),
(Instruction::r#return(false), Span(40, 40)) (Instruction::r#return(false), Span(40, 40))
], ],
vec![ vec![
@ -109,8 +110,8 @@ fn function_declaration() {
], ],
vec![ConcreteValue::string("a"), ConcreteValue::string("b")], vec![ConcreteValue::string("a"), ConcreteValue::string("b")],
vec![ vec![
Local::new(0, Type::Integer, false, Scope::default(), 0), Local::new(0, Type::Integer, false, Scope::default()),
Local::new(1, Type::Integer, false, Scope::default(), 1) Local::new(1, Type::Integer, false, Scope::default())
] ]
)), )),
ConcreteValue::string("add"), ConcreteValue::string("add"),
@ -124,7 +125,6 @@ fn function_declaration() {
}), }),
false, false,
Scope::default(), Scope::default(),
0
),], ),],
)), )),
); );

View File

@ -71,7 +71,9 @@ fn variable_and() {
}, },
vec![ vec![
(Instruction::load_boolean(0, true, false), Span(8, 12)), (Instruction::load_boolean(0, true, false), Span(8, 12)),
(Instruction::define_local(0, 0, false), Span(4, 5)),
(Instruction::load_boolean(1, false, false), Span(22, 27)), (Instruction::load_boolean(1, false, false), Span(22, 27)),
(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, true), Span(31, 33)), (Instruction::test(2, true), Span(31, 33)),
(Instruction::jump(1, true), Span(31, 33)), (Instruction::jump(1, true), Span(31, 33)),
@ -80,8 +82,8 @@ fn variable_and() {
], ],
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
vec![ vec![
Local::new(0, Type::Boolean, false, Scope::default(), 0), Local::new(0, Type::Boolean, false, Scope::default()),
Local::new(1, Type::Boolean, false, Scope::default(), 1), Local::new(1, Type::Boolean, false, Scope::default()),
] ]
)) ))
); );

View File

@ -15,6 +15,7 @@ fn r#while() {
}, },
vec![ vec![
(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::less(true, 0, 2).set_c_is_constant(), *Instruction::less(true, 0, 2).set_c_is_constant(),
Span(23, 24) Span(23, 24)
@ -31,7 +32,7 @@ fn r#while() {
ConcreteValue::Integer(5), ConcreteValue::Integer(5),
ConcreteValue::Integer(1), ConcreteValue::Integer(1),
], ],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)), )),
); );

View File

@ -45,6 +45,7 @@ fn add_assign() {
}, },
vec![ vec![
(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::add(0, 0, 2).set_c_is_constant(), Span(17, 19)), (*Instruction::add(0, 0, 2).set_c_is_constant(), 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))
@ -54,7 +55,7 @@ fn add_assign() {
ConcreteValue::string("a"), ConcreteValue::string("a"),
ConcreteValue::Integer(2) ConcreteValue::Integer(2)
], ],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)) ))
); );
@ -138,6 +139,7 @@ fn divide_assign() {
}, },
vec![ vec![
(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::divide(0, 0, 0).set_c_is_constant(), *Instruction::divide(0, 0, 0).set_c_is_constant(),
Span(17, 19) Span(17, 19)
@ -146,7 +148,7 @@ fn divide_assign() {
(Instruction::r#return(true), Span(24, 24)) (Instruction::r#return(true), Span(24, 24))
], ],
vec![ConcreteValue::Integer(2), ConcreteValue::string("a")], vec![ConcreteValue::Integer(2), ConcreteValue::string("a")],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)) ))
); );
@ -261,6 +263,7 @@ fn multiply_assign() {
}, },
vec![ vec![
(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::multiply(0, 0, 2).set_c_is_constant(), *Instruction::multiply(0, 0, 2).set_c_is_constant(),
Span(17, 19) Span(17, 19)
@ -273,7 +276,7 @@ fn multiply_assign() {
ConcreteValue::string("a"), ConcreteValue::string("a"),
ConcreteValue::Integer(3) ConcreteValue::Integer(3)
], ],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)) ))
); );
@ -341,6 +344,7 @@ fn subtract_assign() {
}, },
vec![ vec![
(Instruction::load_constant(0, 0, false), Span(12, 14)), (Instruction::load_constant(0, 0, false), Span(12, 14)),
(Instruction::define_local(0, 0, true), Span(8, 9)),
( (
*Instruction::subtract(0, 0, 2).set_c_is_constant(), *Instruction::subtract(0, 0, 2).set_c_is_constant(),
Span(18, 20) Span(18, 20)
@ -353,7 +357,7 @@ fn subtract_assign() {
ConcreteValue::string("x"), ConcreteValue::string("x"),
ConcreteValue::Integer(2) ConcreteValue::Integer(2)
], ],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)), )),
); );

View File

@ -60,11 +60,11 @@ fn block_scope() {
ConcreteValue::string("e"), ConcreteValue::string("e"),
], ],
vec![ vec![
Local::new(1, Type::Integer, false, Scope::new(0, 0), 0), Local::new(1, Type::Integer, false, Scope::new(0, 0)),
Local::new(3, Type::Integer, false, Scope::new(1, 1), 0), Local::new(3, Type::Integer, false, Scope::new(1, 1)),
Local::new(5, Type::Integer, false, Scope::new(2, 2), 0), Local::new(5, Type::Integer, false, Scope::new(2, 2)),
Local::new(7, Type::Integer, false, Scope::new(1, 1), 0), Local::new(7, Type::Integer, false, Scope::new(1, 1)),
Local::new(8, Type::Integer, false, Scope::new(0, 0), 0), Local::new(8, Type::Integer, false, Scope::new(0, 0)),
] ]
)), )),
); );
@ -136,15 +136,15 @@ fn multiple_block_scopes() {
ConcreteValue::string("e"), ConcreteValue::string("e"),
], ],
vec![ vec![
Local::new(1, Type::Integer, false, Scope::new(0, 0), 0), Local::new(1, Type::Integer, false, Scope::new(0, 0)),
Local::new(3, Type::Integer, false, Scope::new(1, 1), 0), Local::new(3, Type::Integer, false, Scope::new(1, 1)),
Local::new(5, Type::Integer, false, Scope::new(2, 2), 0), Local::new(5, Type::Integer, false, Scope::new(2, 2)),
Local::new(6, Type::Integer, false, Scope::new(1, 1), 0), Local::new(6, Type::Integer, false, Scope::new(1, 1)),
Local::new(7, Type::Integer, false, Scope::new(0, 0), 0), Local::new(7, Type::Integer, false, Scope::new(0, 0)),
Local::new(3, Type::Integer, false, Scope::new(1, 3), 0), Local::new(3, Type::Integer, false, Scope::new(1, 3)),
Local::new(5, Type::Integer, false, Scope::new(2, 4), 0), Local::new(5, Type::Integer, false, Scope::new(2, 4)),
Local::new(6, Type::Integer, false, Scope::new(1, 3), 0), Local::new(6, Type::Integer, false, Scope::new(1, 3)),
Local::new(8, Type::Integer, false, Scope::new(0, 0), 0), Local::new(8, Type::Integer, false, Scope::new(0, 0)),
] ]
)), )),
); );

View File

@ -15,10 +15,11 @@ fn define_local() {
}, },
vec![ vec![
(Instruction::load_constant(0, 0, false), Span(8, 10)), (Instruction::load_constant(0, 0, false), Span(8, 10)),
(Instruction::define_local(0, 0, false), Span(4, 5)),
(Instruction::r#return(false), Span(11, 11)) (Instruction::r#return(false), Span(11, 11))
], ],
vec![ConcreteValue::Integer(42), ConcreteValue::string("x")], vec![ConcreteValue::Integer(42), ConcreteValue::string("x")],
vec![Local::new(1, Type::Integer, false, Scope::default(), 0)] vec![Local::new(1, Type::Integer, false, Scope::default())]
)), )),
); );
@ -57,8 +58,9 @@ fn set_local() {
}, },
vec![ vec![
(Instruction::load_constant(0, 0, false), Span(12, 14)), (Instruction::load_constant(0, 0, false), Span(12, 14)),
(Instruction::define_local(0, 0, true), Span(8, 9)),
(Instruction::load_constant(1, 2, false), Span(20, 22)), (Instruction::load_constant(1, 2, false), Span(20, 22)),
(Instruction::set_local(0, 0), Span(16, 17)), (Instruction::set_local(1, 0), Span(16, 17)),
(Instruction::get_local(2, 0), Span(24, 25)), (Instruction::get_local(2, 0), Span(24, 25)),
(Instruction::r#return(true), Span(25, 25)), (Instruction::r#return(true), Span(25, 25)),
], ],
@ -67,7 +69,7 @@ fn set_local() {
ConcreteValue::string("x"), ConcreteValue::string("x"),
ConcreteValue::Integer(42) ConcreteValue::Integer(42)
], ],
vec![Local::new(1, Type::Integer, true, Scope::default(), 0)] vec![Local::new(1, Type::Integer, true, Scope::default())]
)), )),
); );