Begin changing value type
This commit is contained in:
parent
956def5ec6
commit
87bced9719
@ -7,7 +7,7 @@ use std::{
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Identifier, Type, Value};
|
use crate::{Identifier, Type, Value, ValueData, ValueError};
|
||||||
|
|
||||||
/// Integrated function that can be called from Dust code.
|
/// Integrated function that can be called from Dust code.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
@ -84,21 +84,17 @@ impl BuiltInFunction {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
BuiltInFunction::ToString => {
|
BuiltInFunction::ToString => {
|
||||||
Ok(Some(Value::String(value_arguments.unwrap()[0].to_string())))
|
Ok(Some(Value::string(value_arguments.unwrap()[0].to_string())))
|
||||||
}
|
}
|
||||||
BuiltInFunction::IsEven => {
|
BuiltInFunction::IsEven => {
|
||||||
if let Value::Integer(integer) = value_arguments.unwrap()[0] {
|
let is_even = value_arguments.unwrap()[0].is_even()?;
|
||||||
Ok(Some(Value::Boolean(integer % 2 == 0)))
|
|
||||||
} else {
|
Ok(Some(is_even))
|
||||||
Err(BuiltInFunctionError::ExpectedInteger)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
BuiltInFunction::IsOdd => {
|
BuiltInFunction::IsOdd => {
|
||||||
if let Value::Integer(integer) = value_arguments.unwrap()[0] {
|
let is_odd = value_arguments.unwrap()[0].is_odd()?;
|
||||||
Ok(Some(Value::Boolean(integer % 2 != 0)))
|
|
||||||
} else {
|
Ok(Some(is_odd))
|
||||||
Err(BuiltInFunctionError::ExpectedInteger)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
BuiltInFunction::ReadLine => {
|
BuiltInFunction::ReadLine => {
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
@ -108,15 +104,45 @@ impl BuiltInFunction {
|
|||||||
Ok(Some(Value::string(input.trim_end_matches('\n'))))
|
Ok(Some(Value::string(input.trim_end_matches('\n'))))
|
||||||
}
|
}
|
||||||
BuiltInFunction::WriteLine => {
|
BuiltInFunction::WriteLine => {
|
||||||
if let Value::String(string) = &value_arguments.unwrap()[0] {
|
let first_argument = &value_arguments.unwrap()[0];
|
||||||
|
|
||||||
|
match first_argument {
|
||||||
|
Value::Raw(ValueData::String(string)) => {
|
||||||
let mut stdout = stdout();
|
let mut stdout = stdout();
|
||||||
|
|
||||||
stdout.write_all(string.as_bytes())?;
|
stdout.write_all(string.as_bytes())?;
|
||||||
stdout.write_all(b"\n")?;
|
stdout.write_all(b"\n")?;
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
}
|
||||||
Err(BuiltInFunctionError::ExpectedString)
|
|
||||||
|
Value::Reference(reference) => match reference.as_ref() {
|
||||||
|
ValueData::String(string) => {
|
||||||
|
let mut stdout = stdout();
|
||||||
|
|
||||||
|
stdout.write_all(string.as_bytes())?;
|
||||||
|
stdout.write_all(b"\n")?;
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
_ => Err(BuiltInFunctionError::ExpectedString),
|
||||||
|
},
|
||||||
|
Value::Mutable(locked) => {
|
||||||
|
let value_data = &*locked.read().unwrap();
|
||||||
|
let string = match value_data {
|
||||||
|
ValueData::String(string) => string,
|
||||||
|
_ => return Err(BuiltInFunctionError::ExpectedString),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stdout = stdout();
|
||||||
|
|
||||||
|
stdout.write_all(string.as_bytes())?;
|
||||||
|
stdout.write_all(b"\n")?;
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => Err(BuiltInFunctionError::ExpectedString),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,6 +158,7 @@ impl Display for BuiltInFunction {
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum BuiltInFunctionError {
|
pub enum BuiltInFunctionError {
|
||||||
Io(io::ErrorKind),
|
Io(io::ErrorKind),
|
||||||
|
ValueError(ValueError),
|
||||||
|
|
||||||
ExpectedString,
|
ExpectedString,
|
||||||
ExpectedList,
|
ExpectedList,
|
||||||
@ -140,6 +167,12 @@ pub enum BuiltInFunctionError {
|
|||||||
WrongNumberOfValueArguments,
|
WrongNumberOfValueArguments,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ValueError> for BuiltInFunctionError {
|
||||||
|
fn from(v: ValueError) -> Self {
|
||||||
|
Self::ValueError(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<io::Error> for BuiltInFunctionError {
|
impl From<io::Error> for BuiltInFunctionError {
|
||||||
fn from(error: io::Error) -> Self {
|
fn from(error: io::Error) -> Self {
|
||||||
Self::Io(error.kind())
|
Self::Io(error.kind())
|
||||||
@ -152,6 +185,9 @@ impl Display for BuiltInFunctionError {
|
|||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
BuiltInFunctionError::Io(error_kind) => write!(f, "I/O error: {}", error_kind),
|
BuiltInFunctionError::Io(error_kind) => write!(f, "I/O error: {}", error_kind),
|
||||||
|
BuiltInFunctionError::ValueError(value_error) => {
|
||||||
|
write!(f, "Value error: {}", value_error)
|
||||||
|
}
|
||||||
BuiltInFunctionError::ExpectedInteger => write!(f, "Expected an integer"),
|
BuiltInFunctionError::ExpectedInteger => write!(f, "Expected an integer"),
|
||||||
BuiltInFunctionError::ExpectedString => write!(f, "Expected a string"),
|
BuiltInFunctionError::ExpectedString => write!(f, "Expected a string"),
|
||||||
BuiltInFunctionError::ExpectedList => write!(f, "Expected a list"),
|
BuiltInFunctionError::ExpectedList => write!(f, "Expected a list"),
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
core_library, parse, Analyzer, BuiltInFunctionError, Constructor, Context, ContextData,
|
core_library, parse, Analyzer, BuiltInFunctionError, Constructor, Context, ContextData,
|
||||||
ContextError, DustError, Expression, Function, FunctionCallError, Identifier, ParseError,
|
ContextError, DustError, Expression, Function, FunctionCallError, Identifier, ParseError,
|
||||||
StructType, Type, Value, ValueError,
|
StructType, Type, Value, ValueData, ValueError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Run the source code and return the result.
|
/// Run the source code and return the result.
|
||||||
@ -200,7 +200,8 @@ impl Vm {
|
|||||||
let position = value.position();
|
let position = value.position();
|
||||||
let value = self
|
let value = self
|
||||||
.run_expression(value, collect_garbage)?
|
.run_expression(value, collect_garbage)?
|
||||||
.expect_value(position)?;
|
.expect_value(position)?
|
||||||
|
.into_reference();
|
||||||
|
|
||||||
self.context
|
self.context
|
||||||
.set_variable_value(identifier.inner, value)
|
.set_variable_value(identifier.inner, value)
|
||||||
@ -367,22 +368,33 @@ impl Vm {
|
|||||||
let start = self
|
let start = self
|
||||||
.run_expression(start, collect_garbage)?
|
.run_expression(start, collect_garbage)?
|
||||||
.expect_value(start_position)?;
|
.expect_value(start_position)?;
|
||||||
|
|
||||||
|
let start_data = match start {
|
||||||
|
Value::Raw(data) => data,
|
||||||
|
Value::Reference(reference) => reference.as_ref().clone(),
|
||||||
|
Value::Mutable(locked) => locked.read().unwrap().clone(),
|
||||||
|
};
|
||||||
let end_position = end.position();
|
let end_position = end.position();
|
||||||
let end = self
|
let end = self
|
||||||
.run_expression(end, collect_garbage)?
|
.run_expression(end, collect_garbage)?
|
||||||
.expect_value(end_position)?;
|
.expect_value(end_position)?;
|
||||||
|
let end_data = match end {
|
||||||
|
Value::Raw(data) => data,
|
||||||
|
Value::Reference(reference) => reference.as_ref().clone(),
|
||||||
|
Value::Mutable(locked) => locked.read().unwrap().clone(),
|
||||||
|
};
|
||||||
|
|
||||||
match (start, end) {
|
match (start_data, end_data) {
|
||||||
(Value::Byte(start), Value::Byte(end)) => {
|
(ValueData::Byte(start), ValueData::Byte(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Character(start), Value::Character(end)) => {
|
(ValueData::Character(start), ValueData::Character(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Float(start), Value::Float(end)) => {
|
(ValueData::Float(start), ValueData::Float(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Integer(start), Value::Integer(end)) => {
|
(ValueData::Integer(start), ValueData::Integer(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
Ok(Evaluation::Return(Some(Value::range(start, end))))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidRange {
|
_ => Err(RuntimeError::InvalidRange {
|
||||||
@ -396,22 +408,33 @@ impl Vm {
|
|||||||
let start = self
|
let start = self
|
||||||
.run_expression(start, collect_garbage)?
|
.run_expression(start, collect_garbage)?
|
||||||
.expect_value(start_position)?;
|
.expect_value(start_position)?;
|
||||||
|
|
||||||
|
let start_data = match start {
|
||||||
|
Value::Raw(data) => data,
|
||||||
|
Value::Reference(reference) => reference.as_ref().clone(),
|
||||||
|
Value::Mutable(locked) => locked.read().unwrap().clone(),
|
||||||
|
};
|
||||||
let end_position = end.position();
|
let end_position = end.position();
|
||||||
let end = self
|
let end = self
|
||||||
.run_expression(end, collect_garbage)?
|
.run_expression(end, collect_garbage)?
|
||||||
.expect_value(end_position)?;
|
.expect_value(end_position)?;
|
||||||
|
let end_data = match end {
|
||||||
|
Value::Raw(data) => data,
|
||||||
|
Value::Reference(reference) => reference.as_ref().clone(),
|
||||||
|
Value::Mutable(locked) => locked.read().unwrap().clone(),
|
||||||
|
};
|
||||||
|
|
||||||
match (start, end) {
|
match (start_data, end_data) {
|
||||||
(Value::Byte(start), Value::Byte(end)) => {
|
(ValueData::Byte(start), ValueData::Byte(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Character(start), Value::Character(end)) => {
|
(ValueData::Character(start), ValueData::Character(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Float(start), Value::Float(end)) => {
|
(ValueData::Float(start), ValueData::Float(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
||||||
}
|
}
|
||||||
(Value::Integer(start), Value::Integer(end)) => {
|
(ValueData::Integer(start), ValueData::Integer(end)) => {
|
||||||
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
Ok(Evaluation::Return(Some(Value::range_inclusive(start, end))))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidRange {
|
_ => Err(RuntimeError::InvalidRange {
|
||||||
@ -441,7 +464,7 @@ impl Vm {
|
|||||||
map.insert(identifier.inner, value);
|
map.insert(identifier.inner, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(Value::Map(map))))
|
Ok(Evaluation::Return(Some(Value::map(map))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_operator(
|
fn run_operator(
|
||||||
@ -483,41 +506,25 @@ impl Vm {
|
|||||||
let right_value = self
|
let right_value = self
|
||||||
.run_expression(right, collect_garbage)?
|
.run_expression(right, collect_garbage)?
|
||||||
.expect_value(right_position)?;
|
.expect_value(right_position)?;
|
||||||
let outcome =
|
let result = match operator.inner {
|
||||||
match operator.inner {
|
|
||||||
ComparisonOperator::Equal => left_value.equal(&right_value),
|
ComparisonOperator::Equal => left_value.equal(&right_value),
|
||||||
ComparisonOperator::NotEqual => left_value.not_equal(&right_value),
|
ComparisonOperator::NotEqual => left_value.not_equal(&right_value),
|
||||||
ComparisonOperator::GreaterThan => left_value
|
ComparisonOperator::GreaterThan => left_value.greater_than(&right_value),
|
||||||
.greater_than(&right_value)
|
ComparisonOperator::GreaterThanOrEqual => {
|
||||||
.map_err(|error| RuntimeError::ValueError {
|
left_value.greater_than_or_equal(&right_value)
|
||||||
error,
|
}
|
||||||
left_position,
|
ComparisonOperator::LessThan => left_value.less_than(&right_value),
|
||||||
right_position,
|
ComparisonOperator::LessThanOrEqual => {
|
||||||
})?,
|
left_value.less_than_or_equal(&right_value)
|
||||||
ComparisonOperator::GreaterThanOrEqual => left_value
|
}
|
||||||
.greater_than_or_equal(&right_value)
|
|
||||||
.map_err(|error| RuntimeError::ValueError {
|
|
||||||
error,
|
|
||||||
left_position,
|
|
||||||
right_position,
|
|
||||||
})?,
|
|
||||||
ComparisonOperator::LessThan => left_value
|
|
||||||
.less_than(&right_value)
|
|
||||||
.map_err(|error| RuntimeError::ValueError {
|
|
||||||
error,
|
|
||||||
left_position,
|
|
||||||
right_position,
|
|
||||||
})?,
|
|
||||||
ComparisonOperator::LessThanOrEqual => left_value
|
|
||||||
.less_than_or_equal(&right_value)
|
|
||||||
.map_err(|error| RuntimeError::ValueError {
|
|
||||||
error,
|
|
||||||
left_position,
|
|
||||||
right_position,
|
|
||||||
})?,
|
|
||||||
};
|
};
|
||||||
|
let value = result.map_err(|error| RuntimeError::ValueError {
|
||||||
|
error,
|
||||||
|
left_position,
|
||||||
|
right_position,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(outcome)))
|
Ok(Evaluation::Return(Some(value)))
|
||||||
}
|
}
|
||||||
OperatorExpression::CompoundAssignment {
|
OperatorExpression::CompoundAssignment {
|
||||||
assignee,
|
assignee,
|
||||||
@ -554,10 +561,11 @@ impl Vm {
|
|||||||
let value = self
|
let value = self
|
||||||
.run_expression(expression, collect_garbage)?
|
.run_expression(expression, collect_garbage)?
|
||||||
.expect_value(position)?;
|
.expect_value(position)?;
|
||||||
let integer = value
|
let negated = value.negate().map_err(|error| RuntimeError::ValueError {
|
||||||
.as_integer()
|
error,
|
||||||
.ok_or(RuntimeError::ExpectedBoolean { position })?;
|
left_position: position,
|
||||||
let negated = Value::Integer(-integer);
|
right_position: position,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(negated)))
|
Ok(Evaluation::Return(Some(negated)))
|
||||||
}
|
}
|
||||||
@ -566,10 +574,11 @@ impl Vm {
|
|||||||
let value = self
|
let value = self
|
||||||
.run_expression(expression, collect_garbage)?
|
.run_expression(expression, collect_garbage)?
|
||||||
.expect_value(position)?;
|
.expect_value(position)?;
|
||||||
let boolean = value
|
let not = value.not().map_err(|error| RuntimeError::ValueError {
|
||||||
.as_boolean()
|
error,
|
||||||
.ok_or(RuntimeError::ExpectedBoolean { position })?;
|
left_position: position,
|
||||||
let not = Value::Boolean(!boolean);
|
right_position: position,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(not)))
|
Ok(Evaluation::Return(Some(not)))
|
||||||
}
|
}
|
||||||
@ -666,14 +675,14 @@ impl Vm {
|
|||||||
fn run_literal(&self, literal: LiteralExpression) -> Result<Evaluation, RuntimeError> {
|
fn run_literal(&self, literal: LiteralExpression) -> Result<Evaluation, RuntimeError> {
|
||||||
let value = match literal {
|
let value = match literal {
|
||||||
LiteralExpression::BuiltInFunction(built_in_function) => {
|
LiteralExpression::BuiltInFunction(built_in_function) => {
|
||||||
Value::Function(Function::BuiltIn(built_in_function))
|
Value::function(Function::BuiltIn(built_in_function))
|
||||||
}
|
}
|
||||||
LiteralExpression::String(string) => Value::String(string),
|
LiteralExpression::String(string) => Value::string(string),
|
||||||
LiteralExpression::Primitive(primitive_expression) => match primitive_expression {
|
LiteralExpression::Primitive(primitive_expression) => match primitive_expression {
|
||||||
PrimitiveValueExpression::Boolean(boolean) => Value::Boolean(boolean),
|
PrimitiveValueExpression::Boolean(boolean) => Value::boolean(boolean),
|
||||||
PrimitiveValueExpression::Character(character) => Value::Character(character),
|
PrimitiveValueExpression::Character(character) => Value::character(character),
|
||||||
PrimitiveValueExpression::Integer(integer) => Value::Integer(integer),
|
PrimitiveValueExpression::Integer(integer) => Value::integer(integer),
|
||||||
PrimitiveValueExpression::Float(float) => Value::Float(float),
|
PrimitiveValueExpression::Float(float) => Value::float(float),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -699,14 +708,14 @@ impl Vm {
|
|||||||
|
|
||||||
let get_index =
|
let get_index =
|
||||||
list_value
|
list_value
|
||||||
.get_index(index_value)
|
.index(&index_value)
|
||||||
.map_err(|error| RuntimeError::ValueError {
|
.map_err(|error| RuntimeError::ValueError {
|
||||||
error,
|
error,
|
||||||
left_position: list_position,
|
left_position: list_position,
|
||||||
right_position: index_position,
|
right_position: index_position,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Evaluation::Return(get_index))
|
Ok(Evaluation::Return(Some(get_index)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_call(
|
fn run_call(
|
||||||
@ -728,14 +737,33 @@ impl Vm {
|
|||||||
.expect_value(container_position)?;
|
.expect_value(container_position)?;
|
||||||
|
|
||||||
let function = if let Some(value) = container_value.get_field(&field.inner) {
|
let function = if let Some(value) = container_value.get_field(&field.inner) {
|
||||||
if let Value::Function(function) = value {
|
match value {
|
||||||
function
|
Value::Raw(ValueData::Function(function)) => function,
|
||||||
} else {
|
Value::Reference(arc) => match arc.as_ref().clone() {
|
||||||
|
ValueData::Function(function) => function,
|
||||||
|
_ => {
|
||||||
return Err(RuntimeError::ExpectedFunction {
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
actual: value,
|
|
||||||
position: container_position,
|
position: container_position,
|
||||||
|
actual: container_value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Value::Mutable(locked) => match locked.read().unwrap().clone() {
|
||||||
|
ValueData::Function(function) => function,
|
||||||
|
_ => {
|
||||||
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
|
position: container_position,
|
||||||
|
actual: container_value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
|
position: container_position,
|
||||||
|
actual: container_value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(RuntimeError::UndefinedField {
|
return Err(RuntimeError::UndefinedField {
|
||||||
value: container_value,
|
value: container_value,
|
||||||
@ -798,13 +826,32 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Evaluation::Return(Some(value)) => {
|
Evaluation::Return(Some(value)) => {
|
||||||
let function = if let Value::Function(function) = value {
|
let function = match value {
|
||||||
function
|
Value::Raw(ValueData::Function(function)) => function,
|
||||||
} else {
|
Value::Reference(arc) => match arc.as_ref() {
|
||||||
|
ValueData::Function(function) => function.clone(),
|
||||||
|
_ => {
|
||||||
return Err(RuntimeError::ExpectedFunction {
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
actual: value.to_owned(),
|
|
||||||
position: invoker_position,
|
position: invoker_position,
|
||||||
|
actual: Value::Reference(arc.clone()),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Value::Mutable(locked) => match locked.read().unwrap().clone() {
|
||||||
|
ValueData::Function(function) => function,
|
||||||
|
_ => {
|
||||||
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
|
position: invoker_position,
|
||||||
|
actual: Value::Mutable(locked.clone()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Err(RuntimeError::ExpectedFunction {
|
||||||
|
position: invoker_position,
|
||||||
|
actual: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut value_arguments: Option<Vec<Value>> = None;
|
let mut value_arguments: Option<Vec<Value>> = None;
|
||||||
@ -880,13 +927,13 @@ impl Vm {
|
|||||||
.run_expression(repeat_operand, collect_garbage)?
|
.run_expression(repeat_operand, collect_garbage)?
|
||||||
.expect_value(position)?;
|
.expect_value(position)?;
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(Value::List(vec![
|
Ok(Evaluation::Return(Some(Value::list(vec![
|
||||||
value;
|
value;
|
||||||
length as usize
|
length as usize
|
||||||
]))))
|
]))))
|
||||||
}
|
}
|
||||||
ListExpression::Ordered(expressions) => {
|
ListExpression::Ordered(expressions) => {
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::with_capacity(expressions.len());
|
||||||
|
|
||||||
for expression in expressions {
|
for expression in expressions {
|
||||||
let position = expression.position();
|
let position = expression.position();
|
||||||
@ -897,7 +944,7 @@ impl Vm {
|
|||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Evaluation::Return(Some(Value::List(values))))
|
Ok(Evaluation::Return(Some(Value::list(values))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user