1
0

Begin changing value type

This commit is contained in:
Jeff 2024-08-23 01:12:20 -04:00
parent 956def5ec6
commit 87bced9719
3 changed files with 1232 additions and 916 deletions

View File

@ -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

View File

@ -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))))
} }
} }
} }