Continue adding type evaluations
This commit is contained in:
parent
960931ce6e
commit
0f3924341f
@ -40,20 +40,17 @@ impl Chunk {
|
|||||||
|
|
||||||
pub fn with_data(
|
pub fn with_data(
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
|
r#type: FunctionType,
|
||||||
instructions: Vec<(Instruction, Span)>,
|
instructions: Vec<(Instruction, Span)>,
|
||||||
constants: Vec<ConcreteValue>,
|
constants: Vec<ConcreteValue>,
|
||||||
locals: Vec<Local>,
|
locals: Vec<Local>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
|
r#type,
|
||||||
instructions,
|
instructions,
|
||||||
constants,
|
constants,
|
||||||
locals,
|
locals,
|
||||||
r#type: FunctionType {
|
|
||||||
type_parameters: None,
|
|
||||||
value_parameters: None,
|
|
||||||
return_type: Box::new(Type::None),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +58,16 @@ impl Chunk {
|
|||||||
self.name.as_ref()
|
self.name.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_name(&mut self, name: String) {
|
||||||
|
self.name = Some(name);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn r#type(&self) -> &FunctionType {
|
pub fn r#type(&self) -> &FunctionType {
|
||||||
&self.r#type
|
&self.r#type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_name(&mut self, name: String) {
|
pub fn set_type(&mut self, r#type: FunctionType) {
|
||||||
self.name = Some(name);
|
self.r#type = r#type;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -38,7 +38,29 @@ pub fn compile(source: &str) -> Result<Chunk, DustError> {
|
|||||||
.parse_top_level()
|
.parse_top_level()
|
||||||
.map_err(|error| DustError::Compile { error, source })?;
|
.map_err(|error| DustError::Compile { error, source })?;
|
||||||
|
|
||||||
Ok(compiler.finish())
|
let return_type = if compiler
|
||||||
|
.chunk
|
||||||
|
.instructions()
|
||||||
|
.iter()
|
||||||
|
.last()
|
||||||
|
.map(|(instruction, _)| {
|
||||||
|
let should_return = instruction.b_as_boolean();
|
||||||
|
|
||||||
|
(instruction.operation(), should_return)
|
||||||
|
})
|
||||||
|
== Some((Operation::Return, true))
|
||||||
|
{
|
||||||
|
Box::new(compiler.previous_expression_type.clone())
|
||||||
|
} else {
|
||||||
|
Box::new(Type::None)
|
||||||
|
};
|
||||||
|
let chunk_type = FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(compiler.finish(chunk_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low-level tool for compiling the input a token at a time while assembling a chunk.
|
/// Low-level tool for compiling the input a token at a time while assembling a chunk.
|
||||||
@ -91,9 +113,11 @@ impl<'src> Compiler<'src> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(self) -> Chunk {
|
pub fn finish(mut self, r#type: FunctionType) -> Chunk {
|
||||||
log::info!("End chunk with {} optimizations", self.optimization_count);
|
log::info!("End chunk with {} optimizations", self.optimization_count);
|
||||||
|
|
||||||
|
self.chunk.set_type(r#type);
|
||||||
|
|
||||||
self.chunk
|
self.chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,13 +212,14 @@ 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;
|
||||||
|
|
||||||
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_definitions.push(register_index);
|
self.local_definitions.push(register_index);
|
||||||
|
|
||||||
(self.chunk.locals().len() as u8 - 1, identifier_index)
|
(local_index, identifier_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allow(&mut self, allowed: Token) -> Result<bool, CompileError> {
|
fn allow(&mut self, allowed: Token) -> Result<bool, CompileError> {
|
||||||
@ -953,8 +978,8 @@ impl<'src> Compiler<'src> {
|
|||||||
|
|
||||||
self.previous_expression_type = Type::None;
|
self.previous_expression_type = Type::None;
|
||||||
|
|
||||||
let mut optimizer = Optimizer::new(self.chunk.instructions_mut());
|
let mut optimizer = Optimizer::new(&mut self.chunk);
|
||||||
let optimized = Optimizer::optimize_set_local(&mut optimizer);
|
let optimized = optimizer.optimize_set_local();
|
||||||
|
|
||||||
if optimized {
|
if optimized {
|
||||||
self.optimization_count += 1;
|
self.optimization_count += 1;
|
||||||
@ -1171,7 +1196,7 @@ impl<'src> Compiler<'src> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if self.chunk.len() >= 4 {
|
if self.chunk.len() >= 4 {
|
||||||
let mut optimizer = Optimizer::new(self.chunk.instructions_mut());
|
let mut optimizer = Optimizer::new(&mut self.chunk);
|
||||||
let optimized = optimizer.optimize_comparison();
|
let optimized = optimizer.optimize_comparison();
|
||||||
|
|
||||||
if optimized {
|
if optimized {
|
||||||
@ -1260,10 +1285,14 @@ impl<'src> Compiler<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let end = self.previous_position.1;
|
let end = self.previous_position.1;
|
||||||
let to_register = self.next_register();
|
let mut to_register = self.next_register();
|
||||||
let argument_count = to_register - start_register;
|
let argument_count = to_register - start_register;
|
||||||
|
|
||||||
self.previous_expression_type = Type::Function(function.r#type());
|
self.previous_expression_type = *function.r#type().return_type;
|
||||||
|
|
||||||
|
if let Type::None = self.previous_expression_type {
|
||||||
|
to_register = 0;
|
||||||
|
}
|
||||||
|
|
||||||
self.emit_instruction(
|
self.emit_instruction(
|
||||||
Instruction::call_native(to_register, function, argument_count),
|
Instruction::call_native(to_register, function, argument_count),
|
||||||
@ -1428,7 +1457,6 @@ impl<'src> Compiler<'src> {
|
|||||||
function_compiler.advance()?;
|
function_compiler.advance()?;
|
||||||
|
|
||||||
let register = function_compiler.next_register();
|
let register = function_compiler.next_register();
|
||||||
|
|
||||||
let (_, identifier_index) = function_compiler.declare_local(
|
let (_, identifier_index) = function_compiler.declare_local(
|
||||||
parameter,
|
parameter,
|
||||||
r#type.clone(),
|
r#type.clone(),
|
||||||
@ -1476,7 +1504,8 @@ impl<'src> Compiler<'src> {
|
|||||||
value_parameters,
|
value_parameters,
|
||||||
return_type,
|
return_type,
|
||||||
};
|
};
|
||||||
let function = ConcreteValue::Function(function_compiler.finish());
|
|
||||||
|
let function = ConcreteValue::Function(function_compiler.finish(function_type.clone()));
|
||||||
let constant_index = self.chunk.push_or_get_constant(function);
|
let constant_index = self.chunk.push_or_get_constant(function);
|
||||||
let function_end = self.current_position.1;
|
let function_end = self.current_position.1;
|
||||||
let register = self.next_register();
|
let register = self.next_register();
|
||||||
|
@ -463,11 +463,11 @@ impl Instruction {
|
|||||||
Operation::DefineLocal => {
|
Operation::DefineLocal => {
|
||||||
let to_register = self.a();
|
let to_register = self.a();
|
||||||
let local_index = self.b();
|
let local_index = self.b();
|
||||||
|
let mutable_display = if self.c_as_boolean() { "mut" } else { "" };
|
||||||
let identifier_display = match chunk.get_identifier(local_index) {
|
let identifier_display = match chunk.get_identifier(local_index) {
|
||||||
Some(identifier) => identifier.to_string(),
|
Some(identifier) => identifier.to_string(),
|
||||||
None => "???".to_string(),
|
None => "???".to_string(),
|
||||||
};
|
};
|
||||||
let mutable_display = if self.c_as_boolean() { "mut" } else { "" };
|
|
||||||
|
|
||||||
format!("R{to_register} = L{local_index} {mutable_display} {identifier_display}")
|
format!("R{to_register} = L{local_index} {mutable_display} {identifier_display}")
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
//! Tool used by the compiler to optimize a chunk's bytecode.
|
//! Tool used by the compiler to optimize a chunk's bytecode.
|
||||||
|
|
||||||
use crate::{Instruction, Operation, Span};
|
use crate::{Chunk, Instruction, Operation, Span};
|
||||||
|
|
||||||
/// An instruction optimizer that mutably borrows instructions from a chunk.
|
/// An instruction optimizer that mutably borrows instructions from a chunk.
|
||||||
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug)]
|
||||||
pub struct Optimizer<'a> {
|
pub struct Optimizer<'a> {
|
||||||
instructions: &'a mut Vec<(Instruction, Span)>,
|
chunk: &'a mut Chunk,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Optimizer<'a> {
|
impl<'a> Optimizer<'a> {
|
||||||
/// Creates a new optimizer with a mutable reference to some of a chunk's instructions.
|
/// Creates a new optimizer with a mutable reference to some of a chunk's instructions.
|
||||||
pub fn new(instructions: &'a mut Vec<(Instruction, Span)>) -> Self {
|
pub fn new(instructions: &'a mut Chunk) -> Self {
|
||||||
Self { instructions }
|
Self {
|
||||||
|
chunk: instructions,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Optimizes a comparison operation.
|
/// Optimizes a comparison operation.
|
||||||
@ -49,14 +51,15 @@ impl<'a> Optimizer<'a> {
|
|||||||
|
|
||||||
log::debug!("Optimizing comparison");
|
log::debug!("Optimizing comparison");
|
||||||
|
|
||||||
|
let instructions = self.instructions_mut();
|
||||||
let first_loader_register = {
|
let first_loader_register = {
|
||||||
let first_loader = &mut self.instructions[2].0;
|
let first_loader = &mut instructions[2].0;
|
||||||
|
|
||||||
first_loader.set_c_to_boolean(true);
|
first_loader.set_c_to_boolean(true);
|
||||||
first_loader.a()
|
first_loader.a()
|
||||||
};
|
};
|
||||||
|
|
||||||
let second_loader = &mut self.instructions[3].0;
|
let second_loader = &mut instructions[3].0;
|
||||||
let mut second_loader_new = Instruction::with_operation(second_loader.operation());
|
let mut second_loader_new = Instruction::with_operation(second_loader.operation());
|
||||||
|
|
||||||
second_loader_new.set_a(first_loader_register);
|
second_loader_new.set_a(first_loader_register);
|
||||||
@ -85,22 +88,27 @@ impl<'a> Optimizer<'a> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("Optimizing set local");
|
self.instructions_mut().pop();
|
||||||
|
|
||||||
self.instructions.pop();
|
log::debug!("Optimizing by removing redundant SetLocal");
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn instructions_mut(&mut self) -> &mut Vec<(Instruction, Span)> {
|
||||||
|
self.chunk.instructions_mut()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_operations<const COUNT: usize>(&self) -> Option<[Operation; COUNT]> {
|
fn get_operations<const COUNT: usize>(&self) -> Option<[Operation; COUNT]> {
|
||||||
if self.instructions.len() < COUNT {
|
if self.chunk.len() < COUNT {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut n_operations = [Operation::Return; COUNT];
|
let mut n_operations = [Operation::Return; COUNT];
|
||||||
|
|
||||||
for (nth, operation) in n_operations.iter_mut().rev().zip(
|
for (nth, operation) in n_operations.iter_mut().rev().zip(
|
||||||
self.instructions
|
self.chunk
|
||||||
|
.instructions()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.map(|(instruction, _)| instruction.operation()),
|
.map(|(instruction, _)| instruction.operation()),
|
||||||
|
@ -8,8 +8,8 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
compile, AbstractValue, AnnotatedError, Chunk, ChunkError, ConcreteValue, DustError,
|
compile, AbstractValue, AnnotatedError, Chunk, ChunkError, ConcreteValue, DustError,
|
||||||
Instruction, NativeFunction, NativeFunctionError, Operation, Span, Type, ValueError,
|
Instruction, NativeFunction, NativeFunctionError, Operation, Span, ValueError, ValueOwned,
|
||||||
ValueOwned, ValueRef,
|
ValueRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn run(source: &str) -> Result<Option<ConcreteValue>, DustError> {
|
pub fn run(source: &str) -> Result<Option<ConcreteValue>, DustError> {
|
||||||
@ -367,29 +367,23 @@ impl<'a> Vm<'a> {
|
|||||||
position: self.current_position,
|
position: self.current_position,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let has_return_value = *chunk.r#type().return_type != Type::None;
|
|
||||||
let mut function_vm = Vm::new(chunk, Some(self));
|
let mut function_vm = Vm::new(chunk, Some(self));
|
||||||
let first_argument_index = function_register + 1;
|
let first_argument_index = function_register + 1;
|
||||||
let last_argument_index = first_argument_index + argument_count;
|
let last_argument_index = first_argument_index + argument_count;
|
||||||
|
|
||||||
for argument_index in first_argument_index..last_argument_index {
|
for (argument_index, argument_register_index) in
|
||||||
let top_of_stack = function_vm.stack.len() as u8;
|
(first_argument_index..last_argument_index).enumerate()
|
||||||
|
{
|
||||||
function_vm.set_register(
|
function_vm.set_register(
|
||||||
top_of_stack,
|
argument_index as u8,
|
||||||
Register::Pointer(Pointer::ParentStack(argument_index)),
|
Register::Pointer(Pointer::ParentStack(argument_register_index)),
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
function_vm.run()?;
|
let return_value = function_vm.run()?;
|
||||||
|
|
||||||
if has_return_value {
|
if let Some(value) = return_value {
|
||||||
let top_of_stack = function_vm.stack.len() as u8 - 1;
|
self.set_register(to_register, Register::ConcreteValue(value))?;
|
||||||
|
|
||||||
self.set_register(
|
|
||||||
to_register,
|
|
||||||
Register::Pointer(Pointer::ParentStack(top_of_stack)),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Operation::CallNative => {
|
Operation::CallNative => {
|
||||||
|
@ -8,6 +8,11 @@ fn constant() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(0, 2)),
|
(Instruction::load_constant(0, 0, false), Span(0, 2)),
|
||||||
(Instruction::r#return(true), Span(2, 2))
|
(Instruction::r#return(true), Span(2, 2))
|
||||||
@ -28,6 +33,11 @@ fn empty() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None)
|
||||||
|
},
|
||||||
vec![(Instruction::r#return(false), Span(0, 0))],
|
vec![(Instruction::r#return(false), Span(0, 0))],
|
||||||
vec![],
|
vec![],
|
||||||
vec![]
|
vec![]
|
||||||
@ -44,6 +54,11 @@ fn parentheses_precedence() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
|
@ -8,6 +8,11 @@ fn equal() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -36,6 +41,11 @@ fn greater() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less_equal(false, 0, 1)
|
*Instruction::less_equal(false, 0, 1)
|
||||||
@ -64,6 +74,11 @@ fn greater_than_or_equal() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less(false, 0, 1)
|
*Instruction::less(false, 0, 1)
|
||||||
@ -92,6 +107,11 @@ fn less_than() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less(true, 0, 1)
|
*Instruction::less(true, 0, 1)
|
||||||
@ -120,6 +140,11 @@ fn less_than_or_equal() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less_equal(true, 0, 1)
|
*Instruction::less_equal(true, 0, 1)
|
||||||
@ -148,6 +173,11 @@ fn not_equal() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(false, 0, 1)
|
*Instruction::equal(false, 0, 1)
|
||||||
|
@ -8,6 +8,11 @@ fn equality_assignment_long() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
@ -38,6 +43,11 @@ fn equality_assignment_short() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
@ -64,8 +74,8 @@ fn equality_assignment_short() {
|
|||||||
fn if_else_assigment_false() {
|
fn if_else_assigment_false() {
|
||||||
let source = r#"
|
let source = r#"
|
||||||
let a = if 4 == 3 {
|
let a = if 4 == 3 {
|
||||||
1; 2; 3; 4;
|
panic();
|
||||||
panic()
|
0
|
||||||
} else {
|
} else {
|
||||||
1; 2; 3; 4;
|
1; 2; 3; 4;
|
||||||
42
|
42
|
||||||
@ -76,6 +86,11 @@ fn if_else_assigment_false() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -83,35 +98,33 @@ fn if_else_assigment_false() {
|
|||||||
.set_c_is_constant(),
|
.set_c_is_constant(),
|
||||||
Span(22, 24)
|
Span(22, 24)
|
||||||
),
|
),
|
||||||
(Instruction::jump(6, true), Span(27, 28)),
|
(Instruction::jump(3, true), Span(27, 28)),
|
||||||
(Instruction::load_constant(0, 2, false), Span(41, 42)),
|
|
||||||
(Instruction::load_constant(1, 3, false), Span(44, 45)),
|
|
||||||
(Instruction::load_constant(2, 1, false), Span(47, 48)),
|
|
||||||
(Instruction::load_constant(3, 0, false), Span(50, 51)),
|
|
||||||
(
|
(
|
||||||
Instruction::call_native(4, NativeFunction::Panic, 0),
|
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||||
Span(65, 72)
|
Span(41, 48)
|
||||||
),
|
),
|
||||||
(Instruction::jump(5, true), Span(138, 139)),
|
(Instruction::load_constant(0, 2, false), Span(62, 63)),
|
||||||
(Instruction::load_constant(5, 2, false), Span(102, 103)),
|
(Instruction::jump(5, true), Span(129, 130)),
|
||||||
(Instruction::load_constant(6, 3, false), Span(105, 106)),
|
(Instruction::load_constant(1, 3, false), Span(93, 94)),
|
||||||
(Instruction::load_constant(7, 1, false), Span(108, 109)),
|
(Instruction::load_constant(2, 4, false), Span(96, 97)),
|
||||||
(Instruction::load_constant(8, 0, false), Span(111, 112)),
|
(Instruction::load_constant(3, 1, false), Span(99, 100)),
|
||||||
(Instruction::load_constant(9, 4, false), Span(126, 128)),
|
(Instruction::load_constant(4, 0, false), Span(102, 103)),
|
||||||
(Instruction::r#move(9, 4), Span(138, 139)),
|
(Instruction::load_constant(5, 5, false), Span(117, 119)),
|
||||||
(Instruction::define_local(9, 0, false), Span(13, 14)),
|
(Instruction::r#move(5, 0), Span(129, 130)),
|
||||||
(Instruction::get_local(10, 0), Span(148, 149)),
|
(Instruction::define_local(5, 0, false), Span(13, 14)),
|
||||||
(Instruction::r#return(true), Span(149, 149)),
|
(Instruction::get_local(6, 0), Span(139, 140)),
|
||||||
|
(Instruction::r#return(true), Span(140, 140)),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
ConcreteValue::Integer(4),
|
ConcreteValue::Integer(4),
|
||||||
ConcreteValue::Integer(3),
|
ConcreteValue::Integer(3),
|
||||||
|
ConcreteValue::Integer(0),
|
||||||
ConcreteValue::Integer(1),
|
ConcreteValue::Integer(1),
|
||||||
ConcreteValue::Integer(2),
|
ConcreteValue::Integer(2),
|
||||||
ConcreteValue::Integer(42),
|
ConcreteValue::Integer(42),
|
||||||
ConcreteValue::string("a")
|
ConcreteValue::string("a")
|
||||||
],
|
],
|
||||||
vec![Local::new(5, Type::Integer, false, Scope::default())]
|
vec![Local::new(6, Type::Integer, false, Scope::default())]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -125,8 +138,8 @@ fn if_else_assigment_true() {
|
|||||||
1; 2; 3; 4;
|
1; 2; 3; 4;
|
||||||
42
|
42
|
||||||
} else {
|
} else {
|
||||||
1; 2; 3; 4;
|
panic();
|
||||||
panic()
|
0
|
||||||
};
|
};
|
||||||
a"#;
|
a"#;
|
||||||
|
|
||||||
@ -134,6 +147,11 @@ fn if_else_assigment_true() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
@ -147,19 +165,16 @@ fn if_else_assigment_true() {
|
|||||||
(Instruction::load_constant(2, 3, false), Span(47, 48)),
|
(Instruction::load_constant(2, 3, false), Span(47, 48)),
|
||||||
(Instruction::load_constant(3, 0, false), Span(50, 51)),
|
(Instruction::load_constant(3, 0, false), Span(50, 51)),
|
||||||
(Instruction::load_constant(4, 4, false), Span(65, 67)),
|
(Instruction::load_constant(4, 4, false), Span(65, 67)),
|
||||||
(Instruction::jump(5, true), Span(138, 139)),
|
(Instruction::jump(2, true), Span(129, 130)),
|
||||||
(Instruction::load_constant(5, 1, false), Span(97, 98)),
|
|
||||||
(Instruction::load_constant(6, 2, false), Span(100, 101)),
|
|
||||||
(Instruction::load_constant(7, 3, false), Span(103, 104)),
|
|
||||||
(Instruction::load_constant(8, 0, false), Span(106, 107)),
|
|
||||||
(
|
(
|
||||||
Instruction::call_native(9, NativeFunction::Panic, 0),
|
Instruction::call_native(0, NativeFunction::Panic, 0),
|
||||||
Span(121, 128)
|
Span(97, 104)
|
||||||
),
|
),
|
||||||
(Instruction::r#move(9, 4), Span(138, 139)),
|
(Instruction::load_constant(5, 5, false), Span(118, 119)),
|
||||||
(Instruction::define_local(9, 0, false), Span(13, 14)),
|
(Instruction::r#move(5, 4), Span(129, 130)),
|
||||||
(Instruction::get_local(10, 0), Span(148, 149)),
|
(Instruction::define_local(5, 0, false), Span(13, 14)),
|
||||||
(Instruction::r#return(true), Span(149, 149)),
|
(Instruction::get_local(6, 0), Span(139, 140)),
|
||||||
|
(Instruction::r#return(true), Span(140, 140)),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
ConcreteValue::Integer(4),
|
ConcreteValue::Integer(4),
|
||||||
@ -167,9 +182,10 @@ fn if_else_assigment_true() {
|
|||||||
ConcreteValue::Integer(2),
|
ConcreteValue::Integer(2),
|
||||||
ConcreteValue::Integer(3),
|
ConcreteValue::Integer(3),
|
||||||
ConcreteValue::Integer(42),
|
ConcreteValue::Integer(42),
|
||||||
|
ConcreteValue::Integer(0),
|
||||||
ConcreteValue::string("a")
|
ConcreteValue::string("a")
|
||||||
],
|
],
|
||||||
vec![Local::new(5, Type::Integer, false, Scope::default())]
|
vec![Local::new(6, Type::Integer, false, Scope::default())]
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -189,6 +205,11 @@ fn if_else_complex() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
@ -300,6 +321,11 @@ fn if_else_false() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -336,6 +362,11 @@ fn if_else_true() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
@ -368,6 +399,11 @@ fn if_false() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -398,6 +434,11 @@ fn if_true() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 0)
|
*Instruction::equal(true, 0, 0)
|
||||||
|
@ -8,6 +8,15 @@ fn function() {
|
|||||||
run(source),
|
run(source),
|
||||||
Ok(Some(ConcreteValue::Function(Chunk::with_data(
|
Ok(Some(ConcreteValue::Function(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Function(FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
}))
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||||
(Instruction::r#return(true), Span(35, 35)),
|
(Instruction::r#return(true), Span(35, 35)),
|
||||||
@ -29,6 +38,11 @@ fn function_call() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(0, 36)),
|
(Instruction::load_constant(0, 0, false), Span(0, 36)),
|
||||||
(Instruction::load_constant(1, 1, false), Span(36, 37)),
|
(Instruction::load_constant(1, 1, false), Span(36, 37)),
|
||||||
@ -39,6 +53,11 @@ fn function_call() {
|
|||||||
vec![
|
vec![
|
||||||
ConcreteValue::Function(Chunk::with_data(
|
ConcreteValue::Function(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||||
(Instruction::r#return(true), Span(35, 36)),
|
(Instruction::r#return(true), Span(35, 36)),
|
||||||
@ -67,15 +86,24 @@ fn function_declaration() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 1, false), Span(0, 40)),
|
(Instruction::load_constant(0, 0, false), Span(0, 40)),
|
||||||
(Instruction::define_local(0, 0, false), Span(3, 6)),
|
(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![
|
||||||
ConcreteValue::string("add"),
|
|
||||||
ConcreteValue::Function(Chunk::with_data(
|
ConcreteValue::Function(Chunk::with_data(
|
||||||
Some("add".to_string()),
|
Some("add".to_string()),
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),
|
||||||
|
return_type: Box::new(Type::Integer)
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(35, 36)),
|
(Instruction::add(2, 0, 1), Span(35, 36)),
|
||||||
(Instruction::r#return(true), Span(40, 40)),
|
(Instruction::r#return(true), Span(40, 40)),
|
||||||
@ -85,10 +113,11 @@ fn function_declaration() {
|
|||||||
Local::new(0, Type::Integer, false, Scope::default()),
|
Local::new(0, Type::Integer, false, Scope::default()),
|
||||||
Local::new(1, Type::Integer, false, Scope::default())
|
Local::new(1, Type::Integer, false, Scope::default())
|
||||||
]
|
]
|
||||||
),)
|
)),
|
||||||
|
ConcreteValue::string("add"),
|
||||||
],
|
],
|
||||||
vec![Local::new(
|
vec![Local::new(
|
||||||
0,
|
1,
|
||||||
Type::Function(FunctionType {
|
Type::Function(FunctionType {
|
||||||
type_parameters: None,
|
type_parameters: None,
|
||||||
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),
|
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),
|
||||||
|
@ -8,6 +8,14 @@ fn empty_list() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::List {
|
||||||
|
item_type: Box::new(Type::Any),
|
||||||
|
length: 0
|
||||||
|
})
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_list(0, 0), Span(0, 2)),
|
(Instruction::load_list(0, 0), Span(0, 2)),
|
||||||
(Instruction::r#return(true), Span(2, 2)),
|
(Instruction::r#return(true), Span(2, 2)),
|
||||||
@ -28,6 +36,14 @@ fn list() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::List {
|
||||||
|
item_type: Box::new(Type::Integer),
|
||||||
|
length: 3
|
||||||
|
})
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(Instruction::load_constant(1, 1, false), Span(4, 5)),
|
(Instruction::load_constant(1, 1, false), Span(4, 5)),
|
||||||
@ -62,6 +78,14 @@ fn list_with_complex_expression() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::List {
|
||||||
|
item_type: Box::new(Type::Integer),
|
||||||
|
length: 3
|
||||||
|
})
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(
|
(
|
||||||
@ -109,6 +133,14 @@ fn list_with_simple_expression() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::List {
|
||||||
|
item_type: Box::new(Type::Integer),
|
||||||
|
length: 3
|
||||||
|
})
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(
|
(
|
||||||
|
@ -8,6 +8,11 @@ fn and() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
(Instruction::test(0, false), Span(5, 7)),
|
(Instruction::test(0, false), Span(5, 7)),
|
||||||
@ -31,6 +36,11 @@ fn or() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
(Instruction::test(0, true), Span(5, 7)),
|
(Instruction::test(0, true), Span(5, 7)),
|
||||||
@ -54,6 +64,11 @@ fn variable_and() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean),
|
||||||
|
},
|
||||||
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::define_local(0, 0, false), Span(4, 5)),
|
||||||
|
@ -8,6 +8,11 @@ fn r#while() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
|
@ -8,6 +8,11 @@ fn add() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
@ -33,6 +38,11 @@ fn add_assign() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -92,6 +102,11 @@ fn divide() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::divide(0, 0, 0)
|
*Instruction::divide(0, 0, 0)
|
||||||
@ -117,6 +132,11 @@ fn divide_assign() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -159,6 +179,11 @@ fn math_operator_precedence() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
@ -201,6 +226,11 @@ fn multiply() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::multiply(0, 0, 1)
|
*Instruction::multiply(0, 0, 1)
|
||||||
@ -226,6 +256,11 @@ fn multiply_assign() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -272,6 +307,11 @@ fn subtract() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::subtract(0, 0, 1)
|
*Instruction::subtract(0, 0, 1)
|
||||||
@ -297,6 +337,11 @@ fn subtract_assign() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
|
@ -8,14 +8,19 @@ fn panic() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(6, 22)),
|
(Instruction::load_constant(0, 0, false), Span(6, 22)),
|
||||||
(Instruction::load_constant(1, 1, false), Span(24, 26)),
|
(Instruction::load_constant(1, 1, false), Span(24, 26)),
|
||||||
(
|
(
|
||||||
Instruction::call_native(2, NativeFunction::Panic, 2),
|
Instruction::call_native(0, NativeFunction::Panic, 2),
|
||||||
Span(0, 27)
|
Span(0, 27)
|
||||||
),
|
),
|
||||||
(Instruction::r#return(true), Span(27, 27))
|
(Instruction::r#return(false), Span(27, 27))
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
ConcreteValue::string("Goodbye world!"),
|
ConcreteValue::string("Goodbye world!"),
|
||||||
@ -45,6 +50,11 @@ fn to_string() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::String { length: None }),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(10, 12)),
|
(Instruction::load_constant(0, 0, false), Span(10, 12)),
|
||||||
(
|
(
|
||||||
|
@ -30,6 +30,11 @@ fn block_scope() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
||||||
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
||||||
@ -93,6 +98,11 @@ fn multiple_block_scopes() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
||||||
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
||||||
|
@ -8,6 +8,11 @@ fn negate() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(*Instruction::negate(0, 0).set_b_is_constant(), Span(0, 1)),
|
(*Instruction::negate(0, 0).set_b_is_constant(), Span(0, 1)),
|
||||||
(Instruction::r#return(true), Span(5, 5)),
|
(Instruction::r#return(true), Span(5, 5)),
|
||||||
@ -28,6 +33,11 @@ fn not() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Boolean),
|
||||||
|
},
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
||||||
(Instruction::not(1, 0), Span(0, 1)),
|
(Instruction::not(1, 0), Span(0, 1)),
|
||||||
|
@ -8,6 +8,11 @@ fn define_local() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::None),
|
||||||
|
},
|
||||||
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::define_local(0, 0, false), Span(4, 5)),
|
||||||
@ -46,6 +51,11 @@ fn set_local() {
|
|||||||
compile(source),
|
compile(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
None,
|
None,
|
||||||
|
FunctionType {
|
||||||
|
type_parameters: None,
|
||||||
|
value_parameters: None,
|
||||||
|
return_type: Box::new(Type::Integer),
|
||||||
|
},
|
||||||
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::define_local(0, 0, true), Span(8, 9)),
|
||||||
|
Loading…
Reference in New Issue
Block a user