dust/dust-lang/src/value.rs

881 lines
26 KiB
Rust
Raw Normal View History

2024-08-09 01:59:09 +00:00
//! Dust value representation
2024-02-25 18:49:26 +00:00
use std::{
2024-02-25 19:26:22 +00:00
cmp::Ordering,
collections::BTreeMap,
2024-08-09 00:58:56 +00:00
error::Error,
2024-03-06 20:36:58 +00:00
fmt::{self, Display, Formatter},
2024-02-25 18:49:26 +00:00
ops::Range,
2024-03-23 12:15:48 +00:00
sync::Arc,
2024-02-25 18:49:26 +00:00
};
use serde::{
de::Visitor,
2024-08-04 00:23:52 +00:00
ser::{SerializeMap, SerializeSeq, SerializeTuple},
Deserialize, Deserializer, Serialize,
};
2024-06-04 18:47:15 +00:00
2024-08-10 00:52:13 +00:00
use crate::{identifier::Identifier, AbstractSyntaxTree, Context, Type, Vm, VmError};
2024-02-25 18:49:26 +00:00
2024-08-07 23:12:40 +00:00
/// Dust value representation
///
/// Each type of value has a corresponding constructor, here are some simple examples:
///
/// ```
/// # use dust_lang::Value;
/// let boolean = Value::boolean(true);
/// let float = Value::float(3.14);
/// let integer = Value::integer(42);
/// let string = Value::string("Hello, world!");
/// ```
///
/// Values can be combined into more complex values:
///
/// ```
/// # use dust_lang::Value;
/// let list = Value::list(vec![
/// Value::integer(1),
/// Value::integer(2),
/// Value::integer(3),
/// ]);
/// ```
///
/// Values have a type, which can be retrieved using the `type` method:
///
/// ```
/// # use std::collections::HashMap;
2024-08-10 08:32:27 +00:00
/// # use dust_lang::*;
/// let context = Context::new();
2024-08-07 23:12:40 +00:00
/// let value = Value::integer(42);
///
2024-08-10 08:32:27 +00:00
/// assert_eq!(value.r#type(&context), Type::Integer);
2024-08-07 23:12:40 +00:00
/// ```
2024-02-25 18:49:26 +00:00
#[derive(Clone, Debug, PartialEq)]
pub struct Value(Arc<ValueInner>);
impl Value {
pub fn inner(&self) -> &Arc<ValueInner> {
&self.0
}
pub fn boolean(boolean: bool) -> Self {
Value(Arc::new(ValueInner::Boolean(boolean)))
}
pub fn float(float: f64) -> Self {
Value(Arc::new(ValueInner::Float(float)))
}
pub fn function(function: Function) -> Self {
Value(Arc::new(ValueInner::Function(function)))
}
2024-02-25 18:49:26 +00:00
pub fn integer(integer: i64) -> Self {
Value(Arc::new(ValueInner::Integer(integer)))
}
2024-06-19 08:56:56 +00:00
pub fn list(list: Vec<Value>) -> Self {
2024-02-25 18:49:26 +00:00
Value(Arc::new(ValueInner::List(list)))
}
2024-02-28 23:36:47 +00:00
pub fn map(map: BTreeMap<Identifier, Value>) -> Self {
Value(Arc::new(ValueInner::Map(map)))
}
2024-02-25 18:49:26 +00:00
pub fn range(range: Range<i64>) -> Self {
Value(Arc::new(ValueInner::Range(range)))
}
2024-03-24 14:58:09 +00:00
pub fn string<T: ToString>(to_string: T) -> Self {
Value(Arc::new(ValueInner::String(to_string.to_string())))
2024-02-25 18:49:26 +00:00
}
2024-08-10 00:52:13 +00:00
pub fn r#type(&self, context: &Context) -> Type {
self.0.r#type(context)
2024-03-06 22:32:31 +00:00
}
pub fn get_property(&self, property: &Identifier) -> Option<Value> {
self.0.get_property(property)
}
2024-03-17 20:59:52 +00:00
pub fn as_boolean(&self) -> Option<bool> {
2024-02-25 19:26:22 +00:00
if let ValueInner::Boolean(boolean) = self.0.as_ref() {
2024-03-17 20:59:52 +00:00
Some(*boolean)
} else {
None
2024-03-09 13:10:54 +00:00
}
}
2024-08-12 09:44:05 +00:00
pub fn as_float(&self) -> Option<f64> {
if let ValueInner::Float(float) = self.0.as_ref() {
Some(*float)
} else {
None
}
}
pub fn as_function(&self) -> Option<&Function> {
if let ValueInner::Function(function) = self.0.as_ref() {
Some(function)
} else {
None
}
}
2024-06-19 08:56:56 +00:00
pub fn as_list(&self) -> Option<&Vec<Value>> {
2024-03-07 17:29:07 +00:00
if let ValueInner::List(list) = self.inner().as_ref() {
Some(list)
} else {
None
}
}
2024-08-12 02:02:17 +00:00
pub fn as_map(&self) -> Option<&BTreeMap<Identifier, Value>> {
if let ValueInner::Map(map) = self.inner().as_ref() {
Some(map)
} else {
None
}
}
2024-03-07 17:29:07 +00:00
pub fn as_integer(&self) -> Option<i64> {
if let ValueInner::Integer(integer) = self.inner().as_ref() {
Some(*integer)
} else {
None
}
}
2024-08-05 02:15:31 +00:00
pub fn add(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::float(left + right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::integer(left.saturating_add(*right)))
2024-08-05 02:15:31 +00:00
}
2024-08-09 04:49:17 +00:00
(ValueInner::String(left), ValueInner::String(right)) => {
Ok(Value::string(left.to_string() + right))
}
2024-08-05 02:15:31 +00:00
_ => Err(ValueError::CannotAdd(self.clone(), other.clone())),
}
}
pub fn subtract(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::float(left - right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::integer(left.saturating_sub(*right)))
}
_ => Err(ValueError::CannotSubtract(self.clone(), other.clone())),
}
}
pub fn multiply(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::float(left * right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::integer(left * right))
}
_ => Err(ValueError::CannotMultiply(self.clone(), other.clone())),
}
}
2024-08-09 10:46:24 +00:00
pub fn divide(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => {
if right == &0.0 {
Err(ValueError::DivisionByZero)
} else {
Ok(Value::float(left / right))
}
}
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
if right == &0 {
Err(ValueError::DivisionByZero)
} else {
Ok(Value::integer(left / right))
}
}
_ => Err(ValueError::CannotDivide(self.clone(), other.clone())),
}
}
2024-08-09 11:02:55 +00:00
pub fn modulo(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::float(left % right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
if right == &0 {
Err(ValueError::DivisionByZero)
} else {
Ok(Value::integer(left % right))
}
}
_ => Err(ValueError::CannotModulo(self.clone(), other.clone())),
}
}
pub fn less_than(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::boolean(left < right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::boolean(left < right))
}
_ => Err(ValueError::CannotLessThan(self.clone(), other.clone())),
}
}
pub fn less_than_or_equal(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => {
Ok(Value::boolean(left <= right))
}
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::boolean(left <= right))
}
_ => Err(ValueError::CannotLessThanOrEqual(
self.clone(),
other.clone(),
)),
}
}
pub fn greater_than(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::boolean(left > right)),
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::boolean(left > right))
}
_ => Err(ValueError::CannotGreaterThan(self.clone(), other.clone())),
}
}
pub fn greater_than_or_equal(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Float(left), ValueInner::Float(right)) => {
Ok(Value::boolean(left >= right))
}
(ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::boolean(left >= right))
}
_ => Err(ValueError::CannotGreaterThanOrEqual(
self.clone(),
other.clone(),
)),
}
}
2024-08-09 08:56:24 +00:00
pub fn and(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Boolean(left), ValueInner::Boolean(right)) => {
Ok(Value::boolean(*left && *right))
}
_ => Err(ValueError::CannotAnd(self.clone(), other.clone())),
}
}
pub fn or(&self, other: &Value) -> Result<Value, ValueError> {
match (self.inner().as_ref(), other.inner().as_ref()) {
(ValueInner::Boolean(left), ValueInner::Boolean(right)) => {
Ok(Value::boolean(*left || *right))
}
_ => Err(ValueError::CannotOr(self.clone(), other.clone())),
}
}
2024-03-06 20:36:58 +00:00
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.inner().as_ref() {
2024-03-08 21:14:47 +00:00
ValueInner::Boolean(boolean) => write!(f, "{boolean}"),
2024-06-24 18:44:10 +00:00
ValueInner::Float(float) => {
2024-08-09 04:31:38 +00:00
if float == &f64::INFINITY {
return write!(f, "Infinity");
}
if float == &f64::NEG_INFINITY {
return write!(f, "-Infinity");
}
2024-06-24 18:44:10 +00:00
write!(f, "{float}")?;
if &float.floor() == float {
write!(f, ".0")?;
}
Ok(())
}
ValueInner::Function(function) => write!(f, "{function}"),
2024-03-08 21:14:47 +00:00
ValueInner::Integer(integer) => write!(f, "{integer}"),
ValueInner::List(list) => {
write!(f, "[")?;
2024-03-08 03:20:59 +00:00
2024-07-12 14:20:52 +00:00
for (index, value) in list.iter().enumerate() {
if index == list.len() - 1 {
2024-06-19 08:56:56 +00:00
write!(f, "{}", value)?;
} else {
2024-06-19 08:56:56 +00:00
write!(f, "{}, ", value)?;
}
2024-03-08 03:20:59 +00:00
}
write!(f, "]")
2024-03-08 03:20:59 +00:00
}
2024-03-08 21:14:47 +00:00
ValueInner::Map(map) => {
2024-06-24 08:16:05 +00:00
write!(f, "{{ ")?;
2024-07-12 14:20:52 +00:00
for (index, (key, value)) in map.iter().enumerate() {
write!(f, "{key} = {value}")?;
2024-03-07 21:19:24 +00:00
2024-06-24 08:16:05 +00:00
if index != map.len() - 1 {
write!(f, ", ")?;
}
2024-03-07 21:19:24 +00:00
}
2024-06-24 08:16:05 +00:00
write!(f, " }}")
2024-03-07 21:19:24 +00:00
}
2024-06-26 15:35:39 +00:00
ValueInner::Range(range) => write!(f, "{}..{}", range.start, range.end),
2024-03-08 21:14:47 +00:00
ValueInner::String(string) => write!(f, "{string}"),
2024-03-06 20:36:58 +00:00
}
}
2024-02-25 19:26:22 +00:00
}
impl Eq for Value {}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Value {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.as_ref().cmp(other.0.as_ref())
}
2024-02-25 18:49:26 +00:00
}
2024-06-04 18:47:15 +00:00
impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2024-06-04 18:47:15 +00:00
where
S: serde::Serializer,
{
match self.0.as_ref() {
ValueInner::Boolean(boolean) => serializer.serialize_bool(*boolean),
ValueInner::Float(float) => serializer.serialize_f64(*float),
ValueInner::Function(function) => function.serialize(serializer),
ValueInner::Integer(integer) => serializer.serialize_i64(*integer),
ValueInner::List(list) => {
let mut list_ser = serializer.serialize_seq(Some(list.len()))?;
for item in list {
2024-06-19 08:56:56 +00:00
list_ser.serialize_element(&item)?;
}
list_ser.end()
}
ValueInner::Map(map) => {
let mut map_ser = serializer.serialize_map(Some(map.len()))?;
for (identifier, value) in map {
map_ser.serialize_entry(identifier, value)?;
}
map_ser.end()
}
ValueInner::Range(range) => {
let mut tuple_ser = serializer.serialize_tuple(2)?;
tuple_ser.serialize_element(&range.start)?;
tuple_ser.serialize_element(&range.end)?;
tuple_ser.end()
}
ValueInner::String(string) => serializer.serialize_str(string),
}
}
}
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.write_str("a boolean, float, function, integer, list, map, range, string or structure")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
2024-06-19 08:56:56 +00:00
Ok(Value::boolean(v))
}
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::integer(v))
}
2024-06-19 08:56:56 +00:00
fn visit_i128<E>(self, _: i128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
todo!()
}
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::integer(v as i64))
}
2024-06-19 08:56:56 +00:00
fn visit_u128<E>(self, _: u128) -> Result<Self::Value, E>
where
E: serde::de::Error,
2024-06-04 18:47:15 +00:00
{
todo!()
}
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
2024-06-19 08:56:56 +00:00
Ok(Value::float(v))
}
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v.encode_utf8(&mut [0u8; 4]))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
2024-06-19 08:56:56 +00:00
Ok(Value::string(v))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Bytes(v),
&self,
))
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(v)
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(&v)
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Option,
&self,
))
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Option,
&self,
))
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Unit,
&self,
))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::NewtypeStruct,
&self,
))
}
2024-06-19 08:56:56 +00:00
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
2024-06-19 08:56:56 +00:00
let mut list = Vec::with_capacity(seq.size_hint().unwrap_or(10));
while let Some(element) = seq.next_element()? {
list.push(element);
}
Ok(Value::list(list))
}
2024-06-19 08:56:56 +00:00
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut btree = BTreeMap::new();
2024-06-19 08:56:56 +00:00
while let Some((key, value)) = map.next_entry()? {
btree.insert(key, value);
}
Ok(Value::map(btree))
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
let _ = data;
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Enum,
&self,
))
}
2024-06-04 18:47:15 +00:00
}
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2024-06-04 18:47:15 +00:00
where
D: Deserializer<'de>,
2024-06-04 18:47:15 +00:00
{
deserializer.deserialize_any(ValueVisitor)
2024-06-04 18:47:15 +00:00
}
}
2024-06-22 17:55:43 +00:00
#[derive(Clone, Debug, PartialEq)]
2024-02-25 18:49:26 +00:00
pub enum ValueInner {
Boolean(bool),
Float(f64),
Function(Function),
2024-02-25 18:49:26 +00:00
Integer(i64),
2024-06-19 08:56:56 +00:00
List(Vec<Value>),
2024-02-28 23:36:47 +00:00
Map(BTreeMap<Identifier, Value>),
2024-02-25 18:49:26 +00:00
Range(Range<i64>),
String(String),
}
2024-03-20 12:36:18 +00:00
impl ValueInner {
fn r#type(&self, context: &Context) -> Type {
2024-08-04 00:23:52 +00:00
match self {
2024-03-20 12:36:18 +00:00
ValueInner::Boolean(_) => Type::Boolean,
ValueInner::Float(_) => Type::Float,
ValueInner::Function(function) => Type::Function {
type_parameters: function.type_parameters.clone(),
value_parameters: function.value_parameters.clone(),
2024-08-10 00:52:13 +00:00
return_type: function.return_type(context).map(Box::new),
},
2024-03-20 12:36:18 +00:00
ValueInner::Integer(_) => Type::Integer,
ValueInner::List(values) => {
2024-08-10 00:52:13 +00:00
let item_type = values.first().unwrap().r#type(context);
2024-03-20 12:36:18 +00:00
2024-06-17 14:10:06 +00:00
Type::List {
item_type: Box::new(item_type),
2024-03-20 12:36:18 +00:00
}
}
2024-06-24 08:02:44 +00:00
ValueInner::Map(value_map) => {
let mut type_map = BTreeMap::new();
2024-06-24 08:02:44 +00:00
for (identifier, value) in value_map {
2024-08-10 00:52:13 +00:00
let r#type = value.r#type(context);
2024-06-24 08:02:44 +00:00
type_map.insert(identifier.clone(), r#type);
}
Type::Map(type_map)
}
2024-03-20 12:36:18 +00:00
ValueInner::Range(_) => Type::Range,
ValueInner::String(_) => Type::String,
2024-08-04 00:23:52 +00:00
}
2024-03-20 12:36:18 +00:00
}
fn get_property(&self, property: &Identifier) -> Option<Value> {
match self {
ValueInner::List(list) => {
if property.as_str() == "length" {
Some(Value::integer(list.len() as i64))
} else {
None
}
}
ValueInner::Map(value_map) => value_map.get(property).cloned(),
_ => None,
}
}
2024-03-20 12:36:18 +00:00
}
2024-02-25 19:26:22 +00:00
impl Eq for ValueInner {}
impl PartialOrd for ValueInner {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ValueInner {
fn cmp(&self, other: &Self) -> Ordering {
use ValueInner::*;
match (self, other) {
(Boolean(left), Boolean(right)) => left.cmp(right),
(Boolean(_), _) => Ordering::Greater,
(Float(left), Float(right)) => left.total_cmp(right),
(Float(_), _) => Ordering::Greater,
(Function(left), Function(right)) => left.cmp(right),
(Function(_), _) => Ordering::Greater,
2024-02-25 19:26:22 +00:00
(Integer(left), Integer(right)) => left.cmp(right),
(Integer(_), _) => Ordering::Greater,
(List(left), List(right)) => left.cmp(right),
(List(_), _) => Ordering::Greater,
2024-02-28 23:36:47 +00:00
(Map(left), Map(right)) => left.cmp(right),
(Map(_), _) => Ordering::Greater,
2024-02-25 19:26:22 +00:00
(Range(left), Range(right)) => {
let start_cmp = left.start.cmp(&right.start);
if start_cmp.is_eq() {
left.end.cmp(&right.end)
} else {
start_cmp
}
}
(Range(_), _) => Ordering::Greater,
(String(left), String(right)) => left.cmp(right),
(String(_), _) => Ordering::Greater,
2024-07-12 14:20:52 +00:00
}
2024-06-22 17:55:43 +00:00
}
2024-03-09 13:10:54 +00:00
}
2024-08-05 02:15:31 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Function {
pub name: Identifier,
pub type_parameters: Option<Vec<Type>>,
pub value_parameters: Option<Vec<(Identifier, Type)>>,
pub body: AbstractSyntaxTree,
}
impl Function {
pub fn call(
self,
2024-08-07 22:46:40 +00:00
_type_arguments: Option<Vec<Type>>,
value_arguments: Option<Vec<Value>>,
context: &mut Context,
) -> Result<Option<Value>, VmError> {
let mut new_context = context.clone();
if let (Some(value_parameters), Some(value_arguments)) =
(self.value_parameters, value_arguments)
{
for ((identifier, _), value) in value_parameters.into_iter().zip(value_arguments) {
new_context.set_value(identifier, value);
}
}
let mut vm = Vm::new(self.body);
vm.run(&mut new_context)
}
2024-08-10 00:52:13 +00:00
pub fn return_type(&self, variables: &Context) -> Option<Type> {
self.body
.nodes
.iter()
.last()
.unwrap()
.inner
.expected_type(variables)
}
}
impl Display for Function {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(type_parameters) = &self.type_parameters {
write!(f, "<")?;
for (index, type_parameter) in type_parameters.iter().enumerate() {
if index > 0 {
write!(f, ", ")?;
}
write!(f, "{}", type_parameter)?;
}
write!(f, ">")?;
}
write!(f, "(")?;
if let Some(value_paramers) = &self.value_parameters {
for (index, (identifier, r#type)) in value_paramers.iter().enumerate() {
if index > 0 {
write!(f, ", ")?;
}
write!(f, "{identifier}: {type}")?;
}
}
write!(f, ") {{")?;
for statement in &self.body.nodes {
write!(f, "{}", statement)?;
}
write!(f, "}}")
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
2024-08-05 02:15:31 +00:00
pub enum ValueError {
CannotAdd(Value, Value),
2024-08-09 08:56:24 +00:00
CannotAnd(Value, Value),
2024-08-09 10:46:24 +00:00
CannotDivide(Value, Value),
CannotGreaterThan(Value, Value),
CannotGreaterThanOrEqual(Value, Value),
2024-08-09 08:56:24 +00:00
CannotLessThan(Value, Value),
CannotLessThanOrEqual(Value, Value),
2024-08-09 11:02:55 +00:00
CannotModulo(Value, Value),
2024-08-09 08:56:24 +00:00
CannotMultiply(Value, Value),
CannotSubtract(Value, Value),
CannotOr(Value, Value),
2024-08-09 10:46:24 +00:00
DivisionByZero,
2024-08-05 18:58:58 +00:00
ExpectedList(Value),
IndexOutOfBounds { value: Value, index: i64 },
2024-08-05 02:15:31 +00:00
}
2024-08-09 00:58:56 +00:00
impl Error for ValueError {}
impl Display for ValueError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
ValueError::CannotAdd(left, right) => write!(f, "Cannot add {} and {}", left, right),
2024-08-09 08:56:24 +00:00
ValueError::CannotAnd(left, right) => write!(
f,
"Cannot use logical and operation on {} and {}",
left, right
),
2024-08-09 10:46:24 +00:00
ValueError::CannotDivide(left, right) => {
write!(f, "Cannot divide {} by {}", left, right)
}
2024-08-09 11:02:55 +00:00
ValueError::CannotModulo(left, right) => {
write!(f, "Cannot modulo {} by {}", left, right)
}
ValueError::CannotMultiply(left, right) => {
write!(f, "Cannot multiply {} and {}", left, right)
}
ValueError::CannotSubtract(left, right) => {
write!(f, "Cannot subtract {} and {}", left, right)
}
ValueError::CannotLessThan(left, right)
| ValueError::CannotLessThanOrEqual(left, right)
| ValueError::CannotGreaterThan(left, right)
| ValueError::CannotGreaterThanOrEqual(left, right) => {
write!(f, "Cannot compare {} and {}", left, right)
}
2024-08-09 08:56:24 +00:00
ValueError::CannotOr(left, right) => {
write!(
f,
"Cannot use logical or operation on {} and {}",
left, right
)
2024-08-09 00:58:56 +00:00
}
2024-08-09 10:46:24 +00:00
ValueError::DivisionByZero => write!(f, "Division by zero"),
2024-08-09 00:58:56 +00:00
ValueError::IndexOutOfBounds { value, index } => {
write!(f, "{} does not have an index of {}", value, index)
}
ValueError::ExpectedList(value) => write!(f, "{} is not a list", value),
}
}
}