Begin wrapping up overhaul
This commit is contained in:
parent
7b91e879b7
commit
960931ce6e
@ -418,7 +418,7 @@ impl<'src> Compiler<'src> {
|
||||
|
||||
let byte = u8::from_str_radix(&text[2..], 16)
|
||||
.map_err(|error| CompileError::ParseIntError { error, position })?;
|
||||
let value = ConcreteValue::byte(byte);
|
||||
let value = ConcreteValue::Byte(byte);
|
||||
|
||||
self.emit_constant(value, position)?;
|
||||
|
||||
@ -440,7 +440,7 @@ impl<'src> Compiler<'src> {
|
||||
if let Token::Character(character) = self.current_token {
|
||||
self.advance()?;
|
||||
|
||||
let value = ConcreteValue::character(character);
|
||||
let value = ConcreteValue::Character(character);
|
||||
|
||||
self.emit_constant(value, position)?;
|
||||
|
||||
@ -468,7 +468,7 @@ impl<'src> Compiler<'src> {
|
||||
error,
|
||||
position: self.previous_position,
|
||||
})?;
|
||||
let value = ConcreteValue::float(float);
|
||||
let value = ConcreteValue::Float(float);
|
||||
|
||||
self.emit_constant(value, position)?;
|
||||
|
||||
@ -496,7 +496,7 @@ impl<'src> Compiler<'src> {
|
||||
error,
|
||||
position: self.previous_position,
|
||||
})?;
|
||||
let value = ConcreteValue::integer(integer);
|
||||
let value = ConcreteValue::Integer(integer);
|
||||
|
||||
self.emit_constant(value, position)?;
|
||||
|
||||
@ -1476,7 +1476,7 @@ impl<'src> Compiler<'src> {
|
||||
value_parameters,
|
||||
return_type,
|
||||
};
|
||||
let function = ConcreteValue::function(function_compiler.finish());
|
||||
let function = ConcreteValue::Function(function_compiler.finish());
|
||||
let constant_index = self.chunk.push_or_get_constant(function);
|
||||
let function_end = self.current_position.1;
|
||||
let register = self.next_register();
|
||||
|
@ -1,14 +1,11 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::{vm::Pointer, ConcreteValue, Type, Vm, VmError};
|
||||
use crate::{vm::Pointer, ConcreteValue, Vm, VmError};
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
pub enum AbstractValue {
|
||||
FunctionSelf,
|
||||
List {
|
||||
items: Vec<Pointer>,
|
||||
item_type: Type,
|
||||
},
|
||||
List { items: Vec<Pointer> },
|
||||
}
|
||||
|
||||
impl AbstractValue {
|
||||
@ -45,7 +42,7 @@ impl AbstractValue {
|
||||
display.push_str(&item_display);
|
||||
}
|
||||
|
||||
display.push_str("]");
|
||||
display.push(']');
|
||||
|
||||
Ok(display)
|
||||
}
|
||||
@ -59,9 +56,8 @@ impl Clone for AbstractValue {
|
||||
|
||||
match self {
|
||||
AbstractValue::FunctionSelf => AbstractValue::FunctionSelf,
|
||||
AbstractValue::List { items, item_type } => AbstractValue::List {
|
||||
AbstractValue::List { items } => AbstractValue::List {
|
||||
items: items.clone(),
|
||||
item_type: item_type.clone(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -20,38 +20,10 @@ pub enum ConcreteValue {
|
||||
}
|
||||
|
||||
impl ConcreteValue {
|
||||
pub fn boolean(value: bool) -> Self {
|
||||
ConcreteValue::Boolean(value)
|
||||
}
|
||||
|
||||
pub fn byte(value: u8) -> Self {
|
||||
ConcreteValue::Byte(value)
|
||||
}
|
||||
|
||||
pub fn character(value: char) -> Self {
|
||||
ConcreteValue::Character(value)
|
||||
}
|
||||
|
||||
pub fn float(value: f64) -> Self {
|
||||
ConcreteValue::Float(value)
|
||||
}
|
||||
|
||||
pub fn function(chunk: Chunk) -> Self {
|
||||
ConcreteValue::Function(chunk)
|
||||
}
|
||||
|
||||
pub fn integer<T: Into<i64>>(into_i64: T) -> Self {
|
||||
ConcreteValue::Integer(into_i64.into())
|
||||
}
|
||||
|
||||
pub fn list<T: Into<Vec<ConcreteValue>>>(into_list: T) -> Self {
|
||||
ConcreteValue::List(into_list.into())
|
||||
}
|
||||
|
||||
pub fn range(range: RangeValue) -> Self {
|
||||
ConcreteValue::Range(range)
|
||||
}
|
||||
|
||||
pub fn string<T: ToString>(to_string: T) -> Self {
|
||||
ConcreteValue::String(to_string.to_string())
|
||||
}
|
||||
@ -91,9 +63,9 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let sum = match (self, other) {
|
||||
(Byte(left), Byte(right)) => ConcreteValue::byte(left.saturating_add(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::float(*left + *right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::integer(left.saturating_add(*right)),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Byte(left.saturating_add(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::Float(*left + *right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_add(*right)),
|
||||
(String(left), String(right)) => ConcreteValue::string(format!("{}{}", left, right)),
|
||||
_ => return Err(ValueError::CannotAdd(self.clone(), other.clone())),
|
||||
};
|
||||
@ -105,9 +77,9 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let difference = match (self, other) {
|
||||
(Byte(left), Byte(right)) => ConcreteValue::byte(left.saturating_sub(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::float(left - right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::integer(left.saturating_sub(*right)),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Byte(left.saturating_sub(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::Float(left - right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_sub(*right)),
|
||||
_ => return Err(ValueError::CannotSubtract(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
@ -118,9 +90,9 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let product = match (self, other) {
|
||||
(Byte(left), Byte(right)) => ConcreteValue::byte(left.saturating_mul(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::float(left * right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::integer(left.saturating_mul(*right)),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Byte(left.saturating_mul(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::Float(left * right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_mul(*right)),
|
||||
_ => return Err(ValueError::CannotMultiply(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
@ -131,9 +103,9 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let quotient = match (self, other) {
|
||||
(Byte(left), Byte(right)) => ConcreteValue::byte(left.saturating_div(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::float(left / right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::integer(left.saturating_div(*right)),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Byte(left.saturating_div(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::Float(left / right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Integer(left.saturating_div(*right)),
|
||||
_ => return Err(ValueError::CannotMultiply(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
@ -144,10 +116,10 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let product = match (self, other) {
|
||||
(Byte(left), Byte(right)) => ConcreteValue::byte(left.wrapping_rem(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::float(left % right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Byte(left.wrapping_rem(*right)),
|
||||
(Float(left), Float(right)) => ConcreteValue::Float(left % right),
|
||||
(Integer(left), Integer(right)) => {
|
||||
ConcreteValue::integer(left.wrapping_rem_euclid(*right))
|
||||
ConcreteValue::Integer(left.wrapping_rem_euclid(*right))
|
||||
}
|
||||
_ => return Err(ValueError::CannotMultiply(self.clone(), other.clone())),
|
||||
};
|
||||
@ -159,10 +131,10 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let negated = match self {
|
||||
Boolean(value) => ConcreteValue::boolean(!value),
|
||||
Byte(value) => ConcreteValue::byte(value.wrapping_neg()),
|
||||
Float(value) => ConcreteValue::float(-value),
|
||||
Integer(value) => ConcreteValue::integer(value.wrapping_neg()),
|
||||
Boolean(value) => ConcreteValue::Boolean(!value),
|
||||
Byte(value) => ConcreteValue::Byte(value.wrapping_neg()),
|
||||
Float(value) => ConcreteValue::Float(-value),
|
||||
Integer(value) => ConcreteValue::Integer(value.wrapping_neg()),
|
||||
_ => return Err(ValueError::CannotNegate(self.clone())),
|
||||
};
|
||||
|
||||
@ -173,7 +145,7 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let not = match self {
|
||||
Boolean(value) => ConcreteValue::boolean(!value),
|
||||
Boolean(value) => ConcreteValue::Boolean(!value),
|
||||
_ => return Err(ValueError::CannotNot(self.clone())),
|
||||
};
|
||||
|
||||
@ -184,15 +156,15 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let equal = match (self, other) {
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::boolean(left == right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::boolean(left == right),
|
||||
(Character(left), Character(right)) => ConcreteValue::boolean(left == right),
|
||||
(Float(left), Float(right)) => ConcreteValue::boolean(left == right),
|
||||
(Function(left), Function(right)) => ConcreteValue::boolean(left == right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::boolean(left == right),
|
||||
(List(left), List(right)) => ConcreteValue::boolean(left == right),
|
||||
(Range(left), Range(right)) => ConcreteValue::boolean(left == right),
|
||||
(String(left), String(right)) => ConcreteValue::boolean(left == right),
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Character(left), Character(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Float(left), Float(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Function(left), Function(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Boolean(left == right),
|
||||
(List(left), List(right)) => ConcreteValue::Boolean(left == right),
|
||||
(Range(left), Range(right)) => ConcreteValue::Boolean(left == right),
|
||||
(String(left), String(right)) => ConcreteValue::Boolean(left == right),
|
||||
_ => return Err(ValueError::CannotCompare(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
@ -203,15 +175,15 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let less_than = match (self, other) {
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::boolean(left < right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::boolean(left < right),
|
||||
(Character(left), Character(right)) => ConcreteValue::boolean(left < right),
|
||||
(Float(left), Float(right)) => ConcreteValue::boolean(left < right),
|
||||
(Function(left), Function(right)) => ConcreteValue::boolean(left < right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::boolean(left < right),
|
||||
(List(left), List(right)) => ConcreteValue::boolean(left < right),
|
||||
(Range(left), Range(right)) => ConcreteValue::boolean(left < right),
|
||||
(String(left), String(right)) => ConcreteValue::boolean(left < right),
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Character(left), Character(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Float(left), Float(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Function(left), Function(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Boolean(left < right),
|
||||
(List(left), List(right)) => ConcreteValue::Boolean(left < right),
|
||||
(Range(left), Range(right)) => ConcreteValue::Boolean(left < right),
|
||||
(String(left), String(right)) => ConcreteValue::Boolean(left < right),
|
||||
_ => return Err(ValueError::CannotCompare(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
@ -222,15 +194,15 @@ impl ConcreteValue {
|
||||
use ConcreteValue::*;
|
||||
|
||||
let less_than_or_equal = match (self, other) {
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Character(left), Character(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Float(left), Float(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Function(left), Function(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::boolean(left <= right),
|
||||
(List(left), List(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Range(left), Range(right)) => ConcreteValue::boolean(left <= right),
|
||||
(String(left), String(right)) => ConcreteValue::boolean(left <= right),
|
||||
(Boolean(left), Boolean(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Byte(left), Byte(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Character(left), Character(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Float(left), Float(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Function(left), Function(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Integer(left), Integer(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(List(left), List(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(Range(left), Range(right)) => ConcreteValue::Boolean(left <= right),
|
||||
(String(left), String(right)) => ConcreteValue::Boolean(left <= right),
|
||||
_ => return Err(ValueError::CannotCompare(self.clone(), other.clone())),
|
||||
};
|
||||
|
||||
|
@ -11,28 +11,7 @@ use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
use crate::{Vm, VmError};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ValueRef<'a> {
|
||||
Abstract(&'a AbstractValue),
|
||||
Concrete(&'a ConcreteValue),
|
||||
}
|
||||
|
||||
impl ValueRef<'_> {
|
||||
pub fn to_concrete_owned(&self, vm: &Vm) -> Result<ConcreteValue, VmError> {
|
||||
match self {
|
||||
ValueRef::Abstract(abstract_value) => abstract_value.to_concrete_owned(vm),
|
||||
ValueRef::Concrete(concrete_value) => Ok((*concrete_value).clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display(&self, vm: &Vm) -> Result<String, VmError> {
|
||||
match self {
|
||||
ValueRef::Abstract(abstract_value) => abstract_value.display(vm),
|
||||
ValueRef::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ValueOwned {
|
||||
Abstract(AbstractValue),
|
||||
Concrete(ConcreteValue),
|
||||
@ -54,6 +33,28 @@ impl ValueOwned {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ValueRef<'a> {
|
||||
Abstract(&'a AbstractValue),
|
||||
Concrete(&'a ConcreteValue),
|
||||
}
|
||||
|
||||
impl ValueRef<'_> {
|
||||
pub fn to_concrete_owned(&self, vm: &Vm) -> Result<ConcreteValue, VmError> {
|
||||
match self {
|
||||
ValueRef::Abstract(abstract_value) => abstract_value.to_concrete_owned(vm),
|
||||
ValueRef::Concrete(concrete_value) => Ok((*concrete_value).clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display(&self, vm: &Vm) -> Result<String, VmError> {
|
||||
match self {
|
||||
ValueRef::Abstract(abstract_value) => abstract_value.display(vm),
|
||||
ValueRef::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ValueError {
|
||||
CannotAdd(ConcreteValue, ConcreteValue),
|
||||
|
@ -14,19 +14,10 @@ use crate::{
|
||||
|
||||
pub fn run(source: &str) -> Result<Option<ConcreteValue>, DustError> {
|
||||
let chunk = compile(source)?;
|
||||
let has_return_value = *chunk.r#type().return_type != Type::None;
|
||||
let mut vm = Vm::new(&chunk, None);
|
||||
|
||||
vm.run()
|
||||
.map_err(|error| DustError::Runtime { error, source })?;
|
||||
|
||||
if has_return_value {
|
||||
vm.take_top_of_stack_as_value()
|
||||
.map(Some)
|
||||
.map_err(|error| DustError::Runtime { error, source })
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_and_display_output(source: &str) {
|
||||
@ -75,7 +66,7 @@ impl<'a> Vm<'a> {
|
||||
self.current_position
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<Option<ValueRef>, VmError> {
|
||||
pub fn run(&mut self) -> Result<Option<ConcreteValue>, VmError> {
|
||||
while let Ok(instruction) = self.read() {
|
||||
log::info!(
|
||||
"{} | {} | {} | {}",
|
||||
@ -117,7 +108,7 @@ impl<'a> Vm<'a> {
|
||||
let to_register = instruction.a();
|
||||
let boolean = instruction.b_as_boolean();
|
||||
let jump = instruction.c_as_boolean();
|
||||
let boolean = ConcreteValue::boolean(boolean);
|
||||
let boolean = ConcreteValue::Boolean(boolean);
|
||||
|
||||
self.set_register(to_register, Register::ConcreteValue(boolean))?;
|
||||
|
||||
@ -142,24 +133,28 @@ impl<'a> Vm<'a> {
|
||||
Operation::LoadList => {
|
||||
let to_register = instruction.a();
|
||||
let start_register = instruction.b();
|
||||
let mut list = Vec::new();
|
||||
let mut pointers = Vec::new();
|
||||
|
||||
for register_index in start_register..to_register {
|
||||
let value = self.open_register(register_index)?;
|
||||
|
||||
list.push(value);
|
||||
if let Some(Register::Empty) = self.stack.get(register_index as usize) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// self.set_register(to_register, Register::List(list))?;
|
||||
let pointer = Pointer::Stack(register_index);
|
||||
|
||||
todo!()
|
||||
pointers.push(pointer);
|
||||
}
|
||||
|
||||
self.set_register(
|
||||
to_register,
|
||||
Register::AbstractValue(AbstractValue::List { items: pointers }),
|
||||
)?;
|
||||
}
|
||||
Operation::LoadSelf => {
|
||||
let to_register = instruction.a();
|
||||
let register = Register::AbstractValue(AbstractValue::FunctionSelf);
|
||||
|
||||
// self.set_register(to_register, Register::Value(function))?;
|
||||
|
||||
todo!()
|
||||
self.set_register(to_register, register)?;
|
||||
}
|
||||
Operation::DefineLocal => {
|
||||
let from_register = instruction.a();
|
||||
@ -263,13 +258,9 @@ impl<'a> Vm<'a> {
|
||||
}
|
||||
Operation::TestSet => todo!(),
|
||||
Operation::Equal => {
|
||||
debug_assert_eq!(
|
||||
self.get_instruction(self.ip)?.0.operation(),
|
||||
Operation::Jump
|
||||
);
|
||||
|
||||
let compare_to = instruction.a_as_boolean();
|
||||
let (left, right) = self.get_arguments(instruction)?;
|
||||
|
||||
let equal_result = left.equal(right).map_err(|error| VmError::Value {
|
||||
error,
|
||||
position: self.current_position,
|
||||
@ -286,17 +277,12 @@ impl<'a> Vm<'a> {
|
||||
if is_equal == compare_to {
|
||||
self.ip += 1;
|
||||
} else {
|
||||
let jump = self.get_instruction(self.ip)?.0;
|
||||
let jump = self.read()?;
|
||||
|
||||
self.jump(jump);
|
||||
}
|
||||
}
|
||||
Operation::Less => {
|
||||
debug_assert_eq!(
|
||||
self.get_instruction(self.ip)?.0.operation(),
|
||||
Operation::Jump
|
||||
);
|
||||
|
||||
let compare_to = instruction.a_as_boolean();
|
||||
let (left, right) = self.get_arguments(instruction)?;
|
||||
let less_result = left.less_than(right).map_err(|error| VmError::Value {
|
||||
@ -315,17 +301,12 @@ impl<'a> Vm<'a> {
|
||||
if is_less_than == compare_to {
|
||||
self.ip += 1;
|
||||
} else {
|
||||
let jump = self.get_instruction(self.ip)?.0;
|
||||
let jump = self.read()?;
|
||||
|
||||
self.jump(jump);
|
||||
}
|
||||
}
|
||||
Operation::LessEqual => {
|
||||
debug_assert_eq!(
|
||||
self.get_instruction(self.ip)?.0.operation(),
|
||||
Operation::Jump
|
||||
);
|
||||
|
||||
let compare_to = instruction.a_as_boolean();
|
||||
let (left, right) = self.get_arguments(instruction)?;
|
||||
let less_or_equal_result =
|
||||
@ -347,7 +328,7 @@ impl<'a> Vm<'a> {
|
||||
if is_less_than_or_equal == compare_to {
|
||||
self.ip += 1;
|
||||
} else {
|
||||
let jump = self.get_instruction(self.ip)?.0;
|
||||
let jump = self.read()?;
|
||||
|
||||
self.jump(jump);
|
||||
}
|
||||
@ -438,9 +419,11 @@ impl<'a> Vm<'a> {
|
||||
}
|
||||
|
||||
return if let Some(register_index) = self.last_assigned_register {
|
||||
let value_ref = self.open_register(register_index)?;
|
||||
let return_value = self
|
||||
.open_register(register_index)?
|
||||
.to_concrete_owned(self)?;
|
||||
|
||||
Ok(Some(value_ref))
|
||||
Ok(Some(return_value))
|
||||
} else {
|
||||
Err(VmError::StackUnderflow {
|
||||
position: self.current_position,
|
||||
@ -508,20 +491,6 @@ impl<'a> Vm<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn take_top_of_stack_as_value(&mut self) -> Result<ConcreteValue, VmError> {
|
||||
let top_of_stack = self.stack.pop().ok_or(VmError::StackUnderflow {
|
||||
position: self.current_position,
|
||||
})?;
|
||||
|
||||
match top_of_stack {
|
||||
Register::ConcreteValue(value) => Ok(value),
|
||||
_ => Err(VmError::ExpectedValue {
|
||||
found: top_of_stack,
|
||||
position: self.current_position,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// DRY helper for handling JUMP instructions
|
||||
fn jump(&mut self, jump: Instruction) {
|
||||
let jump_distance = jump.b();
|
||||
@ -619,7 +588,14 @@ impl<'a> Vm<'a> {
|
||||
}
|
||||
|
||||
fn read(&mut self) -> Result<Instruction, VmError> {
|
||||
let (instruction, position) = self.get_instruction(self.ip)?;
|
||||
let (instruction, position) =
|
||||
self.chunk
|
||||
.get_instruction(self.ip)
|
||||
.copied()
|
||||
.map_err(|error| VmError::Chunk {
|
||||
error,
|
||||
position: self.current_position,
|
||||
})?;
|
||||
|
||||
self.ip += 1;
|
||||
self.current_position = position;
|
||||
@ -627,16 +603,6 @@ impl<'a> Vm<'a> {
|
||||
Ok(instruction)
|
||||
}
|
||||
|
||||
fn get_instruction(&self, index: usize) -> Result<(Instruction, Span), VmError> {
|
||||
self.chunk
|
||||
.get_instruction(index)
|
||||
.copied()
|
||||
.map_err(|error| VmError::Chunk {
|
||||
error,
|
||||
position: self.current_position,
|
||||
})
|
||||
}
|
||||
|
||||
fn define_local(&mut self, local_index: u8, register_index: u8) -> Result<(), VmError> {
|
||||
log::debug!("Define local L{}", local_index);
|
||||
|
||||
@ -650,8 +616,8 @@ impl<'a> Vm<'a> {
|
||||
pub enum Register {
|
||||
Empty,
|
||||
ConcreteValue(ConcreteValue),
|
||||
Pointer(Pointer),
|
||||
AbstractValue(AbstractValue),
|
||||
Pointer(Pointer),
|
||||
}
|
||||
|
||||
impl Display for Register {
|
||||
|
@ -12,12 +12,12 @@ fn constant() {
|
||||
(Instruction::load_constant(0, 0, false), Span(0, 2)),
|
||||
(Instruction::r#return(true), Span(2, 2))
|
||||
],
|
||||
vec![ValueOwned::Primitive(Primitive::Integer(42))],
|
||||
vec![ConcreteValue::Integer(42)],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -58,13 +58,13 @@ fn parentheses_precedence() {
|
||||
(Instruction::r#return(true), Span(11, 11)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3)
|
||||
],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(9))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(9))));
|
||||
}
|
||||
|
@ -20,12 +20,12 @@ fn equal() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||
(Instruction::r#return(true), Span(6, 6)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -48,12 +48,12 @@ fn greater() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -76,12 +76,12 @@ fn greater_than_or_equal() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||
(Instruction::r#return(true), Span(6, 6)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -104,12 +104,12 @@ fn less_than() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 3)),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -132,12 +132,12 @@ fn less_than_or_equal() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||
(Instruction::r#return(true), Span(6, 6)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -160,10 +160,10 @@ fn not_equal() {
|
||||
(Instruction::load_boolean(0, false, false), Span(2, 4)),
|
||||
(Instruction::r#return(true), Span(6, 6)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
@ -22,12 +22,12 @@ fn equality_assignment_long() {
|
||||
(Instruction::get_local(1, 0), Span(43, 44)),
|
||||
(Instruction::r#return(true), Span(44, 44)),
|
||||
],
|
||||
vec![ValueOwned::integer(4), ValueOwned::string("a")],
|
||||
vec![ConcreteValue::Integer(4), ConcreteValue::string("a")],
|
||||
vec![Local::new(1, Type::Boolean, false, Scope::default(),)]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -52,12 +52,12 @@ fn equality_assignment_short() {
|
||||
(Instruction::get_local(1, 0), Span(15, 16)),
|
||||
(Instruction::r#return(true), Span(16, 16)),
|
||||
],
|
||||
vec![ValueOwned::integer(4), ValueOwned::string("a")],
|
||||
vec![ConcreteValue::Integer(4), ConcreteValue::string("a")],
|
||||
vec![Local::new(1, Type::Boolean, false, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -104,18 +104,18 @@ fn if_else_assigment_false() {
|
||||
(Instruction::r#return(true), Span(149, 149)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(4),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(42),
|
||||
ValueOwned::string("a")
|
||||
ConcreteValue::Integer(4),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(42),
|
||||
ConcreteValue::string("a")
|
||||
],
|
||||
vec![Local::new(5, Type::Integer, false, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -162,18 +162,18 @@ fn if_else_assigment_true() {
|
||||
(Instruction::r#return(true), Span(149, 149)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(4),
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(42),
|
||||
ValueOwned::string("a")
|
||||
ConcreteValue::Integer(4),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(42),
|
||||
ConcreteValue::string("a")
|
||||
],
|
||||
vec![Local::new(5, Type::Integer, false, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -210,10 +210,10 @@ fn if_else_complex() {
|
||||
(Instruction::r#return(false), Span(95, 95)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(4),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(4),
|
||||
],
|
||||
vec![]
|
||||
))
|
||||
@ -275,21 +275,21 @@ fn if_else_complex() {
|
||||
// (Instruction::r#return(true), Span(146, 146)),
|
||||
// ],
|
||||
// vec![
|
||||
// ValueOwned::integer(0),
|
||||
// ValueOwned::integer(1),
|
||||
// ValueOwned::integer(0),
|
||||
// ValueOwned::integer(2),
|
||||
// ValueOwned::integer(1),
|
||||
// ValueOwned::integer(0),
|
||||
// ValueOwned::integer(3),
|
||||
// ValueOwned::integer(3),
|
||||
// ValueOwned::integer(4)
|
||||
// ConcreteValue::integer(0),
|
||||
// ConcreteValue::integer(1),
|
||||
// ConcreteValue::integer(0),
|
||||
// ConcreteValue::integer(2),
|
||||
// ConcreteValue::integer(1),
|
||||
// ConcreteValue::integer(0),
|
||||
// ConcreteValue::integer(3),
|
||||
// ConcreteValue::integer(3),
|
||||
// ConcreteValue::integer(4)
|
||||
// ],
|
||||
// vec![]
|
||||
// ))
|
||||
// );
|
||||
|
||||
// assert_eq!(run(source), Ok(Some(ValueOwned::integer(4))));
|
||||
// assert_eq!(run(source), Ok(Some(ConcreteValue::integer(4))));
|
||||
// }
|
||||
|
||||
#[test]
|
||||
@ -317,15 +317,15 @@ fn if_else_false() {
|
||||
(Instruction::r#return(true), Span(33, 33)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(42)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(42)
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -352,12 +352,12 @@ fn if_else_true() {
|
||||
(Instruction::r#move(1, 0), Span(33, 33)),
|
||||
(Instruction::r#return(true), Span(33, 33))
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(42)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(42)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -382,7 +382,7 @@ fn if_false() {
|
||||
),
|
||||
(Instruction::r#return(false), Span(21, 21))
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
@ -412,7 +412,7 @@ fn if_true() {
|
||||
),
|
||||
(Instruction::r#return(false), Span(21, 21))
|
||||
],
|
||||
vec![ValueOwned::integer(1)],
|
||||
vec![ConcreteValue::Integer(1)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
@ -6,13 +6,13 @@ fn function() {
|
||||
|
||||
assert_eq!(
|
||||
run(source),
|
||||
Ok(Some(ValueOwned::function(Chunk::with_data(
|
||||
Ok(Some(ConcreteValue::Function(Chunk::with_data(
|
||||
None,
|
||||
vec![
|
||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||
(Instruction::r#return(true), Span(35, 35)),
|
||||
],
|
||||
vec![ValueOwned::string("a"), ValueOwned::string("b"),],
|
||||
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
|
||||
vec![
|
||||
Local::new(0, Type::Integer, false, Scope::default()),
|
||||
Local::new(1, Type::Integer, false, Scope::default())
|
||||
@ -37,26 +37,26 @@ fn function_call() {
|
||||
(Instruction::r#return(true), Span(41, 41)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::function(Chunk::with_data(
|
||||
ConcreteValue::Function(Chunk::with_data(
|
||||
None,
|
||||
vec![
|
||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||
(Instruction::r#return(true), Span(35, 36)),
|
||||
],
|
||||
vec![ValueOwned::string("a"), ValueOwned::string("b"),],
|
||||
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
|
||||
vec![
|
||||
Local::new(0, Type::Integer, false, Scope::default()),
|
||||
Local::new(1, Type::Integer, false, Scope::default())
|
||||
]
|
||||
)),
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2)
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(3))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(3))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -73,14 +73,14 @@ fn function_declaration() {
|
||||
(Instruction::r#return(false), Span(40, 40))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::string("add"),
|
||||
ValueOwned::function(Chunk::with_data(
|
||||
None,
|
||||
ConcreteValue::string("add"),
|
||||
ConcreteValue::Function(Chunk::with_data(
|
||||
Some("add".to_string()),
|
||||
vec![
|
||||
(Instruction::add(2, 0, 1), Span(35, 36)),
|
||||
(Instruction::r#return(true), Span(40, 40)),
|
||||
],
|
||||
vec![ValueOwned::string("a"), ValueOwned::string("b")],
|
||||
vec![ConcreteValue::string("a"), ConcreteValue::string("b")],
|
||||
vec![
|
||||
Local::new(0, Type::Integer, false, Scope::default()),
|
||||
Local::new(1, Type::Integer, false, Scope::default())
|
||||
|
@ -17,7 +17,7 @@ fn empty_list() {
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::list([]))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::list([]))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -36,9 +36,9 @@ fn list() {
|
||||
(Instruction::r#return(true), Span(9, 9)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3)
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
@ -46,10 +46,10 @@ fn list() {
|
||||
|
||||
assert_eq!(
|
||||
run(source),
|
||||
Ok(Some(ValueOwned::list([
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3)
|
||||
Ok(Some(ConcreteValue::list([
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3)
|
||||
])))
|
||||
);
|
||||
}
|
||||
@ -82,11 +82,11 @@ fn list_with_complex_expression() {
|
||||
(Instruction::r#return(true), Span(18, 18)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(4),
|
||||
ValueOwned::integer(5)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(4),
|
||||
ConcreteValue::Integer(5)
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
@ -94,9 +94,9 @@ fn list_with_complex_expression() {
|
||||
|
||||
assert_eq!(
|
||||
run(source),
|
||||
Ok(Some(ValueOwned::list([
|
||||
ValueOwned::integer(0),
|
||||
ValueOwned::integer(4)
|
||||
Ok(Some(ConcreteValue::list([
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(-15)
|
||||
])))
|
||||
);
|
||||
}
|
||||
@ -122,10 +122,10 @@ fn list_with_simple_expression() {
|
||||
(Instruction::r#return(true), Span(13, 13)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(4),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(4),
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
@ -133,9 +133,10 @@ fn list_with_simple_expression() {
|
||||
|
||||
assert_eq!(
|
||||
run(source),
|
||||
Ok(Some(ValueOwned::list([
|
||||
ValueOwned::integer(0),
|
||||
ValueOwned::integer(3)
|
||||
Ok(Some(ConcreteValue::list([
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(5),
|
||||
ConcreteValue::Integer(4),
|
||||
])))
|
||||
);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fn and() {
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -43,7 +43,7 @@ fn or() {
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(true))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -65,7 +65,7 @@ fn variable_and() {
|
||||
(Instruction::get_local(3, 1), Span(34, 35)),
|
||||
(Instruction::r#return(true), Span(35, 35)),
|
||||
],
|
||||
vec![ValueOwned::string("a"), ValueOwned::string("b"),],
|
||||
vec![ConcreteValue::string("a"), ConcreteValue::string("b"),],
|
||||
vec![
|
||||
Local::new(0, Type::Boolean, false, Scope::default()),
|
||||
Local::new(1, Type::Boolean, false, Scope::default()),
|
||||
@ -73,5 +73,5 @@ fn variable_and() {
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ fn r#while() {
|
||||
(Instruction::r#return(true), Span(42, 42)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(0),
|
||||
ValueOwned::string("x"),
|
||||
ValueOwned::integer(5),
|
||||
ValueOwned::integer(1),
|
||||
ConcreteValue::Integer(0),
|
||||
ConcreteValue::string("x"),
|
||||
ConcreteValue::Integer(5),
|
||||
ConcreteValue::Integer(1),
|
||||
],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(5))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(5))));
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ fn add() {
|
||||
),
|
||||
(Instruction::r#return(true), Span(5, 5))
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(3))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(3))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -41,15 +41,15 @@ fn add_assign() {
|
||||
(Instruction::r#return(true), Span(24, 24))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::string("a"),
|
||||
ValueOwned::integer(2)
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::string("a"),
|
||||
ConcreteValue::Integer(2)
|
||||
],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(3))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(3))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -101,12 +101,12 @@ fn divide() {
|
||||
),
|
||||
(Instruction::r#return(true), Span(5, 5))
|
||||
],
|
||||
vec![ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(1))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -127,12 +127,12 @@ fn divide_assign() {
|
||||
(Instruction::get_local(1, 0), Span(23, 24)),
|
||||
(Instruction::r#return(true), Span(24, 24))
|
||||
],
|
||||
vec![ValueOwned::integer(2), ValueOwned::string("a")],
|
||||
vec![ConcreteValue::Integer(2), ConcreteValue::string("a")],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(1))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -180,17 +180,17 @@ fn math_operator_precedence() {
|
||||
(Instruction::r#return(true), Span(17, 17)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::integer(3),
|
||||
ValueOwned::integer(4),
|
||||
ValueOwned::integer(5),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::Integer(3),
|
||||
ConcreteValue::Integer(4),
|
||||
ConcreteValue::Integer(5),
|
||||
],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(1))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -210,12 +210,12 @@ fn multiply() {
|
||||
),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(2))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(2))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -237,15 +237,15 @@ fn multiply_assign() {
|
||||
(Instruction::r#return(true), Span(23, 23))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::string("a"),
|
||||
ValueOwned::integer(3)
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::string("a"),
|
||||
ConcreteValue::Integer(3)
|
||||
],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(6))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(6))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -281,12 +281,12 @@ fn subtract() {
|
||||
),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
vec![ValueOwned::integer(1), ValueOwned::integer(2)],
|
||||
vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)],
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(-1))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(-1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -308,15 +308,15 @@ fn subtract_assign() {
|
||||
(Instruction::r#return(true), Span(25, 25)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(42),
|
||||
ValueOwned::string("x"),
|
||||
ValueOwned::integer(2)
|
||||
ConcreteValue::Integer(42),
|
||||
ConcreteValue::string("x"),
|
||||
ConcreteValue::Integer(2)
|
||||
],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(40))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(40))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -18,8 +18,8 @@ fn panic() {
|
||||
(Instruction::r#return(true), Span(27, 27))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::string("Goodbye world!"),
|
||||
ValueOwned::integer(42)
|
||||
ConcreteValue::string("Goodbye world!"),
|
||||
ConcreteValue::Integer(42)
|
||||
],
|
||||
vec![]
|
||||
)),
|
||||
@ -53,10 +53,10 @@ fn to_string() {
|
||||
),
|
||||
(Instruction::r#return(true), Span(13, 13))
|
||||
],
|
||||
vec![ValueOwned::integer(42)],
|
||||
vec![ConcreteValue::Integer(42)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::string("42"))))
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::string("42"))))
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ fn allow_access_to_parent_scope() {
|
||||
}
|
||||
"#;
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(1))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -44,15 +44,15 @@ fn block_scope() {
|
||||
(Instruction::r#return(false), Span(165, 165))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(0),
|
||||
ValueOwned::string("a"),
|
||||
ValueOwned::integer(42),
|
||||
ValueOwned::string("b"),
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::string("c"),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::string("d"),
|
||||
ValueOwned::string("e"),
|
||||
ConcreteValue::Integer(0),
|
||||
ConcreteValue::string("a"),
|
||||
ConcreteValue::Integer(42),
|
||||
ConcreteValue::string("b"),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::string("c"),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::string("d"),
|
||||
ConcreteValue::string("e"),
|
||||
],
|
||||
vec![
|
||||
Local::new(1, Type::Integer, false, Scope::new(0, 0)),
|
||||
@ -115,16 +115,16 @@ fn multiple_block_scopes() {
|
||||
(Instruction::r#return(false), Span(307, 307))
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(0),
|
||||
ValueOwned::string("a"),
|
||||
ValueOwned::integer(42),
|
||||
ValueOwned::string("b"),
|
||||
ValueOwned::integer(1),
|
||||
ValueOwned::string("c"),
|
||||
ValueOwned::integer(2),
|
||||
ValueOwned::string("d"),
|
||||
ValueOwned::string("q"),
|
||||
ValueOwned::string("e"),
|
||||
ConcreteValue::Integer(0),
|
||||
ConcreteValue::string("a"),
|
||||
ConcreteValue::Integer(42),
|
||||
ConcreteValue::string("b"),
|
||||
ConcreteValue::Integer(1),
|
||||
ConcreteValue::string("c"),
|
||||
ConcreteValue::Integer(2),
|
||||
ConcreteValue::string("d"),
|
||||
ConcreteValue::string("q"),
|
||||
ConcreteValue::string("e"),
|
||||
],
|
||||
vec![
|
||||
Local::new(1, Type::Integer, false, Scope::new(0, 0)),
|
||||
|
@ -12,12 +12,12 @@ fn negate() {
|
||||
(*Instruction::negate(0, 0).set_b_is_constant(), Span(0, 1)),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
vec![ValueOwned::integer(42)],
|
||||
vec![ConcreteValue::Integer(42)],
|
||||
vec![]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(-42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(-42))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -38,5 +38,5 @@ fn not() {
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::boolean(false))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false))));
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ fn define_local() {
|
||||
(Instruction::define_local(0, 0, false), Span(4, 5)),
|
||||
(Instruction::r#return(false), Span(11, 11))
|
||||
],
|
||||
vec![ValueOwned::integer(42), ValueOwned::string("x")],
|
||||
vec![ConcreteValue::Integer(42), ConcreteValue::string("x")],
|
||||
vec![Local::new(1, Type::Integer, false, Scope::default())]
|
||||
)),
|
||||
);
|
||||
@ -55,13 +55,13 @@ fn set_local() {
|
||||
(Instruction::r#return(true), Span(25, 25)),
|
||||
],
|
||||
vec![
|
||||
ValueOwned::integer(41),
|
||||
ValueOwned::string("x"),
|
||||
ValueOwned::integer(42)
|
||||
ConcreteValue::Integer(41),
|
||||
ConcreteValue::string("x"),
|
||||
ConcreteValue::Integer(42)
|
||||
],
|
||||
vec![Local::new(1, Type::Integer, true, Scope::default())]
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(run(source), Ok(Some(ValueOwned::integer(42))));
|
||||
assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(42))));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user